示例规范 - 您的蓝图标题

包含您的 Launchpad 蓝图的 URL

https://blueprints.launchpad.net/congress/+spec/datalog-column-names

当表包含大量列时,编写策略可能具有挑战性。本规范旨在让终端用户能够通过在 Datalog 规则中直接引用列名来编写策略。

问题描述

主要问题是宽表(包含许多列的表)难以使用。(a) 很难记住所有列是什么,(b) 很容易在规则体中不小心在两个不同的表中使用相同的变量,即创建意外连接,(c) 对数据源驱动程序的更改可能需要对策略进行繁琐/容易出错的修改。

提议的变更

目前人们编写策略语句如下

error(net) :-

neutron:networks(x0,x1,net,x3,x4,x5,x6,x7,x8,x9,x10), …

此更改启用了一种替代语法,其中列通过名称而不是位置进行引用。

error(net) :-

neutron:networks(id=net), …

为了实现此更改,我们将扩展语法以接受列名引用,并修改 AST 构造函数以将规则从列名引用转换回位置引用。

备选方案

在邮件列表讨论中描述了两种替代方案。

2) 严格编写窄表,并编写教程/建议来演示如何操作。

与其使用像…这样的表 neutron:ports(port_id, addr_pairs, security_groups, extra_dhcp_opts, binding_cap, status, name, admin_state_up, network_id, tenant_id, binding_vif, device_owner, mac_address, fixed_ips, router_id, binding_host)

我们会有许多表… neutron:ports(port_id) neutron:ports.addr_pairs(port_id, addr_pairs) neutron:ports.security_groups(port_id, security_groups) neutron:ports.extra_dhcp_opts(port_id, extra_dhcp_opts) neutron:ports.name(port_id, name) …

编写策略的人将编写如下规则 …

p(x) :- neutron:ports.name(port, name), …

[这里,句号(例如 ports.name 中的)不是运算符——只是一种方便的表名拼写方式。]

为此,Congress 需要知道表中的哪些列足以唯一标识一行,在大多数情况下,这只是 ID。

优点:(i) 这只需要更改数据源驱动程序;其他一切保持不变 (ii) 在底层仍然利用数据库技术 (iii) 策略对原始数据字段的变化具有鲁棒性

缺点:(i) 数据源驱动程序可以强制策略编写者使用宽表 (ii) 此数据模型与原始数据模型大相径庭 (iii) 我们需要表的 Primary-Key 信息

  1. 增强 Congress 策略语言以原生处理对象。

与其编写如下规则 …

p(port_id, name, group) :- neutron:ports(port_id, addr_pairs, security_groups, extra_dhcp_opts, binding_cap, status, name, admin_state_up, network_id, tenant_id, binding_vif, device_owner, mac_address, fixed_ips, router_id, binding_host), neutron:ports.security_groups(security_group, group)

我们将编写如下规则 p(port_id, name) :- neutron:ports(port), port.name(name), port.id(port_id), port.security_groups(group)

这里最大的区别是句号(.)是语言中的一个运算符,就像在 C++/Java 中一样。

优点:(i) 我们在 Congress 中使用的数据模型几乎与我们在 Neutron/Nova 中使用的数据模型完全相同。

(ii) 只要这些更改只添加字段,策略对 Neutron/Nova 数据模型的更改就具有鲁棒性。

  1. 程序员可能对这种语言更熟悉一些。

缺点:(i) 明显的实现(直接更改引擎以实现(.)运算符)与传统数据库技术有很大不同。目前来看,这似乎有风险。

(ii) 目前尚不清楚如何通过预处理器实现这一点(从而利用数据库技术)。我看到的关键问题是我们需要将 port.name(…) 转换为类似于上述选项 (2) 的内容。困难在于 TABLE 有时可能是端口,有时可能是网络,有时可能是子网等。

(iii) 需要一些额外的语法限制,以确保我们不会失去可判定性。

(iv) 由于 Congress 和 Nova/Neutron 模型相同,Nova/Neutron 模型的更改可能需要重写策略。

策略

error(net) :-

neutron:networks(id=net)

策略操作

数据源

数据模型影响

REST API 影响

代表策略的 API 调用中的字符串参数可以使用位置或列语法。

安全影响

通知影响

其他最终用户影响

其他 UI 可以公开这种增强语法,但由于目前所有 UI 都只是将策略语句作为字符串传递,因此它们无需实际更改即可利用此增强功能。

性能影响

应该不会对性能产生影响,但可能最终我们希望反转跟踪的预处理步骤,以便向用户呈现更直观的跟踪。

其他部署者影响

开发者影响

实现

负责人

主要负责人

thinrich

工作项

  • 修改语法

  • 使数据源 schema 在运行时可用

  • 向规则 AST 构造函数添加预处理器,将列引用转换为位置引用。

依赖项

以下更改使数据源 schema 可用于策略引擎

Change-Id: I7cfbd82c721509634c0acfd51e66031af2ed7f2d

测试

不需要 tempest 测试。仅限单元测试。

文档影响

应包括对文档的修改,以简化使用多列表的示例。还需要修改我们介绍 Datalog 的部分。