Clearer error messages for ON CONFLICT DO [NOTHING|UPDATE] scenarios

Our current support is limited to "ON CONFLICT DO NOTHING" without
specifying any inference index columns. While we do error out in the
other cases, the error messages do not convey things clearly. So rework
them.
This commit is contained in:
Nikhil 2021-02-23 17:10:22 +05:30 committed by Nikhils
parent 7f9077dc8c
commit a38b564218
7 changed files with 62 additions and 13 deletions

View File

@ -465,10 +465,21 @@ set_arbiter_indexes(ChunkInsertState *state, ChunkDispatch *dispatch)
if (ts_chunk_index_get_by_hypertable_indexrelid(chunk, hypertable_index, &cim) < 1)
{
elog(ERROR,
"could not find arbiter index for hypertable index \"%s\" on chunk \"%s\"",
get_rel_name(hypertable_index),
get_rel_name(RelationGetRelid(state->rel)));
/*
* In case of distributed hypertables, we don't have information about the
* arbiter index on the remote side, so error out with a helpful hint
*/
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("could not find arbiter index for hypertable index \"%s\" on chunk "
"\"%s\"",
get_rel_name(hypertable_index),
get_rel_name(RelationGetRelid(state->rel))),
hypertable_is_distributed(dispatch->hypertable) ?
errhint(
"Omit the index inference specification for the distributed hypertable"
" in the ON CONFLICT clause.") :
0));
}
state->arbiter_indexes = lappend_oid(state->arbiter_indexes, cim.indexoid);

View File

@ -1090,7 +1090,10 @@ plan_remote_insert(PlannerInfo *root, DataNodeDispatchPath *sdpath)
if (onconflict == ONCONFLICT_NOTHING)
do_nothing = true;
else if (onconflict != ONCONFLICT_NONE)
elog(ERROR, "unexpected ON CONFLICT specification: %d", (int) onconflict);
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("ON CONFLICT DO UPDATE not supported"
" on distributed hypertables")));
userid = OidIsValid(rte->checkAsUser) ? rte->checkAsUser : GetUserId();

View File

@ -136,7 +136,10 @@ fdw_plan_foreign_modify(PlannerInfo *root, ModifyTable *plan, Index result_relat
if (plan->onConflictAction == ONCONFLICT_NOTHING)
do_nothing = true;
else if (plan->onConflictAction != ONCONFLICT_NONE)
elog(ERROR, "unexpected ON CONFLICT specification: %d", (int) plan->onConflictAction);
ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("ON CONFLICT DO UPDATE not supported"
" on distributed hypertables")));
/*
* Core code already has some lock on each rel being planned, so we can

View File

@ -1147,11 +1147,19 @@ Sun Sep 03 06:18:00 2017 PDT| 9| 8.7| 3
(1 row)
\set ON_ERROR_STOP 0
-- ON CONFLICT only works with DO NOTHING
-- ON CONFLICT DO NOTHING only works when index inference is omitted
\set VERBOSITY default
INSERT INTO disttable
VALUES ('2017-09-02 06:09', 6)
ON CONFLICT(time,device) DO NOTHING;
ERROR: could not find arbiter index for hypertable index "disttable_pkey" on chunk "_dist_hyper_1_9_chunk"
HINT: Omit the index inference specification for the distributed hypertable in the ON CONFLICT clause.
\set VERBOSITY terse
-- ON CONFLICT only works with DO NOTHING for now
INSERT INTO disttable (time, device, "Color", temp)
VALUES ('2017-09-09 08:13', 7, 3, 27.5)
ON CONFLICT (time) DO UPDATE SET temp = 3.2;
ERROR: unexpected ON CONFLICT specification: 2
ERROR: ON CONFLICT DO UPDATE not supported on distributed hypertables
-- Test that an INSERT that would create a chunk does not work on a
-- data node
SELECT * FROM test.remote_exec(ARRAY[:'DATA_NODE_1'], $$

View File

@ -1147,11 +1147,19 @@ Sun Sep 03 06:18:00 2017 PDT| 9| 8.7| 3
(1 row)
\set ON_ERROR_STOP 0
-- ON CONFLICT only works with DO NOTHING
-- ON CONFLICT DO NOTHING only works when index inference is omitted
\set VERBOSITY default
INSERT INTO disttable
VALUES ('2017-09-02 06:09', 6)
ON CONFLICT(time,device) DO NOTHING;
ERROR: could not find arbiter index for hypertable index "disttable_pkey" on chunk "_dist_hyper_1_9_chunk"
HINT: Omit the index inference specification for the distributed hypertable in the ON CONFLICT clause.
\set VERBOSITY terse
-- ON CONFLICT only works with DO NOTHING for now
INSERT INTO disttable (time, device, "Color", temp)
VALUES ('2017-09-09 08:13', 7, 3, 27.5)
ON CONFLICT (time) DO UPDATE SET temp = 3.2;
ERROR: unexpected ON CONFLICT specification: 2
ERROR: ON CONFLICT DO UPDATE not supported on distributed hypertables
-- Test that an INSERT that would create a chunk does not work on a
-- data node
SELECT * FROM test.remote_exec(ARRAY[:'DATA_NODE_1'], $$

View File

@ -1146,11 +1146,19 @@ Sun Sep 03 06:18:00 2017 PDT| 9| 8.7| 3
(1 row)
\set ON_ERROR_STOP 0
-- ON CONFLICT only works with DO NOTHING
-- ON CONFLICT DO NOTHING only works when index inference is omitted
\set VERBOSITY default
INSERT INTO disttable
VALUES ('2017-09-02 06:09', 6)
ON CONFLICT(time,device) DO NOTHING;
ERROR: could not find arbiter index for hypertable index "disttable_pkey" on chunk "_dist_hyper_1_9_chunk"
HINT: Omit the index inference specification for the distributed hypertable in the ON CONFLICT clause.
\set VERBOSITY terse
-- ON CONFLICT only works with DO NOTHING for now
INSERT INTO disttable (time, device, "Color", temp)
VALUES ('2017-09-09 08:13', 7, 3, 27.5)
ON CONFLICT (time) DO UPDATE SET temp = 3.2;
ERROR: unexpected ON CONFLICT specification: 2
ERROR: ON CONFLICT DO UPDATE not supported on distributed hypertables
-- Test that an INSERT that would create a chunk does not work on a
-- data node
SELECT * FROM test.remote_exec(ARRAY[:'DATA_NODE_1'], $$

View File

@ -365,7 +365,15 @@ $$);
\set ON_ERROR_STOP 0
-- ON CONFLICT only works with DO NOTHING
-- ON CONFLICT DO NOTHING only works when index inference is omitted
\set VERBOSITY default
INSERT INTO disttable
VALUES ('2017-09-02 06:09', 6)
ON CONFLICT(time,device) DO NOTHING;
\set VERBOSITY terse
-- ON CONFLICT only works with DO NOTHING for now
INSERT INTO disttable (time, device, "Color", temp)
VALUES ('2017-09-09 08:13', 7, 3, 27.5)
ON CONFLICT (time) DO UPDATE SET temp = 3.2;