diff --git a/src/backend/optimizer/prep/preptlist.c b/src/backend/optimizer/prep/preptlist.c index afc733f..277ca8b 100644 *** a/src/backend/optimizer/prep/preptlist.c --- b/src/backend/optimizer/prep/preptlist.c *************** expand_targetlist(List *tlist, int comma *** 306,314 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, atttype, COERCE_IMPLICIT_CAST, -1, - false, false); } else --- 306,314 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, atttype, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } else diff --git a/src/backend/parser/parse_coerce.c b/src/backend/parser/parse_coerce.c index 0bc7dba..c406cea 100644 *** a/src/backend/parser/parse_coerce.c --- b/src/backend/parser/parse_coerce.c *************** *** 34,48 **** static Node *coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit, bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, --- 34,49 ---- static Node *coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location, ! bool hideInputCoercion); static void hide_coercion_node(Node *node); static Node *build_coercion_expression(Node *node, CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location); static Node *coerce_record_to_complex(ParseState *pstate, Node *node, Oid targetTypeId, CoercionContext ccontext, *************** coerce_to_target_type(ParseState *pstate *** 110,117 **** */ result = coerce_type_typmod(result, targettype, targettypmod, ! cformat, location, ! (cformat != COERCE_IMPLICIT_CAST), (result != expr && !IsA(result, Const))); if (expr != origexpr) --- 111,117 ---- */ result = coerce_type_typmod(result, targettype, targettypmod, ! ccontext, cformat, location, (result != expr && !IsA(result, Const))); if (expr != origexpr) *************** coerce_type(ParseState *pstate, Node *no *** 355,361 **** result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! cformat, location, false, false); ReleaseSysCache(baseType); --- 355,362 ---- result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! ccontext, cformat, location, ! false); ReleaseSysCache(baseType); *************** coerce_type(ParseState *pstate, Node *no *** 417,436 **** result = build_coercion_expression(node, pathtype, funcId, baseTypeId, baseTypeMod, ! cformat, location, ! (cformat != COERCE_IMPLICIT_CAST)); /* * If domain, coerce to the domain type and relabel with domain ! * type ID. We can skip the internal length-coercion step if the ! * selected coercion function was a type-and-length coercion. */ if (targetTypeId != baseTypeId) result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! cformat, location, true, ! exprIsLengthCoercion(result, ! NULL)); } else { --- 418,434 ---- result = build_coercion_expression(node, pathtype, funcId, baseTypeId, baseTypeMod, ! ccontext, cformat, location); /* * If domain, coerce to the domain type and relabel with domain ! * type ID, hiding the previous coercion node. */ if (targetTypeId != baseTypeId) result = coerce_to_domain(result, baseTypeId, baseTypeMod, targetTypeId, ! ccontext, cformat, location, ! true); } else { *************** coerce_type(ParseState *pstate, Node *no *** 444,450 **** * then we won't need a RelabelType node. */ result = coerce_to_domain(node, InvalidOid, -1, targetTypeId, ! cformat, location, false, false); if (result == node) { /* --- 442,449 ---- * then we won't need a RelabelType node. */ result = coerce_to_domain(node, InvalidOid, -1, targetTypeId, ! ccontext, cformat, location, ! false); if (result == node) { /* *************** can_coerce_type(int nargs, Oid *input_ty *** 636,654 **** * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller * has not bothered to look this up) * 'typeId': target type to coerce to ! * 'cformat': coercion format * 'location': coercion request location * 'hideInputCoercion': if true, hide the input coercion under this one. - * 'lengthCoercionDone': if true, caller already accounted for length, - * ie the input is already of baseTypMod as well as baseTypeId. * * If the target type isn't a domain, the given 'arg' is returned as-is. */ Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionForm cformat, int location, ! bool hideInputCoercion, ! bool lengthCoercionDone) { CoerceToDomain *result; --- 635,651 ---- * 'baseTypeMod': base type typmod of domain, if known (pass -1 if caller * has not bothered to look this up) * 'typeId': target type to coerce to ! * 'ccontext': context indicator to control coercions ! * 'cformat': coercion display format * 'location': coercion request location * 'hideInputCoercion': if true, hide the input coercion under this one. * * If the target type isn't a domain, the given 'arg' is returned as-is. */ Node * coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionContext ccontext, CoercionForm cformat, int location, ! bool hideInputCoercion) { CoerceToDomain *result; *************** coerce_to_domain(Node *arg, Oid baseType *** 677,690 **** * would be safe to do anyway, without lots of knowledge about what the * base type thinks the typmod means. */ ! if (!lengthCoercionDone) ! { ! if (baseTypeMod >= 0) ! arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod, ! COERCE_IMPLICIT_CAST, location, ! (cformat != COERCE_IMPLICIT_CAST), ! false); ! } /* * Now build the domain coercion node. This represents run-time checking --- 674,682 ---- * would be safe to do anyway, without lots of knowledge about what the * base type thinks the typmod means. */ ! arg = coerce_type_typmod(arg, baseTypeId, baseTypeMod, ! ccontext, COERCE_IMPLICIT_CAST, location, ! false); /* * Now build the domain coercion node. This represents run-time checking *************** coerce_to_domain(Node *arg, Oid baseType *** 714,724 **** * The caller must have already ensured that the value is of the correct * type, typically by applying coerce_type. * ! * cformat determines the display properties of the generated node (if any), ! * while isExplicit may affect semantics. If hideInputCoercion is true ! * *and* we generate a node, the input node is forced to IMPLICIT display ! * form, so that only the typmod coercion node will be visible when ! * displaying the expression. * * NOTE: this does not need to work on domain types, because any typmod * coercion for a domain is considered to be part of the type coercion --- 706,719 ---- * The caller must have already ensured that the value is of the correct * type, typically by applying coerce_type. * ! * ccontext may affect semantics, depending on whether the length coercion ! * function pays attention to the isExplicit flag it's passed. ! * ! * cformat determines the display properties of the generated node (if any). ! * ! * If hideInputCoercion is true *and* we generate a node, the input node is ! * forced to IMPLICIT display form, so that only the typmod coercion node will ! * be visible when displaying the expression. * * NOTE: this does not need to work on domain types, because any typmod * coercion for a domain is considered to be part of the type coercion *************** coerce_to_domain(Node *arg, Oid baseType *** 726,733 **** */ static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit, bool hideInputCoercion) { CoercionPathType pathtype; Oid funcId; --- 721,729 ---- */ static Node * coerce_type_typmod(Node *node, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location, ! bool hideInputCoercion) { CoercionPathType pathtype; Oid funcId; *************** coerce_type_typmod(Node *node, Oid targe *** 749,756 **** node = build_coercion_expression(node, pathtype, funcId, targetTypeId, targetTypMod, ! cformat, location, ! isExplicit); } return node; --- 745,751 ---- node = build_coercion_expression(node, pathtype, funcId, targetTypeId, targetTypMod, ! ccontext, cformat, location); } return node; *************** build_coercion_expression(Node *node, *** 799,806 **** CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionForm cformat, int location, ! bool isExplicit) { int nargs = 0; --- 794,801 ---- CoercionPathType pathtype, Oid funcId, Oid targetTypeId, int32 targetTypMod, ! CoercionContext ccontext, CoercionForm cformat, ! int location) { int nargs = 0; *************** build_coercion_expression(Node *node, *** 865,871 **** -1, InvalidOid, sizeof(bool), ! BoolGetDatum(isExplicit), false, true); --- 860,866 ---- -1, InvalidOid, sizeof(bool), ! BoolGetDatum(ccontext == COERCION_EXPLICIT), false, true); *************** build_coercion_expression(Node *node, *** 893,899 **** */ acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ ! acoerce->isExplicit = isExplicit; acoerce->coerceformat = cformat; acoerce->location = location; --- 888,894 ---- */ acoerce->resulttypmod = (nargs >= 2) ? targetTypMod : -1; /* resultcollid will be set by parse_collate.c */ ! acoerce->isExplicit = (ccontext == COERCION_EXPLICIT); acoerce->coerceformat = cformat; acoerce->location = location; diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 6b79c69..a2841d2 100644 *** a/src/backend/rewrite/rewriteHandler.c --- b/src/backend/rewrite/rewriteHandler.c *************** rewriteTargetListIU(List *targetList, *** 875,883 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, COERCE_IMPLICIT_CAST, -1, - false, false); } } --- 875,883 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } } *************** rewriteValuesRTE(RangeTblEntry *rte, Rel *** 1271,1279 **** new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, COERCE_IMPLICIT_CAST, -1, - false, false); } newList = lappend(newList, new_expr); --- 1271,1279 ---- new_expr = coerce_to_domain(new_expr, InvalidOid, -1, att_tup->atttypid, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } newList = lappend(newList, new_expr); diff --git a/src/backend/rewrite/rewriteManip.c b/src/backend/rewrite/rewriteManip.c index ba706b2..d962ae3 100644 *** a/src/backend/rewrite/rewriteManip.c --- b/src/backend/rewrite/rewriteManip.c *************** ReplaceVarsFromTargetList_callback(Var * *** 1429,1437 **** var->varcollid), InvalidOid, -1, var->vartype, COERCE_IMPLICIT_CAST, -1, - false, false); } elog(ERROR, "could not find replacement targetlist entry for attno %d", --- 1429,1437 ---- var->varcollid), InvalidOid, -1, var->vartype, + COERCION_IMPLICIT, COERCE_IMPLICIT_CAST, -1, false); } elog(ERROR, "could not find replacement targetlist entry for attno %d", diff --git a/src/include/parser/parse_coerce.h b/src/include/parser/parse_coerce.h index 06f6529..e560f0c 100644 *** a/src/include/parser/parse_coerce.h --- b/src/include/parser/parse_coerce.h *************** extern Node *coerce_type(ParseState *pst *** 48,56 **** CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionForm cformat, int location, ! bool hideInputCoercion, ! bool lengthCoercionDone); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName); --- 48,55 ---- CoercionContext ccontext, CoercionForm cformat, int location); extern Node *coerce_to_domain(Node *arg, Oid baseTypeId, int32 baseTypeMod, Oid typeId, ! CoercionContext ccontext, CoercionForm cformat, int location, ! bool hideInputCoercion); extern Node *coerce_to_boolean(ParseState *pstate, Node *node, const char *constructName);