Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
Postgres FD Implementation
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Abuhujair Javed
Postgres FD Implementation
Commits
fab177e6
Commit
fab177e6
authored
Aug 12, 2005
by
Bruce Momjian
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Improve documention on loading large data sets into plperl.
David Fetter
parent
ed63689b
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
74 additions
and
12 deletions
+74
-12
doc/src/sgml/plperl.sgml
doc/src/sgml/plperl.sgml
+71
-11
src/backend/storage/buffer/bufmgr.c
src/backend/storage/buffer/bufmgr.c
+3
-1
No files found.
doc/src/sgml/plperl.sgml
View file @
fab177e6
<!--
$PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.4
2 2005/07/13 02:10:42 neilc
Exp $
$PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.4
3 2005/08/12 21:42:53 momjian
Exp $
-->
<chapter id="plperl">
...
...
@@ -46,7 +46,12 @@ $PostgreSQL: pgsql/doc/src/sgml/plperl.sgml,v 2.42 2005/07/13 02:10:42 neilc Exp
<para>
To create a function in the PL/Perl language, use the standard
<xref linkend="sql-createfunction" endterm="sql-createfunction-title">
syntax:
syntax. A PL/Perl function must always return a scalar value. You
can return more complex structures (arrays, records, and sets)
in the appropriate context by returning a reference.
Never return a list. Here follows an example of a PL/Perl
function.
<programlisting>
CREATE FUNCTION <replaceable>funcname</replaceable> (<replaceable>argument-types</replaceable>) RETURNS <replaceable>return-type</replaceable> AS $$
# PL/Perl function body
...
...
@@ -282,7 +287,7 @@ SELECT * FROM perl_set();
</para>
<para>
PL/Perl provides t
wo
additional Perl commands:
PL/Perl provides t
hree
additional Perl commands:
<variablelist>
<varlistentry>
...
...
@@ -293,11 +298,18 @@ SELECT * FROM perl_set();
<term><literal><function>spi_exec_query</>(<replaceable>query</replaceable> [, <replaceable>max-rows</replaceable>])</literal></term>
<term><literal><function>spi_exec_query</>(<replaceable>command</replaceable>)</literal></term>
<term><literal><function>spi_query</>(<replaceable>command</replaceable>)</literal></term>
<term><literal><function>spi_fetchrow</>(<replaceable>command</replaceable>)</literal></term>
<listitem>
<para>
Executes an SQL command. Here is an example of a query
(<command>SELECT</command> command) with the optional maximum
number of rows:
<literal>spi_exec_query</literal> executes an SQL command and
returns the entire rowset as a reference to an array of hash
references. <emphasis>You should only use this command when you know
that the result set will be relatively small.</emphasis> Here is an
example of a query (<command>SELECT</command> command) with the
optional maximum number of rows:
<programlisting>
$rv = spi_exec_query('SELECT * FROM my_table', 5);
</programlisting>
...
...
@@ -345,7 +357,7 @@ INSERT INTO test (i, v) VALUES (2, 'second line');
INSERT INTO test (i, v) VALUES (3, 'third line');
INSERT INTO test (i, v) VALUES (4, 'immortal');
CREATE FUNCTION test_munge() RETURNS SETOF test AS $$
CREATE
OR REPLACE
FUNCTION test_munge() RETURNS SETOF test AS $$
my $rv = spi_exec_query('select i, v from test;');
my $status = $rv->{status};
my $nrows = $rv->{processed};
...
...
@@ -360,7 +372,45 @@ $$ LANGUAGE plperl;
SELECT * FROM test_munge();
</programlisting>
</para>
</para>
<para>
<literal>spi_query</literal> and <literal>spi_fetchrow</literal>
work together as a pair for rowsets which may be large, or for cases
where you wish to return rows as they arrive.
<literal>spi_fetchrow</literal> works <emphasis>only</emphasis> with
<literal>spi_query</literal>. The following example illustrates how
you use them together:
<programlisting>
CREATE TYPE foo_type AS (the_num INTEGER, the_text TEXT);
CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF foo_type AS $$
use Digest::MD5 qw(md5_hex);
my $file = '/usr/share/dict/words';
my $t = localtime;
elog(NOTICE, "opening file $file at $t" );
open my $fh, '<', $file # ooh, it's a file access!
or elog(ERROR, "Can't open $file for reading: $!");
my @words = <$fh>;
close $fh;
$t = localtime;
elog(NOTICE, "closed file $file at $t");
chomp(@words);
my $row;
my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
while (defined ($row = spi_fetchrow($sth))) {
return_next({
the_num => $row->{a},
the_text => md5_hex($words[rand @words])
});
}
return;
$$ LANGUAGE plperlu;
SELECT * from lotsa_md5(500);
</programlisting>
</para>
</listitem>
</varlistentry>
...
...
@@ -716,10 +766,20 @@ CREATE TRIGGER test_valid_id_trig
<listitem>
<para>
In the current implementation, if you are fetching or returning
very large data sets, you should be aware that these will all go
into memory.
If you are fetching very large data sets using
<literal>spi_exec_query</literal>, you should be aware that
these will all go into memory. You can avoid this by using
<literal>spi_query</literal>/<literal>spi_fetchrow</literal> as
illustrated earlier.
</para>
<para>
A similar problem occurs if a set-returning function passes a
large set of rows back to postgres via <literal>return</literal>. You
can avoid this problem too by instead using
<literal>return_next</literal> for each row returned, as shown
previously.
</para>
</listitem>
</itemizedlist>
</para>
...
...
src/backend/storage/buffer/bufmgr.c
View file @
fab177e6
...
...
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.19
3 2005/08/12 05:05:50 tgl
Exp $
* $PostgreSQL: pgsql/src/backend/storage/buffer/bufmgr.c,v 1.19
4 2005/08/12 21:42:53 momjian
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -153,6 +153,8 @@ ReadBuffer(Relation reln, BlockNumber blockNum)
* block is not currently in memory.
*/
bufHdr
=
BufferAlloc
(
reln
,
blockNum
,
&
found
);
/* we are guaranted that nobody else has touched this will-be-new block */
Assert
(
!
(
found
&&
isExtend
));
if
(
found
)
BufferHitCount
++
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment