* Transform one entry in a partition bound spec, producing a constant. */
| 5524 | * Transform one entry in a partition bound spec, producing a constant. |
| 5525 | */ |
| 5526 | Const * |
| 5527 | transformPartitionBoundValue(ParseState *pstate, Node *val, |
| 5528 | const char *colName, Oid colType, int32 colTypmod, |
| 5529 | Oid partCollation) |
| 5530 | { |
| 5531 | Node *value; |
| 5532 | |
| 5533 | /* Transform raw parsetree */ |
| 5534 | value = transformExpr(pstate, val, EXPR_KIND_PARTITION_BOUND); |
| 5535 | |
| 5536 | /* |
| 5537 | * transformExpr() should have already rejected column references, |
| 5538 | * subqueries, aggregates, window functions, and SRFs, based on the |
| 5539 | * EXPR_KIND_ of a partition bound expression. |
| 5540 | */ |
| 5541 | Assert(!contain_var_clause(value)); |
| 5542 | |
| 5543 | /* |
| 5544 | * Coerce to the correct type. This might cause an explicit coercion step |
| 5545 | * to be added on top of the expression, which must be evaluated before |
| 5546 | * returning the result to the caller. |
| 5547 | */ |
| 5548 | value = coerce_to_target_type(pstate, |
| 5549 | value, exprType(value), |
| 5550 | colType, |
| 5551 | colTypmod, |
| 5552 | COERCION_ASSIGNMENT, |
| 5553 | COERCE_IMPLICIT_CAST, |
| 5554 | -1); |
| 5555 | |
| 5556 | if (value == NULL) |
| 5557 | ereport(ERROR, |
| 5558 | (errcode(ERRCODE_DATATYPE_MISMATCH), |
| 5559 | errmsg("specified value cannot be cast to type %s for column \"%s\"", |
| 5560 | format_type_be(colType), colName), |
| 5561 | parser_errposition(pstate, exprLocation(val)))); |
| 5562 | |
| 5563 | /* |
| 5564 | * Evaluate the expression, if needed, assigning the partition key's data |
| 5565 | * type and collation to the resulting Const node. |
| 5566 | */ |
| 5567 | if (!IsA(value, Const)) |
| 5568 | { |
| 5569 | assign_expr_collations(pstate, value); |
| 5570 | value = (Node *) expression_planner((Expr *) value); |
| 5571 | value = (Node *) evaluate_expr((Expr *) value, colType, colTypmod, |
| 5572 | partCollation); |
| 5573 | if (!IsA(value, Const)) |
| 5574 | elog(ERROR, "could not evaluate partition bound expression"); |
| 5575 | } |
| 5576 | else |
| 5577 | { |
| 5578 | /* |
| 5579 | * If the expression is already a Const, as is often the case, we can |
| 5580 | * skip the rather expensive steps above. But we still have to insert |
| 5581 | * the right collation, since coerce_to_target_type doesn't handle |
| 5582 | * that. |
| 5583 | */ |
no test coverage detected