MLSQL 语法扩展设计
前言
MLSQL 语法非常简单,只有:
- set
- select
- train/run/predict
- save
- load
等几种语法。因为MLSQL为了简单起见,对扩展新语法是非常抵触的。比如,用户很希望能查看一张表的schema,在MLSQL中需要这么用:
run command ShowTableExt.`tableName`;
比如杀一个任务,需要这么用:
run command Kill.`jobId`;
虽然已然很简单,但是用户觉得还是不够简洁,用户期待如下的表示方法:
show tableName;
kill jobid;
但是如果加这些,就意味添加了新的语法,需要修改语法文件。那如何简单解决这个冲突呢?
解决方案
我们知道在MLSQL里,ET是扩展性最好的东西,任何功能都可以通过ET来实现。MLSQL内部比如Python支持等也是通过ET实现的。ET对应的其实就是train/run/predict 三个关键字。前面的show table schema, kill job也是通过ET实现的。但是他的语法在简单的场合确实不够简洁。 在不增加新语法的情况下,我们其实可以给一段代码片段重新命名从而实现新的功能。
比如前面的Kill,我们可以这样做:
set kill = '''
-- 注意结尾没有分号
run command Kill.`{}`
''';
接着,我们就获得了一个新的命令,叫kill了,具体这么使用:
!kill "groupid";
MLSQL 如果发现以!
开始,则认为是一个命令的开始,然后会寻找该命令的定义,然后执行对应的kill内容。以!
开始其实是受到Rust 的macro 调用的启发,Rust 采用以!
结尾来区分宏和普通方法的调用。MLSQL以!
开始作区分命令和其他脚本指令的调用。
一些有意思的额外用法
这套类似"宏"的机制有哪些有意思的使用呢?比如可以在不修改现有扩展接口以及语法的情况下,实现一套hdfs相关的功能,类似:
!hdfs ls /
!hdfs rm -rf /abc
....
这样就可以在MLSQL里实现一套完整的hdfs指令集。
结束语
MLSQL 还提供了include语法,从而实现脚本更好的复用。通过新的类似“宏”的支持,可以让脚本获得更好的复用性。不过这种复用性也让脚本更加复杂,用户应当尽量不要使用而应该去使用系统提供了一些内置的“宏”,比如 !desc 查看表结构, !kill 杀任务等。