-- This file and its contents are licensed under the Timescale License.
-- Please see the included NOTICE for copyright information and
-- LICENSE-TIMESCALE for a copy of the license.

\set ECHO errors

DROP TABLE IF EXISTS compressed;
CREATE TABLE compressed AS SELECT :COMPRESSION_CMD AS c FROM (:QUERY) AS sub;
SELECT (_timescaledb_functions.compressed_data_info(c)).*,
       pg_column_size(c) as "compressed size"
  FROM compressed;

--rewrite table (needed to make sure the compressed data does not reference toast table of original)
CREATE TABLE temp AS SELECT * FROM :TABLE_NAME;
DROP TABLE :TABLE_NAME;
ALTER TABLE temp RENAME TO :TABLE_NAME;

--test that decompression gives same result in forward direction
with original AS (
  SELECT row_number() OVER() row_number, * FROM (:QUERY) as q
),
decompressed AS (
  SELECT row_number() OVER () row_number, * FROM (SELECT :DECOMPRESS_FORWARD_CMD FROM compressed) as q
)
SELECT 'Number of rows different between original and decompressed forward (expect 0)', count(*)
FROM original
FULL OUTER JOIN decompressed ON (original.row_number = decompressed.row_number)
WHERE (original.*) IS DISTINCT FROM (decompressed.*);

--test the decompress reverse direction too
with count_orig AS (
  SELECT count(*) as cnt FROM (:QUERY) as q
),
original AS (
  SELECT count_orig.cnt + 1 - row_number() OVER() row_number, q.* FROM (:QUERY) as q, count_orig
),
decompressed AS (
  SELECT row_number() OVER () row_number, * FROM (SELECT :DECOMPRESS_REVERSE_CMD FROM compressed) as q
)
SELECT 'Number of rows different between original and decompressed reversed (expect 0)', count(*)
FROM original
FULL OUTER JOIN decompressed ON (original.row_number = decompressed.row_number)
WHERE (original.*) IS DISTINCT FROM (decompressed.*);

--test that decompression gives same result with compressed_data_to_array
with original AS (
  SELECT row_number() OVER() row_number, * FROM (:QUERY) as q
),
decompressed AS (
  SELECT row_number() OVER () row_number, * FROM (SELECT unnest(_timescaledb_functions.compressed_data_to_array(c, cast(NULL as :TYPE))) FROM compressed ) as q
)
SELECT 'Number of rows different between original and compressed_data_to_array (expect 0)', count(*), :'TYPE' AS type
FROM original
FULL OUTER JOIN decompressed ON (original.row_number = decompressed.row_number)
WHERE (original.*) IS DISTINCT FROM (decompressed.*);

SELECT :'TYPE' AS type, _timescaledb_functions.compressed_data_column_size(c, cast(NULL as :TYPE)) AS "column size" FROM compressed;

--Test IO
SELECT c "COMPRESSED_AS_TEXT" FROM compressed \gset

WITH original AS
(
  SELECT row_number() OVER() row_number, * FROM (:QUERY) as q
),
decompressed AS
(
  SELECT row_number() OVER () row_number, * FROM (SELECT :DECOMPRESS_FORWARD_CMD FROM compressed) as q
),
decompressed_from_text AS (
  SELECT row_number() OVER () row_number, * FROM (SELECT :DECOMPRESS_FORWARD_CMD FROM (SELECT :'COMPRESSED_AS_TEXT'::text as c) as txt) as q
)
SELECT 'Number of rows different between original, decompressed, and decompressed deserializeed (expect 0)', count(*)
FROM original
FULL OUTER JOIN decompressed ON (original.row_number = decompressed.row_number)
FULL OUTER JOIN decompressed_from_text ON (original.row_number = decompressed_from_text.row_number)
WHERE (original.*) IS DISTINCT FROM (decompressed_from_text.*) OR (decompressed.*) IS DISTINCT FROM (decompressed_from_text.*) ;

SELECT
  'Test that deserialization, decompression, recompression, and serialization results in the same text',
  :COMPRESSION_CMD::text IS NOT DISTINCT FROM :'COMPRESSED_AS_TEXT'
FROM
(SELECT :DECOMPRESS_FORWARD_CMD as item FROM (SELECT :'COMPRESSED_AS_TEXT'::text as c) as txt) as decompressed_serialized;

\set ECHO all
