

# 为 RDS for PostgreSQL 创建 TLE 扩展
<a name="PostgreSQL_trusted_language_extension-creating-TLE-extensions"></a>

您可以将使用 TLE 创建的任何扩展安装在安装了 `pg_tle` 扩展的任何 RDS for PostgreSQL 数据库实例中。`pg_tle` 扩展的范围限于安装该扩展的 PostgreSQL 数据库。使用 TLE 创建的扩展的范围限于同一个数据库。

使用各种 `pgtle` 函数安装构成 TLE 扩展的代码。以下可信语言扩展函数全部需要 `pgtle_admin` 角色。
+ [pgtle.install\$1extension](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.install_extension)
+ [pgtle.install\$1update\$1path](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.install_update_path)
+ [pgtle.register\$1feature](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.register_feature)
+ [pgtle.register\$1feature\$1if\$1not\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.register_feature_if_not_exists)
+ [pgtle.set\$1default\$1version](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.set_default_version)
+ [pgtle.uninstall\$1extension(name)](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_extension-name)
+ [pgtle.uninstall\$1extension(name, version)](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_extension-name-version)
+ [pgtle.uninstall\$1extension\$1if\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_extension_if_exists)
+ [pgtle.uninstall\$1update\$1path](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_update_path)
+ [pgtle.uninstall\$1update\$1path\$1if\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.uninstall_update_path_if_exists)
+ [pgtle.unregister\$1feature](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.unregister_feature)
+ [pgtle.unregister\$1feature\$1if\$1exists](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.unregister_feature_if_exists)

## 示例：使用 SQL 创建可信语言扩展
<a name="PostgreSQL_trusted_language_extension-simple-example"></a>

