head	1.33;
access;
symbols;
locks; strict;
comment	@.\" @;


1.33
date	94.06.30.09.10.17;	author aoki;	state Exp;
branches;
next	1.32;

1.32
date	94.06.27.19.38.06;	author aoki;	state Exp;
branches;
next	1.31;

1.31
date	94.03.26.09.43.56;	author aoki;	state Exp;
branches;
next	1.30;

1.30
date	94.03.12.09.57.29;	author aoki;	state Exp;
branches;
next	1.29;

1.29
date	94.03.11.23.11.11;	author aoki;	state Exp;
branches;
next	1.28;

1.28
date	94.03.11.11.52.48;	author aoki;	state Exp;
branches;
next	1.27;

1.27
date	94.03.11.11.19.05;	author aoki;	state Exp;
branches;
next	1.26;

1.26
date	94.02.10.01.47.00;	author sunita;	state Exp;
branches;
next	1.25;

1.25
date	94.02.09.20.51.56;	author aoki;	state Exp;
branches;
next	1.24;

1.24
date	93.10.05.23.07.39;	author aoki;	state Exp;
branches;
next	1.23;

1.23
date	93.10.05.06.46.58;	author aoki;	state Exp;
branches;
next	1.22;

1.22
date	93.10.04.04.10.22;	author aoki;	state Exp;
branches;
next	1.21;

1.21
date	93.10.03.06.15.10;	author aoki;	state Exp;
branches;
next	1.20;

1.20
date	93.10.03.05.48.17;	author aoki;	state Exp;
branches;
next	1.19;

1.19
date	93.05.14.03.14.50;	author aoki;	state Exp;
branches;
next	1.18;

1.18
date	93.03.02.23.00.45;	author avi;	state Exp;
branches;
next	1.17;

1.17
date	93.03.02.22.33.54;	author avi;	state Exp;
branches;
next	1.16;

1.16
date	93.02.19.02.18.35;	author marc;	state Exp;
branches;
next	1.15;

1.15
date	92.07.14.23.04.45;	author mao;	state Exp;
branches;
next	1.14;

1.14
date	92.07.14.22.55.42;	author frew;	state Exp;
branches;
next	1.13;

1.13
date	92.07.14.01.29.19;	author frew;	state Exp;
branches;
next	1.12;

1.12
date	92.07.13.22.59.52;	author joey;	state Exp;
branches;
next	1.11;

1.11
date	92.07.13.20.45.02;	author frew;	state Exp;
branches;
next	1.10;

1.10
date	92.07.07.17.44.44;	author frew;	state Exp;
branches;
next	1.9;

1.9
date	92.07.03.23.23.14;	author mer;	state Exp;
branches;
next	1.8;

1.8
date	92.06.16.01.04.31;	author mer;	state Exp;
branches;
next	1.7;

1.7
date	92.06.16.01.03.12;	author mer;	state Exp;
branches;
next	1.6;

1.6
date	92.06.12.00.05.50;	author hong;	state Exp;
branches;
next	1.5;

1.5
date	92.06.11.22.42.13;	author mer;	state Exp;
branches;
next	1.4;

1.4
date	92.02.28.05.38.55;	author mao;	state Exp;
branches;
next	1.3;

1.3
date	92.01.09.21.09.12;	author mer;	state Exp;
branches;
next	1.2;

1.2
date	91.12.02.05.16.06;	author kemnitz;	state Exp;
branches;
next	1.1;

1.1
date	91.12.02.04.07.14;	author kemnitz;	state Exp;
branches;
next	;


desc
@New Postgres user manual.
@


1.33
log
@4.2 final updates
@
text
@.\" This is -*-nroff-*- with eqn, tbl and -me macros
.\" 
.\" POSTGRES Data Base Management System
.\" 
.\" Copyright (c) 1988 Regents of the University of California
.\" 
.\" Permission to use, copy, modify, and distribute this software and its
.\" documentation for educational, research, and non-profit purposes and
.\" without fee is hereby granted, provided that the above copyright
.\" notice appear in all copies and that both that copyright notice and
.\" this permission notice appear in supporting documentation, and that
.\" the name of the University of California not be used in advertising
.\" or publicity pertaining to distribution of the software without
.\" specific, written prior permission.  Permission to incorporate this
.\" software into commercial products can be obtained from the Campus
.\" Software Office, 295 Evans Hall, University of California, Berkeley,
.\" Ca., 94720.  The University of California makes no representations
.\" about the suitability of this software for any purpose.  It is
.\" provided "as is" without express or implied warranty.
.\" 
.\" ----------------------------------------------------------------
.\" 
.\" The POSTGRES User Manual
.\" 
.\" typeset this document with: groff -set -me -Tps manual.me
.\" 
.\" $Header: /usr/local/devel/postgres/src/doc/user_manual/RCS/manual.me,v 1.32 1994/06/27 19:38:06 aoki Exp aoki $
.\" 
.\" ----------------------------------------------------------------
.\" .he '\*(dA'DRAFT'\*(tI'		\" comment out in production version
.\"------------------------------------
.de cW					\" arg3arg1arg2, constant-width arg1
\&\\$3\\fC\\$1\\fP\\$2
.\"\&\\$3\\fC\\s-1\\$1\\s0\\fP\\$2
..
.\"------------------------------------
.de xP					\" ip for references
.ip \\$1 \\w'[STON90B]'u+2n
..
.\"------------------------------------
.de (P					\" prologue for constant-width block
.ft C
.ps -1
.vs -1
..
.\"-----------------
.de )P					\" epilogue for constant-width block
.vs +1
.ps +1
.ft P
..
.\"------------------------------------
.de (T					\" prologue for constant-width table
.(P
.in +\\n(biu
..
.\"-----------------
.de )T					\" epilogue for constant-width table
.in -\\n(biu
.)P
..
.\"------------------------------------
.de (C					\" begin constant-width list
.(l
.(P
..
.\"-----------------
.de )C					\" end constant-width list
.)P
.)l
..
.\"---------------------------------------------------------------------------
.    ds II \s-1INGRES\s0
.    ds PP \s-1POSTGRES\s0
.    ds UU \s-1UNIX\s0
.    ds PQ \s-1POSTQUEL\s0
.    ds LP \s-1LIBPQ\s0
.    ds PV \s-14.2\s0
.    ds OF \s-1PICASSO\s0
.\"------------------------------------
.ps 11
.vs 13
.\"-----------------
.nr pp \n(.s
.nr sp \n(.s+1				\" +1-pt section headers
.\"-----------------
.nr bs 1v
.nr ps 0.3v
.nr ss 1v
.\"-----------------
.fo ''\\s+1%\s0''			\" page numbers in center footers
.\"-----------------
.nr $i .5i				\" main text indented
.nr so -\n($i				\" section headers un-indented
.\"-----------------
.rm xX					\" scratch register
.\"-----------------
.de HL
.in -\n($i
.b
.hl
.r
.in +\n($i
..
.\"-----------------
.de $1
.sp 2
.sz \n(.s+8
..
.\"-----------------
.EQ
delim @@@@
.EN
.\"------------------------------------
.\"!Gexpand
.\"---------------------------------------------------------------------------
.lp
\&
.sp 10
.(l C
.b
\s+8The \*(PP User Manual\s-8
.sp 2
.i
Edited by the \*(PP Group
Computer Science Div., Dept. of EECS
University of California at Berkeley
.r
.)l
.sp 3
.(f
\*(PP is copyright \(co 1989, 1994 by the Regents of the University of
California.  Permission to use, copy, modify, and distribute this
software and its documentation for educational, research, and
non-profit purposes and without fee is hereby granted, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of the University of California not
be used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.  Permission to
incorporate this software into commercial products can be obtained
from the Campus Software Office, 295 Evans Hall, University of
California, Berkeley, Ca., 94720.  The University of California makes
no representations about the suitability of this software for any
purpose.  It is provided
.q "as is"
without express or implied warranty.
.)f
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "INTRODUCTION"
.HL
.lp
This document is the user manual for the \*(PP database management
system developed at the University of California at Berkeley.  This
project, led by Professor Michael Stonebraker, has been sponsored by
the Defense Advanced Research Projects Agency (DARPA), the Army
Research Office (ARO), the National Science Foundation (NSF), and ESL,
Inc.
.lp
The first part of this manual goes over some basic system concepts and
procedures for starting the \*(PP system.  We then turn to a tutorial
overview of the \*(PQ data model and query language, introducing a few
of its advanced features.  Next, we explain the \*(PP approach to
extensibility and describe how users can extend \*(PP by adding
user-defined types, operators, aggregates, and both query language and
programming language functions.  After an extremely brief overview of
the \*(PP rule system, the manual concludes with a detailed appendix
that discusses some of the more involved and operating system-specific
procedures involved in extending the system.
.\"------------------------------------
.sh 2 "What is \*(PP?"
.lp
Traditional relational database management systems (DBMSs) support a
data model consisting of a collection of named relations, each
attribute of which has a specific type.  In current commercial
systems, possible types including floating point numbers, integers,
character strings, money, and dates.  It is commonly recognized that
this model is inadequate for future data processing applications.
.lp
The relational model succeeded in replacing previous models in part
because of its simplicity.  However, as mentioned, the 
.q "Spartan simplicity"
of the relational model often makes the implementation of certain
applications very difficult.  The \*(PP data model offers
substantial additional power by incorporating the following four
additional basic constructs:
.(l
classes
inheritance
types
functions
.)l
in such a way that users can easily extend the system.  In addition,
\*(PP supports a powerful production rule system.
.\"------------------------------------
.sh 2 "A Short History of the \*(PP Project"
.lp
Implementation of the \*(PP DBMS began in 1986.  The initial concepts
for the system were presented in [STON86] and the definition of the
initial data model appeared in [ROWE87].  The design of the rule system 
at that time was described in [STON87a].  The rationale and
architecture of the storage manager were detailed in [STON87b].
.lp
\*(PP has undergone several major releases since then.  The first
.q demo-ware
system became operational in 1987 and was shown at the 1988 ACM-SIGMOD
Conference.  We released Version 1, described in [STON90a], to a few
external users in June 1989.  In response to a critique of the first
rule system [STON89], the rule system was redesigned [STON90b] 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.
.lp
\*(PP 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 informatics database and several
geographic information systems.  \*(PP has also been used as an
educational tool at several universities.  Finally, at least two
companies (Multimedia Information Systems and Montage Software) have
picked up the prototype code and commercialized it.
.lp
\*(PP became the primary data manager for the Sequoia 2000 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.
.\"------------------------------------
.sh 2 "About This Release"
.lp
Version \*(PV, the current version of \*(PP, is about 200,000 lines of
code in the C programming language.  \*(PP is available free of
charge, and (as of this writing) has been installed by approximately
600 sites around the world.
.lp
This manual describes Version \*(PV of \*(PP.  The \*(PP group has
compiled and tested Version \*(PV on the following platforms:
.TS
box center tab(|);
c|c|c
l|l|l.
architecture|processor|operating system
=
DECstation 3000|Alpha AXP|OSF/1 1.3, 2.0
DECstation 3100 and 5000|MIPS|ULTRIX 4.2A, 4.3A
Sun4|SPARC|SunOS 4.1.3, 4.1.3_U1; Solaris 2.3
H-P 9000/700 and 800|PA-RISC|HP-UX 9.00, 9.01, 9.03
IBM RS/6000|POWER|AIX 3.2.5
.TE
.(f
\*(UU 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.  RS/6000, POWER and AIX
are trademarks of International Business Machines Corp.  OSF/1 is a
trademark of the Open Systems Foundation.  NeXTSTEP is a trademark of
NeXT Computer, Inc.  MIPS and IRIX are trademarks of Silicon Graphics,
Inc.
.)f
Previous versions of \*(PP ran on Sun Microsystems Sun3 and Sequent
Symmetry machines.  \*(PP no longer runs on these systems.  Outside
users have ported previous releases of \*(PP to many platforms,
including
.sm NeXTSTEP ,
IRIX 5.2, Intel System V Release 4, Linux, FreeBSD and NetBSD.
.lp
Version \*(PV has been tuned modestly.  On the Wisconsin benchmark,
one should expect performance about twice that of the public domain,
University of California version of \*(II, a relational prototype from
the late 1970s.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "WHAT YOU SHOULD READ"
.HL
.lp
This manual is primarily intended to provide a broad overview of the
system, as well as to illustrate how C programmers can tie their own
code into the \*(PP database server (commonly referred to as the 
.i "backend server" ,
or simply
.q backend ).
.lp
In addition to this manual, there is another document, the \*(PP
Reference Manual.  The Reference Manual gives full descriptions of the
syntax and options for each command in a format not unlike \*(UU
.q "man pages."
(In fact, the contents of the Reference Manual should be available
on-line as actual man pages.)  However, the Reference Manual is
designed as a complete reference for the experienced \*(PP user and
contains few tutorial examples.  This User Manual does not attempt to
provide all of the information that the Reference Manual provides.
Instead, it describes the major
.i concepts
of the system, gives
.i examples
of the use of the major constructs, and then provides
.i pointers
to the appropriate place in the Reference Manual in which you can find
more information if you so desire.
.lp
If you are new to \*(PP, you should probably read this manual first,
followed by the parts of the \*(PP Reference Manual necessary to build
your application.  In particular, you should read the Reference Manual
section on \*(LP if you intend to build a client application around
\*(PP, as that library is not discussed in this manual.
.lp
If you are not already familiar with relational databases, you should
probably find a good introductory text on the subject.  This manual
assumes that you already have some knowledge of the relational model,
and it doesn't hurt to know a query language such as 
.sm QUEL
or
.sm SQL .
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "POSTGRES ARCHITECTURE CONCEPTS"
.HL
.(z
.hl
.PSPIC manual-arch.eps 4i 3.88930i
.sp
.(c
\fBFigure 1\fP.  How a connection is established.
.)c
.hl
.)z
.lp
Before we continue, you should understand the basic \*(PP system
architecture.  Understanding how the parts of \*(PP interact will make
the next chapter somewhat clearer.
.lp
In database jargon, \*(PP uses a simple 
.q "process-per-user"
client/server model.  A \*(PP session consists of three cooperating
\*(UU processes (programs):
.bu
A supervisory daemon process (the
.cW postmaster ),
.bu
the user's frontend application (e.g., the 
.cW monitor
program), and
.bu
the backend database server (the
.cW postgres
process itself).
.lp
A single
.cW postmaster
manages a given collection of 
.i databases
on a single host.  Such a collection of databases is called an
.i installation
or 
.i site .
Frontend applications that wish to access a given database within an
installation make calls to the \*(LP library.  The library forwards
the user requests over the network to the
.cW postmaster
(Figure 1(a)), which in turn starts a new backend server process
(Figure 1(b)) and connects the frontend process to its server (Figure
1(c)).  From that point on, the frontend process and the backend
server communicate without intervention by the
.cW postmaster .
Hence, the
.cW postmaster
is always running, waiting for requests, whereas the frontend and
backend processes come and go.
.lp
One implication of this architecture is that the
.cW postmaster
and the backend always run on the same machine (the database server),
while the frontend application may or may not be running on a
separate machine (e.g., a client workstation).  You should keep this
in mind, because this means that the files that you can access on your
machine may not be accessible (or may only be accessed using a
different filename) on the database server machine.
.lp
You should also be aware that the 
.cW postmaster
and the
.cW postgres
server run with the user-id of the \*(PP 
.q superuser.
Note that the \*(PP superuser does not have to be a special user
(e.g., a user named 
.q postgres ).
Furthermore, the \*(PP superuser should definitely not be the \*(UU
superuser,
.q root !
In any case, all files relating to a database should belong to this
\*(PP superuser.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "GETTING STARTED WITH POSTGRES"
.HL
.lp
Before you can start learning the \*(PQ query language, you need to
have a working \*(PP system.  This section discusses how to start
\*(PP and set up your own environment so that you can use frontend
applications.
.lp
Some of the steps listed in this section will apply to all \*(PP
users, and some will apply primarily to the site database
administrator.  This
.i "site administrator"
is the person who installed the software, created the database
directories and started the
.cW postmaster
process.  This person does not have to be the \*(UU superuser, 
.q root,
or the computer system administrator.
.lp
In this section, items for end users are labelled
.q User
and items intended for the site administrator are labelled
.q Admin.
.lp
Throughout this manual, any examples that begin with the character
.cW "%" '' ``
are commands that should be typed at the \*(UU shell prompt.  Examples
that begin with the character
.cW "*" '' ``
are commands in the \*(PP query language, \*(PQ.
.\"------------------------------------
.sh 2 "Admin: Installing \*(PP"
.lp
Detailed installation instructions can be found in the \*(PP source
code distribution.  The
.cW troff
source is located in the file
.cW src/doc/postgres-setup.me 
and a formatted version is located at the top of the distribution
directory tree.  Those instructions vary from release to release and
will not be duplicated here.  However, if you are installing \*(PP
now, you must read these instructions and carry them out before going
any further.
.lp
A reminder: don't run the regression tests as the 
.q postgres
user.  Part of the test is a check of the \*(PP security mechanisms
that turns off superuser permissions.  If you run the test as 
.q postgres,
you may not be able to add users later.
.\"------------------------------------
.sh 2 "Admin/User: Setting Up Your Environment"
.(z
.hl
.PSPIC manual-files.eps 6i 2.36196i
.sp
.(c
\fBFigure 2\fP.  \*(PP file layout.
.)c
.hl
.)z
.lp
Figure 2 shows how the \*(PP distribution is laid out when installed
in the default way.  The system can be installed such that the various
top-level directories can be scattered around your disks, but for the
sake of simplifying this manual we will assume that this is not the
case.  In the examples that follow, we will assume that \*(PP has been
installed in the directory
.cW /usr/local/postgres .
Therefore, wherever you see the directory
.cW /usr/local/postgres
you should substitute the name of the directory where \*(PP is
actually installed.
.lp
All \*(PP commands are installed in the directory
.cW /usr/local/postgres/bin .
Therefore, you should add this directory to your shell 
.i "command path" .
If you use a variant of the Berkeley C shell, such as
.cW csh
or
.cW tcsh ,
you would put
.(C
% set path = ( /usr/local/postgres/bin $path )
.)C
in the
.cW .login
file in your home directory.  If you use a variant of the Bourne
shell, such as
.cW sh ,
.cW ksh
or 
.cW bash ,
then you would put
.(C
% PATH=/usr/local/postgres/bin:$PATH
% export PATH
.)C
in the
.cW .profile 
file in your home directory.
.lp
From now on, we will assume that you have put the \*(PP 
.cW bin
directory in your path.  In addition, we will make frequent reference
to 
.q "setting a shell variable"
or 
.q "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 \*(UU
manual pages that describe your user shell before going any further.
.\"------------------------------------
.sh 2 "Admin: Starting the Postmaster"
.lp
It should be clear from the preceding discussion that nothing can
happen to a database unless the
.cW postmaster
process is running.  As the site administrator, there are a number of
things you should remember before starting the
.cW postmaster .
These are discussed in the section of this manual titled,
.q "Administering \*(PP."
However, if \*(PP has been installed by following the installation
instructions exactly as written, the following simple command is all
you should need to start the
.cW postmaster :
.(C
% postmaster &
.)C
If the
.cW postmaster
does not start, but instead prints a series of cryptic error messages,
you should consult the Reference Manual under the heading
.b postmaster .
This manual page contains troubleshooting tips.
.lp
The 
.cW postmaster
occasionally prints out messages to the shell that started it.  This
is often helpful during troubleshooting.  If you do not wish to see
these messages, you can type
.(C
% postmaster -S
.)C
and the 
.cW postmaster
will be \*(lqS\*(rqilent.  Notice that there is no ampersand
(\*(lq&\*(rq) at the end of the last example.
.\"------------------------------------
.sh 2 "Admin: Adding Users"
.lp
The
.cW createuser
command enables specific users to access \*(PP.  Please read the
descriptions of these commands in the Reference Manual for specific
instructions on their use.
.\"------------------------------------
.sh 2 "User: Starting Applications"
.lp
Assuming that your site administrator has properly started the 
.cW postmaster
process and authorized you to use the database, you (as a user) may
begin to start up applications.  As previously mentioned, you should
add
.cW /usr/local/postgres/bin 
to your shell search path.  In most cases, this is all you should have
to do in terms of preparation.\**
.(f
\** 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
.cW PGHOST 
environment variable to the name of the database server machine.
The environment variable
.cW PGPORT
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
.cW postmaster ,
you should immediately consult your site administrator to make sure
that your environment is properly set up.
.)f
.lp
If you get the following error message from a
\*(PP command (such as
.cW monitor
or
.cW createdb ):
.(C
FATAL: StreamOpen: connect() failed: errno=61
FATAL: Failed to connect to postmaster (host=xxx, port=4321)
        Is the postmaster running?
.)C
it is usually because (1) the
.cW postmaster
is not running, or (2) you are attempting to connect to the wrong
server host.
.lp
If you get the following error message:
.(C
FATAL 1:Feb 17 23:19:55:process userid (2360) != 
  database owner (268)
.)C
it means that the site administrator started the 
.cW postmaster
as the wrong user.  Tell him to restart it as the \*(PP superuser.
.\"------------------------------------
.sh 2 "User: Managing a Database"
.lp
Now that \*(PP is up and running we can make some databases with which
to experiment.  Here, we describe the basic commands for managing a
database.
.\"------------------------------------
.sh 3 "Creating a Database"
.lp
Let's say you want to create a database named
.cW foo .
You can do this with the following command:
.(C
% createdb foo
.)C
\*(PP allows you to create any number of databases at a given site and
you automatically become the 
.i "database administrator"
of the database just created.  Database names must have an alphabetic
first character and are limited to 16 characters in length.
.lp
Not every user has authorization to become a database administrator.
If \*(PP 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.
.\"------------------------------------
.sh 3 "Accessing a Database"
.lp
Once you have constructed a database, there are three ways to access
it:
.bu
You can run the \*(PP terminal monitor (the
.cW monitor
program) which allows you to interactively enter, edit, and execute
commands in the \*(PQ query language.
.bu
You can interact with \*(PP from a C program by using the \*(LP
subroutine library.  This allows you to submit \*(PQ commands from C
and get answers and status messages back to your program.  This
interface is discussed further in the \*(LP section of the Reference
Manual.
.bu
You can use the
.i "fast path"
facility, which allows you to execute functions within the server
program itself.  This facility is (minimally) described in the
Reference Manual under
.q "Fast Path."
.lp
This manual will only discuss access through the terminal monitor.
.lp
The terminal monitor can be activated for the
.cW foo
database by typing the command:
.(C
% monitor foo
.)C
You will be greeted with the following message:
.(C
Welcome to the POSTGRES terminal monitor

Go
*
.)C
This prompt indicates that the terminal monitor is listening to you
and that you can type \*(PQ queries into a workspace maintained by the
terminal monitor.
.lp
The 
.cW monitor
program responds to escape codes that begin with the backslash
character, \*(lq\e\*(rq.  For example, you
.cW p rint
the current contents of the workspace by typing:
.(C
* \ep
.)C
Once you have finished entering your queries into the workspace, you
can pass the contents of the workspace to the \*(PP server by typing:
.(C
* \eg
.)C
This tells the server to
.cW g o.
If you make a typing mistake, you can invoke the
.cW vi
text 
.cW e ditor
by typing:
.(C
* \ee
.)C
The workspace will be passed to the editor, and once you exit
.cW vi ,
your edited query will placed in the terminal monitor workspace.  You
can then submit the contents of the workspace to \*(PP by using the
.cW \eg
command as described above.
.lp
To get out of the monitor and return to \*(UU, type
.(C
* \\q
.)C
and 
.cW monitor
will 
.cW q uit
and return you to your command shell.
.lp
There are two other things that 
.cW monitor
understands that make it easier to write nice-looking scripts.  First,
white space (i.e., spaces, tabs and newlines) may be used freely in
\*(PQ queries.  Second, comments that look like those used in the C
programming language, e.g.,
.(C
/* This is a comment. */
.)C
may also be used in your queries.  Beware: you cannot comment out an
escape code.  In other words, this doesn't work as you might expect:
.(C
/* I don't want to send this!\eg  */
retrieve (message = "but I want to send this!") \eg
.)C
.lp
For a complete description of the
.cW monitor
commands and its options, see the Reference Manual under the heading
.b monitor .
.\"------------------------------------
.sh 3 "Destroying a Database"
.lp
If you are the database administrator for the database
.cW foo ,
you can destroy it using the following \*(UU command:
.(C
% destroydb foo
.)C
This action physically removes all of the \*(UU files associated with
the database and cannot be undone, so this should only be done with a
great deal of forethought.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "THE POSTQUEL QUERY LANGUAGE"
.HL
.lp
\*(PQ is the \*(PP query language.  \*(PQ was derived from the
.sm QUEL
language developed by the University of California
.sm INGRES
project, but the two languages are different in many ways.  This
section provides an overview of how to use the more
.sm QUEL -like
features of \*(PQ to perform simple operations.
.lp
In the examples that follow, we assume that you have created the
.cW foo
database as described in the previous subsection and have started the
terminal monitor.
.lp
Before you start reading, take a look at the directory
.cW /usr/local/postgres/src/examples .
This directory contains all of the \*(PQ queries listed in this manual
(the ones that aren't examples of things that don't work, that is)
broken down by chapter.  Instead of typing the queries below into the
.cW monitor
program, you can just cut and paste out of the appropriate file or use
the
.cW \ei 
command at the terminal monitor.
.\"-----------------
.sh 2 "Concepts"
.lp
The fundamental notion in \*(PP is that of a
.i class,
which is a named collection of object
.i instances .
Each instance has the same collection of named
.i attributes ,
and each attribute is of a specific
.i type .
Furthermore, each instance has a permanent
.i "object identifier"
(OID) that is unique throughout the installation.
.lp
As previously discussed, classes are grouped into databases, and a
collection of databases managed by a single
.cW postmaster
process constitutes an installation or site.
.\"-----------------
.sh 2 "Creating a New Class"
.lp
You can create a new class by specifying the class name, along with
all attribute names and their types:
.(C
* create EMP (name = text, salary = int4,
              age = int4, dept = char16) \\g

* create DEPT (dname = char16, floor = int4,
               manager = text) \\g
.)C
The \*(PQ base types used above are a variable-length array of
printable characters
.cW text ), (
a 4-byte signed integer
.cW int4 ), (
and a fixed-length array of 16 characters
.cW char16 .) (
.lp
So far, the \*(PP
.b create
command looks exactly like the command used to create a table in a
traditional relational system.  This exact syntax was used in
.sm QUEL ,
the original
.sm INGRES
query language.  However, we will presently see that classes have
properties that are extensions of the relational model, so we use a
different word to describe them.
.\"-----------------
.sh 2 "Populating a Class with Instances"
.\" we refer to this later
.ds xX \n($1.\n($2
.lp
The 
.b append
command is used to populate a class with instances:
.(C
* append EMP (name = "Claire", salary = 2000,
              age = 40, dept = "shoe") \\g

* append EMP (name = "Joe", salary = 1400,
              age = 40, dept = "shoe") \\g

* append EMP (name = "Sam", salary = 1200,
              age = 29, dept = "toy") \\g

* append EMP (name = "Bill", salary = 1600,
              age = 36, dept = "candy") \\g

* append DEPT (dname = "shoe", floor = 5, 
               manager = "Claire") \\g

* append DEPT (dname = "toy", floor = 3, 
               manager = "Sam") \\g

* append DEPT (dname = "candy", floor = 4, 
               manager = "(None)") \\g
.)C
This adds four instances to the
.cW EMP 
class, one for each
.b append
command.
.lp
You can also use the
.b copy
command to perform load large amounts of data from flat (ASCII) files.
See the Reference Manual under 
.b copy
for details.
.\"-----------------
.sh 2 "Querying a Class"
.lp
The
.cW EMP
class can be queried with normal relational selection and projection
queries.  The \*(PQ equivalent of the
.sm SQL
.b select
statement is 
.b retrieve .
As in 
.sm SQL ,
the statement is divided into a
.i "target list"
(the part that lists the attributes to be returned) and a
.i "qualification"
(the part that specifies any restrictions).  For example, to find the
employees under 35 years of age, type:
.(C
* retrieve (EMP.name) where EMP.age < 35 \\g
.)C
and the output should be:
.(T
.TS
allbox;
l.
name
Sam
.TE
.)T
Note that, unlike
.sm SQL ,
parentheses are required around the target list,
.cW EMP.name .
.lp
\*(PQ allows you to return arbitrary computations in the target list
as long as they are given some kind of name:
.(C
* retrieve (result = EMP.salary / EMP.age)
      where EMP.name = "Bill" \\g
.)C
.(T
.TS
allbox;
l.
result
44
.TE
.)T
In this case, we divided Bill's salary by his age and called the
result
.cW result .
(Of course, the answer is really 44 @@4 over 9@@, but division of two
integers produces another integer so the fraction is lost.).
.lp
Arbitrary Boolean operators
.b and , (
.b or
and
.b not )
are allowed in the qualification of any query.  For example,
.(C
* retrieve (EMP.all) 
      where EMP.age < 30
         or not EMP.name = "Joe" \\g
.)C
.(T
.TS
allbox;
l l l l.
name	salary	age	dept
Claire	2000	36	shoe
Sam	1200	29	toy
Bill	1600	36	candy
.TE
.)T
.lp
As a final note, you can specify that the results of a
.b retrieve
can be returned in a sorted order or with duplicate instances removed.
See the Reference Manual under
.b retrieve
for more information.
.\"-----------------
.sh 2 "Redirecting Retrieve Queries"
.lp
Any 
.b retrieve
query can be redirected to a new class in the database:
.(C
* retrieve into temp (EMP.name)
      where EMP.age < 35 and EMP.salary > 1000 \\g
.)C
This executes an implicit
.b create
command, creating a new class
.cW temp
with the attribute names and types specified in the target list of the
.b "retrieve into"
command.  We can then, of course, perform any operations on the
resulting class that we can perform on other classes.
.(C
* retrieve (temp.all) \\g
.)C
.(T
.TS
allbox;
l.
name
Sam
.TE
.)T
.\"-----------------
.sh 2 "Joins Between Classes"
.lp
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 
.i "join query" .
.lp
As an example, say we wish to find the names of employees which are
the same age.  In effect, we need to compare the 
.cW age
attribute of each 
.cW EMP
instance to the 
.cW age
attribute of all other 
.cW EMP
instances.\**
.(f
\** This is only a conceptual model.  The actual join may be performed
in a more efficient manner, but this is invisible to the user.
.)f
We can do this with the following query:
.(C
* retrieve (E1.name, E2.name)
      from E1 in EMP, E2 in EMP
      where E1.age = E2.age and E1.name != E2.name \\g
.)C
.(T
.TS
allbox;
l l.
name	name
Bill	Claire
Claire	Bill
.TE
.)T
In this case, both
.cW E1
and
.cW E2
are
.i surrogates
for an instance of the class
.cW EMP ,
and both range over all instances of the class.  (In the terminology
of most database systems, 
.cW E1
and
.cW E2
are known as
.q "range variables." )
A \*(PQ query can contain an arbitrary number of class names and
surrogates.\**
.(f
\** 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, \*(PP computes and returns the values
specified in the target list.
.sp
\*(PQ does not assign any meaning to duplicate values in such
expressions.  This means that \*(PP sometimes recomputes the same
target list several times \(em this frequently happens when Boolean
expressions are connected with an
.b or .
To remove such duplicates, you must use the
.b "retrieve unique"
statement.  See the Reference Manual under
.b retrieve
for more details. 
.)f
.\"-----------------
.sh 2 "Updates"
.lp
You can update existing instances using the
.b replace
command:
.(C
* replace EMP (salary = E.salary)
      from E in EMP
      where EMP.name = "Joe" and E.name = "Sam" \\g
.)C
This command replaces the salary of Joe by that of Sam.
.lp
Notice that this example is actually another join query.  Here, we are
using the actual class name
.cW EMP '') (``
as one range variable and a surrogate name for 
.cW EMP
.cW E '') (``
as another range variable.
.\"-----------------
.sh 2 "Deletions"
.lp
Deletions are performed using the
.b delete
command:
.(C
* delete EMP where EMP.salary > 0 \\g
.)C
Since all employees have positive salaries, this command will leave
the
.cW EMP
class empty.
.lp
One should be wary of queries of the form
.(C
delete \fIclassname\fP
.)C
Without a qualification, the 
.b delete
command will simply delete all instances of the given class, leaving
it empty.  The system 
.b "will not request confirmation"
before doing this.
.lp
Before going on, repopulate your EMP database using the 
.b append
commands listed above.
.\"-----------------
.sh 2 "Using Functions"
.lp
\*(PQ queries can contain function calls as well as operators.  If we
wanted to express our very first
.b retrieve 
query as:
.(C
* retrieve (EMP.name) where int4lt(EMP.age, 35) \\g
.)C
.(T
.TS
allbox;
l.
name
Sam
.TE
.)T
we could do so.  Obviously, if we need to compute some function of
more than two arguments, we 
.i must
use the function syntax instead of the operator syntax.
.\"-----------------
.sh 2 "Using Aggregate Functions"
.lp
Like most other query languages, \*(PP supports aggregate functions.
However, the current implementation of \*(PP aggregate functions is
very limited.  Specifically, while there are aggregates to compute
such functions as the count, sum, average, maximum and minimum over a
set of instances, aggregates can only appear in the target list of a
query and not in the qualification (\c
.cW where
clause).  As an example, 
.(C
* retrieve (how_many = count{EMP.name}) \\g
.)C
.(T
.TS
allbox;
l.
how_many
4
.TE
.)T
counts all employees, and 
.(C
* retrieve (avg_salary = 
      int4ave{EMP.salary
              where EMP.dept = "toy"}) \\g
.)C
.(T
.TS
allbox;
l.
avg_salary
1200
.TE
.)T
computes the average salary of all employees in the toy department.
However, the following query (to find out who makes more money than
any of the toy department employees) will
.b not
work:
.(C
* retrieve (EMP.name) where
      EMP.salary > int4max{EMP.salary 
                           where EMP.dept = "toy"} \\g

WARN:Mar  3 00:40:54:parser: syntax error at or near "{"
.)C
because the aggregate is not in the target list.  In addition, if the
qualification of the aggregate expression contains any join clauses
(references to other classes), the aggregate may or may not return the
right result.  (In other words, aggregates with join clauses are
neither disallowed nor are they correctly supported.)  See the
Reference Manual under
.b postquel
for more details.
.\"-----------------
.sh 2 "Help!  What Are the Valid Types, Operators and Functions?"
.lp
So far, we have been rather cavalier in our use of types (such as 
.cW char16 ),
operators (such as
.cW < ),
and aggregate functions (such as 
.cW count ).
A large number of pre-defined types, operators and aggregates are
available by default in \*(PP, and these are listed in the section of
the Reference Manual labelled
.b built-in .
This would be a good time to go ahead and take a peek at that section.
.lp
In a later section of this manual, we will describe how to query the
system to find out the current list of
.i all
valid types, operators, functions, etc. known to the system.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "ADVANCED POSTQUEL FEATURES"
.HL
.lp
Having covered the basics of using \*(PQ to access your data, we will
now discuss those features of \*(PP that distinguish it from
conventional data managers.  These features include inheritance, time
travel and non-atomic data values (array- and set-valued attributes).
.\"-----------------
.sh 2 "Inheritance"
.lp
First, if you haven't done so already, re-populate the
.cW EMP
class by repeating the
.b append
commands in section \*(xX.  Then, create a second class
.cW STUD_EMP ,
and populate it as follows:
.(C
* create STUD_EMP (location = point) inherits (EMP) \\g

* append STUD_EMP (name = "Sunita", salary = 4000,
                   age = 23, dept = "electronics",
                   location = "(3, 5)") \\g
.)C
In this case, an instance of
.cW STUD_EMP
.i inherits
all data fields
.cW name , (
.cW salary ,
.cW age ,
and
.cW dept )
from its parent,
.cW EMP .
Furthermore, student employees have an extra field,
.cW location ,
that shows their address as a coordinate pair.  In \*(PP, a class can
inherit from zero or more other classes,\**
.(f
\** I.e., the inheritance hierarchy is a directed acyclic graph.
.)f
and a query can reference either all instances of a class or all
instances of a class plus all of its descendants.  For example, the
following query finds the employees over 20:
.(C
* retrieve (E.name) from E in EMP where E.age > 20 \\g
.)C
.(T
.TS
allbox;
l.
name
Claire
Joe
Sam
Bill
.TE
.)T
On the other hand, to find the names of all employees, including
student employees, over age 20, the query is:
.(C
* retrieve (E.name) from E in EMP* where E.age > 20 \\g
.)C
which returns:
.(T
.TS
allbox;
l.
name
Claire
Joe
Sam
Bill
Sunita
.TE
.)T
Here the
.cW *
after
.cW EMP
indicates that the query should be run over
.cW EMP
and all classes below
.cW EMP
in the inheritance hierarchy.
Many of the commands that we have already discussed \(em
.b retrieve ,
.b replace
and
.b delete
\(em support this
.cW *
notation, as do others, such as the
.b rename
and 
.b addattr
commands.  See the Reference Manual entries for these commands for
additional details.
.lp
Note that
.cW location
in
.cW STUD_EMP
is not a traditional relational data type.  As we will see later,
\*(PP can be customized with an arbitrary number of user-defined data
types.
.\"-----------------
.sh 2 "Time Travel"
.lp
\*(PP supports the notion of
.i "time travel" .
This feature allows a user to run historical queries.  For example, to
find Sam's current salary, one would query:
.(C
* retrieve (E.salary) from E in EMP["now"]
      where E.name = "Sam" \\g
.)C
.(T
.TS
allbox;
l.
salary
1200
.TE
.)T
\*(PP will automatically find the version of Sam's record valid at the
correct time and get the appropriate salary.
.lp
One can also give a time
.i range .
For example to see all the salaries that Sam has ever earned, one
would query:
.(C
* retrieve (E.salary)
      from E in EMP["epoch", "now"]
      where E.name = "Sam" \\g
.)C
where 
.q epoch
indicates the beginning of the system clock.\**
.(f
\** On \*(UU systems, this is always midnight, January 1, 1970 GMT.
.)f
If you have executed all of the examples so far, then the above query
returns:
.(T
.TS
allbox;
l.
salary
1200
1200
.TE
.)T
Notice that there are two salaries for Sam because he was deleted from
and then re-appended to the
.cW EMP
class.
.lp
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
.cW [,] .'' ``
See Section 3 of the Reference Manual,
.b Built-Ins ,
and the introduction to Section 4,
.b \*(PQ ,
for a full description of the time types (absolute time, relative time
and time ranges).
.\"-----------------
.sh 2 "Non-Atomic Values"
.lp
One of the tenets of the relational model is that the attributes of a
relation are 
.i atomic .
\*(PP 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
.i arrays
of base types or 
.i sets 
of any type.
.\"-----------------
.sh 3 "Arrays"
.lp
\*(PP 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.
.(C
* create SAL_EMP (name = text,
                  pay_by_quarter = int4[],
                  schedule = char16[][]) \\g
.)C
The above query will create a class named
.cW SAL_EMP
with a 
.cW text
string
.cW name ), (
a one-dimensional array of
.cW int4
.cW pay_by_quarter ), (
which represents the employee's salary by quarter and a
two-dimensional array of
.cW char16
.cW schedule ), (
which represents the employee's weekly schedule.  Now we do some
.cW append s;
note that when appending to an array, we enclose the values within
braces and separate them by commas.  If you know C, this is not unlike
the syntax for initializing structures.
.(C
* append SAL_EMP (name = "Bill", 
     pay_by_quarter[4] = "{10000, 10000, 10000, 10000}", 
     schedule[7][2]    = "{{"meeting", "lunch"}, {}}") \\g

* append SAL_EMP (name = "Carol",
        pay_by_quarter = "{20000, 25000, 25000, 25000}", 
        schedule[5][2] = "{{"talk", "consult"}, {"meeting"}}") \\g
.)C
By default, \*(PP uses the 
.q one-based
numbering convention for arrays \(em that is, an array of @@n@@ elements
starts with array[1] and ends with array[@@n@@].  Note that the elements
of an array do not have to be completely specified.  For example, you
may have noticed that we did not initialize all of the elements of the 
attribute
.cW schedule
above.  The value of an uninitialized element is undefined, but it can
be updated later using the
.cW replace 
command.
.lp
Now, we can run some queries on
.cW 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:
.(C
* retrieve (SAL_EMP.name)
      where SAL_EMP.pay_by_quarter[1] !=
            SAL_EMP.pay_by_quarter[2] \\g
.)C
.(T
.TS
allbox;
l.
name
Carol
.TE
.)T
This query retrieves the third quarter pay of all employees:
.(C
* retrieve (SAL_EMP.pay_by_quarter[3]) \\g
.)C
.(T
.TS
allbox;
l.
pay_by_quarter
10000
25000
.TE
.)T
We can also access arbitrary
.i slices
of an array, or
.i subarrays .
This query retrieves the first item on Bill's schedule for the first
three days of the week.
.cW "ill".
.(C
* retrieve (SAL_EMP.schedule[1:3][1:1]) 
      where SAL_EMP.name = "Bill" \\g
.)C
.(T
.TS
allbox;
l.
schedule
{{"meeting"},{""},{""}}
.TE
.)T
Similarly, the
.cW replace
command can be used to update a single array element or an arbitrary
subarray.  This query updates Carol's schedule for the second and
third day of the week.
.(C
* replace SAL_EMP (schedule[2:3][1:2] = 
                   "{{"debugging", "shopping"}, {"meeting", "present"}}") 
                   where SAL_EMP.name = "Carol" \\g
.)C
This query gives a $1000 raise in the first quarter to all members
whose first item on schedule for the first working day is
.cW "debugging" :
.(C
* replace SAL_EMP (pay_by_quarter[1] = 
                   SAL_EMP.pay_by_quarter[1] + 1000)
      where SAL_EMP.schedule[1][1] = "debugging" \\g
.)C
.if 0 \{
When arrays are too large to fit in a single page they can be stored as 
large objects by giving the
name of a large object file as the array string at 
.cW append
time. 
For example, the following append query will cause the array data to be
stored as a large object.
.(C
* append SAL_EMP (name = "Busy_guy", 
		schedule[7][101] = "/LO_name") \\g 
.)C
The 
.cW replace 
query can be used to populate the large object array using the same syntax
as used for ordinary arrays. This query will cause the first four slots
on
.cW "Busy_guy's"
.cW schedule 
to be filled.
.(C
* replace SAL_EMP (schedule[1:1][1:4] = 
		"{{"debugging", "shopping"}, {"meeting", "present"}}") 
		where SAL_EMP.name = "Busy_guy" \\g
.)C
\}
.\"-----------------
.sh 3 "Sets"
.lp
Class attributes can also be 
.i sets
that are defined in an
.i intentional ,
or declarative, manner.  For example, let's say that we want to
create a new kind of department class.  A department consists of a
department name as well as a 
.b query
that lists all members of the department.
.(C
* create NEW_DEPT (deptname = char16,
                   members = setof EMP) \\g

* append NEW_DEPT (deptname = "shoe",
                   members = "retrieve (EMP.all)
                              where EMP.age >= 40") \\g

* append NEW_DEPT (deptname = "toy",
                   members = "retrieve (EMP.all)
                              where EMP.name = \e\e"Sam\e\e"") \\g

* append NEW_DEPT (deptname = "candy",
                   members = "retrieve (EMP.all)
                              where EMP.name != \e\e"Sam\e\e"
                              and EMP.age < 40") \\g
.)C
These amount to our business rules: all people over 40 work in the
shoe department, Sam works alone in the toy department, and everyone
else works in the candy department.
.lp
We can retrieve (but not update) individual attributes of each member
of a set-valued attribute.  We do with the 
.i nested-dot
notation.
.(C
* retrieve (NEW_DEPT.deptname,
            NEW_DEPT.members.name) \\g
.)C
.(T
.TS
allbox;
l l.
deptname	name
shoe	Claire
shoe	Joe
toy	Sam
candy	Bill
.TE
.)T
That is, we project attributes from our set-valued attribute, 
.cW NEW_DEPT.members ,
by adding the reference to the
.cW EMP
attribute
.cW .name .
There are two caveats: the shorthand
.cW .all
doesn't work for set-valued attributes, and retrieval of more than one
attribute from a set-valued attribute may produce unexpected results.
.lp
The main advantage of representing sets in a declarative way (instead
of storing the actual values, or
.cW EMP s,
in this example) is that the set declarations automatically maintain
their consistency.  If we hire someone new, they will be assigned to
the proper
.cW NEW_DEPT
whether we explicitly give them a department or not.
.(C
/* whoops, we forgot to put Ginger in a department... */
* append EMP (name = "Ginger", salary = 2000,
              age = 34) \\g

/* ...but it's ok */
* retrieve (NEW_DEPT.deptname,
            NEW_DEPT.members.name) \\g
.)C
.(T
.TS
allbox;
l l.
deptname	name
shoe	Claire
shoe	Joe
toy	Sam
candy	Bill
candy	Ginger
.TE
.)T
Notice that \*(PP returns several results for each of the departments
that have more than one employee.  This is because \*(PP 
.q flattens
the result when a set attribute contains multiple instances.  In other
words, an instance is returned for each of the set elements and the
contents of the other attributes (in this case,
.cW deptname )
is just duplicated in each of those instances.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "EXTENDING POSTQUEL: AN OVERVIEW"
.HL
.lp
In the sections that follow, we will discuss how you can extend the
\*(PQ query language by adding:
.bu
functions
.bu
types
.bu
operators
.bu
aggregates
.lp
We will then give some integrated examples of their use.
.\"------------------------------------
.sh 2 "How Extensibility Works"
.lp
\*(PP is extensible because its operation is
.i "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
.i "system catalogs" .
(Some systems call this the
.i "data dictionary" ).
The catalogs appear to the user as tables, like any other, but the
DBMS stores its internal bookkeeping in them.  One key difference
between \*(PP and standard relational systems is that \*(PP stores
much more information in its catalogs \(em not only information about
tables and columns, but also information about its types, functions,
access methods, and so on.  These tables can be modified by the user,
and since \*(PP bases its internal operation on these tables, this
means that \*(PP can be extended by users.  By comparison,
conventional database systems can only be extended by changing
hard-coded procedures within the DBMS or by loading modules
specially-written by the DBMS vendor.
.lp
\*(PP is also unlike most other data managers in that the server can
incorporate user-written code into itself through
.i "dynamic loading" .
That is, the user can specify an object code file (e.g., a compiled
.cW .o
file or shared library) that implements a new type or function and
\*(PP will load it as required.  Code written in the \*(PQ query
language are even more trivial to add to the server.
.lp
This ability to modify its operation 
.q "on the fly"
makes \*(PP uniquely suited for rapid prototyping of new applications
and storage structures.
.\"------------------------------------
.sh 2 "The \*(PP Type System"
.lp
The \*(PP type system can be broken down in several ways.
.lp
Types are divided into
.i base
types and
.i composite
types.  Base types are those, like
.cW int4 ,
that are implemented in a language such as C.  They generally
correspond to what are often known as
.q "abstract data types" ;
\*(PP 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.  
.cW EMP
is an example of a composite type.  \*(PP stores these types in only
one way (within the file that stores all instances of the class) but
the user can
.q "look inside"
at the attributes of these types from the query language and optimize
their retrieval by (for example) defining indices on the attributes.
.lp
\*(PP base types are further divided into
.i built-in
types and
.i user-defined
types.  Built-in types (like
.cW int4 )
are those that are compiled into the system.  User-defined types are
those created by the user in the manner to be described below.
.\"------------------------------------
.sh 2 "About the \*(PP System Catalogs"
.lp
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.
.lp
All system catalogs have names that begin with
.cW pg_ .
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.)
.TS
box center tab(|);
c|c
lf(C)|l.
catalog name|description
=
pg_database|databases
pg_class|classes
pg_attribute|class attributes
pg_index|secondary indices

pg_proc|procedures (both C and \*(PQ)
pg_type|types (both base and complex)
pg_operator|operators
pg_aggregate|aggregates and aggregate functions

pg_am|access methods
pg_amop|access method operators
pg_amproc|access method support functions
pg_opclass|access method operator classes
.TE
.(z
.hl
.PSPIC manual-er.eps 6i 6.01776i
.sp
.(c
\fBFigure 3\fP.  The major \*(PP system catalogs.
.)c
.hl
.)z
The Reference Manual gives a more detailed explanation of these
catalogs and their attributes.  However, Figure 3 shows the major
entities and their relationships in the system catalogs.  (Attributes
that do not refer to other entities are not shown unless they are part
of a primary key.)
.lp
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:
.np
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.
.np
Many different features (classes, attributes, functions, types, access
methods, etc.) are tightly integrated in this schema.  A simple 
.b define
command may modify many of these catalogs.
.np
Types and procedures\**
.(f
\** We use the words
.i procedure
and 
.i function
more or less interchangably.
.)f
are central to the schema.  Nearly every catalog contains some
reference to instances in one or both of these classes.  For example,
\*(PP frequently uses type signatures (e.g., of functions and
operators) to identify unique instances of other catalogs.
.np
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
.cW pg_am ,
.cW pg_amop ,
.cW pg_amproc,
.cW pg_operator
and
.cW 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.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "EXTENDING POSTQUEL: FUNCTIONS"
.HL
.lp
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 \*(PP before describing how to add new types.
.lp
\*(PQ provides two types of functions:
.i "query language functions"
(functions written in \*(PQ) and
.i "programming language functions"
(functions written in a compiled programming language such as C.)
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 \*(PQ functions, so we'll start with those.
.\"------------------------------------
.bp
.HL
.sh 2 "Query Language (\*(PQ) Functions"
.HL
.lp
.\"------------------------------------
.sh 3 "\*(PQ Functions on Base Types"
.lp
The simplest possible \*(PQ function has no arguments and simply
returns a base type, such
as
.cW int4 :
.(C
* define function one
      (language = "postquel", returntype = int4)
      as "retrieve (one = 1)" \\g
.)C
.(C
* retrieve (answer = one()) \\g
.)C
.(T
.TS
allbox;
l.
answer
1
.TE
.)T
Notice that we defined a target list for the function (with the name
.cW one ),
but the target list of the query that invoked the function overrode
the function's target list.  Hence, the result is labelled
.cW answer
instead of
.cW one .
.lp
It's almost as easy to define \*(PQ functions that take base types as
arguments.  In the example below, notice how we refer to the arguments
within the function as
.cW "$1"
and
.cW "$2"
and specify their types using the
.cW "arg is"
clause.
.(C
* define function add_pq
      (language = "postquel", returntype = int4)
      arg is (int4, int4)
      as "retrieve (sum = $1 + $2)" \\g
.)C
.(C
* retrieve (answer = add_pq(1, 2)) \\g
.)C
.(T
.TS
allbox;
l.
answer
3
.TE
.)T
.\"------------------------------------
.sh 3 "\*(PQ Functions on Composite Types"
.lp
When specifying functions with arguments of composite types (such as 
.cW EMP ),
we must not only specify which argument we want (as we did above with 
.cW "$1"
and
.cW "$2" )
but we must also specify the attributes of that argument.  For
example, take the function
.cW double_salary
that computes what your salary would be if it were doubled.
.(C
* define function double_salary
      (language = "postquel", returntype = int4)
      arg is (EMP)
      as "retrieve (salary = $1.salary * 2)" \\g

* retrieve (EMP.name, dream = double_salary(EMP))
      where EMP.dept = "toy" \\g
.)C
.(T
.TS
allbox;
l l.
name	dream
Sam	2400
.TE
.)T
This is pretty straightforward.  Notice the use of the syntax
.cW "$1.salary" .
.lp
Before launching into the subject of functions that return composite
types, we must first introduce the 
.i function
notation for projecting attributes.  The simple way to explain this is
that we can usually use the notation
.cW attribute(class)
and
.cW class.attribute
interchangably.
.(C
/*
 * this is the same as:
 * retrieve (youngster = EMP.name)) 
 *    where EMP.age < 30
 */
* retrieve (youngster = name(EMP)) 
      where age(EMP) < 30 \\g
.)C
.(T
.TS
allbox;
l.
youngster
Sam
.TE
.)T
As we shall see, however, this is not always the case.
.lp
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
.cW EMP
instance:
.(C
* define function new_emp
      (language = "postquel", returntype = EMP)
      as "retrieve (name = \e\e"None\e\e"::text,
                    salary = 1000,
                    age = 25,
                    dept = \e\e"none\e\e"::char16)"
.)C
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.
.lp
Defining a function like this can be tricky.  Some of the more
important caveats are as follows:
.bu 
The target list order must be 
.b exactly
the same as that in which the fields appear in the 
.b create
statement (or when you execute a 
.cW .all
query).
.bu
You must be careful to typecast the fields (using
.cW :: )
very carefully or you will see the following error:
.(C
WARN:Mar  3 03:06:18:function declared to return type EMP
  does not retrieve (EMP.all)
.)C
See the Reference Manual under
.b postquel
for a discussion of typecasting.
.lp
.bu
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.
.(C
* retrieve (nobody = name(new_emp())) \\g
.)C
.(T
.TS
allbox;
l.
nobody
None
.TE
.)T
.bu
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.
.(C
* retrieve (nobody = new_emp().name) \\g
WARN:Mar  3 03:09:28:parser: syntax error at or near "."
.)C
.lp
Any collection of commands in the \*(PQ query language can be packaged
together and defined as a function.  The commands can include updates
(i.e.,
.b append ,
.b replace
and 
.b delete )
as well as 
.b retrieve
queries.  However, the final command must be a 
.b retrieve
that returns whatever is specified as the function's
.cW returntype .
.(C
* define function clean_EMP (language = "postquel",
                             returntype = int4)
      as "delete EMP where EMP.salary <= 0
          retrieve (ignore_this = 1)" \\g

* retrieve (x = clean_EMP()) \\g
.)C
.(T
.TS
allbox;
l.
x
1
.TE
.)T
.\"------------------------------------
.sh 3 "\*(PQ Functions on Sets"
.lp
Unfortunately, \*(PP does not really distinguish between functions
that return single instances and those that return sets of instances.
In all cases, instances are returned one-by-one.  Similarly, functions
can only take single instances as their arguments and cannot have sets
as an argument.  For example, the following function
.cW high_pay
returns the set of all employees in class
.cW EMP
whose salaries exceed 1500:
.(C
* define function high_pay
      (language = "postquel", returntype = setof EMP)
      as "retrieve (EMP.all) where EMP.salary > 1500" \\g

* retrieve (overpaid = name(high_pay())) \\g
.)C
.(T
.TS
allbox;
l.
overpaid
Claire
Bill
Ginger
.TE
.)T
However, this function could be defined with
.(C
returntype = EMP
.)C
with exactly the same results.
.\"------------------------------------
.bp
.HL
.sh 2 "Programming Language Functions"
.HL
.lp
We now turn to the more difficult task of defining programming
language functions.  Be warned: this section of the manual will not
make you a programmer.  You must have a good understanding of C
(including the use of pointers and the
.cW malloc
memory manager) before trying to write C functions for use with \*(PP.
.lp
While it may be possible to load functions written in languages other
than C into \*(PP, this is often difficult (when it is possible at all)
because other languages, such as 
.sm FORTRAN
and
Pascal often do not follow the same 
.q "calling convention"
as C.  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 C.
.lp
The basic rules for building C functions are as follows:
.np
Most of the header (include) files for \*(PP should already be
installed in
.cW /usr/local/postgres/include
(see Figure 2).  You should always include
.(C
-I/usr/local/postgres/include
.)C
on your 
.cW 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
.cW include ).
In those cases you may need to add one or more of
.(C
-I/usr/local/postgres/src/backend
-I/usr/local/postgres/src/backend/port/<PORTNAME>
-I/usr/local/postgres/src/backend/obj
.)C
(where 
.cW <PORTNAME>
is the name of the port, e.g., 
.cW alpha
or 
.cW sparc).
.np
When allocating memory, use the \*(PP routines
.cW palloc
and
.cW pfree
instead of the corresponding C library routines
.cW malloc
and 
.cW free .
The memory allocated by
.cW palloc
will be freed automatically at the end of each transaction, preventing
memory leaks.
.np
Always zero the bytes of your structures using
.cW memset
or 
.cW 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.
.np
Most of the internal \*(PP types are declared in
.cW tmp/c.h
and
.cW tmp/postgres.h ,
so it's usually a good idea to include those files as well.
.np
Compiling and loading your object code so that it can be dynamically
loaded into \*(PP always requires special flags.  See Appendix A for a
detailed explanation of how to do it for your particular operating
system.
.\"------------------------------------
.sh 3 "Programming Language Functions on Base Types"
.lp
Internally,
\*(PP regards a base type as a
.q "blob of memory."
The user-defined functions that you define over a type in turn define
the way that \*(PP can operate on it.  That is, \*(PP will only store
and retrieve the data from disk and use your user-defined functions to
input, process, and output the data.
.lp
Base types can have one of three internal formats:
.bu
pass by value, fixed-length
.bu
pass by reference, fixed-length
.bu
pass by reference, variable-length
.lp
By-value types can only be 1, 2 or 4 bytes in length (even if your
computer supports by-value types of other sizes).  \*(PP 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
.cW long
type is dangerous because it is 4 bytes on some machines and 8 bytes
on others, whereas
.cW int
type is 4 bytes on most \*(UU machines (though not on most personal
computers).  A reasonable implementation of the 
.cW int4 
type on \*(UU machines might be:
.(C
/* 4-byte integer, passed by value */
typedef int int4;
.)C
On the other hand, fixed-length types of any size may be passed
by-reference.  For example, here is a sample implementation of the
\*(PP
.cW char16
type:
.(C
/* 16-byte structure, passed by reference */
typedef struct {
    char data[16];
} char16;
.)C
Only pointers to such types can be used when passing them in and out
of \*(PP functions.
.lp
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
.cW text
type as follows:
.(C
typedef struct {
    int4 length;
    char data[1];
} text;
.)C
Obviously, the
.cW data
field is not long enough to hold all possible strings \(em it's
impossible to declare such a structure in C.  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
.cW text
structure, we might use a code fragment like this:
.(C
#include "tmp/c.h"
#include "tmp/postgres.h"
#include "utils/palloc.h"

\&...

void *buffer; /* our source data */

\&...

text *destination = (text *) palloc(sizeof(int4) + 40);
destination->length = sizeof(int4) + 40;
bcopy(buffer, destination->data, 40);

\&...
.)C
.lp
Now that we've gone over all of the possible structures for base
types, we can show some examples of real functions.
.(C
#include <string.h>

#include "tmp/c.h"
#include "tmp/postgres.h" /* for char16, etc. */
#include "utils/palloc.h" /* for palloc */

int
add_one(arg)
    int arg;
{
    return(arg + 1);
}

char16 *
concat16(arg1, arg2)
    char16 *arg1, *arg2;
{
    char16 *new_c16 = (char16 *) palloc(sizeof(char16));

    memset((void *) new_c16, 0, sizeof(char16));
    (void) strncpy(new_c16, arg1, 16);
    return(strncat(new_c16, arg2, 16));
}

text *
copytext(t)
    text *t;
{
    /*
     * VARSIZE is the total size of the struct in bytes.
     */
    text *new_t = (text *) palloc(VARSIZE(t));

    bzero((char *) new_t, VARSIZE(t));

    /*
     * VARDATA is a pointer to the data region of the struct.
     * VARLEN is the size of VARDATA in bytes (so it's always
     * VARSIZE - sizeof(int4)).
     */
    memcpy((void *) VARDATA(new_t), /* destination */
           (void *) VARDATA(t),     /* source */
           VARLEN(t));              /* how many bytes */
    return(new_t);
}
.)C
On 
.sm ULTRIX 
we would type:
.(C
* define function add_one
      (language = "C", returntype = int4)
      arg is (int4)
      as "/usr/local/postgres/src/examples/chapter8.o" \\g

* define function concat16
      (language = "C", returntype = char16)
      arg is (char16, char16)
      as "/usr/local/postgres/src/examples/chapter8.o" \\g

* define function copytext
      (language = "C", returntype = text)
      arg is (text)
      as "/usr/local/postgres/src/examples/chapter8.o" \\g
.)C
On other systems, we might have to make the filename end in
.cW .so
or
.cW .sl
(to indicate that it's a shared library).
.\"------------------------------------
.sh 3 "Programming Language Functions on Composite Types"
.lp
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, \*(PP provides a procedural interface for accessing fields
of composite types from C.
.lp
As \*(PP processes a set of instances, each instance will be passed
into your function as an opaque structure of type TUPLE.
.lp
Suppose we want to write a function to answer the query
.(C
* retrieve (EMP.all) where c_overpaid(EMP) \\g
.)C
In the query above, we can define
.cW c_overpaid
as:
.(C
#include <tmp/c.h>
#include <tmp/postgres.h>
#include <tmp/libpq-fe.h> /* for TUPLE */

bool
c_overpaid(t, limit) 
    TUPLE t;   /* the current instance of EMP */
    int4 limit;
{
    bool isnull = false;
    int4 salary;

    salary = (int4) GetAttributeByName(t, "salary", &isnull);

    if (isnull == true)
	return((bool) false);
    return((bool) (salary > limit));
}
.)C
.cW GetAttributeByName
is the \*(PP 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.
.cW GetAttributeByName
will align data properly so you can cast its return value to the
desired type.  For example, if you have an attribute
.cW name
which is of the \*(PQ type
.cW char16 ,
the
.cW GetAttributeByName
call would look like:
.(C
char *str;
\&...
str = (char *) GetAttributeByName(t, "name", &isnull)
.)C
.lp
The following query lets \*(PP know about the
.cW c_overpaid
function:
.(C
* define function c_overpaid
      (language = "c", returntype = bool)
      arg is (EMP, int4)
      as "/usr/local/postgres/src/examples/overpaid.o" \\g
.)C
.lp
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.  See the document
.(C
/usr/local/postgres/src/doc/implementation/am.me
.)C
for details.
.\"------------------------------------
.sh 3 "Programming Language Functions on Sets"
.lp
No interface has been defined for passing a set of instances into a
function as an argument to a C function, nor is there such an
interface for returning a set of instances from a C function.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "EXTENDING POSTQUEL: TYPES"
.HL
.lp
As previously mentioned, there are two kinds of types in \*(PP:
.i base
types (defined in a programming language) and 
.i composite
types (instances).
.\"------------------------------------
.bp
.HL
.sh 2 "User-Defined Types"
.HL
.lp
.\"------------------------------------
.sh 3 "Functions Needed for a User-Defined Type"
.lp
A user-defined type must always have
.i input
and
.i 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 representation
of the type.  The output function takes the internal representation of
the type and returns a null-delimited character string.
.lp
These functions are usually not hard to write, especially the output
function.  However, there are a number of points to remember.
.np
When defining your external (string) representation, remember that you
must eventually write a complete and robust parser for that
representation as your input function!  This is easy in some cases, or
if we are lazy.  For example, an input function for
.cW int4
can be as simple as:
.(C
int4
int4_input(s)
    char *s;
{
    return(atoi(s));
}
.)C
if we cheat and use the C library function
.cW atoi
(and don't do any checks for such errors as out-of-range integers).
The output function can be almost as simple:
.(C
char *
int4_output(i)
    int4 i;
{
    /* the largest 32-bit number is 10 digits long */
    char *buf = palloc(11);

    (void) sprintf(buf, "%d", i);
    return(buf);
}
.)C
.np
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.
.lp
As discussed earlier, \*(PP fully supports arrays of base types.
Additionally, \*(PP supports arrays of user-defined types as well.
When you define a type, \*(PP 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
.cW _
prepended.
.lp
Composite types do not need any function defined on them, since the
system already understands what they look like inside.
.\"------------------------------------
.sh 3 "Large Objects"
.lp
The types discussed to this point are all
.q small
objects \(em that is, they are smaller than 8KB\**
.(f
\** 8 * 1024 == 8192 bytes.  In fact, the type must be considerably
smaller than 8192 bytes, since the \*(PP tuple and page overhead
must also fit into this 8KB limitation.  The actual value that fits
depends on the machine architecture.
.)f
in size.  If you require a larger type for something like a document
retrieval system or for storing bitmaps, you will need to use the
\*(PP
.i "large object"
interface.  The interface to large objects is quite similar to the
\*(UU file system interface.  The particulars are detailed in Section
7 of the \*(PP Reference Manual.
.\"------------------------------------
.bp
.HL
.sh 2 "Composite Types"
.HL
.lp
Instances of a composite type are just instances of a class.  Here, we
discuss how to create attributes of one class that are composed of one
or more instances of a composite type (another class).  We can do this
using 
.i "set-valued attributes"
or by using functions to create
.i "virtual attributes" .
.lp
We have already discussed how to define a set-valued attribute using
the
.cW setof
keyword in the 
.cW create 
command.  This produces an attribute whose value is procedurally
defined using a query.
.lp
Since \*(PQ functions return instances or sets of instances, they can
also be used to create
.q attributes
of composite types.  For example, consider extending the
.cW EMP
class with a
.cW manager
field.  That is, for each instance of
.cW EMP ,
we want to associate another instance of
.cW EMP 
corresponding to the manager of the first instance.  Specifically, we
will define a \*(PQ function
.cW manager :
.(C
* define function manager
      (language = "postquel", returntype = EMP)
      arg is (EMP)
      as "retrieve (E.all) from E in EMP
              where E.name = DEPT.manager
              and DEPT.dname = $1.dept" \\g
.)C
When a function takes a single composite type argument, \*(PQ allows
us to use the same
.i nested-dot
notation we used for sets to refer into an instance returned by the
function.  Here, the function
.cW manager
takes an 
.cW EMP
instance as its only argument, we can write the query
.(C
* retrieve (EMP.name)
      where name(manager(EMP)) = "Claire" \\g
.)C
as
.(C
* retrieve (EMP.name)
      where EMP.manager.name = "Claire" \\g
.)C
In either case, we get
.(T
.TS
allbox;
l.
name
Claire
Joe
.TE
.)T
We have essentially added an attribute to the
.cW EMP
class which is of type
.cW EMP ,
i.e., it has a value which is an instance of the class
.cW EMP .
The limitations discussed for set-valued attributes generally apply to
virtual attributes as well.  For example, one cannot do direct updates
to such columns.  That is,
.(C
* append EMP (manager.name = "Smith") \\g
WARN:Mar 10 22:48:42:manager: no such class
.)C
.b won't
work.  Non-projected retrieves don't work either.  For example,
queries that attempt to retrieve the entire 
.cW manager
attribute, such as
.(C
* retrieve (EMP.manager) \\g
.)C
don't return anything useful.
.lp
Note that 
.cW manager
is defined as returning a single instance of
.cW EMP .
We can also write a \*(PQ function that returns sets of instances.
For example, consider the function
.(C
* define function same_dept
      (language = "postquel", returntype = setof EMP)
      arg is (EMP)
      as "retrieve (E.all) from E in EMP
              where $1.dept = E.dept" \\g
.)C
The
.cW same_dept
function is defined as returning a set of instances, rather than a
single instance.  Given the query:
.(C
* retrieve (EMP.name, EMP.same_dept.name) \\g
.)C
.(T
.TS
allbox;
l l.
name	name
Claire	Claire
Claire	Joe
Joe	Claire
Joe	Joe
Sam	Sam
Bill	Bill
Ginger	(null)
.TE
.)T
the query in the body of the
.cW same_dept
function returns many instances and the
.b retrieve
query will return all of them in a
.q flattened
form.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "EXTENDING POSTQUEL: OPERATORS"
.HL
.lp
\*(PQ supports left unary, right unary and binary operators.
Operators can be 
.i 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.  (For a discussion of typecasting, see the Reference
Manual under
.b postquel ).
.lp
In this example, we will use some functions that are already built
into \*(PP to define a set of operators that all have the same name, 
.cW ## .
First, we define left unary operators on both
.cW int4
and
.cW int2
that have very different meanings.  To do this, we will use some
mathemetical functions that already happen to be built into \*(PP.
.cW int4fac ,
.cW int2um/int4um
and
.cW int4pl
are functions that calculate integer factorial, unary minus and
addition, respectively.
.(C
/* n! (factorial) for int4 */
* define operator ## (arg2 = int4,
                      associativity = right,
                      procedure = int4fac)
 \\g

/* -n (negation) for int2 */
* define operator ## (arg2 = int2,
                      associativity = right,
                      procedure = int2um)
 \\g
.)C
Next, we define a right unary operator:
.(C
/* -n (negation) for int4 */
* define operator ## (arg1 = int4,
                      associativity = left,
                      procedure = int4um)
 \\g
.)C
.lp
Finally, we define a binary operator:
.(C
/* a+b (addition) for int4 */
* define operator ## (arg1 = int4,
                      arg2 = int4,
                      procedure = int4pl,
                      commutator = ## )
 \\g
.)C
If we give the system enough type information, it can automatically
figure out which operators to use.  In this case, we can take
advantage of the fact that plain
.q numbers
default to the
.cW int4
type to get the following behavior:
.(C
* retrieve (four_factorial = ## 4,
            minus_five = ## 5::int2,
            minus_four = 4 ##,
            four_plus_four = 4 ## 4)
 \\g
.)C
.(T
.TS
allbox;
l l l l.
four_factorial	minus_five	minus_four	four_plus_four
24	-5	-4	8
.TE
.)T
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "EXTENDING POSTQUEL: AGGREGATES"
.HL
.lp
Creation of user-defined aggregates is explained in the Reference
Manual under
.b "define aggregate" .
The key observation to be made, however, is that any aggregate can be
expressed in terms of
.i "state transition functions" .
That is, an aggregate can be defined in terms of 
.i 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 (\c
.i sfunc1
in the 
.b "define aggregate"
syntax) while others only keep track of their own internal state (\c 
.i sfunc2 ).
.lp
If we define an aggregate that uses only 
.cW sfunc1 ,
we define an aggregate that computes a running function of the
attribute values from each instance.  
.q "Sum"
is an example of this kind of aggregate.  
.q "Sum"
starts at zero and always adds the current instance's value to its
running total.  We will use the
.cW int4pl
that is built into \*(PP to perform this addition.
.(C
* define aggregate my_sum (sfunc1 = int4pl, /* addition */
                           basetype = int4, 
                           stype1 = int4,
                           initcond1 = "0") \\g

* retrieve (salary_sum = my_sum{EMP.salary}) \\g
.)C
.(T
.TS
allbox;
l.
salary_sum
8200
.TE
.)T
If we define only
.cW sfunc2 ,
we are specifying an aggregate that computes a running function that
is independent of the attribute values from each instance.  
.q Count
is the most common example of this kind of aggregate.
.q Count
starts at zero and adds one to its running total for each instance,
ignoring the instance value.  Here, we use the built-in 
.cW int4inc
routine to do the work for us.  This routine increments (adds one to)
its argument.
.(C
* define aggregate my_count (sfunc2 = int4inc, /* add one */
                             stype2 = int4,
                             initcond2 = "0") \\g

* retrieve (emp_count = my_count{EMP.oid}) \\g
.)C
.(T
.TS
allbox;
l.
emp_count
5
.TE
.)T
.q 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
.cW int4pl
and
.cW int4inc
routines we used before as well as the \*(PP integer division routine,
.cW int4div ,
to compute the division of the sum by the count.
.(C
* define aggregate my_average (sfunc1 = int4pl, /* sum */
                               basetype = int4,
                               stype1 = int4,
                               sfunc2 = int4inc, /* count */
                               stype2 = int4,
                               finalfunc = int4div, /* division */
                               initcond1 = "0",
                               initcond2 = "0") \\g

* retrieve (emp_average = my_average{EMP.salary}) \\g
.)C
.(T
.TS
allbox;
l.
emp_average
1640
.TE
.)T
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "EXTENDING POSTQUEL: AN EXAMPLE"
.HL
.lp
In this discussion, we will be defining a
.cW circle
type, using functions written in the C programming language.
.lp
For additional examples of how to create new types, functions and
operators, you should look in the directories
.(C
/usr/local/postgres/src/regress/demo
/usr/local/postgres/src/regress/regress
/usr/local/postgres/src/regress/video
.)C
These directories contain several C and \*(PQ files that should how to
perform various extensions to the system, and the routines we use in
our regression tests should always work.
.\"-----------------
.sh 2 "C Data Structures"
.lp
Before we do anything, we have to decide on what a circle looks like,
both in string format and internally in memory.  Circles have a center
and a radius, so a reasonable string representation of a circle would
be an ordered triple:
.(l
(center_x, center_y, radius)
.)l
where each element is a real number with arbitrary units, e.g.:
.(C
(5.0, 10.3, 3)
.)C
This is what the input to the circle input function looks like, and
what the output from the circle output function looks like.
.lp
Now we have to come up with an internal representation for a circle in
memory.  The following declarations are legal and reasonable given the
format we chose above:
.(C
typedef struct {
    double x, y;
} POINT;

typedef struct {
    POINT center;
    double r;
} CIRCLE;
.)C
Memory containing values of type
.cW CIRCLE
will be written to disk and read from disk, so
.cW CIRCLE
must be both
.i complete
and
.i contiguous ;
that is, it cannot contain any pointers.  The type definition
.(C
typedef struct {
    POINT *center   /* NO! */
    double r;
} CIRCLE;
.)C
will
.i NOT
work, because the virtual memory
.i address 
stored in
.cW center
would be written to disk instead of the contents of the
.cW POINT
structure to which
.cW center
presumably points.  \*(PP cannot detect this kind of coding error; you
must guard against it yourself.
.\"-----------------
.sh 2 "Defining the Input and Output Functions"
.lp
Suppose in defining our type
.q circle,
we have a C source file called
.cW circle.c ,
and a corresponding object code file
.cW /usr/local/postgres/src/examples/circle.o .
(All functions related to our
.cW circle
type must be in the same object file.)  For the purposes of this
discussion, suppose our platform is a MIPS DECstation, where 
.cW sizeof(double)
is 8 bytes.  This assumption will be important later.
.lp
We will create source file
.cW circle.c ,
containing C source code for the functions that support our
.cW CIRCLE
type.
.cW circle.c
contains three functions:
.bu
.cW circle_in ,
which is the input function for circles.  It takes a C string as an 
argument and returns a pointer to a
.cW CIRCLE .
.bu
.cW circle_out ,
which is the output function for circles.  It is takes a pointer to a
.cW CIRCLE
as input and returns a C string.  The return value of
.cW circle_in
must be a legal argument to
.cW circle_out ,
and vice versa.
.bu
.cW eq_area_circle ,
which is the equality function for circles.  For the purposes of this
discussion, circles are equal if their areas are equal.
.lp
The contents of
.cW circle.c
are:
.(C
#include <math.h>
#include <stdio.h>
#include <string.h>

#include "tmp/c.h"           /* (always)                 */
#include "utils/geo-decls.h" /* for POINT declaration    */
#include "utils/palloc.h"    /* for palloc() declaration */

typedef struct {
    POINT  center;
    double radius;
} CIRCLE;

#define LDELIM '('
#define RDELIM ')'
#define NARGS  3

CIRCLE *
circle_in(str)
    char   *str;
{
    char   *p, *coord[NARGS];
    int    i;
    CIRCLE *result;

    if (str == (char *) NULL) 
	return((CIRCLE *) NULL);

    for (i = 0, p = str;
         *p && i < NARGS && *p != RDELIM;
         p++)
    {
        if (*p == ',' || (*p == LDELIM && !i))
            coord[i++] = p + 1;
    }

    if (i < NARGS - 1) 
	return((CIRCLE *) NULL);

    result = (CIRCLE *) palloc(sizeof(CIRCLE));

    result->center.x = atof(coord[0]);
    result->center.y = atof(coord[1]);
    result->radius = atof(coord[2]);

    return(result);
}

char *
circle_out(circle)
    CIRCLE *circle;
{
    char   *result;

    if (circle == (CIRCLE *) NULL)
	return((char *) NULL);

    result = (char *) palloc(60);

    sprintf(result, "(%g, %g, %g)",
            circle->center.x, circle->center.y,
            circle->radius);

    return(result);
}

int
eq_area_circle(circle1, circle2)
    CIRCLE *circle1, *circle2;
{
    if (circle1 == (CIRCLE *) NULL)
	return(circle2 == (CIRCLE *) NULL);
    if (circle2 == (CIRCLE *) NULL)
	return(0);
    return(circle1->radius == circle2->radius);
}
.)C
.lp
Now that we have written these functions and compiled the source file,
we have to let \*(PP know that they exist.  First, we run the
following queries to define the input and output functions.  These
functions must be defined
.i before
we define the type.  \*(PP will notify you that return type circle is
not defined yet, but this is OK.  Notice that we use the keyword
.b any
to indicate that the input and/or output of the function is not a
\*(PP type (e.g., a simple C string).
.(C
* define function circle_in
      (language = "c", returntype = circle)
      arg is (any)
      as "/usr/local/postgres/src/examples/circle.o" \\g

* define function circle_out
      (language = "c", returntype = any)
      arg is (any)
      as "/usr/local/postgres/src/examples/circle.o" \\g
.)C
Note that the full pathname of the object code file must be specified,
so you would change
.cW /usr/local/postgres
to whatever is appropriate for your installation.
.lp
Now we can define the
.cW circle
type:
.(C
* define type circle
      (internallength = 24,
       input = circle_in, output = circle_out) \\g
.)C
where
.cW internallength
is the size of the
.cW CIRCLE
structure in bytes.  For circles, the type members are three
.cW double s,
which on most platforms are 8 bytes each, with no additional alignment
constraints.  However, when defining your own types, you should
.i not
make assumptions about structure sizes, but instead write a test
program that does something like
.(C
printf("size is %d\en", sizeof(MYTYPE));
.)C
on your type.
.lp
If
.cW internallength
is defined incorrectly, you will encounter strange errors and may
crash the server.  If this were to happen with our
.cW CIRCLE
type, we would have to do a
.(C
* remove type circle \\g
.)C
and then redefine the
.cW circle
type correctly.  Note that we would
.i not
have to redefine our functions, since their behavior would not have
changed.
.\"-----------------
.sh 4 "Defining Operators"
.lp
Now that we have finished defining the
.cW circle
type, we can
.b create
classes with circles in them,
.b append
records to them with circles defined, and
.b retrieve
the values of the entire list of records.  However, we can't do
anything terribly useful with them until we have some operators and/or
functions.  To do this, we make use of the concept of
.i "operator overloading" ,
and in this case we will set the \*(PP equality operator
.cW = '' ``
to work for circles.  First we have to tell \*(PP that our circle
equality function exists:
.(C
* define function eq_area_circle
      (language = "c", returntype = bool)
      arg is (circle, circle)
      as "/usr/local/postgres/src/examples/circle.o" \\g
.)C
We will now bind this function to the equality symbol with the
following query:
.(C
* define operator =
      (arg1 = circle, arg2 = circle,
       procedure = eq_area_circle) \\g
.)C
.\"-----------------
.sh 4 "Using a New Type"
.lp
Let's create a class
.cW tutorial
that contains a
.cW circle
attribute, and run some queries against it:
.(C
* create tutorial (a = circle) \\g

* append tutorial (a = "(1.0, 1.0, 10.0)"::circle) \\g

* append tutorial (a = "(2.0, 2.0, 5.0)"::circle) \\g

* append tutorial (a = "(0.0, 1.8, 10.0)"::circle) \\g

* retrieve (tutorial.all)
      where tutorial.a = "(0.0, 0.0, 10.0)"::circle \\g
.)C
which returns:
.(T
.TS
allbox;
l.
a
(1.0, 1.0, 10.0)
(0.0, 1.8, 10.0)
.TE
.)T
Recall that we defined circles as being equal if their areas were
equal.
.lp
Other operators (less than, greater than, etc.) can be defined in a
similar way.  Note that the
.cW =
symbol will still work for other types \(em it has merely had a new
type added to the list of types it works on.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "INTERFACING EXTENSIONS TO INDICES"
.HL
.lp
The procedures described thus far let you define a new type, new
functions and new operators.  However, we cannot yet define a
secondary index (such as a B-tree, R-tree or hash access method) over
a new type or its operators.
.lp
Look back at Figure 3.  The right half shows the catalogs that we must
modify in order to tell \*(PP how to use a user-defined type and/or
user-defined operators with an index (i.e.,
.cW pg_am ,
.cW pg_amop ,
.cW pg_amproc
and
.cW pg_opclass ).
Unfortunately, there is no simple command to do this.  We will
demonstrate how to modify these catalogs through a running example: a
new operator class for the B-tree access method that sorts integers in
ascending absolute value order.
.lp
The
.cW pg_am
class contains one instance for every user-defined access method.
Support for the heap access method is built into \*(PP, but every
other access method is described here.  The schema is
.TS
box center tab(|);
lf(C)|l.
amname|name of the access method
_
amowner|object id of the owner's instance in pg_user
_
amkind|not used at present, but set to 'o' as a place holder
_
amstrategies|number of strategies for this access method (see below)
_
amsupport|number of support routines for this access method (see below)
_
T{
amgettuple
.br
aminsert
.br
\&...
T}|T{
procedure identifiers for interface routines to the access method.
For example,
.cW regproc
ids for opening, closing, and getting instances from the access method
appear here.
T}
.TE
The object ID of the instance in
.cW pg_am
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
object ID of the access method instance you want to extend:
.(C
* retrieve (pg_am.oid) where pg_am.amname = "btree" \\g
.TS
allbox;
l.
oid
403
.TE
.)C
The
.cW amstrategies
attribute exists to standardize comparisons across data types.  For
example, B-trees impose a strict ordering on keys, lesser to greater.
Since \*(PP allows the user to define operators, \*(PP cannot look at
the
.b name
of an operator (eg,
.cW >
or
.cW < )
and tell what kind of comparison it is.  In fact, some access methods
don't impose any ordering at all.  For example, R-trees express a
rectangle-containment relationship, whereas a hashed data structure
expresses only bitwise similarity based on the value of a hash
function.  \*(PP 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 \*(PP needs to know, for example,
that the
.cW <=
and
.cW >
operators partition a B-tree.  \*(PP uses strategies to express these
relationships between operators and the way they can be used to scan
indices.
.lp
Defining a new set of strategies is beyond the scope of this
discussion, but we'll explain how B-tree strategies work because
you'll need to know that to add a new operator class.  In the
.cW pg_am
class, the
.cW amstrategies
attribute is the number of strategies defined for this access method.
For B-trees, this number is 5.  These strategies correspond to
.TS
allbox center tab(|);
l n.
less than|1
less than or equal|2
equal|3
greater than or equal|4
greater than|5
.TE
The idea is that you'll need to add procedures corresponding to the
comparisons above to the
.cW pg_amop
relation (see below).  The access method code can use these strategy
numbers, regardless of data type, to figure out how to partition the
B-tree, 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
.cW int2 ,
.cW int4 ,
.cW oid ,
and every other data type on which a B-tree can operate.
.lp
Sometimes, strategies aren't enough information for the system to
figure out how to use an index.  Some access methods require other
support routines in order to work.  For example, the B-tree 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 R-tree
access method must be able to compute intersections, unions, and sizes
of rectangles.  These operations do not correspond to user
qualifications in \*(PQ queries; they are administrative routines used
by the access methods, internally.
.lp
In order to manage diverse support routines consistently across all
\*(PP access methods,
.cW pg_am
includes a field called
.cW amsupport .
This field records the number of support routines used by an access
method.  For B-trees, this number is one \(em the routine to take two
keys and return \(mi\^1, 0, or \(pl\^1, depending on whether the first
key is less than, equal to, or greater than the second.\**
.(f
\** Strictly speaking, this routine can return a negative number (<
0), 0, or a non-zero positive number (> 0).
.)f
.lp
The
.cW amstrategies
entry in
.cW pg_am
is just the 
.i number
of strategies defined for the access method in question.  The
procedures for less than, less equal, and so on don't appear in
.cW pg_am .
Similarly,
.cW amsupport
is just the number of support routines required by the access method.
The actual routines are listed elsewhere.
.lp
The next class of interest is
.cW pg_opclass.
This class exists only to associate a name with an
.cW oid .
In
.cW pg_amop ,
every B-tree operator class has a set of procedures, one through five,
above.  Some existing opclasses are
.cW int2_ops ,
.cW int4_ops ,
and
.cW oid_ops .
You need to add an instance with your opclass name (for example,
.cW int4_abs_ops )
to
.cW pg_opclass .
The
.cW oid
of this instance is a foreign key in other classes.
.(C
* append pg_opclass (opcname = "int4_abs_ops") \\g

* retrieve (cl.oid, cl.opcname) from cl in pg_opclass
      where cl.opcname = "int4_abs_ops" \\g
.TS
tab(|) allbox;
l l.
oid|opcname
17314|int4_abs_ops
.TE
.)C
Note that the
.cW oid
for your
.cW pg_opclass
instance
.b "will be different" !
You should substitute your value for 17314 wherever it appears in this
discussion.
.lp
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
.cW int4_abs_ops
operator class on B-trees, the operators we require are:
.(l
absolute value less-than
absolute value less-than-or-equal
absolute value equal
absolute value greater-than-or-equal
absolute value greater-than
.)l
Suppose the code that implements the functions defined is stored in
the file
.(C
/usr/local/postgres/src/examples/int4_abs.c
.)C
The code is
.(C
/*
 * int4_abs.c -- absolute value comparison functions
 *               for int4 data
 */

#include "tmp/c.h"

#define ABS(a) ((a < 0) ? -a : a)

/* routines to implement operators */

bool int4_abs_lt(a, b) int32 a, b;
     { return(ABS(a) < ABS(b)); }

bool int4_abs_le(a, b) int32 a, b;
     { return(ABS(a) <= ABS(b)); }

bool int4_abs_eq(a, b) int32 a, b;
     { return(ABS(a) == ABS(b)); }

bool int4_abs_ge(a, b) int32 a, b;
     { return(ABS(a) >= ABS(b)); }

bool int4_abs_gt(a, b) int32 a, b;
     { return(ABS(a) > ABS(b)); }

/* support (signed comparison) routine */

int int4_abs_cmp(a, b) int32 a, b;
     { return(ABS(a) - ABS(b)); }
.)C
There are a couple of important things that are happening below.
.lp
First, note that operators for less-than, less-than-or-equal, equal,
greater-than-or-equal, and greater-than for
.cW int4
are being defined.  All of these operators are already defined for
.cW int4
under the names
.cW < ,
.cW <= ,
.cW = ,
.cW >= ,
and
.cW > .
The new operators behave differently, of course.  In order to
guarantee that \*(PP 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 \*(PP, but only if the
operator isn't already defined for the argument types.  That is, if
you have
.cW <
defined for
.cW int4 , (
.cW int4 ),
you can't define it again.
\*(PP
.b "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.
.lp
The other important point is that all the operator functions return
.i Boolean
values.  The access methods rely on this fact.  (On the other hand,
the support function returns whatever the particular access method
expects \(em in this case, a signed integer.)
.lp
The final routine in the file is the 
.q "support routine"
mentioned when we discussed the
.cW amsupport
attribute of the
.cW pg_am
class.  We will use this later on.  For now, ignore it.
.(C
* define function int4_abs_lt
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/src/examples/int4_abs.o" \\g

* define function int4_abs_le
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/src/examples/int4_abs.o" \\g

* define function int4_abs_eq
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/src/examples/int4_abs.o" \\g

* define function int4_abs_ge
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/src/examples/int4_abs.o" \\g

* define function int4_abs_gt
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/src/examples/int4_abs.o" \\g
.)C
Now define the operators that use them.  As noted, the operator names
must be unique among all operators that take two
.cW int4
operands.  In order to see if the operator names listed below are
taken, we can do a query on
.cW pg_operator :
.(C
/*
 * this query uses the regular expression operator (~)
 * to find three-character operator names that end in
 * the character &
 */
* retrieve (o.all)
    from o in pg_operator
    where o.oprname ~ "^..&$"::text \\g
.)C
to see if your name is taken for the types you want.  The important
things here are the procedure (which are the C functions defined
above) and the restriction and join selectivity functions.  You should
just use the ones used below\(emnote that there are different such
functions for the less-than, equal, and greater-than cases.  These
.i must
be supplied, or the access method will crash when it tries to use the
operator.  You should copy the names for
.cW restrict
and
.cW join ,
but use the procedure names you defined in the last step.
.(C
* define operator <<&
      (arg1 = int4, arg2 = int4, procedure=int4_abs_lt,
       associativity = left, restrict = intltsel,
       join = intltjoinsel) \\g

* define operator <=&
      (arg1 = int4, arg2 = int4, procedure = int4_abs_le,
       associativity = left, restrict = intltsel,
       join = intltjoinsel) \\g

* define operator ==&
      (arg1 = int4, arg2 = int4, procedure = int4_abs_eq,
       associativity = left, restrict = eqsel,
       join = eqjoinsel) \\g

* define operator >=&
      (arg1 = int4, arg2 = int4, procedure = int4_abs_ge,
       associativity = left, restrict = intgtsel,
       join = intgtjoinsel) \\g

* define operator >>&
      (arg1 = int4, arg2 = int4, procedure = int4_abs_gt,
       associativity = left, restrict = intgtsel,
       join = intgtjoinsel) \\g
.)C
Notice that five operators corresponding to less, less equal, equal,
greater, and greater equal are defined.
.lp
We're just about finished. the last thing we need to do is to update
the
.cW pg_amop
relation.  To do this, we need the following attributes:
.TS
allbox center tab(|);
lf(C) l.
amopid|T{
the
.cW oid
of the
.cW pg_am
instance for B-tree (== 403, see above)
T}
amopclaid|T{
the
.cW oid
of the
.cW pg_opclass
instance for
.cW int4_abs_ops
(== whatever you got instead of 17314, see above)
T}
amopopr|T{
the
.cW oid s
of the operators for the opclass (which we'll get in just a minute)
T}
T{
amopselect,
.br
amopnpages
T}|cost functions.
.TE
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
.cW btreesel,
which estimates the selectivity of the B-tree, and
.cW btreenpage,
which estimates the number of pages a search will touch in the tree.
.lp
So we need the
.cW oid s
of the operators we just defined.  We'll look up the names of all the
operators that take two
.cW int4 s,
and pick ours out:
.(C
* retrieve (o.oid, o.oprname)
      from o in pg_operator, t in pg_type
      where o.oprleft = t.oid and o.oprright = t.oid
          and t.typname = "int4" \\g
.)C
which returns:
.(T
.TS
tab(|) allbox;
l l.
oid|oprname
96|\\=
97|<
514|*
518|!=
521|>
523|<=
525|>=
528|/
530|%
551|+
555|-
17321|<<&
17322|<=&
17323|==&
17324|>=&
17325|>>&
.TE
.)T
(Again, some of your
.cW oid
numbers will almost certainly be different.)  The operators we are
interested in are those with
.cW oid 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.
.lp
Now we're ready to update
.cW pg_amop
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
.cW pg_amop .
Recall that the B-tree instance's
.cW oid
is 403 and
.cW int4_abs_ops
is
.cW oid
17314.  Then we add the instances we need:
.(C
* append pg_amop
      (amopid = "403"::oid,          /* btree oid        */
       amopclaid = "17314"::oid,     /* pg_opclass tuple */
       amopopr = "17321"::oid,       /* <<& tup oid      */
       amopstrategy = "1"::int2,     /* 1 is <<&         */
       amopselect = "btreesel"::regproc,
       amopnpages = "btreenpage"::regproc) \\g

* append pg_amop (amopid = "403"::oid,
                  amopclaid = "17314"::oid,
                  amopopr = "17322"::oid,
                  amopstrategy = "2"::int2,
                  amopselect = "btreesel"::regproc,
                  amopnpages = "btreenpage"::regproc) \\g

* append pg_amop (amopid = "403"::oid,
                  amopclaid = "17314"::oid,
                  amopopr = "17323"::oid,
                  amopstrategy = "3"::int2,
                  amopselect = "btreesel"::regproc,
                  amopnpages = "btreenpage"::regproc) \\g

* append pg_amop (amopid = "403"::oid,
                  amopclaid = "17314"::oid,
                  amopopr = "17324"::oid,
                  amopstrategy = "4"::int2,
                  amopselect = "btreesel"::regproc,
                  amopnpages = "btreenpage"::regproc) \\g

* append pg_amop (amopid = "403"::oid,
                  amopclaid = "17314"::oid,
                  amopopr = "17325"::oid,
                  amopstrategy = "5"::int2,
                  amopselect = "btreesel"::regproc,
                  amopnpages = "btreenpage"::regproc) \\g
.)C
Note the order:
.q "less than"
is 1,
.q "less than or equal"
is 2,
.q "equal"
is 3,
.q "greater than or equal"
is 4,
and
.q "greater than"
is 5.
.lp
In the file
.(C
/usr/local/postgres/src/examples/chapter13
.)C
we show the \*(PQ that performs the four-way join between 
.cW pg_amop ,
.cW pg_opclass ,
.cW pg_operator
and
.cW pg_type .
Doing the join obviates the need to write down any 
.cW oid s
but the query is considerably more complicated-looking.
.lp
The last step (finally!) is registration of the 
.q "support routine"
previously described in our discussion of
.cW pg_am .
The 
.cW oid
of this support routine is stored in the
.cW pg_amproc
class, keyed by the access method
.cW oid
and the operator class
.cW oid .
First, we need to register the function in \*(PP (recall that we put
the C code that implements this routine in the bottom of the file in
which we implemented the operator routines):
.(C
* define function int4_abs_cmp
      (language = "c", returntype = int4)
      arg is (int4, int4)
      as "/usr/local/postgres/src/examples/int4_abs.o" \\g

* retrieve (p.oid, p.proname)
      from p in pg_proc
      where p.proname = "int4_abs_cmp" \\g
.TS
tab(|) allbox;
l l.
oid|proname
17328|int4_abs_cmp
.TE
.)C
(Again, your
.cW oid
number will probably be different and you should substitute the value
you see for the value below.)  Recalling that the B-tree instance's
.cW oid 
is 403 and that of 
.cW int4_abs_ops
is 17314, we can add the new instance as follows:
.(C
* append pg_amproc
	(amid = "403"::oid,        /* btree oid        */
	 amopclaid = "17314"::oid, /* pg_opclass tuple */
	 amproc = "17328"::oid,    /* new pg_proc oid */
	 amprocnum = "1"::int2) \eg
.)C
.lp
Okay, now it's time to test the new operator class.  First we'll
create and populate a class\**:
.(f
\** In this example, we append only a few instances into the class.
In fact, \*(PP uses a 
.q cost-based
query optimizer that makes the decision whether or not to use an index
based on how much data is touched.  Since this example creates a very
small amount of data, the example will likely not work as advertised
\(em one would have to insert a fair amount of data before using an
index would actually be cheaper than just scanning the underlying heap
data structure.
.q "A fair amount"
typically means on the order of several kilobytes.
.)f
.(C
* create pairs (name = char16, number = int4) \\g

* append pairs (name = "mike", number = -10000) \\g

* append pairs (name = "greg", number = 3000) \\g

* append pairs (name = "lay peng", number = 5000) \\g

* append pairs (name = "jeff", number = -2000) \\g

* append pairs (name = "mao", number = 7000) \\g

* append pairs (name = "cimarron", number = -3000) \\g

* retrieve (pairs.all) \\g
.TS
tab(|) allbox;
l l.
name|number
mike|-10000
greg|3000
lay peng|5000
jeff|-2000
mao|7000
cimarron|-3000
.TE
.)C
Okay, looks pretty random.  Define an index using the new opclass:
.(C
* define index pairsind on pairs
      using btree (number int4_abs_ops) \\g
.)C
Now run a query that doesn't use one of our new operators.  What we're
trying to do here is to run a query that
.i won't
use our index, so that we can tell the difference when we see a query
that
.i does
use the index.  This query won't use the index because the operator we
use in the qualification isn't one that appears in the list of
strategies for our index.
.(C
* retrieve (pairs.all) where pairs.number < 9000 \\g
.TS
tab(|) allbox;
l l.
name|number
mike|-10000
greg|3000
lay peng|5000
jeff|-2000
mao|7000
cimarron|-3000
.TE
.)C
Yup, just as random; that didn't use the index.  Okay, let's run a
query that
.i does
use the index:
.(C
* retrieve (pairs.all) where pairs.number <<& 9000 \\g
.TS
tab(|) allbox;
l l.
name|number
jeff|-2000
cimarron|-3000
greg|3000
lay peng|5000
mao|7000
.TE
.)C
Note that the
.cW number
values are in order of increasing absolute value (as they should be,
since the index was used for this scan) and that we got the right
answer \(em the instance for
.cW mike
doesn't appear, because \(mi10000 
.cW ">=&"
9000.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "THE POSTGRES RULE SYSTEM"
.HL
.lp
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 \*(PP
rule system here.  Instead, you should read [STON90b] to understand
some of these points and the theoretical foundations of the \*(PP rule
system before trying to use rules.  The discussion in this section is
intended to provide an overview of the \*(PP rule system and point the
user at helpful references and examples.
.lp
The main point you should understand is that \*(PP actually has two
rule systems, the
.i "instance-level"
rule system and the
.i "query rewrite"
rule system, and that there are tradeoffs in the employment of each.
.lp
The 
.i "instance-level"
rule system uses markers placed in each instance in a class to
.q "trigger"
rules.  Examples of the instance-level rule system are explained and
illustrated in
.cW /usr/local/postgres/src/regress/demo ,
which is included with the \*(PP distribution.  Additional discussion
of the instance-level rule system can be found in the Reference Manual
under
.b "define rule" .
.lp
The 
.q "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.  Examples can be found in
.cW /usr/local/postgres/src/regress/video ,
and further discussion is in the Reference Manual under
.b "define rule" .
The power of this rule system is discussed in [ONG90] as well as
[STON90b].
.lp
Since each rule system is implemented quite differently, they work
best in different situations.  The query rewrite system is best when
rules affect 
.i most
of the instances in a class, while the instance-level system is best
when a rule affects only a
.i few
instances.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "ADMINISTERING POSTGRES"
.HL
.lp
In this section, we will discuss aspects of \*(PP that are of interest
to those who make extensive use of \*(PP, or who are the site
administrator for a group of \*(PP users.
.\"------------------------------------
.bp
.HL
.sh 2 "Frequent Tasks"
.HL
.lp
Here we will briefly discuss some procedures that you should be
familiar with in managing any \*(PP installation.
.\"------------------------------------
.sh 3 "Starting the Postmaster"
.lp
If you did not install \*(PP exactly as described in the installation
instructions, you may have to perform some additional steps before
starting the 
.cW postmaster
process.
.bu
Even if you were not the person who installed \*(PP, you should
understand the installation instructions.  The installation
instructions explain some important issues with respect to where \*(PP
places some important files, proper settings for environment
variables, etc. that may vary from one version of \*(PP to another.
.bu
You should look at the Reference Manual under the heading
.b postmaster
if you wish to use non-default options (e.g., increased security
options, a non-standard installation directory, etc.).
.bu
You 
.i must
start the
.cW postmaster
process with the user-id that owns the installed database files.  In
most cases, if you have followed the installation instructions, this
will be the user
.q postgres .
If you do not start the 
.cW postmaster
with the right user-id, the backend servers that are started by the
.cW postmaster
will not be able to read the data.
.bu
Make sure that 
.cW /usr/local/postgres/bin
is in your shell command path, because the
.cW postmaster
will use your 
.cW PATH
to locate \*(PP commands.
.bu
Remember to set the environment variable
.cW PGDATA
to the directory where the \*(PP databases are installed.  (This
variable is more fully explained in the \*(PP installation
instructions and the Reference Manual.)
.bu
If you do start the 
.cW postmaster
using non-standard options, such as a different TCP port number,
remember to tell all users so that they can set their 
.cW PGPORT
environment variable correctly.
.\"------------------------------------
.sh 3 "Shutting Down the Postmaster"
.lp
If you need to halt the
.cW postmaster
process, you can use the \*(UU
.cW kill (1)
command.  Some people habitually use the 
.cW -9
or
.cW -KILL
option; this should never be necessary and we do not recommend that
you do this, as the
.cW postmaster
will be unable to free its various shared resources, its child
processes will be unable to exit gracefully, etc.
.\"------------------------------------
.sh 3 "Adding and Removing Users"
.lp
The
.cW createuser
and
.cW destroyuser
commands enable and disable access to \*(PP by specific users on the 
host system.  Please read the descriptions of these commands in the
Reference Manual for specific instructions on their use.
.\"------------------------------------
.sh 3 "Periodic Upkeep"
.lp
The
.cW vacuum
command should be run on each database periodically.  This command
processes deleted instances\**
.(f
\** This may mean different things depending on the 
.i "archive mode"
with which each class has been created.  See the Reference Manual
under the heading
.b "create"
for more details.  However, the current implementation of the 
.cW vacuum
command does
.i not
perform any compaction or clustering of data.  Therefore, the \*(UU
files which store each \*(PP class never shrink and the space
.q reclaimed 
by 
.cW vacuum
is never actually reused.
.)f
and, more importantly, updates the system
.i statistics
concerning the size of each class.  If these statistics are permitted
to become out-of-date and inaccurate, the \*(PP query optimizer may
make extremely poor decisions with respect to query evaluation
strategies.  Therefore, we recommend running
.cW vacuum
every night or so (perhaps in a script that is executed by the \*(UU
.cW cron (1)
or
.cW at (1) 
commands).
.lp
.b "Do frequent backups" .
That is, you should either back up your database directories using the
\*(PP
.b copy
command and/or the \*(UU
.cW dump (1)
or
.cW tar (1)
commands.  You may think, 
.q "Why am I backing up my database?  What about crash recovery?"
One side effect of the \*(PP 
.q "no overwrite"
storage manager is that it is also a 
.q "no log"
storage manager.  That is, the database log stores only abort/commit
data, and this is not enough information to recover the database if
the storage medium (disk) or the database files are corrupted!  In
other words, if a disk block goes bad or \*(PP happens to corrupt a
database file, 
.b "you cannot recover that file" .
This can be disastrous if the file is one of the shared catalogs, such
as 
.cW pg_database .
.\"------------------------------------
.sh 3 "Tuning"
.lp
Once your users start to load a significant amount of data, you will
typically run into performance problems.  \*(PP is not the fastest
DBMS in the world, but many of the worst problems encountered by users
are due to their lack of experience with any DBMS.  Some general tips
include:
.np
Define indices over attributes that are commonly used for
qualifications.  For example, if you often execute queries of the form
.(C
retrieve (EMP.all) where EMP.salary < 5000
.)C
then a B-tree index on the 
.cW salary
column will probably be useful.  If scans involving equality are more
common, as in
.(C
retrieve (EMP.all) where EMP.salary = 5000
.)C
then you should consider defining a hash index on 
.cW salary .
You can define both, though it will use more disk space and may slow 
down updates a bit.  Scans using indices are
.b much
faster than sequential scans of the entire class.
.np
Run the
.cW vacuum
command a lot.  This command updates the statistics that the query
optimizer uses to make intelligent decisions; if the statistics are
inaccurate, the system will make inordinately stupid decisions with
respect to the way it joins and scans classes.
.np
When specifying query qualfications (i.e., the
.cW where
part of the query), try to ensure that a clause involving a constant
can be turned into one of the form
.i "range_variable operator constant" ,
e.g.,
.(C
EMP.salary = 5000
.)C
The \*(PP query optimizer will only use an index with a constant
qualification of this form.  It doesn't hurt to write the clause as
.(C
5000 = EMP.salary
.)C
if the operator (in this case,
.cW = )
has a 
.i commutator
operator defined so that \*(PP can rewrite the query into the desired
form.  However, if such an operator does not exist, \*(PP will never
consider the use of an index.
.np
When joining several classes together in one query, try to write the
join clauses in a 
.q chained
form, e.g.,
.(C
where A.a = B.b and B.b = C.c and ...
.)C
Notice that relatively few clauses refer to a given class and
attribute; the clauses form a linear sequence connecting the
attributes, like links in a chain.  This is preferable to a query
written in a
.q star
form, such as
.(C
where A.a = B.b and A.a = C.c and ...
.)C
Here, many clauses refer to the same class and attribute (in this
case,
.cW A.a ).
When presented with a query of this form, the \*(PP query optimizer
will tend to consider far more choices than it should and may run out
of memory.
.np
If you are really desperate to see what query plans look like, you can
run the
.cW postmaster
with the 
.cW -d
option and then run 
.cW monitor
with the 
.cW -t
option.  The format in which query plans will be printed is hard to
read but you should be able to tell whether any index scans are being
performed.  See the Reference Manual under
.b postgres
and 
.b postmaster .
.\"------------------------------------
.bp
.HL
.sh 2 "Infrequent Tasks"
.HL
.lp
At some time or another, every \*(PP site administrator has to perform
all of the following actions.
.\"------------------------------------
.sh 3 "Cleaning Up After Crashes"
.lp
The 
.cW postgres
server and the
.cW postmaster
run as two different processes.  They may crash separately or
together.  The housekeeping procedures required to fix one kind of
crash are different from those required to fix the other.
.lp
The message you will usually see when the backend server crashes is:
.(C
FATAL: no response from backend: detected in ...
.)C
This generally means one of two things: there is a bug in the \*(PP
server, or there is a bug in some user code that has been dynamically
loaded into \*(PP.  You should be able to restart your application and
resume processing, but there are some considerations:
.np
\*(PP usually dumps a core file (a snapshot of process memory used for
debugging) in the database directory
.(C
/usr/local/postgres/data/base/<database>/core
.)C
on the server machine.  If you don't want to try to debug the problem
or produce a stack trace to report the bug to someone else, you can
delete this file (which is probably around 10MB).
.np
When one backend crashes in an uncontrolled way (i.e., without calling
its built-in cleanup routines), the 
.cW postmaster
will detect this situation, kill all running servers and reinitialize
the state shared among all backends (e.g., the shared buffer pool and
locks).  If your server crashed, you will get the 
.q "no response" 
message shown above.  If your server was killed because someone else's
server crashed, you will see the following message:
.(C
I have been signalled by the postmaster.
Some backend process has died unexpectedly and possibly
corrupted shared memory.  The current transaction was
aborted, and I am going to exit.  Please resend the
last query. -- The postgres backend
.)C
.np
Sometimes shared state is not completely cleaned up.  Frontend
applications may see errors of the form:
.(C
WARN:Mar 11 14:41:29: cannot write block 34 of myclass [mydb] blind
.)C
In this case, you should kill the 
.cW postmaster
and restart it.
.np
When the system crashes while updating the system catalogs (e.g., when
you are creating a class, defining an index, retrieving into a table,
etc.) the B-tree indices defined on the catalogs are sometimes
corrupted.  The general (and non-unique) symptom is that 
.b all
queries stop working.  If you have tried all of the above steps and
nothing else seems to work, try using the
.cW reindexdb 
command.  If 
.cW reindexdb
succeeds but things still don't work, you have another problem; if it
fails, the system catalogs themselves were almost certainly corrupted
and you will have to go back to your backups.
.lp
The
.cW postmaster
does not usually crash (it doesn't do very much except start servers)
but it does happen on occasion.  In addition, there are a few cases
where it encounters problems during the reinitialization of shared
resources.  Specifically, there are race conditions where the
operating system lets the
.cW postmaster
free shared resources but then will not permit it to reallocate the
same amount of shared resources (even when there is no contention).
.lp
You will typically have to run the
.cW ipcclean
command if system errors cause the
.cW postmaster
to crash.
If this happens, you may find (using the \*(UU
.cW ipcs (1)
command) that the
.q postgres
user has shared memory and/or semaphores allocated even though no
.cW postmaster
process is running.  In this case, you should run
.cW ipcclean
as the
.q postgres
user in order to deallocate these resources.  Be warned that 
.i all
such resources owned by the
.q postgres
user will be deallocated.  If you have multiple
.cW postmaster
processes running on the same machine, you should kill all of them
before running
.cW ipcclean 
(otherwise, they will crash on their own when their shared resources
are suddenly deallocated).
.\"------------------------------------
.sh 3 "Moving Database Directories"
.lp
By default,
all \*(PP databases are stored in separate subdirectories under
.cW /usr/local/postgres/data/base .\**
.(f
\** Data for certain classes may stored elsewhere if a non-standard
storage manager was specified when they were created.  Use of
non-standard storage managers is an experimental feature that is not
supported outside of Berkeley.
.)f
At some point, you may find that you wish to move one or more
databases to another location (e.g., to a filesystem with more free
space).
.lp
If you wish to move 
.i all
of your databases to the new location, you can simply:
.bu
Kill the 
.cW postmaster .
.bu
Copy the entire
.cW data
directory to the new location (making sure that the new files are
owned by user
.q postgres ).
.(C
% cp -rp /usr/local/postgres/data /new/place/data
.)C
.bu
Reset your
.cW PGDATA
environment variable (as described earlier in this manual and in the
installation instructions).
.(C
# using csh or tcsh...
% setenv PGDATA /new/place/data

# using sh, ksh or bash...
% PGDATA=/new/place/data; export PGDATA
.)C
.bu
Restart the 
.cW postmaster .
.(C
% postmaster &
.)C
.bu
After you run some queries and are sure that the newly-moved database
works, you can remove the old
.cW data
directory.
.(C
% rm -rf /usr/local/postgres/data
.)C
.lp
To install a 
.i single
database in an alternate directory while leaving all other databases
in place, do the following:
.bu
Create the database (if it doesn't already exist) using the
.b createdb
command.  In the following steps we will assume the database is named
.cW foo .
.bu
Kill the 
.cW postmaster .
.bu
Copy the directory
.cW /usr/local/postgres/data/base/foo
and its contents to its ultimate destination.  It should still be
owned by the
.q postgres
user.
.(C
% cp -rp /usr/local/postgres/data/base/foo /new/place/foo
.)C
.bu
Remove the directory
.cW /usr/local/postgres/data/base/foo :
.(C
% rm -rf /usr/local/postgres/data/base/foo
.)C
.bu
Make a symbolic link from
.cW /usr/local/postgres/data/base
to the new directory:
.(C
% ln -s /new/place/foo /usr/local/postgres/data/base/foo
.)C
.bu
Restart the 
.cW postmaster .
.\"------------------------------------
.sh 3 "Updating Databases"
.lp
\*(PP is a research system.  In general, \*(PP may not retain the same
binary format for the storage of databases from release to release.
Therefore, when you update your \*(PP software, you will probably have
to modify your databases as well.  This is a common occurrence with
commercial database systems as well; unfortunately, unlike commercial
systems, \*(PP does not come with user-friendly utilities to make your
life easier when these updates occur.
.lp
In general, you must do the following to update your databases to a
new software release:
.bu
.i Extensions
(such as user-defined types, functions, aggregates, etc.) must be
reloaded by re-executing the \*(PQ
.b define
commands.  Notice that as of Version 4.2, the method by which you
generate object code for user-defined functions has changed, so you
may have to modify your old
.cW .o
files.  See Appendix A for more details.
.bu
.i Data
must be dumped from the old classes into ASCII files (using the \*(PQ 
.b copy
command), the new classes created in the new database (using the \*(PQ
.b create
command), and the data reloaded from the ASCII files.
.bu
.i Rules
and
.i views
must also be reloaded by re-executing the various \*(PQ
.b define
commands.
.lp
You should give any new release a 
.q "trial period" ;
in particular, do not delete the old database until you are satisfied
that there are no compatibility problems with the new software.  For
example, you do not want to discover that a bug in a type's
.q input
(conversion from ASCII)
and
.q output
(conversion to ASCII) routines prevents you from reloading your data
after you have destroyed your old databases!  (This should be standard
procedure when updating any software package, but some people try to
economize on disk space without applying enough foresight.)
.\"------------------------------------
.bp
.HL
.sh 2 "Database Security"
.HL
.lp
Most sites that use \*(PP are educational or research institutions and
do not pay much attention to security in their \*(PP installations.
If desired, one can install \*(PP with additional security features.
Naturally, such features come with additional administrative overhead
that must be dealt with.
.\"------------------------------------
.sh 3 "Kerberos"
.lp
\*(PP can be configured to use the MIT Kerberos network authentication
system.  This prevents outside users from connecting to your databases
over the network without the correct authentication information.  For
more information on Kerberos, see the file
.cW src/doc/kerberos.faq
and the 
.b \*(UU
section of the Reference Manual.
.\"------------------------------------
.sh 3 "Access Control"
.lp
.i "Access control lists"
(ACLs) can be defined on a per-class basis.  These work rather like a
more flexible version of the \*(UU
.cW chmod (1)
command.  See the Reference Manual under the heading
.b "change acl"
for more details.
.\"------------------------------------
.bp
.HL
.sh 2 "Querying the System Catalogs"
.HL
.lp
As an administrator (or sometimes as a plain user), you want to find
out what extensions have been added to a given database.  The queries
listed below are
.q canned
queries that you can run on any database to get simple answers.
Before executing any of the queries below, be sure to execute the
\*(PP
.cW vacuum
command.  (The queries will run much more quickly that way.)  Also,
note that these queries are also listed in
.(C
/usr/local/postgres/src/examples/chapter15
.)C
so use cut-and-paste (or the
.cW \ei
command) instead of doing a lot of typing.
.lp
This query prints the names of all database adminstrators and the name
of their database(s).
.(C
* retrieve (user_name = u.usename,
            database = d.datname)
      from u in pg_user,
           d in pg_database
      where u.usesysid = int2in(int4out(d.datdba))
      sort by user_name, database
 \\g
.)C
This query lists all user-defined classes in the database.
.(C
* retrieve (class_name = c.relname)
      from c in pg_class
      where c.relkind = 'r'      /* no indices */
        and c.relname !~ "^pg_"  /* no catalogs */
      sort by class_name
 \\g
.)C
This query lists all simple indices (i.e., those that are not defined
over a function of several attributes).
.(C
* retrieve (class_name = bc.relname,
            index_name = ic.relname,
            attr_name = a.attname)
      from bc in pg_class,         /* base class */
           ic in pg_class,         /* index class */
           i in pg_index,
           a in pg_attribute       /* att in base */
      where i.indrelid = bc.oid
        and i.indexrelid = ic.oid
        and i.indkey[0] = a.attnum
        and a.attrelid = bc.oid
        and i.indproc = "0"::oid   /* no functional indices */
      sort by class_name, index_name, 
              attr_name
.)C
This query prints a report of the user-defined attributes and their
types for all user-defined classes in the database.
.(C
* retrieve (class_name = c.relname, 
            attr_name = a.attname, 
            attr_type = t.typname)
      from c in pg_class,
           a in pg_attribute,
           t in pg_type
      where c.relkind = 'r'     /* no indices */
        and c.relname !~ "^pg_" /* no catalogs */
        and a.attnum > 0        /* no system att's */
        and a.attrelid = c.oid
        and a.atttypid = t.oid
      sort by class_name, attr_name
 \\g
.)C
This query lists all user-defined base types (not including array
types).
.(C
* retrieve (owner_name = u.usename,
            type_name = t.typname)
      from t in pg_type,
           u in pg_user
      where u.usesysid = int2in(int4out(t.typowner))
        and t.typrelid = "0"::oid   /* no complex types */
        and t.typelem = "0"::oid    /* no arrays */
        and u.usename != "postgres"
      sort by owner_name, type_name
 \\g
.)C
This query lists all left-associative (post-fix) operators.
.(C
* retrieve (left_unary = o.oprname,
            operand = right.typname,
            return_type = result.typname)
      from o in pg_operator,
           right in pg_type,
           result in pg_type
      where o.oprkind = 'l'           /* left unary */
        and o.oprright = right.oid
        and o.oprresult = result.oid
      sort by operand
 \\g
.)C
This query lists all right-associative (pre-fix) operators.
.(C
* retrieve (right_unary = o.oprname,
            operand = left.typname,
            return_type = result.typname)
      from o in pg_operator,
           left in pg_type,
           result in pg_type
      where o.oprkind = 'r'          /* right unary */
        and o.oprleft = left.oid
        and o.oprresult = result.oid
      sort by operand
 \\g
.)C
This query lists all binary operators.
.(C
* retrieve (binary_op = o.oprname,
            left_opr = left.typname,
            right_opr = right.typname, 
            return_type = result.typname)
      from o in pg_operator,
           left in pg_type,
           right in pg_type,
           result in pg_type
      where o.oprkind = 'b'         /* binary */
        and o.oprleft = left.oid
        and o.oprright = right.oid
        and o.oprresult = result.oid
      sort by left_opr, right_opr
 \\g
.)C
This query returns the name, number of arguments (parameters) and
return type of all user-defined C functions.  The same query can be
used to find all built-in C functions if you change the
.q C
to 
.q internal ,
or all \*(PQ functions if you change the
.q C
to 
.q postquel .
.(C
* retrieve (p.proname, 
            arguments = p.pronargs,
            returntype = t.typname)
      from p in pg_proc,
           l in pg_language,
           t in pg_type
      where p.prolang = l.oid
        and p.prorettype = t.oid
        and l.lanname = "C"
      sort by proname
 \\g
.)C
This query lists all of the aggregate functions that have been
installed and the types to which they can be applied.
.cW count
is not included because it can take any type as its argument.
.(C
* retrieve (aggregate_name = a.aggname,
            type_name = t.typname)
      from a in pg_aggregate,
           t in pg_type
      where a.aggbasetype = t.oid
      sort by aggregate_name, type_name
 \\g
.)C
This query lists all of the operator classes that can be used with
each access method as well as the operators that can be used with the
respective operator classes.
.(C
* retrieve (access_method = am.amname,
            operator_class = opc.opcname,
            operator_name = opr.oprname)
      from am in pg_am,
           amop in pg_amop,
           opc in pg_opclass,
           opr in pg_operator
      where amop.amopid = am.oid
        and amop.amopclaid = opc.oid
        and amop.amopopr = opr.oid
      sort by access_method, operator_class, 
              operator_name
 \\g
.)C
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 1 "REFERENCES"
.HL
.\"------------------------------------
.xP [ONG90]
Ong, L. and Goh, J.,
``A Unified Framework for Version Modeling Using Production Rules in a
Database System,"
Electronics Research Laboratory,
University of California,
ERL Technical Memorandum M90/33,
Berkeley, CA,
April 1990.
.\"------------------------------------
.xP [ROWE87]
Rowe, L. and Stonebraker, M.,
``The POSTGRES Data Model,''
Proc. 1987 VLDB Conference,
Brighton, England,
Sept. 1987.
.\"------------------------------------
.xP [STON86]
Stonebraker, M. and Rowe, L.,
``The Design of POSTGRES,''
Proc. 1986 ACM-SIGMOD Conference on Management of Data,
Washington, DC,
May 1986.
.\"------------------------------------
.xP [STON87a]
Stonebraker, M., Hanson, E. and Hong, C.-H.,
``The Design of the POSTGRES Rules System,''
Proc. 1987 IEEE Conference on Data Engineering,
Los Angeles, CA,
Feb. 1987.
.\"------------------------------------
.xP [STON87b]
Stonebraker, M.,
``The POSTGRES Storage System,''
Proc. 1987 VLDB Conference,
Brighton, England,
Sept. 1987.
.\"------------------------------------
.xP [STON89]
Stonebraker, M., Hearst, M., and Potamianos, S.,
``A Commentary on the POSTGRES Rules System,''
SIGMOD Record \fI18\fP(3),
Sept. 1989.
.\"------------------------------------
.xP [STON90a]
Stonebraker, M., Rowe, L. A., and Hirohama, M.,
``The Implementation of POSTGRES,''
IEEE Transactions on Knowledge and Data Engineering \fI2\fP(1),
March 1990.
.\"------------------------------------
.xP [STON90b]
Stonebraker, M. et al.,
``On Rules, Procedures, Caching and Views in Database Systems,''
Proc. 1990 ACM-SIGMOD Conference on Management of Data,
Atlantic City, N.J.,
June 1990.
.\"---------------------------------------------------------------------------
.bp
.HL
.sh 0 "Appendix A: Linking Dynamically-Loaded Functions"
.HL
.lp
After you have created and registered a user-defined function, your
work is essentially done.  \*(PP, however, must load the 
.i "object code"
(e.g., a
.cW .o 
file, or a shared library) that implements your function.  As
previously mentioned, \*(PP loads your code at run-time, as required.
In order to allow your code to be dynamically loaded, you may have to
compile and link-edit it in a special way.  This section briefly
describes how to perform the compilation and link-editing required
before you can load your user-defined functions into a running \*(PP
server.  Note that
.i "this process has changed as of Version 4.2." \**
.(f
\** The old \*(PP 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 \*(PP 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 \*(UU 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 post-processed a bit before it can be loaded
into \*(PP.  We hope that the large increase in speed and reliability
will make up for the slight decrease in convenience.
.)f
You should expect to read (and reread,
and re-reread) the manual pages for the C compiler,
.cW cc (1),
and the link editor,
.cW ld (1),
if you have specific questions.  In addition, the regression test
suites in the directory
.cW /usr/local/postgres/src/regress
contain several working examples of this process.  If you copy what
these tests do, you should not have any problems.
.lp
The following terminology will be used below:
.ip "Dynamic loading"
is what \*(PP does to an object file.  The object file is copied into
the running \*(PP server and the functions and variables within the
file are made available to the functions within the \*(PP process.
\*(PP does this using the dynamic loading mechanism provided by the
operating system.
.ip "Loading and link editing"
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,
.cW ld (1).
.lp
The following general restrictions and notes also apply to the
discussion below.
.bu
Paths given to the
.b "define function"
command must be absolute paths (i.e., start with \*(lq/\*(rq) that
refer to directories visible on the machine on which the \*(PP server
is running.\**
.(f 
\** 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!
.)f
.bu
The \*(PP user must be able to traverse the path given to the
.b "define function"
command and be able to read the object file.  This is because the
\*(PP server runs as the \*(PP 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 
.q postgres
user is an 
.i extremely
common mistake.)
.bu
Symbol names defined within object files must not conflict with each
other or with symbols defined in \*(PP.
.bu
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.
.uh "ULTRIX"
.lp
It is very easy to build dynamically-loaded object files under 
ULTRIX.  ULTRIX does not have any shared-library 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.
.lp
Under ULTRIX, the only restriction is that you must produce each
object file with the option
.cW "-G 0" .
(Notice that that's the numeral
.cW 0 '' ``
and not the letter
.cW O ''). ``
For example,
.(C
	# simple ULTRIX example
	% cc -G 0 -c foo.c
.)C
produces an object file called
.cW "foo.o"
that can then be dynamically loaded into \*(PP.  No additional loading
or link-editing must be performed.
.uh "DEC OSF/1"
.lp
Under DEC OSF/1, you can take any simple object file and produce a
shared object file by running the
.cW ld
command over it with the correct options.  The commands to do this
look like:
.(C
	# simple DEC OSF/1 example
	% cc -c foo.c
	% ld -shared -expect_unresolved '*' -o foo.so foo.o
.)C
The resulting shared object file can then be loaded into \*(PP.  When
specifying the object file name to the
.b "define function"
command, one must give it the name of the shared object file (ending
in
.cW ".so" )
rather than the simple object file.\**
.(f
\** Actually, \*(PP 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
.cW ".o" ,
this is fine with \*(PP so long as you make sure that the correct file
name is given to the
.b "define 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
.cW Makefile s
to do the link-editing automatically if both the object file and the
shared object file end in
.cW ".o" !
.)f
.uh "SunOS 4.x, Solaris 2.x and HP-UX"
.lp
Under both SunOS 4.x, Solaris 2.x and HP-UX, the simple object file
must be created by compiling the source file with special compiler
flags
.i and
a shared library must be produced.
.lp
The necessary steps with HP-UX are as follows.  The
.cW "+z"
flag to the HP-UX C compiler produces so-called 
.q "Position Independent Code"
(PIC) and the 
.cW "+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
.cW "-b"
option.  This sounds complicated but is actually very simple, since
the commands to do it are just:
.(C
	# simple HP-UX example
	% cc +z +u -c foo.c
	% ld -b -o foo.sl foo.o
.)C
As with the 
.cW ".so"
files mentioned in the last subsection, the 
.b "define 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
.cW ".sl"
file).
.lp
Under SunOS 4.x, the commands look like:
.(C
	# simple SunOS 4.x example
	% cc -PIC -c foo.c
	% ld -dc -dp -Bdynamic -o foo.so foo.o
.)C
and the equivalent lines under Solaris 2.x are:
.(C
	# 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
.)C
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
.cW ld
command line.
.uh "AIX"
.lp
AIX, like SunOS, OSF/1 and HP-UX, requires users to build shared
object files in order to use its built-in dynamic loading mechanism.
No special compiler options must be given to build the simple object
file.  However, AIX provides a very general, flexible and complicated
interface for producing shared object files.  As a result, it is
(relatively) difficult to produce dynamically-loaded object files.
Bear in mind that this only means that it is difficult when compared
to the mechanisms just discussed; it's really not that hard to do.
.lp
AIX allows the user to tell it which program symbols (e.g., function
and global variable names) should be visible to other pieces of code.
This can be convenient in certain cases.  Unfortunately, AIX also
.i requires
the user to tell it which symbols should be visible (i.e., the default
behavior is to disallow sharing).  AIX controls this behavior by using
.i "export files"
and
.i "import files" .
.ip
A symbol may be
.i exported
from the shared object file to the program into which the shared
object file is being loaded.  In other words, the export file
specifies which symbols defined within the shared object file can be
accessed by \*(PP.  We usually want all symbols to be visible to
\*(PP.
.ip
A symbol may be
.i imported
by the shared object file from the program into which the shared
object file is being loaded.  In other words, the import file
specifies which symbols defined with the \*(PP server can be called by
routines defined within the shared object file.  Again, we usually
want all \*(PP symbols to be visible to the user code.
.lp
Hence, in order to load a shared object file, one must have an export
file for the shared object file as well as an import file for the
\*(PP backend server.  This turns out to be easy to do, since export
and import files have the same basic format and may be produced from
the simple object file(s) by running the
.cW mkldexport
command that comes with \*(PP.  The following three steps should work
for most cases:
.(C
	# simple AIX example, using Bourne shell
	% cc -c foo.c
	% mkldexport foo.o `pwd` > foo.exp
	% ld -H512 -T512 -o foo.so -e _nostart \e
		-bI:/usr/local/postgres/lib/postgres.exp \e
		-bE:foo.exp foo.o -lm -lc 2>/dev/null
.)C
The values given for the 
.cW -H ,
.cW -T
and 
.cW -e
flags to 
.cW ld
should simply be taken as voodoo.  The file specified by the
.cW -bI:
flag is produced when the \*(PP server is compiled and installed.
(The library directory 
.cW /usr/local/postgres/lib
given in the example may differ if you have installed \*(PP in a
different place, of course.)  The file specified by the
.cW -bE:
flag must be produced by hand (using the
.cW mkldexport
command, as shown) before the
.cW .so
shared object file can be produced.\**
.(f
\** If you wish to create a shared object file for use with untrusted
functions (see the Reference Manual under the heading
.b "define function" ,
you must use the
.cW pg_ufp.exp
exports file instead of the
.cW postgres.exp
exports file.
.)f
You are probably asking,
.q "If it's so easy, why not do it all for me?!"
In fact, the magic command lines given above do work in most cases and
so could be embedded within \*(PP and hidden from the user.  However,
there are circumstances in which it will fail.  In these cases, the
user must be able to control the loader flags with which the shared
object file is constructed.  In addition, since the file system
.i locations
of the various object files are hardcoded into the export/import files
(and hence into the shared object file), this fact should also be
visible to the user.  Finally, by putting the export/import files
under user control, the user can do as the designers of AIX intended
and actually edit the files (i.e., control link-editing) as desired.
.lp
If you want an actual understanding of how the AIX loader actually
works, you should take a look at the tutorials written by Gary Hook at
the IBM AIX Systems Center.  These tutorials are located in 
.(l
.cW /usr/local/postgres/src/doc/useful/aix-linking.ps
.cW /usr/local/postgres/src/doc/useful/aix-advlink.ps
.)l
@


1.32
log
@fix calls to GetAttributeByName
@
text
@d27 1
a27 1
.\" $Header: /usr/local/devel/postgres/src/doc/user_manual/RCS/manual.me,v 1.31 1994/03/26 09:43:56 aoki Exp aoki $
d250 4
a253 4
DECstation 3000|Alpha AXP|OSF/1 1.3
DECstation 3100 and 5000|MIPS|ULTRIX 4.2, 4.3A
Sun4|SPARC|SunOS 4.1.3
H-P 9000/700 and 800|PA-RISC|HP-UX 9.00, 9.01
d257 8
a264 8
\*(UU is a trademark of Unix Systems Laboratories.  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.  RS/6000,
POWER and AIX are trademarks of International Business Machines Corp.
OSF/1 is a trademark of the Open Systems Foundation.  NeXTSTEP is a
trademark of NeXT Computer, Inc.  MIPS and IRIX are trademarks of
Silicon Graphics, Inc.
d267 3
a269 4
Symmetry machines.  \*(PP no longer runs on these systems, nor does it
currently run on Sun Microsystems computers running the Solaris 2
(SunOS 5) operating system.  Outside users have ported previous
releases of \*(PP to many platforms, including 
d271 1
a271 1
Solaris 2.2, IRIX, Intel System V Release 4, Linux and NetBSD.
d4884 1
a4884 1
.uh "SunOS 4 and HP-UX"
d4886 3
a4888 2
Under both SunOS 4 and HP-UX, the simple object file must be created
by compiling the source file with special compiler flags
d4918 1
a4918 1
Under SunOS 4, the commands look like:
d4920 1
a4920 1
	# simple SunOS 4 example
d4924 8
@


1.31
log
@correct a lie about defining indices
@
text
@d27 1
a27 1
.\" $Header: /usr/local/devel/postgres/src/doc/user_manual/RCS/manual.me,v 1.30 1994/03/12 09:57:29 aoki Exp aoki $
d2363 1
d2370 1
a2370 1
    extern char *GetAttributeByName();
d2373 1
a2373 1
    salary = (int4) GetAttributeByName(t, "salary");
d2375 2
d2382 3
a2384 2
current instance.  It has two arguments: the argument of type TUPLE
passed into the function, and the name of the desired attribute.
d2397 1
a2397 1
str = (char *) GetAttributeByName(t, "name")
@


1.30
log
@mention reindexdb
fix some typos
@
text
@d27 1
a27 1
.\" $Header: /usr/local/devel/postgres/src/doc/user_manual/RCS/manual.me,v 1.29 1994/03/11 23:11:11 aoki Exp aoki $
d318 4
a321 1
and it doesn't hurt to know a query language such as QUEL or SQL.
d4108 2
a4109 2
It doesn't hurt to define both (though it will use more disk space).
Scans using indices are
@


1.29
log
@more admin notes
@
text
@d27 1
a27 1
.\" $Header: /usr/local/devel/postgres/src/doc/user_manual/RCS/manual.me,v 1.28 1994/03/11 11:52:48 aoki Exp aoki $
d4239 14
d4485 1
a4485 1
note that the text used to generate this document can be found in
d4489 3
a4491 1
so use cut-and-paste instead of doing a lot of typing.
@


1.28
log
@formatting glitches
@
text
@d27 1
a27 1
.\" $Header: /usr/local/devel/postgres/src/doc/user_manual/RCS/manual.me,v 1.27 1994/03/11 11:19:05 aoki Exp aoki $
d2676 8
a2683 1
that have very different meanings:
d2768 3
a2770 1
running total.
d2795 4
a2798 1
ignoring the instance value.
d2815 10
a2824 5
is an example of an aggregate that requires both a function that
computes the running sum and a function that computes 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. 
d3202 1
a3202 1
new operator class to the B-tree access method that sorts integers in
d4058 24
d4146 4
a4149 1
rather than in a 
d4151 1
a4151 1
form such as
d4155 3
d4173 4
a4176 1
performed.
d4188 64
a4251 1
You may have occasion to run the
@


1.27
log
@new formatting
@
text
@d27 1
a27 1
.\" $Header: /usr/local/devel/postgres/src/doc/RCS/manual.me,v 1.26 1994/02/10 01:47:00 sunita Exp aoki $
d1758 9
a1814 9
.(z
.hl
.PSPIC manual-er.eps 6i 6.01776i
.sp
.(c
\fBFigure 3\fP.  The major \*(PP system catalogs.
.)c
.hl
.)z
d3208 1
d3210 1
@


1.26
log
@fixed the part on arrays.
@
text
@d1 1
a1 1
.\" This is -*-nroff-*- with tbl and -me macros
d27 1
a27 1
.\" $Header: /usr/local/devel/postgres/src/doc/RCS/manual.me,v 1.25 1994/02/09 20:51:56 aoki Exp sunita $
d30 1
a30 1
.he '\*(dA'DRAFT'\*(tI'		\" comment out in production version
d91 1
a91 1
.fo ''\\s+2%\\s0''			\" +2-pt page numbers in center footers
d95 1
a95 1
.\"------------------------------------
d97 17
d117 3
d122 1
a122 1
\s+3The \*(PP User Manual\s0
d131 18
d150 2
d153 1
d155 17
a171 5
This document is the user manual for the \*(PP database system under
development at the University of California at Berkeley.  This
project, led by Professor Michael Stonebraker, is sponsored by the
Defense Advanced Research Projects Agency (DARPA), the Army Research
Office (ARO), the National Science Foundation (NSF), and ESL, Inc.
d173 1
a173 1
.sh 2 "An Overview of \*(PP"
d198 1
a198 1
.sh 2 "Status of the \*(PP Project"
d200 7
a206 5
The \*(PP DBMS has been under construction since 1986.  The initial
concepts for the system were presented in [STON86] and the definition
of the initial data model appeared in [ROWE87].  The first rule system
that was implemented is discussed in [STON87a] and the storage manager
concepts are detailed in [STON87b].  The first
d208 33
a240 8
was operational in 1987, and we released Version 1 of \*(PP to a few
external users in June 1989.  A critique of the first rule system
followed in [STON89].  A detailed description of Version 1 of \*(PP
appeared in [STON90a].  Version 2 was released in June 1990 and
included the new rule system documented in [STON90b].  Version \*(PV,
the current version of \*(PP, is about 200,000 lines of code in the C
programming language.  \*(PP is available free of charge, and is being
used by approximately 500 sites around the world.
d242 1
a242 1
This manual describes Version \*(PV of \*(PP.  The \*(PP Group has
d245 4
a248 4
center tab(|);
c | c
l | l .
architecture (processor)|operating system
d250 5
a254 5
DECstation 3000 (Alpha AXP)|OSF/1 1.3
DECstation 3100 and 5000 (MIPS)|ULTRIX 4.2, 4.3a
Sun4 (SPARC)|SunOS 4.1.2, 4.1.3
H-P 9000/700 (PA-RISC)|HP-UX 9.01
IBM RS/6000 (POWER)|AIX 3.2.3
d262 3
a264 1
OSF/1 is a trademark of the Open Systems Foundation.
d268 5
a272 2
run on Sun Microsystems computers running the Solaris 2 (SunOS 5)
operating system.
a277 56
.\"------------------------------------
.sh 2 "Acknowledgements"
.lp
\*(PP has been constructed by a team of undergraduate,
graduate, and staff programmers.
The contributors (in alphabetical order) include:
Jeff Anton,
Paul Aoki,
James Bell,
Jennifer Caetta,
Philip Chang,
Jolly Chen,
Ron Choi,
Bob Devine,
Matt Dillon,
Zelaine Fong,
Adam Glass,
Jeffrey Goh,
Steven Grady,
Serge Granik,
Marti Hearst,
Joey Hellerstein,
Michael Hirohama,
Chin-heng Hong,
Wei Hong,
Anant Jhingran,
Greg Kemnitz,
Case Larsen,
Boris Livshitz,
Jeff Meredith,
Michael Olson,
Nels Olson,
Lay-Peng Ong,
Carol Paxson,
Avi Pfeffer,
Spyros Potamianos,
Sunita Sarawagi,
David Muir Sharnoff,
Cimarron Taylor,
Marc Teitelbaum,
Yongdong Wang,
Kristin Wright
and
Andrew Yu.
The HP-UX port is courtesy of Richard Turnbull (University of
Liverpool) and Sebastian Fernandez (University of California at
Berkeley).  The initial AIX port was performed by Rafael Morales
Gamboa (ITESM Campus Morelos, Cuernavaca).
.lp
For version \*(PV, Marc Teitelbaum served as chief programmer and was
responsible for overall coordination of the project.
.lp
This manual is a substantial rewrite of a previous version edited by
Jon Rhein and Greg Kemnitz.  The above implementation team contributed
significantly to this manual and its predecessor, as did Michael
Stonebraker, Chandra Ghosh and Claire Mosher.
d279 2
d282 1
d285 4
a288 3
system, as well as to illustrate how programmers would use functions
to interact with the \*(PP database server (commonly referred to as
the
d292 2
a293 2
Reference Manual.  The Reference Manual fully describes the syntax and
options for each command in a format similar to that used in \*(UU
d295 6
a300 4
The Reference Manual is designed as a complete reference for the
experienced \*(PP user and contains few tutorial examples.  This
manual does not attempt to provide all of the information that the
Reference Manual provides.  Instead, this manual describes the major
d313 6
a318 1
\*(PP, as this is not discussed at all in this manual.
d320 64
a383 1
.sh 1 "ORGANIZATION"
d385 14
a398 9
The first part of this manual goes over some basic system concepts and
procedures for starting the \*(PP system.  We then turn to an overview
of the \*(PQ query language.  Next, we describe user extensions such
as user-defined types, operators, aggregates, and both query language
and programming language functions.  This is followed by an extremely
brief overview of the \*(PP rule system.  The manual concludes with a
series of detailed appendices that discuss some of the more involved
procedures involved in extending the system, such as adding an
operator class to \*(PP for use in access methods.
d400 25
a424 1
.sh 1 "GETTING STARTED WITH \*(PP"
d426 1
a426 1
In the discussion that follows, examples that begin with the character
d433 1
a433 1
.sh 2 "Installing \*(PP"
d435 2
a436 2
Installation instructions can be found in the \*(PP source code
distribution.  The 
d439 13
a451 5
.cW src/doc/postgres-setup.me .
Those instructions vary from release to release and will not be
duplicated here.  However, if you are installing \*(PP now, you 
.i must
read these instructions and carry them out before going any further.
d453 10
a462 1
.sh 2 "Setting Up Your Environment"
d464 5
a468 1
In the examples that follow, we will assume that \*(PP has been
d470 2
a472 3
with the default settings.  In practice, \*(PP can be installed
anywhere you like.  Throughout this document, wherever you see
.cW /usr/local/postgres
d486 1
a486 1
set path = ( /usr/local/postgres/bin $path )
d498 2
a499 2
PATH=/usr/local/postgres/bin:$PATH
export PATH
d516 1
a516 35
.sh 2 "Starting the Postmaster"
.lp
Before we continue, you should understand the basic \*(PP system
architecture.  A \*(PP session consists of three cooperating \*(UU
processes:
.bu
the postmaster
.cW postmaster ), (
.bu
the frontend application, such as the terminal monitor
.cW monitor ), (
and
.bu
the backend database server
.cW postgres ). (
.lp
A single
.cW postmaster
process manages a given collection of 
.i databases .
Such a collection of databases is called an
.i installation .
Frontend applications that wish to access a given database within an
installation send their requests over the network to the 
.cW postmaster ,
which in turn connects each frontend application to a backend server
that responds to its queries.  Hence, the
.cW postmaster
runs all the time, waiting for requests, while the frontend and
backend processes come and go.  Another implication of this
architecture is that the
.cW postmaster
and the backend always run on the same machine (the database server),
while the frontend application may or may not be running on a
separate machine (e.g., a client workstation).
d518 1
a518 1
It should be clear from the preceding paragraph that nothing can
d521 2
a522 19
process is running.  If you get the following error message from a
\*(PP command (such as
.cW monitor
or
.cW createdb ):
.(C
FATAL: StreamOpen: connect() failed: errno=61
FATAL: Failed to connect to postmaster (host=xxx, port=4321)
        Is the postmaster running?
.)C
it is usually because the
.cW postmaster
is not running.  Therefore, your local \*(PP site administrator should
ensure that the
.cW postmaster
is running at all times.
.lp
If you are the site administrator, there are a number of things you
should remember before starting the
d533 1
a533 1
If the 
d539 21
d561 1
a561 1
.sh 2 "Starting Applications"
d565 3
a567 2
process, you (as a user) may begin to start up applications.  As
previously mentioned, you should add 
d585 15
a599 2
.\"---------------------------------------------------------------------------
.sh 1 "USING THE \*(PQ QUERY LANGUAGE"
d601 8
a608 4
\*(PQ is the query language used for interacting with \*(PP.  In this
section, we give an overview of how to use \*(PQ to access data.  The
next section will discuss ways in which ordinary users can extend
\*(PQ.
d610 1
a610 1
.sh 2 "Managing a Database"
d612 3
a614 1
Here, we describe a few basic commands for managing a database.
d625 4
a628 3
you automatically become the database administrator of the database
just created.  Database names must have an alphabetic first character
and are limited to 16 characters in length.
d630 1
d653 3
a655 2
facility, which allows you to directly execute functions stored in the
This facility is (minimally) described in the Reference Manual under
d675 8
a682 3
terminal monitor.  White space (i.e., spaces, tabs and newlines) may
be used freely in \*(PQ queries.  You may view the current contents of
the workspace by typing:
d684 1
a684 1
* \\p
d689 1
a689 1
* \\g
d691 2
d695 3
a697 1
text editor by typing:
d699 1
a699 1
* \\e
d714 19
a732 1
will return you to your command shell.
d750 30
a779 2
.\"------------------------------------
.sh 2 "Basic Use of the \*(PQ Query Language"
d781 1
a781 1
.sh 3 "Concepts"
d791 1
a791 1
Furthermore, each instance has an installation-wide unique, permanent
d793 1
a793 1
(OID).
d798 1
a798 1
process constitutes an installation.
d800 1
a800 6
.sh 3 "Creating a New Class"
.lp
In the examples that follow, we assume that you have created the
.cW foo
database as described in the previous subsection and have started the
terminal monitor.
d802 1
a802 1
A user can create a new class by specifying the class name, along with
d822 7
a828 3
traditional relational system.  However, we will presently see that
classes have properties that are extensions of the relational model,
so we use a different word to describe them.
d830 1
a830 1
.sh 3 "Populating a Class with Instances"
d832 1
a832 1
.ds xX \n($1.\n($2.\n($3
d834 1
a834 1
To populate a class with instances, one can use the
d836 1
a836 1
command:
d838 3
d849 9
d859 1
a859 1
This will add 3 instances to the
d861 1
a861 2
class,
one for each
d864 7
d872 1
a872 1
.sh 3 "Querying a Class"
d876 14
a889 3
class can be queried with normal selection and projection queries.
For example, to find the employees under 35 years of age, one would
type:
d893 1
a893 1
and the output would be:
d902 4
a905 5
Notice that parentheses are required around the
.i "target list"
of returned attributes
(e.g.,
.cW EMP.name .)
d908 1
a908 2
as long as they are given a name (e.g.,
.cW result ):
d913 13
a925 2
.\"-----------------
.sh 3 "Redirecting Retrieve Queries"
d927 1
a927 4
Any 
.b retrieve
query can be redirected to a new class in the database, and arbitrary
Boolean operators
d932 29
a960 1
are allowed in the qualification of any query:
d965 19
d985 1
a985 1
.sh 3 "Joins Between Classes"
d1014 10
a1023 1
In this case both 
d1059 1
a1059 1
.sh 3 "Updates"
d1061 1
a1061 1
Updates are accomplished in \*(PQ using the
d1079 1
a1079 1
.sh 3 "Deletions"
d1081 1
a1081 1
Deletions are done using the
d1094 1
a1094 1
* delete \fIclassname\fP \\g
d1099 7
a1105 1
it empty.  The system will not request confirmation before doing this.
d1107 1
a1107 1
.sh 3 "Arrays"
d1109 4
a1112 4
\*(PP 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.
d1114 1
a1114 2
* create SAL_EMP (name = text, pay_by_quarter = int4[],
  		schedule = char16[][]) \\g
d1116 12
a1127 101
The above query will create a class named
.cW SAL_EMP
with a 
.cW text
string
.cW name ), (
a one-dimensional array of
.cW int4
.cW pay_by_quarter ), (
which represents the employee's salary by quarter and a two-dimensional array of
.cW char16
.cW schedule ), (
which represents the employee's weekly schedule.  
Now we do some
.cW append s;
note that when appending to an array, we enclose the
values within braces and separate them by commas (following a C-like syntax).
.(C
* append SAL_EMP (name = "bill", 
		pay_by_quarter[4] = "{10000, 10000, 10000, 10000}", 
		schedule[7][2] = "{{"meeting", "lunch"}, {}}") \\g

* append SAL_EMP (name = "{"joe"}",
      	pay_by_quarter = "{20000, 25000, 25000, 25000}", 
		schedule[5][2] = "{{"talk", "consult"}, {"meeting"}}") \\g
.)C
By default, \*(PP uses the 
.q one-based
numbering convention for arrays \(em that is, \*(PP arrays start with
array[1] and end with array[n].  (This is the same convention used in
Pascal and FORTRAN.). Note that the elements of an array can be specified partly
or fully. For example, for the attribute
.cW schedule, 
we have initialized only part of 
the array elements. The uninitialized elements are filled with garbage 
and can be updated later using the 
.cW replace 
command.
.lp
Now, we can run some queries on
.cW SAL_EMP .
This query retrieves the names of the employees whose pay changed in
the second quarter:
.(C
* retrieve (SAL_EMP.name)
      where SAL_EMP.pay_by_quarter[1] !=
            SAL_EMP.pay_by_quarter[2] \\g
.)C
This query retrieves the third quarter pay of all employees:
.(C
* retrieve (SAL_EMP.pay_by_quarter[3]) \\g
.)C
This query retrieves the first item on the schedule of the first 
three working days for 
.cW "bill".
.(C
* retrieve (SAL_EMP.schedule[1:3][1:1]) 
		where SAL_EMP.name = "bill" \\g
.)C
The
.cW replace
command can be used to update an element of an array or a subpart of an array.
This query updates the schedule for the second and third day for 
.cW "joe".
.(C
* replace SAL_EMP (schedule[2:3][1:2] = 
		"{{"debugging", "shopping"}, {"meeting", "present"}}") 
		where SAL_EMP.name = "joe" \\g
.)C
This query gives a $1000 raise in the first quater to all members whose first
item on schedule for the first working day is 
.cW "debugging" 
.(C
* replace SAL_EMP (pay_by_quarter[1] = 
		SAL_EMP.pay_by_quarter[1] + 1000)
			where SAL_EMP.schedule[1][1] = "debugging" \\g
.)C
When arrays are too large to fit in a single page they can be stored as 
large objects by giving the
name of a large object file as the array string at 
.cW append
time. 
For example, the following append query will cause the array data to be
stored as a large object.
.(C
* append SAL_EMP (name = "Busy_guy", 
		schedule[7][101] = "/LO_name") \\g 
.)C
The 
.cW replace 
query can be used to populate the large object array using the same syntax
as used for ordinary arrays. This query will cause the first four slots
on
.cW "Busy_guy's"
.cW schedule 
to be filled.
.(C
* replace SAL_EMP (schedule[1:1][1:4] = 
		"{{"debugging", "shopping"}, {"meeting", "present"}}") 
		where SAL_EMP.name = "Busy_guy" \\g
.)C
d1129 1
a1129 1
.sh 3 "Aggregate Functions"
d1131 6
a1136 6
Like relational query languages such as SQL, \*(PP supports aggregate
functions.  However, the current implementation of \*(PP aggregate
functions is very limited.  Specifically, while there are aggregates
to compute such functions as the count, sum, average, maximum and
minimum over a set of instances, aggregates can only appear in the
target list of a query and not in the qualification (also known as the
d1142 8
d1156 8
d1167 1
a1167 1
.i not
d1173 2
d1180 4
a1183 1
neither disallowed nor are they supported.)
d1185 1
a1185 1
.sh 3 "Help!  What Are the Valid Types, Operators, Etc.??"
d1194 4
a1197 3
available by default in \*(PP, and these are listed in Section 3 of
the Reference Manual.  This would be a good time to go ahead and take
a peek at that section.
d1203 10
a1212 10
.\"------------------------------------
.sh 2 "Advanced \*(PQ"
.lp
Now we have covered the basics of using \*(PQ to access your data.  In
this section we will discuss those features of \*(PP which distinguish
it from other data managers, such as inheritance and time travel.  In
the next section we will cover how the user can extend the query
language via query language functions and composite objects, as well
as additional extensions to \*(PP using user-defined types, operators,
and programming language functions.
d1214 1
a1214 1
.sh 3 "Inheritance"
d1216 1
a1216 1
First, re-populate the
d1254 11
d1276 1
d1292 13
d1314 1
a1314 1
.sh 3 "Time Travel"
d1324 8
d1346 6
a1351 2
indicates the beginning of the \*(UU system clock.  If you have
executed all of the examples so far, then the above query returns:
d1376 259
d1636 4
a1639 1
.sh 1 "USER EXTENSIONS TO \*(PQ"
d1641 4
a1644 2
Here, we will discuss user extensions to the \*(PQ query language,
such as:
d1646 1
a1646 1
query language functions
d1648 1
a1648 1
composite types
d1650 39
a1688 1
user-defined types, operators, functions and aggregates
d1690 136
a1825 1
.sh 2 "Query Language (\*(PQ) Functions"
d1831 168
a1998 4
(functions written in a separately-compiled programming language such
as C.)  In this section we will cover \*(PQ functions; programming
language functions will be covered below with the discussion on
user-defined types.
d2000 25
d2026 36
a2061 2
together and defined as a function, usually returning either a set of
instances or a set of base types.  For example, the following function
d2063 1
a2063 1
returns all employees in class
d2065 1
a2065 1
whose salaries exceed 50,000:
d2069 243
a2311 1
      as "retrieve (EMP.all) where EMP.salary > 50000" \\g
d2313 3
a2315 3
\*(PQ functions can also have parameters.  The following function
.cW large_pay
allows the threshold salary to be specified as an argument:
d2317 2
a2318 2
* define function large_pay
      (language = "postquel", returntype = setof EMP)
d2320 159
a2478 1
      as "retrieve (EMP.all) where EMP.salary > $1" \\g
d2480 36
a2515 4
In addition to their obvious utility as
.q aliases
for commonly-used queries, \*(PQ functions are useful for creating
composite types, as described below.
d2517 2
d2520 1
d2522 20
a2541 3
Since \*(PQ functions return instances or sets of instances, they are
the mechanism used to assign values to composite types.  For example,
consider extending the
d2545 1
a2545 2
field.
That is, for each instance of
d2560 5
a2564 1
The function
d2566 3
a2568 7
takes an instance as its only argument, so \*(PQ allows referencing
into it with the use of the nested dot notation.  Whenever such a
function is defined over a class, a user can utilize the cascaded dot
notation to reference into (i.e. access the fields of) the objects
returned by the function.
.lp
The following query finds all the employees who work for Joe:
d2570 2
a2571 1
* retrieve (EMP.name) where EMP.manager.name = "Joe" \\g
d2573 1
a2573 1
This is exactly equivalent to:
d2576 1
a2576 1
      where name(manager(EMP)) = "Joe" \\g
d2578 11
a2588 1
Here, we have essentially added an attribute to the
d2594 10
a2603 5
Since the value of
.cW manager
has a record-oriented structure, we call it a
.i "composite object" .
Consequently, the user can think of the function
d2605 1
a2605 11
as an attribute of
.cW EMP
and can reference it just like any other attribute, with the following
two exceptions.  First, one cannot do direct
.b append s
\(em that is,
.(C
* append emp (emp.manager.name = "Smith") \\g
.)C
.i won't
work.  Non-projected retrieves will also be rejected.  For example,
d2607 1
a2607 1
* retrieve (emp.manager) \\g
d2609 1
a2609 1
will result in a warning from the \*(PQ language parser.
d2614 1
a2614 1
.cW EMP.
d2618 2
a2619 2
* define function children
      (language = "postquel", returntype = setof KIDS)
d2621 2
a2622 3
      as "retrieve (KIDS.all)
              where $1.name = KIDS.dad
              or $1.name = KIDS.mom"\\g
d2625 1
a2625 1
.cW children
d2629 1
a2629 1
* retrieve(emp.name, emp.children.name)
d2631 17
a2647 3
if the query in the body of the
.cW children
function returns many instances, the
d2649 1
a2649 1
query will return all of them, in a
d2651 1
a2651 9
form.  If the query in the body of
.cW manager
returns more than one instance, the
.cW manager
function will return only one instance, arbitrarily chosen from the
set returned by the query in the function's body.  See the \*(PP
Reference Manual's entry on the
.b "define function"
command for further details and examples.
d2653 45
a2697 1
.sh 2 "User-Defined Types, Operators, Functions and Aggregates"
d2699 134
a2832 65
The central concept of extending \*(PP lies in \*(PP's ability to
.i "dynamically load"
an object code file (e.g., a
.cW .o
file or shared library) created by the user.  This allows \*(PP to
call arbitrary user-defined functions which can be written in a
standard programming language, such as C.  These functions can then be
used:
.bu
to convert between
.i internal
(binary) and
.i external
(C character string) representations of user-defined types;
.bu
as operators; and
.bu
to define ordering for indices on user-defined types.
.lp
\*(PP's concept of types includes
.i built-in
types and
.i user-defined
types.  Built-in types are those required by the system to bootstrap
itself.  User-defined types are those created by the user in the
manner described below.  There is no intrinsic performance difference
between using a system type or user-defined type, other than the
overhead due to the complexity of the type itself.
.\"------------------------------------
.sh 3 "Internal Storage of Types"
.lp
.(l C
.hl
FIX ME
need examples of by-value, by-ref-fixed, by-ref-varlena
.hl
.)l
Internally,
\*(PP regards a user-defined type as a
.q "blob of memory"
upon which user-defined functions impose structure and meaning.  \*(PP
will store and retrieve the data from disk and use user-defined
functions to input, process, and output the data.
.\"------------------------------------
.sh 3 "Functions Needed for a User-Defined Type"
.lp
A completely defined user type requires the following user-defined
functions:
.bu
.i input
and
.i output
functions for the type: 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.  These at least are necessary to define
the type.
.bu
.i operator
functions for the type: These functions define the meanings of 
.q "equal to,"
.q "less than,"
.q "greater than,"
etc., for your type.
.\"------------------------------------
.sh 3 "An Example User-Defined Type"
d2837 11
d2849 1
a2849 1
.sh 4 "Data Structures for Our Type"
d2906 1
a2906 1
.sh 4 "Defining the Input and Output Functions for Our Type"
d2913 1
a2913 1
.cW /usr/local/postgres/circle.o .
d3029 1
a3029 15
Now that we have written these functions and compiled the source
file,\**
.(f
\** You will need to supply an option like
.cW -I/usr/local/postgres/src/backend
to your C compiler so it can find the \*(PP header
.cW .h ) (
files.  Also, various platform-specific compiler options may be
required to support \*(PP dynamic linking (for example, the DECstation
ULTRIX compiler requires the
.cW "-G 0" '' ``
option.)  See Appendix B of this manual and the
.b "define function"
section of the \*(PP Reference Manual for details.
.)f
d3043 1
a3043 1
      as "/usr/local/postgres/circle.o" \\g
d3048 1
a3048 1
      as "/usr/local/postgres/circle.o" \\g
d3073 1
a3073 1
program that does a
d3081 2
a3082 2
is defined incorrectly, you will encounter strange errors which may
crash the data manager itself.  If this were to happen with our
d3095 1
a3095 1
.sh 4 "Defining an Operator for a New Type"
d3105 3
a3107 3
the values of the entire list of records.  But we can do nothing else
until we have some circle operators.  To do this, we make use of the
concept of
d3117 1
a3117 1
      as "/usr/local/postgres/circle.o" \\g
d3135 1
a3135 1
* create tutorial(a = circle) \\g
d3161 1
a3161 1
.cW = '' ``
d3163 24
a3186 13
type added to the list of types it works on.  Any string of
.q "punctuation characters"
other than brackets, braces, or parentheses can be used in defining an
operator.
.lp
If you wish to place indices on attributes that are of the new type,
you must first tell the index access method the properties of the new
type.  This is a relatively complicated process and is described in a
separate section of this manual \(em see Appendix A.
.\"------------------------------------
.sh 3 "Additional Information on Creating a User-Defined Function"
.\"-----------------
.sh 4 "Use palloc and not malloc"
d3188 35
a3222 13
In order for \*(PP to correctly manage memory associated with
processing your type, you must use the memory allocator
.cW palloc
and avoid standard \*(UU memory managers such as
.cW malloc .
If you do not, \*(PP will chew up ever increasing amounts of memory.
Worse yet, \*(PP may attempt to free a chunk of memory allocated by 
.cW malloc
in an incorrect way, causing the server to crash.
.cW palloc
has the same arguments as
.cW malloc ,
that is
d3224 7
a3230 2
char *palloc(size)
unsigned long size;
d3232 65
a3296 12
To free memory allocated with
.cW palloc ,
use
.cW pfree ,
which is analogous to the \*(UU library function
.cW free :
.(C
void pfree(ptr)
char *ptr;
.)C
.\"-----------------
.sh 4 "Re-loading User Functions"
d3298 9
a3306 32
In the process of creating a user-defined type, you may find it
necessary to re-load a function in the course of debugging.  This is
.i not
done automatically when you edit or re-compile the file, but
.i is
done if you quit and restart the data manager.
.lp
We would re-load our example functions by using the following command:
.(C
* load "/usr/local/postgres/circle.o" \\g
.)C
.\"-----------------
.sh 4 "Writing a Function of an Instance"
.lp
We've already discussed user functions which take \*(PP base or
user-defined types as arguments; in this section, we will discuss
inheritable C functions or methods.
.lp
C language methods are useful particularly when we want to make a
function
.i inheritable ;
that is, to have the function process every instance in an inheritance
hierarchy of classes.
.lp
In using a function of an instance in qualifying an instance,
\*(PP defines the
.q "current instance"
to be the instance being qualified at the moment your function is
called.  The instance itself will be passed in your function's
parameter list as an opaque structure of type TUPLE, and you will use
\*(PP library routines to access the data in the object as described
below.\**
d3308 2
a3309 4
\** In \*(PP \*(PV,
.cW TUPLE
is defined as
.cW "void *" .
d3312 68
a3379 1
Suppose we want to write a function to answer the query
d3381 1
a3381 1
* retrieve (EMP.all) where overpaid(EMP) \\g
d3383 1
a3383 3
In the query above, a reasonable
.cW overpaid
function might be:
d3385 25
a3409 6
bool
overpaid(t) 
TUPLE t;   /* the current instance */
{
    extern char *GetAttributeByName();
    short salary, seniority, performance;
d3411 1
a3411 3
    salary = (short) GetAttributeByName(t, "salary");
    seniority = (short) GetAttributeByName(t, "seniority");
    performance = (short) GetAttributeByName(t, "performance");
d3413 2
a3414 2
    return (salary > (seniority * performance));
}
d3416 37
a3452 18
.cW GetAttributeByName
is the \*(PP system function that returns attributes out of the
current instance.  It has two arguments: the argument of type TUPLE
passed into the function, and the name of the desired attribute.
.cW GetAttributeByName
will align data properly so you can cast its return value to the
desired type.  For example, if you have an attribute
.cW name
which is of the \*(PQ type
.cW char16 ,
the
.cW GetAttributeByName
call would look like:
.(C
char *str;
\&...
str = (char *) GetAttributeByName(t, "name")
.)C
d3454 7
a3460 4
To let \*(PP know about the
.cW overpaid
function,
do:
d3462 21
a3482 1
* define function overpaid
d3484 2
a3485 2
      arg is (EMP)
      as "/usr/local/postgres/overpaid.o" \\g
d3487 6
a3492 3
.lp
You can have additional complex, base or user-defined types as
arguments to the inheritable function.  Thus,
d3494 8
a3501 2
* retrieve (EMP.all)
      where overpaid2(EMP, DEPT, "bill", 8) \\g
d3503 12
a3514 3
could be written, and
.cW overpaid2
would be declared:
d3516 14
a3529 29
bool
overpaid2(emp, dept, name, number)
    TUPLE emp, dept;
    char *name;
    long number;
.)C
.\"------------------------------------
.sh 3 "Arrays of Types"
.lp
As discussed earlier, \*(PP fully supports arrays of base types.
Additionally, \*(PP supports arrays of user-defined types as well.
When you define a type, \*(PP
.i automatically
provides support for arrays of that type.
.\"-----------------
.sh 4 "Arrays of User-Defined Types"
.lp
Using the
.q circle
example discussed above, we will create a class containing an array of
circles:
.(C
* create circles (list = circle[]) \\g
.)C
and do some 
.b append s:
.(C
* append circles (list = "{"(1.0, 1.0, 5.0)",
                         "(2.0, 2.0, 10.0)"}") \\g
d3531 4
a3534 2
* append circles (list = "{"(2.0, 3.0, 15.0)",
                         "(2.0, 2.0, 10.0)"}") \\g
d3536 4
a3539 1
* append circles (list = "{"(2.0, 3.0, 4.0)"}") \\g
d3541 7
a3547 7
We can now run queries like:
.(C
* retrieve (circles.list[1]) \\g
.)C
which returns the first element of each
.cW list :
.(T
d3549 28
a3576 5
allbox;
l.
list
(1, 1, 5)
(2, 3, 4)
d3578 14
a3591 2
.)T
and
d3593 4
a3596 2
* retrieve (circles.all)
      where circles.list[1] = "(0.0, 0.0, 4.0)" \\g
d3601 19
a3619 4
allbox;
l.
list
{"(2, 3, 4)"}
d3622 8
a3629 5
Note the
.cW {} s,
indicating that an array has been retrieved, as opposed to a single element.
.\"-----------------
.sh 4 "Defining a New Array Type"
d3631 62
a3692 4
An array may be defined as an element of a class, as shown above, or it may
be defined as a type in and of itself.
This is useful for defining
.i "arrays of arrays" .
d3694 1
a3694 6
The special built-in functions
.cW array_in
and
.cW array_out
are used by \*(PP to input and output arrays of any existing type.
Here, we define an array of integers:
d3696 1
a3696 3
* define type int_array
      (element = int4, internallength = variable,
       input = array_in, output = array_out) \\g
d3698 4
a3701 10
The
.cW element
parameter indicates that this is an array, and setting
.cW internallength
to
.cW variable
indicates that the array is a variable-length attribute.\**
.(f
\** Note that any type using
.cW array_in
d3703 4
a3706 4
.cW array_out
.i must
be variable-length.
.)f
d3708 15
a3722 2
We can use our type defined above to create an array of integer
arrays:
d3724 4
a3727 3
* define type int_arrays
      (element = int_array, internallength = variable,
       input = array_in, output = array_out) \\g
d3729 9
a3737 7
* create stuff (a = int_arrays) \\g

* append stuff (a = "{"{1, 2, 3}" , "{4, 5}", "{6, 7, 8}"}") \\g

* append stuff (a = "{"{88, 99, 3}"}") \\g

* retrieve (stuff.a[1]) \\g
d3739 8
a3746 2
Queries like these will not work on 
.i "arrays of arrays".
d3748 5
a3752 1
* retrieve (stuff.a[1][1]) \\g
a3753 3
However, two dimensional arrays can be used to get this behavior.
.\"------------------------------------
.sh 3 "Large Object Types"
d3755 2
a3756 10
.(l C
.hl
FIX ME
jaquith large objects
external large objects
.hl
.)l
The types discussed to this point are all
.i small
objects \(em that is, they are smaller than 8KB\**
d3758 11
a3768 4
\** 8 * 1024 == 8192 bytes.  In fact, the type must be considerably
smaller than 8192 bytes, since the \*(PP tuple and page overhead
must also fit into this 8KB limitation.  The actual value that fits
depends on the machine architecture.
a3769 25
in size.  If you require a larger type for something like a document
retrieval system or for storing bitmaps, you will need to use the
\*(PP
.i "large object"
interface.  The interface to large objects is quite similar to the
\*(UU file system interface.  The particulars are detailed in Section
7 of the \*(PP Reference Manual, which you should have available to
consult as you read the following.
.\"-----------------
.sh 4 "Defining a Large Object"
.lp
Just like any other type, a large object type requires input and
output functions.  For the purposes of this discussion, we assume that
two functions,
.cW large_in
and
.cW large_out
have been written using the large object interface, and that the
compiled functions are in
.cW /usr/local/postgres/large.o .
We also presume that we are using the
.q "file as an ADT"
interface for large objects discussed in the Reference Manual.
.lp
We define a large object which could be used for storing map data:
d3771 11
a3781 4
* define function large_in
      (language = "c", returntype = map)
      arg is (any)
      as "/usr/local/postgres/large.o" \\g
d3783 1
a3783 4
* define function large_out
      (language = "c", returntype = any)
      arg is (any)
      as "/usr/local/postgres/large.o" \\g
d3785 40
a3824 3
* define type map
      (internallength = variable,
       input = large_in, output = large_out) \\g
d3826 4
a3829 7
Note that large objects are
.i always
variable-length.
.lp
Now we can use our
.cW map
object:
d3831 11
a3841 7
* create maps (name = text, a = map) \\g

* append maps (name = "earth",
               a = "/usr/local/postgres/earth") \\g

* append maps (name = "moon",
               a = "/usr/local/postgres/moon") \\g
d3843 9
a3851 25
Notice that the above queries are identical in syntax to those we have
been using all along to define types and such; the fact that this type
is a large object is completely hidden in the large object interface
and \*(PP storage manager.
.\"-----------------
.sh 4 "Writing Functions and Operators for Large Object Types"
.lp
Like any other \*(PP type, you can define functions and operators for
large object types.  The only caveat is that, like any other functions
which process a large object, they
.i must
use the large object interface described in Section 7 of the \*(PP
Reference Manual.  Possible queries which involve functions on large
objects could include
.(C
* retrieve (emp.name) where beard(emp.picture) = "red" \\g

* retrieve (mountain.name)
      where height(mountain.topomap) > 10000 \\g
.)C
Because all functionality is available to large objects,
.i any
aspect of \*(PP is available for use with them, including index access
methods, if the appropriate operator classes have been defined.
Operator classes for index access methods are discussed in Appendix A.
d3853 4
a3856 1
.sh 3 "User-Defined Aggregates"
a3857 8
.(l C
.hl
FIX ME
.hl
.)l
.\"---------------------------------------------------------------------------
.sh 1 "THE \*(PP RULE SYSTEM"
.lp
d3907 4
a3910 1
.sh 1 "ADMINISTERING \*(PP"
d3916 2
d3919 1
d4040 88
d4129 1
d4191 1
a4191 1
% cp -r /usr/local/postgres/data /new/place/data
d4212 2
a4213 1
Remove the old 
d4240 1
a4240 1
% cp -r /usr/local/postgres/data/base/foo /new/place/foo
d4280 1
a4280 1
files.  See Appendix B for more details.
d4310 2
a4311 53
.sh 2 "Troubleshooting \*(PP"
.lp
Occasionally, \*(PP will fail with cryptic error messages that are due
to relatively simple problems.  The following are a list of \*(PP
error messages and the likely fix.  These messages are ones you would
likely see in the
.cW monitor
program.
.(C
Message: semget: No space left on device

Explanation and Likely Fix:
.)C
Either the kernel has not been configured for System V shared memory,
or some other program is using it up.  On most machines, the \*(UU
command
.cW ipcs
will show shared memory and semaphore usage.
.lp
To delete all shared memory and semaphores (may be necessary if a
backend fails), run the
.cW ipcclean
command.  Note, however, that
.cW ipcclean
deletes
.i all
semaphores belonging to the user running it, so the user should be
certain that none of his/her non-\*(PP processes are using semaphores
before running this command.
.(C
Message: Unable to get shared buffers

Explanation and Likely Fix:
.)C
This message means that a \*(PP backend was expecting shared memory to
be available and it was not.  Usually this is due to
.cW ipcclean
being run while a
.cW postmaster
was also running.
.(C
Message: Can't connect to the backend (...)

Explanation and Likely Fix:
.)C
This message means that you are running a \*(LP application but it
could not link up with a
.cW postmaster .
If you see this error message, you should see if a
.cW postmaster
is truly running.  If one is running, the problem is likely related to
your network.
.\"------------------------------------
d4313 1
d4342 12
a4353 57
.sh 2 "How to Find Out What's in a Database"
.lp
This section explains how you can answer questions such as,
.q "What tables do I have in this database?"
and
.q "What extensions have been added to my database?"
.\"------------------------------------
.sh 3 "About the \*(PP System Catalogs"
.lp
If you are familiar with standard relational systems, you know that
they store information about databases, tables, etc., in what are
commonly known as
.i "system catalogs" .
(Some systems call this the
.i "data dictionary" ).
The catalogs appear to the user as tables, like any other, but the
DBMS stores its internal bookkeeping in them.  One key difference
between \*(PP and standard relational systems is that \*(PP stores
much more information in its catalogs \(em not only information about
tables and attributes, but also information about the types,
procedures, access methods, and so on.  These tables can be modified
by the user, and since \*(PP bases its internal operation on these
tables, this means that \*(PP can be extended by users.  By
comparison, standard relational systems can only be extended by
changing hard-coded procedures within the DBMS.
.lp
The following classes contain information that may be useful to the
end user.  There are many other system catalogs, but there should
never be a reason to query them.
.TS
center tab(|);
cf(C)|c
lf(C)|l.
catalog name|description
=
pg_database|databases
pg_class|class
pg_attribute|attributes
pg_index|indexes

pg_proc|procedures
pg_type|types
pg_operator|operators
pg_aggregate|aggregates

pg_am|access methods
pg_amop|access method operators
pg_amproc|access method support functions
pg_opclass|access method operator classes

pg_user|users
pg_group|user groups
.TE
.\"------------------------------------
.sh 3 "Querying the System Catalogs"
.lp
Before executing any of the queries below, be sure to execute the \*(PP
d4358 1
a4358 1
\&.../src/doc/manual.me
d4377 1
a4377 1
      where c.relkind = 'r'      /* no indexes */
d4409 1
a4409 1
      where c.relkind = 'r'     /* no indexes */
d4433 1
a4433 1
* retrieve (left_assoc = o.oprname,
d4439 1
a4439 1
      where o.oprkind = 'l'           /* left assoc */
d4447 1
a4447 1
* retrieve (right_assoc = o.oprname,
d4453 1
a4453 1
      where o.oprkind = 'r'          /* right assoc */
d4531 2
d4534 1
d4594 3
a4596 657
.lp
.sh 0 "APPENDIX A: User-Defined Types and Indices"
.lp
In this section, we will discuss how to extend \*(PP to use a
user-defined type and associated functions with existing access
methods.  This way, you can define a BTREE or RTREE index on your own
type.  To do this, we will discuss how to define a new operator class
in \*(PP for use with an existing access method.
.lp
Our example will be to add a new operator class to the BTREE access
method.  The new operator class will sort integers in ascending
absolute value order.  This tutorial will describe how to define the
operator class.  If you work the example, you will be able to define
and use indices that sort integer keys by absolute value.
.lp
There are several \*(PP system classes that are important in
understanding how the access methods work.  These will be discussed,
and then a sample procedure for adding a new set of operators to an
existing access method will be shown as an example.
.lp
The
.cW pg_am
class contains one instance for every user-defined access method.
Support for the HEAP access method is built into \*(PP, but every
other access method is described here.  The schema is
.TS
center tab(|);
lf(C)|l.
amname|name of the access method
_
amowner|object id of the owner's instance in pg_user
_
amkind|not used at present, but set to 'o' as a place holder
_
amstrategies|number of strategies for this access method (see below)
_
amsupport|number of support routines for this access method (see below)
_
am*|T{
procedure identifiers for interface routines to the access method.
For example,
.cW regproc
ids for opening, closing, and getting instances from the access method
appear here.
T}
.TE
The object ID of the instance in
.cW pg_am
is used as a foreign key in lots of other classes.  For BTREEs, this
object ID is 403.  You don't need to add a new instance to this class;
all you're interested in is the object ID of the access method
instance you want to extend:
.(C
* retrieve (pg_am.oid) where pg_am.amname = "btree" \\g
.TS
allbox;
l.
oid
403
.TE
.)C
The
.cW amstrategies
attribute exists to standardize comparisons across data types.  For
example, BTREEs impose a strict ordering on keys, less to greater.
Since \*(PP allows the user to define operators, \*(PP cannot in
general look at the name of an operator (eg,
.cW > ,
.cW < )
and tell what kind of comparison it is.  In fact, some access methods
(like RTREEs) don't impose a less-to-greater ordering, but some other
ordering, like containment.  \*(PP needs some consistent way of taking
a scan qualification, looking at the operator, deciding if a usable
index exists, and rewriting the query qualification in order to
improve access speeds.  This implies that \*(PP needs to know, for
example, that
.cW <=
and
.cW >
partition a BTREE.  Strategies is the way that we do this.
.lp
Defining a new set of strategies is beyond the scope of this
discussion, but how the BTREE strategies work will be explained, since
you'll need to know that to add a new operator class.  In the
.cW pg_am
class, the
.cW amstrategies
attribute is the number of strategies defined for this access method.
For BTREES, this number is 5.  These strategies correspond to
.TS
center tab(|);
l|l.
less than|1
_
less than or equal|2
_
equal|3
_
greater than or equal|4
_
greater than|5
.TE
The idea is that you'll add procedures corresponding to the
comparisons above to the
.cW pg_amop
relation (see below).  The access method code can use these numbers,
regardless of data type, to figure out how to partition the BTREE,
compute selectivity, and so on.  Don't worry about the details of
adding procedures yet; just understand that there's a set of these for
.cW int2 ,
.cW int4 ,
.cW oid ,
and every other data type on which a BTREE can operate.
.lp
Strategies are used by all of the \*(PP access methods.  Some access
methods require other support routines in order to work.  For example,
the BTREE 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 RTREE access method must be able to compute
intersections, unions, and sizes of rectangles.  These operations do
not correspond to user qualifications in \*(PQ queries; they are
administrative routines used by the access methods, internally.
.lp
In order to manage diverse support routines consistently across all
\*(PP access methods,
.cW pg_am
includes a field called
.cW amsupport .
This field records the number of support routines used by an access
method.  For BTREEs, this number is one \(em the routine to take two
keys and return \(mi\^1, 0, or \(pl\^1, depending on whether the first
key is less than, equal to, or greater than the second.\**
.(f
\** Strictly speaking, this routine can return a negative number (<
0), 0, or a non-zero positive number (> 0).
.)f
.lp
The
.cW amstrategies
entry in
.cW pg_am
is just the 
.i number
of strategies defined for the access method in question.  The
procedures for less than, less equal, and so on don't appear in
.cW pg_am .
Similarly,
.cW amsupport
is just the number of support routines required by the access method.
The actual routines are listed elsewhere.
.lp
The next class of interest is
.cW pg_opclass.
This class exists only to associate a name with an
.cW oid .
In
.cW pg_amop ,
every BTREE operator class has a set of procedures, one through five,
above.  Some existing opclasses are
.cW int2_ops ,
.cW int4_ops ,
and
.cW oid_ops .
You need to add an instance with your opclass name (for example,
.cW int4_abs_ops )
to
.cW pg_opclass .
The
.cW oid
of this instance is a foreign key in other classes.
.(C
* append pg_opclass (opcname = "int4_abs_ops") \\g

* retrieve (cl.oid, cl.opcname) from cl in pg_opclass
      where cl.opcname = "int4_abs_ops" \\g
.TS
tab(|) allbox;
l l.
oid|opcname
17314|int4_abs_ops
.TE
.)C
.i NOTE:
The
.cW oid
for your
.cW pg_opclass
instance
.i "may be different!"
You should substitute your value for 17314 wherever it appears in this
discussion.
.lp
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
.cW int4_abs_ops
operator class on BTREEs, the operators we require are:
.(l
absolute value less-than
absolute value less-than-or-equal
absolute value equal
absolute value greater-than-or-equal
absolute value greater-than
.)l
Suppose the code that implements the functions defined is stored in
the file
.cW /usr/local/postgres/int4_abs.c .
The code is
.(C
/*
 * int4_abs.c -- absolute value comparison functions
 *               for int4 data
 */

#include "tmp/c.h"

#define ABS(a) a = ((a < 0) ? -a : a)

/* routines to implement operators */

bool int4_abs_lt(a, b) int32 a, b;
     { ABS(a); ABS(b); return (a < b); }

bool int4_abs_le(a, b) int32 a, b;
     { ABS(a); ABS(b); return (a <= b); }

bool int4_abs_eq(a, b) int32 a, b;
     { ABS(a); ABS(b); return (a == b); }

bool int4_abs_ge(a, b) int32 a, b;
     { ABS(a); ABS(b); return (a >= b); }

bool int4_abs_gt(a, b) int32 a, b;
     { ABS(a); ABS(b); return (a > b); }

/* support (signed comparison) routine */

int int4_abs_cmp(a, b) int32 a, b;
     { ABS(a); ABS(b); return (a - b); }
.)C
There are a couple of important things that are happening below.
First, note that operators for less-than, less-than-or-equal, equal,
greater-than-or-equal, and greater-than for
.cW int4
are being defined.  All of these operators are already defined for
.cW int4
under the names
.cW < ,
.cW <= ,
.cW = ,
.cW >= ,
and
.cW > .
The new operators behave differently, of course.  In order to
guarantee that \*(PP 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 \*(PP, but only if the
operator isn't already defined for the argument types.
.lp
That is, if you have
.cW <
defined for
.cW int4 , (
.cW int4 ),
you can't define it again.
\*(PP
.i doesn't
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.
.lp
The other important point is that all the operator functions return
.i Boolean
values; the access methods rely on this fact.
.lp
The final routine in the file is the 
.q "support routine"
mentioned when we discussed the
.cW amsupport
attribute of the
.cW pg_am
class.  We will use this later on.  For now, ignore it.
.(C
* define function int4_abs_lt
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/int4_abs.o" \\g

* define function int4_abs_le
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/int4_abs.o" \\g

* define function int4_abs_eq
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/int4_abs.o" \\g

* define function int4_abs_ge
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/int4_abs.o" \\g

* define function int4_abs_gt
      (language = "c", returntype = bool)
      arg is (int4, int4)
      as "/usr/local/postgres/int4_abs.o" \\g
.)C
Now define the operators that use them.  As noted, the operator names
must be unique for two
.cW int4
operands.  You can do a query on
.cW pg_operator :
.(C
* retrieve (pg_operator.all) \\g
.)C
to see if your name is taken for the types you want.  The important
things here are the procedure (which are the C functions defined
above) and the restriction and join selectivity functions.  You should
just use the ones used below\(emnote that there are different such
functions for the less-than, equal, and greater-than cases.  These
.i must
be supplied, or the access method will crash when it tries to use the
operator.  You should copy the names for
.cW restrict
and
.cW join ,
but use the procedure names you defined in the last step.
.(C
* define operator <<&
      (arg1 = int4, arg2 = int4, procedure=int4_abs_lt,
       associativity = left, restrict = intltsel,
       join = intltjoinsel) \\g

* define operator <=&
      (arg1 = int4, arg2 = int4, procedure = int4_abs_le,
       associativity = left, restrict = intltsel,
       join = intltjoinsel) \\g

* define operator ==&
      (arg1 = int4, arg2 = int4, procedure = int4_abs_eq,
       associativity = left, restrict = eqsel,
       join = eqjoinsel) \\g

* define operator >=&
      (arg1 = int4, arg2 = int4, procedure = int4_abs_ge,
       associativity = left, restrict = intgtsel,
       join = intgtjoinsel) \\g

* define operator >>&
      (arg1 = int4, arg2 = int4, procedure = int4_abs_gt,
       associativity = left, restrict = intgtsel,
       join = intgtjoinsel) \\g
.)C
Notice that five operators corresponding to less, less equal, equal,
greater, and greater equal are defined.
.lp
We're just about finished. the last thing we need to do is to update
the
.cW pg_amop
relation.  To do this, we need the following attributes:
.TS
center tab(|);
lf(C)|l.
amopid|T{
the
.cW oid
of the
.cW pg_am
instance for BTREE (== 403, see above)
T}
_
amopclaid|T{
the
.cW oid
of the
.cW pg_opclass
instance for
.cW int4_abs_ops
(== whatever you got instead of 17314, see above)
T}
_
amopopr|T{
the
.cW oid s
of the operators for the opclass (which we'll get in just a minute)
T}
_
T{
amopselect,
.br
amopnpages
T}|cost functions.
.TE
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
.cW btreesel,
which estimates the selectivity of the BTREE, and
.cW btreenpage,
which estimates the number of pages a search will touch in the tree.
.lp
So we need the
.cW oid s
of the operators we just defined.  We'll look up the names of all the
operators that take two
.cW int4 s,
and pick ours out:
.(C
* retrieve (o.oid, o.oprname)
      from o in pg_operator, t in pg_type
      where o.oprleft = t.oid and o.oprright = t.oid
          and t.typname = "int4" \\g
.)C
which returns:
.(T
.TS
tab(|) allbox;
l l.
oid|oprname
96|\\=
97|<
514|*
518|!=
521|>
523|<=
525|>=
528|/
530|%
551|+
555|-
17321|<<&
17322|<=&
17323|==*
17324|>=&
17325|>>&
.TE
.)T
(Note that your
.cW oid
numbers may be different.)  The operators we are interested in are
those with
.cW oid 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.  (Of course,
there are lots of other queries we could used to get the oids we
wanted.)
.lp
Now we're ready to update
.cW pg_amop
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
.cW pg_amop .
Recall that the BTREE instance's
.cW oid
is 403 and
.cW int4_abs_ops
is
.cW oid
17314.  Then we add the instances we need:
.(C
* append pg_amop
      (amopid = "403"::oid,          /* btree oid        */
       amopclaid = "17314"::oid,     /* pg_opclass tuple */
       amopopr = "17321"::oid,       /* <<& tup oid      */
       amopstrategy = "1"::int2,     /* 1 is <<&         */
       amopselect = "btreesel"::regproc,
       amopnpages = "btreenpage"::regproc) \\g

* append pg_amop (amopid = "403"::oid,
                  amopclaid = "17314"::oid,
                  amopopr = "17322"::oid,
                  amopstrategy = "2"::int2,
                  amopselect = "btreesel"::regproc,
                  amopnpages = "btreenpage"::regproc) \\g

* append pg_amop (amopid = "403"::oid,
                  amopclaid = "17314"::oid,
                  amopopr = "17323"::oid,
                  amopstrategy = "3"::int2,
                  amopselect = "btreesel"::regproc,
                  amopnpages = "btreenpage"::regproc) \\g

* append pg_amop (amopid = "403"::oid,
                  amopclaid = "17314"::oid,
                  amopopr = "17324"::oid,
                  amopstrategy = "4"::int2,
                  amopselect = "btreesel"::regproc,
                  amopnpages = "btreenpage"::regproc) \\g

* append pg_amop (amopid = "403"::oid,
                  amopclaid = "17314"::oid,
                  amopopr = "17325"::oid,
                  amopstrategy = "5"::int2,
                  amopselect = "btreesel"::regproc,
                  amopnpages = "btreenpage"::regproc) \\g
.)C
NOTE the order:
.q "less than"
is 1,
.q "less than or equal"
is 2,
.q "equal"
is 3,
.q "greater than or equal"
is 4,
and
.q "greater than"
is 5.
.lp
The last step (finally!) is registration of the 
.q "support routine"
previously described in our discussion of
.cW pg_am .
The 
.cW oid
of this support routine is stored in the
.cW pg_amproc
class, keyed by the access method
.cW oid
and the operator class
.cW oid .
First, we need to register the function in \*(PP (recall that we put
the C code that implements this routine in the bottom of the file in
which we implemented the operator routines):
.(C
* define function int4_abs_cmp
      (language = "c", returntype = int)
      arg is (int4, int4)
      as "/usr/local/postgres/int4_abs.o" \\g

* retrieve (p.oid, p.proname)
      from p in pg_proc
      where p.proname = "int4_abs_cmp" \\g
.TS
tab(|) allbox;
l l.
oid|proname
17328|int4_abs_cmp
.TE
.)C
(Again, your
.cW oid
number will probably be different and you should substitute the value
you see for the value below.)  Recalling that the BTREE instance's
.cW oid 
is 403 and that of 
.cW int4_abs_ops
is 17314, we can add the new instance as follows:
.(C
* append pg_amproc
	(amid = "403"::oid,        /* btree oid        */
	 amopclaid = "17314"::oid, /* pg_opclass tuple */
	 amproc = "17328"::oid,    /* new pg_proc oid */
	 amprocnum = "1"::int2) \eg
.)C
.lp
Okay, now it's time to test the new operator class.  First we'll
create and populate a class\**:
.(f
\** In this example, we append only a few instances into the class.
In fact, \*(PP uses a 
.q cost-based
query optimizer that makes the decision whether or not to use an index
based on how much data is touched.  Since this example creates a very
small amount of data, the example will likely not work as advertised
\(em one would have to insert a fair amount of data before using an
index would actually be cheaper than just scanning the underlying HEAP
data structure.
.q "A fair amount"
typically means on the order of several kilobytes.
.)f
.(C
* create pairs (name = char16, number = int4) \\g

* append pairs (name = "mike", number = -10000) \\g

* append pairs (name = "greg", number = 3000) \\g

* append pairs (name = "lay peng", number = 5000) \\g

* append pairs (name = "jeff", number = -2000) \\g

* append pairs (name = "mao", number = 7000) \\g

* append pairs (name = "cimarron", number = -3000) \\g

* retrieve (pairs.all) \\g
.TS
tab(|) allbox;
l l.
name|number
mike|-10000
greg|3000
lay peng|5000
jeff|-2000
mao|7000
cimarron|-3000
.TE
.)C
Okay, looks pretty random.  Define an index using the new opclass:
.(C
* define index pairsind on pairs
      using btree (number int4_abs_ops) \\g
.)C
Now run a query that doesn't use one of our new operators.  What we're
trying to do here is to run a query that
.i won't
use our index, so that we can tell the difference when we see a query
that
.i does
use the index.  This query won't use the index because the operator we
use in the qualification isn't one that appears in the list of
strategies for our index.
.(C
* retrieve (pairs.all) where pairs.number < 9000 \\g
.TS
tab(|) allbox;
l l.
name|number
mike|-10000
greg|3000
lay peng|5000
jeff|-2000
mao|7000
cimarron|-3000
.TE
.)C
Yup, just as random; that didn't use the index.  Okay, let's run a
query that
.i does
use the index:
.(C
* retrieve (pairs.all) where pairs.number <<& 9000 \\g
.TS
tab(|) allbox;
l l.
name|number
jeff|-2000
cimarron|-3000
greg|3000
lay peng|5000
mao|7000
.TE
.)C
Note that the
.cW number
values are in order of increasing absolute value (as they should be,
since the index was used for this scan) and that we got the right
answer \(em the instance for
.cW mike
doesn't appear, because \(mi10000 >=& 9000.
.\"---------------------------------------------------------------------------
.bp
a4597 2
.sh 0 "Appendix B: Linking Dynamically-Loaded Functions"
.lp
d4645 1
a4645 1
.ip "Link editing"
d4708 1
a4708 1
that can then be dynamically-loaded into \*(PP.  No additional loading
d4710 1
a4710 1
.uh "Alpha OSF/1 and SunOS 4"
d4712 2
a4713 2
Both Alpha OSF/1 and SunOS 4 can take any simple object file and
produce a shared object file by running the 
d4716 1
a4716 1
under Alpha OSF/1 look like:
d4718 1
a4718 1
	# simple Alpha OSF/1 example
a4721 6
whereas under SunOS 4, the commands look like:
.(C
	# simple SunOS 4 example
	% cc -c foo.c
	% ld -Bdynamic -o foo.so foo.o
.)C
d4734 2
a4735 2
this is fine with \*(PP so long as you make sure that the correct
file name is given to the 
d4737 1
a4737 1
command.  In other words, you must be absolutely consistent.  However,
d4747 1
a4747 1
.uh "HP-UX"
d4749 2
a4750 2
Under HP-UX, the simple object file must be created by compiling the
source file with special compiler flags
d4753 2
a4754 1
Specifically, the
d4779 12
d4851 1
a4851 2
should simply be taken as voodoo.
The file specified by the 
d4887 8
@


1.25
log
@give up lock for now
@
text
@d27 1
a27 1
.\" $Header: /usr/local/devel/postgres/src/doc/RCS/manual.me,v 1.24 1993/10/05 23:07:39 aoki Exp aoki $
a812 8
.(l C
.hl
FIX ME
multidimensional
flags
other new behavior
.hl
.)l
d814 3
a816 2
variable-length multi-dimensional arrays.  To illustrate their use, we
first create a class with an array type.
d818 2
a819 2
* create SAL_EMP (name = char[],
                  pay_by_quarter = int4[4]) \\g
d823 1
a823 1
with a variable-length one-dimensional array of
d825 1
a825 1
strings
d827 1
a827 1
and a one-dimensional array of 4
a828 1
integers
d830 5
a834 1
which represents the employee's salary by quarter.  Now we do some
d836 2
a837 2
note that when appending to a non-character array, we enclose the
values within braces and separate them by commas.
d839 7
a845 8
* append SAL_EMP (name = "bill",
      pay_by_quarter = "{10000, 10000, 10000, 10000}") \\g

* append SAL_EMP (name = "jack",
      pay_by_quarter = "{10000, 15000, 15000, 15000}") \\g

* append SAL_EMP (name = "joe",
      pay_by_quarter = "{20000, 25000, 25000, 25000}") \\g
d851 8
a858 1
Pascal and FORTRAN.)
d873 3
a875 13
This query deletes everyone from
.cW SAL_EMP
whose name begins with the letter
.q j.
.cW SAL_EMP
should now contain only the employee named
.q bill :
.(C
* delete SAL_EMP where SAL_EMP.name[1] = 'j' \\g
.)C
Let's make sure (note that the attribute
.cW all
may be used as a shorthand for all attributes of a class):
d877 2
a878 7
* retrieve (SAL_EMP.all) \\g
.TS
allbox tab(|);
l l.
name|pay_by_quarter
bill|{10000,10000,10000,10000}
.TE
d880 41
a920 14
\*(PP supports arrays of base and user-defined types, as well as
.q "arrays of arrays,"
as in the following example:
.(C
* create manager (name = char16, employees = text[]) \\g

* append manager (name = "mike",
                  employees = "{"wei", "greg", "jeff"}") \\g

* append manager (name = "alice",
                  employees = "{"bill", "joe"}") \\g

* append manager (name = "marge",
                  employees = "{"mike", "alice"}") \\g
a921 3
This creates a class
.cW manager ,
and provides a list of employees.
d1820 1
a1820 1
As discussed above, \*(PP fully supports arrays of base types.
a1880 6
.(l C
.hl
FIX ME
this is totally wrong now
.hl
.)l
d1922 1
a1922 141
* append stuff (a = "{{1, 2, 3} , {4, 5}, {6, 7, 8}}") \\g

* append stuff (a = "{{88, 99, 3}}") \\g

* append stuff (a = "{{5, 4, 3} , {2, 2}}") \\g

* retrieve (stuff.a[1])
      where stuff.a[1][1] < stuff.a[1][2] \\g

* retrieve (stuff.a)
      where stuff.a[3][1] < stuff.a[1][2] \\g

* retrieve (s.all) from s in stuff
      where s.a[2][2] = stuff.a[1][1] \\g
.)C
We can also define operators for equality, less than, greater than,
etc., which operate on our new array type as necessary.
.\"-----------------
.sh 4 "Creating an Array Type from Scratch"
.lp
.(l C
.hl
FIX ME
.hl
.)l
There are many situations in which the above scheme for creating an
array type is inappropriate, particularly when it is necessary to
define a fixed-length array.  In this section, we will create an array
of four 
.cW long s
called
.cW quarterly ,
and a variable-length array of 
.cW long s
called
.cW stats .\**
.(f
\** We assume
.cW "sizeof(long) == 4" .
.)f
.lp
The only special things we need to know when writing the input and
output functions for
.cW quarterly
is that \*(PP will pass a
.q simple
(i.e., fixed-length) array of
.cW long s
to the output function and expect a simple array of
.cW long s
in return from the input function.  A simple array suitable for
.cW quarterly
can be declared:
.(C
long quarterly[4];
.)C
For the variable-length array
.cW stats ,
the situation is a little more complicated.  Because \*(PP will not
know in advance how big the array is, \*(PP will expect the length of
the array (in bytes) to be encoded in the first four bytes of the
memory which contains the array.  The expected structure is:
.(C
typedef struct {
    long length;
    unsigned char bytes[1]; /* Force contiguity */
} VAR_LEN_ATTR;
.)C
The input function for the
.cW stats
array will look something like:
.(C
VAR_LEN_ATTR *
stats_in(s)
    char s;
{
    VAR_LEN_ATTR *stats;
    long array_size, *arrayp, nbytes;

    /*
     * nbytes is the total number of bytes in stats,
     * INCLUDING the byte count at the beginning
     */
    nbytes = array_size * sizeof(long)  +  sizeof(long);

    stats = (VAR_LEN_ATTR *) palloc(nbytes);

    stats->length = nbytes;

    arrayp = &(stats->bytes[0]);

    /*
     * put code here that loads interesting stuff into
     * arrayp[0] .. arrayp[array_size]
     */

    return(stats);
}
.)C
The output function for
.cW stats
will get the same
.cW VAR_LEN_ATTR
structure.
.lp
Now, assuming the functions are in
.cW /usr/local/postgres/stats.c
and
.cW /usr/local/postgres/quarterly.c ,
we can define our two arrays.  First we will define the fixed-size
array
.cW quarterly .\**
.(f
\** The assumption that
.cW "internallength == 16"
follows from our assumption about
.cW sizeof(long) .
.)f
.(C
* define function quarterly_in
      (language = "c", returntype = quarterly)
      arg is (any)
      as "/usr/local/postgres/quarterly.o" \\g

* define function quarterly_out
      (language = "c", returntype = any)
      arg is (any)
      as "/usr/local/postgres/quarterly.o" \\g

* define type quarterly
      (element = int4, internallength = 16,
       input = quarterly_in, output = quarterly_out) \\g
.)C
Now we define the
.cW stats
array:
.(C
* define function stats_in
      (language = "c", returntype = stats)
      arg is (any)
      as "/usr/local/postgres/stats.o" \\g
d1924 1
a1924 4
* define function stats_out
      (language = "c", returntype = any)
      arg is (any)
      as "/usr/local/postgres/stats.o" \\g
d1926 1
a1926 3
* define type stats
      (element = int4, internallength = variable,
       input = stats_in, output = stats_out) \\g
d1928 2
a1929 1
Now we can run some queries:
d1931 1
a1931 12
* create test (a = quarterly, b = stats) \\g

* append test (a = "1 2 3 4"::quarterly,
               b = "5 6 7"::stats) \\g

* append test (a = "1 3 2 4"::quarterly,
               b = "6 4"::stats) \\g

* append test (a = "7 11 6 9"::quarterly,
               b = "1 2"::stats) \\g

* retrieve (test.all) where test.a[4] = test.b[2] \\g
d1933 1
a1933 20
which returns:
.(T
.TS
tab(|) allbox;
l l.
a|b
1324|64
.TE
.)T
Note that when you use your own functions to input and output array
types,
.i "your function"
will define how to parse the external (string) representation.  The
braces notation is only a convention used by
.cW array_in
and
.cW array_out
and is
.i not
part of the formal \*(PQ definition.
@


1.24
log
@major reorganization :-P
cleaned up time, aggregates a bit
moved dba stuff around
@
text
@d25 1
a25 1
.\" $Header: /usr/local/devel/postgres/src/doc/RCS/manual.me,v 1.23 1993/10/05 06:46:58 aoki Exp aoki $
d27 2
d30 1
a30 1
.\".he '\*(dA'DRAFT'\*(tI'		\" comment out in production version
d105 1
a105 1
Edited by Paul M. Aoki, Jim Frew and The \*(PP Group
d177 2
a178 2
\*(UU is a trademark of Unix Systems Laboratories, Inc..  SPARC, SunOS
and Solaris are trademarks of Sun Microsystems, Inc.  DECstation,
d181 2
a182 1
POWER and AIX are trademarks of International Business Machines.
d2710 6
a2715 1
command.  (The queries will run much more quickly that way.)
d2728 1
a2728 1
The following query lists all user-defined classes in the database.
d2732 2
a2733 2
      where c.relkind = 'r'     /* exclude indexes */
        and c.relname !~ "^pg_"  /* exclude catalogs */
d2737 20
a2756 2
The following query prints a report of the user-defined attributes and
their types for all user-defined classes in the database.
d2764 1
a2764 1
      where c.relkind = 'r'    /* no indexes */
d2766 1
a2766 1
        and a.attnum > 0       /* no system att's */
d2772 14
d2794 1
a2794 1
      where o.oprkind = 'l'
d2808 1
a2808 1
      where o.oprkind = 'r'
d2824 1
a2824 1
      where o.oprkind = 'b'
d2855 1
a2855 1
installed, except for 
d2857 1
a2857 1
(which can take any type as its argument).
d2859 2
a2860 1
* retrieve (a.aggname, t.typname)
d2864 19
a2882 1
      sort by aggname
d3640 5
a3644 1
if you have specific questions.
d3865 11
a3875 2
shared object file can be produced.
.lp
@


1.23
log
@added discussion of pg_amproc
@
text
@d25 1
a25 1
.\" $Header: /usr/local/devel/postgres/src/doc/RCS/manual.me,v 1.22 1993/10/04 04:10:22 aoki Exp aoki $
d103 1
a103 1
Edited by Jon Rhein, Greg Kemnitz and The \*(PP Group
d110 1
a110 1
.sh 1 "OVERVIEW"
d118 41
a158 1
.sh 2 "DISTRIBUTION"
d172 1
a172 1
IBM RS/6000 (POWER1)|AIX 3.2.3
a173 4
Previous versions of \*(PP ran on Sun Microsystems Sun3 and Sequent
Symmetry systems.  \*(PP no longer runs on these systems.  In
addition, \*(PP does not run on Sun Microsystems computers running the
Solaris (SunOS 5) operating system.
d175 5
a179 5
\*(UU is a trademark of Unix Systems Laboratories.  SPARC, SunOS and
Solaris are trademarks of Sun Microsystems, Inc.  DECstation, Alpha
AXP and ULTRIX are trademarks of Digital Equipment Corp.  PA-RISC and
HP-UX are trademarks of Hewlett-Packard Corp.  RS/6000, POWER and AIX
are trademarks of International Business Machines.
d181 4
a184 2
.\"------------------------------------
.sh 2 "PERFORMANCE"
d191 1
a191 1
.sh 2 "ACKNOWLEDGEMENTS"
d218 1
d242 4
a245 3
The above implementation team contributed significantly to this
manual, as did Michael Stonebraker, Chandra Ghosh, Claire Mosher and
Jim Frew.
d247 23
a269 1
.sh 1 "INTRODUCTION"
d271 5
a275 33
Traditional relational DBMSs support a data model consisting
of a collection of named relations, each attribute of which has a
specific type.
In current commercial systems, possible types are
floating point numbers, integers, character strings, money, and
dates.
It is commonly recognized that this model is inadequate
for future data processing applications.
.lp
The relational model succeeded in
replacing previous models in part because of its simplicity.
The \*(PP data model offers substantial
additional power by incorporating the following four additional basic
constructs:
.(l
classes
inheritance
types
functions
.)l
The \*(PP DBMS has been under construction since 1986.  The initial
concepts for the system were presented in [STON86] and the definition
of the initial data model appeared in [ROWE87].  The first rule system
that was implemented is discussed in [STON87a] and the storage manager
concepts are detailed in [STON87b].  The first
.q demo-ware
was operational in 1987, and we released Version 1 of \*(PP to a few
external users in June 1989.  A critique of version 1 of \*(PP appears
in [STON90a].  Version 2 followed in June 1990, and it included the
new rule system documented in [STON90b].  Version \*(PV, the current
version of \*(PP, is about 200,000 lines of code in the C programming
language.  \*(PP is available free of charge, and is being used by
approximately 500 sites around the world.
d279 11
a289 11
This manual discusses the \*(PQ query language, including extensions
such as user-defined types, operators, and both query language and
programming language functions.  Arrays of types and functions of an
instance are discussed, as well as the \*(PP rule system.  This manual
concludes with a discussion on adding an operator class to \*(PP for
use in access methods.
.lp
This manual describes the major concepts of the system and attempts to
provide an accessible path into using the system.  As such, it tries
to give examples of the use of the major constructs, so a beginning
user does not need to delve immediately into the Reference Manual.
d297 2
a298 2
.\"---------------------------------------------------------------------------
.sh 1 "WHAT YOU SHOULD READ"
d300 10
a309 21
This manual is primarily intended to provide a broad overview of the
system, as well as to illustrate how programmers would use functions
to interact with the \*(PP database server, or
.q backend.
The \*(PP Reference Manual discusses additional aspects of the system,
and provides full syntactic descriptions of every \*(PP and \*(PQ
command in a format similar to that used in \*(UU
.q "man pages."
.lp
If you are new to \*(PP, you should probably read this manual first,
followed by the parts of the \*(PP Reference Manual necessary to build
your application.  In particular, you should read the section on \*(LP
if you intend to build a client application around \*(PP, as this is
not discussed at all in this manual.
.\"---------------------------------------------------------------------------
.sh 1 "INSTALLING AND RUNNING \*(PP"
.sh 2 "Installation"
.lp
Installation instructions for \*(PP can be found in the top level of
the source code distribution.  Those instructions vary from release to
release and will not be duplicated here.
d315 2
a316 2
with the default settings.  In practice, however, \*(PP can be installed
anywhere you like.  Throughout this document, wherever you see  
d323 2
a324 1
Therefore, you should add this directory to your shell command path.
d360 1
d363 1
a363 1
Before we continue, you should understand the basic system
d368 1
a368 1
.cW postmaster ) (
d377 8
a384 1
Frontend applications send requests over the network to the 
d387 1
a387 1
that responds to its queries.  This means that the
d395 1
a395 1
different machine (e.g., a client workstation).
d398 1
a398 1
happen unless the
d400 2
a401 2
process is running.
If you get the following error message from a \*(PP command (such as 
d404 1
a404 1
.cW createdb ),
d412 2
a413 2
is not running.  Therefore, your local \*(PP database administrator
(DBA) should ensure that the
d417 2
a418 2
If you are the DBA, there are a number of things you should remember
before starting the 
d420 6
a425 44
.bu
Even if you were not the person who installed \*(PP, you should
understand the installation instructions.  The installation
instructions explain some important issues with respect to where \*(PP
places some important files, proper settings for environment
variables, etc. that may vary from one version of \*(PP to another.
.bu
You should look at the Reference Manual under the heading
.b postmaster
if you wish to use non-default options (e.g., increased security
options, a non-standard installation directory, etc.).
.bu
You 
.i must
start the
.cW postmaster
process with the user-id that owns the installed database files.  In
most cases, if you have followed the installation instructions, this
will be the user
.q postgres .
If you do not start the 
.cW postmaster
with the right user-id, the backend servers that are started by the
.cW postmaster
will not be able to read the data.
.bu
Make sure that 
.cW /usr/local/postgres/bin
is in your shell command path, because the
.cW postmaster
will use your 
.cW PATH
to locate \*(PP commands.
.bu
Remember to set the environment variable
.cW PGDATA
to the directory where the \*(PP databases are installed.  (This
variable is more fully explained in the \*(PP installation
instructions and the Reference Manual.)
.lp
Once you have checked all of the items just mentioned, the following
simple command starts the
.cW postmaster 
process:
d431 2
a432 2
does not start and instead prints cryptic error messages, you should
consult the Reference Manual under the heading
d435 1
d438 1
a438 1
Assuming that your DBA has properly started the 
d446 3
a448 3
\** If your DBA 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
d453 2
a454 2
may also have to be set.  If you try to start an application program
and it complains that it cannot connect to the 
d456 2
a457 2
you should immediately consult your DBA to make sure that your
environment is properly set up.
d460 1
a460 1
.sh 1 "THE \*(PQ QUERY LANGUAGE"
d462 4
a465 3
\*(PQ is the query language used for interacting with \*(PP.  Here, we
give an overview of how to use \*(PQ to access data.  The next section
will discuss ways in which ordinary users can extend \*(PQ.
d469 1
a469 2
In this section we describe a few basic commands for managing a
database.
d473 3
a475 4
Once \*(PP has been installed at your site, you can create a database
named
.cW foo
using the following command:
d484 3
a486 3
If \*(PP refuses to create databases for you, then the DBA needs to
grant you permission to create databases.  Consult your DBA if this
occurs.
d518 1
a518 1
You will be greeted by the following message:
d574 1
a574 13
great deal of care and forethought.
.\"------------------------------------
.sh 3 "Other Administrative Tasks"
.lp
Other DBA commands include
.cW createuser ,
.cW destroyuser ,
.cW ipcclean
and
.cW vacuum ,
all of which are discussed further in the \*(UU section of the
Reference Manual.  See also the section in this manual on
.q "Administering \*(PP."
d576 1
a576 1
.sh 2 "Classes and the \*(PQ Query Language"
d578 1
a578 1
.sh 3 "Basic Capabilities"
d586 1
a586 2
and each attribute is of
a specific 
d591 5
d619 1
a619 7
.cW char16 .)\** (
.(f
\** For additional information on these types, or information on
additional types that are pre-installed in \*(PP, see the Reference
Manual under the heading
.b "Built-In Types" .
.)f
d685 1
a685 1
.sh 3 "Redirecting retrieve queries"
d701 1
a701 1
.sh 3 "Joins"
d703 22
a724 2
To find the names of employees which are the same age, one could
write:
d743 1
a743 1
would be called 
d754 4
a757 4
In point of fact, \*(PQ does not assign any meaning to duplicate
values in such expressions.  This means that \*(PP sometimes
recomputes the same target list several times \(em this frequently
happens when Boolean expressions are connected with an
d777 8
d798 9
d818 3
a820 3
\*(PP supports both fixed-length and variable-length one-dimensional
arrays.  To illustrate their use, we first create a class with an
array type.
d827 1
a827 1
with a variable-length array of
d831 1
a831 1
and an array of 4
d849 5
a853 2
\*(PP uses the FORTRAN numbering convention for arrays\(emthat is,
\*(PP arrays start with array[1] and end with array[n].
d911 50
a960 5
.(l C
.hl
FIX ME
.hl
.)l
d1066 1
a1066 1
      from E in EMP["Jan 1 00:00:00 1970 GMT", "now"]
d1069 4
a1072 2
If you have executed all of the examples so far, then the above query
returns:
d1082 2
a1083 2
There are two salaries for Sam, since he was deleted from and then
re-appended to the
d1087 3
a1089 12
The default beginning of a time range is the origin of the system
clock (which just happens to be
.cW "Jan 1 00:00:00 1970 GMT" '' ``
on \*(UU systems),
.(l C
.hl
FIX ME
new abstime
.hl
.)l
and the default end is the current time; thus, the above time range
can be abbreviated as
d1091 6
d1283 1
a1283 1
.sh 3 "Internal storage of types"
d1298 1
a1298 1
.sh 3 "Functions needed for a user-defined type"
d1324 1
a1324 1
.sh 4 "Data structures for our type"
d1381 1
a1381 1
.sh 4 "Defining the input and output functions for our type"
d1656 5
d1804 1
a1804 1
.sh 3 "Arrays of types"
d1812 1
a1812 1
.sh 4 "Arrays of user-defined types"
d1865 1
a1865 1
.sh 4 "Defining a new array type"
d1932 1
a1932 1
.sh 4 "Creating an array type from scratch"
d2101 1
a2101 1
.sh 3 "Large Object types"
d2128 1
a2128 1
.sh 4 "Defining a large object"
d2201 1
a2201 1
.sh 3 "User-defined Aggregates"
d2211 12
a2222 4
The discussion in this section is intended to provide an overview of
the \*(PP rule system and point the user at helpful references and
examples.  \*(PP actually has two rule systems, the
.i instance-level
d2225 1
a2225 3
rule system.
.\"------------------------------------
.sh 2 "The Instance-Level Rule System"
d2227 4
a2230 3
The instance-level rule system uses markers placed in each instance in
a class to
.q trigger
a2237 4
The theoretical foundations of the \*(PP rule system can be found in
[STON90b].
.\"------------------------------------
.sh 2 "The Query Rewrite Rule System"
d2239 6
a2244 5
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.
Examples and discussion can be found in the demo in
d2248 2
a2249 3
The power of this rule system is discussed in [ONG90] and [STON90b].
.\"------------------------------------
.sh 2 "Which Rule System Should You Use?"
d2253 5
a2257 2
rules affect most of the instances in a class, while the
instance-level system is best when a rule affects only a few
d2262 78
a2339 3
In this section, we will discuss aspects of \*(PP of interest to those
making extensive use of \*(PP, or who are the database administrator
for a group of \*(PP users.
d2341 1
a2341 1
.sh 2 "User Administration"
d2349 71
a2419 1
Reference Manual for specifics on their use.
d2421 1
a2421 1
.sh 2 "Moving Database Directories Out of /usr/local/postgres/data/base"
a2422 6
.(l C
.hl
FIX ME
PGDATA!!!
.hl
.)l
d2425 1
a2425 1
.cW /usr/local/postgres/data/base/ .\**
d2432 49
a2480 2
To move a particular data base to an alternate directory (e.g., on a
filesystem with more free space), do the following:
d2487 3
d2492 3
a2494 3
and it contents to its ultimate destination.  It should still be owned
by the
.cW postgres
d2496 3
d2501 4
a2504 1
.cW /usr/local/postgres/data/base/foo .
d2506 1
a2506 1
Make a symbolic link in
d2508 58
a2565 1
to the new directory.
d2619 207
d2836 1
a2836 1
Berkeley, CA
d2867 6
d2877 1
a2877 1
Mar. 1990.
d2888 1
a2888 1
.uh "APPENDIX A: User-Defined Types and Indices"
d3545 1
a3545 1
.uh "Appendix B: Linking Dynamically-Loaded Functions"
@


1.22
log
@fixed up the installation section.  still lots of FIX MEs..
@
text
@d25 1
a25 1
.\" $Header: /usr/local/devel/postgres/src/doc/RCS/manual.me,v 1.21 1993/10/03 06:15:10 aoki Exp aoki $
d195 4
a198 3
The HP-UX port is based on work done by Richard Turnbull and Sebastian
Fernandez, and the AIX port is based on work done by Rafael Morales
Gamboa.
d281 1
a281 1
.sh 1 "Installing and Running \*(PP"
d335 1
a335 1
manual pages on your user shell before going any further.
d395 1
a395 1
You should look at the Reference Manual under
d397 2
a398 1
if you wish to use non-default options.
d465 1
a465 1
.sh 1 "The \*(PQ Query Language"
d511 1
a511 1
.b "fast path"
d516 1
a516 2
This manual will only discuss the first method (access through the
terminal monitor).
d531 2
a532 2
This prompt indicates the terminal monitor is listening to you and
that you can type \*(PQ queries into a workspace maintained by the
d534 1
a534 1
be used freely in \*(PQ queries.  You can see the current contents of
d1034 1
a1034 1
.sh 1 "User Extensions to \*(PQ"
d1192 6
a1197 5
an object-code 
.cW .o ) (
file created by the user.  This allows \*(PP to call arbitrary
user-defined functions which can be written in a standard programming
language, such as C.  These functions can then be used:
d1300 1
a1300 1
    POINT *center	/* NO! */
d2140 1
a2140 1
.sh 1 "The \*(PP Rule System"
d2185 1
a2185 1
.sh 1 "Administering \*(PP"
d2346 2
d2478 5
a2482 8
key is less than, equal to, or greater than the second.
.(l C
.hl
FIX ME
foo_cmp functions
pg_amproc entry for foo_cmp
.hl
.)l
d2488 4
a2491 3
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
d2507 2
a2508 1
.cW int4_ops , and
d2535 1
a2535 1
.i "may be different" !
d2565 2
d2581 5
d2588 2
a2589 2
First, note that operators for less, less equal, equal, greater equal,
and greater for
d2619 1
a2619 1
The other important point is that all the functions return
d2622 8
d2848 1
a2848 1
.q less
d2850 1
a2850 1
.q "less equal"
d2852 1
a2852 1
.q equal
d2854 1
a2854 1
.q "greater equal"
d2857 1
a2857 1
.q greater
d2859 47
a2905 7
.(l C
.hl
FIX ME
this example does not work
(too few instances, index doesn't get used)
.hl
.)l
d2907 15
a2921 2
Okay, now it's time to test the new opclass.  First we'll create and
populate a class:
d3003 2
d3029 1
a3029 1
reason for this is because nearly all modern versions of \*(UU use a
d3078 3
a3080 1
unreadable or unexecutable by the \*(PP user is an 
d3102 4
d3235 1
a3235 1
	# simple AIX example
@


1.21
log
@removed a lie about function name lengths
@
text
@d1 27
a28 1
.\"========================================================
a29 4
.\" $Header: /usr/local/devel/postgres/src/doc/RCS/manual.me,v 1.20 1993/10/03 05:48:17 aoki Exp aoki $
.\"------------------------------------
.\" XXX standard disclaimer belongs here....
.\"---------------------------------------------------------------------------
d126 1
a126 1
architecture|operating system
d131 1
a131 1
H-P 9000/700 (PA-RISC)|HP-UX 8.07, 9.01
d135 3
a137 1
Symmetry systems.  These versions are no longer distributed.
d195 3
d203 2
a204 1
manual, as did Claire Mosher, Chandra Ghosh and Jim Frew.
d267 1
a267 1
to interact with the \*(PP
d280 2
a281 1
.sh 1 "Installing and running \*(PP"
d283 7
a289 9
.(l
.hl
FIX ME
update from postgres-setup.me
discussion of PATH, PGHOST
.hl
.)l
For purposes of examples in this manual it is assumed that \*(PP has
been installed in the directory
d292 80
a371 10
anywhere (though this may require you to set some environment variables
and/or recompile the system).  Also, in all of the following examples, 
the \*(PP
.i postmaster
process must be running.  This is because all the commands, such as 
.cW createdb ,
.cW monitor ,
and others all try to connect to the
.cW postmaster .
If you get the following error message from any of these commands:
d375 1
a375 1
	Is the postmaster running?
d377 32
a408 1
it is because 
d410 20
a429 3
is not running.  To start the 
.cW postmaster ,
type the following command:
d433 29
d466 7
a472 2
give an overview of how to use \*(PQ to access data.  In other
sections, user extensions to \*(PQ will be discussed.
d474 1
a474 1
.sh 2 "Creating a database"
d476 2
a477 2
Once \*(PP has been installed at your site by following the directions
in the release notes, you can create a database named
d488 14
a501 7
Once you have constructed a database, there are four ways to interact
with it:
.ip \(bu
You can run the \*(PP terminal monitor which allows you to
interactively enter, edit, and execute commands in the query language
\*(PQ.
.ip \(bu
d503 5
a507 5
library of subroutine and call facilities.  This allows you to submit
\*(PQ commands from C and get answers and status messages back to your
program.  This interface is discussed further in the \*(LP section of
the Reference Manual.
.ip \(bu
d514 3
d530 5
a534 8
The
.cW Go
indicates the terminal monitor is listening to you and that you can
type \*(PQ commands into a workspace maintained by the monitor.  The
monitor indicates it is listening by printing
.cW *
as a prompt.  You can see the current contents of the workspace by
typing:
d538 2
a539 2
and the contents of the workspace can be passed to \*(PP for execution
by typing:
d549 1
a549 4
The workspace will be passed to the editor, and you have the full
power of
.cW vi
to make any necessary changes.  Once you exit
d551 2
a552 2
your edited query will be in the monitor's query buffer and you can
submit it to \*(PP by using the
d554 1
a554 1
command described above.
d560 5
a564 2
and the monitor will return you to your command shell.  For a complete
collection of monitor commands, see the manual page on
d566 4
a569 1
in the \*(UU section of the Reference Manual.
d577 6
d584 3
a586 1
.cW createuser
d588 4
a591 3
.cW destroyuser ,
which are discussed further in the \*(UU section of the Reference
Manual.
d593 1
a593 1
.sh 2 "Classes and the Query Language \*(PQ"
d598 11
a608 8
.b class,
which is a named collection of instances of objects.  Each instance
has the same collection of named attributes, and each attribute is of
a specific type.  Furthermore, each instance has an installation-wide
unique, permanent
.b "object identifier"
or
.b oid .
d614 1
a614 1
database as described in the previous section and have started the
d634 4
a637 3
\** See
.q "Built-In Types"
in the Reference Manual.
a638 8
White space (i.e., spaces, tabs and newlines) may be used freely in
\*(PQ queries.
.(l C
.hl
FIX ME
add list of valid backslash characters for use inside of strings
.hl
.)l
d640 6
a645 6
So far, the
.cW create
command looks exactly like the create statement in a traditional
relational system.  However, we will presently see that classes have
properties that are extensions of the relational model, so we use a
different word to describe them.
d648 1
d652 1
a652 1
.cW append
d664 3
a666 2
This will add 3 instances to
.cW EMP ,
d668 1
a668 1
.cW append
d691 1
a691 1
.b "target list"
d696 2
a697 2
\*(PQ allows you to return computations in the target list as long as
they are given a name (e.g.,
d706 8
a713 5
Any retrieve query can be redirected to a new class in the database,
and arbitrary boolean operators
.cW and , (
.cW or ,
.cW not )
d729 6
a734 2
In this case both E1 and E2 are
.b surrogates
d737 9
a745 2
and both range over all instances of the class.  A \*(PQ query can
contain an arbitrary number of class names and surrogates.\**
d750 13
a762 2
the qualification is true, \*(PP must compute and return the target
list.
a763 6
.(l C
.hl
FIX ME
add discussion of duplicates and unique
.hl
.)l
d768 1
a768 1
.cW replace
d780 1
a780 1
.cW delete
d911 1
a911 1
.cW append
d924 1
a924 1
.b inherits
d938 1
a938 1
\** i.e., the inheritance hierarchy is a directed acyclic graph.
d984 1
a984 1
.b "time travel" .
d995 1
a995 1
.b range .
d1047 1
a1047 1
.b "query language functions"
d1049 1
a1049 1
.b "programming language functions"
d1131 1
a1131 1
.b "composite object" .
d1138 1
a1138 1
.cW append s
d1143 1
a1143 1
.b won't
d1174 1
a1174 1
.b "retrieve"
d1190 1
a1190 1
.b "dynamically load"
d1196 1
a1196 1
.ip \(bu
d1198 1
a1198 1
.b internal
d1200 1
a1200 1
.b external
d1202 1
a1202 1
.ip \(bu
d1204 1
a1204 1
.ip \(bu
d1208 1
a1208 1
.b built-in
d1210 1
a1210 1
.b user-defined
d1236 2
a1237 2
.ip \(bu
.b input
d1239 1
a1239 1
.b output
d1244 2
a1245 2
.ip \(bu
.b operator
d1292 1
a1292 1
.b complete
d1294 1
a1294 1
.b contiguous ;
d1303 1
a1303 1
.b NOT
d1337 1
a1337 1
.ip \(bu
d1342 1
a1342 1
.ip \(bu
d1346 1
a1346 3
as input and returns a C string.
.ip
The return value of
d1351 1
a1351 1
.ip \(bu
d1456 1
a1456 1
.b before
d1459 1
a1459 1
.cW any
d1494 1
a1494 1
.b not
d1498 1
a1498 1
printf("size is %d\en", sizeof (MYTYPE));
d1514 1
a1514 1
.b not
d1523 1
a1523 1
.cW create
d1525 1
a1525 1
.cW append
d1527 1
a1527 1
.cW retrieve
d1531 1
a1531 1
.b "operator overloading" ,
d1601 3
d1627 1
a1627 1
.b not
d1629 1
a1629 1
.b is
d1645 1
a1645 1
.b inheritable ;
a1662 1
.cW 
d1738 1
a1738 1
.b automatically
d1750 2
a1751 1
and do some appends
d1805 1
a1805 1
.b "arrays of arrays" .
d1830 1
a1830 1
.b must
d1878 1
a1878 1
.cW  stats .\**
d1948 1
a1948 2
Now,
assuming the functions are in
d2020 1
a2020 1
.b "your function"
d2027 1
a2027 1
.b not
d2040 1
a2040 1
.b small
d2051 1
a2051 1
.b "large object"
d2089 1
a2089 1
.b always
d2114 1
a2114 1
.b must
d2125 1
a2125 1
.b any
d2143 1
a2143 1
.b instance-level
d2145 1
a2145 1
.b "query rewrite"
d2218 1
a2218 1
.ip \(bu
d2223 1
a2223 1
.ip \(bu
d2230 1
a2230 1
.ip \(bu
d2233 1
a2233 1
.ip \(bu
d2263 1
a2263 1
.b all
d2526 1
a2526 1
.b NOTE:
d2532 1
a2532 1
.b "may be different" !
d2603 1
a2603 1
.b doesn't
d2610 1
a2610 1
.b boolean
d2651 1
a2651 1
.b must
d2886 1
a2886 1
.b won't
d2889 1
a2889 1
.b does
d2909 1
a2909 1
.b does
d2937 10
a2946 8
.cW .o ) (
file that implements your function.  As previously mentioned, \*(PP
loads your code at run-time, as required.  In order to allow your code
to be dynamically loaded, you may have to compile and link-edit it in
a special way.  This section briefly describes how to perform the
compilation and link-editing required before you can load your
user-defined functions into a running \*(PP server.  Note that
.b "this process has changed as of Version 4.2." \**
d2979 2
a2980 2
object file (e.g., an executable program or a shared library).  You do
this using the link editing program,
d3030 1
a3030 1
	cc -G 0 -c foo.c
d3039 1
a3039 1
produce a shared object file by running the program
d3041 2
a3042 2
over it with the correct options.  The commands to do this under Alpha
OSF/1 look like:
d3045 2
a3046 2
	cc -c foo.c
	ld -shared -expect_unresolved '*' -o foo.so foo.o
d3051 2
a3052 2
	cc -c foo.c
	ld -Bdynamic -o foo.so foo.o
d3099 2
a3100 2
	cc +z +u -c foo.c
	ld -b -o foo.sl foo.o
d3157 3
a3159 3
	cc -c foo.c
	mkldexport foo.o `pwd` > foo.exp
	ld -H512 -T512 -o foo.so -e _nostart \e
@


1.20
log
@fixed up a few inaccuracies but MANY bogosities remain.
added a lot of FIX ME comments where i saw major problems.

added an appendix on linking .o files for dynamic loading.
@
text
@d4 1
a4 1
.\" $Header$
a2794 4
Previous restrictions about symbol name lengths have been removed.
(Prior to Version 4.2, there were hardcoded limits on the length of
all function and variable names contained within the object files.)
.bu
@


1.19
log
@changed 400's to 403's, but there are other problems left.
@
text
@d4 1
a4 1
.\" /home1/frew/s2k/postgres/manual/RCS/manual.me,v 1.10 1992/07/07 17:44:44 frew Exp
d54 1
a54 1
.    ds PV \s-14.1\s0
d82 2
a83 2
EECS Dept.
University of California, Berkeley
d90 5
a94 7
This document is the user manual for the \*(PP database
system under development at the University of California,
Berkeley.
This project, led by Professor Michael Stonebraker, is
sponsored by the Defense Advanced Research Projects Agency
(DARPA), the Army Research Office (ARO), the National Science
Foundation (NSF), and ESL, Inc.
d98 2
a99 3
This manual describes Version \*(PV of \*(PP.
The \*(PP Group has compiled and tested Version \*(PV on the following
platforms:
d106 5
a110 2
DECstation (MIPS)|ULTRIX V4.2
SPARC|SunOS 4.1.2
d112 9
d124 4
a127 5
Version \*(PV has been tuned modestly.
On the
Wisconsin benchmark, one should expect performance about twice
that of the public domain, University of California version of
\*(II, a relational prototype from the late 1970's.
d133 38
a170 5
The contributors (in
alphabetical order) consisted of Paul Aoki, James Bell, Jennifer Caetta, Jolly Chen,
Ron Choi, Adam Glass, Jeffrey Goh, Joey Hellerstein, Wei Hong,
Anant Jhingran, Greg Kemnitz, Case Larsen, Jeff Meredith, Michael Olson, Nels Olson,
Lay-Peng Ong, Spyros Potamianos, Sunita Sarawagi and Cimarron Taylor.
d172 1
a172 1
For version \*(PV Marc Teitelbaum served as chief programmer and was
d175 2
a176 2
The above implementation team contributed significantly to
this manual, as did Claire Mosher, Chandra Ghosh, and Jim Frew.
d200 5
a204 7
The \*(PP DBMS has been under construction since 1986.
The initial concepts for the system were presented in [STON86]
and the initial data model appeared in [ROWE87].
The first rule
system that was implemented is discussed in [STON88] and the
storage manager concepts are detailed in [STON87].
The first
d206 7
a212 11
was operational in 1987, and we released Version 1 of
\*(PP to a few external users in June 1989.
A critique of
version 1 of \*(PP appears in [STON90].
Version 2 followed in
June 1990, and it included a new rule system documented in
[STON90B].
Version \*(PV, the current version of \*(PP,
is about 200,000 lines of code in the C programming language.
\*(PP is available free of charge, and is being used by approximately
200 sites around the world at this writing.
d216 18
a233 14
This manual discusses the \*(PQ query language, including extensions such
as user-defined types, operators, and both query language and programming
language functions.
Arrays of types and functions of an instance are
discussed, as well as the \*(PP rule system.
This manual concludes with
a discussion on adding an operator class to \*(PP for use in access methods.
.lp
This manual describes the major
concepts of the system
and attempts to provide an accessible path into using the system.
As such, it tries to give examples of the use of the major
constructs, so a beginning user does not need to delve
immediately into the Reference Manual.
d237 3
a239 3
This manual is primarily intended to provide a broad overview of the system,
as well as to illustrate how programmers would use functions to interact with
the \*(PP
d241 2
a242 3
The \*(PP Reference Manual discusses additional aspects
of
the system, and provides full syntactic descriptions of every \*(PP and \*(PQ
d246 5
a250 5
If you are new to \*(PP, you should probably read this manual first, followed
by the parts of the \*(PP Reference Manual necessary to build your application.
In particular, you should read the section on \*(LP if you intend to build
a client application around \*(PP, as this is not discussed at all in this
manual.
d254 16
a269 6
For purposes of examples in this manual it is assumed that \*(PP has been installed in the
directory "/usr/local/postgres" with all the default settings.  In practice, however,
\*(PP can be installed anywhere.
Also, in all the following examples it is required that the \*(PP 
.cW postmaster
be running.  This is because all the commands, such as 
d274 1
a274 1
If you get the following error message from any of these commands
d276 3
a278 2
StreamOpen: connect: errno=61
Error: Failed to connect to backend (host=xxx, port=4321)
d280 5
a284 2
it is because the postmaster is not running.  To start the postmaster,
type the following command.
d291 3
a293 5
\*(PQ is the query language used for interacting with \*(PP.
Here, we
give an overview of how to use \*(PQ to access data.
In other sections,
user extensions to \*(PQ will be discussed.
d297 2
a298 2
Once \*(PP has been installed at your site by following
the directions in the release notes, you can create a database named
d304 4
a307 6
\*(PP allows you to create any number of databases at a
given site and you automatically become the database
administrator of the database just created.
Database names must
have an alphabetic first character and are limited to 16
characters in length.
d309 2
a310 2
Once you have constructed a database, there are four ways to
interact with it:
d312 3
a314 3
You can run the \*(PP terminal
monitor which allows you to interactively enter, edit, and
execute commands in the query language \*(PQ.
d316 5
a320 8
You can
interact with \*(PP from a C program by using the \*(LP
library of subroutine and call facilities.
This allows you to submit
\*(PQ commands from C and get answers and status messages back
to your program.
This interface is discussed further in the
\*(LP section of the Reference Manual.
d322 1
a322 2
You can
use the
d324 2
a325 4
facility,
which
allows you to directly execute functions stored in the database.
This facility is described in the Reference Manual under
d328 1
a328 2
The terminal monitor can be activated for
the
d330 1
a330 2
database by
typing the command:
a333 3
(the
.cW % '' ``
is your \*(UU shell prompt.)
d336 1
a336 1
Welcome to the C POSTGRES terminal monitor
d343 3
a345 4
indicates the terminal monitor is listening to you and
that you can type \*(PQ commands into a workspace maintained
by the monitor.
The monitor indicates it is listening by typing
d347 1
a347 2
as a prompt.
Printing the workspace can be performed by
d352 2
a353 1
and it can be passed to \*(PP for execution by typing:
d359 1
a359 2
text editor
by typing:
d366 1
a366 2
to make any necessary changes.
For more info on using
d368 2
a369 8
type
.(C
% man vi
.)C
Once you exit
.cW vi ,
your edited query will be in the monitor's query
buffer and you can submit it to \*(PP by using the
d371 1
a371 2
command
described above.
d377 2
a378 7
and the monitor will respond:
.(C
I live to serve you.
%
.)C
For a complete collection of monitor commands, see the manual page
on
d384 1
a384 2
you
can destroy it using the following \*(UU command:
d392 2
a393 1
which are discussed further in the \*(UU section of the Reference Manual.
d401 4
a404 6
which is a named collection of instances of objects.
Each
instance has the same collection of named attributes, and each
attribute is of a specific type.
Furthermore, each instance has
an installation-wide unique (never-changing)
d411 1
a411 1
(In order to try out the following \*(PQ examples, create the
d413 2
a414 3
database
as described in the previous section, and start the terminal
monitor.)
d416 2
a417 2
A user can create a new class by specifying the class name,
along with all attribute names and their types:
d425 2
a426 2
The \*(PQ base types used above are
a variable-length array of printable characters
d433 1
a433 1
\**See
d437 8
a444 1
Spaces, tabs and newlines may be used freely in \*(PQ queries.
d448 4
a451 5
command looks exactly like the create
statement in a traditional relational system.
However, we will presently see
that classes have properties that are extensions of the
relational model, so we use a different word to describe them.
d479 3
a481 4
class can be queried with normal selection and
projection queries.
For example, to find the employees under 35 years of age,
one would type:
d494 1
a494 2
Notice that parentheses are required around
the
d500 2
a501 3
\*(PQ allows you to return
computations in the target list as long as they are given a name
(e.g.,
d510 2
a511 2
Any retrieve query can be redirected to a
new class in the database, and arbitrary boolean operators
d523 2
a524 2
To find the names of employees which are the same age, one
could write:
d532 1
a532 2
for an instance of the
class
d534 2
a535 4
and both range over all instances of the class.
A \*(PQ
query can contain an arbitrary number of class names and
surrogates.\**
d537 5
a541 6
\**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, \*(PP must compute and return the
target list.
d543 6
d570 2
a571 2
Since all employees have positive salaries, this command will
leave the
d577 11
a587 3
\*(PP supports both fixed-length and variable-length
one-dimensional arrays.
To illustrate their use, we first create a class with an array type.
d602 1
a602 2
which represents the employee's salary by quarter.
Now we do some
d604 2
a605 2
note that when appending to a non-character array, we enclose the values
within braces and separate them by commas.
d616 2
a617 2
\*(PP uses the FORTRAN numbering convention for arrays\(emthat is, \*(PP
arrays start with array[1] and end with array[n].
d619 1
a619 2
Now, we can run some
queries on
d621 2
a622 2
This query retrieves the names of the employees whose pay changed in the
second quarter:
d672 8
d683 7
a689 17
Now we have covered the basics of using \*(PQ to access your data.
In this section we will discuss those features of \*(PP which
distinguish it from other data managers, such as
inheritance
and
time travel.
In the next section we will cover how the user can extend
the query language via
query language functions
and
composite objects,
as well
as additional extensions to \*(PP using
user defined types,
operators,
and
programming language functions.
d697 1
a697 2
commands in section \*(xX.
Then, create a second class
d720 2
a721 3
that shows their address as a coordinate pair.
In
\*(PP, a class can inherit from zero or more other classes,\**
d723 1
a723 2
\**i.e.,
the inheritance hierarchy is a directed acyclic graph.
d725 3
a727 5
and a query can reference either all
instances of a class or all instances of a class plus all of its
descendants.
For example, the following query finds the
employees over 20:
d731 2
a732 2
On the other hand, to find the names of all
employees, including student employees, over age 20, the query is:
d762 3
a764 4
is not a traditional
relational data type.
As we will see later, \*(PP can be
customized with an arbitrary number of user-defined data types.
d770 1
a770 3
This
feature allows a user to run historical queries.
For example, to
d776 2
a777 2
\*(PP will automatically find the version of Sam's record
valid at the correct time and get the appropriate salary.
d779 1
a779 2
One can also
give a time
d781 2
a782 2
For example to see all the salaries that Sam has
ever earned, one would query:
d788 2
a789 1
If you have executed all of the examples so far, then the above query returns:
d804 2
a805 2
The default beginning of a time range is the origin of the system clock
(which just happens to be
d808 8
a815 2
and the default end is the current time;
thus, the above time range can be abbreviated as
d821 7
a827 2
query language functions, composite types, and user defined types, functions
and operators.
d829 1
a829 1
.sh 2 "User Defined \*(PQ Functions"
d833 1
a833 2
(functions written in \*(PQ)
and
d835 8
a842 8
(functions written in a separately-compiled programming language such as C.)
In this section we will cover \*(PQ functions; programming language
functions will be covered below with the discussion on user-defined types.
.lp
Any collection of commands in the \*(PQ
query language can be packaged together and defined as a
function, usually returning either a set of instances or a set of base types.
For example, the following function
d852 1
a852 2
\*(PQ functions can also have parameters.
The following function
d863 2
a864 3
for commonly-used queries,
\*(PQ functions are useful for creating composite types, as described
below.
d868 3
a870 4
Since \*(PQ functions return instances or sets of instances,
they are the mechanism used to assign values to composite
types.
For example, consider extending the
d877 1
a877 2
we want to associate another
instance of
d879 2
a880 3
corresponding to the manager of the first instance.
Specifically, we will
define a \*(PQ function
d893 1
a893 2
into it with the use of the nested dot notation.
Whenever such a
d898 1
a898 2
The following query finds all the employees who work for
Joe:
d909 1
a909 2
class which is of
type
d911 1
a911 2
i.e. it has a value which is an instance of
the class
d921 4
a924 6
and can reference it just like any other
attribute, with the following two exceptions.
First, one cannot do
direct
.cW append s\(emthat
is,
d929 1
a929 4
work.
Non-projected
retrieves will also be rejected,
i.e.:
d933 1
a933 2
will result
in a warning from the \*(PQ language parser.
d939 1
a939 2
We can also write a \*(PQ function that returns sets of
instances.
d952 1
a952 2
single instance.
Given the query
d958 3
a960 2
function returns many instances, the retrieve query will return all of
them, in a
d962 1
a962 2
form.
If the query in the body of
d964 1
a964 2
returns more than one instance,
the
d967 3
a969 4
set returned by the query in the function's body.
See the \*(PP
Reference Manual's entry on the 
.cW "define function"
a970 1

d972 1
a972 1
.sh 1 "User Defined Types, Operators, and Programming Language Functions"
d976 5
a980 5
a binary object file created by the user.
This allows \*(PP to call
arbitrary user functions which can be written in a standard programming
language.
These functions can then be used:
d986 1
a986 3
(character string) representations of
user-defined
types;
d990 1
a990 2
to
define ordering for indices on user-defined types.
d996 5
a1000 7
types.
Built-in types are those required by the system to bootstrap itself.
User-defined types are those created by the user in the manner described
below.
There is no intrinsic performance difference between using a system
type or user-defined type, other than the overhead due to the complexity of
the type itself.
d1002 1
a1002 1
.sh 2 "Internal storage of types"
d1004 6
d1013 2
a1014 3
upon which
user-defined functions impose structure and meaning.
\*(PP will store and retrieve the data from disk and use user-defined
d1017 1
a1017 1
.sh 2 "Functions needed for a user-defined type"
d1019 2
a1020 1
A completely defined user type requires the following user-defined functions:
d1025 4
a1028 5
functions for the type:
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.
These at least are necessary to define the type.
d1031 2
a1032 3
functions for the type:
These functions define the meanings of
.q equal,
d1037 1
a1037 1
.sh 2 "An Example User Defined Type"
d1043 1
a1043 1
.sh 3 "Data structures for our type"
d1045 4
a1048 5
Before we do anything, we have to decide on what a circle looks
like, both in string format and internally in memory.
Circles
have a center and a radius, so a reasonable string representation of a circle
would be an ordered triple:
d1052 1
a1052 2
where each element is a real number with arbitrary units,
e.g.:
d1056 6
a1061 10
This is what
the input to the circle input function looks like,
and what the output from the circle output function looks
like.
.lp
Now we have to come up with an internal representation for
a circle in memory.
The following
declarations are legal
and reasonable given the format we chose above:
d1074 1
a1074 2
will be written to
disk and read from disk, so
d1080 1
a1080 2
that is, it cannot contain any pointers.
The alternate declaration
d1083 1
a1083 1
    POINT *center
d1089 3
a1091 2
work,
because only the address stored in
d1093 1
a1093 1
would be written to disk, not the
d1095 1
a1095 1
structure that
d1097 2
a1098 3
presumably points to.
\*(PP cannot detect this kind of coding error;
you must guard against it yourself.
d1100 1
a1100 1
.sh 3 "Defining the input and output functions for our type"
d1110 4
a1113 4
type have to be in the same
object file.)
For the sake of argument, suppose we our platform is a DECstation,
where sizeof(double) is 8 bytes (this will be important later).
d1121 1
a1121 2
contains
three functions:
d1124 2
a1125 3
which is the input function for circles.
It
takes a string as an argument and returns a pointer to a
d1129 1
a1129 3
which is the output function for circles.
It is
takes a pointer to s
d1131 1
a1131 1
as input and returns a string.
d1140 2
a1141 4
which is the equality function for
circles.
For the purposes of this discussion, circles are equal
if their areas are equal.
d1172 2
a1173 1
    if (str == NULL) return(NULL);
d1183 2
a1184 1
    if (i < NARGS - 1) return(NULL);
d1201 2
a1202 1
    if (circle == NULL) return(NULL);
d1217 4
d1225 2
a1226 1
Now that we have written these functions and compiled the source file,\**
d1228 1
a1228 1
\**You will need to supply an option like
d1230 9
a1238 11
to your C compiler so it can find the \*(PP
.cW .h '' ``
files.
Also, various platform-specific compiler options may be required to support
\*(PP dynamic linking (for example, the DECstation ULTRIX compiler requires
the
.cW "-G0" '' ``
option.)
See
.q "define function"
in the Reference Manual for details.
d1240 3
a1242 5
we have to let \*(PP know that they exist.
First, we
run the following queries to define the input and
output functions.
These functions must be defined
d1244 5
a1248 15
we define the
type.
\*(PP will
notify you that return type circle is not defined yet, but this
is OK\**:
.(f
\**By default,
user-defined C functions use addresses instead of values for all but
.q small
(<= 4-byte) argument and return types,
so we can use the \*(PQ type
.cW char16
as a placeholder for the C type
.cW "char *" .
.)f
d1252 1
a1252 1
      arg is (char16)
d1256 2
a1257 2
      (language = "c", returntype = char16)
      arg is (circle)
d1262 1
a1262 1
.cW /usr/local/postgres/
d1277 1
a1277 3
structure
in bytes.
For circles, the type members are three
d1280 1
a1280 3
constraints.
However,
when defining your own types, you should
d1282 2
a1283 4
make assumptions about structure sizes,
but instead
write a test program
that does a
d1291 2
a1292 3
is defined incorrectly, you will encounter strange errors which may crash
the data manager itself.
If this were to happen with our
d1294 1
a1294 2
type,
we would have to do a
d1300 1
a1300 2
type correctly.
Note that we would
d1302 2
a1303 2
have to redefine our functions,
since their behavior would not have changed.
d1305 1
a1305 1
.sh 3 "Defining an operator for our type"
d1313 1
a1313 2
records to them
with circles defined, and
d1315 3
a1317 5
the values of the entire list
of records.
But we can do nothing else until we have some circle
operators.
To do this, we make use of the concept of
d1319 1
a1319 2
and in this case we will set the \*(PP equality
operator
d1321 2
a1322 3
to work for circles.
First we have to tell \*(PP
that our circle equality function exists:
d1329 2
a1330 2
We will now bind this function to the
equality symbol with the following query:
d1337 1
a1337 1
.sh 3 "Using our type"
d1343 1
a1343 2
attribute,
and run some queries against it:
d1369 2
a1370 3
Other operators (less than, greater than, etc.) can be defined in
a similar way.
Note that the
d1372 2
a1373 4
symbol will still work for
other types\(emit has merely had a new type added to the list of
types it works on.
Any string of
d1375 2
a1376 3
other than
brackets,
braces, or parentheses can be used in defining an operator.
d1378 1
a1378 1
.sh 2 "Additional info on creating a user-defined function"
d1380 1
a1380 1
.sh 3 "Use palloc and not malloc"
d1382 2
a1383 3
In order for \*(PP to correctly manage memory associated with processing your
type, you
must use the memory allocator
d1385 1
a1385 2
and avoid standard \*(UU memory managers
such as
d1387 1
a1387 2
If you do not, \*(PP will chew up ever increasing amounts of
memory.
d1400 1
a1400 2
which is analogous to
the \*(UU library function
d1407 1
a1407 1
.sh 3 "Re-loading user functions"
d1409 2
a1410 3
In the process of creating a user-defined type, you may find it necessary to
re-load a function in the course of debugging.
This is
d1421 1
a1421 1
.sh 3 "Writing a Function of an Instance"
d1423 3
a1425 3
We've already discussed user functions which take \*(PP base or user defined
types as arguments; in this section, we will discuss inheritable C functions
or methods.
d1427 2
a1428 1
C language methods are useful particularly when we want to make a function
d1437 1
a1437 2
called.
The instance itself will be passed in your function's
d1442 1
a1442 1
\**In \*(PP \*(PV,
d1472 3
a1474 4
is the \*(PP system function that returns
attributes out of the current instance.
It has two arguments: the argument of type TUPLE passed into the function,
and the name of the desired attribute.
d1476 2
a1477 3
will align data properly so you can cast its return value to
the desired type.
For example, if you have an attribute
d1502 1
a1502 2
arguments to the inheritable function.
Thus,
d1518 1
a1518 1
.sh 2 "Arrays of types"
d1521 2
a1522 4
Additionally,
\*(PP supports arrays of user-defined types as well.
When you define a type,
\*(PP
d1526 1
a1526 1
.sh 3 "Arrays of user-defined types"
d1530 1
a1530 2
example discussed above, we will create a class containing
an array of
d1578 1
a1578 1
.sh 3 "Defining a new array type"
d1580 6
d1596 1
a1596 2
Here,
we define an array of integers:
d1610 1
a1610 2
\**Note
that any type using
d1618 2
a1619 1
We can use our type defined above to create an array of integer arrays:
d1642 2
a1643 2
We can also define operators for equality, less than, greater than, etc. which
operate on our new array type as necessary.
d1645 1
a1645 1
.sh 3 "Creating an array type from scratch"
d1647 11
a1657 4
There are many situations in which the above scheme for creating an array
type is inappropriate, particularly when it is necessary to define a
fixed-length array.
In this section, we will create an array of four longs called
d1659 3
a1661 1
and a variable-length array of longs called
d1664 2
a1665 3
We assume
.cW sizeof(long)
== 4.
d1668 2
a1669 2
The only special things we need to know when writing the input and output
functions for
d1673 1
a1673 1
(i.e. fixed-length) array of
d1675 1
a1675 2
to the
output function and expect a simple array of
d1677 1
a1677 3
in return from the input
function.
A simple array suitable for
d1685 4
a1688 7
the situation is a little more
complicated.
Because \*(PP will not know in advance how big the array is,
\*(PP will expect the length of the array (in bytes) to be encoded in the
first four bytes of the memory which contains the array.
The expected
structure is:
d1737 2
a1738 3
we
can define our two arrays.
First we will define the fixed-size array
d1741 3
a1743 2
.cW internallength
== 16 follows from our assumption about
d1749 1
a1749 1
      arg is (char16)
d1753 2
a1754 2
      (language = "c", returntype = char16)
      arg is (quarterly)
d1767 1
a1767 1
      arg is (char16)
d1771 2
a1772 2
      (language = "c", returntype = char16)
      arg is (stats)
d1803 2
a1804 2
.b NOTE
that when you use your own functions to input and output array types,
d1806 2
a1807 4
will define how to parse the external (string) representation.
The braces
notation is only a
convention used by
d1815 1
a1815 1
.sh 2 "Large Object types"
d1817 7
d1826 1
a1826 2
objects\(emthat is, they are
smaller than 8 Kbytes\**
d1828 4
a1831 1
\**8 * 1,024 == 8,192 bytes
d1833 3
a1835 4
in size.
If you require a larger type for something like
a document retrieval system or for storing bitmaps, you will need to use
the \*(PP
d1837 3
a1839 5
interface.
The interface to large objects is quite similar to the
\*(UU file system interface.
The particulars are detailed in
Section 7 of the \*(PP Reference Manual, which you should have available to
d1842 1
a1842 1
.sh 3 "Defining a large object"
d1844 3
a1846 3
Just like any other type, a large object type requires input and output
functions.
For the purposes of this discussion, we assume that two functions,
d1850 2
a1851 3
have been written using the large object interface, and that the compiled
functions
are in
d1853 1
a1853 2
We also presume that we are using
the
d1855 1
a1855 2
interface for large objects discussed in the Reference
Manual.
d1861 1
a1861 1
      arg is (char16)
d1865 2
a1866 2
      (language = "c", returntype = char16)
      arg is (map)
d1873 1
a1873 2
Note that
large objects are
d1889 10
a1898 11
Notice that the above queries are identical in syntax to those we have been
using
all along to define types and such; the fact that this type is a large object
is completely hidden in the large object interface and \*(PP storage manager.
.\"-----------------
.sh 3 "Writing functions and operators for large object types"
.lp
Like any other \*(PP type, you can define functions and operators for large
object types.
The only caveat is that, like any other functions which process
a large object, they
d1900 3
a1902 3
use the large object interface described in Section 7 of the \*(PP Reference
Manual.
Possible queries which involve functions on large objects could include
d1909 1
a1909 2
Because all functionality is available
to large objects,
d1913 9
a1921 2
Operator
classes for index access methods will be discussed later in this manual.
d1925 3
a1927 3
The discussion in this section is intended to provide an overview of the
\*(PP rule system and point the user at helpful references and examples.
\*(PP actually has two rule systems, the
d1933 1
a1933 1
.sh 2 "The Instance-level Rule System"
d1935 2
a1936 2
The instance-level rule system uses markers placed in each instance in a
class to
d1938 2
a1939 3
rules.
Examples of the instance-level rule system are
explained and illustrated in
d1941 6
a1946 8
which is included with the
\*(PP distribution.
Additional discussion of the instance-level rule system
can be found in the Reference Manual under
.cW "define rule" .
The theoretical
foundations
of the \*(PP rule system can be found in [STON90].
d1951 4
a1954 6
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.
Examples and discussion can
be found in the demo in
d1956 11
a1966 14
and further discussion is in the
Reference Manual under
.cW "define rule" .
The power of this rule system is
discussed in
[ONG90] and [STON90].
.\"------------------------------------
.sh 2 "When to use either?"
.lp
Since each rule system is architected quite differently, they work best in
different situations.
The query rewrite system is best when rules affect
most of the instances in a class, while the instance-level system is best when
a rule affects only a few instances.
d1971 2
a1972 2
making extensive use of \*(PP, or who are the database administrator for
a group of \*(PP users.
d1974 1
a1974 1
.sh 2 "User administration"
d1980 3
a1982 3
enable and disable access to \*(PP by specific users on the host system.
Please read the descriptions of these
commands in the Reference Manual for specifics on their use.
d1984 1
a1984 1
.sh 2 "Moving database directories out of /usr/local/postgres/data/base"
d1986 6
d1996 4
a1999 3
\**Data for certain classes may stored elsewhere if
a non-standard storage manager was specified
when they were created.
d2002 1
a2002 2
filesystem with more free space),
do the following:
d2004 1
a2004 3
Create the database
(if it doesn't already exist)
using the
d2006 1
a2006 3
command.
In the following steps
we will assume the database is named
d2009 1
a2009 2
Copy
the directory
d2011 2
a2012 3
and it contents
to its ultimate destination.
It should still be owned by the
d2025 5
a2029 7
Occasionally, \*(PP will fail with cryptic error messages that are due to
relatively simple problems.
The following are a list of \*(PP error
messages and the likely fix.
These messages are ones you would likely see
in the
monitor
d2036 3
a2038 3
Either the kernel has not been configured for System V shared memory, or some
other program is using it up.
On most machines, the \*(UU command
d2040 1
a2040 2
will
show shared memory and semaphore usage.
d2042 2
a2043 2
To delete all shared memory and
semaphores (may be necessary if a backend fails), run the
d2045 1
a2045 2
command.
Note, however, that
d2049 3
a2051 4
semaphores belonging
to the user running it, so the user should be certain that none of his/her
non-\*(PP
processes are using semaphores before running this command.
d2057 2
a2058 3
This message means that a \*(PP backend was expecting shared memory to be
available and it was not.
Usually this is due to
d2068 2
a2069 2
This message means that you are running a \*(LP application but it could
not link up with a
d2071 1
a2071 2
If you see this error message, you should
see if a
d2073 2
a2074 3
is truly running.
If one is running, the problem is
likely related to your network.
d2080 2
a2081 2
``A Unified Framework for Version Modeling Using Production Rules in a Database
System,"
d2083 3
a2085 2
University of California, Berkeley,
ERL Memo M90/33,
a2094 6
.xP [SCHA90]
Shapiro, L.,
``Join Processing in Database Systems with Large Main Memories,''
ACM-TODS,
Sept. 1986.
.\"------------------------------------
d2096 12
a2107 1
(missing)
d2109 1
a2109 1
.xP [STON87]
d2116 5
a2120 2
.xP [STON88]
(missing)
d2122 2
a2123 2
.xP [STON90]
Stonebraker, M. et. al.,
a2127 6
.\"------------------------------------
.xP [STON90B]
(missing)
.\"------------------------------------
.xP [WANG88]
(missing)
d2129 1
a2129 1
.uh "APPENDIX: User defined types and indices"
d2131 16
a2146 15
In this section, we will discuss how to extend \*(PP to use a user-defined
type and associated functions with existing access methods.
This way, you
can define a BTREE or RTREE index on your own type.
To do this, we will
discuss how to define a new operator class in \*(PP
for use with an existing access method.
.lp
Our example will be to add a new operator class to the BTREE access method.
The new operator class will sort integers in ascending absolute value
order.
This tutorial will describe how to define the operator class.
If you work the example,
you will be able to define and use indices that sort integer
keys by absolute value.
a2147 7
There are several \*(PP system classes that are important in understanding how
the
access methods work.
These will be discussed, and then a sample procedure
for adding a new set of operators to an existing access method will be shown
as an example.
.lp
d2150 3
a2152 4
class contains one instance for every user defined access method.
Support for the HEAP access method is built into \*(PP,
but every other access method is described here.
The schema is
d2167 2
a2168 4
procedure identifiers for interface
routines to the access method.
For
example,
d2170 2
a2171 3
ids for opening, closing,
and getting instances from the access
method appear here.
d2176 4
a2179 6
is used as a foreign key in lots of
other classes.
For BTREES, this object ID is 403.
You don't need to add
a new instance to this class; all you're interested in is the object ID of
the access method instance you want to extend:
d2191 4
a2194 6
attribute exists to standardize comparisons across data
types.
For example, BTREES impose a strict ordering on keys, less to
greater.
Since \*(PP allows the user to define operators, \*(PP cannot
in general look at the name of an operator (eg,
d2197 7
a2203 9
and tell what kind
of comparison it is.
In fact, some access methods (like rtrees) don't impose
a less-to-greater ordering, but some other ordering, like containment.
\*(PP needs some consistent way of taking a scan qualification, looking at
the operator, deciding if a usable index exists, and rewriting the query
qualification in order to improve access speeds.
This implies
that \*(PP needs to know, for example, that
d2207 5
a2211 8
partition
a BTREE.
Strategies is the way that we do this.
.lp
Defining a new set of strategies is beyond the scope of this discussion, but
how the BTREE strategies work will be explained, since you'll need to know that
to add a new operator class.
In the
d2216 1
a2216 3
For BTREES, this
number is 5.
These strategies correspond to
d2230 2
a2231 2
The idea is that you'll add procedures corresponding to the comparisons
above to the
d2233 4
a2236 6
relation (see below).
The access method code can use
these numbers, regardless of data type, to figure out how to partition the
BTREE, compute selectivity, and so on.
Don't worry about the details of adding
procedures yet; just understand that there's a set of these for
d2242 2
a2243 3
Strategies are used by all of the \*(PP access methods.
Some access methods require other support routines in order to work.
For example,
d2246 4
a2249 8
Similarly,
the RTREE access method must be able to compute intersections,
unions,
and sizes of rectangles.
These operations do not correspond to user qualifications in
\*(PQ queries;
they are administrative routines used by the access methods,
internally.
d2251 2
a2252 2
In order to manage diverse support routines consistently across
all \*(PP access methods,
d2256 11
a2266 10
This field records the number of support routines used by
an access method.
For BTREES, this number is one\(emthe routine to take two keys and return
\(mi\^1,
0,
or
\(pl\^1,
depending on whether the first key is less than,
equal to,
or greater than the second.
d2272 3
a2274 3
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
d2287 2
a2288 3
every BTREE operator class has a set of procedures,
one through five, above.
Some existing opclasses are
d2318 6
a2323 8
You should
substitute your value for 17314
wherever it appears in this discussion.
.lp
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
d2325 1
a2325 2
operator class on BTREES,
the operators we require are:
d2333 2
a2334 1
Suppose the code that implements the functions defined is stored in the file
d2366 1
a2366 3
are being defined.
All of these operators are already defined
for
d2375 5
a2379 7
The new operators behave differently, of course.
In order to guarantee that \*(PP 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
\*(PP, but only if the operator isn't already defined for the argument
types.
d2389 4
a2392 6
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.
d2396 1
a2396 2
values;
the access methods rely on this fact.
d2423 2
a2424 3
Now define the operators that use them.
As noted,
the operator names must be unique for two
d2426 1
a2426 2
operands.
You can do a query on
d2431 5
a2435 9
to see if your name is taken for the types you want.
The important things here are the procedure
(which are the C functions defined above)
and the restriction and join selectivity functions.
You should just use the ones used below\(emnote that there are different such
functions for the less-than,
equal,
and greater-than cases.
These
d2437 2
a2438 3
be supplied,
or the access method will die when it tries to use the operator.
You should copy the names for
d2469 2
a2470 2
Notice that five operators corresponding to less, less equal, equal, greater,
and greater equal are defined.
d2472 2
a2473 2
We're just about finished. the last thing we
need to do is to update the
d2475 1
a2475 3
relation.
To do this, we need the
following attributes:
d2494 1
a2494 3
(== whatever you got instead
of 17314,
see above)
d2500 1
a2500 3
of the operators for the
opclass (which we'll get in just a
minute)
d2510 2
a2511 4
or not to use a given index in a scan.
Fortunately, these already
exist.
The two functions we'll use are
d2513 1
a2513 2
which estimates the
selectivity of the btree, and
d2515 1
a2515 2
which estimates the number of
pages a search will touch in the tree.
d2519 2
a2520 3
of the operators we just defined.
We'll look up the
names of all the operators that take two
d2553 1
a2553 2
(Note
that your
d2555 2
a2556 2
numbers may be different.)
The operators we are interested in are those with
d2558 5
a2562 6
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.
(Of course, there are lots of other queries we could used to get the oids
we wanted.)
d2566 3
a2568 4
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
d2570 1
a2570 2
Recall that
the BTREE instance's
d2572 1
a2572 2
is 403
and
d2576 1
a2576 3
17314.
Then we
add the instances we need:
d2626 7
d2634 1
a2634 2
Okay, now it's time to test the new opclass.
First we'll create and
d2664 1
a2664 2
Okay, looks pretty random.
Define an index using the new opclass:
d2669 1
a2669 2
Now run a query that doesn't use one of our new operators.
What we're
d2672 2
a2673 2
use our index, so that
we can tell the difference when we see a query that
d2675 3
a2677 3
use the index.
This query won't use the index because the operator we use in the qualification
isn't one that appears in the list of strategies for our index.
d2692 2
a2693 3
Yup, just as random; that didn't use the index.
Okay, let's run a query
that
d2711 3
a2713 3
values are in order of increasing absolute value
(as they should be, since the index was used for this scan) and that
we got the right answer\(emthe instance for
d2716 269
@


1.18
log
@changed DEPT.name to DEPT.dname in function manager on page 11
@
text
@d2572 1
a2572 1
instance for BTREE (== 400, see above)
d2673 1
a2673 1
is 400
d2683 1
a2683 1
      (amopid = "400"::oid,          /* btree oid        */
d2690 1
a2690 1
* append pg_amop (amopid = "400"::oid,
d2697 1
a2697 1
* append pg_amop (amopid = "400"::oid,
d2704 1
a2704 1
* append pg_amop (amopid = "400"::oid,
d2711 1
a2711 1
* append pg_amop (amopid = "400"::oid,
@


1.17
log
@quotes around function body in high_pay and large_pay on p. 10
@
text
@d863 1
a863 1
              and DEPT.name = $1.dept" \\g
@


1.16
log
@first pass at changing for release 4.1
@
text
@d820 1
a820 1
      as retrieve (EMP.all) where EMP.salary > 50000 \\g
d830 1
a830 1
      as retrieve (EMP.all) where EMP.salary > $1 \\g
@


1.15
log
@shovel some honesty into the discussion of arrays.
@
text
@d54 1
a54 1
.    ds PV \s-14.0\s0
a110 1
Sequent Symmetry (386)|DYNIX V3.0
d126 3
a128 3
alphabetical order) consisted of James Bell, Jennifer Caetta, Jolly Chen,
Ron Choi, Jeffrey Goh, Joey Hellerstein, Wei Hong,
Anant Jhingran, Greg Kemnitz, Case Larsen, Jeff Meredith, Michael Olson,
d131 2
a132 5
For version \*(PV Jeff Meredith served as chief programmer and was
responsible for overall coordination of the project and for individually
implementing the
.q "everything else"
portion of the system.
d214 23
a284 9
.ip \(bu
\*(PP is accessible from the \*(OF programming
environment.
\*(OF is a graphical user interface (GUI) toolkit
that allows a user to build sophisticated DBMS-oriented
applications.
\*(OF is a separate research project described
in a collection of reports
[WANG88, SCHA90] and is not treated further in this manual.
d290 1
a290 12
typing the command\**:
.(f
\**You may first need to set the
.cW POSTGRESHOME
environment variable to the name of the \*(PP root directory at your site,
if it is not the default
.cW /usr/postgres .
If the \*(PP you wish to access is on a remote host, then you will also need to
set the
.cW PGHOST
environment variable to the name of the remote host.
.)f
d676 2
a677 2
* append STUD_EMP (name = "Sunita", salary = 1300,
                   age = 41, dept = "electronics",
d704 1
a704 1
employees over 39:
d706 1
a706 1
* retrieve (E.name) from E in EMP where E.age > 39 \\g
d709 1
a709 1
employees, including student employees, over age 40, the query is:
d711 1
a711 1
* retrieve (E.name) from E in EMP* where E.age > 39 \\g
d720 2
d1106 1
a1106 1
.cW /usr/postgres/tutorial/circle.o .
d1226 1
a1226 1
.cW -I$POSTGRESHOME/src/lib/H
d1264 1
a1264 1
      as "/usr/postgres/tutorial/circle.o" \\g
d1269 1
a1269 1
      as "/usr/postgres/tutorial/circle.o" \\g
d1273 1
a1273 1
.cW /usr/postgres/tutorial
d1352 1
a1352 1
      as "/usr/postgres/tutorial/circle.o" \\g
d1453 1
a1453 1
* load "/usr/postgres/tutorial/circle.o" \\g
d1535 1
a1535 1
      as "/usr/postgres/tutorial/overpaid.o" \\g
d1768 1
a1768 1
.cW /usr/postgres/tutorial/stats.c
d1770 1
a1770 1
.cW /usr/postgres/tutorial/quarterly.c ,
d1784 1
a1784 1
      as "/usr/postgres/tutorial/quarterly.o" \\g
d1789 1
a1789 1
      as "/usr/postgres/tutorial/quarterly.o" \\g
d1802 1
a1802 1
      as "/usr/postgres/tutorial/stats.o" \\g
d1807 1
a1807 1
      as "/usr/postgres/tutorial/stats.o" \\g
d1883 1
a1883 1
.cW /usr/postgres/tutorial/large.o .
d1895 1
a1895 1
      as "/usr/postgres/tutorial/large.o" \\g
d1900 1
a1900 1
      as "/usr/postgres/tutorial/large.o" \\g
d1918 1
a1918 1
               a = "/usr/postgres/maps/earth") \\g
d1921 1
a1921 1
               a = "/usr/postgres/maps/moon") \\g
d1970 1
a1970 1
.cW $POSTGRESHOME/demo ,
d1989 1
a1989 1
.cW $POSTGRESHOME/video ,
d2021 1
a2021 1
.sh 2 "Moving database directories out of $POSTGRESHOME/data/base"
d2025 1
a2025 1
.cW $POSTGRESHOME/data/base/ .\**
d2046 1
a2046 1
.cW $POSTGRESHOME/data/base/foo
d2054 1
a2054 1
.cW $POSTGRESHOME/data/base/foo .
d2057 1
a2057 1
.cW $POSTGRESHOME/data/base
d2407 1
a2407 1
.cW /usr/postgres/tutorial/int4_abs.c .
d2480 1
a2480 1
      as "/usr/postgres/tutorial/int4_abs.o" \\g
d2485 1
a2485 1
      as "/usr/postgres/tutorial/int4_abs.o" \\g
d2490 1
a2490 1
      as "/usr/postgres/tutorial/int4_abs.o" \\g
d2495 1
a2495 1
      as "/usr/postgres/tutorial/int4_abs.o" \\g
d2500 1
a2500 1
      as "/usr/postgres/tutorial/int4_abs.o" \\g
@


1.14
log
@I lied
@
text
@d554 2
a555 1
\*(PP fully supports both fixed-length and variable-length arrays.
a642 18
Note that
the
.cW text
type in \*(PP is defined as an array of character, so queries like
.(C
* retrieve (manager.name)
      where manager.employees[1][1] = 'b' \\g

* retrieve (manager.name)
      where manager.employees[3] = "jeff" \\g

* retrieve (manager.employees[3][2]) \\g

* delete manager where manager.employees[2][1] = 'g' \\g
.)C
will all work.
However, in general \*(PP currently only supports arrays of
one dimension.
@


1.13
log
@minor stuff.  I'll shut up now.
@
text
@d1318 1
a1318 1
printf("size is %d\n", sizeof (MYTYPE));
d1396 1
a1396 1
      where tutorial.a = "(0.0, 0.0, 10.0)"::circle
d1731 2
a1732 1
.cW "stats", the situation is a little more
@


1.12
log
@fix up things relating to Postquel functions and C functions on
complex types.
@
text
@d825 4
a828 3
Any collection of commands in the \*(PQ query language can be packaged
together and defined as a function, usually returning either a set of
instances or a set of base types.  For example, the following function
d865 1
a865 1
.cW EMP
d884 2
a885 1
into it with the use of the nested dot notation.  Whenever such a
d941 2
a942 1
instances.  For example, consider the function
d954 2
a955 1
single instance.  Given the query
d962 4
a965 1
them, in a "flattened" form.  If the query in the body of
d971 2
a972 1
set returned by the query in the function's body.  See the \*(PP
d1487 2
a1488 1
called.  The instance itself will be passed in your function's
d1529 2
a1530 1
the desired type.  For example, if you have an attribute
d1558 2
a1559 1
* retrieve (EMP.all) where overpaid2(EMP, DEPT, "bill", 8) \\g
d1567 3
a1569 3
TUPLE emp, dept;
char *name;
long number;
@


1.11
log
@MAJOR revisions and reformatting.
@
text
@d825 3
a827 4
Any collection of commands in the \*(PQ
query language can be packaged together and defined as a
function, which is assumed to return a collection of instances.
For example, the following function
d855 1
a855 1
Since \*(PQ functions return sets of instances,
d863 9
a871 1
We can do this by simply defining a function:
d874 23
a896 5
      (language = "postquel", returntype = setof EMP)
      arg is (char16)
      as "retrieve (EMP.all)
              where EMP.name = DEPT.manager
              and DEPT.name = $1" \\g
d898 1
a898 1
Here, we have added an attribute to the
d903 1
a903 1
i.e. it has a value which is one or more instances of
a905 7
Specifically, the value of the
.cW manager
field is
intended to be an instance of
.cW EMP
which is the manager of the
indicated employee.
a909 27
.lp
We can also define a function to associate a manager with each
instance of
.cW EMP .
Specifically, we will
define a second \*(PQ function
.cW lookup_mgr :
.(C
* define function lookup_mgr
      (language = "postquel", returntype = EMP)
      arg is (EMP)
      as "retrieve (E.all) from E in EMP
              where E.name = DEPT.manager
              and DEPT.name = $1.dept" \\g
.)C
In this case, the function
.cW lookup_mgr
has an argument which is an
instance of the class
.cW EMP .
Therefore, it takes a value for each
instance of
.cW EMP ,
which is the result of the query with the field
.cW EMP.dept
filled in with its appropriate constant.
.lp
d911 1
a911 1
.cW lookup_mgr
d921 1
a921 1
* append emp (emp.lookup_mgr.name = "Smith") \\g
d929 1
a929 1
* retrieve (emp.lookup_mgr) \\g
d934 6
a939 13
Since
.cW lookup_mgr
takes a class
as its only argument and returns a class,
\*(PQ allows
referencing into it with the use of the nested dot notation.
Whenever such a function is defined over a class, a user can
utilize the cascaded dot notation to reference into (i.e. access the fields
of) the objects returned
by the function.
.lp
The following query finds all the employees who work for
Joe:
d941 28
a968 7
* retrieve (EMP.name) where EMP.manager.name = "Joe" \\g
.)C
This is exactly equivalent to:
.(C
* retrieve (EMP.name)
      where name(lookup_mgr(EMP)) = "Joe" \\g
.)C
d1241 1
a1241 1
.cW "-G 0" '' ``
d1478 12
a1489 5
to be the instance being qualified at
the moment your function is called.
Rather than getting the instance itself
in your function's parameter list, you will use \*(PP library routines to
access the data in the instance as described below.
d1500 2
a1501 1
overpaid() /* note that there are no arguments */
d1503 1
a1503 1
    extern Datum GetAttribute();
d1506 3
a1508 3
    salary = (short) GetAttribute("salary");
    seniority = (short) GetAttribute("seniority");
    performance = (short) GetAttribute("performance");
d1513 1
a1513 1
.cW GetAttribute
d1516 5
a1520 15
It has one argument
which is the name of the desired attribute, and its return type
is a type "Datum" which is defined as being large enough to hold
pointer values and all integer types.\**
.(f
\**In \*(PP \*(PV,
.cW Datum
is defined as
.cW "long int" .
.)f
.cW GetAttribute
will align data properly so you can cast
its return value to the desired type.
For example, if you have an
attribute
d1525 1
a1525 1
.cW GetAttribute
d1530 1
a1530 1
str = (char *) GetAttribute("name")
a1531 2
Note that the instance argument must be the first argument when using your
function in \*(PQ queries.
d1540 1
a1540 1
      arg is (SET)
d1543 3
a1545 8
The special flag
.cW SET
in the argument list tells
\*(PP that this function will be processing an instance.
.lp
Your function may only access one instance via the
.cW GetAttribute
call, but you can have additional base or user-defined types as arguments.
d1548 1
a1548 1
* retrieve (EMP.all) where overpaid2(EMP, "bill", 8) \\g
d1555 2
a1556 1
overpaid2(name, number)
a1559 7
Note that the arguments are
.q shifted
one to the left, and the
.cW EMP
argument
is omitted; its values are referenced via
.cW GetAttribute.
@


1.10
log
@clean up formatting
@
text
@d1 5
a5 1
.he 'revision $Revision$'DRAFT'$Date$'
d7 42
a48 7
.\" $Header: /home1/frew/s2k/postgres/manual/RCS/manual.me,v 1.9 1992/07/03 23:23:14 mer Exp frew $
.\"
.\" Start of nroff/troff specific definitions section.
.\"
.\" Defines II, PP, UU, PQ, LP, PV, OF, for
.\"    INGRES, POSTGRES, UNIX, POSTQUEL, LIBPQ, PICASSO, 4.0
.\"
d56 1
a56 6
.\"
.\" Start of format definition section.
.\"
.nr sp 10    \" standard section title point size
.nr ps .50v    \" .15v larger paragraph prespace
.nr pp 11    \" one point larger paragraph pointsize
d59 17
a75 4
.fo ''\\s+2%\\s0''    \" page numbers in 12 point type
.nr so -.5i    \" -1/2 inch additional section title offset
.nr $i .5i    \" paragraph base indent
.\"
a76 1
.sz \n(sp
d78 2
a79 4
The \*(PP User Manual
.sp 1
.sz \n(pp
.sp 1
a83 1
.sp 1
d87 1
d92 2
a93 1
Berkeley.  This project, led by Professor Michael Stonebraker, is
d97 1
d100 14
a113 4
This manual describes Version \*(PV of \*(PP.  \*(PP
Software is available for SUN 4 class machines, for
DECstation 3100 and 5000 machines, and for the SEQUENT Symmetry
machine.
d116 2
a117 1
Version \*(PV has been tuned modestly.  Hence, on the
d121 1
d125 2
a126 1
graduate, and staff programmers.  The contributors (in
d134 3
a136 1
implementing the "everything else" portion of the system.
d139 2
a140 15
this manual, as did Claire Mosher and Chandra Ghosh.
.sh 1 "ABSTRACT"
.lp
The \*(PP project undertook to build a next generation
DBMS whose purpose was to rectify the known deficiencies in
current relational DBMSs.  This system, constructed over a five
year period by one full time programmer and 3-4 part time
students, is about 200,000 lines of code in the C programming language.
\*(PP is available free of charge, and is being used by approximately
200 sites around the world at this writing.  This manual describes the major
concepts of the system
and attempts to provide an accessible path into using the system.
As such, it tries to give examples of the use of the major
constructs, so a beginning user does not need to delve
immediately into the Reference.
d145 2
a146 1
specific type.  In current commercial systems, possible types are
d148 2
a149 1
dates.  It is commonly recognized that this model is insufficient
d152 5
a156 7
\*(PP tried to build a data model with substantial
additional power, yet requiring the understanding of as few
concepts as possible.  The relational model succeeded in
replacing previous models in part because of its simplicity.  We
wanted to have as few concepts as possible so that users would
have minimum complexity to contend with.  Hence, \*(PP
leverages the following four constructs:
d165 2
a166 1
and the initial data model appeared in [ROWE87].  The first rule
d168 8
a175 4
storage manager concepts are detailed in [STON87].  The first
"demo-ware" was operational in 1987, and we released Version 1 of
\*(PP to a few external users in June 1989.  A critique of
version 1 of \*(PP appears in [STON90].  Version 2 followed in
d177 6
a182 2
[STON90B].  We are now delivering version \*(PV, which is the subject
of this manual.
d187 4
a190 2
language functions.  Arrays of types and functions of an instance are
discussed, as well as the \*(PP rule system.  This manual concludes with
d192 9
a200 1
.sh 1 "WHAT SHOULD BE READ"
d204 4
a207 1
the \*(PP "backend".  The \*(PP Reference discusses additional aspects of
d209 2
a210 1
command in a format similar to that used in \*(UU "man pages".
d213 1
a213 1
by the parts of the \*(PP Reference necessary to build your application.
d217 1
d220 4
a223 2
\*(PQ is the query language used for interacting with \*(PP.  Here, we
give an overview of how to use \*(PQ to access data.  In other sections,
d225 1
d229 2
a230 2
the directions in the release notes, you can create a database,
.b foo,
d232 1
a232 2
.(l
.ft C
d234 1
a234 2
.ft
.)l
d237 2
a238 1
administrator of the database just created.  Database names must
d243 3
a245 1
interact with it.  First, you can run the \*(PP terminal
d247 3
a249 1
execute commands in the query language \*(PQ.  Second, you can
d251 2
a252 1
library of subroutine and call facilities.  This allows you to submit
d254 8
a261 6
to your program.  This interface is discussed further in the
\*(LP section of the Reference.
The third way of interacting
with \*(PP is to use the facility called
.b fast
.b path,
d264 6
a269 3
This facility is described in the Reference under "Fast Path".
Lastly, \*(PP is accessible from the \*(OF programming
environment.  \*(OF is a graphical user interface (GUI) toolkit
d271 2
a272 1
applications.  \*(OF is a separate research project and is described
d276 25
a300 11
The terminal monitor can be activated for any database by
typing the command:
.(l
.ft C
% monitor <dbname>
.ft
.)l
As a result, you will be greeted by the following message:
.(l
.ft C
Welcome to the POSTGRES terminal monitor
d304 4
a307 3
.ft
.)l
The "Go" indicates the terminal monitor is listening to you and
d309 5
a313 2
by the monitor.  The monitor indicates it is listening by typing
* as a prompt.  Printing the workspace can be performed by
d315 1
a315 2
.(l
.ft C
d317 1
a317 2
.ft
.)l
d319 1
a319 2
.(l
.ft C
d321 4
a324 3
.ft
.)l
If you make a typing mistake, you can invoke the vi text editor
d326 1
a326 2
.(l
.ft C
d328 1
a328 2
.ft
.)l
d330 7
a336 4
power of vi to make any necessary changes.  For more info on using
vi, type
.(l
.ft C
d338 7
a344 4
.ft
.)l
Once you exit vi, your edited query will be in the monitor's query
buffer and you can submit it to \*(PP by using the "\\g" command
d348 1
a348 2
.(l
.ft C
d350 1
a350 2
.ft
.)l
d352 1
a352 2
.(l
.ft C
a353 1

d355 1
a355 2
.ft
.)l
d357 7
a363 3
on "monitor" in the \*(UU section of the Reference.
.lp
If you are the database administrator for a database, you
d365 1
a365 2
.(l
.ft C
d367 1
a367 2
.ft
.)l
d369 1
a369 1
.b createuser,
d371 3
a373 2
.b destroyuser,
which are discussed further in the \*(UU section of the Reference.
d375 1
d378 16
a393 2
In order to begin using \*(PP, create the
.b foo
d396 1
a396 6
monitor.  The fundamental notion in \*(PP is that of a class,
which is a named collection of instances of objects.  Each
instance has the same collection of named attributes, and each
attribute is of a specific type.  Furthermore, each instance has
an installation wide unique (never-changing) identifier (OID).
.sh 3 "Creating a New Class"
d399 27
a425 12
along with all attribute names and their types, for example:
.(l
.ft C
* create EMP (name=text, salary=int4,
     age=int4, dept=char16) \\g

* create DEPT (dname=char16, floor=int4,
     manager=text) \\g
.ft
.)l
So far, the create command looks exactly like the create
statement in a traditional relational system.  However, we will presently see
d428 1
d430 1
d432 19
a450 17
To populate a class with instances, one can use the append
command as follows:
.(l
.ft C
* append EMP (name="Joe",salary=1400,
     age=40,dept="shoe")
  \\g

* append EMP (name="Sam",salary=1200,
     age=29,dept="toy")
  \\g

* append EMP (name="Bill",salary=1600,
     age=36,dept="candy") \\g
.ft
.)l
This will add 3 instances to EMP, one for each command.
d453 5
a457 2
The EMP class can be queried with normal selection and
projection queries.  For example, to find the employees under 35
d459 28
a486 19
.(l
.ft C
* retrieve (EMP.name) where EMP.age<35

\\g
.ft
.)l
Notice that parentheses are required around the target list of
returned attributes.  Like Quel, \*(PQ allows you to return
computations in the target list as long as they are given a name,
e.g:
.(l
.ft C
* retrieve (result=EMP.salary/EMP.age)
  where EMP.name="Bill"

\\g
.ft
.)l
d489 7
a495 5
Moreover, like Quel, any retrieve query can be redirected to a
new class in the database and arbitrary boolean operators (and,
or, not) are allowed in the qualification of any query:
.(l
.ft C
d497 3
a499 5
  where EMP.age<35 and EMP.salary>1000

\\g
.ft
.)l
d502 1
a502 2
Joins are done in \*(PQ in essentially the same way as in
QUEL.  To find the names of employees which are the same age, one
d504 1
a504 2
.(l
.ft C
d506 10
a515 9
  from E1 in EMP, E2 in EMP
  where E1.age=E2.age
  and E1.name != E2.name

\\g
.ft
.)l
In this case both E1 and E2 are surrogates for an instance of the
class EMP and range over all instances of the class.  A \*(PQ
d517 4
a520 2
surrogates.  The semantics of such a join are identical to those
of QUEL, namely the qualification is a truth expression defined
d525 2
d529 8
a536 11
Updates are accomplished in \*(PQ using the replacement
statement, e.g:
.(l
.ft C
* replace EMP (salary=E.salary)
  from E in EMP
  where EMP.name="Joe" and E.name="Sam"

\\g
.ft
.)l
d538 1
d541 6
a546 9
Lastly, deletions are done using the delete command, as
follows:
.(l
.ft C
* delete EMP where EMP.salary > 0

\\g
.ft
.)l
d548 4
a551 1
leave the EMP class empty.
d554 3
a556 4
\*(PP fully supports both fixed-length and variable-length arrays, and here we
illustrate their use.  First, we create a class with an array type.
.(l
.ft C
d558 15
a572 10
     pay_by_quarter = int4[4])
\\g
.ft
.)l
The above query will create a class named SAL_EMP with a variable length
field
.b name
and a fixed-length field
.b pay_by_quarter,
which represents the employee's salary by quarter.  Now we do some appends;
d574 2
a575 3
within {curly brackets} and separate them by commas.
.(l
.ft C
d577 1
a577 3
     pay_by_quarter = "{10000, 10000, 10000,
     10000}")
\\g
d580 1
a580 3
     pay_by_quarter = "{10000, 15000, 15000,
     15000}")
\\g
d583 11
a593 10
     pay_by_quarter = "{20000, 25000, 25000,
     25000}")
\\g
.ft
.)l
\*(PP uses the FORTRAN numbering convention for arrays - that is, \*(PP
arrays start with array[1] and end with array[n].  Now, we can run some
queries on SAL_EMP:
.(l
.ft C
d595 34
a628 33
  where SAL_EMP.pay_by_quarter[1] !=
        SAL_EMP.pay_by_quarter[2]

\\g
.ft
.)l
This query retrieves the names of the employees whose pay changed in the
second quarter.
.(l
.ft C
* retrieve (SAL_EMP.pay_by_quarter[3])

\\g
.ft
.)l
This query retrieves the third quarter pay of all employees.
.(l
.ft C
* delete SAL_EMP
  where SAL_EMP.name[1] = 'j'

\\g
.ft
.)l
This query deletes everyone from SAL_EMP whose name begins with the letter
"j".  SAL_EMP should now contain only bill.
.lp
\*(PP supports arrays of base and user-defined types, as well as "arrays of
arrays", as in the following example:
.(l
.ft C
* create manager (name = char16,
     employees = text[]) \\g
d631 1
a631 2
     employees = "{"wei", "greg",
     "jeff"}") \\g
d634 1
a634 1
     employees = "{"bill", "joe"}") \\g
d637 6
a642 4
     employees = "{"mike", "alice"}") \\g
.ft
.)l
This creates a class "manager", and provides a list of employees.  Note that
d644 1
a644 1
.b text
d646 1
a646 2
.(l
.ft C
d648 1
a648 1
  where manager.employees[1][1] = 'b' \\g
d651 1
a651 1
  where manager.employees[3] = "jeff" \\g
d655 4
a658 5
* delete manager
  where manager.employees[2][1] = 'g' \\g
.ft
.)l
will all work.  However, in general \*(PP currently only supports arrays of
d660 1
d665 10
a674 3
distinguish it from other data managers, such as inheritance and time
travel.  In the next section we will cover how the user can extend
the query language via query language functions and composite objects, as well
d676 5
a680 1
user defined types, operators, and programming language functions.
d683 36
a718 28
Starting with the
.b EMP
class from the previous section, reappend the three
persons who were just deleted.
.lp
Now create a second class STUD_EMP, and populate it as follows:
.(l
.ft C
* create STUD_EMP (location=point)
     inherits (EMP)

\\g

* append STUD_EMP
    (name = "Sunita", age = 41,
     salary=1300, dept="electronics",
     location="(3,5)")

\\g
.ft
.)l
In this case, an instance of STUD_EMP inherits all data fields
from its parent, EMP, to wit: name, salary, age, and dept.
Furthermore, student employees have an extra field, location,
that shows their address as a (longitude, latitude) pair.  In
\*(PP a class can inherit from zero or more other classes, and
the inheritance hierarchy is generally a directed acyclic graph.
Additionally, in \*(PQ a query can either reference all
d720 2
a721 1
descendants.  For example, the following query finds the
d723 35
a757 25
.(l
.ft C
* retrieve (E.name) from E in EMP
  where E.age > 39

\\g
.ft
.)l
On the other hand, to find the names of all student
employees and employees over 40, the query is:
.(l
.ft C
* retrieve (E.name) from E in EMP*
  where E.age > 39

\\g
.ft
.)l
Here the * after EMP indicates that the query should be run over
EMP and all classes below EMP in the inheritance hierarchy.  This
use of * allows a user to easily run queries over a class and all
its descendent classes.
.lp
Notice that location in STUD_EMP is not a traditional
relational data type.  As we will see later, a \*(PP installation can be
d759 1
d762 10
a771 12
\*(PP supports the notion of time travel.  This
feature allows a user to run historical queries.  For example, to
find the salary of Sam at time T one would query:
.(l
.ft C
* retrieve (E.salary)
  from E in EMP["now"]
  where E.name="Sam"

\\g
.ft
.)l
d773 8
a780 5
valid at the correct time and get the appropriate salary.  One can also
give a time range.  For example to see all of the salaries that Sam has
ever earned one would query:
.(l
.ft C
d782 26
a807 17
  from E in EMP["Jan 1 00:00:00 1970 GMT",
     "now"]
  where E.name = "Sam"

\\g
.ft
.)l
A short hand notation for the above time range can be given as:
.(l
.ft C
* retrieve (E.salary)
  from E in EMP[,]
  where E.name = "Sam"

\\g
.ft
.)l
d810 1
a810 1
Here, we will discuss user extensions to the \*(PQ query language, via
d813 1
d816 6
a821 2
\*(PQ provides two types of functions: query language functions and
functions provided by the user via a programming language.
d828 6
a833 4
For example, the following function defines the high-paid
employees:
.(l
.ft C
d835 8
a842 9
     (language = "postquel", returntype = EMP)
  as retrieve (EMP.all) where EMP.salary>50000

\\g
.ft
.)l
\*(PQ functions can also have parameters, for example:
.(l
.ft C
d844 7
a850 7
     (language = "postquel", returntype = EMP)
  arg is (int4)
  as retrieve (EMP.all) where EMP.salary>$1

\\g
.ft
.)l
d853 1
d856 1
a856 1
Moreover, since \*(PQ functions return sets of instances,
d858 42
a899 52
types.  For example, consider extending the EMP class with a
manager field:
.(l
.ft C
* addattr (manager=EMP) to EMP

\\g
.ft
.)l
Here, we have added an attribute to the EMP class which is of
type EMP, i.e. it has a value which is zero or more instances of
the class EMP.  Specifically, the value of the manager field is
intended to be an instance of EMP which is the manager of the
indicated employee.  Since the value of manager has a record-
oriented structure, we call it a composite object.  We will now
illustrate assigning values to instances of manager.  First, we
will define the function mgr_lookup:
.(l
.ft C
* define function mgr_lookup
     (language = "postquel", returntype = EMP)
  arg is (char16) as
  retrieve (EMP.all)
  where EMP.name=DEPT.manager
     and DEPT.name=$1

\\g
.ft
.)l
This function can be used to assign values to the manager
attribute in the EMP class, for example:
.(l
.ft C
* append EMP
  (name="Sam",salary=1000.0 ,age=40,dept="shoe",
   manager=mgr_lookup("shoe"))

\\g
.ft
.)l
Since EMP.manager is a composite object, \*(PQ allows
referencing into it with a second use of the dot notation.
Whenever a composite object appears in a class, a user can
utilize the cascaded dot notation to reference into the object.
.lp
In this case, the same \*(PQ function is used to define
the value of manager for every EMP instance.  As a result, there
is a second more efficient way to utilize \*(PQ functions to
assign values to the manager attribute.  Specifically, we will
define a second \*(PQ function, lookup_mgr, as follows:
.(l
.ft C
d901 52
a952 18
     (language="postquel", returntype = EMP)
  arg is (EMP) as
  retrieve (E.all) from E in EMP
  where E.name=DEPT.manager and
     DEPT.name=EMP.dept

\\g
.ft
.)l
In this case, the function lookup_mgr has an argument which is an
instance of the class EMP.  Therefore, it takes a value for each
instance of EMP, which is the result of the query with the field
"EMP.dept" filled in with its appropriate constant.
.lp
Consequently, the user can think of the function lookup_mgr
as an attribute of EMP and can reference it just like any other
attribute (except for direct appends - that is,
append emp (emp.manager.name = "Smith") won't work).
d956 5
a960 11
.(l
.ft C
* retrieve (EMP.name)
  where EMP.manager.name="Joe"

\\g
.ft
.)l
The same query is also available in functional notation:
.(l
.ft C
d962 3
a964 5
  where lookup_mgr(EMP).name="Joe"

\\g
.ft
.)l
d968 3
a970 3
.b dynamically
.b load
a binary object file created by the user.  This allows \*(PP to call
d972 15
a986 3
language.  These functions can then be used to input and output
user types, used as operators for qualifying data, and can be used to
define ordering for use in defining indices on user-defined types.
d988 5
a992 1
\*(PP's concept of types includes built-in types and user-defined types.
d995 2
a996 1
below.  There is no intrinsic performance difference between using a system
d999 1
d1003 3
a1005 1
\*(PP regards a user-defined type as a "blob of memory" upon which
d1009 1
d1013 5
a1017 4
.lp
.b o
Input and output functions for the type.
.lp
d1020 11
a1030 7
in memory.  These at least are necessary to define the type.
.lp
.b o
Operator functions for the type.
.lp
These functions define the meanings of "equal," "less than,"
"greater than," etc for your type.
d1034 3
a1036 2
.b "circle"
type, using functions written in the "C" programming language.
d1040 4
a1043 3
like, both in string format and internally in memory.  Circles
have a center and a radius, so a reasonable way to define a
circle is:
a1044 1
.ft C
a1045 1
.ft
d1047 14
a1060 11
in whatever Cartesian units we desire.  Now we essentially have
defined what the input to our circle input function looks like,
and what the output from the circle output function should look
like.  Now we have to come up with an internal representation for
a circle in memory.  Note that as this memory will be written to
disk and read from disk, our internal representation must be both
.b COMPLETE
and
.b CONTIGUOUS,
that is, we can have no pointers within our structure.  The following
declaration for a circle is legal
d1062 4
a1065 7
.(l
.ft C
typedef struct
{
    double x,y;
}
POINT;
d1067 1
a1067 2
typedef struct
{
d1070 15
a1084 14
}
CIRCLE;
.ft
.)l
Now, just for the sake of argument, we will define what may seem at first
glance to be a correct type and explain why it
.b will
.b not
.b work.
Suppose we define our circle type thus:
.(l
.ft C
typedef struct
{
d1087 15
a1101 14
}
CIRCLE;
.ft
.)l
where POINT is as in the first example.  It will
.b not
work because
.b center
is a volatile pointer and will not have its value written to disk.
.b Beware
of such constructions when defining types, since they may appear to
work until you shut down the data manager, and because there is no way for
\*(PP to let you know that there is a problem until garbage is written to
disk and passed to your output function.
d1104 11
a1114 9
Suppose in defining our type "circle," we have a file called
"circle.c" and it is in /usr/postgres/tutorial/circle.c.  It has
been compiled, and the compiled object is in
/usr/postgres/tutorial/circle.o.  Note that as mentioned above,
all functions related to our "circle" type have to be in one
object (".o") file.  The source code for circle.c is at the end
of this section.
.lp
For the sake of argument, suppose we are on a DECstation,
d1117 29
a1145 19
In "circle.c," there are three functions:
.lp
.b circle_in,
which is the input function for circles.  It
takes a string as input and outputs a pointer to type CIRCLE.  It
must know how to parse the string itself.
.lp
.b circle_out,
which is the output function for circles.  It is
passed a pointer to type CIRCLE as input and returns a string.
This string must be suitable for input to circle_in.  That is,
the following piece of code should work:
.(l
.ft C
CIRCLE *circle, *circle_in();
char *circle_out();
.ft
.)l
.b eq_area_circle,
d1147 2
a1148 1
circles.  For the purposes of this discussion, circles are equal
d1151 7
a1157 119
Now that we have written these functions and compiled them,
we have to let \*(PP know that they exist.  We will do this
first by running the following queries to define the input and
output functions:
.(l
.ft C
* define function circle_in
     (language = "c", returntype=circle)
  arg is (char16)
  as "/usr/postgres/tutorial/circle.o"

\\g

*  define function circle_out
     (language = "c", returntype=char16)
   arg is (circle)
   as "/usr/postgres/tutorial/circle.o"

\\g
.ft
.)l
Now that we have done this, we can define the type.  Note
that in and out functions have to be defined BEFORE we define the
type.  Defining the type first will not work.  \*(PP will
notify you that return type circle is not defined yet, but
everything is OK.  The query to define the "circle" type is:
.(l
.ft C
* define type circle
     (internallength=24, input=circle_in,
     output=circle_out)

\\g
.ft
.)l
where
.b internallength
is the size of the circle structure itself
in bytes.  For circles, the arguments are three doubles, thus
.(l
.ft C
sizeof(circle) =
     3 * sizeof(double) = 3 * 8 = 24
.ft
.)l
When defining your own types, you should write a test program
that does a
.(l
.ft C
printf("size is %d\n", sizeof (mystruct));
.ft
.)l
on your type.  If
.b internallength
is defined incorrectly, you will encounter strange errors which may crash
the data manager itself.  If this were to happen with our CIRCLE type,
we would have to do a
.(l
.ft C
* remove type circle

\\g
.ft
.)l
and redefine the circle type.  Note that we would
.b not
have to redefine our functions - \*(PP already knows about them.
.sh 3 "Defining an operator for our type"
.lp
Now that we have finished defining the "circle" type, we can
create classes with circles in them, append records to them
with circles defined, and retrieve the values of the entire list
of records.  But we can do nothing else until we have some circle
operators.  To do this, we make use of the concept of
.b operator
.b overloading,
and in this case we will set the \*(PP equality
operator "=" to work for circles.  First we have to tell \*(PP
that our circle equality function exists with the following
query:
.(l
.ft C
* define function eq_area_circle
     (language = "c", returntype=bool)
  arg is (circle,circle)
  as "/usr/postgres/tutorial/circle.o"

\\g
.ft
.)l
Now that we have done this, we will now bind this function to the
equality symbol with the following query:
.(l
.ft C
* define operator =
     (arg1=circle, arg2=circle,
     procedure=eq_area_circle)

\\g
.ft
.)l
.sh 3 "Using our type"
.lp
Now we are ready to create a class and run some queries on our new type:
.(l
.ft C
* create tutorial(a=circle)
\\g

* append tutorial
     (a="(1.0,1.0,10.0)" ::circle)
\\g
* append tutorial
     (a="(2.0,2.0,5.0)" ::circle)
\\g
* append tutorial
     (a="(0.0,1.8,10.0)" ::circle)
\\g

d1159 3
a1161 33
* retrieve (tutorial.all)
  where tutorial.a =
     "(0.0,0.0,10.0)"::circle
.ft
.)l
And the monitor will display the result of the retrieve command...
.(l
.ft C
.TS
tab (+) allbox;
l
l.
a
(1.0,1.0,10.0)
(0.0,1.8,10.0)
.TE
.ft
.)l
Recall that we defined circles as being equal if their areas were
equal.
.lp
Other operators (less than, greater than, etc) can be defined in
a similar way.  Note that the "=" symbol will still work for
other types--it has merely had a new type added to the list of
types it works on.  Any string of "punctuation characters" other than brackets,
braces, or parentheses can be used in defining an operator.
.sh 3 "C Source code for our type"
.lp
The following is the source code for circle.c.
.(l
.ft C
#include <stdio.h>
#include "utils/geo-decls.h"
d1164 2
a1165 2
    POINT    center;
    double    radius;
d1168 3
a1170 7
CIRCLE    *circle_in();
char    *circle_out();
int    pt_in_circle();

#define LDELIM    '('
#define RDELIM    ')'
#define NARGS    3
d1174 1
a1174 2
char    *str;

d1176 3
a1178 5
    double  atof(), tmp;
    char    *strcpy(), *p,
            *coord[NARGS], buf2[1000];
    int     i, fd;
    CIRCLE  *result;
d1203 1
a1203 2
CIRCLE    *circle;

d1205 1
a1205 1
    char    *result;
d1211 2
a1212 4
    sprintf(result,
            "(%g,%g,%g)",
            circle->center.x,
            circle->center.y,
d1214 1
d1219 2
a1220 3
pt_in_circle(point, circle)
    POINT    *point;
    CIRCLE    *circle;
d1222 155
a1376 1
    extern double    point_dt();
d1378 33
a1410 7
    return
      ( point_dt(point,
                 &circle->center) <
        circle->radius );
}
.ft
.)l
d1412 1
d1415 15
a1429 8
In order for \*(PP to free memory associated with processing your type, you
must use the memory allocator "palloc" and avoid standard \*(UU memory managers
such as malloc.  If you do not, \*(PP will chew up ever increasing amounts of
memory.  "palloc" has the same arguments as malloc, that is
.(l
.ft C
char
*palloc(size)
d1431 10
a1440 8
.ft
.)l
To free memory allocated with palloc, use "pfree", which is used in identical
manner as the \*(UU "free" library call:
.(l
.ft C
void
pfree(ptr)
d1442 2
a1443 2
.ft
.)l
d1447 2
a1448 1
re-load a function in the course of debugging.  This is
d1455 4
a1458 7
.(l
.ft C
* load "/usr/postgres/tutorial/circle.o"

\\g
.ft
.)l
d1466 1
a1466 1
.b inheritable;
d1471 5
a1475 2
\*(PP defines the "current instance" to be the instance being qualified at
the moment your function is called.  Rather than getting the instance itself
d1480 7
a1486 8
.(l
.ft C
* retrieve (emp.all) where overpaid(emp)
.ft
.)l
In the query above, a reasonable "overpaid" function would be:
.(l
.ft C
d1488 1
a1488 2
overpaid() /* note that there are no
     arguments */
d1491 1
a1491 7
    short age, salary, performance;

    salary=(short) GetAttribute("salary");
    seniority=(short)
     GetAttribute("seniority");
    performance=(short)
     GetAttribute("performance");
d1493 3
a1495 2
    return (salary >
     (seniority * performance));
d1497 1
d1499 2
a1500 3
.ft
.)l
.b GetAttribute
d1502 2
a1503 1
attributes out of the current instance.  It has one argument
d1506 8
a1513 3
pointer values and all other types--currently it is defined as a
"long."
.b GetAttribute
d1515 8
a1522 3
its return value into the desired form.  So if you have an
attribute "name" which is of the \*(PQ type "char16," the
.b GetAttribute
d1524 3
a1526 4
.(l
.ft C
char *str

d1528 1
a1528 2
.ft
.)l
d1532 5
a1536 4
To let \*(PP know about the "overpaid" function,
just do the following:
.(l
.ft C
d1538 7
a1544 8
     (language = "c", returntype=bool)
  arg is (SET)
  as "/usr/postgres/tutorial/overpaid.o"

\\g
.ft
.)l
The special flag "set" in the argument list tells
d1548 1
a1548 1
.b GetAttribute
d1551 7
a1557 9
.(l
.ft C
* retrieve (emp.all)
  where overpaid2(emp, "bill", 8)
.ft
.)l
could be written, and overpaid2 would be declared thus
.(l
.ft C
a1559 1

d1562 6
a1567 3
.ft
.)l
Note that the arguments are "shifted" one to the left, and the "emp" argument
d1569 2
a1570 1
.b GetAttribute.
d1573 4
a1576 2
As discussed above, \*(PP fully supports arrays of base types.  Additionally,
\*(PP supports arrays of user-defined types as well.  When you define a type,
d1580 1
d1584 7
a1590 10
.b circle
example discussed above, we will create a class containing an array of
circles thus:
.(l
.ft C
* create circles (list = circle[])

\\g
.ft
.)l
d1592 26
a1617 25
.(l
.ft C
* append circles
     (list = "{"(1.0, 1.0, 5.0)",
     "(2.0, 2.0, 10.0)"}")

\\g

* append circles
     (list = "{"(2.0, 3.0, 15.0)",
     "(2.0, 2.0, 10.0)"}")
\\g

* append circles
     (list = "{"(2.0, 3.0, 4.0)"}")

\\g
.ft
.)l
We can now run queries like the following:
.(l
.ft C
* retrieve (circles.list[1])

\\g
d1619 15
a1633 7
  where circles.list[1] = "(0.0, 0.0, 4.0)"

\\g
.ft
.)l
.b NOTE:
Recall how we defined circle equality above.
d1637 3
a1639 2
be defined as a type in and of itself.  This is useful for defining "arrays
of arrays".
d1641 2
a1642 2
The special functions
.b array_in
d1644 3
a1646 2
.b array_out
are used by \*(PP to input and output arrays of any existing type.  Here,
d1648 1
a1648 2
.(l
.ft C
d1650 3
a1652 7
     (input = array_in, output = array_out,
     internallength = variable,
     element = int4)

\\g
.ft
.)l
d1654 1
a1654 1
.b element
d1656 1
a1656 1
.b internallength
d1658 4
a1661 3
.b variable
indicates that it is a variable length attribute.
.b NOTE
d1663 1
a1663 1
.b array_in
d1665 4
a1668 3
.b array_out
.i must
be variable length.
d1670 2
a1671 3
Now we can use our type defined above to create an array of integer arrays:
.(l
.ft C
d1673 3
a1675 9
     (input = array_in,
     output = array_out,
     internallength = variable,
     element = int_array) \\g
.ft
.)l
Now we use our new type:
.(l
.ft C
d1678 1
a1678 3
* append stuff
     (a = "{{1, 2, 3} , {4, 5},
     {6, 7, 8}}") \\g
d1682 1
a1682 2
* append stuff (a = "{{5, 4, 3} ,
     {2, 2}}") \\g
d1685 1
a1685 1
  where stuff.a[1][1] < stuff.a[1][2] \\g
d1688 1
a1688 1
  where stuff.a[3][1] < stuff.a[1][2] \\g
d1690 7
a1696 8
* retrieve (s.all)
  from s in stuff
  where s.a[2][2] = stuff.a[1][1] \\g
.ft
.)l
We can also define operators for equality, less than, greater than, etc.
which operate on our new array type as necessary.
.sh 3 "Creating an array type ``from scratch''"
d1700 27
a1726 17
fixed-length array.  In this section, we will discuss how to go about
doing this.
.lp
For the purpose of this section, we will create an array of four longs called
.b quarterly,
and a variable length array of longs called
.b stats.
Also, assume we are on a machine where sizeof(long) is 4.
.lp
The only special things we need to know when writing the in/out functions for
.b quarterly
is that \*(PP will pass a "simple" array of longs to the
output function and expect a "simple" array of longs in return from the input
function.  A sample "simple" array suitable for quarterly can be declared as
follows:
.(l
.ft C
d1728 5
a1732 4
.ft
.)l
For the variable length array "stats", the situation is a little more
complicated.  Because \*(PP will not know in advance how big the array is,
d1734 16
a1749 5
first four bytes of the memory which contains the array.  The expected
structure is as follows:
.(l
.ft C
typedef struct
d1751 8
a1758 11
    long length;
          /* Force contiguity */
    unsigned char bytes[1];
}
VAR_LEN_ATTR;
.ft
.)l
The in function for the stats array will look something like this:
.(l
.ft C
VAR_LEN_ATTR *stats_in(s)
d1760 1
a1760 1
char s;
d1762 1
a1762 3
{
  VAR_LEN_ATTR *stats;
  long array_size, *arrayp;
d1764 1
a1764 2
  ... figure out how long the stats
     array should be
d1766 4
a1769 24
  /*
   * We need the extra sizeof(long)
   * to hold the length
   */

  stats = (VAR_LEN_ATTR *)
    palloc(array_size * sizeof(long) +
     sizeof(long));

  /* length is length of the entire structure
   * in bytes, INCLUDING ItSELF
   */

  stats->length =
    array_size * sizeof(long) +
    sizeof(long);

  arrayp = &(stats->bytes[0]);

  for (i = 0; i < length; i++, arrayp++)
  {
     populate the stats array with
     numbers from s
  }
d1771 1
a1771 1
  return(stats);
d1773 22
a1794 21
.ft
.)l
The output function for stats will get the same VAR_LEN_ATTR structure.
.lp
Now, using the
.b define
.b function
command, and assuming the functions are in
/usr/postgres/tutorial/stats.c and /usr/postgres/tutorial/quarterly.c, we
can define our two arrays.  First we will define the fixed-size array
"quarterly".  Note that internallength is known to be 16, because
.(l
.ft C
sizeof(long) * 4 = 4 * 4 = 16
.ft
.)l
on our hypothetical machine.
.lp
First we define the in/out functions:
.(l
.ft C
d1796 3
a1798 5
     (language="c", returntype=quarterly)
  arg is (char16)
  as "/usr/postgres/tutorial/quarterly.o"

\\g
d1801 3
a1803 3
     (language = "c", returntype = char16)
  arg is (quarterly)
  as "/usr/postgres/tutorial/quarterly.o"
a1804 6
\\g
.ft
.)l
And now we can define the type:
.(l
.ft C
d1806 7
a1812 11
     (internallength = 16,
     input = quarterly_in,
     output = quarterly_out,
     element = int4)

\\g
.ft
.)l
Now we define the stats array.  First we define its in/out functions:
.(l
.ft C
d1814 3
a1816 5
     (language = "c", returntype = stats)
  arg is (char16)
  as "/usr/postgres/tutorial/stats.o"

\\g
d1819 3
a1821 3
     (language = "c", returntype = char16)
  arg is (stats)
  as "/usr/postgres/tutorial/stats.o"
a1822 7
\\g
.ft
.)l
and now we define the type.  Note that setting internallength to variable tells
\*(PP that it is a variable length type.
.(l
.ft C
d1824 6
a1829 4
    (internallength = variable,
     input = stats_in,
     output = stats_out,
     element = int4)
d1831 2
a1832 7
\\g
.ft
.)l
Now we can run some queries:
.(l
.ft C
* create test (a = quarterly, b = stats) \eg
d1834 2
a1835 11
* append test
    (a = "1 2 3 4"::quarterly,
     b = "5 6 7"::stats) \eg

* append test
    (a = "1 3 2 4"::quarterly,
     b = "6 4"::stats) \eg

* append test
    (a = "7 11 6 9"::quarterly,
     b = "1 2"::stats) \eg
d1837 7
a1843 3
* retrieve (test.all)
  where test.a[4] = test.b[2] \eg
.ft C
d1845 1
a1845 2
tab (+) allbox;
l l
d1847 2
a1848 2
a+b
1324+64
d1850 1
a1850 2
.ft
.)l
d1853 4
a1856 3
.i your
.i function
will define how to parse the string.  The brackets notation is only a
d1858 1
a1858 1
.b array_in
d1860 1
a1860 1
.b array_out
d1862 3
a1864 2
.i not
a part of the formal \*(PQ definition.
d1867 9
a1875 2
The types discussed to this point are all "small" objects - that is, they are
smaller than 8K in size.  If you require a larger type for something like
d1877 9
a1885 9
the \*(PP Large Object interface.  The basic model of this interface is the
\*(UU file system interface; the particulars of this interface are detailed in
Section 7 of the \*(PP Reference.
.sh 3 "What can you do with large objects?"
.lp
The answer to this question is anything that can be done with small objects,
as long as all functions which access a large object use the \*(PP large object
interface.  All discussion after this point will presume that you have read
this section of the \*(PP Reference.
d1889 3
a1891 2
functions.  For the purposes of this discussion, we assume that two functions,
.b large_in
d1893 13
a1905 7
.b large_out
have been written using the large object interface, and that these functions
are in /usr/postgres/tutorial/large.c.  We also presume that we are using
the "file as an ADT" interface for large objects discussed in the Reference.
Now, we define a large object which could be used for storing map data:
.(l
.ft C
d1907 3
a1909 3
     (language = "c", returntype = map)
  arg is (char16)
  as "/usr/postgres/tutorial/large.o"
a1910 2
\\g

d1912 3
a1914 5
     (language = "c", returntype = char16)
  arg is (map)
  as "/usr/postgres/tutorial/large.o"

\\g
d1917 5
a1921 8
     (input = large_in, output = large_out,
     internallength = variable)

\\g
.ft
.)l
.b NOTE:
Large objects are
d1923 6
a1928 4
variable length.
Now we can use our large object:
.(l
.ft C
d1931 2
a1932 9
* append maps
     (name = "earth",
     a = "/usr/postgres/maps/earth")

\\g

* append maps
     (name = "moon",
     a = "/usr/postgres/maps/moon")
d1934 5
a1938 4
\\g
.ft
.)l
Notice that the above queries are identical to the syntax we have been using
d1941 1
d1945 2
a1946 1
object types.  The only caveat is that, like any other functions which process
d1949 2
a1950 1
use the large object interface described in Section 7 of the \*(PP Reference.
d1952 2
a1953 4
.(l
.ft C
* retrieve (emp.name)
  where beard(emp.picture) = "red" \\g
d1956 2
a1957 5
  where height(mountain.topomap) > 10000

\\g
.ft
.)l
d1962 2
a1963 1
methods, presuming appropriate operator classes have been defined.  Operator
d1965 221
a2185 1
.sh 2 "User defined types and indices"
d2188 4
a2191 2
type and associated functions with existing access methods.  This way, you
can define a BTREE or RTREE index on your own type.  To do this, we will
d2205 2
a2206 1
access methods work.  These will be discussed, and then a sample procedure
d2210 3
a2212 1
The pg_am class contains one instance for every user defined access method.
d2216 30
a2245 25
.(l
.ft C
amname:  name of the access method

amowner: object id of the owner's instance
         in pg_user

amkind:  not used at present, but set to 'o'
         as a place holder

amstrategies:  number of strategies for this
               access method (see below)

amsupport:  number of support routines for
            this access method (see below)

am*:  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.
.ft
.)l
The object ID of the instance in pg_am is used as a foreign key in lots of
other classes.  For BTREES, this object ID is 403.  You don't need to add
d2247 3
a2249 8
the access method instance you want to extend.
.(l
.ft C
* retrieve (pg_am.oid)
  where pg_am.amname = "btree"

\eg

d2251 1
a2251 2
tab (+) allbox;
l
d2256 1
a2256 2
.ft
.)l
d2258 1
a2258 1
.b amstrategies
d2260 11
a2270 5
types.  For example, BTREES impose a strict ordering on keys, less to
greater.  Since \*(PP allows the user to define operators, \*(PP cannot
in general look at the name of an operator (eg, ">", "<") and tell what kind
of comparison it is.  In fact, some access methods (like rtrees) don't impose
a less to greater ordering, but some other ordering, like containment.
d2273 9
a2281 3
qualification in order to improve access speeds.  This implies
that \*(PP needs to know, for example, that "<=" and ">" partition
a BTREE.  Strategies is the way that we do this.
d2285 5
a2289 2
to add a new operator class.  In the pg_am class, the
.b amstrategies
d2292 2
a2293 3
number is 5.  These strategies correspond to
.(l
.ft C
d2295 11
a2305 8
tab (+);
l l
l l.
less than+1
less than or equal+2
equal+3
greater than or equal+4
greater than+5
a2306 2
.ft
.)l
d2308 4
a2311 1
above to the pg_amop relation (see below).  The access method code can use
d2313 7
a2319 3
BTREE, compute selectivity, and so on.  Don't worry about the details of adding
procedures yet; just understand that there's a set of these for int2's, int4's,
oid's, and every other data type on which a BTREE can operate.
d2337 1
a2337 1
.b pg_am
d2339 1
a2339 1
.b amsupport .
d2342 5
a2346 2
For BTREES, this number is one \*-
the routine to take two keys and return \(mi\^1, 0, or \(pl\^1,
d2352 4
a2355 2
.b amstrategies
entry in pg_am is just the number of strategies defined
d2357 2
a2358 1
The procedures for less than, less equal, and so on don't appear in pg_am.
d2360 1
a2360 1
.b amsupport
d2365 6
a2370 3
.b pg_opclass.
This class exists only to associate a name with an oid.
In pg_amop, every BTREE operator class has a set of procedures,
d2372 4
a2375 1
Some existing opclasses are int2_ops, int4_ops, and oid_ops.
d2377 8
a2384 6
"int4_abs_ops") to pg_opclass.
The oid of this instance is a foreign key in other classes.
.(l
.ft C
* append pg_opclass (opcname = "int4_abs_ops")
\eg
d2386 2
a2387 5
* retrieve (cl.oid, cl.opcname)
  from cl in pg_opclass
  where cl.opcname = "int4_abs_ops"
\eg

d2389 1
a2389 2
tab (+) allbox;
l l
d2391 2
a2392 2
oid+opcname
17314+int4_abs_ops
d2394 1
a2394 2
.ft
.)l
d2396 9
a2404 2
The oid for your pg_opclass instance MAY BE DIFFERENT!  You should
substitute your value for 17314 wherever it appears in this discussion.
d2409 3
a2411 1
For the "int4_abs_ops" operator class on BTREES,
d2414 5
a2418 7
.ft C
    absolute value less-than
    absolute value less-than-or-equal
    absolute value equal
    absolute value greater-than-or-equal
    absolute value greater-than
.ft
d2421 1
a2421 5
.(l
.ft C
/usr/postgres/tutorial/int4_abs.c
.ft
.)l
d2423 1
a2423 2
.(l
.ft C
d2425 2
a2426 3
 * int4_abs.c --
 *   absolute value comparison functions
 *   for int4 data
d2428 1
d2447 1
a2447 2
.ft
.)l
d2450 3
a2452 1
and greater for int4 are being defined.
d2454 9
a2462 1
for int4 under the names "<", "<=", "=", ">=", and ">".
d2471 6
a2476 1
That is, if you have "<" defined for (int4, int4), you can't define it again.
d2486 3
a2488 1
The other important point is that all the functions return BOOLEAN values;
d2490 1
a2490 2
.(l
.ft C
d2492 3
a2494 3
     (language = "c", returntype = bool)
  arg is (int4, int4)
  as "/usr/postgres/tutorial/int4_abs.o" \eg
d2497 3
a2499 3
     (language = "c", returntype = bool)
  arg is (int4, int4)
  as "/usr/postgres/tutorial/int4_abs.o" \eg
d2502 3
a2504 3
     (language = "c", returntype = bool)
  arg is (int4, int4)
  as "/usr/postgres/tutorial/int4_abs.o" \eg
d2507 3
a2509 3
     (language = "c", returntype = bool)
  arg is (int4, int4)
  as "/usr/postgres/tutorial/int4_abs.o" \eg
d2512 4
a2515 5
     (language = "c", returntype = bool)
  arg is (int4, int4)
  as "/usr/postgres/tutorial/int4_abs.o" \eg
.ft
.)l
d2518 8
a2525 7
the operator names must be unique for two int4 operands.
You can do a query on pg_operator
.(l
.ft C
* retrieve (pg_operator.all) \eg
.ft
.)l
d2528 1
a2528 1
(which is the C function defined above)
d2530 2
a2531 2
You should just use the ones used below --
note that there are different such functions for the less,
d2533 1
a2533 1
and greater cases.
d2538 4
a2541 1
You should copy the names for restrict and join,
d2543 1
a2543 2
.(l
.ft C
d2545 3
a2547 4
     (arg1 = int4, arg2 = int4,
     procedure=int4_abs_lt,
     associativity = left, restrict = intltsel,
     join = intltjoinsel)
a2548 2
\\g

d2550 3
a2552 6
     (arg1 = int4, arg2 = int4,
     procedure=int4_abs_le,
     associativity = left, restrict = intltsel,
     join = intltjoinsel)

\\g
d2555 3
a2557 4
     (arg1 = int4, arg2 = int4,
     procedure=int4_abs_eq,
     associativity = left, restrict = eqsel,
     join = eqjoinsel)
a2558 2
\\g

d2560 3
a2562 6
     (arg1 = int4, arg2 = int4,
     procedure=int4_abs_ge,
     associativity = left, restrict = intgtsel,
     join = intgtjoinsel)

\\g
d2565 4
a2568 8
     (arg1 = int4, arg2 = int4,
     procedure=int4_abs_gt,
     associativity = left, restrict = intgtsel,
     join = intgtjoinsel)

\\g
.ft
.)l
d2570 7
a2576 2
and greater equal are defined.  We're just about finished. the last thing we
need to do is to update the pg_amop relation.  To do this, we need the
d2578 32
a2609 14
.(l
.ft C
amopid: the oid of the pg_am instance for
        BTREE (== 400, see above);

amopclaid: the oid of the pg_opclass
           instance for int4_abs_ops
           (== whatever you got instead
           of 17314, see above);

amopopr:   the oids of the operators for the
           opclass (which we'll get in just a
           minute); and

d2611 4
a2614 3
amopnpages:  cost functions.
.ft
.)l
d2616 5
a2620 3
or not to use a given index in a scan.  Fortunately, these already
exist.  The two functions we'll use are
.b btreesel,
d2623 1
a2623 1
.b btreenpage,
d2627 8
a2634 5
So we need the oids of the operators we just defined.  We'll look up the
names of all the operators that take two int4's, and pick ours out.  (Note
that your numbers may be different.)
.(l
.ft C
d2636 6
a2641 5
  from o in pg_operator, t in pg_type
  where o.oprleft = t.oid and o.oprright = t.oid
       and t.typname = "int4"

\\g
d2643 1
a2643 2
tab (#) allbox;
l l
d2645 17
a2661 17
oid+oprname
96#\\=
97#<
514#*
518#!=
521#>
523#<=
525#>=
528#/
530#%
551#+
555#-
17321#<<&
17322#<=&
17323#==*
17324#>=&
17325#>>&
d2663 8
a2670 3
.ft
.)l
The operators we are interested in are those with oids 17321 through 17325.
d2672 1
a2672 1
them for the values I use below.
d2677 4
a2680 1
Now we're ready to update pg_amop with our new operator class.  The most
d2682 12
a2693 2
ordered, from less equal through greater equal, in pg_amop.  Recall that
the BTREE instance's oid is 400 and int4_abs_ops is oid 17314.  Then we
d2695 1
a2695 2
.(l
.ft C
d2697 47
a2743 53
     (amopid = "400"::oid,      /* btree oid */
     amopclaid = "17314"::oid, /*
	pg_opclass tup */
     amopopr = "17321"::oid,   /* <<& tup oid */
     amopstrategy = "1"::int2, /* 1 is <<& */
     amopselect = "btreesel"::regproc,
     amopnpages = "btreenpage"::regproc)

\\g

* append pg_amop
    (amopid = "400"::oid,
     amopclaid = "17314"::oid,
     amopopr = "17322"::oid,
     amopstrategy = "2"::int2,
     amopselect = "btreesel"::regproc,
     amopnpages = "btreenpage"::regproc)

\\g

* append pg_amop
    (amopid = "400"::oid,
     amopclaid = "17314"::oid,
     amopopr = "17323"::oid,
     amopstrategy = "3"::int2,
     amopselect = "btreesel"::regproc,
     amopnpages = "btreenpage"::regproc)

\\g

* append pg_amop
    (amopid = "400"::oid,
     amopclaid = "17314"::oid,
     amopopr = "17324"::oid,
     amopstrategy = "4"::int2,
     amopselect = "btreesel"::regproc,
     amopnpages = "btreenpage"::regproc)

\\g

* append pg_amop
    (amopid = "400"::oid,
     amopclaid = "17314"::oid,
     amopopr = "17325"::oid,
     amopstrategy = "5"::int2,
     amopselect = "btreesel"::regproc,
     amopnpages = "btreenpage"::regproc)

\\g
.ft
.)l
NOTE the order:  "less" is 1, "less equal" is 2, "equal" is 3, "greater
equal" is 4, and "greater" is 5.
d2745 2
a2746 1
Okay, now it's time to test the new opclass.  First we'll create and
d2748 2
a2749 4
.(l
.ft C
* create pairs (name = char16, number = int4)
\\g
d2751 1
a2751 2
* append pairs (name = "mike", number = -10000)
\\g
d2753 1
a2753 2
* append pairs (name = "greg", number = 3000)
\\g
d2755 1
a2755 2
* append pairs (name = "lay peng", number = 5000)
\\g
d2757 1
a2757 2
* append pairs (name = "jeff", number = -2000)
\\g
d2759 1
a2759 2
* append pairs (name = "mao", number = 7000)
\\g
d2761 1
a2761 3
* append pairs (name = "cimarron",
     number = -3000)
\\g
d2763 1
a2763 3
* retrieve (pairs.all)
\\g

d2765 1
a2765 2
tab (+) allbox;
l l
d2767 7
a2773 7
name+number
mike+-10000
greg+3000
lay peng+5000
jeff+-2000
mao+7000
cimarron+-3000
d2775 4
a2778 5
.ft
.)l
okay, looks pretty random.  Define an index using the new opclass:
.(l
.ft C
d2780 10
a2789 7
      using btree (number int4_abs_ops)
\\g
.ft
.)l
Now run a query that doesn't use one of our new operators.  What we're
trying to do here is to run a query that *won't* use our index, so that
we can tell the difference when we see a query that *does* use the index.
d2792 2
a2793 5
.(l
.ft C
* retrieve (pairs.all)
  where pairs.number < 9000
\\g
d2795 1
a2795 2
tab (+) allbox;
l l
d2797 7
a2803 7
name+number
mike+-10000
greg+3000
lay peng+5000
jeff+-2000
mao+7000
cimarron+-3000
d2805 3
a2807 3
.ft
.)l
Yup, just as random; that didn't use the index.  Okay, let's run a query
d2811 2
a2812 4
.(l
.ft C
* retrieve (pairs.all) where pairs.number <<& 9000
\\g
d2814 1
a2814 2
tab (+) allbox;
l l
d2816 6
a2821 6
name+number
jeff+-2000
cimarron+-3000
greg+3000
lay peng+5000
mao+7000
d2823 4
a2826 3
.ft
.)l
Note that the "number" values are in order of increasing absolute value
d2828 3
a2830 113
we got the right answer -- the instance for "mike" doesn't appear, because
-10000 >=& 9000
.sh 1 "The \*(PP Rule System"
.lp
The discussion in this section is intended to provide an overview of the
\*(PP rule system and point the user at helpful references and examples.
\*(PP actually has two rule systems, the Instance-level Rule System and the
Query Rewrite Rule System.
.sh 2 "The Instance-level Rule System"
.lp
The Instance-level Rule System uses markers placed in each instance in a
class to "trigger" rules.  Examples of the Instance-level Rule System are
explained and illustrated in ~postgres/demo, which is included with the
\*(PP distribution.  Additional discussion of the Instance-level Rule System
can be found in the Reference in "define rule".  The theoretical foundations
of the \*(PP rule system can be found in [STON90].
.sh 2 "The Query Rewrite Rule System"
.lp
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.  Examples and discussion can
be found in the demo in ~postgres/video, and further discussion is in the
Reference under "define rule".  The power of this rule system is discussed in
[ONG90] and [STON90].
.sh 2 "When to use either?"
.lp
Since each rule system is architected quite differently, they work best in
different situations.  The Query Rewrite system is best when rules affect
most of the instances in a class, while the Instance-level system is best when
a rule affects only a few instances.
.sh 1 "Administering \*(PP"
.lp
In this section, we will discuss aspects of \*(PP of interest to those
making extensive use of \*(PP, or who are the database administrator for
a group of \*(PP users.
.sh 2 "User administration"
.lp
The
.b createuser
and
.b destroyuser
commands create and destroy \*(PP users.  Please read the "man pages" on these
commands in the Reference for specifics on their use.
.sh 2 "Moving database directories out of ~postgres/data/base"
.lp
If you do not want all users to have databases in ~postgres/data/base/<db>, you
can put their data directories in arbitrary places by using the following
mechanism:
.lp
.b o
Create a database using the
.b createdb
command.
.lp
.b o
Move the directory ~postgres/data/base/<newdb>
to its ultimate destination.  It should still be owned by the "postgres" user.
.lp
.b o
Make a symbolic link from ~postgres/data/base to the new directory.
.sh 2 "Troubleshooting \*(PP"
.lp
Occasionally, \*(PP will fail with cryptic error messages that are due to
relatively simple problems.  The following are a list of \*(PP error
messages and the likely fix.  These messages are ones you would likely see
in the monitor program.
.(l
.ft C
Message: semget: No space left on device

Explanation and Likely Fix:
.ft
.)l
Either the kernel has not been configured for System V shared memory, or some
other program is using it up.  On most machines, the \*(UU command "ipcs" will
show shared memory and semaphore usage.  To delete all shared memory and
semaphores (may be necessary if a backend fails), run the "ipcclean" command.
.lp
Note, however, that the "ipcclean" command deletes all semaphores belonging
to the user running it, so the user should be certain that no non-\*(PP
processes are using semaphores before running this command.
.(l
.ft C
Message: Unable to get shared buffers

Explanation and Likely Fix:
.ft
.)l
This message means that a \*(PP backend was expecting shared memory to be
available and it was not.  Usually this is due to "ipcclean" being run while a
"postmaster" was also running.
.b NOTE:
"ipcclean" will delete ALL semaphores
and shared memory
.i whether
.i they
.i are
.i being
.i used
.i or
.i not.
.(l
.ft C
Message: Can't connect to the backend (...)

Explanation and Likely Fix:
.ft
.)l
This message means that you are running a \*(LP application but it could
not link up with a postmaster.  If you see this error message, you should
see if a postmaster is truly running.  If one is running, the problem is
likely related to your network.
@


1.9
log
@no message
@
text
@d1 1
d3 1
a3 1
.\" $Header: /home/postgres/mer/docs/RCS/manual.me,v 1.8 1992/06/16 01:04:31 mer Exp mer $
a4 67
.\" Start of generic definitions section.
.\"
.\" Defines .SB, .SE, .SP, .SS, .XA, .XP.
.\" Uses constant IW (TOC indent width).
.\" Uses temporary TI (TOC total indent).
.\"
.\" Usage:
.\"
.\" .SB
.\"    begin section formatting (Section formatting is *on* by default.)
.\"
.\" .SE
.\"    end section formatting
.\"
.\" .SP title section data
.\"    start page with given title in given section last modified on date
.\"
.\" .SS section data
.\"    start section with data of last modification
.\"
.\" .XA indent title [page number("_" for no number/dots)]
.\"    add title to TOC with specified indent
.\"
.\" .XP
.\"    print TOC
.\"
.\" Example:
.\"
.\" .SP CREATEDB UNIX 5/4/88
.\"
.\" .XA 0 Introduction
.\" .XA 1 "Section 1" _
.\" .XA 2 "Page 1.1"
.\" .XP
.\"
.de SB
.nr si .5i    \" 1/2 inch relative base indent per section depth
.nr so -.5i    \" -1/2 inch additional section title offset
.nr $0 1    \" section depth of 1
.nr $i \\n(si*\\n($0    \" paragraph base indent
..
.de SE
.nr si 0
.nr so 0
.nr $0 0
.nr $i \\n(si*\\n($0
.in \\n($i+\\n(po
..
.de SP
.he '\fB\\$1 (\\$2)'\\$3'\\$1 (\\$2)\fR'
.bp
..
.de SS
.he '\fB\\$1'\\$2'\\$1\fR'
.bp
..
.de XA
.nr TI \\n(IW*\\$1
.(x t
.ti +\\n(TIu
\\$2
.)x \\$3
..
.de XP
.xp t
..
.\"
d7 2
a8 6
.\" Defines .A.
.\"
.\" Usage:
.\"
.\" .A acronym concatenation
.\"    display acronym in standard acronym format with concatenation
a9 8
.\" Defines II, PP, UU, LL, PQ, LQ, OF, AM, PV +- for
.\"    INGRES, POSTGRES, UNIX, LISP, \*(PQ, LIBPQ, PICASSO, "AM Guide," 4.0 +-.
.\"
.if t \
\{\
.de A
\\s-1\\$1\\s0\\$2
..
a12 1
.    ds LL \s-1LISP\s0
d16 1
a16 19
.\}
.if n \
\{\
.de A
\\$1\\$2
..
.    ds II INGRES
.    ds PP POSTGRES
.    ds UU UNIX
.    ds LL LISP
.    ds PQ \*(PQ
.    ds LP LIBPQ
.    ds PV "4.0
.\}
.\"
.    ds OF Picasso
.    ds AM \*(PP Access Method Implementors' Guide
.if !\n(.V .ds +- +-
.if \n(.V .ds +- \(+-
a19 3
.nr IW 3n    \" 3en table of contents indentation
.\"
.\" .nr tp 10    \" standard title point size
a20 2
.\" .nr fp 8    \" standard footnote pointsize
.\" .nr pi 5n    \" standard paragraph indent
d26 2
a27 1
.SB
d33 1
a33 1

d37 1
a37 1
Edited by Jon Rhein, Greg Kemnitz and The Postgres Group
d40 1
a40 1
.sp
d52 1
a53 3

.sh 2 "DISTRIBUTION"

a57 1

d59 1
a59 1

d63 1
a63 2
Ingres, a relational prototype from the late 1970's.

d65 1
a65 1

a78 1
.lp
d81 1
a81 1
The POSTGRES project undertook to build a next generation
d89 1
a89 1
and attempts to provide an accessible path into using the system. 
a92 1
.lp
a108 1
.lp
d110 4
a113 4
    classes
    inheritance
    types
    functions
d115 1
a115 2
.lp
The \*(PP DBMS has been under construction since 1986. 
a125 1
.lp
d139 1
a139 1
command in a format similar to that used in Unix "man pages".
a145 1
.lp
a150 1
.lp
a156 1
.lp
d159 1
a159 1
    % createdb foo
d172 1
a172 1
interact with \*(PP from a C program by using the "libpq"
d182 1
a182 1
allows you to directly execute functions stored in the database. 
d184 2
a185 2
Lastly, \*(PP is accessible from the PICASSO programming
environment.  PICASSO is a graphical user interface (GUI) toolkit
d187 1
a187 1
applications.  PICASSO is a separate research project and is described
d195 1
a195 1
    % monitor <dbname>
a197 1
.lp
a198 1
.lp
d201 1
a201 2

    Welcome to the POSTGRES terminal monitor
d203 2
a204 2
    Go
    *
a206 1
.lp
a211 1
.lp
d214 1
a214 2

    * \\p
a217 1
.lp
d220 1
a220 2

    * \\g
d227 1
a227 2

    * \\e
d232 1
a232 1
vi, type 
d235 1
a235 2

    % man vi
d239 1
a239 1
buffer and you can submit it to postgres by using the "\\g" command
d242 1
a242 1
To get out of the monitor and return to Unix, type
d245 1
a245 2

    * \\q
a248 1
.lp
d251 1
a251 2

    I live to serve you.
d253 1
a253 1
    %
d257 1
a257 1
on "monitor" in the Unix section of the Reference.
d260 1
a260 2
can destroy it using the following UNIX command:
.lp
d263 1
a263 2

    % destroydb foo
d270 1
a270 2
which are discussed further in the Unix section of the Reference.
.lp
a271 1
.lp
d274 1
a274 1
In order to begin using \*(PP, create the 
a282 1
.lp
a286 1
.lp
d289 2
d292 1
a292 4
* create EMP (name=text, salary=int4, 
     age=int4, dept=char16) \g

* create DEPT (dname=char16, floor=int4, 
a301 1

a305 1

a318 1
.lp
a323 1
.lp
a325 1

a336 1

a344 1

a349 1

d352 1
a352 1
       
a357 1

a362 1

d365 1
a365 1
  where E1.age=E2.age 
d376 2
a377 2
for the cartesian product of the classes indicated in the query. 
For those instances in the cartesian product for which the
a379 1
.lp
a381 1

a385 1

d393 1
a393 2
This command replaces the salary of Joe by that of Sam.  

a395 1

a397 1

a399 1

a404 1
.lp
a412 1

d419 1
a419 1
field 
a427 1

d429 1
a429 1
     pay_by_quarter = "{10000, 10000, 10000, 
d434 1
a434 1
     pay_by_quarter = "{10000, 15000, 15000, 
d439 1
a439 1
     pay_by_quarter = "{20000, 25000, 25000, 
a448 1

a459 1

d468 1
a468 2

* delete SAL_EMP 
d481 1
a481 2

* create manager (name = char16, 
d485 1
a485 1
     employees = "{"wei", "greg", 
d496 1
a496 1
the 
a500 1

a514 1
.lp
a516 1

a523 1

d526 1
a526 2

Starting with the 
d534 1
a534 2

* create STUD_EMP (location=point) 
d548 1
a548 1
from its parent, EMP, to wit: name, salary, age, and dept. 
d552 1
a552 1
the inheritance hierarchy is generally a directed acyclic graph. 
a556 1
.lp
d559 1
a559 2

* retrieve (E.name) from E in EMP 
d569 1
a569 2

* retrieve (E.name) from E in EMP* 
a582 1
.lp
a584 1

a589 1

a602 1

a613 1

a620 1
.lp
a625 1
.lp
d635 1
a635 1
function, which is assumed to return a collection of instances. 
a637 1
.lp
a639 1

a647 1
.lp
a649 1

a659 1
.lp
a661 1

a667 1

a682 1

d687 1
a687 1
  where EMP.name=DEPT.manager 
a696 1

d705 1
a705 1
referencing into it with a second use of the dot notation. 
a715 1

d720 1
a720 1
  where E.name=DEPT.manager and 
d733 1
a733 1
attribute (except for direct appends - that is, 
a739 1

a748 1
    
a754 1
.lp
d760 2
a761 2
a binary object file created by the user.  This allows \*(PP to call 
arbitrary user functions which can be written in a standard programming 
d772 1
a772 2
.lp
.sh 2 "Internal storage of types" 
a778 1
.lp
a794 1
.lp
d797 1
a797 1
In this discussion, we will be defining a 
a799 1
.lp
a807 1

a808 1

a824 1

d840 1
a840 1
glance to be a correct type and explain why it 
a846 1

d857 1
a857 1
work because 
a864 1
.lp
d887 1
a887 1
passed a pointer to type CIRCLE as input and returns a string. 
a891 1

a895 1
.lp
a906 1

a921 1
.lp
a928 1

d931 1
a931 1
     output=circle_out) 
d936 1
a936 1
where 
a941 1

a949 1

a950 1

d953 1
a953 1
on your type.  If 
a959 1

d965 1
a965 1
and redefine the circle type.  Note that we would 
a967 1
.lp
d974 1
a974 1
operators.  To do this, we make use of the concept of 
a982 1

a994 1

a1001 1
.lp
a1006 1

d1022 1
a1022 1
  where tutorial.a = 
a1046 1
.lp
d1049 1
a1049 1
The following is the source code for circle.c.  
a1051 1

a1133 1
.lp 
d1137 1
a1137 1
must use the memory allocator "palloc" and avoid standard Unix memory managers
a1141 1

a1143 1
    
d1148 1
a1148 1
manner as the Unix "free" library call:
a1150 1

a1152 1

a1155 1
.lp
d1161 1
a1161 1
done automatically when you edit or re-compile the file, but 
a1167 1

d1184 1
a1184 1
In using a function of an instance in qualifying an instance, 
a1192 1

a1198 1

d1200 1
a1200 1
overpaid() /* note that there are no 
a1201 1

a1202 1

d1207 1
a1207 1
    seniority=(short) 
d1209 1
a1209 1
    performance=(short) 
d1212 1
a1212 1
    return (salary > 
a1232 1

a1244 1

d1248 1
a1248 1
  as "/usr/postgres/tutorial/overpaid.o" 
d1256 2
a1257 2
Your function may only access one instance via the 
.b GetAttribute 
a1261 1

a1268 1

a1278 1
.lp
d1283 1
a1283 1
\*(PP 
a1293 1

a1301 1

d1303 1
a1303 1
     (list = "{"(1.0, 1.0, 5.0)", 
d1309 1
a1309 1
     (list = "{"(2.0, 3.0, 15.0)", 
d1313 1
a1313 1
* append circles 
a1316 1

a1321 1

d1337 1
a1337 1
of arrays".  
a1346 1

d1349 1
a1349 1
     internallength = variable, 
d1361 1
a1361 1
indicates that it is a variable length attribute.  
d1363 1
a1363 1
that any type using 
a1372 1

a1382 1

d1386 1
a1386 1
     (a = "{{1, 2, 3} , {4, 5}, 
d1391 1
a1391 1
* append stuff (a = "{{5, 4, 3} , 
d1400 1
a1400 1
* retrieve (s.all) 
a1406 1
.lp
a1425 1
.lp
a1427 1

a1435 1
.lp
a1437 1

a1449 1

d1458 2
a1459 2
  ... figure out how long the stats 
     array should be 
d1482 1
a1482 1
     populate the stats array with 
a1489 1
.lp
d1492 2
a1493 2
Now, using the 
.b define 
a1498 1
.lp
a1500 1

a1503 1
.lp
a1506 1
.lp
a1508 1

a1523 1
.lp
a1524 1
.lp
a1526 1

d1528 1
a1528 1
     (internallength = 16, 
d1530 1
a1530 1
     output = quarterly_out, 
d1532 1
a1532 1
       
a1535 1
.lp
a1536 1
.lp
a1538 1

a1553 1
.lp
a1555 1
.lp
a1557 1

a1566 1
.lp
a1567 1
.lp
a1569 1

d1597 1
a1597 1
that when you use your own functions to input and output array types, 
d1605 1
a1605 1
and is 
d1614 1
a1614 1
Unix file system interface; the particulars of this interface are detailed in
a1621 1
.lp
d1627 1
a1627 1
and 
a1634 1

d1657 1
a1657 1
Large objects are 
a1662 1

a1680 1
.lp
d1685 1
a1685 1
a large object, they 
a1690 1

d1696 1
a1696 1
       
d1701 1
a1701 1
to large objects, 
a1705 1
.lp
a1731 1
.lp
a1733 1

a1754 1
.lp
a1758 1
.lp
d1761 2
a1763 3
* retrieve (pg_am.oid)
  where pg_am.amname = "btree" 
        
a1774 1
.lp
a1795 1
.lp
a1809 1
.lp
d1826 1
a1826 1
These operations do not correspond to user qualifications in 
a1862 1
.lp
a1864 1

a1881 1
.lp
a1892 1

a1897 1

a1900 1
.lp
a1906 1
.lp
a1908 1

d1910 1
a1910 1
 * int4_abs.c -- 
a1933 1
.lp
d1948 1
a1948 1
\*(PP 
d1952 1
a1952 1
To avoid this problem, 
a1958 1
.lp
a1960 1

a1986 1
.lp
a1992 1

d2004 1
a2004 1
These 
a2009 1
.lp
a2011 1

a2052 1
.lp
a2056 1
.lp
a2058 1

a2074 1
.lp
d2083 1
a2083 1
pages a search will touch in the tree.  
a2087 1
.lp
a2089 1

a2131 1
.lp
a2133 1

d2136 1
a2136 1
     amopclaid = "17314"::oid, /* 
a2185 1
.lp
a2190 1
.lp
a2192 1

d2211 1
a2211 1
* append pairs (name = "cimarron", 
a2231 1
.lp
a2232 1
.lp
a2234 1

a2239 1
.lp
a2244 1
.lp
d2247 1
a2247 2

* retrieve (pairs.all) 
a2263 1
.lp
d2265 1
a2265 1
that 
a2267 1
.lp
a2269 1

a2284 1
.lp
a2288 1
.lp
d2294 1
a2294 2
Query Rewrite Rule System.  
.lp
d2302 1
a2302 2
of the \*(PP rule system can be found in [STON90]. 
.lp
a2317 1
.lp
d2321 1
a2321 1
making extensive use of \*(PP, or who are the database administrator for 
d2329 1
a2329 1
commands create and destroy \*(PP users.  Please read the "man pages" on these 
a2347 1
.lp
a2353 1
.lp
a2360 1
.lp
d2362 1
a2362 1
other program is using it up.  On most machines, the UNIX command "ipcs" will
a2368 1
.lp
a2370 1

a2375 1
.lp
d2378 1
a2378 1
"postmaster" was also running.  
d2381 1
a2381 1
and shared memory 
a2388 1
.lp
a2390 1

d2396 1
a2396 2
.lp
This message means that you are running a LIBPQ application but it could
@


1.8
log
@oops, I checked in the wrong thing last time (major rework + lie fixes)
@
text
@d2 1
a2 1
.\" $Header: /home/postgres/mer/docs/RCS/manual.me,v 1.6 1992/06/12 00:05:50 hong Exp mer $
d174 1
a174 1
Ron Choi, Adam Glass, Jeffrey Goh, Joey Hellerstein, Wei Hong,
@


1.7
log
@major rework + lie fixes
@
text
@d183 1
a183 1
this manual, as did Claire Mosher and Chandra Gosh.
d422 5
a426 4
* create EMP (name=text, salary=int4,
              age=int4, dept=char16) \\g
    
* create DEPT (dname=char16, floor=int4) \\g
d442 1
a442 1
                  age=40,dept="shoe")
d446 1
a446 1
                  age=29,dept="toy")
d450 1
a450 1
              age=36,dept="candy") \\g
d508 2
a509 1
  where E1.age=E2.age and E1.name != E2.name
d566 1
a566 1
                  pay_by_quarter = int4[4])
d582 2
a583 1
       pay_by_quarter = "{10000, 10000, 10000, 10000}")
d587 2
a588 1
       pay_by_quarter = "{10000, 15000, 15000, 15000}")
d592 2
a593 1
       pay_by_quarter = "{20000, 25000, 25000, 25000}")
d624 2
a625 1
* delete SAL_EMP where SAL_EMP.name[1] = 'j'
d638 2
a639 1
* create manager (name = char16, employees = text[]) \\g
d642 2
a643 1
      employees = "{"wei", "greg", "jeff"}") \\g
d646 1
a646 1
      employees = "{"bill", "joe"}") \\g
d649 1
a649 1
      employees = "{"mike", "alice"}") \\g
d697 2
a698 1
* create STUD_EMP (location=point) inherits (EMP)
d724 2
a725 1
* retrieve (E.name) from E in EMP where E.age > 39
d735 2
a736 1
* retrieve (E.name) from E in EMP* where E.age > 39
d774 2
a775 1
  from E in EMP["Jan 1 00:00:00 1970 GMT","now"]
d816 1
a816 1
       (language = "postquel", returntype = EMP)
d828 1
a828 1
       (language = "postquel", returntype = EMP)
d868 2
a869 1
  where EMP.name=DEPT.manager and DEPT.name=$1
d900 1
a900 1
      (language="postquel", returntype = EMP)
d903 2
a904 1
  where E.name=DEPT.manager and DEPT.name=EMP.dept
d1000 1
d1093 1
a1093 1
.b equal_area_circle,
d1106 1
a1106 1
       (language = "c", returntype=circle)
d1113 1
a1113 1
       (language = "c", returntype=char16)
d1130 2
a1131 2
       (internallength=24, input=circle_in,
        output=circle_out) 
d1144 1
a1144 1
    3 * sizeof(double) = 3 * 8 = 24
d1153 1
d1189 2
a1190 2
* define function equal_area_circle
       (language = "c", returntype=bool)
d1203 2
a1204 2
      (arg1=circle, arg2=circle,
       procedure=equal_area_circle)
d1219 2
a1220 1
* append tutorial(a="(1.0,1.0,10.0)"::circle)
d1222 2
a1223 1
* append tutorial(a="(2.0,2.0,5.0)"::circle)
d1225 2
a1226 1
* append tutorial(a="(0.0,1.8,10.0)"::circle)
d1231 2
a1232 1
  where tutorial.a = "(0.0,0.0,10.0)"::circle
a1237 1

d1239 3
a1241 2
|c|
|l|.
d1420 2
a1421 1
overpaid() /* note that there are no arguments */
d1429 4
a1432 2
    seniority=(short) GetAttribute("seniority");
    performance=(short) GetAttribute("performance");
d1434 2
a1435 1
    return (salary > (seniority * performance));
d1470 1
a1470 1
       (language = "c", returntype=bool)
d1532 2
a1533 1
    (list = "{"(1.0, 1.0, 5.0)", "(2.0, 2.0, 10.0)"}")
d1538 2
a1539 1
    (list = "{"(2.0, 3.0, 15.0)", "(2.0, 2.0, 10.0)"}")
d1542 2
a1543 1
* append circles (list = "{"(2.0, 3.0, 4.0)"}")
d1580 3
a1582 2
    (input = array_in, output = array_out,
     internallength = variable, element = int4)
d1607 4
a1610 4
       (input = array_in,
        output = array_out,
        internallength = variable,
        element = int_array) \\g
d1620 2
a1621 1
    (a = "{{1, 2, 3} , {4, 5}, {6, 7, 8}}") \\g
d1625 2
a1626 1
* append stuff (a = "{{5, 4, 3} , {2, 2}}") \\g
d1698 2
a1699 1
  ... figure out how long the stats array should be 
d1708 1
a1708 1
           sizeof(long));
d1711 1
a1711 1
   * in bytes, INCLUDING ITSELF
d1722 2
a1723 1
     populate the stats array with numbers from s
d1756 1
a1756 1
       (language="c", returntype=quarterly)
d1763 1
a1763 1
       (language = "c", returntype = char16)
d1777 4
a1780 2
       (internallength = 16, input = quarterly_in,
        output = quarterly_out, element = int4)
d1792 1
a1792 1
       (language = "c", returntype = stats)
d1799 1
a1799 1
       (language = "c", returntype = char16)
d1828 1
a1828 1
* create test (a = quarterly, b = stats) \\g
d1832 2
a1833 1
     b = "5 6 7"::stats) \\g
d1836 5
a1840 1
     b = "6 4"::stats) \\g
d1843 9
a1851 7
  where test.a[4] = test.b[2] \\g

------------------
|     a    |  b  |
------------------
| 1 3 2 4  | 6 4 |
------------------
d1896 1
a1896 1
       (language = "c", returntype = map)
d1903 1
a1903 1
       (language = "c", returntype = char16)
d1910 2
a1911 2
       (input = large_in, output = large_out,
        internallength = variable)
d1927 1
a1927 1
    (name = "earth",
d1933 1
a1933 1
    (name = "moon",
d2035 7
a2041 5
---------------
| oid         |
---------------
| 403         |
---------------
d2069 10
a2078 7
.ta 0.5i 2.2i

    less than	1
    less than or equal	2
    equal	3
    greater than or equal	4
    greater than	5
d2147 7
a2153 5
-----------------------------
| oid         | opcname     |
-----------------------------
| 17314       | int4_abs_ops|
-----------------------------
d2174 1
d2199 1
a2199 1
    { ABS(a); ABS(b); return (a < b); }
d2202 1
a2202 1
    { ABS(a); ABS(b); return (a <= b); }
d2205 1
a2205 1
    { ABS(a); ABS(b); return (a == b); }
d2208 1
a2208 1
    { ABS(a); ABS(b); return (a >= b); }
d2211 1
a2211 1
    { ABS(a); ABS(b); return (a > b); }
d2245 1
a2245 1
        (language = "c", returntype = bool)
d2250 1
a2250 1
        (language = "c", returntype = bool)
d2255 1
a2255 1
        (language = "c", returntype = bool)
d2260 1
a2260 1
        (language = "c", returntype = bool)
d2265 1
a2265 1
        (language = "c", returntype = bool)
d2300 4
a2303 4
       (arg1 = int4, arg2 = int4,
        procedure=int4_abs_lt,
        associativity = left, restrict = intltsel,
        join = intltjoinsel)
d2308 4
a2311 4
       (arg1 = int4, arg2 = int4,
        procedure=int4_abs_le,
        associativity = left, restrict = intltsel,
        join = intltjoinsel)
d2316 4
a2319 4
       (arg1 = int4, arg2 = int4,
        procedure=int4_abs_eq,
        associativity = left, restrict = eqsel,
        join = eqjoinsel)
d2324 4
a2327 4
       (arg1 = int4, arg2 = int4,
        procedure=int4_abs_ge,
        associativity = left, restrict = intgtsel,
        join = intgtjoinsel)
d2332 4
a2335 4
       (arg1 = int4, arg2 = int4,
        procedure=int4_abs_gt,
        associativity = left, restrict = intgtsel,
        join = intgtjoinsel)
d2389 22
a2410 37

-----------------------------
| oid         | oprname     |
-----------------------------
| 96          | =           |
-----------------------------
| 97          | <           |
-----------------------------
| 514         | *           |
-----------------------------
| 518         | !=          |
-----------------------------
| 521         | >           |
-----------------------------
| 523         | <=          |
-----------------------------
| 525         | >=          |
-----------------------------
| 528         | /           |
-----------------------------
| 530         | %           |
-----------------------------
| 551         | +           |
-----------------------------
| 555         | -           |
-----------------------------_
| 17321       | <<&         | \e
-----------------------------  \e   these are the ones
| 17322       | <=&         |   \e  we want-- the values
-----------------------------    \e you get for oids will
| 17323       | ==&         |     |probably be different,
-----------------------------    / and you should substitute
| 17324       | >=&         |   /  them for the values i use
-----------------------------  /   below.
| 17325       | >>&         | /
------------------------------

d2413 3
d2430 3
a2432 2
    (amopid = "400"::oid,      /* btree oid */
     amopclaid = "17314"::oid, /* pg_opclass tup */
d2509 2
a2510 1
* append pairs (name = "cimarron", number = -3000)
d2516 12
a2527 15
-----------------------------
| name        | number      |
-----------------------------
| mike        | -10000      |
-----------------------------
| greg        | 3000        |
-----------------------------
| lay peng    | 5000        |
-----------------------------
| jeff        | -2000       |
-----------------------------
| mao         | 7000        |
-----------------------------
| cimarron    | -3000       |
-----------------------------
d2551 2
a2552 1
* retrieve (pairs.all) where pairs.number < 9000
d2554 12
a2565 16

-----------------------------
| name        | number      |
-----------------------------
| mike        | -10000      |
-----------------------------
| greg        | 3000        |
-----------------------------
| lay peng    | 5000        |
-----------------------------
| jeff        | -2000       |
-----------------------------
| mao         | 7000        |
-----------------------------
| cimarron    | -3000       |
-----------------------------
d2579 11
a2589 14

-----------------------------
| name        | number      |
-----------------------------
| jeff        | -2000       |
-----------------------------
| cimarron    | -3000       |
-----------------------------
| greg        | 3000        |
-----------------------------
| lay peng    | 5000        |
-----------------------------
| mao         | 7000        |
-----------------------------
@


1.6
log
@fixed the arrays of user-defined types section
@
text
@d2 1
a2 1
.\" $Header: /mnt/hong/pghome/doc/RCS/manual.me,v 1.5 1992/06/11 22:42:13 mer Exp hong $
d120 1
a120 1
.\" .nr sp 10    \" standard section title point size
d173 1
a173 1
alphabetical order) consisted of James Bell, Jennifer Caetta, Jolly Chen
d183 1
a183 1
this manual, as did Claire Mosher.
d218 4
a221 4
        classes
        inheritance
        types
        functions
d271 3
a273 1
        % createdb foo
d307 3
a309 3

        % monitor <dbname>

d315 1
d317 1
a317 1
        Welcome to the POSTGRES terminal monitor
d319 3
a321 3
        Go
        *

d331 1
d333 2
a334 2
        * \\p

d339 1
d341 2
a342 2
        * \\g

d347 1
d349 2
a350 2
        * \\e

d356 1
d358 2
a359 2
        % man vi

d367 1
d369 2
a370 2
        * \\q

d375 1
d377 1
a377 1
        I live to serve you.
d379 2
a380 2
        %

d389 1
d391 2
a392 2
        % destroydb foo

d420 1
d422 2
a423 1
    * create EMP (name=text, salary=int4, age=int4, dept=char16) \\g
d425 2
a426 2
    * create DEPT (dname=char16, floor=int4) \\g

d438 1
d440 7
a446 1
    * append EMP (name="Joe",salary=1400,age=40,dept="shoe") \\g
d448 3
a450 4
    * append EMP (name="Sam",salary=1200,age=29,dept="toy") \\g

    * append EMP (name="Bill",salary=1600,age=36,dept="candy") \\g

d461 1
d463 1
a463 1
    * retrieve (EMP.name) where EMP.age<35
d465 2
a466 2
    \\g

d473 1
d475 2
a476 2
    * retrieve (result=EMP.salary/EMP.age)
      where EMP.name="Bill"
d478 2
a479 2
    \\g

d488 1
d490 2
a491 2
     * retrieve into temp (EMP.name)
       where EMP.age<35 and EMP.salary>1000
d493 2
a494 2
     \\g

d503 1
d505 3
a507 3
        * retrieve (E1.name, E2.name)
          from E1 in EMP, E2 in EMP
          where E1.age=E2.age and E1.name != E2.name
d509 2
a510 2
        \\g

d528 1
d530 3
a532 3
        * replace EMP (salary=E.salary)
          from E in EMP
          where EMP.name="Joe" and E.name="Sam"
d534 2
a535 2
        \\g

d546 1
d548 1
a548 1
        * delete EMP where EMP.salary > 0
d550 2
a551 2
        \\g

d561 1
d563 4
a566 2
        * create SAL_EMP (name = char[], pay_by_quarter = int4[4]) \\g

d577 1
d579 12
a590 12
        * append SAL_EMP (name = "bill",
               pay_by_quarter = "{10000, 10000, 10000, 10000}")
        \\g

        * append SAL_EMP (name = "jack",
               pay_by_quarter = "{10000, 15000, 15000, 15000}")
        \\g

        * append SAL_EMP (name = "joe",
               pay_by_quarter = "{20000, 25000, 25000, 25000}")
        \\g

d596 1
d598 3
a600 3
        * retrieve (SAL_EMP.name)
          where SAL_EMP.pay_by_quarter[1] !=
                SAL_EMP.pay_by_quarter[2]
d602 2
a603 2
        \\g

d608 1
d610 1
a610 1
        * retrieve (SAL_EMP.pay_by_quarter[3])
d612 2
a613 2
        \\g

d617 1
d619 1
a619 1
        * delete SAL_EMP where SAL_EMP.name[1] = 'j'
d621 2
a622 2
        \\g

d630 1
d632 1
a632 1
        * create manager (name = char[], employees = text[]) \\g
d634 2
a635 2
        * append manager (name = "mike",
              employees = "{"wei", "greg", "jeff"}") \\g
d637 2
a638 2
        * append manager (name = "alice",
              employees = "{"bill", "joe"}") \\g
d640 3
a642 3
        * append manager (name = "marge",
              employees = "{"mike", "alice"}") \\g

d649 1
d651 2
a652 2
        * retrieve (manager.name)
          where manager.employees[1][1] = 'b' \\g
d654 2
a655 2
        * retrieve (manager.name)
          where manager.employees[3] = "jeff" \\g
d657 1
a657 1
        * retrieve (manager.employees[3][2]) \\g
d659 3
a661 2
        * delete manager where manager.employees[2][1] = 'g' \\g

d687 1
d689 1
a689 1
        * create STUD_EMP (location=point) inherits (EMP)
d691 1
a691 1
        \\g
d693 4
a696 2
        * append STUD_EMP (name = "Sunita", age = 41,
              salary=1300, dept="electronics", location="(3,5)")
d698 2
a699 2
        \\g

d713 1
d715 1
a715 1
        * retrieve (E.name) from E in EMP where E.age > 39
d717 2
a718 2
        \\g

d723 1
d725 1
a725 1
        * retrieve (E.name) from E in EMP* where E.age > 39
d727 2
a728 2
        \\g

d746 1
d748 3
a750 1
    * retrieve (E.salary) from E in EMP["now"] where E.name="Sam"
d752 2
a753 2
    \\g

d760 1
d762 3
a764 3
    * retrieve (E.salary)
      from E in EMP["Jan 1 00:00:00 1970 GMT","now"]
      where E.name = "Sam"
d766 2
a767 2
    \\g

d771 1
d773 3
a775 1
    * retrieve (E.salary) from E in EMP[,] where E.name = "Sam"
d777 2
a778 2
    \\g

d801 1
d803 3
a805 4
        * define function high_pay
               (language = "postquel", returntype = EMP)
               as
               retrieve (EMP.all) where EMP.salary>50000
d807 2
a808 2
        \\g

d813 1
d815 4
a818 4
        * define function large_pay
               (language = "postquel", returntype = EMP)
               arg is (int4) as
               retrieve (EMP.all) where EMP.salary>$1
d820 2
a821 2
        \\g

d834 1
d836 1
a836 1
        * addattr (manager=EMP) to EMP
d838 2
a839 2
        \\g

d850 1
d852 5
a856 4
       * define function mgr_lookup
            (language = "postquel", returntype = EMP)
            arg is (char16) as
            retrieve (EMP.all) where EMP.name=DEPT.manager and DEPT.name=$1
d858 2
a859 2
       \\g

d864 1
d866 3
a868 3
       * append to EMP
         (name="Sam",salary=1000.0 ,age=40,dept="shoe",
          manager=mgr_lookup("shoe"))
d870 2
a871 2
       \\g

d884 1
d886 5
a890 4
        * define function lookup_mgr (language="postquel", returntype = EMP)
               arg is (EMP) as
               retrieve (E.all) from E in EMP
               where E.name=DEPT.manager and DEPT.name=EMP.dept
d892 2
a893 2
        \\g

d908 1
d910 2
a911 1
        * retrieve (EMP.name) where EMP.manager.name="Joe"
d913 2
a914 2
        \\g

d918 1
d920 2
a921 1
        * retrieve (EMP.name) where lookup_mgr(EMP).name="Joe"
d923 2
a924 2
        \\g

d983 1
d985 2
a986 2
    (center_x, center_y, radius)

d1001 1
d1003 5
a1007 5
    typedef struct
    {
        double x,y;
    }
    POINT;
d1009 7
a1015 7
    typedef struct
    {
        POINT center;
        double r;
    }
    CIRCLE;

d1024 1
d1026 7
a1032 6
    typedef struct
    {
        POINT *center
        double r;
    }
    CIRCLE;
d1071 1
d1073 3
a1075 4
    CIRCLE *circle, *circle_in();
    char *circle_out();

    circle=circle_in(circle_out(circle_in("(2.0,3.0,5.0)")));
d1088 1
a1088 3
       * define C function circle_in
              (file="/usr/postgres/tutorial/circle.o", returntype=circle)
              arg is (char16)
d1090 11
a1100 1
       * \\g
d1102 2
a1103 6
       *  define C function circle_out
              (file="/usr/postgres/tutorial/circle.o", returntype=char16)
              arg is (circle)

       * \\g

d1112 1
d1114 3
a1116 2
       * define type circle
              (internallength=24, input=circle_in, output=circle_out) 
d1118 2
a1119 2
       * \\g

d1126 1
d1128 3
a1130 2
     sizeof(circle) = 3 * sizeof(double) = 3 * 8 = 24

d1135 1
d1137 2
a1138 2
     printf("size is %d\n", sizeof (mystruct));

d1146 1
d1148 1
a1148 1
       * remove type circle
d1150 2
a1151 2
       * \\g
     
d1171 1
d1173 4
a1176 3
       * define C function equal_area_circle
              (file="/usr/postgres/tutorial/circle.o", returntype=bool)
              arg is (circle,circle)
d1178 2
a1179 2
       * \\g

d1184 1
d1186 3
a1188 2
       * define operator =
             (arg1=circle,arg2=circle,procedure=equal_area_circle)
d1190 2
a1191 2
       * \\g

d1198 1
d1200 2
a1201 2
       * create tutorial(a=circle)
       * \\g
d1203 6
a1208 4
       * append tutorial(a="(1.0,1.0,10.0)"::circle)
       * append tutorial(a="(2.0,2.0,5.0)"::circle)
       * append tutorial(a="(0.0,1.8,10.0)"::circle)
       * \\g
d1211 3
a1213 3
       * retrieve (tutorial.all)
              where tutorial.a = "(0.0,0.0,10.0)"::circle
       * \\g
d1217 1
d1219 8
a1226 8
    ----------------
    |      a       |
    ----------------
    |(1.0,1.0,10.0)|
    ----------------
    |(0.0,1.8,10.0)|
    -----------------

d1241 1
d1272 4
a1275 1
    for (i = 0, p = str; *p && i < NARGS && *p != RDELIM; p++)
d1278 1
d1302 5
a1306 2
    sprintf(result, "(%g,%g,%g)",
            circle->center.x, circle->center.y, circle->radius);
d1317 4
a1320 1
    return (point_dt(point, &circle->center) < circle->radius );
d1322 1
a1322 1

d1333 4
a1336 2
    char
    *palloc(size)
d1338 2
a1339 2
    unsigned long size;

d1344 1
a1344 2
    void
    pfree(ptr)
d1346 2
a1347 1
    char *ptr;
d1349 2
d1364 1
d1366 1
a1366 1
       * load "/usr/postgres/tutorial/circle.o"
d1368 2
a1369 2
       * \\g

d1390 1
d1392 2
a1393 2
       * retrieve (emp.all) where overpaid(emp)

d1397 1
d1399 2
a1400 2
    bool
    overpaid() /* note that there are no arguments */
d1402 1
a1402 1
    {
d1404 2
a1405 2
        extern Datum GetAttribute();
        short age, salary, performance;
d1407 3
a1409 3
        salary=(short) GetAttribute("salary");
        seniority=(short) GetAttribute("seniority");
        performance=(short) GetAttribute("performance");
d1411 1
a1411 1
        return (salary > (seniority * performance));
d1413 2
a1414 1
    }
d1430 1
d1432 1
a1432 1
    char *str
d1434 2
a1435 2
    str = (char *) GetAttribute("name")

d1443 6
a1448 4
       * define function overpaid
              (file="/usr/postgres/tutorial/overpaid.o", language = "c",
               returntype=bool)
         arg is (SET)
d1450 2
a1451 1
       * \\g
d1461 1
a1461 1
       * retrieve (emp.all) where overpaid2(emp, "bill", 8)
d1463 3
d1469 1
d1476 1
a1476 1

d1496 1
a1496 1
       * create circles (list = circle[])
d1498 4
a1501 1
       \\g
d1505 1
a1505 1
       * append circles (list = "{"(1.0, 1.0, 5.0)", "(2.0, 2.0, 10.0)"}")
d1507 2
a1508 1
       \\g
d1510 1
a1510 1
       * append circles (list = "{"(2.0, 3.0, 15.0)", "(2.0, 2.0, 10.0)"}")
d1512 3
a1514 1
       \\g
d1516 1
a1516 1
       * append circles (list = "{"(2.0, 3.0, 4.0)"}")
d1518 3
a1520 1
       \\g
d1524 3
a1526 1
       * retrieve (circles.list[1])
d1528 3
a1530 2
       \\g
       * retrieve (circles.all) where circles.list[1] = "(0.0, 0.0, 4.0)"
d1532 2
a1533 1
       \\g
d1550 5
a1554 3
       * define type int_array
              (input = array_in, output = array_out, internallength = variable,
              element = int4)
d1556 2
a1557 1
       \\g
d1576 1
d1578 6
a1583 3
       * define type int_arrays
              (input = array_in, output = array_out, internallength = variable,
              element = int_array) \\g
d1587 3
a1589 1
       * create stuff (a = int_arrays) \\g
d1591 2
a1592 1
       * append stuff (a = "{{1, 2, 3} , {4, 5}, {6, 7, 8}}") \\g
d1594 1
a1594 1
       * append stuff (a = "{{88, 99, 3}}") \\g
d1596 1
a1596 1
       * append stuff (a = "{{5, 4, 3} , {2, 2}}") \\g
d1598 2
a1599 2
       * retrieve (stuff.a[1])
              where stuff.a[1][1] < stuff.a[1][2] \\g
d1601 2
a1602 2
       * retrieve (stuff.a)
              where stuff.a[3][1] < stuff.a[1][2] \\g
d1604 4
a1607 3
       * retrieve (s.all) 
              from s in stuff
              where s.a[2][2] = stuff.a[1][1] \\g
d1633 1
d1636 1
a1636 1

d1645 1
d1650 2
a1651 1
    unsigned char bytes[1]; /* Force contiguity */
d1654 1
d1658 1
d1665 2
a1666 2
    VAR_LEN_ATTR *stats;
    long array_size, *arrayp;
d1668 1
a1668 1
    ... figure out how long the stats array should be ...
d1670 4
a1673 1
    /* We need the extra sizeof(long) to hold the length */
d1675 3
a1677 1
    stats = (VAR_LEN_ATTR *) palloc(array_size * sizeof(long) + sizeof(long));
d1679 3
a1681 1
    /* length is length of the entire structure in bytes, INCLUDING ITSELF */
d1683 3
a1685 1
    stats->length = array_size * sizeof(long) + sizeof(long);
d1687 1
a1687 1
    arrayp = &(stats->bytes[0]);
d1689 4
a1692 4
    for (i = 0; i < length; i++, arrayp++)
    {
        ... populate the stats array with numbers from s ....
    }
d1694 1
a1694 1
    return(stats);
d1696 1
d1710 1
d1713 1
a1713 1

d1721 1
d1723 11
a1733 11
       * define function quarterly_in
              (file = "/usr/postgres/tutorial/quarterly.o", language = "c",
               returntype = quarterly)
              arg is (char16)

       \\g

       * define function quarterly_out
              (file = "/usr/postgres/tutorial/quarterly.o",language = "c",
               returntype = char16)
              arg is (quarterly)
d1735 2
a1736 1
       \\g
d1742 1
d1744 3
a1746 3
       * define type quarterly
              (internallength = 16, input = quarterly_in,
               output = quarterly_out, element = int4)
d1748 2
a1749 2
       * \\g

d1755 1
d1757 11
a1767 11
       * define function stats_in
              (file = "/usr/postgres/tutorial/stats.o", language = "c",
               returntype = stats)
              arg is (char16)

       \\g

       * define function stats_out
              (file = "/usr/postgres/tutorial/stats.o", language = "c",
               returntype = char16)
              arg is (stats)
d1769 2
a1770 1
       \\g
d1777 1
d1779 5
a1783 3
       * define type stats
              (internallength = variable, input = stats_in,
               output = stats_out, element = int4)
d1785 2
a1786 1
       * \\g
d1792 1
d1794 1
a1794 1
       * create test (a = quarterly, b = stats) \\g
d1796 6
a1801 2
       * append test (a = "1 2 3 4"::quarterly, b = "5 6 7"::stats) \\g
       * append test (a = "1 3 2 4"::quarterly, b = "6 4"::stats) \\g
d1803 2
a1804 1
       * retrieve (test.all) where test.a[4] = test.b[2] \\g
d1808 1
a1808 1
-------------------
d1811 1
d1852 1
d1854 4
a1857 4
       * define function large_in
              (file = "/usr/postgres/tutorial/large.o", language = "c",
               returntype = map)
              arg is (char16)
d1859 1
a1859 1
       \\g
d1861 4
a1864 4
       * define function large_out
              (file = "/usr/postgres/tutorial/large.o", language = "c",
               returntype = char16)
              arg is (map)
d1866 1
a1866 1
       \\g
d1868 3
a1870 2
       * define type map
              (input = large_in, output = large_out, internallength = variable)
d1872 2
a1873 2
       \\g

d1881 1
d1883 1
a1883 1
       * create maps (name = text, a = map) \\g
d1885 3
a1887 1
       * append maps (name = "earth", a = "/usr/postgres/maps/earth")
d1889 1
a1889 1
       \\g
d1891 3
a1893 1
       * append maps (name = "moon", a = "/usr/postgres/maps/moon")
d1895 2
a1896 1
       \\g
d1911 1
d1913 2
a1914 1
       * retrieve (emp.name) where beard(emp.picture) = "red" \\g
d1916 2
a1917 2
       * retrieve (mountain.name)
              where height(mountain.topomap) > 10000
d1919 2
a1920 2
       \\g

d1957 1
a1957 1
    amname:  name of the access method
d1959 1
a1959 1
    amowner: object id of the owner's instance in pg_user
d1961 2
a1962 1
    amkind:  not used at present, but set to 'o' as a place holder
d1964 2
a1965 1
    amstrategies:  number of strategies for this access method (see below)
d1967 2
a1968 1
    amsupport:  number of support routines for this access method (see below)
d1970 9
a1978 3
    am*:  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.
d1988 3
a1990 1
    * retrieve (pg_am.oid) where pg_am.amname = "btree" 
d1992 1
a1992 1
    * \eg
d1994 5
a1998 5
    ---------------
    | oid         |
    ---------------
    | 403         |
    ---------------
d2025 1
d2027 7
a2033 5
	less than	1
	less than or equal	2
	equal	3
	greater than or equal	4
	greater than	5
a2091 2
       * append pg_opclass (opcname = "int4_abs_ops")
       * \eg
d2093 2
a2094 10
       * retrieve (cl.oid, cl.opcname)
              from cl in pg_opclass
              where cl.opcname = "int4_abs_ops"
       * \eg

    -----------------------------
    | oid         | opcname     |
    -----------------------------
    | 17314       | int4_abs_ops|
    -----------------------------
d2096 11
d2119 8
a2126 5
	absolute value less-than
	absolute value less-than-or-equal
	absolute value equal
	absolute value greater-than-or-equal
	absolute value greater-than
d2131 1
d2133 1
d2138 10
d2149 2
a2150 2
    /* int4_abs.c -- absolute value comparison functions for int4 data  */
    #include "tmp/c.h"
d2152 2
a2153 1
    #define ABS(a) a = ((a < 0) ? -a : a)
d2155 2
a2156 5
    bool int4_abs_lt(a, b) int32 a, b; { ABS(a); ABS(b); return (a < b); }
    bool int4_abs_le(a, b) int32 a, b; { ABS(a); ABS(b); return (a <= b); }
    bool int4_abs_eq(a, b) int32 a, b; { ABS(a); ABS(b); return (a == b); }
    bool int4_abs_ge(a, b) int32 a, b; { ABS(a); ABS(b); return (a >= b); }
    bool int4_abs_gt(a, b) int32 a, b; { ABS(a); ABS(b); return (a > b); }
d2158 6
d2194 25
a2218 24
   * define function int4_abs_lt
           (file = "/usr/postgres/tutorial/int4_abs.o",
	    language = "c", returntype = bool)
           arg is (int4, int4) \eg

   * define function int4_abs_le
           (file = "/usr/postgres/tutorial/int4_abs.o",
	    language = "c", returntype = bool)
           arg is (int4, int4) \eg

   * define function int4_abs_eq
           (file = "/usr/postgres/tutorial/int4_abs.o",
	    language = "c", returntype = bool)
           arg is (int4, int4) \eg

   * define function int4_abs_ge
           (file = "/usr/postgres/tutorial/int4_abs.o",
	    language = "c", returntype = bool)
           arg is (int4, int4) \eg

   * define function int4_abs_gt
           (file = "/usr/postgres/tutorial/int4_abs.o",
	    language = "c", returntype = bool)
           arg is (int4, int4) \eg
d2228 2
a2229 1
   * retrieve (pg_operator.all) \eg
d2248 1
d2250 37
a2286 4
       * define operator <<&
              (arg1 = int4, arg2 = int4, procedure=int4_abs_lt,
               associativity = left, restrict = intltsel,
               join = intltjoinsel)
d2288 2
a2289 29
       * \\g

       * define operator <=&
              (arg1 = int4, arg2 = int4, procedure=int4_abs_le,
               associativity = left, restrict = intltsel,
               join = intltjoinsel)

       * \\g

       * define operator ==&
              (arg1 = int4, arg2 = int4, procedure=int4_abs_eq,
               associativity = left, restrict = eqsel,
               join = eqjoinsel)

       * \\g

       * define operator >=&
              (arg1 = int4, arg2 = int4, procedure=int4_abs_ge,
               associativity = left, restrict = intgtsel,
               join = intgtjoinsel)

       * \\g

       * define operator >>&
              (arg1 = int4, arg2 = int4, procedure=int4_abs_gt,
               associativity = left, restrict = intgtsel,
               join = intgtjoinsel)

       * \\g
d2298 1
d2300 2
a2301 1
    amopid:  the oid of the pg_am instance for BTREE (== 400, see above);
d2303 8
a2310 2
    amopclaid:  the oid of the pg_opclass instance for int4_abs_ops
                (== whatever you got instead of 17314, see above);
d2312 3
a2314 6
    amopopr:  the oids of the operators for the opclass (which we'll
              get in just a minute); and

    amopselect,
    amopnpages:  cost functions.

d2332 1
d2334 42
a2375 42
       * retrieve (o.oid, o.oprname)
              from o in pg_operator, t in pg_type
              where o.oprleft = t.oid and o.oprright = t.oid
              and t.typname = "int4"

       * \\g

    -----------------------------
    | oid         | oprname     |
    -----------------------------
    | 96          | =           |
    -----------------------------
    | 97          | <           |
    -----------------------------
    | 514         | *           |
    -----------------------------
    | 518         | !=          |
    -----------------------------
    | 521         | >           |
    -----------------------------
    | 523         | <=          |
    -----------------------------
    | 525         | >=          |
    -----------------------------
    | 528         | /           |
    -----------------------------
    | 530         | %           |
    -----------------------------
    | 551         | +           |
    -----------------------------
    | 555         | -           |
    -----------------------------  _
    | 17321       | <<&         |    \e
    -----------------------------     \e
    | 17322       | <=&         |      \e
    -----------------------------       \e
    | 17323       | ==&         |        | these are the ones we want
    -----------------------------       /  -- the values you get for oids
    | 17324       | >=&         |      /   will probably be different, and
    -----------------------------     /    you should substitute them for
    | 17325       | >>&         |    /     the values i use below.
    -----------------------------  -
d2377 1
d2390 1
d2392 47
a2438 42
       * append pg_amop (amopid = "400"::oid,      /* btree oid */
                         amopclaid = "17314"::oid, /* pg_opclass tup */
                         amopopr = "17321"::oid,   /* <<& tup oid */
                         amopstrategy = "1"::int2, /* 1 is <<& */
                         amopselect = "btreesel"::regproc,
                         amopnpages = "btreenpage"::regproc)

       * \\g

       * append pg_amop (amopid = "400"::oid,
                         amopclaid = "17314"::oid,
                         amopopr = "17322"::oid,
                         amopstrategy = "2"::int2,
                         amopselect = "btreesel"::regproc,
                         amopnpages = "btreenpage"::regproc)

       * \\g

       * append pg_amop (amopid = "400"::oid,
                         amopclaid = "17314"::oid,
                         amopopr = "17323"::oid,
                         amopstrategy = "3"::int2,
                         amopselect = "btreesel"::regproc,
                         amopnpages = "btreenpage"::regproc)

       * \\g

       * append pg_amop (amopid = "400"::oid,
                         amopclaid = "17314"::oid,
                         amopopr = "17324"::oid,
                         amopstrategy = "4"::int2,
                         amopselect = "btreesel"::regproc,
                         amopnpages = "btreenpage"::regproc)

       * \\g

       * append pg_amop (amopid = "400"::oid,
                         amopclaid = "17314"::oid,
                         amopopr = "17325"::oid,
                         amopstrategy = "5"::int2,
                         amopselect = "btreesel"::regproc,
                         amopnpages = "btreenpage"::regproc)
d2440 2
a2441 2
       * \\g

d2451 1
d2453 2
a2454 2
       * create pairs (name = char16, number = int4)
       * \\g
d2456 2
a2457 2
       * append pairs (name = "mike", number = -10000)
       * \\g
d2459 2
a2460 2
       * append pairs (name = "greg", number = 3000)
       * \\g
d2462 31
a2492 31
       * append pairs (name = "lay peng", number = 5000)
       * \\g

       * append pairs (name = "jeff", number = -2000)
       * \\g

       * append pairs (name = "mao", number = 7000)
       * \\g

       * append pairs (name = "cimarron", number = -3000)
       * \\g

       * retrieve (pairs.all)
       * \\g

    -----------------------------
    | name        | number      |
    -----------------------------
    | mike        | -10000      |
    -----------------------------
    | greg        | 3000        |
    -----------------------------
    | lay peng    | 5000        |
    -----------------------------
    | jeff        | -2000       |
    -----------------------------
    | mao         | 7000        |
    -----------------------------
    | cimarron    | -3000       |
    -----------------------------

d2498 1
d2500 4
a2503 3
       * define index pairsind on pairs using btree (number int4_abs_ops)
       * \\g

d2513 1
d2515 2
a2516 2
       * retrieve (pairs.all) where pairs.number < 9000
       * \\g
d2518 16
a2533 16
    -----------------------------
    | name        | number      |
    -----------------------------
    | mike        | -10000      |
    -----------------------------
    | greg        | 3000        |
    -----------------------------
    | lay peng    | 5000        |
    -----------------------------
    | jeff        | -2000       |
    -----------------------------
    | mao         | 7000        |
    -----------------------------
    | cimarron    | -3000       |
    -----------------------------

d2542 1
d2544 2
a2545 2
       * retrieve (pairs.all) where pairs.number <<& 9000
       * \\g
d2547 14
a2560 14
    -----------------------------
    | name        | number      |
    -----------------------------
    | jeff        | -2000       |
    -----------------------------
    | cimarron    | -3000       |
    -----------------------------
    | greg        | 3000        |
    -----------------------------
    | lay peng    | 5000        |
    -----------------------------
    | mao         | 7000        |
    -----------------------------

d2639 1
d2643 1
d2656 1
d2661 1
a2661 1

d2679 1
d2684 1
a2684 1

@


1.5
log
@fix some of the lies
@
text
@d2 1
a2 1
.\" $Header: /home/postgres/mer/docs/RCS/manual.me,v 1.4 1992/02/28 05:38:55 mao Exp mer $
d1392 1
a1392 1
       * \\g
d1398 2
d1402 2
d1406 1
a1406 1
       * \\g
d1412 1
d1415 1
a1415 1
       * \\g
d1436 1
a1436 1
       * \\g
d1458 1
a1458 1
              element = int_array)
d1462 1
a1462 1
       * create stuff (a = int_arrays)
d1464 1
a1464 1
       * append stuff (a = "{{1, 2, 3} , {4, 5}, {6, 7, 8}}")
d1466 1
a1466 1
       * append stuff (a = "{{88, 99, 3}})
d1468 1
a1468 1
       * append stuff (a = "{{5, 4, 3} , {2, 2}}")
d1471 1
a1471 1
              where stuff.a[1][1] < stuff.a[1][2]
d1474 1
a1474 1
              where stuff.a[3][1] < stuff.a[1][2]
d1478 1
a1478 1
              where s.a[2][2] = stuff.a[1][1]
d1582 2
d1589 1
a1589 1
       * \\g
d1613 2
d1620 1
a1620 1
       * \\g
d1639 1
a1639 1
       * create test (a = quarterly, b = stats)
d1641 2
a1642 2
       * append test (a = "1 2 3 4"::quarterly, b = "5 6 7"::stats)
       * append test (a = "1 3 2 4"::quarterly, b = "6 4"::stats)
d1644 1
a1644 3
       * retrieve (test.all) where test.a[4] = test.b[2]

       * \\g
d1697 2
d1704 2
d1709 1
a1709 1
       * \\g
d1719 1
a1719 1
       * create maps (name = text, a = map)
d1722 3
d1727 1
a1727 1
       * \\g
d1743 1
a1743 1
       * retrieve (emp.name) where beard(emp.picture) = "red"
d1747 2
@


1.4
log
@made some changes to section on adding new operator classes to btrees.
still some stuff to do, but don't want to keep the whole file locked
forever.
@
text
@d2 1
a2 1
.\" $Header: /users/mao/postgres/doc/RCS/manual.me,v 1.3 1992/01/09 21:09:12 mer Exp mao $
d80 2
a81 2
.\" Defines II, PP, UU, LL, PQ, LQ, OF, AM, +- for
.\"    INGRES, POSTGRES, UNIX, LISP, \*(PQ, LIBPQ, PICASSO, "AM Guide," +-.
d94 1
d107 1
d138 1
a138 1
Edited by Jon Rhein and Greg Kemnitz
d157 2
a158 2
This manual describes Version 3.0 of \*(PP.  \*(PP
Software is available for SUN 3 and SUN 4 class machines, for
d164 1
a164 1
Version 3.0 has been tuned modestly.  Hence, on the
d172 5
a176 5
graduate, and staff programmers.  The Version 3 contributors (in
alphabetical order) consisted of James Bell, Jennifer Caetta, Ron
Choi, Adam Glass, Jeffrey Goh, Wei Hong, Anant Jhingran, Greg
Kemnitz, Jeff Meredith, Michael Olson, Lay-Peng Ong, Spyros
Potamianos, and Cimarron Taylor.
d178 2
a179 2
Greg Kemnitz served as chief programmer and was responsible
for overall coordination of the project and for individually
d189 1
a189 1
current relational DBMSs.  This system, constructed over a four
d233 1
a233 1
[STON90B].  We are now delivering version 3, which is the subject
d298 2
a299 1
applications.  PICASSO is described in a collection of reports
d337 1
d352 1
d368 1
a368 3
        * I live to serve you.

        * GoodBye
d402 1
a402 1
a unique (never-changing) identifier (OID).
d410 2
a411 3
    * create EMP (name=char[12], salary=float8, age=int4, dept=char[12])
    
    * create DEPT (dname=c[12], floor=int4)
d413 1
a413 1
    * \\g
d417 1
a417 1
statement in a relational system.  However, we will presently see
d427 1
a427 3
    * append EMP (name="Joe",salary=1400.0,age=40,dept="shoe")

    * append EMP (name="sam",salary=1200.0,age=29,dept="toy")
d429 1
a429 1
    * append EMP (name="Bill",salary=1600.0,age=36,dept="candy")
d431 1
a431 1
    * \\g
d446 1
a446 1
    * \\g
d455 2
a456 1
    * retrieve (result=EMP.salary/EMP.age) where EMP.name="Bill"
d458 1
a458 1
    * \\g
d466 1
a466 1
or, not) are allowed in any query:
d469 4
a472 1
     * retrieve into temp (EMP.name) where EMP.age<35 and EMP.salary>1000
a473 2
     * \\g

d484 4
a487 3
              from E1 in EMP, E2 in EMP
              where E1.age=E2.age
              and E1.name != E2.name
a488 1
        * \\g
d508 2
a509 2
               from E in EMP
               where EMP.name="Joe" and E.name="Sam"
d511 2
a512 1
        * \\g
d526 2
a527 1
        * \\g
d538 1
a538 1
        * create SAL_EMP (name = char[], pay_by_quarter = int4[4])
d553 1
d557 1
d561 1
a562 1
        * \\g
d570 4
a573 1
               where SAL_EMP.pay_by_quarter[1] != SAL_EMP.pay_by_quarter[2]
a574 1
        * \\g
d582 1
a582 1
        * \\g
d590 2
a591 1
        * \\g
d600 1
a600 1
        * create manager (name = char[], employees = text[])
d602 2
a603 1
        * append manager (name = "mike", employees = "{"wei", "greg", "jeff"}")
d605 2
a606 1
        * append manager (name = "alice", employees = "{"bill", "joe"}")
d608 2
a609 1
        * append manager (name = "marge", employees = "{"mike", "alice"}")
a610 1
        * \\g
d618 2
a619 1
        * retrieve (manager.name) where manager.employees[1][1] = 'b'
d621 2
a622 1
        * retrieve (manager.name) where manager.employees[3] = "jeff"
d624 1
a624 1
        * retrieve (manager.employees[3][2])
d626 1
a626 1
        * delete manager where manager.employees[2][1] = 'g'
a627 1
        * \\g
d629 2
a630 1
will all work.
d636 1
a636 1
In this section, we will discuss those features of \*(PP which
d638 1
a638 1
travel.  In the next section, we will cover how the user can extend
d647 1
a647 1
.b foo
d651 1
a651 1
Now create a second class STUD_EMP, as follows:
d656 7
a662 1
        * \\g
d669 1
a669 1
the inheritance hierarchy is thereby a directed graph in general. 
d673 1
a673 1
employees over 40:
d677 1
a677 1
        * retrieve (E.name) from E in EMP where E.age > 40
d679 2
a680 1
        * \\g
d682 2
a683 2
On the other hand, if one wanted the names of all student
employees and employees over 40, the notation is:
d686 3
a688 1
        * retrieve (E.name) from E in EMP* where E.age > 40
d697 2
a698 3
relational data type.  A \*(PP installation can be customized
with an arbitrary number of user-defined data types; this will be discussed
later.
d708 1
a708 1
    * retrieve (EMP.salary) using EMP[T] where EMP.name="Sam"
d710 1
a710 1
    * \\g
d714 20
a733 1
valid at the correct time and get the appropriate salary.
d761 2
a762 1
        * \\g
d773 1
a773 1
        * \\g
d788 1
a788 1
        * addattr EMP (manager=EMP)
d790 1
a790 1
        * \\g
d808 1
a808 1
       * \\g
d819 1
a819 1
       * \\g
d839 1
a839 1
        * \\g
d858 1
a858 1
        * \\g
d866 1
a866 1
        * \\g
@


1.3
log
@fix reported from Greg
@
text
@d2 1
a2 1
.\" $Header: /users/mer/postgres/doc/RCS/manual.me,v 1.2 1991/12/02 05:16:06 kemnitz Exp mer $
d1709 8
d1723 4
a1726 3
pg_am contains one instance for every user defined access method.  Support
for the HEAP access method is built into \*(PP, but every other access method
is described here.  The schema is
d1737 2
d1740 1
a1740 1
          for example, regproc ids for opening, closing, and getting instances
a1741 1

d1745 1
a1745 1
other classes.  For BTREES, this object ID is 400.  You don't need to add
d1747 1
a1747 1
the BTREE instance.
d1750 2
a1751 2

        * retrieve (pg_am.oid) where pg_am.amname = "btree" 
d1753 1
a1753 1
        * \\g
d1758 1
a1758 1
    | 400         |
d1760 1
a1760 1

d1763 3
a1765 1
The AMSTRATEGIES attribute exists to standardize comparisons across data
d1768 1
a1768 1
in general look at the name of an operator (eg, ">", "<") and tell what sort
d1779 4
a1782 2
to add a new operator class.  In the pg_am class, the AMSTRATEGIES attribute
is the number of strategies defined for this access method.  For BTREES, this
d1786 6
a1791 6

    less than        1
    less than or equal    2
    equal            3
    greater than or equal    4
    greater than        5
d1801 46
a1846 10
The AMSTRATEGIES 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 pg_am.
.lp
The next class of interest is PG_OPCLASS.  This class exists only to associate
a name with an oid.  In pg_amop, every operator class has a set of procedures,
one through five, above.  Some existing opclasses are int2_ops, int4_ops, and
oid_ops.  You need to add an instance with your opclass name (for example,
"int4_abs_ops") to pg_opclass.  The oid of this instance is a foreign key in
other classes.
d1849 1
a1849 1

d1851 1
a1851 1
       * \\g
d1856 1
a1856 1
       * \\g
d1870 13
a1882 4
So now you have an access method and an operator class. You need some
operators; use the method for defining operators discussed previously.
Now, suppose the c
code that implements the functions defined is stored in the file
d1904 10
a1913 7
There are a couple of important things that are happening below.  First,
note that operators for less, less equal, equal, greater equal, and greater for
int4 are being defined.  All of these operators are already defined
for int4 under the names "<", "<=", "=", ">=", and ">".  The new operators
behave differently, of course.  In order to guarantee that \*(PP 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
d1917 2
a1918 2
That is, if you have "<" defined for (int4, int4), you can't define it
again.  \*(PP 
d1920 2
a1921 1
check this when you define your operator, so be careful.
d1923 3
a1925 4
odd names will be used for the operators.  If you *do* get this wrong, the
access methods are likely to 
.b crash
when you try to do scans.
d1931 46
a1976 53

so here goes -- let's define some functions.

       * define function int4_abs_lt
               (file = "/usr/postgres/tutorial/int4_abs.o", language = "c",
                returntype = bool)
               arg is (int4, int4)
                
       * \\g

       * define function int4_abs_le
               (file = "/usr/postgres/tutorial/int4_abs.o", language = "c",
                returntype = bool)
               arg is (int4, int4)
       
       * \\g

       * define function int4_abs_eq
               (file = "/usr/postgres/tutorial/int4_abs.o", language = "c",
                returntype = bool)
               arg is (int4, int4)

       * \\g

       * define function int4_abs_ge
               (file = "/usr/postgres/tutorial/int4_abs.o", language = "c",
                returntype = bool)
               arg is (int4, int4)

       * \\g

       * define function int4_abs_gt
               (file = "/usr/postgres/tutorial/int4_abs.o", language = "c",
                returntype = bool)
               arg is (int4, int4)
        
       * \\g

.)l
.lp
Now define the operators that use them.  As noted, the operator names
must be unique for two int4 operands.  You can do a query on pg_operator
.(l

       * retrieve (pg_operator.all)

       * \\g
.)l
to see if your name is taken for the types you want.  The important things here
are the procedure (which is the C function 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, equal, and greater
cases.  These 
d1978 4
a1981 5
be supplied or the access method will
.b die
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.
@


1.2
log
@fixed up some stupidities.
@
text
@d2 1
a2 1
.\" $Header: RCS/manual.me,v 1.1 91/12/02 04:07:14 kemnitz Exp Locker: kemnitz $
d1594 1
a1594 1
       * retrieve (test.all) where test.a[3] = test.b[1]
@


1.1
log
@Initial revision
@
text
@d2 1
a2 1
.\" $Header: RCS/pgtmacs,v 1.1 90/07/18 16:26:06 mao Exp $
d196 1
a196 1
immediately into the appendix of this manual.
d285 1
a285 2
appendix of this manual, in the "libpq" section.
.b libpq
d292 1
a292 1
This facility is described in the appendix under "Fast Path".
d371 1
a371 1
on "monitor" in the Unix section of the Appendix.
d385 1
a385 1
which are discussed further in the Unix section of the Appendix.
d585 1
a585 1
'j'.  SAL_EMP should now contain only bill.
d627 1
a627 1
as user extensions to \*(PQ using
d687 1
a687 1
    * retrieve (EMP.salary) using EMP [T] where EMP.name="Sam"
d689 1
a689 1
    * \g
d738 1
a738 1
.sh 2 "Composite Objects"
d743 1
a743 1
objects.  For example, consider extending the EMP class with a
d829 1
a829 1
.sh 2 "User Defined Types, Operators, and Programming Language Functions"
d847 1
a847 1
.sh 3 "Internal storage of types" 
d855 1
a855 1
.sh 3 "Functions needed for a user-defined type"
d1246 5
a1250 5
C language method in \*(PP takes an argument named 
where emp is an instance in the emp class.  Because of this, \*(PP has a
notion of the "current instance" which is being examined in the course of
processing a query.  The current instance is simply the instance being
qualified at the moment your function is called.
a1257 5
Unlike functions that take simple types as arguments, these functions must
call the \*(PP library function
.b GetAttribute,
whose use will be described below.
.lp
d1270 1
a1270 1
        age=(short) GetAttribute("age");
d1273 1
a1273 1
        return (salary > (age * performance));
d1297 2
a1298 2
Note that in queries, the instance argument must be the first
argument.
d1300 1
a1300 1
To let \*(PP know about the first "overpaid" function,
d1332 2
a1333 1
is ommitted.
d1341 1
a1341 1
creates a type suitable for an array of that type.
d1371 1
a1371 1
.b NOTE
d1432 1
a1432 1
              where s.a[1][3] = stuff.a[1][3]
d1667 1
a1667 1
       * create maps (name = text, a = big_object)
@
