Oid baseTypeOid,
int typMod, Constraint *constr,
char *domainName, ObjectAddress *constrAddr);
+static Node *replace_domain_constraint_value(ParseState *pstate,
+ ColumnRef *cref);
/*
domVal->collation = get_typcollation(baseTypeOid);
domVal->location = -1; /* will be set when/if used */
- pstate->p_value_substitute = (Node *) domVal;
+ pstate->p_pre_columnref_hook = replace_domain_constraint_value;
+ pstate->p_ref_hook_state = (void *) domVal;
expr = transformExpr(pstate, constr->raw_expr, EXPR_KIND_DOMAIN_CHECK);
return ccbin;
}
+/* Parser pre_columnref_hook for domain CHECK constraint parsing */
+static Node *
+replace_domain_constraint_value(ParseState *pstate, ColumnRef *cref)
+{
+ /*
+ * Check for a reference to "value", and if that's what it is, replace
+ * with a CoerceToDomainValue as prepared for us by domainAddConstraint.
+ * (We handle VALUE as a name, not a keyword, to avoid breaking a lot of
+ * applications that have used VALUE as a column name in the past.)
+ */
+ if (list_length(cref->fields) == 1)
+ {
+ Node *field1 = (Node *) linitial(cref->fields);
+ char *colname;
+
+ Assert(IsA(field1, String));
+ colname = strVal(field1);
+ if (strcmp(colname, "value") == 0)
+ {
+ CoerceToDomainValue *domVal = copyObject(pstate->p_ref_hook_state);
+
+ /* Propagate location knowledge, if any */
+ domVal->location = cref->location;
+ return (Node *) domVal;
+ }
+ }
+ return NULL;
+}
+
/*
* Execute ALTER TYPE RENAME
/*
* Not known as a column of any range-table entry.
*
- * Consider the possibility that it's VALUE in a domain
- * check expression. (We handle VALUE as a name, not a
- * keyword, to avoid breaking a lot of applications that
- * have used VALUE as a column name in the past.)
- */
- if (pstate->p_value_substitute != NULL &&
- strcmp(colname, "value") == 0)
- {
- node = (Node *) copyObject(pstate->p_value_substitute);
-
- /*
- * Try to propagate location knowledge. This should
- * be extended if p_value_substitute can ever take on
- * other node types.
- */
- if (IsA(node, CoerceToDomainValue))
- ((CoerceToDomainValue *) node)->location = cref->location;
- break;
- }
-
- /*
* Try to find the name as a relation. Note that only
* relations already entered into the rangetable will be
* recognized.
* p_locked_from_parent: true if parent query level applies FOR UPDATE/SHARE
* to this subquery as a whole.
*
- * p_value_substitute: replacement for VALUE references, if we're parsing
- * a domain CHECK constraint.
- *
* p_hasAggs, p_hasWindowFuncs, etc: true if we've found any of the indicated
* constructs in the query.
*
List *p_locking_clause; /* raw FOR UPDATE/FOR SHARE info */
bool p_locked_from_parent; /* parent has marked this subquery
* with FOR UPDATE/FOR SHARE */
- Node *p_value_substitute; /* what to replace VALUE with, if any */
/* Flags telling about things found in the query: */
bool p_hasAggs;