概述
SQL 是强类型语言。也就是说,每个数据都与一个决定其行为和用法的数据类型相关联。OushuDB 有一个可扩大的数据类型零碎,该零碎比其它 SQL 实现更具通用性和灵活性。因而,OushuDB 中大多数类型转换是由通用规定来治理的,而不是由专门的试探法剖析的,这种做法容许应用混合类型的表达式,即使是其中蕴含用户定义的类型也如此。
OushuDB 扫描 / 分析器只将词法元素分解成五个根本品种:整数、浮点数、字符串、标识符、关键字。大多数非数字类型首先表征为字符串,SQL 语言定义容许申明字符串的类型名,而且这种机制能够用于 OushuDB 保障分析器沿着正确的方向运行。例如,查问:
SELECT text ‘Origin’ AS “label”, point ‘(0,0)’ AS “value”;label | value——–+——-Origin | (0,0)(1 row)
有两个文本常量,类型别离为 text 和 point。如果没有为字符串文本申明类型,该文本先被初始化成一个领有存储空间的 unknown 类型,该类型将在前面形容的早期阶段剖析。
在 OushuDB 分析器里,有四种根本的 SQL 元素须要独立的类型转换规定:
函数调用
少数 OushuDB 类型零碎是建设在一套丰盛的函数上的。函数调用能够有一个或多个参数。因为 OushuDB 容许函数重载,所以函数名本身并不惟一地标识将要调用的函数,分析器必须依据函数提供的参数类型抉择正确的函数。
操作符
OushuDB 容许在表达式上应用前缀或后缀(单目) 操作符,也容许表达式外部应用双目操作符 (两个参数)。像函数一样,操作符也能够被重载,因而操作符的抉择也和函数一样取决于参数类型。
值存储
INSERT 和 UPDATE 语句将表达式后果放入表中。语句中的表达式类型必须和指标列的类型统一或者能够转换为统一。
UNION, CASE 和相干结构
因为联结 SELECT 语句中的所有查问后果必须在一列里显示进去,所以每个 SELECT 子句中的元素类型必须互相匹配并转换成一套对立类型。相似地,一个 CASE 结构的后果表达式必须转换成对立的类型,这样 CASE 表达式本身作为整体有一种已知输入类型。同样的要求也存在于 ARRAY 结构中。
零碎表 casts 存储无关哪种数据类型之间存在哪种转换以及如何执行这些转换的信息。额定的转换能够由用户通过 CREATE CAST 命令减少。(这个通常和定义一种新的数据类型一起实现。内置的类型转换集曾经通过认真的雕刻了,因而最好不要去更改它们。)
分析器中还提供了一个额定的搜索器,容许进步对有隐含转换的类型组之间的适当的转换行为的决断。数据类型分成了几个根本 类型分类,包含:boolean, numeric, string, bitstring, datetime, timespan, geometric, network, user-defined(用户定义)。每种类型 (除用户定义) 都有一种或多种 首选类型 用于解决类型抉择的问题。因而歧义的表达式(那些有多个候选解析计划的)当有多个内置类型时能够解决,然而用户定义的类型有多个抉择时会产生谬误。
所有类型转换规定都是建设在上面几个根本原则上的:
● 隐含转换决不能有奇怪的或不可预感的输入。
● 解析器没有 先验 常识的用户定义类型应该是“较高的”类型等级。在混合类型表达式中,本地类型总应该转换为用户定义的类型 (当然,只有转换是必要的)。
● 用户定义的类型是不相干的。当初,除了内置类型的硬编码启发式和可用函数和转换的隐式关系外,OushuDB 没有类型之间关系的可用信息。
● 如果一个查问不须要隐含的类型转换,分析器或执行器不应该进行更多的额定操作。这就是说,任何一个类型匹配、格局清晰的查问不应该在分析器里消耗更多的工夫,也不应该向查问中引入任何不必要的隐含类型转换调用。
另外,如果一个查问通常应用某个函数进行隐含类型转换,而用户定义了一个有正确参数的函数,解释器应该应用新函数取代原先旧函数的隐含操作。