diff --git a/src/backend/columnar/columnar_tableam.c b/src/backend/columnar/columnar_tableam.c index 944032b84..3ed5d8187 100644 --- a/src/backend/columnar/columnar_tableam.c +++ b/src/backend/columnar/columnar_tableam.c @@ -343,21 +343,33 @@ ErrorIfInvalidRowNumber(uint64 rowNumber) static Size columnar_parallelscan_estimate(Relation rel) { - elog(ERROR, "columnar_parallelscan_estimate not implemented"); + return sizeof(ParallelBlockTableScanDescData); } static Size columnar_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan) { - elog(ERROR, "columnar_parallelscan_initialize not implemented"); + ParallelBlockTableScanDesc bpscan = (ParallelBlockTableScanDesc) pscan; + + bpscan->base.phs_relid = RelationGetRelid(rel); + bpscan->phs_nblocks = RelationGetNumberOfBlocks(rel); + bpscan->base.phs_syncscan = synchronize_seqscans && + !RelationUsesLocalBuffers(rel) && + bpscan->phs_nblocks > NBuffers / 4; + SpinLockInit(&bpscan->phs_mutex); + bpscan->phs_startblock = InvalidBlockNumber; + pg_atomic_init_u64(&bpscan->phs_nallocated, 0); + + return sizeof(ParallelBlockTableScanDescData); } static void columnar_parallelscan_reinitialize(Relation rel, ParallelTableScanDesc pscan) { - elog(ERROR, "columnar_parallelscan_reinitialize not implemented"); + ParallelBlockTableScanDesc bpscan = (ParallelBlockTableScanDesc) pscan; + pg_atomic_write_u64(&bpscan->phs_nallocated, 0); } @@ -1101,10 +1113,21 @@ columnar_index_build_range_scan(Relation columnarRelation, if (scan) { /* - * Since we don't support parallel reads on columnar tables, we - * should have already errored out for that, but be on the safe side. + * Scan is initialized iff postgres decided to build the index using + * parallel workers. In this case, we simply return for parallel + * workers since we don't support parallel scan on columnar tables. */ - ereport(ERROR, (errmsg("parallel reads on columnar are not supported"))); + if (IsBackgroundWorker) + { + ereport(DEBUG4, (errmsg("ignoring parallel worker when building " + "index since parallel scan on columnar " + "tables is not supported"))); + return 0; + } + + ereport(NOTICE, (errmsg("falling back to serial index build since " + "parallel scan on columnar tables is not " + "supported"))); } /* @@ -1643,6 +1666,17 @@ static const TableAmRoutine columnar_am_methods = { .scan_rescan = columnar_rescan, .scan_getnextslot = columnar_getnextslot, + /* + * Postgres calls following three callbacks during index builds, if it + * decides to use parallel workers when building the index. On the other + * hand, we don't support parallel scans on columnar tables but we also + * want to fallback to serial index build. For this reason, we both skip + * parallel workers in columnar_index_build_range_scan and also provide + * basic implementations for those callbacks based on their corresponding + * implementations in heapAM. + * Note that for regular query plans, we already ignore parallel paths via + * ColumnarSetRelPathlistHook. + */ .parallelscan_estimate = columnar_parallelscan_estimate, .parallelscan_initialize = columnar_parallelscan_initialize, .parallelscan_reinitialize = columnar_parallelscan_reinitialize, diff --git a/src/test/regress/expected/columnar_indexes.out b/src/test/regress/expected/columnar_indexes.out index 6062cae34..32af88c92 100644 --- a/src/test/regress/expected/columnar_indexes.out +++ b/src/test/regress/expected/columnar_indexes.out @@ -384,5 +384,14 @@ INSERT INTO box_temp SELECT box(point(i, i), point(i * 2, i * 2)) FROM generate_ CREATE TABLE brin_summarize (value int) USING columnar; CREATE INDEX brin_summarize_idx ON brin_summarize USING brin (value) WITH (pages_per_range=2); ERROR: only btree and hash indexes are supported on columnar tables +-- Show that we safely fallback to serial index build. +CREATE TABLE parallel_scan_test(a int) USING columnar WITH ( parallel_workers = 2 ); +INSERT INTO parallel_scan_test SELECT i FROM generate_series(1,10) i; +CREATE INDEX ON parallel_scan_test (a); +NOTICE: falling back to serial index build since parallel scan on columnar tables is not supported +VACUUM FULL parallel_scan_test; +NOTICE: falling back to serial index build since parallel scan on columnar tables is not supported +REINDEX TABLE parallel_scan_test; +NOTICE: falling back to serial index build since parallel scan on columnar tables is not supported SET client_min_messages TO WARNING; DROP SCHEMA columnar_indexes CASCADE; diff --git a/src/test/regress/sql/columnar_indexes.sql b/src/test/regress/sql/columnar_indexes.sql index 60991b56a..2b48e2a37 100644 --- a/src/test/regress/sql/columnar_indexes.sql +++ b/src/test/regress/sql/columnar_indexes.sql @@ -281,5 +281,12 @@ INSERT INTO box_temp SELECT box(point(i, i), point(i * 2, i * 2)) FROM generate_ CREATE TABLE brin_summarize (value int) USING columnar; CREATE INDEX brin_summarize_idx ON brin_summarize USING brin (value) WITH (pages_per_range=2); +-- Show that we safely fallback to serial index build. +CREATE TABLE parallel_scan_test(a int) USING columnar WITH ( parallel_workers = 2 ); +INSERT INTO parallel_scan_test SELECT i FROM generate_series(1,10) i; +CREATE INDEX ON parallel_scan_test (a); +VACUUM FULL parallel_scan_test; +REINDEX TABLE parallel_scan_test; + SET client_min_messages TO WARNING; DROP SCHEMA columnar_indexes CASCADE;