mirror of https://github.com/citusdata/citus.git
commit
29d340331e
|
@ -21,6 +21,7 @@
|
|||
#include "access/nbtree.h"
|
||||
#include "catalog/pg_am.h"
|
||||
#include "commands/defrem.h"
|
||||
#include "distributed/listutils.h"
|
||||
#include "nodes/makefuncs.h"
|
||||
#if PG_VERSION_NUM >= 120000
|
||||
#include "nodes/nodeFuncs.h"
|
||||
|
@ -46,6 +47,13 @@ struct TableReadState
|
|||
TupleDesc tupleDescriptor;
|
||||
Relation relation;
|
||||
|
||||
/*
|
||||
* Following are used for tables with zero columns, or when no
|
||||
* columns are projected.
|
||||
*/
|
||||
uint64 totalRowCount;
|
||||
uint64 readRowCount;
|
||||
|
||||
/*
|
||||
* List of Var pointers for columns in the query. We use this both for
|
||||
* getting vector of projected columns, and also when we want to build
|
||||
|
@ -112,6 +120,13 @@ ColumnarBeginRead(Relation relation, TupleDesc tupleDescriptor,
|
|||
List *projectedColumnList, List *whereClauseList)
|
||||
{
|
||||
List *stripeList = StripesForRelfilenode(relation->rd_node);
|
||||
StripeMetadata *stripeMetadata = NULL;
|
||||
|
||||
uint64 totalRowCount = 0;
|
||||
foreach_ptr(stripeMetadata, stripeList)
|
||||
{
|
||||
totalRowCount += stripeMetadata->rowCount;
|
||||
}
|
||||
|
||||
/*
|
||||
* We allocate all stripe specific data in the stripeReadContext, and reset
|
||||
|
@ -135,6 +150,8 @@ ColumnarBeginRead(Relation relation, TupleDesc tupleDescriptor,
|
|||
readState->stripeReadContext = stripeReadContext;
|
||||
readState->chunkData = NULL;
|
||||
readState->deserializedChunkIndex = -1;
|
||||
readState->readRowCount = 0;
|
||||
readState->totalRowCount = totalRowCount;
|
||||
|
||||
return readState;
|
||||
}
|
||||
|
@ -151,6 +168,26 @@ ColumnarReadNextRow(TableReadState *readState, Datum *columnValues, bool *column
|
|||
StripeMetadata *stripeMetadata = readState->currentStripeMetadata;
|
||||
MemoryContext oldContext = NULL;
|
||||
|
||||
/*
|
||||
* We rely on first column's metadata in rest of this function. So for zero
|
||||
* column tables we just return "true" for totalRowCount times. We do the
|
||||
* same when no columns are projected.
|
||||
*/
|
||||
if (readState->projectedColumnList == NIL)
|
||||
{
|
||||
if (readState->totalRowCount == readState->readRowCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
int columnCount = readState->tupleDescriptor->natts;
|
||||
memset(columnNulls, 1, sizeof(bool) * columnCount);
|
||||
readState->readRowCount++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If no stripes are loaded, load the next non-empty stripe. Note that when
|
||||
* loading stripes, we skip over chunks whose contents can be filtered with
|
||||
|
|
|
@ -240,5 +240,99 @@ SELECT * FROM test_gen_ex;
|
|||
3 | 4
|
||||
(3 rows)
|
||||
|
||||
-- check removing all columns while having some data to simulate
|
||||
-- table with non-zero rows but zero-columns.
|
||||
-- https://github.com/citusdata/citus/issues/4626
|
||||
BEGIN;
|
||||
create table local(y int);
|
||||
insert into local values (1), (2);
|
||||
alter table local drop column y;
|
||||
CREATE TABLE zero_col_columnar (like local) USING COLUMNAR;
|
||||
ALTER TABLE local RENAME TO local_xxxxx;
|
||||
INSERT INTO zero_col_columnar SELECT * FROM local_xxxxx;
|
||||
COMMIT;
|
||||
SELECT * FROM zero_col_columnar;
|
||||
--
|
||||
(2 rows)
|
||||
|
||||
SELECT count(*) FROM zero_col_columnar;
|
||||
count
|
||||
---------------------------------------------------------------------
|
||||
2
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (costs off, summary off) SELECT * FROM zero_col_columnar;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Custom Scan (ColumnarScan) on zero_col_columnar
|
||||
(1 row)
|
||||
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
SELECT * FROM zero_col_columnar;
|
||||
--
|
||||
(5 rows)
|
||||
|
||||
SELECT count(*) FROM zero_col_columnar;
|
||||
count
|
||||
---------------------------------------------------------------------
|
||||
5
|
||||
(1 row)
|
||||
|
||||
EXPLAIN (costs off, summary off) SELECT * FROM zero_col_columnar;
|
||||
QUERY PLAN
|
||||
---------------------------------------------------------------------
|
||||
Custom Scan (ColumnarScan) on zero_col_columnar
|
||||
(1 row)
|
||||
|
||||
VACUUM VERBOSE zero_col_columnar;
|
||||
INFO: statistics for "zero_col_columnar":
|
||||
storage id: xxxxx
|
||||
total file size: 16384, total data size: 0
|
||||
compression rate: 1.00x
|
||||
total row count: 5, stripe count: 4, average rows per stripe: 1
|
||||
chunk count: 0, containing data for dropped columns: 0
|
||||
|
||||
ANALYZE zero_col_columnar;
|
||||
VACUUM FULL zero_col_columnar;
|
||||
SELECT * FROM zero_col_columnar;
|
||||
--
|
||||
(5 rows)
|
||||
|
||||
TRUNCATE zero_col_columnar;
|
||||
SELECT * FROM zero_col_columnar;
|
||||
--
|
||||
(0 rows)
|
||||
|
||||
DROP TABLE zero_col_columnar;
|
||||
CREATE TABLE zero_col_columnar(a int) USING columnar;
|
||||
INSERT INTO zero_col_columnar SELECT i FROM generate_series(1, 5) i;
|
||||
alter table zero_col_columnar drop column a;
|
||||
SELECT * FROM zero_col_columnar;
|
||||
--
|
||||
(5 rows)
|
||||
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
SELECT * FROM zero_col_columnar;
|
||||
--
|
||||
(8 rows)
|
||||
|
||||
VACUUM VERBOSE zero_col_columnar;
|
||||
INFO: statistics for "zero_col_columnar":
|
||||
storage id: xxxxx
|
||||
total file size: 49152, total data size: 60
|
||||
compression rate: 0.40x
|
||||
total row count: 8, stripe count: 4, average rows per stripe: 2
|
||||
chunk count: 4, containing data for dropped columns: 4, zstd compressed: 4
|
||||
|
||||
ANALYZE zero_col_columnar;
|
||||
VACUUM FULL zero_col_columnar;
|
||||
SELECT * FROM zero_col_columnar;
|
||||
--
|
||||
(8 rows)
|
||||
|
||||
SET client_min_messages TO WARNING;
|
||||
DROP SCHEMA columnar_alter CASCADE;
|
||||
|
|
|
@ -123,5 +123,60 @@ INSERT INTO test_gen_ex VALUES (1), (2), (3);
|
|||
ALTER TABLE test_gen_ex ADD COLUMN y int generated always as (x+1) stored;
|
||||
SELECT * FROM test_gen_ex;
|
||||
|
||||
|
||||
-- check removing all columns while having some data to simulate
|
||||
-- table with non-zero rows but zero-columns.
|
||||
-- https://github.com/citusdata/citus/issues/4626
|
||||
BEGIN;
|
||||
create table local(y int);
|
||||
insert into local values (1), (2);
|
||||
alter table local drop column y;
|
||||
|
||||
CREATE TABLE zero_col_columnar (like local) USING COLUMNAR;
|
||||
ALTER TABLE local RENAME TO local_xxxxx;
|
||||
INSERT INTO zero_col_columnar SELECT * FROM local_xxxxx;
|
||||
COMMIT;
|
||||
|
||||
SELECT * FROM zero_col_columnar;
|
||||
SELECT count(*) FROM zero_col_columnar;
|
||||
EXPLAIN (costs off, summary off) SELECT * FROM zero_col_columnar;
|
||||
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
SELECT * FROM zero_col_columnar;
|
||||
SELECT count(*) FROM zero_col_columnar;
|
||||
EXPLAIN (costs off, summary off) SELECT * FROM zero_col_columnar;
|
||||
|
||||
VACUUM VERBOSE zero_col_columnar;
|
||||
ANALYZE zero_col_columnar;
|
||||
VACUUM FULL zero_col_columnar;
|
||||
|
||||
SELECT * FROM zero_col_columnar;
|
||||
|
||||
TRUNCATE zero_col_columnar;
|
||||
|
||||
SELECT * FROM zero_col_columnar;
|
||||
|
||||
DROP TABLE zero_col_columnar;
|
||||
|
||||
CREATE TABLE zero_col_columnar(a int) USING columnar;
|
||||
INSERT INTO zero_col_columnar SELECT i FROM generate_series(1, 5) i;
|
||||
alter table zero_col_columnar drop column a;
|
||||
|
||||
SELECT * FROM zero_col_columnar;
|
||||
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
INSERT INTO zero_col_columnar DEFAULT VALUES;
|
||||
|
||||
SELECT * FROM zero_col_columnar;
|
||||
|
||||
VACUUM VERBOSE zero_col_columnar;
|
||||
ANALYZE zero_col_columnar;
|
||||
VACUUM FULL zero_col_columnar;
|
||||
|
||||
SELECT * FROM zero_col_columnar;
|
||||
|
||||
SET client_min_messages TO WARNING;
|
||||
DROP SCHEMA columnar_alter CASCADE;
|
||||
|
|
Loading…
Reference in New Issue