RFC 28:OGR SQL通用表达式

作者:弗兰克·温特丹

联系方式:warmerdam@pobox.com

状态:通过、实施

总结

OGR SQL求值引擎当前不允许将通用函数应用于SELECT语句中的列。支持一些特殊用途的函数(例如CAST、COUNT、AVG、MAX、MIN和SUM),但不作为更通用表达式的一部分,通常在非常受约束的排列中。此工作项的目的是扩展OGR SQL引擎,以便在OGR SQL SELECT语句的输出字段列表中支持相当通用的表达式求值,并以与标准SQL兼容的方式实现一些初步处理函数。此外,WHERE子句中使用的表达式将被泛化,以支持对非逻辑操作(如数学和函数)的求值。例如,在实现之后,可以对以下内容进行评估。

SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM customers
SELECT id, "Regional Road" AS roadtypename FROM roads where roadtype=3
SELECT (subtotal+salestax) as totalcost from invoice_info where 100 <= (subtotal+salestax)

现在可以在中查看原型实现 http://svn.osgeo.org/gdal/sandbox/warmerdam/gdal-rfc28

技术方法

当前逻辑表达式采用非常受约束的格式,基本元素必须是 * <constant_value>* . 作为泛化的一部分,将支持非逻辑表达式,并平等对待运算符的左侧和右侧。当前的OGR SQL解析器是临时的,实际上不能扩展到这种通用的表达式形式。因此,现在我们将转到基于yacc/bison的表达式语法分析器。

由于当SELECT语句的一部分是表达式时,继续使用现有的特殊SELECT解析并不实际,因此也将使用基于yacc/bison的解析器来解析整个SELECT语句。

当前表达式节点将被泛化为具有0-n个子节点(用于函数的参数),并将字段引用和常量值视为不同的叶节点,而不是将此信息嵌入定义操作的节点中。

应该注意的是,作为一种副作用,从句也将支持更一般的表达式,而不仅仅是逻辑比较。例如:

SELECT * 其中(小计+营业税)>100.0

新功能

  • 数学:+,-, * , /, * *

  • 字符串:CONCAT,SUBSTR

选择规则

SELECT <field-list> FROM <table_def>
     [LEFT JOIN <table_def>
      ON [<table_ref>.]<key_field> = [<table_ref>.].<key_field>]*
     [WHERE <where-expr>]
     [ORDER BY <sort specification list>]

<field-list> ::= <column-spec> [ { , <column-spec> }... ]

<column-spec> ::= <field-spec> [ <as clause> ]
                 | CAST ( <field-spec> AS <data type> ) [ <as clause> ]

<field-spec> ::= [DISTINCT] <field_ref>
                 | <cumm-field-func> ( [DISTINCT] <field-ref> )
                 | <field-expr>
                 | Count(*)

<field-expr> ::= <field_ref>
                 | <constant-value>
                 | <field-expr> <field-operator> <field-expr>
                 | <field-func> ( <field-expr-list> )
                 | ( <field-expr> )

<field-expr-list> ::= field-expr
                 |  field-expr , field-expr-list
                 |  <empty>

<as clause> ::= [ AS ] <column_name>

<data type> ::= character [ ( field_length ) ]
                | float [ ( field_length ) ]
                | numeric [ ( field_length [, field_precision ] ) ]
                | integer [ ( field_length ) ]
                | date [ ( field_length ) ]
                | time [ ( field_length ) ]
                | timestamp [ ( field_length ) ]

<cumm-field-func> ::= AVG | MAX | MIN | SUM | COUNT

<field-operator> ::= '+' | '-' | '/' | '*' | '||'

<field-func> ::= CONCAT | SUBSTR

<field_ref>  ::= [<table_ref>.]field_name

特别注释

现有的CAST和column summary函数COUNT、AVG、MIN、MAX和SUM将或多或少地被视为函数,但被限制为对列定义的根操作,并被视为特殊情况(仍然如此)。

兼容性含义

以前允许作为非引号字段名的一些标识符现在可能必须被引用,因为它们将是语法中的关键字。关键字集为:

  • IN

  • LIKE

  • NULL

  • IS

  • SELECT

  • LEFT

  • JOIN

  • WHERE

  • ON

  • ORDER

  • BY

  • FROM

  • AS

  • ASC

  • DESC

  • DISTINCT

  • CAST

以前的实现是用C编写的,避免了GDAL/OGR服务的所有使用,因此它可以很容易地在其他上下文中使用,包括作为OGDI库的where子句求值器。更新后的代码是C++,直接使用CPL错误等服务已经直接并入。这意味着GDAL和OGDI使用的实现将发生分歧。

在大多数情况下,更改会导致一些OGR SQL语句工作,而这些语句以前可能会生成错误。

绩效影响

我希望对于简单的选择,计算速度不会有明显的不同,但是每个输出字段都需要作为一个表达式进行计算(可能有一个字段节点的值)。

实施计划

frankwartemdam将实现、测试和记录GDAL/OGR 1.8版本。

测试

所有现有的OGR SQL测试套件测试都应通过。将引入一个新的autotest/ogr/ogr_sql_rfc28.py脚本来测试新功能。

文档

这个 OGR SQL 将扩展文档以描述新功能。