Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
2c977aca
T
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1192
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
2c977aca
编写于
6月 14, 2022
作者:
S
Shengliang Guan
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/3.0' into fix/mnode
上级
110bf979
a5bbc0a6
变更
12
显示空白变更内容
内联
并排
Showing
12 changed file
with
1122 addition
and
152 deletion
+1122
-152
docs/en/12-taos-sql/12-keywords.md
docs/en/12-taos-sql/12-keywords.md
+269
-44
docs/zh/12-taos-sql/12-keywords.md
docs/zh/12-taos-sql/12-keywords.md
+268
-42
include/libs/function/functionMgt.h
include/libs/function/functionMgt.h
+4
-0
source/client/src/clientSml.c
source/client/src/clientSml.c
+12
-44
source/client/test/smlTest.cpp
source/client/test/smlTest.cpp
+25
-1
source/libs/executor/src/groupoperator.c
source/libs/executor/src/groupoperator.c
+10
-0
source/libs/function/inc/builtinsimpl.h
source/libs/function/inc/builtinsimpl.h
+4
-0
source/libs/function/src/builtins.c
source/libs/function/src/builtins.c
+83
-0
source/libs/function/src/builtinsimpl.c
source/libs/function/src/builtinsimpl.c
+104
-20
source/libs/parser/src/parInsertData.c
source/libs/parser/src/parInsertData.c
+4
-0
source/util/src/talgo.c
source/util/src/talgo.c
+11
-1
source/util/test/taosbsearchTest.cpp
source/util/test/taosbsearchTest.cpp
+328
-0
未找到文件。
docs/en/12-taos-sql/12-keywords.md
浏览文件 @
2c977aca
...
...
@@ -4,50 +4,275 @@ title: Keywords
There are about 200 keywords reserved by TDengine, they can't be used as the name of database, STable or table with either upper case, lower case or mixed case.
**Keywords List**
| | | | | |
| ----------- | ---------- | --------- | ---------- | ------------ |
| ABORT | CREATE | IGNORE | NULL | STAR |
| ACCOUNT | CTIME | IMMEDIATE | OF | STATE |
| ACCOUNTS | DATABASE | IMPORT | OFFSET | STATEMENT |
| ADD | DATABASES | IN | OR | STATE_WINDOW |
| AFTER | DAYS | INITIALLY | ORDER | STORAGE |
| ALL | DBS | INSERT | PARTITIONS | STREAM |
| ALTER | DEFERRED | INSTEAD | PASS | STREAMS |
| AND | DELIMITERS | INT | PLUS | STRING |
| AS | DESC | INTEGER | PPS | SYNCDB |
| ASC | DESCRIBE | INTERVAL | PRECISION | TABLE |
| ATTACH | DETACH | INTO | PREV | TABLES |
| BEFORE | DISTINCT | IS | PRIVILEGE | TAG |
| BEGIN | DIVIDE | ISNULL | QTIME | TAGS |
| BETWEEN | DNODE | JOIN | QUERIES | TBNAME |
| BIGINT | DNODES | KEEP | QUERY | TIMES |
| BINARY | DOT | KEY | QUORUM | TIMESTAMP |
| BITAND | DOUBLE | KILL | RAISE | TINYINT |
| BITNOT | DROP | LE | REM | TOPIC |
| BITOR | EACH | LIKE | REPLACE | TOPICS |
| BLOCKS | END | LIMIT | REPLICA | TRIGGER |
| BOOL | EQ | LINEAR | RESET | TSERIES |
| BY | EXISTS | LOCAL | RESTRICT | UMINUS |
| CACHE | EXPLAIN | LP | ROW | UNION |
| CACHELAST | FAIL | LSHIFT | RP | UNSIGNED |
| CASCADE | FILE | LT | RSHIFT | UPDATE |
| CHANGE | FILL | MATCH | SCORES | UPLUS |
| CLUSTER | FLOAT | MAXROWS | SELECT | USE |
| COLON | FOR | MINROWS | SEMI | USER |
| COLUMN | FROM | MINUS | SESSION | USERS |
| COMMA | FSYNC | MNODES | SET | USING |
| COMP | GE | MODIFY | SHOW | VALUES |
| COMPACT | GLOB | MODULES | SLASH | VARIABLE |
| CONCAT | GRANTS | NCHAR | SLIDING | VARIABLES |
| CONFLICT | GROUP | NE | SLIMIT | VGROUPS |
| CONNECTION | GT | NONE | SMALLINT | VIEW |
| CONNECTIONS | HAVING | NOT | SOFFSET | VNODES |
| CONNS | ID | NOTNULL | STable | WAL |
| COPY | IF | NOW | STableS | WHERE |
| _C0 | _QSTART | _QSTOP | _QDURATION | _WSTART |
| _WSTOP | _WDURATION | _ROWTS |
## Keywords List
### A
-
ABORT
-
ACCOUNT
-
ACCOUNTS
-
ADD
-
AFTER
-
ALL
-
ALTER
-
AND
-
AS
-
ASC
-
ATTACH
### B
-
BEFORE
-
BEGIN
-
BETWEEN
-
BIGINT
-
BINARY
-
BITAND
-
BITNOT
-
BITOR
-
BLOCKS
-
BOOL
-
BY
### C
-
CACHE
-
CACHELAST
-
CASCADE
-
CHANGE
-
CLUSTER
-
COLON
-
COLUMN
-
COMMA
-
COMP
-
COMPACT
-
CONCAT
-
CONFLICT
-
CONNECTION
-
CONNECTIONS
-
CONNS
-
COPY
-
CREATE
-
CTIME
### D
-
DATABASE
-
DATABASES
-
DAYS
-
DBS
-
DEFERRED
-
DELETE
-
DELIMITERS
-
DESC
-
DESCRIBE
-
DETACH
-
DISTINCT
-
DIVIDE
-
DNODE
-
DNODES
-
DOT
-
DOUBLE
-
DROP
### E
-
END
-
EQ
-
EXISTS
-
EXPLAIN
### F
-
FAIL
-
FILE
-
FILL
-
FLOAT
-
FOR
-
FROM
-
FSYNC
### G
-
GE
-
GLOB
-
GRANTS
-
GROUP
-
GT
### H
-
HAVING
### I
-
ID
-
IF
-
IGNORE
-
IMMEDIA
-
IMPORT
-
IN
-
INITIAL
-
INSERT
-
INSTEAD
-
INT
-
INTEGER
-
INTERVA
-
INTO
-
IS
-
ISNULL
### J
-
JOIN
### K
-
KEEP
-
KEY
-
KILL
### L
-
LE
-
LIKE
-
LIMIT
-
LINEAR
-
LOCAL
-
LP
-
LSHIFT
-
LT
### M
-
MATCH
-
MAXROWS
-
MINROWS
-
MINUS
-
MNODES
-
MODIFY
-
MODULES
### N
-
NE
-
NONE
-
NOT
-
NOTNULL
-
NOW
-
NULL
### O
-
OF
-
OFFSET
-
OR
-
ORDER
### P
-
PARTITION
-
PASS
-
PLUS
-
PPS
-
PRECISION
-
PREV
-
PRIVILEGE
### Q
-
QTIME
-
QUERIE
-
QUERY
-
QUORUM
### R
-
RAISE
-
REM
-
REPLACE
-
REPLICA
-
RESET
-
RESTRIC
-
ROW
-
RP
-
RSHIFT
### S
-
SCORES
-
SELECT
-
SEMI
-
SESSION
-
SET
-
SHOW
-
SLASH
-
SLIDING
-
SLIMIT
-
SMALLIN
-
SOFFSET
-
STable
-
STableS
-
STAR
-
STATE
-
STATEMEN
-
STATE_WI
-
STORAGE
-
STREAM
-
STREAMS
-
STRING
-
SYNCDB
### T
-
TABLE
-
TABLES
-
TAG
-
TAGS
-
TBNAME
-
TIMES
-
TIMESTAMP
-
TINYINT
-
TOPIC
-
TOPICS
-
TRIGGER
-
TSERIES
### U
-
UMINUS
-
UNION
-
UNSIGNED
-
UPDATE
-
UPLUS
-
USE
-
USER
-
USERS
-
USING
### V
-
VALUES
-
VARIABLE
-
VARIABLES
-
VGROUPS
-
VIEW
-
VNODES
### W
-
WAL
-
WHERE
### _
-
_C0
-
_QSTART
-
_QSTOP
-
_QDURATION
-
_WSTART
-
_WSTOP
-
_WDURATION
## Explanations
### TBNAME
...
...
docs/zh/12-taos-sql/12-keywords.md
浏览文件 @
2c977aca
...
...
@@ -45,48 +45,274 @@ title: TDengine 参数限制与保留关键字
目前 TDengine 有将近 200 个内部保留关键字,这些关键字无论大小写均不可以用作库名、表名、STable 名、数据列名及标签列名等。这些关键字列表如下:
| 关键字列表 | | | | |
| ----------- | ---------- | --------- | ---------- | ------------ |
| ABORT | CREATE | IGNORE | NULL | STAR |
| ACCOUNT | CTIME | IMMEDIATE | OF | STATE |
| ACCOUNTS | DATABASE | IMPORT | OFFSET | STATEMENT |
| ADD | DATABASES | IN | OR | STATE_WINDOW |
| AFTER | DAYS | INITIALLY | ORDER | STORAGE |
| ALL | DBS | INSERT | PARTITIONS | STREAM |
| ALTER | DEFERRED | INSTEAD | PASS | STREAMS |
| AND | DELIMITERS | INT | PLUS | STRING |
| AS | DESC | INTEGER | PPS | SYNCDB |
| ASC | DESCRIBE | INTERVAL | PRECISION | TABLE |
| ATTACH | DETACH | INTO | PREV | TABLES |
| BEFORE | DISTINCT | IS | PRIVILEGE | TAG |
| BEGIN | DIVIDE | ISNULL | QTIME | TAGS |
| BETWEEN | DNODE | JOIN | QUERIES | TBNAME |
| BIGINT | DNODES | KEEP | QUERY | TIMES |
| BINARY | DOT | KEY | QUORUM | TIMESTAMP |
| BITAND | DOUBLE | KILL | RAISE | TINYINT |
| BITNOT | DROP | LE | REM | TOPIC |
| BITOR | EACH | LIKE | REPLACE | TOPICS |
| BLOCKS | END | LIMIT | REPLICA | TRIGGER |
| BOOL | EQ | LINEAR | RESET | TSERIES |
| BY | EXISTS | LOCAL | RESTRICT | UMINUS |
| CACHE | EXPLAIN | LP | ROW | UNION |
| CACHELAST | FAIL | LSHIFT | RP | UNSIGNED |
| CASCADE | FILE | LT | RSHIFT | UPDATE |
| CHANGE | FILL | MATCH | SCORES | UPLUS |
| CLUSTER | FLOAT | MAXROWS | SELECT | USE |
| COLON | FOR | MINROWS | SEMI | USER |
| COLUMN | FROM | MINUS | SESSION | USERS |
| COMMA | FSYNC | MNODES | SET | USING |
| COMP | GE | MODIFY | SHOW | VALUES |
| COMPACT | GLOB | MODULES | SLASH | VARIABLE |
| CONCAT | GRANTS | NCHAR | SLIDING | VARIABLES |
| CONFLICT | GROUP | NE | SLIMIT | VGROUPS |
| CONNECTION | GT | NONE | SMALLINT | VIEW |
| CONNECTIONS | HAVING | NOT | SOFFSET | VNODES |
| CONNS | ID | NOTNULL | STABLE | WAL |
| COPY | IF | NOW | STABLES | WHERE |
| _C0 | _QSTART | _QSTOP | _QDURATION | _WSTART |
| _WSTOP | _WDURATION | _ROWTS |
### A
- ABORT
- ACCOUNT
- ACCOUNTS
- ADD
- AFTER
- ALL
- ALTER
- AND
- AS
- ASC
- ATTACH
### B
- BEFORE
- BEGIN
- BETWEEN
- BIGINT
- BINARY
- BITAND
- BITNOT
- BITOR
- BLOCKS
- BOOL
- BY
### C
- CACHE
- CACHELAST
- CASCADE
- CHANGE
- CLUSTER
- COLON
- COLUMN
- COMMA
- COMP
- COMPACT
- CONCAT
- CONFLICT
- CONNECTION
- CONNECTIONS
- CONNS
- COPY
- CREATE
- CTIME
### D
- DATABASE
- DATABASES
- DAYS
- DBS
- DEFERRED
- DELETE
- DELIMITERS
- DESC
- DESCRIBE
- DETACH
- DISTINCT
- DIVIDE
- DNODE
- DNODES
- DOT
- DOUBLE
- DROP
### E
- END
- EQ
- EXISTS
- EXPLAIN
### F
- FAIL
- FILE
- FILL
- FLOAT
- FOR
- FROM
- FSYNC
### G
- GE
- GLOB
- GRANTS
- GROUP
- GT
### H
- HAVING
### I
- ID
- IF
- IGNORE
- IMMEDIA
- IMPORT
- IN
- INITIAL
- INSERT
- INSTEAD
- INT
- INTEGER
- INTERVA
- INTO
- IS
- ISNULL
### J
- JOIN
### K
- KEEP
- KEY
- KILL
### L
- LE
- LIKE
- LIMIT
- LINEAR
- LOCAL
- LP
- LSHIFT
- LT
### M
- MATCH
- MAXROWS
- MINROWS
- MINUS
- MNODES
- MODIFY
- MODULES
### N
- NE
- NONE
- NOT
- NOTNULL
- NOW
- NULL
### O
- OF
- OFFSET
- OR
- ORDER
### P
- PARTITION
- PASS
- PLUS
- PPS
- PRECISION
- PREV
- PRIVILEGE
### Q
- QTIME
- QUERIE
- QUERY
- QUORUM
### R
- RAISE
- REM
- REPLACE
- REPLICA
- RESET
- RESTRIC
- ROW
- RP
- RSHIFT
### S
- SCORES
- SELECT
- SEMI
- SESSION
- SET
- SHOW
- SLASH
- SLIDING
- SLIMIT
- SMALLIN
- SOFFSET
- STable
- STableS
- STAR
- STATE
- STATEMEN
- STATE_WI
- STORAGE
- STREAM
- STREAMS
- STRING
- SYNCDB
### T
- TABLE
- TABLES
- TAG
- TAGS
- TBNAME
- TIMES
- TIMESTAMP
- TINYINT
- TOPIC
- TOPICS
- TRIGGER
- TSERIES
### U
- UMINUS
- UNION
- UNSIGNED
- UPDATE
- UPLUS
- USE
- USER
- USERS
- USING
### V
- VALUES
- VARIABLE
- VARIABLES
- VGROUPS
- VIEW
- VNODES
### W
- WAL
- WHERE
### _
- _C0
- _QSTART
- _QSTOP
- _QDURATION
- _WSTART
- _WSTOP
- _WDURATION
## 特殊说明
### TBNAME
...
...
include/libs/function/functionMgt.h
浏览文件 @
2c977aca
...
...
@@ -138,6 +138,10 @@ typedef enum EFunctionType {
FUNCTION_TYPE_TOP_MERGE
,
FUNCTION_TYPE_BOTTOM_PARTIAL
,
FUNCTION_TYPE_BOTTOM_MERGE
,
FUNCTION_TYPE_FIRST_PARTIAL
,
FUNCTION_TYPE_FIRST_MERGE
,
FUNCTION_TYPE_LAST_PARTIAL
,
FUNCTION_TYPE_LAST_MERGE
,
// user defined funcion
FUNCTION_TYPE_UDF
=
10000
...
...
source/client/src/clientSml.c
浏览文件 @
2c977aca
...
...
@@ -1327,8 +1327,8 @@ static int32_t smlKvTimeArrayCompare(const void *key1, const void *key2) {
static
int32_t
smlKvTimeHashCompare
(
const
void
*
key1
,
const
void
*
key2
)
{
SHashObj
*
s1
=
*
(
SHashObj
**
)
key1
;
SHashObj
*
s2
=
*
(
SHashObj
**
)
key2
;
SSmlKv
*
kv1
=
(
SSmlKv
*
)
taosHashGet
(
s1
,
TS
,
TS_LEN
);
SSmlKv
*
kv2
=
(
SSmlKv
*
)
taosHashGet
(
s2
,
TS
,
TS_LEN
);
SSmlKv
*
kv1
=
*
(
SSmlKv
*
*
)
taosHashGet
(
s1
,
TS
,
TS_LEN
);
SSmlKv
*
kv2
=
*
(
SSmlKv
*
*
)
taosHashGet
(
s2
,
TS
,
TS_LEN
);
ASSERT
(
kv1
->
type
==
TSDB_DATA_TYPE_TIMESTAMP
);
ASSERT
(
kv2
->
type
==
TSDB_DATA_TYPE_TIMESTAMP
);
if
(
kv1
->
i
<
kv2
->
i
)
{
...
...
@@ -1340,29 +1340,13 @@ static int32_t smlKvTimeHashCompare(const void *key1, const void *key2) {
}
}
static
int32_t
smlDealCols
(
SSmlTableInfo
*
oneTable
,
bool
dataFormat
,
SArray
*
cols
)
{
if
(
dataFormat
)
{
void
*
p
=
taosArraySearch
(
oneTable
->
cols
,
&
cols
,
smlKvTimeArrayCompare
,
TD_G
E
);
if
(
p
==
NULL
)
{
static
int32_t
smlDealCols
(
SSmlTableInfo
*
oneTable
,
bool
dataFormat
,
SArray
*
cols
)
{
if
(
dataFormat
)
{
void
*
p
=
taosArraySearch
(
oneTable
->
cols
,
&
cols
,
smlKvTimeArrayCompare
,
TD_G
T
);
if
(
p
==
NULL
)
{
taosArrayPush
(
oneTable
->
cols
,
&
cols
);
}
else
{
// to make the sort stable for update data
SArray
*
sa
=
(
SArray
*
)
p
;
SSmlKv
*
cur
=
(
SSmlKv
*
)
taosArrayGet
(
sa
,
0
);
SSmlKv
*
dCur
=
(
SSmlKv
*
)
taosArrayGet
(
cols
,
0
);
if
(
cur
->
i
>
dCur
->
i
)
{
}
else
{
taosArrayInsert
(
oneTable
->
cols
,
TARRAY_ELEM_IDX
(
oneTable
->
cols
,
p
),
&
cols
);
}
else
{
ASSERT
(
cur
->
i
==
dCur
->
i
);
int32_t
index
=
TARRAY_ELEM_IDX
(
oneTable
->
cols
,
p
)
+
1
;
for
(;
index
<
taosArrayGetSize
(
oneTable
->
cols
);
index
++
)
{
SArray
*
tmp
=
(
SArray
*
)
taosArrayGet
(
oneTable
->
cols
,
index
);
SSmlKv
*
curTs
=
(
SSmlKv
*
)
taosArrayGet
(
tmp
,
0
);
if
(
curTs
->
i
>
dCur
->
i
)
{
break
;
}
}
taosArrayInsert
(
oneTable
->
cols
,
index
,
&
cols
);
}
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -1377,27 +1361,11 @@ static int32_t smlDealCols(SSmlTableInfo *oneTable, bool dataFormat, SArray *col
taosHashPut
(
kvHash
,
kv
->
key
,
kv
->
keyLen
,
&
kv
,
POINTER_BYTES
);
}
void
*
p
=
taosArraySearch
(
oneTable
->
cols
,
&
kvHash
,
smlKvTimeHashCompare
,
TD_G
E
);
if
(
p
==
NULL
)
{
void
*
p
=
taosArraySearch
(
oneTable
->
cols
,
&
kvHash
,
smlKvTimeHashCompare
,
TD_G
T
);
if
(
p
==
NULL
)
{
taosArrayPush
(
oneTable
->
cols
,
&
kvHash
);
}
else
{
// to make the sort stable for update data
SHashObj
*
sa
=
(
SHashObj
*
)
p
;
SSmlKv
*
cur
=
(
SSmlKv
*
)
taosHashGet
(
sa
,
TS
,
TS_LEN
);
SSmlKv
*
dCur
=
(
SSmlKv
*
)
taosArrayGet
(
cols
,
0
);
if
(
cur
->
i
>
dCur
->
i
)
{
taosArrayInsert
(
oneTable
->
cols
,
TARRAY_ELEM_IDX
(
oneTable
->
cols
,
p
),
&
cols
);
}
else
{
ASSERT
(
cur
->
i
==
dCur
->
i
);
int32_t
index
=
TARRAY_ELEM_IDX
(
oneTable
->
cols
,
p
)
+
1
;
for
(;
index
<
taosArrayGetSize
(
oneTable
->
cols
);
index
++
)
{
SHashObj
*
tmp
=
(
SHashObj
*
)
taosArrayGet
(
oneTable
->
cols
,
index
);
SSmlKv
*
curTs
=
(
SSmlKv
*
)
taosHashGet
(
tmp
,
TS
,
TS_LEN
);
if
(
curTs
->
i
>
dCur
->
i
)
{
break
;
}
}
taosArrayInsert
(
oneTable
->
cols
,
index
,
&
cols
);
}
}
else
{
taosArrayInsert
(
oneTable
->
cols
,
TARRAY_ELEM_IDX
(
oneTable
->
cols
,
p
),
&
kvHash
);
}
return
TSDB_CODE_SUCCESS
;
}
...
...
source/client/test/smlTest.cpp
浏览文件 @
2c977aca
...
...
@@ -1260,4 +1260,28 @@ TEST(testCase, sml_16368_Test) {
pRes = taos_schemaless_insert(taos, (char**)sql, sizeof(sql)/sizeof(sql[0]), TSDB_SML_JSON_PROTOCOL, TSDB_SML_TIMESTAMP_MICRO_SECONDS);
ASSERT_EQ(taos_errno(pRes), 0);
taos_free_result(pRes);
}*/
}
TEST(testCase, sml_dup_time_Test) {
TAOS *taos = taos_connect("localhost", "root", "taosdata", NULL, 0);
ASSERT_NE(taos, nullptr);
TAOS_RES* pRes = taos_query(taos, "create database if not exists dup_time schemaless 1");
taos_free_result(pRes);
const char *sql[] = {
//"test_ms,t0=t c0=f 1626006833641",
"ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=false,c1=1i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"xcxvwjvf\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000",
"ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=T,c1=2i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"fixrzcuq\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000",
"ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=3i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"iupzdqub\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000",
"ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=4i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"yvvtzzof\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000",
"ubzlsr,id=qmtcvgd,t0=t,t1=127i8,t2=32767i16,t3=2147483647i32,t4=9223372036854775807i64,t5=11.12345f32,t6=22.123456789f64,t7=\"binaryTagValue\",t8=L\"ncharTagValue\" c0=t,c1=5i8,c2=32767i16,c3=2147483647i32,c4=9223372036854775807i64,c5=11.12345f32,c6=22.123456789f64,c7=\"vbxpilkj\",c8=L\"ncharColValue\",c9=7u64 1626006833639000000"
};
pRes = taos_query(taos, "use dup_time");
taos_free_result(pRes);
pRes = taos_schemaless_insert(taos, (char**)sql, sizeof(sql)/sizeof(sql[0]), TSDB_SML_LINE_PROTOCOL, 0);
ASSERT_EQ(taos_errno(pRes), 0);
taos_free_result(pRes);
}
*/
source/libs/executor/src/groupoperator.c
浏览文件 @
2c977aca
...
...
@@ -582,6 +582,15 @@ int32_t* setupColumnOffset(const SSDataBlock* pBlock, int32_t rowCapacity) {
return
offset
;
}
static
void
clearPartitionOperator
(
SPartitionOperatorInfo
*
pInfo
)
{
void
*
ite
=
NULL
;
while
(
(
ite
=
taosHashIterate
(
pInfo
->
pGroupSet
,
ite
))
!=
NULL
)
{
taosArrayDestroy
(
((
SDataGroupInfo
*
)
ite
)
->
pPageList
);
}
taosHashClear
(
pInfo
->
pGroupSet
);
clearDiskbasedBuf
(
pInfo
->
pBuf
);
}
static
SSDataBlock
*
buildPartitionResult
(
SOperatorInfo
*
pOperator
)
{
SPartitionOperatorInfo
*
pInfo
=
pOperator
->
info
;
...
...
@@ -591,6 +600,7 @@ static SSDataBlock* buildPartitionResult(SOperatorInfo* pOperator) {
pInfo
->
pGroupIter
=
taosHashIterate
(
pInfo
->
pGroupSet
,
pInfo
->
pGroupIter
);
if
(
pInfo
->
pGroupIter
==
NULL
)
{
doSetOperatorCompleted
(
pOperator
);
clearPartitionOperator
(
pInfo
);
return
NULL
;
}
...
...
source/libs/function/inc/builtinsimpl.h
浏览文件 @
2c977aca
...
...
@@ -93,10 +93,14 @@ int32_t diffFunction(SqlFunctionCtx *pCtx);
bool
getFirstLastFuncEnv
(
struct
SFunctionNode
*
pFunc
,
SFuncExecEnv
*
pEnv
);
int32_t
firstFunction
(
SqlFunctionCtx
*
pCtx
);
int32_t
firstFunctionMerge
(
SqlFunctionCtx
*
pCtx
);
int32_t
lastFunction
(
SqlFunctionCtx
*
pCtx
);
int32_t
lastFunctionMerge
(
SqlFunctionCtx
*
pCtx
);
int32_t
firstLastFinalize
(
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
);
int32_t
firstLastPartialFinalize
(
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
);
int32_t
firstCombine
(
SqlFunctionCtx
*
pDestCtx
,
SqlFunctionCtx
*
pSourceCtx
);
int32_t
lastCombine
(
SqlFunctionCtx
*
pDestCtx
,
SqlFunctionCtx
*
pSourceCtx
);
int32_t
getFirstLastInfoSize
(
int32_t
resBytes
);
bool
getTopBotFuncEnv
(
SFunctionNode
*
UNUSED_PARAM
(
pFunc
),
SFuncExecEnv
*
pEnv
);
bool
getTopBotMergeFuncEnv
(
SFunctionNode
*
UNUSED_PARAM
(
pFunc
),
SFuncExecEnv
*
pEnv
);
...
...
source/libs/function/src/builtins.c
浏览文件 @
2c977aca
...
...
@@ -954,6 +954,41 @@ static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t l
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
translateFirstLastImpl
(
SFunctionNode
*
pFunc
,
char
*
pErrBuf
,
int32_t
len
,
bool
isPartial
)
{
// first(col_list) will be rewritten as first(col)
if
(
2
!=
LIST_LENGTH
(
pFunc
->
pParameterList
))
{
//input has two params c0,ts, is this a bug?
return
TSDB_CODE_SUCCESS
;
}
SNode
*
pPara
=
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
uint8_t
paraType
=
((
SExprNode
*
)
pPara
)
->
resType
.
type
;
int32_t
paraBytes
=
((
SExprNode
*
)
pPara
)
->
resType
.
bytes
;
if
(
isPartial
)
{
if
(
QUERY_NODE_COLUMN
!=
nodeType
(
pPara
))
{
return
buildFuncErrMsg
(
pErrBuf
,
len
,
TSDB_CODE_FUNC_FUNTION_ERROR
,
"The parameters of first/last can only be columns"
);
}
pFunc
->
node
.
resType
=
(
SDataType
){.
bytes
=
getFirstLastInfoSize
(
paraBytes
)
+
VARSTR_HEADER_SIZE
,
.
type
=
TSDB_DATA_TYPE_BINARY
};
}
else
{
if
(
TSDB_DATA_TYPE_BINARY
!=
paraType
)
{
return
invaildFuncParaTypeErrMsg
(
pErrBuf
,
len
,
pFunc
->
functionName
);
}
pFunc
->
node
.
resType
=
((
SExprNode
*
)
pPara
)
->
resType
;
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
translateFirstLastPartial
(
SFunctionNode
*
pFunc
,
char
*
pErrBuf
,
int32_t
len
)
{
return
translateFirstLastImpl
(
pFunc
,
pErrBuf
,
len
,
true
);
}
static
int32_t
translateFirstLastMerge
(
SFunctionNode
*
pFunc
,
char
*
pErrBuf
,
int32_t
len
)
{
return
translateFirstLastImpl
(
pFunc
,
pErrBuf
,
len
,
false
);
}
static
int32_t
translateUnique
(
SFunctionNode
*
pFunc
,
char
*
pErrBuf
,
int32_t
len
)
{
if
(
1
!=
LIST_LENGTH
(
pFunc
->
pParameterList
))
{
return
invaildFuncParaNumErrMsg
(
pErrBuf
,
len
,
pFunc
->
functionName
);
...
...
@@ -1704,6 +1739,30 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.
initFunc
=
functionSetup
,
.
processFunc
=
firstFunction
,
.
finalizeFunc
=
firstLastFinalize
,
.
pPartialFunc
=
"_first_partial"
,
.
pMergeFunc
=
"_first_merge"
,
.
combineFunc
=
firstCombine
,
},
{
.
name
=
"_first_partial"
,
.
type
=
FUNCTION_TYPE_FIRST_PARTIAL
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_MULTI_RES_FUNC
|
FUNC_MGT_TIMELINE_FUNC
,
.
translateFunc
=
translateFirstLastPartial
,
.
getEnvFunc
=
getFirstLastFuncEnv
,
.
initFunc
=
functionSetup
,
.
processFunc
=
firstFunction
,
.
finalizeFunc
=
firstLastPartialFinalize
,
.
combineFunc
=
firstCombine
,
},
{
.
name
=
"_first_merge"
,
.
type
=
FUNCTION_TYPE_FIRST_MERGE
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_MULTI_RES_FUNC
|
FUNC_MGT_TIMELINE_FUNC
,
.
translateFunc
=
translateFirstLastMerge
,
.
getEnvFunc
=
getFirstLastFuncEnv
,
.
initFunc
=
functionSetup
,
.
processFunc
=
firstFunctionMerge
,
.
finalizeFunc
=
firstLastFinalize
,
.
combineFunc
=
firstCombine
,
},
{
...
...
@@ -1715,6 +1774,30 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.
initFunc
=
functionSetup
,
.
processFunc
=
lastFunction
,
.
finalizeFunc
=
firstLastFinalize
,
.
pPartialFunc
=
"_last_partial"
,
.
pMergeFunc
=
"_last_merge"
,
.
combineFunc
=
lastCombine
,
},
{
.
name
=
"_last_partial"
,
.
type
=
FUNCTION_TYPE_LAST_PARTIAL
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_MULTI_RES_FUNC
|
FUNC_MGT_TIMELINE_FUNC
,
.
translateFunc
=
translateFirstLastPartial
,
.
getEnvFunc
=
getFirstLastFuncEnv
,
.
initFunc
=
functionSetup
,
.
processFunc
=
lastFunction
,
.
finalizeFunc
=
firstLastPartialFinalize
,
.
combineFunc
=
lastCombine
,
},
{
.
name
=
"_last_merge"
,
.
type
=
FUNCTION_TYPE_LAST_MERGE
,
.
classification
=
FUNC_MGT_AGG_FUNC
|
FUNC_MGT_MULTI_RES_FUNC
|
FUNC_MGT_TIMELINE_FUNC
,
.
translateFunc
=
translateFirstLastMerge
,
.
getEnvFunc
=
getFirstLastFuncEnv
,
.
initFunc
=
functionSetup
,
.
processFunc
=
lastFunctionMerge
,
.
finalizeFunc
=
firstLastFinalize
,
.
combineFunc
=
lastCombine
,
},
{
...
...
source/libs/function/src/builtinsimpl.c
浏览文件 @
2c977aca
...
...
@@ -71,6 +71,12 @@ typedef struct STopBotRes {
STopBotResItem
*
pItems
;
}
STopBotRes
;
typedef
struct
SFirstLastRes
{
bool
hasResult
;
int32_t
bytes
;
char
buf
[];
}
SFirstLastRes
;
typedef
struct
SStddevRes
{
double
result
;
int64_t
count
;
...
...
@@ -2230,9 +2236,13 @@ int32_t apercentileCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx)
return
TSDB_CODE_SUCCESS
;
}
int32_t
getFirstLastInfoSize
(
int32_t
resBytes
)
{
return
sizeof
(
SFirstLastRes
)
+
resBytes
+
sizeof
(
int64_t
);
}
bool
getFirstLastFuncEnv
(
SFunctionNode
*
pFunc
,
SFuncExecEnv
*
pEnv
)
{
SColumnNode
*
pNode
=
(
SColumnNode
*
)
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
pEnv
->
calcMemSize
=
pNode
->
node
.
resType
.
bytes
+
sizeof
(
int64_t
);
SColumnNode
*
pNode
=
(
SColumnNode
*
)
nodesListGetNode
(
pFunc
->
pParameterList
,
0
);
pEnv
->
calcMemSize
=
sizeof
(
SFirstLastRes
)
+
pNode
->
node
.
resType
.
bytes
+
sizeof
(
int64_t
);
return
true
;
}
...
...
@@ -2256,12 +2266,13 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
int32_t
numOfElems
=
0
;
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
char
*
buf
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SFirstLastRes
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SInputColumnInfoData
*
pInput
=
&
pCtx
->
input
;
SColumnInfoData
*
pInputCol
=
pInput
->
pData
[
0
];
int32_t
bytes
=
pInputCol
->
info
.
bytes
;
pInfo
->
bytes
=
bytes
;
// All null data column, return directly.
if
(
pInput
->
colDataAggIsSet
&&
(
pInput
->
pColumnDataAgg
[
0
]
->
numOfNull
==
pInput
->
totalRows
))
{
...
...
@@ -2279,7 +2290,7 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
if
(
blockDataOrder
==
TSDB_ORDER_ASC
)
{
// filter according to current result firstly
if
(
pResInfo
->
numOfRes
>
0
)
{
TSKEY
ts
=
*
(
TSKEY
*
)(
buf
+
bytes
);
TSKEY
ts
=
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
);
if
(
ts
<
startKey
)
{
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -2295,9 +2306,10 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
char
*
data
=
colDataGetData
(
pInputCol
,
i
);
TSKEY
cts
=
getRowPTs
(
pInput
->
pPTS
,
i
);
if
(
pResInfo
->
numOfRes
==
0
||
*
(
TSKEY
*
)(
buf
+
bytes
)
>
cts
)
{
memcpy
(
buf
,
data
,
bytes
);
*
(
TSKEY
*
)(
buf
+
bytes
)
=
cts
;
if
(
pResInfo
->
numOfRes
==
0
||
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
)
>
cts
)
{
memcpy
(
pInfo
->
buf
,
data
,
bytes
);
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
)
=
cts
;
pInfo
->
hasResult
=
true
;
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
pResInfo
->
numOfRes
=
1
;
...
...
@@ -2308,7 +2320,7 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
// in case of descending order time stamp serial, which usually happens as the results of the nest query,
// all data needs to be check.
if
(
pResInfo
->
numOfRes
>
0
)
{
TSKEY
ts
=
*
(
TSKEY
*
)(
buf
+
bytes
);
TSKEY
ts
=
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
);
if
(
ts
<
endKey
)
{
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -2324,9 +2336,10 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
char
*
data
=
colDataGetData
(
pInputCol
,
i
);
TSKEY
cts
=
getRowPTs
(
pInput
->
pPTS
,
i
);
if
(
pResInfo
->
numOfRes
==
0
||
*
(
TSKEY
*
)(
buf
+
bytes
)
>
cts
)
{
memcpy
(
buf
,
data
,
bytes
);
*
(
TSKEY
*
)(
buf
+
bytes
)
=
cts
;
if
(
pResInfo
->
numOfRes
==
0
||
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
)
>
cts
)
{
memcpy
(
pInfo
->
buf
,
data
,
bytes
);
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
)
=
cts
;
pInfo
->
hasResult
=
true
;
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
pResInfo
->
numOfRes
=
1
;
break
;
...
...
@@ -2342,12 +2355,13 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
int32_t
numOfElems
=
0
;
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
char
*
buf
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SFirstLastRes
*
pInfo
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
SInputColumnInfoData
*
pInput
=
&
pCtx
->
input
;
SColumnInfoData
*
pInputCol
=
pInput
->
pData
[
0
];
int32_t
bytes
=
pInputCol
->
info
.
bytes
;
pInfo
->
bytes
=
bytes
;
// All null data column, return directly.
if
(
pInput
->
colDataAggIsSet
&&
(
pInput
->
pColumnDataAgg
[
0
]
->
numOfNull
==
pInput
->
totalRows
))
{
...
...
@@ -2372,10 +2386,11 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
char
*
data
=
colDataGetData
(
pInputCol
,
i
);
TSKEY
cts
=
getRowPTs
(
pInput
->
pPTS
,
i
);
if
(
pResInfo
->
numOfRes
==
0
||
*
(
TSKEY
*
)(
buf
+
bytes
)
<
cts
)
{
memcpy
(
buf
,
data
,
bytes
);
*
(
TSKEY
*
)(
buf
+
bytes
)
=
cts
;
if
(
pResInfo
->
numOfRes
==
0
||
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
)
<
cts
)
{
memcpy
(
pInfo
->
buf
,
data
,
bytes
);
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
)
=
cts
;
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
pInfo
->
hasResult
=
true
;
pResInfo
->
numOfRes
=
1
;
}
break
;
...
...
@@ -2390,9 +2405,10 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
char
*
data
=
colDataGetData
(
pInputCol
,
i
);
TSKEY
cts
=
getRowPTs
(
pInput
->
pPTS
,
i
);
if
(
pResInfo
->
numOfRes
==
0
||
*
(
TSKEY
*
)(
buf
+
bytes
)
<
cts
)
{
memcpy
(
buf
,
data
,
bytes
);
*
(
TSKEY
*
)(
buf
+
bytes
)
=
cts
;
if
(
pResInfo
->
numOfRes
==
0
||
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
)
<
cts
)
{
memcpy
(
pInfo
->
buf
,
data
,
bytes
);
*
(
TSKEY
*
)(
pInfo
->
buf
+
bytes
)
=
cts
;
pInfo
->
hasResult
=
true
;
pResInfo
->
numOfRes
=
1
;
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
}
...
...
@@ -2404,6 +2420,56 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
return
TSDB_CODE_SUCCESS
;
}
static
void
firstLastTransferInfo
(
SFirstLastRes
*
pInput
,
SFirstLastRes
*
pOutput
,
bool
isFirst
)
{
if
(
!
pInput
->
hasResult
)
{
return
;
}
pOutput
->
bytes
=
pInput
->
bytes
;
TSKEY
*
tsIn
=
(
TSKEY
*
)(
pInput
->
buf
+
pInput
->
bytes
);
TSKEY
*
tsOut
=
(
TSKEY
*
)(
pOutput
->
buf
+
pInput
->
bytes
);
if
(
pOutput
->
hasResult
)
{
if
(
isFirst
)
{
if
(
*
tsIn
>
*
tsOut
)
{
return
;
}
}
else
{
if
(
*
tsIn
<
*
tsOut
)
{
return
;
}
}
}
*
tsOut
=
*
tsIn
;
memcpy
(
pOutput
->
buf
,
pInput
->
buf
,
pOutput
->
bytes
);
pOutput
->
hasResult
=
true
;
return
;
}
static
int32_t
firstLastFunctionMergeImpl
(
SqlFunctionCtx
*
pCtx
,
bool
isFirstQuery
)
{
SInputColumnInfoData
*
pInput
=
&
pCtx
->
input
;
SColumnInfoData
*
pCol
=
pInput
->
pData
[
0
];
ASSERT
(
pCol
->
info
.
type
==
TSDB_DATA_TYPE_BINARY
);
SFirstLastRes
*
pInfo
=
GET_ROWCELL_INTERBUF
(
GET_RES_INFO
(
pCtx
));
int32_t
start
=
pInput
->
startRowIndex
;
char
*
data
=
colDataGetData
(
pCol
,
start
);
SFirstLastRes
*
pInputInfo
=
(
SFirstLastRes
*
)
varDataVal
(
data
);
firstLastTransferInfo
(
pInputInfo
,
pInfo
,
isFirstQuery
);
SET_VAL
(
GET_RES_INFO
(
pCtx
),
1
,
1
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
firstFunctionMerge
(
SqlFunctionCtx
*
pCtx
)
{
return
firstLastFunctionMergeImpl
(
pCtx
,
true
);
}
int32_t
lastFunctionMerge
(
SqlFunctionCtx
*
pCtx
)
{
return
firstLastFunctionMergeImpl
(
pCtx
,
false
);
}
int32_t
firstLastFinalize
(
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
)
{
int32_t
slotId
=
pCtx
->
pExpr
->
base
.
resSchema
.
slotId
;
SColumnInfoData
*
pCol
=
taosArrayGet
(
pBlock
->
pDataBlock
,
slotId
);
...
...
@@ -2411,12 +2477,30 @@ int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
SResultRowEntryInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
pResInfo
->
isNullRes
=
(
pResInfo
->
numOfRes
==
0
)
?
1
:
0
;
char
*
in
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
colDataAppend
(
pCol
,
pBlock
->
info
.
rows
,
in
,
pResInfo
->
isNullRes
);
SFirstLastRes
*
pRes
=
GET_ROWCELL_INTERBUF
(
pResInfo
);
colDataAppend
(
pCol
,
pBlock
->
info
.
rows
,
pRes
->
buf
,
pResInfo
->
isNullRes
);
return
pResInfo
->
numOfRes
;
}
int32_t
firstLastPartialFinalize
(
SqlFunctionCtx
*
pCtx
,
SSDataBlock
*
pBlock
)
{
SResultRowEntryInfo
*
pEntryInfo
=
GET_RES_INFO
(
pCtx
);
SFirstLastRes
*
pRes
=
GET_ROWCELL_INTERBUF
(
GET_RES_INFO
(
pCtx
));
int32_t
resultBytes
=
getFirstLastInfoSize
(
pRes
->
bytes
);
char
*
res
=
taosMemoryCalloc
(
resultBytes
+
VARSTR_HEADER_SIZE
,
sizeof
(
char
));
memcpy
(
varDataVal
(
res
),
pRes
,
resultBytes
);
varDataSetLen
(
res
,
resultBytes
);
int32_t
slotId
=
pCtx
->
pExpr
->
base
.
resSchema
.
slotId
;
SColumnInfoData
*
pCol
=
taosArrayGet
(
pBlock
->
pDataBlock
,
slotId
);
colDataAppend
(
pCol
,
pBlock
->
info
.
rows
,
res
,
false
);
taosMemoryFree
(
res
);
return
1
;
}
int32_t
lastCombine
(
SqlFunctionCtx
*
pDestCtx
,
SqlFunctionCtx
*
pSourceCtx
)
{
SResultRowEntryInfo
*
pDResInfo
=
GET_RES_INFO
(
pDestCtx
);
char
*
pDBuf
=
GET_ROWCELL_INTERBUF
(
pDResInfo
);
...
...
source/libs/parser/src/parInsertData.c
浏览文件 @
2c977aca
...
...
@@ -283,6 +283,8 @@ void sortRemoveDataBlockDupRowsRaw(STableDataBlocks* dataBuf) {
if
(
!
dataBuf
->
ordered
)
{
char
*
pBlockData
=
pBlocks
->
data
;
// todo. qsort is unstable, if timestamp is same, should get the last one
qsort
(
pBlockData
,
pBlocks
->
numOfRows
,
dataBuf
->
rowSize
,
rowDataCompar
);
int32_t
i
=
0
;
...
...
@@ -350,6 +352,8 @@ int sortRemoveDataBlockDupRows(STableDataBlocks* dataBuf, SBlockKeyInfo* pBlkKey
if
(
!
dataBuf
->
ordered
)
{
pBlkKeyTuple
=
pBlkKeyInfo
->
pKeyTuple
;
// todo. qsort is unstable, if timestamp is same, should get the last one
qsort
(
pBlkKeyTuple
,
nRows
,
sizeof
(
SBlockKeyTuple
),
rowDataCompar
);
pBlkKeyTuple
=
pBlkKeyInfo
->
pKeyTuple
;
...
...
source/util/src/talgo.c
浏览文件 @
2c977aca
...
...
@@ -175,7 +175,13 @@ void *taosbsearch(const void *key, const void *base, int32_t nmemb, int32_t size
c
=
compar
(
key
,
p
);
if
(
c
==
0
)
{
if
(
flags
==
TD_GT
){
lidx
=
midx
+
1
;
}
else
if
(
flags
==
TD_LT
){
ridx
=
midx
-
1
;
}
else
{
break
;
}
}
else
if
(
c
<
0
)
{
ridx
=
midx
-
1
;
}
else
{
...
...
@@ -189,6 +195,10 @@ void *taosbsearch(const void *key, const void *base, int32_t nmemb, int32_t size
return
(
c
<=
0
)
?
p
:
(
midx
+
1
<
nmemb
?
p
+
size
:
NULL
);
}
else
if
(
flags
==
TD_LE
)
{
return
(
c
>=
0
)
?
p
:
(
midx
>
0
?
p
-
size
:
NULL
);
}
else
if
(
flags
==
TD_GT
)
{
return
(
c
<
0
)
?
p
:
(
midx
+
1
<
nmemb
?
p
+
size
:
NULL
);
}
else
if
(
flags
==
TD_LT
)
{
return
(
c
>
0
)
?
p
:
(
midx
>
0
?
p
-
size
:
NULL
);
}
else
{
ASSERT
(
0
);
}
...
...
source/util/test/taosbsearchTest.cpp
浏览文件 @
2c977aca
...
...
@@ -248,6 +248,170 @@ TEST(testCase, taosbsearch_greater_or_equal) {
ASSERT_EQ
(
pRet
,
nullptr
);
}
TEST
(
testCase
,
taosbsearch_greater
)
{
// For equal test
int
key
=
3
;
void
*
pRet
=
NULL
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
NULL
,
0
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
// 1 element
int
array1
[
1
]
=
{
5
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array1
,
1
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
5
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array1
,
1
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
5
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array1
,
1
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
// 2 element
int
array2
[
2
]
=
{
3
,
6
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
3
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
4
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
7
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
// 3 element
int
array3
[
3
]
=
{
3
,
6
,
8
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
3
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
4
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
7
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
8
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
9
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
// 4 element
int
array4
[
4
]
=
{
3
,
6
,
8
,
11
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
3
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
4
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
7
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
8
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
11
);
key
=
9
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
11
);
key
=
11
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
13
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
// 5 element
int
array5
[
5
]
=
{
3
,
6
,
8
,
11
,
15
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
3
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
4
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
7
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
8
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
11
);
key
=
9
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
11
);
key
=
11
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
15
);
key
=
13
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
15
);
key
=
15
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
17
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_GT
);
ASSERT_EQ
(
pRet
,
nullptr
);
}
TEST
(
testCase
,
taosbsearch_less_or_equal
)
{
// For equal test
int
key
=
3
;
...
...
@@ -412,3 +576,167 @@ TEST(testCase, taosbsearch_less_or_equal) {
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LE
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
15
);
}
TEST
(
testCase
,
taosbsearch_less
)
{
// For equal test
int
key
=
3
;
void
*
pRet
=
NULL
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
NULL
,
0
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
// 1 element
int
array1
[
1
]
=
{
5
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array1
,
1
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array1
,
1
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
5
);
key
=
5
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array1
,
1
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
// 2 element
int
array2
[
2
]
=
{
3
,
6
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
3
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
4
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
7
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array2
,
2
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
// 3 element
int
array3
[
3
]
=
{
3
,
6
,
8
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
3
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
4
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
7
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
8
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
9
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array3
,
3
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
// 4 element
int
array4
[
4
]
=
{
3
,
6
,
8
,
11
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
3
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
4
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
7
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
8
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
9
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
11
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
13
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array4
,
4
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
11
);
// 5 element
int
array5
[
5
]
=
{
3
,
6
,
8
,
11
,
15
};
key
=
1
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
3
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
pRet
,
nullptr
);
key
=
4
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
6
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
3
);
key
=
7
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
8
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
6
);
key
=
9
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
11
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
8
);
key
=
13
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
11
);
key
=
15
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
11
);
key
=
17
;
pRet
=
taosbsearch
((
void
*
)
&
key
,
(
void
*
)
array5
,
5
,
sizeof
(
int
),
compareFunc
,
TD_LT
);
ASSERT_EQ
(
*
(
int
*
)
pRet
,
15
);
}
\ No newline at end of file
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录