mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 14:01:23 +02:00
ParseComplexProjection should make use of expandRecordVariable so that
it can handle cases like (foo.x).y where foo is a subquery and x is a function-returning-RECORD RTE in that subquery.
This commit is contained in:
parent
12a323b7a8
commit
83b72ee286
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.179 2005/04/23 22:09:58 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.180 2005/05/31 01:03:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -25,6 +25,7 @@
|
|||||||
#include "parser/parse_expr.h"
|
#include "parser/parse_expr.h"
|
||||||
#include "parser/parse_func.h"
|
#include "parser/parse_func.h"
|
||||||
#include "parser/parse_relation.h"
|
#include "parser/parse_relation.h"
|
||||||
|
#include "parser/parse_target.h"
|
||||||
#include "parser/parse_type.h"
|
#include "parser/parse_type.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
#include "utils/fmgroids.h"
|
#include "utils/fmgroids.h"
|
||||||
@ -957,6 +958,9 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
|
|||||||
* function. A bonus is that we avoid generating an unnecessary
|
* function. A bonus is that we avoid generating an unnecessary
|
||||||
* FieldSelect; our result can omit the whole-row Var and just be a
|
* FieldSelect; our result can omit the whole-row Var and just be a
|
||||||
* Var for the selected field.
|
* Var for the selected field.
|
||||||
|
*
|
||||||
|
* This case could be handled by expandRecordVariable, but it's
|
||||||
|
* more efficient to do it this way when possible.
|
||||||
*/
|
*/
|
||||||
if (IsA(first_arg, Var) &&
|
if (IsA(first_arg, Var) &&
|
||||||
((Var *) first_arg)->varattno == InvalidAttrNumber)
|
((Var *) first_arg)->varattno == InvalidAttrNumber)
|
||||||
@ -971,12 +975,18 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Else do it the hard way. Note that if the arg is of RECORD type,
|
* Else do it the hard way with get_expr_result_type().
|
||||||
* and isn't resolvable as a function with OUT params, we will never
|
*
|
||||||
* be able to recognize a column name here.
|
* If it's a Var of type RECORD, we have to work even harder: we have
|
||||||
|
* to find what the Var refers to, and pass that to get_expr_result_type.
|
||||||
|
* That task is handled by expandRecordVariable().
|
||||||
*/
|
*/
|
||||||
if (get_expr_result_type(first_arg, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
if (IsA(first_arg, Var) &&
|
||||||
|
((Var *) first_arg)->vartype == RECORDOID)
|
||||||
|
tupdesc = expandRecordVariable(pstate, (Var *) first_arg, 0);
|
||||||
|
else if (get_expr_result_type(first_arg, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||||
return NULL; /* unresolvable RECORD type */
|
return NULL; /* unresolvable RECORD type */
|
||||||
|
Assert(tupdesc);
|
||||||
|
|
||||||
for (i = 0; i < tupdesc->natts; i++)
|
for (i = 0; i < tupdesc->natts; i++)
|
||||||
{
|
{
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.133 2005/04/25 22:02:30 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.134 2005/05/31 01:03:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -44,8 +44,6 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
|
|||||||
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
|
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
|
||||||
static List *ExpandAllTables(ParseState *pstate);
|
static List *ExpandAllTables(ParseState *pstate);
|
||||||
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
|
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
|
||||||
static TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
|
|
||||||
int levelsup);
|
|
||||||
static int FigureColnameInternal(Node *node, char **name);
|
static int FigureColnameInternal(Node *node, char **name);
|
||||||
|
|
||||||
|
|
||||||
@ -905,7 +903,7 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
|
|||||||
*
|
*
|
||||||
* levelsup is an extra offset to interpret the Var's varlevelsup correctly.
|
* levelsup is an extra offset to interpret the Var's varlevelsup correctly.
|
||||||
*/
|
*/
|
||||||
static TupleDesc
|
TupleDesc
|
||||||
expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
|
expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
|
||||||
{
|
{
|
||||||
TupleDesc tupleDesc;
|
TupleDesc tupleDesc;
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.35 2004/12/31 22:03:38 pgsql Exp $
|
* $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.36 2005/05/31 01:03:23 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -27,6 +27,8 @@ extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle,
|
|||||||
List *indirection);
|
List *indirection);
|
||||||
extern List *checkInsertTargets(ParseState *pstate, List *cols,
|
extern List *checkInsertTargets(ParseState *pstate, List *cols,
|
||||||
List **attrnos);
|
List **attrnos);
|
||||||
|
extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
|
||||||
|
int levelsup);
|
||||||
extern char *FigureColname(Node *node);
|
extern char *FigureColname(Node *node);
|
||||||
|
|
||||||
#endif /* PARSE_TARGET_H */
|
#endif /* PARSE_TARGET_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user