Uppercase keywords where appropriate.
This commit is contained in:
parent
b57705673d
commit
705869dd17
|
@ -51,8 +51,8 @@ to check that. Other examples also worked, except polygons: I got an
|
|||
error doing
|
||||
|
||||
<ProgramListing>
|
||||
test=> create index pix on polytmp
|
||||
test-> using gist (p:box gist_poly_ops) with (islossy);
|
||||
test=> CREATE INDEX pix ON polytmp
|
||||
test-> USING GIST (p:box gist_poly_ops) WITH (ISLOSSY);
|
||||
ERROR: cannot open pix
|
||||
|
||||
(PostgreSQL 6.3 Sun Feb 1 14:57:30 EST 1998)
|
||||
|
@ -92,7 +92,7 @@ A few notes on the sources:
|
|||
|
||||
<ProgramListing>
|
||||
-- -- there's a memory leak in rtree poly_ops!!
|
||||
-- -- create index pix2 on polytmp using rtree (p poly_ops);
|
||||
-- -- CREATE INDEX pix2 ON polytmp USING RTREE (p poly_ops);
|
||||
</ProgramListing>
|
||||
|
||||
Roger that!! I thought it could be related to a number of
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/jdbc.sgml,v 1.25 2001/09/13 15:55:22 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/jdbc.sgml,v 1.26 2001/10/12 23:32:33 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="jdbc">
|
||||
|
@ -2311,21 +2311,21 @@ public void unlink(int oid) throws SQLException
|
|||
One of the consequences of this, is that you can have one table
|
||||
refer to a row in another table. For example:
|
||||
<screen>
|
||||
test=> create table users (username name,fullname text);
|
||||
test=> CREATE TABLE users (username NAME,fullname TEXT);
|
||||
CREATE
|
||||
test=> create table server (servername name,adminuser users);
|
||||
test=> CREATE TABLE server (servername NAME,adminuser users);
|
||||
CREATE
|
||||
test=> insert into users values ('peter','Peter Mount');
|
||||
test=> INSERT INTO users VALUES ('peter','Peter Mount');
|
||||
INSERT 2610132 1
|
||||
test=> insert into server values ('maidast',2610132::users);
|
||||
test=> INSERT INTO server VALUES ('maidast',2610132::users);
|
||||
INSERT 2610133 1
|
||||
test=> select * from users;
|
||||
test=> SELECT * FROM users;
|
||||
username|fullname
|
||||
--------+--------------
|
||||
peter |Peter Mount
|
||||
(1 row)
|
||||
|
||||
test=> select * from server;
|
||||
test=> SELECT * FROM server;
|
||||
servername|adminuser
|
||||
----------+---------
|
||||
maidast | 2610132
|
||||
|
|
|
@ -917,7 +917,7 @@ given chunk of code for each tuple in the result.
|
|||
This would work if table <classname>table</> has fields <structfield>control</> and <structfield>name</>
|
||||
(and, perhaps, other fields):
|
||||
<ProgramListing>
|
||||
pg_select $pgconn "SELECT * from table" array {
|
||||
pg_select $pgconn "SELECT * FROM table" array {
|
||||
puts [format "%5d %s" array(control) array(name)]
|
||||
}
|
||||
</ProgramListing>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.32 2001/09/13 15:55:23 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.33 2001/10/12 23:32:34 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="libpqplusplus">
|
||||
|
@ -794,8 +794,8 @@ $Header: /cvsroot/pgsql/doc/src/sgml/Attic/libpq++.sgml,v 1.32 2001/09/13 15:55:
|
|||
|
||||
<programlisting>
|
||||
PgDatabase data;
|
||||
data.Exec("create table foo (a int4, b char(16), d double precision)");
|
||||
data.Exec("copy foo from stdin");
|
||||
data.Exec("CREATE TABLE foo (a int4, b char(16), d double precision)");
|
||||
data.Exec("COPY foo FROM STDIN");
|
||||
data.PutLine("3\tHello World\t4.5\n");
|
||||
data.PutLine("4\tGoodbye World\t7.11\n");
|
||||
&...
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.72 2001/09/13 15:55:23 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/libpq.sgml,v 1.73 2001/10/12 23:32:34 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="libpq">
|
||||
|
@ -302,11 +302,11 @@ PostgresPollingStatusType PQconnectPoll(PGconn *conn)
|
|||
proceed with the connection sequence. Loop thus: Consider a connection
|
||||
<quote>inactive</quote> by default. If <function>PQconnectPoll</function> last returned <symbol>PGRES_POLLING_ACTIVE</>,
|
||||
consider it <quote>active</quote> instead. If <function>PQconnectPoll(conn)</function> last returned
|
||||
<symbol>PGRES_POLLING_READING</symbol>, perform a select for reading on <function>PQsocket(conn)</function>. If
|
||||
it last returned <symbol>PGRES_POLLING_WRITING</symbol>, perform a select for writing on
|
||||
<symbol>PGRES_POLLING_READING</symbol>, perform a SELECT for reading on <function>PQsocket(conn)</function>. If
|
||||
it last returned <symbol>PGRES_POLLING_WRITING</symbol>, perform a SELECT for writing on
|
||||
<function>PQsocket(conn)</function>. If you have yet to call <function>PQconnectPoll</function>, i.e. after the call
|
||||
to <function>PQconnectStart</function>, behave as if it last returned <symbol>PGRES_POLLING_WRITING</symbol>. If
|
||||
the select shows that the socket is ready, consider it <quote>active</quote>. If it has
|
||||
the SELECT shows that the socket is ready, consider it <quote>active</quote>. If it has
|
||||
been decided that this connection is <quote>active</quote>, call <function>PQconnectPoll(conn)</function>
|
||||
again. If this call returns <symbol>PGRES_POLLING_FAILED</symbol>, the connection procedure
|
||||
has failed. If this call returns <symbol>PGRES_POLLING_OK</symbol>, the connection has been
|
||||
|
@ -1763,8 +1763,8 @@ int PQendcopy(PGconn *conn);
|
|||
As an example:
|
||||
|
||||
<programlisting>
|
||||
PQexec(conn, "create table foo (a int4, b char(16), d double precision)");
|
||||
PQexec(conn, "copy foo from stdin");
|
||||
PQexec(conn, "CREATE TABLE foo (a int4, b char(16), d double precision)");
|
||||
PQexec(conn, "COPY foo FROM STDIN");
|
||||
PQputline(conn, "3\thello world\t4.5\n");
|
||||
PQputline(conn,"4\tgoodbye world\t7.11\n");
|
||||
...
|
||||
|
@ -2270,7 +2270,7 @@ main()
|
|||
* fetch rows from the pg_database, the system catalog of
|
||||
* databases
|
||||
*/
|
||||
res = PQexec(conn, "DECLARE mycursor CURSOR FOR select * from pg_database");
|
||||
res = PQexec(conn, "DECLARE mycursor CURSOR FOR SELECT * FROM pg_database");
|
||||
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "DECLARE CURSOR command failed\n");
|
||||
|
@ -2541,7 +2541,7 @@ main()
|
|||
* fetch rows from the pg_database, the system catalog of
|
||||
* databases
|
||||
*/
|
||||
res = PQexec(conn, "DECLARE mycursor BINARY CURSOR FOR select * from test1");
|
||||
res = PQexec(conn, "DECLARE mycursor BINARY CURSOR FOR SELECT * FROM test1");
|
||||
if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
|
||||
{
|
||||
fprintf(stderr, "DECLARE CURSOR command failed\n");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/maintenance.sgml,v 1.4 2001/09/23 04:06:24 momjian Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/maintenance.sgml,v 1.5 2001/10/12 23:32:34 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="maintenance">
|
||||
|
@ -304,7 +304,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/maintenance.sgml,v 1.4 2001/09/23 04:06:24
|
|||
examine this information is to execute the query
|
||||
<informalexample>
|
||||
<programlisting>
|
||||
select datname, age(datfrozenxid) from pg_database;
|
||||
SELECT datname, age(datfrozenxid) FROM pg_database;
|
||||
</programlisting>
|
||||
</informalexample>
|
||||
The <literal>age</> column measures the number of transactions from the
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/perform.sgml,v 1.11 2001/10/09 18:46:00 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/perform.sgml,v 1.12 2001/10/12 23:32:34 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="performance-tips">
|
||||
|
@ -95,7 +95,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/perform.sgml,v 1.11 2001/10/09 18:46:00 pet
|
|||
vacuum analyze, and 7.2 development sources):
|
||||
|
||||
<programlisting>
|
||||
regression=# explain select * from tenk1;
|
||||
regression=# EXPLAIN SELECT * FROM tenk1;
|
||||
NOTICE: QUERY PLAN:
|
||||
|
||||
Seq Scan on tenk1 (cost=0.00..333.00 rows=10000 width=148)
|
||||
|
@ -106,7 +106,7 @@ Seq Scan on tenk1 (cost=0.00..333.00 rows=10000 width=148)
|
|||
This is about as straightforward as it gets. If you do
|
||||
|
||||
<programlisting>
|
||||
select * from pg_class where relname = 'tenk1';
|
||||
SELECT * FROM pg_class WHERE relname = 'tenk1';
|
||||
</programlisting>
|
||||
|
||||
you will find out that <classname>tenk1</classname> has 233 disk
|
||||
|
@ -119,7 +119,7 @@ select * from pg_class where relname = 'tenk1';
|
|||
Now let's modify the query to add a qualification clause:
|
||||
|
||||
<programlisting>
|
||||
regression=# explain select * from tenk1 where unique1 < 1000;
|
||||
regression=# EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 1000;
|
||||
NOTICE: QUERY PLAN:
|
||||
|
||||
Seq Scan on tenk1 (cost=0.00..358.00 rows=1007 width=148)
|
||||
|
@ -144,7 +144,7 @@ Seq Scan on tenk1 (cost=0.00..358.00 rows=1007 width=148)
|
|||
Modify the query to restrict the qualification even more:
|
||||
|
||||
<programlisting>
|
||||
regression=# explain select * from tenk1 where unique1 < 50;
|
||||
regression=# EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 50;
|
||||
NOTICE: QUERY PLAN:
|
||||
|
||||
Index Scan using tenk1_unique1 on tenk1 (cost=0.00..181.09 rows=49 width=148)
|
||||
|
@ -162,7 +162,7 @@ Index Scan using tenk1_unique1 on tenk1 (cost=0.00..181.09 rows=49 width=148)
|
|||
Add another condition to the qualification:
|
||||
|
||||
<programlisting>
|
||||
regression=# explain select * from tenk1 where unique1 < 50 and
|
||||
regression=# EXPLAIN SELECT * FROM tenk1 WHERE unique1 < 50 AND
|
||||
regression-# stringu1 = 'xxx';
|
||||
NOTICE: QUERY PLAN:
|
||||
|
||||
|
@ -177,8 +177,8 @@ Index Scan using tenk1_unique1 on tenk1 (cost=0.00..181.22 rows=1 width=148)
|
|||
Let's try joining two tables, using the fields we have been discussing:
|
||||
|
||||
<programlisting>
|
||||
regression=# explain select * from tenk1 t1, tenk2 t2 where t1.unique1 < 50
|
||||
regression-# and t1.unique2 = t2.unique2;
|
||||
regression=# EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50
|
||||
regression-# AND t1.unique2 = t2.unique2;
|
||||
NOTICE: QUERY PLAN:
|
||||
|
||||
Nested Loop (cost=0.00..330.41 rows=49 width=296)
|
||||
|
@ -225,8 +225,8 @@ Nested Loop (cost=0.00..330.41 rows=49 width=296)
|
|||
<programlisting>
|
||||
regression=# set enable_nestloop = off;
|
||||
SET VARIABLE
|
||||
regression=# explain select * from tenk1 t1, tenk2 t2 where t1.unique1 < 50
|
||||
regression-# and t1.unique2 = t2.unique2;
|
||||
regression=# EXPLAIN SELECT * FROM tenk1 t1, tenk2 t2 WHERE t1.unique1 < 50
|
||||
regression-# AND t1.unique2 = t2.unique2;
|
||||
NOTICE: QUERY PLAN:
|
||||
|
||||
Hash Join (cost=181.22..564.83 rows=49 width=296)
|
||||
|
@ -257,9 +257,9 @@ Hash Join (cost=181.22..564.83 rows=49 width=296)
|
|||
For example, we might get a result like this:
|
||||
|
||||
<screen>
|
||||
regression=# explain analyze
|
||||
regression-# select * from tenk1 t1, tenk2 t2
|
||||
regression-# where t1.unique1 < 50 and t1.unique2 = t2.unique2;
|
||||
regression=# EXPLAIN ANALYZE
|
||||
regression-# SELECT * FROM tenk1 t1, tenk2 t2
|
||||
regression-# WHERE t1.unique1 < 50 AND t1.unique2 = t2.unique2;
|
||||
NOTICE: QUERY PLAN:
|
||||
|
||||
Nested Loop (cost=0.00..330.41 rows=49 width=296) (actual time=1.31..28.90 rows=50 loops=1)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.43 2001/10/12 21:19:09 momjian Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/Attic/plsql.sgml,v 2.44 2001/10/12 23:32:34 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="plpgsql">
|
||||
|
@ -709,10 +709,10 @@ PERFORM <replaceable>query</replaceable>
|
|||
</para>
|
||||
<programlisting>
|
||||
PERFORM create_mv(''cs_session_page_requests_mv'',''
|
||||
select session_id, page_id, count(*) as n_hits,
|
||||
sum(dwell_time) as dwell_time, count(dwell_time) as dwell_count
|
||||
from cs_fact_table
|
||||
group by session_id, page_id '');
|
||||
SELECT session_id, page_id, count(*) AS n_hits,
|
||||
sum(dwell_time) AS dwell_time, count(dwell_time) AS dwell_count
|
||||
FROM cs_fact_table
|
||||
GROUP BY session_id, page_id '');
|
||||
</programlisting>
|
||||
</sect3>
|
||||
|
||||
|
@ -804,19 +804,19 @@ BEGIN
|
|||
-- using the FOR <record> construct.
|
||||
--
|
||||
|
||||
FOR referrer_keys IN select * from cs_referrer_keys order by try_order LOOP
|
||||
a_output := a_output || '' if v_'' || referrer_keys.kind || '' like ''''''''''
|
||||
|| referrer_keys.key_string || '''''''''' then return ''''''
|
||||
|| referrer_keys.referrer_type || ''''''; end if;'';
|
||||
FOR referrer_keys IN SELECT * FROM cs_referrer_keys ORDER BY try_order LOOP
|
||||
a_output := a_output || '' IF v_'' || referrer_keys.kind || '' LIKE ''''''''''
|
||||
|| referrer_keys.key_string || '''''''''' THEN RETURN ''''''
|
||||
|| referrer_keys.referrer_type || ''''''; END IF;'';
|
||||
END LOOP;
|
||||
|
||||
a_output := a_output || '' return null; end; '''' language ''''plpgsql'''';'';
|
||||
a_output := a_output || '' RETURN NULL; END; '''' LANGUAGE ''''plpgsql'''';'';
|
||||
|
||||
-- This works because we are not substituting any variables
|
||||
-- Otherwise it would fail. Look at PERFORM for another way to run functions
|
||||
|
||||
EXECUTE a_output;
|
||||
end;
|
||||
END;
|
||||
' LANGUAGE 'plpgsql';
|
||||
</programlisting>
|
||||
</para>
|
||||
|
@ -1262,7 +1262,7 @@ BEGIN
|
|||
IF users_rec.homepage IS NULL THEN
|
||||
-- user entered no homepage, return "http://"
|
||||
|
||||
return ''http://'';
|
||||
RETURN ''http://'';
|
||||
END IF;
|
||||
END;
|
||||
</programlisting>
|
||||
|
@ -1283,13 +1283,13 @@ FOR <replaceable>record | row</replaceable> IN <replaceable>select_clause</repla
|
|||
END LOOP;
|
||||
</synopsis>
|
||||
The record or row is assigned all the rows
|
||||
resulting from the select clause and the loop body executed
|
||||
resulting from the SELECT clause and the loop body executed
|
||||
for each. Here is an example:
|
||||
</para>
|
||||
|
||||
<para>
|
||||
<programlisting>
|
||||
create function cs_refresh_mviews () returns INTEGER as '
|
||||
CREATE FUNCTION cs_refresh_mviews () RETURNS INTEGER AS '
|
||||
DECLARE
|
||||
mviews RECORD;
|
||||
|
||||
|
@ -1310,7 +1310,7 @@ BEGIN
|
|||
END LOOP;
|
||||
|
||||
PERFORM cs_log(''Done refreshing materialized views.'');
|
||||
return 1;
|
||||
RETURN 1;
|
||||
end;
|
||||
' language 'plpgsql';
|
||||
</programlisting>
|
||||
|
@ -2030,25 +2030,25 @@ END;
|
|||
single quotes in PostgreSQL.
|
||||
|
||||
<programlisting>
|
||||
create or replace procedure cs_update_referrer_type_proc is
|
||||
cursor referrer_keys is
|
||||
select * from cs_referrer_keys
|
||||
order by try_order;
|
||||
CREATE OR REPLACE PROCEDURE cs_update_referrer_type_proc IS
|
||||
CURSOR referrer_keys IS
|
||||
SELECT * FROM cs_referrer_keys
|
||||
ORDER BY try_order;
|
||||
|
||||
a_output varchar(4000);
|
||||
begin
|
||||
a_output := 'create or replace function cs_find_referrer_type(v_host IN varchar, v_domain IN varchar,
|
||||
v_url IN varchar) return varchar is begin';
|
||||
a_output VARCHAR(4000);
|
||||
BEGIN
|
||||
a_output := 'CREATE OR REPLACE FUNCTION cs_find_referrer_type(v_host IN VARCHAR, v_domain IN VARCHAR,
|
||||
v_url IN VARCHAR) RETURN VARCHAR IS BEGIN';
|
||||
|
||||
for referrer_key in referrer_keys loop
|
||||
a_output := a_output || ' if v_' || referrer_key.kind || ' like ''' ||
|
||||
referrer_key.key_string || ''' then return ''' || referrer_key.referrer_type ||
|
||||
'''; end if;';
|
||||
end loop;
|
||||
FOR referrer_key IN referrer_keys LOOP
|
||||
a_output := a_output || ' IF v_' || referrer_key.kind || ' LIKE ''' ||
|
||||
referrer_key.key_string || ''' THEN RETURN ''' || referrer_key.referrer_type ||
|
||||
'''; END IF;';
|
||||
END LOOP;
|
||||
|
||||
a_output := a_output || ' return null; end;';
|
||||
execute immediate a_output;
|
||||
end;
|
||||
a_output := a_output || ' RETURN NULL; END;';
|
||||
EXECUTE IMMEDIATE a_output;
|
||||
END;
|
||||
/
|
||||
show errors
|
||||
</programlisting>
|
||||
|
@ -2075,19 +2075,19 @@ BEGIN
|
|||
-- using the FOR <record> construct.
|
||||
--
|
||||
|
||||
FOR referrer_keys IN select * from cs_referrer_keys order by try_order LOOP
|
||||
a_output := a_output || '' if v_'' || referrer_keys.kind || '' like ''''''''''
|
||||
|| referrer_keys.key_string || '''''''''' then return ''''''
|
||||
|| referrer_keys.referrer_type || ''''''; end if;'';
|
||||
FOR referrer_keys IN SELECT * FROM cs_referrer_keys ORDER BY try_order LOOP
|
||||
a_output := a_output || '' IF v_'' || referrer_keys.kind || '' LIKE ''''''''''
|
||||
|| referrer_keys.key_string || '''''''''' THEN RETURN ''''''
|
||||
|| referrer_keys.referrer_type || ''''''; END IF;'';
|
||||
END LOOP;
|
||||
|
||||
a_output := a_output || '' return null; end; '''' language ''''plpgsql'''';'';
|
||||
a_output := a_output || '' RETURN NULL; END; '''' LANGUAGE ''''plpgsql'''';'';
|
||||
|
||||
-- This works because we are not substituting any variables
|
||||
-- Otherwise it would fail. Look at PERFORM for another way to run functions
|
||||
|
||||
EXECUTE a_output;
|
||||
end;
|
||||
END;
|
||||
' LANGUAGE 'plpgsql';
|
||||
</programlisting>
|
||||
</para>
|
||||
|
@ -2109,41 +2109,41 @@ end;
|
|||
</para>
|
||||
|
||||
<programlisting>
|
||||
create or replace procedure cs_parse_url(
|
||||
v_url IN varchar,
|
||||
v_host OUT varchar, -- This will be passed back
|
||||
v_path OUT varchar, -- This one too
|
||||
v_query OUT varchar) -- And this one
|
||||
CREATE OR REPLACE PROCEDURE cs_parse_url(
|
||||
v_url IN VARCHAR,
|
||||
v_host OUT VARCHAR, -- This will be passed back
|
||||
v_path OUT VARCHAR, -- This one too
|
||||
v_query OUT VARCHAR) -- And this one
|
||||
is
|
||||
a_pos1 integer;
|
||||
a_pos2 integer;
|
||||
a_pos1 INTEGER;
|
||||
a_pos2 INTEGER;
|
||||
begin
|
||||
v_host := NULL;
|
||||
v_path := NULL;
|
||||
v_query := NULL;
|
||||
a_pos1 := instr(v_url, '//'); -- PostgreSQL doesn't have an instr function
|
||||
|
||||
if a_pos1 = 0 then
|
||||
return;
|
||||
end if;
|
||||
IF a_pos1 = 0 THEN
|
||||
RETURN;
|
||||
END IF;
|
||||
a_pos2 := instr(v_url, '/', a_pos1 + 2);
|
||||
if a_pos2 = 0 then
|
||||
IF a_pos2 = 0 THEN
|
||||
v_host := substr(v_url, a_pos1 + 2);
|
||||
v_path := '/';
|
||||
return;
|
||||
end if;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2);
|
||||
a_pos1 := instr(v_url, '?', a_pos2 + 1);
|
||||
|
||||
if a_pos1 = 0 then
|
||||
IF a_pos1 = 0 THEN
|
||||
v_path := substr(v_url, a_pos2);
|
||||
return;
|
||||
end if;
|
||||
RETURN;
|
||||
END IF;
|
||||
|
||||
v_path := substr(v_url, a_pos2, a_pos1 - a_pos2);
|
||||
v_query := substr(v_url, a_pos1 + 1);
|
||||
end;
|
||||
END;
|
||||
/
|
||||
show errors;
|
||||
</programlisting>
|
||||
|
@ -2152,34 +2152,34 @@ show errors;
|
|||
Here is how this procedure could be translated for PostgreSQL:
|
||||
|
||||
<programlisting>
|
||||
drop function cs_parse_url_host(VARCHAR);
|
||||
create function cs_parse_url_host(VARCHAR) RETURNS VARCHAR AS '
|
||||
declare
|
||||
DROP FUNCTION cs_parse_url_host(VARCHAR);
|
||||
CREATE FUNCTION cs_parse_url_host(VARCHAR) RETURNS VARCHAR AS '
|
||||
DECLARE
|
||||
v_url ALIAS FOR $1;
|
||||
v_host varchar;
|
||||
v_path varchar;
|
||||
a_pos1 integer;
|
||||
a_pos2 integer;
|
||||
a_pos3 integer;
|
||||
begin
|
||||
v_host VARCHAR;
|
||||
v_path VARCHAR;
|
||||
a_pos1 INTEGER;
|
||||
a_pos2 INTEGER;
|
||||
a_pos3 INTEGER;
|
||||
BEGIN
|
||||
v_host := NULL;
|
||||
a_pos1 := instr(v_url,''//'');
|
||||
|
||||
if a_pos1 = 0 then
|
||||
return ''''; -- Return a blank
|
||||
end if;
|
||||
IF a_pos1 = 0 THEN
|
||||
RETURN ''''; -- Return a blank
|
||||
END IF;
|
||||
|
||||
a_pos2 := instr(v_url,''/'',a_pos1 + 2);
|
||||
if a_pos2 = 0 then
|
||||
IF a_pos2 = 0 THEN
|
||||
v_host := substr(v_url, a_pos1 + 2);
|
||||
v_path := ''/'';
|
||||
return v_host;
|
||||
end if;
|
||||
RETURN v_host;
|
||||
END IF;
|
||||
|
||||
v_host := substr(v_url, a_pos1 + 2, a_pos2 - a_pos1 - 2 );
|
||||
return v_host;
|
||||
end;
|
||||
' language 'plpgsql';
|
||||
RETURN v_host;
|
||||
END;
|
||||
' LANGUAGE 'plpgsql';
|
||||
</programlisting>
|
||||
</para>
|
||||
</example>
|
||||
|
@ -2211,30 +2211,30 @@ end;
|
|||
An example:
|
||||
|
||||
<programlisting>
|
||||
create or replace procedure cs_create_job(v_job_id in integer)
|
||||
is
|
||||
a_running_job_count integer;
|
||||
pragma autonomous_transaction;<co id="co.plpgsql-porting-pragma">
|
||||
begin
|
||||
lock table cs_jobs in exclusive mode;<co id="co.plpgsql-porting-locktable">
|
||||
CREATE OR REPLACE PROCEDURE cs_create_job(v_job_id IN INTEGER) IS
|
||||
a_running_job_count INTEGER;
|
||||
PRAGMA AUTONOMOUS_TRANSACTION;<co id="co.plpgsql-porting-pragma">
|
||||
BEGIN
|
||||
LOCK TABLE cs_jobs IN EXCLUSIVE MODE;<co id="co.plpgsql-porting-locktable">
|
||||
|
||||
select count(*) into a_running_job_count from cs_jobs
|
||||
where end_stamp is null;
|
||||
SELECT count(*) INTO a_running_job_count
|
||||
FROM cs_jobs
|
||||
WHERE end_stamp IS NULL;
|
||||
|
||||
if a_running_job_count > 0 then
|
||||
commit; -- free lock<co id="co.plpgsql-porting-commit">
|
||||
IF a_running_job_count > 0 THEN
|
||||
COMMIT; -- free lock<co id="co.plpgsql-porting-commit">
|
||||
raise_application_error(-20000, 'Unable to create a new job: a job is currently running.');
|
||||
end if;
|
||||
END IF;
|
||||
|
||||
delete from cs_active_job;
|
||||
insert into cs_active_job(job_id) values(v_job_id);
|
||||
DELETE FROM cs_active_job;
|
||||
INSERT INTO cs_active_job(job_id) VALUES (v_job_id);
|
||||
|
||||
begin
|
||||
insert into cs_jobs(job_id, start_stamp) values(v_job_id, sysdate);
|
||||
exception when dup_val_on_index then null; -- don't worry if it already exists<co id="co.plpgsql-porting-exception">
|
||||
end;
|
||||
commit;
|
||||
end;
|
||||
BEGIN
|
||||
INSERT INTO cs_jobs (job_id, start_stamp) VALUES (v_job_id, sysdate);
|
||||
EXCEPTION WHEN dup_val_on_index THEN NULL; -- don't worry if it already exists<co id="co.plpgsql-porting-exception">
|
||||
END;
|
||||
COMMIT;
|
||||
END;
|
||||
/
|
||||
show errors
|
||||
</programlisting>
|
||||
|
@ -2282,12 +2282,12 @@ show errors
|
|||
So let's see one of the ways we could port this procedure to <application>PL/pgSQL</>:
|
||||
|
||||
<programlisting>
|
||||
drop function cs_create_job(INTEGER);
|
||||
create function cs_create_job(INTEGER) RETURNS INTEGER AS ' DECLARE
|
||||
DROP FUNCTION cs_create_job(INTEGER);
|
||||
CREATE FUNCTION cs_create_job(INTEGER) RETURNS INTEGER AS ' DECLARE
|
||||
v_job_id ALIAS FOR $1;
|
||||
a_running_job_count INTEGER;
|
||||
a_num integer;
|
||||
-- pragma autonomous_transaction;
|
||||
a_num INTEGER;
|
||||
-- PRAGMA AUTONOMOUS_TRANSACTION;
|
||||
BEGIN
|
||||
LOCK TABLE cs_jobs IN EXCLUSIVE MODE;
|
||||
SELECT count(*) INTO a_running_job_count
|
||||
|
@ -2351,29 +2351,25 @@ END;
|
|||
System</ulink>):
|
||||
|
||||
<programlisting>
|
||||
create or replace package body acs
|
||||
as
|
||||
function add_user (
|
||||
user_id in users.user_id%TYPE default null,
|
||||
object_type in acs_objects.object_type%TYPE
|
||||
default 'user',
|
||||
creation_date in acs_objects.creation_date%TYPE
|
||||
default sysdate,
|
||||
creation_user in acs_objects.creation_user%TYPE
|
||||
default null,
|
||||
creation_ip in acs_objects.creation_ip%TYPE default null,
|
||||
CREATE OR REPLACE PACKAGE BODY acs
|
||||
AS
|
||||
FUNCTION add_user (
|
||||
user_id IN users.user_id%TYPE DEFAULT NULL,
|
||||
object_type IN acs_objects.object_type%TYPE DEFAULT 'user',
|
||||
creation_date IN acs_objects.creation_date%TYPE DEFAULT sysdate,
|
||||
creation_user IN acs_objects.creation_user%TYPE DEFAULT NULL,
|
||||
creation_ip IN acs_objects.creation_ip%TYPE DEFAULT NULL,
|
||||
...
|
||||
) return users.user_id%TYPE
|
||||
is
|
||||
) RETURN users.user_id%TYPE
|
||||
IS
|
||||
v_user_id users.user_id%TYPE;
|
||||
v_rel_id membership_rels.rel_id%TYPE;
|
||||
begin
|
||||
BEGIN
|
||||
v_user_id := acs_user.new (user_id, object_type, creation_date,
|
||||
creation_user, creation_ip, email,
|
||||
...
|
||||
return v_user_id;
|
||||
end;
|
||||
end acs;
|
||||
creation_user, creation_ip, email, ...
|
||||
RETURN v_user_id;
|
||||
END;
|
||||
END acs;
|
||||
/
|
||||
show errors
|
||||
</programlisting>
|
||||
|
@ -2491,7 +2487,7 @@ BEGIN
|
|||
pos:= instr($1,$2,1);
|
||||
RETURN pos;
|
||||
END;
|
||||
' language 'plpgsql';
|
||||
' LANGUAGE 'plpgsql';
|
||||
|
||||
|
||||
DROP FUNCTION instr(VARCHAR,VARCHAR,INTEGER);
|
||||
|
@ -2501,10 +2497,10 @@ DECLARE
|
|||
string_to_search ALIAS FOR $2;
|
||||
beg_index ALIAS FOR $3;
|
||||
pos integer NOT NULL DEFAULT 0;
|
||||
temp_str varchar;
|
||||
beg integer;
|
||||
length integer;
|
||||
ss_length integer;
|
||||
temp_str VARCHAR;
|
||||
beg INTEGER;
|
||||
length INTEGER;
|
||||
ss_length INTEGER;
|
||||
BEGIN
|
||||
IF beg_index > 0 THEN
|
||||
|
||||
|
@ -2522,7 +2518,6 @@ BEGIN
|
|||
beg := length + beg_index - ss_length + 2;
|
||||
|
||||
WHILE beg > 0 LOOP
|
||||
|
||||
temp_str := substring(string FROM beg FOR ss_length);
|
||||
pos := position(string_to_search IN temp_str);
|
||||
|
||||
|
@ -2549,7 +2544,7 @@ DECLARE
|
|||
beg_index ALIAS FOR $3;
|
||||
occur_index ALIAS FOR $4;
|
||||
pos integer NOT NULL DEFAULT 0;
|
||||
occur_number integer NOT NULL DEFAULT 0;
|
||||
occur_number INTEGER NOT NULL DEFAULT 0;
|
||||
temp_str VARCHAR;
|
||||
beg INTEGER;
|
||||
i INTEGER;
|
||||
|
|
|
@ -447,7 +447,7 @@ Maximum number of tuples to return
|
|||
which the query will be executed. For example,
|
||||
|
||||
<ProgramListing>
|
||||
SPI_exec ("insert into table select * from table", 5);
|
||||
SPI_exec ("INSERT INTO tab SELECT * FROM tab", 5);
|
||||
</ProgramListing>
|
||||
|
||||
will allow at most 5 tuples to be inserted into table.
|
||||
|
@ -2821,19 +2821,19 @@ execq(text *sql, int cnt)
|
|||
Now, compile and create the function:
|
||||
|
||||
<ProgramListing>
|
||||
create function execq (text, int4) returns int4 as '...path_to_so' language 'c';
|
||||
CREATE FUNCTION execq (TEXT, INT4) RETURNS INT4 AS '...path_to_so' LANGUAGE 'c';
|
||||
</ProgramListing>
|
||||
|
||||
<ProgramListing>
|
||||
vac=> select execq('create table a (x int4)', 0);
|
||||
vac=> SELECT execq('CREATE TABLE a (x INT4)', 0);
|
||||
execq
|
||||
-----
|
||||
0
|
||||
(1 row)
|
||||
|
||||
vac=> insert into a values (execq('insert into a values (0)',0));
|
||||
vac=> INSERT INTO a VALUES (execq('INSERT INTO a VALUES (0)',0));
|
||||
INSERT 167631 1
|
||||
vac=> select execq('select * from a',0);
|
||||
vac=> select execq('SELECT * FROM a',0);
|
||||
NOTICE:EXECQ: 0 <<< inserted by execq
|
||||
|
||||
NOTICE:EXECQ: 1 <<< value returned by execq and inserted by upper INSERT
|
||||
|
@ -2843,13 +2843,13 @@ execq
|
|||
2
|
||||
(1 row)
|
||||
|
||||
vac=> select execq('insert into a select x + 2 from a',1);
|
||||
vac=> SELECT execq('INSERT INTO a SELECT x + 2 FROM a',1);
|
||||
execq
|
||||
-----
|
||||
1
|
||||
(1 row)
|
||||
|
||||
vac=> select execq('select * from a', 10);
|
||||
vac=> SELECT execq('SELECT * FROM a', 10);
|
||||
NOTICE:EXECQ: 0
|
||||
|
||||
NOTICE:EXECQ: 1
|
||||
|
@ -2861,20 +2861,20 @@ execq
|
|||
3 <<< 10 is max value only, 3 is real # of tuples
|
||||
(1 row)
|
||||
|
||||
vac=> delete from a;
|
||||
vac=> DELETE FROM a;
|
||||
DELETE 3
|
||||
vac=> insert into a values (execq('select * from a', 0) + 1);
|
||||
vac=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
|
||||
INSERT 167712 1
|
||||
vac=> select * from a;
|
||||
vac=> SELECT * FROM a;
|
||||
x
|
||||
-
|
||||
1 <<< no tuples in a (0) + 1
|
||||
(1 row)
|
||||
|
||||
vac=> insert into a values (execq('select * from a', 0) + 1);
|
||||
vac=> INSERT INTO a VALUES (execq('SELECT * FROM a', 0) + 1);
|
||||
NOTICE:EXECQ: 0
|
||||
INSERT 167713 1
|
||||
vac=> select * from a;
|
||||
vac=> SELECT * FROM a;
|
||||
x
|
||||
-
|
||||
1
|
||||
|
@ -2883,14 +2883,14 @@ x
|
|||
|
||||
-- This demonstrates data changes visibility rule:
|
||||
|
||||
vac=> insert into a select execq('select * from a', 0) * x from a;
|
||||
vac=> INSERT INTO a SELECT execq('SELECT * FROM a', 0) * x FROM a;
|
||||
NOTICE:EXECQ: 1
|
||||
NOTICE:EXECQ: 2
|
||||
NOTICE:EXECQ: 1
|
||||
NOTICE:EXECQ: 2
|
||||
NOTICE:EXECQ: 2
|
||||
INSERT 0 2
|
||||
vac=> select * from a;
|
||||
vac=> SELECT * FROM a;
|
||||
x
|
||||
-
|
||||
1
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<!--
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.48 2001/10/09 18:46:00 petere Exp $
|
||||
$Header: /cvsroot/pgsql/doc/src/sgml/syntax.sgml,v 1.49 2001/10/12 23:32:34 momjian Exp $
|
||||
-->
|
||||
|
||||
<chapter id="sql-syntax">
|
||||
|
@ -909,7 +909,7 @@ $<replaceable>number</replaceable>
|
|||
|
||||
<programlisting>
|
||||
CREATE FUNCTION dept (text) RETURNS dept
|
||||
AS 'select * from dept where name = $1'
|
||||
AS 'SELECT * FROM dept WHERE name = $1'
|
||||
LANGUAGE 'sql';
|
||||
</programlisting>
|
||||
|
||||
|
|
|
@ -486,7 +486,7 @@ trigf(PG_FUNCTION_ARGS)
|
|||
elog(NOTICE, "trigf (fired %s): SPI_connect returned %d", when, ret);
|
||||
|
||||
/* Get number of tuples in relation */
|
||||
ret = SPI_exec("select count(*) from ttest", 0);
|
||||
ret = SPI_exec("SELECT count(*) FROM ttest", 0);
|
||||
|
||||
if (ret < 0)
|
||||
elog(NOTICE, "trigf (fired %s): SPI_exec returned %d", when, ret);
|
||||
|
@ -513,70 +513,70 @@ trigf(PG_FUNCTION_ARGS)
|
|||
Now, compile and create the trigger function:
|
||||
|
||||
<programlisting>
|
||||
create function trigf () returns opaque as
|
||||
'...path_to_so' language 'C';
|
||||
CREATE FUNCTION trigf () RETURNS OPAQUE AS
|
||||
'...path_to_so' LANGUAGE 'C';
|
||||
|
||||
create table ttest (x int4);
|
||||
CREATE TABLE ttest (x int4);
|
||||
</programlisting>
|
||||
|
||||
<programlisting>
|
||||
vac=> create trigger tbefore before insert or update or delete on ttest
|
||||
for each row execute procedure trigf();
|
||||
vac=> CREATE TRIGGER tbefore BEFORE INSERT OR UPDATE OR DELETE ON ttest
|
||||
FOR EACH ROW EXECUTE PROCEDURE trigf();
|
||||
CREATE
|
||||
vac=> create trigger tafter after insert or update or delete on ttest
|
||||
for each row execute procedure trigf();
|
||||
vac=> CREATE TRIGGER tafter AFTER INSERT OR UPDATE OR DELETE ON ttest
|
||||
FOR EACH ROW EXECUTE PROCEDURE trigf();
|
||||
CREATE
|
||||
vac=> insert into ttest values (null);
|
||||
vac=> INSERT INTO ttest VALUES (NULL);
|
||||
NOTICE:trigf (fired before): there are 0 tuples in ttest
|
||||
INSERT 0 0
|
||||
|
||||
-- Insertion skipped and AFTER trigger is not fired
|
||||
|
||||
vac=> select * from ttest;
|
||||
vac=> SELECT * FROM ttest;
|
||||
x
|
||||
-
|
||||
(0 rows)
|
||||
|
||||
vac=> insert into ttest values (1);
|
||||
vac=> INSERT INTO ttest VALUES (1);
|
||||
NOTICE:trigf (fired before): there are 0 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 1 tuples in ttest
|
||||
^^^^^^^^
|
||||
remember what we said about visibility.
|
||||
INSERT 167793 1
|
||||
vac=> select * from ttest;
|
||||
vac=> SELECT * FROM ttest;
|
||||
x
|
||||
-
|
||||
1
|
||||
(1 row)
|
||||
|
||||
vac=> insert into ttest select x * 2 from ttest;
|
||||
vac=> INSERT INTO ttest SELECT x * 2 FROM ttest;
|
||||
NOTICE:trigf (fired before): there are 1 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 2 tuples in ttest
|
||||
^^^^^^^^
|
||||
remember what we said about visibility.
|
||||
INSERT 167794 1
|
||||
vac=> select * from ttest;
|
||||
vac=> SELECT * FROM ttest;
|
||||
x
|
||||
-
|
||||
1
|
||||
2
|
||||
(2 rows)
|
||||
|
||||
vac=> update ttest set x = null where x = 2;
|
||||
vac=> UPDATE ttest SET x = null WHERE x = 2;
|
||||
NOTICE:trigf (fired before): there are 2 tuples in ttest
|
||||
UPDATE 0
|
||||
vac=> update ttest set x = 4 where x = 2;
|
||||
vac=> UPDATE ttest SET x = 4 WHERE x = 2;
|
||||
NOTICE:trigf (fired before): there are 2 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 2 tuples in ttest
|
||||
UPDATE 1
|
||||
vac=> select * from ttest;
|
||||
vac=> SELECT * FROM ttest;
|
||||
x
|
||||
-
|
||||
1
|
||||
4
|
||||
(2 rows)
|
||||
|
||||
vac=> delete from ttest;
|
||||
vac=> DELETE FROM ttest;
|
||||
NOTICE:trigf (fired before): there are 2 tuples in ttest
|
||||
NOTICE:trigf (fired after ): there are 1 tuples in ttest
|
||||
NOTICE:trigf (fired before): there are 1 tuples in ttest
|
||||
|
@ -584,7 +584,7 @@ NOTICE:trigf (fired after ): there are 0 tuples in ttest
|
|||
^^^^^^^^
|
||||
remember what we said about visibility.
|
||||
DELETE 2
|
||||
vac=> select * from ttest;
|
||||
vac=> SELECT * FROM ttest;
|
||||
x
|
||||
-
|
||||
(0 rows)
|
||||
|
|
|
@ -281,19 +281,18 @@ If only one candidate remains, use it; else continue to the next step.
|
|||
</step>
|
||||
<step performance="required">
|
||||
<para>
|
||||
If any input arguments are <quote>unknown</quote>, check the type categories accepted
|
||||
at those argument positions by the remaining candidates. At each position,
|
||||
select "string"
|
||||
category if any candidate accepts that category (this bias towards string
|
||||
is appropriate since an unknown-type literal does look like a string).
|
||||
Otherwise, if all the remaining candidates accept the same type category,
|
||||
select that category; otherwise fail because
|
||||
the correct choice cannot be deduced without more clues. Also note whether
|
||||
any of the candidates accept a preferred data type within the selected category.
|
||||
Now discard operator candidates that do not accept the selected type category;
|
||||
furthermore, if any candidate accepts a preferred type at a given argument
|
||||
position, discard candidates that accept non-preferred types for that
|
||||
argument.
|
||||
If any input arguments are <quote>unknown</quote>, check the type
|
||||
categories accepted at those argument positions by the remaining
|
||||
candidates. At each position, try the "string" category if any
|
||||
candidate accepts that category (this bias towards string is appropriate
|
||||
since an unknown-type literal does look like a string). Otherwise, if
|
||||
all the remaining candidates accept the same type category, select that
|
||||
category; otherwise fail because the correct choice cannot be deduced
|
||||
without more clues. Also note whether any of the candidates accept a
|
||||
preferred data type within the selected category. Now discard operator
|
||||
candidates that do not accept the selected type category; furthermore,
|
||||
if any candidate accepts a preferred type at a given argument position,
|
||||
discard candidates that accept non-preferred types for that argument.
|
||||
</para>
|
||||
</step>
|
||||
<step performance="required">
|
||||
|
@ -319,7 +318,7 @@ operator defined in the catalog, and it takes arguments of type
|
|||
The scanner assigns an initial type of <type>integer</type> to both arguments
|
||||
of this query expression:
|
||||
<screen>
|
||||
tgl=> select 2 ^ 3 AS "Exp";
|
||||
tgl=> SELECT 2 ^ 3 AS "Exp";
|
||||
Exp
|
||||
-----
|
||||
8
|
||||
|
@ -330,7 +329,7 @@ So the parser does a type conversion on both operands and the query
|
|||
is equivalent to
|
||||
|
||||
<screen>
|
||||
tgl=> select CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "Exp";
|
||||
tgl=> SELECT CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "Exp";
|
||||
Exp
|
||||
-----
|
||||
8
|
||||
|
@ -340,7 +339,7 @@ tgl=> select CAST(2 AS double precision) ^ CAST(3 AS double precision) AS "Exp";
|
|||
or
|
||||
|
||||
<screen>
|
||||
tgl=> select 2.0 ^ 3.0 AS "Exp";
|
||||
tgl=> SELECT 2.0 ^ 3.0 AS "Exp";
|
||||
Exp
|
||||
-----
|
||||
8
|
||||
|
@ -417,7 +416,7 @@ will try to convert that argument to an integer for evaluation of the
|
|||
factorial.
|
||||
|
||||
<screen>
|
||||
tgl=> select (4.3 !);
|
||||
tgl=> SELECT (4.3 !);
|
||||
?column?
|
||||
----------
|
||||
24
|
||||
|
@ -508,8 +507,7 @@ If only one candidate remains, use it; else continue to the next step.
|
|||
<para>
|
||||
If any input arguments are <type>unknown</type>, check the type categories accepted
|
||||
at those argument positions by the remaining candidates. At each position,
|
||||
select <type>string</type>
|
||||
category if any candidate accepts that category (this bias towards string
|
||||
try the <type>string</type> category if any candidate accepts that category (this bias towards string
|
||||
is appropriate since an unknown-type literal does look like a string).
|
||||
Otherwise, if all the remaining candidates accept the same type category,
|
||||
select that category; otherwise fail because
|
||||
|
@ -543,7 +541,7 @@ So the following query automatically converts the <type>int2</type> argument
|
|||
to <type>int4</type>:
|
||||
|
||||
<screen>
|
||||
tgl=> select int4fac(int2 '4');
|
||||
tgl=> SELECT int4fac(int2 '4');
|
||||
int4fac
|
||||
---------
|
||||
24
|
||||
|
@ -552,7 +550,7 @@ tgl=> select int4fac(int2 '4');
|
|||
|
||||
and is actually transformed by the parser to
|
||||
<screen>
|
||||
tgl=> select int4fac(int4(int2 '4'));
|
||||
tgl=> SELECT int4fac(int4(int2 '4'));
|
||||
int4fac
|
||||
---------
|
||||
24
|
||||
|
@ -573,7 +571,7 @@ only one takes two arguments, of types <type>text</type> and <type>int4</type>.
|
|||
If called with a string constant of unspecified type, the type is matched up
|
||||
directly with the only candidate function type:
|
||||
<screen>
|
||||
tgl=> select substr('1234', 3);
|
||||
tgl=> SELECT substr('1234', 3);
|
||||
substr
|
||||
--------
|
||||
34
|
||||
|
@ -585,7 +583,7 @@ tgl=> select substr('1234', 3);
|
|||
If the string is declared to be of type <type>varchar</type>, as might be the case
|
||||
if it comes from a table, then the parser will try to coerce it to become <type>text</type>:
|
||||
<screen>
|
||||
tgl=> select substr(varchar '1234', 3);
|
||||
tgl=> SELECT substr(varchar '1234', 3);
|
||||
substr
|
||||
--------
|
||||
34
|
||||
|
@ -593,7 +591,7 @@ tgl=> select substr(varchar '1234', 3);
|
|||
</screen>
|
||||
which is transformed by the parser to become
|
||||
<screen>
|
||||
tgl=> select substr(text(varchar '1234'), 3);
|
||||
tgl=> SELECT substr(text(varchar '1234'), 3);
|
||||
substr
|
||||
--------
|
||||
34
|
||||
|
@ -615,7 +613,7 @@ explicit type conversion call is really inserted in this case.
|
|||
And, if the function is called with an <type>int4</type>, the parser will
|
||||
try to convert that to <type>text</type>:
|
||||
<screen>
|
||||
tgl=> select substr(1234, 3);
|
||||
tgl=> SELECT substr(1234, 3);
|
||||
substr
|
||||
--------
|
||||
34
|
||||
|
@ -623,7 +621,7 @@ tgl=> select substr(1234, 3);
|
|||
</screen>
|
||||
actually executes as
|
||||
<screen>
|
||||
tgl=> select substr(text(1234), 3);
|
||||
tgl=> SELECT substr(text(1234), 3);
|
||||
substr
|
||||
--------
|
||||
34
|
||||
|
|
Loading…
Reference in New Issue