/*
* 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();
(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)
{
#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"
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);
/*
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
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
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;