From 0bf814117227906fc089011420add221f69be5c2 Mon Sep 17 00:00:00 2001 From: "Thomas G. Lockhart" Date: Mon, 6 Apr 1998 15:33:53 +0000 Subject: [PATCH] Older html conversion of original docs to html superceded by the new sgml/docbook versions. --- doc/manual/admin.html | 539 -------------------------- doc/manual/advanced.html | 237 ------------ doc/manual/appenda.html | 200 ---------- doc/manual/architec.html | 76 ---- doc/manual/copy.html | 32 -- doc/manual/extend.html | 199 ---------- doc/manual/figure01.gif | Bin 10020 -> 0 bytes doc/manual/figure02.gif | Bin 6306 -> 0 bytes doc/manual/figure03.gif | Bin 26163 -> 0 bytes doc/manual/intro.html | 201 ---------- doc/manual/libpq.html | 815 --------------------------------------- doc/manual/lobj.html | 429 --------------------- doc/manual/pg95user.html | 154 -------- doc/manual/query.html | 259 ------------- doc/manual/refs.html | 55 --- doc/manual/rules.html | 43 --- doc/manual/start.html | 231 ----------- doc/manual/xaggr.html | 109 ------ doc/manual/xfunc.html | 474 ----------------------- doc/manual/xindex.html | 430 --------------------- doc/manual/xoper.html | 70 ---- doc/manual/xtypes.html | 148 ------- 22 files changed, 4701 deletions(-) delete mode 100644 doc/manual/admin.html delete mode 100644 doc/manual/advanced.html delete mode 100644 doc/manual/appenda.html delete mode 100644 doc/manual/architec.html delete mode 100644 doc/manual/copy.html delete mode 100644 doc/manual/extend.html delete mode 100644 doc/manual/figure01.gif delete mode 100644 doc/manual/figure02.gif delete mode 100644 doc/manual/figure03.gif delete mode 100644 doc/manual/intro.html delete mode 100644 doc/manual/libpq.html delete mode 100644 doc/manual/lobj.html delete mode 100644 doc/manual/pg95user.html delete mode 100644 doc/manual/query.html delete mode 100644 doc/manual/refs.html delete mode 100644 doc/manual/rules.html delete mode 100644 doc/manual/start.html delete mode 100644 doc/manual/xaggr.html delete mode 100644 doc/manual/xfunc.html delete mode 100644 doc/manual/xindex.html delete mode 100644 doc/manual/xoper.html delete mode 100644 doc/manual/xtypes.html diff --git a/doc/manual/admin.html b/doc/manual/admin.html deleted file mode 100644 index be24aca1e6..0000000000 --- a/doc/manual/admin.html +++ /dev/null @@ -1,539 +0,0 @@ - - - The POSTGRES95 User Manual - ADMINISTERING POSTGRES - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

15. ADMINISTERING POSTGRES

-
- In this section, we will discuss aspects of POSTGRES - that are of interest to those who make extensive use of - POSTGRES, or who are the site administrator for a group - of POSTGRES users. - -

15.1. Frequent Tasks

- Here we will briefly discuss some procedures that you - should be familiar with in managing any POSTGRES - installation. - -

15.1.1. Starting the Postmaster

- If you did not install POSTGRES exactly as described in - the installation instructions, you may have to perform - some additional steps before starting the postmaster - process. - - -

15.1.2. Shutting Down the Postmaster

- If you need to halt the postmaster process, you can use - the UNIX kill(1) command. Some people habitually use - the -9 or -KILL option; this should never be necessary - and we do not recommend that you do this, as the postmaster - will be unable to free its various shared - resources, its child processes will be unable to exit - gracefully, etc. - -

15.1.3. Adding and Removing Users

- The createuser and destroyuser commands enable and disable - access to POSTGRES by specific users on the host - system. - -

15.1.4. Periodic Upkeep

- The vacuum command should be run on each database periodically. - This command processes deleted instances[9] - and, more importantly, updates the system statistics - concerning the size of each class. If these statistics - are permitted to become out-of-date and inaccurate, the - POSTGRES query optimizer may make extremely poor decisions - with respect to query evaluation strategies. - Therefore, we recommend running vacuum every night or - so (perhaps in a script that is executed by the UNIX - cron(1) or at(1) commands). - Do frequent backups. That is, you should either back - up your database directories using the POSTGRES copy - command and/or the UNIX dump(1) or tar(1) commands. - You may think, "Why am I backing up my database? What - about crash recovery?" One side effect of the POSTGRES - "no overwrite" storage manager is that it is also a "no - log" storage manager. That is, the database log stores - only abort/commit data, and this is not enough information - to recover the database if the storage medium - (disk) or the database files are corrupted! In other - words, if a disk block goes bad or POSTGRES happens to - corrupt a database file, you cannot recover that file. - This can be disastrous if the file is one of the shared - catalogs, such as pg_database. - -

15.1.5. Tuning

- Once your users start to load a significant amount of - data, you will typically run into performance problems. - POSTGRES is not the fastest DBMS in the world, but many - of the worst problems encountered by users are due to - their lack of experience with any DBMS. Some general - tips include: -
    -
  1. Define indices over attributes that are commonly - used for qualifications. For example, if you - often execute queries of the form - -
                    SELECT * from EMP where salary < 5000
    -
    - then a B-tree index on the salary attribute will - probably be useful. If scans involving equality - are more common, as in - -
                    SELECT * from EMP where salary = 5000
    -
    - then you should consider defining a hash index - on salary. You can define both, though it will - use more disk space and may slow down updates a - bit. Scans using indices are much faster than - sequential scans of the entire class.

    -

  2. Run the vacuum command a lot. This command - updates the statistics that the query optimizer - uses to make intelligent decisions; if the - statistics are inaccurate, the system will make - inordinately stupid decisions with respect to - the way it joins and scans classes.

    -

  3. When specifying query qualfications (i.e., the - where part of the query), try to ensure that a - clause involving a constant can be turned into - one of the form range_variable operator constant, e.g., - -
                    EMP.salary = 5000
    -
    - The POSTGRES query optimizer will only use an - index with a constant qualification of this - form. It doesn't hurt to write the clause as - -
                    5000 = EMP.salary
    -
    - if the operator (in this case, =) has a commutator - operator defined so that POSTGRES can - rewrite the query into the desired form. However, - if such an operator does not exist, POSTGRES - will never consider the use of an index.

    -

  4. When joining several classes together in one - query, try to write the join clauses in a - "chained" form, e.g., - -
                    where A.a = B.b and B.b = C.c and ...
    -
    - Notice that relatively few clauses refer to a - given class and attribute; the clauses form a - linear sequence connecting the attributes, like - links in a chain. This is preferable to a query - written in a "star" form, such as - -
                    where A.a = B.b and A.a = C.c and ...
    -
    - Here, many clauses refer to the same class and - attribute (in this case, A.a). When presented - with a query of this form, the POSTGRES query - optimizer will tend to consider far more choices - than it should and may run out of memory.

    -

  5. If you are really desperate to see what query - plans look like, you can run the postmaster with - the -d option and then run monitor with the -t - option. The format in which query plans will be - printed is hard to read but you should be able - to tell whether any index scans are being performed.
    -
- -

15.2. Infrequent Tasks

- - At some time or another, every POSTGRES site - administrator has to perform all of the following actions. - -15.2.1. Cleaning Up After Crashes - The postgres server and the postmaster run as two - different processes. They may crash separately or - together. The housekeeping procedures required to fix - one kind of crash are different from those required to - fix the other. - The message you will usually see when the backend - server crashes is: - -
         FATAL: no response from backend: detected in ...
-
- This generally means one of two things: there is a bug - in the POSTGRES server, or there is a bug in some user - code that has been dynamically loaded into POSTGRES. - You should be able to restart your application and - resume processing, but there are some considerations: -
    -
  1. POSTGRES usually dumps a core file (a snapshot - of process memory used for debugging) in the - database directory -
                    /usr/local/postgres95/data/base/<database>/core
    -
    - on the server machine. If you don't want to try - to debug the problem or produce a stack trace to - report the bug to someone else, you can delete - this file (which is probably around 10MB).

    -

  2. When one backend crashes in an uncontrolled way - (i.e., without calling its built-in cleanup - routines), the postmaster will detect this situation, - kill all running servers and reinitialize - the state shared among all backends (e.g., the - shared buffer pool and locks). If your server - crashed, you will get the "no response" message - shown above. If your server was killed because - someone else's server crashed, you will see the - following message: - -
                    I have been signalled by the postmaster.
    -                Some backend process has died unexpectedly and possibly
    -                corrupted shared memory.  The current transaction was
    -                aborted, and I am going to exit.  Please resend the
    -                last query. -- The postgres backend
    -

    -
  3. Sometimes shared state is not completely cleaned - up. Frontend applications may see errors of the - form: - -
                    WARN: cannot write block 34 of myclass [mydb] blind
    -
    - In this case, you should kill the postmaster and - restart it.

    -

  4. When the system crashes while updating the system - catalogs (e.g., when you are creating a - class, defining an index, retrieving into a - class, etc.) the B-tree indices defined on the - catalogs are sometimes corrupted. The general - (and non-unique) symptom is that all queries - stop working. If you have tried all of the - above steps and nothing else seems to work, try - using the reindexdb command. If reindexdb succeeds - but things still don't work, you have - another problem; if it fails, the system catalogs - themselves were almost certainly corrupted - and you will have to go back to your backups.

    -

