# 10.2.操作员

运算符表达式引用的特定运算符使用以下步骤确定。请注意,此过程间接受到所涉及运算符的优先级的影响,因为这将确定哪些子表达式是哪些运算符的输入。看见第4.1.6节了解更多信息。

运算符类型解析

  1. 从列表中选择要考虑的操作员pg_操作员系统目录。如果使用了非模式限定的运算符名称(通常情况下),则考虑的运算符是那些具有匹配名称和参数计数的运算符,它们在当前搜索路径中可见(请参阅)第5.9.3节)。如果给定了限定运算符名称,则只考虑指定架构中的运算符。

    1. 如果搜索路径找到具有相同参数类型的多个运算符,则只考虑路径中最早出现的运算符。无论搜索路径位置如何,具有不同参数类型的运算符都会被平等地考虑。
  2. 检查是否有完全接受输入参数类型的运算符。如果存在一个(在考虑的运算符集中只能有一个精确匹配),请使用它。当通过限定名呼叫时,缺少精确匹配会造成安全隐患[9](不典型),在允许不受信任的用户创建对象的模式中找到的任何运算符。在这种情况下,可以使用参数强制进行精确匹配。

    1. 如果二进制运算符调用的一个参数为未知的类型,然后假设它与此检查的另一个参数的类型相同。涉及两个未知的输入,或带有未知的输入时,将永远无法在此步骤中找到匹配项。

    2. 如果二进制运算符调用的一个参数为未知的类型,另一个是域类型,接下来检查两边是否有一个操作符完全接受域的基本类型;如果是,就用它。

  3. 寻找最佳匹配。

    1. 放弃输入类型不匹配且无法转换(使用隐式转换)以匹配的候选运算符。未知的为了这个目的,文字被认为可以转换成任何东西。如果只剩下一名候选人,就使用它;否则继续下一步。

    2. 如果任何输入参数属于域类型,则在所有后续步骤中将其视为域的基类型。这确保了域的行为与它们的基类型类似,以实现不明确的运算符解析。

    3. 仔细检查所有候选人,并保留那些在输入类型上最精确匹配的候选人。如果没有完全匹配的候选人,则保留所有候选人。如果只剩下一名候选人,就使用它;否则继续下一步。

    4. 浏览所有候选项,并将那些接受首选类型(输入数据类型的类型类别)的候选项保留在需要进行类型转换的大多数位置。保留所有候选人,如果没有人接受首选类型。如果只剩下一名候选人,就使用它;否则继续下一步。

    5. 如果有输入参数未知的,检查其余候选人在这些论点位置接受的类型类别。在每个位置,选择一串类别如果任何候选人接受该类别。(这种对字符串的偏向是适当的,因为未知类型的文字看起来像字符串。)否则,如果所有剩余的候选对象都接受相同的类型类别,请选择该类别;否则就会失败,因为没有更多的线索就无法推断出正确的选择。现在放弃不接受所选类型类别的候选项。此外,如果任何候选者接受该类别中的首选类型,则放弃接受该参数的非首选类型的候选者。如果没有人通过这些测试,就保留所有候选人。如果只剩下一名候选人,就使用它;否则继续下一步。

    6. 如果两者都有未知的已知类型参数,所有已知类型参数都具有相同的类型,假设未知的参数也是这种类型的,并检查哪些候选者可以在未知的-论点立场。如果只有一个候选人通过了这项测试,就使用它。否则,失败。

下面是一些例子。

例10.1.平方根算子类型解析

只有一个平方根运算符(前缀|/)在标准目录中定义,并接受类型为双精度.扫描仪会指定一个初始类型的整数对于此查询表达式中的参数:

SELECT |/ 40 AS "square root of 40";
 square root of 40