以下示例说明如何创建名为 `pg_distance` 的 TLE 扩展，该扩展包含一些 SQL 函数，用于使用不同的公式计算距离。在列表中，您可以找到用于计算曼哈顿距离的函数和用于计算欧几里得距离的函数。有关这些公式之间差异的更多信息，请参阅维基百科中的 [Taxicab 几何](https://en.wikipedia.org/wiki/Taxicab_geometry)和[欧几里得几何](https://en.wikipedia.org/wiki/Euclidean_geometry)。

如果您按照[在 RDS for PostgreSQL 数据库实例中设置可信语言扩展](PostgreSQL_trusted_language_extension-setting-up.md)中详述设置了 `pg_tle` 扩展，则可以在自己的 RDS for PostgreSQL 数据库实例中使用此示例。

**注意**  
您需要拥有 `pgtle_admin` 角色的权限才能执行此过程。

**创建示例 TLE 扩展**

以下步骤使用名为 `labdb` 的示例数据库。该数据库归 `postgres` 主用户所有。`postgres` 角色还具有 `pgtle_admin` 角色的权限。

1. 使用 `psql` 连接到 RDS for PostgreSQL 数据库实例。

   ```
   psql --host=db-instance-123456789012.aws-region.rds.amazonaws.com
   --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 通过复制以下代码并将其粘贴到 `psql` 会话控制台中来创建名为 `pg_distance` 的 TLE 扩展。

   ```
   SELECT pgtle.install_extension
   (
    'pg_distance',
    '0.1',
     'Distance functions for two points',
   $_pg_tle_$
       CREATE FUNCTION dist(x1 float8, y1 float8, x2 float8, y2 float8, norm int)
       RETURNS float8
       AS $$
         SELECT (abs(x2 - x1) ^ norm + abs(y2 - y1) ^ norm) ^ (1::float8 / norm);
       $$ LANGUAGE SQL;
   
       CREATE FUNCTION manhattan_dist(x1 float8, y1 float8, x2 float8, y2 float8)
       RETURNS float8
       AS $$
         SELECT dist(x1, y1, x2, y2, 1);
       $$ LANGUAGE SQL;
   
       CREATE FUNCTION euclidean_dist(x1 float8, y1 float8, x2 float8, y2 float8)
       RETURNS float8
       AS $$
         SELECT dist(x1, y1, x2, y2, 2);
       $$ LANGUAGE SQL;
   $_pg_tle_$
   );
   ```

   您将看到如下输出。

   ```
   install_extension
   ---------------
    t
   (1 row)
   ```

   构成 `pg_distance` 扩展的构件现在已安装在您的数据库中。这些构件包括扩展的控制文件和代码，这些项目需要存在，这样才能使用 `CREATE EXTENSION` 命令创建扩展。换句话说，您仍然需要创建扩展以使其函数可供数据库用户使用。

1. 要创建扩展，请像使用任何其他扩展一样使用 `CREATE EXTENSION` 命令。与其他扩展一样，数据库用户需要在数据库中拥有 `CREATE` 权限。

   ```
   CREATE EXTENSION pg_distance;
   ```

1. 要测试 `pg_distance` TLE 扩展，可以使用它来计算四个点之间的[曼哈顿距离](https://en.wikipedia.org/wiki/Taxicab_geometry)。

   ```
   labdb=> SELECT manhattan_dist(1, 1, 5, 5);
   8
   ```

   要计算同一组点之间的[欧几里得距离](https://en.wikipedia.org/wiki/Euclidean_geometry)，可以使用以下方法。

   ```
   labdb=> SELECT euclidean_dist(1, 1, 5, 5);
   5.656854249492381
   ```

`pg_distance` 扩展将函数加载到数据库中，并使对数据库具有权限的任何用户都可以使用它们。

## 修改您的 TLE 扩展
<a name="PostgreSQL_trusted_language_extension-simple-example.modify"></a>

要提高此 TLE 扩展中打包的函数的查询性能，请在其规范中添加以下两个 PostgreSQL 属性。
+ `IMMUTABLE` – `IMMUTABLE` 属性可确保查询优化程序可以使用优化措施来缩短查询响应时间。有关更多信息，请参阅 PostgreSQL 文档中的[函数波动性类别](https://www.postgresql.org/docs/current/xfunc-volatility.html)。
+ `PARALLEL SAFE` – `PARALLEL SAFE` 属性是允许 PostgreSQL 在并行模式下运行该函数的另一个属性。有关更多信息，请参阅 PostgreSQL 文档中的 [CREATE FUNCTION](https://www.postgresql.org/docs/current/sql-createfunction.html)。

在以下示例中，您可以看到如何使用 `pgtle.install_update_path` 函数向每个函数添加这些属性，以创建 `pg_distance` TLE 扩展的版本 `0.2`。有关此函数的更多信息，请参阅 [pgtle.install\$1update\$1path](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.install_update_path)。您需要拥有 `pgtle_admin` 角色才能执行此任务。

**更新现有 TLE 扩展并指定默认版本**

1. 使用 `psql` 或其他客户端工具（例如 pgAdmin）连接到 RDS for PostgreSQL 数据库实例。

   ```
   psql --host=db-instance-123456789012.aws-region.rds.amazonaws.com
   --port=5432 --username=postgres --password --dbname=labdb
   ```

1. 通过复制以下代码并将其粘贴到 `psql` 会话控制台中来修改现有 TLE 扩展。

   ```
   SELECT pgtle.install_update_path
   (
    'pg_distance',
    '0.1',
    '0.2',
   $_pg_tle_$
       CREATE OR REPLACE FUNCTION dist(x1 float8, y1 float8, x2 float8, y2 float8, norm int)
       RETURNS float8
       AS $$
         SELECT (abs(x2 - x1) ^ norm + abs(y2 - y1) ^ norm) ^ (1::float8 / norm);
       $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
   
       CREATE OR REPLACE FUNCTION manhattan_dist(x1 float8, y1 float8, x2 float8, y2 float8)
       RETURNS float8
       AS $$
         SELECT dist(x1, y1, x2, y2, 1);
       $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
   
       CREATE OR REPLACE FUNCTION euclidean_dist(x1 float8, y1 float8, x2 float8, y2 float8)
       RETURNS float8
       AS $$
         SELECT dist(x1, y1, x2, y2, 2);
       $$ LANGUAGE SQL IMMUTABLE PARALLEL SAFE;
   $_pg_tle_$
   );
   ```

   您看到的响应与以下内容类似。

   ```
   install_update_path
   ---------------------
    t
   (1 row)
   ```

   您可以将此版本的扩展设置为默认版本，这样，数据库用户在其数据库中创建或更新扩展时就不必指定版本。

1. 要将 TLE 扩展的修改版本（版本 0.2）指定为默认版本，请使用以下示例所示的 `pgtle.set_default_version` 函数。

   ```
   SELECT pgtle.set_default_version('pg_distance', '0.2');
   ```

   有关此函数的更多信息，请参阅 [pgtle.set\$1default\$1version](PostgreSQL_trusted_language_extension-functions-reference.md#pgtle.set_default_version)。

1. 代码准备就绪后，您可以使用 `ALTER EXTENSION ... UPDATE` 命令以常规方式更新已安装的 TLE 扩展，如此处所示：

   ```
   ALTER EXTENSION pg_distance UPDATE;
   ```