首页 / 使用基于类型的状态机的查询约束编码

使用基于类型的状态机的查询约束编码有效专利 发明

技术领域

[0001] 本发明涉及查询约束编码,尤其是使用基于类型的状态机的查询约束编码。

相关背景技术

[0002] 数据处理是计算机编程的基本部分。可从各种编程语言中选择创建程序的编程语言。用于特定的应用程序的所选语言可取决于应用程序上下文、开发者的偏好、或公司策略,以及其他因素。无论所选语言如何,开发者最终将必须处理数据,即查询和更新数据。
[0003] 已开发称为集成语言的查询(LINQ)的技术以便于来自编程语言内部的数据交换。LINQ提供方便且声明性简写查询句法以在编程语言(例如, Visual ...)内部允许对查询的指定。具体而言,提供映射到低层语言构造或原语的查询操作符,诸如方法和拉姆达表达式(lambda expression)。提供用于各种运算(例如,过滤、投影、连接、分组、排序……)族的查询运算符,并且查询运算符可包括但不限于映射到实现这些名称所表示的运算符的方法的“where”和“select”运算符。作为示例,用户可以以诸如“from n in numbers where n<10 select n”的形式指定查询,其中“numbers”是数据源并且查询从数据源返回小于10的整数。此外,可以以各种方式组合查询运算符以生成任意复杂度的查询。
[0004] 虽然查询可以在存储器中的数据上本地地执行,但查询也可被远程传输到例如用于执行的另一台计算机。在此情形中,查询被表示为数据而非代码。接下来可转换查询的该数据表示(例如,表达式树)以将任意数据源作为目标。例如,集成语言的查询可被转换为用于由关系数据库系统执行的SQL(结构化查询语言)。作为另一个示例,集成语言的查询的数据表示可被转换为XQuery以允许相对于XML(可扩展标记语言)数据的执行。

具体实施方式

