This section discuses the design principles and architecture of pg_tle
.
pg_tle
follows several design principles that guide decision making and implementation for Trusted Language Extensions. These include:
- Crash safety. Data must be durable and available at all times. Trusted Language Extensions do not crash PostgreSQL servers and disrupt access to data.
- Let developers focus on building apps, not administrating PostgreSQL. Managing a TLE should be frictionless, and any updates to TLE should not break existing TLE extensions.
- Stay within the PostgreSQL security barrier.
- Strike a balance between developer experience and performance.
- Don't reinvent PostgreSQL functionality. Use, expose and extend it.
pg_tle
tries to stay as close to the PostgreSQL extension framework as possible. This is true at all levels, from using the standard PostgreSQL interface for managing extensions (e.g. CREATE EXTENSION
) to the code itself.
The pg_tle
management functions add the ability to load PostgreSQL extensions into the database without access to the filesystem. To do this, pg_tle
stores the relevant extension data in functions within the pgtle
schema. The functions follow the following patterns:
<extension_name>.control
- "control function" -- returns the attributes that are found in a PostgreSQL extension control file<extension_name>--<to-version>.sql
/<extension_name>--<from-version>--<to-version>.sql
- "version function" -- returns the commands to run when installing a specific extension version
pg_tle
uses a ProcessUtility_hook
to intercept certain commands to take certain actions based on if an extension is a TLE or a file-based extension. For all file-based extensions, the ProcessUtility_hook
function falls through and PostgreSQL follows its regular execution path.
Let's look at how pg_tle
processes the CREATE EXTENSION
command:
- When
CREATE EXTENSION
is called,pg_tle
intercepts the command and determines if a file-based extension exists. If it does,pg_tle
returns execution to PostgreSQL to complete the command. - If no file-based extension exists,
pg_tle
then searches to see if a TLE is registered in the current database.pg_tle
checks to see if a<extension_name>.control
function is registered. If it does not find this function,pg_tle
passes through to PostgreSQL to complete execution of the command (which will fail). pg_tle
processes theCREATE EXTENSION
command. If no version is specified,pg_tle
will try to install thedefault_version
of the extension.pg_tle
builds the "extension install path" and finds all of the registered "version functions". If the extension version functions are not found,pg_tle
will error.pg_tle
executes each of the "version functions" required to create the extension at the specified version.
pg_tle
follows similar behavior for the ALTER EXTENSION
command.
pg_tle
has several safeguards to prevent direct modification of the control and version functions, as well as objects within the pgtle
schema.
On the surface, pg_tle
creates its own hook functions that let users define their own SQL-based hook functions. This architectures allows for several features:
- Users can define one or more hook function for the same hook.
- Allow a PostgreSQL user control if a hook is enabled through a configuration parameter (GUC).
- Allow hook functions to be registered in a "features" table,
pgtle.feature_info
. This also allows for creating dependencies on an extension.