|
+
Translation
- box '((0,0),(1,1))' + point '(2.0,0)'
+ box '((0,0),(1,1))' + point '(2.0,0)'
|
-
Translation
- box '((0,0),(1,1))' - point '(2.0,0)'
+ box '((0,0),(1,1))' - point '(2.0,0)'
|
*
Scaling/rotation
- box '((0,0),(1,1))' * point '(2.0,0)'
+ box '((0,0),(1,1))' * point '(2.0,0)'
|
/
Scaling/rotation
- box '((0,0),(2,2))' / point '(2.0,0)'
+ box '((0,0),(2,2))' / point '(2.0,0)'
|
#
Intersection
- '((1,-1),(-1,1))' # '((1,1),(-1,-1))'
+ '((1,-1),(-1,1))' # '((1,1),(-1,-1))'
|
#
Number of points in polygon
- # '((1,0),(0,1),(-1,0))'
+ # '((1,0),(0,1),(-1,0))'
|
##
Point of closest proximity
- point '(0,0)' ## lseg '((2,0),(0,2))'
+ point '(0,0)' ## lseg '((2,0),(0,2))'
|
&&
Overlaps?
- box '((0,0),(1,1))' && box '((0,0),(2,2))'
+ box '((0,0),(1,1))' && box '((0,0),(2,2))'
|
&<
Overlaps to left?
- box '((0,0),(1,1))' &< box '((0,0),(2,2))'
+ box '((0,0),(1,1))' &< box '((0,0),(2,2))'
|
&>
Overlaps to right?
- box '((0,0),(3,3))' &> box '((0,0),(2,2))'
+ box '((0,0),(3,3))' &> box '((0,0),(2,2))'
|
<->
Distance between
- circle '((0,0),1)' <-> circle '((5,0),1)'
+ circle '((0,0),1)' <-> circle '((5,0),1)'
|
<<
Left of?
- circle '((0,0),1)' << circle '((5,0),1)'
+ circle '((0,0),1)' << circle '((5,0),1)'
|
<^
Is below?
- circle '((0,0),1)' <^ circle '((0,5),1)'
+ circle '((0,0),1)' <^ circle '((0,5),1)'
|
>>
Is right of?
- circle '((5,0),1)' >> circle '((0,0),1)'
+ circle '((5,0),1)' >> circle '((0,0),1)'
|
>^
Is above?
- circle '((0,5),1)' >^ circle '((0,0),1)'
+ circle '((0,5),1)' >^ circle '((0,0),1)'
|
?#
Intersects or overlaps
- lseg '((-1,0),(1,0))' ?# box '((-2,-2),(2,2))';
+ lseg '((-1,0),(1,0))' ?# box '((-2,-2),(2,2))'
|
?-
Is horizontal?
- point '(1,0)' ?- point '(0,0)'
+ point '(1,0)' ?- point '(0,0)'
|
?-|
Is perpendicular?
- lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))'
+ lseg '((0,0),(0,1))' ?-| lseg '((0,0),(1,0))'
|
@-@
Length or circumference
- @-@ path '((0,0),(1,0))'
+ @-@ path '((0,0),(1,0))'
|
?|
Is vertical?
- point '(0,1)' ?| point '(0,0)'
+ point '(0,1)' ?| point '(0,0)'
|
?||
Is parallel?
- lseg '((-1,0),(1,0))' ?|| lseg '((-1,2),(1,2))'
+ lseg '((-1,0),(1,0))' ?|| lseg '((-1,2),(1,2))'
|
@
Contained or on
- point '(1,1)' @ circle '((0,0),2)'
+ point '(1,1)' @ circle '((0,0),2)'
|
@@
Center of
- @@ circle '((0,0),10)'
+ @@ circle '((0,0),10)'
|
~=
Same as
- polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'
+ polygon '((0,0),(1,1))' ~= polygon '((1,1),(0,0))'
|
- area(object)
- double precision
+ area(object)
+ double precision
area of item
- area(box '((0,0),(1,1))')
+ area(box '((0,0),(1,1))')
|
- box(box, box)
- box
+ box(box, box)
+ box
intersection box
- box(box '((0,0),(1,1))',box '((0.5,0.5),(2,2))')
+ box(box '((0,0),(1,1))',box '((0.5,0.5),(2,2))')
|
- center(object)
- point
+ center(object)
+ point
center of item
- center(box '((0,0),(1,2))')
+ center(box '((0,0),(1,2))')
|
- diameter(circle)
- double precision
+ diameter(circle)
+ double precision
diameter of circle
- diameter(circle '((0,0),2.0)')
+ diameter(circle '((0,0),2.0)')
|
- height(box)
- double precision
+ height(box)
+ double precision
vertical size of box
- height(box '((0,0),(1,1))')
+ height(box '((0,0),(1,1))')
|
- isclosed(path)
- boolean
+ isclosed(path)
+ boolean
a closed path?
- isclosed(path '((0,0),(1,1),(2,0))')
+ isclosed(path '((0,0),(1,1),(2,0))')
|
- isopen(path)
- boolean
+ isopen(path)
+ boolean
an open path?
- isopen(path '[(0,0),(1,1),(2,0)]')
+ isopen(path '[(0,0),(1,1),(2,0)]')
|
- length(object)
- double precision
+ length(object)
+ double precision
length of item
- length(path '((-1,0),(1,0))')
+ length(path '((-1,0),(1,0))')
|
- pclose(path)
- path
+ pclose(path)
+ path
convert path to closed
- popen(path '[(0,0),(1,1),(2,0)]')
+ popen(path '[(0,0),(1,1),(2,0)]')
---
-Not defined by this name. Implements the intersection operator '#'
+[IGNORE[
+
|
- point(lseg,lseg)
- point
+ point(lseg,lseg)
+ point
intersection
- point(lseg '((-1,0),(1,0))',lseg '((-2,-2),(2,2))')
+ point(lseg '((-1,0),(1,0))',lseg '((-2,-2),(2,2))')
--->
+]]>
|
- npoint(path)
- int4
+ npoint(path)
+ integer
number of points
- npoints(path '[(0,0),(1,1),(2,0)]')
+ npoints(path '[(0,0),(1,1),(2,0)]')
|
- popen(path)
- path
+ popen(path)
+ path
convert path to open path
- popen(path '((0,0),(1,1),(2,0))')
+ popen(path '((0,0),(1,1),(2,0))')
|
- radius(circle)
- double precision
+ radius(circle)
+ double precision
radius of circle
- radius(circle '((0,0),2.0)')
+ radius(circle '((0,0),2.0)')
|
- width(box)
- double precision
+ width(box)
+ double precision
horizontal size
- width(box '((0,0),(1,1))')
+ width(box '((0,0),(1,1))')
|
- box(circle)
- box
+ box(circle)
+ box
circle to box
- box(circle '((0,0),2.0)')
+ box(circle '((0,0),2.0)')
|
- box(point, point)
- box
+ box(point, point)
+ box
points to box
- box(point '(0,0)', point '(1,1)')
+ box(point '(0,0)', point '(1,1)')
|
- box(polygon)
- box
+ box(polygon)
+ box
polygon to box
- box(polygon '((0,0),(1,1),(2,0))')
+ box(polygon '((0,0),(1,1),(2,0))')
|
- circle(box)
- circle
+ circle(box)
+ circle
to circle
- circle(box '((0,0),(1,1))')
+ circle(box '((0,0),(1,1))')
|
- circle(point, double precision)
- circle
+ circle(point, double precision)
+ circle
point to circle
- circle(point '(0,0)', 2.0)
+ circle(point '(0,0)', 2.0)
|
- lseg(box)
- lseg
+ lseg(box)
+ lseg
box diagonal to lseg
- lseg(box '((-1,0),(1,0))')
+ lseg(box '((-1,0),(1,0))')
|
- lseg(point, point)
- lseg
+ lseg(point, point)
+ lseg
points to lseg
- lseg(point '(-1,0)', point '(1,0)')
+ lseg(point '(-1,0)', point '(1,0)')
|
- path(polygon)
- point
+ path(polygon)
+ point
polygon to path
- path(polygon '((0,0),(1,1),(2,0))')
+ path(polygon '((0,0),(1,1),(2,0))')
|
- point(circle)
- point
+ point(circle)
+ point
center
- point(circle '((0,0),2.0)')
+ point(circle '((0,0),2.0)')
|
- point(lseg, lseg)
- point
+ point(lseg, lseg)
+ point
intersection
- point(lseg '((-1,0),(1,0))', lseg '((-2,-2),(2,2))')
+ point(lseg '((-1,0),(1,0))', lseg '((-2,-2),(2,2))')
|
- point(polygon)
- point
+ point(polygon)
+ point
center
- point(polygon '((0,0),(1,1),(2,0))')
+ point(polygon '((0,0),(1,1),(2,0))')
|
- polygon(box)
- polygon
+ polygon(box)
+ polygon
12 point polygon
- polygon(box '((0,0),(1,1))')
+ polygon(box '((0,0),(1,1))')
|
- polygon(circle)
- polygon
+ polygon(circle)
+ polygon
12-point polygon
- polygon(circle '((0,0),2.0)')
+ polygon(circle '((0,0),2.0)')
|
- polygon(npts, circle)
- polygon
+ polygon(npts, circle)
+ polygon
npts polygon
- polygon(12, circle '((0,0),2.0)')
+ polygon(12, circle '((0,0),2.0)')
|
- polygon(path)
- polygon
+ polygon(path)
+ polygon
path to polygon
- polygon(path '((0,0),(1,1),(2,0))')
+ polygon(path '((0,0),(1,1),(2,0))')
|
<
Less than
- inet '192.168.1.5' < inet '192.168.1.6'
+ inet '192.168.1.5' < inet '192.168.1.6'
|
<=
Less than or equal
- inet '192.168.1.5' <= inet '192.168.1.5'
+ inet '192.168.1.5' <= inet '192.168.1.5'
|
=
Equals
- inet '192.168.1.5' = inet '192.168.1.5'
+ inet '192.168.1.5' = inet '192.168.1.5'
|
>=
Greater or equal
- inet '192.168.1.5' >= inet '192.168.1.5'
+ inet '192.168.1.5' >= inet '192.168.1.5'
|
>
Greater
- inet '192.168.1.5' > inet '192.168.1.4'
+ inet '192.168.1.5' > inet '192.168.1.4'
|
<>
Not equal
- inet '192.168.1.5' <> inet '192.168.1.4'
+ inet '192.168.1.5' <> inet '192.168.1.4'
|
<<
is contained within
- inet '192.168.1.5' << inet '192.168.1/24'
+ inet '192.168.1.5' << inet '192.168.1/24'
|
<<=
is contained within or equals
- inet '192.168.1/24' <<= inet '192.168.1/24'
+ inet '192.168.1/24' <<= inet '192.168.1/24'
|
>>
contains
- inet'192.168.1/24' >> inet '192.168.1.5'
+ inet'192.168.1/24' >> inet '192.168.1.5'
|
>>=
contains or equals
- inet '192.168.1/24' >>= inet '192.168.1/24'
+ inet '192.168.1/24' >>= inet '192.168.1/24'
|
- broadcast(inet)
- inet
+ broadcast(inet)
+ inet
broadcast address for network
- broadcast('192.168.1.5/24')
- 192.168.1.255/24
+ broadcast('192.168.1.5/24')
+ 192.168.1.255/24
|
- host(inet)
- text
+ host(inet)
+ text
extract IP address as text
- host('192.168.1.5/24')
- 192.168.1.5
+ host('192.168.1.5/24')
+ 192.168.1.5
|
- masklen(inet)
- integer
+ masklen(inet)
+ integer
extract netmask length
- masklen('192.168.1.5/24')
- 24
+ masklen('192.168.1.5/24')
+ 24
|
- set_masklen(inet,integer)
- inet
+ set_masklen(inet,integer)
+ inet
set netmask length for inet value
- set_masklen('192.168.1.5/24',16)
- 192.168.1.5/16
+ set_masklen('192.168.1.5/24',16)
+ 192.168.1.5/16
|
- netmask(inet)
- inet
+ netmask(inet)
+ inet
construct netmask for network
- netmask('192.168.1.5/24')
- 255.255.255.0
+ netmask('192.168.1.5/24')
+ 255.255.255.0
|
- network(inet)
- cidr
+ network(inet)
+ cidr
extract network part of address
- network('192.168.1.5/24')
- 192.168.1.0/24
+ network('192.168.1.5/24')
+ 192.168.1.0/24
|
- text(inet)
- text
+ text(inet)
+ text
extract IP address and masklen as text
- text(inet '192.168.1.5')
- 192.168.1.5/32
+ text(inet '192.168.1.5')
+ 192.168.1.5/32
|
- abbrev(inet)
- text
+ abbrev(inet)
+ text
extract abbreviated display as text
- abbrev(cidr '10.1.0.0/16')
- 10.1/16
+ abbrev(cidr '10.1.0.0/16')
+ 10.1/16
cidr values as well. The host>(),
text>(), and abbrev>() functions are primarily
intended to offer alternative display formats. You can cast a text
- field to inet using normal casting syntax: inet(fieldname) or
- fieldname::inet.
+ field to inet using normal casting syntax: inet(expression) or
+ colname::inet.
|
- trunc(macaddr)
- macaddr
+ trunc(macaddr)
+ macaddr
set last 3 bytes to zero
- trunc(macaddr '12:34:56:78:90:ab')
- 12:34:56:00:00:00
+ trunc(macaddr '12:34:56:78:90:ab')
+ 12:34:56:00:00:00
|
-
has_table_privilege(user,
+
has_table_privilege(user,
- boolean>
+ boolean>
does user have access to table>
|
-
has_table_privilege(table,
+
has_table_privilege(table,
- boolean>
+ boolean>
does current user have access to table>
has_table_privilege> determines whether a user
can access a table in a particular way. The user can be
- specified by name or by usesysid, or if the argument is omitted
+ specified by name or by ID (pg_user>.usesysid>) or if the argument is omitted
current_user> is assumed. The table can be specified
by name or by OID. (Thus, there are actually six variants of
has_table_privilege>, which can be distinguished by
|
- COUNT(*)
+ count(*)
number of input values
The return value is of type bigint.
|
- COUNT(expression)
+ count(expression)
Counts the input values for which the value of
class="parameter">expression is not NULL.
|
- MAX(expression)
+ max(expression)
the maximum value of expression across all input values
Available for all numeric, string, and date/time types. The
|
- MIN(expression)
+ min(expression)
the minimum value of expression across all input values
Available for all numeric, string, and date/time types. The
|
- STDDEV(expression)
+ stddev(expression)
the sample standard deviation of the input values
|
- SUM(expression)
+ sum(expression)
sum of expression across all input values
Summation is available on the following data types:
|
- VARIANCE(expression)
+ variance(expression)
the sample variance of the input values
California at Berkeley. With over a decade of
development behind it,
PostgreSQL
is the most advanced open-source database available anywhere,
- offering multi-version concurrency control, supporting almost
+ offering multiversion concurrency control, supporting almost
all SQL constructs (including subselects, transactions, and
user-defined types and functions), and having a wide range of
language bindings available (including C, C++, Java, Perl, Tcl, and Python).
Finally,
Illustra Information Technologies
(since merged into
picked up
the code and commercialized it.
Postgres became the primary data manager
A new front-end library, libpgtcl,
supported
Tcl-based clients. A sample shell,
- pgtclsh, provided new Tcl commands to interface
+ pgtclsh, provided new Tcl commands to interface
programs with the
Postgres95 backend.
- Table-level locking has been replaced with multi-version concurrency control,
+ Table-level locking has been replaced with multiversion concurrency control,
which allows readers to continue reading consistent data during writer activity
and enables hot backups from pg_dump while the database stays available for
queries.
-
+
Indexes
retrieving by that combination! However, if you want to make the retrieval
efficient, you'll have to resort to the means your
- - be it an index, my imaginary MEMSTORE command, or an intelligent
+ - be it an index, my imaginary MEMSTORE command, or an intelligent
that creates indexes without your knowledge based on the fact that you have
sent it many queries based on a specific combination of keys... (It learns
that involve deciding what predicate(s) match the workload/query in
some useful way. For those who are into database theory, the problems
are basically analogous to the corresponding materialized view
- problems, albeit with different cost parameters and formulae. These
+ problems, albeit with different cost parameters and formulas. These
are, in the general case, hard problems for the standard ordinal
types; they're super-hard problems with black-box extension types,
- The inheritance hierarchy is a actually a directed acyclic graph.
+ The inheritance hierarchy is actually a directed acyclic graph.
In some cases you may wish to know which table a particular tuple
originated from. There is a system column called
- <quote>TABLEOID> in each table which can tell you the
+ <structfield>TABLEOID> in each table which can tell you the
originating table:
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
PROVIDED HEREUNDER IS ON AN "AS-IS" BASIS, AND THE UNIVERSITY OF
- CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTAINANCE, SUPPORT,
+ CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT,
UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
Managing a Database
-
- This section is currently a thinly disguised copy of the
- Tutorial. Needs to be augmented.
+
+ This section is currently a thinly disguised copy of the
+ Tutorial. Needs to be augmented.
- thomas 1998-01-12
-
-
+
Although the site administrator is responsible for overall management
Alternate database locations are created and referenced by an environment variable
which gives the absolute path to the intended storage location.
This environment variable must have been defined before the postmaster was started
- and the location it points to must be writable by the postgres administrator account.
+ and the location it points to must be writable by the administrator account.
Consult with the site administrator
- regarding preconfigured alternate database locations.
+ regarding preconfigured alternative database locations.
Any valid environment variable name may be used to reference an alternate location,
although using variable names with a prefix of PGDATA is recommended
to avoid confusion
In previous versions of
Postgres,
- it was also permissable to use an absolute path name to specify
+ it was also permissible to use an absolute path name to specify
an alternate storage location.
Although the environment variable style of specification
is to be preferred since it allows the site administrator more flexibility in
- writing a C program using the LIBPQ subroutine
+ writing a C program using the
LIBPQ subroutine
library. This allows you to submit
SQL commands
from C and get answers and status messages back to
your program. This interface is discussed further
-This prompt indicates that psql is listening
+This prompt indicates that psql is listening
to you and that you can type
SQL queries into a
workspace maintained by the terminal monitor.
The
psql program responds to escape codes that begin
terminate your query with a semicolon, the "\g" is not
necessary.
psql will automatically process semicolon terminated queries.
- To read queries from a file, say myFile, instead of
+ To read queries from a file, say myFile, instead of
entering them interactively, type:
mydb=> \i fileName
and
psql will quit and return you to your command
- shell. (For more escape codes, type \? at the psql
+ shell. (For more escape codes, type \? at the psql
prompt.)
White space (i.e., spaces, tabs and newlines) may be
used freely in
SQL queries. Single-line comments are denoted by
- GiST and R-Tree indexes
+
GiST and R-Tree indexes
Examples will show commands executed from various accounts and programs.
- Commands executed from a Unix shell may be preceeded with a dollar sign
+ Commands executed from a Unix shell may be preceded with a dollar sign
($
). Commands executed from particular user
- accounts such as root or postgres are specially flagged and explained.
-
SQL commands may be prece
eded with
+ accounts such as root> or postgres> are specially flagged and explained.
+
SQL commands may be preceded with
=>
or will have no leading prompt, depending on the context.
The notation for
- flagging commands is not universally consistant throughout the
+ flagging commands is not universally consistent throughout the
documentation set.
Please report problems to the documentation mailing list
select * from pg_class where relname = 'tenk1';
- you'll find out that tenk1 has 233 disk
+ you will find out that tenk1 has 233 disk
pages and 10000 tuples. So the cost is estimated at 233 page
- reads, defined as 1.0 apiece, plus 10000 * cpu_tuple_cost which is
+ reads, defined as 1.0 apiece, plus 10000 * cpu_tuple_cost which is
currently 0.01 (try show cpu_tuple_cost).
and you will see that if we make the WHERE condition selective
enough, the planner will
- eventually decide that an indexscan is cheaper than a sequential scan.
+ eventually decide that an index scan is cheaper than a sequential scan.
This plan will only have to visit 50 tuples because of the index,
so it wins despite the fact that each individual fetch is more expensive
than reading a whole disk page sequentially.
Index Scan using tenk1_unique1 on tenk1 (cost=0.00..173.44 rows=1 width=148)
- The added clause "stringu1 = 'xxx'" reduces the output-rows estimate,
+ The added clause stringu1 = 'xxx' reduces the output-rows estimate,
but not the cost because we still have to visit the same set of tuples.
- In this nested-loop join, the outer scan is the same indexscan we had
+ In this nested-loop join, the outer scan is the same index scan we had
in the example before last, and so its cost and row count are the same
because we are applying the "unique1 < 50" WHERE clause at that node.
The "t1.unique2 = t2.unique2" clause isn't relevant yet, so it doesn't
- affect the outer scan's row count. For the inner scan, the
+ affect row count of the outer scan. For the inner scan, the unique2 value of the
current
- outer-scan tuple's unique2 value is plugged into the inner indexscan
- to produce an indexqual like
+ outer-scan tuple is plugged into the inner index scan
+ to produce an index qualification like
"t2.unique2 = constant". So we get the
- same inner-scan plan and costs that we'd get from, say, "explain select
- * from tenk2 where unique2 = 42". The loop node's costs are then set
- on the basis of the outer scan's cost, plus one repetition of the
+ same inner-scan plan and costs that we'd get from, say, explain select
+ * from tenk2 where unique2 = 42. The costs of the loop node are then set
+ on the basis of the cost of the outer scan, plus one repetition of the
inner scan for each outer tuple (47 * 2.01, here), plus a little CPU
time for join processing.
in general you can have WHERE clauses that mention both relations and
so can only be applied at the join point, not to either input scan.
For example, if we added "WHERE ... AND t1.hundred < t2.hundred",
- that'd decrease the output row count of the join node, but not change
+ that would decrease the output row count of the join node, but not change
either input scan.
(cost=0.00..173.32 rows=47 width=148)
- This plan proposes to extract the 50 interesting rows of tenk1
- using ye same olde indexscan, stash them into an in-memory hash table,
- and then do a sequential scan of tenk2, probing into the hash table
- for possible matches of "t1.unique2 = t2.unique2" at each tenk2 tuple.
- The cost to read tenk1 and set up the hash table is entirely start-up
+ This plan proposes to extract the 50 interesting rows of tenk1
+ using ye same olde index scan, stash them into an in-memory hash table,
+ and then do a sequential scan of tenk2, probing into the hash table
+ for possible matches of "t1.unique2 = t2.unique2" at each tenk2 tuple.
+ The cost to read tenk1 and set up the hash table is entirely start-up
cost for the hash join, since we won't get any tuples out until we can
- start reading tenk2. The total time estimate for the join also
+ start reading tenk2. The total time estimate for the join also
includes a hefty charge for CPU time to probe the hash table
10000 times. Note, however, that we are NOT charging 10000 times 173.32;
the hash table setup is only done once in this plan type.
annoyingly long time. When there are too many input tables, the
Postgres planner will switch from exhaustive
search to a genetic probabilistic search
- through a limited number of possibilities. (The switchover threshold is
- set by the GEQO_THRESHOLD run-time
+ through a limited number of possibilities. (The switch-over threshold is
+ set by the GEQO_THRESHOLD run-time
parameter described in the Administrator's Guide.)
The genetic search takes less time, but it won't
necessarily find the best possible plan.
query.
You are encouraged to
minimize the size of your example, but this is not absolutely necessary.
- If the bug is reproduceable, we will find it either way.
+ If the bug is reproducible, we will find it either way.
- If your application uses some other client interface, such as PHP, then
+ If your application uses some other client interface, such as
PHP>, then
please try to isolate the offending queries. We will probably not set up a
web server to reproduce your problem. In any case remember to provide
the exact input files, do not guess that the problem happens for
The output you expected is very important to state. If you just write
"This command gives me that output." or "This is not
what I expected.", we might run it ourselves, scan the output, and
- think it looks okay and is exactly what we expected. We should not have to
+ think it looks OK and is exactly what we expected. We should not have to
spend the time to decode the exact semantics behind your commands.
Especially refrain from merely saying that "This is not what SQL says/Oracle
does." Digging out the correct behavior from
SQL
Any command line options and other start-up options, including concerned
environment variables or configuration files that you changed from the
- default. Again, be exact. If you are using a pre-packaged
+ default. Again, be exact. If you are using a prepackaged
distribution that starts the database server at boot time, you should try
to find out how that is done.
old enough. You can also look into the README file
in the source directory or at the
name of your distribution file or package name.
- If you run a pre-packaged version, such as RPMs, say so, including any
+ If you run a prepackaged version, such as RPMs, say so, including any
subversion the package may have. If you are talking about a CVS
snapshot, mention that, including its date and time.
-
+
Queries
A table reference may be a table name or a derived table such as a
subquery, a table join, or complex combinations of these. If more
than one table reference is listed in the FROM clause they are
- CROSS JOINed (see below) to form the derived table that may then
+ cross-joined (see below) to form the derived table that may then
be subject to transformations by the WHERE, GROUP BY, and HAVING
clauses and is finally the result of the overall table expression.
- Qualified JOINs
+ Qualified joins
The words INNER and OUTER are
- optional for all JOINs. INNER is the default;
+ optional for all joins. INNER is the default;
LEFT, RIGHT, and
FULL imply an OUTER JOIN.
Joins of all types can be chained together or nested: either
or both of T1 and
- T2 may be JOINed tables. Parentheses
+ T2 may be joined tables. Parentheses
may be used around JOIN clauses to control the join order. In the
absence of parentheses, JOIN clauses nest left-to-right.
Which one of these you use is mainly a matter of style. The JOIN
syntax in the FROM clause is probably not as portable to other
products. For outer joins there is no choice in any case: they
- must be done in the FROM clause. An outer join's ON/USING clause
+ must be done in the FROM clause. A ON/USING clause of an outer join
is not> equivalent to a WHERE condition, because it
determines the addition of rows (for unmatched input rows) as well
as the removal of rows from the final result.
- In the examples above, FDT is the table derived in the FROM
- clause. Rows that do not meet the search condition of the where
- clause are eliminated from FDT. Notice the use of scalar
- subqueries as value expressions. Just like
- any other query, the subqueries can employ complex table
- expressions. Notice how FDT is referenced in the subqueries.
- Qualifying C1 as FDT.C1 is only necessary if C1 is also the name of a
- column in the derived input table of the subquery. Qualifying the
- column name adds clarity even when it is not needed. This shows how
- the column naming scope of an outer query extends into its inner queries.
+ In the examples above, FDT is the table derived
+ in the FROM clause. Rows that do not meet the search condition of
+ the where clause are eliminated from
+ FDT. Notice the use of scalar subqueries as
+ value expressions. Just like any other query, the subqueries can
+ employ complex table expressions. Notice how
+ FDT is referenced in the subqueries.
+ Qualifying C1> as FDT.C1> is only necessary
+ if C1> is also the name of a column in the derived
+ input table of the subquery. Qualifying the column name adds
+ clarity even when it is not needed. This shows how the column
+ naming scope of an outer query extends into its inner queries.
FROM products p LEFT JOIN sales s USING ( pid )
GROUP BY pid, p.name, p.price;
- In this example, the columns pid, p.name, and p.price must be in
+ In this example, the columns pid, p.name, and p.price must be in
the GROUP BY clause since they are referenced in the query select
list. The column s.units does not have to be in the GROUP BY list
since it is only used in an aggregate expression
SELECT a AS b FROM table1 ORDER BY a;
But these extensions do not work in queries involving UNION, INTERSECT,
- or EXCEPT, and are not portable to other DBMSes.
+ or EXCEPT, and are not portable to other
DBMS.
- Each column specification may be followed by an optional ASC or
- DESC to set the sort direction. ASC is default. Ascending order
+ Each column specification may be followed by an optional ASC or
+ DESC to set the sort direction. ASC is default. Ascending order
puts smaller values first, where smaller
is defined
in terms of the < operator. Similarly,
descending order is determined with the >
"$" (dollar) cannot be a single-character operator, although it
- can be part of a multi-character operator name.
+ can be part of a multiple-character operator name.
- A multi-character operator name cannot end in "+" or "-",
+ A multiple-character operator name cannot end in "+" or "-",
unless the name also contains at least one of these characters:
~ ! @ # % ^ & | ` ? $
Alternatively, C-style block comments can be used:
-/* multi-line comment
+/* multiline comment
* with nesting: /* nested block comment */
*/
- oid
+ oid>
- tableoid
+ tableoid>
The OID of the table containing this row. This attribute is
particularly handy for queries that select from inheritance
hierarchies, since without it, it's difficult to tell which
- individual table a row came from. The tableoid can be joined
- against the OID attribute of pg_class to obtain the table name.
+ individual table a row came from. The
+ tableoid can be joined against the
+ oid column of
+ pg_class to obtain the table name.
- xmin
+ xmin>
The identity (transaction ID) of the inserting transaction for
- cmin
+ cmin>
The command identifier (starting at zero) within the inserting
- xmax
+ xmax>
The identity (transaction ID) of the deleting transaction,
- cmax
+ cmax>
The command identifier within the deleting transaction, or zero.
- ctid
+ ctid>
The tuple ID of the tuple within its table. This is a pair
(block number, tuple index within block) that identifies the
- physical location of the tuple. Note that although the ctid
- can be used to locate the tuple very quickly, a row's ctid
+ physical location of the tuple. Note that although the ctid
+ can be used to locate the tuple very quickly, a row's ctid
will change each time it is updated or moved by VACUUM
FULL>.
- Therefore ctid is useless as a long-term row identifier.
+ Therefore ctid is useless as a long-term row identifier.
The OID, or even better a user-defined serial number, should
be used to identify logical rows.
Recommended practice when using OIDs for row identification is to create
a unique index on the OID column of each table for which the OID will be
used. Never assume that OIDs are unique across tables; use the
- combination of tableoid and row OID if you need a database-wide
+ combination of tableoid> and row OID if you need a database-wide
identifier. (Future releases of Postgres are likely to use a separate
- OID counter for each table, so that tableoid must> be
+ OID counter for each table, so that tableoid> must> be
included to arrive at a globally unique identifier.)
An additional heuristic is provided in the parser to allow better guesses
at proper behavior for
SQL standard types. There are
-several basic type categories defined: boolean,
-numeric, string, bitstring, datetime, timespan, geometric, network,
+several basic type categories defined: boolean,
+numeric, string, bitstring, datetime, timespan, geometric, network,
and user-defined. Each category, with the exception of user-defined, has
a preferred type which is preferentially selected
when there is ambiguity.
-If any input arguments are "unknown", check the type categories accepted
+If any input arguments are unknown
, check the type categories accepted
at those argument positions by the remaining candidates. At each position,
select "string"
category if any candidate accepts that category (this bias towards string
Otherwise, if all the remaining candidates accept the same type category,
select that category; otherwise fail because
the correct choice cannot be deduced without more clues. Also note whether
-any of the candidates accept a preferred datatype within the selected category.
+any of the candidates accept a preferred data type within the selected category.
Now discard operator candidates that do not accept the selected type category;
furthermore, if any candidate accepts a preferred type at a given argument
position, discard candidates that accept non-preferred types for that
In this case there is no initial hint for which type to use, since no types
are specified in the query. So, the parser looks for all candidate operators
and finds that there are candidates accepting both string-category and
-bitstring-category inputs. Since string category is preferred when available,
+bit-string-category inputs. Since string category is preferred when available,
that category is selected, and then the
"preferred type" for strings, text, is used as the specific
type to resolve the unknown literals to.
-Check for an exact match in the pg_proc system catalog.
+Check for an exact match in the pg_proc system catalog.
(Cases involving unknown will never find a match at
this step.)
Otherwise, if all the remaining candidates accept the same type category,
select that category; otherwise fail because
the correct choice cannot be deduced without more clues. Also note whether
-any of the candidates accept a preferred datatype within the selected category.
+any of the candidates accept a preferred data type within the selected category.
Now discard operator candidates that do not accept the selected type category;
furthermore, if any candidate accepts a preferred type at a given argument
position, discard candidates that accept non-preferred types for that
If no best match could be identified, see whether the function call appears
to be a trivial type coercion request. This happens if the function call
has just one argument and the function name is the same as the (internal)
-name of some datatype. Furthermore, the function argument must be either
+name of some data type. Furthermore, the function argument must be either
an unknown-type literal or a type that is binary-compatible with the named
-datatype. When these conditions are met, the function argument is coerced
-to the named datatype.
+data type. When these conditions are met, the function argument is coerced
+to the named data type.
Factorial Function
-There is only one factorial function defined in the pg_proc catalog.
+There is only one factorial function defined in the pg_proc catalog.
So the following query automatically converts the int2 argument
to int4:
Substring Function
-There are two substr functions declared in pg_proc. However,
+There are two substr functions declared in pg_proc. However,
only one takes two arguments, of types text and int4.
What's really happened here is that the two unknown literals are resolved
to text by default, allowing the || operator to be
resolved as text concatenation. Then the text result of the operator
-is coerced to varchar to match the target column type. (But, since the
-parser knows that text and varchar are binary-compatible, this coercion
+is coerced to varchar to match the target column type. (But, since the
+parser knows that text and varchar are binary-compatible, this coercion
is implicit and does not insert any real function call.) Finally, the
sizing function varchar(varchar,int4) is found in the system
catalogs and applied to the operator's result and the stored column length.