PostgreSQL Internal Subquery Resolution Process

Query Structure

SELECT val FROM (SELECT val FROM source_table);

Internal Representation

  • The derived clause FROM (SELECT val FROM source_table) generates a RangeTblEntry for the enclosing query.
  • The base relation source_table generates a separate RangeTblEntry inside the nested query.
  • All RangeTblEntry instances form a range table list, linked to either Query.rtable or ParseState.p_rtable.
  • The parser also constructs ParseNamespaceItem objects, each mapping to an entity listed in the FROM clause.
  • The inner SELECT command is preserved inside the subquery field of its corresponding RangeTblEntry.

Grammar Evaluation

The semantic action for matching a parenthesized subquery in the FROM clause is defined as:

from_item: subquery_in_parens optional_alias optional_transform
    {
      RangeSubselect *subsel_node = makeNode(RangeSubselect);
      RangeTableRefData *ref_data = (RangeTableRefData *) $3;
      subsel_node->lateral = false;
      subsel_node->subquery_expr = $1;
      subsel_node->alias_name = $2;
      ...
    }
  ;

Unlike typical AST nodes, RangeSubselect processing cannot be located by searching for the T_RangeSubselect node tag dispatch. Instead, tracing the transformFromClause execution path reveals the core transformation routine processSubqueryRange:

static ParseNamespaceItem *
processSubqueryRange(ParseState *state_p, RangeSubselect *range_sub)
{
  /*
   * analyzeSubExpression evaluates range_sub->subquery_expr,
   * corresponding to "SELECT val FROM source_table".
   * state_p acts as the parent ParseState for this nested evaluation.
   */
  Query *parsed_qry = analyzeSubExpression(range_sub->subquery_expr, state_p, ...);

  /*
   * Instantiate a RangeTblEntry and ParseNamespaceItem for the derived table.
   * Upon completion of registerSubqueryEntry, the parent context (state_p)
   * recognizes the subquery characteristics via its p_rtable field, such as:
   * - Query command category
   * - Target column quantity
   * - Inclusion of join operations
   */
  return registerSubqueryEntry(state_p, parsed_qry, range_sub->alias_name, range_sub->lateral, true);
}

Tags: PostgreSQL Database Internals SQL Parsing query optimization

Posted on Thu, 11 Jun 2026 18:24:16 +0000 by Gump