Merge remote-tracking branch 'origin/3.0' into fix/mnode
This commit is contained in:
commit
2c977aca23
|
@ -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.
|
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**
|
## Keywords List
|
||||||
|
|
||||||
| | | | | |
|
### A
|
||||||
| ----------- | ---------- | --------- | ---------- | ------------ |
|
|
||||||
| ABORT | CREATE | IGNORE | NULL | STAR |
|
- ABORT
|
||||||
| ACCOUNT | CTIME | IMMEDIATE | OF | STATE |
|
- ACCOUNT
|
||||||
| ACCOUNTS | DATABASE | IMPORT | OFFSET | STATEMENT |
|
- ACCOUNTS
|
||||||
| ADD | DATABASES | IN | OR | STATE_WINDOW |
|
- ADD
|
||||||
| AFTER | DAYS | INITIALLY | ORDER | STORAGE |
|
- AFTER
|
||||||
| ALL | DBS | INSERT | PARTITIONS | STREAM |
|
- ALL
|
||||||
| ALTER | DEFERRED | INSTEAD | PASS | STREAMS |
|
- ALTER
|
||||||
| AND | DELIMITERS | INT | PLUS | STRING |
|
- AND
|
||||||
| AS | DESC | INTEGER | PPS | SYNCDB |
|
- AS
|
||||||
| ASC | DESCRIBE | INTERVAL | PRECISION | TABLE |
|
- ASC
|
||||||
| ATTACH | DETACH | INTO | PREV | TABLES |
|
- ATTACH
|
||||||
| BEFORE | DISTINCT | IS | PRIVILEGE | TAG |
|
|
||||||
| BEGIN | DIVIDE | ISNULL | QTIME | TAGS |
|
### B
|
||||||
| BETWEEN | DNODE | JOIN | QUERIES | TBNAME |
|
|
||||||
| BIGINT | DNODES | KEEP | QUERY | TIMES |
|
- BEFORE
|
||||||
| BINARY | DOT | KEY | QUORUM | TIMESTAMP |
|
- BEGIN
|
||||||
| BITAND | DOUBLE | KILL | RAISE | TINYINT |
|
- BETWEEN
|
||||||
| BITNOT | DROP | LE | REM | TOPIC |
|
- BIGINT
|
||||||
| BITOR | EACH | LIKE | REPLACE | TOPICS |
|
- BINARY
|
||||||
| BLOCKS | END | LIMIT | REPLICA | TRIGGER |
|
- BITAND
|
||||||
| BOOL | EQ | LINEAR | RESET | TSERIES |
|
- BITNOT
|
||||||
| BY | EXISTS | LOCAL | RESTRICT | UMINUS |
|
- BITOR
|
||||||
| CACHE | EXPLAIN | LP | ROW | UNION |
|
- BLOCKS
|
||||||
| CACHELAST | FAIL | LSHIFT | RP | UNSIGNED |
|
- BOOL
|
||||||
| CASCADE | FILE | LT | RSHIFT | UPDATE |
|
- BY
|
||||||
| CHANGE | FILL | MATCH | SCORES | UPLUS |
|
|
||||||
| CLUSTER | FLOAT | MAXROWS | SELECT | USE |
|
### C
|
||||||
| COLON | FOR | MINROWS | SEMI | USER |
|
|
||||||
| COLUMN | FROM | MINUS | SESSION | USERS |
|
- CACHE
|
||||||
| COMMA | FSYNC | MNODES | SET | USING |
|
- CACHELAST
|
||||||
| COMP | GE | MODIFY | SHOW | VALUES |
|
- CASCADE
|
||||||
| COMPACT | GLOB | MODULES | SLASH | VARIABLE |
|
- CHANGE
|
||||||
| CONCAT | GRANTS | NCHAR | SLIDING | VARIABLES |
|
- CLUSTER
|
||||||
| CONFLICT | GROUP | NE | SLIMIT | VGROUPS |
|
- COLON
|
||||||
| CONNECTION | GT | NONE | SMALLINT | VIEW |
|
- COLUMN
|
||||||
| CONNECTIONS | HAVING | NOT | SOFFSET | VNODES |
|
- COMMA
|
||||||
| CONNS | ID | NOTNULL | STable | WAL |
|
- COMP
|
||||||
| COPY | IF | NOW | STableS | WHERE |
|
- COMPACT
|
||||||
| _C0 | _QSTART | _QSTOP | _QDURATION | _WSTART |
|
- CONCAT
|
||||||
| _WSTOP | _WDURATION | _ROWTS |
|
- 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
|
## Explanations
|
||||||
### TBNAME
|
### TBNAME
|
||||||
|
|
|
@ -45,48 +45,274 @@ title: TDengine 参数限制与保留关键字
|
||||||
|
|
||||||
目前 TDengine 有将近 200 个内部保留关键字,这些关键字无论大小写均不可以用作库名、表名、STable 名、数据列名及标签列名等。这些关键字列表如下:
|
目前 TDengine 有将近 200 个内部保留关键字,这些关键字无论大小写均不可以用作库名、表名、STable 名、数据列名及标签列名等。这些关键字列表如下:
|
||||||
|
|
||||||
| 关键字列表 | | | | |
|
### A
|
||||||
| ----------- | ---------- | --------- | ---------- | ------------ |
|
|
||||||
| ABORT | CREATE | IGNORE | NULL | STAR |
|
- ABORT
|
||||||
| ACCOUNT | CTIME | IMMEDIATE | OF | STATE |
|
- ACCOUNT
|
||||||
| ACCOUNTS | DATABASE | IMPORT | OFFSET | STATEMENT |
|
- ACCOUNTS
|
||||||
| ADD | DATABASES | IN | OR | STATE_WINDOW |
|
- ADD
|
||||||
| AFTER | DAYS | INITIALLY | ORDER | STORAGE |
|
- AFTER
|
||||||
| ALL | DBS | INSERT | PARTITIONS | STREAM |
|
- ALL
|
||||||
| ALTER | DEFERRED | INSTEAD | PASS | STREAMS |
|
- ALTER
|
||||||
| AND | DELIMITERS | INT | PLUS | STRING |
|
- AND
|
||||||
| AS | DESC | INTEGER | PPS | SYNCDB |
|
- AS
|
||||||
| ASC | DESCRIBE | INTERVAL | PRECISION | TABLE |
|
- ASC
|
||||||
| ATTACH | DETACH | INTO | PREV | TABLES |
|
- ATTACH
|
||||||
| BEFORE | DISTINCT | IS | PRIVILEGE | TAG |
|
|
||||||
| BEGIN | DIVIDE | ISNULL | QTIME | TAGS |
|
### B
|
||||||
| BETWEEN | DNODE | JOIN | QUERIES | TBNAME |
|
|
||||||
| BIGINT | DNODES | KEEP | QUERY | TIMES |
|
- BEFORE
|
||||||
| BINARY | DOT | KEY | QUORUM | TIMESTAMP |
|
- BEGIN
|
||||||
| BITAND | DOUBLE | KILL | RAISE | TINYINT |
|
- BETWEEN
|
||||||
| BITNOT | DROP | LE | REM | TOPIC |
|
- BIGINT
|
||||||
| BITOR | EACH | LIKE | REPLACE | TOPICS |
|
- BINARY
|
||||||
| BLOCKS | END | LIMIT | REPLICA | TRIGGER |
|
- BITAND
|
||||||
| BOOL | EQ | LINEAR | RESET | TSERIES |
|
- BITNOT
|
||||||
| BY | EXISTS | LOCAL | RESTRICT | UMINUS |
|
- BITOR
|
||||||
| CACHE | EXPLAIN | LP | ROW | UNION |
|
- BLOCKS
|
||||||
| CACHELAST | FAIL | LSHIFT | RP | UNSIGNED |
|
- BOOL
|
||||||
| CASCADE | FILE | LT | RSHIFT | UPDATE |
|
- BY
|
||||||
| CHANGE | FILL | MATCH | SCORES | UPLUS |
|
|
||||||
| CLUSTER | FLOAT | MAXROWS | SELECT | USE |
|
### C
|
||||||
| COLON | FOR | MINROWS | SEMI | USER |
|
|
||||||
| COLUMN | FROM | MINUS | SESSION | USERS |
|
- CACHE
|
||||||
| COMMA | FSYNC | MNODES | SET | USING |
|
- CACHELAST
|
||||||
| COMP | GE | MODIFY | SHOW | VALUES |
|
- CASCADE
|
||||||
| COMPACT | GLOB | MODULES | SLASH | VARIABLE |
|
- CHANGE
|
||||||
| CONCAT | GRANTS | NCHAR | SLIDING | VARIABLES |
|
- CLUSTER
|
||||||
| CONFLICT | GROUP | NE | SLIMIT | VGROUPS |
|
- COLON
|
||||||
| CONNECTION | GT | NONE | SMALLINT | VIEW |
|
- COLUMN
|
||||||
| CONNECTIONS | HAVING | NOT | SOFFSET | VNODES |
|
- COMMA
|
||||||
| CONNS | ID | NOTNULL | STABLE | WAL |
|
- COMP
|
||||||
| COPY | IF | NOW | STABLES | WHERE |
|
- COMPACT
|
||||||
| _C0 | _QSTART | _QSTOP | _QDURATION | _WSTART |
|
- CONCAT
|
||||||
| _WSTOP | _WDURATION | _ROWTS |
|
- 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
|
### TBNAME
|
||||||
|
|
|
@ -138,6 +138,10 @@ typedef enum EFunctionType {
|
||||||
FUNCTION_TYPE_TOP_MERGE,
|
FUNCTION_TYPE_TOP_MERGE,
|
||||||
FUNCTION_TYPE_BOTTOM_PARTIAL,
|
FUNCTION_TYPE_BOTTOM_PARTIAL,
|
||||||
FUNCTION_TYPE_BOTTOM_MERGE,
|
FUNCTION_TYPE_BOTTOM_MERGE,
|
||||||
|
FUNCTION_TYPE_FIRST_PARTIAL,
|
||||||
|
FUNCTION_TYPE_FIRST_MERGE,
|
||||||
|
FUNCTION_TYPE_LAST_PARTIAL,
|
||||||
|
FUNCTION_TYPE_LAST_MERGE,
|
||||||
|
|
||||||
// user defined funcion
|
// user defined funcion
|
||||||
FUNCTION_TYPE_UDF = 10000
|
FUNCTION_TYPE_UDF = 10000
|
||||||
|
|
|
@ -1327,8 +1327,8 @@ static int32_t smlKvTimeArrayCompare(const void *key1, const void *key2) {
|
||||||
static int32_t smlKvTimeHashCompare(const void *key1, const void *key2) {
|
static int32_t smlKvTimeHashCompare(const void *key1, const void *key2) {
|
||||||
SHashObj *s1 = *(SHashObj **)key1;
|
SHashObj *s1 = *(SHashObj **)key1;
|
||||||
SHashObj *s2 = *(SHashObj **)key2;
|
SHashObj *s2 = *(SHashObj **)key2;
|
||||||
SSmlKv *kv1 = (SSmlKv *)taosHashGet(s1, TS, TS_LEN);
|
SSmlKv *kv1 = *(SSmlKv **)taosHashGet(s1, TS, TS_LEN);
|
||||||
SSmlKv *kv2 = (SSmlKv *)taosHashGet(s2, TS, TS_LEN);
|
SSmlKv *kv2 = *(SSmlKv **)taosHashGet(s2, TS, TS_LEN);
|
||||||
ASSERT(kv1->type == TSDB_DATA_TYPE_TIMESTAMP);
|
ASSERT(kv1->type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||||
ASSERT(kv2->type == TSDB_DATA_TYPE_TIMESTAMP);
|
ASSERT(kv2->type == TSDB_DATA_TYPE_TIMESTAMP);
|
||||||
if (kv1->i < kv2->i) {
|
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) {
|
static int32_t smlDealCols(SSmlTableInfo* oneTable, bool dataFormat, SArray *cols){
|
||||||
if (dataFormat) {
|
if(dataFormat){
|
||||||
void *p = taosArraySearch(oneTable->cols, &cols, smlKvTimeArrayCompare, TD_GE);
|
void *p = taosArraySearch(oneTable->cols, &cols, smlKvTimeArrayCompare, TD_GT);
|
||||||
if (p == NULL) {
|
if(p == NULL){
|
||||||
taosArrayPush(oneTable->cols, &cols);
|
taosArrayPush(oneTable->cols, &cols);
|
||||||
} else { // to make the sort stable for update data
|
}else{
|
||||||
SArray *sa = (SArray *)p;
|
|
||||||
SSmlKv *cur = (SSmlKv *)taosArrayGet(sa, 0);
|
|
||||||
SSmlKv *dCur = (SSmlKv *)taosArrayGet(cols, 0);
|
|
||||||
if (cur->i > dCur->i) {
|
|
||||||
taosArrayInsert(oneTable->cols, TARRAY_ELEM_IDX(oneTable->cols, p), &cols);
|
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;
|
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);
|
taosHashPut(kvHash, kv->key, kv->keyLen, &kv, POINTER_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *p = taosArraySearch(oneTable->cols, &kvHash, smlKvTimeHashCompare, TD_GE);
|
void *p = taosArraySearch(oneTable->cols, &kvHash, smlKvTimeHashCompare, TD_GT);
|
||||||
if (p == NULL) {
|
if(p == NULL){
|
||||||
taosArrayPush(oneTable->cols, &kvHash);
|
taosArrayPush(oneTable->cols, &kvHash);
|
||||||
} else { // to make the sort stable for update data
|
}else{
|
||||||
SHashObj *sa = (SHashObj *)p;
|
taosArrayInsert(oneTable->cols, TARRAY_ELEM_IDX(oneTable->cols, p), &kvHash);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
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);
|
ASSERT_EQ(taos_errno(pRes), 0);
|
||||||
taos_free_result(pRes);
|
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);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
|
@ -582,6 +582,15 @@ int32_t* setupColumnOffset(const SSDataBlock* pBlock, int32_t rowCapacity) {
|
||||||
return offset;
|
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) {
|
static SSDataBlock* buildPartitionResult(SOperatorInfo* pOperator) {
|
||||||
SPartitionOperatorInfo* pInfo = pOperator->info;
|
SPartitionOperatorInfo* pInfo = pOperator->info;
|
||||||
|
|
||||||
|
@ -591,6 +600,7 @@ static SSDataBlock* buildPartitionResult(SOperatorInfo* pOperator) {
|
||||||
pInfo->pGroupIter = taosHashIterate(pInfo->pGroupSet, pInfo->pGroupIter);
|
pInfo->pGroupIter = taosHashIterate(pInfo->pGroupSet, pInfo->pGroupIter);
|
||||||
if (pInfo->pGroupIter == NULL) {
|
if (pInfo->pGroupIter == NULL) {
|
||||||
doSetOperatorCompleted(pOperator);
|
doSetOperatorCompleted(pOperator);
|
||||||
|
clearPartitionOperator(pInfo);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -93,10 +93,14 @@ int32_t diffFunction(SqlFunctionCtx *pCtx);
|
||||||
|
|
||||||
bool getFirstLastFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
bool getFirstLastFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv);
|
||||||
int32_t firstFunction(SqlFunctionCtx *pCtx);
|
int32_t firstFunction(SqlFunctionCtx *pCtx);
|
||||||
|
int32_t firstFunctionMerge(SqlFunctionCtx *pCtx);
|
||||||
int32_t lastFunction(SqlFunctionCtx *pCtx);
|
int32_t lastFunction(SqlFunctionCtx *pCtx);
|
||||||
|
int32_t lastFunctionMerge(SqlFunctionCtx *pCtx);
|
||||||
int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||||
|
int32_t firstLastPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock);
|
||||||
int32_t firstCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
int32_t firstCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx);
|
||||||
int32_t lastCombine(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 getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
|
||||||
bool getTopBotMergeFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
|
bool getTopBotMergeFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv);
|
||||||
|
|
|
@ -954,6 +954,41 @@ static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t l
|
||||||
return TSDB_CODE_SUCCESS;
|
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) {
|
static int32_t translateUnique(SFunctionNode* pFunc, char* pErrBuf, int32_t len) {
|
||||||
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
if (1 != LIST_LENGTH(pFunc->pParameterList)) {
|
||||||
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName);
|
||||||
|
@ -1704,6 +1739,30 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
.processFunc = firstFunction,
|
.processFunc = firstFunction,
|
||||||
.finalizeFunc = firstLastFinalize,
|
.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,
|
.combineFunc = firstCombine,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -1715,6 +1774,30 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
|
||||||
.initFunc = functionSetup,
|
.initFunc = functionSetup,
|
||||||
.processFunc = lastFunction,
|
.processFunc = lastFunction,
|
||||||
.finalizeFunc = firstLastFinalize,
|
.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,
|
.combineFunc = lastCombine,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,6 +71,12 @@ typedef struct STopBotRes {
|
||||||
STopBotResItem* pItems;
|
STopBotResItem* pItems;
|
||||||
} STopBotRes;
|
} STopBotRes;
|
||||||
|
|
||||||
|
typedef struct SFirstLastRes {
|
||||||
|
bool hasResult;
|
||||||
|
int32_t bytes;
|
||||||
|
char buf[];
|
||||||
|
} SFirstLastRes;
|
||||||
|
|
||||||
typedef struct SStddevRes {
|
typedef struct SStddevRes {
|
||||||
double result;
|
double result;
|
||||||
int64_t count;
|
int64_t count;
|
||||||
|
@ -2230,9 +2236,13 @@ int32_t apercentileCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx)
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t getFirstLastInfoSize(int32_t resBytes) {
|
||||||
|
return sizeof(SFirstLastRes) + resBytes + sizeof(int64_t);
|
||||||
|
}
|
||||||
|
|
||||||
bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
bool getFirstLastFuncEnv(SFunctionNode* pFunc, SFuncExecEnv* pEnv) {
|
||||||
SColumnNode* pNode = (SColumnNode*)nodesListGetNode(pFunc->pParameterList, 0);
|
SColumnNode* pNode = (SColumnNode *)nodesListGetNode(pFunc->pParameterList, 0);
|
||||||
pEnv->calcMemSize = pNode->node.resType.bytes + sizeof(int64_t);
|
pEnv->calcMemSize = sizeof(SFirstLastRes) + pNode->node.resType.bytes + sizeof(int64_t);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2256,12 +2266,13 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
int32_t numOfElems = 0;
|
int32_t numOfElems = 0;
|
||||||
|
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
|
SFirstLastRes *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
|
|
||||||
int32_t bytes = pInputCol->info.bytes;
|
int32_t bytes = pInputCol->info.bytes;
|
||||||
|
pInfo->bytes = bytes;
|
||||||
|
|
||||||
// All null data column, return directly.
|
// All null data column, return directly.
|
||||||
if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
|
if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
|
||||||
|
@ -2279,7 +2290,7 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
if (blockDataOrder == TSDB_ORDER_ASC) {
|
if (blockDataOrder == TSDB_ORDER_ASC) {
|
||||||
// filter according to current result firstly
|
// filter according to current result firstly
|
||||||
if (pResInfo->numOfRes > 0) {
|
if (pResInfo->numOfRes > 0) {
|
||||||
TSKEY ts = *(TSKEY*)(buf + bytes);
|
TSKEY ts = *(TSKEY*)(pInfo->buf + bytes);
|
||||||
if (ts < startKey) {
|
if (ts < startKey) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2295,9 +2306,10 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
char* data = colDataGetData(pInputCol, i);
|
char* data = colDataGetData(pInputCol, i);
|
||||||
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
||||||
|
|
||||||
if (pResInfo->numOfRes == 0 || *(TSKEY*)(buf + bytes) > cts) {
|
if (pResInfo->numOfRes == 0 || *(TSKEY*)(pInfo->buf + bytes) > cts) {
|
||||||
memcpy(buf, data, bytes);
|
memcpy(pInfo->buf, data, bytes);
|
||||||
*(TSKEY*)(buf + bytes) = cts;
|
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
||||||
|
pInfo->hasResult = true;
|
||||||
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
|
|
||||||
pResInfo->numOfRes = 1;
|
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,
|
// in case of descending order time stamp serial, which usually happens as the results of the nest query,
|
||||||
// all data needs to be check.
|
// all data needs to be check.
|
||||||
if (pResInfo->numOfRes > 0) {
|
if (pResInfo->numOfRes > 0) {
|
||||||
TSKEY ts = *(TSKEY*)(buf + bytes);
|
TSKEY ts = *(TSKEY*)(pInfo->buf + bytes);
|
||||||
if (ts < endKey) {
|
if (ts < endKey) {
|
||||||
return TSDB_CODE_SUCCESS;
|
return TSDB_CODE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -2324,9 +2336,10 @@ int32_t firstFunction(SqlFunctionCtx* pCtx) {
|
||||||
char* data = colDataGetData(pInputCol, i);
|
char* data = colDataGetData(pInputCol, i);
|
||||||
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
||||||
|
|
||||||
if (pResInfo->numOfRes == 0 || *(TSKEY*)(buf + bytes) > cts) {
|
if (pResInfo->numOfRes == 0 || *(TSKEY*)(pInfo->buf + bytes) > cts) {
|
||||||
memcpy(buf, data, bytes);
|
memcpy(pInfo->buf, data, bytes);
|
||||||
*(TSKEY*)(buf + bytes) = cts;
|
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
||||||
|
pInfo->hasResult = true;
|
||||||
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
pResInfo->numOfRes = 1;
|
pResInfo->numOfRes = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -2342,12 +2355,13 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
int32_t numOfElems = 0;
|
int32_t numOfElems = 0;
|
||||||
|
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
char* buf = GET_ROWCELL_INTERBUF(pResInfo);
|
SFirstLastRes *pInfo = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
|
|
||||||
SInputColumnInfoData* pInput = &pCtx->input;
|
SInputColumnInfoData* pInput = &pCtx->input;
|
||||||
SColumnInfoData* pInputCol = pInput->pData[0];
|
SColumnInfoData* pInputCol = pInput->pData[0];
|
||||||
|
|
||||||
int32_t bytes = pInputCol->info.bytes;
|
int32_t bytes = pInputCol->info.bytes;
|
||||||
|
pInfo->bytes = bytes;
|
||||||
|
|
||||||
// All null data column, return directly.
|
// All null data column, return directly.
|
||||||
if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
|
if (pInput->colDataAggIsSet && (pInput->pColumnDataAgg[0]->numOfNull == pInput->totalRows)) {
|
||||||
|
@ -2372,10 +2386,11 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
char* data = colDataGetData(pInputCol, i);
|
char* data = colDataGetData(pInputCol, i);
|
||||||
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
||||||
if (pResInfo->numOfRes == 0 || *(TSKEY*)(buf + bytes) < cts) {
|
if (pResInfo->numOfRes == 0 || *(TSKEY*)(pInfo->buf + bytes) < cts) {
|
||||||
memcpy(buf, data, bytes);
|
memcpy(pInfo->buf, data, bytes);
|
||||||
*(TSKEY*)(buf + bytes) = cts;
|
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
||||||
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
|
pInfo->hasResult = true;
|
||||||
pResInfo->numOfRes = 1;
|
pResInfo->numOfRes = 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2390,9 +2405,10 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
|
|
||||||
char* data = colDataGetData(pInputCol, i);
|
char* data = colDataGetData(pInputCol, i);
|
||||||
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
TSKEY cts = getRowPTs(pInput->pPTS, i);
|
||||||
if (pResInfo->numOfRes == 0 || *(TSKEY*)(buf + bytes) < cts) {
|
if (pResInfo->numOfRes == 0 || *(TSKEY*)(pInfo->buf + bytes) < cts) {
|
||||||
memcpy(buf, data, bytes);
|
memcpy(pInfo->buf, data, bytes);
|
||||||
*(TSKEY*)(buf + bytes) = cts;
|
*(TSKEY*)(pInfo->buf + bytes) = cts;
|
||||||
|
pInfo->hasResult = true;
|
||||||
pResInfo->numOfRes = 1;
|
pResInfo->numOfRes = 1;
|
||||||
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
// DO_UPDATE_TAG_COLUMNS(pCtx, ts);
|
||||||
}
|
}
|
||||||
|
@ -2404,6 +2420,56 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
|
||||||
return TSDB_CODE_SUCCESS;
|
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 firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
int32_t slotId = pCtx->pExpr->base.resSchema.slotId;
|
||||||
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
SColumnInfoData* pCol = taosArrayGet(pBlock->pDataBlock, slotId);
|
||||||
|
@ -2411,12 +2477,30 @@ int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) {
|
||||||
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx);
|
||||||
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0;
|
||||||
|
|
||||||
char* in = GET_ROWCELL_INTERBUF(pResInfo);
|
SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pResInfo);
|
||||||
colDataAppend(pCol, pBlock->info.rows, in, pResInfo->isNullRes);
|
colDataAppend(pCol, pBlock->info.rows, pRes->buf, pResInfo->isNullRes);
|
||||||
|
|
||||||
return pResInfo->numOfRes;
|
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) {
|
int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx) {
|
||||||
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
SResultRowEntryInfo* pDResInfo = GET_RES_INFO(pDestCtx);
|
||||||
char* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo);
|
char* pDBuf = GET_ROWCELL_INTERBUF(pDResInfo);
|
||||||
|
|
|
@ -283,6 +283,8 @@ void sortRemoveDataBlockDupRowsRaw(STableDataBlocks* dataBuf) {
|
||||||
|
|
||||||
if (!dataBuf->ordered) {
|
if (!dataBuf->ordered) {
|
||||||
char* pBlockData = pBlocks->data;
|
char* pBlockData = pBlocks->data;
|
||||||
|
|
||||||
|
// todo. qsort is unstable, if timestamp is same, should get the last one
|
||||||
qsort(pBlockData, pBlocks->numOfRows, dataBuf->rowSize, rowDataCompar);
|
qsort(pBlockData, pBlocks->numOfRows, dataBuf->rowSize, rowDataCompar);
|
||||||
|
|
||||||
int32_t i = 0;
|
int32_t i = 0;
|
||||||
|
@ -350,6 +352,8 @@ int sortRemoveDataBlockDupRows(STableDataBlocks* dataBuf, SBlockKeyInfo* pBlkKey
|
||||||
|
|
||||||
if (!dataBuf->ordered) {
|
if (!dataBuf->ordered) {
|
||||||
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
||||||
|
|
||||||
|
// todo. qsort is unstable, if timestamp is same, should get the last one
|
||||||
qsort(pBlkKeyTuple, nRows, sizeof(SBlockKeyTuple), rowDataCompar);
|
qsort(pBlkKeyTuple, nRows, sizeof(SBlockKeyTuple), rowDataCompar);
|
||||||
|
|
||||||
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
pBlkKeyTuple = pBlkKeyInfo->pKeyTuple;
|
||||||
|
|
|
@ -175,7 +175,13 @@ void *taosbsearch(const void *key, const void *base, int32_t nmemb, int32_t size
|
||||||
|
|
||||||
c = compar(key, p);
|
c = compar(key, p);
|
||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
|
if (flags == TD_GT){
|
||||||
|
lidx = midx + 1;
|
||||||
|
} else if(flags == TD_LT){
|
||||||
|
ridx = midx - 1;
|
||||||
|
}else{
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
} else if (c < 0) {
|
} else if (c < 0) {
|
||||||
ridx = midx - 1;
|
ridx = midx - 1;
|
||||||
} else {
|
} 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);
|
return (c <= 0) ? p : (midx + 1 < nmemb ? p + size : NULL);
|
||||||
} else if (flags == TD_LE) {
|
} else if (flags == TD_LE) {
|
||||||
return (c >= 0) ? p : (midx > 0 ? p - size : NULL);
|
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 {
|
} else {
|
||||||
ASSERT(0);
|
ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -248,6 +248,170 @@ TEST(testCase, taosbsearch_greater_or_equal) {
|
||||||
ASSERT_EQ(pRet, nullptr);
|
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) {
|
TEST(testCase, taosbsearch_less_or_equal) {
|
||||||
// For equal test
|
// For equal test
|
||||||
int key = 3;
|
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);
|
pRet = taosbsearch((void *)&key, (void *)array5, 5, sizeof(int), compareFunc, TD_LE);
|
||||||
ASSERT_EQ(*(int *)pRet, 15);
|
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);
|
||||||
|
}
|
Loading…
Reference in New Issue