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 EXTENSIONis called,pg_tleintercepts the command and determines if a file-based extension exists. If it does,pg_tlereturns execution to PostgreSQL to complete the command. - If no file-based extension exists,
pg_tlethen searches to see if a TLE is registered in the current database.pg_tlechecks to see if a<extension_name>.controlfunction is registered. If it does not find this function,pg_tlepasses through to PostgreSQL to complete execution of the command (which will fail). pg_tleprocesses theCREATE EXTENSIONcommand. If no version is specified,pg_tlewill try to install thedefault_versionof the extension.pg_tlebuilds the "extension install path" and finds all of the registered "version functions". If the extension version functions are not found,pg_tlewill error.pg_tleexecutes 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.