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
6c498285
Commit
6c498285
authored
Aug 30, 1998
by
Marc G. Fournier
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
parent
6f3de1bb
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
295 additions
and
117 deletions
+295
-117
src/backend/commands/async.c
src/backend/commands/async.c
+226
-99
src/backend/tcop/postgres.c
src/backend/tcop/postgres.c
+43
-12
src/man/create_sequence.l
src/man/create_sequence.l
+18
-1
src/man/listen.l
src/man/listen.l
+8
-5
No files found.
src/backend/commands/async.c
View file @
6c498285
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.3
7 1998/08/19 02:01:39 momjian
Exp $
* $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.3
8 1998/08/30 21:04:43 scrappy
Exp $
*
*-------------------------------------------------------------------------
*/
...
...
@@ -34,29 +34,7 @@
* -- jw, 12/28/93
*
*/
/*
* The following is the old model which does not work.
*/
/*
* Model is:
* 1. Multiple backends on same machine.
*
* 2. Query on one backend sends stuff over an asynchronous portal by
* appending to a relation, and then doing an async. notification
* (which takes place after commit) to all listeners on this relation.
*
* 3. Async. notification results in all backends listening on relation
* to be woken up, by a process signal kill(SIGUSR2), with name of relation
* passed in shared memory.
*
* 4. Each backend notifies its respective frontend over the comm
* channel using the out-of-band channel.
*
* 5. Each frontend receives this notification and processes accordingly.
*
* #4,#5 are changing soon with pending rewrite of portal/protocol.
*
*/
#include <unistd.h>
#include <signal.h>
#include <string.h>
...
...
@@ -82,17 +60,28 @@
#include "tcop/dest.h"
#include "utils/mcxt.h"
#include "utils/syscache.h"
#include <utils/trace.h>
#include <utils/ps_status.h>
#define NotifyUnlock pg_options[OPT_NOTIFYUNLOCK]
#define NotifyHack pg_options[OPT_NOTIFYHACK]
extern
TransactionState
CurrentTransactionState
;
extern
CommandDest
whereToSendOutput
;
GlobalMemory
notifyContext
=
NULL
;
static
int
notifyFrontEndPending
=
0
;
static
int
notifyIssued
=
0
;
static
Dllist
*
pendingNotifies
=
NULL
;
static
int
AsyncExistsPendingNotify
(
char
*
);
static
void
ClearPendingNotify
(
void
);
static
void
Async_NotifyFrontEnd
(
void
);
static
void
Async_NotifyFrontEnd_Aux
(
void
);
void
Async_Unlisten
(
char
*
relname
,
int
pid
);
static
void
Async_UnlistenOnExit
(
int
code
,
char
*
relname
);
static
void
Async_UnlistenAll
(
void
);
/*
*--------------------------------------------------------------
...
...
@@ -116,33 +105,36 @@ static void Async_UnlistenOnExit(int code, char *relname);
void
Async_NotifyHandler
(
SIGNAL_ARGS
)
{
extern
TransactionState
CurrentTransactionState
;
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyHandler"
)
;
if
((
CurrentTransactionState
->
state
==
TRANS_DEFAULT
)
&&
(
CurrentTransactionState
->
blockState
==
TRANS_DEFAULT
))
{
#ifdef ASYNC_DEBUG
elog
(
DEBUG
,
"Waking up sleeping backend process"
);
#endif
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyHandler: "
"waking up sleeping backend process"
);
PS_SET_STATUS
(
"async_notify"
);
Async_NotifyFrontEnd
();
PS_SET_STATUS
(
"idle"
);
}
else
{
#ifdef ASYNC_DEBUG
elog
(
DEBUG
,
"Process is in the middle of another transaction, state = %d, block state = %d"
,
CurrentTransactionState
->
state
,
CurrentTransactionState
->
blockState
);
#endif
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyHandler: "
"process in middle of transaction, state=%d, blockstate=%d"
,
CurrentTransactionState
->
state
,
CurrentTransactionState
->
blockState
);
notifyFrontEndPending
=
1
;
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyHandler: notify frontend pending"
);
}
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyHandler: done"
);
}
/*
*--------------------------------------------------------------
* Async_Notify --
*
* This is executed by the SQL notify command.
*
* Adds the relation to the list of pending notifies.
* All notification happens at end of commit.
* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
...
@@ -151,7 +143,6 @@ Async_NotifyHandler(SIGNAL_ARGS)
* then each backend notifies its corresponding front end at
* the end of commit.
*
* This correspond to 'notify <relname>' command
* -- jw, 12/28/93
*
* Results:
...
...
@@ -180,9 +171,7 @@ Async_Notify(char *relname)
char
*
notifyName
;
#ifdef ASYNC_DEBUG
elog
(
DEBUG
,
"Async_Notify: %s"
,
relname
);
#endif
TPRINTF
(
TRACE_NOTIFY
,
"Async_Notify: %s"
,
relname
);
if
(
!
pendingNotifies
)
pendingNotifies
=
DLNewList
();
...
...
@@ -217,18 +206,32 @@ Async_Notify(char *relname)
{
rTuple
=
heap_modifytuple
(
lTuple
,
lRel
,
value
,
nulls
,
repl
);
heap_replace
(
lRel
,
&
lTuple
->
t_ctid
,
rTuple
);
/* notify is really issued only if a tuple has been changed */
notifyIssued
=
1
;
}
}
heap_endscan
(
sRel
);
RelationUnsetLockForWrite
(
lRel
);
/*
* Note: if the write lock is unset we can get multiple tuples
* with same oid if other backends notify the same relation.
* Use this option at your own risk.
*/
if
(
NotifyUnlock
)
{
RelationUnsetLockForWrite
(
lRel
);
}
heap_close
(
lRel
);
notifyIssued
=
1
;
TPRINTF
(
TRACE_NOTIFY
,
"Async_Notify: done %s"
,
relname
);
}
/*
*--------------------------------------------------------------
* Async_NotifyAtCommit --
*
* This is called at transaction commit.
*
* Signal our corresponding frontend process on relations that
* were notified. Signal all other backend process that
* are listening also.
...
...
@@ -265,14 +268,12 @@ Async_NotifyAtCommit()
if
((
CurrentTransactionState
->
state
==
TRANS_DEFAULT
)
&&
(
CurrentTransactionState
->
blockState
==
TRANS_DEFAULT
))
{
if
(
notifyIssued
)
{
/* 'notify <relname>' issued by us */
{
/* 'notify <relname>' issued by us */
notifyIssued
=
0
;
StartTransactionCommand
();
#ifdef ASYNC_DEBUG
elog
(
DEBUG
,
"Async_NotifyAtCommit."
);
#endif
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyAtCommit"
);
ScanKeyEntryInitialize
(
&
key
,
0
,
Anum_pg_listener_notify
,
F_INT4EQ
,
...
...
@@ -294,16 +295,15 @@ Async_NotifyAtCommit()
if
(
MyProcPid
==
DatumGetInt32
(
d
))
{
#ifdef ASYNC_DEBUG
elog
(
DEBUG
,
"Notifying self, setting notifyFronEndPending to 1"
);
#endif
notifyFrontEndPending
=
1
;
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyAtCommit: notifying self"
);
}
else
{
#ifdef ASYNC_DEBUG
elog
(
DEBUG
,
"Notifying others"
);
#endif
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyAtCommit: notifying pid %d"
,
DatumGetInt32
(
d
));
#ifdef HAVE_KILL
if
(
kill
(
DatumGetInt32
(
d
),
SIGUSR2
)
<
0
)
{
...
...
@@ -315,19 +315,35 @@ Async_NotifyAtCommit()
}
}
heap_endscan
(
sRel
);
RelationUnsetLockForWrite
(
lRel
);
heap_close
(
lRel
);
/*
* Notify the frontend inside the current transaction while
* we still have a valid write lock on pg_listeners. This
* avoid waiting until all other backends have finished
* with pg_listener.
*/
if
(
notifyFrontEndPending
)
{
/* The aux version is called inside transaction */
Async_NotifyFrontEnd_Aux
();
}
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyAtCommit: done"
);
CommitTransactionCommand
();
ClearPendingNotify
();
}
if
(
notifyFrontEndPending
)
{
/* we need to notify the frontend of all
* pending notifies. */
notifyFrontEndPending
=
1
;
Async_NotifyFrontEnd
();
else
{
/*
* No notifies issued by us. If notifyFrontEndPending has been set
* by Async_NotifyHandler notify the frontend of pending notifies
* from other backends.
*/
if
(
notifyFrontEndPending
)
{
Async_NotifyFrontEnd
();
}
}
ClearPendingNotify
();
}
}
...
...
@@ -335,6 +351,8 @@ Async_NotifyAtCommit()
*--------------------------------------------------------------
* Async_NotifyAtAbort --
*
* This is called at transaction commit.
*
* Gets rid of pending notifies. List elements are automatically
* freed through memory context.
*
...
...
@@ -350,20 +368,19 @@ Async_NotifyAtCommit()
void
Async_NotifyAtAbort
()
{
extern
TransactionState
CurrentTransactionState
;
if
(
notifyIssued
)
if
(
pendingNotifies
)
{
ClearPendingNotify
();
notifyIssued
=
0
;
if
(
pendingNotifies
)
DLFreeList
(
pendingNotifies
);
}
pendingNotifies
=
DLNewList
();
notifyIssued
=
0
;
if
((
CurrentTransactionState
->
state
==
TRANS_DEFAULT
)
&&
(
CurrentTransactionState
->
blockState
==
TRANS_DEFAULT
))
{
/* don't forget to notify front end */
if
(
notifyFrontEndPending
)
{
/* don't forget to notify front end */
{
Async_NotifyFrontEnd
();
}
}
...
...
@@ -373,11 +390,11 @@ Async_NotifyAtAbort()
*--------------------------------------------------------------
* Async_Listen --
*
* This is executed by the SQL listen command.
*
* Register a backend (identified by its Unix PID) as listening
* on the specified relation.
*
* This corresponds to the 'listen <relation>' command in SQL
*
* One listener per relation, pg_listener relation is keyed
* on (relname,pid) to provide multiple listeners in future.
*
...
...
@@ -406,9 +423,13 @@ Async_Listen(char *relname, int pid)
char
*
relnamei
;
TupleDesc
tupDesc
;
#ifdef ASYNC_DEBUG
elog
(
DEBUG
,
"Async_Listen: %s"
,
relname
);
#endif
if
(
whereToSendOutput
!=
Remote
)
{
elog
(
NOTICE
,
"Async_Listen: "
"listen not available on interactive sessions"
);
return
;
}
TPRINTF
(
TRACE_NOTIFY
,
"Async_Listen: %s"
,
relname
);
for
(
i
=
0
;
i
<
Natts_pg_listener
;
i
++
)
{
nulls
[
i
]
=
' '
;
...
...
@@ -438,6 +459,10 @@ Async_Listen(char *relname, int pid)
if
(
pid
==
MyProcPid
)
alreadyListener
=
1
;
}
if
(
alreadyListener
)
{
/* No need to scan the rest of the table */
break
;
}
}
heap_endscan
(
scan
);
...
...
@@ -445,15 +470,14 @@ Async_Listen(char *relname, int pid)
{
elog
(
NOTICE
,
"Async_Listen: We are already listening on %s"
,
relname
);
RelationUnsetLockForWrite
(
lDesc
);
heap_close
(
lDesc
);
return
;
}
tupDesc
=
lDesc
->
rd_att
;
newtup
=
heap_formtuple
(
tupDesc
,
values
,
nulls
);
newtup
=
heap_formtuple
(
tupDesc
,
values
,
nulls
);
heap_insert
(
lDesc
,
newtup
);
pfree
(
newtup
);
/*
...
...
@@ -477,12 +501,11 @@ Async_Listen(char *relname, int pid)
*--------------------------------------------------------------
* Async_Unlisten --
*
* This is executed by the SQL unlisten command.
*
* Remove the backend from the list of listening backends
* for the specified relation.
*
* This would correspond to the 'unlisten <relation>'
* command, but there isn't one yet.
*
* Results:
* pg_listeners is updated.
*
...
...
@@ -497,20 +520,81 @@ Async_Unlisten(char *relname, int pid)
Relation
lDesc
;
HeapTuple
lTuple
;
lTuple
=
SearchSysCacheTuple
(
LISTENREL
,
PointerGetDatum
(
relname
),
/* Handle specially the `unlisten "*"' command */
if
((
!
relname
)
||
(
*
relname
==
'\0'
)
||
(
strcmp
(
relname
,
"*"
)
==
0
))
{
Async_UnlistenAll
();
return
;
}
TPRINTF
(
TRACE_NOTIFY
,
"Async_Unlisten %s"
,
relname
);
lTuple
=
SearchSysCacheTuple
(
LISTENREL
,
PointerGetDatum
(
relname
),
Int32GetDatum
(
pid
),
0
,
0
);
lDesc
=
heap_openr
(
ListenerRelationName
);
RelationSetLockForWrite
(
lDesc
);
if
(
lTuple
!=
NULL
)
{
lDesc
=
heap_openr
(
ListenerRelationName
);
RelationSetLockForWrite
(
lDesc
);
heap_delete
(
lDesc
,
&
lTuple
->
t_ctid
);
RelationUnsetLockForWrit
e
(
lDesc
);
heap_close
(
lDesc
);
RelationUnsetLockForWrite
(
lDesc
);
heap_clos
e
(
lDesc
);
}
}
/*
*--------------------------------------------------------------
* Async_UnlistenAll --
*
* Unlisten all relations for this backend.
*
* Results:
* pg_listeners is updated.
*
* Side effects:
* XXX
*
*--------------------------------------------------------------
*/
static
void
Async_UnlistenAll
()
{
HeapTuple
lTuple
;
Relation
lRel
;
HeapScanDesc
sRel
;
TupleDesc
tdesc
;
ScanKeyData
key
[
1
];
TPRINTF
(
TRACE_NOTIFY
,
"Async_UnlistenAll"
);
ScanKeyEntryInitialize
(
&
key
[
0
],
0
,
Anum_pg_listener_pid
,
F_INT4EQ
,
Int32GetDatum
(
MyProcPid
));
lRel
=
heap_openr
(
ListenerRelationName
);
RelationSetLockForWrite
(
lRel
);
tdesc
=
RelationGetTupleDescriptor
(
lRel
);
sRel
=
heap_beginscan
(
lRel
,
0
,
SnapshotNow
,
1
,
key
);
while
(
HeapTupleIsValid
(
lTuple
=
heap_getnext
(
sRel
,
0
)))
{
heap_delete
(
lRel
,
&
lTuple
->
t_ctid
);
}
heap_endscan
(
sRel
);
RelationUnsetLockForWrite
(
lRel
);
heap_close
(
lRel
);
TPRINTF
(
TRACE_NOTIFY
,
"Async_UnlistenAll: done"
);
}
/*
* --------------------------------------------------------------
* Async_UnlistenOnExit --
*
* This is called at backend exit for each registered listen.
*
* Results:
* XXX
*
* --------------------------------------------------------------
*/
static
void
Async_UnlistenOnExit
(
int
code
,
/* from exitpg */
char
*
relname
)
...
...
@@ -522,6 +606,25 @@ Async_UnlistenOnExit(int code, /* from exitpg */
* --------------------------------------------------------------
* Async_NotifyFrontEnd --
*
* This is called outside transactions. The real work is done
* by Async_NotifyFrontEnd_Aux().
*
* --------------------------------------------------------------
*/
static
void
Async_NotifyFrontEnd
()
{
StartTransactionCommand
();
Async_NotifyFrontEnd_Aux
();
CommitTransactionCommand
();
}
/*
* --------------------------------------------------------------
* Async_NotifyFrontEnd_Aux --
*
* This must be called inside a transaction block.
*
* Perform an asynchronous notification to front end over
* portal comm channel. The name of the relation which contains the
* data is sent to the front end.
...
...
@@ -534,12 +637,9 @@ Async_UnlistenOnExit(int code, /* from exitpg */
*
* --------------------------------------------------------------
*/
GlobalMemory
notifyContext
=
NULL
;
static
void
Async_NotifyFrontEnd
()
Async_NotifyFrontEnd
_Aux
()
{
extern
CommandDest
whereToSendOutput
;
HeapTuple
lTuple
,
rTuple
;
Relation
lRel
;
...
...
@@ -552,12 +652,15 @@ Async_NotifyFrontEnd()
nulls
[
3
];
bool
isnull
;
notifyFrontEndPending
=
0
;
#define MAX_DONE 64
#ifdef ASYNC_DEBUG
elog
(
DEBUG
,
"Async_NotifyFrontEnd: notifying front end."
);
#endif
char
*
done
[
MAX_DONE
];
int
ndone
=
0
;
int
i
;
notifyFrontEndPending
=
0
;
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyFrontEnd"
);
StartTransactionCommand
();
ScanKeyEntryInitialize
(
&
key
[
0
],
0
,
Anum_pg_listener_notify
,
...
...
@@ -580,11 +683,35 @@ Async_NotifyFrontEnd()
while
(
HeapTupleIsValid
(
lTuple
=
heap_getnext
(
sRel
,
0
)))
{
d
=
heap_getattr
(
lTuple
,
Anum_pg_listener_relname
,
tdesc
,
&
isnull
);
d
=
heap_getattr
(
lTuple
,
Anum_pg_listener_relname
,
tdesc
,
&
isnull
);
/*
* This hack deletes duplicate tuples which can be left
* in the table if the NotifyUnlock option is set.
* I'm further investigating this. -- dz
*/
if
(
NotifyHack
)
{
for
(
i
=
0
;
i
<
ndone
;
i
++
)
{
if
(
strcmp
(
DatumGetName
(
d
)
->
data
,
done
[
i
])
==
0
)
{
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyFrontEnd: duplicate %s"
,
DatumGetName
(
d
)
->
data
);
heap_delete
(
lRel
,
&
lTuple
->
t_ctid
);
continue
;
}
}
if
(
ndone
<
MAX_DONE
)
{
done
[
ndone
++
]
=
pstrdup
(
DatumGetName
(
d
)
->
data
);
}
}
rTuple
=
heap_modifytuple
(
lTuple
,
lRel
,
value
,
nulls
,
repl
);
heap_replace
(
lRel
,
&
lTuple
->
t_ctid
,
rTuple
);
/* notifying the front end */
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyFrontEnd: notifying %s"
,
DatumGetName
(
d
)
->
data
);
if
(
whereToSendOutput
==
Remote
)
{
...
...
@@ -593,12 +720,12 @@ Async_NotifyFrontEnd()
pq_putstr
(
DatumGetName
(
d
)
->
data
);
pq_flush
();
}
else
elog
(
NOTICE
,
"Async_NotifyFrontEnd: no asynchronous notification to frontend on interactive sessions"
);
}
heap_endscan
(
sRel
);
RelationUnsetLockForWrite
(
lRel
);
heap_close
(
lRel
);
CommitTransactionCommand
();
TPRINTF
(
TRACE_NOTIFY
,
"Async_NotifyFrontEnd: done"
);
}
static
int
...
...
src/backend/tcop/postgres.c
View file @
6c498285
...
...
@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.8
6 1998/08/25 21:34:04
scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.8
7 1998/08/30 21:05:27
scrappy Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
...
...
@@ -443,11 +443,41 @@ pg_parse_and_plan(char *query_string, /* string to execute */
querytree
=
querytree_list
->
qtrees
[
i
];
if
(
DebugPrintQuery
==
true
)
if
(
DebugPrintQuery
)
{
printf
(
"
\n
----
\t
query is:
\n
%s
\n
"
,
query_string
);
printf
(
"
\n
"
);
fflush
(
stdout
);
if
(
DebugPrintQuery
>
3
)
{
/* Print the query string as is if query debug level > 3 */
TPRINTF
(
TRACE_QUERY
,
"query: %s"
,
query_string
);
}
else
{
/* Print condensed query string to fit in one log line */
char
buff
[
8192
+
1
];
char
c
,
*
s
,
*
d
;
int
n
,
is_space
=
1
;
for
(
s
=
query_string
,
d
=
buff
,
n
=
0
;
(
c
=*
s
)
&&
(
n
<
8192
);
s
++
)
{
switch
(
c
)
{
case
'\r'
:
case
'\n'
:
case
'\t'
:
c
=
' '
;
/* fall through */
case
' '
:
if
(
is_space
)
continue
;
is_space
=
1
;
break
;
default:
is_space
=
0
;
break
;
}
*
d
++
=
c
;
n
++
;
}
*
d
=
'\0'
;
TPRINTF
(
TRACE_QUERY
,
"query: %s"
,
buff
);
}
}
/* don't rewrite utilites */
...
...
@@ -457,11 +487,10 @@ pg_parse_and_plan(char *query_string, /* string to execute */
continue
;
}
if
(
DebugPrintParse
==
true
)
if
(
DebugPrintParse
)
{
printf
(
"
\n
----
\t
parser outputs :
\n
"
);
TPRINTF
(
TRACE_PARSE
,
"parser outputs:
"
);
nodeDisplay
(
querytree
);
printf
(
"
\n
"
);
}
/* rewrite queries (retrieve, append, delete, replace) */
...
...
@@ -906,9 +935,11 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
char
firstchar
;
char
parser_input
[
MAX_PARSE_BUFFER
];
char
*
userName
;
char
*
remote_info
;
char
*
remote_host
;
unsigned
short
remote_port
=
0
;
/* Used if verbose is set, must be initialized */
char
*
remote_info
=
"interactive"
;
char
*
remote_host
=
""
;
unsigned
short
remote_port
=
0
;
char
*
DBDate
=
NULL
;
extern
int
optind
;
...
...
@@ -1490,7 +1521,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[])
if
(
!
IsUnderPostmaster
)
{
puts
(
"
\n
POSTGRES backend interactive interface"
);
puts
(
"$Revision: 1.8
6 $ $Date: 1998/08/25 21:34:04
$"
);
puts
(
"$Revision: 1.8
7 $ $Date: 1998/08/30 21:05:27
$"
);
}
/* ----------------
...
...
src/man/create_sequence.l
View file @
6c498285
.\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here....
.\" $Header: /cvsroot/pgsql/src/man/Attic/create_sequence.l,v 1.
5 1998/07/14 01:45:25 momjian
Exp $
.\" $Header: /cvsroot/pgsql/src/man/Attic/create_sequence.l,v 1.
6 1998/08/30 21:03:19 scrappy
Exp $
.TH "CREATE SEQUENCE" SQL 07/13/98 PostgreSQL PostgreSQL
.SH NAME
create sequence - create a new sequence number generator
...
...
@@ -82,6 +82,14 @@ given sequence in the current backend session. Also beware that it
does not give the last number ever allocated, only the last one allocated
by this backend.
.PP
The function
.BR setval
('sequence_name', value)
may be used to set the current value of the specified sequence.
The next call to
.BR nextval
will return the given value + the sequence increment.
.PP
Use a query like
.nf
SELECT * FROM <sequence_name>;
...
...
@@ -134,6 +142,15 @@ select nextval ('seq');
-- Use sequence in insert
--
insert into table _table_ values (nextval ('seq'),...);
.nf
--
-- Set the sequence value after a copy in
--
create function table_id_max() returns int4
as 'select max(id) from _table_'
language 'sql';
copy _table_ from 'input_file';
select setval('seq', table_id_max());
.fi
.SH "SEE ALSO"
drop_sequence(l).
src/man/listen.l
View file @
6c498285
.\" This is -*-nroff-*-
.\" XXX standard disclaimer belongs here....
.\" $Header: /cvsroot/pgsql/src/man/Attic/listen.l,v 1.
7 1998/07/09 03:29:09
scrappy Exp $
.\" $Header: /cvsroot/pgsql/src/man/Attic/listen.l,v 1.
8 1998/08/30 21:03:20
scrappy Exp $
.TH "LISTEN" SQL 03/12/94 PostgreSQL PostgreSQL
.SH NAME
listen - listen for notification on a relation
...
...
@@ -27,16 +27,19 @@ in order to find out the name of the class to which a given
notification corresponds. If this code is not included in
the application, the event notification will be queued and
never be processed.
.PP
Note that
.IR class_name
needs not to be a valid class name but can be any ascii string up to 32
characters long. It must however be eclosed in double-quotes if it is
not valid as class name.
.SH "SEE ALSO"
create_rule(l),
notify(l),
select(l),
unlisten(l),
libpq.
.SH BUGS
There is no way to un-\c
.BR listen
except to drop the connection (i.e., restart the backend server).
.PP
The
.IR psql(1)
command does not poll for asynchronous events.
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