mirror of https://github.com/postgres/postgres
This is advance preparation for introducing even more test modules; the easy solution is to add them to contrib, but that's bloated enough that it seems a good time to think of something different. Moved modules are dummy_seclabel, test_shm_mq, test_parser and worker_spi. (test_decoding was also a candidate, but there was too much opposition to moving that one. We can always reconsider later.)pull/14/head
parent
5b12987b2e
commit
22dfd116a1
@ -1,74 +0,0 @@ |
|||||||
<!-- doc/src/sgml/dummy-seclabel.sgml --> |
|
||||||
|
|
||||||
<sect1 id="dummy-seclabel" xreflabel="dummy_seclabel"> |
|
||||||
<title>dummy_seclabel</title> |
|
||||||
|
|
||||||
<indexterm zone="dummy-seclabel"> |
|
||||||
<primary>dummy_seclabel</primary> |
|
||||||
</indexterm> |
|
||||||
|
|
||||||
<para> |
|
||||||
The <filename>dummy_seclabel</> module exists only to support regression |
|
||||||
testing of the <command>SECURITY LABEL</> statement. It is not intended |
|
||||||
to be used in production. |
|
||||||
</para> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Rationale</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
The <command>SECURITY LABEL</> statement allows the user to assign security |
|
||||||
labels to database objects; however, security labels can only be assigned |
|
||||||
when specifically allowed by a loadable module, so this module is provided |
|
||||||
to allow proper regression testing. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
Security label providers intended to be used in production will typically be |
|
||||||
dependent on a platform-specific feature such as |
|
||||||
<productname>SE-Linux</productname>. This module is platform-independent, |
|
||||||
and therefore better-suited to regression testing. |
|
||||||
</para> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Usage</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Here's a simple example of usage: |
|
||||||
</para> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
# postgresql.conf |
|
||||||
shared_preload_libraries = 'dummy_seclabel' |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
postgres=# CREATE TABLE t (a int, b text); |
|
||||||
CREATE TABLE |
|
||||||
postgres=# SECURITY LABEL ON TABLE t IS 'classified'; |
|
||||||
SECURITY LABEL |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
<para> |
|
||||||
The <filename>dummy_seclabel</> module provides only four hardcoded |
|
||||||
labels: <literal>unclassified</>, <literal>classified</>, |
|
||||||
<literal>secret</>, and <literal>top secret</>. |
|
||||||
It does not allow any other strings as security labels. |
|
||||||
</para> |
|
||||||
<para> |
|
||||||
These labels are not used to enforce access controls. They are only used |
|
||||||
to check whether the <command>SECURITY LABEL</> statement works as expected, |
|
||||||
or not. |
|
||||||
</para> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Author</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
KaiGai Kohei <email>kaigai@ak.jp.nec.com</email> |
|
||||||
</para> |
|
||||||
</sect2> |
|
||||||
|
|
||||||
</sect1> |
|
||||||
@ -1,90 +0,0 @@ |
|||||||
<!-- doc/src/sgml/test-parser.sgml --> |
|
||||||
|
|
||||||
<sect1 id="test-parser" xreflabel="test_parser"> |
|
||||||
<title>test_parser</title> |
|
||||||
|
|
||||||
<indexterm zone="test-parser"> |
|
||||||
<primary>test_parser</primary> |
|
||||||
</indexterm> |
|
||||||
|
|
||||||
<para> |
|
||||||
<filename>test_parser</> is an example of a custom parser for full-text |
|
||||||
search. It doesn't do anything especially useful, but can serve as |
|
||||||
a starting point for developing your own parser. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
<filename>test_parser</> recognizes words separated by white space, |
|
||||||
and returns just two token types: |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
mydb=# SELECT * FROM ts_token_type('testparser'); |
|
||||||
tokid | alias | description |
|
||||||
-------+-------+--------------- |
|
||||||
3 | word | Word |
|
||||||
12 | blank | Space symbols |
|
||||||
(2 rows) |
|
||||||
</programlisting> |
|
||||||
|
|
||||||
These token numbers have been chosen to be compatible with the default |
|
||||||
parser's numbering. This allows us to use its <function>headline()</> |
|
||||||
function, thus keeping the example simple. |
|
||||||
</para> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Usage</title> |
|
||||||
|
|
||||||
<para> |
|
||||||
Installing the <literal>test_parser</> extension creates a text search |
|
||||||
parser <literal>testparser</>. It has no user-configurable parameters. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
You can test the parser with, for example, |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
mydb=# SELECT * FROM ts_parse('testparser', 'That''s my first own parser'); |
|
||||||
tokid | token |
|
||||||
-------+-------- |
|
||||||
3 | That's |
|
||||||
12 | |
|
||||||
3 | my |
|
||||||
12 | |
|
||||||
3 | first |
|
||||||
12 | |
|
||||||
3 | own |
|
||||||
12 | |
|
||||||
3 | parser |
|
||||||
</programlisting> |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
Real-world use requires setting up a text search configuration |
|
||||||
that uses the parser. For example, |
|
||||||
|
|
||||||
<programlisting> |
|
||||||
mydb=# CREATE TEXT SEARCH CONFIGURATION testcfg ( PARSER = testparser ); |
|
||||||
CREATE TEXT SEARCH CONFIGURATION |
|
||||||
|
|
||||||
mydb=# ALTER TEXT SEARCH CONFIGURATION testcfg |
|
||||||
mydb-# ADD MAPPING FOR word WITH english_stem; |
|
||||||
ALTER TEXT SEARCH CONFIGURATION |
|
||||||
|
|
||||||
mydb=# SELECT to_tsvector('testcfg', 'That''s my first own parser'); |
|
||||||
to_tsvector |
|
||||||
------------------------------- |
|
||||||
'that':1 'first':3 'parser':5 |
|
||||||
(1 row) |
|
||||||
|
|
||||||
mydb=# SELECT ts_headline('testcfg', 'Supernovae stars are the brightest phenomena in galaxies', |
|
||||||
mydb(# to_tsquery('testcfg', 'star')); |
|
||||||
ts_headline |
|
||||||
----------------------------------------------------------------- |
|
||||||
Supernovae <b>stars</b> are the brightest phenomena in galaxies |
|
||||||
(1 row) |
|
||||||
</programlisting> |
|
||||||
</para> |
|
||||||
|
|
||||||
</sect2> |
|
||||||
|
|
||||||
</sect1> |
|
||||||
@ -1,71 +0,0 @@ |
|||||||
<!-- doc/src/sgml/test-shm-mq.sgml --> |
|
||||||
|
|
||||||
<sect1 id="test-shm-mq" xreflabel="test_shm_mq"> |
|
||||||
<title>test_shm_mq</title> |
|
||||||
|
|
||||||
<indexterm zone="test-shm-mq"> |
|
||||||
<primary>test_shm_mq</primary> |
|
||||||
</indexterm> |
|
||||||
|
|
||||||
<para> |
|
||||||
<filename>test_shm_mq</> is an example of how to use dynamic shared memory |
|
||||||
and the shared memory message queue facilities to coordinate a user backend |
|
||||||
with the efforts of one or more background workers. It is not intended to |
|
||||||
do anything useful on its own; rather, it is a demonstration of how these |
|
||||||
facilities can be used, and a unit test of those facilities. |
|
||||||
</para> |
|
||||||
|
|
||||||
<para> |
|
||||||
The function is this extension send the same message repeatedly through |
|
||||||
a loop of processes. The message payload, the size of the message queue |
|
||||||
through which it is sent, and the number of processes in the loop are |
|
||||||
configurable. At the end, the message may be verified to ensure that it |
|
||||||
has not been corrupted in transmission. |
|
||||||
</para> |
|
||||||
|
|
||||||
<sect2> |
|
||||||
<title>Functions</title> |
|
||||||
|
|
||||||
<synopsis> |
|
||||||
test_shm_mq(queue_size int8, message text, |
|
||||||
repeat_count int4 default 1, num_workers int4 default 1) |
|
||||||
RETURNS void |
|
||||||
</synopsis> |
|
||||||
|
|
||||||
<para> |
|
||||||
This function sends and receives messages synchronously. The user |
|
||||||
backend sends the provided message to the first background worker using |
|
||||||
a message queue of the given size. The first background worker sends |
|
||||||
the message to the second background worker, if the number of workers |
|
||||||
is greater than one, and so forth. Eventually, the last background |
|
||||||
worker sends the message back to the user backend. If the repeat count |
|
||||||
is greater than one, the user backend then sends the message back to |
|
||||||
the first worker. Once the message has been sent and received by all |
|
||||||
the coordinating processes a number of times equal to the repeat count, |
|
||||||
the user backend verifies that the message finally received matches the |
|
||||||
one originally sent and throws an error if not. |
|
||||||
</para> |
|
||||||
|
|
||||||
<synopsis> |
|
||||||
test_shm_mq_pipelined(queue_size int8, message text, |
|
||||||
repeat_count int4 default 1, num_workers int4 default 1, |
|
||||||
verify bool default true) |
|
||||||
RETURNS void |
|
||||||
</synopsis> |
|
||||||
|
|
||||||
<para> |
|
||||||
This function sends the same message multiple times, as specified by the |
|
||||||
repeat count, to the first background worker using a queue of the given |
|
||||||
size. These messages are then forwarded to each background worker in |
|
||||||
turn, in each case using a queue of the given size. Finally, the last |
|
||||||
background worker sends the messages back to the user backend. The user |
|
||||||
backend uses non-blocking sends and receives, so that it may begin receiving |
|
||||||
copies of the message before it has finished sending all copies of the |
|
||||||
message. The <literal>verify</> argument controls whether or not the |
|
||||||
received copies are checked against the message that was sent. (This |
|
||||||
takes nontrivial time so it may be useful to disable it for benchmarking |
|
||||||
purposes.) |
|
||||||
</para> |
|
||||||
|
|
||||||
</sect2> |
|
||||||
</sect1> |
|
||||||
@ -0,0 +1,13 @@ |
|||||||
|
# src/test/modules/Makefile
|
||||||
|
|
||||||
|
subdir = src/test/modules
|
||||||
|
top_builddir = ../../..
|
||||||
|
include $(top_builddir)/src/Makefile.global |
||||||
|
|
||||||
|
SUBDIRS = \
|
||||||
|
worker_spi \
|
||||||
|
dummy_seclabel \
|
||||||
|
test_shm_mq \
|
||||||
|
test_parser
|
||||||
|
|
||||||
|
$(recurse) |
||||||
@ -0,0 +1,43 @@ |
|||||||
|
The dummy_seclabel module exists only to support regression |
||||||
|
testing of the SECURITY LABEL statement. It is not intended |
||||||
|
to be used in production. |
||||||
|
|
||||||
|
Rationale |
||||||
|
========= |
||||||
|
|
||||||
|
The SECURITY LABEL statement allows the user to assign security |
||||||
|
labels to database objects; however, security labels can only be assigned |
||||||
|
when specifically allowed by a loadable module, so this module is provided |
||||||
|
to allow proper regression testing. |
||||||
|
|
||||||
|
Security label providers intended to be used in production will typically be |
||||||
|
dependent on a platform-specific feature such as |
||||||
|
SE-Linux. This module is platform-independent, |
||||||
|
and therefore better-suited to regression testing. |
||||||
|
|
||||||
|
Usage |
||||||
|
===== |
||||||
|
|
||||||
|
Here's a simple example of usage: |
||||||
|
|
||||||
|
# postgresql.conf |
||||||
|
shared_preload_libraries = 'dummy_seclabel' |
||||||
|
|
||||||
|
postgres=# CREATE TABLE t (a int, b text); |
||||||
|
CREATE TABLE |
||||||
|
postgres=# SECURITY LABEL ON TABLE t IS 'classified'; |
||||||
|
SECURITY LABEL |
||||||
|
|
||||||
|
The dummy_seclabel module provides only four hardcoded |
||||||
|
labels: unclassified, classified, |
||||||
|
secret, and top secret. |
||||||
|
It does not allow any other strings as security labels. |
||||||
|
|
||||||
|
These labels are not used to enforce access controls. They are only used |
||||||
|
to check whether the SECURITY LABEL statement works as expected, |
||||||
|
or not. |
||||||
|
|
||||||
|
Author |
||||||
|
====== |
||||||
|
|
||||||
|
KaiGai Kohei <kaigai@ak.jp.nec.com> |
||||||
@ -0,0 +1,61 @@ |
|||||||
|
test_parser is an example of a custom parser for full-text |
||||||
|
search. It doesn't do anything especially useful, but can serve as |
||||||
|
a starting point for developing your own parser. |
||||||
|
|
||||||
|
test_parser recognizes words separated by white space, |
||||||
|
and returns just two token types: |
||||||
|
|
||||||
|
mydb=# SELECT * FROM ts_token_type('testparser'); |
||||||
|
tokid | alias | description |
||||||
|
-------+-------+--------------- |
||||||
|
3 | word | Word |
||||||
|
12 | blank | Space symbols |
||||||
|
(2 rows) |
||||||
|
|
||||||
|
These token numbers have been chosen to be compatible with the default |
||||||
|
parser's numbering. This allows us to use its headline() |
||||||
|
function, thus keeping the example simple. |
||||||
|
|
||||||
|
Usage |
||||||
|
===== |
||||||
|
|
||||||
|
Installing the test_parser extension creates a text search |
||||||
|
parser testparser. It has no user-configurable parameters. |
||||||
|
|
||||||
|
You can test the parser with, for example, |
||||||
|
|
||||||
|
mydb=# SELECT * FROM ts_parse('testparser', 'That''s my first own parser'); |
||||||
|
tokid | token |
||||||
|
-------+-------- |
||||||
|
3 | That's |
||||||
|
12 | |
||||||
|
3 | my |
||||||
|
12 | |
||||||
|
3 | first |
||||||
|
12 | |
||||||
|
3 | own |
||||||
|
12 | |
||||||
|
3 | parser |
||||||
|
|
||||||
|
Real-world use requires setting up a text search configuration |
||||||
|
that uses the parser. For example, |
||||||
|
|
||||||
|
mydb=# CREATE TEXT SEARCH CONFIGURATION testcfg ( PARSER = testparser ); |
||||||
|
CREATE TEXT SEARCH CONFIGURATION |
||||||
|
|
||||||
|
mydb=# ALTER TEXT SEARCH CONFIGURATION testcfg |
||||||
|
mydb-# ADD MAPPING FOR word WITH english_stem; |
||||||
|
ALTER TEXT SEARCH CONFIGURATION |
||||||
|
|
||||||
|
mydb=# SELECT to_tsvector('testcfg', 'That''s my first own parser'); |
||||||
|
to_tsvector |
||||||
|
------------------------------- |
||||||
|
'that':1 'first':3 'parser':5 |
||||||
|
(1 row) |
||||||
|
|
||||||
|
mydb=# SELECT ts_headline('testcfg', 'Supernovae stars are the brightest phenomena in galaxies', |
||||||
|
mydb(# to_tsquery('testcfg', 'star')); |
||||||
|
ts_headline |
||||||
|
----------------------------------------------------------------- |
||||||
|
Supernovae <b>stars</b> are the brightest phenomena in galaxies |
||||||
|
(1 row) |
||||||
@ -1,4 +1,4 @@ |
|||||||
/* contrib/test_parser/test_parser--1.0.sql */ |
/* src/test/modules/test_parser/test_parser--1.0.sql */ |
||||||
|
|
||||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
||||||
\echo Use "CREATE EXTENSION test_parser" to load this file. \quit |
\echo Use "CREATE EXTENSION test_parser" to load this file. \quit |
||||||
@ -1,4 +1,4 @@ |
|||||||
/* contrib/test_parser/test_parser--unpackaged--1.0.sql */ |
/* src/test/modules/test_parser/test_parser--unpackaged--1.0.sql */ |
||||||
|
|
||||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
||||||
\echo Use "CREATE EXTENSION test_parser FROM unpackaged" to load this file. \quit |
\echo Use "CREATE EXTENSION test_parser FROM unpackaged" to load this file. \quit |
||||||
@ -0,0 +1,49 @@ |
|||||||
|
test_shm_mq is an example of how to use dynamic shared memory |
||||||
|
and the shared memory message queue facilities to coordinate a user backend |
||||||
|
with the efforts of one or more background workers. It is not intended to |
||||||
|
do anything useful on its own; rather, it is a demonstration of how these |
||||||
|
facilities can be used, and a unit test of those facilities. |
||||||
|
|
||||||
|
The function is this extension send the same message repeatedly through |
||||||
|
a loop of processes. The message payload, the size of the message queue |
||||||
|
through which it is sent, and the number of processes in the loop are |
||||||
|
configurable. At the end, the message may be verified to ensure that it |
||||||
|
has not been corrupted in transmission. |
||||||
|
|
||||||
|
Functions |
||||||
|
========= |
||||||
|
|
||||||
|
|
||||||
|
test_shm_mq(queue_size int8, message text, |
||||||
|
repeat_count int4 default 1, num_workers int4 default 1) |
||||||
|
RETURNS void |
||||||
|
|
||||||
|
This function sends and receives messages synchronously. The user |
||||||
|
backend sends the provided message to the first background worker using |
||||||
|
a message queue of the given size. The first background worker sends |
||||||
|
the message to the second background worker, if the number of workers |
||||||
|
is greater than one, and so forth. Eventually, the last background |
||||||
|
worker sends the message back to the user backend. If the repeat count |
||||||
|
is greater than one, the user backend then sends the message back to |
||||||
|
the first worker. Once the message has been sent and received by all |
||||||
|
the coordinating processes a number of times equal to the repeat count, |
||||||
|
the user backend verifies that the message finally received matches the |
||||||
|
one originally sent and throws an error if not. |
||||||
|
|
||||||
|
|
||||||
|
test_shm_mq_pipelined(queue_size int8, message text, |
||||||
|
repeat_count int4 default 1, num_workers int4 default 1, |
||||||
|
verify bool default true) |
||||||
|
RETURNS void |
||||||
|
|
||||||
|
This function sends the same message multiple times, as specified by the |
||||||
|
repeat count, to the first background worker using a queue of the given |
||||||
|
size. These messages are then forwarded to each background worker in |
||||||
|
turn, in each case using a queue of the given size. Finally, the last |
||||||
|
background worker sends the messages back to the user backend. The user |
||||||
|
backend uses non-blocking sends and receives, so that it may begin receiving |
||||||
|
copies of the message before it has finished sending all copies of the |
||||||
|
message. The 'verify' argument controls whether or not the |
||||||
|
received copies are checked against the message that was sent. (This |
||||||
|
takes nontrivial time so it may be useful to disable it for benchmarking |
||||||
|
purposes.) |
||||||
@ -1,4 +1,4 @@ |
|||||||
/* contrib/test_shm_mq/test_shm_mq--1.0.sql */ |
/* src/test/modules/test_shm_mq/test_shm_mq--1.0.sql */ |
||||||
|
|
||||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
||||||
\echo Use "CREATE EXTENSION test_shm_mq" to load this file. \quit |
\echo Use "CREATE EXTENSION test_shm_mq" to load this file. \quit |
||||||
@ -1,4 +1,4 @@ |
|||||||
/* contrib/worker_spi/worker_spi--1.0.sql */ |
/* src/test/modules/worker_spi/worker_spi--1.0.sql */ |
||||||
|
|
||||||
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
-- complain if script is sourced in psql, rather than via CREATE EXTENSION |
||||||
\echo Use "CREATE EXTENSION worker_spi" to load this file. \quit |
\echo Use "CREATE EXTENSION worker_spi" to load this file. \quit |
||||||
Loading…
Reference in new issue