/[gentoo]/xml/htdocs/doc/en/postgres-howto.xml
Gentoo

Contents of /xml/htdocs/doc/en/postgres-howto.xml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.4 - (show annotations) (download) (as text)
Wed Apr 25 07:40:11 2007 UTC (11 years, 2 months ago) by nightmorph
Branch: MAIN
Changes since 1.3: +20 -21 lines
File MIME type: application/xml
updated postgresql guide for bug 174255

1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE guide SYSTEM "/dtd/guide.dtd">
3 <!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/en/postgres-howto.xml,v 1.3 2007/04/10 07:16:49 nightmorph Exp $ -->
4
5 <guide link="/doc/en/postgres-howto.xml" lang="en">
6 <title>PostgreSQL Guide</title>
7
8 <author title="Author">
9 <mail link="chriswhite@gentoo.org">Chris White</mail>
10 </author>
11 <author title="Editor">
12 <mail link="neysx@gentoo.org">Xavier Neys</mail>
13 </author>
14
15 <abstract>
16 This guide is meant to show the basic setup of PostgreSQL. The setup described
17 here should be sufficient enough to use for basic web appplications, and any
18 other program that provides PostgreSQL support.
19 </abstract>
20
21 <!-- The content of this document is licensed under the CC-BY-SA license -->
22 <!-- See http://creativecommons.org/licenses/by-sa/2.5 -->
23 <license/>
24
25 <version>1.2</version>
26 <date>2007-04-25</date>
27
28 <chapter>
29 <title>Introduction</title>
30 <section>
31 <title>PostgreSQL introduction</title>
32 <body>
33
34 <p>
35 When talking to most developers about the different database solutions to use,
36 two major databases will usually form the answer. One would be <c>MySQL</c>,
37 and the other is what this document will refer to, <c>PostgreSQL</c>. The
38 advantages of one over the other is a somewhat long winded debate, however it
39 is just to say that PostgreSQL has had a more firm grasp on true relational
40 database structure than MySQL. Most of the standard features such as
41 <b>FOREIGN KEY</b> was only just added in MySQL 5. However, whatever the case
42 may be, this document assumes that you have selected PostgreSQL as the
43 database to use. The first place to start is the <c>emerge</c> process. In the
44 next section, the installation process through emerge will be described, as
45 well as the basic configuration.
46 </p>
47
48 </body>
49 </section>
50 <section>
51 <title>PostgreSQL installation</title>
52 <body>
53
54 <p>
55 To begin, we must first <c>emerge</c> the PostgreSQL package. To do so, run the
56 following code to first ensure that the options for it are properly set:
57 </p>
58
59 <pre caption="Checking the PostgreSQL build options">
60 # <i>emerge -pv postgresql</i>
61
62 These are the packages that I would merge, in order:
63
64 Calculating dependencies ...done!
65 [ebuild N ] dev-db/postgresql-8.0.4 -doc -kerberos +nls +pam +perl -pg-intdatetime +python +readline (-selinux) +ssl -tcl +xml +zlib 0 kB
66 </pre>
67
68 <p>
69 Here's a list of what the different build options indicate:
70 </p>
71
72 <table>
73 <tr>
74 <th>USE Flag</th>
75 <th>Meaning</th>
76 </tr>
77 <tr>
78 <ti>doc</ti>
79 <ti>
80 This USE flag enables or disables the installation of documentation
81 outside of the standard man pages. The one good time to disable this
82 option is if you are low on space, or you have alternate methods of
83 getting a hold of the documentation (online, etc.)
84 </ti>
85 </tr>
86 <tr>
87 <ti>kerberos</ti>
88 <ti>
89 When connecting to the database, with this option enabled, the admin
90 has the option of using <c>kerberos</c> to authenticate their
91 users/services to the database.
92 </ti>
93 </tr>
94 <tr>
95 <ti>nls</ti>
96 <ti>
97 If this option is enabled, PostgreSQL can utilize translated strings for
98 non-English speaking users.
99 </ti>
100 </tr>
101 <tr>
102 <ti>pam</ti>
103 <ti>
104 If this option is enabled, and the admin configures the PostgreSQL
105 configuration file properly, users/services will be able to login to a
106 PostgreSQL database using <c>PAM</c> (Pluggable Authentication Module).
107 </ti>
108 </tr>
109 <tr>
110 <ti>perl</ti>
111 <ti>
112 If this option is enabled, <c>perl</c> bindings for PostgreSQL will be
113 built.
114 </ti>
115 </tr>
116 <tr>
117 <ti>pg-intdatetime</ti>
118 <ti>
119 If this option is enabled, PostgreSQL will support 64 bit integer date
120 types.
121 </ti>
122 </tr>
123 <tr>
124 <ti>python</ti>
125 <ti>
126 If this option is enabled, PostgreSQL will be built with
127 <c>python</c> bindings.
128 </ti>
129 </tr>
130 <tr>
131 <ti>readline</ti>
132 <ti>
133 If this option is enabled, PostgreSQL will support <c>readline</c> style
134 command line editing. This includes command history and isearch.
135 </ti>
136 </tr>
137 <tr>
138 <ti>selinux</ti>
139 <ti>
140 If this option is enabled, an <c>selinux</c> policy for PostgreSQL will be
141 installed.
142 </ti>
143 </tr>
144 <tr>
145 <ti>ssl</ti>
146 <ti>
147 If this option is enabled, PostgreSQL will utilize the <c>OpenSSL</c>
148 library to encrypt traffic between PostgreSQL clients and servers.
149 </ti>
150 </tr>
151 <tr>
152 <ti>tcl</ti>
153 <ti>
154 If this option is enabled, PostgreSQL will build <c>tcl</c> bindings.
155 </ti>
156 </tr>
157 <tr>
158 <ti>xml</ti>
159 <ti>
160 If this option is enabled, <c>XPATH</c> style xml support will be built.
161 More information on using xml support with PostgreSQL can be found on:
162 <uri link="http://www.throwingbeans.org/postgresql_and_xml.html">
163 PostgreSQL and XML</uri>.
164 </ti>
165 </tr>
166 <tr>
167 <ti>zlib</ti>
168 <ti>
169 This isn't really used by PostgreSQL itself, but by <c>pg_dump</c> to
170 compress the dumps it produces.
171 </ti>
172 </tr>
173 </table>
174
175 <p>
176 Once you've customized PostgreSQL to meet your specific needs, go ahead and
177 start the <c>emerge</c>:
178 </p>
179
180 <pre caption="Emerge-ing PostgreSQL">
181 # <i>emerge postgresql</i>
182 <comment>(Output shortened)</comment>
183 >>> /usr/lib/libecpg.so.5 -> libecpg.so.5.0
184 >>> /usr/bin/postmaster -> postgres
185 * Make sure the postgres user in /etc/passwd has an account setup with /bin/bash as the shell
186 *
187 * Execute the following command
188 * emerge --config =postgresql-8.0.4
189 * to setup the initial database environment.
190 *
191 >>> Regenerating /etc/ld.so.cache...
192 >>> dev-db/postgresql-8.0.4 merged.
193 </pre>
194
195 <p>
196 As shown by the einfo output, there is some post setup that must be done. The
197 next chapter will look at the actual configuration of PostgreSQL.
198 </p>
199
200 </body>
201 </section>
202 </chapter>
203 <chapter>
204 <title>PostgreSQL configuration</title>
205 <section>
206 <title>Setting up the initial database environment</title>
207 <body>
208
209 <p>
210 As noted in the earlier <c>emerge</c> output, the initial database environment
211 must be setup. However, before this is done, one thing needs to be considered.
212 Unlike, say MySQL, PostgreSQL's "root" password is the password of the actual
213 user. However, only the user is created by the ebuild <e>not</e> the password.
214 So before we can begin, the password must be set for the postgres user:
215 </p>
216
217 <pre caption="Setting the password">
218 # <i>passwd postgres</i>
219 New UNIX password:
220 Retype new UNIX password:
221 passwd: password updated successfully
222 </pre>
223
224 <p>
225 Now that this is setup, the creation of the initial database environment can occur:
226 </p>
227
228 <pre caption="Configuring the database environment with emerge --config">
229 # <i>emerge --config =postgresql-8.0.4</i>
230
231
232 Configuring pkg...
233
234 * Creating the data directory ...
235 * Initializing the database ...
236 The files belonging to this database system will be owned by user "postgres".
237 This user must also own the server process.
238
239 The database cluster will be initialized with locale C.
240
241 fixing permissions on existing directory /var/lib/postgresql/data ... ok
242 creating directory /var/lib/postgresql/data/global ... ok
243 creating directory /var/lib/postgresql/data/pg_xlog ... ok
244 creating directory /var/lib/postgresql/data/pg_xlog/archive_status ... ok
245 creating directory /var/lib/postgresql/data/pg_clog ... ok
246 creating directory /var/lib/postgresql/data/pg_subtrans ... ok
247 creating directory /var/lib/postgresql/data/base ... ok
248 creating directory /var/lib/postgresql/data/base/1 ... ok
249 creating directory /var/lib/postgresql/data/pg_tblspc ... ok
250 selecting default max_connections ... 100
251 selecting default shared_buffers ... 1000
252 creating configuration files ... ok
253 creating template1 database in /var/lib/postgresql/data/base/1 ... ok
254 initializing pg_shadow ... ok
255 enabling unlimited row size for system tables ... ok
256 initializing pg_depend ... ok
257 creating system views ... ok
258 loading pg_description ... ok
259 creating conversions ... ok
260 setting privileges on built-in objects ... ok
261 creating information schema ... ok
262 vacuuming database template1 ... ok
263 copying template1 to template0 ... ok
264
265 WARNING: enabling "trust" authentication for local connections
266 You can change this by editing pg_hba.conf or using the -A option the
267 next time you run initdb.
268
269 Success. You can now start the database server using:
270
271 /usr/bin/postmaster -D /var/lib/postgresql/data
272 or
273 /usr/bin/pg_ctl -D /var/lib/postgresql/data -l logfile start
274
275 *
276 * You can use /etc/init.d/postgresql script to run PostgreSQL instead of pg_ctl.
277 *
278 </pre>
279
280 <p>
281 Now the initial database environment is setup. The next section will look at
282 verifying the install and setting up users to access the database.
283 </p>
284
285 </body>
286 </section>
287 <section>
288 <title>PostgreSQL database setup</title>
289 <body>
290
291 <p>
292 Now that PostgreSQL is setup, it's a good idea at this point to verify the
293 installation. First, make sure the service starts up ok:
294 </p>
295
296 <pre caption="Starting up the PostgreSQL service">
297 # <i>/etc/init.d/postgresql start</i>
298 * Starting PostgreSQL ... [ ok ]
299 </pre>
300
301 <p>
302 Once this is verified working, it's also a good idea to add it to the default
303 runlevel so it starts at boot:
304 </p>
305
306 <pre caption="Adding to the default runlevel">
307 # <i>rc-update add postgresql default</i>
308 * postgresql added to runlevel default
309 </pre>
310
311 <p>
312 Now that the service has started, it's time to try setting up a test database.
313 To start out, let's create a test database by using the <c>createdb</c>
314 command. We'll also pass along the <c>-U</c> option to set the user (it
315 defaults to the current user name if you don't), and the <c>-W</c> option to
316 request the password we created earlier. Finally we give it the name of the
317 database we want to create:
318 </p>
319
320 <pre caption="Creating a database with createdb">
321 $ <i>createdb -U postgres -W test</i>
322 Password:
323 CREATE DATABASE
324 </pre>
325
326 <p>
327 The database was successfully created, and we can confirm that the database can
328 run basic tasks. We'll go ahead and drop this database (remove it) with the
329 <c>dropdb</c> command:
330 </p>
331
332 <pre caption="Dropping a database with dropdb">
333 $ <i>dropdb -U postgres -W test</i>
334 Password:
335 DROP DATABASE
336 </pre>
337
338 <p>
339 Right now, only the postgres user can run commands. Obviously this is not the
340 sort of setup one would like in a multi-user environment. The next section will
341 look at working with user accounts.
342 </p>
343
344 </body>
345 </section>
346 <section>
347 <title>Setting up database user accounts</title>
348 <body>
349
350 <p>
351 As mentioned earlier, having to login as the postgres user is somewhat
352 undesirable in a mult-user environment. In most cases there will be various
353 users and services accessing the server, and each have different permission
354 requirements. So, to handle this, the <c>createuser</c> command can be used.
355 This command is an alternative to running a few SQL queries, and is a lot more
356 flexible from an admin standpoint. We'll go ahead and create two users, a
357 'superuser' that can add other users and administer the db, and a standard user:
358 </p>
359
360 <pre caption="Setting up the superuser">
361 <comment>(replace chris with the username you'd like to use)</comment>
362 $ <i>createuser -a -d -P -E -U postgres -W chris</i>
363 Enter password for new user:
364 Enter it again:
365 Password:
366 CREATE USER
367 </pre>
368
369 <p>
370 There, we've created the superuser. The command line option <c>-a</c> specifies
371 that this user can add other users. <c>-d</c> means that this user can create
372 databases. <c>-P</c> let's you enter a password for the user and <c>-E</c> will
373 encrypt it for security purposes. Now then, we'll test this new user's
374 permissions out by setting up our standard user:
375 </p>
376
377 <pre caption="Setting up the standard user">
378 <comment>(replace chris with the username you've just created)</comment>
379 $ <i>createuser -A -D -P -E -U chris -W testuser</i>
380 Enter password for new user:
381 Enter it again:
382 Password:
383 CREATE USER
384 </pre>
385
386 <p>
387 Success! Our new user was created using the previously created superuser. The
388 <c>-A</c> and <c>-D</c> options do the opposite of <c>-a</c> and <c>-d</c>, and
389 instead deny the user the ability to create other users and databases. Now that
390 there are users to work with, the next chapter will look at using the new
391 database.
392 </p>
393
394 </body>
395 </section>
396 </chapter>
397 <chapter>
398 <title>Using PostgreSQL</title>
399 <section>
400 <title>Setting up permissions</title>
401 <body>
402
403 <p>
404 Now there is a user that can create databases and add other users, and the main
405 postgres user that can do anything. The user created earlier can currently login
406 to the server, and that's about it. In general, users need to be able to insert
407 data and retrieve data, and sometimes any other number of tasks. So, for this
408 new user to be able to do anything, they must be setup with the proper
409 permissions. This can easily be done by passing the <c>-O</c> parameter to
410 <c>createdb</c>. We'll start by making a new database, <b>MyDB</b> with our
411 superuser that will be owned by the previous testuser:
412 </p>
413
414 <pre caption="Creating the MyDB database">
415 $ <i>createdb -O testuser -U chris -W MyDB</i>
416 Password:
417 CREATE DATABASE
418 </pre>
419
420 <p>
421 Alright, now we have a new MyDB database, and a testuser that can access it.
422 To test this out, we'll login as the testuser to the new MyDB database. We'll
423 do this with the <c>psql</c> program. This program is what's used to connect to
424 the PostgreSQL database from command line. So connect to the new database like
425 so:
426 </p>
427
428 <pre caption="Logging into the MyDB database as the testuser">
429 $ <i>psql -U testuser -W MyDB</i>
430 Password:
431 Welcome to psql 8.0.4, the PostgreSQL interactive terminal.
432
433 Type: \copyright for distribution terms
434 \h for help with SQL commands
435 \? for help with psql commands
436 \g or terminate with semicolon to execute query
437 \q to quit
438
439 MyDB=&gt;
440 </pre>
441
442 <p>
443 So, the testuser is now logged into the database, and can begin to initiate
444 some commands. To get a feel for using PostgreSQL, the next section will take a
445 look at some of the basic commands in navigating the <c>psql</c> client.
446 </p>
447
448 </body>
449 </section>
450 <section>
451 <title>Basic PostgreSQL commands and creating a table</title>
452 <body>
453
454 <p>
455 For those who are used to MySQL, this is somewhat of a definite read. This is
456 where PostgreSQL may get somewhat unique with regards to running commands. To
457 start, here is a list of some commands that will be discussed:
458 </p>
459
460 <table>
461 <tr>
462 <th>Command</th>
463 <th>Usage</th>
464 <th>MySQL Equivalent</th>
465 </tr>
466 <tr>
467 <ti>\c[onnect] [DBNAME|- [USER]]</ti>
468 <ti>Connects to another database</ti>
469 <ti>USE DATABASE</ti>
470 </tr>
471 <tr>
472 <ti>\q</ti>
473 <ti>Quit the <c>psql</c> client</ti>
474 <ti>quit</ti>
475 </tr>
476 <tr>
477 <ti>\i FILE</ti>
478 <ti>Run commands from <c>FILE</c></ti>
479 <ti>source FILE</ti>
480 </tr>
481 <tr>
482 <ti>\o [FILE]</ti>
483 <ti>Send query results to <c>FILE</c></ti>
484 <ti>INTO OUTFILE, but outputs everything (not just SELECTS)</ti>
485 </tr>
486 <tr>
487 <ti>\d [NAME]</ti>
488 <ti>Describe a database or table (as well as other items)</ti>
489 <ti>DESC(RIBE)</ti>
490 </tr>
491 <tr>
492 <ti>\db [PATTERN]</ti>
493 <ti>
494 List available tables that match <c>PATTERN</c> (all if no pattern
495 is given)
496 </ti>
497 <ti>SHOW TABLES</ti>
498 </tr>
499 </table>
500
501 <p>
502 With the exception of <c>\c[onnect]</c>, all the commands shown will be used
503 later on in the section. So right now the database is empty. That said, we need
504 to insert some data. The first step to inserting data, however, is to put it in
505 a table. Right now there are no tables in the database, so we need to create
506 one. This is done with the <c>CREATE TABLE</c> command. We'll make a table of
507 items. They will contain a Product ID, Description, and price:
508 </p>
509
510 <pre caption="Creating the products table">
511 MyDB=> CREATE TABLE products (
512 MyDB(&gt; product_id SERIAL,
513 MyDB(&gt; description TEXT,
514 MyDB(&gt; price DECIMAL
515 MyDB(&gt; );
516 NOTICE: CREATE TABLE will create implicit sequence "products_product_id_seq"
517 for serial column "products.product_id"
518 CREATE TABLE
519 </pre>
520
521 <p>
522 You can ignore the NOTICE, it's perfectly harmless. Looking at the last line of
523 the function, <c>CREATE TABLE</c> seems to indicate that the command has
524 succeeded. However, let's go ahead and verify that the table was indeed
525 successfully created with the <c>\d</c> command:
526 </p>
527
528 <pre caption="Looking at the newly created table">
529 MyDB=&gt; <i>\d products</i>
530 Table "public.products"
531 Column | Type | Modifiers
532 -------------+---------+------------------------------------------------------------------
533 product_id | integer | not null default nextval('public.products_product_id_seq'::text)
534 description | text |
535 price | numeric |
536 </pre>
537
538 <p>
539 Indeed the table was successfully created. Now that the table is created, it
540 needs to be populated with data. The next section will look at populating the
541 database with data.
542 </p>
543
544 </body>
545 </section>
546 <section>
547 <title>Inserting data into the database</title>
548 <body>
549
550 <p>
551 This section will look at the two ways of populating the newly created table
552 with data. First let's look at the most basic command, <c>INSERT</c>:
553 </p>
554
555 <pre caption="INSERT syntax">
556 INSERT INTO [tablename] (column1,column2,column3) VALUES(value1,value2,value3)
557 </pre>
558
559 <p>
560 <c>tablename</c> contains the name of the table to insert the data into.
561 (column1,column2,column3) lets you specify the specific columns to insert the
562 values into. VALUES(value1,value2,value3) is the listing of values. The values
563 are inserted into the same order as the columns (column1 gets value1, column2
564 gets value2, column3 gets value3). These counts <e>must</e> be the same. So
565 let's go ahead and insert an item into the table:
566 </p>
567
568 <impo>
569 From working with databases for a long time, I personally recommend specifying
570 <c>INSERT</c> statements exactly as above. Developers often make the mistake of
571 using <c>INSERT INTO</c> without specifying columns. This is unproductive, as
572 if a new column gets added to the database, it will cause in error if the value
573 to column count is not the same. You should <e>always</e> specify the columns
574 unless you're 300% sure you'll never add a column.
575 </impo>
576
577 <pre caption="Inserting data into the table">
578 MyDB=&gt; <i>INSERT INTO products (description,price) VALUES('A test product', 12.00);</i>
579 INSERT 17273 1
580 </pre>
581
582 <p>
583 The last line needs a bit of explaining. The return of an insert command is an
584 OID (Object Identifier) and the number of rows inserted. OID's are a bit beyond
585 the scope of this guide, and the <uri
586 link="http://www.postgresql.org/docs/8.1/static/datatype-oid.html">PostgreSQL
587 manual</uri> has some good information on it. Now, for a situation where you
588 have 20,000 products, these insert statements can be a little tedious. However,
589 not all is lost. The <c>COPY</c> command can be used to insert data into a
590 table from a file or stdin. In this example, let's assume that you have a csv
591 (comma separated values) file, which contains the product id, description, and
592 price. The file looks like this:
593 </p>
594
595 <pre caption="products.csv">
596 2,meat,6.79
597 3,soup,0.69
598 4,soda,1.79
599 </pre>
600
601 <p>
602 Now we'll use the <c>COPY</c> command to populate our data:
603 </p>
604
605 <impo>
606 The <c>COPY FROM STDIN</c> command is used because only the postgres user can
607 insert data from a file (for obvious security reasons).
608 </impo>
609
610 <pre caption="Using COPY to populate the products table">
611 MyDB=&gt; <i>COPY products FROM STDIN WITH DELIMITER AS ',';</i>
612 Enter data to be copied followed by a newline.
613 End with a backslash and a period on a line by itself.
614 >> <i>2,meat,6.79</i>
615 >> <i>3,soup,0.69</i>
616 >> <i>4,soda,1.79</i>
617 >> <i>\.</i>
618 </pre>
619
620 <p>
621 Unfortunately, this line doesn't return the same status information as the
622 <c>INSERT INTO</c> statement. How do we know the data was inserted? The next
623 section will look at running queries to check our data.
624 </p>
625
626 </body>
627 </section>
628 <section>
629 <title>Using PostgreSQL queries</title>
630 <body>
631
632 <p>
633 This section will look at using the <c>SELECT</c> statement to view data in our
634 tables. The basic <c>SELECT</c> format looks like this:
635 </p>
636
637 <pre caption="SELECT syntax">
638 SELECT (column1,column2|*) FROM (table) [WHERE (conditionals)]
639 </pre>
640
641 <p>
642 There are two ways to select columns. The first is using <c>*</c> to select all
643 columns, and the second is to specify a list of specific columns you wish to
644 see. The second is quite handy when you want to find a specific column in a
645 rather large list of them. Let's start out with using <c>SELECT</c> with
646 <c>*</c> to specify all columns:
647 </p>
648
649 <pre caption="Viewing the products table">
650 MyDB=&gt; <i>SELECT * FROM products;</i>
651 product_id | description | price
652 ------------+----------------+-------
653 1 | A test product | 12.00
654 2 | meat | 6.79
655 3 | soup | 0.69
656 4 | soda | 1.79
657 (4 rows)
658 </pre>
659
660 <p>
661 As shown here, all the data we inserted earlier is indeed in the table. Now
662 let's say we only want to see the description and the price, and don't care
663 about the product id. In this case we'll use the column specific SELECT form:
664 </p>
665
666 <pre caption="Viewing specific columns from the products table">
667 MyDB=&gt; <i>SELECT description,price FROM products;</i>
668 description | price
669 ----------------+-------
670 A test product | 12.00
671 meat | 6.79
672 soup | 0.69
673 soda | 1.79
674 (4 rows)
675 </pre>
676
677 <p>
678 Now only the product and price is shown, letting us focus on only the important
679 data. Now let's say that we want to see only the items that are greater than
680 $2.00. Here's where the <c>WHERE</c> clause comes in handy:
681 </p>
682
683 <pre caption="Viewing specific rows from the products table">
684 MyDB=&gt; <i>SELECT description,price FROM products WHERE price > 2.00;</i>
685 description | price
686 ----------------+-------
687 A test product | 12.00
688 meat | 6.79
689 (2 rows)
690 </pre>
691
692 <p>
693 Now a listing of products over $2.00 is displayed, focusing the data even more.
694 These forms of querying for information are very powerful, and can help create
695 extremely useful reports.
696 </p>
697
698 </body>
699 </section>
700 <section>
701 <title>Conclusion</title>
702 <body>
703
704 <p>
705 This concludes the PostgreSQL Guide. A big thanks goes to Masatomo Nakano, the
706 previous Gentoo PostgreSQL maintainer for his help in answering my questions.
707 Any suggestions on this guide should be sent to
708 <mail>chriswhite@gentoo.org</mail>. For more extensive documentation, see the
709 <uri link="http://www.postgresql.org">PostgreSQL website</uri>.
710 </p>
711
712 </body>
713 </section>
714 </chapter>
715 </guide>

  ViewVC Help
Powered by ViewVC 1.1.20