aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_expr.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2006-06-26 17:24:41 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2006-06-26 17:24:41 +0000
commitca0d2197ca1ed1e72243c5a3466d93e4954d30b0 (patch)
tree504e97d13b6403683d46c8285dfeb66dcc0ed305 /src/backend/parser/parse_expr.c
parent4b98d423d77682308423ed3c4470b741f08f7b23 (diff)
downloadpostgresql-ca0d2197ca1ed1e72243c5a3466d93e4954d30b0.tar.gz
postgresql-ca0d2197ca1ed1e72243c5a3466d93e4954d30b0.zip
Change the row constructor syntax (ROW(...)) so that list elements foo.*
will be expanded to a list of their member fields, rather than creating a nested rowtype field as formerly. (The old behavior is still available by omitting '.*'.) This syntax is not allowed by the SQL spec AFAICS, so changing its behavior doesn't violate the spec. The new behavior is substantially more useful since it allows, for example, triggers to check for data changes with 'if row(new.*) is distinct from row(old.*)'. Per my recent proposal.
Diffstat (limited to 'src/backend/parser/parse_expr.c')
-rw-r--r--src/backend/parser/parse_expr.c40
1 files changed, 39 insertions, 1 deletions
diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c
index 414afe6dfa5..17d221ac19b 100644
--- a/src/backend/parser/parse_expr.c
+++ b/src/backend/parser/parse_expr.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.192 2006/04/22 01:26:00 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.193 2006/06/26 17:24:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -29,6 +29,7 @@
#include "parser/parse_func.h"
#include "parser/parse_oper.h"
#include "parser/parse_relation.h"
+#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/lsyscache.h"
@@ -1289,6 +1290,43 @@ transformRowExpr(ParseState *pstate, RowExpr *r)
Node *e = (Node *) lfirst(arg);
Node *newe;
+ /*
+ * Check for "something.*". Depending on the complexity of the
+ * "something", the star could appear as the last name in ColumnRef,
+ * or as the last indirection item in A_Indirection.
+ */
+ if (IsA(e, ColumnRef))
+ {
+ ColumnRef *cref = (ColumnRef *) e;
+
+ if (strcmp(strVal(llast(cref->fields)), "*") == 0)
+ {
+ /* It is something.*, expand into multiple items */
+ newargs = list_concat(newargs,
+ ExpandColumnRefStar(pstate, cref,
+ false));
+ continue;
+ }
+ }
+ else if (IsA(e, A_Indirection))
+ {
+ A_Indirection *ind = (A_Indirection *) e;
+ Node *lastitem = llast(ind->indirection);
+
+ if (IsA(lastitem, String) &&
+ strcmp(strVal(lastitem), "*") == 0)
+ {
+ /* It is something.*, expand into multiple items */
+ newargs = list_concat(newargs,
+ ExpandIndirectionStar(pstate, ind,
+ false));
+ continue;
+ }
+ }
+
+ /*
+ * Not "something.*", so transform as a single expression
+ */
newe = transformExpr(pstate, e);
newargs = lappend(newargs, newe);
}