- The postmaster does not usually crash (it doesn't do - very much except start servers) but it does happen on - occasion. In addition, there are a few cases where it - encounters problems during the reinitialization of - shared resources. Specifically, there are race conditions - where the operating system lets the postmaster - free shared resources but then will not permit it to - reallocate the same amount of shared resources (even - when there is no contention). - You will typically have to run the ipcclean command if - system errors cause the postmaster to crash. If this - happens, you may find (using the UNIX ipcs(1) command) - that the "postgres" user has shared memory and/or - semaphores allocated even though no postmaster process - is running. In this case, you should run ipcclean as - the "postgres" user in order to deallocate these - resources. Be warned that all such resources owned by - the "postgres" user will be deallocated. If you have - multiple postmaster processes running on the same - machine, you should kill all of them before running - ipcclean (otherwise, they will crash on their own when - their shared resources are suddenly deallocated). - -

15.2.2. Moving Database Directories

- By default, all POSTGRES databases are stored in - separate subdirectories under - /usr/local/postgres95/data/base.[10] At some point, you - may find that you wish to move one or more databases to - another location (e.g., to a filesystem with more free - space). - If you wish to move all of your databases to the new - location, you can simply: - - To install a single database in an alternate directory - while leaving all other databases in place, do the following: - -

-

15.2.3. Updating Databases

- POSTGRES is a research system. In general, POSTGRES - may not retain the same binary format for the storage - of databases from release to release. Therefore, when - you update your POSTGRES software, you will probably - have to modify your databases as well. This is a common - occurrence with commercial database systems as - well; unfortunately, unlike commercial systems, POSTGRES - does not come with user-friendly utilities to make - your life easier when these updates occur. - In general, you must do the following to update your - databases to a new software release: - - You should give any new release a "trial period"; in - particular, do not delete the old database until you - are satisfied that there are no compatibility problems - with the new software. For example, you do not want to - discover that a bug in a type's "input" (conversion - from ASCII) and "output" (conversion to ASCII) routines - prevents you from reloading your data after you have - destroyed your old databases! (This should be standard - procedure when updating any software package, but some - people try to economize on disk space without applying - enough foresight.) - -

15.3. Database Security

- - Most sites that use POSTGRES are educational or - research institutions and do not pay much attention to - security in their POSTGRES installations. If desired, - one can install POSTGRES with additional security - features. Naturally, such features come with additional - administrative overhead that must be dealt with. - -

15.3.1. Kerberos

- POSTGRES can be configured to use the MIT Kerberos network - authentication system. This prevents outside - users from connecting to your databases over the network - without the correct authentication information. -

-

15.4. Querying the System Catalogs

- As an administrator (or sometimes as a plain user), you - want to find out what extensions have been added to a - given database. The queries listed below are "canned" - queries that you can run on any database to get simple - answers. Before executing any of the queries below, be - sure to execute the POSTGRES vacuum command. (The - queries will run much more quickly that way.) Also, - note that these queries are also listed in -
         /usr/local/postgres95/tutorial/syscat.sql
-
- so use cut-and-paste (or the \i command) instead of - doing a lot of typing. - This query prints the names of all database adminstrators - and the name of their database(s). -
         SELECT usename, datname
-             FROM pg_user, pg_database
-             WHERE usesysid = int2in(int4out(datdba))
-             ORDER BY usename, datname;
-
- This query lists all user-defined classes in the - database. -
         SELECT relname
-             FROM pg_class
-             WHERE relkind = 'r'           -- not indices
-               and relname !~ '^pg_'       -- not catalogs
-               and relname !~ '^Inv'       -- not large objects
-             ORDER BY relname;
-
- This query lists all simple indices (i.e., those that - are not defined over a function of several attributes). -
         SELECT bc.relname AS class_name,
-                  ic.relname AS index_name,
-                  a.attname
-             FROM pg_class bc,             -- base class
-                  pg_class ic,             -- index class
-                  pg_index i,
-                  pg_attribute a           -- att in base
-             WHERE i.indrelid = bc.oid
-                and i.indexrelid = ic.oid
-                and i.indkey[0] = a.attnum
-                and a.attrelid = bc.oid
-                and i.indproc = '0'::oid   -- no functional indices
-             ORDER BY class_name, index_name, attname;
-
- This query prints a report of the user-defined - attributes and their types for all user-defined classes - in the database. -
         SELECT c.relname, a.attname, t.typname
-             FROM pg_class c, pg_attribute a, pg_type t
-             WHERE c.relkind = 'r'     -- no indices
-               and c.relname !~ '^pg_' -- no catalogs
-               and c.relname !~ '^Inv' -- no large objects
-               and a.attnum > 0       -- no system att's
-               and a.attrelid = c.oid
-               and a.atttypid = t.oid
-             ORDER BY relname, attname;
-
- This query lists all user-defined base types (not - including array types). -
         SELECT u.usename, t.typname
-             FROM pg_type t, pg_user u
-             WHERE u.usesysid = int2in(int4out(t.typowner))
-               and t.typrelid = '0'::oid   -- no complex types
-               and t.typelem = '0'::oid    -- no arrays
-               and u.usename <> 'postgres'
-             ORDER BY usename, typname;
-
- This query lists all left-unary (post-fix) operators. -
         SELECT o.oprname AS left_unary,
-                  right.typname AS operand,
-                  result.typname AS return_type
-             FROM pg_operator o, pg_type right, pg_type result
-             WHERE o.oprkind = 'l'           -- left unary
-               and o.oprright = right.oid
-               and o.oprresult = result.oid
-             ORDER BY operand;
-
- This query lists all right-unary (pre-fix) operators. -
         SELECT o.oprname AS right_unary,
-                  left.typname AS operand,
-                  result.typname AS return_type
-             FROM pg_operator o, pg_type left, pg_type result
-             WHERE o.oprkind = 'r'          -- right unary
-               and o.oprleft = left.oid
-               and o.oprresult = result.oid
-             ORDER BY operand;
-
- This query lists all binary operators. -
         SELECT o.oprname AS binary_op,
-                  left.typname AS left_opr,
-                  right.typname AS right_opr,
-                  result.typname AS return_type
-             FROM pg_operator o, pg_type left, pg_type right, pg_type result
-             WHERE o.oprkind = 'b'         -- binary
-               and o.oprleft = left.oid
-               and o.oprright = right.oid
-               and o.oprresult = result.oid
-             ORDER BY left_opr, right_opr;
-
- This query returns the name, number of arguments - (parameters) and return type of all user-defined C - functions. The same query can be used to find all - built-in C functions if you change the "C" to "internal", - or all SQL functions if you change the "C" to - "sql". -
         SELECT p.proname, p.pronargs, t.typname
-             FROM pg_proc p, pg_language l, pg_type t
-             WHERE p.prolang = l.oid
-               and p.prorettype = t.oid
-               and l.lanname = 'c'
-             ORDER BY proname;
-
- This query lists all of the aggregate functions that - have been installed and the types to which they can be - applied. count is not included because it can take any - type as its argument. -
         SELECT a.aggname, t.typname
-             FROM pg_aggregate a, pg_type t
-             WHERE a.aggbasetype = t.oid
-             ORDER BY aggname, typname;
-
- This query lists all of the operator classes that can - be used with each access method as well as the operators - that can be used with the respective operator - classes. -
         SELECT am.amname, opc.opcname, opr.oprname
-             FROM pg_am am, pg_amop amop, pg_opclass opc, pg_operator opr
-             WHERE amop.amopid = am.oid
-               and amop.amopclaid = opc.oid
-               and amop.amopopr = opr.oid
-             ORDER BY amname, opcname, oprname;
-
-

- -


-9. -This may mean different things depending on the archive -mode with which each class has been created. However, the -current implementation of the vacuum command does not perform any compaction or clustering of data. Therefore, the -UNIX files which store each POSTGRES class never shrink and -the space "reclaimed" by vacuum is never actually reused. - -
-10. -Data for certain classes may stored elsewhere if a -non-standard storage manager was specified when they were -created. Use of non-standard storage managers is an experimental feature that is not supported outside of Berkeley. -
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/advanced.html b/doc/manual/advanced.html deleted file mode 100644 index 35ae6744bb..0000000000 --- a/doc/manual/advanced.html +++ /dev/null @@ -1,237 +0,0 @@ - - - The POSTGRES95 User Manual - ADVANCED POSTGRES SQL FEATURES - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

5. ADVANCED POSTGRES SQL FEATURES

-
- Having covered the basics of using POSTGRES SQL to - access your data, we will now discuss those features of - POSTGRES that distinguish it from conventional data - managers. These features include inheritance, time - travel and non-atomic data values (array- and - set-valued attributes). - Examples in this section can also be found in - advance.sql in the tutorial directory. (Refer to the - introduction of the previous chapter for how to use - it.) - -

5.1. Inheritance

- Let's create two classes. The capitals class contains - state capitals which are also cities. Naturally, the - capitals class should inherit from cities. - -
         CREATE TABLE cities (
-                 name            text,
-                 population      float,
-                 altitude        int            -- (in ft)
-         );
-
-         CREATE TABLE capitals (
-                 state           char2
-         ) INHERITS (cities);
-
- In this case, an instance of capitals inherits all - attributes (name, population, and altitude) from its - parent, cities. The type of the attribute name is - text, a built-in POSTGRES type for variable length - ASCII strings. The type of the attribute population is - float4, a built-in POSTGRES type for double precision - floating point numbres. State capitals have an extra - attribute, state, that shows their state. In POSTGRES, - a class can inherit from zero or more other classes,[4] - and a query can reference either all instances of a - class or all instances of a class plus all of its - descendants. For example, the following query finds - all the cities that are situated at an attitude of 500 - 'ft or higher: - -
         SELECT name, altitude
-         FROM cities
-         WHERE altitude > 500;
-
-
-         +----------+----------+
-         |name      | altitude |
-         +----------+----------+
-         |Las Vegas | 2174     |
-         +----------+----------+
-         |Mariposa  | 1953     |
-         +----------+----------+
-
- On the other hand, to find the names of all cities, - including state capitals, that are located at an altitude - over 500 'ft, the query is: - -
         SELECT c.name, c.altitude
-         FROM cities* c
-         WHERE c.altitude > 500;
-
- which returns: - -
         +----------+----------+
-         |name      | altitude |
-         +----------+----------+
-         |Las Vegas | 2174     |
-         +----------+----------+
-         |Mariposa  | 1953     |
-         +----------+----------+
-         |Madison   | 845      |
-         +----------+----------+
-
- Here the * after cities indicates that the query should - be run over cities and all classes below cities in the - inheritance hierarchy. Many of the commands that we - have already discussed -- select, update and delete -- - support this * notation, as do others, like alter command. - -

5.2. Time Travel

- POSTGRES supports the notion of time travel. This feature - allows a user to run historical queries. For - example, to find the current population of Mariposa - city, one would query: - -
         SELECT * FROM cities WHERE name = 'Mariposa';
-
-         +---------+------------+----------+
-         |name     | population | altitude |
-         +---------+------------+----------+
-         |Mariposa | 1320       | 1953     |
-         +---------+------------+----------+
-
- POSTGRES will automatically find the version of Mariposa's - record valid at the current time. - One can also give a time range. For example to see the - past and present populations of Mariposa, one would - query: - -
         SELECT name, population
-         FROM cities['epoch', 'now']
-         WHERE name = 'Mariposa';
-
- where "epoch" indicates the beginning of the system - clock.[5] If you have executed all of the examples so - far, then the above query returns: - -
         +---------+------------+
-         |name     | population |
-         +---------+------------+
-         |Mariposa | 1200       |
-         +---------+------------+
-         |Mariposa | 1320       |
-         +---------+------------+
-
- The default beginning of a time range is the earliest - time representable by the system and the default end is - the current time; thus, the above time range can be - abbreviated as ``[,].'' - -

5.3. Non-Atomic Values

- One of the tenets of the relational model is that the - attributes of a relation are atomic. POSTGRES does not - have this restriction; attributes can themselves contain - sub-values that can be accessed from the query - language. For example, you can create attributes that - are arrays of base types. - -

5.3.1. Arrays

- POSTGRES allows attributes of an instance to be defined - as fixed-length or variable-length multi-dimensional - arrays. Arrays of any base type or user-defined type - can be created. To illustrate their use, we first create a - class with arrays of base types. - -
         * CREATE TABLE SAL_EMP (
-                 name            text,
-                 pay_by_quarter  int4[],
-                 schedule        char16[][]
-         );
-
- The above query will create a class named SAL_EMP with - a text string (name), a one-dimensional array of int4 - (pay_by_quarter), which represents the employee's - salary by quarter and a two-dimensional array of char16 - (schedule), which represents the employee's weekly - schedule. Now we do some INSERTSs; note that when - appending to an array, we enclose the values within - braces and separate them by commas. If you know C, - this is not unlike the syntax for initializing structures. - -
         INSERT INTO SAL_EMP
-              VALUES ('Bill',
-                      '{10000, 10000, 10000, 10000}',
-                      '{{"meeting", "lunch"}, {}}');
-
-         INSERT INTO SAL_EMP
-              VALUES ('Carol',
-                      '{20000, 25000, 25000, 25000}',
-                      '{{"talk", "consult"}, {"meeting"}}');
-
- By default, POSTGRES uses the "one-based" numbering - convention for arrays -- that is, an array of n elements starts with array[1] and ends with array[n]. - Now, we can run some queries on SAL_EMP. First, we - show how to access a single element of an array at a - time. This query retrieves the names of the employees - whose pay changed in the second quarter: - -
         * SELECT name
-           FROM SAL_EMP
-           WHERE SAL_EMP.pay_by_quarter[1] <>
-                   SAL_EMP.pay_by_quarter[2];
-
-         +------+
-         |name  |
-         +------+
-         |Carol |
-         +------+
-
- This query retrieves the third quarter pay of all - employees: - -
         * SELECT SAL_EMP.pay_by_quarter[3] FROM SAL_EMP;
-
-
-         +---------------+
-         |pay_by_quarter |
-         +---------------+
-         |10000          |
-         +---------------+
-         |25000          |
-         +---------------+
-
- We can also access arbitrary slices of an array, or - subarrays. This query retrieves the first item on - Bill's schedule for the first two days of the week. - -
         * SELECT SAL_EMP.schedule[1:2][1:1]
-           FROM SAL_EMP
-           WHERE SAL_EMP.name = 'Bill';
-
-         +-------------------+
-         |schedule           |
-         +-------------------+
-         |{{"meeting"},{""}} |
-         +-------------------+
-
-
-

-


-4. i.e., the inheritance hierarchy is a directed acyclic -graph.
-5. On UNIX systems, this is always midnight, January 1, -1970 GMT.
-
- -[ TOC ] -[ Previous ] -[ Next ] - - diff --git a/doc/manual/appenda.html b/doc/manual/appenda.html deleted file mode 100644 index 6049e85f71..0000000000 --- a/doc/manual/appenda.html +++ /dev/null @@ -1,200 +0,0 @@ - - - The POSTGRES95 User Manual - Appendix A: - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

Appendix A: Linking Dynamically-Loaded Functions

-
- After you have created and registered a user-defined - function, your work is essentially done. POSTGRES, - however, must load the object code (e.g., a .o file, or - a shared library) that implements your function. As - previously mentioned, POSTGRES loads your code at - runtime, as required. In order to allow your code to be - dynamically loaded, you may have to compile and - linkedit it in a special way. This section briefly - describes how to perform the compilation and - linkediting required before you can load your user-defined - functions into a running POSTGRES server. Note that - this process has changed as of Version 4.2.11 You - should expect to read (and reread, and re-reread) the - manual pages for the C compiler, cc(1), and the link - editor, ld(1), if you have specific questions. In - addition, the regression test suites in the directory - /usr/local/postgres95/src/regress contain several - working examples of this process. If you copy what these - tests do, you should not have any problems. - The following terminology will be used below: -
-
Dynamic loading -
is what POSTGRES does to an object file. The - object file is copied into the running POSTGRES - server and the functions and variables within the - file are made available to the functions within - the POSTGRES process. POSTGRES does this using - the dynamic loading mechanism provided by the - operating system. - -
Loading and link editing -
is what you do to an object file in order to produce - another kind of object file (e.g., an executable - program or a shared library). You perform - this using the link editing program, ld(1). -
-

- The following general restrictions and notes also apply - to the discussion below. -

-

-ULTRIX
- It is very easy to build dynamically-loaded object - files under ULTRIX. ULTRIX does not have any sharedlibrary - mechanism and hence does not place any restrictions on - the dynamic loader interface. On the other - hand, we had to (re)write a non-portable dynamic loader - ourselves and could not use true shared libraries. - Under ULTRIX, the only restriction is that you must - produce each object file with the option -G 0. (Notice - that that's the numeral ``0'' and not the letter - ``O''). For example, - -

              # simple ULTRIX example
-              % cc -G 0 -c foo.c
-
- produces an object file called foo.o that can then be - dynamically loaded into POSTGRES. No additional loading or link-editing must be performed. -

-DEC OSF/1
- Under DEC OSF/1, you can take any simple object file - and produce a shared object file by running the ld command over it with the correct options. The commands to - do this look like: - -

              # simple DEC OSF/1 example
-              % cc -c foo.c
-              % ld -shared -expect_unresolved '*' -o foo.so foo.o
-
- The resulting shared object file can then be loaded - into POSTGRES. When specifying the object file name to - the create function command, one must give it the name - of the shared object file (ending in .so) rather than - the simple object file.13 If the file you specify is - not a shared object, the backend will hang! -

-SunOS 4.x, Solaris 2.x and HP-UX
- Under both SunOS 4.x, Solaris 2.x and HP-UX, the simple - object file must be created by compiling the source - file with special compiler flags and a shared library - must be produced. - The necessary steps with HP-UX are as follows. The +z - flag to the HP-UX C compiler produces so-called - "Position Independent Code" (PIC) and the +u flag - removes - some alignment restrictions that the PA-RISC architecture - normally enforces. The object file must be turned - into a shared library using the HP-UX link editor with - the -b option. This sounds complicated but is actually - very simple, since the commands to do it are just: -

              # simple HP-UX example
-              % cc +z +u -c foo.c
-              % ld -b -o foo.sl foo.o
-
- - As with the .so files mentioned in the last subsection, - the create function command must be told which file is - the correct file to load (i.e., you must give it the - location of the shared library, or .sl file). - Under SunOS 4.x, the commands look like: - -
              # simple SunOS 4.x example
-              % cc -PIC -c foo.c
-              % ld -dc -dp -Bdynamic -o foo.so foo.o
-
- and the equivalent lines under Solaris 2.x are: -
              # simple Solaris 2.x example
-              % cc -K PIC -c foo.c
-                   or
-              % gcc -fPIC -c foo.c
-              % ld -G -Bdynamic -o foo.so foo.o
-
- When linking shared libraries, you may have to specify - some additional shared libraries (typically system - libraries, such as the C and math libraries) on your ld - command line. -
-11. The old POSTGRES dynamic -loading mechanism required -in-depth knowledge in terms of executable format, placement -and alignment of executable instructions within memory, etc. -on the part of the person writing the dynamic loader. Such -loaders tended to be slow and buggy. As of Version 4.2, the -POSTGRES dynamic loading mechanism has been rewritten to use -the dynamic loading mechanism provided by the operating -system. This approach is generally faster, more reliable and -more portable than our previous dynamic loading mechanism. -The reason for this is that nearly all modern versions of -UNIX use a dynamic loading mechanism to implement shared -libraries and must therefore provide a fast and reliable -mechanism. On the other hand, the object file must be -postprocessed a bit before it can be loaded into POSTGRES. We -hope that the large increase in speed and reliability will -make up for the slight decrease in convenience. -
-12. Relative paths do in fact work, -but are relative to -the directory where the database resides (which is generally -invisible to the frontend application). Obviously, it makes -no sense to make the path relative to the directory in which -the user started the frontend application, since the server -could be running on a completely different machine!
-
-13. Actually, POSTGRES does not care -what you name the -file as long as it is a shared object file. If you prefer -to name your shared object files with the extension .o, this -is fine with POSTGRES so long as you make sure that the correct -file name is given to the create function command. In -other words, you must simply be consistent. However, from a -pragmatic point of view, we discourage this practice because -you will undoubtedly confuse yourself with regards to which -files have been made into shared object files and which have -not. For example, it's very hard to write Makefiles to do -the link-editing automatically if both the object file and -the shared object file end in .o!
- -
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/architec.html b/doc/manual/architec.html deleted file mode 100644 index 65c6a3e2b4..0000000000 --- a/doc/manual/architec.html +++ /dev/null @@ -1,76 +0,0 @@ - - - The POSTGRES95 User Manual - ARCHITECTURE - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

2. POSTGRES ARCHITECTURE CONCEPTS

-
- Before we continue, you should understand the basic - POSTGRES system architecture. Understanding how the - parts of POSTGRES interact will make the next chapter - somewhat clearer. - In database jargon, POSTGRES uses a simple "process - per-user" client/server model. A POSTGRES session - consists of the following cooperating UNIX processes (programs): - - A single postmaster manages a given collection of - databases on a single host. Such a collection of - databases is called an installation or site. Frontend - applications that wish to access a given database - within an installation make calls to the library. - The library sends user requests over the network to the - postmaster (Figure 1(a)), which in turn starts a new - backend server process (Figure 1(b)) - - Figure 1- How a connection is established
- - and connects the - frontend process to the new server (Figure 1(c)). From - that point on, the frontend process and the backend - server communicate without intervention by the - postmaster. Hence, the postmaster is always running, waiting - for requests, whereas frontend and backend processes - come and go. The LIBPQ library allows a single - frontend to make multiple connections to backend processes. - However, the frontend application is still a - single-threaded process. Multithreaded frontend/backend - connections are not currently supported in LIBPQ. - One implication of this architecture is that the - postmaster and the backend always run on the same - machine (the database server), while the frontend - application may run anywhere. You should keep this - in mind, - because the files that can be accessed on a client - machine may not be accessible (or may only be accessed - using a different filename) on the database server - machine. - You should also be aware that the postmaster and - postgres servers run with the user-id of the POSTGRES - "superuser." Note that the POSTGRES superuser does not - have to be a special user (e.g., a user named - "postgres"). Furthermore, the POSTGRES superuser - should - definitely not be the UNIX superuser, "root"! In any - case, all files relating to a database should belong to - this POSTGRES superuser. - -
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/copy.html b/doc/manual/copy.html deleted file mode 100644 index 387334414b..0000000000 --- a/doc/manual/copy.html +++ /dev/null @@ -1,32 +0,0 @@ - - - The POSTGRES95 - Copyright - - - -

The POSTGRES95 - Copyright

-
- POSTGRES95 is copyright (C) 1994-5 by the Regents of the -University of California. Permission to use, copy, modify, -and distribute this software and its documentation for any -purpose, without fee, and without a written agreement is -hereby granted, provided that the above copyright notice and -this paragraph and the following two paragraphs appear in -all copies.

- IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE - LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, - INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST - PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND - ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA - HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - THE UNIVERSITY OF CALIFORNIA SPECIFICALLY - DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED - HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF - CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, - SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. - - - - diff --git a/doc/manual/extend.html b/doc/manual/extend.html deleted file mode 100644 index a3cdfc0621..0000000000 --- a/doc/manual/extend.html +++ /dev/null @@ -1,199 +0,0 @@ - - - The POSTGRES95 User Manual - EXTENDING SQL: AN OVERVIEW - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -


- -

6. EXTENDING SQL: AN OVERVIEW

-
- In the sections that follow, we will discuss how you - can extend the POSTGRES SQL query language by adding: - -

-

6.1. How Extensibility Works

- POSTGRES is extensible because its operation is - catalog-driven. If you are familiar with standard - relational systems, you know that they store information - about databases, tables, columns, etc., in what are - commonly known as system catalogs. (Some systems call - this the data dictionary). The catalogs appear to the - user as classes, like any other, but the DBMS stores - its internal bookkeeping in them. One key difference - between POSTGRES and standard relational systems is - that POSTGRES stores much more information in its - catalogs -- not only information about tables and columns, - but also information about its types, functions, access - methods, and so on. These classes can be modified by - the user, and since POSTGRES bases its internal operation - on these classes, this means that POSTGRES can be - extended by users. By comparison, conventional - database systems can only be extended by changing hardcoded - procedures within the DBMS or by loading modules - specially-written by the DBMS vendor. - POSTGRES is also unlike most other data managers in - that the server can incorporate user-written code into - itself through dynamic loading. That is, the user can - specify an object code file (e.g., a compiled .o file - or shared library) that implements a new type or function - and POSTGRES will load it as required. Code written - in SQL are even more trivial to add to the server. - This ability to modify its operation "on the fly" makes - POSTGRES uniquely suited for rapid prototyping of new - applications and storage structures. - -

6.2. The POSTGRES Type System

- The POSTGRES type system can be broken down in several - ways. - Types are divided into base types and composite types. - Base types are those, like int4, that are implemented - in a language such as C. They generally correspond to - what are often known as "abstract data types"; POSTGRES - can only operate on such types through methods provided - by the user and only understands the behavior of such - types to the extent that the user describes them. - Composite types are created whenever the user creates a - class. EMP is an example of a composite type. - POSTGRES stores these types in only one way (within the - file that stores all instances of the class) but the - user can "look inside" at the attributes of these types - from the query language and optimize their retrieval by - (for example) defining indices on the attributes. - POSTGRES base types are further divided into built-in - types and user-defined types. Built-in types (like - int4) are those that are compiled into the system. - User-defined types are those created by the user in the - manner to be described below. - -

6.3. About the POSTGRES System Catalogs

- Having introduced the basic extensibility concepts, we - can now take a look at how the catalogs are actually - laid out. You can skip this section for now, but some - later sections will be incomprehensible without the - information given here, so mark this page for later - reference. - All system catalogs have names that begin with pg_. - The following classes contain information that may be - useful to the end user. (There are many other system - catalogs, but there should rarely be a reason to query - them directly.) -

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
catalog name description
pg_database databases
pg_class classes
pg_attribute class attributes
pg_index secondary indices
pg_proc procedures (both C and SQL)
pg_type types (both base and complex)
pg_operator operators
pg_aggregate aggregates and aggregate functions
pg_am access methods
pg_amop access method operators
pg_amproc access method support functions
pg_opclass access method operator classes
-
- -

- Figure 3.  The major POSTGRES system catalogs - The Reference Manual gives a more detailed explanation - of these catalogs and their attributes. However, Figure 3 - shows the major entities and their relationships - in the system catalogs. (Attributes that do not refer - to other entities are not shown unless they are part of - a primary key.) - This diagram is more or less incomprehensible until you - actually start looking at the contents of the catalogs - and see how they relate to each other. For now, the - main things to take away from this diagram are as follows: - -

    -
  1. In several of the sections that follow, we will - present various join queries on the system - catalogs that display information we need to extend - the system. Looking at this diagram should make - some of these join queries (which are often - three- or four-way joins) more understandable, - because you will be able to see that the - attributes used in the queries form foreign keys - in other classes. -
  2. Many different features (classes, attributes, - functions, types, access methods, etc.) are - tightly integrated in this schema. A simple - create command may modify many of these catalogs. -
  3. Types and procedures [6] - are central to the schema. - Nearly every catalog contains some reference to - instances in one or both of these classes. For - example, POSTGRES frequently uses type - signatures (e.g., of functions and operators) to - identify unique instances of other catalogs. -
  4. There are many attributes and relationships that - have obvious meanings, but there are many - (particularly those that have to do with access - methods) that do not. The relationships between - pg_am, pg_amop, pg_amproc, pg_operator and - pg_opclass are particularly hard to understand - and will be described in depth (in the section - on interfacing types and operators to indices) - after we have discussed basic extensions. -
-

-


-6. We use the words procedure and function more or less -interchangably. -
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/figure01.gif b/doc/manual/figure01.gif deleted file mode 100644 index 58337e2595f1f81c246ef08dae6029ffc08d4fa5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10020 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 diff --git a/doc/manual/figure02.gif b/doc/manual/figure02.gif deleted file mode 100644 index bdf3925c9a74f62df99fe6d0d65cf114e13e39a3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6306 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 Y(8CWw3{k`pNi5OC6H!bNvjPABJ6@!?6aWAK diff --git a/doc/manual/figure03.gif b/doc/manual/figure03.gif deleted file mode 100644 index 24e3187e6c69718bc8091484c1ba1dffc67021c0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26163 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 WW_qS*nx<;Hrfk}#Zt4yN0028a^-3%N diff --git a/doc/manual/intro.html b/doc/manual/intro.html deleted file mode 100644 index cf7b75af57..0000000000 --- a/doc/manual/intro.html +++ /dev/null @@ -1,201 +0,0 @@ - - - The POSTGRES95 User Manual - Introduction - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

1. INTRODUCTION

-
- This document is the user manual for the - POSTGRES95 - database management system developed at the University - of California at Berkeley. POSTGRES95 is based on - - POSTGRES release 4.2. The POSTGRES project, - led by Professor Michael Stonebraker, has been sponsored by the - Defense Advanced Research Projects Agency (DARPA), the - Army Research Office (ARO), the National Science - Foundation (NSF), and ESL, Inc. -

1.1. What is POSTGRES?

- Traditional relational database management systems - (DBMSs) support a data model consisting of a collection - of named relations, containing attributes of a specific - type. In current commercial systems, possible types - include floating point numbers, integers, character - strings, money, and dates. It is commonly recognized - that this model is inadequate for future data - processing applications. - The relational model successfully replaced previous - models in part because of its "Spartan simplicity". - However, as mentioned, this simplicity often makes the - implementation of certain applications very difficult - to implement. POSTGRES offers substantial additional - power by incorporating the following four additional - basic constructs in such a way that users can easily - extend the system: -

-

         classes
-         inheritance
-         types
-         functions
-

- In addition, POSTGRES supports a powerful production - rule system. - -

1.2. A Short History of the POSTGRES Project

- Implementation of the POSTGRES DBMS began in 1986. The - initial concepts for the system were presented in - [STON86] and the definition of the initial data model - appeared in [ROWE87]. The design of the rule system at - that time was described in [STON87a]. The rationale - and architecture of the storage manager were detailed - in [STON87b]. - POSTGRES has undergone several major releases since - then. The first "demoware" system became operational - in 1987 and was shown at the 1988 ACM-SIGMOD - Conference. We released Version 1, described in [STON90a], - to a few external users in June 1989. In response to a - critique of the first rule system [STON89], the rule - system was redesigned [STON90b] and Version 2 was - released in June 1990 with the new rule system. - Version 3 appeared in 1991 and added support for multiple - storage managers, an improved query executor, and a - rewritten rewrite rule system. For the most part, - releases since then have focused on portability and - reliability. - POSTGRES has been used to implement many different - research and production applications. These include: a - financial data analysis system, a jet engine - performance monitoring package, an asteroid tracking - database, a medical information database, and several - geographic information systems. POSTGRES has also been - used as an educational tool at several universities. - Finally, Illustra Information Technologies picked up - the code and commercialized it. - POSTGRES became the primary data manager for the - Sequoia 2000 scientific computing project in late 1992. - Furthermore, the size of the external user community - nearly doubled during 1993. It became increasingly - obvious that maintenance of the prototype code and - support was taking up large amounts of time that should - have been devoted to database research. In an effort - to reduce this support burden, the project officially - ended with Version 4.2. - -

1.3. What is POSTGRES95?

- POSTGRES95 is a derivative of the last official release - of POSTGRES (version 4.2). The code is now completely - ANSI C and the code size has been trimmed by 25%. There - are a lot of internal changes that improve performance - and code maintainability. POSTGRES95 runs about 30-50% - faster on the Wisconsin Benchmark compared to v4.2. - Apart from bug fixes, these are the major enhancements: -
    -
  • The query language POSTQUEL has been replaced with - SQL (implemented in the server). We do not support - subqueries (which can be imitated with user defined - SQL functions) at the moment. Aggregates have been - re-implemented. We also added support for GROUP BY. - The libpq interface is still available for C - programs. -
  • In addition to the monitor program, we provide a new - program (psql) which supports GNU readline. -
  • We added a new front-end library, libpgtcl, that - supports Tcl-based clients. A sample shell, - pgtclsh, provides new Tcl commands to interface tcl - programs with the POSTGRES95 backend. -
  • The large object interface has been overhauled. We - kept Inversion large objects as the only mechanism - for storing large objects. (This is not to be - confused with the Inversion file system which has been - removed.) -
  • The instance-level rule system has been removed. -
  • Rules are still available as rewrite rules. -
  • A short tutorial introducing regular SQL features as - well as those of ours is distributed with the source - code. -
  • GNU make (instead of BSD make) is used for the - build. Also, POSTGRES95 can be compiled with an - unpatched gcc (data alignment of doubles has been - fixed). -
-

-

1.4. About This Release

- POSTGRES95 is available free of charge. This manual - describes version 1.0 of POSTGRES95. The authors have - compiled and tested POSTGRES95 on the following - platforms: -

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArchitectureProcessorOperating System
DECstation 3000Alpha AXPOSF/1 2.1, 3.0, 3.2
DECstation 5000MIPSULTRIX 4.4
Sun4SPARCSunOS 4.1.3, 4.1.3_U1; Solaris 2.4
H-P 9000/700 and 800PA-RISCHP-UX 9.00, 9.01, 9.03
IntelX86Linux 1.2.8, ELF
-
-

-

1.5. Outline of This Manual

- From now on, We will use POSTGRES to mean POSTGRES95. - The first part of this manual goes over some basic sys- - tem concepts and procedures for starting the POSTGRES - system. We then turn to a tutorial overview of the - POSTGRES data model and SQL query language, introducing - a few of its advanced features. Next, we explain the - POSTGRES approach to extensibility and describe how - users can extend POSTGRES by adding user-defined types, - operators, aggregates, and both query language and pro- - gramming language functions. After an extremely brief - overview of the POSTGRES rule system, the manual - concludes with a detailed appendix that discusses some of - the more involved and operating system-specific - procedures involved in extending the system. -
-UNIX is a trademark of X/Open, Ltd. Sun4, SPARC, SunOS -and Solaris are trademarks of Sun Microsystems, Inc. DEC, -DECstation, Alpha AXP and ULTRIX are trademarks of Digital -Equipment Corp. PA-RISC and HP-UX are trademarks of -Hewlett-Packard Co. OSF/1 is a trademark of the Open -Software Foundation.

- - We assume proficiency with UNIX and C programming. - -


- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/libpq.html b/doc/manual/libpq.html deleted file mode 100644 index 71f8e7a150..0000000000 --- a/doc/manual/libpq.html +++ /dev/null @@ -1,815 +0,0 @@ - - - The POSTGRES95 User Manual - LIBPQ - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

12. LIBPQ

-
- LIBPQ is the application programming interface to POSTGRES. - LIBPQ is a set of library routines which allows - client programs to pass queries to the POSTGRES backend - server and to receive the results of these queries. - This version of the documentation describes the C - interface library. Three short programs are included - at the end of this section to show how to write programs that use LIBPQ. - There are several examples of LIBPQ applications in the - following directories: - -
         ../src/test/regress
-         ../src/test/examples
-         ../src/bin/psql
-
- Frontend programs which use LIBPQ must include the - header file libpq-fe.h and must link with the libpq - library. - -

12.1. Control and Initialization

- The following environment variables can be used to set - up default environment values to avoid hard-coding - database names into an application program: - -
    -
  • PGHOST sets the default server name. -
  • PGOPTIONS sets additional runtime options for the POSTGRES backend. -
  • PGPORT sets the default port for communicating with the POSTGRES backend. -
  • PGTTY sets the file or tty on which debugging messages from the backend server are displayed. -
  • PGDATABASE sets the default POSTGRES database name. -
  • PGREALM sets the Kerberos realm to use with POSTGRES, if it is different from the local realm. If -
  • PGREALM is set, POSTGRES applications will attempt - authentication with servers for this realm and use - separate ticket files to avoid conflicts with local - ticket files. This environment variable is only - used if Kerberos authentication is enabled. -
- -

12.2. Database Connection Functions

- The following routines deal with making a connection to - a backend from a C program. - -
-
PQsetdb -
Makes a new connection to a backend. -
              PGconn *PQsetdb(char *pghost,
-                              char *pgport,
-                              char *pgoptions,
-                              char *pgtty,
-                              char *dbName);
-
-
If any argument is NULL, then the corresponding - environment variable is checked. If the environment variable is also not set, then hardwired - defaults are used. -
PQsetdb always returns a valid PGconn pointer. -
The PQstatus (see below) command should be called - to ensure that a connection was properly made - before queries are sent via the connection. LIBPQ - programmers should be careful to maintain the -
PGconn abstraction. Use the accessor functions - below to get at the contents of PGconn. Avoid - directly referencing the fields of the PGconn - structure as they are subject to change in the - future.
-
PQdb -
Returns the database name of the connection. -
              char *PQdb(PGconn *conn)
-

-
PQhost -
Returns the host name of the connection. -
              char *PQhost(PGconn *conn)
-

-
PQoptions -
Returns the pgoptions used in the connection. -
              char *PQoptions(PGconn *conn)
-

-
PQport -
Returns the pgport of the connection. -
              char *PQport(PGconn *conn)
-

-
PQtty -
Returns the pgtty of the connection. -
              char *PQtty(PGconn *conn)
-

-
PQstatus -
Returns the status of the connection. -
The status can be CONNECTION_OK or CONNECTION_BAD. -
              ConnStatusType *PQstatus(PGconn *conn)
-

-
PQerrorMessage -
Returns the error message associated with the connection -
              char *PQerrorMessage(PGconn* conn);
-

- -
PQfinish -
Close the connection to the backend. Also frees - memory used by the PGconn structure. The PGconn - pointer should not be used after PQfinish has been - called. -
              void PQfinish(PGconn *conn)
-

-
PQreset -
Reset the communication port with the backend. - This function will close the IPC socket connection - to the backend and attempt to reestablish a new - connection to the same backend. -
              void PQreset(PGconn *conn)
-

-
PQtrace -
Enables tracing of messages passed between the - frontend and the backend. The messages are echoed - to the debug_port file stream. -
              void PQtrace(PGconn *conn,
-                           FILE* debug_port);
-

-
PQuntrace -
Disables tracing of messages passed between the - frontend and the backend. -
              void PQuntrace(PGconn *conn);
-

-
-

12.3. Query Execution Functions

-
-
PQexec -
Submit a query to POSTGRES. Returns a PGresult - pointer if the query was successful or a NULL otherwise. If a NULL is returned, PQerrorMessage can - be used to get more information about the error. -
              PGresult *PQexec(PGconn *conn,
-                               char *query);
-
-
The PGresult structure encapsulates the query - result returned by the backend. LIBPQ programmers - should be careful to maintain the PGresult - abstraction. Use the accessor functions described - below to retrieve the results of the query. Avoid - directly referencing the fields of the PGresult - structure as they are subject to change in the - future.
-
PQresultStatus -
Returns the result status of the query. PQresultStatus can return one of the following values: -
              PGRES_EMPTY_QUERY,
-              PGRES_COMMAND_OK,  /* the query was a command */
-              PGRES_TUPLES_OK,  /* the query successfully returned tuples */
-              PGRES_COPY_OUT,
-              PGRES_COPY_IN,
-              PGRES_BAD_RESPONSE, /* an unexpected response was received */
-              PGRES_NONFATAL_ERROR,
-              PGRES_FATAL_ERROR
-
-
If the result status is PGRES_TUPLES_OK, then the - following routines can be used to retrieve the - tuples returned by the query.
-
PQntuples returns the number of tuples (instances) - in the query result. - -
              int PQntuples(PGresult *res);
-

-
PQnfields -
Returns the number of fields - (attributes) in the query result. - -
              int PQnfields(PGresult *res);
-

-
PQfname -
Returns the field (attribute) name associated with the given field index. Field indices - start at 0. - -
              char *PQfname(PGresult *res,
-                           int field_index);
-

-
PQfnumber -
Returns the field (attribute) index - associated with the given field name. - -
              int PQfnumber(PGresult *res,
-                           char* field_name);
-

-
PQftype -
Returns the field type associated with the - given field index. The integer returned is an - internal coding of the type. Field indices start - at 0. - -
              Oid PQftype(PGresult *res,
-                          int field_num);
-

-
PQfsize -
Returns the size in bytes of the field - associated with the given field index. If the size - returned is -1, the field is a variable length - field. Field indices start at 0. - -
              int2 PQfsize(PGresult *res,
-                           int field_index);
-

-
PQgetvalue -
Returns the field (attribute) value. - For most queries, the value returned by PQgetvalue - is a null-terminated ASCII string representation - of the attribute value. If the query was a result - of a BINARY cursor, then the value returned by - PQgetvalue is the binary representation of the - type in the internal format of the backend server. - It is the programmer's responsibility to cast and - convert the data to the correct C type. The value - returned by PQgetvalue points to storage that is - part of the PGresult structure. One must explicitly - copy the value into other storage if it is to - be used past the lifetime of the PGresult structure itself. - -
              char* PQgetvalue(PGresult *res,
-                               int tup_num,
-                               int field_num);
-

-
PQgetlength -
Returns the length of a field - (attribute) in bytes. If the field is a struct - varlena, the length returned here does not include - the size field of the varlena, i.e., it is 4 bytes - less. -
              int PQgetlength(PGresult *res,
-                              int tup_num,
-                              int field_num);
-

-
PQcmdStatus - Returns the command status associated with the - last query command. -
-              char *PQcmdStatus(PGresult *res);
-

-
PQoidStatus - Returns a string with the object id of the tuple - inserted if the last query is an INSERT command. - Otherwise, returns an empty string. -
              char* PQoidStatus(PGresult *res);
-

-
PQprintTuples - Prints out all the tuples and, optionally, the - attribute names to the specified output stream. - The programs psql and monitor both use PQprintTuples for output. - -
              void PQprintTuples(
-                     PGresult* res,
-                     FILE* fout,      /* output stream */
-                     int printAttName,/* print attribute names or not*/
-                     int terseOutput, /* delimiter bars or not?*/
-                     int width        /* width of column, variable width if 0*/
-                     );
-

- -
PQclear - Frees the storage associated with the PGresult. - Every query result should be properly freed when - it is no longer used. Failure to do this will - result in memory leaks in the frontend application. -
              void PQclear(PQresult *res);
-

-
-

12.4. Fast Path

- POSTGRES provides a fast path interface to send function calls to the backend. This is a trapdoor into - system internals and can be a potential security hole. - Most users will not need this feature. - -
         PGresult* PQfn(PGconn* conn,
-                     int fnid,
-                     int *result_buf,
-                     int *result_len,
-                     int result_is_int,
-                     PQArgBlock *args,
-                     int nargs);
-

- - The fnid argument is the object identifier of the function to be executed. result_buf is the buffer in which - to load the return value. The caller must have allocated sufficient space to store the return value. The - result length will be returned in the storage pointed - to by result_len. If the result is to be an integer - value, than result_is_int should be set to 1; otherwise - it should be set to 0. args and nargs specify the - arguments to the function. -
         typedef struct {
-             int len;
-             int isint;
-             union {
-                 int *ptr;
-              int integer;
-             } u;
-         } PQArgBlock;
-
- PQfn always returns a valid PGresult*. The resultStatus should be checked before the result is used. The - caller is responsible for freeing the PGresult with - PQclear when it is not longer needed. -

12.5. Asynchronous Notification

- POSTGRES supports asynchronous notification via the - LISTEN and NOTIFY commands. A backend registers its - interest in a particular relation with the LISTEN command. All backends listening on a particular relation - will be notified asynchronously when a NOTIFY of that - relation name is executed by another backend. No - additional information is passed from the notifier to - the listener. Thus, typically, any actual data that - needs to be communicated is transferred through the - relation. - LIBPQ applications are notified whenever a connected - backend has received an asynchronous notification. - However, the communication from the backend to the - frontend is not asynchronous. Notification comes - piggy-backed on other query results. Thus, an application must submit queries, even empty ones, in order to - receive notice of backend notification. In effect, the - LIBPQ application must poll the backend to see if there - is any pending notification information. After the - execution of a query, a frontend may call PQNotifies to - see if any notification data is available from the - backend. -
-
PQNotifies -
returns the notification from a list of unhandled - notifications from the backend. Returns NULL if - there are no pending notifications from the backend. PQNotifies behaves like the popping of a - stack. Once a notification is returned from PQnotifies, it is considered handled and will be - removed from the list of notifications. -
              PGnotify* PQNotifies(PGconn *conn);
-

-
- The second sample program gives an example of the use - of asynchronous notification. -

12.6. Functions Associated with the COPY Command

- The copy command in POSTGRES has options to read from - or write to the network connection used by LIBPQ. - Therefore, functions are necessary to access this network connection directly so applications may take full - advantage of this capability. -
-
PQgetline -
Reads a newline-terminated line of characters - (transmitted by the backend server) into a buffer - string of size length. Like fgets(3), this routine copies up to length-1 characters into string. - It is like gets(3), however, in that it converts - the terminating newline into a null character. - PQgetline returns EOF at EOF, 0 if the entire line - has been read, and 1 if the buffer is full but the - terminating newline has not yet been read. - Notice that the application must check to see if a - new line consists of the single character ".", - which indicates that the backend server has finished sending the results of the copy command. - Therefore, if the application ever expects to - receive lines that are more than length-1 characters long, the application must be sure to check - the return value of PQgetline very carefully. - The code in - -
              ../src/bin/psql/psql.c
-
- contains routines that correctly handle the copy - protocol. -
              int PQgetline(PGconn *conn,
-                            char *string,
-                            int length)
-

-
PQputline -
Sends a null-terminated string to the backend - server. - The application must explicitly send the single - character "." to indicate to the backend that it - has finished sending its data. - -
              void PQputline(PGconn *conn,
-                             char *string);
-

-
PQendcopy -
Syncs with the backend. This function waits until - the backend has finished the copy. It should - either be issued when the last string has been - sent to the backend using PQputline or when the - last string has been received from the backend - using PGgetline. It must be issued or the backend - may get "out of sync" with the frontend. Upon - return from this function, the backend is ready to - receive the next query. - The return value is 0 on successful completion, - nonzero otherwise. -
              int PQendcopy(PGconn *conn);
-

- As an example: -
              PQexec(conn, "create table foo (a int4, b char16, d float8)");
-              PQexec(conn, "copy foo from stdin");
-              PQputline(conn, "3<TAB>hello world<TAB>4.5\n");
-              PQputline(conn,"4<TAB>goodbye world<TAB>7.11\n");
-              ...
-              PQputline(conn,".\n");
-              PQendcopy(conn);
-

-
-

12.7. LIBPQ Tracing Functions

-
-
PQtrace -
Enable tracing of the frontend/backend communication to a debugging file stream. -
              void PQtrace(PGconn *conn
-                           FILE *debug_port)
-

- -
PQuntrace -
Disable tracing started by PQtrace -
              void PQuntrace(PGconn *conn)
-

-
-

12.8. User Authentication Functions

- If the user has generated the appropriate authentication credentials (e.g., obtaining Kerberos tickets), - the frontend/backend authentication process is handled - by PQexec without any further intervention. The following routines may be called by LIBPQ programs to tailor the behavior of the authentication process. -
-
fe_getauthname -
Returns a pointer to static space containing whatever name the user has authenticated. Use of this - routine in place of calls to getenv(3) or getpwuid(3) by applications is highly recommended, as - it is entirely possible that the authenticated - user name is not the same as value of the USER - environment variable or the user's entry in - /etc/passwd. - -
              char *fe_getauthname(char* errorMessage)
-

-
fe_setauthsvc -
Specifies that LIBPQ should use authentication - service name rather than its compiled-in default. -
This value is typically taken from a command-line - switch. -
              void fe_setauthsvc(char *name,
-                                 char* errorMessage)
-
-
Any error messages from the authentication - attempts are returned in the errorMessage argument. -
- -

12.9. BUGS

- The query buffer is 8192 bytes long, and queries over - that length will be silently truncated. -

12.10. Sample Programs

-

-

12.10.1. Sample Program 1

-
-         /*
-          * testlibpq.c
-          *   Test the C version of LIBPQ, the POSTGRES frontend library.
-          *
-          *
-          */
-         #include <stdio.h>
-         #include "libpq-fe.h"
-

- void - exit_nicely(PGconn* conn) - { - PQfinish(conn); - exit(1); - } -

- main() - { - char *pghost, *pgport, *pgoptions, *pgtty; - char* dbName; - int nFields; - int i,j; -

- /* FILE *debug; */ -

- PGconn* conn; - PGresult* res; -

- /* begin, by setting the parameters for a backend connection - if the parameters are null, then the system will try to use - reasonable defaults by looking up environment variables - or, failing that, using hardwired constants */ - pghost = NULL; /* host name of the backend server */ - pgport = NULL; /* port of the backend server */ - pgoptions = NULL; /* special options to start up the backend server */ - pgtty = NULL; /* debugging tty for the backend server */ - dbName = "template1"; -

- /* make a connection to the database */ - conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); -

- /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.0, dbName); - fprintf(stderr,"%s",PQerrorMessage(conn)); - exit_nicely(conn); - } -

- /* debug = fopen("/tmp/trace.out","w"); */ - /* PQtrace(conn, debug); */ -

- /* start a transaction block */ - - res = PQexec(conn,"BEGIN"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed0); - PQclear(res); - exit_nicely(conn); - } - /* should PQclear PGresult whenever it is no longer needed to avoid - memory leaks */ - PQclear(res); -

- /* fetch instances from the pg_database, the system catalog of databases*/ - res = PQexec(conn,"DECLARE myportal CURSOR FOR select * from pg_database"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"DECLARE CURSOR command failed0); - PQclear(res); - exit_nicely(conn); - } - PQclear(res); -

- res = PQexec(conn,"FETCH ALL in myportal"); - if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"FETCH ALL command didn't return tuples properly0); - PQclear(res); - exit_nicely(conn); - } -

- /* first, print out the attribute names */ - nFields = PQnfields(res); - for (i=0; i < nFields; i++) { - printf("%-15s",PQfname(res,i)); - } - printf("0); -

- /* next, print out the instances */ - for (i=0; i < PQntuples(res); i++) { - for (j=0 ; j < nFields; j++) { - printf("%-15s", PQgetvalue(res,i,j)); - } - printf("0); - } -

- PQclear(res); -

- /* close the portal */ - res = PQexec(conn, "CLOSE myportal"); - PQclear(res); -

- /* end the transaction */ - res = PQexec(conn, "END"); - PQclear(res); -

- /* close the connection to the database and cleanup */ - PQfinish(conn); - - /* fclose(debug); */ - } -

-

-

12.10.2. Sample Program 2

-
-         /*
-          * testlibpq2.c
-          *   Test of the asynchronous notification interface
-          *
-            populate a database with the following:
-

- CREATE TABLE TBL1 (i int4); -

- CREATE TABLE TBL2 (i int4); -

- CREATE RULE r1 AS ON INSERT TO TBL1 DO [INSERT INTO TBL2 values (new.i); NOTIFY TBL2]; -

- * Then start up this program - * After the program has begun, do -

- INSERT INTO TBL1 values (10); -

- * - * - */ - #include <stdio.h> - #include "libpq-fe.h" -

- void exit_nicely(PGconn* conn) - { - PQfinish(conn); - exit(1); - } -

- main() - { - char *pghost, *pgport, *pgoptions, *pgtty; - char* dbName; - int nFields; - int i,j; -

- PGconn* conn; - PGresult* res; - PGnotify* notify; -

- /* begin, by setting the parameters for a backend connection - if the parameters are null, then the system will try to use - reasonable defaults by looking up environment variables - or, failing that, using hardwired constants */ - pghost = NULL; /* host name of the backend server */ - pgport = NULL; /* port of the backend server */ - pgoptions = NULL; /* special options to start up the backend server */ - pgtty = NULL; /* debugging tty for the backend server */ - dbName = getenv("USER"); /* change this to the name of your test database*/ -

- /* make a connection to the database */ - conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); - - /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.0, dbName); - fprintf(stderr,"%s",PQerrorMessage(conn)); - exit_nicely(conn); - } -

- res = PQexec(conn, "LISTEN TBL2"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"LISTEN command failed0); - PQclear(res); - exit_nicely(conn); - } - /* should PQclear PGresult whenever it is no longer needed to avoid - memory leaks */ - PQclear(res); -

- while (1) { - /* async notification only come back as a result of a query*/ - /* we can send empty queries */ - res = PQexec(conn, " "); - /* printf("res->status = %s0, pgresStatus[PQresultStatus(res)]); */ - /* check for asynchronous returns */ - notify = PQnotifies(conn); - if (notify) { - fprintf(stderr, - "ASYNC NOTIFY of '%s' from backend pid '%d' received0, - notify->relname, notify->be_pid); - free(notify); - break; - } - PQclear(res); - } -

- /* close the connection to the database and cleanup */ - PQfinish(conn); -

- } -

-

-

12.10.3. Sample Program 3

-
-         /*
-          * testlibpq3.c
-          *   Test the C version of LIBPQ, the POSTGRES frontend library.
-          *   tests the binary cursor interface
-          *
-          *
-          *
-          populate a database by doing the following:
-

- CREATE TABLE test1 (i int4, d float4, p polygon); -

- INSERT INTO test1 values (1, 3.567, '(3.0, 4.0, 1.0, 2.0)'::polygon); -

- INSERT INTO test1 values (2, 89.05, '(4.0, 3.0, 2.0, 1.0)'::polygon); -

- the expected output is: -

- tuple 0: got - i = (4 bytes) 1, - d = (4 bytes) 3.567000, - p = (4 bytes) 2 points boundbox = (hi=3.000000/4.000000, lo = 1.000000,2.000000) - tuple 1: got - i = (4 bytes) 2, - d = (4 bytes) 89.050003, - p = (4 bytes) 2 points boundbox = (hi=4.000000/3.000000, lo = 2.000000,1.000000) -

- * - */ - #include <stdio.h> - #include "libpq-fe.h" - #include "utils/geo-decls.h" /* for the POLYGON type */ -

- void exit_nicely(PGconn* conn) - { - PQfinish(conn); - exit(1); - } -

- main() - { - char *pghost, *pgport, *pgoptions, *pgtty; - char* dbName; - int nFields; - int i,j; - int i_fnum, d_fnum, p_fnum; -

- PGconn* conn; - PGresult* res; -

- /* begin, by setting the parameters for a backend connection - if the parameters are null, then the system will try to use - reasonable defaults by looking up environment variables - or, failing that, using hardwired constants */ - pghost = NULL; /* host name of the backend server */ - pgport = NULL; /* port of the backend server */ - pgoptions = NULL; /* special options to start up the backend server */ - pgtty = NULL; /* debugging tty for the backend server */ -

- dbName = getenv("USER"); /* change this to the name of your test database*/ -

- /* make a connection to the database */ - conn = PQsetdb(pghost, pgport, pgoptions, pgtty, dbName); -

- /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.0, dbName); - fprintf(stderr,"%s",PQerrorMessage(conn)); - exit_nicely(conn); - } -

- /* start a transaction block */ - res = PQexec(conn,"BEGIN"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"BEGIN command failed0); - PQclear(res); - exit_nicely(conn); - } - /* should PQclear PGresult whenever it is no longer needed to avoid - memory leaks */ - PQclear(res); -

- /* fetch instances from the pg_database, the system catalog of databases*/ - res = PQexec(conn,"DECLARE mycursor BINARY CURSOR FOR select * from test1"); - if (PQresultStatus(res) != PGRES_COMMAND_OK) { - fprintf(stderr,"DECLARE CURSOR command failed0); - PQclear(res); - exit_nicely(conn); - } - PQclear(res); -

- res = PQexec(conn,"FETCH ALL in mycursor"); - if (PQresultStatus(res) != PGRES_TUPLES_OK) { - fprintf(stderr,"FETCH ALL command didn't return tuples properly0); - PQclear(res); - exit_nicely(conn); - } -

- i_fnum = PQfnumber(res,"i"); - d_fnum = PQfnumber(res,"d"); - p_fnum = PQfnumber(res,"p"); -

- for (i=0;i<3;i++) { - printf("type[%d] = %d, size[%d] = %d0, - i, PQftype(res,i), - i, PQfsize(res,i)); - } - for (i=0; i < PQntuples(res); i++) { - int *ival; - float *dval; - int plen; - POLYGON* pval; - /* we hard-wire this to the 3 fields we know about */ - ival = (int*)PQgetvalue(res,i,i_fnum); - dval = (float*)PQgetvalue(res,i,d_fnum); - plen = PQgetlength(res,i,p_fnum); -

- /* plen doesn't include the length field so need to increment by VARHDSZ*/ - pval = (POLYGON*) malloc(plen + VARHDRSZ); - pval->size = plen; - memmove((char*)&pval->npts, PQgetvalue(res,i,p_fnum), plen); - printf("tuple %d: got0, i); - printf(" i = (%d bytes) %d,0, - PQgetlength(res,i,i_fnum), *ival); - printf(" d = (%d bytes) %f,0, - PQgetlength(res,i,d_fnum), *dval); - printf(" p = (%d bytes) %d points boundbox = (hi=%f/%f, lo = %f,%f)0, - PQgetlength(res,i,d_fnum), - pval->npts, - pval->boundbox.xh, - pval->boundbox.yh, - pval->boundbox.xl, - pval->boundbox.yl); - } -

- PQclear(res); -

- /* close the portal */ - res = PQexec(conn, "CLOSE mycursor"); - PQclear(res); -

- /* end the transaction */ - res = PQexec(conn, "END"); - PQclear(res); -

- /* close the connection to the database and cleanup */ - PQfinish(conn); -

- } -

-
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/lobj.html b/doc/manual/lobj.html deleted file mode 100644 index c8d0e518e8..0000000000 --- a/doc/manual/lobj.html +++ /dev/null @@ -1,429 +0,0 @@ - - - The POSTGRES95 User Manual - LARGE OBJECTS - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

13. LARGE OBJECTS

-
- In POSTGRES, data values are stored in tuples and - individual tuples cannot span data pages. Since the size of - a data page is 8192 bytes, the upper limit on the size - of a data value is relatively low. To support the storage - of larger atomic values, POSTGRES provides a large - object interface. This interface provides file - oriented access to user data that has been declared to - be a large type. - This section describes the implementation and the - programmatic and query language interfaces to POSTGRES - large object data. - -

13.1. Historical Note

- Originally, POSTGRES 4.2 supports three standard - implementations of large objects: as files external - to POSTGRES, as UNIX files managed by POSTGRES, and as data - stored within the POSTGRES database. It causes - considerable confusion among users. As a result, we only - support large objects as data stored within the POSTGRES - database in POSTGRES95. Even though is is slower to - access, it provides stricter data integrity and time - travel. For historical reasons, they are called - Inversion large objects. (We will use Inversion and large - objects interchangeably to mean the same thing in this - section.) - -

13.2. Inversion Large Objects

- The Inversion large object implementation breaks large - objects up into "chunks" and stores the chunks in - tuples in the database. A B-tree index guarantees fast - searches for the correct chunk number when doing random - access reads and writes. - -

13.3. Large Object Interfaces

- The facilities POSTGRES provides to access large - objects, both in the backend as part of user-defined - functions or the front end as part of an application - using the interface, are described below. (For users - familiar with POSTGRES 4.2, POSTGRES95 has a new set of - functions providing a more coherent interface. The - interface is the same for dynamically-loaded C - functions as well as for . - The POSTGRES large object interface is modeled after - the UNIX file system interface, with analogues of - open(2), read(2), write(2), lseek(2), etc. User - functions call these routines to retrieve only the data of - interest from a large object. For example, if a large - object type called mugshot existed that stored - photographs of faces, then a function called beard could - be declared on mugshot data. Beard could look at the - lower third of a photograph, and determine the color of - the beard that appeared there, if any. The entire - large object value need not be buffered, or even - examined, by the beard function. - Large objects may be accessed from dynamically-loaded C - functions or database client programs that link the - library. POSTGRES provides a set of routines that - support opening, reading, writing, closing, and seeking on - large objects. -

-

13.3.1. Creating a Large Object

- The routine -
         Oid lo_creat(PGconn *conn, int mode)
-
- creates a new large object. The mode is a bitmask - describing several different attributes of the new - object. The symbolic constants listed here are defined - in -
         /usr/local/postgres95/src/backend/libpq/libpq-fs.h
-
- The access type (read, write, or both) is controlled by - OR ing together the bits INV_READ and INV_WRITE. If - the large object should be archived -- that is, if - historical versions of it should be moved periodically to - a special archive relation -- then the INV_ARCHIVE bit - should be set. The low-order sixteen bits of mask are - the storage manager number on which the large object - should reside. For sites other than Berkeley, these - bits should always be zero. - The commands below create an (Inversion) large object: -
         inv_oid = lo_creat(INV_READ|INV_WRITE|INV_ARCHIVE);
-
- -

13.3.2. Importing a Large Object

-To import a UNIX file as - a large object, call -
         Oid
-         lo_import(PGconn *conn, text *filename)
-
- The filename argument specifies the UNIX pathname of - the file to be imported as a large object. -

-

13.3.3. Exporting a Large Object

-To export a large object - into UNIX file, call -
         int
-         lo_export(PGconn *conn, Oid lobjId, text *filename)
-
- The lobjId argument specifies the Oid of the large - object to export and the filename argument specifies - the UNIX pathname of the file. -

-

13.3.4. Opening an Existing Large Object

- To open an existing large object, call -
         int
-         lo_open(PGconn *conn, Oid lobjId, int mode, ...)
-
- The lobjId argument specifies the Oid of the large - object to open. The mode bits control whether the - object is opened for reading INV_READ), writing or - both. - A large object cannot be opened before it is created. - lo_open returns a large object descriptor for later use - in lo_read, lo_write, lo_lseek, lo_tell, and lo_close. -

-

13.3.5. Writing Data to a Large Object

- The routine -
         int
-         lo_write(PGconn *conn, int fd, char *buf, int len)
-
- writes len bytes from buf to large object fd. The fd - argument must have been returned by a previous lo_open. - The number of bytes actually written is returned. In - the event of an error, the return value is negative. -

-

13.3.6. Seeking on a Large Object

- To change the current read or write location on a large - object, call -
         int
-         lo_lseek(PGconn *conn, int fd, int offset, int whence)
-
- This routine moves the current location pointer for the - large object described by fd to the new location specified - by offset. The valid values for .i whence are - SEEK_SET SEEK_CUR and SEEK_END. -

-

13.3.7. Closing a Large Object Descriptor

- A large object may be closed by calling -
         int
-         lo_close(PGconn *conn, int fd)
-
- where fd is a large object descriptor returned by - lo_open. On success, lo_close returns zero. On error, - the return value is negative. - -

13.4. Built in registered functions

- There are two built-in registered functions, lo_import - and lo_export which are convenient for use in SQL - queries. - Here is an example of there use -
         CREATE TABLE image (
-                 name            text,
-                 raster          oid
-         );
-
-         INSERT INTO image (name, raster)
-            VALUES ('beautiful image', lo_import('/etc/motd'));
-
-         SELECT lo_export(image.raster, "/tmp/motd") from image
-            WHERE name = 'beautiful image';
-
-

13.5. Accessing Large Objects from LIBPQ

- Below is a sample program which shows how the large object - interface - in LIBPQ can be used. Parts of the program are - commented out but are left in the source for the readers - benefit. This program can be found in -
         ../src/test/examples
-
- Frontend applications which use the large object interface - in LIBPQ should include the header file - libpq/libpq-fs.h and link with the libpq library. - -

13.6. Sample Program

-
         /*--------------------------------------------------------------
-          *
-          * testlo.c--
-          *    test using large objects with libpq
-          *
-          * Copyright (c) 1994, Regents of the University of California
-          *
-          *
-          * IDENTIFICATION
-          *    /usr/local/devel/pglite/cvs/src/doc/manual.me,v 1.16 1995/09/01 23:55:00 jolly Exp
-          *
-          *--------------------------------------------------------------
-          */
-         #include <stdio.h>
-         #include "libpq-fe.h"
-         #include "libpq/libpq-fs.h"
-

- #define BUFSIZE 1024 -

- /* - * importFile * import file "in_filename" into database as large object "lobjOid" - * - */ - Oid importFile(PGconn *conn, char *filename) - { - Oid lobjId; - int lobj_fd; - char buf[BUFSIZE]; - int nbytes, tmp; - int fd; -

- /* - * open the file to be read in - */ - fd = open(filename, O_RDONLY, 0666); - if (fd < 0) { /* error */ - fprintf(stderr, "can't open unix file - } -

- /* - * create the large object - */ - lobjId = lo_creat(conn, INV_READ|INV_WRITE); - if (lobjId == 0) { - fprintf(stderr, "can't create large object"); - } -

- lobj_fd = lo_open(conn, lobjId, INV_WRITE); - /* - * read in from the Unix file and write to the inversion file - */ - while ((nbytes = read(fd, buf, BUFSIZE)) > 0) { - tmp = lo_write(conn, lobj_fd, buf, nbytes); - if (tmp < nbytes) { - fprintf(stderr, "error while reading - } - } -

- (void) close(fd); - (void) lo_close(conn, lobj_fd); -

- return lobjId; - } -

- void pickout(PGconn *conn, Oid lobjId, int start, int len) - { - int lobj_fd; - char* buf; - int nbytes; - int nread; -

- lobj_fd = lo_open(conn, lobjId, INV_READ); - if (lobj_fd < 0) { - fprintf(stderr,"can't open large object %d", - lobjId); - } -

- lo_lseek(conn, lobj_fd, start, SEEK_SET); - buf = malloc(len+1); -

- nread = 0; - while (len - nread > 0) { - nbytes = lo_read(conn, lobj_fd, buf, len - nread); - buf[nbytes] = ' '; - fprintf(stderr,">>> %s", buf); - nread += nbytes; - } - fprintf(stderr,"0); - lo_close(conn, lobj_fd); - } -

- void overwrite(PGconn *conn, Oid lobjId, int start, int len) - { - int lobj_fd; - char* buf; - int nbytes; - int nwritten; - int i; -

- lobj_fd = lo_open(conn, lobjId, INV_READ); - if (lobj_fd < 0) { - fprintf(stderr,"can't open large object %d", - lobjId); - } -

- lo_lseek(conn, lobj_fd, start, SEEK_SET); - buf = malloc(len+1); -

- for (i=0;i<len;i++) - buf[i] = 'X'; - buf[i] = ' '; -

- nwritten = 0; - while (len - nwritten > 0) { - nbytes = lo_write(conn, lobj_fd, buf + nwritten, len - nwritten); - nwritten += nbytes; - } - fprintf(stderr,"0); - lo_close(conn, lobj_fd); - } -

- - /* - * exportFile * export large object "lobjOid" to file "out_filename" - * - */ - void exportFile(PGconn *conn, Oid lobjId, char *filename) - { - int lobj_fd; - char buf[BUFSIZE]; - int nbytes, tmp; - int fd; -

- /* - * create an inversion "object" - */ - lobj_fd = lo_open(conn, lobjId, INV_READ); - if (lobj_fd < 0) { - fprintf(stderr,"can't open large object %d", - lobjId); - } -

- /* - * open the file to be written to - */ - fd = open(filename, O_CREAT|O_WRONLY, 0666); - if (fd < 0) { /* error */ - fprintf(stderr, "can't open unix file - filename); - } -

- /* - * read in from the Unix file and write to the inversion file - */ - while ((nbytes = lo_read(conn, lobj_fd, buf, BUFSIZE)) > 0) { - tmp = write(fd, buf, nbytes); - if (tmp < nbytes) { - fprintf(stderr,"error while writing - filename); - } - } -

- (void) lo_close(conn, lobj_fd); - (void) close(fd); -

- return; - } -

- void - exit_nicely(PGconn* conn) - { - PQfinish(conn); - exit(1); - } -

- int - main(int argc, char **argv) - { - char *in_filename, *out_filename; - char *database; - Oid lobjOid; - PGconn *conn; - PGresult *res; -

- if (argc != 4) { - fprintf(stderr, "Usage: %s database_name in_filename out_filename0, - argv[0]); - exit(1); - } -

- database = argv[1]; - in_filename = argv[2]; - out_filename = argv[3]; -

- /* - * set up the connection - */ - conn = PQsetdb(NULL, NULL, NULL, NULL, database); -

- /* check to see that the backend connection was successfully made */ - if (PQstatus(conn) == CONNECTION_BAD) { - fprintf(stderr,"Connection to database '%s' failed.0, database); - fprintf(stderr,"%s",PQerrorMessage(conn)); - exit_nicely(conn); - } -

- res = PQexec(conn, "begin"); - PQclear(res); - - printf("importing file - /* lobjOid = importFile(conn, in_filename); */ - lobjOid = lo_import(conn, in_filename); - /* - printf("as large object %d.0, lobjOid); -

- printf("picking out bytes 1000-2000 of the large object0); - pickout(conn, lobjOid, 1000, 1000); -

- printf("overwriting bytes 1000-2000 of the large object with X's0); - overwrite(conn, lobjOid, 1000, 1000); - */ -

- printf("exporting large object to file - /* exportFile(conn, lobjOid, out_filename); */ - lo_export(conn, lobjOid,out_filename); -

- res = PQexec(conn, "end"); - PQclear(res); - PQfinish(conn); - exit(0); - } -

-
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/pg95user.html b/doc/manual/pg95user.html deleted file mode 100644 index 7ce98828b6..0000000000 --- a/doc/manual/pg95user.html +++ /dev/null @@ -1,154 +0,0 @@ - - - The POSTGRES95 User Manual - - - -

-The - -POSTGRES95 User Manual

- -

- - Version 1.0 (September 5, 1995)

- - Andrew Yu - and - Jolly Chen
- (with the POSTGRES Group)
- Computer Science Div., Dept. of EECS
- University of California at Berkeley
-

- -

Table of Contents

-
-
1. INTRODUCTION -
-
1.1. A Short History of POSTGRES -
1.2. What is POSTGRES95? -
1.4. About This Release -
1.5. Outline of This Manual -
-
2. ARCHITECTURE CONCEPTS -
3. GETTING STARTED -
-
3.1. Setting Up Your Enviroment -
3.2. Starting The Postmaster -
3.3. Adding And Deleting Users -
3.4. Starting Applications -
3.5. Managing A Database -
-
3.5.1. Creating A Database -
3.5.2. Accessing A Database -
3.5.3. Destroying A Database -
-
-
4. QUERY LANGUAGE -
-
4.1. Concepts -
4.2. Creating a New Class -
4.3. Populating a Class with Instances -
4.4. Querying a Class -
4.5. Redirecting SELECT Queries -
-
5. ADVANCED POSTGRES SQL FEATURES -
-
5.1. Inheritance -
5.2. Time Travel -
5.3. Non-Atomic Values -
-
5.3.1. Arrays -
-
-
6. EXTENDING SQL: AN OVERVIEW -
-
6.1. How Extensibility Works -
6.2. The POSTGRES Type System -
6.3. About the POSTGRES System Catalogs -
-
7. EXTENDING SQL: FUNCTIONS -
-
7.1. Query Language (SQL) Functions -
-
7.1.1. SQL Functions on Base Types -
-
7.2. Programming Language Functions -
-
7.2.1. Programming Language Functions on Base Types -
7.2.2. Programming Language Functions on Composite Types -
7.2.3. Caveats -
-
-
8. EXTENDING SQL: TYPES -
-
8.1. User-Defined Types -
-
8.1.1. Functions Needed for a User-Defined Type -
8.1.2. Large Objects -
-
-
9. EXTENDING SQL: OPERATORS -
-
-
10. EXTENDING SQL: AGGREGATES -
-
-
11. INTERFACING EXTENSIONS TO INDICES -
-
-
12. LIBPQ -
-
12.1. Control and Initialization -
12.2. Database Connection Functions -
12.3. Query Execution Functions -
12.4. Fast Path -
12.5. Asynchronous Notification -
12.6. Functions Associated with the COPY Command -
12.7. LIBPQ Tracing Functions -
12.8. User Authentication Functions -
12.9. BUGS -
12.10. Sample Programs -
-
12.10.1. Sample Program 1 -
12.10.2. Sample Program 2 -
12.10.3. Sample Program 3 -
-
-
13. LARGE OBJECTS -
-
13.1. Historical Note -
13.2. Inversion Large Objects -
13.3. Large Object Interfaces -
-
13.3.1. Creating a Large Object -
13.3.2. Importing a Large Object -
13.3.3. Exporting a Large Object -
13.3.4. Opening an Existing Large Object -
13.3.5. Writing Data to a Large Object -
13.3.6. Seeking on a Large Object -
13.3.7. Closing a Large Object Descriptor -
-
13.4. Built in registered functions -
13.5. Accessing Large Objects from LIBPQ -
13.6. Sample Program -
-
14. THE POSTGRES RULE SYSTEM -
15. ADMINISTERING POSTGRES -
16. REFERENCES -

-

Appendix A: Linking Dynamically-Loaded Functions - -
-
-HyperNews Forum - About this Manual. -
-

POSTGRES95 is copyright © 1994-5 by the Regents of the -University of California.

-Converted to HTML by J. Douglas Dunlop -<dunlop@eol.ists.ca>
-The file - -pg95user.tgz contains the complete manual for download.

- - diff --git a/doc/manual/query.html b/doc/manual/query.html deleted file mode 100644 index a8f8db8147..0000000000 --- a/doc/manual/query.html +++ /dev/null @@ -1,259 +0,0 @@ - - - The POSTGRES95 User Manual - THE QUERY LANGUAGE - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

4. THE QUERY LANGUAGE

-
- The POSTGRES query language is a variant of SQL-3. It - has many extensions such as an extensible type system, - inheritance, functions and production rules. Those are - features carried over from the original POSTGRES query - language, POSTQUEL. This section provides an overview - of how to use POSTGRES SQL to perform simple operations. - This manual is only intended to give you an idea of our - flavor of SQL and is in no way a complete tutorial on - SQL. Numerous books have been written on SQL. For - instance, consult [MELT93] or - [DATE93]. You should also - be aware that some features are not part of the ANSI - standard. - In the examples that follow, we assume that you have - created the mydb database as described in the previous - subsection and have started psql. - Examples in this manual can also be found in - /usr/local/postgres95/src/tutorial. Refer to the - README file in that directory for how to use them. To - start the tutorial, do the following: -
         % cd /usr/local/postgres95/src/tutorial
-         % psql -s mydb
-         Welcome to the POSTGRES95 interactive sql monitor:
-
-            type \? for help on slash commands
-            type \q to quit
-            type \g or terminate with semicolon to execute query
-          You are currently connected to the database: jolly
-
-
-         mydb=> \i basics.sql
-
- The \i command read in queries from the specified - files. The -s option puts you in single step mode which - pauses before sending a query to the backend. Queries - in this section are in the file basics.sql. - -

4.1. Concepts

- The fundamental notion in POSTGRES is that of a class, - which is a named collection of object instances. Each - instance has the same collection of named attributes, - and each attribute is of a specific type. Furthermore, - each instance has a permanent object identifier (OID) - that is unique throughout the installation. Because - SQL syntax refers to tables, we will use the terms - table< and class interchangeably. Likewise, a row is an - instance and columns are attributes. - As previously discussed, classes are grouped into - databases, and a collection of databases managed by a - single postmaster process constitutes an installation - or site. - -

4.2. Creating a New Class

- You can create a new class by specifying the class - name, along with all attribute names and their types: -
         CREATE TABLE weather (
-                 city            varchar(80),
-                 temp_lo         int,           -- low temperature
-                 temp_hi         int,           -- high temperature
-                 prcp            real,          -- precipitation
-                 date            date
-           );
-
- Note that keywords are case-insensitive but identifiers - are case-sensitive. POSTGRES SQL supports the usual - SQL types int, float, real, smallint, char(N), - varchar(N), date, and time. As we will - see later, POSTGRES can be customized with an - arbitrary number of - user-defined data types. Consequently, type names are - not keywords. - So far, the POSTGRES create command looks exactly like - the command used to create a table in a traditional - relational system. However, we will presently see that - classes have properties that are extensions of the - relational model. - -

4.3. Populating a Class with Instances

- The insert statement is used to populate a class with - instances: -
         INSERT INTO weather
-            VALUES ('San Francisco', 46, 50, 0.25, '11/27/1994')
-
- You can also use the copy command to perform load large - amounts of data from flat (ASCII) files. - -

4.4. Querying a Class

- The weather class can be queried with normal relational - selection and projection queries. A SQL select - statement is used to do this. The statement is divided into - a target list (the part that lists the attributes to be - returned) and a qualification (the part that specifies - any restrictions). For example, to retrieve all the - rows of weather, type: -
         SELECT * FROM WEATHER;
-
- - and the output should be: -
-         +--------------+---------+---------+------+------------+
-         |city          | temp_lo | temp_hi | prcp | date       |
-         +--------------+---------+---------+------+------------+
-         |San Francisco | 46      | 50      | 0.25 | 11-27-1994 |
-         +--------------+---------+---------+------+------------+
-         |San Francisco | 43      | 57      | 0    | 11-29-1994 |
-         +--------------+---------+---------+------+------------+
-         |Hayward       | 37      | 54      |      | 11-29-1994 |
-         +--------------+---------+---------+------+------------+
-
- You may specify any aribitrary expressions in the target list. For example, you can do: -
         * SELECT city, (temp_hi+temp_lo)/2 AS temp_avg, date FROM weather;
-
- Arbitrary Boolean operators ( and, or and not) are - allowed in the qualification of any query. For example, -
         SELECT *
-           FROM weather
-           WHERE city = 'San Francisco'
-              and prcp > 0.0;
-
-         +--------------+---------+---------+------+------------+
-         |city          | temp_lo | temp_hi | prcp | date       |
-         +--------------+---------+---------+------+------------+
-         |San Francisco | 46      | 50      | 0.25 | 11-27-1994 |
-         +--------------+---------+---------+------+------------+
-
- - As a final note, you can specify that the results of a - select can be returned in a sorted order or with duplicate instances removed. -
         SELECT DISTINCT city
-           FROM weather
-           ORDER BY city;
-
- -

4.5. Redirecting SELECT Queries

- Any select query can be redirected to a new class -
         SELECT * INTO temp from weather;
-
- This creates an implicit create command, creating a new - class temp with the attribute names and types specified - in the target list of the SELECT INTO command. We can - then, of course, perform any operations on the resulting - class that we can perform on other classes. - -

4.6. Joins Between Classes

- Thus far, our queries have only accessed one class at a - time. Queries can access multiple classes at once, or - access the same class in such a way that multiple - instances of the class are being processed at the same - time. A query that accesses multiple instances of the - same or different classes at one time is called a join - query. - As an example, say we wish to find all the records that - are in the temperature range of other records. In - effect, we need to compare the temp_lo and temp_hi - attributes of each EMP instance to the temp_lo and - temp_hi attributes of all other EMP instances.2 We can - do this with the following query: -
         SELECT W1.city, W1.temp_lo, W1.temp_hi,
-                  W2.city, W2.temp_lo, W2.temp_hi
-         FROM weather W1, weather W2
-         WHERE W1.temp_lo < W2.temp_lo
-              and W1.temp_hi > W2.temp_hi;
-
-         +--------------+---------+---------+---------------+---------+---------+
-         |city          | temp_lo | temp_hi | city          | temp_lo | temp_hi |
-         +--------------+---------+---------+---------------+---------+---------+
-         |San Francisco | 43      | 57      | San Francisco | 46      | 50      |
-         +--------------+---------+---------+---------------+---------+---------+
-         |San Francisco | 37      | 54      | San Francisco | 46      | 50      |
-         +--------------+---------+---------+---------------+---------+---------+
-
- In this case, both W1 and W2 are surrogates for an - instance of the class weather, and both range over all - instances of the class. (In the terminology of most - database systems, W1 and W2 are known as "range variables.") - A query can contain an arbitrary number of - class names and surrogates.3 - -

4.7. Updates

- You can update existing instances using the update command. - Suppose you discover the temperature readings are - all off by 2 degrees as of Nov 28, you may update the - data as follow: -
         * UPDATE weather
-           SET temp_hi = temp_hi - 2,  temp_lo = temp_lo - 2
-           WHERE date > '11/28/1994;
-
- -

4.8. Deletions

- Deletions are performed using the delete command: -
         * DELETE FROM weather WHERE city = 'Hayward';
-
- All weather recording belongs to Hayward is removed. - One should be wary of queries of the form -
         DELETE FROM classname;
-
- Without a qualification, the delete command will simply - delete all instances of the given class, leaving it - empty. The system will not request confirmation before - doing this. - -

4.9. Using Aggregate Functions

- Like most other query languages, POSTGRES supports - aggregate functions. However, the current - implementation of POSTGRES aggregate functions is very limited. - Specifically, while there are aggregates to compute - such functions as the count, sum, average, maximum and - minimum over a set of instances, aggregates can only - appear in the target list of a query and not in the - qualification ( where clause) As an example, -
         SELECT max(temp_lo)
-         FROM weather;
-
- Aggregates may also have GROUP BY clauses: -
-         SELECT city, max(temp_lo)
-         FROM weather
-         GROUP BY city;
-
-
- 2. This is only a conceptual model. The actual join may - be performed in a more efficient manner, but this is invisible to the user.
- - 3. The semantics of such a join are - that the qualification - is a truth expression defined for the Cartesian product of - the classes indicated in the query. For those instances in - the Cartesian product for which the qualification is true, - POSTGRES computes and returns the values specified in the - target list. POSTGRES SQL does not assign any meaning to - duplicate values in such expressions. This means that POSTGRES - sometimes recomputes the same target list several times - this frequently happens when Boolean expressions are connected - with an or. To remove such duplicates, you must use - the select distinct statement. - -
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/refs.html b/doc/manual/refs.html deleted file mode 100644 index 064e9918aa..0000000000 --- a/doc/manual/refs.html +++ /dev/null @@ -1,55 +0,0 @@ - - - The POSTGRES95 User Manual - REFERENCES - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

16. REFERENCES

-
-
-
[DATE93]
Date, C. J. and Darwen, Hugh, A Guide to The - SQL Standard, 3rd Edition, Reading, MA, June - 1993. -
[MELT93]
Melton, J. Understanding the New SQL, 1994. -
[ONG90]
Ong, L. and Goh, J., ``A Unified Framework - for Version Modeling Using Production Rules - in a Database System," Electronics Research - Laboratory, University of California, ERL - Technical Memorandum M90/33, Berkeley, CA, - April 1990. -
[ROWE87]
Rowe, L. and Stonebraker, M., ``The POSTGRES - Data Model,'' Proc. 1987 VLDB Conference, - Brighton, England, Sept. 1987. -
[STON86]
Stonebraker, M. and Rowe, L., ``The Design - of POSTGRES,'' Proc. 1986 ACM-SIGMOD Conference on Management of Data, Washington, DC, - May 1986. -
[STON87a]
Stonebraker, M., Hanson, E. and Hong, C.-H., - ``The Design of the POSTGRES Rules System,'' - Proc. 1987 IEEE Conference on Data Engineering, Los Angeles, CA, Feb. 1987. -
[STON87b]
Stonebraker, M., ``The POSTGRES Storage System,'' Proc. 1987 VLDB Conference, Brighton, - England, Sept. 1987. -
[STON89]
Stonebraker, M., Hearst, M., and Potamianos, - S., ``A Commentary on the POSTGRES Rules - System,'' SIGMOD Record 18(3), Sept. 1989. -
[STON90a]
Stonebraker, M., Rowe, L. A., and Hirohama, - M., ``The Implementation of POSTGRES,'' IEEE - Transactions on Knowledge and Data Engineering 2(1), March 1990. -
[STON90b]
Stonebraker, M. et al., ``On Rules, Procedures, Caching and Views in Database Systems,'' Proc. 1990 ACM-SIGMOD Conference on - Management of Data, Atlantic City, N.J., - June 1990. -
-
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/rules.html b/doc/manual/rules.html deleted file mode 100644 index 927cfd6f1c..0000000000 --- a/doc/manual/rules.html +++ /dev/null @@ -1,43 +0,0 @@ - - - The POSTGRES95 User Manual - THE POSTGRES RULE SYSTEM - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

14. THE POSTGRES RULE SYSTEM -


- Production rule systems are conceptually simple, but - there are many subtle points involved in actually using - them. Consequently, we will not attempt to explain the - actual syntax and operation of the POSTGRES rule system - here. Instead, you should read [STON90b] to understand - some of these points and the theoretical foundations of - the POSTGRES rule system before trying to use rules. - The discussion in this section is intended to provide - an overview of the POSTGRES rule system and point the - user at helpful references and examples. - The "query rewrite" rule system modifies queries to - take rules into consideration, and then passes the modified - query to the query optimizer for execution. It - is very powerful, and can be used for many things such - as query language procedures, views, and versions. The - power of this rule system is discussed in - [ONG90] as - well as [STON90b]. -
- -[ TOC ] -[ Previous ] -[ Next ] - - - - - diff --git a/doc/manual/start.html b/doc/manual/start.html deleted file mode 100644 index db9960661b..0000000000 --- a/doc/manual/start.html +++ /dev/null @@ -1,231 +0,0 @@ - - - The POSTGRES95 User Manual - GETTING STARTED - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

3. GETTING STARTED WITH POSTGRES

-
- This section discusses how to start POSTGRES and set up - your own environment so that you can use frontend - applications. We assume POSTGRES has already been - successfully installed. (Refer to the installation notes - for how to install POSTGRES.) -

- Some of the steps listed in this section will apply to - all POSTGRES users, and some will apply primarily to - the site database administrator. This site administrator - is the person who installed the software, created - the database directories and started the postmaster - process. This person does not have to be the UNIX - superuser, "root," or the computer system administrator. - In this section, items for end users are labelled - "User" and items intended for the site administrator - are labelled "Admin." - Throughout this manual, any examples that begin with - the character ``%'' are commands that should be typed - at the UNIX shell prompt. Examples that begin with the - character ``*'' are commands in the POSTGRES query - language, POSTGRES SQL. - -

3.1. Admin/User: Setting Up Your Environment

- Figure 2.  POSTGRES file layout. - Figure 2. shows how the POSTGRES distribution is laid - out when installed in the default way. For simplicity, - we will assume that POSTGRES has been installed in the - directory /usr/local/postgres95. Therefore, wherever - you see the directory /usr/local/postgres95 you should - substitute the name of the directory where POSTGRES is - actually installed. - All POSTGRES commands are installed in the directory - /usr/local/postgres95/bin. Therefore, you should add - this directory to your shell command path. If you use - a variant of the Berkeley C shell, such as csh or tcsh, - you would add -
         % set path = ( /usr/local/postgres95/bin $path )
-
- in the .login file in your home directory. If you use - a variant of the Bourne shell, such as sh, ksh, or - bash, then you would add -
-         % PATH=/usr/local/postgres95/bin:$PATH
-         % export PATH
-
- to the .profile file in your home directory. - From now on, we will assume that you have added the - POSTGRES bin directory to your path. In addition, we - will make frequent reference to "setting a shell - variable" or "setting an environment variable" throughout - this document. If you did not fully understand the - last paragraph on modifying your search path, you - should consult the UNIX manual pages that describe your - shell before going any further. - -

3.2. Admin: Starting the Postmaster

- It should be clear from the preceding discussion that - nothing can happen to a database unless the postmaster - process is running. As the site administrator, there - are a number of things you should remember before - starting the postmaster. These are discussed in the - section of this manual titled, "Administering POSTGRES." - However, if POSTGRES has been installed by following - the installation instructions exactly as written, the - following simple command is all you should - need to start the postmaster: -
         % postmaster &
-
- The postmaster occasionally prints out messages which - are often helpful during troubleshooting. If you wish - to view debugging messages from the postmaster, you can - start it with the -d option and redirect the output to - the log file: -
         % postmaster -d >& pm.log &
-
- If you do not wish to see these messages, you can type -
         % postmaster -S
-
- and the postmaster will be "S"ilent. Notice that there - is no ampersand ("&") at the end of the last example. - -

3.3. Admin: Adding and Deleting Users

- The createuser command enables specific users to access - POSTGRES. The destroyuser command removes users and - prevents them from accessing POSTGRES. Note that these - commands only affect users with respect to POSTGRES; - they have no effect administration of users that the - operating system manages. - -

3.4. User: Starting Applications

- Assuming that your site administrator has properly - started the postmaster process and authorized you to - use the database, you (as a user) may begin to start up - applications. As previously mentioned, you should add - /usr/local/postgres95/bin to your shell search path. - In most cases, this is all you should have to do in - terms of preparation.1 - If you get the following error message from a POSTGRES - command (such as psql or createdb): -
         connectDB() failed: Is the postmaster running at 'localhost' on port '4322'?
-
- it is usually because (1) the postmaster is not running, or (2) you are attempting to connect to the wrong - server host. - If you get the following error message: -
         FATAL 1:Feb 17 23:19:55:process userid (2360) !=
-           database owner (268)
-
- it means that the site administrator started the postmaster as the wrong user. Tell him to restart it as - the POSTGRES superuser. - -

3.5. User: Managing a Database

- Now that POSTGRES is up and running we can create some - databases to experiment with. Here, we describe the - basic commands for managing a database. - -

3.5.1. Creating a Database

- Let's say you want to create a database named mydb. - You can do this with the following command: -
         % createdb mydb
-
- - POSTGRES allows you to create any number of databases - at a given site and you automatically become the - database administrator of the database you just created. Database names must have an alphabetic first - character and are limited to 16 characters in length. - Not every user has authorization to become a database - administrator. If POSTGRES refuses to create databases - for you, then the site administrator needs to grant you - permission to create databases. Consult your site - administrator if this occurs. - -

3.5.2. Accessing a Database

- Once you have constructed a database, you can access it - by: -
    -
  • running the POSTGRES terminal monitor programs ( - monitor or psql) which allows you to interactively - enter, edit, and execute SQL commands. -
  • 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 - in section ??. -
- You might want to start up psql, to try out the examples in this manual. It can be activated for the mydb - database by typing the command: -
         % psql mydb
-
- You will be greeted with the following message: -
         Welcome to the POSTGRES95 interactive sql monitor:
-
-            type \? for help on slash commands
-            type \q to quit
-            type \g or terminate with semicolon to execute query
-          You are currently connected to the database: mydb
-
-         mydb=>
-
This prompt indicates that the terminal monitor 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 - with the backslash character, "\". For example, you - can get help on the syntax of various POSTGRES SQL commands by typing: -
         mydb=> \h
-
- Once you have finished entering your queries into the - workspace, you can pass the contents of the workspace - to the POSTGRES server by typing: -
         mydb=> \g
-
- This tells the server to process the query. If you - 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 - entering them interactively, type: -
         mydb=> \i fileName
-
- To get out of psql and return to UNIX, type -
         mydb=> \q
-
- and psql will quit and return you to your command - shell. (For more escape codes, type \h at the monitor - prompt.) - White space (i.e., spaces, tabs and newlines) may be - used freely in SQL queries. Comments are denoted by - --. Everything after the dashes up to the end of the - line is ignored. - -

3.5.3. Destroying a Database

- If you are the database administrator for the database - mydb, you can destroy it using the following UNIX command: -
         % destroydb mydb
-
- This action physically removes all of the UNIX files - associated with the database and cannot be undone, so - this should only be done with a great deal of fore-thought. - -

-


- -1. If your site administrator has not set things up in the -default way, you may have some more work to do. For example, if the database server machine is a remote machine, you -will need to set the PGHOST environment variable to the name -of the database server machine. The environment variable -PGPORT may also have to be set. The bottom line is this: if -you try to start an application program and it complains -that it cannot connect to the postmaster, you should immediately consult your site administrator to make sure that your -environment is properly set up. - -
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/xaggr.html b/doc/manual/xaggr.html deleted file mode 100644 index 2870722164..0000000000 --- a/doc/manual/xaggr.html +++ /dev/null @@ -1,109 +0,0 @@ - - - The POSTGRES95 User Manual - EXTENDING SQL: AGGREGATES - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

10. EXTENDING SQL: AGGREGATES

-
- Aggregates in POSTGRES are expressed in terms of state - transition functions. That is, an aggregate can be - defined in terms of state that is modified whenever an - instance is processed. Some state functions look at a - particular value in the instance when computing the new - state (sfunc1 in the create aggregate syntax) while - others only keep track of their own internal state - (sfunc2). - If we define an aggregate that uses only sfunc1, we - define an aggregate that computes a running function of - the attribute values from each instance. "Sum" is an - example of this kind of aggregate. "Sum" starts at - zero and always adds the current instance's value to - its running total. We will use the int4pl that is - built into POSTGRES to perform this addition. - -
         CREATE AGGREGATE complex_sum (
-              sfunc1 = complex_add,
-              basetype = complex,
-              stype1 = complex,
-              initcond1 = '(0,0)'
-           );
-
-
-         SELECT complex_sum(a) FROM test_complex;
-
-
-         +------------+
-         |complex_sum |
-         +------------+
-         |(34,53.9)   |
-         +------------+
-
- - If we define only sfunc2, we are specifying an aggregate - that computes a running function that is independent of - the attribute values from each instance. - "Count" is the most common example of this kind of - aggregate. "Count" starts at zero and adds one to its - running total for each instance, ignoring the instance - value. Here, we use the built-in int4inc routine to do - the work for us. This routine increments (adds one to) - its argument. - -
         CREATE AGGREGATE my_count (sfunc2 = int4inc, -- add one
-                                      basetype = int4, stype2 = int4,
-                                      initcond2 = '0')
-
-         SELECT my_count(*) as emp_count from EMP;
-
-
-         +----------+
-         |emp_count |
-         +----------+
-         |5         |
-         +----------+
-
- - "Average" is an example of an aggregate that requires - both a function to compute the running sum and a function - to compute the running count. When all of the - instances have been processed, the final answer for the - aggregate is the running sum divided by the running - count. We use the int4pl and int4inc routines we used - before as well as the POSTGRES integer division - routine, int4div, to compute the division of the sum by - the count. - -
         CREATE AGGREGATE my_average (sfunc1 = int4pl, --  sum
-                                        basetype = int4,
-                                        stype1 = int4,
-                                        sfunc2 = int4inc, -- count
-                                        stype2 = int4,
-                                        finalfunc = int4div, -- division
-                                        initcond1 = '0',
-                                        initcond2 = '0')
-
-         SELECT my_average(salary) as emp_average FROM EMP;
-
-
-         +------------+
-         |emp_average |
-         +------------+
-         |1640        |
-         +------------+
-
-
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/xfunc.html b/doc/manual/xfunc.html deleted file mode 100644 index 557e9ec0bf..0000000000 --- a/doc/manual/xfunc.html +++ /dev/null @@ -1,474 +0,0 @@ - - - The POSTGRES95 User Manual - EXTENDING SQL: FUNCTIONS - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

7. EXTENDING SQL: FUNCTIONS

-
- As it turns out, part of defining a new type is the - definition of functions that describe its behavior. - Consequently, while it is possible to define a new - function without defining a new type, the reverse is - not true. We therefore describe how to add new functions - to POSTGRES before describing how to add new - types. - POSTGRES SQL provides two types of functions: query - language functions (functions written in SQL and - programming language functions (functions written in a - compiled programming language such as C.) Either kind - of function can take a base type, a composite type or - some combination as arguments (parameters). In addition, - both kinds of functions can return a base type or - a composite type. It's easier to define SQL functions, - so we'll start with those. - Examples in this section can also be found in funcs.sql - and C-code/funcs.c. -

-

7.1. Query Language (SQL) Functions

- -

7.1.1. SQL Functions on Base Types

- The simplest possible SQL function has no arguments and - simply returns a base type, such as int4: - -
         CREATE FUNCTION one() RETURNS int4
-              AS 'SELECT 1 as RESULT' LANGUAGE 'sql';
-
-
-         SELECT one() AS answer;
-
-         +-------+
-         |answer |
-         +-------+
-         |1      |
-         +-------+
-
- Notice that we defined a target list for the function - (with the name RESULT), but the target list of the - query that invoked the function overrode the function's - target list. Hence, the result is labelled answer - instead of one. -

- It's almost as easy to define SQL functions that take - base types as arguments. In the example below, notice - how we refer to the arguments within the function as $1 - and $2. - -

         CREATE FUNCTION add_em(int4, int4) RETURNS int4
-              AS 'SELECT $1 + $2;' LANGUAGE 'sql';
-
-
-         SELECT add_em(1, 2) AS answer;
-
-
-         +-------+
-         |answer |
-         +-------+
-         |3      |
-         +-------+
-
- -

7.1.2. SQL Functions on Composite Types

- When specifying functions with arguments of composite - types (such as EMP), we must not only specify which - argument we want (as we did above with $1 and $2) but - also the attributes of that argument. For example, - take the function double_salary that computes what your - salary would be if it were doubled. - -
         CREATE FUNCTION double_salary(EMP) RETURNS int4
-              AS 'SELECT $1.salary * 2 AS salary;' LANGUAGE 'sql';
-
-         SELECT name, double_salary(EMP) AS dream
-           FROM EMP
-           WHERE EMP.dept = 'toy';
-
-
-         +-----+-------+
-         |name | dream |
-         +-----+-------+
-         |Sam  | 2400  |
-         +-----+-------+
-
- Notice the use of the syntax $1.salary. - Before launching into the subject of functions that - return composite types, we must first introduce the - function notation for projecting attributes. The simple way - to explain this is that we can usually use the - notation attribute(class) and class.attribute interchangably. - -
         --
-         -- this is the same as:
-         --   SELECT EMP.name AS youngster FROM EMP WHERE EMP.age < 30
-         --
-         SELECT name(EMP) AS youngster
-         FROM EMP
-         WHERE age(EMP) < 30;
-
-
-         +----------+
-         |youngster |
-         +----------+
-         |Sam       |
-         +----------+
-
- As we shall see, however, this is not always the case. - This function notation is important when we want to use - a function that returns a single instance. We do this - by assembling the entire instance within the function, - attribute by attribute. This is an example of a function - that returns a single EMP instance: - -
         CREATE FUNCTION new_emp() RETURNS EMP
-            AS 'SELECT \'None\'::text AS name,
-                       1000 AS salary,
-                       25 AS age,
-                       \'none\'::char16 AS dept;'
-            LANGUAGE 'sql';
-
- - In this case we have specified each of the attributes - with a constant value, but any computation or expression - could have been substituted for these constants. - Defining a function like this can be tricky. Some of - the more important caveats are as follows: - - -
    -
  • The target list order must be exactly the same as - that in which the attributes appear in the CREATE - TABLE statement (or when you execute a .* query). -
  • You must be careful to typecast the expressions - (using ::) very carefully or you will see the following error: - -
                WARN::function declared to return type EMP does not retrieve (EMP.*)
    -
    -
  • When calling a function that returns an instance, we - cannot retrieve the entire instance. We must either - project an attribute out of the instance or pass the - entire instance into another function. -
                SELECT name(new_emp()) AS nobody;
    -
    -
    -            +-------+
    -            |nobody |
    -            +-------+
    -            |None   |
    -            +-------+
    -
    -
  • The reason why, in general, we must use the function - syntax for projecting attributes of function return - values is that the parser just doesn't understand - the other (dot) syntax for projection when combined - with function calls. - -
                SELECT new_emp().name AS nobody;
    -            WARN:parser: syntax error at or near "."
    -
    -
- - Any collection of commands in the SQL query language - can be packaged together and defined as a function. - The commands can include updates (i.e., insert, update - and delete) as well as select queries. However, the - final command must be a select that returns whatever is - specified as the function's returntype. - -
-         CREATE FUNCTION clean_EMP () RETURNS int4
-            AS 'DELETE FROM EMP WHERE EMP.salary <= 0;
-                SELECT 1 AS ignore_this'
-            LANGUAGE 'sql';
-
-         SELECT clean_EMP();
-
-
-         +--+
-         |x |
-         +--+
-         |1 |
-         +--+
-
-

- -

7.2. Programming Language Functions

-

7.2.1. Programming Language Functions on Base Types

- Internally, POSTGRES regards a base type as a "blob of - memory." The user-defined functions that you define - over a type in turn define the way that POSTGRES can - operate on it. That is, POSTGRES will only store and - retrieve the data from disk and use your user-defined - functions to input, process, and output the data. - Base types can have one of three internal formats: -
    -
  • pass by value, fixed-length -
  • pass by reference, fixed-length -
  • pass by reference, variable-length -
- By-value types can only be 1, 2 or 4 bytes in length - (even if your computer supports by-value types of other - sizes). POSTGRES itself only passes integer types by - value. You should be careful to define your types such - that they will be the same size (in bytes) on all - architectures. For example, the long type is dangerous - because it is 4 bytes on some machines and 8 bytes on - others, whereas int type is 4 bytes on most UNIX - machines (though not on most personal computers). A - reasonable implementation of the int4 type on UNIX - machines might be: - -
         /* 4-byte integer, passed by value */
-         typedef int int4;
-
- - On the other hand, fixed-length types of any size may - be passed by-reference. For example, here is a sample - implementation of the POSTGRES char16 type: - -
         /* 16-byte structure, passed by reference */
-         typedef struct {
-             char data[16];
-         } char16;
-
- - Only pointers to such types can be used when passing - them in and out of POSTGRES functions. - Finally, all variable-length types must also be passed - by reference. All variable-length types must begin - with a length field of exactly 4 bytes, and all data to - be stored within that type must be located in the memory - immediately following that length field. The - length field is the total length of the structure - (i.e., it includes the size of the length field - itself). We can define the text type as follows: - -
         typedef struct {
-             int4 length;
-             char data[1];
-         } text;
-
- - Obviously, the data field is not long enough to hold - all possible strings -- it's impossible to declare such - a structure in C. When manipulating variable-length - types, we must be careful to allocate the correct - amount of memory and initialize the length field. For - example, if we wanted to store 40 bytes in a text - structure, we might use a code fragment like this: - -
         #include "postgres.h"
-         #include "utils/palloc.h"
-
-         ...
-
-         char buffer[40]; /* our source data */
-
-         ...
-
-         text *destination = (text *) palloc(VARHDRSZ + 40);
-         destination->length = VARHDRSZ + 40;
-         memmove(destination->data, buffer, 40);
-
-         ...
-
-
- Now that we've gone over all of the possible structures - for base types, we can show some examples of real functions. - Suppose funcs.c look like: - -
         #include <string.h>
-         #include "postgres.h"  /* for char16, etc. */
-         #include "utils/palloc.h" /* for palloc */
-
-         int
-         add_one(int arg)
-         {
-             return(arg + 1);
-         }
-
-         char16 *
-         concat16(char16 *arg1, char16 *arg2)
-         {
-             char16 *new_c16 = (char16 *) palloc(sizeof(char16));
-
-             memset((void *) new_c16, 0, sizeof(char16));
-             (void) strncpy(new_c16, arg1, 16);
-             return (char16 *)(strncat(new_c16, arg2, 16));
-         }
-

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

- memset(new_t, 0, VARSIZE(t)); -

- VARSIZE(new_t) = VARSIZE(t); - /* - * VARDATA is a pointer to the data region of the struct. - */ - memcpy((void *) VARDATA(new_t), /* destination */ - (void *) VARDATA(t), /* source */ - VARSIZE(t)-VARHDRSZ); /* how many bytes */ -

- return(new_t); - } -

- On OSF/1 we would type: - -
         CREATE FUNCTION add_one(int4) RETURNS int4
-              AS '/usr/local/postgres95/tutorial/obj/funcs.so' LANGUAGE 'c';
-
-         CREATE FUNCTION concat16(char16, char16) RETURNS char16
-              AS '/usr/local/postgres95/tutorial/obj/funcs.so' LANGUAGE 'c';
-
-         CREATE FUNCTION copytext(text) RETURNS text
-              AS '/usr/local/postgres95/tutorial/obj/funcs.so' LANGUAGE 'c';
-
- - On other systems, we might have to make the filename - end in .sl (to indicate that it's a shared library). -

-

7.2.2. Programming Language Functions on Composite Types

- Composite types do not have a fixed layout like C - structures. Instances of a composite type may contain - null fields. In addition, composite types that are - part of an inheritance hierarchy may have different - fields than other members of the same inheritance hierarchy. - Therefore, POSTGRES provides a procedural - interface for accessing fields of composite types from - C. - As POSTGRES processes a set of instances, each instance - will be passed into your function as an opaque structure of type TUPLE. - Suppose we want to write a function to answer the query - -
         * SELECT name, c_overpaid(EMP, 1500) AS overpaid
-           FROM EMP
-           WHERE name = 'Bill' or name = 'Sam';
-
- In the query above, we can define c_overpaid as: - -
         #include "postgres.h"  /* for char16, etc. */
-         #include "libpq-fe.h" /* for TUPLE */
-

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

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

- if (isnull) - return (false); - return(salary > limit); - } -

- - GetAttributeByName is the POSTGRES system function that - returns attributes out of the current instance. It has - three arguments: the argument of type TUPLE passed into - the function, the name of the desired attribute, and a - return parameter that describes whether the attribute - is null. GetAttributeByName will align data properly - so you can cast its return value to the desired type. - For example, if you have an attribute name which is of - the type char16, the GetAttributeByName call would look - like: - -
         char *str;
-         ...
-         str = (char *) GetAttributeByName(t, "name", &isnull)
-
- - The following query lets POSTGRES know about the - c_overpaid function: - -
         * CREATE FUNCTION c_overpaid(EMP, int4) RETURNS bool
-              AS '/usr/local/postgres95/tutorial/obj/funcs.so' LANGUAGE 'c';
-
- While there are ways to construct new instances or modify - existing instances from within a C function, these - are far too complex to discuss in this manual. -

-

7.2.3. Caveats

- We now turn to the more difficult task of writing - programming language functions. Be warned: this section - of the manual will not make you a programmer. You must - have a good understanding of C (including the use of - pointers and the malloc memory manager) before trying - to write C functions for use with POSTGRES. - While it may be possible to load functions written in - languages other than C into POSTGRES, this is often - difficult (when it is possible at all) because other - languages, such as FORTRAN and Pascal often do not follow - the same "calling convention" as C. That is, other - languages do not pass argument and return values - between functions in the same way. For this reason, we - will assume that your programming language functions - are written in C. - The basic rules for building C functions are as follows: -
    -
  1. Most of the header (include) files for POSTGRES - should already be installed in - /usr/local/postgres95/include (see Figure 2). - You should always include - -
                    -I/usr/local/postgres95/include
    -
    - on your cc command lines. Sometimes, you may - find that you require header files that are in - the server source itself (i.e., you need a file - we neglected to install in include). In those - cases you may need to add one or more of -
    -                -I/usr/local/postgres95/src/backend
    -                -I/usr/local/postgres95/src/backend/include
    -                -I/usr/local/postgres95/src/backend/port/<PORTNAME>
    -                -I/usr/local/postgres95/src/backend/obj
    -
    - - (where <PORTNAME> is the name of the port, e.g., - alpha or sparc). -
  2. When allocating memory, use the POSTGRES - routines palloc and pfree instead of the - corresponding C library routines malloc and free. - The memory allocated by palloc will be freed - automatically at the end of each transaction, - preventing memory leaks. -
  3. Always zero the bytes of your structures using - memset or bzero. Several routines (such as the - hash access method, hash join and the sort algorithm) - compute functions of the raw bits contained in - your structure. Even if you initialize all fields - of your structure, there may be - several bytes of alignment padding (holes in the - structure) that may contain garbage values. -
  4. Most of the internal POSTGRES types are declared - in postgres.h, so it's usually a good idea to - include that file as well. -
  5. Compiling and loading your object code so that - it can be dynamically loaded into POSTGRES - always requires special flags. See Appendix A - for a detailed explanation of how to do it for - your particular operating system. -
-
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/xindex.html b/doc/manual/xindex.html deleted file mode 100644 index aca6b3712e..0000000000 --- a/doc/manual/xindex.html +++ /dev/null @@ -1,430 +0,0 @@ - - - The POSTGRES95 User Manual - THE QUERY LANGUAGE - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

11. INTERFACING EXTENSIONS TO INDICES

-
- The procedures described thus far let you define a new - type, new functions and new operators. However, we - cannot yet define a secondary index (such as a B-tree, - R-tree or hash access method) over a new type or its - operators.

- - Look back at Figure 3. - The right half shows the catalogs - that we must modify in order to tell POSTGRES how - to use a user-defined type and/or user-defined operators - with an index (i.e., pg_am, pg_amop, pg_amproc and - pg_opclass). Unfortunately, there is no simple command - to do this. We will demonstrate how to modify these - catalogs through a running example: a new operator - class for the B-tree access method that sorts integers - in ascending absolute value order.

- - The pg_am class contains one instance for every user - defined access method. Support for the heap access - method is built into POSTGRES, but every other access - method is described here. The schema is -

-

- - - - - - - - - - - - - - - - - - - -
amname name of the access method
amowner object id of the owner's instance in pg_user
amkind not used at present, but set to 'o' as a place holder
amstrategies number of strategies for this access method (see below)
amsupport number of support routines for this access method (see below)
amgettuple
- aminsert
- ...
procedure identifiers for interface routines to the access - method. For example, regproc ids for opening, closing, and - getting instances from the access method appear here.
-
- -

- - The object ID of the instance in pg_am is used as a - foreign key in lots of other classes. You don't need - to add a new instance to this class; all you're interested in - is the object ID of the access method instance - you want to extend: - -

         SELECT oid FROM pg_am WHERE amname = 'btree'
-
-         +----+
-         |oid |
-         +----+
-         |403 |
-         +----+
-
- - The amstrategies attribute exists to standardize - comparisons across data types. For example, B-trees - impose a strict ordering on keys, lesser to greater. - Since POSTGRES allows the user to define operators, - POSTGRES cannot look at the name of an operator (eg, > - or <) and tell what kind of comparison it is. In fact, - some access methods don't impose any ordering at all. - For example, R-trees express a rectangle-containment - relationship, whereas a hashed data structure expresses - only bitwise similarity based on the value of a hash - function. POSTGRES needs some consistent way of taking - a qualification in your query, looking at the operator - and then deciding if a usable index exists. This - implies that POSTGRES needs to know, for example, that - the <= and > operators partition a B-tree. POSTGRES - uses strategies to express these relationships between - operators and the way they can be used to scan indices.

- - Defining a new set of strategies is beyond the scope of - this discussion, but we'll explain how B-tree strategies - work because you'll need to know that to add a new - operator class. In the pg_am class, the amstrategies - attribute is the number of strategies defined for this - access method. For B-trees, this number is 5. These - strategies correspond to -

- -

- - - - - - - - - - - - - - - - -
less than 1
less than or equal 2
equal 3
greater than or equal 4
greater than 5
-
-

- - The idea is that you'll need to add procedures corresponding - to the comparisons above to the pg_amop relation - (see below). The access method code can use these - strategy numbers, regardless of data type, to figure - out how to partition the B-tree, compute selectivity, - and so on. Don't worry about the details of adding - procedures yet; just understand that there must be a - set of these procedures for int2, int4, oid, and every - other data type on which a B-tree can operate. -

- Sometimes, strategies aren't enough information for the - system to figure out how to use an index. Some access - methods require other support routines in order to - work. For example, the B-tree access method must be - able to compare two keys and determine whether one is - greater than, equal to, or less than the other. - Similarly, the R-tree access method must be able to compute - intersections, unions, and sizes of rectangles. These - operations do not correspond to user qualifications in - SQL queries; they are administrative routines used by - the access methods, internally.

- - In order to manage diverse support routines - consistently across all POSTGRES access methods, pg_am - includes an attribute called amsupport. This attribute - records the number of support routines used by an - access method. For B-trees, this number is one -- the - routine to take two keys and return -1, 0, or +1, - depending on whether the first key is less than, equal - to, or greater than the second.[8]

- - The amstrategies entry in pg_am is just the number of - strategies defined for the access method in question. - The procedures for less than, less equal, and so on - don't appear in pg_am. Similarly, amsupport is just - the number of support routines required by the access - method. The actual routines are listed elsewhere.

- - The next class of interest is pg_opclass. This class - exists only to associate a name with an oid. In - pg_amop, every B-tree operator class has a set of - procedures, one through five, above. Some existing - opclasses are int2_ops, int4_ops, and oid_ops. You - need to add an instance with your opclass name (for - example, complex_abs_ops) to pg_opclass. The oid of - this instance is a foreign key in other classes. - -

         INSERT INTO pg_opclass (opcname) VALUES ('complex_abs_ops');
-
-         SELECT oid, opcname
-           FROM pg_opclass
-           WHERE opcname = 'complex_abs_ops';
-
-         +------+--------------+
-         |oid   | opcname      |
-         +------+--------------+
-         |17314 | int4_abs_ops |
-         +------+--------------+
-
- - Note that the oid for your pg_opclass instance will be - different! You should substitute your value for 17314 - wherever it appears in this discussion.

- - So now we have an access method and an operator class. - We still need a set of operators; the procedure for - defining operators was discussed earlier in this manual. - For the complex_abs_ops operator class on Btrees, - the operators we require are: - -

         absolute value less-than
-         absolute value less-than-or-equal
-         absolute value equal
-         absolute value greater-than-or-equal
-         absolute value greater-than
-
- - Suppose the code that implements the functions defined - is stored in the file - -
-         /usr/local/postgres95/src/tutorial/complex.c
-
- - Part of the code look like this: (note that we will - only show the equality operator for the rest of the - examples. The other four operators are very similar. - Refer to complex.c or complex.sql for the details.) - -
         #define Mag(c) ((c)->x*(c)->x + (c)->y*(c)->y)
-
-         bool
-         complex_abs_eq(Complex *a, Complex *b)
-         {
-             double amag = Mag(a), bmag = Mag(b);
-             return (amag==bmag);
-         }
-
- - There are a couple of important things that are happening below.

- - First, note that operators for less-than, less-than-or - equal, equal, greater-than-or-equal, and greater-than - for int4 are being defined. All of these operators are - already defined for int4 under the names <, <=, =, >=, - and >. The new operators behave differently, of - course. In order to guarantee that POSTGRES uses these - new operators rather than the old ones, they need to be - named differently from the old ones. This is a key - point: you can overload operators in POSTGRES, but only - if the operator isn't already defined for the argument - types. That is, if you have < defined for (int4, - int4), you can't define it again. POSTGRES does not - check this when you define your operator, so be careful. - To avoid this problem, odd names will be used for - the operators. If you get this wrong, the access methods - are likely to crash when you try to do scans.

- - The other important point is that all the operator - functions return Boolean values. The access methods - rely on this fact. (On the other hand, the support - function returns whatever the particular access method - expects -- in this case, a signed integer.) - The final routine in the file is the "support routine" - mentioned when we discussed the amsupport attribute of - the pg_am class. We will use this later on. For now, - ignore it. - -

         CREATE FUNCTION complex_abs_eq(complex, complex)
-              RETURNS bool
-              AS '/usr/local/postgres95/tutorial/obj/complex.so'
-              LANGUAGE 'c';
-
- - Now define the operators that use them. As noted, the - operator names must be unique among all operators that - take two int4 operands. In order to see if the - operator names listed below are taken, we can do a query on - pg_operator: - -
         /*
-          * this query uses the regular expression operator (~)
-          * to find three-character operator names that end in
-          * the character &
-          */
-         SELECT *
-         FROM pg_operator
-         WHERE oprname ~ '^..&$'::text;
-
- - to see if your name is taken for the types you want. - The important things here are the procedure (which are - the C functions defined above) and the restriction and - join selectivity functions. You should just use the - ones used below--note that there are different such - functions for the less-than, equal, and greater-than - cases. These must be supplied, or the access method - will crash when it tries to use the operator. You - should copy the names for restrict and join, but use - the procedure names you defined in the last step. - -
         CREATE OPERATOR = (
-            leftarg = complex, rightarg = complex, procedure = complex_abs_eq,
-            restrict = eqsel, join = eqjoinsel
-         )
-
- - Notice that five operators corresponding to less, less - equal, equal, greater, and greater equal are defined.

- - We're just about finished. the last thing we need to do - is to update the pg_amop relation. To do this, we need - the following attributes: -

- -

- - - - - - - - - - - - -
amopid the oid of the pg_am instance for B-tree - (== 403, see above)
amopclaid the oid of the - pg_opclass instance for int4_abs_ops (== - whatever you got instead of 17314, see above)
amopopr the oids of the operators for the opclass (which we'll - get in just a minute)
amopselect, amopnpages cost functions.
-
-

- The cost functions are used by the query optimizer to - decide whether or not to use a given index in a scan. - Fortunately, these already exist. The two functions - we'll use are btreesel, which estimates the selectivity - of the B-tree, and btreenpage, which estimates the - number of pages a search will touch in the tree.

- - So we need the oids of the operators we just defined. - We'll look up the names of all the operators that take - two int4s, and pick ours out: - -

         SELECT o.oid AS opoid, o.oprname
-         INTO TABLE complex_ops_tmp
-         FROM pg_operator o, pg_type t
-         WHERE o.oprleft = t.oid and o.oprright = t.oid
-              and t.typname = 'complex';
-
-     which returns:
-
-         +------+---------+
-         |oid   | oprname |
-         +------+---------+
-         |17321 | <       |
-         +------+---------+
-         |17322 | <=      |
-         +------+---------+
-         |17323 |  =      |
-         +------+---------+
-         |17324 | >=      |
-         +------+---------+
-         |17325 | >       |
-         +------+---------+
-
- - (Again, some of your oid numbers will almost certainly - be different.) The operators we are interested in are - those with oids 17321 through 17325. The values you - get will probably be different, and you should - substitute them for the values below. We can look at the - operator names and pick out the ones we just added.

- - Now we're ready to update pg_amop with our new operator - class. The most important thing in this entire - discussion is that the operators are ordered, from less equal - through greater equal, in pg_amop. We add the - instances we need: - -

          INSERT INTO pg_amop (amopid, amopclaid, amopopr, amopstrategy,
-                              amopselect, amopnpages)
-              SELECT am.oid, opcl.oid, c.opoid, 3,
-                 'btreesel'::regproc, 'btreenpage'::regproc
-              FROM pg_am am, pg_opclass opcl, complex_ops_tmp c
-              WHERE amname = 'btree' and opcname = 'complex_abs_ops'
-                 and c.oprname = '=';
-
- - Note the order: "less than" is 1, "less than or equal" - is 2, "equal" is 3, "greater than or equal" is 4, and - "greater than" is 5.

- - The last step (finally!) is registration of the - "support routine" previously described in our discussion of - pg_am. The oid of this support routine is stored in - the pg_amproc class, keyed by the access method oid and - the operator class oid. First, we need to register the - function in POSTGRES (recall that we put the C code - that implements this routine in the bottom of the file - in which we implemented the operator routines): - -

         CREATE FUNCTION int4_abs_cmp(int4, int4)
-               RETURNS int4
-               AS '/usr/local/postgres95/tutorial/obj/complex.so'
-               LANGUAGE 'c';
-
-         SELECT oid, proname FROM pg_proc WHERE prname = 'int4_abs_cmp';
-
-         +------+--------------+
-         |oid   | proname      |
-         +------+--------------+
-         |17328 | int4_abs_cmp |
-         +------+--------------+
-
- (Again, your oid number will probably be different and - you should substitute the value you see for the value - below.) Recalling that the B-tree instance's oid is - 403 and that of int4_abs_ops is 17314, we can add the - new instance as follows: - -
         INSERT INTO pg_amproc (amid, amopclaid, amproc, amprocnum)
-              VALUES ('403'::oid,        -- btree oid
-                      '17314'::oid,      --  pg_opclass tuple
-                      '17328'::oid,      -- new pg_proc oid
-                      '1'::int2);
-
-

-


-[8] Strictly speaking, this routine can return a negative -number (< 0), 0, or a non-zero positive number (> 0). -
- -[ TOC ] -[ Previous ] -[ Next ] - - - diff --git a/doc/manual/xoper.html b/doc/manual/xoper.html deleted file mode 100644 index 10e5e203c1..0000000000 --- a/doc/manual/xoper.html +++ /dev/null @@ -1,70 +0,0 @@ - - - The POSTGRES95 User Manual - THE QUERY LANGUAGE - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

9. EXTENDING SQL: OPERATORS

-
- POSTGRES supports left unary, right unary and binary - operators. Operators can be overloaded, or re-used - with different numbers and types of arguments. If - there is an ambiguous situation and the system cannot - determine the correct operator to use, it will return - an error and you may have to typecast the left and/or - right operands to help it understand which operator you - meant to use. - To create an operator for adding two complex numbers - can be done as follows. First we need to create a - function to add the new types. Then, we can create the - operator with the function. - -
-         CREATE FUNCTION complex_add(complex, complex)
-            RETURNS complex
-            AS '$PWD/obj/complex.so'
-            LANGUAGE 'c';
-
-
-         CREATE OPERATOR + (
-            leftarg = complex,
-            rightarg = complex,
-            procedure = complex_add,
-            commutator = +
-         );
-
- - We've shown how to create a binary operator here. To - create unary operators, just omit one of leftarg (for - left unary) or rightarg (for right unary). - If we give the system enough type information, it can - automatically figure out which operators to use. - -
-         SELECT (a + b) AS c FROM test_complex;
-
-
-         +----------------+
-         |c               |
-         +----------------+
-         |(5.2,6.05)      |
-         +----------------+
-         |(133.42,144.95) |
-         +----------------+
-
-
- -[ TOC ] -[ Previous ] -[ Next ] - - - - diff --git a/doc/manual/xtypes.html b/doc/manual/xtypes.html deleted file mode 100644 index 55e4569842..0000000000 --- a/doc/manual/xtypes.html +++ /dev/null @@ -1,148 +0,0 @@ - - - The POSTGRES95 User Manual - EXTENDING SQL: TYPES - - - - - -[ TOC ] -[ Previous ] -[ Next ] - -
-

8. EXTENDING SQL: TYPES

-
- As previously mentioned, there are two kinds of types - in POSTGRES: base types (defined in a programming language) - and composite types (instances). - Examples in this section up to interfacing indices can - be found in complex.sql and complex.c. Composite examples - are in funcs.sql. -

-

8.1. User-Defined Types

-

-

8.1.1. Functions Needed for a User-Defined Type

- A user-defined type must always have input and output - functions. These functions determine how the type - appears in strings (for input by the user and output to - the user) and how the type is organized in memory. The - input function takes a null-delimited character string - as its input and returns the internal (in memory) - representation of the type. The output function takes the - internal representation of the type and returns a null - delimited character string. - Suppose we want to define a complex type which represents - complex numbers. Naturally, we choose to represent a - complex in memory as the following C structure: - -
         typedef struct Complex {
-             double      x;
-             double      y;
-         } Complex;
-
- and a string of the form (x,y) as the external string - representation. - These functions are usually not hard to write, especially - the output function. However, there are a number of points - to remember. - -
    -
  1. When defining your external (string) representation, - remember that you must eventually write a - complete and robust parser for that representation - as your input function! - -
                    Complex *
    -                complex_in(char *str)
    -                {
    -                    double x, y;
    -                    Complex *result;
    -
    -                    if (sscanf(str, " ( %lf , %lf )", &x, &y) != 2) {
    -                        elog(WARN, "complex_in: error in parsing
    -                        return NULL;
    -                    }
    -                    result = (Complex *)palloc(sizeof(Complex));
    -                    result->x = x;
    -                    result->y = y;
    -                    return (result);
    -                }
    -
    - - The output function can simply be: - -
                    char *
    -                complex_out(Complex *complex)
    -                {
    -                    char *result;
    -

    - if (complex == NULL) - return(NULL); -

    - result = (char *) palloc(60); - sprintf(result, "(%g,%g)", complex->x, complex->y); - return(result); - } -

    -
  2. You should try to make the input and output - functions inverses of each other. If you do - not, you will have severe problems when you need - to dump your data into a file and then read it - back in (say, into someone else's database on - another computer). This is a particularly common - problem when floating-point numbers are - involved. -
- To define the complex type, we need to create the two - user-defined functions complex_in and complex_out - before creating the type: - -
         CREATE FUNCTION complex_in(opaque)
-            RETURNS complex
-            AS '/usr/local/postgres95/tutorial/obj/complex.so'
-            LANGUAGE 'c';
-
-         CREATE FUNCTION complex_out(opaque)
-            RETURNS opaque
-            AS '/usr/local/postgres95/tutorial/obj/complex.so'
-            LANGUAGE 'c';
-
-         CREATE TYPE complex (
-            internallength = 16,
-            input = complex_in,
-            output = complex_out
-         );
-
- - As discussed earlier, POSTGRES fully supports arrays of - base types. Additionally, POSTGRES supports arrays of - user-defined types as well. When you define a type, - POSTGRES automatically provides support for arrays of - that type. For historical reasons, the array type has - the same name as the user-defined type with the - underscore character _ prepended. - Composite types do not need any function defined on - them, since the system already understands what they - look like inside. -

-

8.1.2. Large Objects

- The types discussed to this point are all "small" - objects -- that is, they are smaller than 8KB[7] in size. - If you require a larger type for something like a document - retrieval system or for storing bitmaps, you will - need to use the POSTGRES large object interface. -

-


-[7] 8 * 1024 == 8192 bytes. In fact, the type must be considerably smaller than 8192 bytes, since the POSTGRES tuple -and page overhead must also fit into this 8KB limitation. -The actual value that fits depends on the machine architecture. -
- -[ TOC ] -[ Previous ] -[ Next ] - - - -