other:merge 3.0

This commit is contained in:
Haojun Liao 2022-09-27 18:12:54 +08:00
commit bd6cf3137f
76 changed files with 5102 additions and 4449 deletions

View File

@ -2,7 +2,7 @@
# taos-tools
ExternalProject_Add(taos-tools
GIT_REPOSITORY https://github.com/taosdata/taos-tools.git
GIT_TAG cf1df1c
GIT_TAG f03c09a
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taos-tools"
BINARY_DIR ""
#BUILD_IN_SOURCE TRUE

View File

@ -13,7 +13,7 @@ Single row functions return a result for each row.
#### ABS
```sql
SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
ABS(expr)
```
**Description**: The absolute value of a specific field.
@ -31,7 +31,7 @@ SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### ACOS
```sql
SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
ACOS(expr)
```
**Description**: The arc cosine of a specific field.
@ -49,7 +49,7 @@ SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### ASIN
```sql
SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
ASIN(expr)
```
**Description**: The arc sine of a specific field.
@ -68,7 +68,7 @@ SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### ATAN
```sql
SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
ATAN(expr)
```
**Description**: The arc tangent of a specific field.
@ -87,7 +87,7 @@ SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### CEIL
```sql
SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
CEIL(expr)
```
**Description**: The rounded up value of a specific field
@ -105,7 +105,7 @@ SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
#### COS
```sql
SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
COS(expr)
```
**Description**: The cosine of a specific field.
@ -123,7 +123,7 @@ SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### FLOOR
```sql
SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
FLOOR(expr)
```
**Description**: The rounded down value of a specific field
@ -132,7 +132,7 @@ SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
#### LOG
```sql
SELECT LOG(field_name[, base]) FROM { tb_name | stb_name } [WHERE clause]
LOG(expr [, base])
```
**Description**: The logarithm of a specific field with `base` as the radix. If you do not enter a base, the natural logarithm of the field is returned.
@ -151,7 +151,7 @@ SELECT LOG(field_name[, base]) FROM { tb_name | stb_name } [WHERE clause]
#### POW
```sql
SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
POW(expr, power)
```
**Description**: The power of a specific field with `power` as the exponent.
@ -170,7 +170,7 @@ SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
#### ROUND
```sql
SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
ROUND(expr)
```
**Description**: The rounded value of a specific field.
@ -180,7 +180,7 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
#### SIN
```sql
SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
SIN(expr)
```
**Description**: The sine of a specific field.
@ -198,7 +198,7 @@ SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### SQRT
```sql
SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
SQRT(expr)
```
**Description**: The square root of a specific field.
@ -216,7 +216,7 @@ SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### TAN
```sql
SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
TAN(expr)
```
**Description**: The tangent of a specific field.
@ -238,7 +238,7 @@ Concatenation functions take strings as input and produce string or numeric valu
#### CHAR_LENGTH
```sql
SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
CHAR_LENGTH(expr)
```
**Description**: The length in number of characters of a string
@ -254,7 +254,7 @@ SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### CONCAT
```sql
SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
CONCAT(expr1, expr2 [, expr] ...)
```
**Description**: The concatenation result of two or more strings
@ -271,7 +271,7 @@ SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHER
#### CONCAT_WS
```sql
SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
CONCAT_WS(separator_expr, expr1, expr2 [, expr] ...)
```
**Description**: The concatenation result of two or more strings with separator
@ -288,7 +288,7 @@ SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | st
#### LENGTH
```sql
SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
LENGTH(expr)
```
**Description**: The length in bytes of a string
@ -305,7 +305,7 @@ SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### LOWER
```sql
SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
LOWER(expr)
```
**Description**: Convert the input string to lower case
@ -322,7 +322,7 @@ SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### LTRIM
```sql
SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
LTRIM(expr)
```
**Description**: Remove the left leading blanks of a string
@ -339,7 +339,7 @@ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### RTRIM
```sql
SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
LTRIM(expr)
```
**Description**: Remove the right tailing blanks of a string
@ -356,7 +356,7 @@ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### SUBSTR
```sql
SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
SUBSTR(expr, pos [, len])
```
**Description**: The sub-string starting from `pos` with length of `len` from the original string `str` - If `len` is not specified, it means from `pos` to the end.
@ -373,7 +373,7 @@ SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
#### UPPER
```sql
SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
UPPER(expr)
```
**Description**: Convert the input string to upper case
@ -394,10 +394,10 @@ Conversion functions change the data type of a value.
#### CAST
```sql
SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
CAST(expr AS type_name)
```
**Description**: Convert the input data `expression` into the type specified by `type_name`. This function can be used only in SELECT statements.
**Description**: Convert the input data `expr` into the type specified by `type_name`. This function can be used only in SELECT statements.
**Return value type**: The type specified by parameter `type_name`
@ -418,7 +418,7 @@ SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
#### TO_ISO8601
```sql
SELECT TO_ISO8601(ts[, timezone]) FROM { tb_name | stb_name } [WHERE clause];
TO_ISO8601(expr [, timezone])
```
**Description**: The ISO8601 date/time format converted from a UNIX timestamp, plus the timezone. You can specify any time zone with the timezone parameter. If you do not enter this parameter, the time zone on the client is used.
@ -441,7 +441,7 @@ SELECT TO_ISO8601(ts[, timezone]) FROM { tb_name | stb_name } [WHERE clause];
#### TO_JSON
```sql
SELECT TO_JSON(str_literal) FROM { tb_name | stb_name } [WHERE clause];
TO_JSON(str_literal)
```
**Description**: Converts a string into JSON.
@ -458,7 +458,7 @@ SELECT TO_JSON(str_literal) FROM { tb_name | stb_name } [WHERE clause];
#### TO_UNIXTIMESTAMP
```sql
SELECT TO_UNIXTIMESTAMP(datetime_string) FROM { tb_name | stb_name } [WHERE clause];
TO_UNIXTIMESTAMP(expr)
```
**Description**: UNIX timestamp converted from a string of date/time format
@ -486,9 +486,7 @@ All functions that return the current time, such as `NOW`, `TODAY`, and `TIMEZON
#### NOW
```sql
SELECT NOW() FROM { tb_name | stb_name } [WHERE clause];
SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior NOW();
INSERT INTO tb_name VALUES (NOW(), ...);
NOW()
```
**Description**: The current time of the client side system
@ -511,7 +509,7 @@ INSERT INTO tb_name VALUES (NOW(), ...);
#### TIMEDIFF
```sql
SELECT TIMEDIFF(ts | datetime_string1, ts | datetime_string2 [, time_unit]) FROM { tb_name | stb_name } [WHERE clause];
TIMEDIFF(expr1, expr2 [, time_unit])
```
**Description**: The difference between two timestamps, and rounded to the time unit specified by `time_unit`
@ -534,7 +532,7 @@ SELECT TIMEDIFF(ts | datetime_string1, ts | datetime_string2 [, time_unit]) FROM
#### TIMETRUNCATE
```sql
SELECT TIMETRUNCATE(ts | datetime_string , time_unit) FROM { tb_name | stb_name } [WHERE clause];
TIMETRUNCATE(expr, time_unit)
```
**Description**: Truncate the input timestamp with unit specified by `time_unit`
@ -555,7 +553,7 @@ SELECT TIMETRUNCATE(ts | datetime_string , time_unit) FROM { tb_name | stb_name
#### TIMEZONE
```sql
SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
TIMEZONE()
```
**Description**: The timezone of the client side system
@ -570,9 +568,7 @@ SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
#### TODAY
```sql
SELECT TODAY() FROM { tb_name | stb_name } [WHERE clause];
SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior TODAY()];
INSERT INTO tb_name VALUES (TODAY(), ...);
TODAY()
```
**Description**: The timestamp of 00:00:00 of the client side system
@ -599,7 +595,12 @@ TDengine supports the following aggregate functions:
### APERCENTILE
```sql
SELECT APERCENTILE(field_name, P[, algo_type]) FROM { tb_name | stb_name } [WHERE clause]
APERCENTILE(expr, p [, algo_type])
algo_type: {
"default"
| "t-digest"
}
```
**Description**: Similar to `PERCENTILE`, but a simulated result is returned
@ -611,14 +612,14 @@ SELECT APERCENTILE(field_name, P[, algo_type]) FROM { tb_name | stb_name } [WHER
**Applicable table types**: standard tables and supertables
**Explanations**
- _P_ is in range [0,100], when _P_ is 0, the result is same as using function MIN; when _P_ is 100, the result is same as function MAX.
- _p_ is in range [0,100], when _p_ is 0, the result is same as using function MIN; when _p_ is 100, the result is same as function MAX.
- `algo_type` can only be input as `default` or `t-digest` Enter `default` to use a histogram-based algorithm. Enter `t-digest` to use the t-digest algorithm to calculate the approximation of the quantile. `default` is used by default.
- The approximation result of `t-digest` algorithm is sensitive to input data order. For example, when querying STable with different input data order there might be minor differences in calculated results.
### AVG
```sql
SELECT AVG(field_name) FROM tb_name [WHERE clause];
AVG(expr)
```
**Description**: The average value of the specified fields.
@ -633,7 +634,7 @@ SELECT AVG(field_name) FROM tb_name [WHERE clause];
### COUNT
```sql
SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
COUNT({* | expr})
```
**Description**: The number of records in the specified fields.
@ -653,7 +654,7 @@ If you input a specific column, the number of non-null values in the column is r
### ELAPSED
```sql
SELECT ELAPSED(ts_primary_key [, time_unit]) FROM { tb_name | stb_name } [WHERE clause] [INTERVAL(interval [, offset]) [SLIDING sliding]];
ELAPSED(ts_primary_key [, time_unit])
```
**Description**`elapsed` function can be used to calculate the continuous time length in which there is valid data. If it's used with `INTERVAL` clause, the returned result is the calcualted time length within each time window. If it's used without `INTERVAL` caluse, the returned result is the calculated time length within the specified time range. Please be noted that the return value of `elapsed` is the number of `time_unit` in the calculated time length.
@ -665,7 +666,7 @@ SELECT ELAPSED(ts_primary_key [, time_unit]) FROM { tb_name | stb_name } [WHERE
**Applicable tables**: table, STable, outter in nested query
**Explanations**
- `field_name` parameter can only be the first column of a table, i.e. timestamp primary key.
- `ts_primary_key` parameter can only be the first column of a table, i.e. timestamp primary key.
- The minimum value of `time_unit` is the time precision of the database. If `time_unit` is not specified, the time precision of the database is used as the default time unit. Time unit specified by `time_unit` can be:
1b (nanoseconds), 1u (microseconds), 1a (milliseconds), 1s (seconds), 1m (minutes), 1h (hours), 1d (days), or 1w (weeks)
- It can be used with `INTERVAL` to get the time valid time length of each time window. Please be noted that the return value is same as the time window for all time windows except for the first and the last time window.
@ -679,7 +680,7 @@ SELECT ELAPSED(ts_primary_key [, time_unit]) FROM { tb_name | stb_name } [WHERE
### LEASTSQUARES
```sql
SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause];
LEASTSQUARES(expr, start_val, step_val)
```
**Description**: The linear regression function of the specified column and the timestamp column (primary key), `start_val` is the initial value and `step_val` is the step value.
@ -694,7 +695,7 @@ SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause]
### SPREAD
```sql
SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
SPREAD(expr)
```
**Description**: The difference between the max and the min of a specific column
@ -709,7 +710,7 @@ SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
### STDDEV
```sql
SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
STDDEV(expr)
```
**Description**: Standard deviation of a specific column in a table or STable
@ -724,7 +725,7 @@ SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
### SUM
```sql
SELECT SUM(field_name) FROM tb_name [WHERE clause];
SUM(expr)
```
**Description**: The sum of a specific column in a table or STable
@ -739,7 +740,7 @@ SELECT SUM(field_name) FROM tb_name [WHERE clause];
### HYPERLOGLOG
```sql
SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
HYPERLOGLOG(expr)
```
**Description**
@ -756,7 +757,7 @@ SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
### HISTOGRAM
```sql
SELECT HISTOGRAM(field_namebin_type, bin_description, normalized) FROM tb_name [WHERE clause];
HISTOGRAM(exprbin_type, bin_description, normalized)
```
**Description**Returns count of data points in user-specified ranges.
@ -786,7 +787,7 @@ SELECT HISTOGRAM(field_namebin_type, bin_description, normalized) FROM tb_nam
### PERCENTILE
```sql
SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
PERCENTILE(expr, p)
```
**Description**: The value whose rank in a specific column matches the specified percentage. If such a value matching the specified percentage doesn't exist in the column, an interpolation value will be returned.
@ -797,7 +798,7 @@ SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
**Applicable table types**: table only
**More explanations**: _P_ is in range [0,100], when _P_ is 0, the result is same as using function MIN; when _P_ is 100, the result is same as function MAX.
**More explanations**: _p_ is in range [0,100], when _p_ is 0, the result is same as using function MIN; when _p_ is 100, the result is same as function MAX.
## Selection Functions
@ -807,7 +808,7 @@ Selection functions return one or more results depending. You can specify the ti
### BOTTOM
```sql
SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
BOTTOM(expr, k)
```
**Description**: The least _k_ values of a specific column in a table or STable. If a value has multiple occurrences in the column but counting all of them in will exceed the upper limit _k_, then a part of them will be returned randomly.
@ -827,7 +828,7 @@ SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
### FIRST
```sql
SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
FIRST(expr)
```
**Description**: The first non-null value of a specific column in a table or STable
@ -847,7 +848,7 @@ SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
### INTERP
```sql
SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] RANGE(timestamp1,timestamp2) EVERY(interval) FILL({ VALUE | PREV | NULL | LINEAR | NEXT});
INTERP(expr)
```
**Description**: The value that matches the specified timestamp range is returned, if existing; or an interpolation value is returned.
@ -870,7 +871,7 @@ SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] RA
### LAST
```sql
SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
LAST(expr)
```
**Description**: The last non-NULL value of a specific column in a table or STable
@ -891,7 +892,7 @@ SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
### LAST_ROW
```sql
SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
LAST_ROW(expr)
```
**Description**: The last row of a table or STable
@ -910,7 +911,7 @@ SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
### MAX
```sql
SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
MAX(expr)
```
**Description**: The maximum value of a specific column of a table or STable
@ -925,7 +926,7 @@ SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
### MIN
```sql
SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
MIN(expr)
```
**Description**: The minimum value of a specific column in a table or STable
@ -940,7 +941,7 @@ SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
### MODE
```sql
SELECT MODE(field_name) FROM tb_name [WHERE clause];
MODE(expr)
```
**Description**:The value which has the highest frequency of occurrence. NULL is returned if there are multiple values which have highest frequency of occurrence.
@ -955,7 +956,7 @@ SELECT MODE(field_name) FROM tb_name [WHERE clause];
### SAMPLE
```sql
SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
SAMPLE(expr, k)
```
**Description**: _k_ sampling values of a specific column. The applicable range of _k_ is [1,1000].
@ -977,7 +978,7 @@ This function cannot be used in expression calculation.
### TAIL
```sql
SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
TAIL(expr, k, offset_val)
```
**Description**: The next _k_ rows are returned after skipping the last `offset_val` rows, NULL values are not ignored. `offset_val` is optional parameter. When it's not specified, the last _k_ rows are returned. When `offset_val` is used, the effect is same as `order by ts desc LIMIT k OFFSET offset_val`.
@ -994,7 +995,7 @@ SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
### TOP
```sql
SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
TOP(expr, k)
```
**Description**: The greatest _k_ values of a specific column in a table or STable. If a value has multiple occurrences in the column but counting all of them in will exceed the upper limit _k_, then a part of them will be returned randomly.
@ -1014,7 +1015,7 @@ SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
### UNIQUE
```sql
SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
UNIQUE(expr)
```
**Description**: The values that occur the first time in the specified column. The effect is similar to `distinct` keyword, but it can also be used to match tags or timestamp. The first occurrence of a timestamp or tag is used.
@ -1033,7 +1034,7 @@ TDengine includes extensions to standard SQL that are intended specifically for
### CSUM
```sql
SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
CSUM(expr)
```
**Description**: The cumulative sum of each row for a specific column. The number of output rows is same as that of the input rows.
@ -1056,7 +1057,12 @@ SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
### DERIVATIVE
```sql
SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHERE clause];
DERIVATIVE(expr, time_inerval, ignore_negative)
ignore_negative: {
0
| 1
}
```
**Description**: The derivative of a specific column. The time rage can be specified by parameter `time_interval`, the minimum allowed time range is 1 second (1s); the value of `ignore_negative` can be 0 or 1, 1 means negative values are ignored.
@ -1075,7 +1081,12 @@ SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHER
### DIFF
```sql
SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHERE clause];
DIFF(expr [, ignore_negative])
ignore_negative: {
0
| 1
}
```
**Description**: The different of each row with its previous row for a specific column. `ignore_negative` can be specified as 0 or 1, the default value is 1 if it's not specified. `1` means negative values are ignored.
@ -1095,7 +1106,7 @@ SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHER
### IRATE
```sql
SELECT IRATE(field_name) FROM tb_name WHERE clause;
IRATE(expr)
```
**Description**: instantaneous rate on a specific column. The last two samples in the specified time range are used to calculate instantaneous rate. If the last sample value is smaller, then only the last sample value is used instead of the difference between the last two sample values.
@ -1110,7 +1121,7 @@ SELECT IRATE(field_name) FROM tb_name WHERE clause;
### MAVG
```sql
SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
MAVG(expr, k)
```
**Description**: The moving average of continuous _k_ values of a specific column. If the number of input rows is less than _k_, nothing is returned. The applicable range of _k_ is [1,1000].
@ -1133,7 +1144,7 @@ SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
### STATECOUNT
```sql
SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clause];
STATECOUNT(expr, oper, val)
```
**Description**: The number of continuous rows satisfying the specified conditions for a specific column. The result is shown as an extra column for each row. If the specified condition is evaluated as true, the number is increased by 1; otherwise the number is reset to -1. If the input value is NULL, then the corresponding row is skipped.
@ -1160,7 +1171,7 @@ SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clau
### STATEDURATION
```sql
SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
STATEDURATION(expr, oper, val, unit)
```
**Description**: The length of time range in which all rows satisfy the specified condition for a specific column. The result is shown as an extra column for each row. The length for the first row that satisfies the condition is 0. Next, if the condition is evaluated as true for a row, the time interval between current row and its previous row is added up to the time range; otherwise the time range length is reset to -1. If the value of the column is NULL, the corresponding row is skipped.
@ -1188,7 +1199,7 @@ SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [W
### TWA
```sql
SELECT TWA(field_name) FROM tb_name WHERE clause;
TWA(expr)
```
**Description**: Time weighted average on a specific column within a time range

View File

@ -14,7 +14,7 @@ toc_max_heading_level: 4
#### ABS
```sql
SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
ABS(expr)
```
**功能说明**:获得指定字段的绝对值。
@ -32,7 +32,7 @@ SELECT ABS(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### ACOS
```sql
SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
ACOS(expr)
```
**功能说明**:获得指定字段的反余弦结果。
@ -50,7 +50,7 @@ SELECT ACOS(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### ASIN
```sql
SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
ASIN(expr)
```
**功能说明**:获得指定字段的反正弦结果。
@ -69,7 +69,7 @@ SELECT ASIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### ATAN
```sql
SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
ATAN(expr)
```
**功能说明**:获得指定字段的反正切结果。
@ -88,7 +88,7 @@ SELECT ATAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### CEIL
```sql
SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
CEIL(expr)
```
**功能说明**:获得指定字段的向上取整数的结果。
@ -106,7 +106,7 @@ SELECT CEIL(field_name) FROM { tb_name | stb_name } [WHERE clause];
#### COS
```sql
SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
COS(expr)
```
**功能说明**:获得指定字段的余弦结果。
@ -124,7 +124,7 @@ SELECT COS(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### FLOOR
```sql
SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
FLOOR(expr)
```
**功能说明**:获得指定字段的向下取整数的结果。
@ -133,10 +133,10 @@ SELECT FLOOR(field_name) FROM { tb_name | stb_name } [WHERE clause];
#### LOG
```sql
SELECT LOG(field_name[, base]) FROM { tb_name | stb_name } [WHERE clause]
LOG(expr1[, expr2])
```
**功能说明**:获得指定字段对于底数 base 的对数。如果 base 参数省略,则返回指定字段的自然对数值。
**功能说明**:获得 expr1 对于底数 expr2 的对数。如果 expr2 参数省略,则返回指定字段的自然对数值。
**返回结果类型**DOUBLE。
@ -152,10 +152,10 @@ SELECT LOG(field_name[, base]) FROM { tb_name | stb_name } [WHERE clause]
#### POW
```sql
SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
POW(expr1, expr2)
```
**功能说明**:获得指定字段的指数为 power 的幂。
**功能说明**:获得 expr1 的指数为 expr2 的幂。
**返回结果类型**DOUBLE。
@ -171,7 +171,7 @@ SELECT POW(field_name, power) FROM { tb_name | stb_name } [WHERE clause]
#### ROUND
```sql
SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
ROUND(expr)
```
**功能说明**:获得指定字段的四舍五入的结果。
@ -181,7 +181,7 @@ SELECT ROUND(field_name) FROM { tb_name | stb_name } [WHERE clause];
#### SIN
```sql
SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
SIN(expr)
```
**功能说明**:获得指定字段的正弦结果。
@ -199,7 +199,7 @@ SELECT SIN(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### SQRT
```sql
SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
SQRT(expr)
```
**功能说明**:获得指定字段的平方根。
@ -217,7 +217,7 @@ SELECT SQRT(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### TAN
```sql
SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
TAN(expr)
```
**功能说明**:获得指定字段的正切结果。
@ -239,7 +239,7 @@ SELECT TAN(field_name) FROM { tb_name | stb_name } [WHERE clause]
#### CHAR_LENGTH
```sql
SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
CHAR_LENGTH(expr)
```
**功能说明**:以字符计数的字符串长度。
@ -255,7 +255,7 @@ SELECT CHAR_LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### CONCAT
```sql
SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
CONCAT(expr1, expr2 [, expr] ... )
```
**功能说明**:字符串连接函数。
@ -272,7 +272,7 @@ SELECT CONCAT(str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHER
#### CONCAT_WS
```sql
SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | stb_name } [WHERE clause]
CONCAT_WS(separator_expr, expr1, expr2 [, expr] ...)
```
**功能说明**:带分隔符的字符串连接函数。
@ -289,7 +289,7 @@ SELECT CONCAT_WS(separator, str1|column1, str2|column2, ...) FROM { tb_name | st
#### LENGTH
```sql
SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
LENGTH(expr)
```
**功能说明**:以字节计数的字符串长度。
@ -306,7 +306,7 @@ SELECT LENGTH(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### LOWER
```sql
SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
LOWER(expr)
```
**功能说明**:将字符串参数值转换为全小写字母。
@ -323,7 +323,7 @@ SELECT LOWER(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### LTRIM
```sql
SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
LTRIM(expr)
```
**功能说明**:返回清除左边空格后的字符串。
@ -340,7 +340,7 @@ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### RTRIM
```sql
SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
LTRIM(expr)
```
**功能说明**:返回清除右边空格后的字符串。
@ -357,7 +357,7 @@ SELECT LTRIM(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### SUBSTR
```sql
SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
SUBSTR(expr, pos [,len])
```
**功能说明**:从源字符串 str 中的指定位置 pos 开始取一个长度为 len 的子串并返回。如果输入参数 len 被忽略,返回的子串包含从 pos 开始的整个字串。
@ -374,7 +374,7 @@ SELECT SUBSTR(str,pos[,len]) FROM { tb_name | stb_name } [WHERE clause]
#### UPPER
```sql
SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
UPPER(expr)
```
**功能说明**:将字符串参数值转换为全大写字母。
@ -395,10 +395,10 @@ SELECT UPPER(str|column) FROM { tb_name | stb_name } [WHERE clause]
#### CAST
```sql
SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
CAST(expr AS type_name)
```
**功能说明**:数据类型转换函数,返回 expression 转换为 type_name 指定的类型后的结果。只适用于 select 子句中。
**功能说明**:数据类型转换函数,返回 expr 转换为 type_name 指定的类型后的结果。只适用于 select 子句中。
**返回结果类型**CAST 中指定的类型type_name)。
@ -419,7 +419,7 @@ SELECT CAST(expression AS type_name) FROM { tb_name | stb_name } [WHERE clause]
#### TO_ISO8601
```sql
SELECT TO_ISO8601(ts[, timezone]) FROM { tb_name | stb_name } [WHERE clause];
TO_ISO8601(expr [, timezone])
```
**功能说明**:将 UNIX 时间戳转换成为 ISO8601 标准的日期时间格式并附加时区信息。timezone 参数允许用户为输出结果指定附带任意时区信息。如果 timezone 参数省略,输出结果则附带当前客户端的系统时区信息。
@ -442,7 +442,7 @@ SELECT TO_ISO8601(ts[, timezone]) FROM { tb_name | stb_name } [WHERE clause];
#### TO_JSON
```sql
SELECT TO_JSON(str_literal) FROM { tb_name | stb_name } [WHERE clause];
TO_JSON(str_literal)
```
**功能说明**: 将字符串常量转换为 JSON 类型。
@ -459,7 +459,7 @@ SELECT TO_JSON(str_literal) FROM { tb_name | stb_name } [WHERE clause];
#### TO_UNIXTIMESTAMP
```sql
SELECT TO_UNIXTIMESTAMP(datetime_string) FROM { tb_name | stb_name } [WHERE clause];
TO_UNIXTIMESTAMP(expr)
```
**功能说明**:将日期时间格式的字符串转换成为 UNIX 时间戳。
@ -487,9 +487,7 @@ SELECT TO_UNIXTIMESTAMP(datetime_string) FROM { tb_name | stb_name } [WHERE clau
#### NOW
```sql
SELECT NOW() FROM { tb_name | stb_name } [WHERE clause];
SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior NOW();
INSERT INTO tb_name VALUES (NOW(), ...);
NOW()
```
**功能说明**:返回客户端当前系统时间。
@ -512,7 +510,7 @@ INSERT INTO tb_name VALUES (NOW(), ...);
#### TIMEDIFF
```sql
SELECT TIMEDIFF(ts | datetime_string1, ts | datetime_string2 [, time_unit]) FROM { tb_name | stb_name } [WHERE clause];
TIMEDIFF(expr1, expr2 [, time_unit])
```
**功能说明**:计算两个时间戳之间的差值,并近似到时间单位 time_unit 指定的精度。
@ -535,7 +533,7 @@ SELECT TIMEDIFF(ts | datetime_string1, ts | datetime_string2 [, time_unit]) FROM
#### TIMETRUNCATE
```sql
SELECT TIMETRUNCATE(ts | datetime_string , time_unit) FROM { tb_name | stb_name } [WHERE clause];
TIMETRUNCATE(expr, time_unit)
```
**功能说明**:将时间戳按照指定时间单位 time_unit 进行截断。
@ -556,7 +554,7 @@ SELECT TIMETRUNCATE(ts | datetime_string , time_unit) FROM { tb_name | stb_name
#### TIMEZONE
```sql
SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
TIMEZONE()
```
**功能说明**:返回客户端当前时区信息。
@ -571,9 +569,7 @@ SELECT TIMEZONE() FROM { tb_name | stb_name } [WHERE clause];
#### TODAY
```sql
SELECT TODAY() FROM { tb_name | stb_name } [WHERE clause];
SELECT select_expr FROM { tb_name | stb_name } WHERE ts_col cond_operatior TODAY()];
INSERT INTO tb_name VALUES (TODAY(), ...);
TODAY()
```
**功能说明**:返回客户端当日零时的系统时间。
@ -600,7 +596,12 @@ TDengine 支持针对数据的聚合查询。提供如下聚合函数。
### APERCENTILE
```sql
SELECT APERCENTILE(field_name, P[, algo_type]) FROM { tb_name | stb_name } [WHERE clause]
APERCENTILE(expr, p [, algo_type])
algo_type: {
"default"
| "t-digest"
}
```
**功能说明**:统计表/超级表中指定列的值的近似百分比分位数,与 PERCENTILE 函数相似,但是返回近似结果。
@ -612,14 +613,14 @@ SELECT APERCENTILE(field_name, P[, algo_type]) FROM { tb_name | stb_name } [WHER
**适用于**:表和超级表。
**说明**
- P值范围是[0,100]当为0时等同于MIN为100时等同于MAX。
- p值范围是[0,100]当为0时等同于MIN为100时等同于MAX。
- algo_type 取值为 "default" 或 "t-digest"。 输入为 "default" 时函数使用基于直方图算法进行计算。输入为 "t-digest" 时使用t-digest算法计算分位数的近似结果。如果不指定 algo_type 则使用 "default" 算法。
- "t-digest"算法的近似结果对于输入数据顺序敏感,对超级表查询时不同的输入排序结果可能会有微小的误差。
### AVG
```sql
SELECT AVG(field_name) FROM tb_name [WHERE clause];
AVG(expr)
```
**功能说明**:统计指定字段的平均值。
@ -634,7 +635,7 @@ SELECT AVG(field_name) FROM tb_name [WHERE clause];
### COUNT
```sql
SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
COUNT({* | expr})
```
**功能说明**:统计指定字段的记录行数。
@ -654,7 +655,7 @@ SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause];
### ELAPSED
```sql
SELECT ELAPSED(ts_primary_key [, time_unit]) FROM { tb_name | stb_name } [WHERE clause] [INTERVAL(interval [, offset]) [SLIDING sliding]];
ELAPSED(ts_primary_key [, time_unit])
```
**功能说明**elapsed函数表达了统计周期内连续的时间长度和twa函数配合使用可以计算统计曲线下的面积。在通过INTERVAL子句指定窗口的情况下统计在给定时间范围内的每个窗口内有数据覆盖的时间范围如果没有INTERVAL子句则返回整个给定时间范围内的有数据覆盖的时间范围。注意ELAPSED返回的并不是时间范围的绝对值而是绝对值除以time_unit所得到的单位个数。
@ -666,7 +667,7 @@ SELECT ELAPSED(ts_primary_key [, time_unit]) FROM { tb_name | stb_name } [WHERE
**适用于**: 表,超级表,嵌套查询的外层查询
**说明**
- field_name参数只能是表的第一列,即 TIMESTAMP 类型的主键列。
- ts_primary_key参数只能是表的第一列,即 TIMESTAMP 类型的主键列。
- 按time_unit参数指定的时间单位返回最小是数据库的时间分辨率。time_unit 参数未指定时,以数据库的时间分辨率为时间单位。支持的时间单位 time_unit 如下:
1b(纳秒), 1u(微秒)1a(毫秒)1s(秒)1m(分)1h(小时)1d(天), 1w(周)。
- 可以和interval组合使用返回每个时间窗口的时间戳差值。需要特别注意的是除第一个时间窗口和最后一个时间窗口外中间窗口的时间戳差值均为窗口长度。
@ -680,14 +681,14 @@ SELECT ELAPSED(ts_primary_key [, time_unit]) FROM { tb_name | stb_name } [WHERE
### LEASTSQUARES
```sql
SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause];
LEASTSQUARES(expr, start_val, step_val)
```
**功能说明**统计表中某列的值是主键时间戳的拟合直线方程。start_val 是自变量初始值step_val 是自变量的步长值。
**返回数据类型**:字符串表达式(斜率, 截距)。
**适用数据类型**field_name 必须是数值类型。
**适用数据类型**expr 必须是数值类型。
**适用于**:表。
@ -695,7 +696,7 @@ SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause]
### SPREAD
```sql
SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
SPREAD(expr)
```
**功能说明**:统计表中某列的最大值和最小值之差。
@ -710,7 +711,7 @@ SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause];
### STDDEV
```sql
SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
STDDEV(expr)
```
**功能说明**:统计表中某列的均方差。
@ -725,7 +726,7 @@ SELECT STDDEV(field_name) FROM tb_name [WHERE clause];
### SUM
```sql
SELECT SUM(field_name) FROM tb_name [WHERE clause];
SUM(expr)
```
**功能说明**:统计表/超级表中某列的和。
@ -740,7 +741,7 @@ SELECT SUM(field_name) FROM tb_name [WHERE clause];
### HYPERLOGLOG
```sql
SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
HYPERLOGLOG(expr)
```
**功能说明**
@ -757,7 +758,7 @@ SELECT HYPERLOGLOG(field_name) FROM { tb_name | stb_name } [WHERE clause];
### HISTOGRAM
```sql
SELECT HISTOGRAM(field_namebin_type, bin_description, normalized) FROM tb_name [WHERE clause];
HISTOGRAM(exprbin_type, bin_description, normalized)
```
**功能说明**:统计数据按照用户指定区间的分布。
@ -787,7 +788,7 @@ SELECT HISTOGRAM(field_namebin_type, bin_description, normalized) FROM tb_nam
### PERCENTILE
```sql
SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
PERCENTILE(expr, p)
```
**功能说明**:统计表中某列的值百分比分位数。
@ -808,7 +809,7 @@ SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause];
### BOTTOM
```sql
SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
BOTTOM(expr, k)
```
**功能说明**:统计表/超级表中某列的值最小 _k_ 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。
@ -828,7 +829,7 @@ SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
### FIRST
```sql
SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
FIRST(expr)
```
**功能说明**:统计表/超级表中某列的值最先写入的非 NULL 值。
@ -848,7 +849,7 @@ SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause];
### INTERP
```sql
SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] RANGE(timestamp1,timestamp2) EVERY(interval) FILL({ VALUE | PREV | NULL | LINEAR | NEXT});
INTERP(expr)
```
**功能说明**:返回指定时间截面指定列的记录值或插值。
@ -871,7 +872,7 @@ SELECT INTERP(field_name) FROM { tb_name | stb_name } [WHERE where_condition] RA
### LAST
```sql
SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
LAST(expr)
```
**功能说明**:统计表/超级表中某列的值最后写入的非 NULL 值。
@ -892,7 +893,7 @@ SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause];
### LAST_ROW
```sql
SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
LAST_ROW(expr)
```
**功能说明**:返回表/超级表的最后一条记录。
@ -911,7 +912,7 @@ SELECT LAST_ROW(field_name) FROM { tb_name | stb_name };
### MAX
```sql
SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
MAX(expr)
```
**功能说明**:统计表/超级表中某列的值最大值。
@ -926,7 +927,7 @@ SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause];
### MIN
```sql
SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
MIN(expr)
```
**功能说明**:统计表/超级表中某列的值最小值。
@ -941,7 +942,7 @@ SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause];
### MODE
```sql
SELECT MODE(field_name) FROM tb_name [WHERE clause];
MODE(expr)
```
**功能说明**返回出现频率最高的值若存在多个频率相同的最高值输出NULL。
@ -956,7 +957,7 @@ SELECT MODE(field_name) FROM tb_name [WHERE clause];
### SAMPLE
```sql
SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
SAMPLE(expr, k)
```
**功能说明** 获取数据的 k 个采样值。参数 k 的合法输入范围是 1≤ k ≤ 1000。
@ -978,7 +979,7 @@ SELECT SAMPLE(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
### TAIL
```sql
SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
TAIL(expr, k [, offset_rows])
```
**功能说明**:返回跳过最后 offset_val 个,然后取连续 k 个记录,不忽略 NULL 值。offset_val 可以不输入。此时返回最后的 k 个记录。当有 offset_val 输入的情况下,该函数功能等效于 `order by ts desc LIMIT k OFFSET offset_val`
@ -995,7 +996,7 @@ SELECT TAIL(field_name, k, offset_val) FROM {tb_name | stb_name} [WHERE clause];
### TOP
```sql
SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
TOP(expr, k)
```
**功能说明** 统计表/超级表中某列的值最大 _k_ 个非 NULL 值。如果多条数据取值一样,全部取用又会超出 k 条限制时,系统会从相同值中随机选取符合要求的数量返回。
@ -1015,7 +1016,7 @@ SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause];
### UNIQUE
```sql
SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
UNIQUE(expr)
```
**功能说明**:返回该列的数值首次出现的值。该函数功能与 distinct 相似,但是可以匹配标签和时间戳信息。可以针对除时间列以外的字段进行查询,可以匹配标签和时间戳,其中的标签和时间戳是第一次出现时刻的标签和时间戳。
@ -1034,7 +1035,7 @@ SELECT UNIQUE(field_name) FROM {tb_name | stb_name} [WHERE clause];
### CSUM
```sql
SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
CSUM(expr)
```
**功能说明**累加和Cumulative sum输出行与输入行数相同。
@ -1057,7 +1058,12 @@ SELECT CSUM(field_name) FROM { tb_name | stb_name } [WHERE clause]
### DERIVATIVE
```sql
SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHERE clause];
DERIVATIVE(expr, time_interval, ignore_negative)
ignore_negative: {
0
| 1
}
```
**功能说明**:统计表中某列数值的单位变化率。其中单位时间区间的长度可以通过 time_interval 参数指定,最小可以是 1 秒1signore_negative 参数的值可以是 0 或 1为 1 时表示忽略负值。
@ -1076,7 +1082,12 @@ SELECT DERIVATIVE(field_name, time_interval, ignore_negative) FROM tb_name [WHER
### DIFF
```sql
SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHERE clause];
DIFF(expr [, ignore_negative])
ignore_negative: {
0
| 1
}
```
**功能说明**:统计表中某列的值与前一行对应值的差。 ignore_negative 取值为 0|1 , 可以不填,默认值为 0. 不忽略负值。ignore_negative 为 1 时表示忽略负数。
@ -1096,7 +1107,7 @@ SELECT {DIFF(field_name, ignore_negative) | DIFF(field_name)} FROM tb_name [WHER
### IRATE
```sql
SELECT IRATE(field_name) FROM tb_name WHERE clause;
IRATE(expr)
```
**功能说明**:计算瞬时增长率。使用时间区间中最后两个样本数据来计算瞬时增长速率;如果这两个值呈递减关系,那么只取最后一个数用于计算,而不是使用二者差值。
@ -1111,7 +1122,7 @@ SELECT IRATE(field_name) FROM tb_name WHERE clause;
### MAVG
```sql
SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
MAVG(expr, k)
```
**功能说明** 计算连续 k 个值的移动平均数moving average。如果输入行数小于 k则无结果输出。参数 k 的合法输入范围是 1≤ k ≤ 1000。
@ -1134,7 +1145,7 @@ SELECT MAVG(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
### STATECOUNT
```sql
SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clause];
STATECOUNT(expr, oper, val)
```
**功能说明**:返回满足某个条件的连续记录的个数,结果作为新的一列追加在每行后面。条件根据参数计算,如果条件为 true 则加 1条件为 false 则重置为-1如果数据为 NULL跳过该条数据。
@ -1161,7 +1172,7 @@ SELECT STATECOUNT(field_name, oper, val) FROM { tb_name | stb_name } [WHERE clau
### STATEDURATION
```sql
SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [WHERE clause];
STATEDURATION(expr, oper, val, unit)
```
**功能说明**:返回满足某个条件的连续记录的时间长度,结果作为新的一列追加在每行后面。条件根据参数计算,如果条件为 true 则加上两个记录之间的时间长度(第一个满足条件的记录时间长度记为 0条件为 false 则重置为-1如果数据为 NULL跳过该条数据。
@ -1189,7 +1200,7 @@ SELECT stateDuration(field_name, oper, val, unit) FROM { tb_name | stb_name } [W
### TWA
```sql
SELECT TWA(field_name) FROM tb_name WHERE clause;
TWA(expr)
```
**功能说明**:时间加权平均函数。统计表中某列在一段时间内的时间加权平均。

View File

@ -98,6 +98,7 @@ extern int32_t tsQueryRsmaTolerance;
extern bool tsQueryPlannerTrace;
extern int32_t tsQueryNodeChunkSize;
extern bool tsQueryUseNodeAllocator;
extern bool tsKeepColumnName;
// client
extern int32_t tsMinSlidingTime;

View File

@ -866,7 +866,8 @@ int32_t tSerializeSDbCfgReq(void* buf, int32_t bufLen, SDbCfgReq* pReq);
int32_t tDeserializeSDbCfgReq(void* buf, int32_t bufLen, SDbCfgReq* pReq);
typedef struct {
char db[TSDB_DB_FNAME_LEN];
char db[TSDB_DB_FNAME_LEN];
int32_t maxSpeed;
} STrimDbReq;
int32_t tSerializeSTrimDbReq(void* buf, int32_t bufLen, STrimDbReq* pReq);
@ -1426,10 +1427,10 @@ typedef struct {
typedef struct {
SExplainRsp rsp;
uint64_t qId;
uint64_t tId;
int64_t rId;
int32_t eId;
uint64_t qId;
uint64_t tId;
int64_t rId;
int32_t eId;
} SExplainLocalRsp;
typedef struct STableScanAnalyzeInfo {
@ -1446,7 +1447,7 @@ typedef struct STableScanAnalyzeInfo {
int32_t tSerializeSExplainRsp(void* buf, int32_t bufLen, SExplainRsp* pRsp);
int32_t tDeserializeSExplainRsp(void* buf, int32_t bufLen, SExplainRsp* pRsp);
void tFreeSExplainRsp(SExplainRsp *pRsp);
void tFreeSExplainRsp(SExplainRsp* pRsp);
typedef struct {
char fqdn[TSDB_FQDN_LEN]; // end point, hostname:port
@ -1729,6 +1730,8 @@ typedef struct {
int64_t maxDelay;
int64_t watermark;
int8_t igExpired;
int32_t numOfTags;
SArray* pTags; // array of SField
} SCMCreateStreamReq;
typedef struct {

View File

@ -107,227 +107,230 @@
#define TK_TABLE_PREFIX 89
#define TK_TABLE_SUFFIX 90
#define TK_NK_COLON 91
#define TK_TABLE 92
#define TK_NK_LP 93
#define TK_NK_RP 94
#define TK_STABLE 95
#define TK_ADD 96
#define TK_COLUMN 97
#define TK_MODIFY 98
#define TK_RENAME 99
#define TK_TAG 100
#define TK_SET 101
#define TK_NK_EQ 102
#define TK_USING 103
#define TK_TAGS 104
#define TK_COMMENT 105
#define TK_BOOL 106
#define TK_TINYINT 107
#define TK_SMALLINT 108
#define TK_INT 109
#define TK_INTEGER 110
#define TK_BIGINT 111
#define TK_FLOAT 112
#define TK_DOUBLE 113
#define TK_BINARY 114
#define TK_TIMESTAMP 115
#define TK_NCHAR 116
#define TK_UNSIGNED 117
#define TK_JSON 118
#define TK_VARCHAR 119
#define TK_MEDIUMBLOB 120
#define TK_BLOB 121
#define TK_VARBINARY 122
#define TK_DECIMAL 123
#define TK_MAX_DELAY 124
#define TK_WATERMARK 125
#define TK_ROLLUP 126
#define TK_TTL 127
#define TK_SMA 128
#define TK_FIRST 129
#define TK_LAST 130
#define TK_SHOW 131
#define TK_DATABASES 132
#define TK_TABLES 133
#define TK_STABLES 134
#define TK_MNODES 135
#define TK_MODULES 136
#define TK_QNODES 137
#define TK_FUNCTIONS 138
#define TK_INDEXES 139
#define TK_ACCOUNTS 140
#define TK_APPS 141
#define TK_CONNECTIONS 142
#define TK_LICENCES 143
#define TK_GRANTS 144
#define TK_QUERIES 145
#define TK_SCORES 146
#define TK_TOPICS 147
#define TK_VARIABLES 148
#define TK_BNODES 149
#define TK_SNODES 150
#define TK_CLUSTER 151
#define TK_TRANSACTIONS 152
#define TK_DISTRIBUTED 153
#define TK_CONSUMERS 154
#define TK_SUBSCRIPTIONS 155
#define TK_VNODES 156
#define TK_LIKE 157
#define TK_INDEX 158
#define TK_FUNCTION 159
#define TK_INTERVAL 160
#define TK_TOPIC 161
#define TK_AS 162
#define TK_WITH 163
#define TK_META 164
#define TK_CONSUMER 165
#define TK_GROUP 166
#define TK_DESC 167
#define TK_DESCRIBE 168
#define TK_RESET 169
#define TK_QUERY 170
#define TK_CACHE 171
#define TK_EXPLAIN 172
#define TK_ANALYZE 173
#define TK_VERBOSE 174
#define TK_NK_BOOL 175
#define TK_RATIO 176
#define TK_NK_FLOAT 177
#define TK_OUTPUTTYPE 178
#define TK_AGGREGATE 179
#define TK_BUFSIZE 180
#define TK_STREAM 181
#define TK_INTO 182
#define TK_TRIGGER 183
#define TK_AT_ONCE 184
#define TK_WINDOW_CLOSE 185
#define TK_IGNORE 186
#define TK_EXPIRED 187
#define TK_KILL 188
#define TK_CONNECTION 189
#define TK_TRANSACTION 190
#define TK_BALANCE 191
#define TK_VGROUP 192
#define TK_MERGE 193
#define TK_REDISTRIBUTE 194
#define TK_SPLIT 195
#define TK_DELETE 196
#define TK_INSERT 197
#define TK_NULL 198
#define TK_NK_QUESTION 199
#define TK_NK_ARROW 200
#define TK_ROWTS 201
#define TK_TBNAME 202
#define TK_QSTART 203
#define TK_QEND 204
#define TK_QDURATION 205
#define TK_WSTART 206
#define TK_WEND 207
#define TK_WDURATION 208
#define TK_CAST 209
#define TK_NOW 210
#define TK_TODAY 211
#define TK_TIMEZONE 212
#define TK_CLIENT_VERSION 213
#define TK_SERVER_VERSION 214
#define TK_SERVER_STATUS 215
#define TK_CURRENT_USER 216
#define TK_COUNT 217
#define TK_LAST_ROW 218
#define TK_CASE 219
#define TK_END 220
#define TK_WHEN 221
#define TK_THEN 222
#define TK_ELSE 223
#define TK_BETWEEN 224
#define TK_IS 225
#define TK_NK_LT 226
#define TK_NK_GT 227
#define TK_NK_LE 228
#define TK_NK_GE 229
#define TK_NK_NE 230
#define TK_MATCH 231
#define TK_NMATCH 232
#define TK_CONTAINS 233
#define TK_IN 234
#define TK_JOIN 235
#define TK_INNER 236
#define TK_SELECT 237
#define TK_DISTINCT 238
#define TK_WHERE 239
#define TK_PARTITION 240
#define TK_BY 241
#define TK_SESSION 242
#define TK_STATE_WINDOW 243
#define TK_SLIDING 244
#define TK_FILL 245
#define TK_VALUE 246
#define TK_NONE 247
#define TK_PREV 248
#define TK_LINEAR 249
#define TK_NEXT 250
#define TK_HAVING 251
#define TK_RANGE 252
#define TK_EVERY 253
#define TK_ORDER 254
#define TK_SLIMIT 255
#define TK_SOFFSET 256
#define TK_LIMIT 257
#define TK_OFFSET 258
#define TK_ASC 259
#define TK_NULLS 260
#define TK_ABORT 261
#define TK_AFTER 262
#define TK_ATTACH 263
#define TK_BEFORE 264
#define TK_BEGIN 265
#define TK_BITAND 266
#define TK_BITNOT 267
#define TK_BITOR 268
#define TK_BLOCKS 269
#define TK_CHANGE 270
#define TK_COMMA 271
#define TK_COMPACT 272
#define TK_CONCAT 273
#define TK_CONFLICT 274
#define TK_COPY 275
#define TK_DEFERRED 276
#define TK_DELIMITERS 277
#define TK_DETACH 278
#define TK_DIVIDE 279
#define TK_DOT 280
#define TK_EACH 281
#define TK_FAIL 282
#define TK_FILE 283
#define TK_FOR 284
#define TK_GLOB 285
#define TK_ID 286
#define TK_IMMEDIATE 287
#define TK_IMPORT 288
#define TK_INITIALLY 289
#define TK_INSTEAD 290
#define TK_ISNULL 291
#define TK_KEY 292
#define TK_NK_BITNOT 293
#define TK_NK_SEMI 294
#define TK_NOTNULL 295
#define TK_OF 296
#define TK_PLUS 297
#define TK_PRIVILEGE 298
#define TK_RAISE 299
#define TK_REPLACE 300
#define TK_RESTRICT 301
#define TK_ROW 302
#define TK_SEMI 303
#define TK_STAR 304
#define TK_STATEMENT 305
#define TK_STRING 306
#define TK_TIMES 307
#define TK_UPDATE 308
#define TK_VALUES 309
#define TK_VARIABLE 310
#define TK_VIEW 311
#define TK_WAL 312
#define TK_MAX_SPEED 92
#define TK_TABLE 93
#define TK_NK_LP 94
#define TK_NK_RP 95
#define TK_STABLE 96
#define TK_ADD 97
#define TK_COLUMN 98
#define TK_MODIFY 99
#define TK_RENAME 100
#define TK_TAG 101
#define TK_SET 102
#define TK_NK_EQ 103
#define TK_USING 104
#define TK_TAGS 105
#define TK_COMMENT 106
#define TK_BOOL 107
#define TK_TINYINT 108
#define TK_SMALLINT 109
#define TK_INT 110
#define TK_INTEGER 111
#define TK_BIGINT 112
#define TK_FLOAT 113
#define TK_DOUBLE 114
#define TK_BINARY 115
#define TK_TIMESTAMP 116
#define TK_NCHAR 117
#define TK_UNSIGNED 118
#define TK_JSON 119
#define TK_VARCHAR 120
#define TK_MEDIUMBLOB 121
#define TK_BLOB 122
#define TK_VARBINARY 123
#define TK_DECIMAL 124
#define TK_MAX_DELAY 125
#define TK_WATERMARK 126
#define TK_ROLLUP 127
#define TK_TTL 128
#define TK_SMA 129
#define TK_FIRST 130
#define TK_LAST 131
#define TK_SHOW 132
#define TK_DATABASES 133
#define TK_TABLES 134
#define TK_STABLES 135
#define TK_MNODES 136
#define TK_MODULES 137
#define TK_QNODES 138
#define TK_FUNCTIONS 139
#define TK_INDEXES 140
#define TK_ACCOUNTS 141
#define TK_APPS 142
#define TK_CONNECTIONS 143
#define TK_LICENCES 144
#define TK_GRANTS 145
#define TK_QUERIES 146
#define TK_SCORES 147
#define TK_TOPICS 148
#define TK_VARIABLES 149
#define TK_BNODES 150
#define TK_SNODES 151
#define TK_CLUSTER 152
#define TK_TRANSACTIONS 153
#define TK_DISTRIBUTED 154
#define TK_CONSUMERS 155
#define TK_SUBSCRIPTIONS 156
#define TK_VNODES 157
#define TK_LIKE 158
#define TK_INDEX 159
#define TK_FUNCTION 160
#define TK_INTERVAL 161
#define TK_TOPIC 162
#define TK_AS 163
#define TK_WITH 164
#define TK_META 165
#define TK_CONSUMER 166
#define TK_GROUP 167
#define TK_DESC 168
#define TK_DESCRIBE 169
#define TK_RESET 170
#define TK_QUERY 171
#define TK_CACHE 172
#define TK_EXPLAIN 173
#define TK_ANALYZE 174
#define TK_VERBOSE 175
#define TK_NK_BOOL 176
#define TK_RATIO 177
#define TK_NK_FLOAT 178
#define TK_OUTPUTTYPE 179
#define TK_AGGREGATE 180
#define TK_BUFSIZE 181
#define TK_STREAM 182
#define TK_INTO 183
#define TK_TRIGGER 184
#define TK_AT_ONCE 185
#define TK_WINDOW_CLOSE 186
#define TK_IGNORE 187
#define TK_EXPIRED 188
#define TK_SUBTABLE 189
#define TK_KILL 190
#define TK_CONNECTION 191
#define TK_TRANSACTION 192
#define TK_BALANCE 193
#define TK_VGROUP 194
#define TK_MERGE 195
#define TK_REDISTRIBUTE 196
#define TK_SPLIT 197
#define TK_DELETE 198
#define TK_INSERT 199
#define TK_NULL 200
#define TK_NK_QUESTION 201
#define TK_NK_ARROW 202
#define TK_ROWTS 203
#define TK_TBNAME 204
#define TK_QSTART 205
#define TK_QEND 206
#define TK_QDURATION 207
#define TK_WSTART 208
#define TK_WEND 209
#define TK_WDURATION 210
#define TK_IROWTS 211
#define TK_CAST 212
#define TK_NOW 213
#define TK_TODAY 214
#define TK_TIMEZONE 215
#define TK_CLIENT_VERSION 216
#define TK_SERVER_VERSION 217
#define TK_SERVER_STATUS 218
#define TK_CURRENT_USER 219
#define TK_COUNT 220
#define TK_LAST_ROW 221
#define TK_CASE 222
#define TK_END 223
#define TK_WHEN 224
#define TK_THEN 225
#define TK_ELSE 226
#define TK_BETWEEN 227
#define TK_IS 228
#define TK_NK_LT 229
#define TK_NK_GT 230
#define TK_NK_LE 231
#define TK_NK_GE 232
#define TK_NK_NE 233
#define TK_MATCH 234
#define TK_NMATCH 235
#define TK_CONTAINS 236
#define TK_IN 237
#define TK_JOIN 238
#define TK_INNER 239
#define TK_SELECT 240
#define TK_DISTINCT 241
#define TK_WHERE 242
#define TK_PARTITION 243
#define TK_BY 244
#define TK_SESSION 245
#define TK_STATE_WINDOW 246
#define TK_SLIDING 247
#define TK_FILL 248
#define TK_VALUE 249
#define TK_NONE 250
#define TK_PREV 251
#define TK_LINEAR 252
#define TK_NEXT 253
#define TK_HAVING 254
#define TK_RANGE 255
#define TK_EVERY 256
#define TK_ORDER 257
#define TK_SLIMIT 258
#define TK_SOFFSET 259
#define TK_LIMIT 260
#define TK_OFFSET 261
#define TK_ASC 262
#define TK_NULLS 263
#define TK_ABORT 264
#define TK_AFTER 265
#define TK_ATTACH 266
#define TK_BEFORE 267
#define TK_BEGIN 268
#define TK_BITAND 269
#define TK_BITNOT 270
#define TK_BITOR 271
#define TK_BLOCKS 272
#define TK_CHANGE 273
#define TK_COMMA 274
#define TK_COMPACT 275
#define TK_CONCAT 276
#define TK_CONFLICT 277
#define TK_COPY 278
#define TK_DEFERRED 279
#define TK_DELIMITERS 280
#define TK_DETACH 281
#define TK_DIVIDE 282
#define TK_DOT 283
#define TK_EACH 284
#define TK_FAIL 285
#define TK_FILE 286
#define TK_FOR 287
#define TK_GLOB 288
#define TK_ID 289
#define TK_IMMEDIATE 290
#define TK_IMPORT 291
#define TK_INITIALLY 292
#define TK_INSTEAD 293
#define TK_ISNULL 294
#define TK_KEY 295
#define TK_NK_BITNOT 296
#define TK_NK_SEMI 297
#define TK_NOTNULL 298
#define TK_OF 299
#define TK_PLUS 300
#define TK_PRIVILEGE 301
#define TK_RAISE 302
#define TK_REPLACE 303
#define TK_RESTRICT 304
#define TK_ROW 305
#define TK_SEMI 306
#define TK_STAR 307
#define TK_STATEMENT 308
#define TK_STRING 309
#define TK_TIMES 310
#define TK_UPDATE 311
#define TK_VALUES 312
#define TK_VARIABLE 313
#define TK_VIEW 314
#define TK_WAL 315
#define TK_NK_SPACE 300
#define TK_NK_COMMENT 301

View File

@ -106,6 +106,8 @@ void mndPostProcessQueryMsg(SRpcMsg *pMsg);
*/
void mndGenerateMachineCode();
void mndDumpSdb();
#ifdef __cplusplus
}
#endif

View File

@ -119,9 +119,10 @@ typedef enum EFunctionType {
FUNCTION_TYPE_WSTART,
FUNCTION_TYPE_WEND,
FUNCTION_TYPE_WDURATION,
FUNCTION_TYPE_IROWTS,
// internal function
FUNCTION_TYPE_SELECT_VALUE,
FUNCTION_TYPE_SELECT_VALUE = 3750,
FUNCTION_TYPE_BLOCK_DIST, // block distribution aggregate function
FUNCTION_TYPE_BLOCK_DIST_INFO, // block distribution pseudo column function
FUNCTION_TYPE_TO_COLUMN,
@ -212,6 +213,7 @@ bool fmIsClientPseudoColumnFunc(int32_t funcId);
bool fmIsMultiRowsFunc(int32_t funcId);
bool fmIsKeepOrderFunc(int32_t funcId);
bool fmIsCumulativeFunc(int32_t funcId);
bool fmIsInterpPseudoColumnFunc(int32_t funcId);
int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc);

View File

@ -119,6 +119,7 @@ typedef struct SFlushDatabaseStmt {
typedef struct STrimDatabaseStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
int32_t maxSpeed;
} STrimDatabaseStmt;
typedef struct STableOptions {
@ -383,6 +384,8 @@ typedef struct SCreateStreamStmt {
bool ignoreExists;
SStreamOptions* pOptions;
SNode* pQuery;
SNodeList* pTags;
SNode* pSubtable;
} SCreateStreamStmt;
typedef struct SDropStreamStmt {

View File

@ -27,9 +27,9 @@ extern "C" {
#define LIST_LENGTH(l) (NULL != (l) ? (l)->length : 0)
#define FOREACH(node, list) \
for (SListCell* cell = (NULL != (list) ? (list)->pHead : NULL); \
(NULL != cell ? (node = cell->pNode, true) : (node = NULL, false)); cell = cell->pNext)
#define FOREACH(node, list) \
for (SListCell *cell = (NULL != (list) ? (list)->pHead : NULL), *pNext; \
(NULL != cell ? (node = cell->pNode, pNext = cell->pNext, true) : (node = NULL, pNext = NULL, false)); cell = pNext)
#define REPLACE_NODE(newNode) cell->pNode = (SNode*)(newNode)

View File

@ -94,6 +94,8 @@ typedef struct SScanLogicNode {
SArray* pSmaIndexes;
SNodeList* pGroupTags;
bool groupSort;
SNodeList* pTags; // for create stream
SNode* pSubtable; // for create stream
int8_t cacheLastMode;
bool hasNormalCols; // neither tag column nor primary key tag column
bool sortPrimaryKey;
@ -233,6 +235,8 @@ typedef struct SSortLogicNode {
typedef struct SPartitionLogicNode {
SLogicNode node;
SNodeList* pPartitionKeys;
SNodeList* pTags;
SNode* pSubtable;
} SPartitionLogicNode;
typedef enum ESubplanType {
@ -332,6 +336,8 @@ typedef struct STableScanPhysiNode {
SNodeList* pDynamicScanFuncs;
SNodeList* pGroupTags;
bool groupSort;
SNodeList* pTags;
SNode* pSubtable;
int64_t interval;
int64_t offset;
int64_t sliding;
@ -495,7 +501,11 @@ typedef struct SPartitionPhysiNode {
SNodeList* pTargets;
} SPartitionPhysiNode;
typedef SPartitionPhysiNode SStreamPartitionPhysiNode;
typedef struct SStreamPartitionPhysiNode {
SPartitionPhysiNode part;
SNodeList* pTags;
SNode* pSubtable;
} SStreamPartitionPhysiNode;
typedef struct SDataSinkNode {
ENodeType type;

View File

@ -261,6 +261,8 @@ typedef struct SSelectStmt {
SNode* pFromTable;
SNode* pWhere;
SNodeList* pPartitionByList;
SNodeList* pTags; // for create stream
SNode* pSubtable; // for create stream
SNode* pWindow;
SNodeList* pGroupByList; // SGroupingSetNode
SNode* pHaving;

View File

@ -167,7 +167,7 @@ uint32_t ip2uint(const char *const ip_addr);
void taosIgnSIGPIPE();
void taosSetMaskSIGPIPE();
uint32_t taosInetAddr(const char *ipAddr);
const char *taosInetNtoa(struct in_addr ipInt);
const char *taosInetNtoa(struct in_addr ipInt, char *dstStr, int32_t len);
#ifdef __cplusplus
}

View File

@ -77,7 +77,6 @@ int32_t taosWcharsWidth(TdWchar *pWchar, int32_t size);
int32_t taosMbToWchar(TdWchar *pWchar, const char *pStr, int32_t size);
int32_t taosMbsToWchars(TdWchar *pWchars, const char *pStrs, int32_t size);
int32_t taosWcharToMb(char *pStr, TdWchar wchar);
int32_t taosWcharsToMbs(char *pStrs, TdWchar *pWchars, int32_t size);
char *taosStrCaseStr(const char *str, const char *pattern);

View File

@ -79,7 +79,7 @@
#define NCHAR_ADD_LEN 3 // L"nchar" 3 means L" "
#define MAX_RETRY_TIMES 5
#define LINE_BATCH 20000
#define LINE_BATCH 2000
//=================================================================================================
typedef TSDB_SML_PROTOCOL_TYPE SMLProtocolType;
@ -151,13 +151,14 @@ typedef struct {
typedef struct {
SRequestObj *request;
tsem_t sem;
int32_t cnt;
int32_t total;
TdThreadSpinlock lock;
} Params;
typedef struct {
int64_t id;
Params *params;
bool isLast;
SMLProtocolType protocol;
int8_t precision;
@ -1531,6 +1532,7 @@ static SSmlHandle* smlBuildSmlInfo(STscObj* pTscObj, SRequestObj* request, SMLPr
info->pRequest = request;
info->msgBuf.buf = info->pRequest->msgBuf;
info->msgBuf.len = ERROR_MSG_BUF_DEFAULT_SIZE;
info->pRequest->stmtType = info->pQuery->pRoot->type;
}
info->exec = smlInitHandle(info->pQuery);
@ -2331,6 +2333,9 @@ static int32_t smlInsertData(SSmlHandle *info) {
// info->affectedRows = taos_affected_rows(info->pRequest);
// return info->pRequest->code;
SAppClusterSummary *pActivity = &info->taos->pAppInfo->summary;
atomic_add_fetch_64((int64_t *)&pActivity->numOfInsertsReq, 1);
launchAsyncQuery(info->pRequest, info->pQuery, NULL);
return TSDB_CODE_SUCCESS;
}
@ -2449,28 +2454,26 @@ static void smlInsertCallback(void *param, void *res, int32_t code) {
int32_t rows = taos_affected_rows(pRequest);
uDebug("SML:0x%" PRIx64 " result. code:%d, msg:%s", info->id, pRequest->code, pRequest->msgBuf);
// lock
taosThreadSpinLock(&info->params->lock);
if (code != TSDB_CODE_SUCCESS) {
info->params->request->code = code;
info->params->request->body.resInfo.numOfRows += rows;
}else{
info->params->request->body.resInfo.numOfRows += info->affectedRows;
}
taosThreadSpinUnlock(&info->params->lock);
// unlock
uDebug("SML:0x%" PRIx64 " insert finished, code: %d, rows: %d, total: %d", info->id, code, rows, info->affectedRows);
Params *pParam = info->params;
bool isLast = info->isLast;
// lock
taosThreadSpinLock(&pParam->lock);
pParam->cnt++;
if (code != TSDB_CODE_SUCCESS) {
pParam->request->code = code;
pParam->request->body.resInfo.numOfRows += rows;
}else{
pParam->request->body.resInfo.numOfRows += info->affectedRows;
}
if (pParam->cnt == pParam->total) {
tsem_post(&pParam->sem);
}
taosThreadSpinUnlock(&pParam->lock);
// unlock
uDebug("SML:0x%" PRIx64 " insert finished, code: %d, rows: %d, total: %d", info->id, code, rows, info->affectedRows);
info->cost.endTime = taosGetTimestampUs();
info->cost.code = code;
smlPrintStatisticInfo(info);
smlDestroyInfo(info);
if (isLast) {
tsem_post(&pParam->sem);
}
}
/**
@ -2512,7 +2515,7 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr
pTscObj->schemalessType = 1;
SSmlMsgBuf msg = {ERROR_MSG_BUF_DEFAULT_SIZE, request->msgBuf};
Params params;
Params params = {0};
params.request = request;
tsem_init(&params.sem, 0, 0);
taosThreadSpinInit(&(params.lock), 0);
@ -2557,6 +2560,7 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr
}
batchs = ceil(((double)numLines) / LINE_BATCH);
params.total = batchs;
for (int i = 0; i < batchs; ++i) {
SRequestObj* req = (SRequestObj*)createRequest(pTscObj->id, TSDB_SQL_INSERT);
if(!req){
@ -2575,11 +2579,9 @@ TAOS_RES* taos_schemaless_insert(TAOS* taos, char* lines[], int numLines, int pr
if (numLines > perBatch) {
numLines -= perBatch;
info->isLast = false;
} else {
perBatch = numLines;
numLines = 0;
info->isLast = true;
}
info->params = &params;

View File

@ -95,6 +95,7 @@ int32_t tsQueryRsmaTolerance = 1000; // the tolerance time (ms) to judge from w
bool tsQueryPlannerTrace = false;
int32_t tsQueryNodeChunkSize = 32 * 1024;
bool tsQueryUseNodeAllocator = true;
bool tsKeepColumnName = false;
/*
* denote if the server needs to compress response message at the application layer to client, including query rsp,
@ -290,6 +291,7 @@ static int32_t taosAddClientCfg(SConfig *pCfg) {
if (cfgAddBool(pCfg, "queryPlannerTrace", tsQueryPlannerTrace, true) != 0) return -1;
if (cfgAddInt32(pCfg, "queryNodeChunkSize", tsQueryNodeChunkSize, 1024, 128 * 1024, true) != 0) return -1;
if (cfgAddBool(pCfg, "queryUseNodeAllocator", tsQueryUseNodeAllocator, true) != 0) return -1;
if (cfgAddBool(pCfg, "keepColumnName", tsKeepColumnName, true) != 0) return -1;
if (cfgAddString(pCfg, "smlChildTableName", "", 1) != 0) return -1;
if (cfgAddString(pCfg, "smlTagName", tsSmlTagName, 1) != 0) return -1;
if (cfgAddBool(pCfg, "smlDataFormat", tsSmlDataFormat, 1) != 0) return -1;
@ -652,6 +654,7 @@ static int32_t taosSetClientCfg(SConfig *pCfg) {
tsQueryPlannerTrace = cfgGetItem(pCfg, "queryPlannerTrace")->bval;
tsQueryNodeChunkSize = cfgGetItem(pCfg, "queryNodeChunkSize")->i32;
tsQueryUseNodeAllocator = cfgGetItem(pCfg, "queryUseNodeAllocator")->bval;
tsKeepColumnName = cfgGetItem(pCfg, "keepColumnName")->bval;
return 0;
}
@ -685,7 +688,9 @@ static int32_t taosSetServerCfg(SConfig *pCfg) {
tsQueryBufferSize = cfgGetItem(pCfg, "queryBufferSize")->i32;
tsPrintAuth = cfgGetItem(pCfg, "printAuth")->bval;
#if !defined(WINDOWS) && !defined(DARWIN)
tsMultiProcess = cfgGetItem(pCfg, "multiProcess")->bval;
#endif
tsMnodeShmSize = cfgGetItem(pCfg, "mnodeShmSize")->i32;
tsVnodeShmSize = cfgGetItem(pCfg, "vnodeShmSize")->i32;
tsQnodeShmSize = cfgGetItem(pCfg, "qnodeShmSize")->i32;
@ -843,6 +848,9 @@ int32_t taosSetCfg(SConfig *pCfg, char *name) {
break;
}
case 'k': {
if (strcasecmp("keepColumnName", name) == 0) {
tsKeepColumnName = cfgGetItem(pCfg, "keepColumnName")->bval;
}
break;
}
case 'l': {
@ -919,7 +927,9 @@ int32_t taosSetCfg(SConfig *pCfg, char *name) {
}
case 'u': {
if (strcasecmp("multiProcess", name) == 0) {
#if !defined(WINDOWS) && !defined(DARWIN)
tsMultiProcess = cfgGetItem(pCfg, "multiProcess")->bval;
#endif
} else if (strcasecmp("udfDebugFlag", name) == 0) {
udfDebugFlag = cfgGetItem(pCfg, "udfDebugFlag")->i32;
}

View File

@ -2682,6 +2682,7 @@ int32_t tSerializeSTrimDbReq(void *buf, int32_t bufLen, STrimDbReq *pReq) {
if (tStartEncode(&encoder) < 0) return -1;
if (tEncodeCStr(&encoder, pReq->db) < 0) return -1;
if (tEncodeI32(&encoder, pReq->maxSpeed) < 0) return -1;
tEndEncode(&encoder);
int32_t tlen = encoder.pos;
@ -2695,6 +2696,7 @@ int32_t tDeserializeSTrimDbReq(void *buf, int32_t bufLen, STrimDbReq *pReq) {
if (tStartDecode(&decoder) < 0) return -1;
if (tDecodeCStrTo(&decoder, pReq->db) < 0) return -1;
if (tDecodeI32(&decoder, &pReq->maxSpeed) < 0) return -1;
tEndDecode(&decoder);
tDecoderClear(&decoder);
@ -3347,12 +3349,12 @@ int32_t tDeserializeSSTbHbRsp(void *buf, int32_t bufLen, SSTbHbRsp *pRsp) {
return 0;
}
void tFreeSTableMetaRsp(void *pRsp) {
void tFreeSTableMetaRsp(void *pRsp) {
if (NULL == pRsp) {
return;
}
taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pSchemas);
taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pSchemas);
}
void tFreeSTableIndexRsp(void *info) {
@ -4373,8 +4375,7 @@ int32_t tDeserializeSExplainRsp(void *buf, int32_t bufLen, SExplainRsp *pRsp) {
if (tDecodeDouble(&decoder, &pRsp->subplanInfo[i].totalCost) < 0) return -1;
if (tDecodeU64(&decoder, &pRsp->subplanInfo[i].numOfRows) < 0) return -1;
if (tDecodeU32(&decoder, &pRsp->subplanInfo[i].verboseLen) < 0) return -1;
if (tDecodeBinaryAlloc(&decoder, &pRsp->subplanInfo[i].verboseInfo, NULL) < 0)
return -1;
if (tDecodeBinaryAlloc(&decoder, &pRsp->subplanInfo[i].verboseInfo, NULL) < 0) return -1;
}
tEndDecode(&decoder);
@ -4826,6 +4827,14 @@ int32_t tSerializeSCMCreateStreamReq(void *buf, int32_t bufLen, const SCMCreateS
if (tEncodeI8(&encoder, pReq->igExpired) < 0) return -1;
if (sqlLen > 0 && tEncodeCStr(&encoder, pReq->sql) < 0) return -1;
if (astLen > 0 && tEncodeCStr(&encoder, pReq->ast) < 0) return -1;
if (tEncodeI32(&encoder, pReq->numOfTags) < 0) return -1;
for (int32_t i = 0; i < pReq->numOfTags; ++i) {
SField *pField = taosArrayGet(pReq->pTags, i);
if (tEncodeI8(&encoder, pField->type) < 0) return -1;
if (tEncodeI8(&encoder, pField->flags) < 0) return -1;
if (tEncodeI32(&encoder, pField->bytes) < 0) return -1;
if (tEncodeCStr(&encoder, pField->name) < 0) return -1;
}
tEndEncode(&encoder);
@ -4864,6 +4873,28 @@ int32_t tDeserializeSCMCreateStreamReq(void *buf, int32_t bufLen, SCMCreateStrea
if (pReq->ast == NULL) return -1;
if (tDecodeCStrTo(&decoder, pReq->ast) < 0) return -1;
}
if (tDecodeI32(&decoder, &pReq->numOfTags) < 0) return -1;
if (pReq->numOfTags > 0) {
pReq->pTags = taosArrayInit(pReq->numOfTags, sizeof(SField));
if (pReq->pTags == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1;
}
for (int32_t i = 0; i < pReq->numOfTags; ++i) {
SField field = {0};
if (tDecodeI8(&decoder, &field.type) < 0) return -1;
if (tDecodeI8(&decoder, &field.flags) < 0) return -1;
if (tDecodeI32(&decoder, &field.bytes) < 0) return -1;
if (tDecodeCStrTo(&decoder, field.name) < 0) return -1;
if (taosArrayPush(pReq->pTags, &field) == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
return -1;
}
}
}
tEndDecode(&decoder);
tDecoderClear(&decoder);

View File

@ -16,10 +16,12 @@
#define _DEFAULT_SOURCE
#include "dmMgmt.h"
#include "tconfig.h"
#include "mnode.h"
#define DM_APOLLO_URL "The apollo string to use when configuring the server, such as: -a 'jsonFile:./tests/cfg.json', cfg.json text can be '{\"fqdn\":\"td1\"}'."
#define DM_CFG_DIR "Configuration directory."
#define DM_DMP_CFG "Dump configuration."
#define DM_SDB_INFO "Dump sdb info."
#define DM_ENV_CMD "The env cmd variable string to use when configuring the server, such as: -e 'TAOS_FQDN=td1'."
#define DM_ENV_FILE "The env variable file path to use when configuring the server, default is './.env', .env text can be 'TAOS_FQDN=td1'."
#define DM_NODE_TYPE "Startup type of the node, default is 0."
@ -31,6 +33,7 @@ static struct {
bool winServiceMode;
#endif
bool dumpConfig;
bool dumpSdb;
bool generateGrant;
bool printAuth;
bool printVersion;
@ -82,6 +85,8 @@ static int32_t dmParseArgs(int32_t argc, char const *argv[]) {
}
} else if (strcmp(argv[i], "-a") == 0) {
tstrncpy(global.apolloUrl, argv[++i], PATH_MAX);
} else if (strcmp(argv[i], "-s") == 0) {
global.dumpSdb = true;
} else if (strcmp(argv[i], "-E") == 0) {
tstrncpy(global.envFile, argv[++i], PATH_MAX);
} else if (strcmp(argv[i], "-n") == 0) {
@ -131,6 +136,7 @@ static void dmPrintHelp() {
printf("Usage: taosd [OPTION...] \n\n");
printf("%s%s%s%s\n", indent, "-a,", indent, DM_APOLLO_URL);
printf("%s%s%s%s\n", indent, "-c,", indent, DM_CFG_DIR);
printf("%s%s%s%s\n", indent, "-s,", indent, DM_SDB_INFO);
printf("%s%s%s%s\n", indent, "-C,", indent, DM_DMP_CFG);
printf("%s%s%s%s\n", indent, "-e,", indent, DM_ENV_CMD);
printf("%s%s%s%s\n", indent, "-E,", indent, DM_ENV_FILE);
@ -229,6 +235,14 @@ int mainWindows(int argc,char** argv) {
return 0;
}
if (global.dumpSdb) {
mndDumpSdb();
taosCleanupCfg();
taosCloseLog();
taosCleanupArgs();
return 0;
}
dmSetProcInfo(argc, (char **)argv);
taosCleanupArgs();

View File

@ -40,6 +40,8 @@ int32_t mndBuildSMCreateStbRsp(SMnode *pMnode, char* dbFName, char* stbFName, vo
void mndExtractDbNameFromStbFullName(const char *stbFullName, char *dst);
void mndExtractTbNameFromStbFullName(const char *stbFullName, char *dst, int32_t dstSize);
const char *mndGetStbStr(const char *src);
#ifdef __cplusplus
}
#endif

View File

@ -315,7 +315,7 @@ static int32_t mndProcessUptimeTimer(SRpcMsg *pReq) {
return 0;
}
mTrace("update cluster uptime to %" PRId64, clusterObj.upTime);
mInfo("update cluster uptime to %" PRId64, clusterObj.upTime);
STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_ROLLBACK, TRN_CONFLICT_NOTHING, pReq, "update-uptime");
if (pTrans == NULL) return -1;

View File

@ -54,13 +54,15 @@ static int32_t mndProcessConsumerLostMsg(SRpcMsg *pMsg);
static int32_t mndProcessConsumerRecoverMsg(SRpcMsg *pMsg);
int32_t mndInitConsumer(SMnode *pMnode) {
SSdbTable table = {.sdbType = SDB_CONSUMER,
.keyType = SDB_KEY_INT64,
.encodeFp = (SdbEncodeFp)mndConsumerActionEncode,
.decodeFp = (SdbDecodeFp)mndConsumerActionDecode,
.insertFp = (SdbInsertFp)mndConsumerActionInsert,
.updateFp = (SdbUpdateFp)mndConsumerActionUpdate,
.deleteFp = (SdbDeleteFp)mndConsumerActionDelete};
SSdbTable table = {
.sdbType = SDB_CONSUMER,
.keyType = SDB_KEY_INT64,
.encodeFp = (SdbEncodeFp)mndConsumerActionEncode,
.decodeFp = (SdbDecodeFp)mndConsumerActionDecode,
.insertFp = (SdbInsertFp)mndConsumerActionInsert,
.updateFp = (SdbUpdateFp)mndConsumerActionUpdate,
.deleteFp = (SdbDeleteFp)mndConsumerActionDelete,
};
mndSetMsgHandle(pMnode, TDMT_MND_SUBSCRIBE, mndProcessSubscribeReq);
mndSetMsgHandle(pMnode, TDMT_MND_MQ_HB, mndProcessMqHbReq);
@ -176,6 +178,8 @@ static int32_t mndProcessMqTimerMsg(SRpcMsg *pMsg) {
SMqConsumerObj *pConsumer;
void *pIter = NULL;
mTrace("start to process mq timer");
// rebalance cannot be parallel
if (!mndRebTryStart()) {
mInfo("mq rebalance already in progress, do nothing");

View File

@ -0,0 +1,645 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _DEFAULT_SOURCE
#include "mndDb.h"
#include "mndInt.h"
#include "mndStb.h"
#include "sdb.h"
#include "tconfig.h"
#include "tjson.h"
#include "ttypes.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
void reportStartup(const char *name, const char *desc) {}
void sendRsp(SRpcMsg *pMsg) { rpcFreeCont(pMsg->pCont); }
int32_t sendReq(const SEpSet *pEpSet, SRpcMsg *pMsg) {
terrno = TSDB_CODE_INVALID_PTR;
return -1;
}
char *i642str(int64_t val) {
static char str[24] = {0};
snprintf(str, sizeof(str), "%" PRId64, val);
return str;
}
void dumpFunc(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "funcs");
while (1) {
SFuncObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_FUNC, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "name", pObj->name);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "funcType", i642str(pObj->funcType));
tjsonAddStringToObject(item, "scriptType", i642str(pObj->scriptType));
tjsonAddStringToObject(item, "align", i642str(pObj->align));
tjsonAddStringToObject(item, "outputType", i642str(pObj->outputType));
tjsonAddStringToObject(item, "outputLen", i642str(pObj->outputLen));
tjsonAddStringToObject(item, "bufSize", i642str(pObj->bufSize));
tjsonAddStringToObject(item, "signature", i642str(pObj->signature));
tjsonAddStringToObject(item, "commentSize", i642str(pObj->commentSize));
tjsonAddStringToObject(item, "codeSize", i642str(pObj->codeSize));
sdbRelease(pSdb, pObj);
}
}
void dumpDb(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "dbs", items);
while (1) {
SDbObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "db", item);
tjsonAddStringToObject(item, "name", mndGetDbStr(pObj->name));
tjsonAddStringToObject(item, "acct", pObj->acct);
tjsonAddStringToObject(item, "createUser", pObj->createUser);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "uid", i642str(pObj->uid));
tjsonAddStringToObject(item, "cfgVersion", i642str(pObj->cfgVersion));
tjsonAddStringToObject(item, "vgVersion", i642str(pObj->vgVersion));
tjsonAddStringToObject(item, "numOfVgroups", i642str(pObj->cfg.numOfVgroups));
tjsonAddStringToObject(item, "numOfStables", i642str(pObj->cfg.numOfStables));
tjsonAddStringToObject(item, "buffer", i642str(pObj->cfg.buffer));
tjsonAddStringToObject(item, "pageSize", i642str(pObj->cfg.pageSize));
tjsonAddStringToObject(item, "pages", i642str(pObj->cfg.pages));
tjsonAddStringToObject(item, "cacheLastSize", i642str(pObj->cfg.cacheLastSize));
tjsonAddStringToObject(item, "daysPerFile", i642str(pObj->cfg.daysPerFile));
tjsonAddStringToObject(item, "daysToKeep0", i642str(pObj->cfg.daysToKeep0));
tjsonAddStringToObject(item, "daysToKeep1", i642str(pObj->cfg.daysToKeep1));
tjsonAddStringToObject(item, "daysToKeep2", i642str(pObj->cfg.daysToKeep2));
tjsonAddStringToObject(item, "minRows", i642str(pObj->cfg.minRows));
tjsonAddStringToObject(item, "maxRows", i642str(pObj->cfg.maxRows));
tjsonAddStringToObject(item, "precision", i642str(pObj->cfg.precision));
tjsonAddStringToObject(item, "compression", i642str(pObj->cfg.compression));
tjsonAddStringToObject(item, "replications", i642str(pObj->cfg.replications));
tjsonAddStringToObject(item, "strict", i642str(pObj->cfg.strict));
tjsonAddStringToObject(item, "cacheLast",i642str( pObj->cfg.cacheLast));
tjsonAddStringToObject(item, "hashMethod", i642str(pObj->cfg.hashMethod));
tjsonAddStringToObject(item, "hashPrefix", i642str(pObj->cfg.hashPrefix));
tjsonAddStringToObject(item, "hashSuffix", i642str(pObj->cfg.hashSuffix));
tjsonAddStringToObject(item, "sstTrigger", i642str(pObj->cfg.sstTrigger));
tjsonAddStringToObject(item, "tsdbPageSize",i642str( pObj->cfg.tsdbPageSize));
tjsonAddStringToObject(item, "schemaless", i642str(pObj->cfg.schemaless));
tjsonAddStringToObject(item, "walLevel",i642str( pObj->cfg.walLevel));
tjsonAddStringToObject(item, "walFsyncPeriod", i642str(pObj->cfg.walFsyncPeriod));
tjsonAddStringToObject(item, "walRetentionPeriod", i642str(pObj->cfg.walRetentionPeriod));
tjsonAddStringToObject(item, "walRetentionSize",i642str( pObj->cfg.walRetentionSize));
tjsonAddStringToObject(item, "walRollPeriod", i642str(pObj->cfg.walRollPeriod));
tjsonAddStringToObject(item, "walSegmentSize", i642str(pObj->cfg.walSegmentSize));
tjsonAddStringToObject(item, "numOfRetensions",i642str( pObj->cfg.numOfRetensions));
for (int32_t i = 0; i < pObj->cfg.numOfRetensions; ++i) {
SJson *rentensions = tjsonAddArrayToObject(item, "rentensions");
SJson *rentension = tjsonCreateObject();
tjsonAddItemToArray(rentensions, rentension);
SRetention *pRetension = taosArrayGet(pObj->cfg.pRetensions, i);
tjsonAddStringToObject(item, "freq", i642str(pRetension->freq));
tjsonAddStringToObject(item, "freqUnit", i642str(pRetension->freqUnit));
tjsonAddStringToObject(item, "keep", i642str(pRetension->keep));
tjsonAddStringToObject(item, "keepUnit",i642str( pRetension->keepUnit));
}
sdbRelease(pSdb, pObj);
}
}
void dumpStb(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "stbs");
while (1) {
SStbObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "name", mndGetStbStr(pObj->name));
tjsonAddStringToObject(item, "db", mndGetDbStr(pObj->db));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "uid", i642str(pObj->uid));
tjsonAddStringToObject(item, "dbUid", i642str(pObj->dbUid));
tjsonAddStringToObject(item, "tagVer",i642str( pObj->tagVer));
tjsonAddStringToObject(item, "colVer", i642str(pObj->colVer));
tjsonAddStringToObject(item, "smaVer", i642str(pObj->smaVer));
tjsonAddStringToObject(item, "nextColId", i642str(pObj->nextColId));
tjsonAddStringToObject(item, "watermark1", i642str(pObj->watermark[0]));
tjsonAddStringToObject(item, "watermark2", i642str(pObj->watermark[1]));
tjsonAddStringToObject(item, "maxdelay0",i642str( pObj->maxdelay[0]));
tjsonAddStringToObject(item, "maxdelay1",i642str( pObj->maxdelay[1]));
tjsonAddStringToObject(item, "ttl",i642str( pObj->ttl));
tjsonAddStringToObject(item, "numOfFuncs",i642str( pObj->numOfFuncs));
tjsonAddStringToObject(item, "commentLen", i642str(pObj->commentLen));
tjsonAddStringToObject(item, "ast1Len", i642str(pObj->ast1Len));
tjsonAddStringToObject(item, "ast2Len",i642str( pObj->ast2Len));
tjsonAddStringToObject(item, "numOfColumns",i642str( pObj->numOfColumns));
SJson *columns = tjsonAddArrayToObject(item, "columns");
for (int32_t i = 0; i < pObj->numOfColumns; ++i) {
SJson *column = tjsonCreateObject();
tjsonAddItemToArray(columns, column);
SSchema *pColumn = &pObj->pColumns[i];
tjsonAddStringToObject(column, "type", i642str(pColumn->type));
tjsonAddStringToObject(column, "typestr", tDataTypes[pColumn->type].name);
tjsonAddStringToObject(column, "flags", i642str(pColumn->flags));
tjsonAddStringToObject(column, "colId", i642str(pColumn->colId));
tjsonAddStringToObject(column, "bytes", i642str(pColumn->bytes));
tjsonAddStringToObject(column, "name", pColumn->name);
}
tjsonAddStringToObject(item, "numOfTags", i642str(pObj->numOfTags));
SJson *tags = tjsonAddArrayToObject(item, "tags");
for (int32_t i = 0; i < pObj->numOfTags; ++i) {
SJson *tag = tjsonCreateObject();
tjsonAddItemToArray(tags, tag);
SSchema *pTag = &pObj->pTags[i];
tjsonAddStringToObject(tag, "type", i642str(pTag->type));
tjsonAddStringToObject(tag, "typestr", tDataTypes[pTag->type].name);
tjsonAddStringToObject(tag, "flags",i642str( pTag->flags));
tjsonAddStringToObject(tag, "colId", i642str(pTag->colId));
tjsonAddStringToObject(tag, "bytes", i642str(pTag->bytes));
tjsonAddStringToObject(tag, "name", pTag->name);
}
sdbRelease(pSdb, pObj);
}
}
void dumpSma(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "smas");
while (1) {
SSmaObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_SMA, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "name", mndGetStbStr(pObj->name));
tjsonAddStringToObject(item, "stb", mndGetStbStr(pObj->stb));
tjsonAddStringToObject(item, "db", mndGetDbStr(pObj->db));
tjsonAddStringToObject(item, "dstTbName", mndGetStbStr(pObj->dstTbName));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "uid", i642str(pObj->uid));
tjsonAddStringToObject(item, "stbUid", i642str(pObj->stbUid));
tjsonAddStringToObject(item, "dbUid", i642str(pObj->dbUid));
tjsonAddStringToObject(item, "dstTbUid", i642str(pObj->dstTbUid));
tjsonAddStringToObject(item, "intervalUnit", i642str(pObj->intervalUnit));
tjsonAddStringToObject(item, "slidingUnit",i642str( pObj->slidingUnit));
tjsonAddStringToObject(item, "timezone", i642str(pObj->timezone));
tjsonAddStringToObject(item, "dstVgId",i642str( pObj->dstVgId));
tjsonAddStringToObject(item, "interval", i642str(pObj->interval));
tjsonAddStringToObject(item, "offset", i642str(pObj->offset));
tjsonAddStringToObject(item, "sliding", i642str(pObj->sliding));
tjsonAddStringToObject(item, "exprLen",i642str( pObj->exprLen));
tjsonAddStringToObject(item, "tagsFilterLen", i642str(pObj->tagsFilterLen));
tjsonAddStringToObject(item, "sqlLen",i642str( pObj->sqlLen));
tjsonAddStringToObject(item, "astLen",i642str( pObj->astLen));
sdbRelease(pSdb, pObj);
}
}
void dumpVgroup(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "vgroups");
while (1) {
SVgObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "vgId", i642str(pObj->vgId));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "version",i642str(pObj->version));
tjsonAddStringToObject(item, "hashBegin", i642str(pObj->hashBegin));
tjsonAddStringToObject(item, "hashEnd", i642str(pObj->hashEnd));
tjsonAddStringToObject(item, "db", mndGetDbStr(pObj->dbName));
tjsonAddStringToObject(item, "dbUid", i642str(pObj->dbUid));
tjsonAddStringToObject(item, "isTsma", i642str(pObj->isTsma));
tjsonAddStringToObject(item, "replica",i642str( pObj->replica));
for (int32_t i = 0; i < pObj->replica; ++i) {
SJson *replicas = tjsonAddArrayToObject(item, "replicas");
SJson *replica = tjsonCreateObject();
tjsonAddItemToArray(replicas, replica);
tjsonAddStringToObject(replica, "dnodeId", i642str(pObj->vnodeGid[i].dnodeId));
}
sdbRelease(pSdb, pObj);
}
}
void dumpTopic(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "topics");
while (1) {
SMqTopicObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_TOPIC, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "name", mndGetDbStr(pObj->name));
tjsonAddStringToObject(item, "name", mndGetDbStr(pObj->db));
tjsonAddStringToObject(item, "createTime", i642str(pObj->createTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "uid", i642str(pObj->uid));
tjsonAddStringToObject(item, "dbUid", i642str(pObj->dbUid));
tjsonAddStringToObject(item, "version",i642str( pObj->version));
tjsonAddStringToObject(item, "subType",i642str( pObj->subType));
tjsonAddStringToObject(item, "withMeta", i642str(pObj->withMeta));
tjsonAddStringToObject(item, "stbUid", i642str(pObj->stbUid));
tjsonAddStringToObject(item, "sqlLen", i642str(pObj->sqlLen));
tjsonAddStringToObject(item, "astLen",i642str( pObj->astLen));
tjsonAddStringToObject(item, "sqlLen",i642str( pObj->sqlLen));
tjsonAddStringToObject(item, "ntbUid", i642str(pObj->ntbUid));
tjsonAddStringToObject(item, "ctbStbUid", i642str(pObj->ctbStbUid));
sdbRelease(pSdb, pObj);
}
}
void dumpConsumer(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "consumers");
while (1) {
SMqConsumerObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_CONSUMER, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "consumerId", i642str(pObj->consumerId));
tjsonAddStringToObject(item, "cgroup", pObj->cgroup);
sdbRelease(pSdb, pObj);
}
}
void dumpSubscribe(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "subscribes");
while (1) {
SMqSubscribeObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_SUBSCRIBE, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "key", pObj->key);
tjsonAddStringToObject(item, "dbUid", i642str(pObj->dbUid));
tjsonAddStringToObject(item, "stbUid", i642str(pObj->stbUid));
sdbRelease(pSdb, pObj);
}
}
void dumpOffset(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "offsets");
while (1) {
SMqOffsetObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_OFFSET, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "key", pObj->key);
tjsonAddStringToObject(item, "dbUid", i642str(pObj->dbUid));
tjsonAddStringToObject(item, "offset", i642str(pObj->offset));
sdbRelease(pSdb, pObj);
}
}
void dumpStream(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "streams");
while (1) {
SStreamObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_STREAM, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "name", mndGetDbStr(pObj->name));
tjsonAddStringToObject(item, "createTime", i642str(pObj->createTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "version", i642str(pObj->version));
tjsonAddStringToObject(item, "totalLevel", i642str(pObj->totalLevel));
tjsonAddStringToObject(item, "smaId", i642str(pObj->smaId));
tjsonAddStringToObject(item, "uid", i642str(pObj->uid));
tjsonAddStringToObject(item, "status",i642str( pObj->status));
tjsonAddStringToObject(item, "igExpired",i642str( pObj->igExpired));
tjsonAddStringToObject(item, "trigger",i642str( pObj->trigger));
tjsonAddStringToObject(item, "triggerParam", i642str(pObj->triggerParam));
tjsonAddStringToObject(item, "watermark", i642str(pObj->watermark));
tjsonAddStringToObject(item, "sourceDbUid", i642str(pObj->sourceDbUid));
tjsonAddStringToObject(item, "targetDbUid", i642str(pObj->targetDbUid));
tjsonAddStringToObject(item, "sourceDb", mndGetDbStr(pObj->sourceDb));
tjsonAddStringToObject(item, "targetDb", mndGetDbStr(pObj->targetDb));
tjsonAddStringToObject(item, "targetSTbName", mndGetStbStr(pObj->targetSTbName));
tjsonAddStringToObject(item, "targetStbUid", i642str(pObj->targetStbUid));
tjsonAddStringToObject(item, "fixedSinkVgId", i642str(pObj->fixedSinkVgId));
sdbRelease(pSdb, pObj);
}
}
void dumpAcct(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "accts");
while (1) {
SAcctObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_ACCT, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "acct", pObj->acct);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "acctId", i642str(pObj->acctId));
sdbRelease(pSdb, pObj);
}
}
void dumpAuth(SSdb *pSdb, SJson *json) {
// todo
}
void dumpUser(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "users");
while (1) {
SUserObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "name", pObj->user);
tjsonAddStringToObject(item, "acct", pObj->acct);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "superUser",i642str( pObj->superUser));
tjsonAddStringToObject(item, "authVersion", i642str(pObj->authVersion));
tjsonAddStringToObject(item, "numOfReadDbs",i642str( taosHashGetSize(pObj->readDbs)));
tjsonAddStringToObject(item, "numOfWriteDbs", i642str(taosHashGetSize(pObj->writeDbs)));
sdbRelease(pSdb, pObj);
}
}
void dumpDnode(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "dnodes");
while (1) {
SDnodeObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "id",i642str( pObj->id));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "port",i642str( pObj->port));
tjsonAddStringToObject(item, "fqdn", pObj->fqdn);
sdbRelease(pSdb, pObj);
}
}
void dumpBnode(SSdb *pSdb, SJson *json) {
// not implemented yet
}
void dumpSnode(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "snodes");
while (1) {
SSnodeObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_QNODE, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "id",i642str( pObj->id));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
sdbRelease(pSdb, pObj);
}
}
void dumpQnode(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "qnodes");
while (1) {
SQnodeObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_QNODE, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "id", i642str(pObj->id));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
sdbRelease(pSdb, pObj);
}
}
void dumpMnode(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "mnodes");
while (1) {
SMnodeObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "id", i642str(pObj->id));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
sdbRelease(pSdb, pObj);
}
}
void dumpCluster(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "clusters");
while (1) {
SClusterObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_CLUSTER, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "id", i642str(pObj->id));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "name", pObj->name);
sdbRelease(pSdb, pObj);
}
}
void dumpTrans(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonAddArrayToObject(json, "transactions");
while (1) {
STrans *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_TRANS, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToArray(items, item);
tjsonAddStringToObject(item, "id", i642str(pObj->id));
tjsonAddStringToObject(item, "stage", i642str(pObj->stage));
tjsonAddStringToObject(item, "policy", i642str(pObj->policy));
tjsonAddStringToObject(item, "conflict",i642str( pObj->conflict));
tjsonAddStringToObject(item, "exec", i642str(pObj->exec));
tjsonAddStringToObject(item, "oper", i642str(pObj->oper));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "dbname", pObj->dbname);
tjsonAddStringToObject(item, "stbname", pObj->stbname);
tjsonAddStringToObject(item, "opername", pObj->opername);
tjsonAddStringToObject(item, "commitLogNum",i642str( taosArrayGetSize(pObj->commitActions)));
tjsonAddStringToObject(item, "redoActionNum",i642str(taosArrayGetSize(pObj->redoActions)));
tjsonAddStringToObject(item, "undoActionNum", i642str(taosArrayGetSize(pObj->undoActions)));
sdbRelease(pSdb, pObj);
}
}
void dumpHeader(SSdb *pSdb, SJson *json) {
tjsonAddStringToObject(json, "sver", i642str(1));
tjsonAddStringToObject(json, "applyIndex", i642str(pSdb->applyIndex));
tjsonAddStringToObject(json, "applyTerm", i642str(pSdb->applyTerm));
tjsonAddStringToObject(json, "applyConfig", i642str(pSdb->applyConfig));
SJson *maxIdsJson = tjsonCreateObject();
tjsonAddItemToObject(json, "maxIds", maxIdsJson);
for (int32_t i = 0; i < SDB_MAX; ++i) {
int64_t maxId = 0;
if (i < SDB_MAX) {
maxId = pSdb->maxId[i];
}
tjsonAddStringToObject(maxIdsJson, sdbTableName(i), i642str(maxId));
}
SJson *tableVersJson = tjsonCreateObject();
tjsonAddItemToObject(json, "tableVers", tableVersJson);
for (int32_t i = 0; i < SDB_MAX; ++i) {
int64_t tableVer = 0;
if (i < SDB_MAX) {
tableVer = pSdb->tableVer[i];
}
tjsonAddStringToObject(tableVersJson, sdbTableName(i), i642str(tableVer));
}
}
void mndDumpSdb() {
mInfo("start to dump sdb info to sdb.json");
char path[PATH_MAX * 2] = {0};
snprintf(path, sizeof(path), "%s%smnode", tsDataDir, TD_DIRSEP);
SMsgCb msgCb = {0};
msgCb.reportStartupFp = reportStartup;
msgCb.sendReqFp = sendReq;
msgCb.sendRspFp = sendRsp;
msgCb.mgmt = (SMgmtWrapper *)(&msgCb); // hack
tmsgSetDefault(&msgCb);
walInit();
syncInit();
SMnodeOpt opt = {.msgCb = msgCb};
SMnode *pMnode = mndOpen(path, &opt);
if (pMnode == NULL) return;
SSdb *pSdb = pMnode->pSdb;
SJson *json = tjsonCreateObject();
dumpHeader(pSdb, json);
dumpFunc(pSdb, json);
dumpDb(pSdb, json);
dumpStb(pSdb, json);
dumpSma(pSdb, json);
dumpVgroup(pSdb, json);
dumpTopic(pSdb, json);
dumpConsumer(pSdb, json);
dumpSubscribe(pSdb, json);
dumpOffset(pSdb, json);
dumpStream(pSdb, json);
dumpAcct(pSdb, json);
dumpAuth(pSdb, json);
dumpUser(pSdb, json);
dumpDnode(pSdb, json);
dumpBnode(pSdb, json);
dumpSnode(pSdb, json);
dumpQnode(pSdb, json);
dumpMnode(pSdb, json);
dumpCluster(pSdb, json);
dumpTrans(pSdb, json);
char *pCont = tjsonToString(json);
int32_t contLen = strlen(pCont);
char file[] = "sdb.json";
TdFilePtr pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
if (pFile == NULL) {
terrno = TAOS_SYSTEM_ERROR(errno);
mError("failed to write %s since %s", file, terrstr());
return;
}
taosWriteFile(pFile, pCont, contLen);
taosWriteFile(pFile, "\n", 1);
taosFsyncFile(pFile);
taosCloseFile(&pFile);
tjsonDelete(json);
taosMemoryFree(pCont);
mInfo("dump sdb info success");
}
#pragma GCC diagnostic pop

View File

@ -38,13 +38,15 @@ static int32_t mndRetrieveFuncs(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pB
static void mndCancelGetNextFunc(SMnode *pMnode, void *pIter);
int32_t mndInitFunc(SMnode *pMnode) {
SSdbTable table = {.sdbType = SDB_FUNC,
.keyType = SDB_KEY_BINARY,
.encodeFp = (SdbEncodeFp)mndFuncActionEncode,
.decodeFp = (SdbDecodeFp)mndFuncActionDecode,
.insertFp = (SdbInsertFp)mndFuncActionInsert,
.updateFp = (SdbUpdateFp)mndFuncActionUpdate,
.deleteFp = (SdbDeleteFp)mndFuncActionDelete};
SSdbTable table = {
.sdbType = SDB_FUNC,
.keyType = SDB_KEY_BINARY,
.encodeFp = (SdbEncodeFp)mndFuncActionEncode,
.decodeFp = (SdbDecodeFp)mndFuncActionDecode,
.insertFp = (SdbInsertFp)mndFuncActionInsert,
.updateFp = (SdbUpdateFp)mndFuncActionUpdate,
.deleteFp = (SdbDeleteFp)mndFuncActionDelete,
};
mndSetMsgHandle(pMnode, TDMT_MND_CREATE_FUNC, mndProcessCreateFuncReq);
mndSetMsgHandle(pMnode, TDMT_MND_DROP_FUNC, mndProcessDropFuncReq);

View File

@ -119,28 +119,30 @@ static void *mndThreadFp(void *param) {
lastTime++;
taosMsleep(100);
if (mndGetStop(pMnode)) break;
if (lastTime % 10 != 0) continue;
if (lastTime % (tsTtlPushInterval * 10) == 1) {
int64_t sec = lastTime / 10;
if (sec % tsTtlPushInterval == 0) {
mndPullupTtl(pMnode);
}
if (lastTime % (tsTransPullupInterval * 10) == 0) {
if (sec % tsTransPullupInterval == 0) {
mndPullupTrans(pMnode);
}
if (lastTime % (tsMqRebalanceInterval * 10) == 0) {
if (sec % tsMqRebalanceInterval == 0) {
mndCalMqRebalance(pMnode);
}
if (lastTime % (tsTelemInterval * 10) == ((tsTelemInterval - 1) * 10)) {
if (sec % tsTelemInterval == (TMIN(60, (tsTelemInterval - 1)))) {
mndPullupTelem(pMnode);
}
if (lastTime % (tsGrantHBInterval * 10) == 0) {
if (sec % tsGrantHBInterval == 0) {
mndPullupGrant(pMnode);
}
if ((lastTime % (tsUptimeInterval * 10)) == ((tsUptimeInterval - 1) * 10)) {
if (sec % tsUptimeInterval == 0) {
mndIncreaseUpTime(pMnode);
}
}
@ -399,15 +401,15 @@ void mndPreClose(SMnode *pMnode) {
atomic_store_8(&(pMnode->syncMgmt.leaderTransferFinish), 0);
syncLeaderTransfer(pMnode->syncMgmt.sync);
/*
mInfo("vgId:1, mnode start leader transfer");
// wait for leader transfer finish
while (!atomic_load_8(&(pMnode->syncMgmt.leaderTransferFinish))) {
taosMsleep(10);
mInfo("vgId:1, mnode waiting for leader transfer");
}
mInfo("vgId:1, mnode finish leader transfer");
*/
#if 0
mInfo("vgId:1, mnode start leader transfer");
// wait for leader transfer finish
while (!atomic_load_8(&(pMnode->syncMgmt.leaderTransferFinish))) {
taosMsleep(10);
mInfo("vgId:1, mnode waiting for leader transfer");
}
mInfo("vgId:1, mnode finish leader transfer");
#endif
}
}

View File

@ -834,6 +834,8 @@ static int32_t mndProcessTtlTimer(SRpcMsg *pReq) {
int32_t reqLen = tSerializeSVDropTtlTableReq(NULL, 0, &ttlReq);
int32_t contLen = reqLen + sizeof(SMsgHead);
mInfo("start to process ttl timer");
while (1) {
pIter = sdbFetch(pSdb, SDB_VGROUP, pIter, (void **)&pVgroup);
if (pIter == NULL) break;
@ -2579,3 +2581,14 @@ static void mndCancelGetNextStb(SMnode *pMnode, void *pIter) {
SSdb *pSdb = pMnode->pSdb;
sdbCancelFetch(pSdb, pIter);
}
const char *mndGetStbStr(const char *src) {
char *posDb = strstr(src, TS_PATH_DELIMITER);
if (posDb != NULL) ++posDb;
if (posDb == NULL) return src;
char *posStb = strstr(posDb, TS_PATH_DELIMITER);
if (posStb != NULL) ++posStb;
if (posStb == NULL) return posDb;
return posStb;
}

View File

@ -133,7 +133,7 @@ static int32_t mndProcessTelemTimer(SRpcMsg* pReq) {
if (taosSendHttpReport(tsTelemServer, tsTelemPort, pCont, strlen(pCont), HTTP_FLAT) != 0) {
mError("failed to send telemetry report");
} else {
mTrace("succeed to send telemetry report");
mInfo("succeed to send telemetry report");
}
taosMemoryFree(pCont);
}

View File

@ -1478,6 +1478,7 @@ void mndTransExecute(SMnode *pMnode, STrans *pTrans) {
}
static int32_t mndProcessTransTimer(SRpcMsg *pReq) {
mTrace("start to process trans timer");
mndTransPullup(pReq->info.node);
return 0;
}
@ -1604,7 +1605,7 @@ static int32_t mndRetrieveTrans(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBl
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
colDataAppend(pColInfo, numOfRows, (const char *)dbname, false);
char stbname[TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
char stbname[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
STR_WITH_MAXSIZE_TO_VARSTR(stbname, mndGetDbStr(pTrans->stbname), pShow->pMeta->pSchemas[cols].bytes);
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
colDataAppend(pColInfo, numOfRows, (const char *)stbname, false);

View File

@ -40,6 +40,8 @@ const char *sdbTableName(ESdbType type) {
return "auth";
case SDB_ACCT:
return "acct";
case SDB_STREAM_CK:
return "stream_ck";
case SDB_STREAM:
return "stream";
case SDB_OFFSET:
@ -219,14 +221,15 @@ static int32_t sdbDeleteRow(SSdb *pSdb, SHashObj *hash, SSdbRaw *pRaw, SSdbRow *
return terrno;
}
SSdbRow *pOldRow = *ppOldRow;
pOldRow->status = pRaw->status;
atomic_add_fetch_32(&pOldRow->refCount, 1);
sdbPrintOper(pSdb, pOldRow, "delete");
taosHashRemove(hash, pOldRow->pObj, keySize);
pSdb->tableVer[pOldRow->type]++;
taosThreadRwlockUnlock(pLock);
pSdb->tableVer[pOldRow->type]++;
sdbFreeRow(pSdb, pRow, false);
sdbCheckRow(pSdb, pOldRow);
@ -315,7 +318,7 @@ static void sdbCheckRow(SSdb *pSdb, SSdbRow *pRow) {
TdThreadRwlock *pLock = &pSdb->locks[pRow->type];
taosThreadRwlockWrlock(pLock);
int32_t ref = atomic_load_32(&pRow->refCount);
int32_t ref = atomic_sub_fetch_32(&pRow->refCount, 1);
sdbPrintOper(pSdb, pRow, "check");
if (ref <= 0 && pRow->status == SDB_STATUS_DROPPED) {
sdbFreeRow(pSdb, pRow, true);

View File

@ -32,6 +32,12 @@ extern "C" {
#define tsdbTrace(...) do { if (tsdbDebugFlag & DEBUG_TRACE) { taosPrintLog("TSD ", DEBUG_TRACE, tsdbDebugFlag, __VA_ARGS__); }} while(0)
// clang-format on
#define TSDB_CHECK_CODE(CODE, LINO, LABEL) \
if (CODE) { \
LINO = __LINE__; \
goto LABEL; \
}
typedef struct TSDBROW TSDBROW;
typedef struct TABLEID TABLEID;
typedef struct TSDBKEY TSDBKEY;
@ -88,9 +94,8 @@ typedef struct SLDataIter SLDataIter;
static FORCE_INLINE int64_t tsdbLogicToFileSize(int64_t lSize, int32_t szPage) {
int64_t fOffSet = LOGIC_TO_FILE_OFFSET(lSize, szPage);
int64_t pgno = OFFSET_PGNO(fOffSet, szPage);
int32_t szPageCont = PAGE_CONTENT_SIZE(szPage);
if (fOffSet % szPageCont == 0) {
if (fOffSet % szPage == 0) {
pgno--;
}
@ -151,7 +156,7 @@ int32_t tCmprBlockL(void const *lhs, void const *rhs);
int32_t tBlockDataCreate(SBlockData *pBlockData);
void tBlockDataDestroy(SBlockData *pBlockData, int8_t deepClear);
int32_t tBlockDataInit(SBlockData *pBlockData, int64_t suid, int64_t uid, STSchema *pTSchema);
int32_t tBlockDataInit(SBlockData *pBlockData, TABLEID *pId, STSchema *pTSchema, int16_t *aCid, int32_t nCid);
int32_t tBlockDataInitEx(SBlockData *pBlockData, SBlockData *pBlockDataFrom);
void tBlockDataReset(SBlockData *pBlockData);
int32_t tBlockDataAppendRow(SBlockData *pBlockData, TSDBROW *pRow, STSchema *pTSchema, int64_t uid);
@ -273,6 +278,7 @@ int32_t tsdbReadSttBlk(SDataFReader *pReader, int32_t iStt, SArray *aSttBlk);
int32_t tsdbReadBlockSma(SDataFReader *pReader, SDataBlk *pBlock, SArray *aColumnDataAgg);
int32_t tsdbReadDataBlock(SDataFReader *pReader, SDataBlk *pBlock, SBlockData *pBlockData);
int32_t tsdbReadSttBlock(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData);
int32_t tsdbReadSttBlockEx(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData);
// SDelFWriter
int32_t tsdbDelFWriterOpen(SDelFWriter **ppWriter, SDelFile *pFile, STsdb *pTsdb);
int32_t tsdbDelFWriterClose(SDelFWriter **ppWriter, int8_t sync);
@ -285,8 +291,8 @@ int32_t tsdbDelFReaderClose(SDelFReader **ppReader);
int32_t tsdbReadDelData(SDelFReader *pReader, SDelIdx *pDelIdx, SArray *aDelData);
int32_t tsdbReadDelIdx(SDelFReader *pReader, SArray *aDelIdx);
// tsdbRead.c ==============================================================================================
int32_t tsdbTakeReadSnap(STsdb *pTsdb, STsdbReadSnap **ppSnap, const char* id);
void tsdbUntakeReadSnap(STsdb *pTsdb, STsdbReadSnap *pSnap, const char* id);
int32_t tsdbTakeReadSnap(STsdb *pTsdb, STsdbReadSnap **ppSnap, const char *id);
void tsdbUntakeReadSnap(STsdb *pTsdb, STsdbReadSnap *pSnap, const char *id);
// tsdbMerge.c ==============================================================================================
int32_t tsdbMerge(STsdb *pTsdb);
@ -634,6 +640,9 @@ typedef struct SSttBlockLoadInfo {
int32_t currentLoadBlockIndex;
int32_t loadBlocks;
double elapsedTime;
STSchema *pSchema;
int16_t *colIds;
int32_t numOfCols;
} SSttBlockLoadInfo;
typedef struct SMergeTree {
@ -653,13 +662,14 @@ typedef struct {
} SSkmInfo;
int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFReader, uint64_t suid, uint64_t uid,
STimeWindow *pTimeWindow, SVersionRange *pVerRange, void *pLoadInfo, const char *idStr);
STimeWindow *pTimeWindow, SVersionRange *pVerRange, void *pBlockLoadInfo, STSchema *pSchema,
int16_t *pCols, int32_t numOfCols, const char *idStr);
void tMergeTreeAddIter(SMergeTree *pMTree, SLDataIter *pIter);
bool tMergeTreeNext(SMergeTree *pMTree);
TSDBROW tMergeTreeGetRow(SMergeTree *pMTree);
void tMergeTreeClose(SMergeTree *pMTree);
SSttBlockLoadInfo *tCreateLastBlockLoadInfo();
SSttBlockLoadInfo *tCreateLastBlockLoadInfo(STSchema *pSchema, int16_t *colList, int32_t numOfCols);
void resetLastBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo);
void getLastBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo, int64_t *blocks, double *el);
void *destroyLastBlockLoadInfo(SSttBlockLoadInfo *pLoadInfo);

View File

@ -457,7 +457,7 @@ static int32_t getNextRowFromFSLast(void *iter, TSDBROW **ppRow) {
tMergeTreeOpen(&state->mergeTree, 1, state->pDataFReader, state->suid, state->uid,
&(STimeWindow){.skey = TSKEY_MIN, .ekey = TSKEY_MAX},
&(SVersionRange){.minVer = 0, .maxVer = UINT64_MAX}, NULL, NULL);
&(SVersionRange){.minVer = 0, .maxVer = UINT64_MAX}, NULL, NULL, NULL, 0, NULL);
bool hasVal = tMergeTreeNext(&state->mergeTree);
if (!hasVal) {
state->state = SFSLASTNEXTROW_FILESET;
@ -612,7 +612,8 @@ static int32_t getNextRowFromFS(void *iter, TSDBROW **ppRow) {
tMapDataGetItemByIdx(&state->blockMap, state->iBlock, &block, tGetDataBlk);
/* code = tsdbReadBlockData(state->pDataFReader, &state->blockIdx, &block, &state->blockData, NULL, NULL); */
tBlockDataReset(state->pBlockData);
code = tBlockDataInit(state->pBlockData, state->suid, state->uid, state->pTSchema);
TABLEID tid = {.suid = state->suid, .uid = state->uid};
code = tBlockDataInit(state->pBlockData, &tid, state->pTSchema, NULL, 0);
if (code) goto _err;
code = tsdbReadDataBlock(state->pDataFReader, &block, state->pBlockData);

View File

@ -437,7 +437,7 @@ static int32_t tsdbOpenCommitIter(SCommitter *pCommitter) {
pIter->iSttBlk = 0;
SSttBlk *pSttBlk = (SSttBlk *)taosArrayGet(pIter->aSttBlk, 0);
code = tsdbReadSttBlock(pCommitter->dReader.pReader, iStt, pSttBlk, &pIter->bData);
code = tsdbReadSttBlockEx(pCommitter->dReader.pReader, iStt, pSttBlk, &pIter->bData);
if (code) goto _err;
pIter->iRow = 0;
@ -1049,7 +1049,7 @@ static int32_t tsdbNextCommitRow(SCommitter *pCommitter) {
if (pIter->iSttBlk < taosArrayGetSize(pIter->aSttBlk)) {
SSttBlk *pSttBlk = (SSttBlk *)taosArrayGet(pIter->aSttBlk, pIter->iSttBlk);
code = tsdbReadSttBlock(pCommitter->dReader.pReader, pIter->iStt, pSttBlk, &pIter->bData);
code = tsdbReadSttBlockEx(pCommitter->dReader.pReader, pIter->iStt, pSttBlk, &pIter->bData);
if (code) goto _exit;
pIter->iRow = 0;
@ -1305,7 +1305,8 @@ static int32_t tsdbInitLastBlockIfNeed(SCommitter *pCommitter, TABLEID id) {
if (!pBDatal->suid && !pBDatal->uid) {
ASSERT(pCommitter->skmTable.suid == id.suid);
ASSERT(pCommitter->skmTable.uid == id.uid);
code = tBlockDataInit(pBDatal, id.suid, id.suid ? 0 : id.uid, pCommitter->skmTable.pTSchema);
TABLEID tid = {.suid = id.suid, .uid = id.suid ? 0 : id.uid};
code = tBlockDataInit(pBDatal, &tid, pCommitter->skmTable.pTSchema, NULL, 0);
if (code) goto _exit;
}
@ -1428,9 +1429,9 @@ static int32_t tsdbCommitFileDataImpl(SCommitter *pCommitter) {
// impl
code = tsdbUpdateTableSchema(pCommitter->pTsdb->pVnode->pMeta, id.suid, id.uid, &pCommitter->skmTable);
if (code) goto _err;
code = tBlockDataInit(&pCommitter->dReader.bData, id.suid, id.uid, pCommitter->skmTable.pTSchema);
code = tBlockDataInit(&pCommitter->dReader.bData, &id, pCommitter->skmTable.pTSchema, NULL, 0);
if (code) goto _err;
code = tBlockDataInit(&pCommitter->dWriter.bData, id.suid, id.uid, pCommitter->skmTable.pTSchema);
code = tBlockDataInit(&pCommitter->dWriter.bData, &id, pCommitter->skmTable.pTSchema, NULL, 0);
if (code) goto _err;
/* merge with data in .data file */

View File

@ -28,11 +28,10 @@ struct SLDataIter {
uint64_t uid;
STimeWindow timeWindow;
SVersionRange verRange;
SSttBlockLoadInfo* pBlockLoadInfo;
};
SSttBlockLoadInfo* tCreateLastBlockLoadInfo() {
SSttBlockLoadInfo* tCreateLastBlockLoadInfo(STSchema* pSchema, int16_t* colList, int32_t numOfCols) {
SSttBlockLoadInfo* pLoadInfo = taosMemoryCalloc(TSDB_DEFAULT_STT_FILE, sizeof(SSttBlockLoadInfo));
if (pLoadInfo == NULL) {
terrno = TSDB_CODE_OUT_OF_MEMORY;
@ -55,6 +54,9 @@ SSttBlockLoadInfo* tCreateLastBlockLoadInfo() {
}
pLoadInfo[i].aSttBlk = taosArrayInit(4, sizeof(SSttBlk));
pLoadInfo[i].pSchema = pSchema;
pLoadInfo[i].colIds = colList;
pLoadInfo[i].numOfCols = numOfCols;
}
return pLoadInfo;
@ -111,7 +113,19 @@ static SBlockData* loadLastBlock(SLDataIter *pIter, const char* idStr) {
pInfo->currentLoadBlockIndex ^= 1;
if (pIter->pSttBlk != NULL) { // current block not loaded yet
int64_t st = taosGetTimestampUs();
code = tsdbReadSttBlock(pIter->pReader, pIter->iStt, pIter->pSttBlk, &pInfo->blockData[pInfo->currentLoadBlockIndex]);
SBlockData* pBlock = &pInfo->blockData[pInfo->currentLoadBlockIndex];
TABLEID id = {0};
if (pIter->pSttBlk->suid != 0) {
id.suid = pIter->pSttBlk->suid;
} else {
id.uid = pIter->uid;
}
tBlockDataInit(pBlock, &id, pInfo->pSchema, pInfo->colIds, pInfo->numOfCols);
code = tsdbReadSttBlock(pIter->pReader, pIter->iStt, pIter->pSttBlk, pBlock);
double el = (taosGetTimestampUs() - st)/ 1000.0;
pInfo->elapsedTime += el;
pInfo->loadBlocks += 1;
@ -460,7 +474,8 @@ static FORCE_INLINE int32_t tLDataIterCmprFn(const void *p1, const void *p2) {
}
int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFReader, uint64_t suid, uint64_t uid,
STimeWindow *pTimeWindow, SVersionRange *pVerRange, void* pBlockLoadInfo, const char* idStr) {
STimeWindow *pTimeWindow, SVersionRange *pVerRange, void* pBlockLoadInfo, STSchema* pSchema,
int16_t* pCols, int32_t numOfCols, const char* idStr) {
pMTree->backward = backward;
pMTree->pIter = NULL;
pMTree->pIterList = taosArrayInit(4, POINTER_BYTES);
@ -475,9 +490,10 @@ int32_t tMergeTreeOpen(SMergeTree *pMTree, int8_t backward, SDataFReader *pFRead
SSttBlockLoadInfo* pLoadInfo = NULL;
if (pBlockLoadInfo == NULL) {
ASSERT(0);
if (pMTree->pLoadInfo == NULL) {
pMTree->destroyLoadInfo = true;
pMTree->pLoadInfo = tCreateLastBlockLoadInfo();
pMTree->pLoadInfo = tCreateLastBlockLoadInfo(pSchema, pCols, numOfCols);
}
pLoadInfo = pMTree->pLoadInfo;

View File

@ -79,6 +79,7 @@ typedef struct SBlockLoadSuppInfo {
SColumnDataAgg tsColAgg;
SColumnDataAgg** plist;
int16_t* colIds; // column ids for loading file block data
int32_t numOfCols;
char** buildBuf; // build string tmp buffer, todo remove it later after all string format being updated.
} SBlockLoadSuppInfo;
@ -203,6 +204,7 @@ static int32_t setColumnIdSlotList(STsdbReader* pReader, SSDataBlock* pBlock) {
size_t numOfCols = blockDataGetNumOfCols(pBlock);
pSupInfo->numOfCols = numOfCols;
pSupInfo->colIds = taosMemoryMalloc(numOfCols * sizeof(int16_t));
pSupInfo->buildBuf = taosMemoryCalloc(numOfCols, POINTER_BYTES);
if (pSupInfo->buildBuf == NULL || pSupInfo->colIds == NULL) {
@ -352,7 +354,8 @@ static int32_t initFilesetIterator(SFilesetIter* pIter, SArray* aDFileSet, STsdb
tMergeTreeClose(&pLReader->mergeTree);
if (pLReader->pInfo == NULL) {
pLReader->pInfo = tCreateLastBlockLoadInfo();
// here we ignore the first column, which is always be the primary timestamp column
pLReader->pInfo = tCreateLastBlockLoadInfo(pReader->pSchema, &pReader->suppInfo.colIds[1], pReader->suppInfo.numOfCols - 1);
if (pLReader->pInfo == NULL) {
tsdbDebug("init fileset iterator failed, code:%s %s", tstrerror(terrno), pReader->idStr);
return terrno;
@ -1274,14 +1277,8 @@ static bool doCheckforDatablockOverlap(STableBlockScanInfo* pBlockScanInfo, cons
if (p->version >= pBlock->minVer) {
if (i < num - 1) {
TSDBKEY* pnext = taosArrayGet(pBlockScanInfo->delSkyline, i + 1);
// if (i + 1 == num - 1) { // pnext is the last point
if (pnext->ts >= pBlock->minKey.ts) {
return true;
// }
// } else {
// if (pnext->ts >= pBlock->minKey.ts) {
// return true;
// }
}
} else { // it must be the last point
ASSERT(p->version == 0);
@ -1996,7 +1993,8 @@ static bool initLastBlockReader(SLastBlockReader* pLBlockReader, STableBlockScan
int32_t code =
tMergeTreeOpen(&pLBlockReader->mergeTree, (pLBlockReader->order == TSDB_ORDER_DESC), pReader->pFileReader,
pReader->suid, pScanInfo->uid, &w, &pLBlockReader->verRange, pLBlockReader->pInfo, pReader->idStr);
pReader->suid, pScanInfo->uid, &w, &pLBlockReader->verRange, pLBlockReader->pInfo,
pReader->pSchema, pReader->suppInfo.colIds, pReader->suppInfo.numOfCols, pReader->idStr);
if (code != TSDB_CODE_SUCCESS) {
return false;
}
@ -2453,7 +2451,8 @@ static int32_t doBuildDataBlock(STsdbReader* pReader) {
code = buildComposedDataBlock(pReader);
} else if (fileBlockShouldLoad(pReader, pBlockInfo, pBlock, pScanInfo, keyInBuf, pLastBlockReader)) {
tBlockDataReset(&pStatus->fileBlockData);
code = tBlockDataInit(&pStatus->fileBlockData, pReader->suid, pScanInfo->uid, pReader->pSchema);
TABLEID tid = {.suid = pReader->suid, .uid = pScanInfo->uid};
code = tBlockDataInit(&pStatus->fileBlockData, &tid, pReader->pSchema, NULL, 0);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
@ -2933,7 +2932,8 @@ static int32_t checkForNeighborFileBlock(STsdbReader* pReader, STableBlockScanIn
// 3. load the neighbor block, and set it to be the currently accessed file data block
tBlockDataReset(&pStatus->fileBlockData);
int32_t code = tBlockDataInit(&pStatus->fileBlockData, pReader->suid, pFBlock->uid, pReader->pSchema);
TABLEID tid = {.suid = pReader->suid, .uid = pFBlock->uid};
int32_t code = tBlockDataInit(&pStatus->fileBlockData, &tid, pReader->pSchema, NULL, 0);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
@ -3216,8 +3216,8 @@ int32_t doAppendRowFromFileBlock(SSDataBlock* pResBlock, STsdbReader* pReader, S
tColDataGetValue(pData, rowIndex, &cv);
doCopyColVal(pCol, outputRowIndex, i, &cv, pSupInfo);
j += 1;
} else if (pData->cid >
pCol->info.colId) { // the specified column does not exist in file block, fill with null data
} else if (pData->cid > pCol->info.colId) {
// the specified column does not exist in file block, fill with null data
colDataAppendNULL(pCol, outputRowIndex);
}
@ -3403,14 +3403,18 @@ int32_t tsdbReaderOpen(SVnode* pVnode, SQueryTableDataCond* pCond, SArray* pTabl
STsdbReader* pPrevReader = pReader->innerReader[0];
STsdbReader* pNextReader = pReader->innerReader[1];
// we need only one row
pPrevReader->capacity = 1;
pPrevReader->status.pTableMap = pReader->status.pTableMap;
pPrevReader->pReadSnap = pReader->pReadSnap;
// we need only one row
pPrevReader->capacity = 1;
pPrevReader->status.pTableMap = pReader->status.pTableMap;
pPrevReader->pSchema = pReader->pSchema;
pPrevReader->pMemSchema = pReader->pMemSchema;
pPrevReader->pReadSnap = pReader->pReadSnap;
pNextReader->capacity = 1;
pNextReader->status.pTableMap = pReader->status.pTableMap;
pNextReader->pReadSnap = pReader->pReadSnap;
pNextReader->capacity = 1;
pNextReader->status.pTableMap = pReader->status.pTableMap;
pNextReader->pSchema = pReader->pSchema;
pNextReader->pMemSchema = pReader->pMemSchema;
pNextReader->pReadSnap = pReader->pReadSnap;
code = doOpenReaderImpl(pPrevReader);
if (code != TSDB_CODE_SUCCESS) {
@ -3444,11 +3448,19 @@ void tsdbReaderClose(STsdbReader* pReader) {
{
if (pReader->innerReader[0] != NULL) {
pReader->innerReader[0]->status.pTableMap = NULL;
pReader->innerReader[0]->pReadSnap = NULL;
STsdbReader* p = pReader->innerReader[0];
pReader->innerReader[1]->status.pTableMap = NULL;
pReader->innerReader[1]->pReadSnap = NULL;
p->status.pTableMap = NULL;
p->pReadSnap = NULL;
p->pSchema = NULL;
p->pMemSchema = NULL;
p = pReader->innerReader[1];
p->status.pTableMap = NULL;
p->pReadSnap = NULL;
p->pSchema = NULL;
p->pMemSchema = NULL;
tsdbReaderClose(pReader->innerReader[0]);
tsdbReaderClose(pReader->innerReader[1]);
@ -3691,7 +3703,8 @@ static SArray* doRetrieveDataBlock(STsdbReader* pReader) {
STableBlockScanInfo* pBlockScanInfo = taosHashGet(pStatus->pTableMap, &pFBlock->uid, sizeof(pFBlock->uid));
tBlockDataReset(&pStatus->fileBlockData);
int32_t code = tBlockDataInit(&pStatus->fileBlockData, pReader->suid, pBlockScanInfo->uid, pReader->pSchema);
TABLEID tid = {.suid = pReader->suid, .uid = pBlockScanInfo->uid};
int32_t code = tBlockDataInit(&pStatus->fileBlockData, &tid, pReader->pSchema, NULL, 0);
if (code != TSDB_CODE_SUCCESS) {
terrno = code;
return NULL;

View File

@ -926,12 +926,13 @@ _err:
return code;
}
static int32_t tsdbReadBlockDataImpl(SDataFReader *pReader, SBlockInfo *pBlkInfo, SBlockData *pBlockData) {
static int32_t tsdbReadBlockDataImpl(SDataFReader *pReader, SBlockInfo *pBlkInfo, SBlockData *pBlockData,
int32_t iStt) {
int32_t code = 0;
tBlockDataClear(pBlockData);
STsdbFD *pFD = pReader->pDataFD;
STsdbFD *pFD = (iStt < 0) ? pReader->pDataFD : pReader->aSttFD[iStt];
// uid + version + tskey
code = tRealloc(&pReader->aBuf[0], pBlkInfo->szKey);
@ -1070,9 +1071,12 @@ _err:
int32_t tsdbReadDataBlock(SDataFReader *pReader, SDataBlk *pDataBlk, SBlockData *pBlockData) {
int32_t code = 0;
code = tsdbReadBlockDataImpl(pReader, &pDataBlk->aSubBlock[0], pBlockData);
code = tsdbReadBlockDataImpl(pReader, &pDataBlk->aSubBlock[0], pBlockData, -1);
if (code) goto _err;
ASSERT(pDataBlk->nSubBlock == 1);
#if 0
if (pDataBlk->nSubBlock > 1) {
SBlockData bData1;
SBlockData bData2;
@ -1113,6 +1117,7 @@ int32_t tsdbReadDataBlock(SDataFReader *pReader, SDataBlk *pDataBlk, SBlockData
tBlockDataDestroy(&bData1, 1);
tBlockDataDestroy(&bData2, 1);
}
#endif
return code;
@ -1123,23 +1128,38 @@ _err:
int32_t tsdbReadSttBlock(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData) {
int32_t code = 0;
int32_t lino = 0;
code = tsdbReadBlockDataImpl(pReader, &pSttBlk->bInfo, pBlockData, iStt);
TSDB_CHECK_CODE(code, lino, _exit);
_exit:
if (code) {
tsdbError("vgId:%d %s failed at %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code));
}
return code;
}
int32_t tsdbReadSttBlockEx(SDataFReader *pReader, int32_t iStt, SSttBlk *pSttBlk, SBlockData *pBlockData) {
int32_t code = 0;
int32_t lino = 0;
// alloc
code = tRealloc(&pReader->aBuf[0], pSttBlk->bInfo.szBlock);
if (code) goto _err;
TSDB_CHECK_CODE(code, lino, _exit);
// read
code = tsdbReadFile(pReader->aSttFD[iStt], pSttBlk->bInfo.offset, pReader->aBuf[0], pSttBlk->bInfo.szBlock);
if (code) goto _err;
TSDB_CHECK_CODE(code, lino, _exit);
// decmpr
code = tDecmprBlockData(pReader->aBuf[0], pSttBlk->bInfo.szBlock, pBlockData, &pReader->aBuf[1]);
if (code) goto _err;
TSDB_CHECK_CODE(code, lino, _exit);
return code;
_err:
tsdbError("vgId:%d tsdb read stt block failed since %s", TD_VID(pReader->pTsdb->pVnode), tstrerror(code));
_exit:
if (code) {
tsdbError("vgId:%d %s failed at %d since %s", TD_VID(pReader->pTsdb->pVnode), __func__, lino, tstrerror(code));
}
return code;
}

View File

@ -140,7 +140,7 @@ static int32_t tsdbSnapReadOpenFile(STsdbSnapReader* pReader) {
if (pSttBlk->minVer > pReader->ever) continue;
if (pSttBlk->maxVer < pReader->sver) continue;
code = tsdbReadSttBlock(pReader->pDataFReader, iStt, pSttBlk, &pIter->bData);
code = tsdbReadSttBlockEx(pReader->pDataFReader, iStt, pSttBlk, &pIter->bData);
if (code) goto _err;
for (pIter->iRow = 0; pIter->iRow < pIter->bData.nRow; pIter->iRow++) {
@ -223,7 +223,7 @@ static int32_t tsdbSnapNextRow(STsdbSnapReader* pReader) {
if (pSttBlk->minVer > pReader->ever || pSttBlk->maxVer < pReader->sver) continue;
code = tsdbReadSttBlock(pReader->pDataFReader, pIter->iStt, pSttBlk, &pIter->bData);
code = tsdbReadSttBlockEx(pReader->pDataFReader, pIter->iStt, pSttBlk, &pIter->bData);
if (code) goto _err;
pIter->iRow = -1;
@ -319,7 +319,7 @@ static int32_t tsdbSnapReadData(STsdbSnapReader* pReader, uint8_t** ppData) {
code = tsdbUpdateTableSchema(pTsdb->pVnode->pMeta, id.suid, id.uid, &pReader->skmTable);
if (code) goto _err;
code = tBlockDataInit(pBlockData, id.suid, id.uid, pReader->skmTable.pTSchema);
code = tBlockDataInit(pBlockData, &id, pReader->skmTable.pTSchema, NULL, 0);
if (code) goto _err;
while (pRowInfo->suid == id.suid && pRowInfo->uid == id.uid) {
@ -715,7 +715,7 @@ static int32_t tsdbSnapWriteTableDataStart(STsdbSnapWriter* pWriter, TABLEID* pI
if (code) goto _err;
tMapDataReset(&pWriter->dWriter.mDataBlk);
code = tBlockDataInit(&pWriter->dWriter.bData, pId->suid, pId->uid, pWriter->skmTable.pTSchema);
code = tBlockDataInit(&pWriter->dWriter.bData, pId, pWriter->skmTable.pTSchema, NULL, 0);
if (code) goto _err;
return code;
@ -1000,7 +1000,8 @@ static int32_t tsdbSnapWriteToSttFile(STsdbSnapWriter* pWriter, int32_t iRow) {
code = tsdbUpdateTableSchema(pWriter->pTsdb->pVnode->pMeta, pWriter->id.suid, pWriter->id.uid, &pWriter->skmTable);
if (code) goto _err;
code = tBlockDataInit(pBData, pWriter->id.suid, pWriter->id.suid ? 0 : pWriter->id.uid, pWriter->skmTable.pTSchema);
TABLEID tid = {.suid = pWriter->id.suid, .uid = pWriter->id.suid ? 0 : pWriter->id.uid};
code = tBlockDataInit(pBData, &tid, pWriter->skmTable.pTSchema, NULL, 0);
if (code) goto _err;
}

View File

@ -948,24 +948,47 @@ void tBlockDataDestroy(SBlockData *pBlockData, int8_t deepClear) {
pBlockData->aColData = NULL;
}
int32_t tBlockDataInit(SBlockData *pBlockData, int64_t suid, int64_t uid, STSchema *pTSchema) {
int32_t tBlockDataInit(SBlockData *pBlockData, TABLEID *pId, STSchema *pTSchema, int16_t *aCid, int32_t nCid) {
int32_t code = 0;
ASSERT(suid || uid);
ASSERT(pId->suid || pId->uid);
pBlockData->suid = suid;
pBlockData->uid = uid;
pBlockData->suid = pId->suid;
pBlockData->uid = pId->uid;
pBlockData->nRow = 0;
taosArrayClear(pBlockData->aIdx);
for (int32_t iColumn = 1; iColumn < pTSchema->numOfCols; iColumn++) {
if (aCid) {
int32_t iColumn = 1;
STColumn *pTColumn = &pTSchema->columns[iColumn];
for (int32_t iCid = 0; iCid < nCid; iCid++) {
while (pTColumn && pTColumn->colId < aCid[iCid]) {
iColumn++;
pTColumn = (iColumn < pTSchema->numOfCols) ? &pTSchema->columns[iColumn] : NULL;
}
SColData *pColData;
code = tBlockDataAddColData(pBlockData, iColumn - 1, &pColData);
if (code) goto _exit;
if (pTColumn == NULL) {
break;
} else if (pTColumn->colId == aCid[iCid]) {
SColData *pColData;
code = tBlockDataAddColData(pBlockData, taosArrayGetSize(pBlockData->aIdx), &pColData);
if (code) goto _exit;
tColDataInit(pColData, pTColumn->colId, pTColumn->type, (pTColumn->flags & COL_SMA_ON) ? 1 : 0);
tColDataInit(pColData, pTColumn->colId, pTColumn->type, (pTColumn->flags & COL_SMA_ON) ? 1 : 0);
iColumn++;
pTColumn = (iColumn < pTSchema->numOfCols) ? &pTSchema->columns[iColumn] : NULL;
}
}
} else {
for (int32_t iColumn = 1; iColumn < pTSchema->numOfCols; iColumn++) {
STColumn *pTColumn = &pTSchema->columns[iColumn];
SColData *pColData;
code = tBlockDataAddColData(pBlockData, iColumn - 1, &pColData);
if (code) goto _exit;
tColDataInit(pColData, pTColumn->colId, pTColumn->type, (pTColumn->flags & COL_SMA_ON) ? 1 : 0);
}
}
_exit:

View File

@ -688,6 +688,8 @@ static void vnodeRestoreFinish(struct SSyncFSM *pFsm) {
}
} while (true);
walApplyVer(pVnode->pWal, pVnode->state.applied);
pVnode->restored = true;
vDebug("vgId:%d, sync restore finished", pVnode->config.vgId);
}

View File

@ -991,7 +991,7 @@ SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SStateWi
SOperatorInfo* createPartitionOperatorInfo(SOperatorInfo* downstream, SPartitionPhysiNode* pPartNode,
SExecTaskInfo* pTaskInfo);
SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SPartitionPhysiNode* pPartNode,
SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStreamPartitionPhysiNode* pPartNode,
SExecTaskInfo* pTaskInfo);
SOperatorInfo* createTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pNode, SExecTaskInfo* pTaskInfo);

View File

@ -1110,7 +1110,8 @@ void setResultRowInitCtx(SResultRow* pResult, SqlFunctionCtx* pCtx, int32_t numO
}
}
static void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const SColumnInfoData* p, bool keep, int32_t status);
static void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const SColumnInfoData* p, bool keep,
int32_t status);
void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock, const SArray* pColMatchInfo, SFilterInfo* pFilterInfo) {
if (pFilterNode == NULL || pBlock->info.rows == 0) {
@ -1133,7 +1134,7 @@ void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock, const SArray* pColM
code = filterSetDataFromSlotId(filter, &param1);
SColumnInfoData* p = NULL;
int32_t status = 0;
int32_t status = 0;
// todo the keep seems never to be True??
bool keep = filterExecute(filter, pBlock, &p, NULL, param1.numOfCols, &status);
@ -1209,7 +1210,7 @@ void extractQualifiedTupleByFilterResult(SSDataBlock* pBlock, const SColumnInfoD
}
}
void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, int32_t numOfOutput, uint64_t groupId) {
void doSetTableGroupOutputBuf(SOperatorInfo* pOperator, int32_t numOfOutput, uint64_t groupId) {
// for simple group by query without interval, all the tables belong to one group result.
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SAggOperatorInfo* pAggInfo = pOperator->info;
@ -1795,7 +1796,9 @@ static int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInf
if (pSource->localExec) {
SDataBuf pBuf = {0};
int32_t code = (*pTaskInfo->localFetch.fp)(pTaskInfo->localFetch.handle, pSource->schedId, pTaskInfo->id.queryId, pSource->taskId, 0, pSource->execId, &pBuf.pData, pTaskInfo->localFetch.explainRes);
int32_t code =
(*pTaskInfo->localFetch.fp)(pTaskInfo->localFetch.handle, pSource->schedId, pTaskInfo->id.queryId,
pSource->taskId, 0, pSource->execId, &pBuf.pData, pTaskInfo->localFetch.explainRes);
loadRemoteDataCallback(pWrapper, &pBuf, code);
taosMemoryFree(pWrapper);
} else {
@ -1806,8 +1809,8 @@ static int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInf
}
qDebug("%s build fetch msg and send to vgId:%d, ep:%s, taskId:0x%" PRIx64 ", execId:%d, %d/%" PRIzu,
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->addr.epSet.eps[0].fqdn, pSource->taskId, pSource->execId,
sourceIndex, totalSources);
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->addr.epSet.eps[0].fqdn, pSource->taskId,
pSource->execId, sourceIndex, totalSources);
pMsg->header.vgId = htonl(pSource->addr.nodeId);
pMsg->sId = htobe64(pSource->schedId);
@ -1832,7 +1835,8 @@ static int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInf
pMsgSendInfo->fp = loadRemoteDataCallback;
int64_t transporterId = 0;
int32_t code = asyncSendMsgToServer(pExchangeInfo->pTransporter, &pSource->addr.epSet, &transporterId, pMsgSendInfo);
int32_t code =
asyncSendMsgToServer(pExchangeInfo->pTransporter, &pSource->addr.epSet, &transporterId, pMsgSendInfo);
}
return TSDB_CODE_SUCCESS;
@ -3364,9 +3368,7 @@ static void cleanupTableSchemaInfo(SSchemaInfo* pSchemaInfo) {
tDeleteSSchemaWrapper(pSchemaInfo->qsw);
}
static void cleanupStreamInfo(SStreamTaskInfo* pStreamInfo) {
tDeleteSSchemaWrapper(pStreamInfo->schema);
}
static void cleanupStreamInfo(SStreamTaskInfo* pStreamInfo) { tDeleteSSchemaWrapper(pStreamInfo->schema); }
static int32_t sortTableGroup(STableListInfo* pTableListInfo) {
taosArrayClear(pTableListInfo->pGroupList);
@ -3547,7 +3549,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
STableScanInfo* pScanInfo = pOperator->info;
pTaskInfo->cost.pRecoder = &pScanInfo->readRecorder;
} else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) {
pOperator = createExchangeOperatorInfo(pHandle ? pHandle->pMsgCb->clientRpc : NULL, (SExchangePhysiNode*)pPhyNode, pTaskInfo);
pOperator = createExchangeOperatorInfo(pHandle ? pHandle->pMsgCb->clientRpc : NULL, (SExchangePhysiNode*)pPhyNode,
pTaskInfo);
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) {
STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode;
if (pHandle->vnode) {
@ -3737,7 +3740,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo
} else if (QUERY_NODE_PHYSICAL_PLAN_PARTITION == type) {
pOptr = createPartitionOperatorInfo(ops[0], (SPartitionPhysiNode*)pPhyNode, pTaskInfo);
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION == type) {
pOptr = createStreamPartitionOperatorInfo(ops[0], (SPartitionPhysiNode*)pPhyNode, pTaskInfo);
pOptr = createStreamPartitionOperatorInfo(ops[0], (SStreamPartitionPhysiNode*)pPhyNode, pTaskInfo);
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_STATE == type) {
SStateWinodwPhysiNode* pStateNode = (SStateWinodwPhysiNode*)pPhyNode;
pOptr = createStatewindowOperatorInfo(ops[0], pStateNode, pTaskInfo);

View File

@ -989,11 +989,11 @@ SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStr
goto _error;
}
int32_t code = TSDB_CODE_SUCCESS;
pInfo->partitionSup.pGroupCols = extractPartitionColInfo(pPartNode->pPartitionKeys);
pInfo->partitionSup.pGroupCols = extractPartitionColInfo(pPartNode->part.pPartitionKeys);
if (pPartNode->pExprs != NULL) {
if (pPartNode->part.pExprs != NULL) {
int32_t num = 0;
SExprInfo* pCalExprInfo = createExprInfo(pPartNode->pExprs, NULL, &num);
SExprInfo* pCalExprInfo = createExprInfo(pPartNode->part.pExprs, NULL, &num);
code = initExprSupp(&pInfo->scalarSup, pCalExprInfo, num);
if (code != TSDB_CODE_SUCCESS) {
goto _error;
@ -1008,7 +1008,7 @@ SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStr
}
pInfo->partitionSup.needCalc = true;
SSDataBlock* pResBlock = createResDataBlock(pPartNode->node.pOutputDataBlockDesc);
SSDataBlock* pResBlock = createResDataBlock(pPartNode->part.node.pOutputDataBlockDesc);
if (!pResBlock) {
goto _error;
}
@ -1022,7 +1022,7 @@ SOperatorInfo* createStreamPartitionOperatorInfo(SOperatorInfo* downstream, SStr
pInfo->pDelRes = createSpecialDataBlock(STREAM_DELETE_RESULT);
int32_t numOfCols = 0;
SExprInfo* pExprInfo = createExprInfo(pPartNode->pTargets, NULL, &numOfCols);
SExprInfo* pExprInfo = createExprInfo(pPartNode->part.pTargets, NULL, &numOfCols);
pOperator->name = "StreamPartitionOperator";
pOperator->blocking = false;

View File

@ -50,6 +50,7 @@ extern "C" {
#define FUNC_MGT_KEEP_ORDER_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(21)
#define FUNC_MGT_CUMULATIVE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(22)
#define FUNC_MGT_FORBID_STABLE_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(23)
#define FUNC_MGT_INTERP_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(24)
#define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0)

View File

@ -3146,6 +3146,16 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.classification = FUNC_MGT_SYSTEM_INFO_FUNC | FUNC_MGT_SCALAR_FUNC,
.translateFunc = translateUserFunc,
},
{
.name = "_irowts",
.type = FUNCTION_TYPE_IROWTS,
.classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_INTERP_PC_FUNC,
.translateFunc = translateTimePseudoColumn,
.getEnvFunc = getTimePseudoFuncEnv,
.initFunc = NULL,
.sprocessFunc = NULL,
.finalizeFunc = NULL
},
};
// clang-format on

View File

@ -2977,10 +2977,9 @@ int32_t lastFunction(SqlFunctionCtx* pCtx) {
return TSDB_CODE_SUCCESS;
}
static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst) {
static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, SFirstLastRes* pOutput, bool isFirst, int32_t rowIndex) {
SInputColumnInfoData* pColInfo = &pCtx->input;
int32_t start = pColInfo->startRowIndex;
if (pOutput->hasResult) {
if (isFirst) {
if (pInput->ts > pOutput->ts) {
@ -2998,7 +2997,7 @@ static void firstLastTransferInfo(SqlFunctionCtx* pCtx, SFirstLastRes* pInput, S
pOutput->bytes = pInput->bytes;
memcpy(pOutput->buf, pInput->buf, pOutput->bytes);
firstlastSaveTupleData(pCtx->pSrcBlock, start, pCtx, pOutput);
firstlastSaveTupleData(pCtx->pSrcBlock, rowIndex, pCtx, pOutput);
pOutput->hasResult = true;
}
@ -3016,7 +3015,7 @@ static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuer
for (int32_t i = start; i < start + pInput->numOfRows; ++i) {
char* data = colDataGetData(pCol, i);
SFirstLastRes* pInputInfo = (SFirstLastRes*)varDataVal(data);
firstLastTransferInfo(pCtx, pInputInfo, pInfo, isFirstQuery);
firstLastTransferInfo(pCtx, pInputInfo, pInfo, isFirstQuery, i);
if (!numOfElems) {
numOfElems = pInputInfo->hasResult ? 1 : 0;
}

View File

@ -224,6 +224,8 @@ bool fmIsInterpFunc(int32_t funcId) {
return FUNCTION_TYPE_INTERP == funcMgtBuiltins[funcId].type;
}
bool fmIsInterpPseudoColumnFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_INTERP_PC_FUNC); }
bool fmIsLastRowFunc(int32_t funcId) {
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
return false;

View File

@ -381,6 +381,8 @@ static int32_t logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
COPY_SCALAR_FIELD(igExpired);
CLONE_NODE_LIST_FIELD(pGroupTags);
COPY_SCALAR_FIELD(groupSort);
CLONE_NODE_LIST_FIELD(pTags);
CLONE_NODE_FIELD(pSubtable);
return TSDB_CODE_SUCCESS;
}
@ -488,6 +490,8 @@ static int32_t logicSortCopy(const SSortLogicNode* pSrc, SSortLogicNode* pDst) {
static int32_t logicPartitionCopy(const SPartitionLogicNode* pSrc, SPartitionLogicNode* pDst) {
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
CLONE_NODE_LIST_FIELD(pPartitionKeys);
CLONE_NODE_LIST_FIELD(pTags);
CLONE_NODE_FIELD(pSubtable);
return TSDB_CODE_SUCCESS;
}

View File

@ -1538,6 +1538,8 @@ static const char* jkTableScanPhysiPlanWatermark = "Watermark";
static const char* jkTableScanPhysiPlanIgnoreExpired = "IgnoreExpired";
static const char* jkTableScanPhysiPlanGroupTags = "GroupTags";
static const char* jkTableScanPhysiPlanGroupSort = "GroupSort";
static const char* jkTableScanPhysiPlanTags = "Tags";
static const char* jkTableScanPhysiPlanSubtable = "Subtable";
static const char* jkTableScanPhysiPlanAssignBlockUid = "AssignBlockUid";
static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
@ -1595,6 +1597,12 @@ static int32_t physiTableScanNodeToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkTableScanPhysiPlanGroupSort, pNode->groupSort);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkTableScanPhysiPlanTags, pNode->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkTableScanPhysiPlanSubtable, nodeToJson, pNode->pSubtable);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkTableScanPhysiPlanAssignBlockUid, pNode->assignBlockUid);
}
@ -1657,6 +1665,12 @@ static int32_t jsonToPhysiTableScanNode(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkTableScanPhysiPlanGroupSort, &pNode->groupSort);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkTableScanPhysiPlanTags, &pNode->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkTableScanPhysiPlanSubtable, &pNode->pSubtable);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkTableScanPhysiPlanAssignBlockUid, &pNode->assignBlockUid);
}
@ -2270,6 +2284,37 @@ static int32_t jsonToPhysiPartitionNode(const SJson* pJson, void* pObj) {
return code;
}
static const char* jkStreamPartitionPhysiPlanTags = "Tags";
static const char* jkStreamPartitionPhysiPlanSubtable = "Subtable";
static int32_t physiStreamPartitionNodeToJson(const void* pObj, SJson* pJson) {
const SStreamPartitionPhysiNode* pNode = (const SStreamPartitionPhysiNode*)pObj;
int32_t code = physiPartitionNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkStreamPartitionPhysiPlanTags, pNode->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkStreamPartitionPhysiPlanSubtable, nodeToJson, pNode->pSubtable);
}
return code;
}
static int32_t jsonToPhysiStreamPartitionNode(const SJson* pJson, void* pObj) {
SStreamPartitionPhysiNode* pNode = (SStreamPartitionPhysiNode*)pObj;
int32_t code = jsonToPhysiPartitionNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkStreamPartitionPhysiPlanTags, &pNode->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkStreamPartitionPhysiPlanSubtable, &pNode->pSubtable);
}
return code;
}
static const char* jkIndefRowsFuncPhysiPlanExprs = "Exprs";
static const char* jkIndefRowsFuncPhysiPlanFuncs = "Funcs";
@ -4109,6 +4154,8 @@ static const char* jkSelectStmtProjections = "Projections";
static const char* jkSelectStmtFrom = "From";
static const char* jkSelectStmtWhere = "Where";
static const char* jkSelectStmtPartitionBy = "PartitionBy";
static const char* jkSelectStmtTags = "Tags";
static const char* jkSelectStmtSubtable = "Subtable";
static const char* jkSelectStmtWindow = "Window";
static const char* jkSelectStmtGroupBy = "GroupBy";
static const char* jkSelectStmtHaving = "Having";
@ -4134,6 +4181,12 @@ static int32_t selectStmtToJson(const void* pObj, SJson* pJson) {
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkSelectStmtPartitionBy, pNode->pPartitionByList);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkSelectStmtTags, pNode->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkSelectStmtSubtable, nodeToJson, pNode->pSubtable);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkSelectStmtWindow, nodeToJson, pNode->pWindow);
}
@ -4178,6 +4231,12 @@ static int32_t jsonToSelectStmt(const SJson* pJson, void* pObj) {
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkSelectStmtPartitionBy, &pNode->pPartitionByList);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkSelectStmtTags, &pNode->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkSelectStmtSubtable, &pNode->pSubtable);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeObject(pJson, jkSelectStmtWindow, &pNode->pWindow);
}
@ -4586,8 +4645,9 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE:
return physiStateWindowNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
return physiPartitionNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
return physiStreamPartitionNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
return physiIndefRowsFuncNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:
@ -4738,8 +4798,9 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
case QUERY_NODE_PHYSICAL_PLAN_STREAM_STATE:
return jsonToPhysiStateWindowNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
return jsonToPhysiPartitionNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
return jsonToPhysiStreamPartitionNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
return jsonToPhysiIndefRowsFuncNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC:

View File

@ -1993,7 +1993,9 @@ enum {
PHY_TABLE_SCAN_CODE_SCAN = 1,
PHY_TABLE_SCAN_CODE_INLINE_ATTRS,
PHY_TABLE_SCAN_CODE_DYN_SCAN_FUNCS,
PHY_TABLE_SCAN_CODE_GROUP_TAGS
PHY_TABLE_SCAN_CODE_GROUP_TAGS,
PHY_TABLE_SCAN_CODE_TAGS,
PHY_TABLE_SCAN_CODE_SUBTABLE
};
static int32_t physiTableScanNodeInlineToMsg(const void* pObj, STlvEncoder* pEncoder) {
@ -2062,6 +2064,12 @@ static int32_t physiTableScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder)
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_TABLE_SCAN_CODE_GROUP_TAGS, nodeListToMsg, pNode->pGroupTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_TABLE_SCAN_CODE_TAGS, nodeListToMsg, pNode->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_TABLE_SCAN_CODE_SUBTABLE, nodeToMsg, pNode->pSubtable);
}
return code;
}
@ -2138,6 +2146,12 @@ static int32_t msgToPhysiTableScanNode(STlvDecoder* pDecoder, void* pObj) {
case PHY_TABLE_SCAN_CODE_GROUP_TAGS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pGroupTags);
break;
case PHY_TABLE_SCAN_CODE_TAGS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTags);
break;
case PHY_TABLE_SCAN_CODE_SUBTABLE:
code = msgToNodeFromTlv(pTlv, (void**)&pNode->pSubtable);
break;
default:
break;
}
@ -2914,6 +2928,46 @@ static int32_t msgToPhysiPartitionNode(STlvDecoder* pDecoder, void* pObj) {
return code;
}
enum { PHY_STREAM_PARTITION_CODE_BASE_NODE = 1, PHY_STREAM_PARTITION_CODE_TAGS, PHY_STREAM_PARTITION_CODE_SUBTABLE };
static int32_t physiStreamPartitionNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
const SStreamPartitionPhysiNode* pNode = (const SStreamPartitionPhysiNode*)pObj;
int32_t code = tlvEncodeObj(pEncoder, PHY_STREAM_PARTITION_CODE_BASE_NODE, physiPartitionNodeToMsg, &pNode->part);
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_STREAM_PARTITION_CODE_TAGS, nodeListToMsg, pNode->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_STREAM_PARTITION_CODE_SUBTABLE, nodeToMsg, pNode->pSubtable);
}
return code;
}
static int32_t msgToPhysiStreamPartitionNode(STlvDecoder* pDecoder, void* pObj) {
SStreamPartitionPhysiNode* pNode = (SStreamPartitionPhysiNode*)pObj;
int32_t code = TSDB_CODE_SUCCESS;
STlv* pTlv = NULL;
tlvForEach(pDecoder, pTlv, code) {
switch (pTlv->type) {
case PHY_STREAM_PARTITION_CODE_BASE_NODE:
code = tlvDecodeObjFromTlv(pTlv, msgToPhysiPartitionNode, &pNode->part);
break;
case PHY_STREAM_PARTITION_CODE_TAGS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTags);
break;
case PHY_STREAM_PARTITION_CODE_SUBTABLE:
code = msgToNodeFromTlv(pTlv, (void**)&pNode->pSubtable);
break;
default:
break;
}
}
return code;
}
enum { PHY_INDEF_ROWS_FUNC_CODE_BASE_NODE = 1, PHY_INDEF_ROWS_FUNC_CODE_EXPRS, PHY_INDEF_ROWS_FUNC_CODE_FUNCS };
static int32_t physiIndefRowsFuncNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
@ -3592,9 +3646,11 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
code = physiStateWindowNodeToMsg(pObj, pEncoder);
break;
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
code = physiPartitionNodeToMsg(pObj, pEncoder);
break;
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
code = physiStreamPartitionNodeToMsg(pObj, pEncoder);
break;
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
code = physiIndefRowsFuncNodeToMsg(pObj, pEncoder);
break;
@ -3727,9 +3783,11 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) {
code = msgToPhysiStateWindowNode(pDecoder, pObj);
break;
case QUERY_NODE_PHYSICAL_PLAN_PARTITION:
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
code = msgToPhysiPartitionNode(pDecoder, pObj);
break;
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
code = msgToPhysiStreamPartitionNode(pDecoder, pObj);
break;
case QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC:
code = msgToPhysiIndefRowsFuncNode(pDecoder, pObj);
break;

View File

@ -378,6 +378,8 @@ void nodesWalkSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeWalker wa
nodesWalkExpr(pSelect->pWhere, walker, pContext);
case SQL_CLAUSE_WHERE:
nodesWalkExprs(pSelect->pPartitionByList, walker, pContext);
nodesWalkExprs(pSelect->pTags, walker, pContext);
nodesWalkExpr(pSelect->pSubtable, walker, pContext);
case SQL_CLAUSE_PARTITION_BY:
nodesWalkExpr(pSelect->pWindow, walker, pContext);
case SQL_CLAUSE_WINDOW:
@ -412,6 +414,8 @@ void nodesRewriteSelectStmt(SSelectStmt* pSelect, ESqlClause clause, FNodeRewrit
nodesRewriteExpr(&(pSelect->pWhere), rewriter, pContext);
case SQL_CLAUSE_WHERE:
nodesRewriteExprs(pSelect->pPartitionByList, rewriter, pContext);
nodesRewriteExprs(pSelect->pTags, rewriter, pContext);
nodesRewriteExpr(&(pSelect->pSubtable), rewriter, pContext);
case SQL_CLAUSE_PARTITION_BY:
nodesRewriteExpr(&(pSelect->pWindow), rewriter, pContext);
case SQL_CLAUSE_WINDOW:

View File

@ -772,6 +772,8 @@ void nodesDestroyNode(SNode* pNode) {
nodesDestroyNode(pStmt->pFromTable);
nodesDestroyNode(pStmt->pWhere);
nodesDestroyList(pStmt->pPartitionByList);
nodesDestroyList(pStmt->pTags);
nodesDestroyNode(pStmt->pSubtable);
nodesDestroyNode(pStmt->pWindow);
nodesDestroyList(pStmt->pGroupByList);
nodesDestroyNode(pStmt->pHaving);

View File

@ -147,7 +147,7 @@ SNode* createCreateDatabaseStmt(SAstCreateContext* pCxt, bool ignoreExists, STok
SNode* createDropDatabaseStmt(SAstCreateContext* pCxt, bool ignoreNotExists, SToken* pDbName);
SNode* createAlterDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName, SNode* pOptions);
SNode* createFlushDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName);
SNode* createTrimDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName);
SNode* createTrimDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName, int32_t maxSpeed);
SNode* createDefaultTableOptions(SAstCreateContext* pCxt);
SNode* createAlterTableOptions(SAstCreateContext* pCxt);
SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, void* pVal);
@ -212,7 +212,7 @@ SNode* createCreateFunctionStmt(SAstCreateContext* pCxt, bool ignoreExists, bool
SNode* createDropFunctionStmt(SAstCreateContext* pCxt, bool ignoreNotExists, const SToken* pFuncName);
SNode* createStreamOptions(SAstCreateContext* pCxt);
SNode* createCreateStreamStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pStreamName, SNode* pRealTable,
SNode* pOptions, SNode* pQuery);
SNode* pOptions, SNodeList* pTags, SNode* pSubtable, SNode* pQuery);
SNode* createDropStreamStmt(SAstCreateContext* pCxt, bool ignoreNotExists, const SToken* pStreamName);
SNode* createKillStmt(SAstCreateContext* pCxt, ENodeType type, const SToken* pId);
SNode* createKillQueryStmt(SAstCreateContext* pCxt, const SToken* pQueryId);

View File

@ -159,7 +159,7 @@ cmd ::= DROP DATABASE exists_opt(A) db_name(B).
cmd ::= USE db_name(A). { pCxt->pRootNode = createUseDatabaseStmt(pCxt, &A); }
cmd ::= ALTER DATABASE db_name(A) alter_db_options(B). { pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &A, B); }
cmd ::= FLUSH DATABASE db_name(A). { pCxt->pRootNode = createFlushDatabaseStmt(pCxt, &A); }
cmd ::= TRIM DATABASE db_name(A). { pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &A); }
cmd ::= TRIM DATABASE db_name(A) speed_opt(B). { pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &A, B); }
%type not_exists_opt { bool }
%destructor not_exists_opt { }
@ -246,6 +246,11 @@ retention_list(A) ::= retention_list(B) NK_COMMA retention(C).
retention(A) ::= NK_VARIABLE(B) NK_COLON NK_VARIABLE(C). { A = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &B), createDurationValueNode(pCxt, &C)); }
%type speed_opt { int32_t }
%destructor speed_opt { }
speed_opt(A) ::= . { A = 0; }
speed_opt(A) ::= MAX_SPEED NK_INTEGER(B). { A = taosStr2Int32(B.z, NULL, 10); }
/************************************************ create/drop table/stable ********************************************/
cmd ::= CREATE TABLE not_exists_opt(A) full_table_name(B)
NK_LP column_def_list(C) NK_RP tags_def_opt(D) table_options(E). { pCxt->pRootNode = createCreateTableStmt(pCxt, A, B, C, D, E); }
@ -501,8 +506,8 @@ bufsize_opt(A) ::= .
bufsize_opt(A) ::= BUFSIZE NK_INTEGER(B). { A = taosStr2Int32(B.z, NULL, 10); }
/************************************************ create/drop stream **************************************************/
cmd ::= CREATE STREAM not_exists_opt(E) stream_name(A)
stream_options(B) INTO full_table_name(C) AS query_or_subquery(D). { pCxt->pRootNode = createCreateStreamStmt(pCxt, E, &A, C, B, D); }
cmd ::= CREATE STREAM not_exists_opt(E) stream_name(A) stream_options(B) INTO
full_table_name(C) tags_def_opt(F) subtable_opt(G) AS query_or_subquery(D). { pCxt->pRootNode = createCreateStreamStmt(pCxt, E, &A, C, B, F, G, D); }
cmd ::= DROP STREAM exists_opt(A) stream_name(B). { pCxt->pRootNode = createDropStreamStmt(pCxt, A, &B); }
stream_options(A) ::= . { A = createStreamOptions(pCxt); }
@ -512,6 +517,9 @@ stream_options(A) ::= stream_options(B) TRIGGER MAX_DELAY duration_literal(C).
stream_options(A) ::= stream_options(B) WATERMARK duration_literal(C). { ((SStreamOptions*)B)->pWatermark = releaseRawExprNode(pCxt, C); A = B; }
stream_options(A) ::= stream_options(B) IGNORE EXPIRED NK_INTEGER(C). { ((SStreamOptions*)B)->ignoreExpired = taosStr2Int8(C.z, NULL, 10); A = B; }
subtable_opt(A) ::= . { A = NULL; }
subtable_opt(A) ::= SUBTABLE NK_LP expression(B) NK_RP. { A = releaseRawExprNode(pCxt, B); }
/************************************************ kill connection/query ***********************************************/
cmd ::= KILL CONNECTION NK_INTEGER(A). { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_CONNECTION_STMT, &A); }
cmd ::= KILL QUERY NK_STRING(A). { pCxt->pRootNode = createKillQueryStmt(pCxt, &A); }
@ -699,6 +707,7 @@ pseudo_column(A) ::= QDURATION(B).
pseudo_column(A) ::= WSTART(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
pseudo_column(A) ::= WEND(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
pseudo_column(A) ::= WDURATION(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
pseudo_column(A) ::= IROWTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); }
function_expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
function_expression(A) ::= star_func(B) NK_LP star_func_para_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); }
@ -909,7 +918,16 @@ where_clause_opt(A) ::= WHERE search_condition(B).
%type partition_by_clause_opt { SNodeList* }
%destructor partition_by_clause_opt { nodesDestroyList($$); }
partition_by_clause_opt(A) ::= . { A = NULL; }
partition_by_clause_opt(A) ::= PARTITION BY expression_list(B). { A = B; }
partition_by_clause_opt(A) ::= PARTITION BY partition_list(B). { A = B; }
%type partition_list { SNodeList* }
%destructor partition_list { nodesDestroyList($$); }
partition_list(A) ::= partition_item(B). { A = createNodeList(pCxt, B); }
partition_list(A) ::= partition_list(B) NK_COMMA partition_item(C). { A = addNodeToList(pCxt, B, C); }
partition_item(A) ::= expr_or_subquery(B). { A = releaseRawExprNode(pCxt, B); }
partition_item(A) ::= expr_or_subquery(B) column_alias(C). { A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &C); }
partition_item(A) ::= expr_or_subquery(B) AS column_alias(C). { A = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, B), &C); }
twindow_clause_opt(A) ::= . { A = NULL; }
twindow_clause_opt(A) ::=

View File

@ -1055,7 +1055,7 @@ SNode* createFlushDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) {
return (SNode*)pStmt;
}
SNode* createTrimDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) {
SNode* createTrimDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName, int32_t maxSpeed) {
CHECK_PARSER_STATUS(pCxt);
if (!checkDbName(pCxt, pDbName, false)) {
return NULL;
@ -1063,6 +1063,7 @@ SNode* createTrimDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) {
STrimDatabaseStmt* pStmt = (STrimDatabaseStmt*)nodesMakeNode(QUERY_NODE_TRIM_DATABASE_STMT);
CHECK_OUT_OF_MEM(pStmt);
COPY_STRING_FORM_ID_TOKEN(pStmt->dbName, pDbName);
pStmt->maxSpeed = maxSpeed;
return (SNode*)pStmt;
}
@ -1700,7 +1701,7 @@ SNode* createStreamOptions(SAstCreateContext* pCxt) {
}
SNode* createCreateStreamStmt(SAstCreateContext* pCxt, bool ignoreExists, const SToken* pStreamName, SNode* pRealTable,
SNode* pOptions, SNode* pQuery) {
SNode* pOptions, SNodeList* pTags, SNode* pSubtable, SNode* pQuery) {
CHECK_PARSER_STATUS(pCxt);
SCreateStreamStmt* pStmt = (SCreateStreamStmt*)nodesMakeNode(QUERY_NODE_CREATE_STREAM_STMT);
CHECK_OUT_OF_MEM(pStmt);
@ -1713,6 +1714,8 @@ SNode* createCreateStreamStmt(SAstCreateContext* pCxt, bool ignoreExists, const
pStmt->ignoreExists = ignoreExists;
pStmt->pOptions = (SStreamOptions*)pOptions;
pStmt->pQuery = pQuery;
pStmt->pTags = pTags;
pStmt->pSubtable = pSubtable;
return (SNode*)pStmt;
}

View File

@ -275,6 +275,12 @@ static int32_t calcConstSelectFrom(SCalcConstContext* pCxt, SSelectStmt* pSelect
if (TSDB_CODE_SUCCESS == code) {
code = calcConstList(pSelect->pPartitionByList);
}
if (TSDB_CODE_SUCCESS == code) {
code = calcConstList(pSelect->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = calcConstNode(&pSelect->pSubtable);
}
if (TSDB_CODE_SUCCESS == code) {
code = calcConstNode(&pSelect->pWindow);
}

View File

@ -129,6 +129,7 @@ static SKeyword keywordTable[] = {
{"MATCH", TK_MATCH},
{"MAXROWS", TK_MAXROWS},
{"MAX_DELAY", TK_MAX_DELAY},
{"MAX_SPEED", TK_MAX_SPEED},
{"MERGE", TK_MERGE},
{"META", TK_META},
{"MINROWS", TK_MINROWS},
@ -200,6 +201,7 @@ static SKeyword keywordTable[] = {
{"STREAMS", TK_STREAMS},
{"STRICT", TK_STRICT},
{"SUBSCRIPTIONS", TK_SUBSCRIPTIONS},
{"SUBTABLE", TK_SUBTABLE},
{"SYSINFO", TK_SYSINFO},
{"TABLE", TK_TABLE},
{"TABLES", TK_TABLES},
@ -250,6 +252,7 @@ static SKeyword keywordTable[] = {
{"WITH", TK_WITH},
{"WRITE", TK_WRITE},
{"_C0", TK_ROWTS},
{"_IROWTS", TK_IROWTS},
{"_QDURATION", TK_QDURATION},
{"_QEND", TK_QEND},
{"_QSTART", TK_QSTART},

View File

@ -1556,6 +1556,9 @@ static int32_t translateMultiResFunc(STranslateContext* pCxt, SFunctionNode* pFu
"%s(*) is only supported in SELECTed list", pFunc->functionName);
}
}
if (tsKeepColumnName) {
strcpy(pFunc->node.userAlias, ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->userAlias);
}
return TSDB_CODE_SUCCESS;
}
@ -2388,8 +2391,12 @@ static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) {
SColumnNode* pCol = (SColumnNode*)pExpr;
len = snprintf(buf, sizeof(buf), "%s(%s.%s)", pSrcFunc->functionName, pCol->tableAlias, pCol->colName);
strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1));
len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pCol->colName);
strncpy(pFunc->node.userAlias, buf, TMIN(len, sizeof(pFunc->node.userAlias) - 1));
if (tsKeepColumnName) {
strcpy(pFunc->node.userAlias, pCol->colName);
} else {
len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pCol->colName);
strncpy(pFunc->node.userAlias, buf, TMIN(len, sizeof(pFunc->node.userAlias) - 1));
}
} else {
len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pExpr->aliasName);
strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1));
@ -3076,7 +3083,14 @@ static int32_t translatePartitionBy(STranslateContext* pCxt, SSelectStmt* pSelec
return TSDB_CODE_SUCCESS;
}
pCxt->currClause = SQL_CLAUSE_PARTITION_BY;
return translateExprList(pCxt, pSelect->pPartitionByList);
int32_t code = translateExprList(pCxt, pSelect->pPartitionByList);
if (TSDB_CODE_SUCCESS == code) {
code = translateExprList(pCxt, pSelect->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = translateExpr(pCxt, &pSelect->pSubtable);
}
return code;
}
static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) {
@ -3968,7 +3982,7 @@ static int32_t translateAlterDatabase(STranslateContext* pCxt, SAlterDatabaseStm
}
static int32_t translateTrimDatabase(STranslateContext* pCxt, STrimDatabaseStmt* pStmt) {
STrimDbReq req = {0};
STrimDbReq req = {.maxSpeed = pStmt->maxSpeed};
SName name = {0};
tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName));
tNameGetFullDbName(&name, req.db);
@ -5211,6 +5225,93 @@ static int32_t addWstartTsToCreateStreamQuery(SNode* pStmt) {
return code;
}
static int32_t addTagsToCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt, SSelectStmt* pSelect) {
if (NULL == pStmt->pTags) {
return TSDB_CODE_SUCCESS;
}
SNode* pTag = NULL;
FOREACH(pTag, pStmt->pTags) {
bool found = false;
SNode* pPart = NULL;
FOREACH(pPart, pSelect->pPartitionByList) {
if (0 == strcmp(((SColumnDefNode*)pTag)->colName, ((SExprNode*)pPart)->userAlias)) {
if (TSDB_CODE_SUCCESS != nodesListMakeStrictAppend(&pSelect->pTags, nodesCloneNode(pPart))) {
return TSDB_CODE_OUT_OF_MEMORY;
}
found = true;
break;
}
}
if (!found) {
return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_INVALID_COLUMN, ((SColumnDefNode*)pTag)->colName);
}
}
return TSDB_CODE_SUCCESS;
}
typedef struct SRewriteSubtableCxt {
STranslateContext* pCxt;
SNodeList* pPartitionList;
} SRewriteSubtableCxt;
static EDealRes rewriteSubtable(SNode** pNode, void* pContext) {
if (QUERY_NODE_COLUMN == nodeType(*pNode)) {
SRewriteSubtableCxt* pCxt = pContext;
bool found = false;
SNode* pPart = NULL;
FOREACH(pPart, pCxt->pPartitionList) {
if (0 == strcmp(((SColumnNode*)*pNode)->colName, ((SExprNode*)pPart)->userAlias)) {
SNode* pNew = nodesCloneNode(pPart);
if (NULL == pNew) {
pCxt->pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY;
return DEAL_RES_ERROR;
}
nodesDestroyNode(*pNode);
*pNode = pNew;
found = true;
break;
}
if (!found) {
return generateDealNodeErrMsg(pCxt->pCxt, TSDB_CODE_PAR_INVALID_COLUMN, ((SColumnNode*)*pNode)->colName);
}
}
return DEAL_RES_IGNORE_CHILD;
}
return DEAL_RES_CONTINUE;
}
static int32_t addSubtableNameToCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt,
SSelectStmt* pSelect) {
if (NULL == pStmt->pSubtable) {
return TSDB_CODE_SUCCESS;
}
pSelect->pSubtable = nodesCloneNode(pStmt->pSubtable);
if (NULL == pSelect->pSubtable) {
return TSDB_CODE_OUT_OF_MEMORY;
}
SRewriteSubtableCxt cxt = {.pCxt = pCxt, .pPartitionList = pSelect->pPartitionByList};
nodesRewriteExpr(&pSelect->pSubtable, rewriteSubtable, &cxt);
return pCxt->errCode;
}
static int32_t addSubtableInfoToCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt) {
SSelectStmt* pSelect = (SSelectStmt*)pStmt->pQuery;
if (NULL == pSelect->pPartitionByList) {
if (NULL != pStmt->pTags || NULL != pStmt->pSubtable) {
return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_STREAM_QUERY, "Unsupported stream query");
}
return TSDB_CODE_SUCCESS;
}
int32_t code = addTagsToCreateStreamQuery(pCxt, pStmt, pSelect);
if (TSDB_CODE_SUCCESS == code) {
code = addSubtableNameToCreateStreamQuery(pCxt, pStmt, pSelect);
}
return code;
}
static int32_t checkStreamQuery(STranslateContext* pCxt, SSelectStmt* pSelect) {
if (TSDB_DATA_TYPE_TIMESTAMP != ((SExprNode*)nodesListGetNode(pSelect->pProjectionList, 0))->resType.type ||
!pSelect->isTimeLineResult || crossTableWithoutAggOper(pSelect) || NULL != pSelect->pOrderByList ||
@ -5220,18 +5321,21 @@ static int32_t checkStreamQuery(STranslateContext* pCxt, SSelectStmt* pSelect) {
return TSDB_CODE_SUCCESS;
}
static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SNode* pStmt, SCMCreateStreamReq* pReq) {
static int32_t buildCreateStreamQuery(STranslateContext* pCxt, SCreateStreamStmt* pStmt, SCMCreateStreamReq* pReq) {
pCxt->createStream = true;
int32_t code = addWstartTsToCreateStreamQuery(pStmt);
int32_t code = addWstartTsToCreateStreamQuery(pStmt->pQuery);
if (TSDB_CODE_SUCCESS == code) {
code = translateQuery(pCxt, pStmt);
code = addSubtableInfoToCreateStreamQuery(pCxt, pStmt);
}
if (TSDB_CODE_SUCCESS == code) {
code = checkStreamQuery(pCxt, (SSelectStmt*)pStmt);
code = translateQuery(pCxt, pStmt->pQuery);
}
if (TSDB_CODE_SUCCESS == code) {
getSourceDatabase(pStmt, pCxt->pParseCxt->acctId, pReq->sourceDB);
code = nodesNodeToString(pStmt, false, &pReq->ast, NULL);
code = checkStreamQuery(pCxt, (SSelectStmt*)pStmt->pQuery);
}
if (TSDB_CODE_SUCCESS == code) {
getSourceDatabase(pStmt->pQuery, pCxt->pParseCxt->acctId, pReq->sourceDB);
code = nodesNodeToString(pStmt->pQuery, false, &pReq->ast, NULL);
}
return code;
}
@ -5249,7 +5353,7 @@ static int32_t buildCreateStreamReq(STranslateContext* pCxt, SCreateStreamStmt*
tNameExtractFullName(&name, pReq->targetStbFullName);
}
int32_t code = buildCreateStreamQuery(pCxt, pStmt->pQuery, pReq);
int32_t code = buildCreateStreamQuery(pCxt, pStmt, pReq);
if (TSDB_CODE_SUCCESS == code) {
pReq->sql = strdup(pCxt->pParseCxt->pSql);
if (NULL == pReq->sql) {
@ -5262,6 +5366,8 @@ static int32_t buildCreateStreamReq(STranslateContext* pCxt, SCreateStreamStmt*
pReq->maxDelay = (NULL != pStmt->pOptions->pDelay ? ((SValueNode*)pStmt->pOptions->pDelay)->datum.i : 0);
pReq->watermark = (NULL != pStmt->pOptions->pWatermark ? ((SValueNode*)pStmt->pOptions->pWatermark)->datum.i : 0);
pReq->igExpired = pStmt->pOptions->ignoreExpired;
columnDefNodeToField(pStmt->pTags, &pReq->pTags);
pReq->numOfTags = LIST_LENGTH(pStmt->pTags);
}
return code;

File diff suppressed because it is too large Load Diff

View File

@ -610,6 +610,20 @@ TEST_F(ParserInitialCTest, createStream) {
expect.igExpired = igExpired;
};
auto addTag = [&](const char* pFieldName, uint8_t type, int32_t bytes = 0) {
SField field = {0};
strcpy(field.name, pFieldName);
field.type = type;
field.bytes = bytes > 0 ? bytes : tDataTypes[type].bytes;
field.flags |= COL_SMA_ON;
if (NULL == expect.pTags) {
expect.pTags = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SField));
}
taosArrayPush(expect.pTags, &field);
expect.numOfTags += 1;
};
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_CREATE_STREAM_STMT);
SCMCreateStreamReq req = {0};
@ -625,6 +639,19 @@ TEST_F(ParserInitialCTest, createStream) {
ASSERT_EQ(req.maxDelay, expect.maxDelay);
ASSERT_EQ(req.watermark, expect.watermark);
ASSERT_EQ(req.igExpired, expect.igExpired);
ASSERT_EQ(req.numOfTags, expect.numOfTags);
if (expect.numOfTags > 0) {
ASSERT_EQ(taosArrayGetSize(req.pTags), expect.numOfTags);
ASSERT_EQ(taosArrayGetSize(req.pTags), taosArrayGetSize(expect.pTags));
for (int32_t i = 0; i < expect.numOfTags; ++i) {
SField* pField = (SField*)taosArrayGet(req.pTags, i);
SField* pExpectField = (SField*)taosArrayGet(expect.pTags, i);
ASSERT_EQ(std::string(pField->name), std::string(pExpectField->name));
ASSERT_EQ(pField->type, pExpectField->type);
ASSERT_EQ(pField->bytes, pExpectField->bytes);
ASSERT_EQ(pField->flags, pExpectField->flags);
}
}
tFreeSCMCreateStreamReq(&req);
});
@ -640,6 +667,17 @@ TEST_F(ParserInitialCTest, createStream) {
run("CREATE STREAM IF NOT EXISTS s1 TRIGGER MAX_DELAY 20s WATERMARK 10s IGNORE EXPIRED 0 INTO st1 AS SELECT COUNT(*) "
"FROM t1 INTERVAL(10S)");
clearCreateStreamReq();
setCreateStreamReqFunc(
"s1", "test",
"create stream s1 into st3 tags(tname varchar(10), id int) subtable(concat('new-', tname)) as "
"select _wstart wstart, count(*) cnt from st1 partition by tbname tname, tag1 id interval(10s)",
"st3");
addTag("tname", TSDB_DATA_TYPE_VARCHAR, 10 + VARSTR_HEADER_SIZE);
addTag("id", TSDB_DATA_TYPE_INT);
run("CREATE STREAM s1 INTO st3 TAGS(tname VARCHAR(10), id INT) SUBTABLE(CONCAT('new-', tname)) "
"AS SELECT _WSTART wstart, COUNT(*) cnt FROM st1 PARTITION BY TBNAME tname, tag1 id INTERVAL(10S)");
clearCreateStreamReq();
}
TEST_F(ParserInitialCTest, createStreamSemanticCheck) {

View File

@ -250,7 +250,10 @@ TEST_F(ParserShowToUseTest, trimDatabase) {
STrimDbReq expect = {0};
auto setTrimDbReq = [&](const char* pDb) { snprintf(expect.db, sizeof(expect.db), "0.%s", pDb); };
auto setTrimDbReq = [&](const char* pDb, int32_t maxSpeed = 0) {
snprintf(expect.db, sizeof(expect.db), "0.%s", pDb);
expect.maxSpeed = maxSpeed;
};
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_TRIM_DATABASE_STMT);
@ -258,10 +261,14 @@ TEST_F(ParserShowToUseTest, trimDatabase) {
STrimDbReq req = {0};
ASSERT_EQ(tDeserializeSTrimDbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
ASSERT_EQ(std::string(req.db), std::string(expect.db));
ASSERT_EQ(req.maxSpeed, expect.maxSpeed);
});
setTrimDbReq("wxy_db");
run("TRIM DATABASE wxy_db");
setTrimDbReq("wxy_db", 100);
run("TRIM DATABASE wxy_db MAX_SPEED 100");
}
TEST_F(ParserShowToUseTest, useDatabase) {

View File

@ -611,6 +611,8 @@ static int32_t createIndefRowsFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt
return code;
}
static bool isInterpFunc(int32_t funcId) { return fmIsInterpFunc(funcId) || fmIsInterpPseudoColumnFunc(funcId); }
static int32_t createInterpFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SLogicNode** pLogicNode) {
if (!pSelect->hasInterpFunc) {
return TSDB_CODE_SUCCESS;
@ -625,7 +627,7 @@ static int32_t createInterpFuncLogicNode(SLogicPlanContext* pCxt, SSelectStmt* p
pInterpFunc->node.requireDataOrder = getRequireDataOrder(true, pSelect);
pInterpFunc->node.resultDataOrder = pInterpFunc->node.requireDataOrder;
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, fmIsInterpFunc, &pInterpFunc->pFuncs);
int32_t code = nodesCollectFuncs(pSelect, SQL_CLAUSE_SELECT, isInterpFunc, &pInterpFunc->pFuncs);
if (TSDB_CODE_SUCCESS == code) {
code = rewriteExprsForSelect(pInterpFunc->pFuncs, pSelect, SQL_CLAUSE_SELECT);
}
@ -1022,6 +1024,20 @@ static int32_t createPartitionLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pS
}
}
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pTags) {
pPartition->pTags = nodesCloneList(pSelect->pTags);
if (NULL == pPartition->pTags) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
}
if (TSDB_CODE_SUCCESS == code && NULL != pSelect->pSubtable) {
pPartition->pSubtable = nodesCloneNode(pSelect->pSubtable);
if (NULL == pPartition->pSubtable) {
code = TSDB_CODE_OUT_OF_MEMORY;
}
}
if (TSDB_CODE_SUCCESS == code) {
*pLogicNode = (SLogicNode*)pPartition;
} else {

View File

@ -1615,6 +1615,8 @@ static int32_t partTagsOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSub
SScanLogicNode* pScan = (SScanLogicNode*)nodesListGetNode(pNode->pChildren, 0);
if (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode)) {
TSWAP(((SPartitionLogicNode*)pNode)->pPartitionKeys, pScan->pGroupTags);
TSWAP(((SPartitionLogicNode*)pNode)->pTags, pScan->pTags);
TSWAP(((SPartitionLogicNode*)pNode)->pSubtable, pScan->pSubtable);
int32_t code = replaceLogicNode(pLogicSubplan, pNode, (SLogicNode*)pScan);
if (TSDB_CODE_SUCCESS == code) {
code = adjustLogicNodeDataRequirement((SLogicNode*)pScan, pNode->resultDataOrder);

View File

@ -563,7 +563,16 @@ static int32_t createTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubp
pTableScan->igExpired = pScanLogicNode->igExpired;
pTableScan->assignBlockUid = pCxt->pPlanCxt->rSmaQuery ? true : false;
return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pTableScan, pPhyNode);
int32_t code = createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pTableScan, pPhyNode);
if (TSDB_CODE_SUCCESS == code) {
code = setListSlotId(pCxt, pTableScan->scan.node.pOutputDataBlockDesc->dataBlockId, -1, pScanLogicNode->pTags,
&pTableScan->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = setNodeSlotId(pCxt, pTableScan->scan.node.pOutputDataBlockDesc->dataBlockId, -1, pScanLogicNode->pSubtable,
&pTableScan->pSubtable);
}
return code;
}
static int32_t createSystemTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan,
@ -1322,11 +1331,10 @@ static int32_t createSortPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren
return code;
}
static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SPartitionLogicNode* pPartLogicNode, SPhysiNode** pPhyNode) {
SPartitionPhysiNode* pPart = (SPartitionPhysiNode*)makePhysiNode(
pCxt, (SLogicNode*)pPartLogicNode,
pCxt->pPlanCxt->streamQuery ? QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION : QUERY_NODE_PHYSICAL_PLAN_PARTITION);
static int32_t createPartitionPhysiNodeImpl(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SPartitionLogicNode* pPartLogicNode, ENodeType type,
SPhysiNode** pPhyNode) {
SPartitionPhysiNode* pPart = (SPartitionPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pPartLogicNode, type);
if (NULL == pPart) {
return TSDB_CODE_OUT_OF_MEMORY;
}
@ -1371,6 +1379,34 @@ static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChi
return code;
}
static int32_t createStreamPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SPartitionLogicNode* pPartLogicNode, SPhysiNode** pPhyNode) {
SStreamPartitionPhysiNode* pPart = NULL;
int32_t code = createPartitionPhysiNodeImpl(pCxt, pChildren, pPartLogicNode,
QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION, (SPhysiNode**)&pPart);
SDataBlockDescNode* pChildTupe = (((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc);
if (TSDB_CODE_SUCCESS == code) {
code = setListSlotId(pCxt, pChildTupe->dataBlockId, -1, pPartLogicNode->pTags, &pPart->pTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = setNodeSlotId(pCxt, pChildTupe->dataBlockId, -1, pPartLogicNode->pSubtable, &pPart->pSubtable);
}
if (TSDB_CODE_SUCCESS == code) {
*pPhyNode = (SPhysiNode*)pPart;
} else {
nodesDestroyNode((SNode*)pPart);
}
return code;
}
static int32_t createPartitionPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SPartitionLogicNode* pPartLogicNode, SPhysiNode** pPhyNode) {
if (pCxt->pPlanCxt->streamQuery) {
return createStreamPartitionPhysiNode(pCxt, pChildren, pPartLogicNode, pPhyNode);
}
return createPartitionPhysiNodeImpl(pCxt, pChildren, pPartLogicNode, QUERY_NODE_PHYSICAL_PLAN_PARTITION, pPhyNode);
}
static int32_t createFillPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren, SFillLogicNode* pFillNode,
SPhysiNode** pPhyNode) {
SFillPhysiNode* pFill = (SFillPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pFillNode, QUERY_NODE_PHYSICAL_PLAN_FILL);

View File

@ -101,6 +101,8 @@ TEST_F(PlanBasicTest, interpFunc) {
useDb("root", "test");
run("SELECT INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR)");
run("SELECT _IROWTS, INTERP(c1) FROM t1 RANGE('2017-7-14 18:00:00', '2017-7-14 19:00:00') EVERY(5s) FILL(LINEAR)");
}
TEST_F(PlanBasicTest, lastRowFunc) {

View File

@ -32,6 +32,12 @@ TEST_F(PlanOtherTest, createStream) {
run("create stream if not exists s1 trigger window_close watermark 10s into st1 as select count(*) from t1 "
"interval(10s)");
run("CREATE STREAM s1 INTO st3 TAGS(tname VARCHAR(10), id INT) SUBTABLE(CONCAT('new-', tname)) "
"AS SELECT _WSTART wstart, COUNT(*) cnt FROM st1 PARTITION BY TBNAME tname, c1 id INTERVAL(10S)");
run("CREATE STREAM s1 INTO st3 TAGS(tname VARCHAR(10), id INT) SUBTABLE(CONCAT('new-', tname)) "
"AS SELECT _WSTART wstart, COUNT(*) cnt FROM st1 PARTITION BY TBNAME tname, tag1 id INTERVAL(10S)");
}
TEST_F(PlanOtherTest, createStreamUseSTable) {

View File

@ -3093,6 +3093,8 @@ static FORCE_INLINE bool filterExecuteImplIsNull(void *pinfo, int32_t numOfRows,
if (p[i] == 0) {
all = false;
} else {
(*numOfQualified) += 1;
}
}
@ -3117,6 +3119,8 @@ static FORCE_INLINE bool filterExecuteImplNotNull(void *pinfo, int32_t numOfRows
p[i] = ((colData != NULL) && !colDataIsNull((SColumnInfoData *)info->cunits[uidx].colData, 0, i, NULL));
if (p[i] == 0) {
all = false;
} else {
(*numOfQualified) += 1;
}
}
@ -3196,6 +3200,8 @@ bool filterExecuteImplMisc(void *pinfo, int32_t numOfRows, SColumnInfoData *pRes
if (p[i] == 0) {
all = false;
} else {
(*numOfQualified) += 1;
}
}
@ -3269,6 +3275,8 @@ bool filterExecuteImpl(void *pinfo, int32_t numOfRows, SColumnInfoData *pRes, SC
if (p[i] == 0) {
all = false;
} else {
(*numOfQualified) += 1;
}
}

View File

@ -46,7 +46,7 @@ SRaftStore *raftStoreOpen(const char *path) {
ASSERT(pRaftStore->pFile != NULL);
int len = taosReadFile(pRaftStore->pFile, storeBuf, RAFT_STORE_BLOCK_SIZE);
ASSERT(len == RAFT_STORE_BLOCK_SIZE);
ASSERT(len > 0);
ret = raftStoreDeserialize(pRaftStore, storeBuf, len);
ASSERT(ret == 0);

View File

@ -57,7 +57,7 @@ void syncUtilU642Addr(uint64_t u64, char* host, size_t len, uint16_t* port) {
struct in_addr addr;
addr.s_addr = hostU32;
snprintf(host, len, "%s", taosInetNtoa(addr));
taosInetNtoa(addr, host, len);
*port = (uint16_t)((u64 & 0x00000000FFFF0000) >> 16);
}

View File

@ -58,6 +58,24 @@ int wordexp(char *words, wordexp_t *pwordexp, int flags) {
void wordfree(wordexp_t *pwordexp) {}
#elif defined(DARWIN)
#include <dirent.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <wordexp.h>
typedef struct dirent dirent;
typedef struct dirent TdDirEntry;
typedef struct TdDir {
TdDirEntry dirEntry;
TdDirEntry dirEntry1;
TdDirEntryPtr dirEntryPtr;
DIR *pDir;
} TdDir;
#else
#include <dirent.h>
@ -343,7 +361,7 @@ char *taosDirName(char *name) {
name[0] = 0;
}
return name;
#elif defined(_TD_DARWIN_64)
#else
char *end = strrchr(name, '/');
if (end != NULL) {
*end = '\0';
@ -351,8 +369,6 @@ char *taosDirName(char *name) {
name[0] = 0;
}
return name;
#else
return dirname(name);
#endif
}
@ -362,7 +378,9 @@ char *taosDirEntryBaseName(char *name) {
_splitpath(name, NULL, NULL, Filename1, Ext1);
return name + (strlen(name) - strlen(Filename1) - strlen(Ext1));
#else
return (char *)basename(name);
char *pPoint = strchr(name, '.');
if (pPoint != NULL) pPoint = 0;
return name;
#endif
}
@ -386,6 +404,13 @@ TdDirPtr taosOpenDir(const char *dirname) {
return NULL;
}
return pDir;
#elif defined(DARWIN)
DIR *pDir = opendir(dirname);
if (pDir == NULL) return NULL;
TdDirPtr dirPtr = (TdDirPtr)taosMemoryMalloc(sizeof(TdDir));
dirPtr->dirEntryPtr = (TdDirEntryPtr)&(dirPtr->dirEntry1);
dirPtr->pDir = pDir;
return dirPtr;
#else
return (TdDirPtr)opendir(dirname);
#endif
@ -400,6 +425,12 @@ TdDirEntryPtr taosReadDir(TdDirPtr pDir) {
return NULL;
}
return (TdDirEntryPtr) & (pDir->dirEntry.findFileData);
#elif defined(DARWIN)
if (readdir_r(pDir->pDir, (dirent*)&(pDir->dirEntry), (dirent**)&(pDir->dirEntryPtr)) == 0) {
return pDir->dirEntryPtr;
} else {
return NULL;
}
#else
return (TdDirEntryPtr)readdir((DIR *)pDir);
#endif
@ -436,6 +467,11 @@ int32_t taosCloseDir(TdDirPtr *ppDir) {
taosMemoryFree(*ppDir);
*ppDir = NULL;
return 0;
#elif defined(DARWIN)
closedir((*ppDir)->pDir);
taosMemoryFree(*ppDir);
*ppDir = NULL;
return 0;
#else
closedir((DIR *)*ppDir);
*ppDir = NULL;

View File

@ -106,293 +106,8 @@ int32_t tsem_timewait(tsem_t* sem, int64_t nanosecs) {
#elif defined(_TD_DARWIN_64)
/*
* darwin implementation
*/
#include <libproc.h>
// #define SEM_USE_PTHREAD
// #define SEM_USE_POSIX
// #define SEM_USE_SEM
// #ifdef SEM_USE_SEM
// #include <mach/mach_error.h>
// #include <mach/mach_init.h>
// #include <mach/semaphore.h>
// #include <mach/task.h>
// static TdThread sem_thread;
// static TdThreadOnce sem_once;
// static task_t sem_port;
// static volatile int sem_inited = 0;
// static semaphore_t sem_exit;
// static void *sem_thread_routine(void *arg) {
// (void)arg;
// setThreadName("sem_thrd");
// sem_port = mach_task_self();
// kern_return_t ret = semaphore_create(sem_port, &sem_exit, SYNC_POLICY_FIFO, 0);
// if (ret != KERN_SUCCESS) {
// fprintf(stderr, "==%s[%d]%s()==failed to create sem_exit\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__);
// sem_inited = -1;
// return NULL;
// }
// sem_inited = 1;
// semaphore_wait(sem_exit);
// return NULL;
// }
// static void once_init(void) {
// int r = 0;
// r = taosThreadCreate(&sem_thread, NULL, sem_thread_routine, NULL);
// if (r) {
// fprintf(stderr, "==%s[%d]%s()==failed to create thread\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__);
// return;
// }
// while (sem_inited == 0) {
// ;
// }
// }
// #endif
// struct tsem_s {
// #ifdef SEM_USE_PTHREAD
// TdThreadMutex lock;
// TdThreadCond cond;
// volatile int64_t val;
// #elif defined(SEM_USE_POSIX)
// size_t id;
// sem_t *sem;
// #elif defined(SEM_USE_SEM)
// semaphore_t sem;
// #else // SEM_USE_PTHREAD
// dispatch_semaphore_t sem;
// #endif // SEM_USE_PTHREAD
// volatile unsigned int valid : 1;
// };
// int tsem_init(tsem_t *sem, int pshared, unsigned int value) {
// // fprintf(stderr, "==%s[%d]%s():[%p]==creating\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__, sem);
// if (*sem) {
// fprintf(stderr, "==%s[%d]%s():[%p]==already initialized\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// struct tsem_s *p = (struct tsem_s *)taosMemoryCalloc(1, sizeof(*p));
// if (!p) {
// fprintf(stderr, "==%s[%d]%s():[%p]==out of memory\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__, sem);
// abort();
// }
// #ifdef SEM_USE_PTHREAD
// int r = taosThreadMutexInit(&p->lock, NULL);
// do {
// if (r) break;
// r = taosThreadCondInit(&p->cond, NULL);
// if (r) {
// taosThreadMutexDestroy(&p->lock);
// break;
// }
// p->val = value;
// } while (0);
// if (r) {
// fprintf(stderr, "==%s[%d]%s():[%p]==not created\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__, sem);
// abort();
// }
// #elif defined(SEM_USE_POSIX)
// static size_t tick = 0;
// do {
// size_t id = atomic_add_fetch_64(&tick, 1);
// if (id == SEM_VALUE_MAX) {
// atomic_store_64(&tick, 0);
// id = 0;
// }
// char name[NAME_MAX - 4];
// snprintf(name, sizeof(name), "/t" PRId64, id);
// p->sem = sem_open(name, O_CREAT | O_EXCL, pshared, value);
// p->id = id;
// if (p->sem != SEM_FAILED) break;
// int e = errno;
// if (e == EEXIST) continue;
// if (e == EINTR) continue;
// fprintf(stderr, "==%s[%d]%s():[%p]==not created[%d]%s\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem,
// e, strerror(e));
// abort();
// } while (p->sem == SEM_FAILED);
// #elif defined(SEM_USE_SEM)
// taosThreadOnce(&sem_once, once_init);
// if (sem_inited != 1) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal resource init failed\n", taosDirEntryBaseName(__FILE__), __LINE__,
// __func__, sem);
// errno = ENOMEM;
// return -1;
// }
// kern_return_t ret = semaphore_create(sem_port, &p->sem, SYNC_POLICY_FIFO, value);
// if (ret != KERN_SUCCESS) {
// fprintf(stderr, "==%s[%d]%s():[%p]==semophore_create failed\n", taosDirEntryBaseName(__FILE__), __LINE__,
// __func__,
// sem);
// // we fail-fast here, because we have less-doc about semaphore_create for the moment
// abort();
// }
// #else // SEM_USE_PTHREAD
// p->sem = dispatch_semaphore_create(value);
// if (p->sem == NULL) {
// fprintf(stderr, "==%s[%d]%s():[%p]==not created\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__, sem);
// abort();
// }
// #endif // SEM_USE_PTHREAD
// p->valid = 1;
// *sem = p;
// return 0;
// }
// int tsem_wait(tsem_t *sem) {
// if (!*sem) {
// fprintf(stderr, "==%s[%d]%s():[%p]==not initialized\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__, sem);
// abort();
// }
// struct tsem_s *p = *sem;
// if (!p->valid) {
// fprintf(stderr, "==%s[%d]%s():[%p]==already destroyed\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem); abort();
// }
// #ifdef SEM_USE_PTHREAD
// if (taosThreadMutexLock(&p->lock)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// p->val -= 1;
// if (p->val < 0) {
// if (taosThreadCondWait(&p->cond, &p->lock)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__,
// __func__,
// sem);
// abort();
// }
// }
// if (taosThreadMutexUnlock(&p->lock)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// return 0;
// #elif defined(SEM_USE_POSIX)
// return sem_wait(p->sem);
// #elif defined(SEM_USE_SEM)
// return semaphore_wait(p->sem);
// #else // SEM_USE_PTHREAD
// return dispatch_semaphore_wait(p->sem, DISPATCH_TIME_FOREVER);
// #endif // SEM_USE_PTHREAD
// }
// int tsem_post(tsem_t *sem) {
// if (!*sem) {
// fprintf(stderr, "==%s[%d]%s():[%p]==not initialized\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__, sem);
// abort();
// }
// struct tsem_s *p = *sem;
// if (!p->valid) {
// fprintf(stderr, "==%s[%d]%s():[%p]==already destroyed\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem); abort();
// }
// #ifdef SEM_USE_PTHREAD
// if (taosThreadMutexLock(&p->lock)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// p->val += 1;
// if (p->val <= 0) {
// if (taosThreadCondSignal(&p->cond)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__,
// __func__,
// sem);
// abort();
// }
// }
// if (taosThreadMutexUnlock(&p->lock)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// return 0;
// #elif defined(SEM_USE_POSIX)
// return sem_post(p->sem);
// #elif defined(SEM_USE_SEM)
// return semaphore_signal(p->sem);
// #else // SEM_USE_PTHREAD
// return dispatch_semaphore_signal(p->sem);
// #endif // SEM_USE_PTHREAD
// }
// int tsem_destroy(tsem_t *sem) {
// // fprintf(stderr, "==%s[%d]%s():[%p]==destroying\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__, sem);
// if (!*sem) {
// // fprintf(stderr, "==%s[%d]%s():[%p]==not initialized\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// // abort();
// return 0;
// }
// struct tsem_s *p = *sem;
// if (!p->valid) {
// // fprintf(stderr, "==%s[%d]%s():[%p]==already destroyed\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// // sem); abort();
// return 0;
// }
// #ifdef SEM_USE_PTHREAD
// if (taosThreadMutexLock(&p->lock)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// p->valid = 0;
// if (taosThreadCondDestroy(&p->cond)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// if (taosThreadMutexUnlock(&p->lock)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// if (taosThreadMutexDestroy(&p->lock)) {
// fprintf(stderr, "==%s[%d]%s():[%p]==internal logic error\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem);
// abort();
// }
// #elif defined(SEM_USE_POSIX)
// char name[NAME_MAX - 4];
// snprintf(name, sizeof(name), "/t" PRId64, p->id);
// int r = sem_unlink(name);
// if (r) {
// int e = errno;
// fprintf(stderr, "==%s[%d]%s():[%p]==unlink failed[%d]%s\n", taosDirEntryBaseName(__FILE__), __LINE__, __func__,
// sem,
// e, strerror(e));
// abort();
// }
// #elif defined(SEM_USE_SEM)
// semaphore_destroy(sem_port, p->sem);
// #else // SEM_USE_PTHREAD
// #endif // SEM_USE_PTHREAD
// p->valid = 0;
// taosMemoryFree(p);
// *sem = NULL;
// return 0;
// }
int tsem_init(tsem_t *psem, int flags, unsigned int count) {
*psem = dispatch_semaphore_create(count);
if (*psem == NULL) return -1;
@ -401,8 +116,8 @@ int tsem_init(tsem_t *psem, int flags, unsigned int count) {
int tsem_destroy(tsem_t *psem) {
if (psem == NULL || *psem == NULL) return -1;
dispatch_release(*psem);
*psem = NULL;
// dispatch_release(*psem);
// *psem = NULL;
return 0;
}

View File

@ -312,14 +312,8 @@ uint32_t taosInetAddr(const char *ipAddr) {
return inet_addr(ipAddr);
#endif
}
const char *taosInetNtoa(struct in_addr ipInt) {
#ifdef WINDOWS
// not thread safe, only for debug usage while print log
static char tmpDstStr[16];
return inet_ntop(AF_INET, &ipInt, tmpDstStr, INET6_ADDRSTRLEN);
#else
return inet_ntoa(ipInt);
#endif
const char *taosInetNtoa(struct in_addr ipInt, char *dstStr, int32_t len) {
return inet_ntop(AF_INET, &ipInt, dstStr, len);
}
#ifndef SIGPIPE
@ -670,7 +664,7 @@ int taosGetLocalIp(const char *eth, char *ip) {
return -1;
}
memcpy(&sin, &ifr.ifr_addr, sizeof(sin));
snprintf(ip, 64, "%s", inet_ntoa(sin.sin_addr));
taosInetNtoa(sin.sin_addr, ip, 64);
taosCloseSocketNoCheck1(fd);
#endif
return 0;

View File

@ -306,8 +306,6 @@ int32_t taosMbsToWchars(TdWchar *pWchars, const char *pStrs, int32_t size) { ret
int32_t taosWcharToMb(char *pStr, TdWchar wchar) { return wctomb(pStr, wchar); }
int32_t taosWcharsToMbs(char *pStrs, TdWchar *pWchars, int32_t size) { return wcstombs(pStrs, pWchars, size); }
char *taosStrCaseStr(const char *str, const char *pattern) {
size_t i;
@ -326,6 +324,9 @@ char *taosStrCaseStr(const char *str, const char *pattern) {
int64_t taosStr2Int64(const char *str, char **pEnd, int32_t radix) {
int64_t tmp = strtoll(str, pEnd, radix);
#ifdef DARWIN
if (errno == EINVAL) errno = 0;
#endif
#ifdef TD_CHECK_STR_TO_INT_ERROR
assert(errno != ERANGE);
assert(errno != EINVAL);
@ -335,6 +336,9 @@ int64_t taosStr2Int64(const char *str, char **pEnd, int32_t radix) {
uint64_t taosStr2UInt64(const char *str, char **pEnd, int32_t radix) {
uint64_t tmp = strtoull(str, pEnd, radix);
#ifdef DARWIN
if (errno == EINVAL) errno = 0;
#endif
#ifdef TD_CHECK_STR_TO_INT_ERROR
assert(errno != ERANGE);
assert(errno != EINVAL);
@ -344,6 +348,9 @@ uint64_t taosStr2UInt64(const char *str, char **pEnd, int32_t radix) {
int32_t taosStr2Int32(const char *str, char **pEnd, int32_t radix) {
int32_t tmp = strtol(str, pEnd, radix);
#ifdef DARWIN
if (errno == EINVAL) errno = 0;
#endif
#ifdef TD_CHECK_STR_TO_INT_ERROR
assert(errno != ERANGE);
assert(errno != EINVAL);
@ -353,6 +360,9 @@ int32_t taosStr2Int32(const char *str, char **pEnd, int32_t radix) {
uint32_t taosStr2UInt32(const char *str, char **pEnd, int32_t radix) {
uint32_t tmp = strtol(str, pEnd, radix);
#ifdef DARWIN
if (errno == EINVAL) errno = 0;
#endif
#ifdef TD_CHECK_STR_TO_INT_ERROR
assert(errno != ERANGE);
assert(errno != EINVAL);
@ -362,6 +372,9 @@ uint32_t taosStr2UInt32(const char *str, char **pEnd, int32_t radix) {
int16_t taosStr2Int16(const char *str, char **pEnd, int32_t radix) {
int32_t tmp = strtol(str, pEnd, radix);
#ifdef DARWIN
if (errno == EINVAL) errno = 0;
#endif
#ifdef TD_CHECK_STR_TO_INT_ERROR
assert(errno != ERANGE);
assert(errno != EINVAL);
@ -373,6 +386,9 @@ int16_t taosStr2Int16(const char *str, char **pEnd, int32_t radix) {
uint16_t taosStr2UInt16(const char *str, char **pEnd, int32_t radix) {
uint32_t tmp = strtoul(str, pEnd, radix);
#ifdef DARWIN
if (errno == EINVAL) errno = 0;
#endif
#ifdef TD_CHECK_STR_TO_INT_ERROR
assert(errno != ERANGE);
assert(errno != EINVAL);
@ -394,6 +410,9 @@ int8_t taosStr2Int8(const char *str, char **pEnd, int32_t radix) {
uint8_t taosStr2UInt8(const char *str, char **pEnd, int32_t radix) {
uint32_t tmp = strtoul(str, pEnd, radix);
#ifdef DARWIN
if (errno == EINVAL) errno = 0;
#endif
#ifdef TD_CHECK_STR_TO_INT_ERROR
assert(errno != ERANGE);
assert(errno != EINVAL);

View File

@ -143,8 +143,11 @@ static int32_t taosGetSysCpuInfo(SysCpuInfo *cpuInfo) {
cpuInfo->user = CompareFileTime(&pre_userTime, &userTime);
cpuInfo->nice = 0;
}
#elif defined(_TD_DARWIN_64)
assert(0);
#elif defined(DARWIN)
cpuInfo->idle = 0;
cpuInfo->system = 0;
cpuInfo->user = 0;
cpuInfo->nice = 0;
#else
TdFilePtr pFile = taosOpenFile(tsSysCpuFile, TD_FILE_READ | TD_FILE_STREAM);
if (pFile == NULL) {
@ -180,8 +183,11 @@ static int32_t taosGetProcCpuInfo(ProcCpuInfo *cpuInfo) {
cpuInfo->cutime = 0;
cpuInfo->cstime = 0;
}
#elif defined(_TD_DARWIN_64)
assert(0);
#elif defined(DARWIN)
cpuInfo->stime = 0;
cpuInfo->utime = 0;
cpuInfo->cutime = 0;
cpuInfo->cstime = 0;
#else
TdFilePtr pFile = taosOpenFile(tsProcCpuFile, TD_FILE_READ | TD_FILE_STREAM);
if (pFile == NULL) {
@ -359,7 +365,7 @@ int32_t taosGetCpuInfo(char *cpuModel, int32_t maxLen, float *numOfCores) {
pCmd = taosOpenCmd("sysctl -n machdep.cpu.core_count");
if (pCmd == NULL) return code;
memset(buf, 0, sizeof(buf));
if (taosGetsCmd(pCmd, maxLen, cpuModel) > 0) {
if (taosGetsCmd(pCmd, sizeof(buf) - 1, buf) > 0) {
code = 0;
done |= 2;
*numOfCores = atof(buf);

View File

@ -891,6 +891,7 @@ void taosGetSystemTimezone(char *outTimezoneStr, enum TdTimezone *tsTimezone) {
time_t tx1 = taosGetTimestampSec();
struct tm tm1;
taosLocalTime(&tx1, &tm1);
daylight = tm1.tm_isdst;
/*
* format example:

View File

@ -415,23 +415,15 @@ class TDDnode:
i += 1
if i > 50:
break
tailCmdStr = 'tail -f '
popen = subprocess.Popen(
tailCmdStr + logFile,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
pid = popen.pid
# print('Popen.pid:' + str(pid))
timeout = time.time() + 60 * 2
while True:
line = popen.stdout.readline().strip()
if bkey in line:
popen.kill()
break
if time.time() > timeout:
tdLog.exit('wait too long for taosd start')
tdLog.debug("the dnode:%d has been started." % (self.index))
with open(logFile) as f:
timeout = time.time() + 60 * 2
while True:
line = f.readline().encode('utf-8')
if bkey in line:
break
if time.time() > timeout:
tdLog.exit('wait too long for taosd start')
tdLog.debug("the dnode:%d has been started." % (self.index))
else:
tdLog.debug(
"wait 10 seconds for the dnode:%d to start." %
@ -480,19 +472,21 @@ class TDDnode:
toBeKilled = "valgrind.bin"
if self.running != 0:
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs" % toBeKilled
processID = subprocess.check_output(
psCmd, shell=True).decode("utf-8")
psCmd, shell=True).decode("utf-8").strip()
onlyKillOnceWindows = 0
while(processID):
if not platform.system().lower() == 'windows' or (onlyKillOnceWindows == 0 and platform.system().lower() == 'windows'):
killCmd = "kill -INT %s > /dev/null 2>&1" % processID
if platform.system().lower() == 'windows':
killCmd = "kill -INT %s > nul 2>&1" % processID
os.system(killCmd)
onlyKillOnceWindows = 1
time.sleep(1)
processID = subprocess.check_output(
psCmd, shell=True).decode("utf-8")
psCmd, shell=True).decode("utf-8").strip()
if not platform.system().lower() == 'windows':
for port in range(6030, 6041):
fuserCmd = "fuser -k -n tcp %d > /dev/null" % port
@ -516,11 +510,11 @@ class TDDnode:
if self.running != 0:
if platform.system().lower() == 'windows':
psCmd = "for /f %%a in ('wmic process where \"name='taosd.exe' and CommandLine like '%%dnode%d%%'\" get processId ^| xargs echo ^| awk ^'{print $2}^' ^&^& echo aa') do @(ps | grep %%a | awk '{print $1}' )" % (self.index)
psCmd = "for /f %%a in ('wmic process where \"name='taosd.exe' and CommandLine like '%%dnode%d%%'\" get processId ^| xargs echo ^| awk ^'{print $2}^' ^&^& echo aa') do @(ps | grep %%a | awk '{print $1}' | xargs)" % (self.index)
else:
psCmd = "ps -ef|grep -w %s| grep dnode%d|grep -v grep | awk '{print $2}'" % (toBeKilled,self.index)
psCmd = "ps -ef|grep -w %s| grep dnode%d|grep -v grep | awk '{print $2}' | xargs" % (toBeKilled,self.index)
processID = subprocess.check_output(
psCmd, shell=True).decode("utf-8")
psCmd, shell=True).decode("utf-8").strip()
onlyKillOnceWindows = 0
while(processID):
@ -530,7 +524,7 @@ class TDDnode:
onlyKillOnceWindows = 1
time.sleep(1)
processID = subprocess.check_output(
psCmd, shell=True).decode("utf-8")
psCmd, shell=True).decode("utf-8").strip()
if self.valgrind:
time.sleep(2)
@ -547,9 +541,9 @@ class TDDnode:
toBeKilled = "valgrind.bin"
if self.running != 0:
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}'" % toBeKilled
psCmd = "ps -ef|grep -w %s| grep -v grep | awk '{print $2}' | xargs" % toBeKilled
processID = subprocess.check_output(
psCmd, shell=True).decode("utf-8")
psCmd, shell=True).decode("utf-8").strip()
onlyKillOnceWindows = 0
while(processID):
@ -559,7 +553,7 @@ class TDDnode:
onlyKillOnceWindows = 1
time.sleep(1)
processID = subprocess.check_output(
psCmd, shell=True).decode("utf-8")
psCmd, shell=True).decode("utf-8").strip()
for port in range(6030, 6041):
fuserCmd = "fuser -k -n tcp %d" % port
os.system(fuserCmd)
@ -704,15 +698,15 @@ class TDDnodes:
for i in range(len(self.dnodes)):
self.dnodes[i].stop()
psCmd = "ps -ef | grep -w taosd | grep 'root' | grep -v grep| grep -v defunct | awk '{print $2}'"
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
psCmd = "ps -ef | grep -w taosd | grep 'root' | grep -v grep| grep -v defunct | awk '{print $2}' | xargs"
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8").strip()
if processID:
cmd = "sudo systemctl stop taosd"
os.system(cmd)
# if os.system(cmd) != 0 :
# tdLog.exit(cmd)
psCmd = "ps -ef|grep -w taosd| grep -v grep| grep -v defunct | awk '{print $2}'"
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
psCmd = "ps -ef|grep -w taosd| grep -v grep| grep -v defunct | awk '{print $2}' | xargs"
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8").strip()
while(processID):
if platform.system().lower() == 'windows':
killCmd = "kill -9 %s > nul 2>&1" % processID
@ -721,11 +715,11 @@ class TDDnodes:
os.system(killCmd)
time.sleep(1)
processID = subprocess.check_output(
psCmd, shell=True).decode("utf-8")
psCmd, shell=True).decode("utf-8").strip()
if self.killValgrind == 1:
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}'"
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8")
psCmd = "ps -ef|grep -w valgrind.bin| grep -v grep | awk '{print $2}' | xargs"
processID = subprocess.check_output(psCmd, shell=True).decode("utf-8").strip()
while(processID):
if platform.system().lower() == 'windows':
killCmd = "kill -TERM %s > nul 2>&1" % processID
@ -734,7 +728,7 @@ class TDDnodes:
os.system(killCmd)
time.sleep(1)
processID = subprocess.check_output(
psCmd, shell=True).decode("utf-8")
psCmd, shell=True).decode("utf-8").strip()
# if os.system(cmd) != 0 :
# tdLog.exit(cmd)

View File

@ -40,20 +40,3 @@ target_link_libraries(
PUBLIC common
PUBLIC os
)
add_executable(sdbDump sdbDump.c)
target_link_libraries(
sdbDump
PUBLIC dnode
PUBLIC mnode
PUBLIC stream
PUBLIC sdb
PUBLIC os
)
target_include_directories(
sdbDump
PUBLIC "${TD_SOURCE_DIR}/include/dnode/mnode"
PRIVATE "${TD_SOURCE_DIR}/source/dnode/mnode/impl/inc"
PRIVATE "${TD_SOURCE_DIR}/source/dnode/mnode/sdb/inc"
PRIVATE "${TD_SOURCE_DIR}/source/dnode/mgmt/node_mgmt/inc"
)

View File

@ -201,7 +201,7 @@ void *threadFunc(void *param) {
int64_t t = pInfo->tableBeginIndex;
for (; t <= pInfo->tableEndIndex;) {
// int64_t batch = (pInfo->tableEndIndex - t);
// batch = MIN(batch, batchNum);
// batch = TMIN(batch, batchNum);
int32_t len = sprintf(qstr, "create table");
for (int32_t i = 0; i < batchNumOfTbl;) {

View File

@ -1,475 +0,0 @@
/*
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"), as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#define _DEFAULT_SOURCE
#include "dmMgmt.h"
#include "mndInt.h"
#include "sdb.h"
#include "tconfig.h"
#include "tjson.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
#define TMP_DNODE_DIR TD_TMP_DIR_PATH "dumpsdb"
#define TMP_MNODE_DIR TD_TMP_DIR_PATH "dumpsdb" TD_DIRSEP "mnode"
#define TMP_SDB_DATA_DIR TD_TMP_DIR_PATH "dumpsdb" TD_DIRSEP "mnode" TD_DIRSEP "data"
#define TMP_SDB_SYNC_DIR TD_TMP_DIR_PATH "dumpsdb" TD_DIRSEP "mnode" TD_DIRSEP "sync"
#define TMP_SDB_MNODE_JSON TD_TMP_DIR_PATH "dumpsdb" TD_DIRSEP "mnode" TD_DIRSEP "mnode.json"
#define TMP_SDB_DATA_FILE TD_TMP_DIR_PATH "dumpsdb" TD_DIRSEP "mnode" TD_DIRSEP "data" TD_DIRSEP "sdb.data"
#define TMP_SDB_RAFT_CFG_FILE TD_TMP_DIR_PATH "dumpsdb" TD_DIRSEP "mnode" TD_DIRSEP "sync" TD_DIRSEP "raft_config.json"
#define TMP_SDB_RAFT_STORE_FILE TD_TMP_DIR_PATH "dumpsdb" TD_DIRSEP "mnode" TD_DIRSEP "sync" TD_DIRSEP "raft_store.json"
void reportStartup(const char *name, const char *desc) {}
void sendRsp(SRpcMsg *pMsg) { rpcFreeCont(pMsg->pCont); }
int32_t sendReq(const SEpSet *pEpSet, SRpcMsg *pMsg) {
terrno = TSDB_CODE_INVALID_PTR;
return -1;
}
char *i642str(int64_t val) {
static char str[24] = {0};
snprintf(str, sizeof(str), "%" PRId64, val);
return str;
}
void dumpFunc(SSdb *pSdb, SJson *json) {}
void dumpDb(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "dbs", items);
while (1) {
SDbObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_DB, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "db", item);
tjsonAddStringToObject(item, "name", pObj->name);
tjsonAddStringToObject(item, "acct", pObj->acct);
tjsonAddStringToObject(item, "createUser", pObj->createUser);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "uid", i642str(pObj->uid));
tjsonAddIntegerToObject(item, "cfgVersion", pObj->cfgVersion);
tjsonAddIntegerToObject(item, "vgVersion", pObj->vgVersion);
tjsonAddIntegerToObject(item, "numOfVgroups", pObj->cfg.numOfVgroups);
tjsonAddIntegerToObject(item, "numOfStables", pObj->cfg.numOfStables);
tjsonAddIntegerToObject(item, "buffer", pObj->cfg.buffer);
tjsonAddIntegerToObject(item, "pageSize", pObj->cfg.pageSize);
tjsonAddIntegerToObject(item, "pages", pObj->cfg.pages);
tjsonAddIntegerToObject(item, "cacheLastSize", pObj->cfg.cacheLastSize);
tjsonAddIntegerToObject(item, "daysPerFile", pObj->cfg.daysPerFile);
tjsonAddIntegerToObject(item, "daysToKeep0", pObj->cfg.daysToKeep0);
tjsonAddIntegerToObject(item, "daysToKeep1", pObj->cfg.daysToKeep1);
tjsonAddIntegerToObject(item, "daysToKeep2", pObj->cfg.daysToKeep2);
tjsonAddIntegerToObject(item, "minRows", pObj->cfg.minRows);
tjsonAddIntegerToObject(item, "maxRows", pObj->cfg.maxRows);
tjsonAddIntegerToObject(item, "precision", pObj->cfg.precision);
tjsonAddIntegerToObject(item, "compression", pObj->cfg.compression);
tjsonAddIntegerToObject(item, "replications", pObj->cfg.replications);
tjsonAddIntegerToObject(item, "strict", pObj->cfg.strict);
tjsonAddIntegerToObject(item, "cacheLast", pObj->cfg.cacheLast);
tjsonAddIntegerToObject(item, "hashMethod", pObj->cfg.hashMethod);
tjsonAddIntegerToObject(item, "numOfRetensions", pObj->cfg.numOfRetensions);
tjsonAddIntegerToObject(item, "schemaless", pObj->cfg.schemaless);
tjsonAddIntegerToObject(item, "walLevel", pObj->cfg.walLevel);
tjsonAddIntegerToObject(item, "walFsyncPeriod", pObj->cfg.walFsyncPeriod);
tjsonAddIntegerToObject(item, "walRetentionPeriod", pObj->cfg.walRetentionPeriod);
tjsonAddIntegerToObject(item, "walRetentionSize", pObj->cfg.walRetentionSize);
tjsonAddIntegerToObject(item, "walRollPeriod", pObj->cfg.walRollPeriod);
tjsonAddIntegerToObject(item, "walSegmentSize", pObj->cfg.walSegmentSize);
sdbRelease(pSdb, pObj);
}
}
void dumpStb(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "stbs", items);
while (1) {
SStbObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_STB, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "stb", item);
tjsonAddStringToObject(item, "name", pObj->name);
tjsonAddStringToObject(item, "db", pObj->db);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "uid", i642str(pObj->uid));
tjsonAddStringToObject(item, "dbUid", i642str(pObj->dbUid));
tjsonAddIntegerToObject(item, "tagVer", pObj->tagVer);
tjsonAddIntegerToObject(item, "colVer", pObj->colVer);
tjsonAddIntegerToObject(item, "nextColId", pObj->nextColId);
tjsonAddIntegerToObject(item, "watermark1", pObj->watermark[0]);
tjsonAddIntegerToObject(item, "watermark2", pObj->watermark[1]);
tjsonAddIntegerToObject(item, "maxdelay1", pObj->maxdelay[0]);
tjsonAddIntegerToObject(item, "maxdelay2", pObj->maxdelay[1]);
tjsonAddIntegerToObject(item, "ttl", pObj->ttl);
tjsonAddIntegerToObject(item, "numOfColumns", pObj->numOfColumns);
tjsonAddIntegerToObject(item, "numOfTags", pObj->numOfTags);
tjsonAddIntegerToObject(item, "commentLen", pObj->commentLen);
tjsonAddIntegerToObject(item, "ast1Len", pObj->ast1Len);
tjsonAddIntegerToObject(item, "ast2Len", pObj->ast2Len);
sdbRelease(pSdb, pObj);
}
}
void dumpSma(SSdb *pSdb, SJson *json) {}
void dumpVgroup(SSdb *pSdb, SJson *json) {}
void dumpTopic(SSdb *pSdb, SJson *json) {}
void dumpConsumber(SSdb *pSdb, SJson *json) {}
void dumpSubscribe(SSdb *pSdb, SJson *json) {}
void dumpOffset(SSdb *pSdb, SJson *json) {}
void dumpStream(SSdb *pSdb, SJson *json) {}
void dumpAcct(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "accts", items);
while (1) {
SAcctObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_ACCT, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "acct", item);
tjsonAddStringToObject(item, "acct", pObj->acct);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddIntegerToObject(item, "acctId", pObj->acctId);
sdbRelease(pSdb, pObj);
}
}
void dumpAuth(SSdb *pSdb, SJson *json) {}
void dumpUser(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "users", items);
while (1) {
SUserObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_USER, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "user", item);
tjsonAddStringToObject(item, "name", pObj->user);
tjsonAddStringToObject(item, "pass", pObj->pass);
tjsonAddStringToObject(item, "acct", pObj->acct);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddIntegerToObject(item, "superUser", pObj->superUser);
tjsonAddIntegerToObject(item, "authVersion", pObj->authVersion);
tjsonAddIntegerToObject(item, "numOfReadDbs", taosHashGetSize(pObj->readDbs));
tjsonAddIntegerToObject(item, "numOfWriteDbs", taosHashGetSize(pObj->writeDbs));
sdbRelease(pSdb, pObj);
}
}
void dumpDnode(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "dnodes", items);
while (1) {
SDnodeObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_DNODE, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "dnode", item);
tjsonAddIntegerToObject(item, "id", pObj->id);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddIntegerToObject(item, "port", pObj->port);
tjsonAddStringToObject(item, "fqdn", pObj->fqdn);
sdbRelease(pSdb, pObj);
}
}
void dumpBnode(SSdb *pSdb, SJson *json) {}
void dumpSnode(SSdb *pSdb, SJson *json) {}
void dumpQnode(SSdb *pSdb, SJson *json) {}
void dumpMnode(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "mnodes", items);
while (1) {
SMnodeObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_MNODE, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "mnode", item);
tjsonAddIntegerToObject(item, "id", pObj->id);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
sdbRelease(pSdb, pObj);
}
}
void dumpCluster(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "clusters", items);
while (1) {
SClusterObj *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_CLUSTER, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "cluster", item);
tjsonAddStringToObject(item, "id", i642str(pObj->id));
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "updateTime", i642str(pObj->updateTime));
tjsonAddStringToObject(item, "name", pObj->name);
sdbRelease(pSdb, pObj);
}
}
void dumpTrans(SSdb *pSdb, SJson *json) {
void *pIter = NULL;
SJson *items = tjsonCreateObject();
tjsonAddItemToObject(json, "transactions", items);
while (1) {
STrans *pObj = NULL;
pIter = sdbFetch(pSdb, SDB_TRANS, pIter, (void **)&pObj);
if (pIter == NULL) break;
SJson *item = tjsonCreateObject();
tjsonAddItemToObject(items, "trans", item);
tjsonAddIntegerToObject(item, "id", pObj->id);
tjsonAddIntegerToObject(item, "stage", pObj->stage);
tjsonAddIntegerToObject(item, "policy", pObj->policy);
tjsonAddIntegerToObject(item, "conflict", pObj->conflict);
tjsonAddIntegerToObject(item, "exec", pObj->exec);
tjsonAddStringToObject(item, "createdTime", i642str(pObj->createdTime));
tjsonAddStringToObject(item, "dbname", pObj->dbname);
tjsonAddStringToObject(item, "stbname", pObj->stbname);
tjsonAddIntegerToObject(item, "commitLogNum", taosArrayGetSize(pObj->commitActions));
tjsonAddIntegerToObject(item, "redoActionNum", taosArrayGetSize(pObj->redoActions));
tjsonAddIntegerToObject(item, "undoActionNum", taosArrayGetSize(pObj->undoActions));
sdbRelease(pSdb, pObj);
}
}
void dumpHeader(SSdb *pSdb, SJson *json) {
tjsonAddIntegerToObject(json, "sver", 1);
tjsonAddStringToObject(json, "applyIndex", i642str(pSdb->applyIndex));
tjsonAddStringToObject(json, "applyTerm", i642str(pSdb->applyTerm));
tjsonAddStringToObject(json, "applyConfig", i642str(pSdb->applyConfig));
SJson *maxIdsJson = tjsonCreateObject();
tjsonAddItemToObject(json, "maxIds", maxIdsJson);
for (int32_t i = 0; i < SDB_MAX; ++i) {
int64_t maxId = 0;
if (i < SDB_MAX) {
maxId = pSdb->maxId[i];
}
tjsonAddStringToObject(maxIdsJson, sdbTableName(i), i642str(maxId));
}
SJson *tableVersJson = tjsonCreateObject();
tjsonAddItemToObject(json, "tableVers", tableVersJson);
for (int32_t i = 0; i < SDB_MAX; ++i) {
int64_t tableVer = 0;
if (i < SDB_MAX) {
tableVer = pSdb->tableVer[i];
}
tjsonAddStringToObject(tableVersJson, sdbTableName(i), i642str(tableVer));
}
}
int32_t dumpSdb() {
wDebugFlag = 0;
mDebugFlag = 0;
sDebugFlag = 0;
SMsgCb msgCb = {0};
msgCb.reportStartupFp = reportStartup;
msgCb.sendReqFp = sendReq;
msgCb.sendRspFp = sendRsp;
msgCb.mgmt = (SMgmtWrapper *)(&msgCb); // hack
tmsgSetDefault(&msgCb);
walInit();
syncInit();
SMnodeOpt opt = {.msgCb = msgCb};
SMnode *pMnode = mndOpen(TMP_MNODE_DIR, &opt);
if (pMnode == NULL) return -1;
SSdb *pSdb = pMnode->pSdb;
SJson *json = tjsonCreateObject();
dumpHeader(pSdb, json);
dumpFunc(pSdb, json);
dumpDb(pSdb, json);
dumpStb(pSdb, json);
dumpSma(pSdb, json);
dumpVgroup(pSdb, json);
dumpTopic(pSdb, json);
dumpConsumber(pSdb, json);
dumpSubscribe(pSdb, json);
dumpOffset(pSdb, json);
dumpStream(pSdb, json);
dumpAcct(pSdb, json);
dumpAuth(pSdb, json);
dumpUser(pSdb, json);
dumpDnode(pSdb, json);
dumpBnode(pSdb, json);
dumpSnode(pSdb, json);
dumpQnode(pSdb, json);
dumpMnode(pSdb, json);
dumpCluster(pSdb, json);
dumpTrans(pSdb, json);
char *pCont = tjsonToString(json);
int32_t contLen = strlen(pCont);
char file[] = "sdb.json";
TdFilePtr pFile = taosOpenFile(file, TD_FILE_CREATE | TD_FILE_WRITE | TD_FILE_TRUNC);
if (pFile == NULL) {
terrno = TAOS_SYSTEM_ERROR(errno);
dError("failed to write %s since %s", file, terrstr());
return -1;
}
taosWriteFile(pFile, pCont, contLen);
taosWriteFile(pFile, "\n", 1);
taosFsyncFile(pFile);
taosCloseFile(&pFile);
tjsonDelete(json);
taosMemoryFree(pCont);
taosRemoveDir(TMP_DNODE_DIR);
return 0;
}
int32_t parseArgs(int32_t argc, char *argv[]) {
for (int32_t i = 1; i < argc; ++i) {
if (strcmp(argv[i], "-c") == 0) {
if (i < argc - 1) {
if (strlen(argv[++i]) >= PATH_MAX) {
printf("config file path overflow");
return -1;
}
tstrncpy(configDir, argv[i], PATH_MAX);
} else {
printf("'-c' requires a parameter, default is %s\n", configDir);
return -1;
}
} else {
printf("-c Configuration directory. \n");
return -1;
}
}
if (taosCreateLog("dumplog", 1, configDir, NULL, NULL, NULL, NULL, 1) != 0) {
printf("failed to dump since init log error\n");
return -1;
}
if (taosInitCfg(configDir, NULL, NULL, NULL, NULL, 0) != 0) {
printf("failed to dump since read config error\n");
return -1;
}
char mnodeJson[PATH_MAX] = {0};
char dataFile[PATH_MAX] = {0};
char raftCfgFile[PATH_MAX] = {0};
char raftStoreFile[PATH_MAX] = {0};
snprintf(mnodeJson, PATH_MAX, "%s" TD_DIRSEP "mnode" TD_DIRSEP "mnode.json", tsDataDir);
snprintf(dataFile, PATH_MAX, "%s" TD_DIRSEP "mnode" TD_DIRSEP "data" TD_DIRSEP "sdb.data", tsDataDir);
snprintf(raftCfgFile, PATH_MAX, "%s" TD_DIRSEP "mnode" TD_DIRSEP "sync" TD_DIRSEP "raft_config.json", tsDataDir);
snprintf(raftStoreFile, PATH_MAX, "%s" TD_DIRSEP "mnode" TD_DIRSEP "sync" TD_DIRSEP "raft_store.json", tsDataDir);
char cmd[PATH_MAX * 2] = {0};
snprintf(cmd, sizeof(cmd), "rm -rf %s", TMP_DNODE_DIR);
system(cmd);
#ifdef WINDOWS
taosMulMkDir(TMP_SDB_DATA_DIR);
taosMulMkDir(TMP_SDB_SYNC_DIR);
snprintf(cmd, sizeof(cmd), "cp %s %s 2>nul", mnodeJson, TMP_SDB_MNODE_JSON);
system(cmd);
snprintf(cmd, sizeof(cmd), "cp %s %s 2>nul", dataFile, TMP_SDB_DATA_FILE);
system(cmd);
snprintf(cmd, sizeof(cmd), "cp %s %s 2>nul", raftCfgFile, TMP_SDB_RAFT_CFG_FILE);
system(cmd);
snprintf(cmd, sizeof(cmd), "cp %s %s 2>nul", raftStoreFile, TMP_SDB_RAFT_STORE_FILE);
system(cmd);
#else
snprintf(cmd, sizeof(cmd), "mkdir -p %s", TMP_SDB_DATA_DIR);
system(cmd);
snprintf(cmd, sizeof(cmd), "mkdir -p %s", TMP_SDB_SYNC_DIR);
system(cmd);
snprintf(cmd, sizeof(cmd), "cp %s %s 2>/dev/null", mnodeJson, TMP_SDB_MNODE_JSON);
system(cmd);
snprintf(cmd, sizeof(cmd), "cp %s %s 2>/dev/null", dataFile, TMP_SDB_DATA_FILE);
system(cmd);
snprintf(cmd, sizeof(cmd), "cp %s %s 2>/dev/null", raftCfgFile, TMP_SDB_RAFT_CFG_FILE);
system(cmd);
snprintf(cmd, sizeof(cmd), "cp %s %s 2>/dev/null", raftStoreFile, TMP_SDB_RAFT_STORE_FILE);
system(cmd);
#endif
strcpy(tsDataDir, TMP_DNODE_DIR);
return 0;
}
int32_t main(int32_t argc, char *argv[]) {
if (parseArgs(argc, argv) != 0) {
return -1;
}
return dumpSdb();
}
#pragma GCC diagnostic pop