diff options
author | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-04-03 17:33:05 -0300 |
---|---|---|
committer | Alvaro Herrera <alvherre@alvh.no-ip.org> | 2015-04-03 17:33:05 -0300 |
commit | 9550e8348b7965715789089555bb5a3fda8c269c (patch) | |
tree | 97ae0663caae7308e8f7f87f5647783ac2387647 /src/backend/parser/parse_utilcmd.c | |
parent | 4ff695b17d32a9c330952192dbc789d31a5e2f5e (diff) | |
download | postgresql-9550e8348b7965715789089555bb5a3fda8c269c.tar.gz postgresql-9550e8348b7965715789089555bb5a3fda8c269c.zip |
Transform ALTER TABLE/SET TYPE/USING expr during parse analysis
This lets later stages have access to the transformed expression; in
particular it allows DDL-deparsing code during event triggers to pass
the transformed expression to ruleutils.c, so that the complete command
can be deparsed.
This shuffles the timing of the transform calls a bit: previously,
nothing was transformed during parse analysis, and only the
RELKIND_RELATION case was being handled during execution. After this
patch, all expressions are transformed during parse analysis (including
those for relkinds other than RELATION), and the error for other
relation kinds is thrown only during execution. So we do more work than
before to reject some bogus cases. That seems acceptable.
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r-- | src/backend/parser/parse_utilcmd.c | 40 |
1 files changed, 37 insertions, 3 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index 1bbed9582c9..1fc8c2cbe1e 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -2372,6 +2372,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, List *newcmds = NIL; bool skipValidation = true; AlterTableCmd *newcmd; + RangeTblEntry *rte; /* * We must not scribble on the passed-in AlterTableStmt, so copy it. (This @@ -2382,10 +2383,17 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, /* 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) { @@ -2413,8 +2421,8 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, /* * 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) { @@ -2446,6 +2454,7 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, newcmds = lappend(newcmds, cmd); break; } + case AT_AddConstraint: /* @@ -2472,6 +2481,31 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt, 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; |