↑↓ 选择 ↵ 打开 ⌫ 改范围 完整检索页

pgsql.cc 提供对 postgresql.org 官网内容的中文翻译,由 Pigsty 团队维护。

不受支持的版本: 6.3
历史版本PostgreSQL 6.3 已于 2003 年 3 月结束社区维护,本页译文保留供仍在使用旧版本的读者参考。新系统请看当前版本手册首页。

第 32 章 扩展 SQL:类型

如前所述,Postgres中有两类 类型:基本类型(用编程语言定义) 和组合类型(实例)。 本节中直到索引接口之前的示例可以在 complex.sql和complex.c中 找到。组合类型的示例 在funcs.sql中。

32.1. 用户定义的类型

32.1.1. 用户定义类型所需的函数

用户定义的类型必须始终具有输入和输出 函数。这些函数决定该类型 在字符串中如何表示(供用户输入和输出给 用户)以及在内存中如何组织。 输入函数接受一个以空字符结尾的字符串 作为输入,并返回该类型的内部(内存中) 表示。输出函数接受该类型的内部表示, 并返回一个以空字符结尾的字符串。 假设我们想定义一个表示复数的 complex 类型。 很自然,我们会选择用下面的C结构在内存中 表示复数:

         typedef struct Complex {
             double      x;
             double      y;
         } Complex;

并选择形如 (x,y) 的字符串作为外部字符串 表示。 这些函数通常不难编写,输出函数尤其如此。 不过,有几点需要记住:

  • 在定义你的外部(字符串)表示时, 请记住:你最终必须为该表示编写一个 完整而健壮的解析器作为输入函数!

                    Complex *
                    complex_in(char *str)
                    {
                        double x, y;
                        Complex *result;
                        if (sscanf(str, " ( [percnt]lf , [percnt]lf )", &x, &y) != 2) {
                            elog(WARN, "complex_in: error in parsing
                            return NULL;
                        }
                        result = (Complex *)palloc(sizeof(Complex));
                        result->x = x;
                        result->y = y;
                        return (result);
                    }
    

    输出函数可以简单地写成:

                    char *
                    complex_out(Complex *complex)
                    {
                        char *result;
                        if (complex == NULL)
                            return(NULL);
                        result = (char *) palloc(60);
                        sprintf(result, "([percnt]g,[percnt]g)", complex->x, complex->y);
                        return(result);
                    }
    
  • 你应当尽量让输入和输出 函数互为逆函数。否则,在你需要 把数据转储到文件中再读回来时(比如读到另一台计算机上 某人的数据库中),就会出现严重的问题。 当涉及浮点数时,这是一个 特别常见的问题。

要定义complex类型,我们需要在创建 类型之前先创建 complex_in 和 complex_out 这两个用户定义的函数:

         CREATE FUNCTION complex_in(opaque)
            RETURNS complex
            AS 'PGROOT/tutorial/obj/complex.so'
            LANGUAGE 'c';

         CREATE FUNCTION complex_out(opaque)
            RETURNS opaque
            AS 'PGROOT/tutorial/obj/complex.so'
            LANGUAGE 'c';

         CREATE TYPE complex (
            internallength = 16,
            input = complex_in,
            output = complex_out
         );

如前面所讨论的,Postgres完全支持 基本类型的数组。此外,Postgres也 支持用户定义类型的数组。当你定义一个类型时, Postgres会自动提供对该类型 数组的支持。由于历史原因,数组类型的名称与 用户定义类型相同,只是在前面加上 下划线字符 _。 组合类型不需要在其上定义任何函数,因为系统 已经知道它们内部是什么样子。

32.1.2. 大对象

到此为止讨论的类型都是"小"对象——也就是说, 它们的大小小于 8KB。

注意

1024 长字 == 8192 字节。实际上,类型必须显著小于 8192 字节, 因为Postgres的元组 和 页开销也必须放进这个 8KB 的限制内。 实际能放下的值取决于机器体系结构。

如果你需要一个更大的类型,比如用于文档检索系统 或存储位图,你将 需要使用Postgres的大对象接口。

提交更正

译文有误、术语不当或页面显示问题,请到译文仓库 pgsty/pgdoc 报告译文问题。 英文原文本身的问题,请在当前版本的对应页面向上游反馈;上游不再修订已结束维护的版本。