char *colName = cmd->name;
ColumnDef *def = (ColumnDef *) cmd->def;
TypeName *typeName = def->typeName;
- Node *transform = def->raw_default;
+ Node *transform = def->cooked_default;
HeapTuple tuple;
Form_pg_attribute attTup;
AttrNumber attnum;
{
/*
* Set up an expression to transform the old data value to the new
- * type. If a USING option was given, transform and use that
- * expression, else just take the old value and try to coerce it. We
- * do this first so that type incompatibility can be detected before
- * we waste effort, and because we need the expression to be parsed
- * against the original table row type.
+ * type. If a USING option was given, use the expression as transformed
+ * by transformAlterTableStmt, else just take the old value and try to
+ * coerce it. We do this first so that type incompatibility can be
+ * detected before we waste effort, and because we need the expression
+ * to be parsed against the original table row type.
*/
- if (transform)
- {
- RangeTblEntry *rte;
-
- /* Expression must be able to access vars of old table */
- rte = addRangeTableEntryForRelation(pstate,
- rel,
- NULL,
- false,
- true);
- addRTEtoQuery(pstate, rte, false, true, true);
-
- transform = transformExpr(pstate, transform,
- EXPR_KIND_ALTER_COL_TRANSFORM);
-
- /* It can't return a set */
- if (expression_returns_set(transform))
- ereport(ERROR,
- (errcode(ERRCODE_DATATYPE_MISMATCH),
- errmsg("transform expression must not return a set")));
- }
- else
+ if (!transform)
{
transform = (Node *) makeVar(1, attnum,
attTup->atttypid, attTup->atttypmod,
List *newcmds = NIL;
bool skipValidation = true;
AlterTableCmd *newcmd;
+ RangeTblEntry *rte;
/*
* We must not scribble on the passed-in AlterTableStmt, so copy it. (This
/* Caller is responsible for locking the relation */
rel = relation_open(relid, NoLock);
- /* Set up pstate and CreateStmtContext */
+ /* Set up pstate */
pstate = make_parsestate(NULL);
pstate->p_sourcetext = queryString;
+ rte = addRangeTableEntryForRelation(pstate,
+ rel,
+ NULL,
+ false,
+ true);
+ addRTEtoQuery(pstate, rte, false, true, true);
+ /* Set up CreateStmtContext */
cxt.pstate = pstate;
if (stmt->relkind == OBJECT_FOREIGN_TABLE)
{
/*
* The only subtypes that currently require parse transformation handling
- * are ADD COLUMN and ADD CONSTRAINT. These largely re-use code from
- * CREATE TABLE.
+ * are ADD COLUMN, ADD CONSTRAINT and SET DATA TYPE. These largely re-use
+ * code from CREATE TABLE.
*/
foreach(lcmd, stmt->cmds)
{
newcmds = lappend(newcmds, cmd);
break;
}
+
case AT_AddConstraint:
/*
newcmds = lappend(newcmds, cmd);
break;
+ case AT_AlterColumnType:
+ {
+ ColumnDef *def = (ColumnDef *) cmd->def;
+
+ /*
+ * For ALTER COLUMN TYPE, transform the USING clause if
+ * one was specified.
+ */
+ if (def->raw_default)
+ {
+ def->cooked_default =
+ transformExpr(pstate, def->raw_default,
+ EXPR_KIND_ALTER_COL_TRANSFORM);
+
+ /* it can't return a set */
+ if (expression_returns_set(def->cooked_default))
+ ereport(ERROR,
+ (errcode(ERRCODE_DATATYPE_MISMATCH),
+ errmsg("transform expression must not return a set")));
+ }
+
+ newcmds = lappend(newcmds, cmd);
+ break;
+ }
+
default:
newcmds = lappend(newcmds, cmd);
break;