Course contentsShow
← Databases & SQL
Lesson 882 of 1,9538. PostgreSQL InternalsFree lesson

Using SPI for Query Execution

You will use the Server Programming Interface to perform SQL queries from within C extensions.

Using SPI for Query Execution

In this lesson, you will learn how to bridge the gap between custom C extensions and the PostgreSQL execution engine using the Server Programming Interface (SPI).

While writing extensions in C provides immense performance and flexibility, your code often needs to interact with the database tables themselves. You shouldn't try to read raw data files or bypass the transaction manager; instead, you use the Server Programming Interface (SPI). SPI allows your C code to execute standard SQL commands—SELECT, INSERT, UPDATE, or DELETE—as if they were coming from a client, but entirely within the backend process memory space.

Executing Queries via SPI

To use SPI, your C function must follow a specific lifecycle: initialization, execution, and cleanup.

  1. SPI_connect(): You must first open a connection to the SPI manager. This creates a private execution context for your function.
  2. SPI_execute(): This function takes a SQL command string as an argument. It parses, plans, and executes the query. The result is stored in an SPITUPLTABLE structure, which contains the returned rows.
  3. SPI_finish(): Finally, you must close the connection to clean up resources and release memory.

Consider this simplified snippet that executes a query to count rows in a table:

int count_rows(const char *query) {
    int ret = SPI_connect();
    if (ret != SPI_OK_CONNECT) return -1;

    int res = SPI_execute(query, true, 0);
    int count = SPI_processed; // SPI_processed holds row count of the last query

    SPI_finish();
    return count;
}

By using SPI_execute, you inherit PostgreSQL’s full power: the query planner optimizes your SQL, the security system validates permissions, and the transaction manager ensures ACID compliance. This is far safer and more maintainable than writing your own data access logic.

When building extensions, remember that SPI operations are performed within the current transaction context. If your C function fails or triggers an error, the SPI will automatically handle the transaction abort, ensuring your database remains consistent.

Key Takeaway: The SPI provides a safe, high-level interface for your C extensions to execute SQL commands, allowing you to leverage PostgreSQL’s existing query engine rather than interacting with the storage layer directly.