<!--
-$PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.54 2004/12/28 19:08:58 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/backup.sgml,v 2.55 2005/01/22 22:56:35 momjian Exp $
-->
<chapter id="backup">
<title>Backup and Restore</title>
following command dumps a database using the custom dump format:
<programlisting>
-pg_dump -Fc <replaceable class="parameter">dbname</replaceable> > <replaceable class="parameter">filename</replaceable>
+pg_dump -Fc <replaceable class="parameter">dbname</replaceable> > <replaceable class="parameter">filename</replaceable>
</programlisting>
A custom-format dump is not a script for <application>psql</>, but
version, start the new server, restore the data. For example:
<programlisting>
-pg_dumpall > backup
+pg_dumpall > backup
pg_ctl stop
mv /usr/local/pgsql /usr/local/pgsql.old
cd ~/postgresql-&version;
gmake install
initdb -D /usr/local/pgsql/data
postmaster -D /usr/local/pgsql/data
-psql template1 < backup
+psql template1 < backup
</programlisting>
See <xref linkend="runtime"> about ways to start and stop the
<!--
-$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.154 2005/01/17 18:47:15 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/datatype.sgml,v 1.155 2005/01/22 22:56:35 momjian Exp $
-->
<chapter id="datatype">
</row>
<row>
<entry><literal>04:05 PM</literal></entry>
- <entry>same as 16:05; input hour must be <= 12</entry>
+ <entry>same as 16:05; input hour must be <= 12</entry>
</row>
<row>
<entry><literal>04:05:06.789-8</literal></entry>
<entry><type>circle</type></entry>
<entry>24 bytes</entry>
<entry>Circle</entry>
- <entry><(x,y),r> (center and radius)</entry>
+ <entry><(x,y),r> (center and radius)</entry>
</row>
</tbody>
</tgroup>
-<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.38 2005/01/17 01:29:02 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.39 2005/01/22 22:56:35 momjian Exp $ -->
<chapter id="ddl">
<title>Data Definition</title>
CREATE TABLE products (
product_no integer,
name text,
- price numeric <emphasis>CHECK (price > 0)</emphasis>
+ price numeric <emphasis>CHECK (price > 0)</emphasis>
);
</programlisting>
</para>
CREATE TABLE products (
product_no integer,
name text,
- price numeric <emphasis>CONSTRAINT positive_price</emphasis> CHECK (price > 0)
+ price numeric <emphasis>CONSTRAINT positive_price</emphasis> CHECK (price > 0)
);
</programlisting>
So, to specify a named constraint, use the key word
CREATE TABLE products (
product_no integer,
name text,
- price numeric CHECK (price > 0),
- discounted_price numeric CHECK (discounted_price > 0),
- <emphasis>CHECK (price > discounted_price)</emphasis>
+ price numeric CHECK (price > 0),
+ discounted_price numeric CHECK (discounted_price > 0),
+ <emphasis>CHECK (price > discounted_price)</emphasis>
);
</programlisting>
</para>
product_no integer,
name text,
price numeric,
- CHECK (price > 0),
+ CHECK (price > 0),
discounted_price numeric,
- CHECK (discounted_price > 0),
- CHECK (price > discounted_price)
+ CHECK (discounted_price > 0),
+ CHECK (price > discounted_price)
);
</programlisting>
or even
CREATE TABLE products (
product_no integer,
name text,
- price numeric CHECK (price > 0),
+ price numeric CHECK (price > 0),
discounted_price numeric,
- CHECK (discounted_price > 0 AND price > discounted_price)
+ CHECK (discounted_price > 0 AND price > discounted_price)
);
</programlisting>
It's a matter of taste.
product_no integer,
name text,
price numeric,
- CHECK (price > 0),
+ CHECK (price > 0),
discounted_price numeric,
- CHECK (discounted_price > 0),
- <emphasis>CONSTRAINT valid_discount</> CHECK (price > discounted_price)
+ CHECK (discounted_price > 0),
+ <emphasis>CONSTRAINT valid_discount</> CHECK (price > discounted_price)
);
</programlisting>
</para>
CREATE TABLE products (
product_no integer NOT NULL,
name text NOT NULL,
- price numeric NOT NULL CHECK (price > 0)
+ price numeric NOT NULL CHECK (price > 0)
);
</programlisting>
The order doesn't matter. It does not necessarily determine in which
<!--
-$PostgreSQL: pgsql/doc/src/sgml/dfunc.sgml,v 1.28 2004/11/15 06:32:13 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/dfunc.sgml,v 1.29 2005/01/22 22:56:35 momjian Exp $
-->
<sect2 id="dfunc">
You must then create a symbol \*(lqexports\*(rq file for the object
file:
.nf
-mkldexport foo.o `pwd` > foo.exp
+mkldexport foo.o `pwd` > foo.exp
.fi
Finally, you can create the shared library:
.nf
-<!-- $PostgreSQL: pgsql/doc/src/sgml/dml.sgml,v 1.9 2004/12/23 05:37:39 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/dml.sgml,v 1.10 2005/01/22 22:56:35 momjian Exp $ -->
<chapter id="dml">
<title>Data Manipulation</title>
<literal>UPDATE</literal> command by listing more than one
assignment in the <literal>SET</literal> clause. For example:
<programlisting>
-UPDATE mytable SET a = 5, b = 3, c = 1 WHERE a > 0;
+UPDATE mytable SET a = 5, b = 3, c = 1 WHERE a > 0;
</programlisting>
</para>
</sect1>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/ecpg.sgml,v 1.62 2005/01/08 22:13:25 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ecpg.sgml,v 1.63 2005/01/22 22:56:35 momjian Exp $
-->
<chapter id="ecpg">
<literal>INTO</literal> clause:
<programlisting>
EXEC SQL BEGIN DECLARE SECTION;
-const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?";
+const char *stmt = "SELECT a, b, c FROM test1 WHERE a > ?";
int v1, v2;
VARCHAR v3;
EXEC SQL END DECLARE SECTION;
<!--
-$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.234 2005/01/09 20:08:50 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/func.sgml,v 1.235 2005/01/22 22:56:35 momjian Exp $
PostgreSQL documentation
-->
<row>
<entry> <literal>>^</literal> </entry>
<entry>Is above?</entry>
- <entry><literal>circle '((0,5),1)' >^ circle '((0,0),1)'</literal></entry>
+ <entry><literal>circle '((0,5),1)' >^ circle '((0,0),1)'</literal></entry>
</row>
<row>
<entry> <literal>?#</literal> </entry>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/geqo.sgml,v 1.27 2005/01/05 23:42:03 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/geqo.sgml,v 1.28 2005/01/22 22:56:36 momjian Exp $
Genetic Optimizer
-->
<literallayout class="monospaced">
+=========================================+
-|>>>>>>>>>>> Algorithm GA <<<<<<<<<<<<<<|
+|>>>>>>>>>>> Algorithm GA <<<<<<<<<<<<<<|
+=========================================+
| INITIALIZE t := 0 |
+=========================================+
-<!-- $PostgreSQL: pgsql/doc/src/sgml/indices.sgml,v 1.49 2005/01/08 22:13:25 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/indices.sgml,v 1.50 2005/01/22 22:56:36 momjian Exp $ -->
<chapter id="indexes">
<title id="indexes-title">Indexes</title>
such as this:
<programlisting>
CREATE INDEX access_log_client_ip_ix ON access_log (client_ip)
- WHERE NOT (client_ip > inet '192.168.100.0' AND client_ip < inet '192.168.100.255');
+ WHERE NOT (client_ip > inet '192.168.100.0' AND client_ip < inet '192.168.100.255');
</programlisting>
</para>
<para>
A possible query to use this index would be
<programlisting>
-SELECT * FROM orders WHERE billed is not true AND order_nr < 10000;
+SELECT * FROM orders WHERE billed is not true AND order_nr < 10000;
</programlisting>
However, the index can also be used in queries that do not involve
<structfield>order_nr</> at all, e.g.,
<programlisting>
-SELECT * FROM orders WHERE billed is not true AND amount > 5000.00;
+SELECT * FROM orders WHERE billed is not true AND amount > 5000.00;
</programlisting>
This is not as efficient as a partial index on the
<structfield>amount</> column would be, since the system has to
<!--
-$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.57 2005/01/15 03:38:44 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/plpgsql.sgml,v 1.58 2005/01/22 22:56:36 momjian Exp $
-->
<chapter id="plpgsql">
</programlisting>
<programlisting>
-IF v_count > 0 THEN
+IF v_count > 0 THEN
INSERT INTO users_count (count) VALUES (v_count);
RETURN 't';
ELSE
SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;
- IF a_running_job_count > 0 THEN
+ IF a_running_job_count > 0 THEN
COMMIT; -- free lock<co id="co.plpgsql-porting-commit">
raise_application_error(-20000, 'Unable to create a new job: a job is currently running.');
END IF;
SELECT count(*) INTO a_running_job_count FROM cs_jobs WHERE end_stamp IS NULL;
- IF a_running_job_count > 0 THEN
+ IF a_running_job_count > 0 THEN
RAISE EXCEPTION 'Unable to create a new job: a job is currently running';<co id="co.plpgsql-porting-raise">
END IF;
length integer;
ss_length integer;
BEGIN
- IF beg_index > 0 THEN
+ IF beg_index > 0 THEN
temp_str := substring(string FROM beg_index);
pos := position(string_to_search IN temp_str);
length := char_length(string);
beg := length + beg_index - ss_length + 2;
- WHILE beg > 0 LOOP
+ WHILE beg > 0 LOOP
temp_str := substring(string FROM beg FOR ss_length);
pos := position(string_to_search IN temp_str);
- IF pos > 0 THEN
+ IF pos > 0 THEN
RETURN beg;
END IF;
length integer;
ss_length integer;
BEGIN
- IF beg_index > 0 THEN
+ IF beg_index > 0 THEN
beg := beg_index;
temp_str := substring(string FROM beg_index);
length := char_length(string);
beg := length + beg_index - ss_length + 2;
- WHILE beg > 0 LOOP
+ WHILE beg > 0 LOOP
temp_str := substring(string FROM beg FOR ss_length);
pos := position(string_to_search IN temp_str);
- IF pos > 0 THEN
+ IF pos > 0 THEN
occur_number := occur_number + 1;
IF occur_number = occur_index THEN
<!--
-$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.33 2004/12/30 21:45:37 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/pltcl.sgml,v 2.34 2005/01/22 22:56:36 momjian Exp $
-->
<chapter id="pltcl">
<programlisting>
CREATE FUNCTION tcl_max(integer, integer) RETURNS integer AS $$
- if {$1 > $2} {return $1}
+ if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl STRICT;
</programlisting>
return $2
}
if {[argisnull 2]} { return $1 }
- if {$1 > $2} {return $1}
+ if {$1 > $2} {return $1}
return $2
$$ LANGUAGE pltcl;
</programlisting>
);
CREATE FUNCTION overpaid(employee) RETURNS boolean AS $$
- if {200000.0 < $1(salary)} {
+ if {200000.0 < $1(salary)} {
return "t"
}
- if {$1(age) < 30 && 100000.0 < $1(salary)} {
+ if {$1(age) < 30 && 100000.0 < $1(salary)} {
return "t"
}
return "f"
-<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.32 2004/12/23 05:37:40 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/queries.sgml,v 1.33 2005/01/22 22:56:36 momjian Exp $ -->
<chapter id="queries">
<title>Queries</title>
</programlisting>
then we get the following results for the various joins:
<screen>
-<prompt>=></> <userinput>SELECT * FROM t1 CROSS JOIN t2;</>
+<prompt>=></> <userinput>SELECT * FROM t1 CROSS JOIN t2;</>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 5 | zzz
(9 rows)
-<prompt>=></> <userinput>SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;</>
+<prompt>=></> <userinput>SELECT * FROM t1 INNER JOIN t2 ON t1.num = t2.num;</>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
(2 rows)
-<prompt>=></> <userinput>SELECT * FROM t1 INNER JOIN t2 USING (num);</>
+<prompt>=></> <userinput>SELECT * FROM t1 INNER JOIN t2 USING (num);</>
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 rows)
-<prompt>=></> <userinput>SELECT * FROM t1 NATURAL INNER JOIN t2;</>
+<prompt>=></> <userinput>SELECT * FROM t1 NATURAL INNER JOIN t2;</>
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(2 rows)
-<prompt>=></> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;</>
+<prompt>=></> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num;</>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
3 | c | 3 | yyy
(3 rows)
-<prompt>=></> <userinput>SELECT * FROM t1 LEFT JOIN t2 USING (num);</>
+<prompt>=></> <userinput>SELECT * FROM t1 LEFT JOIN t2 USING (num);</>
num | name | value
-----+------+-------
1 | a | xxx
3 | c | yyy
(3 rows)
-<prompt>=></> <userinput>SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;</>
+<prompt>=></> <userinput>SELECT * FROM t1 RIGHT JOIN t2 ON t1.num = t2.num;</>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
| | 5 | zzz
(3 rows)
-<prompt>=></> <userinput>SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;</>
+<prompt>=></> <userinput>SELECT * FROM t1 FULL JOIN t2 ON t1.num = t2.num;</>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
prove useful for some queries but needs to be thought out
carefully. For example:
<screen>
-<prompt>=></> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';</>
+<prompt>=></> <userinput>SELECT * FROM t1 LEFT JOIN t2 ON t1.num = t2.num AND t2.value = 'xxx';</>
num | name | num | value
-----+------+-----+-------
1 | a | 1 | xxx
current query — it is no longer possible to refer to the table
by the original name. Thus
<programlisting>
-SELECT * FROM my_table AS m WHERE my_table.a > 5;
+SELECT * FROM my_table AS m WHERE my_table.a > 5;
</programlisting>
is not valid SQL syntax. What will actually happen (this is a
<productname>PostgreSQL</productname> extension to the standard)
<literal>FROM</literal> clause, so the query is processed as if
it were written as
<programlisting>
-SELECT * FROM my_table AS m, my_table AS my_table WHERE my_table.a > 5;
+SELECT * FROM my_table AS m, my_table AS my_table WHERE my_table.a > 5;
</programlisting>
which will result in a cross join, which is usually not what you
want.
<para>
Here are some examples of <literal>WHERE</literal> clauses:
<programlisting>
-SELECT ... FROM fdt WHERE c1 > 5
+SELECT ... FROM fdt WHERE c1 > 5
SELECT ... FROM fdt WHERE c1 IN (1, 2, 3)
SELECT ... FROM fdt WHERE c1 BETWEEN (SELECT c3 FROM t2 WHERE c2 = fdt.c1 + 10) AND 100
-SELECT ... FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1)
+SELECT ... FROM fdt WHERE EXISTS (SELECT c1 FROM t2 WHERE c2 > fdt.c1)
</programlisting>
<literal>fdt</literal> is the table derived in the
<literal>FROM</> clause. Rows that do not meet the search
eliminate redundancy in the output and/or compute aggregates that
apply to these groups. For instance:
<screen>
-<prompt>=></> <userinput>SELECT * FROM test1;</>
+<prompt>=></> <userinput>SELECT * FROM test1;</>
x | y
---+---
a | 3
a | 1
(4 rows)
-<prompt>=></> <userinput>SELECT x FROM test1 GROUP BY x;</>
+<prompt>=></> <userinput>SELECT x FROM test1 GROUP BY x;</>
x
---
a
used in the grouping cannot be referenced except in aggregate
expressions. An example with aggregate expressions is:
<screen>
-<prompt>=></> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x;</>
+<prompt>=></> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x;</>
x | sum
---+-----
a | 4
<para>
Example:
<screen>
-<prompt>=></> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;</>
+<prompt>=></> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x HAVING sum(y) > 3;</>
x | sum
---+-----
a | 4
b | 5
(2 rows)
-<prompt>=></> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';</>
+<prompt>=></> <userinput>SELECT x, sum(y) FROM test1 GROUP BY x HAVING x < 'c';</>
x | sum
---+-----
a | 4
<programlisting>
SELECT product_id, p.name, (sum(s.units) * (p.price - p.cost)) AS profit
FROM products p LEFT JOIN sales s USING (product_id)
- WHERE s.date > CURRENT_DATE - INTERVAL '4 weeks'
+ WHERE s.date > CURRENT_DATE - INTERVAL '4 weeks'
GROUP BY product_id, p.name, p.price, p.cost
- HAVING sum(p.price * s.units) > 5000;
+ HAVING sum(p.price * s.units) > 5000;
</programlisting>
In the example above, the <literal>WHERE</> clause is selecting
rows by a column that is not grouped (the expression is only true for
<!--
-$PostgreSQL: pgsql/doc/src/sgml/query.sgml,v 1.42 2005/01/08 01:44:08 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/query.sgml,v 1.43 2005/01/22 22:56:36 momjian Exp $
-->
<chapter id="tutorial-sql">
SELECT W1.city, W1.temp_lo AS low, W1.temp_hi AS high,
W2.city, W2.temp_lo AS low, W2.temp_hi AS high
FROM weather W1, weather W2
- WHERE W1.temp_lo < W2.temp_lo
- AND W1.temp_hi > W2.temp_hi;
+ WHERE W1.temp_lo < W2.temp_lo
+ AND W1.temp_hi > W2.temp_hi;
city | low | high | city | low | high
---------------+-----+------+---------------+-----+------
SELECT city, max(temp_lo)
FROM weather
GROUP BY city
- HAVING max(temp_lo) < 40;
+ HAVING max(temp_lo) < 40;
</programlisting>
<screen>
FROM weather
WHERE city LIKE 'S%'<co id="co.tutorial-agg-like">
GROUP BY city
- HAVING max(temp_lo) < 40;
+ HAVING max(temp_lo) < 40;
</programlisting>
<calloutlist>
<callout arearefs="co.tutorial-agg-like">
<programlisting>
UPDATE weather
SET temp_hi = temp_hi - 2, temp_lo = temp_lo - 2
- WHERE date > '1994-11-28';
+ WHERE date > '1994-11-28';
</programlisting>
</para>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.322 2005/01/22 22:06:17 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/release.sgml,v 1.323 2005/01/22 22:56:36 momjian Exp $
-->
<appendix id="release">
</para>
<para>
Fixes improper failure of cases such as <literal>SELECT SUM(win)/SUM(lose)
- ... GROUP BY ... HAVING SUM(lose) > 0</>. This should work but formerly
+ ... GROUP BY ... HAVING SUM(lose) > 0</>. This should work but formerly
could fail with divide-by-zero.
</para>
</listitem>
<listitem><para>Force zero_damaged_pages to be on during recovery from WAL</para></listitem>
<listitem><para>Prevent some obscure cases of <quote>variable not in subplan target lists</quote></para></listitem>
<listitem><para>Make <function>PQescapeBytea</function> and <function>byteaout</function> consistent with each other (Joe)</para></listitem>
-<listitem><para>Escape <type>bytea</type> output for bytes > 0x7e(Joe)</para>
+<listitem><para>Escape <type>bytea</type> output for bytes > 0x7e(Joe)</para>
<para>
If different client encodings are used for <type>bytea</type> output and input, it
is possible for <type>bytea</type> values to be corrupted by the differing
<listitem><para>Allow libpq to compile with Borland C++ compiler (Lester Godwin, Karl Waclawek)</para></listitem>
<listitem><para>Use our own version of <function>getopt_long()</function> if needed (Peter)</para></listitem>
<listitem><para>Convert administration scripts to C (Peter)</para></listitem>
- <listitem><para> Bison >= 1.85 is now required to build the <productname>PostgreSQL</> grammar, if building from CVS</para></listitem>
+ <listitem><para> Bison >= 1.85 is now required to build the <productname>PostgreSQL</> grammar, if building from CVS</para></listitem>
<listitem><para>Merge documentation into one book (Peter)</para></listitem>
<listitem><para>Add Windows compatibility functions (Bruce)</para></listitem>
<listitem><para>Allow client interfaces to compile under MinGW (Bruce)</para></listitem>
<listitem><para>Make cursors insensitive, meaning their contents do not change (Tom)</para></listitem>
<listitem><para>Disable LIMIT #,# syntax; now only LIMIT # OFFSET # supported (Bruce)</para></listitem>
<listitem><para>Increase identifier length to 63 (Neil, Bruce)</para></listitem>
-<listitem><para>UNION fixes for merging >= 3 columns of different lengths (Tom)</para></listitem>
+<listitem><para>UNION fixes for merging >= 3 columns of different lengths (Tom)</para></listitem>
<listitem><para>Add DEFAULT key word to INSERT, e.g., INSERT ... (..., DEFAULT, ...) (Rod)</para></listitem>
<listitem><para>Allow views to have default values using ALTER COLUMN ... SET DEFAULT (Neil)</para></listitem>
<listitem><para>Fail on INSERTs with column lists that don't supply all column values, e.g., INSERT INTO tab (col1, col2) VALUES ('val1'); (Rod)</para></listitem>
<listitem><para>New pg_settings table to view/modify GUC settings (Joe)</para></listitem>
<listitem><para>Add smart quoting, portability improvements to <application>pg_dump</> output (Peter)</para></listitem>
<listitem><para>Dump serial columns out as SERIAL (Tom)</para></listitem>
-<listitem><para>Enable large file support, >2G for <application>pg_dump</> (Peter, Philip Warner, Bruce)</para></listitem>
+<listitem><para>Enable large file support, >2G for <application>pg_dump</> (Peter, Philip Warner, Bruce)</para></listitem>
<listitem><para>Disallow TRUNCATE on tables that are involved in referential constraints (Rod)</para></listitem>
<listitem><para>Have TRUNCATE also auto-truncate the toast table of the relation (Tom)</para></listitem>
<listitem><para>Add clusterdb utility that will auto-cluster an entire database based on previous CLUSTER operations (Alvaro Herrera)</para></listitem>
<listitem><para>Add additional encodings: Korean (JOHAB), Thai (WIN874), Vietnamese (TCVN), Arabic (WIN1256), Simplified Chinese (GBK), Korean (UHC) (Eiji Tokuya)</para></listitem>
<listitem><para>Enable locale support by default (Peter)</para></listitem>
<listitem><para>Add locale variables (Peter)</para></listitem>
-<listitem><para>Escape byes >= 0x7f for multibyte in PQescapeBytea/PQunescapeBytea (Tatsuo)</para></listitem>
+<listitem><para>Escape byes >= 0x7f for multibyte in PQescapeBytea/PQunescapeBytea (Tatsuo)</para></listitem>
<listitem><para>Add locale awareness to regular expression character classes</para></listitem>
<listitem><para>Enable multibyte support by default (Tatsuo)</para></listitem>
<listitem><para>Add GB18030 multibyte support (Bill Huang)</para></listitem>
<itemizedlist>
<listitem><para>Allow EXECUTE of "CREATE TABLE AS ... SELECT" in PL/pgSQL (Tom)</para></listitem>
<listitem><para>Fix for compressed transaction log id wraparound (Tom)</para></listitem>
-<listitem><para>Fix PQescapeBytea/PQunescapeBytea so that they handle bytes > 0x7f (Tatsuo)</para></listitem>
+<listitem><para>Fix PQescapeBytea/PQunescapeBytea so that they handle bytes > 0x7f (Tatsuo)</para></listitem>
<listitem><para>Fix for psql and <application>pg_dump</> crashing when invoked with non-existent long options (Tatsuo)</para></listitem>
<listitem><para>Fix crash when invoking geometric operators (Tom)</para></listitem>
<listitem><para>Allow OPEN cursor(args) (Tom)</para></listitem>
Fix SELECT * FROM pg_class where oid in (0,-1)
Fix SELECT COUNT('asdf') FROM pg_class WHERE oid=12
Prevent user who can create databases can modifying pg_database table (Peter E)
-Fix btree to give a useful elog when key > 1/2 (page - overhead) (Tom)
+Fix btree to give a useful elog when key > 1/2 (page - overhead) (Tom)
Fix INSERT of 0.0 into DECIMAL(4,4) field (Tom)
Enhancements
Improved LIKE optimizer estimates (Tom)
Prevent fsync in SELECT-only queries (Vadim)
Make index creation use psort code, because it is now faster (Tom)
-Allow creation of sort temp tables > 1 Gig
+Allow creation of sort temp tables > 1 Gig
Source Tree Changes
-------------------
using an axis-crossing algorithm(Thomas)
Add routine to convert circle-box(Thomas)
Merge conflicting operators for different geometric data types(Thomas)
-Replace distance operator "<===>" with "<->"(Thomas)
+Replace distance operator "<===>" with "<->"(Thomas)
Replace "above" operator "!^" with ">^" and "below" operator "!|" with "<^"(Thomas)
Add routines for text trimming on both ends, substring, and string position(Thomas)
Added conversion routines circle(box) and poly(circle)(Thomas)
-<!-- $PostgreSQL: pgsql/doc/src/sgml/rowtypes.sgml,v 2.4 2004/12/23 05:37:40 tgl Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/rowtypes.sgml,v 2.5 2005/01/22 22:56:36 momjian Exp $ -->
<sect1 id="rowtypes">
<title>Composite Types</title>
CREATE TABLE inventory_item (
name text,
supplier_id integer REFERENCES suppliers,
- price numeric CHECK (price > 0)
+ price numeric CHECK (price > 0)
);
</programlisting>
then the same <literal>inventory_item</> composite type shown above would
like:
<programlisting>
-SELECT item.name FROM on_hand WHERE item.price > 9.99;
+SELECT item.name FROM on_hand WHERE item.price > 9.99;
</programlisting>
This will not work since the name <literal>item</> is taken to be a table
name, not a field name, per SQL syntax rules. You must write it like this:
<programlisting>
-SELECT (item).name FROM on_hand WHERE (item).price > 9.99;
+SELECT (item).name FROM on_hand WHERE (item).price > 9.99;
</programlisting>
or if you need to use the table name as well (for instance in a multi-table
query), like this:
<programlisting>
-SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;
+SELECT (on_hand.item).name FROM on_hand WHERE (on_hand.item).price > 9.99;
</programlisting>
Now the parenthesized object is correctly interpreted as a reference to
-<!-- $PostgreSQL: pgsql/doc/src/sgml/rules.sgml,v 1.38 2005/01/22 22:06:27 momjian Exp $ -->
+<!-- $PostgreSQL: pgsql/doc/src/sgml/rules.sgml,v 1.39 2005/01/22 22:56:36 momjian Exp $ -->
<Chapter Id="rules">
<Title>The Rule System</Title>
<ProgramListing>
CREATE FUNCTION min(integer, integer) RETURNS integer AS $$
- SELECT CASE WHEN $1 < $2 THEN $1 ELSE $2 END
+ SELECT CASE WHEN $1 < $2 THEN $1 ELSE $2 END
$$ LANGUAGE SQL STRICT;
</ProgramListing>
</Para>
min(rsh.sh_avail, rsl.sl_avail) AS total_avail
FROM shoe rsh, shoelace rsl
WHERE rsl.sl_color = rsh.slcolor
- AND rsl.sl_len_cm >= rsh.slminlen_cm
- AND rsl.sl_len_cm <= rsh.slmaxlen_cm;
+ AND rsl.sl_len_cm >= rsh.slminlen_cm
+ AND rsl.sl_len_cm <= rsh.slmaxlen_cm;
</ProgramListing>
The <command>CREATE VIEW</command> command for the
total number of exactly matching pairs is greater or equal to two.
<ProgramListing>
-SELECT * FROM shoe_ready WHERE total_avail >= 2;
+SELECT * FROM shoe_ready WHERE total_avail >= 2;
shoename | sh_avail | sl_name | sl_avail | total_avail
----------+----------+---------+----------+-------------
shoe_ready.sl_name, shoe_ready.sl_avail,
shoe_ready.total_avail
FROM shoe_ready shoe_ready
- WHERE shoe_ready.total_avail >= 2;
+ WHERE shoe_ready.total_avail >= 2;
</ProgramListing>
The first rule applied will be the one for the
min(rsh.sh_avail, rsl.sl_avail) AS total_avail
FROM shoe rsh, shoelace rsl
WHERE rsl.sl_color = rsh.slcolor
- AND rsl.sl_len_cm >= rsh.slminlen_cm
- AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
- WHERE shoe_ready.total_avail >= 2;
+ AND rsl.sl_len_cm >= rsh.slminlen_cm
+ AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
+ WHERE shoe_ready.total_avail >= 2;
</ProgramListing>
Similarly, the rules for <literal>shoe</literal> and
FROM shoelace_data s, unit u
WHERE s.sl_unit = u.un_name) rsl
WHERE rsl.sl_color = rsh.slcolor
- AND rsl.sl_len_cm >= rsh.slminlen_cm
- AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
- WHERE shoe_ready.total_avail > 2;
+ AND rsl.sl_len_cm >= rsh.slminlen_cm
+ AND rsl.sl_len_cm <= rsh.slmaxlen_cm) shoe_ready
+ WHERE shoe_ready.total_avail > 2;
</ProgramListing>
</para>
is
<ProgramListing>
-DELETE FROM computer WHERE hostname >= 'old'
- AND hostname < 'ole'
+DELETE FROM computer WHERE hostname >= 'old'
+ AND hostname < 'ole'
</ProgramListing>
The command added by the rule will be
<ProgramListing>
-DELETE FROM software WHERE computer.hostname >= 'old' AND computer.hostname < 'ole'
+DELETE FROM software WHERE computer.hostname >= 'old' AND computer.hostname < 'ole'
AND software.hostname = computer.hostname;
</ProgramListing>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.301 2005/01/08 22:13:35 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.302 2005/01/22 22:56:36 momjian Exp $
-->
<Chapter Id="runtime">
<filename>proc</filename> file system (without reboot). For
example, to allow 128 MB:
<screen>
-<prompt>$</prompt> <userinput>echo 134217728 >/proc/sys/kernel/shmall</userinput>
-<prompt>$</prompt> <userinput>echo 134217728 >/proc/sys/kernel/shmmax</userinput>
+<prompt>$</prompt> <userinput>echo 134217728 >/proc/sys/kernel/shmall</userinput>
+<prompt>$</prompt> <userinput>echo 134217728 >/proc/sys/kernel/shmmax</userinput>
</screen>
You could put these commands into a script run at boot-time.
</para>
<!--
-$PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.38 2005/01/22 22:06:27 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/spi.sgml,v 1.39 2005/01/22 22:56:36 momjian Exp $
-->
<chapter id="spi">
* If this is a SELECT and some rows were fetched,
* then the rows are printed via elog(INFO).
*/
- if (ret == SPI_OK_SELECT && SPI_processed > 0)
+ if (ret == SPI_OK_SELECT && SPI_processed > 0)
{
TupleDesc tupdesc = SPI_tuptable->tupdesc;
SPITupleTable *tuptable = SPI_tuptable;
char buf[8192];
int i, j;
- for (j = 0; j < proc; j++)
+ for (j = 0; j < proc; j++)
{
HeapTuple tuple = tuptable->vals[j];
- for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
+ for (i = 1, buf[0] = 0; i <= tupdesc->natts; i++)
snprintf(buf + strlen (buf), sizeof(buf) - strlen(buf), " %s%s",
SPI_getvalue(tuple, tupdesc, i),
(i == tupdesc->natts) ? " " : " |");
Here is a sample session:
<programlisting>
-=> SELECT execq('CREATE TABLE a (x integer)', 0);
+=> SELECT execq('CREATE TABLE a (x integer)', 0);
execq
-------
0
(1 row)
-=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0));
+=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)', 0));
INSERT 167631 1
-=> SELECT execq('SELECT * FROM a', 0);
+=> SELECT execq('SELECT * FROM a', 0);
INFO: EXECQ: 0 -- inserted by execq
INFO: EXECQ: 1 -- returned by execq and inserted by upper INSERT
2
(1 row)
-=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a', 1);
+=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a', 1);
execq
-------
1
(1 row)
-=> SELECT execq('SELECT * FROM a', 10);
+=> SELECT execq('SELECT * FROM a', 10);
INFO: EXECQ: 0
INFO: EXECQ: 1
INFO: EXECQ: 2 -- 0 + 2, only one row inserted - as specified
3 -- 10 is the max value only, 3 is the real number of rows
(1 row)
-=> DELETE FROM a;
+=> DELETE FROM a;
DELETE 3
-=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
+=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
INSERT 167712 1
-=> SELECT * FROM a;
+=> SELECT * FROM a;
x
---
1 -- no rows in a (0) + 1
(1 row)
-=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
+=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
INFO: EXECQ: 0
INSERT 167713 1
-=> SELECT * FROM a;
+=> SELECT * FROM a;
x
---
1
-- This demonstrates the data changes visibility rule:
-=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
+=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
INFO: EXECQ: 1
INFO: EXECQ: 2
INFO: EXECQ: 1
INFO: EXECQ: 2
INFO: EXECQ: 2
INSERT 0 2
-=> SELECT * FROM a;
+=> SELECT * FROM a;
x
---
1
<!--
-$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.33 2004/11/15 06:32:14 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/sql.sgml,v 1.34 2005/01/22 22:56:36 momjian Exp $
-->
<chapter id="sql-intro">
<programlisting>
SELECT * FROM PART
- WHERE PRICE > 10;
+ WHERE PRICE > 10;
</programlisting>
and get the table:
<programlisting>
SELECT PNAME, PRICE
FROM PART
- WHERE PRICE > 10;
+ WHERE PRICE > 10;
</programlisting>
In this case the result is:
SELECT PNAME, PRICE
FROM PART
WHERE PNAME = 'Bolt' AND
- (PRICE = 0 OR PRICE <= 15);
+ (PRICE = 0 OR PRICE <= 15);
</programlisting>
will lead to the result:
<programlisting>
SELECT PNAME, PRICE * 2 AS DOUBLE
FROM PART
- WHERE PRICE * 2 < 50;
+ WHERE PRICE * 2 < 50;
</programlisting>
and we get:
FROM SUPPLIER S, SELLS SE
WHERE S.SNO = SE.SNO
GROUP BY S.SNO, S.SNAME
- HAVING COUNT(SE.PNO) > 1;
+ HAVING COUNT(SE.PNO) > 1;
</programlisting>
and get:
<programlisting>
SELECT *
FROM PART
- WHERE PRICE > (SELECT PRICE FROM PART
+ WHERE PRICE > (SELECT PRICE FROM PART
WHERE PNAME='Screw');
</programlisting>
</para>
<programlisting>
SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S
- WHERE S.SNO > 1
+ WHERE S.SNO > 1
INTERSECT
SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S
- WHERE S.SNO < 3;
+ WHERE S.SNO < 3;
</programlisting>
gives the result:
<programlisting>
SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S
- WHERE S.SNO > 1
+ WHERE S.SNO > 1
EXCEPT
SELECT S.SNO, S.SNAME, S.CITY
FROM SUPPLIER S
- WHERE S.SNO > 3;
+ WHERE S.SNO > 3;
</programlisting>
gives the result:
<!--
-$PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.40 2005/01/22 22:06:27 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/trigger.sgml,v 1.41 2005/01/22 22:56:36 momjian Exp $
-->
<chapter id="triggers">
tupdesc = trigdata->tg_relation->rd_att;
/* connect to SPI manager */
- if ((ret = SPI_connect()) < 0)
+ if ((ret = SPI_connect()) < 0)
elog(INFO, "trigf (fired %s): SPI_connect returned %d", when, ret);
/* get number of rows in table */
ret = SPI_exec("SELECT count(*) FROM ttest", 0);
- if (ret < 0)
+ if (ret < 0)
elog(NOTICE, "trigf (fired %s): SPI_exec returned %d", when, ret);
/* count(*) returns int8, so be careful to convert */
<para>
Now you can test the operation of the trigger:
<screen>
-=> INSERT INTO ttest VALUES (NULL);
+=> INSERT INTO ttest VALUES (NULL);
INFO: trigf (fired before): there are 0 rows in ttest
INSERT 0 0
-- Insertion skipped and AFTER trigger is not fired
-=> SELECT * FROM ttest;
+=> SELECT * FROM ttest;
x
---
(0 rows)
-=> INSERT INTO ttest VALUES (1);
+=> INSERT INTO ttest VALUES (1);
INFO: trigf (fired before): there are 0 rows in ttest
INFO: trigf (fired after ): there are 1 rows in ttest
^^^^^^^^
remember what we said about visibility.
INSERT 167793 1
-vac=> SELECT * FROM ttest;
+vac=> SELECT * FROM ttest;
x
---
1
(1 row)
-=> INSERT INTO ttest SELECT x * 2 FROM ttest;
+=> INSERT INTO ttest SELECT x * 2 FROM ttest;
INFO: trigf (fired before): there are 1 rows in ttest
INFO: trigf (fired after ): there are 2 rows in ttest
^^^^^^
remember what we said about visibility.
INSERT 167794 1
-=> SELECT * FROM ttest;
+=> SELECT * FROM ttest;
x
---
1
2
(2 rows)
-=> UPDATE ttest SET x = NULL WHERE x = 2;
+=> UPDATE ttest SET x = NULL WHERE x = 2;
INFO: trigf (fired before): there are 2 rows in ttest
UPDATE 0
-=> UPDATE ttest SET x = 4 WHERE x = 2;
+=> UPDATE ttest SET x = 4 WHERE x = 2;
INFO: trigf (fired before): there are 2 rows in ttest
INFO: trigf (fired after ): there are 2 rows in ttest
UPDATE 1
-vac=> SELECT * FROM ttest;
+vac=> SELECT * FROM ttest;
x
---
1
4
(2 rows)
-=> DELETE FROM ttest;
+=> DELETE FROM ttest;
INFO: trigf (fired before): there are 2 rows in ttest
INFO: trigf (fired after ): there are 1 rows in ttest
INFO: trigf (fired before): there are 1 rows in ttest
^^^^^^
remember what we said about visibility.
DELETE 2
-=> SELECT * FROM ttest;
+=> SELECT * FROM ttest;
x
---
(0 rows)
<!--
-$PostgreSQL: pgsql/doc/src/sgml/xaggr.sgml,v 1.25 2004/11/15 06:32:14 neilc Exp $
+$PostgreSQL: pgsql/doc/src/sgml/xaggr.sgml,v 1.26 2005/01/22 22:56:36 momjian Exp $
-->
<sect1 id="xaggr">
<programlisting>
SELECT attrelid::regclass, array_accum(attname)
FROM pg_attribute
- WHERE attnum > 0 AND attrelid = 'pg_user'::regclass
+ WHERE attnum > 0 AND attrelid = 'pg_user'::regclass
GROUP BY attrelid;
attrelid | array_accum
SELECT attrelid::regclass, array_accum(atttypid)
FROM pg_attribute
- WHERE attnum > 0 AND attrelid = 'pg_user'::regclass
+ WHERE attnum > 0 AND attrelid = 'pg_user'::regclass
GROUP BY attrelid;
attrelid | array_accum
<!--
-$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.97 2005/01/22 22:06:27 momjian Exp $
+$PostgreSQL: pgsql/doc/src/sgml/xfunc.sgml,v 1.98 2005/01/22 22:56:36 momjian Exp $
-->
<sect1 id="xfunc">
return type, but the converse is not. For example:
<screen>
CREATE FUNCTION is_greater(anyelement, anyelement) RETURNS boolean AS $$
- SELECT $1 > $2;
+ SELECT $1 > $2;
$$ LANGUAGE SQL;
SELECT is_greater(1, 2);