2.00.11 版本
2.00.11.5
Bug 修复造成的系统影响
shell
函数的权限发生了变化:-
之前版本,允许管理员用户调用。
-
当前版本,默认不允许任何用户调用。可通过设置配置参数 enableShellFunction=true ,允许管理员用户调用。
2.00.11.1
Bug 修复造成的系统影响
在此次版本中,存在以下对计算兼容性构成系统影响的 bug 修复:
-
修改了通过
update
更新分布式表,且对跨分区数据使用聚合函数、序列函数、自定义函数时的行为:-
此前版本中,可以进行更新,但结果不正确
-
当前版本中,禁止这种行为,增加了报错信息。但当其搭配
context by
语句,且context by
指定了所有分区列时,可以正常执行。有关使用详情,参考: update。dbName = "dfs://test_update" if (existsDatabase(dbName)) { dropDatabase(dbName) } // 分区表有 2 个分区,每个分区内 3 条数据 numParts = 2 numRowsPerPart = 3 numRows = numParts * numRowsPerPart t = table(stretch(1..numParts, numRows) as partCol, take(1..numRowsPerPart, numRows) as val); db = database(dbName, VALUE, 1..numParts, engine="TSDB") pt = db.createPartitionedTable(t, "pt", partitionColumns="partCol", sortColumns="partCol") pt.append!(t) //之前的版本可以正常执行,但仅在分区内部更新了数据,并没有在整个表内进行更新。 update pt set val=prev(val) //等价于 update pt set val=prev(val) context by partCol
更新后的结果为:partCol val 1 1 1 1 2 2 2 1 2 2
//当前版本,会出现报错 update pt set val=prev(val) //prev(val) => Aggregate or order-sensitive functions are not allowed without context by clause when updating a partitioned table. //通过 context by 指定分区列后,可以正常执行 update pt set val=prev(val) context by partCol
更新后的结果为:
partCol val 1 1 1 1 2 2 2 1 2 2
-
-
增加了查询分布式表时使用
order by
排序的限定条件。-
此前版本中,查询分布式表时,
order by
之后可以使用序列函数或自定义函数。有些查询在分区内计算序列函数,有些在合并的分区结果上计算序列函数,导致排序行为不一致。 -
当前版本中,不允许对
order by
指定的列使用序列函数或自定义函数。
dbName = "dfs://test_orderby" if (existsDatabase(dbName)) { dropDatabase(dbName) } // 分区表有 2 个分区,每个分区内 3 条数据 numParts = 2 numRowsPerPart = 3 numRows = numParts * numRowsPerPart t = table(stretch(1..numParts, numRows) as partCol, take(1..numRowsPerPart, numRows) as val); db = database(dbName, VALUE, 1..numParts, engine="TSDB") pt = db.createPartitionedTable(t, "pt", partitionColumns=`partCol, sortColumns=`partCol) pt.append!(t) //之前的版本中: //order by 利用分区内 next(val) 的结果进行排序 select * from pt order by next(val) //order by 利用分区结果合并后的 next(val) 的结果进行排序 select *, next(val) from pt order by next(val)
第一个查询的结果:
partCol val 1 3 2 3 1 1 2 1 1 2 2 2
第二个查询的结果:partCol val next_val 2 3 1 3 1 1 1 2 2 1 2 1 2 3 2 2 3
//在当前版本中,进行上述查询会出现报错: //Order-sensitive or user-defined functions are not allowed in the order by clause [next(val) asc] for a query over a parti tioned table.'
-
-
修改了使用
wj
连接两表且 agg 指定了count
函数时,当右表无匹配数据时的返回值:-
此前版本中,该特定场景下的返回结果为 NULL。
-
当前版本中,该特定场景下的返回结果为 0。
s1 = take([2021.12.31,2022.01.03,2022.01.06] ,3) s2 = take([2020.01.14],1) t1 = table(s1 as date, take("A", 3).sort() as symbol, 1..3 as a1,1..3 as a2) t2 = table(s2 as date, take("F", 1).sort() as symbol, 1..1 as a1, 1..1 as a2).sortBy!("date") select * from wj(t1, t2, 0:2,<[count(t2.a1)]> , ["symbol","date"]) order by symbol,date
此前版本中,结果表中的 count_a1 列为空:
date symbol a1 a2 count_a1 2021.12.31 A 1 1 2022.01.03 A 2 2 2022.01.06 A 3 3
当前版本中, 结果表中的 count_a1 列为 0:
date symbol a1 a2 count_a1 2021.12.31 A 1 1 0 2022.01.03 A 2 2 0 2022.01.06 A 3 3 0
-
-
修改了以下高阶函数的入参是空对象时的行为:
each
,eachPre
,eachPost
,eachLeft
,eachRight
,cross
,reduce
,accumulate
,any
,all
,loop
,ploop
-
此前版本中, 部分函数抛出异常,部分函数返回空值(例如
loop
,ploop
),导致计算中断。 -
当前版本中,上述高阶函数入参是空对象时将返回一个空的元组,从而避免计算中断。
each(sum,[]) //之前的版本会报错:Empty object can't be applied to the higher order function 'each //当前版本返回空的元组。
-
2.00.11
为匹配行业实践或 SQL 标准而进行的更改
-
修改配置项 datanodeRestartInterval 的行为:
在之前版本中,无论数据节点是宕机还是主动关闭,控制节点都会在满足条件时自动启动数据节点。
在当前版本中,控制节点会根据数据节点下线的类型决定是否自动启动数据节点,以下情况不会自动启动:
- 在控制节点通过执行 stopDataNode 关闭
- 在集群 web 界面通过停止节点按钮关闭
-
修改用户或组多次被授予指定前缀库的 DB_OWNER 权限的行为:
在之前版本中,后面的 grant 操作会覆盖之前
grant
操作的 objs。在当前版本中,后面的 grant 操作不会覆盖之前grant
操作的 objs。dbNames = ["dfs://db1_owner*", "dfs://db2_owner*"] grant("user1", DB_OWNER, dbNames[0]) grant("user1", DB_OWNER, dbNames[1]) getUserAccess("user1")[`DB_OWNER_allowed][0] //之前版本返回 dfs://db2_owner* //当前版本返回 dfs://db1_owner*,dfs://db2_owner*
-
拒绝用户或组指定前缀库的 DB_OWNER 权限的行为发生改变:
在之前版本中,这种操作可以执行,但会拒绝该用户对所有数据库的 DB_OWNER 权限。
当前版本不允许这种操作。deny("user1", DB_OWNER,"dfs://db1_owner*") //之前版本不报错 //当前版本报错:DENY to DB_OWNER only applies when objs is '*'.'
-
拒绝用户或组全局(objs 是 *)的以下权限后,再授予用户或组某些这些权限时的行为发生变化:DB_READ,DB_WRITE,DB_INSERT,DB_UPDATE,DB_DELETE,TABLE_READ,TABLE_WRITE,TABLE_INSERT,TABLE_UPDATE,TABLE_DELETE,DBOBJ_CREATE,DBOBJ_DELETE,VIEW_EXEC,DB_MANAGE,DB_MANAGE,DB_OWNER,DB_OWNER
在之前版本中,授予操作可以生效。
在当前版本中,授予操作不生效。deny("group1", DB_OWNER, "*") grant("group1",DB_OWNER, "dfs://test1*" ) //之前版本,grant 会生效, group1 组内成员可以创建以 dfs://test1 开头的数据库 //当前版本会报错:Invalid grant: grant [dfs://test1*] and [deny *] are in conflict.' deny("group1", DB_OWNER, "*") grant("user2",DB_OWNER, "dfs://test1*" ) //user2 是 group1 的成员。之前版本中,grant 会生效,user2 可以创建以 dfs://test1 开头的数据库 //当前版本不会报错,也不会生效,即 user2 无法创建数据库。
-
对分区表使用 context by 进行分组,且未使用 order by 语句,查询结果发生变化:
在之前版本中
- 如果同时满足 from 的对象不包含表连接,分区表是COMPO分区,context by 有且仅有一列、且是分区列,则结果顺序未定义。
- 除上述情况外:
- 如果select 不含聚合函数、序列函数、用户自定义函数,且没有 having 子句,结果按照分区排序。
- 否则,结果根据 context by 分组顺序排列。
在当前版本中,返回结果根据 context by 分组顺序排列。
-
n = 10 t = table([1,2,3,3,2,1,1,3,2,1] as id,[1,2,3,3,2,1,1,3,2,1] as sym, 1..10 as val) if(existsDatabase("dfs://test")){ dropDatabase("dfs://test") } db = database("dfs://test", HASH, [INT,2]) pt = db.createPartitionedTable(t, `pt, `id).append!(t) select sym from pt context by sym //之前版本返回[2,2,2,1,3,3,1,1,3,1] //当前版本返回[1,1,1,2,2,2,2,2,3,3]
-
修改
addMarketHoliday
中指定 marketName 的规则:在之前版本中,marketName 可以使用非字母,且不限制长度。
在当前版本中,marketName 只能由4个大写字母组成,如果不满足要求会报错 marketName must be a string consists of 4 uppercase letters.
Bug 修复造成的系统影响
-
查询语句中
order by
指定 BLOB 或数组向量列时的行为发生改变:在之前版本中,不会报错,但排序不生效。
在当前版本中,会报错。t=table(100:100, `col1`col2`blobv,[INT, INT, BLOB]) t[`col1] = rand(1..10,100) t[`col2] = 1..100 t[`blobv] = blob(string(rand("aa"+string(1..10),100))) //之前版本不报错,但排序不生效。当前版本会报错:StringVector::sort not implemented yet select * from t order by blobv //之前版本不报错,但排序不生效。当前版本会报错: Failed to sort vector blobv select * from t order by col1, blobv
-
查询语句中 order by 指定的列名与内置函数同名时的行为发生改变:
在之前的版本中,执行无报错,但排序无效。
在当前的版本中,会报错 Failed to sort vector <functionName>。n=1000 tmp=table(take(now()+1..100,n)as time,rand("sym"+string(1..100),n) as sym,rand(10.0,n) as price,rand(10.0,n) as val) select * from tmp order by time,symbol //之前版本会执行,但排序无效 //当前版本会报错:Failed to sort vector symbol
-
分布式表写入 STRING, BLOB, SYMBOL 类型数据时的行为发生改变:
在之前版本中,
-
针对超过64KB的字符串, Redo Log 反序列化该字符串时可能会失败。
-
针对超过64MB的blob,可以正常写入。
-
针对超过255字节的symbol,可以正常写入。
在当前版本中,
-
针对超过64KB的字符串,将被截断至65535字节。
-
针对超过64MB的blob,将被截断至67108863字节。
-
针对超过255字节的symbol,将禁止写入数据库。
-
-
wj
函数的参数 window指定为 0:0 时,计算规则发生改变:在之前的版本中,和左表当前数据相同的所有右表数据组成一个计算窗口吗,此时相当于
ej
;在当前版本中,左表当前记录的时间戳为 t,上一条记录的时间戳为 t0,则 [t0, t)为右表的计算窗口。t1 = table(`A`A`B as sym, 09:56:06 09:56:07 09:56:06 as time, 10.6 10.7 20.6 as price) t2 = table(take(`A,3) join take(`B,3) as sym, take(09:56:00+5..7,6) as time, (10-0.05*1..3) join (20-0.05*1..3) as bid); wj(t1, t2, 0:0, <last(bid)>, `sym`time) //之前版本结果为: // | sym | time | price | last_bid | // | A | 09:56:06 | 10.60 | 9.90 | // | A | 09:56:07 | 10.70 | 9.85 | // | B | 09:56:06 | 20.60 | 19.90 | //当前版本结果为: // | sym | time | price | last_bid | // | A | 09:56:06 | 10.60 | 9.95 | // | A | 09:56:07 | 10.70 | 9.90 | // | B | 09:56:06 | 20.60 | 19.95 |
-
同一个自定义函数多次添加函数视图时的行为发生改变:
在之前版本中,可以多次添加。
在当前版本中,不允许多次添加,第二次添加会报错。
-
row 系列向量函数当输入为列式元组时的行为发生改变:
在之前的版本中,返回一个数组向量。
在当前的版本中,返回数组向量或列式元组取决于配置项 keepTupleInRowFunction 的设置:
- 默认值为 true,表示返回列式元组。
- 设置为 false 时,返回数组向量。
a=[11 23 14 21,10 12 32 21] a.setColumnarTuple!() rowNext(a) //以前版本返回[[23,14,21,],[12,32,21,]],为数组向量 //当前版本: //keepTupleInRowFunction=false 时,返回[[23,14,21,],[12,32,21,]],为数组向量 //keepTupleInRowFunction=true 时,返回([23,14,21,],[12,32,21,]),为列式元组
-
transFrep
,resample
,asFreq
,temporalSeq
,spline
,neville
,loess
,dividedDifference
函数指定 rule 为天以上频率时,函数行为发生改变:在之前的版本中,closed 和 label 参数不支持默认值以外的选项。
在当前的版本中,closed 和 label 参数的指定值会生效。temporalSeq(2023.01.01,2023.01.20,"2W","left") //以前版本返回[2023.01.01,2023.01.15,2023.01.29], closed = left 不生效 //现在版本返回[2023.01.15,2023.01.29], closed = left 生效
-
函数
transFreq
,resample
,asFreq
的 rule 指定为以数字开头的交易日历时的行为发生变化:在之前的版本中,“10AIXK”会识别为交易日历“10AIXK”。
在当前的版本中,“10AIXK”会识别为对交易日历“AIXK”按照频率10天取值。假设存在一个名称为 "10AIXK" 的交易日历文件,文件内容为[2021.12.30, 2022.01.02, 2022.01.03, 2022.01.05, 2022.01.07, 2022.01.09] s =[2021.12.30, 2022.01.02, 2022.01.03, 2022.01.05, 2022.01.07, 2022.01.09] s.transFreq("10AIXK") //以前版本返回[2021.12.29,2021.12.31,2021.12.31,2022.01.04,2022.01.06,2022.01.06] //现在版本返回[2021.12.30,2021.12.30,2021.12.30,2021.12.30,2021.12.30,2021.12.30]