DEV Community

Mohamed Mokhtar
Mohamed Mokhtar

Posted on

Introduction to PNSI and its relation to RTE and ability to Replace it? Can it be done or not?

What is PNSI?

PNSI stands for Parse Namespace Item. It is a struct defined in src/parse_node.h file, What exactly it does and what is the purpose of it. Literally from its name we can consider it as a part of a larger group as it is an item. so that we are having a ParseNameSpace [List] consists of multiple entries of that Item. Okay what is that list and what is that item; That list of ParseNameSpaceItem is a part of another struct called ParseState, so if we want to understand what is parsenamepsaceitem is we must understand what is the list of it and understand what is the container of that list (ParseState).

ParseState

Definition: State information used during parse analysis, i.e. during the parsing phase we need to keep our state within the memory, the data structure used for that is called ParseState

ParseNamespaceItem List (p_namespace)

It is a field within the ParseState it considered as a part of it that list is used to describe and operate in the parsing phase; its purpose is?
We can say it is list of ParseNamespaceItems that represents the current namespace for table and column lookup
(The RTEs listed here may be just subset of the whole rtable.

Another ParseNamespaceItem inside ParseState

p_target_nsitem: target relation's ParseNamespaceItem.

Query Parsing revision

The query parsing process involves converting a query string into a tree-like structure called a parse tree
Each node in the parse tree represents a component of the query, such as a table name, a column name, or a join condition.

Postgres Namespace

In PostgreSQL, the namespace is a collection of objects such as tables, views, functions, and types that are available in the current scope of a query or transaction.

There are several namespaces in PostgreSQL, each with a specific purpose. The most commonly used namespaces are:

  • pg_catalog: This namespace contains the system catalogs and other system objects that are required for PostgreSQL to function properly. These objects are always available in any database, and their names are reserved keywords that cannot be used for user-defined objects.

  • public: This is the default namespace for user-defined

ParseNameSpaceItem

We have said it is a representation of the current namespace for table and column lookup. The ParseNameSpaceItem (PNSI) is a parse node that represents an item in the namespace, which is a collection of objects such as tables, views, and functions that are available in the current scope of the query. The PNSI node is used to reference these objects within the query.

PNSI in action example

Suppose we have a database with a table called employees, which has columns id, name, and salary. We want to retrieve the name and salary of all employees with a salary greater than 50000. We can write this query as follows
SELECT name, salary
FROM employees
WHERE salary > 50000;

When PostgreSQL parses this query, it creates a parse tree that represents the various components of the query. That is represented within a ParseState and that parse state contains p_namespace which is related to the namespace of the query. The parse tree (ParseState) includes a PNSI node for the employees table, which contains information about the table, such as its name and columns

What actually the ParseNamespaceItem is? (PG13)

struct ParseNamespaceItem
{
    RangeTblEntry *p_rte;       /* The relation's rangetable entry */
    int         p_rtindex;      /* The relation's index in the rangetable */
    /* array of same length as p_rte->eref->colnames: */
    ParseNamespaceColumn *p_nscolumns;  /* per-column data */
    bool        p_rel_visible;  /* Relation name is visible? */
    bool        p_cols_visible; /* Column names visible as unqualified refs? */
    bool        p_lateral_only; /* Is only visible to LATERAL expressions? */
    bool        p_lateral_ok;   /* If so, does join type allow use? */
};
Enter fullscreen mode Exit fullscreen mode

In the other side of

typedef struct ParseNamespaceItem
{
    RangeTblEntry *p_rte;       /* The relation's rangetable entry */
    bool        p_rel_visible;  /* Relation name is visible? */
    bool        p_cols_visible; /* Column names visible as unqualified refs? */
    bool        p_lateral_only; /* Is only visible to LATERAL expressions? */
    bool        p_lateral_ok;   /* If so, does join type allow use? */
} ParseNamespaceItem;
Enter fullscreen mode Exit fullscreen mode

We notice that the following fields are added on PG13

    int         p_rtindex;      /* The relation's index in the rangetable */
    /* array of same length as p_rte->eref->colnames: */
    ParseNamespaceColumn *p_nscolumns;  /* per-column data */
Enter fullscreen mode Exit fullscreen mode

(USING THE PNSI)
During query analysis, the parser checks that all references to the employees table are valid and that the referenced columns (name and salary) exist and have the correct data types. It also checks that the salary column has a data type that can be compared to the integer literal 50000

If the query passes this analysis, the parser generates an execution plan that uses the PNSI node to retrieve the data from the employees table. The execution plan might involve scanning the table to find all rows where the salary column has a value greater than 50000, and then projecting the name and salary columns from those rows

Overall, the PNSI node is used in this query to reference the employees table and its columns, and to ensure that the query is syntactically and semantically valid.

So that we conclude the PNSI is used in the parse state during the parsing phase and also during the execution phase.

Similarity and differences between both RTE and PNSI

PNSI is a parse state and execution state usage-wise element
while RTE is being used within the Query processing [building the query tree]

Can PNSI replace RTE? As long as having the PNSI got RTE within it inside it's definition I think it is can be replaced but with having something letting us know we are just by-pass that or containerizing the RTE with PNSI to unify the signature for example?
The ParseNamespaceItem (PNSI) and RangeTblEntry (RTE) are both important components of PostgreSQL's query parsing and execution process, but they serve different purposes and cannot be directly replaced with each other.

The PNSI node is used to represent an item in the namespace, which is a collection of objects such as tables, views, and functions that are available in the current scope of the query. The PNSI node contains information about the referenced object, including its name, type, and definition.

The RTE, on the other hand, is used to represent a table or subquery in the query's range table. The range table is a list of tables and subqueries that are referenced in the query, along with their aliases and join clauses. The RTE contains information about the table or subquery, such as its name, columns, and join clauses.

During query analysis, PostgreSQL creates a PNSI node for each item in the namespace and a corresponding RTE for each table or subquery in the range table. The PNSI node is used to resolve references to objects in the namespace, while the RTE is used to generate the query execution plan.

In other words, the PNSI and RTE nodes are complementary and work together to enable PostgreSQL to resolve references to objects and generate an execution plan for the query. They cannot be replaced with each other because they serve different purposes and represent different components of the query.

Can PNSI replace RTE? No.

If you have missed RTE you can check it the last blog
https://dev.to/rrrokhtar/introduction-to-rangetableentry-rte-query-from-postgresql-perspective-150p

Resources & References

Top comments (0)