diff --git a/src/backend/columnar/cstore_customscan.c b/src/backend/columnar/cstore_customscan.c index c033f3e12..e8117a070 100644 --- a/src/backend/columnar/cstore_customscan.c +++ b/src/backend/columnar/cstore_customscan.c @@ -162,6 +162,12 @@ CStoreSetRelPathlistHook(PlannerInfo *root, RelOptInfo *rel, Index rti, Relation relation = RelationIdGetRelation(rte->relid); if (relation->rd_tableam == GetColumnarTableAmRoutine()) { + if (rte->tablesample != NULL) + { + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("sample scans not supported on columnar tables"))); + } + Path *customPath = CreateCStoreScanPath(rel, rte); ereport(DEBUG1, (errmsg("pathlist hook for cstore table am"))); diff --git a/src/backend/columnar/cstore_tableam.c b/src/backend/columnar/cstore_tableam.c index 012f851dd..b73d7da23 100644 --- a/src/backend/columnar/cstore_tableam.c +++ b/src/backend/columnar/cstore_tableam.c @@ -55,7 +55,7 @@ #include "distributed/commands/utility_hook.h" #include "distributed/metadata_cache.h" -#define CSTORE_TABLEAM_NAME "cstore_tableam" +#define CSTORE_TABLEAM_NAME "columnar" /* * Timing parameters for truncate locking heuristics. @@ -320,42 +320,45 @@ cstore_getnextslot(TableScanDesc sscan, ScanDirection direction, TupleTableSlot static Size cstore_parallelscan_estimate(Relation rel) { - elog(ERROR, "cstore_parallelscan_estimate not implemented"); + elog(ERROR, "columnar_parallelscan_estimate not implemented"); } static Size cstore_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan) { - elog(ERROR, "cstore_parallelscan_initialize not implemented"); + elog(ERROR, "columnar_parallelscan_initialize not implemented"); } static void cstore_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan) { - elog(ERROR, "cstore_parallelscan_reinitialize not implemented"); + elog(ERROR, "columnar_parallelscan_reinitialize not implemented"); } static IndexFetchTableData * cstore_index_fetch_begin(Relation rel) { - elog(ERROR, "cstore_index_fetch_begin not implemented"); + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("indexes not supported for columnar tables"))); } static void cstore_index_fetch_reset(IndexFetchTableData *scan) { - elog(ERROR, "cstore_index_fetch_reset not implemented"); + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("indexes not supported for columnar tables"))); } static void cstore_index_fetch_end(IndexFetchTableData *scan) { - elog(ERROR, "cstore_index_fetch_end not implemented"); + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("indexes not supported for columnar tables"))); } @@ -366,7 +369,8 @@ cstore_index_fetch_tuple(struct IndexFetchTableData *scan, TupleTableSlot *slot, bool *call_again, bool *all_dead) { - elog(ERROR, "cstore_index_fetch_tuple not implemented"); + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("indexes not supported for columnar tables"))); } @@ -376,7 +380,7 @@ cstore_fetch_row_version(Relation relation, Snapshot snapshot, TupleTableSlot *slot) { - elog(ERROR, "cstore_fetch_row_version not implemented"); + elog(ERROR, "columnar_fetch_row_version not implemented"); } @@ -384,14 +388,14 @@ static void cstore_get_latest_tid(TableScanDesc sscan, ItemPointer tid) { - elog(ERROR, "cstore_get_latest_tid not implemented"); + elog(ERROR, "columnar_get_latest_tid not implemented"); } static bool cstore_tuple_tid_valid(TableScanDesc scan, ItemPointer tid) { - elog(ERROR, "cstore_tuple_tid_valid not implemented"); + elog(ERROR, "columnar_tuple_tid_valid not implemented"); } @@ -408,7 +412,7 @@ cstore_compute_xid_horizon_for_tuples(Relation rel, ItemPointerData *tids, int nitems) { - elog(ERROR, "cstore_compute_xid_horizon_for_tuples not implemented"); + elog(ERROR, "columnar_compute_xid_horizon_for_tuples not implemented"); } @@ -450,7 +454,7 @@ cstore_tuple_insert_speculative(Relation relation, TupleTableSlot *slot, CommandId cid, int options, BulkInsertState bistate, uint32 specToken) { - elog(ERROR, "cstore_tuple_insert_speculative not implemented"); + elog(ERROR, "columnar_tuple_insert_speculative not implemented"); } @@ -458,7 +462,7 @@ static void cstore_tuple_complete_speculative(Relation relation, TupleTableSlot *slot, uint32 specToken, bool succeeded) { - elog(ERROR, "cstore_tuple_complete_speculative not implemented"); + elog(ERROR, "columnar_tuple_complete_speculative not implemented"); } @@ -500,7 +504,7 @@ cstore_tuple_delete(Relation relation, ItemPointer tid, CommandId cid, Snapshot snapshot, Snapshot crosscheck, bool wait, TM_FailureData *tmfd, bool changingPart) { - elog(ERROR, "cstore_tuple_delete not implemented"); + elog(ERROR, "columnar_tuple_delete not implemented"); } @@ -510,7 +514,7 @@ cstore_tuple_update(Relation relation, ItemPointer otid, TupleTableSlot *slot, bool wait, TM_FailureData *tmfd, LockTupleMode *lockmode, bool *update_indexes) { - elog(ERROR, "cstore_tuple_update not implemented"); + elog(ERROR, "columnar_tuple_update not implemented"); } @@ -520,7 +524,7 @@ cstore_tuple_lock(Relation relation, ItemPointer tid, Snapshot snapshot, LockWaitPolicy wait_policy, uint8 flags, TM_FailureData *tmfd) { - elog(ERROR, "cstore_tuple_lock not implemented"); + elog(ERROR, "columnar_tuple_lock not implemented"); } @@ -586,7 +590,7 @@ cstore_relation_nontransactional_truncate(Relation rel) static void cstore_relation_copy_data(Relation rel, const RelFileNode *newrnode) { - elog(ERROR, "cstore_relation_copy_data not implemented"); + elog(ERROR, "columnar_relation_copy_data not implemented"); } @@ -612,7 +616,8 @@ cstore_relation_copy_for_cluster(Relation OldHeap, Relation NewHeap, if (OldIndex != NULL || use_sort) { - ereport(ERROR, (errmsg(CSTORE_TABLEAM_NAME " doesn't support indexes"))); + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("indexes not supported for columnar tables"))); } /* @@ -955,7 +960,8 @@ cstore_index_build_range_scan(Relation heapRelation, void *callback_state, TableScanDesc scan) { - elog(ERROR, "cstore_index_build_range_scan not implemented"); + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("indexes not supported for columnar tables"))); } @@ -966,7 +972,8 @@ cstore_index_validate_scan(Relation heapRelation, Snapshot snapshot, ValidateIndexState *state) { - elog(ERROR, "cstore_index_validate_scan not implemented"); + ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("indexes not supported for columnar tables"))); } @@ -1024,7 +1031,7 @@ cstore_estimate_rel_size(Relation rel, int32 *attr_widths, static bool cstore_scan_sample_next_block(TableScanDesc scan, SampleScanState *scanstate) { - elog(ERROR, "cstore_scan_sample_next_block not implemented"); + elog(ERROR, "columnar_scan_sample_next_block not implemented"); } @@ -1032,7 +1039,7 @@ static bool cstore_scan_sample_next_tuple(TableScanDesc scan, SampleScanState *scanstate, TupleTableSlot *slot) { - elog(ERROR, "cstore_scan_sample_next_tuple not implemented"); + elog(ERROR, "columnar_scan_sample_next_tuple not implemented"); } diff --git a/src/test/regress/columnar_am_schedule b/src/test/regress/columnar_am_schedule index 4ee21f862..659a317bf 100644 --- a/src/test/regress/columnar_am_schedule +++ b/src/test/regress/columnar_am_schedule @@ -10,7 +10,7 @@ test: am_data_types test: am_drop test: am_empty test: am_insert -test: am_update +test: am_update_delete test: am_copyto test: am_alter test: am_alter_set_type diff --git a/src/test/regress/expected/am_create.out b/src/test/regress/expected/am_create.out index 61695e3a2..7a1f0768d 100644 --- a/src/test/regress/expected/am_create.out +++ b/src/test/regress/expected/am_create.out @@ -5,6 +5,9 @@ CREATE TABLE contestant (handle TEXT, birthdate DATE, rating INT, percentile FLOAT, country CHAR(3), achievements TEXT[]) USING columnar; +-- should fail +CREATE INDEX contestant_idx on contestant(handle); +ERROR: indexes not supported for columnar tables -- Create compressed table with automatically determined file path -- COMPRESSED CREATE TABLE contestant_compressed (handle TEXT, birthdate DATE, rating INT, diff --git a/src/test/regress/expected/am_drop.out b/src/test/regress/expected/am_drop.out index cbda10691..3d244b487 100644 --- a/src/test/regress/expected/am_drop.out +++ b/src/test/regress/expected/am_drop.out @@ -7,7 +7,7 @@ -- DROP DATABASE -- -- Note that travis does not create --- columnar extension in default database (postgres). This has caused +-- citus extension in default database (postgres). This has caused -- different behavior between travis tests and local tests. Thus -- 'postgres' directory is excluded from comparison to have the same result. -- store postgres database oid diff --git a/src/test/regress/expected/am_query.out b/src/test/regress/expected/am_query.out index 211cec8a9..a96fd36fd 100644 --- a/src/test/regress/expected/am_query.out +++ b/src/test/regress/expected/am_query.out @@ -39,6 +39,22 @@ SELECT * FROM contestant ORDER BY handle; h | 1987-10-26 | 2112 | 95.4 | XD | {w,a} (8 rows) +-- all special column accesses should fail +SELECT ctid FROM contestant; +ERROR: UPDATE and CTID scans not supported for ColumnarScan +SELECT cmin FROM contestant; +ERROR: UPDATE and CTID scans not supported for ColumnarScan +SELECT cmax FROM contestant; +ERROR: UPDATE and CTID scans not supported for ColumnarScan +SELECT xmin FROM contestant; +ERROR: UPDATE and CTID scans not supported for ColumnarScan +SELECT xmax FROM contestant; +ERROR: UPDATE and CTID scans not supported for ColumnarScan +SELECT tableid FROM contestant; +ERROR: column "tableid" does not exist +-- sample scans should fail +SELECT * FROM contestant TABLESAMPLE SYSTEM(0.1); +ERROR: sample scans not supported on columnar tables -- Query compressed data SELECT count(*) FROM contestant_compressed; count diff --git a/src/test/regress/expected/am_update.out b/src/test/regress/expected/am_update_delete.out similarity index 66% rename from src/test/regress/expected/am_update.out rename to src/test/regress/expected/am_update_delete.out index 84e137fe9..551886256 100644 --- a/src/test/regress/expected/am_update.out +++ b/src/test/regress/expected/am_update_delete.out @@ -5,6 +5,9 @@ INSERT INTO columnar_update VALUES (3, 30); -- should fail UPDATE columnar_update SET j = j+1 WHERE i = 2; ERROR: UPDATE and CTID scans not supported for ColumnarScan +-- should fail +DELETE FROM columnar_update WHERE i = 2; +ERROR: UPDATE and CTID scans not supported for ColumnarScan -- should succeed because there's no target INSERT INTO columnar_update VALUES (3, 5), @@ -40,28 +43,51 @@ CREATE TABLE p2 PARTITION OF parent INSERT INTO parent VALUES('2020-01-15', 10, 100, 'one thousand'); -- columnar INSERT INTO parent VALUES('2020-02-15', 20, 200, 'two thousand'); -- columnar INSERT INTO parent VALUES('2020-03-15', 30, 300, 'three thousand'); -- row +INSERT INTO parent VALUES('2020-03-21', 31, 301, 'three thousand and one'); -- row +INSERT INTO parent VALUES('2020-03-22', 32, 302, 'three thousand and two'); -- row +INSERT INTO parent VALUES('2020-03-23', 33, 303, 'three thousand and three'); -- row SELECT * FROM parent; - ts | i | n | s + ts | i | n | s --------------------------------------------------------------------- Wed Jan 15 00:00:00 2020 PST | 10 | 100 | one thousand Sat Feb 15 00:00:00 2020 PST | 20 | 200 | two thousand Sun Mar 15 00:00:00 2020 PDT | 30 | 300 | three thousand -(3 rows) + Sat Mar 21 00:00:00 2020 PDT | 31 | 301 | three thousand and one + Sun Mar 22 00:00:00 2020 PDT | 32 | 302 | three thousand and two + Mon Mar 23 00:00:00 2020 PDT | 33 | 303 | three thousand and three +(6 rows) -- update on specific row partition should succeed UPDATE p2 SET i = i+1 WHERE ts = '2020-03-15'; +DELETE FROM p2 WHERE ts = '2020-03-21'; -- update on specific columnar partition should fail UPDATE p1 SET i = i+1 WHERE ts = '2020-02-15'; ERROR: UPDATE and CTID scans not supported for ColumnarScan +DELETE FROM p1 WHERE ts = '2020-02-15'; +ERROR: UPDATE and CTID scans not supported for ColumnarScan -- partitioned updates that affect only row tables -- should succeed UPDATE parent SET i = i+1 WHERE ts = '2020-03-15'; +DELETE FROM parent WHERE ts = '2020-03-22'; -- partitioned updates that affect columnar tables -- should fail UPDATE parent SET i = i+1 WHERE ts > '2020-02-15'; ERROR: UPDATE and CTID scans not supported for ColumnarScan +DELETE FROM parent WHERE ts > '2020-02-15'; +ERROR: UPDATE and CTID scans not supported for ColumnarScan -- non-partitioned update should fail, even if it -- only affects a row partition UPDATE parent SET i = i+1 WHERE n = 300; ERROR: UPDATE and CTID scans not supported for ColumnarScan +DELETE FROM parent WHERE n = 303; +ERROR: UPDATE and CTID scans not supported for ColumnarScan +SELECT * FROM parent; + ts | i | n | s +--------------------------------------------------------------------- + Wed Jan 15 00:00:00 2020 PST | 10 | 100 | one thousand + Sat Feb 15 00:00:00 2020 PST | 20 | 200 | two thousand + Mon Mar 23 00:00:00 2020 PDT | 33 | 303 | three thousand and three + Sun Mar 15 00:00:00 2020 PDT | 32 | 300 | three thousand +(4 rows) + DROP TABLE parent; diff --git a/src/test/regress/sql/am_create.sql b/src/test/regress/sql/am_create.sql index 412bfe784..0b46f8c01 100644 --- a/src/test/regress/sql/am_create.sql +++ b/src/test/regress/sql/am_create.sql @@ -8,6 +8,8 @@ CREATE TABLE contestant (handle TEXT, birthdate DATE, rating INT, percentile FLOAT, country CHAR(3), achievements TEXT[]) USING columnar; +-- should fail +CREATE INDEX contestant_idx on contestant(handle); -- Create compressed table with automatically determined file path -- COMPRESSED diff --git a/src/test/regress/sql/am_drop.sql b/src/test/regress/sql/am_drop.sql index 81c739ca1..06a110bf3 100644 --- a/src/test/regress/sql/am_drop.sql +++ b/src/test/regress/sql/am_drop.sql @@ -8,7 +8,7 @@ -- -- Note that travis does not create --- columnar extension in default database (postgres). This has caused +-- citus extension in default database (postgres). This has caused -- different behavior between travis tests and local tests. Thus -- 'postgres' directory is excluded from comparison to have the same result. diff --git a/src/test/regress/sql/am_query.sql b/src/test/regress/sql/am_query.sql index 85135370a..12e4ab4e3 100644 --- a/src/test/regress/sql/am_query.sql +++ b/src/test/regress/sql/am_query.sql @@ -12,6 +12,17 @@ SELECT country, avg(rating) FROM contestant WHERE rating > 2200 GROUP BY country ORDER BY country; SELECT * FROM contestant ORDER BY handle; +-- all special column accesses should fail +SELECT ctid FROM contestant; +SELECT cmin FROM contestant; +SELECT cmax FROM contestant; +SELECT xmin FROM contestant; +SELECT xmax FROM contestant; +SELECT tableid FROM contestant; + +-- sample scans should fail +SELECT * FROM contestant TABLESAMPLE SYSTEM(0.1); + -- Query compressed data SELECT count(*) FROM contestant_compressed; SELECT avg(rating), stddev_samp(rating) FROM contestant_compressed; diff --git a/src/test/regress/sql/am_update.sql b/src/test/regress/sql/am_update_delete.sql similarity index 79% rename from src/test/regress/sql/am_update.sql rename to src/test/regress/sql/am_update_delete.sql index 083478aa6..3e38d2cc8 100644 --- a/src/test/regress/sql/am_update.sql +++ b/src/test/regress/sql/am_update_delete.sql @@ -7,6 +7,8 @@ INSERT INTO columnar_update VALUES (3, 30); -- should fail UPDATE columnar_update SET j = j+1 WHERE i = 2; +-- should fail +DELETE FROM columnar_update WHERE i = 2; -- should succeed because there's no target INSERT INTO columnar_update VALUES @@ -46,26 +48,36 @@ CREATE TABLE p2 PARTITION OF parent INSERT INTO parent VALUES('2020-01-15', 10, 100, 'one thousand'); -- columnar INSERT INTO parent VALUES('2020-02-15', 20, 200, 'two thousand'); -- columnar INSERT INTO parent VALUES('2020-03-15', 30, 300, 'three thousand'); -- row +INSERT INTO parent VALUES('2020-03-21', 31, 301, 'three thousand and one'); -- row +INSERT INTO parent VALUES('2020-03-22', 32, 302, 'three thousand and two'); -- row +INSERT INTO parent VALUES('2020-03-23', 33, 303, 'three thousand and three'); -- row SELECT * FROM parent; -- update on specific row partition should succeed UPDATE p2 SET i = i+1 WHERE ts = '2020-03-15'; +DELETE FROM p2 WHERE ts = '2020-03-21'; -- update on specific columnar partition should fail UPDATE p1 SET i = i+1 WHERE ts = '2020-02-15'; +DELETE FROM p1 WHERE ts = '2020-02-15'; -- partitioned updates that affect only row tables -- should succeed UPDATE parent SET i = i+1 WHERE ts = '2020-03-15'; +DELETE FROM parent WHERE ts = '2020-03-22'; -- partitioned updates that affect columnar tables -- should fail UPDATE parent SET i = i+1 WHERE ts > '2020-02-15'; +DELETE FROM parent WHERE ts > '2020-02-15'; -- non-partitioned update should fail, even if it -- only affects a row partition UPDATE parent SET i = i+1 WHERE n = 300; +DELETE FROM parent WHERE n = 303; + +SELECT * FROM parent; DROP TABLE parent;