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
53166fe2
Commit
53166fe2
authored
Jul 08, 2014
by
Peter Eisentraut
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
doc: Fix spacing in verbatim environments
parent
6048896e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
96 additions
and
95 deletions
+96
-95
doc/src/sgml/config.sgml
doc/src/sgml/config.sgml
+21
-21
doc/src/sgml/extend.sgml
doc/src/sgml/extend.sgml
+10
-10
doc/src/sgml/func.sgml
doc/src/sgml/func.sgml
+5
-5
doc/src/sgml/json.sgml
doc/src/sgml/json.sgml
+32
-32
doc/src/sgml/logicaldecoding.sgml
doc/src/sgml/logicaldecoding.sgml
+23
-22
doc/src/sgml/protocol.sgml
doc/src/sgml/protocol.sgml
+3
-3
doc/src/sgml/test-decoding.sgml
doc/src/sgml/test-decoding.sgml
+2
-2
No files found.
doc/src/sgml/config.sgml
View file @
53166fe2
...
@@ -238,9 +238,9 @@ include 'filename'
...
@@ -238,9 +238,9 @@ include 'filename'
The <filename>postgresql.conf</> file can also contain
The <filename>postgresql.conf</> file can also contain
<literal>include_dir</literal> directives, which specify an entire directory
<literal>include_dir</literal> directives, which specify an entire directory
of configuration files to include. It is used similarly:
of configuration files to include. It is used similarly:
<programlisting>
<programlisting>
include_dir 'directory'
include_dir 'directory'
</programlisting>
</programlisting>
Non-absolute directory names follow the same rules as single file include
Non-absolute directory names follow the same rules as single file include
directives: they are relative to the directory containing the referencing
directives: they are relative to the directory containing the referencing
configuration file. Within that directory, only non-directory files whose
configuration file. Within that directory, only non-directory files whose
...
@@ -263,11 +263,11 @@ include 'filename'
...
@@ -263,11 +263,11 @@ include 'filename'
situation is to break the custom configuration changes for your site into
situation is to break the custom configuration changes for your site into
three files. You could add this to the end of your
three files. You could add this to the end of your
<filename>postgresql.conf</> file to include them:
<filename>postgresql.conf</> file to include them:
<programlisting>
<programlisting>
include 'shared.conf'
include 'shared.conf'
include 'memory.conf'
include 'memory.conf'
include 'server.conf'
include 'server.conf'
</programlisting>
</programlisting>
All systems would have the same <filename>shared.conf</>. Each server
All systems would have the same <filename>shared.conf</>. Each server
with a particular amount of memory could share the same
with a particular amount of memory could share the same
<filename>memory.conf</>; you might have one for all servers with 8GB of RAM,
<filename>memory.conf</>; you might have one for all servers with 8GB of RAM,
...
@@ -279,15 +279,15 @@ include 'filename'
...
@@ -279,15 +279,15 @@ include 'filename'
Another possibility is to create a configuration file directory and
Another possibility is to create a configuration file directory and
put this information into files there. For example, a <filename>conf.d</>
put this information into files there. For example, a <filename>conf.d</>
directory could be referenced at the end of<filename>postgresql.conf</>:
directory could be referenced at the end of<filename>postgresql.conf</>:
<screen
>
<programlisting
>
include_dir 'conf.d'
include_dir 'conf.d'
</screen
>
</programlisting
>
Then you could name the files in the <filename>conf.d</> directory like this:
Then you could name the files in the <filename>conf.d</> directory like this:
<screen
>
<programlisting
>
00shared.conf
00shared.conf
01memory.conf
01memory.conf
02server.conf
02server.conf
</screen
>
</programlisting
>
This shows a clear order in which these files will be loaded. This is
This shows a clear order in which these files will be loaded. This is
important because only the last setting encountered when the server is
important because only the last setting encountered when the server is
reading its configuration will be used. Something set in
reading its configuration will be used. Something set in
...
@@ -298,11 +298,11 @@ include 'filename'
...
@@ -298,11 +298,11 @@ include 'filename'
<para>
<para>
You might instead use this configuration directory approach while naming
You might instead use this configuration directory approach while naming
these files more descriptively:
these files more descriptively:
<screen
>
<programlisting
>
00shared.conf
00shared.conf
01memory-8GB.conf
01memory-8GB.conf
02server-foo.conf
02server-foo.conf
</screen
>
</programlisting
>
This sort of arrangement gives a unique name for each configuration file
This sort of arrangement gives a unique name for each configuration file
variation. This can help eliminate ambiguity when several servers have
variation. This can help eliminate ambiguity when several servers have
their configurations all stored in one place, such as in a version
their configurations all stored in one place, such as in a version
...
...
doc/src/sgml/extend.sgml
View file @
53166fe2
...
@@ -1167,12 +1167,12 @@ include $(PGXS)
...
@@ -1167,12 +1167,12 @@ include $(PGXS)
This procedure is also called a
This procedure is also called a
<indexterm><primary>VPATH</primary></indexterm><firstterm>VPATH</firstterm>
<indexterm><primary>VPATH</primary></indexterm><firstterm>VPATH</firstterm>
build. Here's how:
build. Here's how:
<screen
>
<programlisting
>
<userinput>mkdir build_dir</userinput>
mkdir build_dir
<userinput>cd build_dir</userinput>
cd build_dir
<userinput>make -f /path/to/extension/source/tree/Makefile</userinput>
make -f /path/to/extension/source/tree/Makefile
<userinput>make -f /path/to/extension/source/tree/Makefile install</userinput>
make -f /path/to/extension/source/tree/Makefile install
</screen
>
</programlisting
>
</para>
</para>
<para>
<para>
...
@@ -1181,10 +1181,10 @@ include $(PGXS)
...
@@ -1181,10 +1181,10 @@ include $(PGXS)
core script <filename>config/prep_buildtree</>. Once this has been done
core script <filename>config/prep_buildtree</>. Once this has been done
you can build by setting the <literal>make</literal> variable
you can build by setting the <literal>make</literal> variable
<varname>USE_VPATH</varname> like this:
<varname>USE_VPATH</varname> like this:
<screen
>
<programlisting
>
<userinput>make USE_VPATH=/path/to/extension/source/tree</userinput>
make USE_VPATH=/path/to/extension/source/tree
<userinput>make USE_VPATH=/path/to/extension/source/tree install</userinput>
make USE_VPATH=/path/to/extension/source/tree install
</screen
>
</programlisting
>
This procedure can work with a greater variety of directory layouts.
This procedure can work with a greater variety of directory layouts.
</para>
</para>
...
...
doc/src/sgml/func.sgml
View file @
53166fe2
...
@@ -10495,7 +10495,7 @@ table2-mapping
...
@@ -10495,7 +10495,7 @@ table2-mapping
-----+-------
-----+-------
a | "foo"
a | "foo"
b | "bar"
b | "bar"
</programlisting>
</programlisting>
</entry>
</entry>
</row>
</row>
<row>
<row>
...
@@ -10514,7 +10514,7 @@ table2-mapping
...
@@ -10514,7 +10514,7 @@ table2-mapping
-----+-------
-----+-------
a | foo
a | foo
b | bar
b | bar
</programlisting>
</programlisting>
</entry>
</entry>
</row>
</row>
<row>
<row>
...
@@ -10598,7 +10598,7 @@ table2-mapping
...
@@ -10598,7 +10598,7 @@ table2-mapping
---+---
---+---
1 | 2
1 | 2
3 | 4
3 | 4
</programlisting>
</programlisting>
</entry>
</entry>
</row>
</row>
<row>
<row>
...
@@ -10671,7 +10671,7 @@ table2-mapping
...
@@ -10671,7 +10671,7 @@ table2-mapping
a | b | d
a | b | d
---+---------+---
---+---------+---
1 | [1,2,3] |
1 | [1,2,3] |
</programlisting>
</programlisting>
</entry>
</entry>
</row>
</row>
<row>
<row>
...
@@ -10692,7 +10692,7 @@ table2-mapping
...
@@ -10692,7 +10692,7 @@ table2-mapping
---+-----
---+-----
1 | foo
1 | foo
2 |
2 |
</programlisting>
</programlisting>
</entry>
</entry>
</row>
</row>
</tbody>
</tbody>
...
...
doc/src/sgml/json.sgml
View file @
53166fe2
...
@@ -163,7 +163,7 @@
...
@@ -163,7 +163,7 @@
</para>
</para>
<para>
<para>
The following are all valid <type>json</> (or <type>jsonb</>) expressions:
The following are all valid <type>json</> (or <type>jsonb</>) expressions:
<programlisting>
<programlisting>
-- Simple scalar/primitive value
-- Simple scalar/primitive value
-- Primitive values can be numbers, quoted strings, true, false, or null
-- Primitive values can be numbers, quoted strings, true, false, or null
SELECT '5'::json;
SELECT '5'::json;
...
@@ -177,7 +177,7 @@ SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json;
...
@@ -177,7 +177,7 @@ SELECT '{"bar": "baz", "balance": 7.77, "active": false}'::json;
-- Arrays and objects can be nested arbitrarily
-- Arrays and objects can be nested arbitrarily
SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;
SELECT '{"foo": [true, "bar"], "tags": {"a": 1, "b": null}}'::json;
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
...
@@ -262,7 +262,7 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
...
@@ -262,7 +262,7 @@ SELECT '{"reading": 1.230e-5}'::json, '{"reading": 1.230e-5}'::jsonb;
one <type>jsonb</> document has contained within it another one.
one <type>jsonb</> document has contained within it another one.
These examples return true except as noted:
These examples return true except as noted:
</para>
</para>
<programlisting>
<programlisting>
-- Simple scalar/primitive values contain only the identical value:
-- Simple scalar/primitive values contain only the identical value:
SELECT '"foo"'::jsonb @> '"foo"'::jsonb;
SELECT '"foo"'::jsonb @> '"foo"'::jsonb;
...
@@ -282,7 +282,7 @@ SELECT '[1, 2, [1, 3]]'::jsonb @> '[[1, 3]]'::jsonb;
...
@@ -282,7 +282,7 @@ SELECT '[1, 2, [1, 3]]'::jsonb @> '[[1, 3]]'::jsonb;
-- Similarly, containment is not reported here:
-- Similarly, containment is not reported here:
SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb; -- yields false
SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb; -- yields false
</programlisting>
</programlisting>
<para>
<para>
The general principle is that the contained object must match the
The general principle is that the contained object must match the
...
@@ -296,13 +296,13 @@ SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb; -- yields f
...
@@ -296,13 +296,13 @@ SELECT '{"foo": {"bar": "baz"}}'::jsonb @> '{"bar": "baz"}'::jsonb; -- yields f
As a special exception to the general principle that the structures
As a special exception to the general principle that the structures
must match, an array may contain a primitive value:
must match, an array may contain a primitive value:
</para>
</para>
<programlisting>
<programlisting>
-- This array contains the primitive string value:
-- This array contains the primitive string value:
SELECT '["foo", "bar"]'::jsonb @> '"bar"'::jsonb;
SELECT '["foo", "bar"]'::jsonb @> '"bar"'::jsonb;
-- This exception is not reciprocal -- non-containment is reported here:
-- This exception is not reciprocal -- non-containment is reported here:
SELECT '"bar"'::jsonb @> '["bar"]'::jsonb; -- yields false
SELECT '"bar"'::jsonb @> '["bar"]'::jsonb; -- yields false
</programlisting>
</programlisting>
<para>
<para>
<type>jsonb</> also has an <firstterm>existence</> operator, which is
<type>jsonb</> also has an <firstterm>existence</> operator, which is
...
@@ -363,22 +363,22 @@ SELECT '"foo"'::jsonb ? 'foo';
...
@@ -363,22 +363,22 @@ SELECT '"foo"'::jsonb ? 'foo';
(For details of the semantics that these operators
(For details of the semantics that these operators
implement, see <xref linkend="functions-jsonb-op-table">.)
implement, see <xref linkend="functions-jsonb-op-table">.)
An example of creating an index with this operator class is:
An example of creating an index with this operator class is:
<programlisting>
<programlisting>
CREATE INDEX idxgin ON api USING gin (jdoc);
CREATE INDEX idxgin ON api USING gin (jdoc);
</programlisting>
</programlisting>
The non-default GIN operator class <literal>jsonb_path_ops</>
The non-default GIN operator class <literal>jsonb_path_ops</>
supports indexing the <literal>@></> operator only.
supports indexing the <literal>@></> operator only.
An example of creating an index with this operator class is:
An example of creating an index with this operator class is:
<programlisting>
<programlisting>
CREATE INDEX idxginp ON api USING gin (jdoc jsonb_path_ops);
CREATE INDEX idxginp ON api USING gin (jdoc jsonb_path_ops);
</programlisting>
</programlisting>
</para>
</para>
<para>
<para>
Consider the example of a table that stores JSON documents
Consider the example of a table that stores JSON documents
retrieved from a third-party web service, with a documented schema
retrieved from a third-party web service, with a documented schema
definition. A typical document is:
definition. A typical document is:
<programlisting>
<programlisting>
{
{
"guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a",
"guid": "9c36adc1-7fb5-4d5b-83b4-90356a46061a",
"name": "Angela Barton",
"name": "Angela Barton",
...
@@ -394,32 +394,32 @@ CREATE INDEX idxginp ON api USING gin (jdoc jsonb_path_ops);
...
@@ -394,32 +394,32 @@ CREATE INDEX idxginp ON api USING gin (jdoc jsonb_path_ops);
"qui"
"qui"
]
]
}
}
</programlisting>
</programlisting>
We store these documents in a table named <structname>api</>,
We store these documents in a table named <structname>api</>,
in a <type>jsonb</> column named <structfield>jdoc</>.
in a <type>jsonb</> column named <structfield>jdoc</>.
If a GIN index is created on this column,
If a GIN index is created on this column,
queries like the following can make use of the index:
queries like the following can make use of the index:
<programlisting>
<programlisting>
-- Find documents in which the key "company" has value "Magnafone"
-- Find documents in which the key "company" has value "Magnafone"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}';
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"company": "Magnafone"}';
</programlisting>
</programlisting>
However, the index could not be used for queries like the
However, the index could not be used for queries like the
following, because though the operator <literal>?</> is indexable,
following, because though the operator <literal>?</> is indexable,
it is not applied directly to the indexed column <structfield>jdoc</>:
it is not applied directly to the indexed column <structfield>jdoc</>:
<programlisting>
<programlisting>
-- Find documents in which the key "tags" contains key or array element "qui"
-- Find documents in which the key "tags" contains key or array element "qui"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui';
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc -> 'tags' ? 'qui';
</programlisting>
</programlisting>
Still, with appropriate use of expression indexes, the above
Still, with appropriate use of expression indexes, the above
query can use an index. If querying for particular items within
query can use an index. If querying for particular items within
the <literal>"tags"</> key is common, defining an index like this
the <literal>"tags"</> key is common, defining an index like this
may be worthwhile:
may be worthwhile:
<programlisting>
<programlisting>
-- Note that the "jsonb -> text" operator can only be called on a JSON
-- Note that the "jsonb -> text" operator can only be called on a JSON
-- object, so as a consequence of creating this index the root of each
-- object, so as a consequence of creating this index the root of each
-- "jdoc" value must be an object. This is enforced during insertion.
-- "jdoc" value must be an object. This is enforced during insertion.
CREATE INDEX idxgintags ON api USING gin ((jdoc -> 'tags'));
CREATE INDEX idxgintags ON api USING gin ((jdoc -> 'tags'));
</programlisting>
</programlisting>
Now, the <literal>WHERE</> clause <literal>jdoc -> 'tags' ? 'qui'</>
Now, the <literal>WHERE</> clause <literal>jdoc -> 'tags' ? 'qui'</>
will be recognized as an application of the indexable
will be recognized as an application of the indexable
operator <literal>?</> to the indexed
operator <literal>?</> to the indexed
...
@@ -429,10 +429,10 @@ CREATE INDEX idxgintags ON api USING gin ((jdoc -> 'tags'));
...
@@ -429,10 +429,10 @@ CREATE INDEX idxgintags ON api USING gin ((jdoc -> 'tags'));
</para>
</para>
<para>
<para>
Another approach to querying is to exploit containment, for example:
Another approach to querying is to exploit containment, for example:
<programlisting>
<programlisting>
-- Find documents in which the key "tags" contains array element "qui"
-- Find documents in which the key "tags" contains array element "qui"
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}';
SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qui"]}';
</programlisting>
</programlisting>
A simple GIN index on the <structfield>jdoc</> column can support this
A simple GIN index on the <structfield>jdoc</> column can support this
query. But note that such an index will store copies of every key and
query. But note that such an index will store copies of every key and
value in the <structfield>jdoc</> column, whereas the expression index
value in the <structfield>jdoc</> column, whereas the expression index
...
@@ -460,7 +460,7 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
...
@@ -460,7 +460,7 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
and a <literal>jsonb_path_ops</literal> GIN index is that the former
and a <literal>jsonb_path_ops</literal> GIN index is that the former
creates independent index items for each key and value in the data,
creates independent index items for each key and value in the data,
while the latter creates index items only for each value in the
while the latter creates index items only for each value in the
data.
data.
<footnote>
<footnote>
<para>
<para>
For this purpose, the term <quote>value</> includes array elements,
For this purpose, the term <quote>value</> includes array elements,
...
@@ -501,17 +501,17 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
...
@@ -501,17 +501,17 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
equality of complete JSON documents.
equality of complete JSON documents.
The <literal>btree</> ordering for <type>jsonb</> datums is seldom
The <literal>btree</> ordering for <type>jsonb</> datums is seldom
of great interest, but for completeness it is:
of great interest, but for completeness it is:
<synopsis>
<synopsis>
<replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable>
<replaceable>Object</replaceable> > <replaceable>Array</replaceable> > <replaceable>Boolean</replaceable> > <replaceable>Number</replaceable> > <replaceable>String</replaceable> > <replaceable>Null</replaceable>
<replaceable>Object with n pairs</replaceable> > <replaceable>object with n - 1 pairs</replaceable>
<replaceable>Object with n pairs</replaceable> > <replaceable>object with n - 1 pairs</replaceable>
<replaceable>Array with n elements</replaceable> > <replaceable>array with n - 1 elements</replaceable>
<replaceable>Array with n elements</replaceable> > <replaceable>array with n - 1 elements</replaceable>
</synopsis>
</synopsis>
Objects with equal numbers of pairs are compared in the order:
Objects with equal numbers of pairs are compared in the order:
<synopsis>
<synopsis>
<replaceable>key-1</replaceable>, <replaceable>value-1</replaceable>, <replaceable>key-2</replaceable> ...
<replaceable>key-1</replaceable>, <replaceable>value-1</replaceable>, <replaceable>key-2</replaceable> ...
</synopsis>
</synopsis>
Note that object keys are compared in their storage order;
Note that object keys are compared in their storage order;
in particular, since shorter keys are stored before longer keys, this
in particular, since shorter keys are stored before longer keys, this
can lead to results that might be unintuitive, such as:
can lead to results that might be unintuitive, such as:
...
@@ -520,9 +520,9 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
...
@@ -520,9 +520,9 @@ SELECT jdoc->'guid', jdoc->'name' FROM api WHERE jdoc @> '{"tags": ["qu
</programlisting>
</programlisting>
Similarly, arrays with equal numbers of elements are compared in the
Similarly, arrays with equal numbers of elements are compared in the
order:
order:
<synopsis>
<synopsis>
<replaceable>element-1</replaceable>, <replaceable>element-2</replaceable> ...
<replaceable>element-1</replaceable>, <replaceable>element-2</replaceable> ...
</synopsis>
</synopsis>
Primitive JSON values are compared using the same
Primitive JSON values are compared using the same
comparison rules as for the underlying
comparison rules as for the underlying
<productname>PostgreSQL</productname> data type. Strings are
<productname>PostgreSQL</productname> data type. Strings are
...
...
doc/src/sgml/logicaldecoding.sgml
View file @
53166fe2
...
@@ -51,7 +51,7 @@
...
@@ -51,7 +51,7 @@
Then, you should connect to the target database (in the example
Then, you should connect to the target database (in the example
below, <literal>postgres</literal>) as a superuser.
below, <literal>postgres</literal>) as a superuser.
</para>
</para>
<programlisting>
<programlisting>
postgres=# -- Create a slot named 'regression_slot' using the output plugin 'test_decoding'
postgres=# -- Create a slot named 'regression_slot' using the output plugin 'test_decoding'
postgres=# SELECT * FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
postgres=# SELECT * FROM pg_create_logical_replication_slot('regression_slot', 'test_decoding');
slot_name | xlog_position
slot_name | xlog_position
...
@@ -139,7 +139,7 @@ postgres=# SELECT pg_drop_replication_slot('regression_slot');
...
@@ -139,7 +139,7 @@ postgres=# SELECT pg_drop_replication_slot('regression_slot');
-----------------------
-----------------------
(1 row)
(1 row)
</programlisting>
</programlisting>
<para>
<para>
The following example shows usage of the walsender interface using
The following example shows usage of the walsender interface using
the <link linkend="app-pgrecvlogical"><command>pg_recvlogical</command></link>
the <link linkend="app-pgrecvlogical"><command>pg_recvlogical</command></link>
...
@@ -148,7 +148,7 @@ postgres=# SELECT pg_drop_replication_slot('regression_slot');
...
@@ -148,7 +148,7 @@ postgres=# SELECT pg_drop_replication_slot('regression_slot');
and <varname>max_wal_senders</varname> to be set sufficiently high for
and <varname>max_wal_senders</varname> to be set sufficiently high for
another connection.
another connection.
</para>
</para>
<programlisting>
<programlisting>
# pg_recvlogical -d postgres --slot test --create
# pg_recvlogical -d postgres --slot test --create
# pg_recvlogical -d postgres --slot test --start -f -
# pg_recvlogical -d postgres --slot test --start -f -
CTRL-Z
CTRL-Z
...
@@ -159,7 +159,7 @@ table public.data: INSERT: id[integer]:4 data[text]:'4'
...
@@ -159,7 +159,7 @@ table public.data: INSERT: id[integer]:4 data[text]:'4'
COMMIT 693
COMMIT 693
CTRL-C
CTRL-C
# pg_recvlogical -d postgres --slot test --drop
# pg_recvlogical -d postgres --slot test --drop
</programlisting>
</programlisting>
</sect1>
</sect1>
<sect1 id="logicaldecoding-explanation">
<sect1 id="logicaldecoding-explanation">
<title>Logical Decoding Concepts</title>
<title>Logical Decoding Concepts</title>
...
@@ -317,7 +317,7 @@ CTRL-C
...
@@ -317,7 +317,7 @@ CTRL-C
<function>_PG_output_plugin_init</function>. This function is passed a
<function>_PG_output_plugin_init</function>. This function is passed a
struct that needs to be filled with the callback function pointers for
struct that needs to be filled with the callback function pointers for
individual actions.
individual actions.
<programlisting>
<programlisting>
typedef struct OutputPluginCallbacks
typedef struct OutputPluginCallbacks
{
{
LogicalDecodeStartupCB startup_cb;
LogicalDecodeStartupCB startup_cb;
...
@@ -326,8 +326,9 @@ typedef struct OutputPluginCallbacks
...
@@ -326,8 +326,9 @@ typedef struct OutputPluginCallbacks
LogicalDecodeCommitCB commit_cb;
LogicalDecodeCommitCB commit_cb;
LogicalDecodeShutdownCB shutdown_cb;
LogicalDecodeShutdownCB shutdown_cb;
} OutputPluginCallbacks;
} OutputPluginCallbacks;
typedef void (*LogicalOutputPluginInit)(struct OutputPluginCallbacks *cb);
typedef void (*LogicalOutputPluginInit)(struct OutputPluginCallbacks *cb);
</programlisting>
</programlisting>
The <function>begin_cb</function>, <function>change_cb</function>
The <function>begin_cb</function>, <function>change_cb</function>
and <function>commit_cb</function> callbacks are required,
and <function>commit_cb</function> callbacks are required,
while <function>startup_cb</function>
while <function>startup_cb</function>
...
@@ -344,10 +345,10 @@ typedef void (*LogicalOutputPluginInit)(struct OutputPluginCallbacks *cb);
...
@@ -344,10 +345,10 @@ typedef void (*LogicalOutputPluginInit)(struct OutputPluginCallbacks *cb);
accessed that either have been created by <command>initdb</command> in
accessed that either have been created by <command>initdb</command> in
the <literal>pg_catalog</literal> schema, or have been marked as user
the <literal>pg_catalog</literal> schema, or have been marked as user
provided catalog tables using
provided catalog tables using
<programlisting>
<programlisting>
ALTER TABLE user_catalog_table SET (user_catalog_table = true);
ALTER TABLE user_catalog_table SET (user_catalog_table = true);
CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
</programlisting>
</programlisting>
Any actions leading to xid assignment are prohibited. That, among others,
Any actions leading to xid assignment are prohibited. That, among others,
includes writing to tables, performing DDL changes and
includes writing to tables, performing DDL changes and
calling <literal>txid_current()</literal>.
calling <literal>txid_current()</literal>.
...
@@ -385,23 +386,23 @@ CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
...
@@ -385,23 +386,23 @@ CREATE TABLE another_catalog_table(data text) WITH (user_catalog_table = true);
The optional <function>startup_cb</function> callback is called whenever
The optional <function>startup_cb</function> callback is called whenever
a replication slot is created or asked to stream changes, independent
a replication slot is created or asked to stream changes, independent
of the number of changes that are ready to be put out.
of the number of changes that are ready to be put out.
<programlisting>
<programlisting>
typedef void (*LogicalDecodeStartupCB) (
typedef void (*LogicalDecodeStartupCB) (
struct LogicalDecodingContext *ctx,
struct LogicalDecodingContext *ctx,
OutputPluginOptions *options,
OutputPluginOptions *options,
bool is_init
bool is_init
);
);
</programlisting>
</programlisting>
The <literal>is_init</literal> parameter will be true when the
The <literal>is_init</literal> parameter will be true when the
replication slot is being created and false
replication slot is being created and false
otherwise. <parameter>options</parameter> points to a struct of options
otherwise. <parameter>options</parameter> points to a struct of options
that output plugins can set:
that output plugins can set:
<programlisting>
<programlisting>
typedef struct OutputPluginOptions
typedef struct OutputPluginOptions
{
{
OutputPluginOutputType output_type;
OutputPluginOutputType output_type;
} OutputPluginOptions;
} OutputPluginOptions;
</programlisting>
</programlisting>
<literal>output_type</literal> has to either be set to
<literal>output_type</literal> has to either be set to
<literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</literal>
<literal>OUTPUT_PLUGIN_TEXTUAL_OUTPUT</literal>
or <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal>.
or <literal>OUTPUT_PLUGIN_BINARY_OUTPUT</literal>.
...
@@ -420,11 +421,11 @@ typedef struct OutputPluginOptions
...
@@ -420,11 +421,11 @@ typedef struct OutputPluginOptions
whenever a formerly active replication slot is not used anymore and can
whenever a formerly active replication slot is not used anymore and can
be used to deallocate resources private to the output plugin. The slot
be used to deallocate resources private to the output plugin. The slot
isn't necessarily being dropped, streaming is just being stopped.
isn't necessarily being dropped, streaming is just being stopped.
<programlisting>
<programlisting>
typedef void (*LogicalDecodeShutdownCB) (
typedef void (*LogicalDecodeShutdownCB) (
struct LogicalDecodingContext *ctx
struct LogicalDecodingContext *ctx
);
);
</programlisting>
</programlisting>
</para>
</para>
</sect3>
</sect3>
<sect3 id="logicaldecoding-output-plugin-begin">
<sect3 id="logicaldecoding-output-plugin-begin">
...
@@ -433,12 +434,12 @@ typedef void (*LogicalDecodeShutdownCB) (
...
@@ -433,12 +434,12 @@ typedef void (*LogicalDecodeShutdownCB) (
The required <function>begin_cb</function> callback is called whenever a
The required <function>begin_cb</function> callback is called whenever a
start of a commited transaction has been decoded. Aborted transactions
start of a commited transaction has been decoded. Aborted transactions
and their contents never get decoded.
and their contents never get decoded.
<programlisting>
<programlisting>
typedef void (*LogicalDecodeBeginCB) (
typedef void (*LogicalDecodeBeginCB) (
struct LogicalDecodingContext *,
struct LogicalDecodingContext *,
ReorderBufferTXN *txn
ReorderBufferTXN *txn
);
);
</programlisting>
</programlisting>
The <parameter>txn</parameter> parameter contains meta information about
The <parameter>txn</parameter> parameter contains meta information about
the transaction, like the timestamp at which it has been committed and
the transaction, like the timestamp at which it has been committed and
its XID.
its XID.
...
@@ -452,12 +453,12 @@ typedef void (*LogicalDecodeBeginCB) (
...
@@ -452,12 +453,12 @@ typedef void (*LogicalDecodeBeginCB) (
decoded. The <function>change_cb</function> callbacks for all modified
decoded. The <function>change_cb</function> callbacks for all modified
rows will have been called before this, if there have been any modified
rows will have been called before this, if there have been any modified
rows.
rows.
<programlisting>
<programlisting>
typedef void (*LogicalDecodeCommitCB) (
typedef void (*LogicalDecodeCommitCB) (
struct LogicalDecodingContext *,
struct LogicalDecodingContext *,
ReorderBufferTXN *txn
ReorderBufferTXN *txn
);
);
</programlisting>
</programlisting>
</para>
</para>
</sect3>
</sect3>
<sect3 id="logicaldecoding-output-plugin-change">
<sect3 id="logicaldecoding-output-plugin-change">
...
@@ -470,14 +471,14 @@ typedef void (*LogicalDecodeCommitCB) (
...
@@ -470,14 +471,14 @@ typedef void (*LogicalDecodeCommitCB) (
or <command>DELETE</command>. Even if the original command modified
or <command>DELETE</command>. Even if the original command modified
several rows at once the callback will be called indvidually for each
several rows at once the callback will be called indvidually for each
row.
row.
<programlisting>
<programlisting>
typedef void (*LogicalDecodeChangeCB) (
typedef void (*LogicalDecodeChangeCB) (
struct LogicalDecodingContext *ctx,
struct LogicalDecodingContext *ctx,
ReorderBufferTXN *txn,
ReorderBufferTXN *txn,
Relation relation,
Relation relation,
ReorderBufferChange *change
ReorderBufferChange *change
);
);
</programlisting>
</programlisting>
The <parameter>ctx</parameter> and <parameter>txn</parameter> parameters
The <parameter>ctx</parameter> and <parameter>txn</parameter> parameters
have the same contents as for the <function>begin_cb</function>
have the same contents as for the <function>begin_cb</function>
and <function>commit_cb</function> callbacks, but additionally the
and <function>commit_cb</function> callbacks, but additionally the
...
@@ -513,11 +514,11 @@ typedef void (*LogicalDecodeChangeCB) (
...
@@ -513,11 +514,11 @@ typedef void (*LogicalDecodeChangeCB) (
<para>
<para>
The following example shows how to output data to the consumer of an
The following example shows how to output data to the consumer of an
output plugin:
output plugin:
<programlisting>
<programlisting>
OutputPluginPrepareWrite(ctx, true);
OutputPluginPrepareWrite(ctx, true);
appendStringInfo(ctx->out, "BEGIN %u", txn->xid);
appendStringInfo(ctx->out, "BEGIN %u", txn->xid);
OutputPluginWrite(ctx, true);
OutputPluginWrite(ctx, true);
</programlisting>
</programlisting>
</para>
</para>
</sect2>
</sect2>
</sect1>
</sect1>
...
...
doc/src/sgml/protocol.sgml
View file @
53166fe2
...
@@ -1315,9 +1315,9 @@ the connection to be used for logical replication from that database.
...
@@ -1315,9 +1315,9 @@ the connection to be used for logical replication from that database.
connection via <application>psql</application> or any other <literal>libpq</literal>-using
connection via <application>psql</application> or any other <literal>libpq</literal>-using
tool with a connection string including the <literal>replication</literal> option,
tool with a connection string including the <literal>replication</literal> option,
e.g.:
e.g.:
<programlisting>
<programlisting>
psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
</programlisting>
</programlisting>
However it is often more useful to use
However it is often more useful to use
<application>pg_receivexlog</application> (for physical replication) or
<application>pg_receivexlog</application> (for physical replication) or
<application>pg_recvlogical</application> (for logical replication).
<application>pg_recvlogical</application> (for logical replication).
...
...
doc/src/sgml/test-decoding.sgml
View file @
53166fe2
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
Typical output from this plugin, used over the SQL logical decoding
Typical output from this plugin, used over the SQL logical decoding
interface, might be:
interface, might be:
<programlisting>
<programlisting>
postgres=# SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'include-xids', '0');
postgres=# SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'include-xids', '0');
location | xid | data
location | xid | data
-----------+-----+--------------------------------------------------
-----------+-----+--------------------------------------------------
...
@@ -36,7 +36,7 @@ postgres=# SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'i
...
@@ -36,7 +36,7 @@ postgres=# SELECT * FROM pg_logical_slot_get_changes('test_slot', NULL, NULL, 'i
0/16D3398 | 692 | table public.data: DELETE: id[int4]:3
0/16D3398 | 692 | table public.data: DELETE: id[int4]:3
0/16D3398 | 692 | COMMIT
0/16D3398 | 692 | COMMIT
(8 rows)
(8 rows)
</programlisting>
</programlisting>
</para>
</para>
</sect1>
</sect1>
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