* transformOnConflictArbiter - * transform arbiter expressions in an ON CONFLICT clause. * * Transformed expressions used to infer one unique index relation to serve as * an ON CONFLICT arbiter. Partial unique indexes may be inferred using WHERE * clause from inference specification clause. */
| 3477 | * clause from inference specification clause. |
| 3478 | */ |
| 3479 | void |
| 3480 | transformOnConflictArbiter(ParseState *pstate, |
| 3481 | OnConflictClause *onConflictClause, |
| 3482 | List **arbiterExpr, Node **arbiterWhere, |
| 3483 | Oid *constraint) |
| 3484 | { |
| 3485 | InferClause *infer = onConflictClause->infer; |
| 3486 | |
| 3487 | *arbiterExpr = NIL; |
| 3488 | *arbiterWhere = NULL; |
| 3489 | *constraint = InvalidOid; |
| 3490 | |
| 3491 | if (onConflictClause->action == ONCONFLICT_UPDATE && !infer) |
| 3492 | ereport(ERROR, |
| 3493 | (errcode(ERRCODE_SYNTAX_ERROR), |
| 3494 | errmsg("ON CONFLICT DO UPDATE requires inference specification or constraint name"), |
| 3495 | errhint("For example, ON CONFLICT (column_name)."), |
| 3496 | parser_errposition(pstate, |
| 3497 | exprLocation((Node *) onConflictClause)))); |
| 3498 | |
| 3499 | /* |
| 3500 | * To simplify certain aspects of its design, speculative insertion into |
| 3501 | * system catalogs is disallowed |
| 3502 | */ |
| 3503 | if (IsCatalogRelation(pstate->p_target_relation)) |
| 3504 | ereport(ERROR, |
| 3505 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 3506 | errmsg("ON CONFLICT is not supported with system catalog tables"), |
| 3507 | parser_errposition(pstate, |
| 3508 | exprLocation((Node *) onConflictClause)))); |
| 3509 | |
| 3510 | /* Same applies to table used by logical decoding as catalog table */ |
| 3511 | if (RelationIsUsedAsCatalogTable(pstate->p_target_relation)) |
| 3512 | ereport(ERROR, |
| 3513 | (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), |
| 3514 | errmsg("ON CONFLICT is not supported on table \"%s\" used as a catalog table", |
| 3515 | RelationGetRelationName(pstate->p_target_relation)), |
| 3516 | parser_errposition(pstate, |
| 3517 | exprLocation((Node *) onConflictClause)))); |
| 3518 | |
| 3519 | /* ON CONFLICT DO NOTHING does not require an inference clause */ |
| 3520 | if (infer) |
| 3521 | { |
| 3522 | if (infer->indexElems) |
| 3523 | *arbiterExpr = resolve_unique_index_expr(pstate, infer, |
| 3524 | pstate->p_target_relation); |
| 3525 | |
| 3526 | /* |
| 3527 | * Handling inference WHERE clause (for partial unique index |
| 3528 | * inference) |
| 3529 | */ |
| 3530 | if (infer->whereClause) |
| 3531 | *arbiterWhere = transformExpr(pstate, infer->whereClause, |
| 3532 | EXPR_KIND_INDEX_PREDICATE); |
| 3533 | |
| 3534 | /* |
| 3535 | * If the arbiter is specified by constraint name, get the constraint |
| 3536 | * OID and mark the constrained columns as requiring SELECT privilege, |
no test coverage detected