[0021] 以下细节通常涉及捕捉目标查询语言的约束,并接下来采用该约束将源集成语言的查询的表达性限于目标查询语言所支持的。集成语言的查询通常允许查询操作符的无穷的组合。但是,通过该句法(例如,经由运行时转换)定为目标的很多外部查询语言无法提供相似的灵活性。因此,给程序员一种表达性的错觉,因为存在这样的大量的查询,它们在源语言中很好地编译但不具有向目标查询语言的有意义的转换从而经常导致运行时异常。可通过捕捉目标语言的约束并且经由编译时检查在集成语言的查询表达性上强制实施这些约束来解决这个问题。
[0022] 更具体地,包括语法和类型系统的查询语言语义可在状态机中被编码,可采用该状态机来方便编译时检查。状态机可以是基于类型的,其中状态被编码为类型,并且状态之间的转变被编码为方法。以此方式,状态机可捕捉所支持的查询运算符和查询运算符的模式等。在编译时,状态机可用于检测无效的查询。类似的,状态机可用于辅助在查询指定期间对反馈的提供,包括错误识别和代码完成建议。
[0023] 现在参考附图更详细地描述本公开的各个方面,在全部附图中用相似的标记来指示相似或相应的元素。然而应该理解,附图及其相关详细描述不旨在将所要求保护的主题限于所公开的具体形式。相反,其意图是覆盖落在所要求保护主题的精神和范围之内的所有修改、等效和替换的方案。
[0024] 首先参考图1,示出了查询分析系统100。查询分析系统100包括被配置为接收、检索、或以其他方式获得或获取查询120的验证组件110。例如,查询120可对应于集成语言的查询(LINQ查询)以及其它类型的查询。验证组件110根据状态机组件130(此处也被简单地称为状态机)对查询120进行检查或验证,该状态机组件捕捉目标查询语言的约束,包括但不限于例如所支持的查询运算符和查询运算符的模式(例如,对查询运算符的出现数量和查询运算符的相对排序的限制)。根据一个实施例,状态机组件130可以是如以下进一步讨论的基于类型的状态机,其捕捉约束作为类型和方法。如果确定查询120未考虑目标查询语言的约束,例如如果检测到无效的查询运算符或查询运算符的无效模式,则验证组件110可发出出错信号。根据一个实施例,验证组件110可执行查询120的编译时检查从而减轻运行时失败的风险。因此,验证组件110可构成程序语言编译器的部分。
[0025] 图2描绘包括分析组件210和生成组件220的状态机生成系统200。分析组件210可分析包括语法和类型系统的目标查询语言的语义(或换言之,语言说明)以确定约束,或换言之对目标查询语言的限制,其中语法描述可接受的句法,并且类型系统描述数据类型的适当使用。基于分析,生成组件220可生成捕捉目标查询语言的约束的状态机(例如,状态机组件130)。根据一个实施例,状态机可以是基于类型的,或者换言之生成组件220可生成类型的状态机。在此情形中,状态可被编码为类型,并且状态之间的转换可被编码为方法。生成组件220还可接收指示所生成的状态机的期望大小和/或复杂度的一个或多个参数(例如,以预防拒绝服务(DOS)攻击)。因此,状态机可包括由语法和类型系统指定的全部约束、约束的子集、或者甚至是约束的超集(比由语法和类型系统指定的更多的约束)。
[0026] 简要地转向图3A,描绘了约束变型300的图形表示。此处,例如,内圈对应于由语法310和/或类型系统指示的约束,并且外圈表示由状态机捕捉的约束。内圈和外圈之间的距离表示由语法310和状态机130所指定的约束的区别。状态机130可基于大量的因素被调整为包括更多或更少的约束,该因素包括但不限于状态机组件130的特定版本和/或费用的支付。例如,用于生成基于类型的状态机的系统的收费版本可生成包括由语法310指定的基本上全部目标程序语言的约束的状态机,而其他版本可提供例如更少的覆盖。还注意到,状态机130可如虚线所示施加比语法更多的约束以进一步减轻运行时错误的风险。
[0027] 图3B是查询检查时302的图形表示以有助于澄清关于本发明的各方面。可在运行时320或编译时330检查查询是否符合各个约束。如果查询在运行时320不符合约束,则计算机程序可能崩溃和/或返回非预期的结果。因此,可在编译时330进行的检查越多越好。如虚线所示,通常在运行时320执行的检查也可在编译时进行以改善程序安全性。通常,集成语言的查询仅在运行时320被检查并导致大量的运行时错误。通过使用此处描述的状态机来添加对集成语言的查询的编译时检查,可减少运行时错误。
[0028] 图4示出便于编程的系统400。具体而言,系统可辅助对查询的指定,诸如在第一语言中指定的并被转换为第二语言执行的查询。如所描绘的,系统400包括用户可用来指定查询的接口组件410。例如,接口组件410可单独对应于代码编辑器,或作为集成开发环境(IDE)的部分。建议组件420通信地耦合到接口组件410。当用户经由接口组件410指定查询时,建议组件420向用户提供建议。例如,可提供代码完成功能。根据状态机组件130可提供关于涉及查询的建议的信息。如前所述,状态机组件130可捕捉与目标查询语言相关联的约束,诸如由语言的语法或类型系统提供的约束。因此,涉及在第一语言中指定的查询的所提供的建议可被限于由第二语言支持的操作。此外,可以理解,可基于状态机组件
130经由接口组件410向用户标识出(例如,红色波浪下划线)查询指定中的错误。
[0029] 以下是有助于对于所公开的主题的各方面的清晰度和理解的状态机构建的更为详细的讨论。应当理解,以下提供的具体细节是用于前述目的,并不旨在于以任何方式隐式地限制要求保护的主题。无论如何,通过描述如何从语法标识出目标查询语言的约束并在基于类型的状态机内对其进行编码开始讨论。接下来,讨论解决如何通过将枚举限于中间类型来捕捉最小的查询。进一步的讨论涉及区分实体类型与查询制定类型,以及查询制定中使用的领域专用数据类型的生成。接着,描述跨子句的状态跟踪,其中引入特定的查询制定类型以跟踪运算符及可选地它们的参数的使用。最后,描述用于专用查询类型的代码生成。
[0030] 从目标查询语言的指定开始,按照语法可标识可用的查询运算符。例如,以下片段按照可选和强制运算符、其相对顺序及允许的出现计数(例如,按照克林(Kleene)闭包运算符)示出查询语言的指定。
[0031]
[0032]
[0033] 由以上可知,可手动地、自动地或半自动地导出关于目标查询语言的限制。例如,可确定的是:
[0034] 查询语言中的整个子句是可选的。其中的某些由于[optional]符号而立即显而易见,但其他的需要一些领域专用的知识。具体而言,“SELECT*”有效地意为“没有投影”,因此从语义的观点来看,“SELECT”子句的使用是可选的。
[0035] 某些子句仅允许出现一次,而其他子句允许多次-可能是有限次的出现。在上述语法中,“WHERE”可被使用任意次,而“ORDER BY”最多出现两次,由可选的逗号分隔的键值的嵌套使用所指示。
[0036] 尽管在目标语言中某些子句看来是混合的(诸如带有嵌套“TOP”子句的“SELECT”),但它们通常可被拆分为独立的查询运算符(也称为序列运算符)。以上,“TOP”可被转换为与“Select”运算符不同的“Take”运算符。
[0037] 取决于目标查询语言,查询运算符的顺序可具有语义影响。对于以上语法,虽然在过滤、排序和投影已经发生之后最后应用“TOP”行计数限制子句,但“WHERE”和“ORDER BY”子句的相对顺序没有影响。因此,等价的“Take”运算符可在最后单独地出现。
[0038] 给定从分析查询语言的语法中获得的知识,可生成对单个查询运算符的调用的相对顺序进行编码的状态机。该方案在根本上不同于提供诸如“IQueryable”的接口的常规查询运算符,后者陷入对用于指定查询的查询运算符的无穷无尽的组合中。例如,使用基于“IQueryable”的方案,可以用 编写以下查询表达式:
[0039]
[0040] 如果该查询表达式要被转换为前述示例性语法所描述的目标查询语言,则会存在很多问题,例如:
[0041] “Take”运算符的使用出现在目标语言不支持的位置。更具体地,如参考目标查询语言的分析的先前所述,在其他查询子句已被处理之后,对应的“TOP”约束将限制行数。显然,“Where”和“Take”的使用没有交换。
[0042] 已经指定了三个“orderby”键值,而目标语言仅支持两个。注意其他问题可能出现在“orderby”的使用上,例如仅允许一个排序顺序,诸如“ascending(升序)”。在此情形中,“descending(降序)”关键词的使用应被拒绝。
[0043] 在相同的查询内部正对第二数据源进行查询,有效地意识到“products”和“orders”之间的某种连接。示例目标查询语言不提供对这样的操作的直接支持,并由此多个from子句应被拒绝。
[0044] 目标语言中不支持“Skip”运算符。这是使用完整大小的“IQueryable”接口的查询提供方的共同问题,而所针对的查询语言通常仅支持少量的查询运算符。
[0045] 为了限制集成语言的查询的表达性,应当意识到这些查询仅是方法调用链的顶端的句法美化,其中目标方法已知为查询运算符。具体而言,语言不关心在何处实现那些方法,因为应用了常规方法解决规则。作为示例,以上示出的查询句法转换为以下的方法调用链,其中子句有时被转换为对拉姆达表达式的使用:
[0046] products
[0047] .Take(100)
[0048] .Where(product=>product.Price>1000)
[0049] .OrderByDescending(product=>product.Price)
[0050] .ThenBy(product=>product.Name)
[0051] .ThenBy(product=>product.UnitsInStock)
[0052] .SelectMany(product = > product.Orders,(product,order) = >new{product.Name,order.Customer})
[0053] .Skip(5)
[0054] 通过在以上转换中限制方法中的某些的可用性(以进一步讨论的方式),编译器或类似的机制可在编译时发出出错信号,从而阻止用户编写目标语言不支持的查询表达式。以上,给定之前提供的示例性语法,不应被允许的方法被标明下划线。
[0055] 为了实现此限制性效果,例如可通过目标查询语言的语法对所支持的查询运算符的使用路径进行分析,并将该查询运算符的使用路径转换为类型的状态机(此处也被称为基于类型的状态机)。每次使用查询运算符(例如,状态机中的边)之后,对查询运算符的进一步使用可变为受限的。在以上示例中,对“ThenBy”的第一次调用不应允许对“ThenBy”的任何进一步的使用,因为只能有两个指定的排序子句。在通过语法的某些路径的结尾,不允许进一步的运算符使用,在此处用户不能进行任何操作,只能调用对查询结果的计算。这对应于状态机中的最终状态。例如,在以上示例中,“Take”的使用不应允许对查询运算符的任何进一步的使用。
[0056] 对状态机术语的以下映射可应用:
[0057] 节点对应于表示(可能是中间)查询运算的类型。那些类型捕捉运算符的历史,包括迄今为止已被使用的运算符的顺序,例如以标定的方式(例如,类型的名称对已被使用过的运算进行编码)。基于该信息,可限制进一步的移动(边)。
[0058] 状态机的开始节点表示可查询的数据源,将初始的查询运算符展示为允许使用的方法(边)。
[0059] 最终节点不具有展示的任何此外的查询运算符,但可以触发查询的执行。中间节点可以或者不可以触发查询的执行(例如,可能需要在运行查询之前指定至少一个where子句)。
[0060] 边对应于类型上的方法,表示基于在节点类型中捕捉的历史,在查询表达式阶段允许使用的查询运算符。那些方法可在查询运算符的签名之后,以便查询句法可将其作为目标。
[0061] 通过循环边的自引用节点表示可被使用任意次数的查询运算符(对应于克林闭包“*”运算符),从状态机的当前状态(节点)开始。
[0062] 对于仅允许使用设定次数的查询运算符(例如,在运行示例中“ORDERBY”的计数限制),中间节点可被引入到每次使用中,有效地携带在类型中编码的使用计数。此外,由于并非全部运算符都交换,因此状态机可捕捉查询运算符的相对排序。例如,在“Where”运算符后指定“Take”运算符可产生与在“Take”运算符后指定“Where”运算符不同的结果。
[0063] 将注意力转到图5,提供示例性状态机图500以具体化以上描述中的某些。仅出于简化的目的,在基于类型的状态机图500中采用查询运算符的子集,聚焦于“OrderBy”、“Where”和“Select”。
[0064] 此处,“源”节点520(表示为类型)当作状态机图的开始,并具有三条传出边(每条被表示为方法):“OrderBy”、“Where”和“Select”。中间节点的类型名称表达关于迄今为止所捕捉的查询表达式的信息。例如,当沿着从“源”节点502开始的“Where”和“OrderBy”边时,到达“已过滤已排序(FilteredOrdered)”节点504或者“已排序已过滤(OrderedFilter)”节点506,其包括过滤器子句和排序键值选择器二者。注意即使仅有部分信息可用,某些节点可被重复使用;例如,可通过从“源”节点502沿着“Select”边到达“已过滤已排序已投影(FilteredOrderedProjected)”节点508。在此情形中,过滤器将是不变的返回真的函数,并且用于排序的键值列表将为空。
[0065] 为了限制可被指定的排序子句的数量,可存在单独的节点以倒计允许使用的剩余运算符的数量。在此情形中,“OrderBy”指定第一个键值选择器,并且其后可跟随一个且仅有一个指定第二级排序的“ThenBy”调用。“已排序”节点510和“已排序2”节点512反映无法使用其他“ThenBy”运算符的状态。在允许三个键值选择器的情形中,可添加“已排序3”节点。参考从“已过滤”节点516达到的“已过滤已排序”节点504和“已过滤已排序2”节点514,发生类似的情况。
[0066] 创建交换运算符的排列。例如,“OrderBy”和“Where”可被交换,引出通过状态机图500的两条单独的路径。由于语言编译器通常不将运算符重新排序为某种普通形式,因此这为终端用户编写查询提供最大的灵活性。仅按照使用查询运算符关键词的顺序调用对应的方法。
[0067] 在该示例状态机图500中,“已过滤已排序已投影”节点508是最终节点。因此,不允许添加此外的查询运算符。由于运行的示例中无法嵌套查询,因此例如在目标查询语言中无法在已经进行表示改变投影之后执行过滤器。
[0068] 由某些查询语言引入的另一个要求或约束是具有最小的查询,通常以确保对原始数据源的结果的某些限制性。例如,可在收集结果之前必须指定至少一个过滤器。数据提供方可用来避免通过网络向用户传送巨大的数据量,或者预防盗窃大量数据。在此情形中,缺少过滤器的查询将被目标执行环境拒绝。如果这样的查询通过单独地产生那些中间节点无法实现该目标则可被静态地拒绝,在状态机中该中间节点在其上具有足够的查询信息以带来对象,其中允许针对该对象的查询执行触发。例如,结果集合对象可实现用于在基于拉(例如,存储器中,数据库……)或基于推(例如,事件、异步计算……)的数据集合上进行迭代的可枚举或可观察的图案或接口(例如,抽象数据类型)。当对象上缺少枚举器或可观察的图案时,编译器或类似的机制可被配置为不允许在由(不完整的)查询所表示的结果上的迭代。
[0069] 参考图6,提供与图5的状态机图500基本上相同的状态机图600,此处还示出了在枚举发生之前需要至少单个过滤器(“Where”)的情形。“源”节点502、“已排序”节点510和“已排序2”节点512被示为具有虚线边界以指示它们不能触发查询执行。作为示例而非限制,不允许这些节点在由查询所表示的结果上进行迭代。还注意到边中的某些也已经从状态机图600中移除,因为若已无过滤器子句,则允许(转变到最终状态的)投影也没有意义。在可执行查询之前必须发生至少某些数量的运算符调用的情形中,可引入中间节点以进行这样的计数,如之前针对排序情形所描述的。在该设定中,可以将可枚举的节点认为是状态机中的最终节点。例如,对“OrderBy”和“ThenBy”的连续使用不会导致可枚举的查询对象,因为尚未指定过滤器。另一方面,沿着从“源”节点502开始的“Where”边在“已过滤”节点516产生可枚举的对象。
[0070] 用于表达查询的内建接口的使用混合了关于类型化的两个不同的问题。一个是展示给查询的消费者的对象的类型。例如,如果从数据源中检索对象“人”,则将人的“姓名”属性展示为常规的字符串类型是有意义的,以便对象与任何其他对象一样可被使用(例如,允许调用对象上的各种方法,诸如“ToUpper”)。这种数据类型可被称为“实体类型”。
[0071] 另一方面,表示正被查询的数据的相同的实体类型也可用于查询的制定。这意味着在已使用的数据类型(例如,字符串的“StartsWith”方法)上可用的运算在制定查询时也可供人使用。例如:
[0072] from p in people
[0073] where p.FirstName.StartsWith(“B”)
[0074] select p.FirstName+““+p.LastName
[0075] 但是,情况可能正好是由查询提供方所针对的查询语言以任何方式都不支持在字符串上的“开始”运算。同样,仅对于不支持的查询运算符,制定查询的典型方法是将检测不支持的构建的负担置于查询提供方(将查询从第一语言转换为第二语言的实体),该查询提供方将在运行时检测这样的问题并使用产生次优的开发者经验的异常发出指示问题的信号。通过将“实体类型”与“查询制定类型”分隔,可显著地改善这种情况。
[0076] 将以上用于查询表达式的代码片段转换为基于方法的形式生成以下:
[0077] people
[0078] .Where(p=>p.FirstName.StartsWith(“B”))
[0079] .Select(p=>p.FirstName+““+p.LastName)
[0080] 尽管拉姆达表达式参数“p”在两个拉姆达表达式中具有相同的类型,但这不是必须的情形。此外,拉姆达表达式不必被逐字类型化为用于正被查询的集合中元素的“实体类型”。因此,如果限制应用于在过滤器子句和(可能具有不同能力的)投影子句中可获得的目标查询语言的语法,则可使用不同的拉姆达表达式中p的特定的查询制定类型来对其进行建模。代替使用完整大小的(作为拉姆达表达式的相同图标属性通过语言直接支持的)表达式树,可建立领域专用的表达式语言。为了使其尽量无摩擦地使用,可采用运算符过载。
[0081] 例如,在以上的过滤器中,如果“p”是如下定义的“Person”类型,则采用“Func”过滤器委托的“Where”方法将允许编写导致布尔值的任何表达式:
[0082]
[0083] 正确的过滤器的示例包括“p=>true”、“p=>false”、“p=>“Joe”==“Adam””。由于那些过滤器没有使用参数“p”,因此它们可被完整地编译。这示出了过滤器的返回值为布尔值时对用户所编写的内容如何实际上不提供任何限制。更多有用的过滤器子句将有可能使用“p”在其属性的某些上表达过滤条件,以使其被转换为目标查询语言。由于示例中的“FirstName”被类型化为“string(字符串)”,因此基于它的任何布尔表达式可在编译时被接受以用在查询表达式中,例如“p=>p.FirstName.ToUpper().EndsWith(“t”)”。然而,情况可能正好是目标语言不支持“ToUpper”、“EndsWith”或其组合。
[0084] 通过引入在查询制定中使用的领域专用的数据类型,可以避免这个问题。例如,为了减少字符串属性上可用的运算(例如,表示数据源中的列),可引入仅带有查询中使用的所支持的运算的特定的字符串类型:
[0085]
[0086] 所展示的“FilterableString”类型现在将仅包括所允许的运算,返回类型位于过滤器表达式中使用的可接受类型的封闭世界中:
[0087]
[0088] 此处,允许从标准字符串到“FilterableString”的隐式对话以提供平滑的方式来使用文字。“StartsWith”方法的返回类型现在是已经过载用于已允许的布尔运算的运算符的“FilterableBoolean”:
[0089]
[0090] 即使在使用“&&”运算符时,在以上的示例中过载假(false)运算符允许得到对“&”运算符的调用。这是基于由编译器执行的对“&&”的转换。该技术的重要性是能够从各种方法内部建立领域专用的表达式树,例如:
[0091] public FilterableBooleanStartsWith(FilterableString prefix){returnFilterableBoolean(new StartsWith(this,prefix));}
[0092] 其中“StartsWith”类型仅是包括用于“StartsWith”运算的左手边和右手边的两个属性的数据类型。表示在查询中可用的运算的类型包括,对准备好用于转换为目标查询语言的用户已编写的查询的表示。由于那些表达式在拉姆达抽象之后结束,因此查询转换器需要做的全部(由在得到的查询对象上的枚举所触发的)是执行通过为其提供查询制定类型为拉姆达创建的异步方法委托。例如:
[0093] 定义站点(用户代码):
[0094] .Where(p=>p.FirstName.StartsWith(“B”))
[0095] 转换站点(框架代码):
[0096]
[0097]
[0098] 类似的表达性限制可被应用于其他查询运算符,诸如通常应当定义返回列而非复杂表达式的键值选择器的排序。例如:
[0099] people
[0100] .OrderBy(p=>p.Age)
[0101] .Select(p=>p.FirstName+““+p.LastName)
[0102] 通过定义从某些公共Column基类导出(或使其实现某些接口)的查询制定类型上的属性,“OrderBy”可被定义为由查询制定类型变为Column:
[0103]
[0104] 现在只能指定提取用于排序的单个列的键值选择器。在排序子句的转换中使用的查询制定类型的构造函数可使用串文字或对底层列的引用的另一个内部表示来初始化列对象。“ThenBy”运算符的后续使用可创建包括键值选择器列表的新的“Ordered”对象。
[0105]
[0106] 某些查询子句不适于该技术,因为它们通常用于选择一列、或多列、或在列上的多个计算。例如,像“select”的投影运算符可被提供为创建新的异步类型以保持多个值的选择器函数,例如:
[0107] people
[0108] .Select(p=>new{p.FirstName,p.LastName,p.Age})
[0109] 在此情形中,无法限制拉姆达表达式的返回类型,因为不存在用于全部可能的投影的公共基类型。此外,投影位于查询制定和对查询结果的形状的定义之间的边上,因此,不应允许泄露查询制定的数据类型(像“StringColumn”或其他领域专用的类型),因为它们不提供在消费终端可灵活使用的全保真类型(像带有多种本地支持运算的“System.String”)。内建到语言中的诸如表示式树的查询的数据表示可用于这样的情形,缺点是对用户编写的表达式进行运行时检查。
[0110] 有时对某些表达式构建的使用阻止了在查询表达式上的某些进一步的运算。例如,在基于对某些实体对象属性的各种谓词来限制结果的查询语言中,情况可以是仅能使用某些这样的限制性谓词一次(或几次)。考虑使用多个“Where”过滤器、使用在某些数据源上运算的以下查询。在这样的目标查询语言中,通常的情形
是每种谓词仅能被使用一次,例如只能在“From”上指定一个限制:
[0111] tweets
[0112] .Where(t=>t.Location==“Seattle”)
[0113] .Where(t=>t.From==“Mr.X”)
[0114] .Where(t=>t.Posted>DateTime.Now-TimeSpan.FromDays(7))
[0115] 在此情形中,某些谓词的使用限制了查询句法中的下游的运算。验证在编译时满足这样的限制的一种方式是通过引入跟踪哪些谓词已被使用的查询制定类型。例如,参考图7,示出了允许在行中指定“Where”运算符的数量的状态机图700。如所示的,从“源”节点710指定了两个“Where”运算符“WhereA”和“WhereB”:生成对应的过滤器节点“已过滤A”节点720和“已过滤B”722。“已过滤A,B”节点730表示跟踪谓词使用的类型。
[0116] 对于任何数量的可能的谓词,排列作为通过状态机图700的路径而存在。离开节点的每条边表示对带有专用谓词函数的查询运算符的过载。基于所选择的过载,运算符方法的返回类型确定了进一步可能的运算。实际上,运算符的返回类型不仅对已被使用过的运算符的历史也对在那些运算符内部所使用的谓词(或键值选择器、投影……)的历史进行编码。例如,状态机图700中的“源”节点710具有Where的两个过载:
[0117]
[0118]
[0119] 此处,类型“T”代表查询制定类型,例如在上述示例中的 基于该类型的给定所展示的属性的任何谓词导致“FilterBy*”结果。例如:
[0120]
[0121] 此处,仅在“Where”谓词自变量上使用“FilterableTweet”类型,使用“*”原语数据类型来类型化各种属性,该原语数据类型对属性使用进行编码并仅限于过滤运算(由此“Tweet*ForFiltering”对模式进行命名)。这一类型的示例在下面示出:
[0122]
[0123] 在此情形中,完整的谓词将被类型化为“FilterByLocation”,而将使用特定的类型“FilterBySender”等对通过例如“Sender”表达的谓词进行类型化。当用户制定对源的查询时,将编写具有一个“FilterBy*”结果类型的谓词表达式,允许编译器选择最具体的过载,例如:
[0124] tweets
[0125] .Where(t=>t.Location==“Seattle”)
[0126] 返回“FilteredByLocation”类型的对象。该类型此次具有允许附加谓词的进一步指定的“Where”过载,但这一次不给出对“Location”的谓词作为选项。这通过将新的查询制定类型用作对“Where”谓词拉姆达表达式的自变量来实现。
[0127] 将注意力简要地转向图8,对查询运算符结果和过滤器表达式进行类型化的图解说明。一般而言,原始源810具有查询制定类型“T”,在使用基于列“A”进行限制的过滤器820之后,使用用于进一步的过滤运算的新的查询制定类型“T\{A}”830。对于运行中的示例,这导致在制定查询时的以下经验:
[0128]
[0129] “FilteredBy*”类型携带关于按照用户编写的拉姆达表达式所表达的谓词的信息。当触发查询的执行时,可执行那些拉姆达表达式委托以获得“FilterBy*”对象,该“FilterBy*”对象包装关于所编写的谓词的信息(例如,使用用于之前描述的自定义领域专用的表达式树的技术)。
[0130] 之前的讨论涉及如何限制运算符用户的数量。在上面,注意到可多次使用相同的运算符(例如,Where),但是具有每种谓词最多一次。一般地,“FilterByLocation”可指示基于位置的过滤器的单次使用,而仍然允许位置上的另一个过滤器。同样,可跟踪类型中使用的数量。
[0131] 无论表示正被查询的对象的实体类型是否是固定的(例如,对于Twitter,仅存在可被表示为Tweet类型的一种固定的数据类型;相对的是如SQL或 系统中的自组织表定义),给定用于查询语言的语法和此处使用的可能的表达式(例如,用于谓词、投影……),可以生成提供严格的领域专用查询制定的中间类型。这包括:
[0132] 跟踪运算符使用和有效使用模式的顶层状态机的生成
[0133] 表示正被查询的实体的查询制定类型的生成
[0134] 限制对“远程的”表达式(跨应用程序边界传送的表达式)的可能的查询运算的表达式树类型的集合的生成
[0135] 用于表示查询结果的对象的实体类型的生成(全保真本地类型化)
[0136] 划分查询用于在机器网络(例如,云)上的并行执行
[0137] 参考若干组件之间的交互已经描述了上述系统、体系结构、环境等。应该理解,这样的系统和组件可以包括这些组件或其中指定的子组件,某些指定的组件或子组件,和/或附加的组件。子组件也可以被实现为在通信上被耦合到其他组件而不是被包括在父组件中的组件。此外,一个或多个组件和/或子组件可以结合成提供聚集功能的单个组件。系统、组件、和/或子组件之间的通信可以根据推(push)和/或拉模型来实现。各组件也可以与一个或多个其他组件进行交互,出于简要考虑在此未具体描述该组件但本领域的技术人员均已知。
[0138] 此外,应该理解以上所公开的系统及以下方法的各部分可以包括或包含基于人工智能、机器学习或知识或规则的组件、子组件、进程、装置、方法或机制(例如,支持向量机、神经网络、专家系统、贝叶斯信任网络、模糊逻辑、数据融合引擎、分类器……)。这样的组件和其它组件可以自动化执行某些机制或进程,由此使得系统和方法的各部分更为自适应、高效及智能。作为示例而非限制,这样的机制可由生成组件220采用以辅助状态机的生成,包括确定或推断状态机的适合的尺寸和/或复杂度。
[0139] 考虑到以上描述的示例性系统,参考图9-11的流程图将可以更好地理解根据所公开的主题实现的方法。尽管为了说明简洁起见,作为一系列框示出和描述了方法,但是,应该理解,所要求保护的主题不仅限于所描述框的顺序,一些框可以按与此处所描绘和描述的不同的顺序进行和/或与其他框并发地进行。此外,并非全部所示出的框都是实现下面所描述的方法所必需的。
[0140] 参考图9,示出查询分析的方法900。在附图标记910,标识用于目标查询语言的基于类型的状态机,例如,其中基于类型的状态机按照对状态进行编码的类型和对状态之间的转换进行编码的方法来捕捉目标查询语言的查询约束或限制。在附图标记920,根据基于类型的状态机分析源查询以确定源查询是否是目标查询语言中的有效查询。在附图标记930,如果目标查询语言不完全支持源查询,则发出一个或多个出错信号,例如在检测出无效查询运算符或查询运算符的无效模式之后。根据一个实施例,查询分析900的方法可由编译器捕捉。此外,由于约束是按照类型捕捉的,因此编译器的类型检查器可用于确定源查询是有效的还是无效的。
[0141] 图10示出状态机生成1000的方法。在附图标记1010,分析目标查询语言的语法(例如,上下文无关的语法)以确定查询语言的约束或限制。例如,可确定所支持的查询运算符以及对查询运算符的出现数量和相对排序的上限。在标记1020,可分析目标查询语言的类型系统以确定类型规则,这可标识以各种方式计算的值的类型。作为简化的示例,类型规则可指示只有整数类型的值可被加在一起,而非,例如,整数和按钮。在附图标记1030,可接收、检索、确定、或推断有关状态机的大小和/或复杂度的参数。例如,可生成基于类型的状态机以反映目标查询语言的全部约束、约束的子集、或者例如基于给定版本、费用的支付或根据成本/效益分析等的约束的超集。在附图标记1040,根据语言的语法和/或类型系统以及控制大小和/或复杂度的特定参数来生成基于类型的状态机,其中按照作为状态的类型和方法对约束进行编码,该方法管理状态(或换言之类型)之间的转换。
[0142] 图11是方便对查询的指定的方法的流程图。在附图标记1110,例如单独从代码编辑器或集成开发环境的指令接收查询输入。此处,查询可对应于预定被转换为目标编程语言中的查询的源编程语言中指定的查询。例如,可在面向对象编程语言(例如,Visual ……)内部将查询指定为集成语言的查询的句法,该查询的句法接下来被转换或变型为用于针对关系数据库的执行的SQL(结构化查询语言)。在附图标记1120,标识用于目标查询语言的基于类型的状态机,其表示至少对句法的约束、作为分别与状态和状态之间的转换相对应的类型和方法的约束。在标记1130,根据所接收的查询输入和基于类型的状态机标识错误。根据一个实施例,编译器类型检查器可将不支持的查询特征标识为静态类型错误。在标记1140,可向程序员提供反馈以辅助对输入查询的指定。在一个实例中,可例如使用着色的波浪线来标识错误或不支持的查询特征。此外,这样的反馈可与例如关于代码完成的建议相对应。
[0143] 此处使用的术语“组件”和“系统”及其各种形式意指与计算机相关的实体,其可以是硬件、硬件和软件的组合、软件、或执行中的软件。例如,组件可以是但不限于是,在处理器上运行的进程、处理器、对象、实例、可执行程序、执行的线程、程序和/或计算机。作为说明,在计算机上运行的应用程序程序和计算机都可以是组件。一个或多个组件可以驻留在进程和/或执行线程中,并且组件可以位于一个计算机内和/或分布在两个或更多的计算机之间。
[0144] 如此处使用的,词语“远程的”的动词形式,诸如但不限于动名词、过去分词和单数第三人称,旨在意指跨应用程序域的代码或数据的传送,该应用程序域在物理上和/或逻辑上隔离软件应用程序,因此它们互不影响。在远程发送之后,远程发送的主题(例如,代码或数据)可位于其源自的相同的计算机上或者例如连接到不同网络的计算机上。
[0145] 就此处使用的术语“查询表达式”而言,其旨在意指用于指定查询的句法,该句法包括映射到底层语言原语实现的一个或多个查询运算符,诸如同名的方法。
[0146] 除非另有注明,关于程序语言(例如,“程序语言语义”、“语言语义”……)使用的术语“语义”旨在被广义地解释为涵盖语言的形式、说明、或说明的形式。以此方式,类型规则和句法二者是语义以及计算复杂度等的各方面。
[0147] 在本文中使用的词语“示例性”或其各种形式意味着用作示例、实例或说明。在此被描述为“示例性”的任何方面或设计并不一定要被解释为相比其他方面或设计更优选或有利。此外,各示例只是出于清楚和理解的目的来提供的并且并不意味着以任何方式限制或约束所要求保护主题或本发明的相关部分。可以理解,本可呈现不同范围的多个附加或替换示例,但出于简明的目的已省略了。
[0148] 如此处所使用,术语“推论”或“推断”通常指的是从经由事件和/或数据捕捉的一组观察结果来推理或推断系统、环境、和/或用户的状态的过程。可以使用推断来标识特定上下文或动作,也可以生成例如状态上的概率分布。推断可以是概率性的,即,基于对数据和事件的考虑,计算在感兴趣状态上的概率分布。推断也可以是指用于从一组事件和/或数据构成较高级别的事件的技术。这样的推断导致从一组观察到的事件和/或存储的事件数据构建新的事件或动作,不管事件在时间上是否紧密相关,以及事件和数据是来自一个还是多个事件和数据源。可采用各种分类方案和/或系统(例如,支持向量机、神经网络、专家系统、贝叶斯信任网络、模糊逻辑、数据融合引擎……)来执行关于所要求保护主题的自动化和/或推断的动作。
[0149] 而且,对于在详细描述或权利要求书中使用术语“包括”、“包含”、“具有”、“含有”或其它形式的变型而言,这样的术语旨在以类似于术语“包括”的方式体现包含性,如同“包括”在用作权利要求书中的过渡词时所解释的那样。
[0150] 为了为所要求保护主题提供上下文,图12以及以下讨论旨在提供对其中可以实现本主题的各方面的合适环境的简要、概括描述。然而,合适的环境只是示例并且并非旨在对使用范围或功能提出任何限制。
[0151] 尽管能够在可以在一台或多台计算机上运行的程序的计算机可执行指令的一般上下文中描述以上公开的系统和方法,但是,本领域的技术人员将认识到,各方面也可以与其他程序模块等相结合地实现。一般而言,程序模块包括执行特定任务或实现特定抽象数据类型的例程、程序、组件和数据结构等。此外,本领域技术人员可以理解,上述系统和方法可用各种计算机系统配置实现,包括单处理器、多处理器或多核处理器计算机系统、小型计算设备、大型计算机、以及个人计算机、手持式计算设备(例如,个人数字助理(PDA)、电话、手表……)、基于微处理器或可编程消费者或工业电子设备等。各方面也可以在其中任务由通过通信网络链接的远程处理设备执行的分布式计算环境中实现。然而,所要求保护主题的某些方面,如果不是所有方面的话,可以在独立计算机上实施。在分布式计算环境中,程序模块可以位于本地和远程存储器存储设备中的一个或两者中。
[0152] 参考图12,示出了示例计算机1210或计算设备(例如,台式机、膝上型计算机、服务器、手持式设备、可编程消费或工业电子产品、机顶盒、游戏系统……)。计算机1210包括一个或多个处理器1220、系统存储器1230、系统总线1240、海量存储1250、以及一个或多个接口组件1270。系统总线1240与至少上述系统组件通信地耦合。然而,可以理解,在其最简单的形式中,计算机1210可包括耦合到系统存储器1230的一个或多个处理器1220,该一个或多个处理器1220执行各种计算机可执行动作、指令和或组件。
[0153] 处理器1220可以用通用处理器、数字信号处理器(DSP)、应用程序专用集成电路(ASIC)、现场可编程门阵列(FPGA)或其它可编程逻辑设备、分立门或晶体管逻辑、分立硬件组件或被设计为执行此处描述的功能的其任意组合来实现。通用处理器可以是微处理器,但在替换方案中,处理器可以是任何处理器、控制器、微控制器、或状态机。处理器1220还可被实现为计算设备的组合,例如DSP和微处理器的组合、多个微处理器、多核处理器、结合一个DSP核的一个或多个微处理器、或任何其它这种配置。
[0154] 计算机1210可包括各种计算机可读介质或以其他方式与其交互以便于控制计算机1210来实现所要求保护主题的一个或多个方面。计算机可读介质可以是能由计算机1210访问的任何可用介质,并包含易失性和非易失性介质以及可移动、不可移动介质。作为示例而非限制,计算机可读介质可包括计算机存储介质和通信介质。
[0155] 计算机存储介质包括以用于存储诸如计算机可读指令、数据结构、程序模块或其它数据这样的信息的任意方法或技术来实现的易失性和非易失性、可移动和不可移动介质。计算机存储介质包括但不限于,存储器设备(例如,随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)……)、磁存储设备(例如,硬盘、软盘、磁带盒、磁带……)、光盘(例如,紧致盘(CD)、数字多功能盘(DVD)……)、以及固态设备(例如,固态驱动器(SSD)、闪存驱动器(例如,卡、棒、键驱动器……)……)、或者可用于存储所需信息并且可由计算机1210访问的任何其他介质。
[0156] 通信介质通常以诸如载波或其他传输机制等已调制数据信号来体现计算机可读指令、数据结构、程序模块或其他数据,并包括任何信息传送介质。术语“已调制数据信号”是指一个或多个特征以在信号中编码信息的方式被设定或改变的信号。作为示例而非限制,通信介质包括诸如有线网络或直接线连接之类的有线介质,以及诸如声学、RF、红外及其他无线介质之类的无线介质。上述的任意组合也应包含在计算机可读介质的范围内。
[0157] 系统存储器1230和海量存储1250都是计算机可读存储介质的示例。取决于计算设备的确切配置和类型,系统存储器1230可以是易失性的(例如RAM)、非易失性的(例如ROM、闪存……)或是两者的某种组合。作为示例,基本输入/输出系统(BIOS),包括诸如在启动期间在计算机1210内的元件之间传输信息的基本例程,可被存储在非易失性存储器中,而易失性存储器可担当外部高速缓存存储器以便于处理器1220的处理等。
[0158] 海量存储1250包括相对于系统存储器1230用于存储大量数据的可移动/不可移动、易失性/非易失性计算机存储介质。例如,海量存储1250包括但不限于,诸如磁盘或光盘驱动器、软盘驱动器、闪存存储器、固态驱动器、或记忆棒的一个或多个设备。
[0159] 系统存储器1230和海量存储1250可包括或其中存储有操作系统1260、一个或多个应用程序1262、一个或多个程序模块1264和数据1266。操作系统1260用于控制和分配计算机1210的资源。应用程序1262包括系统和应用程序软件中的一个或两个,并且可通过存储在系统存储器1230和/或海量存储1250中的程序模块1264和数据1266来利用操作系统1260对资源的管理以执行一个或多个动作。因此,应用程序1262可根据由此提供的逻辑来将通用计算机1210变成专用机器。
[0160] 所要求保护主题的全部或各部分可以使用产生控制计算机以实现所公开功能的软件、固件、硬件或其任意组合的标准编程和/或工程技术来实现。作为示例而非限制,查询分析系统100和状态机生成系统200可以是或构成应用程序1262的一部分,并且包括存储在存储器和/或海量存储1250中的一个或多个模块1264和数据1266,其功能可以在由所示的一个或多个处理器1220执行时实现。
[0161] 计算机1210还包括通信地耦合到系统总线1240并方便与计算机1210的交互的一个或多个接口组件1270。作为示例,接口组件1270可以是端口(例如,串行、并行、PCMCIA、USB、火线……)或接口卡(例如,声音、视频……)等。在一个示例实现中,接口组件1270可被具体化为用户输入/输出接口,该用户输入/输出接口使得用户能够通过一个或多个输入设备(例如,诸如鼠标的指向设备、跟踪球、指示笔、触摸垫、键盘、话筒、操纵杆、游戏垫、圆盘式卫星天线、扫描仪、相机、其他计算机……)来将命令和信息输入到计算机1210中。在另一示例实现中,接口组件1270可被具体化为输出外围接口,该输出外围接口向显示器(例如,CRT、LCD、等离子……)、扬声器、打印机和/或其他计算机等提供输出。此外,接口组件1270可被具体化为网络接口,该网络接口使得能够诸如通过有线或无线通信链路与其他计算设备(未示出)通信。
[0162] 以上所已经描述的内容包括所要求保护主题的各方面的示例。当然,出于描绘所要求保护主题的目的而描述每一个可以想到的组件或方法的组合是不可能的,但本领域内的普通技术人员应该认识到,所要求保护主题的许多进一步的组合和排列都是可能的。从而,所公开的主题旨在涵盖落入所附权利要求书的精神和范围内的所有这样的变更、修改和变化。

当前第1页 第1页 第2页 第3页
相关技术
机查询相关技术
查询约束相关技术
B·德斯梅特发明人的其他相关专利技术