Tests for UPDATE and error message improvement.

UPDATEs on partitioned tables that affect only row partitions should
succeed, the rest should fail.

Also rename CStoreScan to ColumnarScan to make the error message more
relevant.
pull/4394/head
Jeff Davis 2020-12-07 08:25:34 -08:00
parent 45ac491885
commit ad919ff220
6 changed files with 155 additions and 9 deletions

View File

@ -76,17 +76,17 @@ static bool EnableCStoreCustomScan = true;
const struct CustomPathMethods CStoreScanPathMethods = {
.CustomName = "CStoreScan",
.CustomName = "ColumnarScan",
.PlanCustomPath = CStoreScanPath_PlanCustomPath,
};
const struct CustomScanMethods CStoreScanScanMethods = {
.CustomName = "CStoreScan",
.CustomName = "ColumnarScan",
.CreateCustomScanState = CStoreScan_CreateCustomScanState,
};
const struct CustomExecMethods CStoreExecuteMethods = {
.CustomName = "CStoreScan",
.CustomName = "ColumnarScan",
.BeginCustomScan = CStoreScan_BeginCustomScan,
.ExecCustomScan = CStoreScan_ExecCustomScan,
@ -304,6 +304,13 @@ CStoreAttrNeeded(ScanState *ss)
{
Var *var = lfirst(lc);
if (var->varattno < 0)
{
ereport(ERROR, (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg(
"UPDATE and CTID scans not supported for ColumnarScan")));
}
if (var->varattno == 0)
{
elog(DEBUG1, "Need attribute: all");

View File

@ -10,6 +10,7 @@ test: am_data_types
test: am_drop
test: am_empty
test: am_insert
test: am_update
test: am_copyto
test: am_alter
test: am_alter_set_type

View File

@ -54,15 +54,15 @@ select count(*) from t_compressed;
-- explain
explain (costs off, summary off, timing off) select * from t_uncompressed;
QUERY PLAN
QUERY PLAN
---------------------------------------------------------------------
Custom Scan (CStoreScan) on t_uncompressed
Custom Scan (ColumnarScan) on t_uncompressed
(1 row)
explain (costs off, summary off, timing off) select * from t_compressed;
QUERY PLAN
QUERY PLAN
---------------------------------------------------------------------
Custom Scan (CStoreScan) on t_compressed
Custom Scan (ColumnarScan) on t_compressed
(1 row)
-- vacuum

View File

@ -28,9 +28,9 @@ WHERE things.id > 299990;
Aggregate
-> Nested Loop
Join Filter: (users.id = things.user_id)
-> Custom Scan (CStoreScan) on things
-> Custom Scan (ColumnarScan) on things
Filter: (id > 299990)
-> Custom Scan (CStoreScan) on users
-> Custom Scan (ColumnarScan) on users
(6 rows)
SET client_min_messages TO warning;

View File

@ -0,0 +1,67 @@
CREATE TABLE columnar_update(i int, j int) USING columnar;
INSERT INTO columnar_update VALUES (1, 10);
INSERT INTO columnar_update VALUES (2, 20);
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 succeed because there's no target
INSERT INTO columnar_update VALUES
(3, 5),
(4, 5),
(5, 5)
ON CONFLICT DO NOTHING;
-- should fail because we can't create an index on columnar_update.i
INSERT INTO columnar_update VALUES
(3, 5),
(4, 5),
(5, 5)
ON CONFLICT (i) DO NOTHING;
ERROR: there is no unique or exclusion constraint matching the ON CONFLICT specification
-- tuple locks should fail
SELECT * FROM columnar_update WHERE i = 2 FOR SHARE;
ERROR: UPDATE and CTID scans not supported for ColumnarScan
SELECT * FROM columnar_update WHERE i = 2 FOR UPDATE;
ERROR: UPDATE and CTID scans not supported for ColumnarScan
-- CTID scans should fail
SELECT * FROM columnar_update WHERE ctid = '(0,2)';
ERROR: UPDATE and CTID scans not supported for ColumnarScan
DROP TABLE columnar_update;
CREATE TABLE parent(ts timestamptz, i int, n numeric, s text)
PARTITION BY RANGE (ts);
CREATE TABLE p0 PARTITION OF parent
FOR VALUES FROM ('2020-01-01') TO ('2020-02-01')
USING COLUMNAR;
CREATE TABLE p1 PARTITION OF parent
FOR VALUES FROM ('2020-02-01') TO ('2020-03-01')
USING COLUMNAR;
CREATE TABLE p2 PARTITION OF parent
FOR VALUES FROM ('2020-03-01') TO ('2020-04-01');
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
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
Sun Mar 15 00:00:00 2020 PDT | 30 | 300 | three thousand
(3 rows)
-- update on specific row partition should succeed
UPDATE p2 SET i = i+1 WHERE ts = '2020-03-15';
-- 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
-- partitioned updates that affect only row tables
-- should succeed
UPDATE parent SET i = i+1 WHERE ts = '2020-03-15';
-- 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
-- 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
DROP TABLE parent;

View File

@ -0,0 +1,71 @@
CREATE TABLE columnar_update(i int, j int) USING columnar;
INSERT INTO columnar_update VALUES (1, 10);
INSERT INTO columnar_update VALUES (2, 20);
INSERT INTO columnar_update VALUES (3, 30);
-- should fail
UPDATE columnar_update SET j = j+1 WHERE i = 2;
-- should succeed because there's no target
INSERT INTO columnar_update VALUES
(3, 5),
(4, 5),
(5, 5)
ON CONFLICT DO NOTHING;
-- should fail because we can't create an index on columnar_update.i
INSERT INTO columnar_update VALUES
(3, 5),
(4, 5),
(5, 5)
ON CONFLICT (i) DO NOTHING;
-- tuple locks should fail
SELECT * FROM columnar_update WHERE i = 2 FOR SHARE;
SELECT * FROM columnar_update WHERE i = 2 FOR UPDATE;
-- CTID scans should fail
SELECT * FROM columnar_update WHERE ctid = '(0,2)';
DROP TABLE columnar_update;
CREATE TABLE parent(ts timestamptz, i int, n numeric, s text)
PARTITION BY RANGE (ts);
CREATE TABLE p0 PARTITION OF parent
FOR VALUES FROM ('2020-01-01') TO ('2020-02-01')
USING COLUMNAR;
CREATE TABLE p1 PARTITION OF parent
FOR VALUES FROM ('2020-02-01') TO ('2020-03-01')
USING COLUMNAR;
CREATE TABLE p2 PARTITION OF parent
FOR VALUES FROM ('2020-03-01') TO ('2020-04-01');
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
SELECT * FROM parent;
-- update on specific row partition should succeed
UPDATE p2 SET i = i+1 WHERE ts = '2020-03-15';
-- update on specific columnar partition should fail
UPDATE p1 SET i = i+1 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';
-- partitioned updates that affect columnar tables
-- should fail
UPDATE parent SET i = i+1 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;
DROP TABLE parent;