Introduction to PNSI and its relation to RTE and ability to Replace it? Can it be done or not?
Tags: database, postgres, apacheage, programming
Published: 2023-06-09 15:03:10

## 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)
```C
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? */
};
```
In the other side of 
```C
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;
```
We notice that the following fields are added on PG13
```C
	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 */
```

**(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

- https://github.com/apache/age
- https://age.apache.org/
- https://github.com/postgres/postgres/ (Branches 12 and 13)