MCPcopy Create free account
hub / github.com/apache/cloudberry / ParseComplexProjection

Function ParseComplexProjection

src/backend/parser/parse_func.c:1966–2033  ·  view source on GitHub ↗

* ParseComplexProjection - * handles function calls with a single argument that is of complex type. * If the function call is actually a column projection, return a suitably * transformed expression tree. If not, return NULL. */

Source from the content-addressed store, hash-verified

1964 * transformed expression tree. If not, return NULL.
1965 */
1966static Node *
1967ParseComplexProjection(ParseState *pstate, const char *funcname, Node *first_arg,
1968 int location)
1969{
1970 TupleDesc tupdesc;
1971 int i;
1972
1973 /*
1974 * Special case for whole-row Vars so that we can resolve (foo.*).bar even
1975 * when foo is a reference to a subselect, join, or RECORD function. A
1976 * bonus is that we avoid generating an unnecessary FieldSelect; our
1977 * result can omit the whole-row Var and just be a Var for the selected
1978 * field.
1979 *
1980 * This case could be handled by expandRecordVariable, but it's more
1981 * efficient to do it this way when possible.
1982 */
1983 if (IsA(first_arg, Var) &&
1984 ((Var *) first_arg)->varattno == InvalidAttrNumber)
1985 {
1986 ParseNamespaceItem *nsitem;
1987
1988 nsitem = GetNSItemByRangeTablePosn(pstate,
1989 ((Var *) first_arg)->varno,
1990 ((Var *) first_arg)->varlevelsup);
1991 /* Return a Var if funcname matches a column, else NULL */
1992 return scanNSItemForColumn(pstate, nsitem,
1993 ((Var *) first_arg)->varlevelsup,
1994 funcname, location);
1995 }
1996
1997 /*
1998 * Else do it the hard way with get_expr_result_tupdesc().
1999 *
2000 * If it's a Var of type RECORD, we have to work even harder: we have to
2001 * find what the Var refers to, and pass that to get_expr_result_tupdesc.
2002 * That task is handled by expandRecordVariable().
2003 */
2004 if (IsA(first_arg, Var) &&
2005 ((Var *) first_arg)->vartype == RECORDOID)
2006 tupdesc = expandRecordVariable(pstate, (Var *) first_arg, 0);
2007 else
2008 tupdesc = get_expr_result_tupdesc(first_arg, true);
2009 if (!tupdesc)
2010 return NULL; /* unresolvable RECORD type */
2011
2012 for (i = 0; i < tupdesc->natts; i++)
2013 {
2014 Form_pg_attribute att = TupleDescAttr(tupdesc, i);
2015
2016 if (strcmp(funcname, NameStr(att->attname)) == 0 &&
2017 !att->attisdropped)
2018 {
2019 /* Success, so generate a FieldSelect expression */
2020 FieldSelect *fselect = makeNode(FieldSelect);
2021
2022 fselect->arg = (Expr *) first_arg;
2023 fselect->fieldnum = i + 1;

Callers 1

ParseFuncOrColumnFunction · 0.85

Calls 4

scanNSItemForColumnFunction · 0.85
expandRecordVariableFunction · 0.85
get_expr_result_tupdescFunction · 0.85

Tested by

no test coverage detected