mirror of
https://github.com/postgres/postgres.git
synced 2025-05-15 00:02:24 -04:00
SGML source for new documentation.
This commit is contained in:
parent
878531f1ac
commit
c8cfb0cea8
120
doc/src/Makefile
Normal file
120
doc/src/Makefile
Normal file
@ -0,0 +1,120 @@
|
||||
# Postgres documentation makefile
|
||||
# Thomas Lockhart
|
||||
|
||||
PGDOCS= ..
|
||||
SRCDIR= ../../src
|
||||
|
||||
HPATH=$(PGDOCS)/doc
|
||||
PPATH=$(PGDOCS)/doc
|
||||
|
||||
#HSTYLE=/usr/lib/sgml/stylesheets/jade/docbook/html
|
||||
#PSTYLE=/usr/lib/sgml/stylesheets/jade/docbook/print
|
||||
|
||||
HSTYLE=/home/tgl/SGML/db107.d/docbook/html
|
||||
PSTYLE=/home/tgl/SGML/db107.d/docbook/print
|
||||
|
||||
HDSL=$(HSTYLE)/docbook.dsl
|
||||
PDSL=$(PSTYLE)/docbook.dsl
|
||||
|
||||
#DBOPTS=-V %no-split-output% -V %no-make-index%
|
||||
|
||||
TAR= tar
|
||||
TAREXCLUDE= --exclude=Makefile --exclude='*.sgml'
|
||||
|
||||
# Pick up Makefile.custom from the source area
|
||||
# This is the only resource from the code source area and is optional
|
||||
|
||||
ifneq ($(wildcard $(SRCDIR)/Makefile.custom), )
|
||||
include $(SRCDIR)/Makefile.custom
|
||||
endif
|
||||
|
||||
TARGETS= postgres tutorial user admin programmer
|
||||
|
||||
HTARGETS=#make this a mapping from targets
|
||||
PTARGETS=#make this a mapping from targets
|
||||
|
||||
.PRECIOUS: postgres.html postgres.tex postgres.dvi
|
||||
.PHONY: sources clean
|
||||
|
||||
install::
|
||||
$(MAKE) all
|
||||
(mv -rf *.gz ..)
|
||||
|
||||
all:: $(SGO) $(SGP)
|
||||
|
||||
sources::
|
||||
($(TAR) zcf sources.tar.gz --exclude='*.htm*' --exclude='*.gz' .)
|
||||
|
||||
user.tar.gz:
|
||||
$(MAKE) -C sgml clean
|
||||
$(MAKE) -C sgml user.html
|
||||
($(TAR) zcf $@ $(TAREXCLUDE) -C sgml .)
|
||||
|
||||
tutorial.tar.gz:
|
||||
$(MAKE) -C sgml clean
|
||||
$(MAKE) -C sgml tutorial.html
|
||||
($(TAR) zcf $@ $(TAREXCLUDE) -C sgml . -C .. -C graphics clientserver.gif)
|
||||
|
||||
clean::
|
||||
(rm -rf *.html *.htm)
|
||||
|
||||
distclean::
|
||||
$(MAKE) -C sgml clean
|
||||
|
||||
# Generic production rules
|
||||
|
||||
# Compressed file
|
||||
|
||||
%.gz: %
|
||||
(gzip -f $<)
|
||||
|
||||
# TAR file for HTML package
|
||||
|
||||
%.tar: %.html # %.ps
|
||||
(tar cf $@ $*.html index.html *.htm *.gif) # $*.ps
|
||||
(rm -rf index.html *.htm)
|
||||
|
||||
# (mkdir $*)
|
||||
# (rm -rf $*/*)
|
||||
# (mv *.htm $*/)
|
||||
# (cd $*/; ln -sf book01.htm index.html)
|
||||
# (tar cf $@ $*)
|
||||
|
||||
# HTML
|
||||
# Include some softlinks to the generic default file names
|
||||
|
||||
%.html: %.sgml $(HDSL)
|
||||
(rm -rf *.htm)
|
||||
jade $(DBOPTS) -D sgml -d $(HDSL) -t sgml $<
|
||||
(ln -sf book01.htm index.html)
|
||||
(ln -sf book01.htm $*.html)
|
||||
|
||||
# (mkdir $(HPATH)/$*) # be sure there is somewhere to put them
|
||||
# (rm -rf $(HPATH)/$*/*) # remove existing files since some names may be obsolete
|
||||
# (mv *.htm $(HPATH)/$*/) # and copy 'em over
|
||||
# (cd $(HPATH)/$*/; ln -sf book01.htm index.html)
|
||||
|
||||
# RTF to allow minor editing for hardcopy
|
||||
# This is used for v6.3 docs
|
||||
|
||||
%.rtf: %.sgml $(PDSL)
|
||||
jade $(DBOPTS) -d $(PDSL) -t rtf $<
|
||||
|
||||
# TeX and DVI
|
||||
|
||||
%.tex: %.sgml $(PDSL)
|
||||
jade $(DBOPTS) -d $(PDSL) -t tex $<
|
||||
|
||||
%.dvi: %.tex
|
||||
jadetex $<
|
||||
jadetex $<
|
||||
|
||||
# Postscript from TeX
|
||||
|
||||
%.ps: %.dvi
|
||||
dvips -o $@ $<
|
||||
|
||||
# Graphics
|
||||
|
||||
%.gif:
|
||||
cp -p graphics/%.gif .
|
103
doc/src/sgml/admin.sgml
Normal file
103
doc/src/sgml/admin.sgml
Normal file
@ -0,0 +1,103 @@
|
||||
<!-- admin.sgml
|
||||
-
|
||||
- Postgres administrator's guide.
|
||||
- Derived from postgres.sgml.
|
||||
- thomas 1998-02-27
|
||||
-
|
||||
- -->
|
||||
<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
|
||||
<!entity intro SYSTEM "intro.sgml">
|
||||
|
||||
<!entity install SYSTEM "install.sgml">
|
||||
<!entity ports SYSTEM "ports.sgml">
|
||||
<!entity recovery SYSTEM "recovery.sgml">
|
||||
<!entity regress SYSTEM "regress.sgml">
|
||||
<!entity release SYSTEM "release.sgml">
|
||||
<!entity start-ag SYSTEM "start-ag.sgml">
|
||||
|
||||
<!entity biblio SYSTEM "biblio.sgml">
|
||||
]>
|
||||
<!-- entity manpages SYSTEM "man/manpages.sgml" subdoc -->
|
||||
<Book>
|
||||
|
||||
<!-- Title information -->
|
||||
|
||||
<Title>PostgreSQL Administrator's Guide</Title>
|
||||
<BookInfo>
|
||||
<ReleaseInfo>Covering v6.3 for general release</ReleaseInfo>
|
||||
<BookBiblio>
|
||||
<AuthorGroup>
|
||||
<CorpAuthor>The PostgreSQL Development Team</CorpAuthor>
|
||||
</AuthorGroup>
|
||||
<!-- editor in authorgroup is not supported
|
||||
<AuthorGroup>
|
||||
-->
|
||||
<Editor>
|
||||
<FirstName>Thomas</FirstName>
|
||||
<SurName>Lockhart</SurName>
|
||||
<Affiliation>
|
||||
<OrgName>Caltech/JPL</OrgName>
|
||||
</Affiliation>
|
||||
</Editor>
|
||||
<!--
|
||||
</AuthorGroup>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<AuthorInitials>TGL</AuthorInitials>
|
||||
-->
|
||||
|
||||
<Date>(last updated 1998-02-23)</Date>
|
||||
</BookBiblio>
|
||||
|
||||
<LegalNotice>
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> is copyright (C) 1998 by the Postgres Global Development Group.
|
||||
</Para>
|
||||
</LegalNotice>
|
||||
|
||||
</BookInfo>
|
||||
|
||||
<!--
|
||||
<TOC> </TOC>
|
||||
<LOT> </LOT>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<Dedication>
|
||||
<Para>
|
||||
Your name here...
|
||||
</Para>
|
||||
</Dedication>
|
||||
-->
|
||||
|
||||
<Preface>
|
||||
<Title>Summary</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName>,
|
||||
developed originally in the UC Berkeley Computer Science Department,
|
||||
pioneered many of the object-relational concepts
|
||||
now becoming available in some commercial databases.
|
||||
It provides SQL92/SQL3 language support,
|
||||
transaction integrity, and type extensibility.
|
||||
<ProductName>PostgreSQL</ProductName> is a public-domain, open source descendant
|
||||
of this original Berkeley code.
|
||||
</Para>
|
||||
</Preface>
|
||||
|
||||
&intro;
|
||||
|
||||
&ports;
|
||||
&install;
|
||||
&start-ag;
|
||||
&recovery;
|
||||
®ress;
|
||||
&release;
|
||||
|
||||
&biblio;
|
||||
|
||||
<INDEX> </INDEX>
|
||||
|
||||
</Book>
|
||||
|
304
doc/src/sgml/advanced.sgml
Normal file
304
doc/src/sgml/advanced.sgml
Normal file
@ -0,0 +1,304 @@
|
||||
<Chapter>
|
||||
<Title>Advanced <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> Features</Title>
|
||||
|
||||
<Para>
|
||||
Having covered the basics of using <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> to
|
||||
access your data, we will now discuss those features of
|
||||
<ProductName>Postgres</ProductName> 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
|
||||
<FileName>advance.sql</FileName> in the tutorial directory.
|
||||
(Refer to <XRef LinkEnd="QUERY"> for how to use it.)
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Inheritance</Title>
|
||||
|
||||
<Para>
|
||||
Let's create two classes. The capitals class contains
|
||||
state capitals which are also cities. Naturally, the
|
||||
capitals class should inherit from cities.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE TABLE cities (
|
||||
name text,
|
||||
population float,
|
||||
altitude int -- (in ft)
|
||||
);
|
||||
|
||||
CREATE TABLE capitals (
|
||||
state char2
|
||||
) INHERITS (cities);
|
||||
</ProgramListing>
|
||||
|
||||
In this case, an instance of capitals <FirstTerm>inherits</FirstTerm> all
|
||||
attributes (name, population, and altitude) from its
|
||||
parent, cities. The type of the attribute name is
|
||||
<Type>text</Type>, a native <ProductName>Postgres</ProductName> type for variable length
|
||||
ASCII strings. The type of the attribute population is
|
||||
<Type>float</Type>, a native <ProductName>Postgres</ProductName> type for double precision
|
||||
floating point numbers. State capitals have an extra
|
||||
attribute, state, that shows their state. In <ProductName>Postgres</ProductName>,
|
||||
a class can inherit from zero or more other classes,
|
||||
and a query can reference either all instances of a
|
||||
class or all instances of a class plus all of its
|
||||
descendants.
|
||||
<Note>
|
||||
<Para>
|
||||
The inheritance hierarchy is a directed acyclic graph.
|
||||
</Para>
|
||||
</Note>
|
||||
For example, the following query finds
|
||||
all the cities that are situated at an attitude of 500ft or higher:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT name, altitude
|
||||
FROM cities
|
||||
WHERE altitude > 500;
|
||||
|
||||
+----------+----------+
|
||||
|name | altitude |
|
||||
+----------+----------+
|
||||
|Las Vegas | 2174 |
|
||||
+----------+----------+
|
||||
|Mariposa | 1953 |
|
||||
+----------+----------+
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
On the other hand, to find the names of all cities,
|
||||
including state capitals, that are located at an altitude
|
||||
over 500ft, the query is:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT c.name, c.altitude
|
||||
FROM cities* c
|
||||
WHERE c.altitude > 500;
|
||||
</ProgramListing>
|
||||
|
||||
which returns:
|
||||
|
||||
<ProgramListing>
|
||||
+----------+----------+
|
||||
|name | altitude |
|
||||
+----------+----------+
|
||||
|Las Vegas | 2174 |
|
||||
+----------+----------+
|
||||
|Mariposa | 1953 |
|
||||
+----------+----------+
|
||||
|Madison | 845 |
|
||||
+----------+----------+
|
||||
</ProgramListing>
|
||||
|
||||
Here the <Quote>*</Quote> 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 (<Command>select</Command>, <Command>update</Command> and <Command>delete</Command>)
|
||||
support this <Quote>*</Quote> notation, as do others, like <Command>alter</Command>.
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Non-Atomic Values</Title>
|
||||
|
||||
<Para>
|
||||
One of the tenets of the relational model is that the
|
||||
attributes of a relation are atomic. <ProductName>Postgres</ProductName> 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.
|
||||
|
||||
<Sect2>
|
||||
<Title>Arrays</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE TABLE SAL_EMP (
|
||||
name text,
|
||||
pay_by_quarter int4[],
|
||||
schedule char16[][]
|
||||
);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The above query will create a class named SAL_EMP with
|
||||
a <FirstTerm>text</FirstTerm> string (name), a one-dimensional array of <FirstTerm>int4</FirstTerm>
|
||||
(pay_by_quarter), which represents the employee's
|
||||
salary by quarter and a two-dimensional array of <FirstTerm>char16</FirstTerm>
|
||||
(schedule), which represents the employee's weekly
|
||||
schedule. Now we do some <FirstTerm>INSERTS</FirstTerm>s; note that when
|
||||
appending to an array, we enclose the values within
|
||||
braces and separate them by commas. If you know <FirstTerm>C</FirstTerm>,
|
||||
this is not unlike the syntax for initializing structures.
|
||||
|
||||
<ProgramListing>
|
||||
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"}}');
|
||||
</ProgramListing>
|
||||
|
||||
By default, <ProductName>Postgres</ProductName> 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:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT name
|
||||
FROM SAL_EMP
|
||||
WHERE SAL_EMP.pay_by_quarter[1] <>
|
||||
SAL_EMP.pay_by_quarter[2];
|
||||
|
||||
+------+
|
||||
|name |
|
||||
+------+
|
||||
|Carol |
|
||||
+------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
This query retrieves the third quarter pay of all
|
||||
employees:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT SAL_EMP.pay_by_quarter[3] FROM SAL_EMP;
|
||||
|
||||
|
||||
+---------------+
|
||||
|pay_by_quarter |
|
||||
+---------------+
|
||||
|10000 |
|
||||
+---------------+
|
||||
|25000 |
|
||||
+---------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
|
||||
<ProgramListing>
|
||||
SELECT SAL_EMP.schedule[1:2][1:1]
|
||||
FROM SAL_EMP
|
||||
WHERE SAL_EMP.name = 'Bill';
|
||||
|
||||
+-------------------+
|
||||
|schedule |
|
||||
+-------------------+
|
||||
|{{"meeting"},{""}} |
|
||||
+-------------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Time Travel</Title>
|
||||
|
||||
<Para>
|
||||
As of <ProductName>Postgres</ProductName> v6.2, <Emphasis>time travel is no longer supported</Emphasis>. There are
|
||||
several reasons for this: performance impact, storage size, and a pg_time file which grows
|
||||
toward infinite size in a short period of time.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
New features such as triggers allow one to mimic the behavior of time travel when desired, without
|
||||
incurring the overhead when it is not needed (for most users, this is most of the time).
|
||||
See examples in the <FileName>contrib</FileName> directory for more information.
|
||||
</Para>
|
||||
|
||||
<Note>
|
||||
<Title>Time travel is deprecated</Title>
|
||||
<Para>
|
||||
The remaining text in this section is retained only until it can be rewritten in the context
|
||||
of new techniques to accomplish the same purpose. Volunteers? - thomas 1998-01-12
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT * FROM cities WHERE name = 'Mariposa';
|
||||
|
||||
+---------+------------+----------+
|
||||
|name | population | altitude |
|
||||
+---------+------------+----------+
|
||||
|Mariposa | 1320 | 1953 |
|
||||
+---------+------------+----------+
|
||||
</ProgramListing>
|
||||
|
||||
<ProductName>Postgres</ProductName> 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:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT name, population
|
||||
FROM cities['epoch', 'now']
|
||||
WHERE name = 'Mariposa';
|
||||
</ProgramListing>
|
||||
|
||||
where "epoch" indicates the beginning of the system
|
||||
clock.
|
||||
<Note>
|
||||
<Para>
|
||||
On UNIX systems, this is always midnight, January 1, 1970 GMT.
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
If you have executed all of the examples so
|
||||
far, then the above query returns:
|
||||
|
||||
<ProgramListing>
|
||||
+---------+------------+
|
||||
|name | population |
|
||||
+---------+------------+
|
||||
|Mariposa | 1200 |
|
||||
+---------+------------+
|
||||
|Mariposa | 1320 |
|
||||
+---------+------------+
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
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 ``[,].''
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>More Advanced Features</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> has many features not touched upon in this
|
||||
tutorial introduction, which has been oriented toward newer users of <Acronym>SQL</Acronym>.
|
||||
These are discussed in more detail in both the User's and Programmer's Guides.
|
||||
|
||||
</Chapter>
|
80
doc/src/sgml/arch-dev.sgml
Normal file
80
doc/src/sgml/arch-dev.sgml
Normal file
@ -0,0 +1,80 @@
|
||||
<Chapter>
|
||||
<TITLE>Architecture</TITLE>
|
||||
|
||||
<Sect1>
|
||||
<Title><ProductName>Postgres</ProductName> Architectural Concepts</Title>
|
||||
|
||||
<Para>
|
||||
Before we continue, you should understand the basic
|
||||
<ProductName>Postgres</ProductName> system architecture. Understanding how the
|
||||
parts of <ProductName>Postgres</ProductName> interact will make the next chapter
|
||||
somewhat clearer.
|
||||
In database jargon, <ProductName>Postgres</ProductName> uses a simple "process
|
||||
per-user" client/server model. A <ProductName>Postgres</ProductName> session
|
||||
consists of the following cooperating UNIX processes (programs):
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A supervisory daemon process (<Application>postmaster</Application>),
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
the user's frontend application (e.g., the <Application>psql</Application> program), and
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
the one or more backend database servers (the <Application>postgres</Application> process itself).
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
<Para>
|
||||
A single <Application>postmaster</Application> 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
|
||||
<Application>postmaster</Application> (<XRef LinkEnd="ARCHDEV-CONNECTIONS" EndTerm="ARCHDEV-CONNECTIONS">(a)), which in turn starts a new
|
||||
backend server process (<XRef LinkEnd="ARCHDEV-CONNECTIONS" EndTerm="ARCHDEV-CONNECTIONS">(b))
|
||||
|
||||
<Figure id="ARCHDEV-CONNECTIONS">
|
||||
<Title>How a connection is established</Title>
|
||||
<Graphic Align="center" FileRef="connections.gif" Format="GIF"></Graphic>
|
||||
</Figure>
|
||||
|
||||
and connects the
|
||||
frontend process to the new server (<XRef LinkEnd="ARCHDEV-CONNECTIONS" EndTerm="ARCHDEV-CONNECTIONS">(c)). From
|
||||
that point on, the frontend process and the backend
|
||||
server communicate without intervention by the
|
||||
<Application>postmaster</Application>. Hence, the <Application>postmaster</Application> is always running, waiting
|
||||
for requests, whereas frontend and backend processes
|
||||
come and go. The <FileName>libpq</FileName> 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 <FileName>libpq</FileName>.
|
||||
One implication of this architecture is that the
|
||||
<Application>postmaster</Application> 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 <Application>postmaster</Application> and
|
||||
postgres servers run with the user-id of the <ProductName>Postgres</ProductName>
|
||||
"superuser." Note that the <ProductName>Postgres</ProductName> superuser does not
|
||||
have to be a special user (e.g., a user named
|
||||
"postgres"). Furthermore, the <ProductName>Postgres</ProductName> superuser
|
||||
should
|
||||
definitely not be the UNIX superuser, "root"! In any
|
||||
case, all files relating to a database should belong to
|
||||
this <ProductName>Postgres</ProductName> superuser.
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
83
doc/src/sgml/arch-pg.sgml
Normal file
83
doc/src/sgml/arch-pg.sgml
Normal file
@ -0,0 +1,83 @@
|
||||
<Chapter>
|
||||
<TITLE>Architecture</TITLE>
|
||||
|
||||
<Sect1>
|
||||
<Title><ProductName>Postgres</ProductName> Architectural Concepts</Title>
|
||||
|
||||
<Para>
|
||||
Before we continue, you should understand the basic
|
||||
<ProductName>Postgres</ProductName> system architecture. Understanding how the
|
||||
parts of <ProductName>Postgres</ProductName> interact will make the next chapter
|
||||
somewhat clearer.
|
||||
In database jargon, <ProductName>Postgres</ProductName> uses a simple "process
|
||||
per-user" client/server model. A <ProductName>Postgres</ProductName> session
|
||||
consists of the following cooperating UNIX processes (programs):
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A supervisory daemon process (<Application>postmaster</Application>),
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
the user's frontend application (e.g., the <Application>psql</Application> program), and
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
the one or more backend database servers (the <Application>postgres</Application> process itself).
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
<Para>
|
||||
A single <Application>postmaster</Application> 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
|
||||
<Application>postmaster</Application>
|
||||
(<XRef LinkEnd="PGARCH-CONNECTIONS" EndTerm="PGARCH-CONNECTIONS">(a)),
|
||||
which in turn starts a new backend server process
|
||||
(<XRef LinkEnd="PGARCH-CONNECTIONS" EndTerm="PGARCH-CONNECTIONS">(b))
|
||||
|
||||
<Figure Id="PGARCH-CONNECTIONS">
|
||||
<Title>How a connection is established</Title>
|
||||
<Graphic Align="center" FileRef="connections.gif" Format="GIF"></Graphic>
|
||||
</Figure>
|
||||
|
||||
and connects the frontend process to the new server
|
||||
(<XRef LinkEnd="PGARCH-CONNECTIONS" EndTerm="PGARCH-CONNECTIONS">(c)).
|
||||
From that point on, the frontend process and the backend
|
||||
server communicate without intervention by the
|
||||
<Application>postmaster</Application>. Hence, the <Application>postmaster</Application> is always running, waiting
|
||||
for requests, whereas frontend and backend processes
|
||||
come and go. The <FileName>libpq</FileName> 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 <FileName>libpq</FileName>.
|
||||
One implication of this architecture is that the
|
||||
<Application>postmaster</Application> 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 <Application>postmaster</Application> and
|
||||
postgres servers run with the user-id of the <ProductName>Postgres</ProductName>
|
||||
"superuser."
|
||||
Note that the <ProductName>Postgres</ProductName> superuser does not
|
||||
have to be a special user (e.g., a user named
|
||||
"postgres"), although many systems are installed that way.
|
||||
Furthermore, the <ProductName>Postgres</ProductName> superuser should
|
||||
definitely not be the UNIX superuser, "root"! In any
|
||||
case, all files relating to a database should belong to
|
||||
this <ProductName>Postgres</ProductName> superuser.
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
85
doc/src/sgml/arch.sgml
Normal file
85
doc/src/sgml/arch.sgml
Normal file
@ -0,0 +1,85 @@
|
||||
<Chapter>
|
||||
<TITLE>Architecture</TITLE>
|
||||
|
||||
<Sect1>
|
||||
<Title><ProductName>Postgres</ProductName> Architectural Concepts</Title>
|
||||
|
||||
<Para>
|
||||
Before we begin, you should understand the basic
|
||||
<ProductName>Postgres</ProductName> system architecture. Understanding how the
|
||||
parts of <ProductName>Postgres</ProductName> interact will make the next chapter
|
||||
somewhat clearer.
|
||||
In database jargon, <ProductName>Postgres</ProductName> uses a simple "process
|
||||
per-user" client/server model. A <ProductName>Postgres</ProductName> session
|
||||
consists of the following cooperating UNIX processes (programs):
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A supervisory daemon process (<Application>postmaster</Application>),
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
the user's frontend application (e.g., the <Application>psql</Application> program), and
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
the one or more backend database servers (the <Application>postgres</Application> process itself).
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
<Para>
|
||||
A single <Application>postmaster</Application> 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
|
||||
<Application>postmaster</Application> (<XRef LinkEnd="ARCH-CLIENTSERVER" EndTerm="ARCH-CLIENTSERVER">),
|
||||
which in turn starts a new backend server process
|
||||
|
||||
<Figure Id="ARCH-CLIENTSERVER">
|
||||
<Title>How a connection is established</Title>
|
||||
<Graphic Align="center" FileRef="clientserver.gif" Format="GIF"></Graphic>
|
||||
</Figure>
|
||||
|
||||
and connects the
|
||||
frontend process to the new server. From
|
||||
that point on, the frontend process and the backend
|
||||
server communicate without intervention by the
|
||||
<Application>postmaster</Application>. Hence, the <Application>postmaster</Application> is always running, waiting
|
||||
for requests, whereas frontend and backend processes
|
||||
come and go.
|
||||
|
||||
<Para>
|
||||
The <FileName>libpq</FileName> 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 <FileName>libpq</FileName>.
|
||||
One implication of this architecture is that the
|
||||
<Application>postmaster</Application> 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.
|
||||
|
||||
<Para>
|
||||
You should also be aware that the <Application>postmaster</Application> and
|
||||
postgres servers run with the user-id of the <ProductName>Postgres</ProductName>
|
||||
"superuser." Note that the <ProductName>Postgres</ProductName> superuser does not
|
||||
have to be a special user (e.g., a user named
|
||||
"postgres"). Furthermore, the <ProductName>Postgres</ProductName> superuser
|
||||
should
|
||||
definitely not be the UNIX superuser ("root")! In any
|
||||
case, all files relating to a database should belong to
|
||||
this <ProductName>Postgres</ProductName> superuser.
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
108
doc/src/sgml/array.sgml
Normal file
108
doc/src/sgml/array.sgml
Normal file
@ -0,0 +1,108 @@
|
||||
<Chapter>
|
||||
<Title>Arrays</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
This must become a chapter on array behavior. Volunteers? - thomas 1998-01-12
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE TABLE SAL_EMP (
|
||||
name text,
|
||||
pay_by_quarter int4[],
|
||||
schedule char16[][]
|
||||
);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The above query will create a class named SAL_EMP with
|
||||
a <FirstTerm>text</FirstTerm> string (name), a one-dimensional array of <FirstTerm>int4</FirstTerm>
|
||||
(pay_by_quarter), which represents the employee's
|
||||
salary by quarter and a two-dimensional array of <FirstTerm>char16</FirstTerm>
|
||||
(schedule), which represents the employee's weekly
|
||||
schedule. Now we do some <FirstTerm>INSERTS</FirstTerm>s; note that when
|
||||
appending to an array, we enclose the values within
|
||||
braces and separate them by commas. If you know <FirstTerm>C</FirstTerm>,
|
||||
this is not unlike the syntax for initializing structures.
|
||||
|
||||
<ProgramListing>
|
||||
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"}}');
|
||||
</ProgramListing>
|
||||
|
||||
By default, <ProductName>Postgres</ProductName> 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:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT name
|
||||
FROM SAL_EMP
|
||||
WHERE SAL_EMP.pay_by_quarter[1] <>
|
||||
SAL_EMP.pay_by_quarter[2];
|
||||
|
||||
+------+
|
||||
|name |
|
||||
+------+
|
||||
|Carol |
|
||||
+------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
This query retrieves the third quarter pay of all
|
||||
employees:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT SAL_EMP.pay_by_quarter[3] FROM SAL_EMP;
|
||||
|
||||
|
||||
+---------------+
|
||||
|pay_by_quarter |
|
||||
+---------------+
|
||||
|10000 |
|
||||
+---------------+
|
||||
|25000 |
|
||||
+---------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
|
||||
<ProgramListing>
|
||||
SELECT SAL_EMP.schedule[1:2][1:1]
|
||||
FROM SAL_EMP
|
||||
WHERE SAL_EMP.name = 'Bill';
|
||||
|
||||
+-------------------+
|
||||
|schedule |
|
||||
+-------------------+
|
||||
|{{"meeting"},{""}} |
|
||||
+-------------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
504
doc/src/sgml/biblio.sgml
Normal file
504
doc/src/sgml/biblio.sgml
Normal file
@ -0,0 +1,504 @@
|
||||
<BIBLIOGRAPHY>
|
||||
<Title><Acronym>SQL</Acronym> References</Title>
|
||||
|
||||
<Para>
|
||||
Selected references and readings for <Acronym>SQL</Acronym> and <ProductName>Postgres</ProductName>.
|
||||
</Para>
|
||||
|
||||
<BIBLIODIV>
|
||||
<TITLE><Acronym>SQL</Acronym> Reference Books</TITLE>
|
||||
<PARA>Reference texts for <Acronym>SQL</Acronym> features.</PARA>
|
||||
|
||||
<BIBLIOENTRY ID="BOWMAN93">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="BOWMAN93">
|
||||
-->
|
||||
<TITLE>The Practical <Acronym>SQL</Acronym> Handbook</TITLE>
|
||||
<SUBTITLE>Using Structured Query Language</SUBTITLE>
|
||||
<EDITION>3</EDITION>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>Judity</FIRSTNAME>
|
||||
<SURNAME>Bowman</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>Sandra</FIRSTNAME>
|
||||
<SURNAME>Emerson</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>Marcy</FIRSTNAME>
|
||||
<SURNAME>Damovsky</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<ISBN>0-201-44787-8</ISBN>
|
||||
<PUBDATE>1996</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>Addison-Wesley</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<COPYRIGHT>
|
||||
<YEAR>1997</YEAR>
|
||||
<HOLDER>Addison-Wesley Longman, Inc.</HOLDER>
|
||||
</COPYRIGHT>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="DATE97">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="DATE97">
|
||||
-->
|
||||
<TITLE>A Guide to The <Acronym>SQL</Acronym> Standard</TITLE>
|
||||
<TITLEABBREV>The <Acronym>SQL</Acronym> Standard</TITLEABBREV>
|
||||
<SUBTITLE>A user's guide to the standard database language <Acronym>SQL</Acronym></SUBTITLE>
|
||||
<EDITION>4</EDITION>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>C. J.</FIRSTNAME>
|
||||
<SURNAME>Date</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>Hugh</FIRSTNAME>
|
||||
<SURNAME>Darwen</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<ISBN>0-201-96426-0</ISBN>
|
||||
<PUBDATE>1997</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>Addison-Wesley</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<COPYRIGHT>
|
||||
<YEAR>1997</YEAR>
|
||||
<HOLDER>Addison-Wesley Longman, Inc.</HOLDER>
|
||||
</COPYRIGHT>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="MELT93">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="MELT93">
|
||||
-->
|
||||
<TITLE>Understanding the New <Acronym>SQL</Acronym></TITLE>
|
||||
<SUBTITLE>A complete guide</SUBTITLE>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>Jim</FIRSTNAME>
|
||||
<SURNAME>Melton</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>Alan R.</FIRSTNAME>
|
||||
<SURNAME>Simon</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<ISBN>1-55860-245-3</ISBN>
|
||||
<PUBDATE>1993</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>Morgan Kaufmann</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<COPYRIGHT>
|
||||
<YEAR>1993</YEAR>
|
||||
<HOLDER>Morgan Kaufmann Publishers, Inc.</HOLDER>
|
||||
</COPYRIGHT>
|
||||
<ABSTRACT>
|
||||
<TITLE>Abstract</TITLE>
|
||||
<PARA>Accessible reference for <Acronym>SQL</Acronym> features.</PARA>
|
||||
</ABSTRACT>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
</BIBLIODIV>
|
||||
<BIBLIODIV>
|
||||
<TITLE>PostgreSQL-Specific Documentation</TITLE>
|
||||
<PARA>This section is for related documentation.</PARA>
|
||||
|
||||
<BIBLIOENTRY ID="ADMIN-GUIDE">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="ADMIN-GUIDE">
|
||||
-->
|
||||
<TITLE>The <ProductName>PostgreSQL</ProductName> Administrator's Guide</TITLE>
|
||||
<Editor>
|
||||
<FIRSTNAME>Thomas</FIRSTNAME>
|
||||
<SURNAME>Lockhart</SURNAME>
|
||||
</Editor>
|
||||
|
||||
<PUBDATE>1998-03-01</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>The PostgreSQL Global Development Group</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="PROGRAMMERS-GUIDE">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="PROGRAMMERS-GUIDE">
|
||||
-->
|
||||
<TITLE>The <ProductName>PostgreSQL</ProductName> Programmer's Guide</TITLE>
|
||||
<Editor>
|
||||
<FIRSTNAME>Thomas</FIRSTNAME>
|
||||
<SURNAME>Lockhart</SURNAME>
|
||||
</Editor>
|
||||
|
||||
<PUBDATE>1998-03-01</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>The PostgreSQL Global Development Group</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="TUTORIAL">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="REFERENCE">
|
||||
-->
|
||||
<TITLE>The <ProductName>PostgreSQL</ProductName> Reference Manual</TITLE>
|
||||
<Editor>
|
||||
<FIRSTNAME>Thomas</FIRSTNAME>
|
||||
<SURNAME>Lockhart</SURNAME>
|
||||
</Editor>
|
||||
|
||||
<PUBDATE>1998-03-01</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>The PostgreSQL Global Development Group</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="USERS-GUIDE">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="TUTORIAL">
|
||||
-->
|
||||
<TITLE>The <ProductName>PostgreSQL</ProductName> Tutorial Introduction</TITLE>
|
||||
<Editor>
|
||||
<FIRSTNAME>Thomas</FIRSTNAME>
|
||||
<SURNAME>Lockhart</SURNAME>
|
||||
</Editor>
|
||||
|
||||
<PUBDATE>1998-03-01</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>The PostgreSQL Global Development Group</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="REFERENCE">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="USERS-GUIDE">
|
||||
-->
|
||||
<TITLE>The <ProductName>PostgreSQL</ProductName> User's Guide</TITLE>
|
||||
<Editor>
|
||||
<FIRSTNAME>Thomas</FIRSTNAME>
|
||||
<SURNAME>Lockhart</SURNAME>
|
||||
</Editor>
|
||||
|
||||
<PUBDATE>1998-03-01</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>The PostgreSQL Global Development Group</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="YU95">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="YU95">
|
||||
-->
|
||||
<TITLE>The <ProductName>Postgres95</ProductName> User Manual</TITLE>
|
||||
<TITLEABBREV>YU95</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>A.</FIRSTNAME>
|
||||
<SURNAME>Yu</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>J.</FIRSTNAME>
|
||||
<SURNAME>Chen</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<AUTHORGROUP>
|
||||
<COLLAB>
|
||||
<COLLABNAME>
|
||||
The POSTGRES Group
|
||||
</COLLABNAME>
|
||||
</COLLAB>
|
||||
</AUTHORGROUP>
|
||||
|
||||
<PUBDATE>Sept. 5, 1995</PUBDATE>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>University of California, Berkeley CA</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
</BIBLIODIV>
|
||||
<BIBLIODIV>
|
||||
<TITLE>Proceedings and Articles</TITLE>
|
||||
<PARA>This section is for articles and newsletters.</PARA>
|
||||
|
||||
<BIBLIOENTRY ID="ONG90">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="ONG90">
|
||||
-->
|
||||
<TITLE>A Unified Framework for Version Modeling Using Production Rules in a Database System</TITLE>
|
||||
<TITLEABBREV>ONG90</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>L.</FIRSTNAME>
|
||||
<SURNAME>Ong</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>J.</FIRSTNAME>
|
||||
<SURNAME>Goh</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<PUBDATE>April, 1990</PUBDATE>
|
||||
<ISSN>ERL Technical Memorandum M90/33</ISSN>
|
||||
<PUBLISHER>
|
||||
<PUBLISHERNAME>University of California, Berkeley CA</PUBLISHERNAME>
|
||||
</PUBLISHER>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="ROWE87">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="ROWE87">
|
||||
-->
|
||||
<TITLE>The <ProductName>Postgres</ProductName> Data Model</TITLE>
|
||||
<TITLEABBREV>ROWE87</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>L.</FIRSTNAME>
|
||||
<SURNAME>Rowe</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Stonebraker</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<CONFGROUP>
|
||||
<CONFDATES>Sept. 1987</CONFDATES>
|
||||
<CONFTITLE>VLDB Conference, Brighton, England</CONFTITLE>
|
||||
<CONFNUM>1987</CONFNUM>
|
||||
</CONFGROUP>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="STON86">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="STON86">
|
||||
-->
|
||||
<TITLE>The Design of <ProductName>Postgres</ProductName></TITLE>
|
||||
<TITLEABBREV>STON86</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Stonebraker</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>L.</FIRSTNAME>
|
||||
<SURNAME>Rowe</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<CONFGROUP>
|
||||
<CONFDATES>May 1986</CONFDATES>
|
||||
<CONFTITLE>Conference on Management of Data, Washington DC</CONFTITLE>
|
||||
<CONFSPONSOR>ACM-SIGMOD</CONFSPONSOR>
|
||||
<CONFNUM>1986</CONFNUM>
|
||||
</CONFGROUP>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="STON87a">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="STON87a">
|
||||
-->
|
||||
<TITLE>The Design of the <ProductName>Postgres</ProductName> Rules System</TITLE>
|
||||
<TITLEABBREV>STON87a</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Stonebraker</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>E.</FIRSTNAME>
|
||||
<SURNAME>Hanson</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>C. H.</FIRSTNAME>
|
||||
<SURNAME>Hong</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<CONFGROUP>
|
||||
<CONFDATES>Feb. 1987</CONFDATES>
|
||||
<CONFTITLE>Conference on Data Engineering, Los Angeles, CA</CONFTITLE>
|
||||
<CONFSPONSOR>IEEE</CONFSPONSOR>
|
||||
<CONFNUM>1987</CONFNUM>
|
||||
</CONFGROUP>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="STON87b">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="STON87b">
|
||||
-->
|
||||
<TITLE>The <ProductName>Postgres</ProductName> Storage System</TITLE>
|
||||
<TITLEABBREV>STON87b</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Stonebraker</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<CONFGROUP>
|
||||
<CONFDATES>Sept. 1987</CONFDATES>
|
||||
<CONFTITLE>VLDB Conference, Brighton, England</CONFTITLE>
|
||||
<CONFNUM>1987</CONFNUM>
|
||||
</CONFGROUP>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="STON89">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="STON89">
|
||||
-->
|
||||
<TITLE>A Commentary on the <ProductName>Postgres</ProductName> Rules System</TITLE>
|
||||
<TITLEABBREV>STON89</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Stonebraker</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Hearst</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>S.</FIRSTNAME>
|
||||
<SURNAME>Potamianos</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<CONFGROUP>
|
||||
<CONFDATES>Sept. 1989</CONFDATES>
|
||||
<CONFTITLE>Record 18(3)</CONFTITLE>
|
||||
<CONFSPONSOR>SIGMOD</CONFSPONSOR>
|
||||
<CONFNUM>1987</CONFNUM>
|
||||
</CONFGROUP>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="STON90a">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="STON90a">
|
||||
-->
|
||||
<TITLE>The Implementation of <ProductName>Postgres</ProductName></TITLE>
|
||||
<TITLEABBREV>STON90a</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Stonebraker</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>L. A.</FIRSTNAME>
|
||||
<SURNAME>Rowe</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Hirohama</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<CONFGROUP>
|
||||
<CONFDATES>March 1990</CONFDATES>
|
||||
<CONFTITLE>Transactions on Knowledge and Data Engineering 2(1)</CONFTITLE>
|
||||
<CONFSPONSOR>IEEE</CONFSPONSOR>
|
||||
</CONFGROUP>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
<BIBLIOENTRY ID="STON90b">
|
||||
<!--
|
||||
<BIBLIOMISC>‐</BIBLIOMISC>
|
||||
|
||||
<BOOKBIBLIO ID="STON90b">
|
||||
-->
|
||||
<TITLE>On Rules, Procedures, Caching and Views in Database Systems</TITLE>
|
||||
<TITLEABBREV>STON90b</TITLEABBREV>
|
||||
<AUTHORGROUP>
|
||||
<AUTHOR>
|
||||
<FIRSTNAME>M.</FIRSTNAME>
|
||||
<SURNAME>Stonebraker</SURNAME>
|
||||
</AUTHOR>
|
||||
<AUTHOR>
|
||||
<SURNAME>et. al.</SURNAME>
|
||||
</AUTHOR>
|
||||
</AUTHORGROUP>
|
||||
<CONFGROUP>
|
||||
<CONFDATES>June 1990</CONFDATES>
|
||||
<CONFTITLE>Conference on Management of Data</CONFTITLE>
|
||||
<CONFSPONSOR>ACM-SIGMOD</CONFSPONSOR>
|
||||
</CONFGROUP>
|
||||
<!--
|
||||
</BOOKBIBLIO>
|
||||
-->
|
||||
</BIBLIOENTRY>
|
||||
|
||||
</BIBLIODIV>
|
||||
</BIBLIOGRAPHY>
|
73
doc/src/sgml/compiler.sgml
Normal file
73
doc/src/sgml/compiler.sgml
Normal file
@ -0,0 +1,73 @@
|
||||
<Chapter>
|
||||
<DocInfo>
|
||||
<AuthorGroup>
|
||||
<Author>
|
||||
<FirstName>Brian</FirstName>
|
||||
<Surname>Gallew</Surname>
|
||||
</Author>
|
||||
</AuthorGroup>
|
||||
<Date>Transcribed 1998-02-12</Date>
|
||||
</DocInfo>
|
||||
|
||||
<Title>GCC Default Optimizations</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
Contributed by <ULink url="mailto:geek+@cmu.edu">Brian Gallew</ULink>
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
Configuring gcc to use certain flags by default is a simple matter of
|
||||
editing the
|
||||
<FileName>/usr/local/lib/gcc-lib/<Replaceable>platform</Replaceable>/<Replaceable>version</Replaceable>/specs</FileName>
|
||||
file.
|
||||
The format of this file pretty simple. The file is broken into
|
||||
sections, each of which is three lines long. The first line is
|
||||
"*<Replaceable>section_name</Replaceable>:" (e.g. "*asm:").
|
||||
The second line is a list of flags,
|
||||
and the third line is blank.
|
||||
|
||||
<Para>
|
||||
The easiest change to make is to append
|
||||
the desired default flags to the list in the appropriate section. As
|
||||
an example, let's suppose that I have linux running on a '486 with gcc
|
||||
2.7.2 installed in the default location. In the file
|
||||
/usr/local/lib/gcc-lib/i486-linux/2.7.2/specs, 13 lines down I find
|
||||
the following section:
|
||||
<ProgramListing>
|
||||
- ----------SECTION----------
|
||||
*cc1:
|
||||
|
||||
|
||||
- ----------SECTION----------
|
||||
</ProgramListing>
|
||||
As you can see, there aren't any default flags. If I always wanted
|
||||
compiles of C code to use "-m486 -fomit-frame-pointer", I would
|
||||
change it to look like:
|
||||
<ProgramListing>
|
||||
- ----------SECTION----------
|
||||
*cc1:
|
||||
- -m486 -fomit-frame-pointer
|
||||
|
||||
- ----------SECTION----------
|
||||
</ProgramListing>
|
||||
If I wanted to be able to generate 386 code for another, older linux
|
||||
box lying around, I'd have to make it look like this:
|
||||
<ProgramListing>
|
||||
- ----------SECTION----------
|
||||
*cc1:
|
||||
%{!m386:-m486} -fomit-frame-pointer
|
||||
|
||||
- ----------SECTION----------
|
||||
</ProgramListing>
|
||||
This will always omit frame pointers, any will build 486-optimized
|
||||
code unless -m386 is specified on the command line.
|
||||
|
||||
<Para>
|
||||
You can actually do quite a lot of customization with the specs file.
|
||||
Always remember, however, that these changes are global, and affect
|
||||
all users of the system.
|
||||
|
||||
</Chapter>
|
23
doc/src/sgml/contacts.sgml
Normal file
23
doc/src/sgml/contacts.sgml
Normal file
@ -0,0 +1,23 @@
|
||||
<Appendix label="B">
|
||||
<Title>Contacts</Title>
|
||||
|
||||
<Sect1>
|
||||
<Title>Introduction</Title>
|
||||
<Para>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>People</Title>
|
||||
|
||||
<Para>
|
||||
<ItemizedList Mark="bullet" Spacing="compact">
|
||||
<ListItem>
|
||||
<Para>
|
||||
<ULink url="http://alumni.caltech.edu/~lockhart">Thomas Lockhart</ULink>
|
||||
works on SQL standards compliance and documentation.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
</Para>
|
||||
|
||||
</Appendix>
|
2064
doc/src/sgml/datatype.sgml
Normal file
2064
doc/src/sgml/datatype.sgml
Normal file
File diff suppressed because it is too large
Load Diff
242
doc/src/sgml/dfunc.sgml
Normal file
242
doc/src/sgml/dfunc.sgml
Normal file
@ -0,0 +1,242 @@
|
||||
<Chapter>
|
||||
<Title>Linking Dynamically-Loaded Functions</Title>
|
||||
|
||||
<Para>
|
||||
After you have created and registered a user-defined
|
||||
function, your work is essentially done. <ProductName>Postgres</ProductName>,
|
||||
however, must load the object code (e.g., a <FileName>.o</FileName> file, or
|
||||
a shared library) that implements your function. As
|
||||
previously mentioned, <ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName> server. Note that
|
||||
this process has changed as of Version 4.2.
|
||||
<Tip>
|
||||
<Para>
|
||||
The old <ProductName>Postgres</ProductName> 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
|
||||
<ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName>. We
|
||||
hope that the large increase in speed and reliability will
|
||||
make up for the slight decrease in convenience.
|
||||
<Para>
|
||||
</Tip>
|
||||
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
|
||||
<FileName>PGROOT/src/regress</FileName> 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:
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
<FirstTerm>Dynamic loading</FirstTerm>
|
||||
is what <ProductName>Postgres</ProductName> does to an object file. The
|
||||
object file is copied into the running <ProductName>Postgres</ProductName>
|
||||
server and the functions and variables within the
|
||||
file are made available to the functions within
|
||||
the <ProductName>Postgres</ProductName> process. <ProductName>Postgres</ProductName> does this using
|
||||
the dynamic loading mechanism provided by the
|
||||
operating system.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
<FirstTerm>Loading and link editing</FirstTerm>
|
||||
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).
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The following general restrictions and notes also apply
|
||||
to the discussion below:
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
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
|
||||
<ProductName>Postgres</ProductName> server is running.
|
||||
<Tip>
|
||||
<Para>
|
||||
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!
|
||||
</Para>
|
||||
</Tip>
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The <ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName>
|
||||
server runs as the <ProductName>Postgres</ProductName> 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.)
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Symbol names defined within object files must not
|
||||
conflict with each other or with symbols defined in
|
||||
<ProductName>Postgres</ProductName>.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
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.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
<Sect1>
|
||||
<Title><Acronym>ULTRIX</Acronym></Title>
|
||||
|
||||
<Para>
|
||||
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,
|
||||
<ProgramListing>
|
||||
# simple ULTRIX example
|
||||
% cc -G 0 -c foo.c
|
||||
</ProgramListing>
|
||||
produces an object file called foo.o that can then be
|
||||
dynamically loaded into <ProductName>Postgres</ProductName>. No additional loading or link-editing must be performed.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title><Acronym>DEC OSF/1</Acronym></Title>
|
||||
|
||||
<Para>
|
||||
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:
|
||||
<ProgramListing>
|
||||
# simple DEC OSF/1 example
|
||||
% cc -c foo.c
|
||||
% ld -shared -expect_unresolved '*' -o foo.so foo.o
|
||||
</ProgramListing>
|
||||
|
||||
The resulting shared object file can then be loaded
|
||||
into <ProductName>Postgres</ProductName>. 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.
|
||||
<Tip>
|
||||
<Para>
|
||||
Actually, <ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName> 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!
|
||||
</Para>
|
||||
</Tip>
|
||||
|
||||
If the file you specify is
|
||||
not a shared object, the backend will hang!
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>
|
||||
<Acronym>SunOS 4.x</Acronym>, <Acronym>Solaris 2.x</Acronym> and <Acronym>HP-UX</Acronym></Title>
|
||||
|
||||
<Para>
|
||||
Under 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:
|
||||
<ProgramListing>
|
||||
# simple HP-UX example
|
||||
% cc +z +u -c foo.c
|
||||
% ld -b -o foo.sl foo.o
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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:
|
||||
<ProgramListing>
|
||||
# simple SunOS 4.x example
|
||||
% cc -PIC -c foo.c
|
||||
% ld -dc -dp -Bdynamic -o foo.so foo.o
|
||||
</ProgramListing>
|
||||
|
||||
and the equivalent lines under Solaris 2.x are:
|
||||
<ProgramListing>
|
||||
# simple Solaris 2.x example
|
||||
% cc -K PIC -c foo.c
|
||||
or
|
||||
% gcc -fPIC -c foo.c
|
||||
% ld -G -Bdynamic -o foo.so foo.o
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
</Para>
|
||||
</Sect1>
|
||||
</Chapter>
|
347
doc/src/sgml/docguide.sgml
Normal file
347
doc/src/sgml/docguide.sgml
Normal file
@ -0,0 +1,347 @@
|
||||
<Appendix label="A">
|
||||
<DocInfo>
|
||||
<AuthorGroup>
|
||||
<Author>
|
||||
<FirstName>Thomas</FirstName>
|
||||
<Surname>Lockhart</Surname>
|
||||
</Author>
|
||||
</AuthorGroup>
|
||||
<Date>1998-02-26</Date>
|
||||
</DocInfo>
|
||||
|
||||
<Title>Documentation</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> documentation is written using
|
||||
the <FirstTerm>Standard Generalized Markup Language</FirstTerm>
|
||||
(<Acronym>SGML</Acronym>)
|
||||
<ULink url="http://www.ora.com/davenport/"><ProductName>DocBook</ProductName></ULink>
|
||||
<FirstTerm>Document Type Definition</FirstTerm> (<Acronym>DTD</Acronym>).
|
||||
|
||||
<Para>
|
||||
Packaged documentation is available in both <FirstTerm>HTML</FirstTerm> and <FirstTerm>Postscript</FirstTerm>
|
||||
formats. These are available as part of the standard <ProductName>Postgres</ProductName> installation.
|
||||
We discuss here working with the documentation sources and generating documentation packages.
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
This is the first release of new <ProductName>Postgres</ProductName> documentation in three years.
|
||||
The content and environment are in flux and still evolving.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Sect1>
|
||||
<Title>Introduction</Title>
|
||||
|
||||
<Para>
|
||||
The purpose of <Acronym>SGML</Acronym> is to allow an author to specify the structure and content of
|
||||
a document (e.g. using the <ProductName>DocBook</ProductName> <Acronym>DTD</Acronym>),
|
||||
and to have the document style define
|
||||
how that content is rendered into a final form
|
||||
(e.g. using Norm Walsh's stylesheets).
|
||||
|
||||
<Para>
|
||||
See
|
||||
<ULink url="http://nis-www.lanl.gov/~rosalia/mydocs/docbook-intro.html">Introduction to DocBook</ULink>
|
||||
for a nice "quickstart" summary of DocBook features.
|
||||
<ULink url="http://www.ora.com/homepages/dtdparse/docbook/3.0/">DocBook Elements</ULink>
|
||||
provides a powerful cross-reference for features of <ProductName>DocBook</ProductName>.
|
||||
|
||||
<Para>
|
||||
This documentation set is constructed using several tools,
|
||||
including James Clark's
|
||||
<ULink url="http://www.jclark.com/jade/"><ProductName>jade</ProductName></ULink>
|
||||
and Norm Walsh's
|
||||
<ULink url="http://www.berkshire.net/~norm/docbook/dsssl">Modular DocBook Stylesheets</ULink>.
|
||||
|
||||
<Para>
|
||||
Currently, hardcopy is produced by importing <FirstTerm>Rich Text Format</FirstTerm> (<Acronym>RTF</Acronym>)
|
||||
output from <Application>jade</Application> to <ProductName>ApplixWare</ProductName>
|
||||
for minor formatting fixups then exporting as a Postscript file.
|
||||
|
||||
<Para>
|
||||
<ULink url="http://sunsite.unc.edu/pub/packages/TeX/systems/unix/"><ProductName>TeX</ProductName></ULink>
|
||||
is a supported format for <Application>jade</Application> output, but was not used at this time for
|
||||
several reasons, including the inability to make minor format fixes before committing to hardcopy and
|
||||
generally inadequate table support in the <ProductName>TeX</ProductName> stylesheets.
|
||||
|
||||
<Sect1>
|
||||
<Title>Styles and Conventions</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>DocBook</ProductName> has a rich set of tags and constructs, and a suprisingly large
|
||||
percentage are directly and obviously useful for well-formed documentation.
|
||||
The <ProductName>Postgres</ProductName> documentation set has only recently
|
||||
been adapted to <Acronym>SGML</Acronym>, and in the near future several sections of the set
|
||||
will be selected and maintained as prototypical examples of <ProductName>DocBook</ProductName>
|
||||
usage. Also, a short summary of <ProductName>DocBook</ProductName> tags will be included below.
|
||||
|
||||
<!--
|
||||
<Para>
|
||||
<TABLE TOCENTRY="1">
|
||||
<TITLE>SGML Constructs</TITLE>
|
||||
<TITLEABBREV>SGML Constructs</TITLEABBREV>
|
||||
<TGROUP COLS="2">
|
||||
<THEAD>
|
||||
<ROW>
|
||||
<ENTRY>SGML Tag</ENTRY>
|
||||
<ENTRY>Usage</ENTRY>
|
||||
</ROW>
|
||||
</THEAD>
|
||||
<TBODY>
|
||||
<ROW>
|
||||
</ROW>
|
||||
</TBODY>
|
||||
</TGROUP>
|
||||
</TABLE>
|
||||
</Para>
|
||||
|
||||
-->
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Building Documentation</Title>
|
||||
|
||||
<Para>
|
||||
HTML documentation packages can be generated from the SGML source by typing
|
||||
|
||||
<ProgramListing>
|
||||
% cd doc/src
|
||||
% make tutorial.tar.gz
|
||||
% make user.tar.gz
|
||||
% make admin.tar.gz
|
||||
% make programmer.tar.gz
|
||||
% make postgres.tar.gz
|
||||
% make install
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
These packages can be installed from the main documentation directory by typing
|
||||
<ProgramListing>
|
||||
% cd doc
|
||||
% make install
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Toolsets</Title>
|
||||
|
||||
<Sect2>
|
||||
<Title><ProductName>jade</ProductName></Title>
|
||||
|
||||
<Para>
|
||||
The current stable release of <ProductName>jade</ProductName> is version 1.0.1.
|
||||
</Para>
|
||||
|
||||
<Sect3>
|
||||
<Title>Installation for Linux</Title>
|
||||
|
||||
<Para>
|
||||
Install <ULink url="ftp://ftp.cygnus.com/pub/home/rosalia/"><Acronym>RPMs</Acronym></ULink>
|
||||
for <ProductName>jade</ProductName> and related packages.
|
||||
</Para>
|
||||
</Sect3>
|
||||
|
||||
<Sect3>
|
||||
<Title>Installation for non-Linux Platforms</Title>
|
||||
|
||||
<Para>
|
||||
There are some other packaged distributions for jade. <ProductName>FreeBSD</ProductName> seems
|
||||
to have one available. Please report package status to the docs mailing list and we will
|
||||
include that information here.
|
||||
|
||||
<Para>
|
||||
For other platforms, install <ULink url="ftp://ftp.cygnus.com/pub/eichin/docware/SOURCES/">sources</ULink>
|
||||
for <ProductName>jade</ProductName> and related packages and build from scratch.
|
||||
</Para>
|
||||
</Sect3>
|
||||
|
||||
<Sect2>
|
||||
<Title><ProductName>Modular Style Sheets</ProductName></Title>
|
||||
|
||||
<Para>
|
||||
The current stable release of the <ProductName>Modular Style Sheets</ProductName> is version 1.0.7.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Hardcopy Generation for v6.3</Title>
|
||||
|
||||
<Para>
|
||||
The hardcopy Postscript documentation is generated by converting the <Acronym>SGML</Acronym>
|
||||
source code to <Acronym>RTF</Acronym>, then importing into Applixware. After a little cleanup
|
||||
(see the following section) the output is "printed" to a postscript file.
|
||||
|
||||
<Para>
|
||||
Some figures were redrawn to avoid having bitmap <Acronym>GIF</Acronym> files in the hardcopy
|
||||
documentation. One figure, of the system catalogs, was sufficiently complex that there was
|
||||
not time to redraw it. It was converted to fit using the following commands:
|
||||
|
||||
<ProgramListing>
|
||||
% convert -v -geometry 400x400'>' figure03.gif con.gif
|
||||
% convert -v -crop 400x380 con.gif connections.gif
|
||||
</ProgramListing>
|
||||
|
||||
<Sect2>
|
||||
<Title>RTF Cleanup Procedure</Title>
|
||||
|
||||
<Para>
|
||||
Several items must be addressed in generating Postscript hardcopy:
|
||||
|
||||
<Procedure>
|
||||
<Title>Applixware RTF Cleanup</Title>
|
||||
|
||||
<Para>
|
||||
Applixware does not seem to do a complete job of importing RTF generated by jade/MSS. In particular,
|
||||
all text is given the <Quote>Header1</Quote> style attribute label, although the text formatting itself
|
||||
is acceptable. Also, the Table of Contents page numbers do not refer to the section listed in the
|
||||
table, but rather refer to the page of the ToC itself.
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Generate the <Acronym>RTF</Acronym> input by typing
|
||||
<ProgramListing>
|
||||
% cd doc/src/sgml
|
||||
% make tutorial.rtf
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Open a new document in <ProductName>Applix Words</ProductName> and then import the RTF file.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Print out the existing Table of Contents, to mark up in the following few steps.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Insert figures into the document. Center each figure on the page using the centering margins button.
|
||||
|
||||
<Para>
|
||||
Not all documents have figures. You can grep the SGML source files for the string <Quote>Graphic</Quote>
|
||||
to identify those parts of the documentation which may have figures. A few figures are replicated in
|
||||
various parts of the documentation.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Work through the document, adjusting page breaks and table column widths.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
If a bibliography is present, Applix Words seems to mark all remaining text after the first title
|
||||
as having an underlined attribute. Select all remaining text, turn off underlining using the underlining button,
|
||||
then explicitly underline each document and book title.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Work through the document, marking up the ToC hardcopy with the actual page number of each ToC entry.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Replace the right-justified incorrect page numbers in the ToC with correct values. This only takes a few
|
||||
minutes per document.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Save the document as native Applix Words format to allow easier last minute editing later.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Export the document to a file in Postscript format.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Compress the Postscript file using <Application>gzip</Application>. Place the compressed file into the
|
||||
<FileName>doc</FileName> directory.
|
||||
</Para>
|
||||
</Step>
|
||||
</Procedure>
|
||||
|
||||
</Sect2>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Alternate Toolsets</Title>
|
||||
|
||||
<Para>
|
||||
The current stable release of <ProductName>sgml-tools</ProductName> is version 1.0.4.
|
||||
The v1.0 release includes some restructuring of the directory tree
|
||||
to more easily support additional document styles, possibly including <ProductName>DocBook</ProductName>.
|
||||
The only version of <ProductName>sgml-tools</ProductName> evaluated for <ProductName>Postgres</ProductName> was v0.99.0.
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title><ProductName>sgml-tools</ProductName></Title>
|
||||
|
||||
<Para>
|
||||
Install
|
||||
<ProductName>sgml-tools-0.99.0</ProductName>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Apply
|
||||
<ULink url="http://alumni.caltech.edu/~lockhart/postgres/linuxdoc/sgml-tools-patches-0.99.0.tar.gz">
|
||||
<ProductName>sgml-tools-patches</ProductName>
|
||||
</ULink>
|
||||
to the linuxdoc styles. These patches fix small problems with
|
||||
table formatting and with figure file names on conversion to postscript or html.
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title><ProductName>sgml2latex</ProductName></Title>
|
||||
|
||||
<Para>
|
||||
The current stable release of <ProductName>sgml2latex</ProductName> is version 1.4.
|
||||
I have misplaced the original reference
|
||||
for this package, so will temporarily post it with this example.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Install <ULink url="http://alumni.caltech.edu/~lockhart/postgres/linuxdoc/sgml2latex-format.1.4.tar.gz">
|
||||
<ProductName>sgml2latex</ProductName>
|
||||
</ULink>.
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title><ProductName>latex</ProductName></Title>
|
||||
|
||||
<Para>
|
||||
Get and install <ProductName>texmf</ProductName>, <ProductName>teTeX</ProductName>,
|
||||
or another package providing full tex/latex functionality.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Add the
|
||||
<ULink url="http://alumni.caltech.edu/~lockhart/postgres/linuxdoc/latex-styles-0.99.0.tar.gz">required styles</ULink>
|
||||
linuxdoc-sgml.sty, linuxdoc-sgml-a4.sty isolatin.sty, qwertz.sty, and null.sty
|
||||
to texmf/tex/latex/tools/ or the appropriate area.
|
||||
<ProgramListing>
|
||||
% cat latex-styles-0.99.0.tar.gz | (cd texmf/tex/latex/tools/; tar zxvf -)
|
||||
</ProgramListing>
|
||||
|
||||
Run <ProductName>texhash</ProductName> to update the tex database.
|
||||
</Para>
|
||||
|
||||
|
||||
</Appendix>
|
836
doc/src/sgml/ecpg.sgml
Normal file
836
doc/src/sgml/ecpg.sgml
Normal file
@ -0,0 +1,836 @@
|
||||
<Chapter>
|
||||
<DocInfo>
|
||||
<AuthorGroup>
|
||||
<Author>
|
||||
<FirstName>Linux</FirstName>
|
||||
<Surname>Tolke</Surname>
|
||||
</Author>
|
||||
<Author>
|
||||
<FirstName>Michael</FirstName>
|
||||
<Surname>Meskes</Surname>
|
||||
</Author>
|
||||
</AuthorGroup>
|
||||
<Copyright>
|
||||
<Year>1996-1997</Year>
|
||||
<Holder>Linus Tolke</Holder>
|
||||
</Copyright>
|
||||
<Copyright>
|
||||
<Year>1998</Year>
|
||||
<Holder>Michael Meskes</Holder>
|
||||
</Copyright>
|
||||
<Date>Transcribed 1998-02-12</Date>
|
||||
</DocInfo>
|
||||
|
||||
<Title><Application>ecpg</Application> - Embedded <Acronym>SQL</Acronym> in <Acronym>C</Acronym></Title>
|
||||
|
||||
<Para>
|
||||
This describes an embedded <Acronym>SQL</Acronym> in <Acronym>C</Acronym> package for <ProductName>Postgres</ProductName>.
|
||||
|
||||
It is written by <ULink url="mailto:linus@epact.se">Linus Tolke</ULink>
|
||||
and <ULink url="mailto:meskes@debian.org">Michael Meskes</ULink>.
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
Permission is granted to copy and use in the same way as you are allowed
|
||||
to copy and use the rest of the <ProductName>PostgreSQL</ProductName>.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Sect1>
|
||||
<Title>Why Embedded <Acronym>SQL</Acronym>?</Title>
|
||||
|
||||
<Para>
|
||||
Embedded <Acronym>SQL</Acronym> has some small advantages over other ways to handle <Acronym>SQL</Acronym>
|
||||
queries. It takes care of all the tedious moving of information to and
|
||||
from variables in your <Acronym>C</Acronym> program. Many <Acronym>RDBMS</Acronym> packages
|
||||
support this embedded language.
|
||||
|
||||
<Para>
|
||||
There is an ANSI-standard describing how the embedded language should
|
||||
work. Most embedded <Acronym>SQL</Acronym> preprocessors I have seen and heard of make
|
||||
extensions so it is difficult to obtain portability between them
|
||||
anyway. I have not read the standard but I hope that my implementation
|
||||
does not deviate too much and that it would be possible to port programs
|
||||
with embedded <Acronym>SQL</Acronym> written for other <Acronym>RDBMS</Acronym> packages
|
||||
to <ProductName>Postgres</ProductName> and thus
|
||||
promoting the spirit of free software.
|
||||
|
||||
<Sect1>
|
||||
<Title>The Concept</Title>
|
||||
|
||||
<Para>
|
||||
You write your program in <Acronym>C</Acronym> with some special <Acronym>SQL</Acronym> things.
|
||||
For declaring variables that can be used in <Acronym>SQL</Acronym> statements you need to
|
||||
put them in a special declare section.
|
||||
You use a special syntax for the <Acronym>SQL</Acronym> queries.
|
||||
|
||||
<Para>
|
||||
Before compiling you run the file through the embedded <Acronym>SQL</Acronym> <Acronym>C</Acronym>
|
||||
preprocessor and it converts the <Acronym>SQL</Acronym> statements you used to function
|
||||
calls with the variables used as arguments. Both variables that are used
|
||||
as input to the <Acronym>SQL</Acronym> statements and variables that will contain the
|
||||
result are passed.
|
||||
|
||||
<Para>
|
||||
Then you compile and at link time you link with a special library that
|
||||
contains the functions used. These functions (actually it is mostly one
|
||||
single function) fetches the information from the arguments, performs
|
||||
the <Acronym>SQL</Acronym> query using the ordinary interface (<FileName>libpq</FileName>) and puts back
|
||||
the result in the arguments dedicated for output.
|
||||
|
||||
<Para>
|
||||
Then you run your program and when the control arrives to the <Acronym>SQL</Acronym>
|
||||
statement the <Acronym>SQL</Acronym> statement is performed against the database and you
|
||||
can continue with the result.
|
||||
|
||||
|
||||
<Sect1>
|
||||
<Title>How To Use <Application>egpc</Application></Title>
|
||||
|
||||
<Para>
|
||||
This section describes how to use the <Application>egpc</Application> tool.
|
||||
|
||||
<Sect2>
|
||||
<Title>Preprocessor
|
||||
|
||||
<Para>
|
||||
The preprocessor is called <Application>ecpg</Application>. After installation it resides in
|
||||
the <ProductName>Postgres</ProductName> <FileName>bin/</FileName> directory.
|
||||
|
||||
<Sect2>
|
||||
<Title>Library
|
||||
|
||||
<Para>
|
||||
The <Application>ecpg</Application> library is called <FileName>libecpg.a</FileName> or
|
||||
<FileName>libecpg.so</FileName>. Additionally, the library
|
||||
uses the <FileName>libpq</FileName> library for communication to the
|
||||
<ProductName>Postgres</ProductName> server so you will
|
||||
have to link your program with <Parameter>-lecpg -lpq</Parameter>.
|
||||
|
||||
<Para>
|
||||
The library has some methods that are "hidden" but that could prove very
|
||||
useful sometime.
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>ECPGdebug(int, FILE *stream)</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
If this is called, with the first argument non-zero, then debuglogging is turned
|
||||
on. Debuglogging is done on <Function>stream</Function>. Most <Acronym>SQL</Acronym> statement logs its
|
||||
arguments and result.
|
||||
|
||||
<Para>
|
||||
The most important one (<Function>ECPGdo</Function>) that is called on all <Acronym>SQL</Acronym>
|
||||
statements except <Command>EXEC SQL COMMIT</Command>, <Command>EXEC SQL ROLLBACK</Command>,
|
||||
<Command>EXEC SQL CONNECT</Command> logs both its expanded string, i.e. the string
|
||||
with all the input variables inserted, and the result from the
|
||||
<ProductName>Postgres</ProductName> server. This can be very useful when searching for errors
|
||||
in your <Acronym>SQL</Acronym> statements.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>ECPGstatus()</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This method returns TRUE if we are connected to a database and FALSE if not.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
||||
<Sect2>
|
||||
<Title>Error handling
|
||||
|
||||
<Para>
|
||||
To be able to detect errors from the <ProductName>Postgres</ProductName> server you include a line
|
||||
like
|
||||
<ProgramListing>
|
||||
exec sql include sqlca;
|
||||
</ProgramListing>
|
||||
in the include section of your file. This will define a struct and a
|
||||
variable with the name <Parameter>sqlca</Parameter> as following:
|
||||
<ProgramListing>
|
||||
struct sqlca {
|
||||
int sqlcode;
|
||||
struct {
|
||||
int sqlerrml;
|
||||
char sqlerrmc[1000];
|
||||
} sqlerrm;
|
||||
} sqlca;
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
If an error occured in the last <Acronym>SQL</Acronym> statement then <Parameter>sqlca.sqlcode</Parameter>
|
||||
will be non-zero. If <Parameter>sqlca.sqlcode</Parameter> is less that 0 then this is
|
||||
some kind of serious error, like the database definition does not match
|
||||
the query given. If it is bigger than 0 then this is a normal error like
|
||||
the table did not contain the requested row.
|
||||
|
||||
<Para>
|
||||
sqlca.sqlerrm.sqlerrmc will contain a string that describes the error.
|
||||
The string ends with <Quote>line 23.</Quote> where the line is the line number
|
||||
in the source file (actually the file generated by the preprocessor but
|
||||
I hope I can fix this to be the line number in the input file.)
|
||||
|
||||
<Para>
|
||||
List of errors that can occur:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>-1, Unsupported type %s on line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Does not normally occur. This is a sign that the preprocessor has
|
||||
generated something that the library does not know about. Perhaps you
|
||||
are running incompatible versions of the preprocessor and the library.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Too many arguments line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The preprocessor has goofed up and generated some incorrect code.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Too few arguments line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The preprocessor has goofed up and generated some incorrect code.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Error starting transaction line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> signalled to us that we cannot open the connection.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Postgres error: %s line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Some <ProductName>Postgres</ProductName> error. The message contains the error message from the
|
||||
<ProductName>Postgres</ProductName> backend.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>1, Data not found line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This is a "normal" error that tells you that what you are quering cannot
|
||||
be found or we have gone through the cursor.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, To many matches line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This means that the query has returned several lines. The <Command>SELECT</Command>
|
||||
you made probably was not unique.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Not correctly formatted int type: %s line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This means that the host variable is of an <Type>int</Type> type and the field
|
||||
in the <ProductName>Postgres</ProductName> database is of another type and contains a value that
|
||||
cannot be interpreted as an <Type>int</Type>. The library uses <Function>strtol</Function>
|
||||
for this conversion.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Not correctly formatted unsigned type: %s line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This means that the host variable is of an <Type>unsigned int</Type> type and
|
||||
the field in the <ProductName>Postgres</ProductName> database is of another type and contains a
|
||||
value that cannot be interpreted as an <Type>unsigned int</Type>. The library
|
||||
uses <Function>strtoul</Function> for this conversion.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Not correctly formatted floating point type: %s line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This means that the host variable is of an <Type>float</Type> type and
|
||||
the field in the <ProductName>Postgres</ProductName> database is of another type and contains a
|
||||
value that cannot be interpreted as an <Type>float</Type>. The library
|
||||
uses <Function>strtod</Function> for this conversion.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Too few arguments line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This means that <ProductName>Postgres</ProductName> has returned more records than we have
|
||||
matching variables. Perhaps you have forgotten a couple of the host
|
||||
variables in the <Command>INTO :var1,:var2</Command>-list.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Too many arguments line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This means that <ProductName>Postgres</ProductName> has returned fewer records than we have
|
||||
host variables. Perhaps you have to many host variables in the
|
||||
<Command>INTO :var1,:var2</Command>-list.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Empty query line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> returned PGRES_EMPTY_QUERY.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Error: %s line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This means that <ProductName>Postgres</ProductName> returned on of the errors
|
||||
PGRES_NONFATAL_ERROR, PGRES_FATAL_ERROR or PGRES_BAD_RESPONSE. Which one
|
||||
and why is explained in the message.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Postgres error line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> returns something that the library does not know how to
|
||||
handle. This is probably because the version of <ProductName>Postgres</ProductName> does not
|
||||
match the version of the <Application>ecpg</Application> library.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Error committing line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Error during <Command>COMMIT</Command>. <Command>EXEC SQL COMMIT</Command> is translated to an
|
||||
<Command>end</Command> operation in <ProductName>Postgres</ProductName> and that is the operation that could
|
||||
not be performed.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, Error rolling back line %d.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Error during <Command>ROLLBACK</Command>. <Command>EXEC SQL ROLLBACK</Command> is translated to
|
||||
an <Command>abort</Command> operation in <ProductName>Postgres</ProductName> and that is the operation that
|
||||
could not be performed.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>-1, ECPGconnect: could not open database %s.</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The connect to the database did not work.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect1>
|
||||
<Title>Limitations</Title>
|
||||
|
||||
<Para>
|
||||
What will never be included and why or what cannot be done with this
|
||||
concept.
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>oracles single tasking possibility</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Oracle version 7.0 on AIX 3 uses the OS-supported locks on the shared
|
||||
memory segments and allows the application designer to link an
|
||||
application in a so called single tasking way. Instead of starting one
|
||||
client process per application process both the database part and the
|
||||
application part is run in the same process. In later versions of oracle
|
||||
this is no longer supported.
|
||||
|
||||
<Para>
|
||||
This would require a total redesign of the <ProductName>Postgres</ProductName> access model and
|
||||
that effort can not justify the performance gained.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
||||
<Sect1>
|
||||
<Title>Porting From Other <Acronym>RDBMS</Acronym> Packages</Title>
|
||||
|
||||
<Para>
|
||||
To be written by persons that knows the different <Acronym>RDBMS</Acronym> packages and that
|
||||
actually does port something...
|
||||
|
||||
<Sect1>
|
||||
<Title>Installation</Title>
|
||||
|
||||
<Para>
|
||||
Since version 0.5 <Application>ecpg</Application> is distributed together with <ProductName>Postgres</ProductName>. So you
|
||||
should get your precompiler, libraries and header files compiled and
|
||||
installed on the fly.
|
||||
|
||||
<Sect1>
|
||||
<Title>For the Developer</Title>
|
||||
|
||||
<Para>
|
||||
This section is for those that wants to develop the <Application>ecpg</Application> interface. It
|
||||
describes how the things work. The ambition is to make this section
|
||||
contain things for those that want to have a look inside and the section
|
||||
on How to use it should be enough for all normal questions.
|
||||
|
||||
So, read this before looking at the internals of the <Application>ecpg</Application>. If
|
||||
you are not interested in how it really works, skip this section.
|
||||
|
||||
<Sect2>
|
||||
<Title>ToDo List</Title>
|
||||
|
||||
<Para>
|
||||
This version the preprocessor has some flaws:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>Preprocessor output</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The variables should be static.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Preprocessor cannot do syntax checking on your <Acronym>SQL</Acronym> statements</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Whatever you write is copied more or less exactly to the <ProductName>Postgres</ProductName> and
|
||||
you will not be able to locate your errors until run-time.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>no restriction to strings only</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The PQ interface, and most of all the PQexec function, that is used by
|
||||
the <Application>ecpg</Application> relies on that the request is built up as a string. In some
|
||||
cases, like when the data contains the null character, this will be a
|
||||
serious problem.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>error codes</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
There should be different error numbers for the different errors instead
|
||||
of just -1 for them all.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>library functions</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
to_date et al.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>records</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Possibility to define records or structures in the declare section
|
||||
in a way that the record can be filled from one row in the database.
|
||||
|
||||
<Para>
|
||||
This is a simpler way to handle an entire row at a time.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>array operations</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Oracle has array operations that enhances speed. When implementing it in
|
||||
<Application>ecpg</Application> it is done for compatibility reasons only. For them to
|
||||
improve speed would require a lot more insight in the <ProductName>Postgres</ProductName> internal
|
||||
mechanisms than I possess.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>indicator variables</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Oracle has indicator variables that tell if a value is <Type>null</Type> or if
|
||||
it is empty. This largely simplifies array operations and provides for a
|
||||
way to hack around some design flaws in the handling of <Type>VARCHAR2</Type>
|
||||
(like that an empty string isn't distinguishable from a
|
||||
<Type>null</Type> value). I am not sure if this is an Oracle extension or part
|
||||
of the ANSI standard.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>typedefs</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
As well as complex types like records and arrays, typedefs would be
|
||||
a good thing to take care of.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>conversion of scripts</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
To set up a database you need a few scripts with table definitions and
|
||||
other configuration parameters. If you have these scripts for an old
|
||||
database you would like to just apply them to get a <ProductName>Postgres</ProductName> database
|
||||
that works in the same way.
|
||||
|
||||
<Para>
|
||||
To set up a database you need a few scripts with table definitions and
|
||||
The functionality could be accomplished with some conversion scripts.
|
||||
Speed will never be accomplished in this way. To do this you need a
|
||||
bigger insight in the database construction and the use of the database
|
||||
than could be realised in a script.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
||||
<Sect2>
|
||||
<Title>The Preprocessor</Title>
|
||||
|
||||
<Para>
|
||||
First four lines are written to the output. Two comments and two include
|
||||
lines necessary for the interface to the library.
|
||||
|
||||
<Para>
|
||||
Then the preprocessor works in one pass only reading the input file and
|
||||
writing to the output as it goes along. Normally it just echoes
|
||||
everything to the output without looking at it further.
|
||||
|
||||
<Para>
|
||||
When it comes to an <Command>EXEC SQL</Command> statements it interviens and
|
||||
changes them depending on what iit is. The <Command>EXEC SQL</Command> statement can
|
||||
be one of these:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>Declare sections</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Declare sections begins with
|
||||
<ProgramListing>
|
||||
exec sql begin declare section;
|
||||
</ProgramListing>
|
||||
and ends with
|
||||
<ProgramListing>
|
||||
exec sql end declare section;
|
||||
</ProgramListing>
|
||||
In the section only variable declarations are allowed. Every variable
|
||||
declare within this section is also entered in a list of variables
|
||||
indexed on their name together with the corresponding type.
|
||||
|
||||
<Para>
|
||||
The declaration is echoed to the file to make the variable a normal
|
||||
C-variable also.
|
||||
|
||||
<Para>
|
||||
The special types VARCHAR and VARCHAR2 are converted into a named struct
|
||||
for every variable. A declaration like:
|
||||
<ProgramListing>
|
||||
VARCHAR var[180];
|
||||
</ProgramListing>
|
||||
is converted into
|
||||
<ProgramListing>
|
||||
struct varchar_var { int len; char arr[180]; } var;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Include statements</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An include statement looks like:
|
||||
<ProgramListing>
|
||||
exec sql include filename;
|
||||
</ProgramListing>
|
||||
It is converted into
|
||||
<ProgramListing>
|
||||
#include <filename.h>
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Connect statement</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A connect statement looks like:
|
||||
<ProgramListing>
|
||||
exec sql connect '<Replaceable>database</Replaceable>';
|
||||
</ProgramListing>
|
||||
That statement is converted into
|
||||
<ProgramListing>
|
||||
ECPGconnect("<Replaceable>database</Replaceable>");
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Open cursor statement</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An open cursor statement looks like:
|
||||
<ProgramListing>
|
||||
exec sql open <Replaceable>cursor</Replaceable>;
|
||||
</ProgramListing>
|
||||
and is ignore and not copied from the output.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Commit statement</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A commit statement looks like
|
||||
<ProgramListing>
|
||||
exec sql commit;
|
||||
</ProgramListing>
|
||||
and is translated on the output to
|
||||
<ProgramListing>
|
||||
ECPGcommit(__LINE__);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Rollback statement</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A rollback statement looks like
|
||||
<ProgramListing>
|
||||
exec sql rollback;
|
||||
</ProgramListing>
|
||||
and is translated on the output to
|
||||
<ProgramListing>
|
||||
ECPGrollback(__LINE__);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Other statements</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Other <Acronym>SQL</Acronym> statements are other statements that start with
|
||||
<Command>exec sql</Command> and ends with <Command>;</Command>. Everything inbetween is treated
|
||||
as an <Acronym>SQL</Acronym> statement and parsed for variable substitution.
|
||||
|
||||
<Para>
|
||||
Variable substitution occur when a symbol starts with a colon
|
||||
(<Command>:</Command>). Then a variable with that name is found among the variables
|
||||
that were previously declared within a declare section and depending on
|
||||
whether or not the <Acronym>SQL</Acronym> statements knows it to be a variable for input or
|
||||
output the pointers to the variables are written to the output to allow
|
||||
for access by the function.
|
||||
|
||||
<Para>
|
||||
For every variable that is part of the <Acronym>SQL</Acronym> request the function gets
|
||||
another five arguments.
|
||||
|
||||
<SimpleList>
|
||||
<Member>The type as a special symbol</Member>
|
||||
<Member>A pointer to the value</Member>
|
||||
<Member>The size of the variable if it is a varchar</Member>
|
||||
<Member>Number of elements in the array (for array fetches)</Member>
|
||||
<Member>The offset to the next element in the array (for array fetches)</Member>
|
||||
</SimpleList>
|
||||
|
||||
<Para>
|
||||
Since the array fetches are not implemented yet the two last arguments
|
||||
are not really important. They could perhaps have been left out.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>A Complete Example</Title>
|
||||
|
||||
<Para>
|
||||
Here is a complete example describing the output of the preprocessor:
|
||||
<ProgramListing>
|
||||
exec sql begin declare section;
|
||||
int index;
|
||||
int result;
|
||||
exec sql end declare section;
|
||||
...
|
||||
exec sql select res into :result from mytable where index = :index;
|
||||
</ProgramListing>
|
||||
is translated into:
|
||||
<ProgramListing>
|
||||
/* These two include files are added by the preprocessor */
|
||||
#include <ecpgtype.h>
|
||||
#include <ecpglib.h>
|
||||
/* exec sql begin declare section */
|
||||
|
||||
int index;
|
||||
int result;
|
||||
/* exec sql end declare section */
|
||||
|
||||
...
|
||||
ECPGdo(__LINE__, "select res from mytable where index = ;;",
|
||||
ECPGt_int,&index,0,0,sizeof(int),
|
||||
ECPGt_EOIT,
|
||||
ECPGt_int,&result,0,0,sizeof(int),
|
||||
ECPGt_EORT );
|
||||
</ProgramListing>
|
||||
(the indentation in this manual is added for readability and not
|
||||
something that the preprocessor can do.)
|
||||
|
||||
<Sect2>
|
||||
<Title>The Library</Title>
|
||||
|
||||
<Para>
|
||||
The most important function in the library is the <Function>ECPGdo</Function>
|
||||
function. It takes a variable amount of arguments. Hopefully we wont run
|
||||
into machines with limits on the amount of variables that can be
|
||||
accepted by a varchar function. This could easily add up to 50 or so
|
||||
arguments.
|
||||
|
||||
<Para>
|
||||
The arguments are:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>A line number</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This is a line number for the original line used in error messages only.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>A string</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
This is the <Acronym>SQL</Acronym> request that is to be issued. This request is modified
|
||||
by the input variables, i.e. the variables that where not known at
|
||||
compile time but are to be entered in the request. Where the variables
|
||||
should go the string contains <Quote>;</Quote>.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Input variables</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
As described in the section about the preprocessor every input variable
|
||||
gets five arguments.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>ECPGt_EOIT</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An enum telling that there are no more input variables.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Output variables</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
As described in the section about the preprocessor every input variable
|
||||
gets five arguments. These variables are filled by the function.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>ECPGt_EORT</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An enum telling that there are no more variables.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
||||
<Para>
|
||||
All the <Acronym>SQL</Acronym> statements are performed in one transaction unless you issue
|
||||
a commit transaction. This works so that the first transaction or the
|
||||
first after a commit or rollback always begins a transaction.
|
||||
|
||||
<Para>
|
||||
To be completed: entries describing the other entries.
|
||||
|
||||
</Chapter>
|
62
doc/src/sgml/environ.sgml
Normal file
62
doc/src/sgml/environ.sgml
Normal file
@ -0,0 +1,62 @@
|
||||
<Chapter>
|
||||
<Title>Setting Up Your Environment</Title>
|
||||
|
||||
<Para>
|
||||
This section discusses how to set up
|
||||
your own environment so that you can use frontend
|
||||
applications. We assume <ProductName>Postgres</ProductName> has already been
|
||||
successfully installed and started; refer to the Administrator's Guide
|
||||
and the installation notes
|
||||
for how to install Postgres.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> is a client/server application. As a user,
|
||||
you only need access to the client portions of the installation (an example
|
||||
of a client application is the interactive monitor <Application>psql</Application>).
|
||||
For simplicity,
|
||||
we will assume that <ProductName>Postgres</ProductName> has been installed in the
|
||||
directory <FileName>/usr/local/pgsql</FileName>. Therefore, wherever
|
||||
you see the directory <FileName>/usr/local/pgsql</FileName> you should
|
||||
substitute the name of the directory where <ProductName>Postgres</ProductName> is
|
||||
actually installed.
|
||||
All <ProductName>Postgres</ProductName> commands are installed in the directory
|
||||
<FileName>/usr/local/pgsql/bin</FileName>. Therefore, you should add
|
||||
this directory to your shell command path. If you use
|
||||
a variant of the Berkeley C shell, such as <Application>csh</Application> or <Application>tcsh</Application>,
|
||||
you would add
|
||||
<ProgramListing>
|
||||
set path = ( /usr/local/pgsql/bin path )
|
||||
</ProgramListing>
|
||||
in the <FileName>.login</FileName> file in your home directory. If you use
|
||||
a variant of the Bourne shell, such as <Application>sh</Application>, <Application>ksh</Application>, or
|
||||
<Application>bash</Application>, then you would add
|
||||
<ProgramListing>
|
||||
PATH=/usr/local/pgsql/bin PATH
|
||||
export PATH
|
||||
</ProgramListing>
|
||||
to the <FileName>.profile</FileName> file in your home directory.
|
||||
From now on, we will assume that you have added the
|
||||
<ProductName>Postgres</ProductName> bin directory to your path. In addition, we
|
||||
will make frequent reference to <Quote>setting a shell
|
||||
variable</Quote> or <Quote>setting an environment variable</Quote> 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.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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 <Acronym>PGHOST</Acronym> environment variable to the name
|
||||
of the database server machine. The environment variable
|
||||
<Acronym>PGPORT</Acronym> 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 <Application>postmaster</Application>,
|
||||
you should immediately consult your site administrator to make sure that your
|
||||
environment is properly set up.
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
250
doc/src/sgml/extend.sgml
Normal file
250
doc/src/sgml/extend.sgml
Normal file
@ -0,0 +1,250 @@
|
||||
<Chapter>
|
||||
<Title>Extending <Acronym>SQL</Acronym>: An Overview</Title>
|
||||
|
||||
<Para>
|
||||
In the sections that follow, we will discuss how you
|
||||
can extend the <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> query language by adding:
|
||||
<ItemizedList Mark="bullet" Spacing="compact">
|
||||
<ListItem>
|
||||
<Para>
|
||||
functions
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
types
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
operators
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
aggregates
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>How Extensibility Works</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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 <Acronym>DBMS</Acronym> stores
|
||||
its internal bookkeeping in them. One key difference
|
||||
between <ProductName>Postgres</ProductName> and standard relational systems is
|
||||
that <ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName> bases its internal operation
|
||||
on these classes, this means that <ProductName>Postgres</ProductName> can be
|
||||
extended by users. By comparison, conventional
|
||||
database systems can only be extended by changing hardcoded
|
||||
procedures within the <Acronym>DBMS</Acronym> or by loading modules
|
||||
specially-written by the <Acronym>DBMS</Acronym> vendor.
|
||||
</Para>
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName> will load it as required. Code written
|
||||
in <Acronym>SQL</Acronym> are even more trivial to add to the server.
|
||||
This ability to modify its operation "on the fly" makes
|
||||
<ProductName>Postgres</ProductName> uniquely suited for rapid prototyping of new
|
||||
applications and storage structures.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>The <ProductName>Postgres</ProductName> Type System</Title>
|
||||
|
||||
<Para>
|
||||
The <ProductName>Postgres</ProductName> type system can be broken down in several ways.
|
||||
Types are divided into base types and composite types.
|
||||
Base types are those, like <FirstTerm>int4</FirstTerm>, that are implemented
|
||||
in a language such as <ProductName>C</ProductName>. They generally correspond to
|
||||
what are often known as "abstract data types"; <ProductName>Postgres</ProductName>
|
||||
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.
|
||||
</Para>
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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.
|
||||
<ProductName>Postgres</ProductName> base types are further divided into built-in
|
||||
types and user-defined types. Built-in types (like
|
||||
<FirstTerm>int4</FirstTerm>) are those that are compiled into the system.
|
||||
User-defined types are those created by the user in the
|
||||
manner to be described below.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>About the <ProductName>Postgres</ProductName> System Catalogs</Title>
|
||||
|
||||
<Para>
|
||||
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 <FirstTerm>pg_</FirstTerm>.
|
||||
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.)
|
||||
|
||||
<TABLE TOCENTRY="1">
|
||||
<TITLE>Postgres System Catalogs</TITLE>
|
||||
<TITLEABBREV>Catalogs</TITLEABBREV>
|
||||
<TGROUP COLS="2">
|
||||
<THEAD>
|
||||
<ROW>
|
||||
<ENTRY>Catalog Name</ENTRY>
|
||||
<ENTRY>Description</ENTRY>
|
||||
</ROW>
|
||||
</THEAD>
|
||||
<TBODY>
|
||||
<ROW>
|
||||
<ENTRY>pg_database</ENTRY>
|
||||
<ENTRY> databases</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_class</ENTRY>
|
||||
<ENTRY> classes</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_attribute</ENTRY>
|
||||
<ENTRY> class attributes</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_index</ENTRY>
|
||||
<ENTRY> secondary indices</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_proc</ENTRY>
|
||||
<ENTRY> procedures (both C and SQL)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_type</ENTRY>
|
||||
<ENTRY> types (both base and complex)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_operator</ENTRY>
|
||||
<ENTRY> operators</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_aggregate</ENTRY>
|
||||
<ENTRY> aggregates and aggregate functions</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_am</ENTRY>
|
||||
<ENTRY> access methods</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_amop</ENTRY>
|
||||
<ENTRY> access method operators</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_amproc</ENTRY>
|
||||
<ENTRY> access method support functions</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>pg_opclass</ENTRY>
|
||||
<ENTRY> access method operator classes</ENTRY>
|
||||
</ROW>
|
||||
</TBODY>
|
||||
</TGROUP>
|
||||
</TABLE>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<Figure Id="EXTEND-CATALOGS" Float="1">
|
||||
<Title>The major <ProductName>Postgres</ProductName> system catalogs</Title>
|
||||
<Graphic Align="center" FileRef="catalogs.gif" Format="GIF"></Graphic>
|
||||
</Figure>
|
||||
|
||||
The Reference Manual gives a more detailed explanation
|
||||
of these catalogs and their attributes. However,
|
||||
<XRef LinkEnd="EXTEND-CATALOGS" EndTerm="EXTEND-CATALOGS">
|
||||
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:
|
||||
|
||||
<ItemizedList Mark="bullet" Spacing="compact">
|
||||
<ListItem>
|
||||
<Para>
|
||||
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.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para> 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.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para> Types and procedures
|
||||
are central to the schema.
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
We use the words <FirstTerm>procedure</FirstTerm> and <FirstTerm>function</FirstTerm> more or less
|
||||
interchangably.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
Nearly every catalog contains some reference to
|
||||
instances in one or both of these classes. For
|
||||
example, <ProductName>Postgres</ProductName> frequently uses type
|
||||
signatures (e.g., of functions and operators) to
|
||||
identify unique instances of other catalogs.
|
||||
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para> 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
|
||||
pg_am, pg_amop, pg_amproc, pg_operator and
|
||||
pg_opclass 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.
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
</Para>
|
||||
</Chapter>
|
19
doc/src/sgml/func-ref.sgml
Normal file
19
doc/src/sgml/func-ref.sgml
Normal file
@ -0,0 +1,19 @@
|
||||
<Chapter>
|
||||
<Title>Functions</Title>
|
||||
|
||||
<Abstract>
|
||||
<Para>
|
||||
Reference information for user-callable functions.
|
||||
</Para>
|
||||
</Abstract>
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
This section needs to be written. Volunteers?
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
228
doc/src/sgml/geqo.sgml
Normal file
228
doc/src/sgml/geqo.sgml
Normal file
@ -0,0 +1,228 @@
|
||||
<Chapter>
|
||||
<DocInfo>
|
||||
<Author>
|
||||
<FirstName>Martin</FirstName>
|
||||
<SurName>Utesch</SurName>
|
||||
</Author>
|
||||
</DocInfo>
|
||||
|
||||
<Title>Genetic Query Optimization in Database Systems</Title>
|
||||
|
||||
<Para>
|
||||
<ProgramListing>
|
||||
<ULink url="utesch@aut.tu-freiberg.de">Martin Utesch</ULink>
|
||||
|
||||
Institute of Automatic Control
|
||||
University of Mining and Technology
|
||||
Freiberg, Germany
|
||||
|
||||
02/10/1997
|
||||
|
||||
|
||||
1.) Query Handling as a Complex Optimization Problem
|
||||
====================================================
|
||||
|
||||
Among all relational operators the most difficult one to process and
|
||||
optimize is the JOIN. The number of alternative plans to answer a query
|
||||
grows exponentially with the number of JOINs included in it. Further
|
||||
optimization effort is caused by the support of a variety of *JOIN
|
||||
methods* (e.g., nested loop, index scan, merge join in Postgres) to
|
||||
process individual JOINs and a diversity of *indices* (e.g., r-tree,
|
||||
b-tree, hash in Postgres) as access paths for relations.
|
||||
|
||||
The current Postgres optimizer implementation performs a *near-
|
||||
exhaustive search* over the space of alternative strategies. This query
|
||||
optimization technique is inadequate to support database application
|
||||
domains that involve the need for extensive queries, such as artificial
|
||||
intelligence.
|
||||
|
||||
The Institute of Automatic Control at the University of Mining and
|
||||
Technology, in Freiberg, Germany, encountered the described problems as its
|
||||
folks wanted to take the Postgres DBMS as the backend for a decision
|
||||
support knowledge based system for the maintenance of an electrical
|
||||
power grid. The DBMS needed to handle large JOIN queries for the
|
||||
inference machine of the knowledge based system.
|
||||
|
||||
Performance difficulties within exploring the space of possible query
|
||||
plans arose the demand for a new optimization technique being developed.
|
||||
|
||||
In the following we propose the implementation of a *Genetic
|
||||
Algorithm* as an option for the database query optimization problem.
|
||||
|
||||
|
||||
2.) Genetic Algorithms (GA)
|
||||
===========================
|
||||
|
||||
The GA is a heuristic optimization method which operates through
|
||||
determined, randomized search. The set of possible solutions for the
|
||||
optimization problem is considered as a *population* of *individuals*.
|
||||
The degree of adaption of an individual to its environment is specified
|
||||
by its *fitness*.
|
||||
|
||||
The coordinates of an individual in the search space are represented
|
||||
by *chromosomes*, in essence a set of character strings. A *gene* is a
|
||||
subsection of a chromosome which encodes the value of a single parameter
|
||||
being optimized. Typical encodings for a gene could be *binary* or
|
||||
*integer*.
|
||||
|
||||
Through simulation of the evolutionary operations *recombination*,
|
||||
*mutation*, and *selection* new generations of search points are found
|
||||
that show a higher average fitness than their ancestors.
|
||||
|
||||
According to the "comp.ai.genetic" FAQ it cannot be stressed too
|
||||
strongly that a GA is not a pure random search for a solution to a
|
||||
problem. A GA uses stochastic processes, but the result is distinctly
|
||||
non-random (better than random).
|
||||
|
||||
Structured Diagram of a GA:
|
||||
---------------------------
|
||||
|
||||
P(t) generation of ancestors at a time t
|
||||
P''(t) generation of descendants at a time t
|
||||
|
||||
+=========================================+
|
||||
|>>>>>>>>>>> Algorithm GA <<<<<<<<<<<<<<|
|
||||
+=========================================+
|
||||
| INITIALIZE t := 0 |
|
||||
+=========================================+
|
||||
| INITIALIZE P(t) |
|
||||
+=========================================+
|
||||
| evalute FITNESS of P(t) |
|
||||
+=========================================+
|
||||
| while not STOPPING CRITERION do |
|
||||
| +-------------------------------------+
|
||||
| | P'(t) := RECOMBINATION{P(t)} |
|
||||
| +-------------------------------------+
|
||||
| | P''(t) := MUTATION{P'(t)} |
|
||||
| +-------------------------------------+
|
||||
| | P(t+1) := SELECTION{P''(t) + P(t)} |
|
||||
| +-------------------------------------+
|
||||
| | evalute FITNESS of P''(t) |
|
||||
| +-------------------------------------+
|
||||
| | t := t + 1 |
|
||||
+===+=====================================+
|
||||
|
||||
|
||||
3.) Genetic Query Optimization (GEQO) in PostgreSQL
|
||||
===================================================
|
||||
|
||||
The GEQO module is intended for the solution of the query
|
||||
optimization problem similar to a traveling salesman problem (TSP).
|
||||
Possible query plans are encoded as integer strings. Each string
|
||||
represents the JOIN order from one relation of the query to the next.
|
||||
E. g., the query tree /\
|
||||
/\ 2
|
||||
/\ 3
|
||||
4 1 is encoded by the integer string '4-1-3-2',
|
||||
which means, first join relation '4' and '1', then '3', and
|
||||
then '2', where 1, 2, 3, 4 are relids in PostgreSQL.
|
||||
|
||||
Parts of the GEQO module are adapted from D. Whitley's Genitor
|
||||
algorithm.
|
||||
|
||||
Specific characteristics of the GEQO implementation in PostgreSQL
|
||||
are:
|
||||
|
||||
o usage of a *steady state* GA (replacement of the least fit
|
||||
individuals in a population, not whole-generational replacement)
|
||||
allows fast convergence towards improved query plans. This is
|
||||
essential for query handling with reasonable time;
|
||||
|
||||
o usage of *edge recombination crossover* which is especially suited
|
||||
to keep edge losses low for the solution of the TSP by means of a GA;
|
||||
|
||||
o mutation as genetic operator is deprecated so that no repair
|
||||
mechanisms are needed to generate legal TSP tours.
|
||||
|
||||
The GEQO module gives the following benefits to the PostgreSQL DBMS
|
||||
compared to the Postgres query optimizer implementation:
|
||||
|
||||
o handling of large JOIN queries through non-exhaustive search;
|
||||
|
||||
o improved cost size approximation of query plans since no longer
|
||||
plan merging is needed (the GEQO module evaluates the cost for a
|
||||
query plan as an individual).
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
J. Heitk"otter, D. Beasley:
|
||||
---------------------------
|
||||
"The Hitch-Hicker's Guide to Evolutionary Computation",
|
||||
FAQ in 'comp.ai.genetic',
|
||||
'ftp://ftp.Germany.EU.net/pub/research/softcomp/EC/Welcome.html'
|
||||
|
||||
Z. Fong:
|
||||
--------
|
||||
"The Design and Implementation of the Postgres Query Optimizer",
|
||||
file 'planner/Report.ps' in the 'postgres-papers' distribution
|
||||
|
||||
R. Elmasri, S. Navathe:
|
||||
-----------------------
|
||||
"Fundamentals of Database Systems",
|
||||
The Benjamin/Cummings Pub., Inc.
|
||||
|
||||
|
||||
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
|
||||
* Things left to done for the PostgreSQL *
|
||||
= Genetic Query Optimization (GEQO) =
|
||||
* module implementation *
|
||||
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
|
||||
* Martin Utesch * Institute of Automatic Control *
|
||||
= = University of Mining and Technology =
|
||||
* utesch@aut.tu-freiberg.de * Freiberg, Germany *
|
||||
=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=
|
||||
|
||||
|
||||
1.) Basic Improvements
|
||||
===============================================================
|
||||
|
||||
a) improve freeing of memory when query is already processed:
|
||||
-------------------------------------------------------------
|
||||
with large JOIN queries the computing time spent for the genetic query
|
||||
optimization seems to be a mere *fraction* of the time Postgres
|
||||
needs for freeing memory via routine 'MemoryContextFree',
|
||||
file 'backend/utils/mmgr/mcxt.c';
|
||||
debugging showed that it get stucked in a loop of routine
|
||||
'OrderedElemPop', file 'backend/utils/mmgr/oset.c';
|
||||
the same problems arise with long queries when using the normal
|
||||
Postgres query optimization algorithm;
|
||||
|
||||
b) improve genetic algorithm parameter settings:
|
||||
------------------------------------------------
|
||||
file 'backend/optimizer/geqo/geqo_params.c', routines
|
||||
'gimme_pool_size' and 'gimme_number_generations';
|
||||
we have to find a compromise for the parameter settings
|
||||
to satisfy two competing demands:
|
||||
1. optimality of the query plan
|
||||
2. computing time
|
||||
|
||||
c) find better solution for integer overflow:
|
||||
---------------------------------------------
|
||||
file 'backend/optimizer/geqo/geqo_eval.c', routine
|
||||
'geqo_joinrel_size';
|
||||
the present hack for MAXINT overflow is to set the Postgres integer
|
||||
value of 'rel->size' to its logarithm;
|
||||
modifications of 'struct Rel' in 'backend/nodes/relation.h' will
|
||||
surely have severe impacts on the whole PostgreSQL implementation.
|
||||
|
||||
d) find solution for exhausted memory:
|
||||
--------------------------------------
|
||||
that may occur with more than 10 relations involved in a query,
|
||||
file 'backend/optimizer/geqo/geqo_eval.c', routine
|
||||
'gimme_tree' which is recursively called;
|
||||
maybe I forgot something to be freed correctly, but I dunno what;
|
||||
of course the 'rel' data structure of the JOIN keeps growing and
|
||||
growing the more relations are packed into it;
|
||||
suggestions are welcome :-(
|
||||
|
||||
|
||||
2.) Further Improvements
|
||||
===============================================================
|
||||
Enable bushy query tree processing within PostgreSQL;
|
||||
that may improve the quality of query plans.
|
||||
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Chapter>
|
98
doc/src/sgml/gist.sgml
Normal file
98
doc/src/sgml/gist.sgml
Normal file
@ -0,0 +1,98 @@
|
||||
<Chapter>
|
||||
<DocInfo>
|
||||
<AuthorGroup>
|
||||
<Author>
|
||||
<FirstName>Gene</FirstName>
|
||||
<Surname>Selkov</Surname>
|
||||
</Author>
|
||||
</AuthorGroup>
|
||||
<Date>Transcribed 1998-02-19</Date>
|
||||
</DocInfo>
|
||||
<Title>GiST Indices</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Title>Caveat</Title>
|
||||
<Para>
|
||||
This extraction from an e-mail sent by
|
||||
<ULink url="mailto:selkovjr@mcs.anl.gov">Eugene Selkov Jr.</ULink>
|
||||
contains good information
|
||||
on GiST. Hopefully we will learn more in the future and update this information.
|
||||
- thomas
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
Well, I can't say I quite understand what's going on, but at least
|
||||
I (almost) succeeded in porting GiST examples to linux. The GiST access
|
||||
method is already in the postgres tree (<FileName>src/backend/access/gist</FileName>).
|
||||
|
||||
<Para>
|
||||
<ULink url="ftp://s2k-ftp.cs.berkeley.edu/pub/gist/pggist/pggist.tgz">Examples at Berkeley</ULink>
|
||||
come with an overview of the methods and demonstrate spatial index
|
||||
mechanisms for 2D boxes, polygons, integer intervals and text
|
||||
(see also <ULink url="http://gist.cs.berkeley.edu:8000/gist/">GiST at Berkeley</ULink>).
|
||||
In the box example, we
|
||||
are supposed to see a performance gain when using the GiST index; it did
|
||||
work for me but I do not have a reasonably large collection of boxes
|
||||
to check that. Other examples also worked, except polygons: I got an
|
||||
error doing
|
||||
|
||||
<ProgramListing>
|
||||
test=> create index pix on polytmp using gist (p:box gist_poly_ops) with
|
||||
(islossy);
|
||||
ERROR: cannot open pix
|
||||
|
||||
(PostgreSQL 6.3 Sun Feb 1 14:57:30 EST 1998)
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
I could not get sense of this error message; it appears to be something
|
||||
we'd rather ask the developers about (see also Note 4 below). What I
|
||||
would suggest here is that someone of you linux guys (linux==gcc?) fetch the
|
||||
original sources quoted above and apply my patch (see attachment) and
|
||||
tell us what you feel about it. Looks cool to me, but I would not like
|
||||
to hold it up while there are so many competent people around.
|
||||
|
||||
<Para>
|
||||
A few notes on the sources:
|
||||
|
||||
<Para>
|
||||
1. I failed to make use of the original (HPUX) Makefile and rearranged
|
||||
the Makefile from the ancient postgres95 tutorial to do the job. I
|
||||
tried
|
||||
to keep it generic, but I am a very poor makefile writer -- just did
|
||||
some monkey work. Sorry about that, but I guess it is now a little
|
||||
more portable that the original makefile.
|
||||
|
||||
<Para>
|
||||
2. I built the example sources right under pgsql/src (just extracted the
|
||||
tar file there). The aforementioned Makefile assumes it is one level
|
||||
below pgsql/src (in our case, in pgsql/src/pggist).
|
||||
|
||||
<Para>
|
||||
3. The changes I made to the *.c files were all about #include's,
|
||||
function prototypes and typecasting. Other than that, I just threw
|
||||
away a bunch of unused vars and added a couple parentheses to please
|
||||
gcc. I hope I did not screw up too much :)
|
||||
|
||||
<Para>
|
||||
4. There is a comment in polyproc.sql:
|
||||
|
||||
<ProgramListing>
|
||||
-- -- there's a memory leak in rtree poly_ops!!
|
||||
-- -- create index pix2 on polytmp using rtree (p poly_ops);
|
||||
</ProgramListing>
|
||||
|
||||
Roger that!! I thought it could be related to a number of
|
||||
<ProductName>Postgres</ProductName> versions
|
||||
back and tried the query. My system went nuts and I had to shoot down
|
||||
the postmaster in about ten minutes.
|
||||
|
||||
|
||||
<Para>
|
||||
I will continue to look into GiST for a while, but I would also
|
||||
appreciate
|
||||
more examples of R-tree usage.
|
||||
|
||||
</Chapter>
|
87
doc/src/sgml/inherit.sgml
Normal file
87
doc/src/sgml/inherit.sgml
Normal file
@ -0,0 +1,87 @@
|
||||
<Chapter>
|
||||
<Title>Inheritance</Title>
|
||||
|
||||
<Para>
|
||||
Let's create two classes. The capitals class contains
|
||||
state capitals which are also cities. Naturally, the
|
||||
capitals class should inherit from cities.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE TABLE cities (
|
||||
name text,
|
||||
population float,
|
||||
altitude int -- (in ft)
|
||||
);
|
||||
|
||||
CREATE TABLE capitals (
|
||||
state char2
|
||||
) INHERITS (cities);
|
||||
</ProgramListing>
|
||||
|
||||
In this case, an instance of capitals <FirstTerm>inherits</FirstTerm> all
|
||||
attributes (name, population, and altitude) from its
|
||||
parent, cities. The type of the attribute name is
|
||||
<Type>text</Type>, a native <ProductName>Postgres</ProductName> type for variable length
|
||||
ASCII strings. The type of the attribute population is
|
||||
<Type>float</Type>, a native <ProductName>Postgres</ProductName> type for double precision
|
||||
floating point numbers. State capitals have an extra
|
||||
attribute, state, that shows their state. In <ProductName>Postgres</ProductName>,
|
||||
a class can inherit from zero or more other classes,
|
||||
and a query can reference either all instances of a
|
||||
class or all instances of a class plus all of its
|
||||
descendants.
|
||||
<Note>
|
||||
<Para>
|
||||
The inheritance hierarchy is a actually a directed acyclic graph.
|
||||
</Para>
|
||||
</Note>
|
||||
For example, the following query finds
|
||||
all the cities that are situated at an attitude of 500ft or higher:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT name, altitude
|
||||
FROM cities
|
||||
WHERE altitude > 500;
|
||||
|
||||
+----------+----------+
|
||||
|name | altitude |
|
||||
+----------+----------+
|
||||
|Las Vegas | 2174 |
|
||||
+----------+----------+
|
||||
|Mariposa | 1953 |
|
||||
+----------+----------+
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
On the other hand, to find the names of all cities,
|
||||
including state capitals, that are located at an altitude
|
||||
over 500ft, the query is:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT c.name, c.altitude
|
||||
FROM cities* c
|
||||
WHERE c.altitude > 500;
|
||||
</ProgramListing>
|
||||
|
||||
which returns:
|
||||
|
||||
<ProgramListing>
|
||||
+----------+----------+
|
||||
|name | altitude |
|
||||
+----------+----------+
|
||||
|Las Vegas | 2174 |
|
||||
+----------+----------+
|
||||
|Mariposa | 1953 |
|
||||
+----------+----------+
|
||||
|Madison | 845 |
|
||||
+----------+----------+
|
||||
</ProgramListing>
|
||||
|
||||
Here the <Quote>*</Quote> 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 -- <Command>select</Command>, <Command>update</Command> and <Command>delete</Command> --
|
||||
support this <Quote>*</Quote> notation, as do others, like <Command>alter</Command>.
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
1032
doc/src/sgml/install.sgml
Normal file
1032
doc/src/sgml/install.sgml
Normal file
File diff suppressed because it is too large
Load Diff
74
doc/src/sgml/intro-pg.sgml
Normal file
74
doc/src/sgml/intro-pg.sgml
Normal file
@ -0,0 +1,74 @@
|
||||
<Chapter>
|
||||
<TITLE>Introduction</TITLE>
|
||||
|
||||
<Para>
|
||||
This document is the programmer's manual for the
|
||||
<Ulink url="http://postgresql.org/"><ProductName>PostgreSQL</ProductName></Ulink>
|
||||
database management system, originally developed at the University
|
||||
of California at Berkeley. <ProductName>PostgreSQL</ProductName> is based on
|
||||
<Ulink url="http://s2k-ftp.CS.Berkeley.EDU:8000/postgres/postgres.html">
|
||||
<ProductName>Postgres release 4.2</ProductName></Ulink>.
|
||||
The <ProductName>Postgres</ProductName> project,
|
||||
led by Professor Michael Stonebraker, has been sponsored by the
|
||||
Defense Advanced Research Projects Agency (<Acronym>DARPA</Acronym>), the
|
||||
Army Research Office (<Acronym>ARO</Acronym>), the National Science
|
||||
Foundation (<Acronym>NSF</Acronym>), and ESL, Inc.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The first part of this manual
|
||||
explains the
|
||||
<ProductName>Postgres</ProductName> approach to extensibility and describe how
|
||||
users can extend <ProductName>Postgres</ProductName> by adding user-defined types,
|
||||
operators, aggregates, and both query language and programming language functions.
|
||||
After an extremely brief
|
||||
overview of the <ProductName>Postgres</ProductName> rule system, we discuss
|
||||
the trigger and SPI interfaces.
|
||||
The manual concludes with a detailed description of the programming interfaces and
|
||||
support libraries for various languages.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
We assume proficiency with UNIX and C programming.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Copyrights and Trademarks</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> is copyright (C) 1996-8 by the PostgreSQL Global Development Group,
|
||||
and is distributed under the terms of the Berkeley license.
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres95</ProductName> 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.
|
||||
</Para>
|
||||
<Para>
|
||||
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.
|
||||
</Para>
|
||||
<Para>
|
||||
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
|
||||
maintainance, support, updates, enhancements, or modifications.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<Acronym>UNIX</Acronym> 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.
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
482
doc/src/sgml/intro.sgml
Normal file
482
doc/src/sgml/intro.sgml
Normal file
@ -0,0 +1,482 @@
|
||||
<Chapter>
|
||||
<TITLE>Introduction</TITLE>
|
||||
|
||||
<Para>
|
||||
This document is the user manual for the
|
||||
<Ulink url="http://postgresql.org/"><ProductName>PostgreSQL</ProductName></Ulink>
|
||||
database management system, originally developed at the University
|
||||
of California at Berkeley. <ProductName>PostgreSQL</ProductName> is based on
|
||||
<Ulink url="http://s2k-ftp.CS.Berkeley.EDU:8000/postgres/postgres.html">
|
||||
<ProductName>Postgres release 4.2</ProductName></Ulink>.
|
||||
The <ProductName>Postgres</ProductName> project,
|
||||
led by Professor Michael Stonebraker, has been sponsored by the
|
||||
Defense Advanced Research Projects Agency (<Acronym>DARPA</Acronym>), the
|
||||
Army Research Office (<Acronym>ARO</Acronym>), the National Science
|
||||
Foundation (<Acronym>NSF</Acronym>), and ESL, Inc.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title> What is <ProductName>Postgres</ProductName>?</Title>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
<ProductName>Postgres</ProductName> offers substantial additional
|
||||
power by incorporating the following four additional
|
||||
basic concepts in such a way that users can easily
|
||||
extend the system:
|
||||
|
||||
<SimpleList>
|
||||
<Member>classes</Member>
|
||||
<Member>inheritance</Member>
|
||||
<Member>types</Member>
|
||||
<Member>functions</Member>
|
||||
</SimpleList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Other features provide additional power and flexibility:
|
||||
|
||||
<SimpleList>
|
||||
<Member>constraints</Member>
|
||||
<Member>triggers</Member>
|
||||
<Member>rules</Member>
|
||||
<Member>transaction integrity</Member>
|
||||
</SimpleList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
These features put <ProductName>Postgres</ProductName> into the category of databases
|
||||
referred to as <FirstTerm>object-relational</FirstTerm>. Note that this is distinct
|
||||
from those referred to as <FirstTerm>object-oriented</FirstTerm>, which in general
|
||||
are not as well suited to supporting the traditional relational database languages.
|
||||
So, although <ProductName>Postgres</ProductName> has some object-oriented features,
|
||||
it is firmly in the relational database world. In fact, some commercial databases
|
||||
have recently incorporated features pioneered by <ProductName>Postgres</ProductName>.
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>A Short History of <ProductName>Postgres</ProductName></Title>
|
||||
|
||||
<Sect2>
|
||||
<Title>The Berkeley <ProductName>Postgres</ProductName> Project</Title>
|
||||
|
||||
<Para>
|
||||
Implementation of the <ProductName>Postgres</ProductName> <Acronym>DBMS</Acronym> began in 1986. The
|
||||
initial concepts for the system were presented in
|
||||
<!--
|
||||
<XRef LinkEnd="STON86">
|
||||
-->
|
||||
<Citation>[STON86]</Citation>
|
||||
and the definition of the initial data model
|
||||
appeared in
|
||||
<!--
|
||||
<XRef LinkEnd="ROWE87">.
|
||||
-->
|
||||
<Citation>[ROWE87]</Citation>.
|
||||
The design of the rule system at
|
||||
that time was described in
|
||||
<!--
|
||||
<XRef LinkEnd="STON87a">.
|
||||
-->
|
||||
<Citation>[STON87a]</Citation>.
|
||||
The rationale
|
||||
and architecture of the storage manager were detailed in
|
||||
<!--
|
||||
<XRef LinkEnd="STON87b">.
|
||||
-->
|
||||
<Citation>[STON87b]</Citation>.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> has undergone several major releases since
|
||||
then. The first "demoware" system became operational
|
||||
in 1987 and was shown at the 1988 <Acronym>ACM-SIGMOD</Acronym>
|
||||
Conference. We released Version 1, described in
|
||||
<!--
|
||||
<XRef LinkEnd="STON90a">,
|
||||
-->
|
||||
<Citation>[STON90a]</Citation>,
|
||||
to a few external users in June 1989. In response to a
|
||||
critique of the first rule system
|
||||
<!--
|
||||
(<XRef LinkEnd="STON89">),
|
||||
-->
|
||||
(<Citation>[STON89]</Citation>),
|
||||
the rule
|
||||
system was redesigned
|
||||
<!--
|
||||
(<XRef LinkEnd="STON90b">)
|
||||
-->
|
||||
(<Citation>[STON90b]</Citation>)
|
||||
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.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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. <ProductName>Postgres</ProductName> has also been
|
||||
used as an educational tool at several universities.
|
||||
Finally, <Ulink url="http://www.illustra.com/">Illustra Information Technologies</Ulink> picked up
|
||||
the code and commercialized it.
|
||||
<ProductName>Postgres</ProductName> became the primary data manager for the
|
||||
<Ulink url="http://www.sdsc.edu/0/Parts_Collabs/S2K/s2k_home.html">Sequoia 2000</Ulink>
|
||||
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 Version 4.2.
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title><ProductName>Postgres95</ProductName></Title>
|
||||
|
||||
<Para>
|
||||
In 1994,
|
||||
<ULink url="mailto:ayu@informix.com">Andrew Yu</ULink>
|
||||
and
|
||||
<ULink url="http://http.cs.berkeley.edu/~jolly/">Jolly Chen</ULink>
|
||||
added a SQL language interpreter to <ProductName>Postgres</ProductName>, and the code was subsequently released to
|
||||
the Web to find its own way in the world. <ProductName>Postgres95</ProductName> was a public-domain, open source descendant
|
||||
of this original Berkeley code.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres95</ProductName> is a derivative of the last official release
|
||||
of <ProductName>Postgres</ProductName> (version 4.2). The code is now completely
|
||||
ANSI C and the code size has been trimmed by 25%. There
|
||||
are a lot of internal changes that improve performance
|
||||
and code maintainability. <ProductName>Postgres95</ProductName> v1.0.x runs about 30-50%
|
||||
faster on the Wisconsin Benchmark compared to v4.2.
|
||||
Apart from bug fixes, these are the major enhancements:
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The query language <ProductName>Postquel</ProductName> has been replaced with
|
||||
<Acronym>SQL</Acronym> (implemented in the server). We do not yet support
|
||||
subqueries (which can be imitated with user defined
|
||||
<Acronym>SQL</Acronym> functions). Aggregates have been
|
||||
re-implemented. We also added support for ``GROUP BY''.
|
||||
The <FileName>libpq</FileName> interface is still available for <Acronym>C</Acronym>
|
||||
programs.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
In addition to the monitor program, we provide a new
|
||||
program (<Application>psql</Application>) which supports <Acronym>GNU</Acronym> <FileName>readline</FileName>.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
We added a new front-end library, <FileName>libpgtcl</FileName>, that
|
||||
supports <Acronym>Tcl</Acronym>-based clients. A sample shell,
|
||||
pgtclsh, provides new Tcl commands to interface <Application>tcl</Application>
|
||||
programs with the <ProductName>Postgres95</ProductName> backend.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
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.)
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The instance-level rule system has been removed.
|
||||
Rules are still available as rewrite rules.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
A short tutorial introducing regular <Acronym>SQL</Acronym> features as
|
||||
well as those of ours is distributed with the source
|
||||
code.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
<Acronym>GNU</Acronym> make (instead of <Acronym>BSD</Acronym> make) is used for the
|
||||
build. Also, <ProductName>Postgres95</ProductName> can be compiled with an
|
||||
unpatched <ProductName>gcc</ProductName> (data alignment of doubles has been
|
||||
fixed).
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title><ProductName>PostgreSQL</ProductName></Title>
|
||||
|
||||
<Para>
|
||||
By 1996, it became clear that the name <Quote>Postgres95</Quote> would not stand
|
||||
the test of time. A new name, <ProductName>PostgreSQL</ProductName>, was chosen to reflect the
|
||||
relationship between original <ProductName>Postgres</ProductName> and the more recent
|
||||
versions with <Acronym>SQL</Acronym> capability. At the same time, the version numbering
|
||||
was reset to start at 6.0, putting the numbers back into the sequence originally begun by
|
||||
the <ProductName>Postgres</ProductName> Project.
|
||||
|
||||
<Para>
|
||||
The emphasis on development for the v1.0.x releases of <ProductName>Postgres95</ProductName>
|
||||
was on stabilizing the backend code.
|
||||
With the v6.x series of <ProductName>PostgreSQL</ProductName>, the emphasis has shifted from
|
||||
identifying and understanding existing problems in the backend to augmenting features and capabilities, although
|
||||
work continues in all areas.
|
||||
|
||||
<Para>
|
||||
Major enhancements include:
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Important backend features, including subselects, defaults, constraints, and triggers, have been implemented.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Additional <Acronym>SQL92</Acronym>-compliant language features have been added,
|
||||
including primary keys, quoted identifiers, literal string type coersion, type casting,
|
||||
and binary and hexadecimal integer input.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Built-in types have been improved, including new wide-range date/time types and additional geometric type support.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Overall backend code speed has been increased by approximately 20%, and backend startup speed has decreased 80%.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect1>
|
||||
<Title>About This Release</Title>
|
||||
|
||||
<Para>
|
||||
From now on, We will use <ProductName>Postgres</ProductName> to mean <ProductName>PostgreSQL</ProductName>.
|
||||
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> is available without cost. This manual
|
||||
describes version 6.3 of <ProductName>PostgreSQL</ProductName>.
|
||||
|
||||
<Para>
|
||||
Check the Administrator's Guide for a list of currently supported machines. In general,
|
||||
<ProductName>PostgreSQL</ProductName> is portable to any Unix/Posix-compatible system
|
||||
with full libc library support.
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Resources</Title>
|
||||
|
||||
<Para>
|
||||
This manual set is organized into several parts:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>Tutorial</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
An introduction for new users. Does not cover advanced features.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>User's Guide</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
General information for users, including available commands and data types.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Programmer's Guide</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Advanced information for application programmers. Topics include
|
||||
type and function extensibility, library interfaces, and application design issues.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Administrator's Guide</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Installation and management information. List of supported machines.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Developer's Guide</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Information for <ProductName>Postgres</ProductName> developers. This is intended
|
||||
for those who are contributing to the <ProductName>Postgres</ProductName>
|
||||
project; application development information should appear in the Programmer's Guide.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Reference Manual</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Detailed reference information on command syntax.
|
||||
At the moment, this manual is very sparse, but eventually should contain
|
||||
information similar to that in the man pages.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
||||
<Para>
|
||||
In addition to this manual set, there are other resources to help you with
|
||||
<ProductName>Postgres</ProductName> installation and use:
|
||||
|
||||
<VariableList>
|
||||
<VarListEntry>
|
||||
<Term>man pages</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The man pages have general information on command syntax.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>FAQs</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The Frequently Asked Questions (FAQ) documents address both general issues
|
||||
and some platform-specific issues.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>READMEs</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
README files are available for some contributed packages.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Web Site</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The <ULink url="postgresql.org"><ProductName>Postgres</ProductName></ULink> web site has some information
|
||||
not appearing in the distribution. There is a <ProductName>mhonarc</ProductName> catalog of mailing list traffic
|
||||
which is a rich resource for many topics.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Mailing Lists</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The <ULink url="mailto:questions@postgresql.org"><ProductName>Postgres</ProductName> Questions</ULink>
|
||||
mailing list is a good place to have user questions answered. Other mailing lists are available; consult
|
||||
the web page for details.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
|
||||
<VarListEntry>
|
||||
<Term>Yourself!</Term>
|
||||
<ListItem>
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> is an open source product. As such, it depends on the user community for
|
||||
ongoing support. As you begin to use <ProductName>Postgres</ProductName>, you will rely on others
|
||||
for help, either through the documentation or through the mailing lists. Consider contributing your
|
||||
knowledge back. If you learn something which is not in the documentation, write it up and contribute it.
|
||||
If you add features to the code, contribute it. Even those without a lot of experience can provide
|
||||
corrections and minor changes in the documentation, and that is a good way to start.
|
||||
The <ULink url="mailto:docs@postgresql.org"><ProductName>Postgres</ProductName> Documentation</ULink>
|
||||
mailing list is the place to get going.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</VarListEntry>
|
||||
</VariableList>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Copyrights and Trademarks</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> is copyright (C) 1996-8 by the PostgreSQL Global Development Group,
|
||||
and is distributed under the terms of the Berkeley license.
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres95</ProductName> 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.
|
||||
</Para>
|
||||
<Para>
|
||||
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.
|
||||
</Para>
|
||||
<Para>
|
||||
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
|
||||
maintainance, support, updates, enhancements, or modifications.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<Acronym>UNIX</Acronym> 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.
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
8
doc/src/sgml/jdbc.sgml
Normal file
8
doc/src/sgml/jdbc.sgml
Normal file
@ -0,0 +1,8 @@
|
||||
<Chapter>
|
||||
<Title>JDBC Interface</Title>
|
||||
|
||||
<Para>
|
||||
There is a JDBC interface available for Postgres. It is documented elsewhere using
|
||||
the accepted tool for Java-language code.
|
||||
|
||||
</Chapter>
|
1641
doc/src/sgml/libpgtcl.sgml
Normal file
1641
doc/src/sgml/libpgtcl.sgml
Normal file
File diff suppressed because it is too large
Load Diff
1099
doc/src/sgml/libpq.sgml
Normal file
1099
doc/src/sgml/libpq.sgml
Normal file
File diff suppressed because it is too large
Load Diff
485
doc/src/sgml/lobj.sgml
Normal file
485
doc/src/sgml/lobj.sgml
Normal file
@ -0,0 +1,485 @@
|
||||
<Chapter>
|
||||
<Title>Large Objects</Title>
|
||||
|
||||
<Para>
|
||||
In <ProductName>Postgres</ProductName>, 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, <ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName>
|
||||
large object data.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Historical Note</Title>
|
||||
|
||||
<Para>
|
||||
Originally, <ProductName>Postgres 4.2</ProductName> supported three standard
|
||||
implementations of large objects: as files external
|
||||
to <ProductName>Postgres</ProductName>, as <Acronym>UNIX</Acronym> files managed by <ProductName>Postgres</ProductName>, and as data
|
||||
stored within the <ProductName>Postgres</ProductName> database. It causes
|
||||
considerable confusion among users. As a result, we only
|
||||
support large objects as data stored within the <ProductName>Postgres</ProductName>
|
||||
database in <ProductName>PostgreSQL</ProductName>. Even though is is slower to
|
||||
access, it provides stricter data integrity.
|
||||
For historical reasons, this storage scheme is referred to as
|
||||
Inversion large objects. (We will use Inversion and large
|
||||
objects interchangeably to mean the same thing in this
|
||||
section.)
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Inversion Large Objects</Title>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Large Object Interfaces</Title>
|
||||
|
||||
<Para>
|
||||
The facilities <ProductName>Postgres</ProductName> 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 <ProductName>Postgres 4.2</ProductName>, <ProductName>PostgreSQL</ProductName> 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 XXX LOST TEXT? WHAT SHOULD GO HERE??.
|
||||
|
||||
The <ProductName>Postgres</ProductName> large object interface is modeled after
|
||||
the <Acronym>UNIX</Acronym> file system interface, with analogues of
|
||||
<Function>open(2)</Function>, <Function>read(2)</Function>, <Function>write(2)</Function>,
|
||||
<Function>lseek(2)</Function>, 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 <Acronym>C</Acronym>
|
||||
functions or database client programs that link the
|
||||
library. <ProductName>Postgres</ProductName> provides a set of routines that
|
||||
support opening, reading, writing, closing, and seeking on
|
||||
large objects.
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title>Creating a Large Object</Title>
|
||||
|
||||
<Para>
|
||||
The routine
|
||||
<ProgramListing>
|
||||
Oid lo_creat(PGconn *conn, int mode)
|
||||
</ProgramListing>
|
||||
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
|
||||
<FileName>
|
||||
PGROOT/src/backend/libpq/libpq-fs.h
|
||||
</FileName>
|
||||
The access type (read, write, or both) is controlled by
|
||||
OR ing together the bits <Acronym>INV_READ</Acronym> and <Acronym>INV_WRITE</Acronym>. 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 <Acronym>INV_ARCHIVE</Acronym> 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:
|
||||
<ProgramListing>
|
||||
inv_oid = lo_creat(INV_READ|INV_WRITE|INV_ARCHIVE);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Importing a Large Object</Title>
|
||||
|
||||
<Para>
|
||||
To import a <Acronym>UNIX</Acronym> file as
|
||||
a large object, call
|
||||
<ProgramListing>
|
||||
Oid lo_import(PGconn *conn, text *filename)
|
||||
</ProgramListing>
|
||||
The filename argument specifies the <Acronym>UNIX</Acronym> pathname of
|
||||
the file to be imported as a large object.
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Exporting a Large Object</Title>
|
||||
|
||||
<Para>
|
||||
To export a large object
|
||||
into <Acronym>UNIX</Acronym> file, call
|
||||
<ProgramListing>
|
||||
int lo_export(PGconn *conn, Oid lobjId, text *filename)
|
||||
</ProgramListing>
|
||||
The lobjId argument specifies the Oid of the large
|
||||
object to export and the filename argument specifies
|
||||
the <Acronym>UNIX</Acronym> pathname of the file.
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Opening an Existing Large Object</Title>
|
||||
|
||||
<Para>
|
||||
To open an existing large object, call
|
||||
<ProgramListing>
|
||||
int lo_open(PGconn *conn, Oid lobjId, int mode, ...)
|
||||
</ProgramListing>
|
||||
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.
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Writing Data to a Large Object</Title>
|
||||
|
||||
<Para>
|
||||
The routine
|
||||
<ProgramListing>
|
||||
int lo_write(PGconn *conn, int fd, char *buf, int len)
|
||||
</ProgramListing>
|
||||
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.
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Seeking on a Large Object</Title>
|
||||
|
||||
<Para>
|
||||
To change the current read or write location on a large
|
||||
object, call
|
||||
<ProgramListing>
|
||||
int lo_lseek(PGconn *conn, int fd, int offset, int whence)
|
||||
</ProgramListing>
|
||||
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.
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Closing a Large Object Descriptor</Title>
|
||||
|
||||
<Para>
|
||||
A large object may be closed by calling
|
||||
<ProgramListing>
|
||||
int lo_close(PGconn *conn, int fd)
|
||||
</ProgramListing>
|
||||
where fd is a large object descriptor returned by
|
||||
lo_open. On success, <Acronym>lo_close</Acronym> returns zero. On error,
|
||||
the return value is negative.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Built in registered functions</Title>
|
||||
|
||||
<Para>
|
||||
There are two built-in registered functions, <Acronym>lo_import</Acronym>
|
||||
and <Acronym>lo_export</Acronym> which are convenient for use in <Acronym>SQL</Acronym>
|
||||
queries.
|
||||
Here is an example of their use
|
||||
<ProgramListing>
|
||||
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';
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Accessing Large Objects from LIBPQ</Title>
|
||||
|
||||
<Para>
|
||||
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
|
||||
<FileName>
|
||||
../src/test/examples
|
||||
</FileName>
|
||||
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.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Sample Program</Title>
|
||||
|
||||
<Para>
|
||||
<ProgramListing>
|
||||
/*--------------------------------------------------------------
|
||||
*
|
||||
* testlo.c--
|
||||
* test using large objects with libpq
|
||||
*
|
||||
* Copyright (c) 1994, Regents of the University of California
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* /usr/local/devel/pglite/cvs/src/doc/manual.me,v 1.16 1995/09/01 23:55:00 jolly Exp
|
||||
*
|
||||
*--------------------------------------------------------------
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "libpq-fe.h"
|
||||
#include "libpq/libpq-fs.h"
|
||||
|
||||
#define BUFSIZE 1024
|
||||
|
||||
/*
|
||||
* importFile * import file "in_filename" into database as large object "lobjOid"
|
||||
*
|
||||
*/
|
||||
Oid importFile(PGconn *conn, char *filename)
|
||||
{
|
||||
Oid lobjId;
|
||||
int lobj_fd;
|
||||
char buf[BUFSIZE];
|
||||
int nbytes, tmp;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* open the file to be read in
|
||||
*/
|
||||
fd = open(filename, O_RDONLY, 0666);
|
||||
if (fd < 0) { /* error */
|
||||
fprintf(stderr, "can't open unix file
|
||||
}
|
||||
|
||||
/*
|
||||
* create the large object
|
||||
*/
|
||||
lobjId = lo_creat(conn, INV_READ|INV_WRITE);
|
||||
if (lobjId == 0) {
|
||||
fprintf(stderr, "can't create large object");
|
||||
}
|
||||
|
||||
lobj_fd = lo_open(conn, lobjId, INV_WRITE);
|
||||
/*
|
||||
* read in from the Unix file and write to the inversion file
|
||||
*/
|
||||
while ((nbytes = read(fd, buf, BUFSIZE)) > 0) {
|
||||
tmp = lo_write(conn, lobj_fd, buf, nbytes);
|
||||
if (tmp < nbytes) {
|
||||
fprintf(stderr, "error while reading
|
||||
}
|
||||
}
|
||||
|
||||
(void) close(fd);
|
||||
(void) lo_close(conn, lobj_fd);
|
||||
|
||||
return lobjId;
|
||||
}
|
||||
|
||||
void pickout(PGconn *conn, Oid lobjId, int start, int len)
|
||||
{
|
||||
int lobj_fd;
|
||||
char* buf;
|
||||
int nbytes;
|
||||
int nread;
|
||||
|
||||
lobj_fd = lo_open(conn, lobjId, INV_READ);
|
||||
if (lobj_fd < 0) {
|
||||
fprintf(stderr,"can't open large object %d",
|
||||
lobjId);
|
||||
}
|
||||
|
||||
lo_lseek(conn, lobj_fd, start, SEEK_SET);
|
||||
buf = malloc(len+1);
|
||||
|
||||
nread = 0;
|
||||
while (len - nread > 0) {
|
||||
nbytes = lo_read(conn, lobj_fd, buf, len - nread);
|
||||
buf[nbytes] = ' ';
|
||||
fprintf(stderr,">>> %s", buf);
|
||||
nread += nbytes;
|
||||
}
|
||||
fprintf(stderr,"0);
|
||||
lo_close(conn, lobj_fd);
|
||||
}
|
||||
|
||||
void overwrite(PGconn *conn, Oid lobjId, int start, int len)
|
||||
{
|
||||
int lobj_fd;
|
||||
char* buf;
|
||||
int nbytes;
|
||||
int nwritten;
|
||||
int i;
|
||||
|
||||
lobj_fd = lo_open(conn, lobjId, INV_READ);
|
||||
if (lobj_fd < 0) {
|
||||
fprintf(stderr,"can't open large object %d",
|
||||
lobjId);
|
||||
}
|
||||
|
||||
lo_lseek(conn, lobj_fd, start, SEEK_SET);
|
||||
buf = malloc(len+1);
|
||||
|
||||
for (i=0;i<len;i++)
|
||||
buf[i] = 'X';
|
||||
buf[i] = ' ';
|
||||
|
||||
nwritten = 0;
|
||||
while (len - nwritten > 0) {
|
||||
nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten);
|
||||
nwritten += nbytes;
|
||||
}
|
||||
fprintf(stderr,"0);
|
||||
lo_close(conn, lobj_fd);
|
||||
}
|
||||
|
||||
/*
|
||||
* exportFile * export large object "lobjOid" to file "out_filename"
|
||||
*
|
||||
*/
|
||||
void exportFile(PGconn *conn, Oid lobjId, char *filename)
|
||||
{
|
||||
int lobj_fd;
|
||||
char buf[BUFSIZE];
|
||||
int nbytes, tmp;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* create an inversion "object"
|
||||
*/
|
||||
lobj_fd = lo_open(conn, lobjId, INV_READ);
|
||||
if (lobj_fd < 0) {
|
||||
fprintf(stderr,"can't open large object %d",
|
||||
lobjId);
|
||||
}
|
||||
|
||||
/*
|
||||
* open the file to be written to
|
||||
*/
|
||||
fd = open(filename, O_CREAT|O_WRONLY, 0666);
|
||||
if (fd < 0) { /* error */
|
||||
fprintf(stderr, "can't open unix file
|
||||
filename);
|
||||
}
|
||||
|
||||
/*
|
||||
* read in from the Unix file and write to the inversion file
|
||||
*/
|
||||
while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) {
|
||||
tmp = write(fd, buf, nbytes);
|
||||
if (tmp < nbytes) {
|
||||
fprintf(stderr,"error while writing
|
||||
filename);
|
||||
}
|
||||
}
|
||||
|
||||
(void) lo_close(conn, lobj_fd);
|
||||
(void) close(fd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
exit_nicely(PGconn* conn)
|
||||
{
|
||||
PQfinish(conn);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *in_filename, *out_filename;
|
||||
char *database;
|
||||
Oid lobjOid;
|
||||
PGconn *conn;
|
||||
PGresult *res;
|
||||
|
||||
if (argc != 4) {
|
||||
fprintf(stderr, "Usage: %s database_name in_filename out_filename0,
|
||||
argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
database = argv[1];
|
||||
in_filename = argv[2];
|
||||
out_filename = argv[3];
|
||||
|
||||
/*
|
||||
* set up the connection
|
||||
*/
|
||||
conn = PQsetdb(NULL, NULL, NULL, NULL, database);
|
||||
|
||||
/* check to see that the backend connection was successfully made */
|
||||
if (PQstatus(conn) == CONNECTION_BAD) {
|
||||
fprintf(stderr,"Connection to database '%s' failed.0, database);
|
||||
fprintf(stderr,"%s",PQerrorMessage(conn));
|
||||
exit_nicely(conn);
|
||||
}
|
||||
|
||||
res = PQexec(conn, "begin");
|
||||
PQclear(res);
|
||||
|
||||
printf("importing file
|
||||
/* lobjOid = importFile(conn, in_filename); */
|
||||
lobjOid = lo_import(conn, in_filename);
|
||||
/*
|
||||
printf("as large object %d.0, lobjOid);
|
||||
|
||||
printf("picking out bytes 1000-2000 of the large object0);
|
||||
pickout(conn, lobjOid, 1000, 1000);
|
||||
|
||||
printf("overwriting bytes 1000-2000 of the large object with X's0);
|
||||
overwrite(conn, lobjOid, 1000, 1000);
|
||||
*/
|
||||
|
||||
printf("exporting large object to file
|
||||
/* exportFile(conn, lobjOid, out_filename); */
|
||||
lo_export(conn, lobjOid,out_filename);
|
||||
|
||||
res = PQexec(conn, "end");
|
||||
PQclear(res);
|
||||
PQfinish(conn);
|
||||
exit(0);
|
||||
}
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
</Chapter>
|
294
doc/src/sgml/manage.sgml
Normal file
294
doc/src/sgml/manage.sgml
Normal file
@ -0,0 +1,294 @@
|
||||
<Chapter>
|
||||
<Title>Managing a Database</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
This section is currently a thinly disguised copy of the Tutorial. Needs to be augmented.
|
||||
- thomas 1998-01-12
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Although the <FirstTerm>site administrator</FirstTerm> is responsible for overall management of the
|
||||
<ProductName>Postgres</ProductName> installation, some databases within the
|
||||
installation may be managed by another person, designated the <FirstTerm>database administrator</FirstTerm>.
|
||||
This assignment of responsibilities occurs when a database is created. A user may be assigned
|
||||
explicit privileges to create databases and/or to create new users. A user assigned both privileges
|
||||
can perform most administrative task within <ProductName>Postgres</ProductName>, but will
|
||||
not by default have the same operating system privileges as the site administrator.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The Database Administrator's Guide covers these topics in more detail.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Database Creation</Title>
|
||||
|
||||
<Para>
|
||||
Databases are created by the <Command>create database</Command> issued from
|
||||
within <ProductName>Postgres</ProductName>. <Application>createdb</Application> is a command-line
|
||||
utility provided to give the same functionality from outside <ProductName>Postgres</ProductName>.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The <ProductName>Postgres</ProductName> backend must be running for either method
|
||||
to succeed, and the user issuing the command must be the <ProductName>Postgres</ProductName>
|
||||
<FirstTerm>superuser</FirstTerm> or have been assigned database creation privileges by the
|
||||
superuser.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
To create a new database named <Quote>mydb</Quote> from the command line, type
|
||||
<ProgramListing>
|
||||
% createdb mydb
|
||||
</ProgramListing>
|
||||
|
||||
and to do the same from within <Application>psql</Application> type
|
||||
<ProgramListing>
|
||||
* CREATE DATABASE mydb;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If you do not have the privileges required to create a database, you will see
|
||||
the following:
|
||||
<ProgramListing>
|
||||
% createdb mydb
|
||||
WARN:user "your username" is not allowed to create/destroy databases
|
||||
createdb: database creation failed on mydb.
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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 32 characters in length.
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Alternate Database Locations</Title>
|
||||
|
||||
<Para>
|
||||
It is possible to create a database in a location other than the default
|
||||
location for the installation. Remember that all database access actually
|
||||
occurs through the database backend, so that any location specified must
|
||||
be accessible by the backend.
|
||||
|
||||
<Para>
|
||||
Either an absolute path name or an environment variable
|
||||
may be specified as a location.
|
||||
Any environment variable specifying an alternate location must have
|
||||
been defined before the backend was started.
|
||||
Consult with the site administrator
|
||||
regarding preconfigured alternate database locations.
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
The environment variable style of specification
|
||||
is to be preferred since it allows the site administrator more flexibility in
|
||||
managing disk storage.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
For security and integrity reasons,
|
||||
any path or environment variable specified has some
|
||||
additional path fields appended.
|
||||
|
||||
<Para>
|
||||
Alternate database locations must be prepared by running <Application>initlocation</Application>.
|
||||
|
||||
<Para>
|
||||
To create a data storage area in <FileName>/alt/postgres/data</FileName>, ensure
|
||||
that <FileName>/alt/postgres</FileName> already exists.
|
||||
From the command line, type
|
||||
<ProgramListing>
|
||||
% initlocation /alt/postgres/data
|
||||
Creating Postgres database system directory /alt/postgres/data
|
||||
|
||||
Creating Postgres database system directory /alt/postgres/data/base
|
||||
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
To do the same using an environment variable PGDATA2, type
|
||||
<ProgramListing>
|
||||
% initlocation $PGDATA2
|
||||
Creating Postgres database system directory /alt/postgres/data
|
||||
|
||||
Creating Postgres database system directory /alt/postgres/data/base
|
||||
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
To create a database in the alternate storage area <FileName>/alt/postgres/data</FileName>
|
||||
from the command line,
|
||||
type
|
||||
<ProgramListing>
|
||||
% createdb -D /alt/postgres/data mydb
|
||||
</ProgramListing>
|
||||
|
||||
or
|
||||
|
||||
<ProgramListing>
|
||||
% createdb -D PGDATA2 mydb
|
||||
</ProgramListing>
|
||||
|
||||
and to do the same from within <Application>psql</Application> type
|
||||
<ProgramListing>
|
||||
* CREATE DATABASE mydb WITH LOCATION = 'PGDATA2';
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If you do not have the privileges required to create a database, you will see
|
||||
the following:
|
||||
<ProgramListing>
|
||||
% createdb mydb
|
||||
WARN:user "your username" is not allowed to create/destroy databases
|
||||
createdb: database creation failed on mydb.
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If the specified location does not exist or the database backend does not have
|
||||
permission to access it or to write to directories under it, you will see
|
||||
the following:
|
||||
<ProgramListing>
|
||||
% createdb -D /alt/postgres/data mydb
|
||||
ERROR: Unable to create database directory /alt/postgres/data/base/mydb
|
||||
createdb: database creation failed on mydb.
|
||||
</ProgramListing>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Accessing a Database</Title>
|
||||
|
||||
<Para>
|
||||
Once you have constructed a database, you can access it
|
||||
by:
|
||||
|
||||
<ItemizedList Mark="bullet" Spacing="compact">
|
||||
<ListItem>
|
||||
<Para>
|
||||
running the <ProductName>Postgres</ProductName> terminal monitor programs (e.g.
|
||||
<Application>psql</Application>) which allows you to interactively
|
||||
enter, edit, and execute <Acronym>SQL</Acronym> commands.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
writing a C program using the LIBPQ subroutine
|
||||
library. This allows you to submit <Acronym>SQL</Acronym> commands
|
||||
from C and get answers and status messages back to
|
||||
your program. This interface is discussed further
|
||||
in section ??.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
You might want to start up <Application>psql</Application>, to try out the examples in this manual.
|
||||
It can be activated for the <Database>mydb</Database>
|
||||
database by typing the command:
|
||||
<ProgramListing>
|
||||
% psql mydb
|
||||
</ProgramListing>
|
||||
|
||||
You will be greeted with the following message:
|
||||
<ProgramListing>
|
||||
Welcome to the POSTGRESQL interactive sql monitor:
|
||||
Please read the file COPYRIGHT for copyright terms of POSTGRESQL
|
||||
|
||||
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: template1
|
||||
|
||||
mydb=>
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
This prompt indicates that the terminal monitor is listening
|
||||
to you and that you can type <Acronym>SQL</Acronym> queries into a
|
||||
workspace maintained by the terminal monitor.
|
||||
The <Application>psql</Application> program responds to escape codes that begin
|
||||
with the backslash character, <Quote>\</Quote> For example, you
|
||||
can get help on the syntax of various
|
||||
<ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> commands by typing:
|
||||
<ProgramListing>
|
||||
mydb=> \h
|
||||
</ProgramListing>
|
||||
|
||||
Once you have finished entering your queries into the
|
||||
workspace, you can pass the contents of the workspace
|
||||
to the <ProductName>Postgres</ProductName> server by typing:
|
||||
<ProgramListing>
|
||||
mydb=> \g
|
||||
</ProgramListing>
|
||||
|
||||
This tells the server to process the query. If you
|
||||
terminate your query with a semicolon, the <Quote>\g</Quote> is not
|
||||
necessary. <Application>psql</Application> will automatically process semicolon terminated queries.
|
||||
To read queries from a file, say myFile, instead of
|
||||
entering them interactively, type:
|
||||
<ProgramListing>
|
||||
mydb=> \i fileName
|
||||
</ProgramListing>
|
||||
|
||||
To get out of <Application>psql</Application> and return to UNIX, type
|
||||
<ProgramListing>
|
||||
mydb=> \q
|
||||
</ProgramListing>
|
||||
|
||||
and <Application>psql</Application> will quit and return you to your command
|
||||
shell. (For more escape codes, type <Command>\h</Command> at the monitor
|
||||
prompt.)
|
||||
White space (i.e., spaces, tabs and newlines) may be
|
||||
used freely in <Acronym>SQL</Acronym> queries. Single-line comments are denoted by
|
||||
<Quote>--</Quote>. Everything after the dashes up to the end of the
|
||||
line is ignored. Multiple-line comments, and comments within a line,
|
||||
are denoted by <Quote>/* ... */</Quote>
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title>Database Privileges</Title>
|
||||
|
||||
<Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Table Privileges</Title>
|
||||
|
||||
<Para>
|
||||
TBD
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Destroying a Database</Title>
|
||||
|
||||
<Para>
|
||||
If you are the database administrator for the database
|
||||
<Database>mydb</Database>, you can destroy it using the following UNIX command:
|
||||
<ProgramListing>
|
||||
% destroydb mydb
|
||||
</ProgramListing>
|
||||
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 forethought.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
</Chapter>
|
98
doc/src/sgml/odbc.sgml
Normal file
98
doc/src/sgml/odbc.sgml
Normal file
@ -0,0 +1,98 @@
|
||||
<Chapter>
|
||||
<DocInfo>
|
||||
<AuthorGroup>
|
||||
<Author>
|
||||
<FirstName>Tim</FirstName>
|
||||
<Surname>Goeke</Surname>
|
||||
</Author>
|
||||
</AuthorGroup>
|
||||
<Date>Transcribed 1998-02-12</Date>
|
||||
</DocInfo>
|
||||
|
||||
<Title>ODBC Interface</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
Contributed by <ULink url="mailto:tgoeke@xpressway.com">Tim Goeke</ULink>
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
ODBC is an abstract API which allows you to write standard "ODBC" code,
|
||||
using the ODBC API.
|
||||
|
||||
<Sect1>
|
||||
<Title>Background</Title>
|
||||
|
||||
<Para>
|
||||
The ODBC API matches up on the backend to an ODBC compatible data source.
|
||||
This could be anything from a text file to an Oracle RDBMS.
|
||||
|
||||
<Para>
|
||||
The backend access come from ODBC drivers, or vendor specifc drivers that
|
||||
allow data access. PostODBC is such a driver, along with others that are
|
||||
available, such as the OpenLink ODBC drivers.
|
||||
|
||||
<Para>
|
||||
Once you write an ODBC application, you SHOULD be able to connect to ANY
|
||||
back end database, regardless of the vendor, as long as the database schema
|
||||
is the same.
|
||||
|
||||
<Para>
|
||||
For example. you could have MS SQL Server and PostgreSQL servers which have
|
||||
exactly the same data. Using ODBC, your Windows app would make exactly the
|
||||
same calls and the back end data source would look the same (to the windows
|
||||
app).
|
||||
|
||||
<Para>
|
||||
In the real world, differences in drivers and the level of ODBC support
|
||||
lessens the potential of ODBC:
|
||||
|
||||
<SimpleList>
|
||||
<Member>
|
||||
Access, Delphi, and Visual Basic all support ODBC directly.
|
||||
|
||||
<Member>
|
||||
Under C++, such as Visual C++, you can use the C++ ODBC API.
|
||||
|
||||
<Member>
|
||||
In Visual C++, you can use the CRecordSet class, which wraps the ODBC API
|
||||
set within and MFC 4.2 class. This is the easiest route if you are doing
|
||||
Windows C++ development under Windows NT.
|
||||
</SimpleList>
|
||||
|
||||
<Para>
|
||||
If I write an app for PostgreSQL can I write it using ODBC calls
|
||||
to the PostgreSQL server, or is that only when another database program
|
||||
like MS SQL Server or Access needs to access the data?
|
||||
|
||||
<Para>
|
||||
Again, the ODBC API set is the way to go. You can find out more at
|
||||
Microsoft's web site or in your Visual C++ docs (if that's what you are
|
||||
using.)
|
||||
|
||||
<Para>
|
||||
Visual Basic and the other RAD tools have Recordset objects that use ODBC
|
||||
directly to access data. Using the data-aware controls, you can quickly
|
||||
link to the ODBC back end database (<Emphasis>very</Emphasis> quickly).
|
||||
|
||||
<Para>
|
||||
Playing around with MS Access will help you sort this out. Try using
|
||||
File->Get External Data
|
||||
|
||||
<Para>
|
||||
<Tip>
|
||||
<Para>
|
||||
You'll have to set up a DSN first.
|
||||
</Para>
|
||||
</Tip>
|
||||
|
||||
<Para>
|
||||
<Tip>
|
||||
<Para>
|
||||
The PostgreSQL datetime type will break MS Access.
|
||||
</Para>
|
||||
</Tip>
|
||||
|
||||
</Chapter>
|
8
doc/src/sgml/pgaccess.sgml
Normal file
8
doc/src/sgml/pgaccess.sgml
Normal file
@ -0,0 +1,8 @@
|
||||
<Chapter>
|
||||
<Title><Command>pgaccess</Command></Title>
|
||||
|
||||
<Para>
|
||||
This section needs to be written. Volunteers?
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
264
doc/src/sgml/ports.sgml
Normal file
264
doc/src/sgml/ports.sgml
Normal file
@ -0,0 +1,264 @@
|
||||
<Chapter>
|
||||
<Title>Ports</Title>
|
||||
|
||||
<Sect1>
|
||||
<Title>Currently Supported Platforms</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> is available free of charge. This manual
|
||||
describes version 6.3 of <ProductName>Postgres</ProductName>. The authors have
|
||||
compiled and tested <ProductName>Postgres</ProductName> on the following
|
||||
platforms:
|
||||
|
||||
<TABLE TOCENTRY="1">
|
||||
<TITLE>Supported Platforms</TITLE>
|
||||
<TGROUP COLS="4">
|
||||
<THEAD>
|
||||
<ROW>
|
||||
<ENTRY><Acronym>OS</Acronym></ENTRY>
|
||||
<ENTRY>Processor</ENTRY>
|
||||
<ENTRY>Version</ENTRY>
|
||||
<ENTRY>Reported</ENTRY>
|
||||
<ENTRY>Remarks</ENTRY>
|
||||
</ROW>
|
||||
</THEAD>
|
||||
<TBODY>
|
||||
<ROW>
|
||||
<ENTRY>AIX 4.1.x-4.2</ENTRY>
|
||||
<ENTRY>RS6000</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>4.1.4.0,4.2 (<ULink url="mailto:darrenk@insightdist.com">Darren King</ULink>),
|
||||
4.1.5 (<ULink url="mailto:Andreas.Zeugswetter@telecom.at">Andreas Zeugswetter</ULink>);
|
||||
3.2.5 confirmed on v6.2.1 (<ULink url="mailto:danaf@ans.net">Frank Dana</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>BSDi</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:maillist@candle.pha.pa.us">Bruce Momjian</ULink></ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>FreeBSD 2.2.x-3.x</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:t-ishii@sra.co.jp">Tatsuo Ishii</ULink>,
|
||||
<ULink url="mailto:scrappy@hub.org">Marc Fournier</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>NetBSD 1.3</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:brook@trillium.NMSU.Edu">Brook Milligan</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>NetBSD 1.3</ENTRY>
|
||||
<ENTRY>Sparc</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:tih@hamartun.priv.no">Tom I Helbekkmo</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>NetBSD 1.3</ENTRY>
|
||||
<ENTRY>VAX</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:tih@hamartun.priv.no">Tom I Helbekkmo</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>DGUX 5.4R4.11</ENTRY>
|
||||
<ENTRY>m88k</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:geek+@cmu.edu">Brian E Gallew</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>HPUX 10.20</ENTRY>
|
||||
<ENTRY>PA-RISC</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>9.0.x confirmed on v6.2.1 (<ULink url="mailto:stanb@awod.com">Stan Brown</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>IRIX 6.x</ENTRY>
|
||||
<ENTRY>MIPS</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>5.x is different (<ULink url="mailto:martin@biochemistry.ucl.ac.uk">Andrew Martin</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>Digital 4.0</ENTRY>
|
||||
<ENTRY>Alpha</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>in progress; v6.2.1 confirmed working (<ULink url="mailto:pjlobo@euitt.upm.es">Pedro J. Lobo</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>linux 2.0.x</ENTRY>
|
||||
<ENTRY>Alpha</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>partial success (<ULink url="mailto:rkirkpat@nag.cs.colorado.edu">Ryan Kirkpatrick</ULink>,
|
||||
<ULink url="mailto:jsturm@zenacomp.com"> Jeff Sturm </ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>linux 2.0.x</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:lockhart@alumni.caltech.edu">Thomas Lockhart</ULink>,
|
||||
<ULink url="mailto:t-ishii@sra.co.jp">Tatsuo Ishii</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>linux 2.0.x</ENTRY>
|
||||
<ENTRY>Sparc</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:szybist@boxhill.com">Tom Szybist</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>mklinux</ENTRY>
|
||||
<ENTRY>PPC</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:t-ishii@sra.co.jp">Tatsuo Ishii</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>SCO</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>partial success (<ULink url="mailto:Bill.Allie@mug.org">Billy G. Allie</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>Solaris</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:scrappy@hub.org">Marc Fournier</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>Solaris 2.5.1-2.6</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>(<ULink url="mailto:scrappy@hub.org">Marc Fournier</ULink>,
|
||||
<ULink url="mailto:t-ishii@sra.co.jp">Tatsuo Ishii</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>SunOS 4.1.4</ENTRY>
|
||||
<ENTRY>Sparc</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>patches submitted (<ULink url="mailto:t-ishii@sra.co.jp">Tatsuo Ishii</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>SVR4</ENTRY>
|
||||
<ENTRY>MIPS</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>similar to v6.2.1; "mostly working" (<ULink url="mailto:ridderbusch.pad@sni.de">Frank Ridderbusch</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>SVR4 4.4</ENTRY>
|
||||
<ENTRY>m88k</ENTRY>
|
||||
<ENTRY>v6.2.1</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>confirmed with patching (<ULink url="mailto:dlw@seavme.xroads.com">Doug Winterburn</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>Unixware</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>aka UNIVEL (<ULink url="mailto:Bill.Allie@mug.org">Billy G. Allie</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>NextStep</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.x</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>client-only support; v1.0.9 worked with patches (<ULink url="mailto:dave@turbocat.de">David Wetzel</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
</TBODY>
|
||||
</TGROUP>
|
||||
</TABLE>
|
||||
|
||||
<Sect1>
|
||||
<Title>Unsupported Platforms</Title>
|
||||
|
||||
<Para>
|
||||
A few platforms which have been attempted and which have been
|
||||
reported to not work with the standard distribution.
|
||||
Others listed here do not provide sufficient library support for an attempt.
|
||||
|
||||
<TABLE TOCENTRY="1">
|
||||
<TITLE>Possibly Incompatible Platforms</TITLE>
|
||||
<TITLEABBREV>Incompatibles</TITLEABBREV>
|
||||
<TGROUP COLS="4">
|
||||
<THEAD>
|
||||
<ROW>
|
||||
<ENTRY><Acronym>OS</Acronym></ENTRY>
|
||||
<ENTRY>Processor</ENTRY>
|
||||
<ENTRY>Version</ENTRY>
|
||||
<ENTRY>Reported</ENTRY>
|
||||
<ENTRY>Remarks</ENTRY>
|
||||
</ROW>
|
||||
</THEAD>
|
||||
<TBODY>
|
||||
<ROW>
|
||||
<ENTRY>MacOS</ENTRY>
|
||||
<ENTRY>all</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>not library compatible; use ODBC/JDBC</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>NetBSD</ENTRY>
|
||||
<ENTRY>arm32</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>not yet working (<ULink url="mailto:dmill@globalnet.co.uk">Dave Millen</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>NetBSD</ENTRY>
|
||||
<ENTRY>m68k</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>Amiga, HP300, Mac; not yet working (<ULink url="mailto:hotz@jpl.nasa.gov">Henry Hotz</ULink>)</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>Ultrix</ENTRY>
|
||||
<ENTRY>MIPS,VAX?</ENTRY>
|
||||
<ENTRY>v6.x</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>no recent reports; obsolete?</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>Windows NT</ENTRY>
|
||||
<ENTRY>all</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>not library compatible; client side maybe; use ODBC/JDBC</ENTRY>
|
||||
</ROW>
|
||||
<ROW>
|
||||
<ENTRY>Windows</ENTRY>
|
||||
<ENTRY>x86</ENTRY>
|
||||
<ENTRY>v6.3</ENTRY>
|
||||
<ENTRY>1998-03-01</ENTRY>
|
||||
<ENTRY>not library compatible; client side maybe; use ODBC/JDBC</ENTRY>
|
||||
</ROW>
|
||||
</TBODY>
|
||||
</TGROUP>
|
||||
</TABLE>
|
||||
|
||||
<Para>
|
||||
Note that Windows ports of the frontend are apparently possible
|
||||
using third-party Posix porting tools and libraries.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
</Chapter>
|
244
doc/src/sgml/postgres.sgml
Normal file
244
doc/src/sgml/postgres.sgml
Normal file
@ -0,0 +1,244 @@
|
||||
<!-- postgres.sgml
|
||||
-
|
||||
- Postgres integrated documentation.
|
||||
- Other subset docs should be copied and shrunk from here.
|
||||
- thomas 1998-02-23
|
||||
-
|
||||
- -->
|
||||
<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
|
||||
<!entity intro SYSTEM "intro.sgml">
|
||||
<!entity arch SYSTEM "arch.sgml">
|
||||
<!entity start SYSTEM "start.sgml">
|
||||
<!entity query SYSTEM "query.sgml">
|
||||
|
||||
<!entity advanced SYSTEM "advanced.sgml">
|
||||
<!entity environ SYSTEM "environ.sgml">
|
||||
<!entity manage SYSTEM "manage.sgml">
|
||||
<!entity datatype SYSTEM "datatype.sgml">
|
||||
<!entity array SYSTEM "array.sgml">
|
||||
<!entity inherit SYSTEM "inherit.sgml">
|
||||
<!entity query-ug SYSTEM "query-ug.sgml">
|
||||
<!entity storage SYSTEM "storage.sgml">
|
||||
<!entity psql SYSTEM "psql.sgml">
|
||||
<!entity pgaccess SYSTEM "pgaccess.sgml">
|
||||
|
||||
<!entity start-ag SYSTEM "start-ag.sgml">
|
||||
<!entity install SYSTEM "install.sgml">
|
||||
<!entity recovery SYSTEM "recovery.sgml">
|
||||
<!entity regress SYSTEM "regress.sgml">
|
||||
<!entity ports SYSTEM "ports.sgml">
|
||||
<!entity release SYSTEM "release.sgml">
|
||||
|
||||
<!entity intro-pg SYSTEM "intro-pg.sgml">
|
||||
<!entity arch-pg SYSTEM "arch-pg.sgml">
|
||||
<!entity extend SYSTEM "extend.sgml">
|
||||
<!entity rules SYSTEM "rules.sgml">
|
||||
<!entity xfunc SYSTEM "xfunc.sgml">
|
||||
<!entity xtypes SYSTEM "xtypes.sgml">
|
||||
<!entity xoper SYSTEM "xoper.sgml">
|
||||
<!entity xaggr SYSTEM "xaggr.sgml">
|
||||
<!entity xindex SYSTEM "xindex.sgml">
|
||||
<!entity gist SYSTEM "gist.sgml">
|
||||
<!entity dfunc SYSTEM "dfunc.sgml">
|
||||
<!entity lobj SYSTEM "lobj.sgml">
|
||||
<!entity trigger SYSTEM "trigger.sgml">
|
||||
<!entity spi SYSTEM "spi.sgml">
|
||||
<!entity func-ref SYSTEM "func-ref.sgml">
|
||||
<!entity libpq SYSTEM "libpq.sgml">
|
||||
<!entity libpgtcl SYSTEM "libpgtcl.sgml">
|
||||
<!entity ecpg SYSTEM "ecpg.sgml">
|
||||
<!entity odbc SYSTEM "odbc.sgml">
|
||||
<!entity jdbc SYSTEM "jdbc.sgml">
|
||||
|
||||
<!entity arch-dev SYSTEM "arch-dev.sgml">
|
||||
<!entity geqo SYSTEM "geqo.sgml">
|
||||
<!entity protocol SYSTEM "protocol.sgml">
|
||||
<!entity compiler SYSTEM "compiler.sgml">
|
||||
<!entity docguide SYSTEM "docguide.sgml">
|
||||
<!entity biblio SYSTEM "biblio.sgml">
|
||||
<!entity contacts SYSTEM "contacts.sgml">
|
||||
]>
|
||||
<!-- entity manpages SYSTEM "man/manpages.sgml" subdoc -->
|
||||
<Book>
|
||||
|
||||
<!-- Title information -->
|
||||
|
||||
<Title>PostgreSQL</Title>
|
||||
<BookInfo>
|
||||
<ReleaseInfo>Covering v6.3 for general release</ReleaseInfo>
|
||||
<BookBiblio>
|
||||
<AuthorGroup>
|
||||
<CorpAuthor>The PostgreSQL Development Team</CorpAuthor>
|
||||
</AuthorGroup>
|
||||
<!-- editor in authorgroup is not supported
|
||||
<AuthorGroup>
|
||||
-->
|
||||
<Editor>
|
||||
<FirstName>Thomas</FirstName>
|
||||
<SurName>Lockhart</SurName>
|
||||
<Affiliation>
|
||||
<OrgName>Caltech/JPL</OrgName>
|
||||
</Affiliation>
|
||||
</Editor>
|
||||
<!--
|
||||
</AuthorGroup>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<AuthorInitials>TGL</AuthorInitials>
|
||||
-->
|
||||
|
||||
<Date>(last updated 1998-02-23)</Date>
|
||||
</BookBiblio>
|
||||
|
||||
<LegalNotice>
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> is copyright (C) 1998 by the Postgres Global Development Group.
|
||||
</Para>
|
||||
</LegalNotice>
|
||||
|
||||
</BookInfo>
|
||||
|
||||
<!--
|
||||
<TOC> </TOC>
|
||||
<LOT> </LOT>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<Dedication>
|
||||
<Para>
|
||||
Your name here...
|
||||
</Para>
|
||||
</Dedication>
|
||||
-->
|
||||
|
||||
<Preface>
|
||||
<Title>Summary</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName>,
|
||||
developed originally in the UC Berkeley Computer Science Department,
|
||||
pioneered many of the object-relational concepts
|
||||
now becoming available in some commercial databases.
|
||||
It provides SQL92/SQL3 language support,
|
||||
transaction integrity, and type extensibility.
|
||||
<ProductName>PostgreSQL</ProductName> is a public-domain, open source descendant
|
||||
of this original Berkeley code.
|
||||
</Para>
|
||||
</Preface>
|
||||
|
||||
<Part>
|
||||
<Title>Tutorial</Title>
|
||||
<PartIntro>
|
||||
<Para>
|
||||
Introduction for new users.
|
||||
</Para>
|
||||
</PartIntro>
|
||||
&intro;
|
||||
&arch;
|
||||
&start;
|
||||
&query;
|
||||
&advanced;
|
||||
</Part>
|
||||
|
||||
<Part>
|
||||
<Title>User's Guide</Title>
|
||||
<PartIntro>
|
||||
<Para>
|
||||
Information for users.
|
||||
</Para>
|
||||
</PartIntro>
|
||||
&environ;
|
||||
&manage;
|
||||
&datatype;
|
||||
&array;
|
||||
&inherit;
|
||||
&query-ug;
|
||||
&storage;
|
||||
&psql;
|
||||
&pgaccess;
|
||||
</Part>
|
||||
|
||||
<Part>
|
||||
<Title>Administrator's Guide</Title>
|
||||
<PartIntro>
|
||||
<Para>
|
||||
Installation and maintenance information.
|
||||
</Para>
|
||||
</PartIntro>
|
||||
&ports;
|
||||
&install;
|
||||
&start-ag;
|
||||
&recovery;
|
||||
®ress;
|
||||
&release;
|
||||
</Part>
|
||||
|
||||
<Part>
|
||||
<Title>Programmer's Guide</Title>
|
||||
<PartIntro>
|
||||
<Para>
|
||||
Information for extending <ProductName>Postgres</ProductName>.
|
||||
</Para>
|
||||
</PartIntro>
|
||||
&intro-pg;
|
||||
&arch-pg;
|
||||
&extend;
|
||||
&xfunc;
|
||||
&xtypes;
|
||||
&xoper;
|
||||
&xaggr;
|
||||
&xindex;
|
||||
&gist;
|
||||
&dfunc;
|
||||
&trigger;
|
||||
&spi;
|
||||
&libpq;
|
||||
</Part>
|
||||
|
||||
<Part>
|
||||
<Title>Reference</Title>
|
||||
<PartIntro>
|
||||
<Para>
|
||||
User and programmer interfaces.
|
||||
</Para>
|
||||
</PartIntro>
|
||||
&func-ref;
|
||||
&lobj;
|
||||
&ecpg;
|
||||
&libpq;
|
||||
&libpgtcl;
|
||||
&odbc;
|
||||
&jdbc;
|
||||
</Part>
|
||||
|
||||
<Part>
|
||||
<Title>Developer's Guide</Title>
|
||||
<PartIntro>
|
||||
<Para>
|
||||
The Developer's Guide includes discussion of design decisions and suggestions for
|
||||
future development.
|
||||
</Para>
|
||||
</PartIntro>
|
||||
&arch-dev;
|
||||
&geqo;
|
||||
&protocol;
|
||||
&compiler;
|
||||
</Part>
|
||||
|
||||
<Part>
|
||||
<Title>Appendices</Title>
|
||||
<PartIntro>
|
||||
<Para>
|
||||
Additional related information.
|
||||
</Para>
|
||||
</PartIntro>
|
||||
&docguide;
|
||||
&contacts;
|
||||
&biblio;
|
||||
</Part>
|
||||
|
||||
<INDEX> </INDEX>
|
||||
|
||||
</Book>
|
||||
|
173
doc/src/sgml/programmer.sgml
Normal file
173
doc/src/sgml/programmer.sgml
Normal file
@ -0,0 +1,173 @@
|
||||
<!-- programmer.sgml
|
||||
-
|
||||
- Postgres programmer's guide.
|
||||
- Derived from postgres.sgml.
|
||||
- thomas 1998-02-24
|
||||
-
|
||||
- -->
|
||||
<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
|
||||
<!entity intro SYSTEM "intro.sgml">
|
||||
<!entity arch SYSTEM "arch.sgml">
|
||||
<!entity start SYSTEM "start.sgml">
|
||||
<!entity query SYSTEM "query.sgml">
|
||||
|
||||
<!entity advanced SYSTEM "advanced.sgml">
|
||||
<!entity environ SYSTEM "environ.sgml">
|
||||
<!entity manage SYSTEM "manage.sgml">
|
||||
<!entity datatype SYSTEM "datatype.sgml">
|
||||
<!entity array SYSTEM "array.sgml">
|
||||
<!entity inherit SYSTEM "inherit.sgml">
|
||||
<!entity query-ug SYSTEM "query-ug.sgml">
|
||||
<!entity storage SYSTEM "storage.sgml">
|
||||
<!entity psql SYSTEM "psql.sgml">
|
||||
<!entity pgaccess SYSTEM "pgaccess.sgml">
|
||||
|
||||
<!entity start-ag SYSTEM "start-ag.sgml">
|
||||
<!entity install SYSTEM "install.sgml">
|
||||
<!entity recovery SYSTEM "recovery.sgml">
|
||||
<!entity regress SYSTEM "regress.sgml">
|
||||
<!entity ports SYSTEM "ports.sgml">
|
||||
<!entity release SYSTEM "release.sgml">
|
||||
|
||||
<!entity intro-pg SYSTEM "intro-pg.sgml">
|
||||
<!entity arch-pg SYSTEM "arch-pg.sgml">
|
||||
<!entity extend SYSTEM "extend.sgml">
|
||||
<!entity rules SYSTEM "rules.sgml">
|
||||
<!entity xfunc SYSTEM "xfunc.sgml">
|
||||
<!entity xtypes SYSTEM "xtypes.sgml">
|
||||
<!entity xoper SYSTEM "xoper.sgml">
|
||||
<!entity xaggr SYSTEM "xaggr.sgml">
|
||||
<!entity xindex SYSTEM "xindex.sgml">
|
||||
<!entity gist SYSTEM "gist.sgml">
|
||||
<!entity dfunc SYSTEM "dfunc.sgml">
|
||||
<!entity lobj SYSTEM "lobj.sgml">
|
||||
<!entity trigger SYSTEM "trigger.sgml">
|
||||
<!entity spi SYSTEM "spi.sgml">
|
||||
<!entity func-ref SYSTEM "func-ref.sgml">
|
||||
<!entity libpq SYSTEM "libpq.sgml">
|
||||
<!entity libpgtcl SYSTEM "libpgtcl.sgml">
|
||||
<!entity ecpg SYSTEM "ecpg.sgml">
|
||||
<!entity odbc SYSTEM "odbc.sgml">
|
||||
<!entity jdbc SYSTEM "jdbc.sgml">
|
||||
|
||||
<!entity arch-dev SYSTEM "arch-dev.sgml">
|
||||
<!entity geqo SYSTEM "geqo.sgml">
|
||||
<!entity protocol SYSTEM "protocol.sgml">
|
||||
<!entity compiler SYSTEM "compiler.sgml">
|
||||
<!entity docguide SYSTEM "docguide.sgml">
|
||||
<!entity biblio SYSTEM "biblio.sgml">
|
||||
<!entity contacts SYSTEM "contacts.sgml">
|
||||
]>
|
||||
<!-- entity manpages SYSTEM "man/manpages.sgml" subdoc -->
|
||||
<Book>
|
||||
|
||||
<!-- Title information -->
|
||||
|
||||
<Title>PostgreSQL Programmer's Guide</Title>
|
||||
<BookInfo>
|
||||
<ReleaseInfo>Covering v6.3 for general release</ReleaseInfo>
|
||||
<BookBiblio>
|
||||
<AuthorGroup>
|
||||
<CorpAuthor>The PostgreSQL Development Team</CorpAuthor>
|
||||
</AuthorGroup>
|
||||
<!-- editor in authorgroup is not supported
|
||||
<AuthorGroup>
|
||||
-->
|
||||
<Editor>
|
||||
<FirstName>Thomas</FirstName>
|
||||
<SurName>Lockhart</SurName>
|
||||
<Affiliation>
|
||||
<OrgName>Caltech/JPL</OrgName>
|
||||
</Affiliation>
|
||||
</Editor>
|
||||
<!--
|
||||
</AuthorGroup>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<AuthorInitials>TGL</AuthorInitials>
|
||||
-->
|
||||
|
||||
<Date>(last updated 1998-02-24)</Date>
|
||||
</BookBiblio>
|
||||
|
||||
<LegalNotice>
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> is copyright (C) 1998 by the Postgres Global Development Group.
|
||||
</Para>
|
||||
</LegalNotice>
|
||||
|
||||
</BookInfo>
|
||||
|
||||
<!--
|
||||
<TOC> </TOC>
|
||||
<LOT> </LOT>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<Dedication>
|
||||
<Para>
|
||||
Your name here...
|
||||
</Para>
|
||||
</Dedication>
|
||||
-->
|
||||
|
||||
<Preface>
|
||||
<Title>Summary</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName>,
|
||||
developed originally in the UC Berkeley Computer Science Department,
|
||||
pioneered many of the object-relational concepts
|
||||
now becoming available in some commercial databases.
|
||||
It provides SQL92/SQL3 language support,
|
||||
transaction integrity, and type extensibility.
|
||||
<ProductName>PostgreSQL</ProductName> is a public-domain, open source descendant
|
||||
of this original Berkeley code.
|
||||
</Para>
|
||||
</Preface>
|
||||
|
||||
&intro-pg;
|
||||
&arch-pg;
|
||||
&extend;
|
||||
&xfunc;
|
||||
&xtypes;
|
||||
&xoper;
|
||||
&xaggr;
|
||||
&xindex;
|
||||
&gist;
|
||||
&dfunc;
|
||||
&trigger;
|
||||
&spi;
|
||||
|
||||
<!-- reference -->
|
||||
|
||||
&func-ref;
|
||||
&lobj;
|
||||
&ecpg;
|
||||
&libpq;
|
||||
&libpgtcl;
|
||||
&odbc;
|
||||
&jdbc;
|
||||
|
||||
<!-- development -->
|
||||
|
||||
&arch-dev;
|
||||
&geqo;
|
||||
&protocol;
|
||||
&compiler;
|
||||
|
||||
<!-- appendices -->
|
||||
|
||||
&docguide;
|
||||
<!--
|
||||
&contacts;
|
||||
-->
|
||||
&biblio;
|
||||
|
||||
<!--
|
||||
<INDEX> </INDEX>
|
||||
-->
|
||||
|
||||
</Book>
|
||||
|
1509
doc/src/sgml/protocol.sgml
Normal file
1509
doc/src/sgml/protocol.sgml
Normal file
File diff suppressed because it is too large
Load Diff
8
doc/src/sgml/psql.sgml
Normal file
8
doc/src/sgml/psql.sgml
Normal file
@ -0,0 +1,8 @@
|
||||
<Chapter>
|
||||
<Title><Command>psql</Command></Title>
|
||||
|
||||
<Para>
|
||||
This section needs to be written. Volunteers?
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
332
doc/src/sgml/query-ug.sgml
Normal file
332
doc/src/sgml/query-ug.sgml
Normal file
@ -0,0 +1,332 @@
|
||||
<Chapter>
|
||||
<TITLE>The Query Language</TITLE>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
This chapter must go into depth on each area of the query language. Currently a copy of the tutorial.
|
||||
- thomas 1998-01-12
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The <ProductName>Postgres</ProductName> query language is a variant of
|
||||
<Acronym>SQL3</Acronym>. It
|
||||
has many extensions such as an extensible type system,
|
||||
inheritance, functions and production rules. Those are
|
||||
features carried over from the original <ProductName>Postgres</ProductName> query
|
||||
language, <ProductName>PostQuel</ProductName>. This section provides an overview
|
||||
of how to use <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> to perform simple operations.
|
||||
This manual is only intended to give you an idea of our
|
||||
flavor of <Acronym>SQL</Acronym> and is in no way a complete tutorial on
|
||||
<Acronym>SQL</Acronym>. Numerous books have been written on <Acronym>SQL</Acronym>. For
|
||||
instance, consult <Ulink url="refs.html#MELT93">[MELT93]</ULink> or
|
||||
<Ulink url="refs.html#DATE93">[DATE93]</ULink>. You should also
|
||||
be aware that some features are not part of the <Acronym>ANSI</Acronym>
|
||||
standard.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Concepts</Title>
|
||||
|
||||
<Para>
|
||||
The fundamental notion in <ProductName>Postgres</ProductName> 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 <FirstTerm>object identifier</FirstTerm> (<Acronym>OID</Acronym>)
|
||||
that is unique throughout the installation. Because
|
||||
<Acronym>SQL</Acronym> syntax refers to tables, we will use the terms
|
||||
<FirstTerm>table</FirstTerm> and <FirstTerm>class</FirstTerm> interchangeably.
|
||||
Likewise, an <Acronym>SQL</Acronym> <FirstTerm>row</FirstTerm> is an
|
||||
<FirstTerm>instance</FirstTerm> and <Acronym>SQL</Acronym> <FirstTerm>columns</FirstTerm>
|
||||
are <FirstTerm>attributes</FirstTerm>.
|
||||
As previously discussed, classes are grouped into
|
||||
databases, and a collection of databases managed by a
|
||||
single <FileName>postmaster</FileName> process constitutes an installation
|
||||
or site.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Creating a New Class</Title>
|
||||
|
||||
<Para>
|
||||
You can create a new class by specifying the class
|
||||
name, along with all attribute names and their types:
|
||||
|
||||
<ProgramListing>
|
||||
CREATE TABLE weather (
|
||||
city varchar(80),
|
||||
temp_lo int, -- low temperature
|
||||
temp_hi int, -- high temperature
|
||||
prcp real, -- precipitation
|
||||
date date
|
||||
);
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
Note that keywords are case-insensitive and identifiers
|
||||
are usually case-insensitive.
|
||||
<Acronym>Postgres</Acronym> allows <Acronym>SQL92</Acronym> <FirstTerm>delimited identifiers</FirstTerm>
|
||||
(identifiers surrounded by double-quotes) to include mixed-case and spaces, tabs, etc.
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> supports the usual
|
||||
<Acronym>SQL</Acronym> types <Type>int</Type>,
|
||||
<Type>float</Type>, <Type>real</Type>, <Type>smallint</Type>, <Type>char(N)</Type>,
|
||||
<Type>varchar(N)</Type>, <Type>date</Type>, <Type>time</Type>,
|
||||
and <Type>timestamp</Type>, as well as other types of general utility and
|
||||
a rich set of geometric types. As we will
|
||||
see later, <ProductName>Postgres</ProductName> can be customized with an
|
||||
arbitrary number of
|
||||
user-defined data types. Consequently, type names are
|
||||
not syntactical keywords, except where required to support special cases in the <Acronym>SQL92</Acronym> standard.
|
||||
So far, the <ProductName>Postgres</ProductName> 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.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Populating a Class with Instances</Title>
|
||||
|
||||
<Para>
|
||||
The <Command>insert</Command> statement is used to populate a class with
|
||||
instances:
|
||||
|
||||
<ProgramListing>
|
||||
INSERT INTO weather
|
||||
VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
You can also use the <Command>copy</Command> command to perform load large
|
||||
amounts of data from flat (<Acronym>ASCII</Acronym>) files.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Querying a Class</Title>
|
||||
|
||||
<Para>
|
||||
The weather class can be queried with normal relational
|
||||
selection and projection queries. A <Acronym>SQL</Acronym> <Command>select</Command>
|
||||
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:
|
||||
<ProgramListing>
|
||||
SELECT * FROM WEATHER;
|
||||
</ProgramListing>
|
||||
|
||||
and the output should be:
|
||||
<ProgramListing>
|
||||
+--------------+---------+---------+------+------------+
|
||||
|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 |
|
||||
+--------------+---------+---------+------+------------+
|
||||
</ProgramListing>
|
||||
You may specify any arbitrary expressions in the target list. For example, you can do:
|
||||
<ProgramListing>
|
||||
SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
Arbitrary Boolean operators
|
||||
(<Command>and</Command>, <Command>or</Command> and <Command>not</Command>) are
|
||||
allowed in the qualification of any query. For example,
|
||||
|
||||
<ProgramListing>
|
||||
SELECT * FROM weather
|
||||
WHERE city = 'San Francisco'
|
||||
AND prcp > 0.0;
|
||||
|
||||
+--------------+---------+---------+------+------------+
|
||||
|city | temp_lo | temp_hi | prcp | date |
|
||||
+--------------+---------+---------+------+------------+
|
||||
|San Francisco | 46 | 50 | 0.25 | 11-27-1994 |
|
||||
+--------------+---------+---------+------+------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
As a final note, you can specify that the results of a
|
||||
select can be returned in a <FirstTerm>sorted order</FirstTerm>
|
||||
or with <FirstTerm>duplicate instances</FirstTerm> removed.
|
||||
|
||||
<ProgramListing>
|
||||
SELECT DISTINCT city
|
||||
FROM weather
|
||||
ORDER BY city;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Redirecting SELECT Queries</Title>
|
||||
|
||||
<Para>
|
||||
Any select query can be redirected to a new class
|
||||
<ProgramListing>
|
||||
SELECT * INTO TABLE temp FROM weather;
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
This forms an implicit <Command>create</Command> command, creating a new
|
||||
class temp with the attribute names and types specified
|
||||
in the target list of the <Command>select into</Command> command. We can
|
||||
then, of course, perform any operations on the resulting
|
||||
class that we can perform on other classes.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Joins Between Classes</Title>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
<Note>
|
||||
<Para>
|
||||
This is only a conceptual model. The actual join may
|
||||
be performed in a more efficient manner, but this is invisible to the user.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
We can do this with the following query:
|
||||
|
||||
<ProgramListing>
|
||||
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 < W2.temp_lo
|
||||
AND W1.temp_hi > 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 |
|
||||
+--------------+---------+---------+---------------+---------+---------+
|
||||
</ProgramListing>
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
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,
|
||||
<ProductName>Postgres</ProductName> computes and returns the values specified in the
|
||||
target list. <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> does not assign any meaning to
|
||||
duplicate values in such expressions. This means that <ProductName>Postgres</ProductName>
|
||||
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 <Command>select distinct</Command> statement.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
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 <FirstTerm>range variables</FirstTerm>.)
|
||||
A query can contain an arbitrary number of
|
||||
class names and surrogates.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Updates</Title>
|
||||
|
||||
<Para>
|
||||
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:
|
||||
|
||||
<ProgramListing>
|
||||
UPDATE weather
|
||||
SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
|
||||
WHERE date > '11/28/1994';
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Deletions</Title>
|
||||
|
||||
<Para>
|
||||
Deletions are performed using the <Command>delete</Command> command:
|
||||
<ProgramListing>
|
||||
DELETE FROM weather WHERE city = 'Hayward';
|
||||
</ProgramListing>
|
||||
|
||||
All weather recording belongs to Hayward is removed.
|
||||
One should be wary of queries of the form
|
||||
<ProgramListing>
|
||||
DELETE FROM classname;
|
||||
</ProgramListing>
|
||||
|
||||
Without a qualification, <Command>delete</Command> will simply
|
||||
remove all instances of the given class, leaving it
|
||||
empty. The system will not request confirmation before
|
||||
doing this.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Using Aggregate Functions</Title>
|
||||
|
||||
<Para>
|
||||
Like most other query languages, <ProductName>PostgreSQL</ProductName> supports
|
||||
aggregate functions.
|
||||
The current implementation of <ProductName>Postgres</ProductName> aggregate functions have some limitations.
|
||||
Specifically, while there are aggregates to compute
|
||||
such functions as the <Function>count</Function>, <Function>sum</Function>,
|
||||
<Function>avg</Function> (average), <Function>max</Function> (maximum) and
|
||||
<Function>min</Function> (minimum) over a set of instances, aggregates can only
|
||||
appear in the target list of a query and not directly in the
|
||||
qualification (the <FirstTerm>where</FirstTerm> clause). As an example,
|
||||
|
||||
<ProgramListing>
|
||||
SELECT max(temp_lo) FROM weather;
|
||||
</ProgramListing>
|
||||
|
||||
is allowed, while
|
||||
|
||||
<ProgramListing>
|
||||
SELECT city FROM weather WHERE temp_lo = max(temp_lo);
|
||||
</ProgramListing>
|
||||
|
||||
is not. However, as is often the case the query can be restated to accomplish
|
||||
the intended result; here by using a <FirstTerm>subselect</FirstTerm>:
|
||||
<ProgramListing>
|
||||
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Aggregates may also have <FirstTerm>group by</FirstTerm> clauses:
|
||||
<ProgramListing>
|
||||
SELECT city, max(temp_lo)
|
||||
FROM weather
|
||||
GROUP BY city;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
362
doc/src/sgml/query.sgml
Normal file
362
doc/src/sgml/query.sgml
Normal file
@ -0,0 +1,362 @@
|
||||
<Chapter ID="QUERY">
|
||||
<TITLE>The Query Language</TITLE>
|
||||
|
||||
<Para>
|
||||
The <ProductName>Postgres</ProductName> query language is a variant of
|
||||
the <Acronym>SQL3</Acronym> draft next-generation standard. It
|
||||
has many extensions such as an extensible type system,
|
||||
inheritance, functions and production rules. These are
|
||||
features carried over from the original <ProductName>Postgres</ProductName> query
|
||||
language, <ProductName>PostQuel</ProductName>. This section provides an overview
|
||||
of how to use <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> to perform simple operations.
|
||||
This manual is only intended to give you an idea of our
|
||||
flavor of <Acronym>SQL</Acronym> and is in no way a complete tutorial on
|
||||
<Acronym>SQL</Acronym>. Numerous books have been written on <Acronym>SQL</Acronym>, including
|
||||
<!--
|
||||
<XRef LinkEnd="MELT93"> and <XRef LinkEnd="DATE97">.
|
||||
-->
|
||||
[MELT93] and [DATE97].
|
||||
You should be aware that some language features
|
||||
are not part of the <Acronym>ANSI</Acronym> standard.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Interactive Monitor</Title>
|
||||
|
||||
<Para>
|
||||
In the examples that follow, we assume that you have
|
||||
created the mydb database as described in the previous
|
||||
subsection and have started <Application>psql</Application>.
|
||||
Examples in this manual can also be found in
|
||||
<FileName>/usr/local/pgsql/src/tutorial/</FileName>. Refer to the
|
||||
<FileName>README</FileName> file in that directory for how to use them. To
|
||||
start the tutorial, do the following:
|
||||
|
||||
<ProgramListing>
|
||||
% cd /usr/local/pgsql/src/tutorial
|
||||
% psql -s mydb
|
||||
Welcome to the POSTGRESQL interactive sql monitor:
|
||||
Please read the file COPYRIGHT for copyright terms of POSTGRESQL
|
||||
|
||||
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: postgres
|
||||
|
||||
mydb=> \i basics.sql
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The <Literal>\i</Literal> command read in queries from the specified
|
||||
files. The <Literal>-s</Literal> option puts you in single step mode which
|
||||
pauses before sending a query to the backend. Queries
|
||||
in this section are in the file <FileName>basics.sql</FileName>.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<Application>psql</Application>
|
||||
has a variety of <Literal>\d</Literal> commands for showing system information.
|
||||
Consult these commands for more details;
|
||||
for a listing, type <Literal>\?</Literal> at the <Application>psql</Application> prompt.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Concepts</Title>
|
||||
|
||||
<Para>
|
||||
The fundamental notion in <ProductName>Postgres</ProductName> 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 <FirstTerm>object identifier</FirstTerm> (<Acronym>OID</Acronym>)
|
||||
that is unique throughout the installation. Because
|
||||
<Acronym>SQL</Acronym> syntax refers to tables, we will use the terms
|
||||
<FirstTerm>table</FirstTerm> and <FirstTerm>class</FirstTerm> interchangeably.
|
||||
Likewise, an <Acronym>SQL</Acronym> <FirstTerm>row</FirstTerm> is an
|
||||
<FirstTerm>instance</FirstTerm> and <Acronym>SQL</Acronym> <FirstTerm>columns</FirstTerm>
|
||||
are <FirstTerm>attributes</FirstTerm>.
|
||||
As previously discussed, classes are grouped into
|
||||
databases, and a collection of databases managed by a
|
||||
single <Application>postmaster</Application> process constitutes an installation
|
||||
or site.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Creating a New Class</Title>
|
||||
|
||||
<Para>
|
||||
You can create a new class by specifying the class
|
||||
name, along with all attribute names and their types:
|
||||
|
||||
<ProgramListing>
|
||||
CREATE TABLE weather (
|
||||
city varchar(80),
|
||||
temp_lo int, -- low temperature
|
||||
temp_hi int, -- high temperature
|
||||
prcp real, -- precipitation
|
||||
date date
|
||||
);
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
Note that both keywords and identifiers are case-insensitive; identifiers can become
|
||||
case-sensitive by surrounding them with double-quotes as allowed by <Acronym>SQL92</Acronym>.
|
||||
<ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> supports the usual
|
||||
<Acronym>SQL</Acronym> types <Type>int</Type>,
|
||||
<Type>float</Type>, <Type>real</Type>, <Type>smallint</Type>, <Type>char(N)</Type>,
|
||||
<Type>varchar(N)</Type>, <Type>date</Type>, <Type>time</Type>,
|
||||
and <Type>timestamp</Type>, as well as other types of general utility and
|
||||
a rich set of geometric types. As we will
|
||||
see later, <ProductName>Postgres</ProductName> can be customized with an
|
||||
arbitrary number of
|
||||
user-defined data types. Consequently, type names are
|
||||
not syntactical keywords, except where required to support special cases in the <Acronym>SQL92</Acronym> standard.
|
||||
So far, the <ProductName>Postgres</ProductName> 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.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Populating a Class with Instances</Title>
|
||||
|
||||
<Para>
|
||||
The <Command>insert</Command> statement is used to populate a class with
|
||||
instances:
|
||||
|
||||
<ProgramListing>
|
||||
INSERT INTO weather
|
||||
VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
You can also use the <Command>copy</Command> command to perform load large
|
||||
amounts of data from flat (<Acronym>ASCII</Acronym>) files.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Querying a Class</Title>
|
||||
|
||||
<Para>
|
||||
The weather class can be queried with normal relational
|
||||
selection and projection queries. A <Acronym>SQL</Acronym> <Command>select</Command>
|
||||
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:
|
||||
<ProgramListing>
|
||||
SELECT * FROM WEATHER;
|
||||
</ProgramListing>
|
||||
|
||||
and the output should be:
|
||||
<ProgramListing>
|
||||
+--------------+---------+---------+------+------------+
|
||||
|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 |
|
||||
+--------------+---------+---------+------+------------+
|
||||
</ProgramListing>
|
||||
You may specify any arbitrary expressions in the target list. For example, you can do:
|
||||
<ProgramListing>
|
||||
SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
Arbitrary Boolean operators
|
||||
(<Command>and</Command>, <Command>or</Command> and <Command>not</Command>) are
|
||||
allowed in the qualification of any query. For example,
|
||||
|
||||
<ProgramListing>
|
||||
SELECT * FROM weather
|
||||
WHERE city = 'San Francisco'
|
||||
AND prcp > 0.0;
|
||||
|
||||
+--------------+---------+---------+------+------------+
|
||||
|city | temp_lo | temp_hi | prcp | date |
|
||||
+--------------+---------+---------+------+------------+
|
||||
|San Francisco | 46 | 50 | 0.25 | 11-27-1994 |
|
||||
+--------------+---------+---------+------+------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
As a final note, you can specify that the results of a
|
||||
select can be returned in a <FirstTerm>sorted order</FirstTerm>
|
||||
or with <FirstTerm>duplicate instances</FirstTerm> removed.
|
||||
|
||||
<ProgramListing>
|
||||
SELECT DISTINCT city
|
||||
FROM weather
|
||||
ORDER BY city;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Redirecting SELECT Queries</Title>
|
||||
|
||||
<Para>
|
||||
Any select query can be redirected to a new class
|
||||
<ProgramListing>
|
||||
SELECT * INTO TABLE temp FROM weather;
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
This forms an implicit <Command>create</Command> command, creating a new
|
||||
class temp with the attribute names and types specified
|
||||
in the target list of the <Command>select into</Command> command. We can
|
||||
then, of course, perform any operations on the resulting
|
||||
class that we can perform on other classes.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Joins Between Classes</Title>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
<Note>
|
||||
<Para>
|
||||
This is only a conceptual model. The actual join may
|
||||
be performed in a more efficient manner, but this is invisible to the user.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
We can do this with the following query:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
|
||||
W2.city, W2.temp_lo AS low, W2.temp_hi AS high
|
||||
FROM weather W1, weather W2
|
||||
WHERE W1.temp_lo < W2.temp_lo
|
||||
AND W1.temp_hi > W2.temp_hi;
|
||||
|
||||
+--------------+-----+------+---------------+-----+------+
|
||||
|city | low | high | city | low | high |
|
||||
+--------------+-----+------+---------------+-----+------+
|
||||
|San Francisco | 43 | 57 | San Francisco | 46 | 50 |
|
||||
+--------------+-----+------+---------------+-----+------+
|
||||
|San Francisco | 37 | 54 | San Francisco | 46 | 50 |
|
||||
+--------------+-----+------+---------------+-----+------+
|
||||
</ProgramListing>
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
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,
|
||||
<ProductName>Postgres</ProductName> computes and returns the values specified in the
|
||||
target list. <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> does not assign any meaning to
|
||||
duplicate values in such expressions. This means that <ProductName>Postgres</ProductName>
|
||||
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 <Command>select distinct</Command> statement.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
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 <FirstTerm>range variables</FirstTerm>.)
|
||||
A query can contain an arbitrary number of
|
||||
class names and surrogates.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Updates</Title>
|
||||
|
||||
<Para>
|
||||
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:
|
||||
|
||||
<ProgramListing>
|
||||
UPDATE weather
|
||||
SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
|
||||
WHERE date > '11/28/1994';
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Deletions</Title>
|
||||
|
||||
<Para>
|
||||
Deletions are performed using the <Command>delete</Command> command:
|
||||
<ProgramListing>
|
||||
DELETE FROM weather WHERE city = 'Hayward';
|
||||
</ProgramListing>
|
||||
|
||||
All weather recording belongs to Hayward is removed.
|
||||
One should be wary of queries of the form
|
||||
<ProgramListing>
|
||||
DELETE FROM classname;
|
||||
</ProgramListing>
|
||||
|
||||
Without a qualification, <Command>delete</Command> will simply
|
||||
remove all instances of the given class, leaving it
|
||||
empty. The system will not request confirmation before
|
||||
doing this.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Using Aggregate Functions</Title>
|
||||
|
||||
<Para>
|
||||
Like most other query languages, <ProductName>PostgreSQL</ProductName> supports
|
||||
aggregate functions.
|
||||
The current implementation of <ProductName>Postgres</ProductName> aggregate functions have some limitations.
|
||||
Specifically, while there are aggregates to compute
|
||||
such functions as the <Function>count</Function>, <Function>sum</Function>,
|
||||
<Function>avg</Function> (average), <Function>max</Function> (maximum) and
|
||||
<Function>min</Function> (minimum) over a set of instances, aggregates can only
|
||||
appear in the target list of a query and not directly in the
|
||||
qualification (the where clause). As an example,
|
||||
|
||||
<ProgramListing>
|
||||
SELECT max(temp_lo) FROM weather;
|
||||
</ProgramListing>
|
||||
|
||||
is allowed, while
|
||||
|
||||
<ProgramListing>
|
||||
SELECT city FROM weather WHERE temp_lo = max(temp_lo);
|
||||
</ProgramListing>
|
||||
|
||||
is not. However, as is often the case the query can be restated to accomplish
|
||||
the intended result; here by using a <FirstTerm>subselect</FirstTerm>:
|
||||
<ProgramListing>
|
||||
SELECT city FROM weather WHERE temp_lo = (SELECT max(temp_lo) FROM weather);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Aggregates may also have <FirstTerm>group by</FirstTerm> clauses:
|
||||
<ProgramListing>
|
||||
SELECT city, max(temp_lo)
|
||||
FROM weather
|
||||
GROUP BY city;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
8
doc/src/sgml/recovery.sgml
Normal file
8
doc/src/sgml/recovery.sgml
Normal file
@ -0,0 +1,8 @@
|
||||
<Chapter>
|
||||
<Title>Database Recovery</Title>
|
||||
|
||||
<Para>
|
||||
This section needs to be written. Volunteers?
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
448
doc/src/sgml/regress.sgml
Normal file
448
doc/src/sgml/regress.sgml
Normal file
@ -0,0 +1,448 @@
|
||||
<Chapter>
|
||||
<Title>Regression Test</Title>
|
||||
|
||||
<Abstract>
|
||||
<Para>
|
||||
Regression test instructions and analysis.
|
||||
</Para>
|
||||
</Abstract>
|
||||
|
||||
<Para>
|
||||
The PostgreSQL regression tests are a comprehensive set of tests for the
|
||||
SQL implementation embedded in PostgreSQL developed by Jolly Chen and
|
||||
Andrew Yu. It tests standard SQL operations as well as the extended
|
||||
capabilities of PostgreSQL.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
These tests have recently been revised by Marc Fournier and Thomas Lockhart
|
||||
and are now packaged as
|
||||
functional units which should make them easier to run and easier to interpret.
|
||||
From <ProductName>PostgreSQL</ProductName> v6.1 onward
|
||||
the regression tests are current for every official release.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Some properly installed and fully functional PostgreSQL installations
|
||||
can fail some of these regression tests due to artifacts of floating point
|
||||
representation and time zone support. The current tests are evaluated
|
||||
using a simple "diff" algorithm, and are sensitive to small system
|
||||
differences. For apparently failed tests, examining the differences
|
||||
may reveal that the differences are not significant.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The regression testing notes below assume the following (except where noted):
|
||||
<ItemizedList Mark="bullet" Spacing="compact">
|
||||
<ListItem>
|
||||
<Para>
|
||||
Commands are Unix-compatible. See note below.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Defaults are used except where noted.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
User postgres is the <ProductName>Postgres</ProductName> superuser.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The source path is /usr/src/pgsql (other paths are possible).
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The runtime path is /usr/local/pgsql (other paths are possible).
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Regression Environment</Title>
|
||||
|
||||
<Para>
|
||||
The regression test is invoked by the <Command>make</Command> command which compiles
|
||||
a <Acronym>C</Acronym> program into a shared library
|
||||
in the current directory. Localized shell scripts are also created in
|
||||
the current directory. The output file templates are massaged into the
|
||||
<FileName>./expected/*.out</FileName> files. The localization replaces macros in the source
|
||||
files with absolute pathnames and user names.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Normally, the regression test should be run as the pg_superuser since
|
||||
the 'src/test/regress' directory and sub-directories are owned by the
|
||||
pg_superuser. If you run the regression test as another user the
|
||||
'src/test/regress' directory tree should be writeable to that user.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The postmaster should be invoked with the system time zone set for
|
||||
Berkeley, California. This is done automatically by the regression
|
||||
test script. However, it does require machine support for the PST8PDT
|
||||
time zone.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
To verify that your machine does have this support, type
|
||||
the following:
|
||||
<ProgramListing>
|
||||
setenv TZ PST8PDT
|
||||
date
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The "date" command above should have returned the current system time
|
||||
in the PST8PDT time zone. If the PST8PDT database is not available, then
|
||||
your system may have returned the time in GMT. If the PST8PDT time zone
|
||||
is not available, you can set the time zone rules explicitly:
|
||||
<ProgramListing>
|
||||
setenv PGTZ PST8PDT7,M04.01.0,M10.05.03
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Directory Layout</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
This should become a table in the previous section.
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProgramListing>
|
||||
input/ .... .source files that are converted using 'make all' into
|
||||
some of the .sql files in the 'sql' subdirectory
|
||||
|
||||
output/ ... .source files that are converted using 'make all' into
|
||||
.out files in the 'expected' subdirectory
|
||||
|
||||
sql/ ...... .sql files used to perform the regression tests
|
||||
|
||||
expected/ . .out files that represent what we *expect* the results to
|
||||
look like
|
||||
|
||||
results/ .. .out files that represent what the results *actually* look
|
||||
like. Also used as temporary storage for table copy testing.
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Regression Test Procedure</Title>
|
||||
|
||||
<Para>
|
||||
Commands were tested on RedHat Linux version 4.2 using the bash shell.
|
||||
Except where noted, they will probably work on most systems. Commands
|
||||
like <FileName>ps</FileName> and <FileName>tar</FileName> vary wildly on what options you should use on each
|
||||
platform. <Emphasis>Use common sense</Emphasis> before typing in these commands.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<Procedure>
|
||||
<Title><ProductName>Postgres</ProductName> Regression Configuration</Title>
|
||||
|
||||
<Para>
|
||||
For a fresh install or upgrading from previous releases of
|
||||
<ProductName>Postgres</ProductName>:
|
||||
</Para>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Build the regression test. Type
|
||||
<ProgramListing>
|
||||
cd /usr/src/pgsql/src/test/regress
|
||||
gmake all
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="optional">
|
||||
<Para>
|
||||
If you have prevously invoked the regression test, clean up the
|
||||
working directory with:
|
||||
|
||||
<ProgramListing>
|
||||
cd /usr/src/pgsql/src/test/regress
|
||||
make clean
|
||||
</ProgramListing>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
The file /usr/src/pgsql/src/test/regress/README has detailed
|
||||
instructions for running and interpreting the regression tests.
|
||||
A short version follows here:
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If the postmaster is not already running, start the postmaster on an
|
||||
available window by typing
|
||||
<ProgramListing>
|
||||
postmaster
|
||||
</ProgramListing>
|
||||
|
||||
or start the postmaster daemon running in the background by typing
|
||||
<ProgramListing>
|
||||
cd
|
||||
nohup postmaster > regress.log 2>&1 &
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Run postmaster from your <ProductName>Postgres</ProductName> super user account (typically
|
||||
account postgres).
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
Do not run <FileName>postmaster</FileName> from the root account.
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
Run the regression tests. Type
|
||||
|
||||
<ProgramListing>
|
||||
cd /usr/src/pgsql/src/test/regress
|
||||
gmake runtest
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
|
||||
You do not need to type "gmake clean" if this is the first time you
|
||||
are running the tests.
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
|
||||
You should get on the screen (and also written to file ./regress.out)
|
||||
a series of statements stating which tests passed and which tests
|
||||
failed. Please note that it can be normal for some of the tests to
|
||||
"fail". For the failed tests, use diff to compare the files in
|
||||
directories ./results and ./expected. If float8 failed, type
|
||||
something like:
|
||||
<ProgramListing>
|
||||
cd /usr/src/pgsql/src/test/regress
|
||||
diff -w expected/float8.out results
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
<Step Performance="required">
|
||||
<Para>
|
||||
After running the tests, type
|
||||
<ProgramListing>
|
||||
destroydb regression
|
||||
cd /usr/src/pgsql/src/test/regress
|
||||
gmake clean
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Step>
|
||||
|
||||
</Procedure>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Regression Analysis</Title>
|
||||
|
||||
<Para>
|
||||
<Quote>Failed</Quote> tests may have failed due to slightly different error messages,
|
||||
math libraries, or output formatting.
|
||||
"Failures" of this type do not indicate a problem with
|
||||
<ProductName>Postgres</ProductName>.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
For a i686/Linux-ELF platform, no tests failed since this is the
|
||||
v6.2.1 regression testing reference platform.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
For the SPARC/Linux-ELF platform, using the 970525 beta version of
|
||||
<ProductName>Postgres</ProductName> v6.2 the following tests "failed":
|
||||
float8 and geometry "failed" due to minor precision differences in
|
||||
floating point numbers. select_views produces massively different output,
|
||||
but the differences are due to minor floating point differences.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Conclusion? If you do see failures, try to understand the nature of
|
||||
the differences and then decide if those differences will affect your
|
||||
intended use of <ProductName>Postgres</ProductName>. However, keep in mind that this is likely
|
||||
to be the most solid release of <ProductName>Postgres</ProductName> to date, incorporating many
|
||||
bug fixes from v6.1, and that previous versions of <ProductName>Postgres</ProductName> have been
|
||||
in use successfully for some time now.
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title>Comparing expected/actual output</Title>
|
||||
|
||||
<Para>
|
||||
The results are in files in the ./results directory. These results
|
||||
can be compared with results in the ./expected directory using 'diff'.
|
||||
The files might not compare exactly. The following paragraphs attempt
|
||||
to explain the differences.
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Error message differences</Title>
|
||||
|
||||
<Para>
|
||||
Some of the regression tests involve intentional invalid input values.
|
||||
Error messages can come from either the Postgres code or from the host
|
||||
platform system routines. In the latter case, the messages may vary
|
||||
between platforms, but should reflect similar information. These
|
||||
differences in messages will result in a "failed" regression test which
|
||||
can be validated by inspection.
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>OID differences</Title>
|
||||
|
||||
<Para>
|
||||
There are several places where PostgreSQL OID (object identifiers) appear
|
||||
in 'regress.out'. OID's are unique 32-bit integers which are generated
|
||||
by the PostgreSQL backend whenever a table row is inserted or updated.
|
||||
If you run the regression test on a non-virgin database or run it multiple
|
||||
times, the OID's reported will have different values.
|
||||
|
||||
The following SQL statements in 'misc.out' have shown this behavior:
|
||||
|
||||
QUERY: SELECT user_relns() AS user_relns ORDER BY user_relns;
|
||||
|
||||
The 'a,523676' row is composed from an OID.
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Date and time differences</Title>
|
||||
|
||||
<Para>
|
||||
On many supported platforms, you can force PostgreSQL to believe that it
|
||||
is running in the same time zone as Berkeley, California. See details in
|
||||
the section on how to run the regression tests.
|
||||
|
||||
If you do not explicitly set your time zone environment to PST8PDT, then
|
||||
most of the date and time results will reflect your local time zone and
|
||||
will fail the regression testing.
|
||||
|
||||
There appears to be some systems which do not accept the recommended syntax
|
||||
for explicitly setting the local time zone rules. Some systems using the
|
||||
public domain time zone package exhibit minor problems with pre-1970 PDT
|
||||
times, representing them in PST instead.
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Floating point differences</Title>
|
||||
|
||||
<Para>
|
||||
Some of the tests involve computing 64-bit (<Type>float8</Type>) number from table
|
||||
columns. Differences in results involving mathematical functions of
|
||||
<Type>float8</Type> columns have been observed. These differences occur where
|
||||
different operating systems are used on the same platform ie:
|
||||
BSDI and SOLARIS on Intel/86, and where the same operating system is
|
||||
used used on different platforms, ie: SOLARIS on SPARC and Intel/86.
|
||||
|
||||
Human eyeball comparison is needed to determine the real significance
|
||||
of these differences which are usually 10 places to the right of
|
||||
the decimal point.
|
||||
|
||||
Some systems signal errors from pow() and exp() differently from
|
||||
the mechanism expected by the current Postgres code.
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Polygon differences</Title>
|
||||
|
||||
<Para>
|
||||
Several of the tests involve operations on geographic date about the
|
||||
Oakland/Berkley CA street map. The map data is expressed as polygons
|
||||
whose vertices are represented as pairs of <Type>float8</Type> numbers (decimal
|
||||
latitude and longitude). Initially, some tables are created and
|
||||
loaded with geographic data, then some views are created which join
|
||||
two tables using the polygon intersection operator (##), then a select
|
||||
is done on the view.
|
||||
|
||||
When comparing the results from different platforms, differences occur
|
||||
in the 2nd or 3rd place to the right of the decimal point. The SQL
|
||||
statements where these problems occur are the folowing:
|
||||
|
||||
<ProgramListing>
|
||||
QUERY: SELECT * from street;
|
||||
QUERY: SELECT * from iexit;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Random differences</Title>
|
||||
|
||||
<Para>
|
||||
There is at least one test case in random.out which is intended to produce
|
||||
random results. This causes random to fail the regression testing.
|
||||
Typing
|
||||
<ProgramListing>
|
||||
diff results/random.out expected/random.out
|
||||
</ProgramListing>
|
||||
|
||||
should produce only
|
||||
one or a few lines of differences for this reason, but other floating
|
||||
point differences on dissimilar architectures might cause many more
|
||||
differences. See the release notes below.
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>The <Quote>expected</Quote> files</Title>
|
||||
|
||||
<Para>
|
||||
The <FileName>./expected/*.out</FileName> files were adapted from the original monolithic
|
||||
<FileName>expected.input</FileName> file provided by Jolly Chen et al. Newer versions of these
|
||||
files generated on various development machines have been substituted after
|
||||
careful (?) inspection. Many of the development machines are running a
|
||||
Unix OS variant (FreeBSD, Linux, etc) on Ix86 hardware.
|
||||
|
||||
The original <FileName>expected.input</FileName> file was created on a SPARC Solaris 2.4
|
||||
system using the <FileName>postgres5-1.02a5.tar.gz</FileName> source tree. It was compared
|
||||
with a file created on an I386 Solaris 2.4 system and the differences
|
||||
were only in the floating point polygons in the 3rd digit to the right
|
||||
of the decimal point. (see below)
|
||||
|
||||
The original <FileName>sample.regress.out</FileName> file was from the postgres-1.01 release
|
||||
constructed by Jolly Chen and is included here for reference. It may
|
||||
have been created on a DEC ALPHA machine as the <FileName>Makefile.global</FileName>
|
||||
in the postgres-1.01 release has PORTNAME=alpha.
|
||||
</Para>
|
||||
|
||||
</Sect2>
|
||||
|
||||
</Sect1>
|
||||
|
||||
</Chapter>
|
144
doc/src/sgml/release.sgml
Normal file
144
doc/src/sgml/release.sgml
Normal file
@ -0,0 +1,144 @@
|
||||
<Chapter>
|
||||
<Title>Release Notes</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
Should include the migration notes from <FileName>migration/</FileName>.
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The release notes have not yet been integrated into the new documentation.
|
||||
Check for plain text files in the top of the distribution directory tree
|
||||
and in the <FileName>migration/</FileName> directory for current information.
|
||||
|
||||
<Sect1>
|
||||
<Title>Release 6.3</Title>
|
||||
|
||||
<Para>
|
||||
TBD
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Release 6.2.1</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
v6.2.1 was a bug-fix and usability release on v6.2. Needs only a few notes.
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Release 6.2</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
This should include information based on Bruce's release summary.
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Release 6.1</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
This should include information based on Bruce's release summary.
|
||||
</Para>
|
||||
</Note>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The regression tests have been adapted and extensively modified for the
|
||||
v6.1 release of PostgreSQL.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Three new data types (datetime, timespan, and circle) have been added to
|
||||
the native set of PostgreSQL types. Points, boxes, paths, and polygons
|
||||
have had their output formats made consistant across the data types.
|
||||
The polygon output in misc.out has only been spot-checked for correctness
|
||||
relative to the original regression output.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
PostgreSQL v6.1 introduces a new, alternate optimizer which uses <FirstTerm>genetic</FirstTerm>
|
||||
algorithms. These algorithms introduce a random behavior in the ordering
|
||||
of query results when the query contains multiple qualifiers or multiple
|
||||
tables (giving the optimizer a choice on order of evaluation). Several
|
||||
regression tests have been modified to explicitly order the results, and
|
||||
hence are insensitive to optimizer choices. A few regression tests are
|
||||
for data types which are inherently unordered (e.g. points and time
|
||||
intervals) and tests involving those types are explicitly bracketed with
|
||||
<Command>set geqo to 'off'</Command> and <Command>reset geqo</Command>.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The interpretation of array specifiers (the curly braces around atomic
|
||||
values) appears to have changed sometime after the original regression
|
||||
tests were generated. The current <FileName>./expected/*.out</FileName> files reflect this
|
||||
new interpretation, which may not be correct!
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The float8 regression test fails on at least some platforms. This is due
|
||||
to differences in implementations of pow() and exp() and the signaling
|
||||
mechanisms used for overflow and underflow conditions.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The "random" results in the random test should cause the "random" test
|
||||
to be "failed", since the regression tests are evaluated using a simple
|
||||
diff. However, "random" does not seem to produce random results on my
|
||||
test machine (Linux/gcc/i686).
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Timing Results</Title>
|
||||
|
||||
<Para>
|
||||
These timing results are from running the regression test with the command
|
||||
|
||||
<ProgramListing>
|
||||
% time make runtest
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
Timing under Linux 2.0.27 seems to have a roughly 5% variation from run
|
||||
to run, presumably due to the timing vagaries of multitasking systems.
|
||||
|
||||
<Sect2>
|
||||
<Title>v6.3</Title>
|
||||
|
||||
<Para>
|
||||
<ProgramListing>
|
||||
Time System
|
||||
02:30 Dual Pentium Pro 180, 96MB, UW-SCSI, Linux 2.0.30, gcc 2.7.2.1 -O2 -m486
|
||||
04:12 Dual Pentium Pro 180, 96MB, EIDE, Linux 2.0.30, gcc 2.7.2.1 -O2 -m486
|
||||
</ProgramListing>
|
||||
|
||||
<Sect2>
|
||||
<Title>v6.1</Title>
|
||||
|
||||
<Para>
|
||||
<ProgramListing>
|
||||
Time System
|
||||
06:12 Pentium Pro 180, 32MB, Linux 2.0.30, gcc 2.7.2 -O2 -m486
|
||||
12:06 P-100, 48MB, Linux 2.0.29, gcc
|
||||
39:58 Sparc IPC 32MB, Solaris 2.5, gcc 2.7.2.1 -O -g
|
||||
</ProgramListing>
|
||||
|
||||
</Chapter>
|
||||
|
28
doc/src/sgml/rules.sgml
Normal file
28
doc/src/sgml/rules.sgml
Normal file
@ -0,0 +1,28 @@
|
||||
<Chapter>
|
||||
<Title>The <ProductName>Postgres</ProductName> Rule System</Title>
|
||||
|
||||
<Para>
|
||||
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 <ProductName>Postgres</ProductName> rule system
|
||||
here. Instead, you should read
|
||||
<XRef LinkEnd="STON90b" EndTerm="[STON90b]"> to understand
|
||||
some of these points and the theoretical foundations of
|
||||
the <ProductName>Postgres</ProductName> rule system before trying to use rules.
|
||||
The discussion in this section is intended to provide
|
||||
an overview of the <ProductName>Postgres</ProductName> 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
|
||||
<XRef LinkEnd="ONG90" EndTerm="[ONG90]">
|
||||
as well as
|
||||
<XRef LinkEnd="STON90b" EndTerm="[STON90b]">.
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
2831
doc/src/sgml/spi.sgml
Normal file
2831
doc/src/sgml/spi.sgml
Normal file
File diff suppressed because it is too large
Load Diff
432
doc/src/sgml/start-ag.sgml
Normal file
432
doc/src/sgml/start-ag.sgml
Normal file
@ -0,0 +1,432 @@
|
||||
<!--
|
||||
- This file currently contains several small chapters.
|
||||
- Each chapter should be split off into a separate source file...
|
||||
- - thomas 1998-02-24
|
||||
-->
|
||||
|
||||
<Chapter>
|
||||
<Title>Runtime Environment</Title>
|
||||
|
||||
<Para>
|
||||
<Figure Id="ADMIN-LAYOUT">
|
||||
<Title><ProductName>Postgres</ProductName> file layout</Title>
|
||||
<Graphic Align="center" FileRef="layout.gif" Format="GIF"></Graphic>
|
||||
</Figure>
|
||||
|
||||
<XRef LinkEnd="ADMIN-LAYOUT" EndTerm="ADMIN-LAYOUT">
|
||||
shows how the <ProductName>Postgres</ProductName> distribution is laid
|
||||
out when installed in the default way. For simplicity,
|
||||
we will assume that <ProductName>Postgres</ProductName> has been installed in the
|
||||
directory <FileName>/usr/local/pgsql</FileName>. Therefore, wherever
|
||||
you see the directory <FileName>/usr/local/pgsql</FileName> you should
|
||||
substitute the name of the directory where <ProductName>Postgres</ProductName> is
|
||||
actually installed.
|
||||
All <ProductName>Postgres</ProductName> commands are installed in the directory
|
||||
<FileName>/usr/local/pgsql/bin</FileName>. 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
|
||||
<ProgramListing>
|
||||
set path = ( /usr/local/pgsql/bin path )
|
||||
</ProgramListing>
|
||||
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
|
||||
<ProgramListing>
|
||||
PATH=/usr/local/pgsql/bin PATH
|
||||
export PATH
|
||||
</ProgramListing>
|
||||
to the .profile file in your home directory.
|
||||
From now on, we will assume that you have added the
|
||||
<ProductName>Postgres</ProductName> 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.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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 <Acronym>PGHOST</Acronym> environment variable to the name
|
||||
of the database server machine. The environment variable
|
||||
<Acronym>PGPORT</Acronym> 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 <Application>postmaster</Application>, you should immediately consult your site administrator to make sure that your
|
||||
environment is properly set up.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Locale Support</Title>
|
||||
|
||||
<Para>
|
||||
<Note>
|
||||
<Para>
|
||||
Written by Oleg Bartunov.
|
||||
See <ULink url="http://www.sai.msu.su/~megera/postgres/">Oleg's web page</ULink>
|
||||
for additional information on locale and Russian language support.
|
||||
|
||||
</Para>
|
||||
</Note>
|
||||
While doing a project for a company in Moscow, Russia, I encountered the problem that postgresql had no
|
||||
support of national alphabets. After looking for possible workarounds I decided to develop support of locale myself.
|
||||
I'm not a C-programer but already had some experience with locale programming when I work with perl
|
||||
(debugging) and glimpse. After several days of digging through
|
||||
the <ProductName>Postgres</ProductName> source tree I made very minor corections to
|
||||
src/backend/utils/adt/varlena.c and src/backend/main/main.c and got what I needed! I did support only for
|
||||
LC_CTYPE and LC_COLLATE, but later LC_MONETARY was added by others. I got many
|
||||
messages from people about this patch so I decided to send it to developers and (to my surprise) it was
|
||||
incorporated into postgresql distribution.
|
||||
|
||||
<Para>
|
||||
People often complain that locale doesn't work for them. There are several common mistakes:
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Didn't properly configure postgresql before compilation.
|
||||
You must run configure with --enable-locale option to enable locale support.
|
||||
Didn't setup environment correctly when starting postmaster.
|
||||
You must define environment variables $LC_CTYPE and $LC_COLLATE before running postmaster
|
||||
because backend gets information about locale from environment. I use following shell script
|
||||
(runpostgres):
|
||||
|
||||
<ProgramListing>
|
||||
#!/bin/sh
|
||||
|
||||
export LC_CTYPE=koi8-r
|
||||
export LC_COLLATE=koi8-r
|
||||
postmaster -B 1024 -S -D/usr/local/pgsql/data/ -o '-Fe'
|
||||
</ProgramListing>
|
||||
|
||||
and run it from rc.local as
|
||||
|
||||
<ProgramListing>
|
||||
/bin/su - postgres -c "/home/postgres/runpostgres"
|
||||
</ProgramListing>
|
||||
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Broken locale support in OS (for example, locale support in libc under Linux several times has changed
|
||||
and this caused a lot of problems). Latest perl has also support of locale and if locale is broken perl -v will
|
||||
complain something like:
|
||||
|
||||
8:17[mira]:~/WWW/postgres>setenv LC_CTYPE not_exist
|
||||
8:18[mira]:~/WWW/postgres>perl -v
|
||||
perl: warning: Setting locale failed.
|
||||
perl: warning: Please check that your locale settings:
|
||||
LC_ALL = (unset),
|
||||
LC_CTYPE = "not_exist",
|
||||
LANG = (unset)
|
||||
are supported and installed on your system.
|
||||
perl: warning: Falling back to the standard locale ("C").
|
||||
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Wrong location of locale files!
|
||||
|
||||
Possible location: <FileName>/usr/lib/locale</FileName> (Linux, Solaris), <FileName>/usr/share/locale</FileName> (Linux), <FileName>/usr/lib/nls/loc</FileName> (DUX 4.0)
|
||||
Check man locale for right place. Under Linux I did a symbolical link between <FileName>/usr/lib/locale</FileName> and
|
||||
<FileName>/usr/share/locale</FileName> to be sure next libc will not break my locale.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
<Sect2>
|
||||
<Title>What are the Benefits?</Title>
|
||||
|
||||
<Para>
|
||||
You can use ~* and order by operators for strings contain characters from national alphabets. Non-english users
|
||||
definitely need that. If you won't use locale stuff just undefine USE_LOCALE variable.
|
||||
|
||||
<Sect2>
|
||||
<Title>What are the Drawbacks?</Title>
|
||||
|
||||
<Para>
|
||||
There is one evident drawback of using locale - it's speed ! So, use locale only if you really need it.
|
||||
|
||||
</Chapter>
|
||||
|
||||
<Chapter>
|
||||
<Title>Starting <Application>postmaster</Application></Title>
|
||||
|
||||
<Para>
|
||||
Nothing can happen to a database unless the <Application>postmaster</Application>
|
||||
process is running. As the site administrator, there
|
||||
are a number of things you should remember before
|
||||
starting the <Application>postmaster</Application>. These are discussed in the
|
||||
section of this manual titled, "Administering Postgres."
|
||||
However, if <ProductName>Postgres</ProductName> has been installed by following
|
||||
the installation instructions exactly as written, the
|
||||
following simple command is all you should
|
||||
need to start the <Application>postmaster</Application>:
|
||||
<ProgramListing>
|
||||
% postmaster
|
||||
</ProgramListing>
|
||||
The <Application>postmaster</Application> occasionally prints out messages which
|
||||
are often helpful during troubleshooting. If you wish
|
||||
to view debugging messages from the <Application>postmaster</Application>, you can
|
||||
start it with the -d option and redirect the output to
|
||||
the log file:
|
||||
<ProgramListing>
|
||||
% postmaster -d >& pm.log &
|
||||
</ProgramListing>
|
||||
If you do not wish to see these messages, you can type
|
||||
<ProgramListing>
|
||||
% postmaster -S
|
||||
</ProgramListing>
|
||||
and the <Application>postmaster</Application> will be "S"ilent. Notice that there
|
||||
is no ampersand ("&") at the end of the last example.
|
||||
</Para>
|
||||
</Chapter>
|
||||
|
||||
<Chapter>
|
||||
<Title>Adding and Deleting Users</Title>
|
||||
|
||||
<Para>
|
||||
<Application>createuser</Application> enables specific users to access
|
||||
<ProductName>Postgres</ProductName>. <Application>destroyuser</Application> removes users and
|
||||
prevents them from accessing <ProductName>Postgres</ProductName>. Note that these
|
||||
commands only affect users with respect to <ProductName>Postgres</ProductName>;
|
||||
they have no effect on users other privileges or status with regards
|
||||
to the underlying
|
||||
operating system.
|
||||
</Para>
|
||||
</Chapter>
|
||||
|
||||
<Chapter>
|
||||
<Title>Disk Management</Title>
|
||||
|
||||
<Para>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Alternate Locations</Title>
|
||||
|
||||
<Para>
|
||||
It is possible to create a database in a location other than the default
|
||||
location for the installation. Remember that all database access actually
|
||||
occurs through the database backend, so that any location specified must
|
||||
be accessible by the backend.
|
||||
|
||||
<Para>
|
||||
Either an absolute path name or an environment variable
|
||||
may be specified as a location. Note that for security and integrity reasons,
|
||||
all paths and environment variables so specified have some
|
||||
additional path fields appended.
|
||||
|
||||
<Note>
|
||||
<Para>
|
||||
The environment variable style of specification
|
||||
is to be preferred since it allows the site administrator more flexibility in
|
||||
managing disk storage.
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
Remember that database creation is actually performed by the database backend.
|
||||
Therefore, any environment variable specifying an alternate location must have
|
||||
been defined before the backend was started. To define an alternate location
|
||||
PGDATA2 pointing to <FileName>/home/postgres/data</FileName>, type
|
||||
<ProgramListing>
|
||||
% setenv PGDATA2 /home/postgres/data
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
Usually, you will want to define this variable in the <ProductName>Postgres</ProductName> superuser's
|
||||
<FileName>.profile</FileName>
|
||||
or
|
||||
<FileName>.cshrc</FileName>
|
||||
initialization file to ensure that it is defined upon system startup.
|
||||
|
||||
<Para>
|
||||
To create a data storage area in <FileName>/home/postgres/data</FileName>, ensure
|
||||
that <FileName>/home/postgres</FileName> already exists and is writable.
|
||||
From the command line, type
|
||||
<ProgramListing>
|
||||
% initlocation $PGDATA2
|
||||
Creating Postgres database system directory /home/postgres/data
|
||||
|
||||
Creating Postgres database system directory /home/postgres/data/base
|
||||
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
To test the new location, create a database <Database>test</Database> by typing
|
||||
<ProgramListing>
|
||||
% createdb -D PGDATA2 test
|
||||
% destroydb test
|
||||
</ProgramListing>
|
||||
</Sect1>
|
||||
</Chapter>
|
||||
|
||||
<Chapter>
|
||||
<Title>Troubleshooting</Title>
|
||||
|
||||
<Para>
|
||||
Assuming that your site administrator has properly
|
||||
started the <Application>postmaster</Application> process and authorized you to
|
||||
use the database, you (as a user) may begin to start up
|
||||
applications. As previously mentioned, you should add
|
||||
<FileName>/usr/local/pgsql/bin</FileName> to your shell search path.
|
||||
In most cases, this is all you should have to do in
|
||||
terms of preparation.
|
||||
|
||||
<Para>
|
||||
If you get the following error message from a <ProductName>Postgres</ProductName>
|
||||
command (such as <Application>psql</Application> or <Application>createdb</Application>):
|
||||
<ProgramListing>
|
||||
connectDB() failed: Is the postmaster running at 'localhost' on port '4322'?
|
||||
</ProgramListing>
|
||||
it is usually because either the <Application>postmaster</Application> is not running,
|
||||
or you are attempting to connect to the wrong server host.
|
||||
If you get the following error message:
|
||||
<ProgramListing>
|
||||
FATAL 1:Feb 17 23:19:55:process userid (2360) != database owner (268)
|
||||
</ProgramListing>
|
||||
it means that the site administrator started the <Application>postmaster</Application>
|
||||
as the wrong user. Tell him to restart it as
|
||||
the <ProductName>Postgres</ProductName> superuser.
|
||||
</Para>
|
||||
</Chapter>
|
||||
|
||||
<Chapter>
|
||||
<Title>Managing a Database</Title>
|
||||
|
||||
<Para>
|
||||
Now that <ProductName>Postgres</ProductName> is up and running we can create some
|
||||
databases to experiment with. Here, we describe the
|
||||
basic commands for managing a database.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Creating a Database</Title>
|
||||
|
||||
<Para>
|
||||
Let's say you want to create a database named mydb.
|
||||
You can do this with the following command:
|
||||
<ProgramListing>
|
||||
% createdb mydb
|
||||
</ProgramListing>
|
||||
|
||||
<ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName> 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.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Accessing a Database</Title>
|
||||
|
||||
<Para>
|
||||
Once you have constructed a database, you can access it
|
||||
by:
|
||||
|
||||
<ItemizedList Mark="bullet" Spacing="compact">
|
||||
<ListItem>
|
||||
<Para>
|
||||
running the <ProductName>Postgres</ProductName> terminal monitor programs (
|
||||
monitor or <Application>psql</Application>) which allows you to interactively
|
||||
enter, edit, and execute <Acronym>SQL</Acronym> commands.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
writing a C program using the LIBPQ subroutine
|
||||
library. This allows you to submit <Acronym>SQL</Acronym> commands
|
||||
from C and get answers and status messages back to
|
||||
your program. This interface is discussed further
|
||||
in section ??.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
You might want to start up <Application>psql</Application>, to try out the examples in this manual. It can be activated for the mydb
|
||||
database by typing the command:
|
||||
<ProgramListing>
|
||||
% psql mydb
|
||||
</ProgramListing>
|
||||
|
||||
You will be greeted with the following message:
|
||||
<ProgramListing>
|
||||
Welcome to the Postgres 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=>
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
This prompt indicates that the terminal monitor is listening to you and that you can type <Acronym>SQL</Acronym> queries into a
|
||||
workspace maintained by the terminal monitor.
|
||||
The <Application>psql</Application> program responds to escape codes that begin
|
||||
with the backslash character, "\". For example, you
|
||||
can get help on the syntax of various <ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> commands by typing:
|
||||
<ProgramListing>
|
||||
mydb=> \h
|
||||
</ProgramListing>
|
||||
|
||||
Once you have finished entering your queries into the
|
||||
workspace, you can pass the contents of the workspace
|
||||
to the <ProductName>Postgres</ProductName> server by typing:
|
||||
<ProgramListing>
|
||||
mydb=> \g
|
||||
</ProgramListing>
|
||||
|
||||
This tells the server to process the query. If you
|
||||
terminate your query with a semicolon, the backslash-g is not
|
||||
necessary. <Application>psql</Application> will automatically process semicolon terminated queries.
|
||||
To read queries from a file, say myFile, instead of
|
||||
entering them interactively, type:
|
||||
<ProgramListing>
|
||||
mydb=> \i fileName
|
||||
</ProgramListing>
|
||||
|
||||
To get out of <Application>psql</Application> and return to UNIX, type
|
||||
<ProgramListing>
|
||||
mydb=> \q
|
||||
</ProgramListing>
|
||||
|
||||
and <Application>psql</Application> will quit and return you to your command
|
||||
shell. (For more escape codes, type backslash-h at the monitor
|
||||
prompt.)
|
||||
White space (i.e., spaces, tabs and newlines) may be
|
||||
used freely in <Acronym>SQL</Acronym> queries. Single-line comments are denoted by
|
||||
<Quote>--</Quote>. Everything after the dashes up to the end of the
|
||||
line is ignored. Multiple-line comments, and comments within a line,
|
||||
are denoted by <Quote>/* ... */</Quote>
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Destroying a Database</Title>
|
||||
|
||||
<Para>
|
||||
If you are the database administrator for the database
|
||||
mydb, you can destroy it using the following UNIX command:
|
||||
<ProgramListing>
|
||||
% destroydb mydb
|
||||
</ProgramListing>
|
||||
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 forethought.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
</Chapter>
|
315
doc/src/sgml/start.sgml
Normal file
315
doc/src/sgml/start.sgml
Normal file
@ -0,0 +1,315 @@
|
||||
<Chapter>
|
||||
<Title>Getting Started</Title>
|
||||
|
||||
<Abstract>
|
||||
<Para>
|
||||
How to begin work with <ProductName>Postgres</ProductName> for a new user.
|
||||
</Para>
|
||||
</Abstract>
|
||||
|
||||
<Para>
|
||||
Some of the steps required to use <ProductName>Postgres</ProductName>
|
||||
can be performed by any Postgres user, and some must be done by
|
||||
the site database administrator. This site administrator
|
||||
is the person who installed the software, created
|
||||
the database directories and started the <Application>postmaster</Application>
|
||||
process. This person does not have to be the UNIX
|
||||
superuser (<Quote>root</Quote>)
|
||||
or the computer system administrator; a person can install and use
|
||||
<ProductName>Postgres</ProductName> without any special accounts or privileges.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If you are installing <ProductName>Postgres</ProductName> yourself, then
|
||||
refer to the Administrator's Guide for instructions on installation, and return
|
||||
to this guide when the installation is complete.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Throughout this manual, any examples that begin with
|
||||
the character <Quote>&percnt</Quote> are commands that should be typed
|
||||
at the UNIX shell prompt. Examples that begin with the
|
||||
character <Quote>*</Quote> are commands in the Postgres query
|
||||
language, Postgres <Acronym>SQL</Acronym>.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Setting Up Your Environment</Title>
|
||||
|
||||
<Para>
|
||||
This section discusses how to set up
|
||||
your own environment so that you can use frontend
|
||||
applications. We assume <ProductName>Postgres</ProductName> has already been
|
||||
successfully installed and started; refer to the Administrator's Guide
|
||||
and the installation notes
|
||||
for how to install Postgres.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> is a client/server application. As a user,
|
||||
you only need access to the client portions of the installation (an example
|
||||
of a client application is the interactive monitor <Application>psql</Application>).
|
||||
For simplicity,
|
||||
we will assume that <ProductName>Postgres</ProductName> has been installed in the
|
||||
directory <FileName>/usr/local/pgsql</FileName>. Therefore, wherever
|
||||
you see the directory <FileName>/usr/local/pgsql</FileName> you should
|
||||
substitute the name of the directory where <ProductName>Postgres</ProductName> is
|
||||
actually installed.
|
||||
All <ProductName>Postgres</ProductName> commands are installed in the directory
|
||||
<FileName>/usr/local/pgsql/bin</FileName>. 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
|
||||
<ProgramListing>
|
||||
% set path = ( /usr/local/pgsql/bin path )
|
||||
</ProgramListing>
|
||||
in the <FileName>.login</FileName> file in your home directory. If you use
|
||||
a variant of the Bourne shell, such as sh, ksh, or
|
||||
bash, then you would add
|
||||
<ProgramListing>
|
||||
% PATH=/usr/local/pgsql/bin PATH
|
||||
% export PATH
|
||||
</ProgramListing>
|
||||
to the .profile file in your home directory.
|
||||
From now on, we will assume that you have added the
|
||||
<ProductName>Postgres</ProductName> bin directory to your path. In addition, we
|
||||
will make frequent reference to <Quote>setting a shell
|
||||
variable</Quote> or <Quote>setting an environment variable</Quote> 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.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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 <Acronym>PGHOST</Acronym> environment variable to the name
|
||||
of the database server machine. The environment variable
|
||||
<Acronym>PGPORT</Acronym> 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 <Application>postmaster</Application>,
|
||||
you should immediately consult your site administrator to make sure that your
|
||||
environment is properly set up.
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Starting the Interactive Monitor (psql)</Title>
|
||||
|
||||
<Para>
|
||||
Assuming that your site administrator has properly
|
||||
started the <Application>postmaster</Application> process and authorized you to
|
||||
use the database, you (as a user) may begin to start up
|
||||
applications. As previously mentioned, you should add
|
||||
<FileName>/usr/local/pgsql/bin</FileName> to your shell search path.
|
||||
In most cases, this is all you should have to do in
|
||||
terms of preparation.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
As of <ProductName>Postgres</ProductName> v6.3, two different styles of connections
|
||||
are supported. The site administrator will have chosen to allow TCP/IP network connections
|
||||
or will have restricted database access to local (same-machine) socket connections only.
|
||||
These choices become significant if you encounter problems in connecting to a database.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If you get the following error message from a <ProductName>Postgres</ProductName>
|
||||
command (such as <Application>psql</Application> or <Application>createdb</Application>):
|
||||
|
||||
<ProgramListing>
|
||||
% psql template1
|
||||
Connection to database 'postgres' failed.
|
||||
connectDB() failed: Is the postmaster running and accepting connections
|
||||
at 'UNIX Socket' on port '5432'?
|
||||
</ProgramListing>
|
||||
|
||||
or
|
||||
|
||||
<ProgramListing>
|
||||
% psql -h localhost template1
|
||||
Connection to database 'postgres' failed.
|
||||
connectDB() failed: Is the postmaster running and accepting TCP/IP
|
||||
(with -i) connections at 'localhost' on port '5432'?
|
||||
</ProgramListing>
|
||||
|
||||
it is usually because (1) the <Application>postmaster</Application> is not running,
|
||||
or (2) you are attempting to connect to the wrong server host.
|
||||
If you get the following error message:
|
||||
|
||||
<ProgramListing>
|
||||
FATAL 1:Feb 17 23:19:55:process userid (2360) != database owner (268)
|
||||
</ProgramListing>
|
||||
|
||||
it means that the site administrator started the <Application>postmaster</Application>
|
||||
as the wrong user. Tell him to restart it as
|
||||
the <ProductName>Postgres</ProductName> superuser.
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Managing a Database</Title>
|
||||
|
||||
<Para>
|
||||
Now that <ProductName>Postgres</ProductName> is up and running we can create some
|
||||
databases to experiment with. Here, we describe the
|
||||
basic commands for managing a database.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Most <ProductName>Postgres</ProductName>
|
||||
applications assume that the database name, if not specified, is the same as the name on your computer
|
||||
account.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If your database administrator has set up your account without database creation privileges,
|
||||
then she should have told you what the name of your database is. If this is the case, then you
|
||||
can skip the sections on creating and destroying databases.
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title>Creating a Database</Title>
|
||||
|
||||
<Para>
|
||||
Let's say you want to create a database named <Database>mydb</Database>.
|
||||
You can do this with the following command:
|
||||
<ProgramListing>
|
||||
% createdb mydb
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If you do not have the privileges required to create a database, you will see
|
||||
the following:
|
||||
<ProgramListing>
|
||||
% createdb mydb
|
||||
WARN:user "your username" is not allowed to create/destroy databases
|
||||
createdb: database creation failed on mydb.
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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 32 characters in length.
|
||||
Not every user has authorization to become a database
|
||||
administrator. If <ProductName>Postgres</ProductName> 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.
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Accessing a Database</Title>
|
||||
|
||||
<Para>
|
||||
Once you have constructed a database, you can access it
|
||||
by:
|
||||
|
||||
<ItemizedList Mark="bullet" Spacing="compact">
|
||||
<ListItem>
|
||||
<Para>
|
||||
running the <ProductName>Postgres</ProductName> terminal monitor programs (e.g.
|
||||
<Application>psql</Application>) which allows you to interactively
|
||||
enter, edit, and execute <Acronym>SQL</Acronym> commands.
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para>
|
||||
writing a <Acronym>C</Acronym> program using the LIBPQ subroutine
|
||||
library. This allows you to submit <Acronym>SQL</Acronym> commands
|
||||
from <Acronym>C</Acronym> and get answers and status messages back to
|
||||
your program. This interface is discussed further
|
||||
in <XRef LinkEnd="PROGRAMMERS-GUIDE">.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
You might want to start up <Application>psql</Application>, to try out the examples in this manual.
|
||||
It can be activated for the <Database>mydb</Database>
|
||||
database by typing the command:
|
||||
<ProgramListing>
|
||||
% psql mydb
|
||||
</ProgramListing>
|
||||
|
||||
You will be greeted with the following message:
|
||||
<ProgramListing>
|
||||
Welcome to the POSTGRESQL interactive sql monitor:
|
||||
Please read the file COPYRIGHT for copyright terms of POSTGRESQL
|
||||
|
||||
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: template1
|
||||
|
||||
mydb=>
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
This prompt indicates that the terminal monitor is listening
|
||||
to you and that you can type <Acronym>SQL</Acronym> queries into a
|
||||
workspace maintained by the terminal monitor.
|
||||
The <Application>psql</Application> program responds to escape codes that begin
|
||||
with the backslash character, <Quote>\</Quote> For example, you
|
||||
can get help on the syntax of various
|
||||
<ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> commands by typing:
|
||||
<ProgramListing>
|
||||
mydb=> \h
|
||||
</ProgramListing>
|
||||
|
||||
Once you have finished entering your queries into the
|
||||
workspace, you can pass the contents of the workspace
|
||||
to the <ProductName>Postgres</ProductName> server by typing:
|
||||
<ProgramListing>
|
||||
mydb=> \g
|
||||
</ProgramListing>
|
||||
|
||||
This tells the server to process the query. If you
|
||||
terminate your query with a semicolon, the <Quote>\g</Quote> is not
|
||||
necessary. <Application>psql</Application> will automatically process semicolon terminated queries.
|
||||
To read queries from a file, say myFile, instead of
|
||||
entering them interactively, type:
|
||||
<ProgramListing>
|
||||
mydb=> \i fileName
|
||||
</ProgramListing>
|
||||
|
||||
To get out of <Application>psql</Application> and return to UNIX, type
|
||||
<ProgramListing>
|
||||
mydb=> \q
|
||||
</ProgramListing>
|
||||
|
||||
and <Application>psql</Application> will quit and return you to your command
|
||||
shell. (For more escape codes, type <Command>\h</Command> at the monitor
|
||||
prompt.)
|
||||
White space (i.e., spaces, tabs and newlines) may be
|
||||
used freely in <Acronym>SQL</Acronym> queries. Single-line comments are denoted by
|
||||
<Quote>--</Quote>. Everything after the dashes up to the end of the
|
||||
line is ignored. Multiple-line comments, and comments within a line,
|
||||
are denoted by <Quote>/* ... */</Quote>
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Destroying a Database</Title>
|
||||
|
||||
<Para>
|
||||
If you are the database administrator for the database
|
||||
<Database>mydb</Database>, you can destroy it using the following UNIX command:
|
||||
<ProgramListing>
|
||||
% destroydb mydb
|
||||
</ProgramListing>
|
||||
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 forethought.
|
||||
</Para>
|
||||
</Sect2>
|
||||
</Sect1>
|
||||
|
||||
</Chapter>
|
9
doc/src/sgml/storage.sgml
Normal file
9
doc/src/sgml/storage.sgml
Normal file
@ -0,0 +1,9 @@
|
||||
<Chapter>
|
||||
<Title>Disk Storage</Title>
|
||||
|
||||
<Para>
|
||||
This section needs to be written. Some information is in the FAQ. Volunteers?
|
||||
- thomas 1998-01-11
|
||||
</Para>
|
||||
|
||||
</Chapter>
|
396
doc/src/sgml/trigger.sgml
Normal file
396
doc/src/sgml/trigger.sgml
Normal file
@ -0,0 +1,396 @@
|
||||
<Chapter>
|
||||
<Title>Triggers</Title>
|
||||
|
||||
<Para>
|
||||
While the current version of <ProductName>Postgres</ProductName> has various client interfaces
|
||||
such as Perl, Tcl, Python and C, it lacks an actual <FirstTerm>Procedural Language</FirstTerm>
|
||||
(PL). We hope to have a proper PL one day. In the meantime it is possible
|
||||
to call C functions as trigger actions. Note that STATEMENT-level trigger
|
||||
events are not supported in the current version. You can currently specify
|
||||
BEFORE or AFTER on INSERT, DELETE or UPDATE of a tuple as a trigger event.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Trigger Creation</Title>
|
||||
|
||||
<Para>
|
||||
If a trigger event occurs, the trigger manager (called by the Executor)
|
||||
initializes the global structure TriggerData *CurrentTriggerData (described
|
||||
below) and calls the trigger function to handle the event.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The trigger function must be created before the trigger is created as a
|
||||
function taking no arguments and returns opaque.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The syntax for creating triggers is as follows:
|
||||
|
||||
<ProgramListing>
|
||||
CREATE TRIGGER <trigger name> <BEFORE|AFTER> <INSERT|DELETE|UPDATE>
|
||||
ON <relation name> FOR EACH <ROW|STATEMENT>
|
||||
EXECUTE PROCEDURE <procedure name> (<function args>);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The name of the trigger is used if you ever have to delete the trigger.
|
||||
It is used as an argument to the DROP TRIGGER command.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The next word determines whether the function is called before or after
|
||||
the event.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The next element of the command determines on what event(s) will trigger
|
||||
the function. Multiple events can be specified separated by OR.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The relation name determines which table the event applies to.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The FOR EACH statement determines whether the trigger is fired for each
|
||||
affected row or before (or after) the entire statement has completed.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The procedure name is the C function called.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The args are passed to the function in the CurrentTriggerData structure.
|
||||
The purpose of passing arguments to the function is to allow different
|
||||
triggers with similar requirements to call the same function.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Also, function may be used for triggering different relations (these
|
||||
functions are named as "general trigger functions").
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
As example of using both features above, there could be a general
|
||||
function that takes as its arguments two field names and puts the current
|
||||
user in one and the current timestamp in the other. This allows triggers to
|
||||
be written on INSERT events to automatically track creation of records in a
|
||||
transaction table for example. It could also be used as a "last updated"
|
||||
function if used in an UPDATE event.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Trigger functions return HeapTuple to the calling Executor. This
|
||||
is ignored for triggers fired after an INSERT, DELETE or UPDATE operation
|
||||
but it allows BEFORE triggers to:
|
||||
|
||||
- return NULL to skip the operation for the current tuple (and so the
|
||||
tuple will not be inserted/updated/deleted);
|
||||
- return a pointer to another tuple (INSERT and UPDATE only) which will
|
||||
be inserted (as the new version of the updated tuple if UPDATE) instead
|
||||
of original tuple.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Note, that there is no initialization performed by the CREATE TRIGGER
|
||||
handler. This will be changed in the future. Also, if more than one trigger
|
||||
is defined for the same event on the same relation, the order of trigger
|
||||
firing is unpredictable. This may be changed in the future.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If a trigger function executes SQL-queries (using SPI) then these queries
|
||||
may fire triggers again. This is known as cascading triggers. There is no
|
||||
explicit limitation on the number of cascade levels.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If a trigger is fired by INSERT and inserts a new tuple in the same
|
||||
relation then this trigger will be fired again. Currently, there is nothing
|
||||
provided for synchronization (etc) of these cases but this may change. At
|
||||
the moment, there is function funny_dup17() in the regress tests which uses
|
||||
some techniques to stop recursion (cascading) on itself...
|
||||
</Para>
|
||||
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Interaction with the Trigger Manager</Title>
|
||||
|
||||
<Para>
|
||||
As mentioned above, when function is called by the trigger manager,
|
||||
structure TriggerData *CurrentTriggerData is NOT NULL and initialized. So
|
||||
it is better to check CurrentTriggerData against being NULL at the start
|
||||
and set it to NULL just after fetching the information to prevent calls to
|
||||
a trigger function not from the trigger manager.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
struct TriggerData is defined in src/include/commands/trigger.h:
|
||||
|
||||
<ProgramListing>
|
||||
typedef struct TriggerData
|
||||
{
|
||||
TriggerEvent tg_event;
|
||||
Relation tg_relation;
|
||||
HeapTuple tg_trigtuple;
|
||||
HeapTuple tg_newtuple;
|
||||
Trigger *tg_trigger;
|
||||
} TriggerData;
|
||||
</ProgramListing>
|
||||
|
||||
<ProgramListing>
|
||||
tg_event
|
||||
describes event for which the function is called. You may use the
|
||||
following macros to examine tg_event:
|
||||
|
||||
TRIGGER_FIRED_BEFORE(event) returns TRUE if trigger fired BEFORE;
|
||||
TRIGGER_FIRED_AFTER(event) returns TRUE if trigger fired AFTER;
|
||||
TRIGGER_FIRED_FOR_ROW(event) returns TRUE if trigger fired for
|
||||
ROW-level event;
|
||||
TRIGGER_FIRED_FOR_STATEMENT(event) returns TRUE if trigger fired for
|
||||
STATEMENT-level event;
|
||||
TRIGGER_FIRED_BY_INSERT(event) returns TRUE if trigger fired by INSERT;
|
||||
TRIGGER_FIRED_BY_DELETE(event) returns TRUE if trigger fired by DELETE;
|
||||
TRIGGER_FIRED_BY_UPDATE(event) returns TRUE if trigger fired by UPDATE.
|
||||
|
||||
tg_relation
|
||||
is pointer to structure describing the triggered relation. Look at
|
||||
src/include/utils/rel.h for details about this structure. The most
|
||||
interest things are tg_relation->rd_att (descriptor of the relation
|
||||
tuples) and tg_relation->rd_rel->relname (relation's name. This is not
|
||||
char*, but NameData. Use SPI_getrelname(tg_relation) to get char* if
|
||||
you need a copy of name).
|
||||
|
||||
tg_trigtuple
|
||||
is a pointer to the tuple for which the trigger is fired. This is the tuple
|
||||
being inserted (if INSERT), deleted (if DELETE) or updated (if UPDATE).
|
||||
If INSERT/DELETE then this is what you are to return to Executor if
|
||||
you don't want to replace tuple with another one (INSERT) or skip the
|
||||
operation.
|
||||
|
||||
tg_newtuple
|
||||
is a pointer to the new version of tuple if UPDATE and NULL if this is
|
||||
for an INSERT or a DELETE. This is what you are to return to Executor if
|
||||
UPDATE and you don't want to replace this tuple with another one or skip
|
||||
the operation.
|
||||
|
||||
tg_trigger
|
||||
is pointer to structure Trigger defined in src/include/utils/rel.h:
|
||||
|
||||
typedef struct Trigger
|
||||
{
|
||||
char *tgname;
|
||||
Oid tgfoid;
|
||||
func_ptr tgfunc;
|
||||
int16 tgtype;
|
||||
int16 tgnargs;
|
||||
int16 tgattr[8];
|
||||
char **tgargs;
|
||||
} Trigger;
|
||||
|
||||
tgname is the trigger's name, tgnargs is number of arguments in tgargs,
|
||||
tgargs is an array of pointers to the arguments specified in the CREATE
|
||||
TRIGGER statement. Other members are for internal use only.
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Visibility of Data Changes</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> data changes visibility rule: during a query execution, data
|
||||
changes made by the query itself (via SQL-function, SPI-function, triggers)
|
||||
are invisible to the query scan. For example, in query
|
||||
|
||||
<ProgramListing>
|
||||
INSERT INTO a SELECT * FROM a
|
||||
</ProgramListing>
|
||||
|
||||
tuples inserted are invisible for SELECT' scan. In effect, this
|
||||
duplicates the database table within itself (subject to unique index
|
||||
rules, of course) without recursing.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
But keep in mind this notice about visibility in the SPI documentation:
|
||||
|
||||
<ProgramListing>
|
||||
Changes made by query Q are visible by queries which are started after
|
||||
query Q, no matter whether they are started inside Q (during the
|
||||
execution of Q) or after Q is done.
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
This is true for triggers as well so, though a tuple being inserted
|
||||
(tg_trigtuple) is not visible to queries in a BEFORE trigger, this tuple
|
||||
(just inserted) is visible to queries in an AFTER trigger, and to queries
|
||||
in BEFORE/AFTER triggers fired after this!
|
||||
</Para>
|
||||
</Sect1>
|
||||
|
||||
<Sect1>
|
||||
<Title>Examples</Title>
|
||||
|
||||
<Para>
|
||||
There are more complex examples in in src/test/regress/regress.c and
|
||||
in contrib/spi.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Here is a very simple example of trigger usage. Function trigf reports
|
||||
the number of tuples in the triggered relation ttest and skips the
|
||||
operation if the query attempts to insert NULL into x (i.e - it acts as a
|
||||
NOT NULL constraint but doesn't abort the transaction).
|
||||
|
||||
<ProgramListing>
|
||||
#include "executor/spi.h" /* this is what you need to work with SPI */
|
||||
#include "commands/trigger.h" /* -"- and triggers */
|
||||
|
||||
HeapTuple trigf(void);
|
||||
|
||||
HeapTuple
|
||||
trigf()
|
||||
{
|
||||
TupleDesc tupdesc;
|
||||
HeapTuple rettuple;
|
||||
char *when;
|
||||
bool checknull = false;
|
||||
bool isnull;
|
||||
int ret, i;
|
||||
|
||||
if (!CurrentTriggerData)
|
||||
elog(WARN, "trigf: triggers are not initialized");
|
||||
|
||||
/* tuple to return to Executor */
|
||||
if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))
|
||||
rettuple = CurrentTriggerData->tg_newtuple;
|
||||
else
|
||||
rettuple = CurrentTriggerData->tg_trigtuple;
|
||||
|
||||
/* check for NULLs ? */
|
||||
if (!TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event) &&
|
||||
TRIGGER_FIRED_BEFORE(CurrentTriggerData->tg_event))
|
||||
checknull = true;
|
||||
|
||||
if (TRIGGER_FIRED_BEFORE(CurrentTriggerData->tg_event))
|
||||
when = "before";
|
||||
else
|
||||
when = "after ";
|
||||
|
||||
tupdesc = CurrentTriggerData->tg_relation->rd_att;
|
||||
CurrentTriggerData = NULL;
|
||||
|
||||
/* Connect to SPI manager */
|
||||
if ((ret = SPI_connect()) < 0)
|
||||
elog(WARN, "trigf (fired %s): SPI_connect returned %d", when, ret);
|
||||
|
||||
/* Get number of tuples in relation */
|
||||
ret = SPI_exec("select count(*) from ttest", 0);
|
||||
|
||||
if (ret < 0)
|
||||
elog(WARN, "trigf (fired %s): SPI_exec returned %d", when, ret);
|
||||
|
||||
i = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull);
|
||||
|
||||
elog (NOTICE, "trigf (fired %s): there are %d tuples in ttest", when, i);
|
||||
|
||||
SPI_finish();
|
||||
|
||||
if (checknull)
|
||||
{
|
||||
i = SPI_getbinval(rettuple, tupdesc, 1, &isnull);
|
||||
if (isnull)
|
||||
rettuple = NULL;
|
||||
}
|
||||
|
||||
return (rettuple);
|
||||
}
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Now, compile and
|
||||
create table ttest (x int4);
|
||||
create function trigf () returns opaque as
|
||||
'...path_to_so' language 'c';
|
||||
|
||||
<ProgramListing>
|
||||
vac=> create trigger tbefore before insert or update or delete on ttest
|
||||
for each row execute procedure trigf();
|
||||
CREATE
|
||||
vac=> create trigger tafter after insert or update or delete on ttest
|
||||
for each row execute procedure trigf();
|
||||
CREATE
|
||||
vac=> insert into ttest values (null);
|
||||
NOTICE:trigf (fired before): there are 0 tuples in ttest
|
||||
INSERT 0 0
|
||||
|
||||
-- Insertion skipped and AFTER trigger is not fired
|
||||
|
||||
vac=> select * from ttest;
|
||||
x
|
||||
-
|
||||
(0 rows)
|
||||
|
||||
vac=> insert into ttest values (1);
|
||||
NOTICE:trigf (fired before): there are 0 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 1 tuples in ttest
|
||||
^^^^^^^^
|
||||
remember what we said about visibility.
|
||||
INSERT 167793 1
|
||||
vac=> select * from ttest;
|
||||
x
|
||||
-
|
||||
1
|
||||
(1 row)
|
||||
|
||||
vac=> insert into ttest select x * 2 from ttest;
|
||||
NOTICE:trigf (fired before): there are 1 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 2 tuples in ttest
|
||||
^^^^^^^^
|
||||
remember what we said about visibility.
|
||||
INSERT 167794 1
|
||||
vac=> select * from ttest;
|
||||
x
|
||||
-
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
vac=> update ttest set x = null where x = 2;
|
||||
NOTICE:trigf (fired before): there are 2 tuples in ttest
|
||||
UPDATE 0
|
||||
vac=> update ttest set x = 4 where x = 2;
|
||||
NOTICE:trigf (fired before): there are 2 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 2 tuples in ttest
|
||||
UPDATE 1
|
||||
vac=> select * from ttest;
|
||||
x
|
||||
-
|
||||
1
|
||||
4
|
||||
(2 rows)
|
||||
|
||||
vac=> delete from ttest;
|
||||
NOTICE:trigf (fired before): there are 2 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 1 tuples in ttest
|
||||
NOTICE:trigf (fired before): there are 1 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 0 tuples in ttest
|
||||
^^^^^^^^
|
||||
remember what we said about visibility.
|
||||
DELETE 2
|
||||
vac=> select * from ttest;
|
||||
x
|
||||
-
|
||||
(0 rows)
|
||||
</ProgramListing>
|
||||
|
||||
</Para>
|
||||
</Sect1>
|
||||
</Chapter>
|
94
doc/src/sgml/tutorial.sgml
Normal file
94
doc/src/sgml/tutorial.sgml
Normal file
@ -0,0 +1,94 @@
|
||||
<!-- tutorial.sgml
|
||||
-
|
||||
- Postgres tutorial. Derived from postgres.sgml.
|
||||
- thomas 1998-02-23
|
||||
-
|
||||
- -->
|
||||
<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
|
||||
<!entity intro SYSTEM "intro.sgml">
|
||||
<!entity arch SYSTEM "arch.sgml">
|
||||
<!entity start SYSTEM "start.sgml">
|
||||
<!entity query SYSTEM "query.sgml">
|
||||
<!entity advanced SYSTEM "advanced.sgml">
|
||||
<!entity biblio SYSTEM "biblio.sgml">
|
||||
]>
|
||||
<Book>
|
||||
|
||||
<!-- Title information -->
|
||||
|
||||
<Title>PostgreSQL Tutorial</Title>
|
||||
<BookInfo>
|
||||
<ReleaseInfo>Covering v6.3 for general release</ReleaseInfo>
|
||||
<BookBiblio>
|
||||
<AuthorGroup>
|
||||
<CorpAuthor>The PostgreSQL Development Team</CorpAuthor>
|
||||
</AuthorGroup>
|
||||
<!-- editor in authorgroup is not supported
|
||||
<AuthorGroup>
|
||||
-->
|
||||
<Editor>
|
||||
<FirstName>Thomas</FirstName>
|
||||
<SurName>Lockhart</SurName>
|
||||
<Affiliation>
|
||||
<OrgName>Caltech/JPL</OrgName>
|
||||
</Affiliation>
|
||||
</Editor>
|
||||
<!--
|
||||
</AuthorGroup>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<AuthorInitials>TGL</AuthorInitials>
|
||||
-->
|
||||
|
||||
<Date>(last updated 1998-02-23)</Date>
|
||||
</BookBiblio>
|
||||
|
||||
<LegalNotice>
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> is copyright (C) 1998 by the Postgres Global Development Group.
|
||||
</Para>
|
||||
</LegalNotice>
|
||||
|
||||
</BookInfo>
|
||||
|
||||
<!--
|
||||
<TOC> </TOC>
|
||||
<LOT> </LOT>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<Dedication>
|
||||
<Para>
|
||||
Your name here...
|
||||
</Para>
|
||||
</Dedication>
|
||||
-->
|
||||
|
||||
<Preface>
|
||||
<Title>Summary</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName>,
|
||||
developed originally in the UC Berkeley Computer Science Department,
|
||||
pioneered many of the object-relational concepts
|
||||
now becoming available in some commercial databases.
|
||||
It provides SQL92/SQL3 language support,
|
||||
transaction integrity, and type extensibility.
|
||||
<ProductName>PostgreSQL</ProductName> is a public-domain, open source descendant
|
||||
of this original Berkeley code.
|
||||
</Para>
|
||||
</Preface>
|
||||
|
||||
&intro;
|
||||
&arch;
|
||||
&start;
|
||||
&query;
|
||||
&advanced;
|
||||
|
||||
&biblio;
|
||||
|
||||
<INDEX> </INDEX>
|
||||
|
||||
</Book>
|
||||
|
110
doc/src/sgml/user.sgml
Normal file
110
doc/src/sgml/user.sgml
Normal file
@ -0,0 +1,110 @@
|
||||
<!-- user.sgml
|
||||
-
|
||||
- Postgres User's Manual.
|
||||
- Derived from postgres.sgml.
|
||||
- thomas 1998-02-24
|
||||
-
|
||||
- -->
|
||||
<!doctype book PUBLIC "-//Davenport//DTD DocBook V3.0//EN" [
|
||||
<!entity intro SYSTEM "intro.sgml">
|
||||
<!entity advanced SYSTEM "advanced.sgml">
|
||||
<!entity environ SYSTEM "environ.sgml">
|
||||
<!entity manage SYSTEM "manage.sgml">
|
||||
<!entity datatype SYSTEM "datatype.sgml">
|
||||
<!entity array SYSTEM "array.sgml">
|
||||
<!entity inherit SYSTEM "inherit.sgml">
|
||||
<!entity query-ug SYSTEM "query-ug.sgml">
|
||||
<!entity storage SYSTEM "storage.sgml">
|
||||
<!entity psql SYSTEM "psql.sgml">
|
||||
<!entity pgaccess SYSTEM "pgaccess.sgml">
|
||||
<!entity biblio SYSTEM "biblio.sgml">
|
||||
]>
|
||||
<!-- entity manpages SYSTEM "man/manpages.sgml" subdoc -->
|
||||
<Book>
|
||||
|
||||
<!-- Title information -->
|
||||
|
||||
<Title>PostgreSQL User's Guide</Title>
|
||||
<BookInfo>
|
||||
<ReleaseInfo>Covering v6.3 for general release</ReleaseInfo>
|
||||
<BookBiblio>
|
||||
<AuthorGroup>
|
||||
<CorpAuthor>The PostgreSQL Development Team</CorpAuthor>
|
||||
</AuthorGroup>
|
||||
<!-- editor in authorgroup is not supported
|
||||
<AuthorGroup>
|
||||
-->
|
||||
<Editor>
|
||||
<FirstName>Thomas</FirstName>
|
||||
<SurName>Lockhart</SurName>
|
||||
<Affiliation>
|
||||
<OrgName>Caltech/JPL</OrgName>
|
||||
</Affiliation>
|
||||
</Editor>
|
||||
<!--
|
||||
</AuthorGroup>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<AuthorInitials>TGL</AuthorInitials>
|
||||
-->
|
||||
|
||||
<Date>(last updated 1998-02-23)</Date>
|
||||
</BookBiblio>
|
||||
|
||||
<LegalNotice>
|
||||
<Para>
|
||||
<ProductName>PostgreSQL</ProductName> is copyright (C) 1998 by the Postgres Global Development Group.
|
||||
</Para>
|
||||
</LegalNotice>
|
||||
|
||||
</BookInfo>
|
||||
|
||||
<!--
|
||||
<TOC> </TOC>
|
||||
<LOT> </LOT>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<Dedication>
|
||||
<Para>
|
||||
Your name here...
|
||||
</Para>
|
||||
</Dedication>
|
||||
-->
|
||||
|
||||
<Preface>
|
||||
<Title>Summary</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName>,
|
||||
developed originally in the UC Berkeley Computer Science Department,
|
||||
pioneered many of the object-relational concepts
|
||||
now becoming available in some commercial databases.
|
||||
It provides SQL92/SQL3 language support,
|
||||
transaction integrity, and type extensibility.
|
||||
<ProductName>PostgreSQL</ProductName> is a public-domain, open source descendant
|
||||
of this original Berkeley code.
|
||||
</Para>
|
||||
</Preface>
|
||||
|
||||
&intro;
|
||||
&environ;
|
||||
&manage;
|
||||
&datatype;
|
||||
&array;
|
||||
&inherit;
|
||||
&query-ug;
|
||||
&storage;
|
||||
&psql;
|
||||
&pgaccess;
|
||||
|
||||
<!--
|
||||
&contacts;
|
||||
-->
|
||||
&biblio;
|
||||
|
||||
<INDEX> </INDEX>
|
||||
|
||||
</Book>
|
||||
|
95
doc/src/sgml/xaggr.sgml
Normal file
95
doc/src/sgml/xaggr.sgml
Normal file
@ -0,0 +1,95 @@
|
||||
<Chapter>
|
||||
<Title>Extending <Acronym>SQL</Acronym>: Aggregates</Title>
|
||||
|
||||
<Para>
|
||||
Aggregates in <ProductName>Postgres</ProductName> 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 (<Acronym>sfunc1</Acronym> in the create aggregate syntax) while
|
||||
others only keep track of their own internal state
|
||||
(<Acronym>sfunc2</Acronym>).
|
||||
If we define an aggregate that uses only <Acronym>sfunc1</Acronym>, 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 <Acronym>int4pl</Acronym> that is
|
||||
built into <ProductName>Postgres</ProductName> to perform this addition.
|
||||
|
||||
<ProgramListing>
|
||||
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) |
|
||||
+------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
If we define only <Acronym>sfunc2</Acronym>, 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 <Acronym>int4inc</Acronym> routine to do
|
||||
the work for us. This routine increments (adds one to)
|
||||
its argument.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE AGGREGATE my_count (sfunc2 = int4inc, -- add one
|
||||
basetype = int4, stype2 = int4,
|
||||
initcond2 = '0')
|
||||
|
||||
SELECT my_count(*) as emp_count from EMP;
|
||||
|
||||
+----------+
|
||||
|emp_count |
|
||||
+----------+
|
||||
|5 |
|
||||
+----------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
"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 <Acronym>int4pl</Acronym> and <Acronym>int4inc</Acronym> routines we used
|
||||
before as well as the <ProductName>Postgres</ProductName> integer division
|
||||
routine, <Acronym>int4div</Acronym>, to compute the division of the sum by
|
||||
the count.
|
||||
|
||||
<ProgramListing>
|
||||
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 |
|
||||
+------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Chapter>
|
533
doc/src/sgml/xfunc.sgml
Normal file
533
doc/src/sgml/xfunc.sgml
Normal file
@ -0,0 +1,533 @@
|
||||
<Chapter>
|
||||
<Title>Extending <Acronym>SQL</Acronym>: Functions</Title>
|
||||
|
||||
<Para>
|
||||
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 <ProductName>Postgres</ProductName> before describing how to add new
|
||||
types.
|
||||
<ProductName>Postgres</ProductName> <Acronym>SQL</Acronym> provides two types of functions: query
|
||||
language functions (functions written in <Acronym>SQL</Acronym> and
|
||||
programming language functions (functions written in a
|
||||
compiled programming language such as <Acronym>C</Acronym>.) 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 <Acronym>SQL</Acronym> functions,
|
||||
so we'll start with those.
|
||||
Examples in this section can also be found in <FileName>funcs.sql</FileName>
|
||||
and <FileName>C-code/funcs.c</FileName>.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Query Language (<Acronym>SQL</Acronym>) Functions</Title>
|
||||
|
||||
<Sect2>
|
||||
<Title><Acronym>SQL</Acronym> Functions on Base Types</Title>
|
||||
|
||||
<Para>
|
||||
The simplest possible <Acronym>SQL</Acronym> function has no arguments and
|
||||
simply returns a base type, such as <Acronym>int4</Acronym>:
|
||||
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION one() RETURNS int4
|
||||
AS 'SELECT 1 as RESULT' LANGUAGE 'sql';
|
||||
|
||||
SELECT one() AS answer;
|
||||
|
||||
+-------+
|
||||
|answer |
|
||||
+-------+
|
||||
|1 |
|
||||
+-------+
|
||||
</ProgramListing>
|
||||
|
||||
</Para>
|
||||
<Para>
|
||||
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.
|
||||
</Para>
|
||||
<Para>
|
||||
It's almost as easy to define <Acronym>SQL</Acronym> functions that take
|
||||
base types as arguments. In the example below, notice
|
||||
how we refer to the arguments within the function as $1
|
||||
and $2.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION add_em(int4, int4) RETURNS int4
|
||||
AS 'SELECT $1 + $2;' LANGUAGE 'sql';
|
||||
|
||||
SELECT add_em(1, 2) AS answer;
|
||||
|
||||
+-------+
|
||||
|answer |
|
||||
+-------+
|
||||
|3 |
|
||||
+-------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title><Acronym>SQL</Acronym> Functions on Composite Types</Title>
|
||||
|
||||
<Para>
|
||||
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 $1 and $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.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION double_salary(EMP) RETURNS int4
|
||||
AS 'SELECT $1.salary * 2 AS salary;' LANGUAGE 'sql';
|
||||
|
||||
SELECT name, double_salary(EMP) AS dream
|
||||
FROM EMP
|
||||
WHERE EMP.dept = 'toy';
|
||||
|
||||
+-----+-------+
|
||||
|name | dream |
|
||||
+-----+-------+
|
||||
|Sam | 2400 |
|
||||
+-----+-------+
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
Notice the use of the syntax $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.
|
||||
|
||||
<ProgramListing>
|
||||
--
|
||||
-- this is the same as:
|
||||
-- SELECT EMP.name AS youngster FROM EMP WHERE EMP.age < 30
|
||||
--
|
||||
SELECT name(EMP) AS youngster
|
||||
FROM EMP
|
||||
WHERE age(EMP) < 30;
|
||||
|
||||
+----------+
|
||||
|youngster |
|
||||
+----------+
|
||||
|Sam |
|
||||
+----------+
|
||||
</ProgramListing>
|
||||
|
||||
<Para>
|
||||
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:
|
||||
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION new_emp() RETURNS EMP
|
||||
AS 'SELECT \'None\'::text AS name,
|
||||
1000 AS salary,
|
||||
25 AS age,
|
||||
\'none\'::char16 AS dept;'
|
||||
LANGUAGE 'sql';
|
||||
</ProgramListing>
|
||||
|
||||
</Para>
|
||||
<Para>
|
||||
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:
|
||||
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
The target list order must be exactly the same as
|
||||
that in which the attributes appear in the CREATE
|
||||
TABLE statement (or when you execute a .* query).
|
||||
</Para>
|
||||
<ListItem>
|
||||
<Para>
|
||||
You must typecast the expressions
|
||||
(using ::) very carefully or you will see the following error:
|
||||
|
||||
<ProgramListing>
|
||||
WARN::function declared to return type EMP does not retrieve (EMP.*)
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
<ListItem>
|
||||
<Para>
|
||||
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.
|
||||
<ProgramListing>
|
||||
SELECT name(new_emp()) AS nobody;
|
||||
|
||||
+-------+
|
||||
|nobody |
|
||||
+-------+
|
||||
|None |
|
||||
+-------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
<ListItem>
|
||||
<Para>
|
||||
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.
|
||||
|
||||
<ProgramListing>
|
||||
SELECT new_emp().name AS nobody;
|
||||
WARN:parser: syntax error at or near "."
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</ItemizedList>
|
||||
|
||||
<Para>
|
||||
Any collection of commands in the <Acronym>SQL</Acronym> query language
|
||||
can be packaged together and defined as a function.
|
||||
The commands can include updates (i.e., <Acronym>insert</Acronym>, <Acronym>update</Acronym>
|
||||
and <Acronym>delete</Acronym>) as well as <Acronym>select</Acronym> queries. However, the
|
||||
final command must be a <Acronym>select</Acronym> that returns whatever is
|
||||
specified as the function's returntype.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION clean_EMP () RETURNS int4
|
||||
AS 'DELETE FROM EMP WHERE EMP.salary <= 0;
|
||||
SELECT 1 AS ignore_this'
|
||||
LANGUAGE 'sql';
|
||||
|
||||
SELECT clean_EMP();
|
||||
|
||||
+--+
|
||||
|x |
|
||||
+--+
|
||||
|1 |
|
||||
+--+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>Programming Language Functions</Title>
|
||||
|
||||
<Sect2>
|
||||
<Title>Programming Language Functions on Base Types</Title>
|
||||
|
||||
<Para>
|
||||
Internally, <ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName> can
|
||||
operate on it. That is, <ProductName>Postgres</ProductName> 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:
|
||||
<ItemizedList>
|
||||
<ListItem><Para>pass by value, fixed-length</Para>
|
||||
<ListItem><Para>pass by reference, fixed-length</Para>
|
||||
<ListItem><Para>pass by reference, variable-length</Para>
|
||||
</ItemizedList>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
By-value types can only be 1, 2 or 4 bytes in length
|
||||
(even if your computer supports by-value types of other
|
||||
sizes). <ProductName>Postgres</ProductName> 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 <Acronym>long</Acronym> type is dangerous
|
||||
because it is 4 bytes on some machines and 8 bytes on
|
||||
others, whereas <Acronym>int</Acronym> type is 4 bytes on most <Acronym>UNIX</Acronym>
|
||||
machines (though not on most personal computers). A
|
||||
reasonable implementation of the <Acronym>int4</Acronym> type on <Acronym>UNIX</Acronym>
|
||||
machines might be:
|
||||
|
||||
<ProgramListing>
|
||||
/* 4-byte integer, passed by value */
|
||||
typedef int int4;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
On the other hand, fixed-length types of any size may
|
||||
be passed by-reference. For example, here is a sample
|
||||
implementation of the <ProductName>Postgres</ProductName> char16 type:
|
||||
|
||||
<ProgramListing>
|
||||
/* 16-byte structure, passed by reference */
|
||||
typedef struct {
|
||||
char data[16];
|
||||
} char16;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Only pointers to such types can be used when passing
|
||||
them in and out of <ProductName>Postgres</ProductName> 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:
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProgramListing>
|
||||
typedef struct {
|
||||
int4 length;
|
||||
char data[1];
|
||||
} text;
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Obviously, the data field is not long enough to hold
|
||||
all possible strings -- it's impossible to declare such
|
||||
a structure in <Acronym>C</Acronym>. 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:
|
||||
<ProgramListing>
|
||||
#include "postgres.h"
|
||||
#include "utils/palloc.h"
|
||||
...
|
||||
char buffer[40]; /* our source data */
|
||||
...
|
||||
text *destination = (text *) palloc(VARHDRSZ + 40);
|
||||
destination->length = VARHDRSZ + 40;
|
||||
memmove(destination->data, buffer, 40);
|
||||
...
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Now that we've gone over all of the possible structures
|
||||
for base types, we can show some examples of real functions.
|
||||
Suppose <FileName>funcs.c</FileName> look like:
|
||||
<ProgramListing>
|
||||
#include <string.h>
|
||||
#include "postgres.h" /* for char16, etc. */
|
||||
#include "utils/palloc.h" /* for palloc */
|
||||
int
|
||||
add_one(int arg)
|
||||
{
|
||||
return(arg + 1);
|
||||
}
|
||||
char16 *
|
||||
concat16(char16 *arg1, char16 *arg2)
|
||||
{
|
||||
char16 *new_c16 = (char16 *) palloc(sizeof(char16));
|
||||
memset((void *) new_c16, 0, sizeof(char16));
|
||||
(void) strncpy(new_c16, arg1, 16);
|
||||
return (char16 *)(strncat(new_c16, arg2, 16));
|
||||
}
|
||||
text *
|
||||
copytext(text *t)
|
||||
{
|
||||
/*
|
||||
* VARSIZE is the total size of the struct in bytes.
|
||||
*/
|
||||
text *new_t = (text *) palloc(VARSIZE(t));
|
||||
memset(new_t, 0, VARSIZE(t));
|
||||
VARSIZE(new_t) = VARSIZE(t);
|
||||
/*
|
||||
* VARDATA is a pointer to the data region of the struct.
|
||||
*/
|
||||
memcpy((void *) VARDATA(new_t), /* destination */
|
||||
(void *) VARDATA(t), /* source */
|
||||
VARSIZE(t)-VARHDRSZ); /* how many bytes */
|
||||
return(new_t);
|
||||
}
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
On <Acronym>OSF/1</Acronym> we would type:
|
||||
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION add_one(int4) RETURNS int4
|
||||
AS 'PGROOT/tutorial/obj/funcs.so' LANGUAGE 'c';
|
||||
|
||||
CREATE FUNCTION concat16(char16, char16) RETURNS char16
|
||||
AS 'PGROOT/tutorial/obj/funcs.so' LANGUAGE 'c';
|
||||
|
||||
CREATE FUNCTION copytext(text) RETURNS text
|
||||
AS 'PGROOT/tutorial/obj/funcs.so' LANGUAGE 'c';
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
On other systems, we might have to make the filename
|
||||
end in .sl (to indicate that it's a shared library).
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Programming Language Functions on Composite Types</Title>
|
||||
|
||||
<Para>
|
||||
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, <ProductName>Postgres</ProductName> provides a procedural
|
||||
interface for accessing fields of composite types from
|
||||
C.
|
||||
As <ProductName>Postgres</ProductName> processes a set of instances, each instance
|
||||
will be passed into your function as an opaque structure of type <Acronym>TUPLE</Acronym>.
|
||||
Suppose we want to write a function to answer the query
|
||||
<ProgramListing>
|
||||
* SELECT name, c_overpaid(EMP, 1500) AS overpaid
|
||||
FROM EMP
|
||||
WHERE name = 'Bill' or name = 'Sam';
|
||||
</ProgramListing>
|
||||
In the query above, we can define c_overpaid as:
|
||||
|
||||
<ProgramListing>
|
||||
#include "postgres.h" /* for char16, etc. */
|
||||
#include "libpq-fe.h" /* for TUPLE */
|
||||
bool
|
||||
c_overpaid(TUPLE t,/* the current instance of EMP */
|
||||
int4 limit)
|
||||
{
|
||||
bool isnull = false;
|
||||
int4 salary;
|
||||
salary = (int4) GetAttributeByName(t, "salary", &isnull);
|
||||
if (isnull)
|
||||
return (false);
|
||||
return(salary > limit);
|
||||
}
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<Acronym>GetAttributeByName</Acronym> is the <ProductName>Postgres</ProductName> 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. <Acronym>GetAttributeByName</Acronym> 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 <Acronym>GetAttributeByName</Acronym> call would look
|
||||
like:
|
||||
<ProgramListing>
|
||||
char *str;
|
||||
...
|
||||
str = (char *) GetAttributeByName(t, "name", &isnull)
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The following query lets <ProductName>Postgres</ProductName> know about the
|
||||
c_overpaid function:
|
||||
<ProgramListing>
|
||||
* CREATE FUNCTION c_overpaid(EMP, int4) RETURNS bool
|
||||
AS 'PGROOT/tutorial/obj/funcs.so' LANGUAGE 'c';
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
</Para>
|
||||
</Sect2>
|
||||
|
||||
<Sect2>
|
||||
<Title>Caveats</Title>
|
||||
|
||||
<Para>
|
||||
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 <Acronym>C</Acronym> (including the use of
|
||||
pointers and the malloc memory manager) before trying
|
||||
to write <Acronym>C</Acronym> functions for use with <ProductName>Postgres</ProductName>.
|
||||
While it may be possible to load functions written in
|
||||
languages other than <Acronym>C</Acronym> into <ProductName>Postgres</ProductName>, this is often
|
||||
difficult (when it is possible at all) because other
|
||||
languages, such as <Acronym>FORTRAN</Acronym> and <Acronym>Pascal</Acronym> often do not follow
|
||||
the same "calling convention" as <Acronym>C</Acronym>. 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 <Acronym>C</Acronym>.
|
||||
The basic rules for building <Acronym>C</Acronym> functions are as follows:
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para>
|
||||
Most of the header (include) files for <ProductName>Postgres</ProductName>
|
||||
should already be installed in
|
||||
<FileName>PGROOT/include</FileName> (see Figure 2).
|
||||
You should always include
|
||||
|
||||
<ProgramListing>
|
||||
-I$PGROOT/include
|
||||
</ProgramListing>
|
||||
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
|
||||
<ProgramListing>
|
||||
-I$PGROOT/src/backend
|
||||
-I$PGROOT/src/backend/include
|
||||
-I$PGROOT/src/backend/port/<PORTNAME>
|
||||
-I$PGROOT/src/backend/obj
|
||||
</ProgramListing>
|
||||
(where <PORTNAME> is the name of the port, e.g.,
|
||||
alpha or sparc).
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para> When allocating memory, use the <ProductName>Postgres</ProductName>
|
||||
routines palloc and pfree instead of the
|
||||
corresponding <Acronym>C</Acronym> library routines malloc and free.
|
||||
The memory allocated by palloc will be freed
|
||||
automatically at the end of each transaction,
|
||||
preventing memory leaks.
|
||||
</Para>
|
||||
<ListItem>
|
||||
<Para> 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.
|
||||
</Para>
|
||||
<ListItem>
|
||||
<Para> Most of the internal <ProductName>Postgres</ProductName> types are declared
|
||||
in postgres.h, so it's usually a good idea to
|
||||
include that file as well.
|
||||
</Para>
|
||||
<ListItem>
|
||||
<Para> Compiling and loading your object code so that
|
||||
it can be dynamically loaded into <ProductName>Postgres</ProductName>
|
||||
always requires special flags. See Appendix A
|
||||
for a detailed explanation of how to do it for
|
||||
your particular operating system.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
</Para>
|
||||
</Sect2>
|
515
doc/src/sgml/xindex.sgml
Normal file
515
doc/src/sgml/xindex.sgml
Normal file
@ -0,0 +1,515 @@
|
||||
<Chapter>
|
||||
<Title>Interfacing Extensions To Indices</Title>
|
||||
|
||||
<Para>
|
||||
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 <Acronym>B-tree</Acronym>,
|
||||
<Acronym>R-tree</Acronym> or hash access method) over a new type or its
|
||||
operators.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Look back at
|
||||
<XRef LinkEnd="EXTEND-CATALOGS" EndTerm="EXTEND-CATALOGS">.
|
||||
The right half shows the catalogs
|
||||
that we must modify in order to tell <ProductName>Postgres</ProductName> how
|
||||
to use a user-defined type and/or user-defined operators
|
||||
with an index (i.e., <FileName>pg_am, pg_amop, pg_amproc</FileName> and
|
||||
<FileName>pg_opclass</FileName>). 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 <Acronym>B-tree</Acronym> access method that sorts integers
|
||||
in ascending absolute value order.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The <FileName>pg_am</FileName> class contains one instance for every user
|
||||
defined access method. Support for the heap access
|
||||
method is built into <ProductName>Postgres</ProductName>, but every other access
|
||||
method is described here. The schema is
|
||||
|
||||
<TABLE TOCENTRY="1">
|
||||
<Title>Index Schema</Title>
|
||||
<TitleAbbrev>Indices</TitleAbbrev>
|
||||
<TGroup Cols="2">
|
||||
<THead>
|
||||
<Row>
|
||||
<Entry>Attribute</Entry>
|
||||
<Entry>Description</Entry>
|
||||
</Row>
|
||||
</THead>
|
||||
<TBody>
|
||||
<Row>
|
||||
<Entry>amname</Entry>
|
||||
<Entry>name of the access method</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>amowner</Entry>
|
||||
<Entry>object id of the owner's instance in pg_user</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>amkind</Entry>
|
||||
<Entry>not used at present, but set to 'o' as a place holder</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>amstrategies</Entry>
|
||||
<Entry>number of strategies for this access method (see below)</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>amsupport</Entry>
|
||||
<Entry>number of support routines for this access method (see below)</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>amgettuple
|
||||
aminsert
|
||||
...</Entry>
|
||||
|
||||
<Entry>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. </Entry>
|
||||
</Row>
|
||||
</TBody>
|
||||
</TGroup>
|
||||
</TABLE>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The <Acronym>object ID</Acronym> of the instance in <FileName>pg_am</FileName> 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 <Acronym>object ID</Acronym> of the access method instance
|
||||
you want to extend:
|
||||
|
||||
<ProgramListing>
|
||||
SELECT oid FROM pg_am WHERE amname = 'btree';
|
||||
|
||||
+----+
|
||||
|oid |
|
||||
+----+
|
||||
|403 |
|
||||
+----+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The <FileName>amstrategies</FileName> attribute exists to standardize
|
||||
comparisons across data types. For example, <Acronym>B-tree</Acronym>s
|
||||
impose a strict ordering on keys, lesser to greater.
|
||||
Since <ProductName>Postgres</ProductName> allows the user to define operators,
|
||||
<ProductName>Postgres</ProductName> cannot look at the name of an operator (eg, ">"
|
||||
or "<") and tell what kind of comparison it is. In fact,
|
||||
some access methods don't impose any ordering at all.
|
||||
For example, <Acronym>R-tree</Acronym>s express a rectangle-containment
|
||||
relationship, whereas a hashed data structure expresses
|
||||
only bitwise similarity based on the value of a hash
|
||||
function. <ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName> needs to know, for example, that
|
||||
the "<=" and ">" operators partition a <Acronym>B-tree</Acronym>. <ProductName>Postgres</ProductName>
|
||||
uses strategies to express these relationships between
|
||||
operators and the way they can be used to scan indices.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Defining a new set of strategies is beyond the scope of
|
||||
this discussion, but we'll explain how <Acronym>B-tree</Acronym> strategies
|
||||
work because you'll need to know that to add a new
|
||||
operator class. In the <FileName>pg_am</FileName> class, the amstrategies
|
||||
attribute is the number of strategies defined for this
|
||||
access method. For <Acronym>B-tree</Acronym>s, this number is 5. These
|
||||
strategies correspond to
|
||||
|
||||
<TABLE TOCENTRY="1">
|
||||
<Title>B-tree Strategies</Title>
|
||||
<TitleAbbrev>B-tree</TitleAbbrev>
|
||||
<TGroup Cols="2">
|
||||
<THead>
|
||||
<Row>
|
||||
<Entry>Operation</Entry>
|
||||
<Entry>Index</Entry>
|
||||
</Row>
|
||||
</THead>
|
||||
<TBody>
|
||||
<Row>
|
||||
<Entry>less than</Entry>
|
||||
<Entry>1</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>less than or equal</Entry>
|
||||
<Entry>2</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>equal</Entry>
|
||||
<Entry>3</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>greater than or equal</Entry>
|
||||
<Entry>4</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>greater than</Entry>
|
||||
<Entry>5</Entry>
|
||||
</Row>
|
||||
</TBody>
|
||||
</TGroup>
|
||||
</TABLE>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The idea is that you'll need to add procedures corresponding
|
||||
to the comparisons above to the <FileName>pg_amop</FileName> relation
|
||||
(see below). The access method code can use these
|
||||
strategy numbers, regardless of data type, to figure
|
||||
out how to partition the <Acronym>B-tree</Acronym>, 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 <FileName>int2, int4, oid,</FileName> and every
|
||||
other data type on which a <Acronym>B-tree</Acronym> can operate.
|
||||
|
||||
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 <Acronym>B-tree</Acronym> 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 <Acronym>R-tree</Acronym> 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.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
In order to manage diverse support routines
|
||||
consistently across all <ProductName>Postgres</ProductName> access methods, <FileName>pg_am</FileName>
|
||||
includes an attribute called <FileName>amsupport</FileName>. This attribute
|
||||
records the number of support routines used by an
|
||||
access method. For <Acronym>B-tree</Acronym>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.
|
||||
<Note>
|
||||
<Para>
|
||||
Strictly speaking, this routine can return a negative
|
||||
number (< 0), 0, or a non-zero positive number (> 0).
|
||||
</Para>
|
||||
</Note>
|
||||
|
||||
<Para>
|
||||
The <FileName>amstrategies</FileName> 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 <FileName>pg_am</FileName>. Similarly, <FileName>amsupport</FileName> is just
|
||||
the number of support routines required by the access
|
||||
method. The actual routines are listed elsewhere.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The next class of interest is pg_opclass. This class
|
||||
exists only to associate a name with an oid. In
|
||||
pg_amop, every <Acronym>B-tree</Acronym> operator class has a set of
|
||||
procedures, one through five, above. Some existing
|
||||
opclasses are <FileName>int2_ops, int4_ops, and oid_ops</FileName>. You
|
||||
need to add an instance with your opclass name (for
|
||||
example, <FileName>complex_abs_ops</FileName>) to <FileName>pg_opclass</FileName>. The <FileName>oid</FileName> of
|
||||
this instance is a foreign key in other classes.
|
||||
|
||||
<ProgramListing>
|
||||
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 |
|
||||
+------+--------------+
|
||||
</ProgramListing>
|
||||
|
||||
Note that the oid for your <FileName>pg_opclass</FileName> instance will be
|
||||
different! You should substitute your value for 17314
|
||||
wherever it appears in this discussion.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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:
|
||||
|
||||
<ProgramListing>
|
||||
absolute value less-than
|
||||
absolute value less-than-or-equal
|
||||
absolute value equal
|
||||
absolute value greater-than-or-equal
|
||||
absolute value greater-than
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Suppose the code that implements the functions defined
|
||||
is stored in the file
|
||||
<FileName>PGROOT/src/tutorial/complex.c</FileName>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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 <FileName>complex.c</FileName> or <FileName>complex.sql</FileName> for the details.)
|
||||
|
||||
<ProgramListing>
|
||||
#define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
|
||||
|
||||
bool
|
||||
complex_abs_eq(Complex *a, Complex *b)
|
||||
{
|
||||
double amag = Mag(a), bmag = Mag(b);
|
||||
return (amag==bmag);
|
||||
}
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
There are a couple of important things that are happening below.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
First, note that operators for less-than, less-than-or
|
||||
equal, equal, greater-than-or-equal, and greater-than
|
||||
for <FileName>int4</FileName> are being defined. All of these operators are
|
||||
already defined for <FileName>int4</FileName> under the names <, <=, =, >=,
|
||||
and >. The new operators behave differently, of
|
||||
course. In order to guarantee that <ProductName>Postgres</ProductName> 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 <ProductName>Postgres</ProductName>, but only
|
||||
if the operator isn't already defined for the argument
|
||||
types. That is, if you have < defined for (int4,
|
||||
int4), you can't define it again. <ProductName>Postgres</ProductName> 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.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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 <FileName>pg_am</FileName> class. We will use this later on. For now,
|
||||
ignore it.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION complex_abs_eq(complex, complex)
|
||||
RETURNS bool
|
||||
AS 'PGROOT/tutorial/obj/complex.so'
|
||||
LANGUAGE 'c';
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Now define the operators that use them. As noted, the
|
||||
operator names must be unique among all operators that
|
||||
take two <FileName>int4</FileName> operands. In order to see if the
|
||||
operator names listed below are taken, we can do a query on
|
||||
<FileName>pg_operator</FileName>:
|
||||
|
||||
<ProgramListing>
|
||||
/*
|
||||
* this query uses the regular expression operator (~)
|
||||
* to find three-character operator names that end in
|
||||
* the character &
|
||||
*/
|
||||
SELECT *
|
||||
FROM pg_operator
|
||||
WHERE oprname ~ '^..&$'::text;
|
||||
</ProgramListing>
|
||||
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
to see if your name is taken for the types you want.
|
||||
The important things here are the procedure (which are
|
||||
the <Acronym>C</Acronym> 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.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE OPERATOR = (
|
||||
leftarg = complex, rightarg = complex,
|
||||
procedure = complex_abs_eq,
|
||||
restrict = eqsel, join = eqjoinsel
|
||||
)
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Notice that five operators corresponding to less, less
|
||||
equal, equal, greater, and greater equal are defined.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
We're just about finished. the last thing we need to do
|
||||
is to update the <FileName>pg_amop</FileName> relation. To do this, we need
|
||||
the following attributes:
|
||||
|
||||
<TABLE TOCENTRY="1">
|
||||
<Title><FileName>pg_amproc</FileName> Schema</Title>
|
||||
<TitleAbbrev><FileName>pg_amproc</FileName></TitleAbbrev>
|
||||
<TGroup Cols="2">
|
||||
<THead>
|
||||
<Row>
|
||||
<Entry>Attribute</Entry>
|
||||
<Entry>Description</Entry>
|
||||
</Row>
|
||||
</THead>
|
||||
<TBody>
|
||||
<Row>
|
||||
<Entry>amopid</Entry>
|
||||
<Entry>the <FileName>oid</FileName> of the <FileName>pg_am</FileName> instance
|
||||
for B-tree (== 403, see above)</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>amopclaid</Entry>
|
||||
<Entry>the <FileName>oid</FileName> of the
|
||||
<FileName>pg_opclass</FileName> instance for <FileName>int4_abs_ops</FileName>
|
||||
(== whatever you got instead of <FileName>17314</FileName>, see above)</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>amopopr</Entry>
|
||||
<Entry>the <FileName>oid</FileName>s of the operators for the opclass
|
||||
(which we'll get in just a minute)</Entry>
|
||||
</Row>
|
||||
<Row>
|
||||
<Entry>amopselect, amopnpages</Entry>
|
||||
<Entry>cost functions</Entry>
|
||||
</Row>
|
||||
</TBody>
|
||||
</TGroup>
|
||||
</TABLE>
|
||||
|
||||
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 <FileName>btreesel</FileName>, which estimates the selectivity
|
||||
of the <Acronym>B-tree</Acronym>, and <FileName>btreenpage</FileName>, which estimates the
|
||||
number of pages a search will touch in the tree.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
So we need the <FileName>oid</FileName>s of the operators we just defined.
|
||||
We'll look up the names of all the operators that take
|
||||
two <FileName>int4</FileName>s, and pick ours out:
|
||||
|
||||
<ProgramListing>
|
||||
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';
|
||||
|
||||
+------+---------+
|
||||
|oid | oprname |
|
||||
+------+---------+
|
||||
|17321 | < |
|
||||
+------+---------+
|
||||
|17322 | <= |
|
||||
+------+---------+
|
||||
|17323 | = |
|
||||
+------+---------+
|
||||
|17324 | >= |
|
||||
+------+---------+
|
||||
|17325 | > |
|
||||
+------+---------+
|
||||
</ProgramListing>
|
||||
|
||||
(Again, some of your <FileName>oid</FileName> numbers will almost certainly
|
||||
be different.) The operators we are interested in are
|
||||
those with <FileName>oid</FileName>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.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
Now we're ready to update <FileName>pg_amop</FileName> 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 <FileName>pg_amop</FileName>. We add the
|
||||
instances we need:
|
||||
|
||||
<ProgramListing>
|
||||
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 = '=';
|
||||
</ProgramListing>
|
||||
|
||||
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.
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
The last step (finally!) is registration of the
|
||||
"support routine" previously described in our discussion of
|
||||
<FileName>pg_am</FileName>. The <FileName>oid</FileName> of this support routine is stored in
|
||||
the <FileName>pg_amproc</FileName> class, keyed by the access method <FileName>oid</FileName> and
|
||||
the operator class <FileName>oid</FileName>. First, we need to register the
|
||||
function in <ProductName>Postgres</ProductName> (recall that we put the <Acronym>C</Acronym> code
|
||||
that implements this routine in the bottom of the file
|
||||
in which we implemented the operator routines):
|
||||
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION int4_abs_cmp(int4, int4)
|
||||
RETURNS int4
|
||||
AS 'PGROOT/tutorial/obj/complex.so'
|
||||
LANGUAGE 'c';
|
||||
|
||||
SELECT oid, proname FROM pg_proc
|
||||
WHERE prname = 'int4_abs_cmp';
|
||||
|
||||
+------+--------------+
|
||||
|oid | proname |
|
||||
+------+--------------+
|
||||
|17328 | int4_abs_cmp |
|
||||
+------+--------------+
|
||||
</ProgramListing>
|
||||
|
||||
(Again, your <FileName>oid</FileName> number will probably be different and
|
||||
you should substitute the value you see for the value
|
||||
below.) Recalling that the <Acronym>B-tree</Acronym> instance's oid is
|
||||
403 and that of <FileName>int4_abs_ops</FileName> is 17314, we can add the
|
||||
new instance as follows:
|
||||
|
||||
<ProgramListing>
|
||||
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);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Chapter>
|
52
doc/src/sgml/xoper.sgml
Normal file
52
doc/src/sgml/xoper.sgml
Normal file
@ -0,0 +1,52 @@
|
||||
<Chapter>
|
||||
<Title>Extending <Acronym>SQL</Acronym>: Operators</Title>
|
||||
|
||||
<Para>
|
||||
<ProductName>Postgres</ProductName> 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.
|
||||
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION complex_add(complex, complex)
|
||||
RETURNS complex
|
||||
AS '$PWD/obj/complex.so'
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE OPERATOR + (
|
||||
leftarg = complex,
|
||||
rightarg = complex,
|
||||
procedure = complex_add,
|
||||
commutator = +
|
||||
);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
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.
|
||||
|
||||
<ProgramListing>
|
||||
SELECT (a + b) AS c FROM test_complex;
|
||||
|
||||
+----------------+
|
||||
|c |
|
||||
+----------------+
|
||||
|(5.2,6.05) |
|
||||
+----------------+
|
||||
|(133.42,144.95) |
|
||||
+----------------+
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</Chapter>
|
149
doc/src/sgml/xtypes.sgml
Normal file
149
doc/src/sgml/xtypes.sgml
Normal file
@ -0,0 +1,149 @@
|
||||
<Chapter>
|
||||
<Title>Extending <Acronym>SQL</Acronym>: Types</Title>
|
||||
<Para>
|
||||
As previously mentioned, there are two kinds of types
|
||||
in <ProductName>Postgres</ProductName>: base types (defined in a programming language)
|
||||
and composite types (instances).
|
||||
Examples in this section up to interfacing indices can
|
||||
be found in <FileName>complex.sql</FileName> and <FileName>complex.c</FileName>. Composite examples
|
||||
are in <FileName>funcs.sql</FileName>.
|
||||
</Para>
|
||||
|
||||
<Sect1>
|
||||
<Title>User-Defined Types</Title>
|
||||
|
||||
<Sect2>
|
||||
<Title>Functions Needed for a User-Defined Type</Title>
|
||||
<Para>
|
||||
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 <Acronym>C</Acronym> structure:
|
||||
<ProgramListing>
|
||||
typedef struct Complex {
|
||||
double x;
|
||||
double y;
|
||||
} Complex;
|
||||
</ProgramListing>
|
||||
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:
|
||||
|
||||
<ItemizedList>
|
||||
<ListItem>
|
||||
<Para> When defining your external (string) representation,
|
||||
remember that you must eventually write a
|
||||
complete and robust parser for that representation
|
||||
as your input function!
|
||||
<ProgramListing>
|
||||
Complex *
|
||||
complex_in(char *str)
|
||||
{
|
||||
double x, y;
|
||||
Complex *result;
|
||||
if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) {
|
||||
elog(WARN, "complex_in: error in parsing
|
||||
return NULL;
|
||||
}
|
||||
result = (Complex *)palloc(sizeof(Complex));
|
||||
result->x = x;
|
||||
result->y = y;
|
||||
return (result);
|
||||
}
|
||||
</ProgramListing>
|
||||
|
||||
The output function can simply be:
|
||||
<ProgramListing>
|
||||
char *
|
||||
complex_out(Complex *complex)
|
||||
{
|
||||
char *result;
|
||||
if (complex == NULL)
|
||||
return(NULL);
|
||||
result = (char *) palloc(60);
|
||||
sprintf(result, "(%g,%g)", complex->x, complex->y);
|
||||
return(result);
|
||||
}
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
</ListItem>
|
||||
<ListItem>
|
||||
<Para> 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.
|
||||
</Para>
|
||||
</ListItem>
|
||||
</ItemizedList>
|
||||
|
||||
<Para>
|
||||
To define the <Acronym>complex</Acronym> type, we need to create the two
|
||||
user-defined functions complex_in and complex_out
|
||||
before creating the type:
|
||||
<ProgramListing>
|
||||
CREATE FUNCTION complex_in(opaque)
|
||||
RETURNS complex
|
||||
AS 'PGROOT/tutorial/obj/complex.so'
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE FUNCTION complex_out(opaque)
|
||||
RETURNS opaque
|
||||
AS 'PGROOT/tutorial/obj/complex.so'
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE TYPE complex (
|
||||
internallength = 16,
|
||||
input = complex_in,
|
||||
output = complex_out
|
||||
);
|
||||
</ProgramListing>
|
||||
</Para>
|
||||
|
||||
<Para>
|
||||
As discussed earlier, <ProductName>Postgres</ProductName> fully supports arrays of
|
||||
base types. Additionally, <ProductName>Postgres</ProductName> supports arrays of
|
||||
user-defined types as well. When you define a type,
|
||||
<ProductName>Postgres</ProductName> 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.
|
||||
</Para>
|
||||
|
||||
<Sect2>
|
||||
<Title>Large Objects</Title>
|
||||
|
||||
<Para>
|
||||
The types discussed to this point are all "small"
|
||||
objects -- that is, they are smaller than 8KB in size.
|
||||
<Note>
|
||||
<Para>
|
||||
1024 longwords == 8192 bytes. In fact, the type must be considerably smaller than 8192 bytes,
|
||||
since the <ProductName>Postgres</ProductName> tuple
|
||||
and page overhead must also fit into this 8KB limitation.
|
||||
The actual value that fits depends on the machine architecture.
|
||||
</Para>
|
||||
</Note>
|
||||
If you require a larger type for something like a document
|
||||
retrieval system or for storing bitmaps, you will
|
||||
need to use the <ProductName>Postgres</ProductName> large object interface.
|
||||
|
||||
</Sect2>
|
||||
</Sect1>
|
||||
</Chapter>
|
Loading…
x
Reference in New Issue
Block a user