Fix interaction of TOAST compression with expression indexes.
Before, trying to compress a value for insertion into an expression index would crash. Dilip Kumar, with some editing by me. Report by Jaime Casanova. Discussion: http://postgr.es/m/CAJKUy5gcs0zGOp6JXU2mMVdthYhuQpFk=S3V8DOKT=LZC1L36Q@mail.gmail.com
This commit is contained in:
parent
71f4c8c6f7
commit
5db1fd7823
@ -220,10 +220,12 @@ brin_form_tuple(BrinDesc *brdesc, BlockNumber blkno, BrinMemTuple *tuple,
|
||||
|
||||
/*
|
||||
* If the BRIN summary and indexed attribute use the same data
|
||||
* type, we can use the same compression method. Otherwise we
|
||||
* have to use the default method.
|
||||
* type and it has a valid compression method, we can use the
|
||||
* same compression method. Otherwise we have to use the
|
||||
* default method.
|
||||
*/
|
||||
if (att->atttypid == atttype->type_id)
|
||||
if (att->atttypid == atttype->type_id &&
|
||||
CompressionMethodIsValid(att->attcompression))
|
||||
compression = att->attcompression;
|
||||
else
|
||||
compression = GetDefaultToastCompression();
|
||||
|
@ -103,8 +103,19 @@ index_form_tuple(TupleDesc tupleDescriptor,
|
||||
(att->attstorage == TYPSTORAGE_EXTENDED ||
|
||||
att->attstorage == TYPSTORAGE_MAIN))
|
||||
{
|
||||
Datum cvalue = toast_compress_datum(untoasted_values[i],
|
||||
att->attcompression);
|
||||
Datum cvalue;
|
||||
char compression = att->attcompression;
|
||||
|
||||
/*
|
||||
* If the compression method is not valid, use the default. We
|
||||
* don't expect this to happen for regular index columns, which
|
||||
* inherit the setting from the corresponding table column, but
|
||||
* we do expect it to happen whenever an expression is indexed.
|
||||
*/
|
||||
if (!CompressionMethodIsValid(compression))
|
||||
compression = GetDefaultToastCompression();
|
||||
|
||||
cvalue = toast_compress_datum(untoasted_values[i], compression);
|
||||
|
||||
if (DatumGetPointer(cvalue) != NULL)
|
||||
{
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include "access/relscan.h"
|
||||
#include "access/sysattr.h"
|
||||
#include "access/tableam.h"
|
||||
#include "access/toast_compression.h"
|
||||
#include "access/transam.h"
|
||||
#include "access/visibilitymap.h"
|
||||
#include "access/xact.h"
|
||||
@ -379,6 +380,15 @@ ConstructTupleDescriptor(Relation heapRelation,
|
||||
to->attalign = typeTup->typalign;
|
||||
to->atttypmod = exprTypmod(indexkey);
|
||||
|
||||
/*
|
||||
* For expression columns, set attcompression invalid, since
|
||||
* there's no table column from which to copy the value. Whenever
|
||||
* we actually need to compress a value, we'll use whatever the
|
||||
* current value of default_compression_method is at that point
|
||||
* in time.
|
||||
*/
|
||||
to->attcompression = InvalidCompressionMethod;
|
||||
|
||||
ReleaseSysCache(tuple);
|
||||
|
||||
/*
|
||||
|
@ -313,6 +313,12 @@ SELECT pg_column_compression(f1) FROM cmdata;
|
||||
lz4
|
||||
(2 rows)
|
||||
|
||||
-- test expression index
|
||||
DROP TABLE cmdata2;
|
||||
CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4);
|
||||
CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2));
|
||||
INSERT INTO cmdata2 VALUES((SELECT array_agg(md5(g::TEXT))::TEXT FROM
|
||||
generate_series(1, 50) g), VERSION());
|
||||
-- check data is ok
|
||||
SELECT length(f1) FROM cmdata;
|
||||
length
|
||||
|
@ -309,6 +309,19 @@ SELECT pg_column_compression(f1) FROM cmdata;
|
||||
pglz
|
||||
(2 rows)
|
||||
|
||||
-- test expression index
|
||||
DROP TABLE cmdata2;
|
||||
CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4);
|
||||
ERROR: unsupported LZ4 compression method
|
||||
DETAIL: This functionality requires the server to be built with lz4 support.
|
||||
HINT: You need to rebuild PostgreSQL using --with-lz4.
|
||||
CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2));
|
||||
ERROR: relation "cmdata2" does not exist
|
||||
INSERT INTO cmdata2 VALUES((SELECT array_agg(md5(g::TEXT))::TEXT FROM
|
||||
generate_series(1, 50) g), VERSION());
|
||||
ERROR: relation "cmdata2" does not exist
|
||||
LINE 1: INSERT INTO cmdata2 VALUES((SELECT array_agg(md5(g::TEXT))::...
|
||||
^
|
||||
-- check data is ok
|
||||
SELECT length(f1) FROM cmdata;
|
||||
length
|
||||
|
@ -130,6 +130,13 @@ SELECT pg_column_compression(f1) FROM cmdata;
|
||||
VACUUM FULL cmdata;
|
||||
SELECT pg_column_compression(f1) FROM cmdata;
|
||||
|
||||
-- test expression index
|
||||
DROP TABLE cmdata2;
|
||||
CREATE TABLE cmdata2 (f1 TEXT COMPRESSION pglz, f2 TEXT COMPRESSION lz4);
|
||||
CREATE UNIQUE INDEX idx1 ON cmdata2 ((f1 || f2));
|
||||
INSERT INTO cmdata2 VALUES((SELECT array_agg(md5(g::TEXT))::TEXT FROM
|
||||
generate_series(1, 50) g), VERSION());
|
||||
|
||||
-- check data is ok
|
||||
SELECT length(f1) FROM cmdata;
|
||||
SELECT length(f1) FROM cmdata1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user