feat:[TS-4897] virtual table (#30098)

* feat: [TS-4897] Support create/drop/alter/show/describe vtable

* feat: [TS-4897] Support vtable's query

* feat: [TS-4897] Support create virtual supertable

* feat: [TS-4897] Support explain analyze / where / count(*) and only select ts of vtable.

* feat: [TS-4897] Add create test and fix bugs

* feat: [TS-4897] Add alter/drop test and fix bugs

* feat: [TS-4897] Add describe/show test and fix bugs

* feat: [TS-4897] Add auth test and fix bugs

* feat: [TS-4897] Fix meta/catalog/cache bugs

* feat: [TS-4897] Support select tag from virtual child table

* feat: [TS-4897] Add select test and fix plenty of bugs

* feat: [TS-4897] Add optimize rule for vtable scan / support create vtable cross database / remove enterprise constraint / fix bugs.

* feat: [TS-4897] Fix 'schema is old'

* feat: [TS-4897] Support virtual stable query

* feat: [TS-4897] Add tests and Fix bugs

* feat: [TS-4897] resolve conflict.
This commit is contained in:
Jing Sima 2025-03-15 14:10:46 +08:00 committed by GitHub
parent 49f8f5ce0f
commit 410324746b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
198 changed files with 317511 additions and 783 deletions

View File

@ -372,90 +372,90 @@ This document details the server error codes that may be encountered when using
## parser
| Error Code | Description | Possible Error Scenarios or Reasons | Suggested Actions for Users |
| ---------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ |
| 0x80002600 | syntax error near | SQL syntax error | Check and correct the SQL statement |
| 0x80002601 | Incomplete SQL statement | Incomplete SQL statement | Check and correct the SQL statement |
| 0x80002602 | Invalid column name | Illegal or non-existent column name | Check and correct the SQL statement |
| 0x80002603 | Table does not exist | Table does not exist | Check and confirm the existence of the table in the SQL statement |
| 0x80002604 | Column ambiguously defined | Column (alias) redefined | Check and correct the SQL statement |
| 0x80002605 | Invalid value type | Illegal constant value | Check and correct the SQL statement |
| 0x80002608 | There mustn't be aggregation | Aggregation function used in illegal clause | Check and correct the SQL statement |
| 0x80002609 | ORDER BY item must be the number of a SELECT-list expression | Illegal position specified in Order by | Check and correct the SQL statement |
| 0x8000260A | Not a GROUP BY expression | Illegal group by statement | Check and correct the SQL statement |
| 0x8000260B | Not SELECTed expression | Illegal expression | Check and correct the SQL statement |
| 0x8000260C | Not a single-group group function | Illegal use of column and function | Check and correct the SQL statement |
| 0x8000260D | Tags number not matched | Mismatched number of tag columns | Check and correct the SQL statement |
| 0x8000260E | Invalid tag name | Invalid or non-existent tag name | Check and correct the SQL statement |
| 0x80002610 | Value is too long | Value length exceeds limit | Check and correct the SQL statement or API parameters |
| 0x80002611 | Password too short or empty | Password is empty or less than 8 chars | Use a valid password |
| 0x80002612 | Port should be an integer that is less than 65535 and greater than 0 | Illegal port number | Check and correct the port number |
| 0x80002613 | Endpoint should be in the format of 'fqdn:port' | Incorrect address format | Check and correct the address information |
| 0x80002614 | This statement is no longer supported | Feature has been deprecated | Refer to the feature documentation |
| 0x80002615 | Interval too small | Interval value exceeds the allowed minimum | Change the INTERVAL value |
| 0x80002616 | Database not specified | Database not specified | Specify the database for the current operation |
| 0x80002617 | Invalid identifier name | Illegal or invalid length ID | Check the names of related libraries, tables, columns, TAGs, etc. in the statement |
| 0x80002618 | Corresponding supertable not in this db | Supertable does not exist | Check if the corresponding supertable exists in the database |
| 0x80002619 | Invalid database option | Illegal database option value | Check and correct the database option values |
| 0x8000261A | Invalid table option | Illegal table option value | Check and correct the table option values |
| 0x80002624 | GROUP BY and WINDOW-clause can't be used together | Group by and window cannot be used together | Check and correct the SQL statement |
| 0x80002627 | Aggregate functions do not support nesting | Functions do not support nested use | Check and correct the SQL statement |
| 0x80002628 | Only support STATE_WINDOW on integer/bool/varchar column | Unsupported STATE_WINDOW data type | Check and correct the SQL statement |
| 0x80002629 | Not support STATE_WINDOW on tag column | STATE_WINDOW not supported on tag column | Check and correct the SQL statement |
| 0x8000262A | STATE_WINDOW not support for supertable query | STATE_WINDOW not supported for supertable | Check and correct the SQL statement |
| 0x8000262B | SESSION gap should be fixed time window, and greater than 0 | Illegal SESSION window value | Check and correct the SQL statement |
| 0x8000262C | Only support SESSION on primary timestamp column | Illegal SESSION window column | Check and correct the SQL statement |
| 0x8000262D | Interval offset cannot be negative | Illegal INTERVAL offset value | Check and correct the SQL statement |
| 0x8000262E | Cannot use 'year' as offset when interval is 'month' | Illegal INTERVAL offset unit | Check and correct the SQL statement |
| 0x8000262F | Interval offset should be shorter than interval | Illegal INTERVAL offset value | Check and correct the SQL statement |
| 0x80002630 | Does not support sliding when interval is natural month/year | Illegal sliding unit | Check and correct the SQL statement |
| 0x80002631 | sliding value no larger than the interval value | Illegal sliding value | Check and correct the SQL statement |
| 0x80002632 | sliding value can not less than 1%% of interval value | Illegal sliding value | Check and correct the SQL statement |
| 0x80002633 | Only one tag if there is a json tag | Only single JSON tag column supported | Check and correct the SQL statement |
| 0x80002634 | Query block has incorrect number of result columns | Mismatched number of columns | Check and correct the SQL statement |
| 0x80002635 | Incorrect TIMESTAMP value | Illegal primary timestamp column value | Check and correct the SQL statement |
| 0x80002637 | soffset/offset can not be less than 0 | Illegal soffset/offset value | Check and correct the SQL statement |
| 0x80002638 | slimit/soffset only available for PARTITION/GROUP BY query | slimit/soffset only supported for PARTITION BY/GROUP BY statements | Check and correct the SQL statement |
| 0x80002639 | Invalid topic query | Unsupported TOPIC query | |
| 0x8000263A | Cannot drop supertable in batch | Batch deletion of supertables not supported | Check and correct the SQL statement |
| 0x8000263B | Start(end) time of query range required or time range too large | Window count exceeds limit | Check and correct the SQL statement |
| 0x8000263C | Duplicated column names | Duplicate column names | Check and correct the SQL statement |
| 0x8000263D | Tags length exceeds max length | tag value length exceeds maximum supported range | Check and correct the SQL statement |
| 0x8000263E | Row length exceeds max length | Row length check and correct SQL statement | Check and correct the SQL statement |
| 0x8000263F | Illegal number of columns | Incorrect number of columns | Check and correct the SQL statement |
| 0x80002640 | Too many columns | Number of columns exceeds limit | Check and correct the SQL statement |
| 0x80002641 | First column must be timestamp | The first column must be the primary timestamp column | Check and correct the SQL statement |
| 0x80002642 | Invalid binary/nchar column/tag length | Incorrect length for binary/nchar | Check and correct the SQL statement |
| 0x80002643 | Invalid number of tag columns | Incorrect number of tag columns | Check and correct the SQL statement |
| 0x80002644 | Permission denied | Permission error | Check and confirm user permissions |
| 0x80002645 | Invalid stream query | Illegal stream statement | Check and correct the SQL statement |
| 0x80002646 | Invalid _c0 or_rowts expression | Illegal use of _c0 or_rowts | Check and correct the SQL statement |
| 0x80002647 | Invalid timeline function | Function depends on non-existent primary timestamp | Check and correct the SQL statement |
| 0x80002648 | Invalid password | Password does not meet standards | Check and change the password |
| 0x80002649 | Invalid alter table statement | Illegal modify table statement | Check and correct the SQL statement |
| 0x8000264A | Primary timestamp column cannot be dropped | Primary timestamp column cannot be deleted | Check and correct the SQL statement |
| 0x8000264B | Only binary/nchar column length could be modified, and the length can only be increased, not decreased | Illegal column modification | Check and correct the SQL statement |
| 0x8000264C | Invalid tbname pseudocolumn | Illegal use of tbname column | Check and correct the SQL statement |
| 0x8000264D | Invalid function name | Illegal function name | Check and correct the function name |
| 0x8000264E | Comment too long | Comment length exceeds limit | Check and correct the SQL statement |
| 0x8000264F | Function(s) only allowed in SELECT list, cannot mixed with non scalar functions or columns | Illegal mixing of functions | Check and correct the SQL statement |
| 0x80002650 | Window query not supported, since no valid timestamp column included in the result of subquery | Window query depends on non-existent primary timestamp column | Check and correct the SQL statement |
| 0x80002651 | No columns can be dropped | Essential columns cannot be deleted | Check and correct the SQL statement |
| 0x80002652 | Only tag can be json type | Normal columns do not support JSON type | Check and correct the SQL statement |
| 0x80002655 | The DELETE statement must have a definite time window range | Illegal WHERE condition in DELETE statement | Check and correct the SQL statement |
| 0x80002656 | The REDISTRIBUTE VGROUP statement only support 1 to 3 dnodes | Illegal number of DNODEs specified in REDISTRIBUTE VGROUP | Check and correct the SQL statement |
| 0x80002657 | Fill now allowed | Function does not allow FILL feature | Check and correct the SQL statement |
| 0x80002658 | Invalid windows pc | Illegal use of window pseudocolumn | Check and correct the SQL statement |
| 0x80002659 | Window not allowed | Function cannot be used in window | Check and correct the SQL statement |
| 0x8000265A | Stream not allowed | Function cannot be used in stream computation | Check and correct the SQL statement |
| 0x8000265B | Group by not allowd | Function cannot be used in grouping | Check and correct the SQL statement |
| 0x8000265D | Invalid interp clause | Illegal INTERP or related statement | Check and correct the SQL statement |
| 0x8000265E | Not valid function ion window | Illegal window statement | Check and correct the SQL statement |
| 0x8000265F | Only support single table | Function only supported in single table queries | Check and correct the SQL statement |
| 0x80002660 | Invalid sma index | Illegal creation of SMA statement | Check and correct the SQL statement |
| 0x80002661 | Invalid SELECTed expression | Invalid query statement | Check and correct the SQL statement |
| 0x80002662 | Fail to get table info | Failed to retrieve table metadata information | Preserve the scene and logs, report issue on GitHub |
| 0x80002663 | Not unique table/alias | Table name (alias) conflict | Check and correct the SQL statement |
| Error Code | Description | Possible Error Scenarios or Reasons | Suggested Actions for Users |
|------------| ------------------------------------------------------------ |----------------------------------------------------------------------------| ------------------------------------------------------------ |
| 0x80002600 | syntax error near | SQL syntax error | Check and correct the SQL statement |
| 0x80002601 | Incomplete SQL statement | Incomplete SQL statement | Check and correct the SQL statement |
| 0x80002602 | Invalid column name | Illegal or non-existent column name | Check and correct the SQL statement |
| 0x80002603 | Table does not exist | Table does not exist | Check and confirm the existence of the table in the SQL statement |
| 0x80002604 | Column ambiguously defined | Column (alias) redefined | Check and correct the SQL statement |
| 0x80002605 | Invalid value type | Illegal constant value | Check and correct the SQL statement |
| 0x80002608 | There mustn't be aggregation | Aggregation function used in illegal clause | Check and correct the SQL statement |
| 0x80002609 | ORDER BY item must be the number of a SELECT-list expression | Illegal position specified in Order by | Check and correct the SQL statement |
| 0x8000260A | Not a GROUP BY expression | Illegal group by statement | Check and correct the SQL statement |
| 0x8000260B | Not SELECTed expression | Illegal expression | Check and correct the SQL statement |
| 0x8000260C | Not a single-group group function | Illegal use of column and function | Check and correct the SQL statement |
| 0x8000260D | Tags number not matched | Mismatched number of tag columns | Check and correct the SQL statement |
| 0x8000260E | Invalid tag name | Invalid or non-existent tag name | Check and correct the SQL statement |
| 0x80002610 | Value is too long | Value length exceeds limit | Check and correct the SQL statement or API parameters |
| 0x80002611 | Password too short or empty | Password is empty or less than 8 chars | Use a valid password |
| 0x80002612 | Port should be an integer that is less than 65535 and greater than 0 | Illegal port number | Check and correct the port number |
| 0x80002613 | Endpoint should be in the format of 'fqdn:port' | Incorrect address format | Check and correct the address information |
| 0x80002614 | This statement is no longer supported | Feature has been deprecated | Refer to the feature documentation |
| 0x80002615 | Interval too small | Interval value exceeds the allowed minimum | Change the INTERVAL value |
| 0x80002616 | Database not specified | Database not specified | Specify the database for the current operation |
| 0x80002617 | Invalid identifier name | Illegal or invalid length ID | Check the names of related libraries, tables, columns, TAGs, etc. in the statement |
| 0x80002618 | Corresponding supertable not in this db | Supertable does not exist | Check if the corresponding supertable exists in the database |
| 0x80002619 | Invalid database option | Illegal database option value | Check and correct the database option values |
| 0x8000261A | Invalid table option | Illegal table option value | Check and correct the table option values |
| 0x80002624 | GROUP BY and WINDOW-clause can't be used together | Group by and window cannot be used together | Check and correct the SQL statement |
| 0x80002627 | Aggregate functions do not support nesting | Functions do not support nested use | Check and correct the SQL statement |
| 0x80002628 | Only support STATE_WINDOW on integer/bool/varchar column | Unsupported STATE_WINDOW data type | Check and correct the SQL statement |
| 0x80002629 | Not support STATE_WINDOW on tag column | STATE_WINDOW not supported on tag column | Check and correct the SQL statement |
| 0x8000262A | STATE_WINDOW not support for supertable query | STATE_WINDOW not supported for supertable | Check and correct the SQL statement |
| 0x8000262B | SESSION gap should be fixed time window, and greater than 0 | Illegal SESSION window value | Check and correct the SQL statement |
| 0x8000262C | Only support SESSION on primary timestamp column | Illegal SESSION window column | Check and correct the SQL statement |
| 0x8000262D | Interval offset cannot be negative | Illegal INTERVAL offset value | Check and correct the SQL statement |
| 0x8000262E | Cannot use 'year' as offset when interval is 'month' | Illegal INTERVAL offset unit | Check and correct the SQL statement |
| 0x8000262F | Interval offset should be shorter than interval | Illegal INTERVAL offset value | Check and correct the SQL statement |
| 0x80002630 | Does not support sliding when interval is natural month/year | Illegal sliding unit | Check and correct the SQL statement |
| 0x80002631 | sliding value no larger than the interval value | Illegal sliding value | Check and correct the SQL statement |
| 0x80002632 | sliding value can not less than 1%% of interval value | Illegal sliding value | Check and correct the SQL statement |
| 0x80002633 | Only one tag if there is a json tag | Only single JSON tag column supported | Check and correct the SQL statement |
| 0x80002634 | Query block has incorrect number of result columns | Mismatched number of columns | Check and correct the SQL statement |
| 0x80002635 | Incorrect TIMESTAMP value | Illegal primary timestamp column value | Check and correct the SQL statement |
| 0x80002637 | soffset/offset can not be less than 0 | Illegal soffset/offset value | Check and correct the SQL statement |
| 0x80002638 | slimit/soffset only available for PARTITION/GROUP BY query | slimit/soffset only supported for PARTITION BY/GROUP BY statements | Check and correct the SQL statement |
| 0x80002639 | Invalid topic query | Unsupported TOPIC query | |
| 0x8000263A | Cannot drop supertable in batch | Batch deletion of supertables not supported | Check and correct the SQL statement |
| 0x8000263B | Start(end) time of query range required or time range too large | Window count exceeds limit | Check and correct the SQL statement |
| 0x8000263C | Duplicated column names | Duplicate column names | Check and correct the SQL statement |
| 0x8000263D | Tags length exceeds max length | tag value length exceeds maximum supported range | Check and correct the SQL statement |
| 0x8000263E | Row length exceeds max length | Row length check and correct SQL statement | Check and correct the SQL statement |
| 0x8000263F | Illegal number of columns | Incorrect number of columns | Check and correct the SQL statement |
| 0x80002640 | Too many columns | Number of columns exceeds limit | Check and correct the SQL statement |
| 0x80002641 | First column must be timestamp | The first column must be the primary timestamp column | Check and correct the SQL statement |
| 0x80002642 | Invalid binary/nchar column/tag length | Incorrect length for binary/nchar | Check and correct the SQL statement |
| 0x80002643 | Invalid number of tag columns | Incorrect number of tag columns | Check and correct the SQL statement |
| 0x80002644 | Permission denied | Permission error | Check and confirm user permissions |
| 0x80002645 | Invalid stream query | Illegal stream statement | Check and correct the SQL statement |
| 0x80002646 | Invalid _c0 or_rowts expression | Illegal use of _c0 or_rowts | Check and correct the SQL statement |
| 0x80002647 | Invalid timeline function | Function depends on non-existent primary timestamp | Check and correct the SQL statement |
| 0x80002648 | Invalid password | Password does not meet standards | Check and change the password |
| 0x80002649 | Invalid alter table statement | Illegal modify table statement | Check and correct the SQL statement |
| 0x8000264A | Primary timestamp column cannot be dropped | Primary timestamp column cannot be deleted | Check and correct the SQL statement |
| 0x8000264B | Only binary/nchar column length could be modified, and the length can only be increased, not decreased | Illegal column modification | Check and correct the SQL statement |
| 0x8000264C | Invalid tbname pseudocolumn | Illegal use of tbname column | Check and correct the SQL statement |
| 0x8000264D | Invalid function name | Illegal function name | Check and correct the function name |
| 0x8000264E | Comment too long | Comment length exceeds limit | Check and correct the SQL statement |
| 0x8000264F | Function(s) only allowed in SELECT list, cannot mixed with non scalar functions or columns | Illegal mixing of functions | Check and correct the SQL statement |
| 0x80002650 | Window query not supported, since no valid timestamp column included in the result of subquery | Window query depends on non-existent primary timestamp column | Check and correct the SQL statement |
| 0x80002651 | No columns can be dropped | Essential columns cannot be deleted | Check and correct the SQL statement |
| 0x80002652 | Only tag can be json type | Normal columns do not support JSON type | Check and correct the SQL statement |
| 0x80002655 | The DELETE statement must have a definite time window range | Illegal WHERE condition in DELETE statement | Check and correct the SQL statement |
| 0x80002656 | The REDISTRIBUTE VGROUP statement only support 1 to 3 dnodes | Illegal number of DNODEs specified in REDISTRIBUTE VGROUP | Check and correct the SQL statement |
| 0x80002657 | Fill now allowed | Function does not allow FILL feature | Check and correct the SQL statement |
| 0x80002658 | Invalid windows pc | Illegal use of window pseudocolumn | Check and correct the SQL statement |
| 0x80002659 | Window not allowed | Function cannot be used in window | Check and correct the SQL statement |
| 0x8000265A | Stream not allowed | Function cannot be used in stream computation | Check and correct the SQL statement |
| 0x8000265B | Group by not allowd | Function cannot be used in grouping | Check and correct the SQL statement |
| 0x8000265D | Invalid interp clause | Illegal INTERP or related statement | Check and correct the SQL statement |
| 0x8000265E | Not valid function ion window | Illegal window statement | Check and correct the SQL statement |
| 0x8000265F | Only support single table | Function only supported in single table queries | Check and correct the SQL statement |
| 0x80002660 | Invalid sma index | Illegal creation of SMA statement | Check and correct the SQL statement |
| 0x80002661 | Invalid SELECTed expression | Invalid query statement | Check and correct the SQL statement |
| 0x80002662 | Fail to get table info | Failed to retrieve table metadata information | Preserve the scene and logs, report issue on GitHub |
| 0x80002663 | Not unique table/alias | Table name (alias) conflict | Check and correct the SQL statement |
| 0x80002664 | Join requires valid time-series input | Unsupported JOIN query without primary timestamp column output in subquery | Check and correct the SQL statement |
| 0x80002665 | The _TAGS pseudocolumn can only be used for subtable and supertable queries | Illegal tag column query | Check and correct the SQL statement |
| 0x80002666 | Subquery does not output primary timestamp column | Check and correct the SQL statement | |
@ -466,10 +466,17 @@ This document details the server error codes that may be encountered when using
| 0x8000268A | Cols function's first param must be a select function that output a single row | The first parameter of the cols function should be a selection function | Check and correct the SQL statement |
| 0x8000268B | Invalid using alias for cols function | Illegal cols function alias | Check and correct the SQL statement |
| 0x8000268C | Join primary key col must be timestmap type | Join primary key data type error | Check and correct the SQL statement |
| 0x8000268D | Invalid virtual table's ref column | Create/Update Virtual table using incorrect data source column | Check and correct the SQL statement |
| 0x8000268E | Invalid table type | Incorrect Table type | Check and correct the SQL statement |
| 0x8000268F | Invalid ref column type | Virtual table's column type and data source column's type are different | Check and correct the SQL statement |
| 0x80002690 | Create child table using virtual super table | Create non-virtual child table using virtual super table | Check and correct the SQL statement |
| 0x800026FF | Parser internal error | Internal error in parser | Preserve the scene and logs, report issue on GitHub |
| 0x80002700 | Planner internal error | Internal error in planner | Preserve the scene and logs, report issue on GitHub |
| 0x80002701 | Expect ts equal | JOIN condition validation failed | Preserve the scene and logs, report issue on GitHub |
| 0x80002702 | Cross join not support | CROSS JOIN not supported | Check and correct the SQL statement |
| 0x80002704 | Planner slot key not found | Planner cannot find slotId during making physic plan | Preserve the scene and logs, report issue on GitHub |
| 0x80002705 | Planner invalid table type | Planner get invalid table type | Preserve the scene and logs, report issue on GitHub |
| 0x80002706 | Planner invalid query control plan type | Planner get invalid query control plan type during making physic plan | Preserve the scene and logs, report issue on GitHub |
## function
@ -547,3 +554,12 @@ This document details the server error codes that may be encountered when using
| 0x80004017 | Invalid status, please subscribe topic first | tmq status invalidate | Without calling subscribe, directly poll data |
| 0x80004100 | Stream task not exist | The stream computing task does not exist | Check the server-side error logs |
## virtual table
| Error Code | Description | Possible Error Scenarios or Reasons | Recommended Actions for Users |
|-------------|---------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------|
| 0x80006200 | Virtual table scan internal error | virtual table scan operator internal error, generally does not occur | Check error logs, contact development for handling |
| 0x80006201 | Virtual table scan invalid downstream operator type | The incorrect execution plan generated causes the downstream operator type of the virtual table scan operator to be incorrect. | Check error logs, contact development for handling |
| 0x80006202 | Virtual table prim timestamp column should not has ref | The timestamp primary key column of a virtual table should not have a data source. If it does, this error will occur during subsequent queries on the virtual table. | Check error logs, contact development for handling |
| 0x80006203 | Create virtual child table must use virtual super table | Create virtual child table using non-virtual super table | create virtual child table using virtual super table |

View File

@ -389,63 +389,63 @@ description: TDengine 服务端的错误码列表和详细说明
## parser
| 错误码 | 错误描述 | 可能的出错场景或者可能的原因 | 建议用户采取的措施 |
| ---------- | ------------------------------------------------------------------------------------------------------ | --------------------------------------------- | ------------------------------------- |
| 0x80002600 | syntax error near | SQL 语法错误 | 检查并修正 SQL 语句 |
| 0x80002601 | Incomplete SQL statement | 不完整的 SQL 语句 | 检查并修正 SQL 语句 |
| 0x80002602 | Invalid column name | 不合法或不存在的列名 | 检查并修正 SQL 语句 |
| 0x80002603 | Table does not exist | 表不存在 | 检查并确认SQL语句中的表是否存在 |
| 0x80002604 | Column ambiguously defined | 列名(别名)重复定义 | 检查并修正 SQL 语句 |
| 0x80002605 | Invalid value type | 常量值非法 | 检查并修正 SQL 语句 |
| 0x80002608 | There mustn't be aggregation | 聚合函数出现在非法子句中 | 检查并修正 SQL 语句 |
| 0x80002609 | ORDER BY item must be the number of a SELECT-list expression | Order by 指定的位置不合法 | 检查并修正 SQL 语句 |
| 错误码 | 错误描述 | 可能的出错场景或者可能的原因 | 建议用户采取的措施 |
|------------| ------------------------------------------------------------------------------------------------------ |---------------------------------------------| ------------------------------------- |
| 0x80002600 | syntax error near | SQL 语法错误 | 检查并修正 SQL 语句 |
| 0x80002601 | Incomplete SQL statement | 不完整的 SQL 语句 | 检查并修正 SQL 语句 |
| 0x80002602 | Invalid column name | 不合法或不存在的列名 | 检查并修正 SQL 语句 |
| 0x80002603 | Table does not exist | 表不存在 | 检查并确认SQL语句中的表是否存在 |
| 0x80002604 | Column ambiguously defined | 列名(别名)重复定义 | 检查并修正 SQL 语句 |
| 0x80002605 | Invalid value type | 常量值非法 | 检查并修正 SQL 语句 |
| 0x80002608 | There mustn't be aggregation | 聚合函数出现在非法子句中 | 检查并修正 SQL 语句 |
| 0x80002609 | ORDER BY item must be the number of a SELECT-list expression | Order by 指定的位置不合法 | 检查并修正 SQL 语句 |
| 0x8000260A | Not a GROUP BY expression | 非法 group by 语句 | 检查并修正 SQL 语句 |
| 0x8000260B | Not SELECTed expression | 非法表达式 | 检查并修正 SQL 语句 |
| 0x8000260C | Not a single-group group function | 非法使用列与函数 | 检查并修正 SQL 语句 |
| 0x8000260D | Tags number not matched | tag 列个数不匹配 | 检查并修正 SQL 语句 |
| 0x8000260E | Invalid tag name | 无效或不存在的 tag 名 | 检查并修正 SQL 语句 |
| 0x80002610 | Value is too long | 值长度超出限制 | 检查并修正 SQL 语句或 API 参数 |
| 0x80002611 | Password too short or empty | 密码为空或少于 8 个字符 | 使用合法的密码 |
| 0x80002612 | Port should be an integer that is less than 65535 and greater than 0 | 端口号非法 | 检查并修正端口号 |
| 0x80002613 | Endpoint should be in the format of 'fqdn:port' | 地址格式错误 | 检查并修正地址信息 |
| 0x80002614 | This statement is no longer supported | 功能已经废弃 | 参考功能文档说明 |
| 0x80002615 | Interval too small | interval 值超过允许的最小值 | 更改 INTERVAL 值 |
| 0x80002616 | Database not specified | 未指定数据库 | 指定当前操作的数据库 |
| 0x80002617 | Invalid identifier name | ID 非法或长度不合法 | 检查语句中相关的库、表、列、TAG 等名称 |
| 0x80002618 | Corresponding super table not in this db | 超级表不存在 | 检查库中是否存在对应的超级表 |
| 0x80002619 | Invalid database option | 数据库选项值非法 | 检查并修正数据库选项值 |
| 0x8000261A | Invalid table option | 表选项值非法 | 检查并修正数据表选项值 |
| 0x80002624 | GROUP BY and WINDOW-clause can't be used together | Group by 和窗口不能同时使用 | 检查并修正 SQL 语句 |
| 0x80002627 | Aggregate functions do not support nesting | 函数不支持嵌套使用 | 检查并修正 SQL 语句 |
| 0x80002628 | Only support STATE_WINDOW on integer/bool/varchar column | 不支持的 STATE_WINDOW 数据类型 | 检查并修正 SQL 语句 |
| 0x8000260B | Not SELECTed expression | 非法表达式 | 检查并修正 SQL 语句 |
| 0x8000260C | Not a single-group group function | 非法使用列与函数 | 检查并修正 SQL 语句 |
| 0x8000260D | Tags number not matched | tag 列个数不匹配 | 检查并修正 SQL 语句 |
| 0x8000260E | Invalid tag name | 无效或不存在的 tag 名 | 检查并修正 SQL 语句 |
| 0x80002610 | Value is too long | 值长度超出限制 | 检查并修正 SQL 语句或 API 参数 |
| 0x80002611 | Password too short or empty | 密码为空或少于 8 个字符 | 使用合法的密码 |
| 0x80002612 | Port should be an integer that is less than 65535 and greater than 0 | 端口号非法 | 检查并修正端口号 |
| 0x80002613 | Endpoint should be in the format of 'fqdn:port' | 地址格式错误 | 检查并修正地址信息 |
| 0x80002614 | This statement is no longer supported | 功能已经废弃 | 参考功能文档说明 |
| 0x80002615 | Interval too small | interval 值超过允许的最小值 | 更改 INTERVAL 值 |
| 0x80002616 | Database not specified | 未指定数据库 | 指定当前操作的数据库 |
| 0x80002617 | Invalid identifier name | ID 非法或长度不合法 | 检查语句中相关的库、表、列、TAG 等名称 |
| 0x80002618 | Corresponding super table not in this db | 超级表不存在 | 检查库中是否存在对应的超级表 |
| 0x80002619 | Invalid database option | 数据库选项值非法 | 检查并修正数据库选项值 |
| 0x8000261A | Invalid table option | 表选项值非法 | 检查并修正数据表选项值 |
| 0x80002624 | GROUP BY and WINDOW-clause can't be used together | Group by 和窗口不能同时使用 | 检查并修正 SQL 语句 |
| 0x80002627 | Aggregate functions do not support nesting | 函数不支持嵌套使用 | 检查并修正 SQL 语句 |
| 0x80002628 | Only support STATE_WINDOW on integer/bool/varchar column | 不支持的 STATE_WINDOW 数据类型 | 检查并修正 SQL 语句 |
| 0x80002629 | Not support STATE_WINDOW on tag column | 不支持 TAG 列的 STATE_WINDOW | 检查并修正 SQL 语句 |
| 0x8000262A | STATE_WINDOW not support for super table query | 不支持超级表的 STATE_WINDOW | 检查并修正 SQL 语句 |
| 0x8000262B | SESSION gap should be fixed time window, and greater than 0 | SESSION 窗口值非法 | 检查并修正 SQL 语句 |
| 0x8000262C | Only support SESSION on primary timestamp column | SESSION 窗口列非法 | 检查并修正 SQL 语句 |
| 0x8000262D | Interval offset cannot be negative | INTERVAL offset值非法 | 检查并修正 SQL 语句 |
| 0x8000262E | Cannot use 'year' as offset when interval is 'month' | INTERVAL offset单位非法 | 检查并修正 SQL 语句 |
| 0x8000262F | Interval offset should be shorter than interval | INTERVAL offset值非法 | 检查并修正 SQL 语句 |
| 0x80002630 | Does not support sliding when interval is natural month/year | sliding 单位非法 | 检查并修正 SQL 语句 |
| 0x8000262A | STATE_WINDOW not support for super table query | 不支持超级表的 STATE_WINDOW | 检查并修正 SQL 语句 |
| 0x8000262B | SESSION gap should be fixed time window, and greater than 0 | SESSION 窗口值非法 | 检查并修正 SQL 语句 |
| 0x8000262C | Only support SESSION on primary timestamp column | SESSION 窗口列非法 | 检查并修正 SQL 语句 |
| 0x8000262D | Interval offset cannot be negative | INTERVAL offset值非法 | 检查并修正 SQL 语句 |
| 0x8000262E | Cannot use 'year' as offset when interval is 'month' | INTERVAL offset单位非法 | 检查并修正 SQL 语句 |
| 0x8000262F | Interval offset should be shorter than interval | INTERVAL offset值非法 | 检查并修正 SQL 语句 |
| 0x80002630 | Does not support sliding when interval is natural month/year | sliding 单位非法 | 检查并修正 SQL 语句 |
| 0x80002631 | sliding value no larger than the interval value | sliding 值非法 | 检查并修正 SQL 语句 |
| 0x80002632 | sliding value can not less than 1%% of interval value | sliding 值非法 | 检查并修正 SQL 语句 |
| 0x80002633 | Only one tag if there is a json tag | 只支持单个 JSON TAG 列 | 检查并修正 SQL 语句 |
| 0x80002634 | Query block has incorrect number of result columns | 列个数不匹配 | 检查并修正 SQL 语句 |
| 0x80002635 | Incorrect TIMESTAMP value | 主键时间戳列值非法 | 检查并修正 SQL 语句 |
| 0x80002633 | Only one tag if there is a json tag | 只支持单个 JSON TAG 列 | 检查并修正 SQL 语句 |
| 0x80002634 | Query block has incorrect number of result columns | 列个数不匹配 | 检查并修正 SQL 语句 |
| 0x80002635 | Incorrect TIMESTAMP value | 主键时间戳列值非法 | 检查并修正 SQL 语句 |
| 0x80002637 | soffset/offset can not be less than 0 | soffset/offset 值非法 | 检查并修正 SQL 语句 |
| 0x80002638 | slimit/soffset only available for PARTITION/GROUP BY query | slimit/soffset 只支持 PARTITION BY/GROUP BY 语句 | 检查并修正 SQL 语句 |
| 0x80002639 | Invalid topic query | 不支持的 TOPIC 查询语法 |
| 0x8000263A | Cannot drop super table in batch | 不支持批量删除超级表 | 检查并修正 SQL 语句 |
| 0x8000263B | Start(end) time of query range required or time range too large | 窗口个数超出限制 | 检查并修正 SQL 语句 |
| 0x8000263C | Duplicated column names | 列名称重复 | 检查并修正 SQL 语句 |
| 0x8000263D | Tags length exceeds max length | TAG 值长度超出最大支持范围 | 检查并修正 SQL 语句 |
| 0x8000263E | Row length exceeds max length | 行长度检查并修正 SQL 语句 | 检查并修正 SQL 语句 |
| 0x8000263F | Illegal number of columns | 列个数错误 | 检查并修正 SQL 语句 |
| 0x80002640 | Too many columns | 列个数超出上限 | 检查并修正 SQL 语句 |
| 0x80002641 | First column must be timestamp | 第一列必须是主键时间戳列 | 检查并修正 SQL 语句 |
| 0x80002642 | Invalid binary/nchar column/tag length | binary/nchar 长度错误 | 检查并修正 SQL 语句 |
| 0x80002643 | Invalid number of tag columns | TAG 列个数错误 | 检查并修正 SQL 语句 |
| 0x80002644 | Permission denied | 权限错误 | 检查确认用户是否有相应操作权限 |
| 0x80002645 | Invalid stream query | 非法流语句 | 检查并修正 SQL 语句 |
| 0x80002639 | Invalid topic query | 不支持的 TOPIC 查询语法 |
| 0x8000263A | Cannot drop super table in batch | 不支持批量删除超级表 | 检查并修正 SQL 语句 |
| 0x8000263B | Start(end) time of query range required or time range too large | 窗口个数超出限制 | 检查并修正 SQL 语句 |
| 0x8000263C | Duplicated column names | 列名称重复 | 检查并修正 SQL 语句 |
| 0x8000263D | Tags length exceeds max length | TAG 值长度超出最大支持范围 | 检查并修正 SQL 语句 |
| 0x8000263E | Row length exceeds max length | 行长度检查并修正 SQL 语句 | 检查并修正 SQL 语句 |
| 0x8000263F | Illegal number of columns | 列个数错误 | 检查并修正 SQL 语句 |
| 0x80002640 | Too many columns | 列个数超出上限 | 检查并修正 SQL 语句 |
| 0x80002641 | First column must be timestamp | 第一列必须是主键时间戳列 | 检查并修正 SQL 语句 |
| 0x80002642 | Invalid binary/nchar column/tag length | binary/nchar 长度错误 | 检查并修正 SQL 语句 |
| 0x80002643 | Invalid number of tag columns | TAG 列个数错误 | 检查并修正 SQL 语句 |
| 0x80002644 | Permission denied | 权限错误 | 检查确认用户是否有相应操作权限 |
| 0x80002645 | Invalid stream query | 非法流语句 | 检查并修正 SQL 语句 |
| 0x80002646 | Invalid _c0 or _rowts expression | _c0 或 _rowts 非法使用 | 检查并修正 SQL 语句 |
| 0x80002647 | Invalid timeline function | 函数依赖的主键时间戳不存在 | 检查并修正 SQL 语句 |
| 0x80002648 | Invalid password | 密码不符合规范 | 检查并修改密码 |
@ -483,11 +483,17 @@ description: TDengine 服务端的错误码列表和详细说明
| 0x8000268A | Cols function's first param must be a select function that output a single row | cols 函数第一个参数应该为选择函数 | 检查并修正 SQL 语句 |
| 0x8000268B | Invalid using alias for cols function | cols 函数输出列重命名错误 | 检查并修正 SQL 语句 |
| 0x8000268C | Join primary key col must be timestmap type | 关联查询主键列等值条件类型错误 | 检查并修正 SQL 语句 |
| 0x8000268D | Invalid virtual table's ref column | 创建/更新虚拟表时数据源列不正确 | 检查并修正SQL语句 |
| 0x8000268E | Invalid table type | 表类型不正确 | 检查并修正SQL语句 |
| 0x8000268F | Invalid ref column type | 虚拟表列的数据类型与数据源的数据类型不同 | 检查并修正SQL语句 |
| 0x80002690 | Create child table using virtual super table | 创建非虚拟子表 USING 了虚拟超级表 | 检查并修正SQL语句 |
| 0x800026FF | Parser internal error | 解析器内部错误 | 保留现场和日志github上报issue |
| 0x80002700 | Planner internal error | 计划期内部错误 | 保留现场和日志github上报issue |
| 0x80002701 | Expect ts equal | JOIN 条件校验失败 | 保留现场和日志github上报issue |
| 0x80002702 | Cross join not support | 不支持 CROSS JOIN | 检查并修正 SQL 语句 |
| 0x80002704 | Planner slot key not found | 生成物理计划时查找不到 slotId | 保留现场和日志github上报issue |
| 0x80002705 | Planner invalid table type | 计划器生成计划时得到了错误的表类型 | 保留现场和日志github上报issue |
| 0x80002706 | Planner invalid query control plan type | 计划器生成 dynamic query control 计划时得到的类型不正确 | 保留现场和日志github上报issue |
## function
@ -567,3 +573,13 @@ description: TDengine 服务端的错误码列表和详细说明
| 0x80004017 | Invalid status, please subscribe topic first | 数据订阅状态不对 | 没有调用 subscribe直接 poll 数据 |
| 0x80004100 | Stream task not exist | 流计算任务不存在 | 具体查看 server 端的错误日志 |
## virtual table
| 错误码 | 错误描述 | 可能的出错场景或者可能的原因 | 建议用户采取的措施 |
|------------|---------------------------------------------------------|------------------------------------------------|------------------------|
| 0x80006200 | Virtual table scan 算子内部错误 | virtual table scan 算子内部逻辑错误,一般不会出现 | 具体查看client端的错误日志提示 |
| 0x80006201 | Virtual table scan invalid downstream operator type | 由于生成的执行计划不对,导致 virtual table scan 算子的下游算子类型不正确 | 保留 explain 执行计划,联系开发处理 |
| 0x80006202 | Virtual table prim timestamp column should not has ref | 虚拟表的时间戳主键列不应该有数据源,如果有,后续查询虚拟表的时候就会出现该错误 | 检查错误日志,联系开发处理 |
| 0x80006203 | Create virtual child table must use virtual super table | 虚拟子表必须建在虚拟超级表下,否则就会出现该错误 | 创建虚拟子表的时候USING 虚拟超级表 |

View File

@ -39,7 +39,9 @@ typedef enum {
TSDB_SYSTEM_TABLE = 5,
TSDB_TSMA_TABLE = 6, // time-range-wise sma
TSDB_VIEW_TABLE = 7,
TSDB_TABLE_MAX = 8
TSDB_VIRTUAL_NORMAL_TABLE = 8,
TSDB_VIRTUAL_CHILD_TABLE = 9,
TSDB_TABLE_MAX = 10
} ETableType;
typedef enum {

View File

@ -80,6 +80,7 @@ uint8_t columnEncodeVal(const char* encode);
uint16_t columnCompressVal(const char* compress);
bool withExtSchema(uint8_t tableType);
bool hasRefCol(uint8_t tableType);
bool checkColumnEncode(char encode[TSDB_CL_COMPRESS_OPTION_LEN]);
bool checkColumnEncodeOrSetDefault(uint8_t type, char encode[TSDB_CL_COMPRESS_OPTION_LEN]);
bool checkColumnCompress(char compress[TSDB_CL_COMPRESS_OPTION_LEN]);

View File

@ -267,6 +267,8 @@ int32_t createDataBlock(SSDataBlock** pResBlock);
void blockDataDestroy(SSDataBlock* pBlock);
void blockDataFreeRes(SSDataBlock* pBlock);
int32_t createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData, SSDataBlock** pResBlock);
int32_t createOneDataBlockWithColArray(const SSDataBlock* pDataBlock, SArray* pColArray, SSDataBlock** pResBlock);
int32_t createOneDataBlockWithTwoBlock(const SSDataBlock* pDataBlock, const SSDataBlock* pOrgBlock, SSDataBlock** pResBlock);
int32_t createSpecialDataBlock(EStreamType type, SSDataBlock** pBlock);
int32_t blockCopyOneRow(const SSDataBlock* pDataBlock, int32_t rowIdx, SSDataBlock** pResBlock);

View File

@ -182,6 +182,9 @@ typedef enum _mgmt_table {
#define TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS 13
#define TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION 14
#define TSDB_ALTER_TABLE_UPDATE_MULTI_TAG_VAL 15
#define TSDB_ALTER_TABLE_ALTER_COLUMN_REF 16
#define TSDB_ALTER_TABLE_REMOVE_COLUMN_REF 17
#define TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF 18
#define TSDB_FILL_NONE 0
#define TSDB_FILL_NULL 1
@ -222,9 +225,11 @@ typedef enum _mgmt_table {
#define TSDB_COL_IS_UD_COL(f) ((f & (~(TSDB_COL_NULL))) == TSDB_COL_UDC)
#define TSDB_COL_REQ_NULL(f) (((f)&TSDB_COL_NULL) != 0)
#define TD_SUPER_TABLE TSDB_SUPER_TABLE
#define TD_CHILD_TABLE TSDB_CHILD_TABLE
#define TD_NORMAL_TABLE TSDB_NORMAL_TABLE
#define TD_SUPER_TABLE TSDB_SUPER_TABLE
#define TD_CHILD_TABLE TSDB_CHILD_TABLE
#define TD_NORMAL_TABLE TSDB_NORMAL_TABLE
#define TD_VIRTUAL_NORMAL_TABLE TSDB_VIRTUAL_NORMAL_TABLE
#define TD_VIRTUAL_CHILD_TABLE TSDB_VIRTUAL_CHILD_TABLE
typedef enum ENodeType {
// Syntax nodes are used in parser and planner module, and some are also used in executor module, such as COLUMN,
@ -270,6 +275,7 @@ typedef enum ENodeType {
QUERY_NODE_ANOMALY_WINDOW,
QUERY_NODE_RANGE_AROUND,
QUERY_NODE_STREAM_NOTIFY_OPTIONS,
QUERY_NODE_VIRTUAL_TABLE,
// Statement nodes are used in parser and planner module.
QUERY_NODE_SET_OPERATOR = 100,
@ -327,6 +333,13 @@ typedef enum ENodeType {
QUERY_NODE_REVOKE_STMT,
QUERY_NODE_ALTER_CLUSTER_STMT,
QUERY_NODE_S3MIGRATE_DATABASE_STMT,
QUERY_NODE_CREATE_TSMA_STMT,
QUERY_NODE_DROP_TSMA_STMT,
QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT,
QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT,
QUERY_NODE_DROP_VIRTUAL_TABLE_STMT,
QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT,
// placeholder for [154, 180]
QUERY_NODE_SHOW_CREATE_VIEW_STMT = 181,
QUERY_NODE_SHOW_CREATE_DATABASE_STMT,
@ -360,6 +373,8 @@ typedef enum ENodeType {
QUERY_NODE_DROP_ANODE_STMT,
QUERY_NODE_UPDATE_ANODE_STMT,
QUERY_NODE_ASSIGN_LEADER_STMT,
QUERY_NODE_SHOW_CREATE_TSMA_STMT,
QUERY_NODE_SHOW_CREATE_VTABLE_STMT,
// show statement nodes
// see 'sysTableShowAdapter', 'SYSTABLE_SHOW_TYPE_OFFSET'
@ -404,11 +419,9 @@ typedef enum ENodeType {
QUERY_NODE_SHOW_ANODES_STMT,
QUERY_NODE_SHOW_ANODES_FULL_STMT,
QUERY_NODE_SHOW_USAGE_STMT,
QUERY_NODE_CREATE_TSMA_STMT,
QUERY_NODE_SHOW_CREATE_TSMA_STMT,
QUERY_NODE_DROP_TSMA_STMT,
QUERY_NODE_SHOW_FILESETS_STMT,
QUERY_NODE_SHOW_TRANSACTION_DETAILS_STMT,
QUERY_NODE_SHOW_VTABLES_STMT,
// logic plan node
QUERY_NODE_LOGIC_PLAN_SCAN = 1000,
@ -429,6 +442,7 @@ typedef enum ENodeType {
QUERY_NODE_LOGIC_PLAN_GROUP_CACHE,
QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL,
QUERY_NODE_LOGIC_PLAN_FORECAST_FUNC,
QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN,
// physical plan node
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN = 1100,
@ -493,6 +507,7 @@ typedef enum ENodeType {
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_STATE,
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_EVENT,
QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_COUNT,
QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN,
} ENodeType;
typedef struct {
@ -595,6 +610,20 @@ STSRow* tGetSubmitBlkNext(SSubmitBlkIter* pIter);
// for debug
int32_t tPrintFixedSchemaSubmitReq(SSubmitReq* pReq, STSchema* pSchema);
typedef struct {
bool hasRef;
col_id_t id;
char refDbName[TSDB_DB_NAME_LEN];
char refTableName[TSDB_TABLE_NAME_LEN];
char refColName[TSDB_COL_NAME_LEN];
} SColRef;
typedef struct {
int32_t nCols;
int32_t version;
SColRef* pColRef;
} SColRefWrapper;
struct SSchema {
int8_t type;
int8_t flags;
@ -636,6 +665,9 @@ typedef struct {
int8_t sysInfo;
SSchema* pSchemas;
SSchemaExt* pSchemaExt;
int8_t virtualStb;
int32_t numOfColRefs;
SColRef* pColRefs;
} STableMetaRsp;
typedef struct {
@ -734,6 +766,23 @@ typedef struct {
SColCmpr* pColCmpr;
} SColCmprWrapper;
static FORCE_INLINE int32_t tInitDefaultSColRefWrapperByCols(SColRefWrapper* pRef, int32_t nCols) {
if (pRef->pColRef) {
return TSDB_CODE_INVALID_PARA;
}
pRef->pColRef = (SColRef*)taosMemoryCalloc(nCols, sizeof(SColRef));
if (pRef->pColRef == NULL) {
return terrno;
}
pRef->nCols = nCols;
for (int32_t i = 0; i < nCols; i++) {
pRef->pColRef[i].hasRef = false;
pRef->pColRef[i].id = (col_id_t)(i + 1);
}
return 0;
}
static FORCE_INLINE SColCmprWrapper* tCloneSColCmprWrapper(const SColCmprWrapper* pSrcWrapper) {
if (pSrcWrapper->pColCmpr == NULL || pSrcWrapper->nCols == 0) {
terrno = TSDB_CODE_INVALID_PARA;
@ -878,6 +927,29 @@ static FORCE_INLINE int32_t tDecodeSSchemaExt(SDecoder* pDecoder, SSchemaExt* pS
return 0;
}
static FORCE_INLINE int32_t tEncodeSColRef(SEncoder* pEncoder, const SColRef* pColRef) {
TAOS_CHECK_RETURN(tEncodeI8(pEncoder, pColRef->hasRef));
TAOS_CHECK_RETURN(tEncodeI16(pEncoder, pColRef->id));
if (pColRef->hasRef) {
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pColRef->refDbName));
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pColRef->refTableName));
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pColRef->refColName));
}
return 0;
}
static FORCE_INLINE int32_t tDecodeSColRef(SDecoder* pDecoder, SColRef* pColRef) {
TAOS_CHECK_RETURN(tDecodeI8(pDecoder, (int8_t*)&pColRef->hasRef));
TAOS_CHECK_RETURN(tDecodeI16(pDecoder, &pColRef->id));
if (pColRef->hasRef) {
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pColRef->refDbName));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pColRef->refTableName));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pColRef->refColName));
}
return 0;
}
static FORCE_INLINE int32_t taosEncodeSSchemaWrapper(void** buf, const SSchemaWrapper* pSW) {
int32_t tlen = 0;
tlen += taosEncodeVariantI32(buf, pSW->nCols);
@ -977,6 +1049,7 @@ typedef struct {
int32_t sqlLen;
char* sql;
int64_t keep;
int8_t virtualStb;
} SMCreateStbReq;
int32_t tSerializeSMCreateStbReq(void* buf, int32_t bufLen, SMCreateStbReq* pReq);
@ -1335,6 +1408,8 @@ typedef struct {
int32_t tagsLen;
char* pTags;
SSchemaExt* pSchemaExt;
int8_t virtualStb;
SColRef* pColRefs;
} STableCfg;
typedef STableCfg STableCfgRsp;
@ -2843,13 +2918,37 @@ typedef struct SOperatorParam {
int32_t downstreamIdx;
void* value;
SArray* pChildren; // SArray<SOperatorParam*>
bool reUse;
} SOperatorParam;
typedef struct SColIdNameKV {
col_id_t colId;
char colName[TSDB_COL_NAME_LEN];
} SColIdNameKV;
typedef struct SColIdPair {
col_id_t vtbColId;
col_id_t orgColId;
} SColIdPair;
typedef struct SOrgTbInfo {
int32_t vgId;
char tbName[TSDB_TABLE_FNAME_LEN];
SArray* colMap; // SArray<SColIdNameKV>
} SOrgTbInfo;
typedef struct STableScanOperatorParam {
bool tableSeq;
SArray* pUidList;
bool tableSeq;
SArray* pUidList;
SOrgTbInfo* pOrgTbInfo;
STimeWindow window;
} STableScanOperatorParam;
typedef struct SVTableScanOperatorParam {
uint64_t uid;
SArray* pOpParamArray; // SArray<SOperatorParam>
} SVTableScanOperatorParam;
typedef struct {
SMsgHead header;
uint64_t sId;
@ -3279,6 +3378,7 @@ typedef struct SVCreateStbReq {
SColCmprWrapper colCmpr;
int64_t keep;
SExtSchema* pExtSchemas;
int8_t virtualStb;
} SVCreateStbReq;
int tEncodeSVCreateStbReq(SEncoder* pCoder, const SVCreateStbReq* pReq);
@ -3320,6 +3420,7 @@ typedef struct SVCreateTbReq {
char* sql;
SColCmprWrapper colCmpr;
SExtSchema* pExtSchemas;
SColRefWrapper colRef; // col reference for virtual table
} SVCreateTbReq;
int tEncodeSVCreateTbReq(SEncoder* pCoder, const SVCreateTbReq* pReq);
@ -3334,16 +3435,17 @@ static FORCE_INLINE void tdDestroySVCreateTbReq(SVCreateTbReq* req) {
taosMemoryFreeClear(req->sql);
taosMemoryFreeClear(req->name);
taosMemoryFreeClear(req->comment);
if (req->type == TSDB_CHILD_TABLE) {
if (req->type == TSDB_CHILD_TABLE || req->type == TSDB_VIRTUAL_CHILD_TABLE) {
taosMemoryFreeClear(req->ctb.pTag);
taosMemoryFreeClear(req->ctb.stbName);
taosArrayDestroy(req->ctb.tagName);
req->ctb.tagName = NULL;
} else if (req->type == TSDB_NORMAL_TABLE) {
} else if (req->type == TSDB_NORMAL_TABLE || req->type == TSDB_VIRTUAL_NORMAL_TABLE) {
taosMemoryFreeClear(req->ntb.schemaRow.pSchema);
}
taosMemoryFreeClear(req->colCmpr.pColCmpr);
taosMemoryFreeClear(req->pExtSchemas);
taosMemoryFreeClear(req->colRef.pColRef);
}
typedef struct {
@ -3391,6 +3493,7 @@ typedef struct {
uint64_t suid; // for tmq in wal format
int64_t uid;
int8_t igNotExists;
int8_t isVirtual;
} SVDropTbReq;
typedef struct {
@ -3430,7 +3533,7 @@ typedef struct SMultiTagUpateVal {
int8_t isNull;
SArray* pTagArray;
} SMultiTagUpateVal;
typedef struct {
typedef struct SVAlterTbReq{
char* tbName;
int8_t action;
char* colName;
@ -3462,6 +3565,11 @@ typedef struct {
SArray* pMultiTag; // TSDB_ALTER_TABLE_ADD_MULTI_TAGS
// for Add column
STypeMod typeMod;
// TSDB_ALTER_TABLE_ALTER_COLUMN_REF
char* refDbName;
char* refTbName;
char* refColName;
// TSDB_ALTER_TABLE_REMOVE_COLUMN_REF
} SVAlterTbReq;
int32_t tEncodeSVAlterTbReq(SEncoder* pEncoder, const SVAlterTbReq* pReq);

View File

@ -132,6 +132,7 @@
TD_DEF_MSG_TYPE(TDMT_MND_RETRIEVE_ANAL_ALGO, "retrieve-anal-algo", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_FAILED_STREAM, "create-stream-failed", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_CHECK_STREAM_TIMER, "check-stream-status", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_GET_DB_INFO, "get-db-info", NULL, NULL)
TD_CLOSE_MSG_SEG(TDMT_DND_MSG)
TD_NEW_MSG_SEG(TDMT_MND_MSG) // 1<<8
@ -265,6 +266,7 @@
TD_DEF_MSG_TYPE(TDMT_MND_CONFIG, "init-config", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_CONFIG_SDB, "config-sdb", NULL, NULL)
TD_DEF_MSG_TYPE(TDMT_MND_RESET_STREAM, "reset-stream", NULL, NULL)
// do not add new message type here, since mnode msg overload. you can add new message type after dnode msg
TD_CLOSE_MSG_SEG(TDMT_END_MND_MSG)
TD_NEW_MSG_SEG(TDMT_VND_MSG) // 2<<8

View File

@ -30,6 +30,7 @@ extern "C" {
#define DS_BUF_EMPTY 3
#define DS_FLAG_USE_MEMPOOL (1 << 0)
#define DS_FLAG_PROCESS_ONE_BLOCK (1 << 1)
struct SSDataBlock;
@ -87,7 +88,7 @@ typedef struct SOutputData {
* @param pHandle output
* @return error code
*/
int32_t dsCreateDataSinker(void* pSinkManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, void* pParam, const char* id);
int32_t dsCreateDataSinker(void* pSinkManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, void* pParam, const char* id, bool processOneBlock);
int32_t dsDataSinkGetCacheSize(SDataSinkStat* pStat);

View File

@ -168,7 +168,7 @@ int32_t qGetQueryTableSchemaVersion(qTaskInfo_t tinfo, char* dbName, int32_t dbN
* @param handle
* @return
*/
int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal);
int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal, bool processOneBlock);
int32_t qExecTask(qTaskInfo_t tinfo, SSDataBlock** pBlock, uint64_t* useconds);

View File

@ -85,6 +85,7 @@ typedef struct SMetaEntry {
SColCmprWrapper colCmpr; // col compress alg
SExtSchema* pExtSchemas;
SColRefWrapper colRef; // col reference for virtual table
} SMetaEntry;
typedef struct SMetaReader {

View File

@ -279,6 +279,7 @@ bool fmIsForbidSysTableFunc(int32_t funcId);
bool fmIsIntervalInterpoFunc(int32_t funcId);
bool fmIsInterpFunc(int32_t funcId);
bool fmIsLastRowFunc(int32_t funcId);
bool fmIsLastFunc(int32_t funcId);
bool fmIsForecastFunc(int32_t funcId);
bool fmIsNotNullOutputFunc(int32_t funcId);
bool fmIsSelectValueFunc(int32_t funcId);

View File

@ -25,10 +25,12 @@ extern "C" {
#define DESCRIBE_RESULT_COLS 4
#define DESCRIBE_RESULT_COLS_COMPRESS 7
#define DESCRIBE_RESULT_COLS_REF 5
#define DESCRIBE_RESULT_FIELD_LEN (TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE)
#define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE)
#define DESCRIBE_RESULT_NOTE_LEN (16 + VARSTR_HEADER_SIZE)
#define DESCRIBE_RESULT_COPRESS_OPTION_LEN (TSDB_CL_COMPRESS_OPTION_LEN + VARSTR_HEADER_SIZE)
#define DESCRIBE_RESULT_COL_REF_LEN (TSDB_COL_FNAME_LEN + VARSTR_HEADER_SIZE)
#define SHOW_CREATE_DB_RESULT_COLS 2
#define SHOW_CREATE_DB_RESULT_FIELD1_LEN (TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE)
@ -184,6 +186,7 @@ typedef struct SCompactVgroupsStmt {
typedef struct STableOptions {
ENodeType type;
bool virtualStb;
bool commentNull;
char comment[TSDB_TB_COMMENT_LEN];
SNodeList* pMaxDelay;
@ -210,7 +213,12 @@ typedef struct SColumnOptions {
char compress[TSDB_CL_COMPRESS_OPTION_LEN];
char compressLevel[TSDB_CL_COMPRESS_OPTION_LEN];
bool bPrimaryKey;
bool hasRef;
char refDb[TSDB_DB_NAME_LEN];
char refTable[TSDB_TABLE_NAME_LEN];
char refColumn[TSDB_COL_NAME_LEN];
} SColumnOptions;
typedef struct SColumnDefNode {
ENodeType type;
char colName[TSDB_COL_NAME_LEN];
@ -229,6 +237,27 @@ typedef struct SCreateTableStmt {
STableOptions* pOptions;
} SCreateTableStmt;
typedef struct SCreateVTableStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
bool ignoreExists;
SNodeList* pCols;
} SCreateVTableStmt;
typedef struct SCreateVSubTableStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
char useDbName[TSDB_DB_NAME_LEN];
char useTableName[TSDB_TABLE_NAME_LEN];
bool ignoreExists;
SNodeList* pSpecificTags;
SNodeList* pValsOfTags;
SNodeList* pSpecificColRefs;
SNodeList* pColRefs;
} SCreateVSubTableStmt;
typedef struct SCreateSubTableClause {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
@ -278,6 +307,14 @@ typedef struct SDropSuperTableStmt {
bool withOpt;
} SDropSuperTableStmt;
typedef struct SDropVirtualTableStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
char tableName[TSDB_TABLE_NAME_LEN];
bool ignoreNotExists;
bool withOpt;
} SDropVirtualTableStmt;
typedef struct SAlterTableStmt {
ENodeType type;
char dbName[TSDB_DB_NAME_LEN];
@ -290,6 +327,9 @@ typedef struct SAlterTableStmt {
SValueNode* pVal;
SColumnOptions* pColOptions;
SNodeList* pNodeListTagValue;
char refDbName[TSDB_DB_NAME_LEN];
char refTableName[TSDB_TABLE_NAME_LEN];
char refColName[TSDB_COL_NAME_LEN];
} SAlterTableStmt;
typedef struct SAlterTableMultiStmt {

View File

@ -129,6 +129,7 @@ typedef struct SScanLogicNode {
bool smallDataTsSort; // disable row id sort for table merge scan
bool needSplit;
bool noPseudoRefAfterGrp; // no pseudo columns referenced ater group/partition clause
bool virtualStableScan;
} SScanLogicNode;
typedef struct SJoinLogicNode {
@ -170,6 +171,19 @@ typedef struct SJoinLogicNode {
SNode* pRightOnCond; // table onCond filter
} SJoinLogicNode;
typedef struct SVirtualScanLogicNode {
SLogicNode node;
bool scanAllCols;
SNodeList* pScanCols;
SNodeList* pScanPseudoCols;
int8_t tableType;
uint64_t tableId;
uint64_t stableId;
SVgroupsInfo* pVgroupList;
EScanType scanType;
SName tableName;
} SVirtualScanLogicNode;
typedef struct SAggLogicNode {
SLogicNode node;
SNodeList* pGroupKeys;
@ -247,10 +261,17 @@ typedef struct SDynQueryCtrlStbJoin {
bool srcScan[2];
} SDynQueryCtrlStbJoin;
typedef struct SDynQueryCtrlVtbScan {
bool scanAllCols;
uint64_t suid;
SVgroupsInfo* pVgroupList;
} SDynQueryCtrlVtbScan;
typedef struct SDynQueryCtrlLogicNode {
SLogicNode node;
EDynQueryType qType;
SDynQueryCtrlStbJoin stbJoin;
SDynQueryCtrlVtbScan vtbScan;
} SDynQueryCtrlLogicNode;
typedef enum EModifyTableType { MODIFY_TABLE_TYPE_INSERT = 1, MODIFY_TABLE_TYPE_DELETE } EModifyTableType;
@ -413,6 +434,7 @@ typedef struct SLogicSubplan {
int32_t level;
int32_t splitFlag;
int32_t numOfComputeNodes;
bool processOneBlock;
} SLogicSubplan;
typedef struct SQueryLogicPlan {
@ -462,6 +484,7 @@ typedef struct SScanPhysiNode {
int8_t tableType;
SName tableName;
bool groupOrderScan;
bool virtualStableScan;
} SScanPhysiNode;
typedef struct STagScanPhysiNode {
@ -471,6 +494,14 @@ typedef struct STagScanPhysiNode {
typedef SScanPhysiNode SBlockDistScanPhysiNode;
typedef struct SVirtualScanPhysiNode {
SScanPhysiNode scan;
SNodeList* pGroupTags;
bool groupSort;
bool scanAllCols;
SNodeList* pTargets;
}SVirtualScanPhysiNode;
typedef struct SLastRowScanPhysiNode {
SScanPhysiNode scan;
SNodeList* pGroupTags;
@ -629,11 +660,20 @@ typedef struct SStbJoinDynCtrlBasic {
bool srcScan[2];
} SStbJoinDynCtrlBasic;
typedef struct SVtbScanDynCtrlBasic {
bool scanAllCols;
uint64_t suid;
int32_t accountId;
SEpSet mgmtEpSet;
SNodeList *pScanCols;
} SVtbScanDynCtrlBasic;
typedef struct SDynQueryCtrlPhysiNode {
SPhysiNode node;
EDynQueryType qType;
union {
SStbJoinDynCtrlBasic stbJoin;
SVtbScanDynCtrlBasic vtbScan;
};
} SDynQueryCtrlPhysiNode;
@ -861,6 +901,7 @@ typedef struct SSubplan {
bool isAudit;
bool dynamicRowThreshold;
int32_t rowsThreshold;
bool processOneBlock;
} SSubplan;
typedef enum EExplainMode { EXPLAIN_MODE_DISABLE = 1, EXPLAIN_MODE_STATIC, EXPLAIN_MODE_ANALYZE } EExplainMode;

View File

@ -94,12 +94,19 @@ typedef struct SColumnNode {
bool isPk;
int32_t projRefIdx;
int32_t resIdx;
bool hasDep;
bool hasRef;
char refDbName[TSDB_DB_NAME_LEN];
char refTableName[TSDB_TABLE_NAME_LEN];
char refColName[TSDB_COL_NAME_LEN];
} SColumnNode;
typedef struct SColumnRefNode {
ENodeType type;
SDataType resType;
char colName[TSDB_COL_NAME_LEN];
char refDbName[TSDB_DB_NAME_LEN];
char refTableName[TSDB_TABLE_NAME_LEN];
char refColName[TSDB_COL_NAME_LEN];
} SColumnRefNode;
typedef struct STargetNode {
@ -238,6 +245,13 @@ typedef struct STempTableNode {
SNode* pSubquery;
} STempTableNode;
typedef struct SVirtualTableNode {
STableNode table; // QUERY_NODE_VIRTUAL_TABLE
struct STableMeta* pMeta;
SVgroupsInfo* pVgroupList;
SNodeList* refTables;
} SVirtualTableNode;
typedef struct SViewNode {
STableNode table; // QUERY_NODE_REAL_TABLE
struct STableMeta* pMeta;
@ -281,6 +295,7 @@ typedef enum EJoinAlgorithm {
typedef enum EDynQueryType {
DYN_QTYPE_STB_HASH = 1,
DYN_QTYPE_VTB_SCAN,
} EDynQueryType;
typedef struct SJoinTableNode {
@ -395,6 +410,7 @@ typedef enum EShowKind {
SHOW_KIND_ALL = 1,
SHOW_KIND_TABLES_NORMAL,
SHOW_KIND_TABLES_CHILD,
SHOW_KIND_TABLES_VIRTUAL,
SHOW_KIND_DATABASES_USER,
SHOW_KIND_DATABASES_SYSTEM
} EShowKind;

View File

@ -24,6 +24,31 @@ extern "C" {
#include "query.h"
#include "querynodes.h"
#define PAR_ERR_RET(c) \
do { \
int32_t _code = c; \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
return _code; \
} \
} while (0)
#define PAR_RET(c) \
do { \
int32_t _code = c; \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
} \
return _code; \
} while (0)
#define PAR_ERR_JRET(c) \
do { \
code = c; \
if (code != TSDB_CODE_SUCCESS) { \
terrno = code; \
goto _return; \
} \
} while (0)
typedef struct SStmtCallback {
TAOS_STMT* pStmt;
int32_t (*getTbNameFn)(TAOS_STMT*, char**);

View File

@ -53,6 +53,7 @@ typedef struct SPlanContext {
char pWendName[TSDB_COL_NAME_LEN];
char pGroupIdName[TSDB_COL_NAME_LEN];
char pIsWindowFilledName[TSDB_COL_NAME_LEN];
bool virtualStableQuery;
} SPlanContext;
// Create the physical plan for the query, according to the AST.

View File

@ -105,8 +105,20 @@ typedef struct SCTableMeta {
} SCTableMeta;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct SVCTableMeta {
uint64_t uid;
uint64_t suid;
int32_t vgId;
int8_t tableType;
int32_t numOfColRefs;
SColRef* colRef;
} SVCTableMeta;
#pragma pack(pop)
#pragma pack(push, 1)
typedef struct STableMeta {
// BEGIN: KEEP THIS PART SAME WITH SVCTableMeta
// BEGIN: KEEP THIS PART SAME WITH SCTableMeta
uint64_t uid;
uint64_t suid;
@ -114,6 +126,10 @@ typedef struct STableMeta {
int8_t tableType;
// END: KEEP THIS PART SAME WITH SCTableMeta
int32_t numOfColRefs;
SColRef* colRef;
// END: KEEP THIS PART SAME WITH SVCTableMeta
// if the table is TSDB_CHILD_TABLE, the following information is acquired from the corresponding super table meta
// info
int32_t sversion;
@ -121,7 +137,8 @@ typedef struct STableMeta {
STableComInfo tableInfo;
SSchemaExt* schemaExt; // There is no additional memory allocation, and the pointer is fixed to the next address of
// the schema content.
SSchema schema[];
int8_t virtualStb;
SSchema schema[];
} STableMeta;
#pragma pack(pop)
@ -153,16 +170,22 @@ typedef struct SUseDbOutput {
SDBVgInfo* dbVgroup;
} SUseDbOutput;
enum { META_TYPE_NULL_TABLE = 1, META_TYPE_CTABLE, META_TYPE_TABLE, META_TYPE_BOTH_TABLE };
enum { META_TYPE_NULL_TABLE = 1,
META_TYPE_CTABLE,
META_TYPE_VCTABLE,
META_TYPE_TABLE,
META_TYPE_BOTH_TABLE,
META_TYPE_BOTH_VTABLE};
typedef struct STableMetaOutput {
int32_t metaType;
uint64_t dbId;
char dbFName[TSDB_DB_FNAME_LEN];
char ctbName[TSDB_TABLE_NAME_LEN];
char tbName[TSDB_TABLE_NAME_LEN];
SCTableMeta ctbMeta;
STableMeta* tbMeta;
int32_t metaType;
uint64_t dbId;
char dbFName[TSDB_DB_FNAME_LEN];
char ctbName[TSDB_TABLE_NAME_LEN];
char tbName[TSDB_TABLE_NAME_LEN];
SCTableMeta ctbMeta;
SVCTableMeta* vctbMeta;
STableMeta* tbMeta;
} STableMetaOutput;
typedef struct SViewMetaOutput {
@ -331,6 +354,7 @@ bool tIsValidSchema(struct SSchema* pSchema, int32_t numOfCols, int32_
int32_t getAsofJoinReverseOp(EOperatorType op);
int32_t queryCreateCTableMetaFromMsg(STableMetaRsp* msg, SCTableMeta* pMeta);
int32_t queryCreateVCTableMetaFromMsg(STableMetaRsp *msg, SVCTableMeta **pMeta);
int32_t queryCreateTableMetaFromMsg(STableMetaRsp* msg, bool isSuperTable, STableMeta** pMeta);
int32_t queryCreateTableMetaExFromMsg(STableMetaRsp* msg, bool isSuperTable, STableMeta** pMeta);
char* jobTaskStatusStr(int32_t status);
@ -340,6 +364,7 @@ SSchema createSchema(int8_t type, int32_t bytes, col_id_t colId, const char* nam
void destroyQueryExecRes(SExecResult* pRes);
int32_t dataConverToStr(char* str, int64_t capacity, int type, void* buf, int32_t bufSize, int32_t* len);
void parseTagDatatoJson(void* p, char** jsonStr, void *charsetCxt);
int32_t setColRef(SColRef* colRef, col_id_t colId, char* refColName, char* refTableName, char* refDbName);
int32_t cloneTableMeta(STableMeta* pSrc, STableMeta** pDst);
void getColumnTypeFromMeta(STableMeta* pMeta, char* pName, ETableColumnType* pType);
int32_t cloneDbVgInfo(SDBVgInfo* pSrc, SDBVgInfo** pDst);
@ -353,10 +378,12 @@ extern int32_t (*queryProcessMsgRsp[TDMT_MAX])(void* output, char* msg, int32_t
void* getTaskPoolWorkerCb();
#define SET_META_TYPE_NULL(t) (t) = META_TYPE_NULL_TABLE
#define SET_META_TYPE_CTABLE(t) (t) = META_TYPE_CTABLE
#define SET_META_TYPE_TABLE(t) (t) = META_TYPE_TABLE
#define SET_META_TYPE_BOTH_TABLE(t) (t) = META_TYPE_BOTH_TABLE
#define SET_META_TYPE_NULL(t) (t) = META_TYPE_NULL_TABLE
#define SET_META_TYPE_CTABLE(t) (t) = META_TYPE_CTABLE
#define SET_META_TYPE_VCTABLE(t) (t) = META_TYPE_VCTABLE
#define SET_META_TYPE_TABLE(t) (t) = META_TYPE_TABLE
#define SET_META_TYPE_BOTH_TABLE(t) (t) = META_TYPE_BOTH_TABLE
#define SET_META_TYPE_BOTH_VTABLE(t) (t) = META_TYPE_BOTH_VTABLE
#define NEED_CLIENT_RM_TBLMETA_ERROR(_code) \
((_code) == TSDB_CODE_PAR_TABLE_NOT_EXIST || (_code) == TSDB_CODE_TDB_TABLE_NOT_EXIST || \

View File

@ -922,6 +922,10 @@ int32_t taosGetErrSize();
#define TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC TAOS_DEF_ERROR_CODE(0, 0x268A)
#define TSDB_CODE_PAR_INVALID_COLS_ALIAS TAOS_DEF_ERROR_CODE(0, 0x268B)
#define TSDB_CODE_PAR_PRIM_KEY_MUST_BE_TS TAOS_DEF_ERROR_CODE(0, 0x268C)
#define TSDB_CODE_PAR_INVALID_REF_COLUMN TAOS_DEF_ERROR_CODE(0, 0x268D)
#define TSDB_CODE_PAR_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x268E)
#define TSDB_CODE_PAR_INVALID_REF_COLUMN_TYPE TAOS_DEF_ERROR_CODE(0, 0x268F)
#define TSDB_CODE_PAR_MISMATCH_STABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x2690)
#define TSDB_CODE_PAR_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x26FF)
//planner
@ -929,6 +933,9 @@ int32_t taosGetErrSize();
#define TSDB_CODE_PLAN_EXPECTED_TS_EQUAL TAOS_DEF_ERROR_CODE(0, 0x2701)
#define TSDB_CODE_PLAN_NOT_SUPPORT_CROSS_JOIN TAOS_DEF_ERROR_CODE(0, 0x2702)
#define TSDB_CODE_PLAN_NOT_SUPPORT_JOIN_COND TAOS_DEF_ERROR_CODE(0, 0x2703)
#define TSDB_CODE_PLAN_SLOT_NOT_FOUND TAOS_DEF_ERROR_CODE(0, 0x2704)
#define TSDB_CODE_PLAN_INVALID_TABLE_TYPE TAOS_DEF_ERROR_CODE(0, 0x2705)
#define TSDB_CODE_PLAN_INVALID_DYN_CTRL_TYPE TAOS_DEF_ERROR_CODE(0, 0x2706)
//function
#define TSDB_CODE_FUNC_FUNTION_ERROR TAOS_DEF_ERROR_CODE(0, 0x2800)
@ -1056,6 +1063,11 @@ int32_t taosGetErrSize();
#define TSDB_CODE_AUDIT_FAIL_SEND_AUDIT_RECORD TAOS_DEF_ERROR_CODE(0, 0x6101)
#define TSDB_CODE_AUDIT_FAIL_GENERATE_JSON TAOS_DEF_ERROR_CODE(0, 0x6102)
// VTABLE
#define TSDB_CODE_VTABLE_SCAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x6200)
#define TSDB_CODE_VTABLE_SCAN_INVALID_DOWNSTREAM TAOS_DEF_ERROR_CODE(0, 0x6201)
#define TSDB_CODE_VTABLE_PRIMTS_HAS_REF TAOS_DEF_ERROR_CODE(0, 0x6202)
#define TSDB_CODE_VTABLE_NOT_VIRTUAL_SUPER_TABLE TAOS_DEF_ERROR_CODE(0, 0x6203)
#ifdef __cplusplus
}
#endif

View File

@ -285,6 +285,7 @@ typedef enum ELogicConditionType {
#define TSDB_COL_NAME_LEN 65
#define TSDB_COL_NAME_EXLEN 8
#define TSDB_COL_FNAME_LEN (TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN + TSDB_NAME_DELIMITER_LEN)
#define TSDB_COL_FNAME_EX_LEN (TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_TABLE_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_NAME_LEN)
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
#define TSDB_MAX_SQL_SHOW_LEN 1024

View File

@ -704,6 +704,8 @@ int32_t tSerializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pReq
ENCODESQL();
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pReq->virtualStb));
tEndEncode(&encoder);
_exit:
@ -818,6 +820,12 @@ int32_t tDeserializeSMCreateStbReq(void *buf, int32_t bufLen, SMCreateStbReq *pR
DECODESQL();
if (!tDecodeIsEnd(&decoder)) {
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pReq->virtualStb));
} else {
pReq->virtualStb = 0;
}
tEndDecode(&decoder);
_exit:
@ -3954,6 +3962,14 @@ int32_t tSerializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp) {
}
}
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pRsp->virtualStb));
if (hasRefCol(pRsp->tableType)) {
for (int32_t i = 0; i < pRsp->numOfColumns; ++i) {
SColRef *pColRef = &pRsp->pColRefs[i];
TAOS_CHECK_EXIT(tEncodeSColRef(&encoder, pColRef));
}
}
tEndEncode(&encoder);
_exit:
@ -4037,6 +4053,23 @@ int32_t tDeserializeSTableCfgRsp(void *buf, int32_t bufLen, STableCfgRsp *pRsp)
pRsp->pSchemaExt = NULL;
}
}
if (!tDecodeIsEnd(&decoder)) {
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &pRsp->virtualStb));
if (hasRefCol(pRsp->tableType) && pRsp->numOfColumns > 0) {
pRsp->pColRefs = taosMemoryMalloc(sizeof(SColRef) * pRsp->numOfColumns);
if (pRsp->pColRefs == NULL) {
TAOS_CHECK_EXIT(terrno);
}
for (int32_t i = 0; i < pRsp->numOfColumns; ++i) {
SColRef *pColRef = &pRsp->pColRefs[i];
TAOS_CHECK_EXIT(tDecodeSColRef(&decoder, pColRef));
}
} else {
pRsp->pColRefs = NULL;
}
}
tEndDecode(&decoder);
_exit:
@ -4052,6 +4085,7 @@ void tFreeSTableCfgRsp(STableCfgRsp *pRsp) {
taosMemoryFreeClear(pRsp->pComment);
taosMemoryFreeClear(pRsp->pSchemas);
taosMemoryFreeClear(pRsp->pSchemaExt);
taosMemoryFreeClear(pRsp->pColRefs);
taosMemoryFreeClear(pRsp->pTags);
taosArrayDestroy(pRsp->pFuncs);
@ -6125,6 +6159,15 @@ static int32_t tEncodeSTableMetaRsp(SEncoder *pEncoder, STableMetaRsp *pRsp) {
}
}
TAOS_CHECK_RETURN(tEncodeI8(pEncoder, pRsp->virtualStb));
TAOS_CHECK_RETURN(tEncodeI32(pEncoder, pRsp->numOfColRefs));
if (hasRefCol(pRsp->tableType)) {
for (int32_t i = 0; i < pRsp->numOfColRefs; ++i) {
SColRef *pColRef = &pRsp->pColRefs[i];
TAOS_CHECK_RETURN(tEncodeSColRef(pEncoder, pColRef));
}
}
return 0;
}
@ -6173,6 +6216,23 @@ static int32_t tDecodeSTableMetaRsp(SDecoder *pDecoder, STableMetaRsp *pRsp) {
pRsp->pSchemaExt = NULL;
}
}
if (!tDecodeIsEnd(pDecoder)) {
TAOS_CHECK_RETURN(tDecodeI8(pDecoder, &pRsp->virtualStb));
TAOS_CHECK_RETURN(tDecodeI32(pDecoder, &pRsp->numOfColRefs));
if (hasRefCol(pRsp->tableType) && pRsp->numOfColRefs > 0) {
pRsp->pColRefs = taosMemoryMalloc(sizeof(SColRef) * pRsp->numOfColRefs);
if (pRsp->pColRefs == NULL) {
TAOS_CHECK_RETURN(terrno);
}
for (int32_t i = 0; i < pRsp->numOfColRefs; ++i) {
SColRef *pColRef = &pRsp->pColRefs[i];
TAOS_CHECK_RETURN(tDecodeSColRef(pDecoder, pColRef));
}
} else {
pRsp->pColRefs = NULL;
}
}
return 0;
}
@ -6282,6 +6342,7 @@ int32_t tDeserializeSSTbHbRsp(void *buf, int32_t bufLen, SSTbHbRsp *pRsp) {
if (taosArrayPush(pRsp->pMetaRsp, &tableMetaRsp) == NULL) {
taosMemoryFree(tableMetaRsp.pSchemas);
taosMemoryFree(tableMetaRsp.pSchemaExt);
taosMemoryFree(tableMetaRsp.pColRefs);
TAOS_CHECK_EXIT(terrno);
}
}
@ -6337,6 +6398,7 @@ void tFreeSTableMetaRsp(void *pRsp) {
taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pSchemas);
taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pSchemaExt);
taosMemoryFreeClear(((STableMetaRsp *)pRsp)->pColRefs);
}
void tFreeSTableIndexRsp(void *info) {
@ -8463,9 +8525,9 @@ int32_t tSerializeSMArbUpdateGroupBatchReq(void *buf, int32_t bufLen, SMArbUpdat
SMArbUpdateGroup *pGroup = taosArrayGet(pReq->updateArray, i);
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->vgId));
TAOS_CHECK_EXIT(tEncodeI64(&encoder, pGroup->dbUid));
for (int i = 0; i < TSDB_ARB_GROUP_MEMBER_NUM; i++) {
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->members[i].dnodeId));
TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pGroup->members[i].token));
for (int j = 0; j < TSDB_ARB_GROUP_MEMBER_NUM; j++) {
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->members[j].dnodeId));
TAOS_CHECK_EXIT(tEncodeCStr(&encoder, pGroup->members[j].token));
}
TAOS_CHECK_EXIT(tEncodeI8(&encoder, pGroup->isSync));
TAOS_CHECK_EXIT(tEncodeI32(&encoder, pGroup->assignedLeader.dnodeId));
@ -8515,12 +8577,12 @@ int32_t tDeserializeSMArbUpdateGroupBatchReq(void *buf, int32_t bufLen, SMArbUpd
SMArbUpdateGroup group = {0};
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.vgId));
TAOS_CHECK_EXIT(tDecodeI64(&decoder, &group.dbUid));
for (int i = 0; i < TSDB_ARB_GROUP_MEMBER_NUM; i++) {
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.members[i].dnodeId));
if ((group.members[i].token = taosMemoryMalloc(TSDB_ARB_TOKEN_SIZE)) == NULL) {
for (int j = 0; j < TSDB_ARB_GROUP_MEMBER_NUM; j++) {
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.members[j].dnodeId));
if ((group.members[j].token = taosMemoryMalloc(TSDB_ARB_TOKEN_SIZE)) == NULL) {
TAOS_CHECK_EXIT(terrno);
}
TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, group.members[i].token));
TAOS_CHECK_EXIT(tDecodeCStrTo(&decoder, group.members[j].token));
}
TAOS_CHECK_EXIT(tDecodeI8(&decoder, &group.isSync));
TAOS_CHECK_EXIT(tDecodeI32(&decoder, &group.assignedLeader.dnodeId));
@ -8568,8 +8630,8 @@ void tFreeSMArbUpdateGroupBatchReq(SMArbUpdateGroupBatchReq *pReq) {
int32_t sz = taosArrayGetSize(pReq->updateArray);
for (int32_t i = 0; i < sz; i++) {
SMArbUpdateGroup *pGroup = taosArrayGet(pReq->updateArray, i);
for (int i = 0; i < TSDB_ARB_GROUP_MEMBER_NUM; i++) {
taosMemoryFreeClear(pGroup->members[i].token);
for (int j = 0; j < TSDB_ARB_GROUP_MEMBER_NUM; j++) {
taosMemoryFreeClear(pGroup->members[j].token);
}
taosMemoryFreeClear(pGroup->assignedLeader.token);
}
@ -9209,6 +9271,22 @@ int32_t tSerializeSOperatorParam(SEncoder *pEncoder, SOperatorParam *pOpParam) {
int64_t *pUid = taosArrayGet(pScan->pUidList, m);
TAOS_CHECK_RETURN(tEncodeI64(pEncoder, *pUid));
}
if (pScan->pOrgTbInfo) {
TAOS_CHECK_RETURN(tEncodeBool(pEncoder, true));
TAOS_CHECK_RETURN(tEncodeI32(pEncoder, pScan->pOrgTbInfo->vgId));
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pScan->pOrgTbInfo->tbName));
int32_t num = taosArrayGetSize(pScan->pOrgTbInfo->colMap);
TAOS_CHECK_RETURN(tEncodeI32(pEncoder, num));
for (int32_t i = 0; i < num; ++i) {
SColIdNameKV *pColKV = taosArrayGet(pScan->pOrgTbInfo->colMap, i);
TAOS_CHECK_RETURN(tEncodeI16(pEncoder, pColKV->colId));
TAOS_CHECK_RETURN(tEncodeCStr(pEncoder, pColKV->colName));
}
} else {
TAOS_CHECK_RETURN(tEncodeBool(pEncoder, false));
}
TAOS_CHECK_RETURN(tEncodeI64(pEncoder, pScan->window.skey));
TAOS_CHECK_RETURN(tEncodeI64(pEncoder, pScan->window.ekey));
break;
}
default:
@ -9222,6 +9300,7 @@ int32_t tSerializeSOperatorParam(SEncoder *pEncoder, SOperatorParam *pOpParam) {
TAOS_CHECK_RETURN(tSerializeSOperatorParam(pEncoder, pChild));
}
TAOS_CHECK_RETURN(tEncodeBool(pEncoder, pOpParam->reUse));
return 0;
}
@ -9253,6 +9332,33 @@ int32_t tDeserializeSOperatorParam(SDecoder *pDecoder, SOperatorParam *pOpParam)
} else {
pScan->pUidList = NULL;
}
bool hasTbInfo = false;
TAOS_CHECK_RETURN(tDecodeBool(pDecoder, &hasTbInfo));
if (hasTbInfo) {
pScan->pOrgTbInfo = taosMemoryMalloc(sizeof(SOrgTbInfo));
if (NULL == pScan->pOrgTbInfo) {
TAOS_CHECK_RETURN(terrno);
}
TAOS_CHECK_RETURN(tDecodeI32(pDecoder, &pScan->pOrgTbInfo->vgId));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pScan->pOrgTbInfo->tbName));
int32_t num = 0;
TAOS_CHECK_RETURN(tDecodeI32(pDecoder, &num));
pScan->pOrgTbInfo->colMap = taosArrayInit(num, sizeof(SColIdNameKV));
for (int32_t i = 0; i < num; ++i) {
SColIdNameKV pColKV;
TAOS_CHECK_RETURN(tDecodeI16(pDecoder, (int16_t *)&(pColKV.colId)));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, pColKV.colName));
if (taosArrayPush(pScan->pOrgTbInfo->colMap, &pColKV) == NULL) {
TAOS_CHECK_RETURN(terrno);
}
}
} else {
pScan->pOrgTbInfo = NULL;
}
TAOS_CHECK_RETURN(tDecodeI64(pDecoder, &pScan->window.skey));
TAOS_CHECK_RETURN(tDecodeI64(pDecoder, &pScan->window.ekey));
pOpParam->value = pScan;
break;
}
@ -9282,6 +9388,12 @@ int32_t tDeserializeSOperatorParam(SDecoder *pDecoder, SOperatorParam *pOpParam)
pOpParam->pChildren = NULL;
}
if (!tDecodeIsEnd(pDecoder)) {
TAOS_CHECK_RETURN(tDecodeBool(pDecoder, &pOpParam->reUse));
} else {
pOpParam->reUse = false;
}
return 0;
}
@ -10449,6 +10561,57 @@ _exit:
return code;
}
int32_t tEncodeSColRefWrapper(SEncoder *pCoder, const SColRefWrapper *pWrapper) {
int32_t code = 0;
int32_t lino;
TAOS_CHECK_EXIT(tEncodeI32v(pCoder, pWrapper->nCols));
TAOS_CHECK_EXIT(tEncodeI32v(pCoder, pWrapper->version));
for (int32_t i = 0; i < pWrapper->nCols; i++) {
SColRef *p = &pWrapper->pColRef[i];
TAOS_CHECK_EXIT(tEncodeI8(pCoder, p->hasRef));
TAOS_CHECK_EXIT(tEncodeI16v(pCoder, p->id));
if (p->hasRef) {
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, p->refDbName));
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, p->refTableName));
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, p->refColName));
}
}
_exit:
return code;
}
int32_t tDecodeSColRefWrapperEx(SDecoder *pDecoder, SColRefWrapper *pWrapper) {
int32_t code = 0;
int32_t lino;
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pWrapper->nCols));
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pWrapper->version));
pWrapper->pColRef = (SColRef *)tDecoderMalloc(pDecoder, pWrapper->nCols * sizeof(SColRef));
if (pWrapper->pColRef == NULL) {
TAOS_CHECK_EXIT(terrno);
}
for (int i = 0; i < pWrapper->nCols; i++) {
SColRef *p = &pWrapper->pColRef[i];
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, (int8_t *)&p->hasRef));
TAOS_CHECK_EXIT(tDecodeI16v(pDecoder, &p->id));
if (p->hasRef) {
TAOS_CHECK_EXIT(tDecodeCStrTo(pDecoder, p->refDbName));
TAOS_CHECK_EXIT(tDecodeCStrTo(pDecoder, p->refTableName));
TAOS_CHECK_EXIT(tDecodeCStrTo(pDecoder, p->refColName));
}
}
_exit:
if (code) {
taosMemoryFree(pWrapper->pColRef);
}
return code;
}
int32_t tEncodeSColCmprWrapper(SEncoder *pCoder, const SColCmprWrapper *pWrapper) {
int32_t code = 0;
int32_t lino;
@ -10558,6 +10721,7 @@ int tEncodeSVCreateStbReq(SEncoder *pCoder, const SVCreateStbReq *pReq) {
} else {
TAOS_CHECK_EXIT(tEncodeI8(pCoder, 0));
}
TAOS_CHECK_EXIT(tEncodeI8(pCoder, pReq->virtualStb));
tEndEncode(pCoder);
_exit:
@ -10603,6 +10767,9 @@ int tDecodeSVCreateStbReq(SDecoder *pCoder, SVCreateStbReq *pReq) {
}
}
}
if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_EXIT(tDecodeI8(pCoder, &pReq->virtualStb));
}
tEndDecode(pCoder);
_exit:
@ -10626,7 +10793,7 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) {
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, pReq->comment));
}
if (pReq->type == TSDB_CHILD_TABLE) {
if (pReq->type == TSDB_CHILD_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, pReq->ctb.stbName));
TAOS_CHECK_EXIT(tEncodeU8(pCoder, pReq->ctb.tagNum));
TAOS_CHECK_EXIT(tEncodeI64(pCoder, pReq->ctb.suid));
@ -10637,7 +10804,7 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) {
char *name = taosArrayGet(pReq->ctb.tagName, i);
TAOS_CHECK_EXIT(tEncodeCStr(pCoder, name));
}
} else if (pReq->type == TSDB_NORMAL_TABLE) {
} else if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_EXIT(tEncodeSSchemaWrapper(pCoder, &pReq->ntb.schemaRow));
} else {
return TSDB_CODE_INVALID_MSG;
@ -10651,12 +10818,15 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) {
// Encode Column Options: encode compress level
if (pReq->type == TSDB_SUPER_TABLE || pReq->type == TSDB_NORMAL_TABLE) {
TAOS_CHECK_EXIT(tEncodeSColCmprWrapper(pCoder, &pReq->colCmpr));
if (pReq->pExtSchemas) {
TAOS_CHECK_EXIT(tEncodeI8(pCoder, 1));
TAOS_CHECK_EXIT(tEncodeSExtSchemas(pCoder, pReq->pExtSchemas, pReq->ntb.schemaRow.nCols));
} else {
TAOS_CHECK_EXIT(tEncodeI8(pCoder, 0));
}
}
if (pReq->type == TSDB_VIRTUAL_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_EXIT(tEncodeSColRefWrapper(pCoder, &pReq->colRef));
}
if (pReq->pExtSchemas) {
TAOS_CHECK_EXIT(tEncodeI8(pCoder, 1));
TAOS_CHECK_EXIT(tEncodeSExtSchemas(pCoder, pReq->pExtSchemas, pReq->ntb.schemaRow.nCols));
} else {
TAOS_CHECK_EXIT(tEncodeI8(pCoder, 0));
}
tEndEncode(pCoder);
@ -10685,7 +10855,7 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) {
TAOS_CHECK_EXIT(tDecodeCStrTo(pCoder, pReq->comment));
}
if (pReq->type == TSDB_CHILD_TABLE) {
if (pReq->type == TSDB_CHILD_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_EXIT(tDecodeCStr(pCoder, &pReq->ctb.stbName));
TAOS_CHECK_EXIT(tDecodeU8(pCoder, &pReq->ctb.tagNum));
TAOS_CHECK_EXIT(tDecodeI64(pCoder, &pReq->ctb.suid));
@ -10705,7 +10875,7 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) {
TAOS_CHECK_EXIT(terrno);
}
}
} else if (pReq->type == TSDB_NORMAL_TABLE) {
} else if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_EXIT(tDecodeSSchemaWrapperEx(pCoder, &pReq->ntb.schemaRow));
} else {
return TSDB_CODE_INVALID_MSG;
@ -10717,11 +10887,16 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) {
if (pReq->sqlLen > 0) {
TAOS_CHECK_EXIT(tDecodeBinaryAlloc(pCoder, (void **)&pReq->sql, NULL));
}
if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_SUPER_TABLE)
if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_SUPER_TABLE) {
if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_EXIT(tDecodeSColCmprWrapperEx(pCoder, &pReq->colCmpr));
}
} else if (pReq->type == TSDB_VIRTUAL_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_EXIT(tDecodeSColRefWrapperEx(pCoder, &pReq->colRef));
}
}
if (!tDecodeIsEnd(pCoder)) {
int8_t hasExtSchema = 0;
TAOS_CHECK_EXIT(tDecodeI8(pCoder, &hasExtSchema));
@ -10742,25 +10917,18 @@ void tDestroySVCreateTbReq(SVCreateTbReq *pReq, int32_t flags) {
if (flags & TSDB_MSG_FLG_ENCODE) {
// TODO
} else if (flags & TSDB_MSG_FLG_DECODE) {
if (pReq->comment) {
pReq->comment = NULL;
taosMemoryFree(pReq->comment);
}
taosMemoryFreeClear(pReq->comment);
if (pReq->type == TSDB_CHILD_TABLE) {
if (pReq->ctb.tagName) taosArrayDestroy(pReq->ctb.tagName);
} else if (pReq->type == TSDB_NORMAL_TABLE) {
if (pReq->ntb.schemaRow.pSchema) taosMemoryFree(pReq->ntb.schemaRow.pSchema);
if (pReq->type == TSDB_CHILD_TABLE || pReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
taosArrayDestroy(pReq->ctb.tagName);
} else if (pReq->type == TSDB_NORMAL_TABLE || pReq->type == TSDB_VIRTUAL_NORMAL_TABLE) {
taosMemoryFreeClear(pReq->ntb.schemaRow.pSchema);
}
}
if (pReq->colCmpr.pColCmpr) taosMemoryFree(pReq->colCmpr.pColCmpr);
pReq->colCmpr.pColCmpr = NULL;
if (pReq->sql != NULL) {
taosMemoryFree(pReq->sql);
}
pReq->sql = NULL;
taosMemoryFreeClear(pReq->colCmpr.pColCmpr);
taosMemoryFreeClear(pReq->colRef.pColRef);
taosMemoryFreeClear(pReq->sql);
}
int tEncodeSVCreateTbBatchReq(SEncoder *pCoder, const SVCreateTbBatchReq *pReq) {
@ -10803,7 +10971,7 @@ void tDeleteSVCreateTbBatchReq(SVCreateTbBatchReq *pReq) {
SVCreateTbReq *pCreateReq = pReq->pReqs + iReq;
taosMemoryFreeClear(pCreateReq->sql);
taosMemoryFreeClear(pCreateReq->comment);
if (pCreateReq->type == TSDB_CHILD_TABLE) {
if (pCreateReq->type == TSDB_CHILD_TABLE || pCreateReq->type == TSDB_VIRTUAL_CHILD_TABLE) {
taosArrayDestroy(pCreateReq->ctb.tagName);
pCreateReq->ctb.tagName = NULL;
}
@ -10853,6 +11021,7 @@ void tFreeSVCreateTbRsp(void *param) {
if (pRsp->pMeta) {
taosMemoryFree(pRsp->pMeta->pSchemas);
taosMemoryFree(pRsp->pMeta->pSchemaExt);
taosMemoryFree(pRsp->pMeta->pColRefs);
taosMemoryFree(pRsp->pMeta);
}
}
@ -10864,6 +11033,7 @@ static int32_t tEncodeSVDropTbReq(SEncoder *pCoder, const SVDropTbReq *pReq) {
TAOS_CHECK_RETURN(tEncodeU64(pCoder, pReq->suid));
TAOS_CHECK_RETURN(tEncodeI64(pCoder, pReq->uid));
TAOS_CHECK_RETURN(tEncodeI8(pCoder, pReq->igNotExists));
TAOS_CHECK_RETURN(tEncodeI8(pCoder, pReq->isVirtual));
tEndEncode(pCoder);
return 0;
@ -10875,6 +11045,9 @@ static int32_t tDecodeSVDropTbReq(SDecoder *pCoder, SVDropTbReq *pReq) {
TAOS_CHECK_RETURN(tDecodeU64(pCoder, &pReq->suid));
TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pReq->uid));
TAOS_CHECK_RETURN(tDecodeI8(pCoder, &pReq->igNotExists));
if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_RETURN(tDecodeI8(pCoder, &pReq->isVirtual));
}
tEndDecode(pCoder);
return 0;
@ -11081,6 +11254,24 @@ int32_t tEncodeSVAlterTbReq(SEncoder *pEncoder, const SVAlterTbReq *pReq) {
TAOS_CHECK_EXIT(tEncodeI32v(pEncoder, pReq->bytes));
TAOS_CHECK_EXIT(tEncodeU32(pEncoder, pReq->compress));
break;
case TSDB_ALTER_TABLE_ALTER_COLUMN_REF:
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->colName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refDbName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refTbName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refColName));
break;
case TSDB_ALTER_TABLE_REMOVE_COLUMN_REF:
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->colName));
break;
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF:
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->colName));
TAOS_CHECK_EXIT(tEncodeI8(pEncoder, pReq->type));
TAOS_CHECK_EXIT(tEncodeI8(pEncoder, pReq->flags));
TAOS_CHECK_EXIT(tEncodeI32v(pEncoder, pReq->bytes));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refDbName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refTbName));
TAOS_CHECK_EXIT(tEncodeCStr(pEncoder, pReq->refColName));
break;
default:
break;
}
@ -11171,6 +11362,25 @@ static int32_t tDecodeSVAlterTbReqCommon(SDecoder *pDecoder, SVAlterTbReq *pReq)
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->flags));
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pReq->bytes));
TAOS_CHECK_EXIT(tDecodeU32(pDecoder, &pReq->compress));
break;
case TSDB_ALTER_TABLE_ALTER_COLUMN_REF:
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->colName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refDbName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refTbName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refColName));
break;
case TSDB_ALTER_TABLE_REMOVE_COLUMN_REF:
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->colName));
break;
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF:
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->colName));
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->type));
TAOS_CHECK_EXIT(tDecodeI8(pDecoder, &pReq->flags));
TAOS_CHECK_EXIT(tDecodeI32v(pDecoder, &pReq->bytes));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refDbName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refTbName));
TAOS_CHECK_EXIT(tDecodeCStr(pDecoder, &pReq->refColName));
break;
default:
break;
}
@ -11308,6 +11518,7 @@ void tFreeSMAlterStbRsp(SMAlterStbRsp *pRsp) {
if (pRsp->pMeta) {
taosMemoryFree(pRsp->pMeta->pSchemas);
taosMemoryFree(pRsp->pMeta->pSchemaExt);
taosMemoryFree(pRsp->pMeta->pColRefs);
taosMemoryFree(pRsp->pMeta);
}
}
@ -11359,6 +11570,7 @@ void tFreeSMCreateStbRsp(SMCreateStbRsp *pRsp) {
if (pRsp->pMeta) {
taosMemoryFree(pRsp->pMeta->pSchemas);
taosMemoryFree(pRsp->pMeta->pSchemaExt);
taosMemoryFree(pRsp->pMeta->pColRefs);
taosMemoryFree(pRsp->pMeta);
}
}

View File

@ -164,6 +164,7 @@ static const SSysDbTableSchema userStbsSchema[] = {
{.name = "max_delay", .bytes = 64 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
{.name = "rollup", .bytes = 128 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false},
{.name = "uid", .bytes = 8, .type = TSDB_DATA_TYPE_BIGINT, .sysInfo = false},
{.name = "isvirtual", .bytes = 1, .type = TSDB_DATA_TYPE_BOOL, .sysInfo = false},
};
static const SSysDbTableSchema streamSchema[] = {
@ -247,7 +248,8 @@ static const SSysDbTableSchema userColsSchema[] = {
{.name = "col_length", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
{.name = "col_precision", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
{.name = "col_scale", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
{.name = "col_nullable", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false}
{.name = "col_nullable", .bytes = 4, .type = TSDB_DATA_TYPE_INT, .sysInfo = false},
{.name = "col_source", .bytes = TSDB_COL_FNAME_LEN - 1 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}
};
static const SSysDbTableSchema userTblDistSchema[] = {

View File

@ -354,6 +354,10 @@ bool withExtSchema(uint8_t tableType) {
return TSDB_SUPER_TABLE == tableType || TSDB_NORMAL_TABLE == tableType || TSDB_CHILD_TABLE == tableType;
}
bool hasRefCol(uint8_t tableType) {
return TSDB_VIRTUAL_NORMAL_TABLE == tableType || TSDB_VIRTUAL_CHILD_TABLE == tableType;
}
int8_t validColCompressLevel(uint8_t type, uint8_t level) {
if (level == TSDB_COLVAL_LEVEL_DISABLED) return 1;
if (level < TSDB_COLVAL_LEVEL_NOCHANGE || level > TSDB_COLVAL_LEVEL_HIGH) {

View File

@ -1224,7 +1224,7 @@ size_t blockDataGetRowSize(SSDataBlock* pBlock) {
*/
size_t blockDataGetSerialMetaSize(uint32_t numOfCols) {
// | version | total length | total rows | blankFull | total columns | flag seg| block group id | column schema
// | each column length |
// | each column length
return sizeof(int32_t) + sizeof(int32_t) + sizeof(int32_t) + sizeof(bool) + sizeof(int32_t) + sizeof(int32_t) +
sizeof(uint64_t) + numOfCols * (sizeof(int8_t) + sizeof(int32_t)) + numOfCols * sizeof(int32_t);
}
@ -2112,6 +2112,97 @@ int32_t createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData, SSDataB
return code;
}
int32_t createOneDataBlockWithColArray(const SSDataBlock* pDataBlock, SArray* pColArray, SSDataBlock** pResBlock) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SSDataBlock* pDstBlock = NULL;
QRY_PARAM_CHECK(pResBlock);
QUERY_CHECK_NULL(pDataBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
QUERY_CHECK_CODE(createDataBlock(&pDstBlock), lino, _return);
pDstBlock->info = pDataBlock->info;
pDstBlock->info.pks[0].pData = NULL;
pDstBlock->info.pks[1].pData = NULL;
pDstBlock->info.rows = 0;
pDstBlock->info.capacity = 0;
pDstBlock->info.rowSize = 0;
pDstBlock->info.id = pDataBlock->info.id;
pDstBlock->info.blankFill = pDataBlock->info.blankFill;
for (int32_t i = 0; i < taosArrayGetSize(pColArray); ++i) {
SColIdPair *pColPair = taosArrayGet(pColArray, i);
QUERY_CHECK_NULL(pColPair, code, lino, _return, terrno);
for (int32_t j = 0; j < taosArrayGetSize(pDataBlock->pDataBlock); ++j) {
SColumnInfoData* p = taosArrayGet(pDataBlock->pDataBlock, j);
if (p == NULL) {
continue;
}
if (p->info.colId == pColPair->vtbColId) {
QUERY_CHECK_CODE(blockDataAppendColInfo(pDstBlock, p), lino, _return);
break;
}
}
}
*pResBlock = pDstBlock;
return code;
_return:
uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
blockDataDestroy(pDstBlock);
return code;
}
int32_t createOneDataBlockWithTwoBlock(const SSDataBlock* pDataBlock, const SSDataBlock* pOrgBlock, SSDataBlock** pResBlock) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SSDataBlock *pDstBlock = NULL;
QRY_PARAM_CHECK(pResBlock);
QUERY_CHECK_NULL(pDataBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
QUERY_CHECK_NULL(pOrgBlock, code, lino, _return, TSDB_CODE_INVALID_PARA);
QUERY_CHECK_CODE(createOneDataBlock(pOrgBlock, false, &pDstBlock), lino, _return);
QUERY_CHECK_CODE(blockDataEnsureCapacity(pDstBlock, pDataBlock->info.rows), lino, _return);
for (int32_t i = 0; i < taosArrayGetSize(pOrgBlock->pDataBlock); ++i) {
SColumnInfoData* pDst = taosArrayGet(pDstBlock->pDataBlock, i);
SColumnInfoData* pSrc = taosArrayGet(pOrgBlock->pDataBlock, i);
QUERY_CHECK_NULL(pDst, code, lino, _return, terrno);
QUERY_CHECK_NULL(pSrc, code, lino, _return, terrno);
bool found = false;
for (int32_t j = 0; j < taosArrayGetSize(pDataBlock->pDataBlock); j++) {
SColumnInfoData *p = taosArrayGet(pDataBlock->pDataBlock, j);
if (p->info.slotId == pSrc->info.slotId) {
QUERY_CHECK_CODE(colDataAssign(pDst, p, (int32_t)pDataBlock->info.rows, &pDataBlock->info), lino, _return);
found = true;
break;
}
}
if (!found) {
colDataSetNNULL(pDst, 0, pDataBlock->info.rows);
}
}
pDstBlock->info.rows = pDataBlock->info.rows;
pDstBlock->info.capacity = pDataBlock->info.rows;
pDstBlock->info.window = pDataBlock->info.window;
*pResBlock = pDstBlock;
return code;
_return:
uError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
blockDataDestroy(pDstBlock);
return code;
}
int32_t createDataBlock(SSDataBlock** pResBlock) {
QRY_PARAM_CHECK(pResBlock);
SSDataBlock* pBlock = taosMemoryCalloc(1, sizeof(SSDataBlock));

View File

@ -188,6 +188,7 @@ SArray *mmGetMsgHandles() {
if (dmSetMgmtHandle(pArray, TDMT_VND_FETCH_TTL_EXPIRED_TBS_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_VND_DROP_TABLE_RSP, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_RESET_STREAM, mmPutMsgToWriteQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_GET_DB_INFO, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_ANAL_ALGO, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;
if (dmSetMgmtHandle(pArray, TDMT_MND_RETRIEVE_IP_WHITE, mmPutMsgToReadQueue, 0) == NULL) goto _OVER;

View File

@ -164,6 +164,7 @@ static void dmProcessRpcMsg(SDnode *pDnode, SRpcMsg *pRpc, SEpSet *pEpSet) {
case TDMT_SCH_FETCH_RSP:
case TDMT_SCH_MERGE_FETCH_RSP:
case TDMT_VND_SUBMIT_RSP:
case TDMT_MND_GET_DB_INFO_RSP:
code = qWorkerProcessRspMsg(NULL, NULL, pRpc, 0);
return;
case TDMT_MND_STATUS_RSP:

View File

@ -593,6 +593,7 @@ typedef struct {
SColCmpr* pCmpr;
int64_t keep;
SExtSchema* pExtSchemas;
int8_t virtualStb;
} SStbObj;
typedef struct {

View File

@ -80,6 +80,7 @@ int32_t mndInitDb(SMnode *pMnode) {
mndSetMsgHandle(pMnode, TDMT_MND_TRIM_DB, mndProcessTrimDbReq);
mndSetMsgHandle(pMnode, TDMT_MND_GET_DB_CFG, mndProcessGetDbCfgReq);
mndSetMsgHandle(pMnode, TDMT_MND_S3MIGRATE_DB, mndProcessS3MigrateDbReq);
mndSetMsgHandle(pMnode, TDMT_MND_GET_DB_INFO, mndProcessUseDbReq);
mndAddShowRetrieveHandle(pMnode, TSDB_MGMT_TABLE_DB, mndRetrieveDbs);
mndAddShowFreeIterHandle(pMnode, TSDB_MGMT_TABLE_DB, mndCancelGetNextDb);

View File

@ -198,6 +198,7 @@ void dumpStb(SSdb *pSdb, SJson *json) {
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "commentLen", i642str(pObj->commentLen)), pObj, &lino, _OVER);
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "ast1Len", i642str(pObj->ast1Len)), pObj, &lino, _OVER);
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "ast2Len", i642str(pObj->ast2Len)), pObj, &lino, _OVER);
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "virtual", i642str(pObj->virtualStb)), pObj, &lino, _OVER);
RETRIEVE_CHECK_GOTO(tjsonAddStringToObject(item, "numOfColumns", i642str(pObj->numOfColumns)), pObj, &lino, _OVER);
SJson *columns = tjsonAddArrayToObject(item, "columns");

View File

@ -47,6 +47,7 @@ static int32_t mndInsInitMeta(SHashObj *hash) {
meta.tableType = TSDB_SYSTEM_TABLE;
meta.sversion = 1;
meta.tversion = 1;
meta.virtualStb = false;
size_t size = 0;
const SSysTableMeta *pInfosTableMeta = NULL;
@ -128,6 +129,7 @@ int32_t mndBuildInsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbN
pRsp->numOfTags = pMeta->numOfTags;
pRsp->numOfColumns = pMeta->numOfColumns;
pRsp->tableType = pMeta->tableType;
pRsp->virtualStb = pMeta->virtualStb;
pRsp->pSchemas = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchema));
if (pRsp->pSchemas == NULL) {
@ -139,6 +141,7 @@ int32_t mndBuildInsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbN
memcpy(pRsp->pSchemas, pMeta->pSchemas, pMeta->numOfColumns * sizeof(SSchema));
pRsp->pSchemaExt = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchemaExt));
pRsp->pColRefs = taosMemCalloc(pMeta->numOfColumns, sizeof(SColRef));
TAOS_RETURN(code);
}

View File

@ -46,6 +46,7 @@ int32_t mndPerfsInitMeta(SHashObj *hash) {
meta.tableType = TSDB_SYSTEM_TABLE;
meta.sversion = 1;
meta.tversion = 1;
meta.virtualStb = false;
size_t size = 0;
const SSysTableMeta *pSysDbTableMeta = NULL;
@ -113,6 +114,7 @@ int32_t mndBuildPerfsTableCfg(SMnode *pMnode, const char *dbFName, const char *t
pRsp->numOfTags = pMeta->numOfTags;
pRsp->numOfColumns = pMeta->numOfColumns;
pRsp->tableType = pMeta->tableType;
pRsp->virtualStb = pMeta->virtualStb;
pRsp->pSchemas = taosMemoryCalloc(pMeta->numOfColumns, sizeof(SSchema));
if (pRsp->pSchemas == NULL) {

View File

@ -33,7 +33,7 @@
#include "mndVgroup.h"
#include "tname.h"
#define STB_VER_NUMBER 2
#define STB_VER_NUMBER 3
#define STB_RESERVE_SIZE 56
static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw);
@ -194,13 +194,13 @@ SSdbRaw *mndStbActionEncode(SStbObj *pStb) {
}
SDB_SET_INT64(pRaw, dataPos, pStb->keep, _OVER)
if (hasTypeMod) {
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
SDB_SET_INT32(pRaw, dataPos, pStb->pExtSchemas[i].typeMod, _OVER);
}
}
SDB_SET_INT8(pRaw, dataPos, pStb->virtualStb, _OVER)
SDB_SET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
SDB_SET_DATALEN(pRaw, dataPos, _OVER)
@ -313,7 +313,7 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
}
pStb->pCmpr = taosMemoryCalloc(pStb->numOfColumns, sizeof(SColCmpr));
if (sver < STB_VER_NUMBER) {
if (sver < STB_VER_NUMBER - 1) {
// compatible with old data, setup default compress value
// impl later
for (int i = 0; i < pStb->numOfColumns; i++) {
@ -341,6 +341,12 @@ static SSdbRow *mndStbActionDecode(SSdbRaw *pRaw) {
}
}
if (sver < STB_VER_NUMBER) {
pStb->virtualStb = 0;
} else {
SDB_GET_INT8(pRaw, dataPos, &pStb->virtualStb, _OVER)
}
SDB_GET_RESERVE(pRaw, dataPos, STB_RESERVE_SIZE, _OVER)
terrno = 0;
@ -544,6 +550,7 @@ void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int3
req.alterOriData = alterOriData;
req.alterOriDataLen = alterOriDataLen;
req.source = pStb->source;
req.virtualStb = pStb->virtualStb;
// todo
req.schemaRow.nCols = pStb->numOfColumns;
req.schemaRow.version = pStb->colVer;
@ -674,6 +681,11 @@ int32_t mndCheckCreateStbReq(SMCreateStbReq *pCreate) {
TAOS_RETURN(code);
}
if (pCreate->virtualStb != 0 && pCreate->virtualStb != 1) {
code = TSDB_CODE_MND_INVALID_STB_OPTION;
TAOS_RETURN(code);
}
if (pCreate->numOfColumns < TSDB_MIN_COLUMNS || pCreate->numOfTags + pCreate->numOfColumns > TSDB_MAX_COLUMNS) {
code = TSDB_CODE_PAR_INVALID_COLUMNS_NUM;
TAOS_RETURN(code);
@ -909,6 +921,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat
pDst->pFuncs = pCreate->pFuncs;
pDst->source = pCreate->source;
pDst->keep = pCreate->keep;
pDst->virtualStb = pCreate->virtualStb;
pCreate->pFuncs = NULL;
if (pDst->commentLen > 0) {
@ -2223,6 +2236,7 @@ static int32_t mndSetAlterStbRedoActions2(SMnode *pMnode, STrans *pTrans, SDbObj
TAOS_RETURN(code);
}
static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbName, STableMetaRsp *pRsp) {
int32_t code = 0;
taosRLockLatch(&pStb->lock);
@ -2240,7 +2254,8 @@ static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbNa
code = terrno;
TAOS_RETURN(code);
}
pRsp->numOfColRefs = 0;
pRsp->pColRefs = NULL;
tstrncpy(pRsp->dbFName, pStb->db, sizeof(pRsp->dbFName));
tstrncpy(pRsp->tbName, tbName, sizeof(pRsp->tbName));
tstrncpy(pRsp->stbName, tbName, sizeof(pRsp->stbName));
@ -2253,6 +2268,7 @@ static int32_t mndBuildStbSchemaImp(SDbObj *pDb, SStbObj *pStb, const char *tbNa
pRsp->tversion = pStb->tagVer;
pRsp->suid = pStb->uid;
pRsp->tuid = pStb->uid;
pRsp->virtualStb = pStb->virtualStb;
for (int32_t i = 0; i < pStb->numOfColumns; ++i) {
SSchema *pSchema = &pRsp->pSchemas[i];
@ -2350,6 +2366,8 @@ static int32_t mndBuildStbCfgImp(SDbObj *pDb, SStbObj *pStb, const char *tbName,
pSchExt->typeMod = pStb->pExtSchemas[i].typeMod;
}
}
pRsp->virtualStb = pStb->virtualStb;
pRsp->pColRefs = NULL;
taosRUnLockLatch(&pStb->lock);
TAOS_RETURN(code);
@ -3493,6 +3511,10 @@ static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBloc
RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)(&pStb->uid), false), pStb, &lino, _ERROR);
}
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
if (pColInfo) {
RETRIEVE_CHECK_GOTO(colDataSetVal(pColInfo, numOfRows, (const char *)(&pStb->virtualStb), false), pStb, &lino, _ERROR);
}
numOfRows++;
sdbRelease(pSdb, pStb);
}
@ -3573,7 +3595,7 @@ static int32_t buildDbColsInfoBlock(const SSDataBlock *p, const SSysTableMeta *p
pColInfoData = taosArrayGet(p->pDataBlock, 5);
TAOS_CHECK_GOTO(colDataSetVal(pColInfoData, numOfRows, (const char *)&pm->schema[j].bytes, false), &lino, _OVER);
for (int32_t k = 6; k <= 8; ++k) {
for (int32_t k = 6; k <= 9; ++k) {
pColInfoData = taosArrayGet(p->pDataBlock, k);
colDataSetNULL(pColInfoData, numOfRows);
}
@ -3581,6 +3603,7 @@ static int32_t buildDbColsInfoBlock(const SSDataBlock *p, const SSysTableMeta *p
numOfRows += 1;
}
}
return numOfRows;
_OVER:
mError("failed at %s:%d since %s", __FUNCTION__, lino, tstrerror(code));
return numOfRows;

View File

@ -298,6 +298,8 @@ typedef struct {
int64_t numOfSTables;
int64_t numOfCTables;
int64_t numOfNTables;
int64_t numOfVTables;
int64_t numOfVCTables;
int64_t numOfReportedTimeSeries;
int64_t numOfNTimeSeries;
int64_t numOfTimeSeries;
@ -348,6 +350,10 @@ struct SVnodeCfg {
#define TABLE_IS_COL_COMPRESSED(FLG) (((FLG) & (TABLE_COL_COMPRESSED)) != 0)
#define TABLE_SET_COL_COMPRESSED(FLG) ((FLG) |= TABLE_COL_COMPRESSED)
#define TABLE_VIRTUAL ((int8_t)0x4)
#define TABLE_IS_VIRTUAL(FLG) (((FLG) & (TABLE_VIRTUAL)) != 0)
#define TABLE_SET_VIRTUAL(FLG) ((FLG) |= TABLE_VIRTUAL)
struct SFileSetReader;
int32_t tsdbFileSetReaderOpen(void *pVnode, struct SFileSetReader **ppReader);
int32_t tsdbFileSetReaderNext(struct SFileSetReader *pReader);

View File

@ -165,6 +165,7 @@ int32_t metaFilterTableName(void* pVnode, SMetaFltParam* param, SArray* pUids);
int32_t metaFilterTtl(void* pVnode, SMetaFltParam* param, SArray* pUids);
int32_t metaGetColCmpr(SMeta* pMeta, tb_uid_t uid, SHashObj** colCmprObj);
int32_t updataTableColRef(SColRefWrapper *pWp, const SSchema *pSchema, int8_t add, SColRef *pColRef);
#if !defined(META_REFACT) && !defined(TD_ASTRA)
// SMetaDB
int metaOpenDB(SMeta* pMeta);

View File

@ -44,6 +44,25 @@ static int32_t metaEncodeExtSchema(SEncoder* pCoder, const SMetaEntry* pME) {
return 0;
}
int meteEncodeColRefEntry(SEncoder *pCoder, const SMetaEntry *pME) {
const SColRefWrapper *pw = &pME->colRef;
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->nCols));
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->version));
uDebug("encode cols:%d", pw->nCols);
for (int32_t i = 0; i < pw->nCols; i++) {
SColRef *p = &pw->pColRef[i];
TAOS_CHECK_RETURN(tEncodeI8(pCoder, p->hasRef));
TAOS_CHECK_RETURN(tEncodeI16v(pCoder, p->id));
if (p->hasRef) {
TAOS_CHECK_RETURN(tEncodeCStr(pCoder, p->refDbName));
TAOS_CHECK_RETURN(tEncodeCStr(pCoder, p->refTableName));
TAOS_CHECK_RETURN(tEncodeCStr(pCoder, p->refColName));
}
}
return 0;
}
static int32_t metaDecodeExtSchemas(SDecoder* pDecoder, SMetaEntry* pME) {
bool hasExtSchema = false;
SSchemaWrapper* pSchWrapper = NULL;
@ -83,8 +102,8 @@ SExtSchema* metaGetSExtSchema(const SMetaEntry *pME) {
hasTypeMods = schemasHasTypeMod(pSchWrapper->pSchema, pSchWrapper->nCols);
if (hasTypeMods) {
SExtSchema* ret = taosMemoryMalloc(sizeof(SExtSchema) * pSchWrapper->nCols);
if (ret != NULL){
SExtSchema *ret = taosMemoryMalloc(sizeof(SExtSchema) * pSchWrapper->nCols);
if (ret != NULL) {
memcpy(ret, pME->pExtSchemas, pSchWrapper->nCols * sizeof(SExtSchema));
}
return ret;
@ -92,6 +111,62 @@ SExtSchema* metaGetSExtSchema(const SMetaEntry *pME) {
return NULL;
}
int meteDecodeColRefEntry(SDecoder *pDecoder, SMetaEntry *pME) {
SColRefWrapper *pWrapper = &pME->colRef;
TAOS_CHECK_RETURN(tDecodeI32v(pDecoder, &pWrapper->nCols));
if (pWrapper->nCols == 0) {
return 0;
}
TAOS_CHECK_RETURN(tDecodeI32v(pDecoder, &pWrapper->version));
uDebug("decode cols:%d", pWrapper->nCols);
pWrapper->pColRef = (SColRef *)tDecoderMalloc(pDecoder, pWrapper->nCols * sizeof(SColRef));
if (pWrapper->pColRef == NULL) {
return terrno;
}
for (int i = 0; i < pWrapper->nCols; i++) {
SColRef *p = &pWrapper->pColRef[i];
TAOS_CHECK_RETURN(tDecodeI8(pDecoder, (int8_t *)&p->hasRef));
TAOS_CHECK_RETURN(tDecodeI16v(pDecoder, &p->id));
if (p->hasRef) {
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, p->refDbName));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, p->refTableName));
TAOS_CHECK_RETURN(tDecodeCStrTo(pDecoder, p->refColName));
}
}
return 0;
}
static FORCE_INLINE int32_t metatInitDefaultSColRefWrapper(SDecoder *pDecoder, SColRefWrapper *pRef,
SSchemaWrapper *pSchema) {
pRef->nCols = pSchema->nCols;
if ((pRef->pColRef = (SColRef *)tDecoderMalloc(pDecoder, pRef->nCols * sizeof(SColRef))) == NULL) {
return terrno;
}
for (int32_t i = 0; i < pRef->nCols; i++) {
SColRef *pColRef = &pRef->pColRef[i];
SSchema *pColSchema = &pSchema->pSchema[i];
pColRef->id = pColSchema->colId;
pColRef->hasRef = false;
}
return 0;
}
static int32_t metaCloneColRef(const SColRefWrapper*pSrc, SColRefWrapper *pDst) {
if (pSrc->nCols > 0) {
pDst->nCols = pSrc->nCols;
pDst->version = pSrc->version;
pDst->pColRef = (SColRef*)taosMemoryCalloc(pSrc->nCols, sizeof(SColRef));
if (NULL == pDst->pColRef) {
return terrno;
}
memcpy(pDst->pColRef, pSrc->pColRef, pSrc->nCols * sizeof(SColRef));
}
return 0;
}
int meteEncodeColCmprEntry(SEncoder *pCoder, const SMetaEntry *pME) {
const SColCmprWrapper *pw = &pME->colCmpr;
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pw->nCols));
@ -155,6 +230,12 @@ static int32_t metaCloneColCmpr(const SColCmprWrapper *pSrc, SColCmprWrapper *pD
return 0;
}
static void metaCloneColRefFree(SColRefWrapper *pColRef) {
if (pColRef) {
taosMemoryFreeClear(pColRef->pColRef);
}
}
static void metaCloneColCmprFree(SColCmprWrapper *pCmpr) {
if (pCmpr) {
taosMemoryFreeClear(pCmpr->pColCmpr);
@ -181,7 +262,7 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
if (TABLE_IS_ROLLUP(pME->flags)) {
TAOS_CHECK_RETURN(tEncodeSRSmaParam(pCoder, &pME->stbEntry.rsmaParam));
}
} else if (pME->type == TSDB_CHILD_TABLE) {
} else if (pME->type == TSDB_CHILD_TABLE || pME->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ctbEntry.btime));
TAOS_CHECK_RETURN(tEncodeI32(pCoder, pME->ctbEntry.ttlDays));
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pME->ctbEntry.commentLen));
@ -190,7 +271,7 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
}
TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ctbEntry.suid));
TAOS_CHECK_RETURN(tEncodeTag(pCoder, (const STag *)pME->ctbEntry.pTags));
} else if (pME->type == TSDB_NORMAL_TABLE) {
} else if (pME->type == TSDB_NORMAL_TABLE || pME->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_RETURN(tEncodeI64(pCoder, pME->ntbEntry.btime));
TAOS_CHECK_RETURN(tEncodeI32(pCoder, pME->ntbEntry.ttlDays));
TAOS_CHECK_RETURN(tEncodeI32v(pCoder, pME->ntbEntry.commentLen));
@ -205,7 +286,11 @@ int metaEncodeEntry(SEncoder *pCoder, const SMetaEntry *pME) {
metaError("meta/entry: invalide table type: %" PRId8 " encode failed.", pME->type);
return TSDB_CODE_INVALID_PARA;
}
TAOS_CHECK_RETURN(meteEncodeColCmprEntry(pCoder, pME));
if (pME->type == TSDB_VIRTUAL_NORMAL_TABLE || pME->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_RETURN(meteEncodeColRefEntry(pCoder, pME));
} else {
TAOS_CHECK_RETURN(meteEncodeColCmprEntry(pCoder, pME));
}
TAOS_CHECK_RETURN(metaEncodeExtSchema(pCoder, pME));
}
if (pME->type == TSDB_SUPER_TABLE) {
@ -237,7 +322,7 @@ int metaDecodeEntryImpl(SDecoder *pCoder, SMetaEntry *pME, bool headerOnly) {
if (TABLE_IS_ROLLUP(pME->flags)) {
TAOS_CHECK_RETURN(tDecodeSRSmaParam(pCoder, &pME->stbEntry.rsmaParam));
}
} else if (pME->type == TSDB_CHILD_TABLE) {
} else if (pME->type == TSDB_CHILD_TABLE || pME->type == TSDB_VIRTUAL_CHILD_TABLE) {
TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ctbEntry.btime));
TAOS_CHECK_RETURN(tDecodeI32(pCoder, &pME->ctbEntry.ttlDays));
TAOS_CHECK_RETURN(tDecodeI32v(pCoder, &pME->ctbEntry.commentLen));
@ -246,7 +331,7 @@ int metaDecodeEntryImpl(SDecoder *pCoder, SMetaEntry *pME, bool headerOnly) {
}
TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ctbEntry.suid));
TAOS_CHECK_RETURN(tDecodeTag(pCoder, (STag **)&pME->ctbEntry.pTags));
} else if (pME->type == TSDB_NORMAL_TABLE) {
} else if (pME->type == TSDB_NORMAL_TABLE || pME->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_RETURN(tDecodeI64(pCoder, &pME->ntbEntry.btime));
TAOS_CHECK_RETURN(tDecodeI32(pCoder, &pME->ntbEntry.ttlDays));
TAOS_CHECK_RETURN(tDecodeI32v(pCoder, &pME->ntbEntry.commentLen));
@ -288,6 +373,16 @@ int metaDecodeEntryImpl(SDecoder *pCoder, SMetaEntry *pME, bool headerOnly) {
TAOS_CHECK_RETURN(metatInitDefaultSColCmprWrapper(pCoder, &pME->colCmpr, &pME->ntbEntry.schemaRow));
}
TABLE_SET_COL_COMPRESSED(pME->flags);
} else if (pME->type == TSDB_VIRTUAL_NORMAL_TABLE || pME->type == TSDB_VIRTUAL_CHILD_TABLE) {
if (!tDecodeIsEnd(pCoder)) {
uDebug("set type: %d, tableName:%s", pME->type, pME->name);
TAOS_CHECK_RETURN(meteDecodeColRefEntry(pCoder, pME));
} else {
uDebug("set default type: %d, tableName:%s", pME->type, pME->name);
if (pME->type == TSDB_VIRTUAL_NORMAL_TABLE) {
TAOS_CHECK_RETURN(metatInitDefaultSColRefWrapper(pCoder, &pME->colRef, &pME->ntbEntry.schemaRow));
}
}
}
if (!tDecodeIsEnd(pCoder)) {
TAOS_CHECK_RETURN(metaDecodeExtSchemas(pCoder, pME));
@ -342,10 +437,10 @@ void metaCloneEntryFree(SMetaEntry **ppEntry) {
if (TSDB_SUPER_TABLE == (*ppEntry)->type) {
metaCloneSchemaFree(&(*ppEntry)->stbEntry.schemaRow);
metaCloneSchemaFree(&(*ppEntry)->stbEntry.schemaTag);
} else if (TSDB_CHILD_TABLE == (*ppEntry)->type) {
} else if (TSDB_CHILD_TABLE == (*ppEntry)->type || TSDB_VIRTUAL_CHILD_TABLE == (*ppEntry)->type) {
taosMemoryFreeClear((*ppEntry)->ctbEntry.comment);
taosMemoryFreeClear((*ppEntry)->ctbEntry.pTags);
} else if (TSDB_NORMAL_TABLE == (*ppEntry)->type) {
} else if (TSDB_NORMAL_TABLE == (*ppEntry)->type || TSDB_VIRTUAL_NORMAL_TABLE == (*ppEntry)->type) {
metaCloneSchemaFree(&(*ppEntry)->ntbEntry.schemaRow);
taosMemoryFreeClear((*ppEntry)->ntbEntry.comment);
} else {
@ -353,6 +448,7 @@ void metaCloneEntryFree(SMetaEntry **ppEntry) {
}
metaCloneColCmprFree(&(*ppEntry)->colCmpr);
taosMemoryFreeClear((*ppEntry)->pExtSchemas);
metaCloneColRefFree(&(*ppEntry)->colRef);
taosMemoryFreeClear(*ppEntry);
return;
@ -402,7 +498,7 @@ int32_t metaCloneEntry(const SMetaEntry *pEntry, SMetaEntry **ppEntry) {
return code;
}
(*ppEntry)->stbEntry.keep = pEntry->stbEntry.keep;
} else if (pEntry->type == TSDB_CHILD_TABLE) {
} else if (pEntry->type == TSDB_CHILD_TABLE || pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
(*ppEntry)->ctbEntry.btime = pEntry->ctbEntry.btime;
(*ppEntry)->ctbEntry.ttlDays = pEntry->ctbEntry.ttlDays;
(*ppEntry)->ctbEntry.suid = pEntry->ctbEntry.suid;
@ -428,7 +524,7 @@ int32_t metaCloneEntry(const SMetaEntry *pEntry, SMetaEntry **ppEntry) {
return code;
}
memcpy((*ppEntry)->ctbEntry.pTags, pEntry->ctbEntry.pTags, pTags->len);
} else if (pEntry->type == TSDB_NORMAL_TABLE) {
} else if (pEntry->type == TSDB_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
(*ppEntry)->ntbEntry.btime = pEntry->ntbEntry.btime;
(*ppEntry)->ntbEntry.ttlDays = pEntry->ntbEntry.ttlDays;
(*ppEntry)->ntbEntry.ncid = pEntry->ntbEntry.ncid;
@ -455,10 +551,18 @@ int32_t metaCloneEntry(const SMetaEntry *pEntry, SMetaEntry **ppEntry) {
return TSDB_CODE_INVALID_PARA;
}
code = metaCloneColCmpr(&pEntry->colCmpr, &(*ppEntry)->colCmpr);
if (code) {
metaCloneEntryFree(ppEntry);
return code;
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
code = metaCloneColRef(&pEntry->colRef, &(*ppEntry)->colRef);
if (code) {
metaCloneEntryFree(ppEntry);
return code;
}
} else {
code = metaCloneColCmpr(&pEntry->colCmpr, &(*ppEntry)->colCmpr);
if (code) {
metaCloneEntryFree(ppEntry);
return code;
}
}
if (pEntry->pExtSchemas && pEntry->colCmpr.nCols > 0) {
(*ppEntry)->pExtSchemas = taosMemoryCalloc(pEntry->colCmpr.nCols, sizeof(SExtSchema));

View File

@ -218,7 +218,7 @@ static int32_t metaSchemaTableUpsert(SMeta *pMeta, const SMetaHandleParam *pPara
const SSchemaWrapper *pSchema = NULL;
if (pEntry->type == TSDB_SUPER_TABLE) {
pSchema = &pEntry->stbEntry.schemaRow;
} else if (pEntry->type == TSDB_NORMAL_TABLE) {
} else if (pEntry->type == TSDB_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
pSchema = &pEntry->ntbEntry.schemaRow;
} else {
return TSDB_CODE_INVALID_PARA;
@ -370,6 +370,88 @@ static int32_t metaAddOrDropTagIndexOfSuperTable(SMeta *pMeta, const SMetaHandle
return code;
}
static int32_t metaAddOrDropColumnIndexOfVirtualSuperTable(SMeta *pMeta, const SMetaHandleParam *pParam,
const SSchema *pOldColumn, const SSchema *pNewColumn) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
const SMetaEntry *pOldEntry = pParam->pOldEntry;
enum { ADD_COLUMN, DROP_COLUMN } action;
if (pOldColumn && pNewColumn) {
return TSDB_CODE_SUCCESS;
} else if (pOldColumn) {
action = DROP_COLUMN;
} else {
action = ADD_COLUMN;
}
// fetch all child tables
SArray *childTables = 0;
code = metaGetChildUidsOfSuperTable(pMeta, pEntry->uid, &childTables);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
// do drop or add index
for (int32_t i = 0; i < taosArrayGetSize(childTables); i++) {
int64_t uid = *(int64_t *)taosArrayGet(childTables, i);
// fetch child entry
SMetaEntry *pChildEntry = NULL;
code = metaFetchEntryByUid(pMeta, uid, &pChildEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
return code;
}
SMetaHandleParam param = {
.pEntry = pChildEntry
};
if (action == ADD_COLUMN) {
code = updataTableColRef(&pChildEntry->colRef, pNewColumn, 1, NULL);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
metaFetchEntryFree(&pChildEntry);
return code;
}
code = metaEntryTableUpdate(pMeta, &param);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
metaFetchEntryFree(&pChildEntry);
return code;
}
} else {
code = updataTableColRef(&pChildEntry->colRef, pOldColumn, 0, NULL);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
metaFetchEntryFree(&pChildEntry);
return code;
}
code = metaEntryTableUpdate(pMeta, &param);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
taosArrayDestroy(childTables);
metaFetchEntryFree(&pChildEntry);
return code;
}
}
metaFetchEntryFree(&pChildEntry);
}
taosArrayDestroy(childTables);
return code;
}
static int32_t metaUpdateSuperTableTagSchema(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
@ -431,6 +513,67 @@ static int32_t metaUpdateSuperTableTagSchema(SMeta *pMeta, const SMetaHandlePara
return code;
}
static int32_t metaUpdateSuperTableRowSchema(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
const SMetaEntry *pOldEntry = pParam->pOldEntry;
const SSchemaWrapper *pNewRowSchema = &pEntry->stbEntry.schemaRow;
const SSchemaWrapper *pOldRowSchema = &pOldEntry->stbEntry.schemaRow;
int32_t iOld = 0, iNew = 0;
for (; iOld < pOldRowSchema->nCols && iNew < pNewRowSchema->nCols;) {
SSchema *pOldColumn = pOldRowSchema->pSchema + iOld;
SSchema *pNewColumn = pNewRowSchema->pSchema + iNew;
if (pOldColumn->colId == pNewColumn->colId) {
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, pOldColumn, pNewColumn);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
iOld++;
iNew++;
} else if (pOldColumn->colId < pNewColumn->colId) {
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, pOldColumn, NULL);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
iOld++;
} else {
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, NULL, pNewColumn);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
iNew++;
}
}
for (; iOld < pOldRowSchema->nCols; iOld++) {
SSchema *pOldColumn = pOldRowSchema->pSchema + iOld;
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, pOldColumn, NULL);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
for (; iNew < pNewRowSchema->nCols; iNew++) {
SSchema *pNewColumn = pNewRowSchema->pSchema + iNew;
code = metaAddOrDropColumnIndexOfVirtualSuperTable(pMeta, pParam, NULL, pNewColumn);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
return code;
}
static int32_t metaSchemaTableUpdate(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
@ -441,7 +584,7 @@ static int32_t metaSchemaTableUpdate(SMeta *pMeta, const SMetaHandleParam *pPara
return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA);
}
if (pEntry->type == TSDB_NORMAL_TABLE) {
if (pEntry->type == TSDB_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
// check row schema
if (pOldEntry->ntbEntry.schemaRow.version != pEntry->ntbEntry.schemaRow.version) {
return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA);
@ -449,7 +592,12 @@ static int32_t metaSchemaTableUpdate(SMeta *pMeta, const SMetaHandleParam *pPara
} else if (pEntry->type == TSDB_SUPER_TABLE) {
// check row schema
if (pOldEntry->stbEntry.schemaRow.version != pEntry->stbEntry.schemaRow.version) {
return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA);
if (TABLE_IS_VIRTUAL(pEntry->flags)) {
return metaUpdateSuperTableRowSchema(pMeta, pParam);
} else {
return metaSchemaTableUpsert(pMeta, pParam, META_TABLE_OP_UPDATA);
}
}
// check tag schema
@ -478,10 +626,10 @@ static void metaBuildEntryInfo(const SMetaEntry *pEntry, SMetaInfo *pInfo) {
if (pEntry->type == TSDB_SUPER_TABLE) {
pInfo->suid = pEntry->uid;
pInfo->skmVer = pEntry->stbEntry.schemaRow.version;
} else if (pEntry->type == TSDB_CHILD_TABLE) {
} else if (pEntry->type == TSDB_CHILD_TABLE || pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
pInfo->suid = pEntry->ctbEntry.suid;
pInfo->skmVer = 0;
} else if (pEntry->type == TSDB_NORMAL_TABLE) {
} else if (pEntry->type == TSDB_NORMAL_TABLE || pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
pInfo->suid = 0;
pInfo->skmVer = pEntry->ntbEntry.schemaRow.version;
}
@ -877,9 +1025,9 @@ static int32_t metaBtimeIdxUpsert(SMeta *pMeta, const SMetaHandleParam *pParam,
.uid = pEntry->uid,
};
if (TSDB_CHILD_TABLE == pEntry->type) {
if (TSDB_CHILD_TABLE == pEntry->type || TSDB_VIRTUAL_CHILD_TABLE == pEntry->type) {
key.btime = pEntry->ctbEntry.btime;
} else if (TSDB_NORMAL_TABLE == pEntry->type) {
} else if (TSDB_NORMAL_TABLE == pEntry->type || TSDB_VIRTUAL_NORMAL_TABLE == pEntry->type) {
key.btime = pEntry->ntbEntry.btime;
} else {
return TSDB_CODE_INVALID_PARA;
@ -1249,6 +1397,121 @@ static int32_t metaHandleChildTableCreate(SMeta *pMeta, const SMetaEntry *pEntry
return code;
}
static int32_t metaHandleVirtualNormalTableCreateImpl(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_INSERT}, //
{META_SCHEMA_TABLE, META_TABLE_OP_UPDATA}, // TODO: need to be insert
{META_UID_IDX, META_TABLE_OP_INSERT}, //
{META_NAME_IDX, META_TABLE_OP_INSERT}, //
{META_BTIME_IDX, META_TABLE_OP_INSERT}, //
};
for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
SMetaHandleParam param = {
.pEntry = pEntry,
};
code = metaTableOpFn[op->table][op->op](pMeta, &param);
if (TSDB_CODE_SUCCESS != code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
return code;
}
static int32_t metaHandleVirtualNormalTableCreate(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
// update TDB
metaWLock(pMeta);
code = metaHandleVirtualNormalTableCreateImpl(pMeta, pEntry);
metaULock(pMeta);
// update other stuff
if (TSDB_CODE_SUCCESS == code) {
pMeta->pVnode->config.vndStats.numOfVTables++;
} else {
metaErr(TD_VID(pMeta->pVnode), code);
}
return code;
}
static int32_t metaHandleVirtualChildTableCreateImpl(SMeta *pMeta, const SMetaEntry *pEntry, const SMetaEntry *pSuperEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_INSERT}, //
{META_UID_IDX, META_TABLE_OP_INSERT}, //
{META_NAME_IDX, META_TABLE_OP_INSERT}, //
{META_CHILD_IDX, META_TABLE_OP_INSERT}, //
{META_TAG_IDX, META_TABLE_OP_INSERT}, //
{META_BTIME_IDX, META_TABLE_OP_INSERT}, //
};
for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
SMetaHandleParam param = {
.pEntry = pEntry,
.pSuperEntry = pSuperEntry,
};
code = metaTableOpFn[op->table][op->op](pMeta, &param);
if (TSDB_CODE_SUCCESS != code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
if (TSDB_CODE_SUCCESS == code) {
metaUpdateStbStats(pMeta, pSuperEntry->uid, 1, 0, -1);
int32_t ret = metaUidCacheClear(pMeta, pSuperEntry->uid);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
ret = metaTbGroupCacheClear(pMeta, pSuperEntry->uid);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
}
return code;
}
static int32_t metaHandleVirtualChildTableCreate(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pSuperEntry = NULL;
// get the super table entry
code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuperEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
// update TDB
metaWLock(pMeta);
code = metaHandleVirtualChildTableCreateImpl(pMeta, pEntry, pSuperEntry);
metaULock(pMeta);
// update other stuff
if (TSDB_CODE_SUCCESS == code) {
pMeta->pVnode->config.vndStats.numOfVCTables++;
} else {
metaErr(TD_VID(pMeta->pVnode), code);
}
metaFetchEntryFree(&pSuperEntry);
return code;
}
static int32_t metaHandleNormalTableDropImpl(SMeta *pMeta, SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
@ -1439,6 +1702,165 @@ static int32_t metaHandleChildTableDrop(SMeta *pMeta, const SMetaEntry *pEntry,
return code;
}
static int32_t metaHandleVirtualNormalTableDropImpl(SMeta *pMeta, SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_DELETE}, //
{META_UID_IDX, META_TABLE_OP_DELETE}, //
{META_NAME_IDX, META_TABLE_OP_DELETE}, //
{META_BTIME_IDX, META_TABLE_OP_DELETE}, //
// {META_SCHEMA_TABLE, META_TABLE_OP_DELETE}, //
};
for (int32_t i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
code = metaTableOpFn[op->table][op->op](pMeta, pParam);
if (code) {
const SMetaEntry *pEntry = pParam->pEntry;
metaErr(TD_VID(pMeta->pVnode), code);
}
}
return code;
}
static int32_t metaHandleVirtualNormalTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pOldEntry = NULL;
// fetch the entry
code = metaFetchEntryByUid(pMeta, pEntry->uid, &pOldEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
SMetaHandleParam param = {
.pEntry = pEntry,
.pOldEntry = pOldEntry,
};
// do the drop
metaWLock(pMeta);
code = metaHandleVirtualNormalTableDropImpl(pMeta, &param);
metaULock(pMeta);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pOldEntry);
return code;
}
// update other stuff
pMeta->pVnode->config.vndStats.numOfVTables--;
#if 0
if (tbUids) {
if (taosArrayPush(tbUids, &uid) == NULL) {
rc = terrno;
goto _exit;
}
}
#endif
if (!TSDB_CACHE_NO(pMeta->pVnode->config)) {
int32_t ret = tsdbCacheDropTable(pMeta->pVnode->pTsdb, pOldEntry->uid, 0, NULL);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
}
metaFetchEntryFree(&pOldEntry);
return code;
}
static int32_t metaHandleVirtualChildTableDropImpl(SMeta *pMeta, const SMetaHandleParam *pParam, bool superDropped) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
const SMetaEntry *pChild = pParam->pOldEntry;
const SMetaEntry *pSuper = pParam->pSuperEntry;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_DELETE}, //
{META_UID_IDX, META_TABLE_OP_DELETE}, //
{META_NAME_IDX, META_TABLE_OP_DELETE}, //
{META_CHILD_IDX, META_TABLE_OP_DELETE}, //
{META_TAG_IDX, META_TABLE_OP_DELETE}, //
{META_BTIME_IDX, META_TABLE_OP_DELETE}, //
};
for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
if (op->table == META_ENTRY_TABLE && superDropped) {
continue;
}
code = metaTableOpFn[op->table][op->op](pMeta, pParam);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
--pMeta->pVnode->config.vndStats.numOfVCTables;
metaUpdateStbStats(pMeta, pParam->pSuperEntry->uid, -1, 0, -1);
int32_t ret = metaUidCacheClear(pMeta, pSuper->uid);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
ret = metaTbGroupCacheClear(pMeta, pSuper->uid);
if (ret < 0) {
metaErr(TD_VID(pMeta->pVnode), ret);
}
return code;
}
static int32_t metaHandleVirtualChildTableDrop(SMeta *pMeta, const SMetaEntry *pEntry, bool superDropped) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pChild = NULL;
SMetaEntry *pSuper = NULL;
// fetch old entry
code = metaFetchEntryByUid(pMeta, pEntry->uid, &pChild);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
// fetch super entry
code = metaFetchEntryByUid(pMeta, pChild->ctbEntry.suid, &pSuper);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pChild);
return code;
}
SMetaHandleParam param = {
.pEntry = pEntry,
.pOldEntry = pChild,
.pSuperEntry = pSuper,
};
// do the drop
metaWLock(pMeta);
code = metaHandleVirtualChildTableDropImpl(pMeta, &param, superDropped);
metaULock(pMeta);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pChild);
metaFetchEntryFree(&pSuper);
return code;
}
metaFetchEntryFree(&pChild);
metaFetchEntryFree(&pSuper);
return code;
}
static int32_t metaGetChildUidsOfSuperTable(SMeta *pMeta, tb_uid_t suid, SArray **childList) {
int32_t code = TSDB_CODE_SUCCESS;
void *key = NULL;
@ -1551,6 +1973,65 @@ static int32_t metaHandleNormalTableUpdateImpl(SMeta *pMeta, const SMetaHandlePa
return code;
}
static int32_t metaHandleVirtualNormalTableUpdateImpl(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_UPDATA}, //
{META_SCHEMA_TABLE, META_TABLE_OP_UPDATA}, //
{META_UID_IDX, META_TABLE_OP_UPDATA}, //
};
for (int32_t i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
code = metaTableOpFn[op->table][op->op](pMeta, pParam);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
#if 0
if (metaUpdateChangeTime(pMeta, entry.uid, pAlterTbReq->ctimeMs) < 0) {
metaError("vgId:%d, failed to update change time:%s uid:%" PRId64, TD_VID(pMeta->pVnode), entry.name, entry.uid);
}
#endif
return code;
}
static int32_t metaHandleVirtualChildTableUpdateImpl(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
const SMetaEntry *pEntry = pParam->pEntry;
const SMetaEntry *pOldEntry = pParam->pOldEntry;
const SMetaEntry *pSuperEntry = pParam->pSuperEntry;
SMetaTableOp ops[] = {
{META_ENTRY_TABLE, META_TABLE_OP_UPDATA}, //
{META_UID_IDX, META_TABLE_OP_UPDATA}, //
{META_TAG_IDX, META_TABLE_OP_UPDATA}, //
{META_CHILD_IDX, META_TABLE_OP_UPDATA}, //
};
for (int i = 0; i < sizeof(ops) / sizeof(ops[0]); i++) {
SMetaTableOp *op = &ops[i];
code = metaTableOpFn[op->table][op->op](pMeta, pParam);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
}
if (metaUidCacheClear(pMeta, pSuperEntry->uid) < 0) {
metaErr(TD_VID(pMeta->pVnode), code);
}
if (metaTbGroupCacheClear(pMeta, pSuperEntry->uid) < 0) {
metaErr(TD_VID(pMeta->pVnode), code);
}
return code;
}
static int32_t metaHandleChildTableUpdateImpl(SMeta *pMeta, const SMetaHandleParam *pParam) {
int32_t code = TSDB_CODE_SUCCESS;
@ -1809,6 +2290,76 @@ static int32_t metaHandleNormalTableUpdate(SMeta *pMeta, const SMetaEntry *pEntr
return code;
}
static int32_t metaHandleVirtualNormalTableUpdate(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pOldEntry = NULL;
// fetch old entry
code = metaFetchEntryByUid(pMeta, pEntry->uid, &pOldEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
// handle update
SMetaHandleParam param = {
.pEntry = pEntry,
.pOldEntry = pOldEntry,
};
metaWLock(pMeta);
code = metaHandleVirtualNormalTableUpdateImpl(pMeta, &param);
metaULock(pMeta);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pOldEntry);
return code;
}
metaTimeSeriesNotifyCheck(pMeta);
metaFetchEntryFree(&pOldEntry);
return code;
}
static int32_t metaHandleVirtualChildTableUpdate(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SMetaEntry *pOldEntry = NULL;
SMetaEntry *pSuperEntry = NULL;
code = metaFetchEntryByUid(pMeta, pEntry->uid, &pOldEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
return code;
}
code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuperEntry);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pOldEntry);
return code;
}
SMetaHandleParam param = {
.pEntry = pEntry,
.pOldEntry = pOldEntry,
.pSuperEntry = pSuperEntry,
};
metaWLock(pMeta);
code = metaHandleVirtualChildTableUpdateImpl(pMeta, &param);
metaULock(pMeta);
if (code) {
metaErr(TD_VID(pMeta->pVnode), code);
metaFetchEntryFree(&pOldEntry);
metaFetchEntryFree(&pSuperEntry);
return code;
}
metaFetchEntryFree(&pOldEntry);
metaFetchEntryFree(&pSuperEntry);
return code;
}
static int32_t metaHandleSuperTableDrop(SMeta *pMeta, const SMetaEntry *pEntry) {
int32_t code = TSDB_CODE_SUCCESS;
SArray *childList = NULL;
@ -1912,6 +2463,22 @@ int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry) {
}
break;
}
case TSDB_VIRTUAL_NORMAL_TABLE: {
if (isExist) {
code = metaHandleVirtualNormalTableUpdate(pMeta, pEntry);
} else {
code = metaHandleVirtualNormalTableCreate(pMeta, pEntry);
}
break;
}
case TSDB_VIRTUAL_CHILD_TABLE: {
if (isExist) {
code = metaHandleVirtualChildTableUpdate(pMeta, pEntry);
} else {
code = metaHandleVirtualChildTableCreate(pMeta, pEntry);
}
break;
}
default: {
code = TSDB_CODE_INVALID_PARA;
break;
@ -1931,6 +2498,14 @@ int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry) {
code = metaHandleNormalTableDrop(pMeta, pEntry);
break;
}
case TSDB_VIRTUAL_NORMAL_TABLE: {
code = metaHandleVirtualNormalTableDrop(pMeta, pEntry);
break;
}
case TSDB_VIRTUAL_CHILD_TABLE: {
code = metaHandleVirtualChildTableDrop(pMeta, pEntry, false);
break;
}
default: {
code = TSDB_CODE_INVALID_PARA;
break;

View File

@ -25,7 +25,8 @@ int32_t metaUpdateTableTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pRe
int32_t metaUpdateTableMultiTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
int32_t metaUpdateTableOptions2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
int32_t metaUpdateTableColCompress2(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq);
int32_t metaAlterTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp);
int32_t metaRemoveTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp);
int32_t metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
int32_t metaDelJsonVarFromIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema);
@ -103,6 +104,49 @@ int32_t dropTableExtSchema(SMetaEntry *pEntry, int32_t dropColId, int32_t newCol
return 0;
}
int32_t updataTableColRef(SColRefWrapper *pWp, const SSchema *pSchema, int8_t add, SColRef *pColRef) {
int32_t nCols = pWp->nCols;
int32_t ver = pWp->version;
if (add) {
SColRef *p = taosMemoryRealloc(pWp->pColRef, sizeof(SColRef) * (nCols + 1));
if (p == NULL) {
return terrno;
}
pWp->pColRef = p;
SColRef *pCol = p + nCols;
if (NULL == pColRef) {
pCol->hasRef = false;
pCol->id = pSchema->colId;
} else {
pCol->hasRef = pColRef->hasRef;
pCol->id = pSchema->colId;
if (pCol->hasRef) {
tstrncpy(pCol->refDbName, pColRef->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pCol->refTableName, pColRef->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pCol->refColName, pColRef->refColName, TSDB_COL_NAME_LEN);
}
}
pWp->nCols = nCols + 1;
pWp->version = ver;
} else {
for (int32_t i = 0; i < nCols; i++) {
SColRef *pOColRef = &pWp->pColRef[i];
if (pOColRef->id == pSchema->colId) {
int32_t left = (nCols - i - 1) * sizeof(SColRef);
if (left) {
memmove(pWp->pColRef + i, pWp->pColRef + i + 1, left);
}
nCols--;
break;
}
}
pWp->nCols = nCols;
pWp->version = ver;
}
return 0;
}
int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp) {
pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
if (NULL == pMetaRsp->pSchemas) {
@ -120,12 +164,56 @@ int metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STabl
pMetaRsp->tableType = TSDB_NORMAL_TABLE;
pMetaRsp->sversion = pSchema->version;
pMetaRsp->tuid = uid;
pMetaRsp->virtualStb = false; // super table will never be processed here
memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));
return 0;
}
int32_t metaUpdateVtbMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, SColRefWrapper *pRef,
STableMetaRsp *pMetaRsp, int8_t tableType) {
int32_t code = TSDB_CODE_SUCCESS;
if (!pRef) {
return TSDB_CODE_INVALID_PARA;
}
if (pSchema) {
pMetaRsp->pSchemas = taosMemoryMalloc(pSchema->nCols * sizeof(SSchema));
if (NULL == pMetaRsp->pSchemas) {
code = terrno;
goto _return;
}
pMetaRsp->pSchemaExt = taosMemoryMalloc(pSchema->nCols * sizeof(SSchemaExt));
if (pMetaRsp->pSchemaExt == NULL) {
code = terrno;
goto _return;
}
pMetaRsp->numOfColumns = pSchema->nCols;
pMetaRsp->sversion = pSchema->version;
memcpy(pMetaRsp->pSchemas, pSchema->pSchema, pSchema->nCols * sizeof(SSchema));
}
pMetaRsp->pColRefs = taosMemoryMalloc(pRef->nCols * sizeof(SColRef));
if (NULL == pMetaRsp->pColRefs) {
code = terrno;
goto _return;
}
memcpy(pMetaRsp->pColRefs, pRef->pColRef, pRef->nCols * sizeof(SColRef));
tstrncpy(pMetaRsp->tbName, tbName, TSDB_TABLE_NAME_LEN);
pMetaRsp->tuid = uid;
pMetaRsp->tableType = tableType;
pMetaRsp->virtualStb = false; // super table will never be processed here
pMetaRsp->numOfColRefs = pRef->nCols;
return code;
_return:
taosMemoryFreeClear(pMetaRsp->pSchemaExt);
taosMemoryFreeClear(pMetaRsp->pSchemas);
taosMemoryFreeClear(pMetaRsp->pColRefs);
return code;
}
int metaSaveJsonVarToIdx(SMeta *pMeta, const SMetaEntry *pCtbEntry, const SSchema *pSchema) {
int32_t code = 0;
@ -390,7 +478,7 @@ static int32_t metaFilterTableByHash(SMeta *pMeta, SArray *uidList) {
char tbFName[TSDB_TABLE_FNAME_LEN + 1];
snprintf(tbFName, sizeof(tbFName), "%s.%s", pMeta->pVnode->config.dbname, me.name);
tbFName[TSDB_TABLE_FNAME_LEN] = '\0';
int32_t ret = vnodeValidateTableHash(pMeta->pVnode, tbFName);
ret = vnodeValidateTableHash(pMeta->pVnode, tbFName);
if (ret < 0 && terrno == TSDB_CODE_VND_HASH_MISMATCH) {
if (taosArrayPush(uidList, &me.uid) == NULL) {
code = terrno;
@ -531,7 +619,7 @@ static int metaDropTableByUid(SMeta *pMeta, tb_uid_t uid, int *type, tb_uid_t *p
SMetaEntry stbEntry = {0};
tDecoderInit(&tdc, tData, tLen);
int32_t ret = metaDecodeEntry(&tdc, &stbEntry);
ret = metaDecodeEntry(&tdc, &stbEntry);
if (ret < 0) {
tDecoderClear(&tdc);
metaError("vgId:%d, failed to decode child table:%s uid:%" PRId64 " since %s", TD_VID(pMeta->pVnode), e.name,
@ -709,6 +797,7 @@ int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMeta
switch (pReq->action) {
case TSDB_ALTER_TABLE_ADD_COLUMN:
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION:
case TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF:
return metaAddTableColumn(pMeta, version, pReq, pMetaRsp);
case TSDB_ALTER_TABLE_DROP_COLUMN:
return metaDropTableColumn(pMeta, version, pReq, pMetaRsp);
@ -724,6 +813,10 @@ int metaAlterTable(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMeta
return metaUpdateTableOptions2(pMeta, version, pReq);
case TSDB_ALTER_TABLE_UPDATE_COLUMN_COMPRESS:
return metaUpdateTableColCompress2(pMeta, version, pReq);
case TSDB_ALTER_TABLE_ALTER_COLUMN_REF:
return metaAlterTableColumnRef(pMeta, version, pReq, pMetaRsp);
case TSDB_ALTER_TABLE_REMOVE_COLUMN_REF:
return metaRemoveTableColumnRef(pMeta, version, pReq, pMetaRsp);
default:
return terrno = TSDB_CODE_VND_INVALID_TABLE_ACTION;
break;

View File

@ -17,6 +17,8 @@
extern int32_t metaHandleEntry2(SMeta *pMeta, const SMetaEntry *pEntry);
extern int32_t metaUpdateMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, STableMetaRsp *pMetaRsp);
extern int32_t metaUpdateVtbMetaRsp(tb_uid_t uid, char *tbName, SSchemaWrapper *pSchema, SColRefWrapper *pRef,
STableMetaRsp *pMetaRsp, int8_t tableType);
extern int32_t metaFetchEntryByUid(SMeta *pMeta, int64_t uid, SMetaEntry **ppEntry);
extern int32_t metaFetchEntryByName(SMeta *pMeta, const char *name, SMetaEntry **ppEntry);
extern void metaFetchEntryFree(SMetaEntry **ppEntry);
@ -192,8 +194,13 @@ int32_t metaCreateSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq
TABLE_SET_COL_COMPRESSED(entry.flags);
entry.colCmpr = pReq->colCmpr;
}
entry.pExtSchemas = pReq->pExtSchemas;
if (pReq->virtualStb) {
TABLE_SET_VIRTUAL(entry.flags);
}
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, super table %s suid:%" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
@ -495,6 +502,141 @@ static int32_t metaCreateNormalTable(SMeta *pMeta, int64_t version, SVCreateTbRe
TAOS_RETURN(code);
}
static int32_t metaBuildCreateVirtualNormalTableRsp(SMeta *pMeta, SMetaEntry *pEntry, STableMetaRsp **ppRsp) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == ppRsp) {
return code;
}
*ppRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
if (NULL == *ppRsp) {
return terrno;
}
code = metaUpdateVtbMetaRsp(pEntry->uid, pEntry->name, &pEntry->ntbEntry.schemaRow, &pEntry->colRef, *ppRsp, TSDB_VIRTUAL_NORMAL_TABLE);
if (code) {
taosMemoryFreeClear(*ppRsp);
return code;
}
return code;
}
static int32_t metaCreateVirtualNormalTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
// check request
int32_t code = metaCheckCreateNormalTableReq(pMeta, version, pReq);
if (code) {
if (TSDB_CODE_TDB_TABLE_ALREADY_EXIST != code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
__FILE__, __LINE__, tstrerror(code), version, pReq->name);
}
TAOS_RETURN(code);
}
SMetaEntry entry = {
.version = version,
.type = TSDB_VIRTUAL_NORMAL_TABLE,
.uid = pReq->uid,
.name = pReq->name,
.ntbEntry.btime = pReq->btime,
.ntbEntry.ttlDays = pReq->ttl,
.ntbEntry.commentLen = pReq->commentLen,
.ntbEntry.comment = pReq->comment,
.ntbEntry.schemaRow = pReq->ntb.schemaRow,
.ntbEntry.ncid = pReq->ntb.schemaRow.pSchema[pReq->ntb.schemaRow.nCols - 1].colId + 1,
.colRef = pReq->colRef
};
code = metaBuildCreateVirtualNormalTableRsp(pMeta, &entry, ppRsp);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__,
tstrerror(code));
}
// handle entry
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, normal table:%s uid %" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
pReq->uid, version);
} else {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
}
TAOS_RETURN(code);
#if 0
metaTimeSeriesNotifyCheck(pMeta);
#endif
}
static int32_t metaBuildCreateVirtualChildTableRsp(SMeta *pMeta, SMetaEntry *pEntry, STableMetaRsp **ppRsp) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == ppRsp) {
return code;
}
*ppRsp = taosMemoryCalloc(1, sizeof(STableMetaRsp));
if (NULL == *ppRsp) {
return terrno;
}
code = metaUpdateVtbMetaRsp(pEntry->uid, pEntry->name, NULL, &pEntry->colRef, *ppRsp, TSDB_VIRTUAL_CHILD_TABLE);
if (code) {
taosMemoryFreeClear(*ppRsp);
return code;
}
(*ppRsp)->suid = pEntry->ctbEntry.suid;
return code;
}
static int32_t metaCreateVirtualChildTable(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STableMetaRsp **ppRsp) {
// check request
int32_t code = metaCheckCreateChildTableReq(pMeta, version, pReq);
if (code) {
if (TSDB_CODE_TDB_TABLE_ALREADY_EXIST != code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64 " name:%s", TD_VID(pMeta->pVnode), __func__,
__FILE__, __LINE__, tstrerror(code), version, pReq->name);
}
TAOS_RETURN(code);
}
SMetaEntry entry = {
.version = version,
.type = TSDB_VIRTUAL_CHILD_TABLE,
.uid = pReq->uid,
.name = pReq->name,
.ctbEntry.btime = pReq->btime,
.ctbEntry.ttlDays = pReq->ttl,
.ctbEntry.commentLen = pReq->commentLen,
.ctbEntry.comment = pReq->comment,
.ctbEntry.suid = pReq->ctb.suid,
.ctbEntry.pTags = pReq->ctb.pTag,
.colRef = pReq->colRef
};
code = metaBuildCreateVirtualChildTableRsp(pMeta, &entry, ppRsp);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s", TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__,
tstrerror(code));
}
// handle entry
code = metaHandleEntry2(pMeta, &entry);
if (TSDB_CODE_SUCCESS == code) {
metaInfo("vgId:%d, normal table:%s uid %" PRId64 " is created, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->name,
pReq->uid, version);
} else {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pReq->uid, pReq->name, version);
}
TAOS_RETURN(code);
#if 0
metaTimeSeriesNotifyCheck(pMeta);
#endif
}
// Drop Normal Table
// Alter Normal Table
@ -505,6 +647,10 @@ int32_t metaCreateTable2(SMeta *pMeta, int64_t version, SVCreateTbReq *pReq, STa
code = metaCreateChildTable(pMeta, version, pReq, ppRsp);
} else if (TSDB_NORMAL_TABLE == pReq->type) {
code = metaCreateNormalTable(pMeta, version, pReq, ppRsp);
} else if (TSDB_VIRTUAL_NORMAL_TABLE == pReq->type) {
code = metaCreateVirtualNormalTable(pMeta, version, pReq, ppRsp);
} else if (TSDB_VIRTUAL_CHILD_TABLE == pReq->type) {
code = metaCreateVirtualChildTable(pMeta, version, pReq, ppRsp);
} else {
code = TSDB_CODE_INVALID_MSG;
}
@ -536,10 +682,18 @@ int32_t metaDropTable2(SMeta *pMeta, int64_t version, SVDropTbReq *pReq) {
.uid = pReq->uid,
};
if (pReq->suid == 0) {
entry.type = -TSDB_NORMAL_TABLE;
if (pReq->isVirtual) {
if (pReq->suid == 0) {
entry.type = -TSDB_VIRTUAL_NORMAL_TABLE;
} else {
entry.type = -TSDB_VIRTUAL_CHILD_TABLE;
}
} else {
entry.type = -TSDB_CHILD_TABLE;
if (pReq->suid == 0) {
entry.type = -TSDB_NORMAL_TABLE;
} else {
entry.type = -TSDB_CHILD_TABLE;
}
}
code = metaHandleEntry2(pMeta, &entry);
if (code) {
@ -583,7 +737,7 @@ static int32_t metaCheckAlterTableColumnReq(SMeta *pMeta, int64_t version, SVAlt
code = TSDB_CODE_INTERNAL_ERROR;
TAOS_RETURN(code);
}
if (info.suid != 0) {
if (info.suid != 0 && pReq->action != TSDB_ALTER_TABLE_ALTER_COLUMN_REF && pReq->action != TSDB_ALTER_TABLE_REMOVE_COLUMN_REF) {
metaError("vgId:%d, %s failed at %s:%d since table %s uid %" PRId64 " is not a normal table, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, uid, version);
code = TSDB_CODE_VND_INVALID_TABLE_ACTION;
@ -665,18 +819,39 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
pColumn->colId = pEntry->ntbEntry.ncid++;
extSchema.typeMod = pReq->typeMod;
tstrncpy(pColumn->name, pReq->colName, TSDB_COL_NAME_LEN);
uint32_t compress;
if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) {
compress = createDefaultColCmprByType(pColumn->type);
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
SColRef tmpRef;
if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) {
tmpRef.hasRef = false;
tmpRef.id = pColumn->colId;
} else {
tmpRef.hasRef = true;
tmpRef.id = pColumn->colId;
tstrncpy(tmpRef.refDbName, pReq->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(tmpRef.refTableName, pReq->refTbName, TSDB_TABLE_NAME_LEN);
tstrncpy(tmpRef.refColName, pReq->refColName, TSDB_COL_NAME_LEN);
}
code = updataTableColRef(&pEntry->colRef, pColumn, 1, &tmpRef);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
__LINE__, tstrerror(code), version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(code);
}
} else {
compress = pReq->compress;
}
code = updataTableColCmpr(&pEntry->colCmpr, pColumn, 1, compress);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
__LINE__, tstrerror(code), version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(code);
uint32_t compress;
if (TSDB_ALTER_TABLE_ADD_COLUMN == pReq->action) {
compress = createDefaultColCmprByType(pColumn->type);
} else {
compress = pReq->compress;
}
code = updataTableColCmpr(&pEntry->colCmpr, pColumn, 1, compress);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
__LINE__, tstrerror(code), version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(code);
}
}
code = addTableExtSchema(pEntry, pColumn, pSchema->nCols, &extSchema);
if (code) {
@ -698,14 +873,32 @@ int32_t metaAddTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, ST
pEntry->uid, version);
}
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
} else {
for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
pRsp->pSchemaExt[i].colId = p->id;
pRsp->pSchemaExt[i].compress = p->alg;
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
pRsp->pSchemaExt[i].colId = p->id;
pRsp->pSchemaExt[i].compress = p->alg;
}
}
}
@ -779,18 +972,34 @@ int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, S
}
pSchema->nCols--;
pSchema->version++;
code = updataTableColCmpr(&pEntry->colCmpr, &tColumn, 0, 0);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
__LINE__, tstrerror(code), version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(code);
}
if (pEntry->colCmpr.nCols != pSchema->nCols) {
metaError("vgId:%d, %s failed at %s:%d since column count mismatch, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
code = updataTableColRef(&pEntry->colRef, &tColumn, 0, NULL);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
__LINE__, tstrerror(code), version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(code);
}
if (pEntry->colRef.nCols != pSchema->nCols) {
metaError("vgId:%d, %s failed at %s:%d since column count mismatch, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
}
} else {
code = updataTableColCmpr(&pEntry->colCmpr, &tColumn, 0, 0);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, version:%" PRId64, TD_VID(pMeta->pVnode), __func__, __FILE__,
__LINE__, tstrerror(code), version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(code);
}
if (pEntry->colCmpr.nCols != pSchema->nCols) {
metaError("vgId:%d, %s failed at %s:%d since column count mismatch, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_VND_INVALID_TABLE_ACTION);
}
}
// update column extschema
@ -814,14 +1023,32 @@ int32_t metaDropTableColumn(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, S
}
// build response
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
} else {
for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
pRsp->pSchemaExt[i].colId = p->id;
pRsp->pSchemaExt[i].compress = p->alg;
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
pRsp->pSchemaExt[i].colId = p->id;
pRsp->pSchemaExt[i].compress = p->alg;
}
}
}
@ -904,14 +1131,32 @@ int32_t metaAlterTableColumnName(SMeta *pMeta, int64_t version, SVAlterTbReq *pR
}
// build response
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
} else {
for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
pRsp->pSchemaExt[i].colId = p->id;
pRsp->pSchemaExt[i].compress = p->alg;
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
pRsp->pSchemaExt[i].colId = p->id;
pRsp->pSchemaExt[i].compress = p->alg;
}
}
}
@ -1005,14 +1250,32 @@ int32_t metaAlterTableColumnBytes(SMeta *pMeta, int64_t version, SVAlterTbReq *p
}
// build response
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
if (pEntry->type == TSDB_VIRTUAL_NORMAL_TABLE) {
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
} else {
for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
pRsp->pSchemaExt[i].colId = p->id;
pRsp->pSchemaExt[i].compress = p->alg;
if (metaUpdateMetaRsp(pEntry->uid, pReq->tbName, pSchema, pRsp) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colCmpr.nCols; i++) {
SColCmpr *p = &pEntry->colCmpr.pColCmpr[i];
pRsp->pSchemaExt[i].colId = p->id;
pRsp->pSchemaExt[i].compress = p->alg;
}
}
}
@ -1063,7 +1326,7 @@ int32_t metaUpdateTableTagValue(SMeta *pMeta, int64_t version, SVAlterTbReq *pRe
TAOS_RETURN(code);
}
if (pChild->type != TSDB_CHILD_TABLE) {
if (pChild->type != TSDB_CHILD_TABLE && pChild->type != TSDB_VIRTUAL_CHILD_TABLE) {
metaError("vgId:%d, %s failed at %s:%d since table %s is not a child table, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, version);
metaFetchEntryFree(&pChild);
@ -1561,6 +1824,224 @@ int32_t metaUpdateTableColCompress2(SMeta *pMeta, int64_t version, SVAlterTbReq
TAOS_RETURN(code);
}
int32_t metaAlterTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
int32_t code = TSDB_CODE_SUCCESS;
// check request
code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
if (code) {
TAOS_RETURN(code);
}
if (NULL == pReq->refDbName) {
metaError("vgId:%d, %s failed at %s:%d since invalid ref db name, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
TAOS_RETURN(TSDB_CODE_INVALID_MSG);
}
if (NULL == pReq->refTbName) {
metaError("vgId:%d, %s failed at %s:%d since invalid ref table name, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
TAOS_RETURN(TSDB_CODE_INVALID_MSG);
}
if (NULL == pReq->refColName) {
metaError("vgId:%d, %s failed at %s:%d since invalid ref Col name, version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, version);
TAOS_RETURN(TSDB_CODE_INVALID_MSG);
}
// fetch old entry
SMetaEntry *pEntry = NULL;
code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
__FILE__, __LINE__, pReq->tbName, version);
TAOS_RETURN(code);
}
if (pEntry->version >= version) {
metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
}
// fetch super entry
SMetaEntry *pSuper = NULL;
if (pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuper);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since super table uid %" PRId64 " not found, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pEntry->ctbEntry.suid, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_INTERNAL_ERROR);
}
}
// search the column to update
SSchemaWrapper *pSchema = pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? &pSuper->stbEntry.schemaRow : &pEntry->ntbEntry.schemaRow;
SColRef *pColRef = NULL;
int32_t iColumn = 0;
for (int32_t i = 0; i < pSchema->nCols; i++) {
if (strncmp(pSchema->pSchema[i].name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
pColRef = &pEntry->colRef.pColRef[i];
iColumn = i;
break;
}
}
if (NULL == pColRef) {
metaError("vgId:%d, %s failed at %s:%d since column id %d not found in table %s, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->colId, pReq->tbName, version);
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
}
// do update column name
pEntry->version = version;
pColRef->hasRef = true;
pColRef->id = pSchema->pSchema[iColumn].colId;
tstrncpy(pColRef->refDbName, pReq->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pColRef->refTableName, pReq->refTbName, TSDB_TABLE_NAME_LEN);
tstrncpy(pColRef->refColName, pReq->refColName, TSDB_COL_NAME_LEN);
pSchema->version++;
// do handle entry
code = metaHandleEntry2(pMeta, pEntry);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(code);
} else {
metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
pEntry->uid, version);
}
// build response
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(code);
}
int32_t metaRemoveTableColumnRef(SMeta *pMeta, int64_t version, SVAlterTbReq *pReq, STableMetaRsp *pRsp) {
int32_t code = TSDB_CODE_SUCCESS;
// check request
code = metaCheckAlterTableColumnReq(pMeta, version, pReq);
if (code) {
TAOS_RETURN(code);
}
// fetch old entry
SMetaEntry *pEntry = NULL;
code = metaFetchEntryByName(pMeta, pReq->tbName, &pEntry);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since table %s not found, version:%" PRId64, TD_VID(pMeta->pVnode), __func__,
__FILE__, __LINE__, pReq->tbName, version);
TAOS_RETURN(code);
}
if (pEntry->version >= version) {
metaError("vgId:%d, %s failed at %s:%d since table %s version %" PRId64 " is not less than %" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pReq->tbName, pEntry->version, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_INVALID_PARA);
}
// fetch super entry
SMetaEntry *pSuper = NULL;
if (pEntry->type == TSDB_VIRTUAL_CHILD_TABLE) {
code = metaFetchEntryByUid(pMeta, pEntry->ctbEntry.suid, &pSuper);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since super table uid %" PRId64 " not found, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, pEntry->ctbEntry.suid, version);
metaFetchEntryFree(&pEntry);
TAOS_RETURN(TSDB_CODE_INTERNAL_ERROR);
}
}
// search the column to update
SSchemaWrapper *pSchema = pEntry->type == TSDB_VIRTUAL_CHILD_TABLE ? &pSuper->stbEntry.schemaRow : &pEntry->ntbEntry.schemaRow;
SColRef *pColRef = NULL;
int32_t iColumn = 0;
for (int32_t i = 0; i < pSchema->nCols; i++) {
if (strncmp(pSchema->pSchema[i].name, pReq->colName, TSDB_COL_NAME_LEN) == 0) {
pColRef = &pEntry->colRef.pColRef[i];
iColumn = i;
break;
}
}
if (NULL == pColRef) {
metaError("vgId:%d, %s failed at %s:%d since column id %d not found in table %s, version:%" PRId64,
TD_VID(pMeta->pVnode), __func__, __FILE__, __LINE__, iColumn + 1, pReq->tbName, version);
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(TSDB_CODE_VND_COL_NOT_EXISTS);
}
// do update column name
pEntry->version = version;
pColRef->hasRef = false;
pColRef->id = pSchema->pSchema[iColumn].colId;
pSchema->version++;
// do handle entry
code = metaHandleEntry2(pMeta, pEntry);
if (code) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(code);
} else {
metaInfo("vgId:%d, table %s uid %" PRId64 " is updated, version:%" PRId64, TD_VID(pMeta->pVnode), pReq->tbName,
pEntry->uid, version);
}
// build response
if (metaUpdateVtbMetaRsp(pEntry->uid, pReq->tbName, pSchema, &pEntry->colRef, pRsp, pEntry->type) < 0) {
metaError("vgId:%d, %s failed at %s:%d since %s, uid:%" PRId64 " name:%s version:%" PRId64, TD_VID(pMeta->pVnode),
__func__, __FILE__, __LINE__, tstrerror(code), pEntry->uid, pReq->tbName, version);
} else {
for (int32_t i = 0; i < pEntry->colRef.nCols; i++) {
SColRef *p = &pEntry->colRef.pColRef[i];
pRsp->pColRefs[i].hasRef = p->hasRef;
pRsp->pColRefs[i].id = p->id;
if (p->hasRef) {
tstrncpy(pRsp->pColRefs[i].refDbName, p->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refTableName, p->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRsp->pColRefs[i].refColName, p->refColName, TSDB_COL_NAME_LEN);
}
}
}
metaFetchEntryFree(&pEntry);
metaFetchEntryFree(&pSuper);
TAOS_RETURN(code);
}
int32_t metaAddIndexToSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq) {
int32_t code = TSDB_CODE_SUCCESS;
@ -1791,6 +2272,9 @@ int32_t metaAlterSuperTable(SMeta *pMeta, int64_t version, SVCreateStbReq *pReq)
.pExtSchemas = pReq->pExtSchemas,
};
TABLE_SET_COL_COMPRESSED(entry.flags);
if (pReq->virtualStb) {
TABLE_SET_VIRTUAL(entry.flags);
}
// do handle the entry
code = metaHandleEntry2(pMeta, &entry);

View File

@ -692,7 +692,7 @@ static int32_t tdRSmaExecAndSubmitResult(SSma *pSma, qTaskInfo_t taskInfo, SRSma
while (1) {
uint64_t ts;
bool hasMore = false;
code = qExecTaskOpt(taskInfo, pResList, &ts, &hasMore, NULL);
code = qExecTaskOpt(taskInfo, pResList, &ts, &hasMore, NULL, false);
if (code == TSDB_CODE_QRY_IN_EXEC) {
code = 0;
break;

View File

@ -77,6 +77,28 @@ void vnodePrintTableMeta(STableMetaRsp *pMeta) {
}
}
int32_t fillTableColRef(SMetaReader *reader, SColRef *pRef, int32_t numOfCol) {
int8_t tblType = reader->me.type;
if (hasRefCol(tblType)) {
SColRefWrapper *p = &(reader->me.colRef);
if (numOfCol != p->nCols) {
vError("fillTableColRef table type:%d, col num:%d, col cmpr num:%d mismatch", tblType, numOfCol, p->nCols);
return TSDB_CODE_APP_ERROR;
}
for (int i = 0; i < p->nCols; i++) {
SColRef *pColRef = &p->pColRef[i];
pRef[i].hasRef = pColRef->hasRef;
pRef[i].id = pColRef->id;
if(pRef[i].hasRef) {
tstrncpy(pRef[i].refDbName, pColRef->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pRef[i].refTableName, pColRef->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pRef[i].refColName, pColRef->refColName, TSDB_COL_NAME_LEN);
}
}
}
return 0;
}
int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
STableInfoReq infoReq = {0};
STableMetaRsp metaRsp = {0};
@ -139,24 +161,34 @@ int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
metaRsp.vgId = TD_VID(pVnode);
metaRsp.tuid = mer1.me.uid;
if (mer1.me.type == TSDB_SUPER_TABLE) {
tstrncpy(metaRsp.stbName, mer1.me.name, TSDB_TABLE_NAME_LEN);
schema = mer1.me.stbEntry.schemaRow;
schemaTag = mer1.me.stbEntry.schemaTag;
metaRsp.suid = mer1.me.uid;
} else if (mer1.me.type == TSDB_CHILD_TABLE) {
metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK);
if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit2;
switch (mer1.me.type) {
case TSDB_SUPER_TABLE: {
(void)strcpy(metaRsp.stbName, mer1.me.name);
schema = mer1.me.stbEntry.schemaRow;
schemaTag = mer1.me.stbEntry.schemaTag;
metaRsp.suid = mer1.me.uid;
break;
}
case TSDB_CHILD_TABLE:
case TSDB_VIRTUAL_CHILD_TABLE:{
metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK);
if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit2;
tstrncpy(metaRsp.stbName, mer2.me.name, TSDB_TABLE_NAME_LEN);
metaRsp.suid = mer2.me.uid;
schema = mer2.me.stbEntry.schemaRow;
schemaTag = mer2.me.stbEntry.schemaTag;
} else if (mer1.me.type == TSDB_NORMAL_TABLE) {
schema = mer1.me.ntbEntry.schemaRow;
} else {
vError("vnodeGetTableMeta get invalid table type:%d", mer1.me.type);
goto _exit3;
(void)strcpy(metaRsp.stbName, mer2.me.name);
metaRsp.suid = mer2.me.uid;
schema = mer2.me.stbEntry.schemaRow;
schemaTag = mer2.me.stbEntry.schemaTag;
break;
}
case TSDB_NORMAL_TABLE:
case TSDB_VIRTUAL_NORMAL_TABLE: {
schema = mer1.me.ntbEntry.schemaRow;
break;
}
default: {
vError("vnodeGetTableMeta get invalid table type:%d", mer1.me.type);
goto _exit3;
}
}
metaRsp.numOfTags = schemaTag.nCols;
@ -187,6 +219,19 @@ int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
code = TSDB_CODE_OUT_OF_MEMORY;
goto _exit;
}
if (hasRefCol(mer1.me.type)) {
metaRsp.pColRefs = (SColRef*)taosMemoryMalloc(sizeof(SColRef) * metaRsp.numOfColumns);
if (metaRsp.pColRefs) {
code = fillTableColRef(&mer1, metaRsp.pColRefs, metaRsp.numOfColumns);
if (code < 0) {
goto _exit;
}
}
metaRsp.numOfColRefs = metaRsp.numOfColumns;
} else {
metaRsp.pColRefs = NULL;
metaRsp.numOfColRefs = 0;
}
vnodePrintTableMeta(&metaRsp);
@ -215,6 +260,7 @@ int32_t vnodeGetTableMeta(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
}
_exit:
taosMemoryFree(metaRsp.pColRefs);
taosMemoryFree(metaRsp.pSchemas);
taosMemoryFree(metaRsp.pSchemaExt);
_exit2:
@ -286,7 +332,7 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
if (mer1.me.type == TSDB_SUPER_TABLE) {
code = TSDB_CODE_VND_HASH_MISMATCH;
goto _exit;
} else if (mer1.me.type == TSDB_CHILD_TABLE) {
} else if (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
metaReaderDoInit(&mer2, pVnode->pMeta, META_READER_NOLOCK);
if (metaReaderGetTableEntryByUid(&mer2, mer1.me.ctbEntry.suid) < 0) goto _exit;
@ -310,7 +356,7 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
goto _exit;
}
(void)memcpy(cfgRsp.pTags, pTag, cfgRsp.tagsLen);
} else if (mer1.me.type == TSDB_NORMAL_TABLE) {
} else if (mer1.me.type == TSDB_NORMAL_TABLE || mer1.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
schema = mer1.me.ntbEntry.schemaRow;
cfgRsp.ttl = mer1.me.ntbEntry.ttlDays;
cfgRsp.commentLen = mer1.me.ntbEntry.commentLen;
@ -329,10 +375,12 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
cfgRsp.numOfTags = schemaTag.nCols;
cfgRsp.numOfColumns = schema.nCols;
cfgRsp.virtualStb = false; // vnode don't have super table, so it's always false
cfgRsp.pSchemas = (SSchema *)taosMemoryMalloc(sizeof(SSchema) * (cfgRsp.numOfColumns + cfgRsp.numOfTags));
cfgRsp.pSchemaExt = (SSchemaExt *)taosMemoryMalloc(cfgRsp.numOfColumns * sizeof(SSchemaExt));
cfgRsp.pColRefs = (SColRef *)taosMemoryMalloc(sizeof(SColRef) * cfgRsp.numOfColumns);
if (NULL == cfgRsp.pSchemas || NULL == cfgRsp.pSchemaExt) {
if (NULL == cfgRsp.pSchemas || NULL == cfgRsp.pSchemaExt || NULL == cfgRsp.pColRefs) {
code = terrno;
goto _exit;
}
@ -341,22 +389,36 @@ int32_t vnodeGetTableCfg(SVnode *pVnode, SRpcMsg *pMsg, bool direct) {
(void)memcpy(cfgRsp.pSchemas + schema.nCols, schemaTag.pSchema, sizeof(SSchema) * schemaTag.nCols);
}
// if (useCompress(cfgRsp.tableType)) {
SMetaReader *pReader = mer1.me.type == TSDB_CHILD_TABLE ? &mer2 : &mer1;
SMetaReader *pReader = (mer1.me.type == TSDB_CHILD_TABLE || mer1.me.type == TSDB_VIRTUAL_CHILD_TABLE) ? &mer2 : &mer1;
SColCmprWrapper *pColCmpr = &pReader->me.colCmpr;
SColRefWrapper *pColRef = &mer1.me.colRef;
for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
SColCmpr *pCmpr = &pColCmpr->pColCmpr[i];
SSchemaExt *pSchExt = cfgRsp.pSchemaExt + i;
pSchExt->colId = pCmpr->id;
pSchExt->compress = pCmpr->alg;
if (pReader->me.pExtSchemas)
pSchExt->typeMod = pReader->me.pExtSchemas[i].typeMod;
else
pSchExt->typeMod = 0;
if (withExtSchema(cfgRsp.tableType)) {
for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
SColCmpr *pCmpr = &pColCmpr->pColCmpr[i];
SSchemaExt *pSchExt = cfgRsp.pSchemaExt + i;
pSchExt->colId = pCmpr->id;
pSchExt->compress = pCmpr->alg;
if (pReader->me.pExtSchemas)
pSchExt->typeMod = pReader->me.pExtSchemas[i].typeMod;
else
pSchExt->typeMod = 0;
}
}
cfgRsp.virtualStb = false;
if (hasRefCol(cfgRsp.tableType)) {
for (int32_t i = 0; i < cfgRsp.numOfColumns; i++) {
SColRef *pRef = &pColRef->pColRef[i];
cfgRsp.pColRefs[i].hasRef = pRef->hasRef;
cfgRsp.pColRefs[i].id = pRef->id;
if (cfgRsp.pColRefs[i].hasRef) {
tstrncpy(cfgRsp.pColRefs[i].refDbName, pRef->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(cfgRsp.pColRefs[i].refTableName, pRef->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(cfgRsp.pColRefs[i].refColName, pRef->refColName, TSDB_COL_NAME_LEN);
}
}
}
//}
// encode and send response
rspLen = tSerializeSTableCfgRsp(NULL, 0, &cfgRsp);

View File

@ -1563,6 +1563,9 @@ _exit:
taosMemoryFree(vMetaRsp.pSchemas);
taosMemoryFree(vMetaRsp.pSchemaExt);
}
if (vMetaRsp.pColRefs) {
taosMemoryFree(vMetaRsp.pColRefs);
}
return 0;
}

View File

@ -777,10 +777,12 @@ typedef struct SCtgCacheItemInfo {
#define CTG_META_NHIT_INC() CTG_CACHE_NHIT_INC(CTG_CI_OTHERTABLE_META, 1)
#define CTG_IS_META_NULL(type) ((type) == META_TYPE_NULL_TABLE)
#define CTG_IS_META_CTABLE(type) ((type) == META_TYPE_CTABLE)
#define CTG_IS_META_TABLE(type) ((type) == META_TYPE_TABLE)
#define CTG_IS_META_BOTH(type) ((type) == META_TYPE_BOTH_TABLE)
#define CTG_IS_META_NULL(type) ((type) == META_TYPE_NULL_TABLE)
#define CTG_IS_META_CTABLE(type) ((type) == META_TYPE_CTABLE)
#define CTG_IS_META_VCTABLE(type) ((type) == META_TYPE_VCTABLE)
#define CTG_IS_META_TABLE(type) ((type) == META_TYPE_TABLE)
#define CTG_IS_META_BOTH(type) ((type) == META_TYPE_BOTH_TABLE)
#define CTG_IS_META_VBOTH(type) ((type) == META_TYPE_BOTH_VTABLE)
#define CTG_FLAG_STB 0x1
#define CTG_FLAG_NOT_STB 0x2

View File

@ -138,7 +138,7 @@ int32_t ctgRefreshTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx*
taosMemoryFreeClear(output->tbMeta);
CTG_ERR_JRET(ctgGetTbMetaFromMnodeImpl(pCtg, pConn, output->dbFName, output->tbName, output, NULL));
} else if (CTG_IS_META_BOTH(output->metaType)) {
} else if (CTG_IS_META_BOTH(output->metaType) || CTG_IS_META_VBOTH(output->metaType)) {
int32_t exist = 0;
if (!CTG_FLAG_IS_FORCE_UPDATE(ctx->flag)) {
CTG_ERR_JRET(ctgTbMetaExistInCache(pCtg, output->dbFName, output->tbName, &exist));
@ -157,7 +157,11 @@ int32_t ctgRefreshTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx*
} else {
taosMemoryFreeClear(output->tbMeta);
SET_META_TYPE_CTABLE(output->metaType);
if (CTG_IS_META_BOTH(output->metaType)) {
SET_META_TYPE_CTABLE(output->metaType);
} else {
SET_META_TYPE_VCTABLE(output->metaType);
}
}
}
}
@ -189,6 +193,7 @@ _return:
if (output) {
taosMemoryFreeClear(output->tbMeta);
taosMemoryFreeClear(output->vctbMeta);
taosMemoryFreeClear(output);
}
@ -219,8 +224,30 @@ int32_t ctgGetTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx* ctx
goto _return;
}
if (CTG_IS_META_VBOTH(output->metaType) || CTG_IS_META_VCTABLE(output->metaType)) {
int32_t colRefSize = output->vctbMeta->numOfColRefs * sizeof(SColRef);
if (output->tbMeta) {
int32_t metaSize = CTG_META_SIZE(output->tbMeta);
int32_t schemaExtSize = 0;
if (withExtSchema(output->tbMeta->tableType) && output->tbMeta->schemaExt) {
schemaExtSize = output->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
TAOS_MEMCPY(output->tbMeta, output->vctbMeta, sizeof(SVCTableMeta));
output->tbMeta->colRef = (SColRef *)((char *)output->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(output->tbMeta->colRef, output->vctbMeta->colRef, colRefSize);
} else {
TAOS_MEMCPY(output->tbMeta, output->vctbMeta, sizeof(SVCTableMeta) + colRefSize);
output->tbMeta->colRef = (SColRef *)((char *)output->tbMeta + sizeof(SVCTableMeta));
}
output->tbMeta->numOfColRefs = output->vctbMeta->numOfColRefs;
taosMemoryFreeClear(output->vctbMeta);
*pTableMeta = output->tbMeta;
goto _return;
}
if ((!CTG_IS_META_CTABLE(output->metaType)) || output->tbMeta) {
ctgError("invalid metaType:%d", output->metaType);
taosMemoryFreeClear(output->vctbMeta);
taosMemoryFreeClear(output->tbMeta);
CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR);
}
@ -228,6 +255,7 @@ int32_t ctgGetTbMeta(SCatalog* pCtg, SRequestConnInfo* pConn, SCtgTbMetaCtx* ctx
// HANDLE ONLY CHILD TABLE META
taosMemoryFreeClear(output->tbMeta);
taosMemoryFreeClear(output->vctbMeta);
SName stbName = *ctx->pName;
TAOS_STRCPY(stbName.tname, output->tbName);
@ -292,6 +320,12 @@ int32_t ctgUpdateTbMeta(SCatalog* pCtg, STableMetaRsp* rspMsg, bool syncOp) {
SET_META_TYPE_CTABLE(output->metaType);
CTG_ERR_JRET(queryCreateCTableMetaFromMsg(rspMsg, &output->ctbMeta));
} else if (TSDB_VIRTUAL_CHILD_TABLE == rspMsg->tableType && NULL == rspMsg->pSchemas) {
TAOS_STRCPY(output->ctbName, rspMsg->tbName);
SET_META_TYPE_VCTABLE(output->metaType);
CTG_ERR_JRET(queryCreateVCTableMetaFromMsg(rspMsg, &output->vctbMeta));
} else {
TAOS_STRCPY(output->tbName, rspMsg->tbName);
@ -310,6 +344,7 @@ _return:
if (output) {
taosMemoryFreeClear(output->tbMeta);
taosMemoryFreeClear(output->vctbMeta);
taosMemoryFreeClear(output);
}

View File

@ -1638,7 +1638,7 @@ int32_t ctgHandleGetTbMetaRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf
taosMemoryFreeClear(pOut->tbMeta);
CTG_RET(ctgGetTbMetaFromMnode(pCtg, pConn, pName, NULL, tReq));
} else if (CTG_IS_META_BOTH(pOut->metaType)) {
} else if (CTG_IS_META_BOTH(pOut->metaType) || CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t exist = 0;
if (!CTG_FLAG_IS_FORCE_UPDATE(flag)) {
SName stbName = *pName;
@ -1674,6 +1674,28 @@ int32_t ctgHandleGetTbMetaRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf
TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta));
}
if (CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t colRefSize = pOut->vctbMeta->numOfColRefs * sizeof(SColRef);
if (pOut->tbMeta) {
int32_t metaSize = CTG_META_SIZE(pOut->tbMeta);
int32_t schemaExtSize = 0;
if (withExtSchema(pOut->tbMeta->tableType) && pOut->tbMeta->schemaExt) {
schemaExtSize = pOut->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, metaSize + schemaExtSize + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(pOut->tbMeta->colRef, pOut->vctbMeta->colRef, colRefSize);
} else {
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, sizeof(STableMeta) + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
TAOS_MEMCPY(pOut->tbMeta + sizeof(STableMeta), pOut->vctbMeta + sizeof(SVCTableMeta), colRefSize);
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + sizeof(STableMeta));
}
pOut->tbMeta->numOfColRefs = pOut->vctbMeta->numOfColRefs;
taosMemoryFreeClear(pOut->vctbMeta);
}
/*
else if (CTG_IS_META_CTABLE(pOut->metaType)) {
SName stbName = *pName;
@ -1823,7 +1845,7 @@ int32_t ctgHandleGetTbMetasRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBu
taosMemoryFreeClear(pOut->tbMeta);
CTG_RET(ctgGetTbMetaFromMnode(pCtg, pConn, pName, NULL, tReq));
} else if (CTG_IS_META_BOTH(pOut->metaType)) {
} else if (CTG_IS_META_BOTH(pOut->metaType) || CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t exist = 0;
if (!CTG_FLAG_IS_FORCE_UPDATE(flag)) {
SName stbName = *pName;
@ -1865,6 +1887,27 @@ int32_t ctgHandleGetTbMetasRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBu
TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta));
}
if (CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t colRefSize = pOut->vctbMeta->numOfColRefs * sizeof(SColRef);
if (pOut->tbMeta) {
int32_t metaSize = CTG_META_SIZE(pOut->tbMeta);
int32_t schemaExtSize = 0;
if (withExtSchema(pOut->tbMeta->tableType) && pOut->tbMeta->schemaExt) {
schemaExtSize = pOut->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, metaSize + schemaExtSize + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(pOut->tbMeta->colRef, pOut->vctbMeta->colRef, colRefSize);
} else {
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, sizeof(STableMeta) + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
TAOS_MEMCPY(pOut->tbMeta + sizeof(STableMeta), pOut->vctbMeta + sizeof(SVCTableMeta), colRefSize);
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + sizeof(STableMeta));
}
pOut->tbMeta->numOfColRefs = pOut->vctbMeta->numOfColRefs;
taosMemoryFreeClear(pOut->vctbMeta);
}
/*
else if (CTG_IS_META_CTABLE(pOut->metaType)) {
SName stbName = *pName;
@ -1895,6 +1938,7 @@ int32_t ctgHandleGetTbMetasRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBu
pRes->code = 0;
pRes->pRes = pOut->tbMeta;
pOut->tbMeta = NULL;
pOut->vctbMeta = NULL;
if (0 == atomic_sub_fetch_32(&ctx->fetchNum, 1)) {
TSWAP(pTask->res, ctx->pResList);
taskDone = true;
@ -2066,6 +2110,28 @@ static int32_t ctgHandleGetTbNamesRsp(SCtgTaskReq* tReq, int32_t reqType, const
TAOS_MEMCPY(pOut->tbMeta, &pOut->ctbMeta, sizeof(pOut->ctbMeta));
}
if (CTG_IS_META_VBOTH(pOut->metaType)) {
int32_t colRefSize = pOut->vctbMeta->numOfColRefs * sizeof(SColRef);
if (pOut->tbMeta) {
int32_t metaSize = CTG_META_SIZE(pOut->tbMeta);
int32_t schemaExtSize = 0;
if (withExtSchema(pOut->tbMeta->tableType) && pOut->tbMeta->schemaExt) {
schemaExtSize = pOut->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, metaSize + schemaExtSize + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(pOut->tbMeta->colRef, pOut->vctbMeta->colRef, colRefSize);
} else {
pOut->tbMeta = taosMemoryRealloc(pOut->tbMeta, sizeof(STableMeta) + colRefSize);
TAOS_MEMCPY(pOut->tbMeta, pOut->vctbMeta, sizeof(SVCTableMeta));
TAOS_MEMCPY(pOut->tbMeta + sizeof(STableMeta), pOut->vctbMeta + sizeof(SVCTableMeta), colRefSize);
pOut->tbMeta->colRef = (SColRef *)((char *)pOut->tbMeta + sizeof(STableMeta));
}
pOut->tbMeta->numOfColRefs = pOut->vctbMeta->numOfColRefs;
taosMemoryFreeClear(pOut->vctbMeta);
}
SMetaRes* pRes = taosArrayGet(ctx->pResList, pFetch->resIdx);
if (NULL == pRes) {
ctgTaskError("fail to get the %dth res in pResList, resNum:%d", pFetch->resIdx,
@ -2076,8 +2142,10 @@ static int32_t ctgHandleGetTbNamesRsp(SCtgTaskReq* tReq, int32_t reqType, const
if (!pRes->pRes) {
pRes->code = 0;
pRes->pRes = pOut->tbMeta;
taosMemoryFreeClear(pOut->vctbMeta);
pOut->tbMeta = NULL;
} else {
taosMemoryFreeClear(pOut->vctbMeta);
taosMemoryFreeClear(pOut->tbMeta);
}

View File

@ -538,34 +538,55 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
ctx->tbInfo.suid = tbMeta->suid;
ctx->tbInfo.tbType = tbMeta->tableType;
if (tbMeta->tableType != TSDB_CHILD_TABLE) {
if (tbMeta->tableType != TSDB_CHILD_TABLE && tbMeta->tableType != TSDB_VIRTUAL_CHILD_TABLE) {
int32_t schemaExtSize = 0;
int32_t colRefSize = 0;
int32_t metaSize = CTG_META_SIZE(tbMeta);
if (tbMeta->schemaExt != NULL) {
if (withExtSchema(tbMeta->tableType) && tbMeta->schemaExt != NULL) {
schemaExtSize = tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
*pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize);
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef != NULL) {
colRefSize += tbMeta->tableInfo.numOfColumns * sizeof(SColRef);
}
*pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize + colRefSize);
if (NULL == *pTableMeta) {
CTG_ERR_RET(terrno);
}
TAOS_MEMCPY(*pTableMeta, tbMeta, metaSize);
if (tbMeta->schemaExt != NULL) {
if (withExtSchema(tbMeta->tableType) && tbMeta->schemaExt != NULL) {
(*pTableMeta)->schemaExt = (SSchemaExt *)((char *)*pTableMeta + metaSize);
TAOS_MEMCPY((*pTableMeta)->schemaExt, tbMeta->schemaExt, schemaExtSize);
} else {
(*pTableMeta)->schemaExt = NULL;
}
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef) {
(*pTableMeta)->colRef = (SColRef *)((char *)*pTableMeta + metaSize + schemaExtSize);
TAOS_MEMCPY((*pTableMeta)->colRef, tbMeta->colRef, colRefSize);
(*pTableMeta)->numOfColRefs = tbMeta->numOfColRefs;
} else {
(*pTableMeta)->colRef = NULL;
}
ctgDebug("tb:%s, get meta from cache, type:%d, db:%s", ctx->pName->tname, tbMeta->tableType, dbFName);
return TSDB_CODE_SUCCESS;
}
// PROCESS FOR CHILD TABLE
int32_t metaSize = sizeof(SCTableMeta);
*pTableMeta = taosMemoryCalloc(1, metaSize);
int32_t colRefSize = 0;
int32_t numOfColRefs = 0;
SColRef *tmpRef = NULL;
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef != NULL) {
colRefSize += tbMeta->numOfColRefs * sizeof(SColRef);
numOfColRefs = tbMeta->numOfColRefs;
tmpRef = taosMemoryMalloc(colRefSize);
TAOS_MEMCPY(tmpRef, tbMeta->colRef, colRefSize);
}
*pTableMeta = taosMemoryCalloc(1, metaSize + colRefSize);
if (NULL == *pTableMeta) {
taosMemoryFreeClear(tmpRef);
CTG_ERR_RET(terrno);
}
@ -582,6 +603,7 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
CTG_ERR_RET(ctgAcquireStbMetaFromCache(dbCache, pCtg, dbFName, ctx->tbInfo.suid, &tbCache));
if (NULL == tbCache) {
taosMemoryFreeClear(tmpRef);
taosMemoryFreeClear(*pTableMeta);
*pDb = NULL;
ctgDebug("stb:0x%" PRIx64 ", meta not in cache", ctx->tbInfo.suid);
@ -594,6 +616,7 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
if (stbMeta->suid != ctx->tbInfo.suid) {
ctgError("stb:0x%" PRIx64 ", suid in stbCache mis-match, expected suid:0x%" PRIx64, stbMeta->suid, ctx->tbInfo.suid);
taosMemoryFreeClear(*pTableMeta);
taosMemoryFreeClear(tmpRef);
CTG_ERR_RET(TSDB_CODE_CTG_INTERNAL_ERROR);
}
@ -602,12 +625,13 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
if (stbMeta->schemaExt) {
schemaExtSize = stbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
*pTableMeta = taosMemoryRealloc(*pTableMeta, metaSize + schemaExtSize);
*pTableMeta = taosMemoryRealloc(*pTableMeta, metaSize + schemaExtSize + colRefSize);
if (NULL == *pTableMeta) {
taosMemoryFreeClear(tmpRef);
CTG_ERR_RET(terrno);
}
TAOS_MEMCPY(&(*pTableMeta)->sversion, &stbMeta->sversion, metaSize - sizeof(SCTableMeta));
TAOS_MEMCPY(&(*pTableMeta)->numOfColRefs, &stbMeta->numOfColRefs, metaSize - sizeof(SCTableMeta));
if (stbMeta->schemaExt) {
(*pTableMeta)->schemaExt = (SSchemaExt*)((char*)*pTableMeta + metaSize);
TAOS_MEMCPY((*pTableMeta)->schemaExt, stbMeta->schemaExt, schemaExtSize);
@ -615,6 +639,15 @@ int32_t ctgCopyTbMeta(SCatalog *pCtg, SCtgTbMetaCtx *ctx, SCtgDBCache **pDb, SCt
(*pTableMeta)->schemaExt = NULL;
}
if (colRefSize != 0) {
(*pTableMeta)->colRef = (SColRef *)((char *)*pTableMeta + metaSize + schemaExtSize);
(*pTableMeta)->numOfColRefs = numOfColRefs;
TAOS_MEMCPY((*pTableMeta)->colRef, tmpRef, colRefSize);
} else {
(*pTableMeta)->colRef = NULL;
}
taosMemoryFreeClear(tmpRef);
return TSDB_CODE_SUCCESS;
}
@ -1230,6 +1263,7 @@ _return:
if (output) {
taosMemoryFree(output->tbMeta);
taosMemoryFree(output->vctbMeta);
taosMemoryFree(output);
}
@ -2433,12 +2467,14 @@ int32_t ctgOpUpdateTbMeta(SCtgCacheOperation *operation) {
goto _return;
}
if ((!CTG_IS_META_CTABLE(pMeta->metaType)) && NULL == pMeta->tbMeta) {
if ((!CTG_IS_META_CTABLE(pMeta->metaType) && !CTG_IS_META_VCTABLE(pMeta->metaType)) && NULL == pMeta->tbMeta) {
ctgError("no valid tbmeta got from meta rsp, db:%s, tbName:%s", pMeta->dbFName, pMeta->tbName);
CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR);
}
if (CTG_IS_META_BOTH(pMeta->metaType) && TSDB_SUPER_TABLE != pMeta->tbMeta->tableType) {
if ((CTG_IS_META_BOTH(pMeta->metaType) ||
CTG_IS_META_VBOTH(pMeta->metaType)) &&
TSDB_SUPER_TABLE != pMeta->tbMeta->tableType) {
ctgError("table type error, expected:%d, actual:%d", TSDB_SUPER_TABLE, pMeta->tbMeta->tableType);
CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR);
}
@ -2449,7 +2485,7 @@ int32_t ctgOpUpdateTbMeta(SCtgCacheOperation *operation) {
CTG_ERR_JRET(TSDB_CODE_CTG_INTERNAL_ERROR);
}
if (CTG_IS_META_TABLE(pMeta->metaType) || CTG_IS_META_BOTH(pMeta->metaType)) {
if (CTG_IS_META_TABLE(pMeta->metaType) || CTG_IS_META_BOTH(pMeta->metaType) || CTG_IS_META_VBOTH(pMeta->metaType)) {
code = ctgWriteTbMetaToCache(pCtg, dbCache, pMeta->dbFName, pMeta->dbId, pMeta->tbName, pMeta->tbMeta);
pMeta->tbMeta = NULL;
CTG_ERR_JRET(code);
@ -2465,9 +2501,16 @@ int32_t ctgOpUpdateTbMeta(SCtgCacheOperation *operation) {
(STableMeta *)ctbMeta));
}
if (CTG_IS_META_VCTABLE(pMeta->metaType) || CTG_IS_META_VBOTH(pMeta->metaType)) {
code = ctgWriteTbMetaToCache(pCtg, dbCache, pMeta->dbFName, pMeta->dbId, pMeta->ctbName, (STableMeta *)pMeta->vctbMeta);
pMeta->vctbMeta = NULL;
CTG_ERR_JRET(code);
}
_return:
taosMemoryFreeClear(pMeta->tbMeta);
taosMemoryFreeClear(pMeta->vctbMeta);
taosMemoryFreeClear(pMeta);
taosMemoryFreeClear(msg);
@ -3162,6 +3205,7 @@ void ctgFreeCacheOperationData(SCtgCacheOperation *op) {
case CTG_OP_UPDATE_TB_META: {
SCtgUpdateTbMetaMsg *msg = op->data;
taosMemoryFreeClear(msg->pMeta->tbMeta);
taosMemoryFreeClear(msg->pMeta->vctbMeta);
taosMemoryFreeClear(msg->pMeta);
taosMemoryFreeClear(op->data);
break;
@ -3426,6 +3470,7 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
int32_t code = TSDB_CODE_SUCCESS;
uint64_t lastSuid = 0;
STableMeta *lastTableMeta = NULL;
SColRef *tmpRef = NULL;
SName *pName = taosArrayGet(pList, 0);
if (NULL == pName) {
ctgError("fail to get the 0th SName from tableList, tableNum:%d", (int32_t)taosArrayGetSize(pList));
@ -3505,26 +3550,37 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
SMetaRes res = {0};
STableMeta *pTableMeta = NULL;
if (tbMeta->tableType != TSDB_CHILD_TABLE) {
if (tbMeta->tableType != TSDB_CHILD_TABLE && tbMeta->tableType != TSDB_VIRTUAL_CHILD_TABLE) {
int32_t schemaExtSize = 0;
int32_t colRefSize = 0;
int32_t metaSize = CTG_META_SIZE(tbMeta);
if (tbMeta->schemaExt != NULL) {
if (withExtSchema(tbMeta->tableType) && tbMeta->schemaExt != NULL) {
schemaExtSize = tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef) {
colRefSize = tbMeta->tableInfo.numOfColumns * sizeof(SColRef);
}
pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize);
pTableMeta = taosMemoryCalloc(1, metaSize + schemaExtSize + colRefSize);
if (NULL == pTableMeta) {
ctgReleaseTbMetaToCache(pCtg, dbCache, pCache);
CTG_ERR_RET(terrno);
}
TAOS_MEMCPY(pTableMeta, tbMeta, metaSize);
if (tbMeta->schemaExt != NULL) {
if (withExtSchema(tbMeta->tableType) && tbMeta->schemaExt != NULL) {
pTableMeta->schemaExt = (SSchemaExt *)((char *)pTableMeta + metaSize);
TAOS_MEMCPY(pTableMeta->schemaExt, tbMeta->schemaExt, schemaExtSize);
} else {
pTableMeta->schemaExt = NULL;
}
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef) {
pTableMeta->colRef = (SColRef *)((char *)pTableMeta + metaSize + schemaExtSize);
pTableMeta->numOfColRefs = tbMeta->tableInfo.numOfColumns;
TAOS_MEMCPY(pTableMeta->colRef, tbMeta->colRef, colRefSize);
} else {
pTableMeta->colRef = NULL;
}
CTG_UNLOCK(CTG_READ, &pCache->metaLock);
taosHashRelease(dbCache->tbCache, pCache);
@ -3541,7 +3597,7 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
// PROCESS FOR CHILD TABLE
if (lastSuid && tbMeta->suid == lastSuid && lastTableMeta) {
if (lastSuid && tbMeta->suid == lastSuid && lastTableMeta && tbMeta->tableType != TSDB_VIRTUAL_CHILD_TABLE) {
code = cloneTableMeta(lastTableMeta, &pTableMeta);
if (code) {
CTG_UNLOCK(CTG_READ, &pCache->metaLock);
@ -3565,12 +3621,23 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
}
int32_t metaSize = sizeof(SCTableMeta);
int32_t colRefSize = 0;
int32_t colRefNum = 0;
pTableMeta = taosMemoryCalloc(1, metaSize);
if (NULL == pTableMeta) {
ctgReleaseTbMetaToCache(pCtg, dbCache, pCache);
CTG_ERR_RET(terrno);
}
if (hasRefCol(tbMeta->tableType) && tbMeta->colRef != NULL) {
colRefSize = tbMeta->numOfColRefs * sizeof(SColRef);
colRefNum = tbMeta->numOfColRefs;
taosMemoryFreeClear(tmpRef);
tmpRef = taosMemoryMalloc(colRefSize);
TAOS_MEMCPY(tmpRef, tbMeta->colRef, colRefSize);
}
TAOS_MEMCPY(pTableMeta, tbMeta, metaSize);
CTG_UNLOCK(CTG_READ, &pCache->metaLock);
@ -3651,19 +3718,29 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
schemaExtSize = stbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
metaSize = CTG_META_SIZE(stbMeta);
pTableMeta = taosMemoryRealloc(pTableMeta, metaSize + schemaExtSize);
pTableMeta = taosMemoryRealloc(pTableMeta, metaSize + schemaExtSize + colRefSize);
if (NULL == pTableMeta) {
ctgReleaseTbMetaToCache(pCtg, dbCache, pCache);
taosMemoryFreeClear(tmpRef);
CTG_ERR_RET(terrno);
}
TAOS_MEMCPY(&pTableMeta->sversion, &stbMeta->sversion, metaSize + schemaExtSize - sizeof(SCTableMeta));
if (stbMeta->schemaExt != NULL) {
TAOS_MEMCPY(&pTableMeta->numOfColRefs, &stbMeta->numOfColRefs, metaSize + schemaExtSize - sizeof(SCTableMeta));
if (withExtSchema(stbMeta->tableType) && stbMeta->schemaExt != NULL) {
pTableMeta->schemaExt = (SSchemaExt *)((char *)pTableMeta + metaSize);
} else {
pTableMeta->schemaExt = NULL;
}
if (colRefSize != 0) {
pTableMeta->numOfColRefs = colRefNum;
pTableMeta->colRef = (SColRef *)((char *)pTableMeta + metaSize + schemaExtSize);
TAOS_MEMCPY(pTableMeta->colRef, tmpRef, colRefSize);
} else {
pTableMeta->colRef = NULL;
}
taosMemoryFreeClear(tmpRef);
CTG_UNLOCK(CTG_READ, &pCache->metaLock);
taosHashRelease(dbCache->tbCache, pCache);
@ -3679,7 +3756,7 @@ int32_t ctgGetTbMetasFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgTbMe
}
_return:
taosMemoryFreeClear(tmpRef);
ctgReleaseDBCache(pCtg, dbCache);
return code;

View File

@ -591,6 +591,7 @@ void ctgFreeMsgCtx(SCtgMsgCtx* pCtx) {
case TDMT_VND_TABLE_NAME: {
STableMetaOutput* pOut = (STableMetaOutput*)pCtx->out;
taosMemoryFree(pOut->tbMeta);
taosMemoryFree(pOut->vctbMeta);
taosMemoryFreeClear(pCtx->out);
break;
}
@ -676,6 +677,7 @@ void ctgFreeSTableMetaOutput(STableMetaOutput* pOutput) {
}
taosMemoryFree(pOutput->tbMeta);
taosMemoryFree(pOutput->vctbMeta);
taosMemoryFree(pOutput);
}
@ -1681,15 +1683,42 @@ int32_t ctgCloneMetaOutput(STableMetaOutput* output, STableMetaOutput** pOutput)
TAOS_MEMCPY(*pOutput, output, sizeof(STableMetaOutput));
if (output->vctbMeta) {
int32_t metaSize = sizeof(SVCTableMeta);
int32_t colRefSize = 0;
if (hasRefCol(output->vctbMeta->tableType) && (*pOutput)->vctbMeta->colRef) {
colRefSize = output->vctbMeta->numOfColRefs * sizeof(SColRef);
}
(*pOutput)->vctbMeta = taosMemoryMalloc(metaSize + colRefSize);
if (NULL == (*pOutput)->vctbMeta) {
qError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
taosMemoryFreeClear(*pOutput);
CTG_ERR_RET(terrno);
}
TAOS_MEMCPY((*pOutput)->vctbMeta, output->vctbMeta, metaSize);
if (hasRefCol(output->vctbMeta->tableType) && (*pOutput)->vctbMeta->colRef) {
(*pOutput)->vctbMeta->colRef = (SColRef*)((char*)(*pOutput)->vctbMeta + metaSize);
TAOS_MEMCPY((*pOutput)->vctbMeta->colRef, output->vctbMeta->colRef, colRefSize);
} else {
(*pOutput)->vctbMeta->colRef = NULL;
}
}
if (output->tbMeta) {
int32_t metaSize = CTG_META_SIZE(output->tbMeta);
int32_t schemaExtSize = 0;
int32_t colRefSize = 0;
if (withExtSchema(output->tbMeta->tableType) && (*pOutput)->tbMeta->schemaExt) {
schemaExtSize = output->tbMeta->tableInfo.numOfColumns * sizeof(SSchemaExt);
}
if (hasRefCol(output->tbMeta->tableType) && (*pOutput)->tbMeta->colRef) {
colRefSize = output->tbMeta->tableInfo.numOfColumns * sizeof(SColRef);
}
(*pOutput)->tbMeta = taosMemoryMalloc(metaSize + schemaExtSize);
(*pOutput)->tbMeta = taosMemoryMalloc(metaSize + schemaExtSize + colRefSize);
qTrace("tbmeta cloned, size:%d, p:%p", metaSize, (*pOutput)->tbMeta);
if (NULL == (*pOutput)->tbMeta) {
qError("malloc %d failed", (int32_t)sizeof(STableMetaOutput));
taosMemoryFreeClear(*pOutput);
@ -1703,6 +1732,12 @@ int32_t ctgCloneMetaOutput(STableMetaOutput* output, STableMetaOutput** pOutput)
} else {
(*pOutput)->tbMeta->schemaExt = NULL;
}
if (hasRefCol(output->tbMeta->tableType) && (*pOutput)->tbMeta->colRef) {
(*pOutput)->tbMeta->colRef = (SColRef*)((char*)(*pOutput)->tbMeta + metaSize + schemaExtSize);
TAOS_MEMCPY((*pOutput)->tbMeta->colRef, output->tbMeta->colRef, colRefSize);
} else {
(*pOutput)->tbMeta->colRef = NULL;
}
}
return TSDB_CODE_SUCCESS;
@ -2087,12 +2122,12 @@ int32_t ctgChkSetTbAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) {
CTG_ERR_JRET(ctgGetTbMeta(pCtg, req->pConn, &ctx, &pMeta));
}
if (TSDB_SUPER_TABLE == pMeta->tableType || TSDB_NORMAL_TABLE == pMeta->tableType) {
if (TSDB_SUPER_TABLE == pMeta->tableType || TSDB_NORMAL_TABLE == pMeta->tableType || TSDB_VIRTUAL_NORMAL_TABLE == pMeta->tableType) {
res->pRawRes->pass[AUTH_RES_BASIC] = false;
goto _return;
}
if (TSDB_CHILD_TABLE == pMeta->tableType) {
if (TSDB_CHILD_TABLE == pMeta->tableType || TSDB_VIRTUAL_CHILD_TABLE == pMeta->tableType) {
CTG_ERR_JRET(ctgGetCachedStbNameFromSuid(pCtg, dbFName, pMeta->suid, &stbName));
if (NULL == stbName) {
if (req->onlyCache) {
@ -2410,6 +2445,8 @@ FORCE_INLINE uint64_t ctgGetTbMetaCacheSize(STableMeta* pMeta) {
return sizeof(*pMeta) + (pMeta->tableInfo.numOfColumns + pMeta->tableInfo.numOfTags) * sizeof(SSchema);
case TSDB_CHILD_TABLE:
return sizeof(SCTableMeta);
case TSDB_VIRTUAL_CHILD_TABLE:
return sizeof(SVCTableMeta);
default:
return sizeof(*pMeta) + pMeta->tableInfo.numOfColumns * sizeof(SSchema);
}

View File

@ -210,6 +210,8 @@ void ctgTestBuildCTableMetaOutput(STableMetaOutput *output) {
output->tbMeta->sversion = ctgTestSVersion;
output->tbMeta->tversion = ctgTestTVersion;
output->vctbMeta = NULL;
SSchema *s = NULL;
s = &output->tbMeta->schema[0];
s->type = TSDB_DATA_TYPE_TIMESTAMP;

View File

@ -29,6 +29,7 @@ extern "C" {
//newline area
#define EXPLAIN_TAG_SCAN_FORMAT "Tag Scan on %s"
#define EXPLAIN_VIRTUAL_TABLE_SCAN_FORMAT "Virtual Table Scan on %s"
#define EXPLAIN_TBL_SCAN_FORMAT "Table Scan on %s"
#define EXPLAIN_TBL_MERGE_SCAN_FORMAT "Table Merge Scan on %s"
#define EXPLAIN_SYSTBL_SCAN_FORMAT "System Table Scan on %s"

View File

@ -122,7 +122,10 @@ static int32_t buildDescResultDataBlock(SSDataBlock** pOutput) {
infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_COPRESS_OPTION_LEN, 7);
code = blockDataAppendColInfo(pBlock, &infoData);
}
if (TSDB_CODE_SUCCESS == code) {
infoData = createColumnInfoData(TSDB_DATA_TYPE_VARCHAR, DESCRIBE_RESULT_COL_REF_LEN, 8);
code = blockDataAppendColInfo(pBlock, &infoData);
}
if (TSDB_CODE_SUCCESS == code) {
*pOutput = pBlock;
} else {
@ -151,12 +154,18 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock,
SColumnInfoData* pCol6 = NULL;
// level
SColumnInfoData* pCol7 = NULL;
// colref
SColumnInfoData* pCol8 = NULL;
if (withExtSchema(pMeta->tableType)) {
pCol5 = taosArrayGet(pBlock->pDataBlock, 4);
pCol6 = taosArrayGet(pBlock->pDataBlock, 5);
pCol7 = taosArrayGet(pBlock->pDataBlock, 6);
}
if (hasRefCol(pMeta->tableType)) {
pCol5 = taosArrayGet(pBlock->pDataBlock, 4);
}
int32_t fillTagCol = 0;
char buf[DESCRIBE_RESULT_FIELD_LEN] = {0};
for (int32_t i = 0; i < numOfRows; ++i) {
@ -207,6 +216,24 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock,
STR_TO_VARSTR(buf, fillTagCol == 0 ? "" : "disabled");
COL_DATA_SET_VAL_AND_CHECK(pCol7, pBlock->info.rows, buf, false);
}
} else if (hasRefCol(pMeta->tableType) && pMeta->colRef) {
if (i < pMeta->numOfColRefs) {
if (pMeta->colRef[i].hasRef) {
char refColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN] = {0};
strcat(refColName, pMeta->colRef[i].refDbName);
strcat(refColName, ".");
strcat(refColName, pMeta->colRef[i].refTableName);
strcat(refColName, ".");
strcat(refColName, pMeta->colRef[i].refColName);
STR_TO_VARSTR(buf, refColName);
} else {
STR_TO_VARSTR(buf, "");
}
COL_DATA_SET_VAL_AND_CHECK(pCol5, pBlock->info.rows, buf, false);
} else {
STR_TO_VARSTR(buf, "");
COL_DATA_SET_VAL_AND_CHECK(pCol5, pBlock->info.rows, buf, false);
}
}
fillTagCol = 0;
@ -244,8 +271,14 @@ static int32_t execDescribe(bool sysInfoUser, SNode* pStmt, SRetrieveTableRsp**
code = setDescResultIntoDataBlock(sysInfoUser, pBlock, numOfRows, pDesc->pMeta, biMode);
}
if (TSDB_CODE_SUCCESS == code) {
if (pDesc->pMeta && withExtSchema(pDesc->pMeta->tableType) && pDesc->pMeta->schemaExt) {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS_COMPRESS, pRsp);
if (pDesc->pMeta) {
if (withExtSchema(pDesc->pMeta->tableType) && pDesc->pMeta->schemaExt) {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS_COMPRESS, pRsp);
} else if (hasRefCol(pDesc->pMeta->tableType) && pDesc->pMeta->colRef) {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS_REF, pRsp);
} else {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS, pRsp);
}
} else {
code = buildRetrieveTableRsp(pBlock, DESCRIBE_RESULT_COLS, pRsp);
}
@ -536,7 +569,8 @@ static int32_t buildCreateViewResultDataBlock(SSDataBlock** pOutput) {
static void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) {
for (int32_t i = 0; i < pCfg->numOfColumns; ++i) {
SSchema* pSchema = pCfg->pSchemas + i;
#define LTYPE_LEN (32 + 60) // 60 byte for compress info
SColRef* pRef = pCfg->pColRefs + i;
#define LTYPE_LEN (32 + 60 + TSDB_COL_FNAME_LEN + TSDB_DB_NAME_LEN + 10) // 60 byte for compress info, TSDB_COL_FNAME_LEN + TSDB_DB_NAME_LEN for column ref
char type[LTYPE_LEN];
snprintf(type, LTYPE_LEN, "%s", tDataTypes[pSchema->type].name);
int typeLen = strlen(type);
@ -560,6 +594,15 @@ static void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) {
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, " LEVEL \'%s\'",
columnLevelStr(COMPRESS_L2_TYPE_LEVEL_U32(pCfg->pSchemaExt[i].compress)));
}
if (hasRefCol(pCfg->tableType) && pCfg->pColRefs && pRef->hasRef) {
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, " FROM `%s`", pRef->refDbName);
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, ".");
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, "`%s`", pRef->refTableName);
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, ".");
typeLen += tsnprintf(type + typeLen, LTYPE_LEN - typeLen, "`%s`", pRef->refColName);
}
if (!(pSchema->flags & COL_IS_KEY)) {
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len),
"%s`%s` %s", ((i > 0) ? ", " : ""), pSchema->name, type);
@ -571,6 +614,29 @@ static void appendColumnFields(char* buf, int32_t* len, STableCfg* pCfg) {
}
}
static void appendColRefFields(char* buf, int32_t* len, STableCfg* pCfg) {
for (int32_t i = 1; i < pCfg->numOfColumns; ++i) {
SSchema* pSchema = pCfg->pSchemas + i;
SColRef* pRef = pCfg->pColRefs + i;
char type[TSDB_COL_NAME_LEN + 10 + TSDB_COL_FNAME_LEN + TSDB_DB_NAME_LEN];
int typeLen = 0;
if (hasRefCol(pCfg->tableType) && pCfg->pColRefs && pRef->hasRef) {
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, "FROM `%s`", pRef->refDbName);
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, ".");
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, "`%s`", pRef->refTableName);
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, ".");
typeLen += tsnprintf(type + typeLen, sizeof(type) - typeLen, "`%s`", pRef->refColName);
} else {
continue;
}
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len),
"%s`%s` %s", ((i > 1) ? ", " : ""), pSchema->name, type);
}
}
static void appendTagFields(char* buf, int32_t* len, STableCfg* pCfg) {
for (int32_t i = 0; i < pCfg->numOfTags; ++i) {
SSchema* pSchema = pCfg->pSchemas + pCfg->numOfColumns + i;
@ -749,6 +815,11 @@ static void appendTableOptions(char* buf, int32_t* len, SDbCfgInfo* pDbCfg, STab
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE, ")");
}
}
if (pCfg->virtualStb) {
*len += tsnprintf(buf + VARSTR_HEADER_SIZE + *len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + *len),
" VIRTUAL %d", pCfg->virtualStb);
}
}
static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* pDbCfg, char* tbName, STableCfg* pCfg,
@ -791,13 +862,33 @@ static int32_t setCreateTBResultIntoDataBlock(SSDataBlock* pBlock, SDbCfgInfo* p
len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
appendTableOptions(buf2, &len, pDbCfg, pCfg);
} else {
} else if (TSDB_NORMAL_TABLE == pCfg->tableType){
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE,
"CREATE TABLE `%s` (", tbName);
appendColumnFields(buf2, &len, pCfg);
len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
appendTableOptions(buf2, &len, pDbCfg, pCfg);
} else if (TSDB_VIRTUAL_NORMAL_TABLE == pCfg->tableType) {
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE,
"CREATE VTABLE `%s` (", tbName);
appendColumnFields(buf2, &len, pCfg);
len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
} else if (TSDB_VIRTUAL_CHILD_TABLE == pCfg->tableType) {
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE, SHOW_CREATE_TB_RESULT_FIELD2_LEN - VARSTR_HEADER_SIZE,
"CREATE VTABLE `%s` (", tbName);
appendColRefFields(buf2, &len, pCfg);
len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len),
") USING `%s` (", pCfg->stbName);
appendTagNameFields(buf2, &len, pCfg);
len += tsnprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len),
") TAGS (");
code = appendTagValues(buf2, &len, pCfg, charsetCxt);
TAOS_CHECK_ERRNO(code);
len +=
snprintf(buf2 + VARSTR_HEADER_SIZE + len, SHOW_CREATE_TB_RESULT_FIELD2_LEN - (VARSTR_HEADER_SIZE + len), ")");
}
varDataLen(buf2) = (len > 65535) ? 65535 : len;
@ -856,6 +947,19 @@ static int32_t execShowCreateTable(SShowCreateTableStmt* pStmt, SRetrieveTableRs
return code;
}
static int32_t execShowCreateVTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) {
SSDataBlock* pBlock = NULL;
int32_t code = buildCreateTbResultDataBlock(&pBlock);
if (TSDB_CODE_SUCCESS == code) {
code = setCreateTBResultIntoDataBlock(pBlock, pStmt->pDbCfg, pStmt->tableName, pStmt->pTableCfg, charsetCxt);
}
if (TSDB_CODE_SUCCESS == code) {
code = buildRetrieveTableRsp(pBlock, SHOW_CREATE_TB_RESULT_COLS, pRsp);
}
(void)blockDataDestroy(pBlock);
return code;
}
static int32_t execShowCreateSTable(SShowCreateTableStmt* pStmt, SRetrieveTableRsp** pRsp, void* charsetCxt) {
STableCfg* pCfg = (STableCfg*)pStmt->pTableCfg;
if (TSDB_SUPER_TABLE != pCfg->tableType) {
@ -1109,6 +1213,8 @@ int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieve
return execShowCreateDatabase((SShowCreateDatabaseStmt*)pStmt, pRsp);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
return execShowCreateTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt);
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
return execShowCreateVTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt);
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return execShowCreateSTable((SShowCreateTableStmt*)pStmt, pRsp, charsetCxt);
case QUERY_NODE_SHOW_CREATE_VIEW_STMT:

View File

@ -420,6 +420,52 @@ static int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx
}
break;
}
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN: {
SVirtualScanPhysiNode *pVirtualTableScanNode = (SVirtualScanPhysiNode *)pNode;
EXPLAIN_ROW_NEW(level, EXPLAIN_VIRTUAL_TABLE_SCAN_FORMAT, pVirtualTableScanNode->scan.tableName.tname);
EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT);
if (pResNode->pExecInfo) {
QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
}
if (pVirtualTableScanNode->scan.pScanPseudoCols) {
EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pVirtualTableScanNode->scan.pScanPseudoCols->length);
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
}
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->totalRowSize);
EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT);
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level));
if (verbose) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT,
nodesGetOutputNumFromSlotList(pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->pSlots));
EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT);
EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pVirtualTableScanNode->scan.node.pOutputDataBlockDesc->outputRowSize);
EXPLAIN_ROW_APPEND_LIMIT(pVirtualTableScanNode->scan.node.pLimit);
EXPLAIN_ROW_APPEND_SLIMIT(pVirtualTableScanNode->scan.node.pSlimit);
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
if (pResNode->pExecInfo) {
QRY_ERR_RET(qExplainBufAppendVerboseExecInfo(pResNode->pExecInfo, tbuf, &tlen));
if (tlen) {
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
}
}
if (pVirtualTableScanNode->scan.node.pConditions) {
EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT);
QRY_ERR_RET(nodesNodeToSQL(pVirtualTableScanNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE,
TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen));
EXPLAIN_ROW_END();
QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1));
}
}
break;
}
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: {

View File

@ -52,7 +52,7 @@ typedef struct SDataSinkHandle {
FGetSinkFlags fGetFlags;
} SDataSinkHandle;
int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle);
int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, bool processOneBlock);
int32_t createDataDeleter(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle,
void* pParam);
int32_t createDataInserter(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle,

View File

@ -74,10 +74,28 @@ typedef struct SStbJoinDynCtrlInfo {
SDataBlockDescNode* pOutputDataBlockDesc;
} SStbJoinDynCtrlInfo;
typedef struct SVtbScanDynCtrlInfo {
int32_t acctId;
SUseDbRsp* pRsp;
SUseDbReq req;
tsem_t ready;
SEpSet epSet;
uint64_t suid;
SReadHandle readHandle;
SArray* childTableList;
int32_t lastTableIdx;
SOperatorParam* vtbScanParam;
int32_t readTableIdx;
SHashObj* dbVgInfoMap;
SArray* readColList;
bool scanAllCols;
} SVtbScanDynCtrlInfo;
typedef struct SDynQueryCtrlOperatorInfo {
EDynQueryType qType;
union {
SStbJoinDynCtrlInfo stbJoin;
SVtbScanDynCtrlInfo vtbScan;
};
} SDynQueryCtrlOperatorInfo;

View File

@ -192,6 +192,8 @@ SColumn extractColumnFromColumnNode(SColumnNode* pColNode);
int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysiNode* pTableScanNode,
const SReadHandle* readHandle);
int32_t initQueryTableDataCondWithColArray(SQueryTableDataCond* pCond, SQueryTableDataCond* pOrgCond,
const SReadHandle* readHandle, SArray* colArray);
void cleanupQueryTableDataCond(SQueryTableDataCond* pCond);
int32_t convertFillType(int32_t mode);

View File

@ -161,10 +161,13 @@ typedef struct SSortMergeJoinOperatorParam {
} SSortMergeJoinOperatorParam;
typedef struct SExchangeOperatorBasicParam {
int32_t vgId;
int32_t srcOpType;
bool tableSeq;
SArray* uidList;
int32_t vgId;
int32_t srcOpType;
bool tableSeq;
SArray* uidList;
bool isVtbRefScan;
SOrgTbInfo* colMap;
STimeWindow window;
} SExchangeOperatorBasicParam;
typedef struct SExchangeOperatorBatchParam {
@ -253,6 +256,7 @@ typedef struct STableScanBase {
STsdbReader* dataReader;
SFileBlockLoadRecorder readRecorder;
SQueryTableDataCond cond;
SQueryTableDataCond orgCond; // use for virtual super table scan
SAggOptrPushDownInfo pdInfo;
SColMatchInfo matchInfo;
SReadHandle readHandle;
@ -283,6 +287,9 @@ typedef struct STableScanInfo {
bool hasGroupByTag;
bool filesetDelimited;
bool needCountEmptyTable;
SSDataBlock* pOrgBlock;
bool ignoreTag;
bool virtualStableScan;
} STableScanInfo;
typedef enum ESubTableInputType {
@ -1190,6 +1197,7 @@ void* decodeSTimeWindowAggSupp(void* buf, STimeWindowAggSupp* pTwAggSup);
void destroyOperatorParamValue(void* pValues);
int32_t mergeOperatorParams(SOperatorParam* pDst, SOperatorParam* pSrc);
int32_t buildTableScanOperatorParam(SOperatorParam** ppRes, SArray* pUidList, int32_t srcOpType, bool tableSeq);
int32_t buildTableScanOperatorParamEx(SOperatorParam** ppRes, SArray* pUidList, int32_t srcOpType, SOrgTbInfo *pMap, bool tableSeq, STimeWindow *window);
void freeExchangeGetBasicOperatorParam(void* pParam);
void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type);
void freeResetOperatorParams(struct SOperatorInfo* pOperator, SOperatorParamType type, bool allFree);

View File

@ -172,7 +172,7 @@ int32_t createGroupCacheOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfD
int32_t createAnomalywindowOperatorInfo(SOperatorInfo* downstream, SPhysiNode* physiNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pInfo);
int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream, SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** pInfo);
int32_t createStreamTimeSliceOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** ppOptInfo);
@ -186,6 +186,8 @@ int32_t createStateNonblockOperatorInfo(SOperatorInfo* downstream, SPhysiNode* p
int32_t createEventNonblockOperatorInfo(SOperatorInfo* downstream, SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHandle* pHandle, SOperatorInfo** ppOptInfo);
int32_t createVirtualTableMergeOperatorInfo(SOperatorInfo** pDownstream, SReadHandle* readHandle, STableListInfo* pTableListInfo, int32_t numOfDownstream, SVirtualScanPhysiNode * pJoinNode, SExecTaskInfo* pTaskInfo, SOperatorInfo** pOptrInfo);
// clang-format on
SOperatorFpSet createOperatorFpSet(__optr_open_fn_t openFn, __optr_fn_t nextFn, __optr_fn_t cleanup,

View File

@ -166,6 +166,22 @@ void tsortGetValue(STupleHandle* pVHandle, int32_t colId, void** pVal);
*/
uint64_t tsortGetGroupId(STupleHandle* pVHandle);
void tsortGetBlockInfo(STupleHandle* pVHandle, SDataBlockInfo* pInfo);
/**
* return the SColumnInfoData of columns in the tuple
* @param pVHandle
* @param colId
* @return
*/
void tsortGetColumnInfo(STupleHandle* pVHandle, int32_t colIndex, SColumnInfoData** pColInfo);
/**
* return the number of columns in the tuple
* @param pVHandle
* @return
*/
size_t tsortGetColNum(STupleHandle* pVHandle);
/**
*
* @param pSortHandle

View File

@ -0,0 +1,47 @@
/*
* 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/>.
*/
#ifndef TDENGINE_VIRTUALTABLESCAN_H
#define TDENGINE_VIRTUALTABLESCAN_H
#ifdef __cplusplus
extern "C" {
#endif
#include "executorInt.h"
#include "operator.h"
#define VTS_ERR_RET(c) \
do { \
int32_t _code = (c); \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
return _code; \
} \
} while (0)
#define VTS_ERR_JRET(c) \
do { \
code = (c); \
if (code != TSDB_CODE_SUCCESS) { \
terrno = code; \
goto _return; \
} \
} while (0)
#ifdef __cplusplus
}
#endif
#endif // TDENGINE_VIRTUALTABLESCAN_H

View File

@ -268,7 +268,7 @@ static int32_t putDataBlock(SDataSinkHandle* pHandle, const SInputData* pInput,
QRY_ERR_JRET(taosWriteQitem(pDispatcher->pDataBlocks, pBuf));
int32_t status = updateStatus(pDispatcher);
*pContinue = (status == DS_BUF_LOW || status == DS_BUF_EMPTY);
*pContinue = (status == DS_BUF_LOW || status == DS_BUF_EMPTY) && !(pDispatcher->flags & DS_FLAG_PROCESS_ONE_BLOCK);
return TSDB_CODE_SUCCESS;
_return:
@ -438,7 +438,7 @@ int32_t getOutputColCounts(SDataBlockDescNode* pInputDataBlockDesc) {
return numOfCols;
}
int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle) {
int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, bool processOneBlock) {
int32_t code;
SDataSinkNode* pDataSink = *ppDataSink;
code = blockDescNodeCheck(pDataSink->pInputDataBlockDesc);
@ -480,6 +480,9 @@ int32_t createDataDispatcher(SDataSinkManager* pManager, SDataSinkNode** ppDataS
}
dispatcher->flags = DS_FLAG_USE_MEMPOOL;
if (processOneBlock) {
dispatcher->flags |= DS_FLAG_PROCESS_ONE_BLOCK;
}
*pHandle = dispatcher;
return TSDB_CODE_SUCCESS;

View File

@ -39,11 +39,11 @@ int32_t dsDataSinkGetCacheSize(SDataSinkStat* pStat) {
return TSDB_CODE_SUCCESS;
}
int32_t dsCreateDataSinker(void* pSinkManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, void* pParam, const char* id) {
int32_t dsCreateDataSinker(void* pSinkManager, SDataSinkNode** ppDataSink, DataSinkHandle* pHandle, void* pParam, const char* id, bool processOneBlock) {
SDataSinkManager* pManager = pSinkManager;
switch ((int)nodeType(*ppDataSink)) {
case QUERY_NODE_PHYSICAL_PLAN_DISPATCH:
return createDataDispatcher(pManager, ppDataSink, pHandle);
return createDataDispatcher(pManager, ppDataSink, pHandle, processOneBlock);
case QUERY_NODE_PHYSICAL_PLAN_DELETE: {
return createDataDeleter(pManager, ppDataSink, pHandle, pParam);
}

View File

@ -15,7 +15,6 @@
#include "executorInt.h"
#include "filter.h"
#include "function.h"
#include "nodes.h"
#include "operator.h"
#include "os.h"
@ -28,6 +27,7 @@
#include "tdatablock.h"
#include "thash.h"
#include "tmsg.h"
#include "trpc.h"
#include "ttypes.h"
#include "dynqueryctrl.h"
@ -80,6 +80,35 @@ static void destroyStbJoinDynCtrlInfo(SStbJoinDynCtrlInfo* pStbJoin) {
destroyStbJoinTableList(pStbJoin->ctx.prev.pListHead);
}
void freeUseDbOutput(void* pOutput) {
SUseDbOutput *pOut = *(SUseDbOutput**)pOutput;
if (NULL == pOutput) {
return;
}
if (pOut->dbVgroup) {
freeVgInfo(pOut->dbVgroup);
}
taosMemFree(pOut);
}
static void destroyVtbScanDynCtrlInfo(SVtbScanDynCtrlInfo* pVtbScan) {
if (pVtbScan->childTableList) {
taosArrayDestroy(pVtbScan->childTableList);
}
if (pVtbScan->readColList) {
taosArrayDestroy(pVtbScan->readColList);
}
if (pVtbScan->dbVgInfoMap) {
taosHashSetFreeFp(pVtbScan->dbVgInfoMap, freeUseDbOutput);
taosHashCleanup(pVtbScan->dbVgInfoMap);
}
if (pVtbScan->pRsp) {
tFreeSUsedbRsp(pVtbScan->pRsp);
taosMemoryFreeClear(pVtbScan->pRsp);
}
}
static void destroyDynQueryCtrlOperator(void* param) {
SDynQueryCtrlOperatorInfo* pDyn = (SDynQueryCtrlOperatorInfo*)param;
@ -87,6 +116,9 @@ static void destroyDynQueryCtrlOperator(void* param) {
case DYN_QTYPE_STB_HASH:
destroyStbJoinDynCtrlInfo(&pDyn->stbJoin);
break;
case DYN_QTYPE_VTB_SCAN:
destroyVtbScanDynCtrlInfo(&pDyn->vtbScan);
break;
default:
qError("unsupported dynamic query ctrl type: %d", pDyn->qType);
break;
@ -199,6 +231,7 @@ static int32_t buildGroupCacheOperatorParam(SOperatorParam** ppRes, int32_t down
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE;
(*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pGc;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
}
@ -226,12 +259,13 @@ static int32_t buildGroupCacheNotifyOperatorParam(SOperatorParam** ppRes, int32_
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE;
(*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pGc;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
}
static int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, int32_t* pVgId, int64_t* pUid) {
static int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, const int32_t* pVgId, int64_t* pUid) {
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
if (NULL == *ppRes) {
return terrno;
@ -246,7 +280,9 @@ static int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, int32_t downst
pExc->multiParams = false;
pExc->basic.vgId = *pVgId;
pExc->basic.tableSeq = true;
pExc->basic.isVtbRefScan = false;
pExc->basic.srcOpType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
pExc->basic.colMap = NULL;
pExc->basic.uidList = taosArrayInit(1, sizeof(int64_t));
if (NULL == pExc->basic.uidList) {
taosMemoryFree(pExc);
@ -261,11 +297,11 @@ static int32_t buildExchangeOperatorParam(SOperatorParam** ppRes, int32_t downst
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
(*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pExc;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
}
static int32_t buildBatchExchangeOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, SSHashObj* pVg) {
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
if (NULL == *ppRes) {
@ -298,7 +334,9 @@ static int32_t buildBatchExchangeOperatorParam(SOperatorParam** ppRes, int32_t d
SArray* pUidList = *(SArray**)p;
basic.vgId = *pVgId;
basic.uidList = pUidList;
basic.colMap = NULL;
basic.tableSeq = false;
basic.isVtbRefScan = false;
QRY_ERR_RET(tSimpleHashPut(pExc->pBatchs, pVgId, sizeof(*pVgId), &basic, sizeof(basic)));
@ -309,10 +347,65 @@ static int32_t buildBatchExchangeOperatorParam(SOperatorParam** ppRes, int32_t d
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
(*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pExc;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
}
static int32_t buildExchangeOperatorParamForVScan(SOperatorParam** ppRes, int32_t downstreamIdx, SOrgTbInfo* pMap) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SExchangeOperatorParam* pExc = NULL;
SExchangeOperatorBasicParam* basic = NULL;
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
QUERY_CHECK_NULL(*ppRes, code, lino, _return, terrno);
(*ppRes)->pChildren = NULL;
pExc = taosMemoryMalloc(sizeof(SExchangeOperatorParam));
QUERY_CHECK_NULL(pExc, code, lino, _return, terrno);
pExc->multiParams = false;
basic = &pExc->basic;
basic->srcOpType = QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN;
basic->vgId = pMap->vgId;
basic->tableSeq = false;
basic->isVtbRefScan = true;
basic->colMap = taosMemoryMalloc(sizeof(SOrgTbInfo));
QUERY_CHECK_NULL(basic->colMap, code, lino, _return, terrno);
basic->colMap->vgId = pMap->vgId;
tstrncpy(basic->colMap->tbName, pMap->tbName, TSDB_TABLE_FNAME_LEN);
basic->colMap->colMap = taosArrayDup(pMap->colMap, NULL);
QUERY_CHECK_NULL(basic->colMap->colMap, code, lino, _return, terrno);
basic->uidList = taosArrayInit(1, sizeof(int64_t));
QUERY_CHECK_NULL(basic->uidList, code, lino, _return, terrno);
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_EXCHANGE;
(*ppRes)->downstreamIdx = downstreamIdx;
(*ppRes)->value = pExc;
(*ppRes)->reUse = true;
return TSDB_CODE_SUCCESS;
_return:
qError("failed to build exchange operator param for vscan, code:%d", code);
taosMemoryFreeClear(*ppRes);
if (basic) {
if (basic->colMap) {
taosArrayDestroy(basic->colMap->colMap);
taosMemoryFreeClear(basic->colMap);
}
if (basic->uidList) {
taosArrayDestroy(basic->uidList);
}
taosMemoryFreeClear(basic);
}
taosMemoryFreeClear(pExc);
return code;
}
static int32_t buildMergeJoinOperatorParam(SOperatorParam** ppRes, bool initParam, SOperatorParam** ppChild0, SOperatorParam** ppChild1) {
int32_t code = TSDB_CODE_SUCCESS;
@ -355,11 +448,11 @@ static int32_t buildMergeJoinOperatorParam(SOperatorParam** ppRes, bool initPara
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN;
(*ppRes)->value = pJoin;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
}
static int32_t buildMergeJoinNotifyOperatorParam(SOperatorParam** ppRes, SOperatorParam* pChild0, SOperatorParam* pChild1) {
int32_t code = TSDB_CODE_SUCCESS;
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
@ -395,12 +488,11 @@ static int32_t buildMergeJoinNotifyOperatorParam(SOperatorParam** ppRes, SOperat
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN;
(*ppRes)->value = NULL;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
}
static int32_t buildBatchTableScanOperatorParam(SOperatorParam** ppRes, int32_t downstreamIdx, SSHashObj* pVg) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t vgNum = tSimpleHashGetSize(pVg);
@ -516,7 +608,6 @@ static int32_t buildSeqStbJoinOperatorParam(SDynQueryCtrlOperatorInfo* pInfo, SS
return code;
}
static void seqJoinLaunchNewRetrieveImpl(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
SDynQueryCtrlOperatorInfo* pInfo = pOperator->info;
SStbJoinDynCtrlInfo* pStbJoin = (SStbJoinDynCtrlInfo*)&pInfo->stbJoin;
@ -918,8 +1009,11 @@ static int32_t seqStableJoinComposeRes(SStbJoinDynCtrlInfo* pStbJoin, SSDataBloc
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
SColumnInfoData colInfo = createColumnInfoData(pSlot->dataType.type, pSlot->dataType.bytes, pSlot->slotId);
colInfoDataEnsureCapacity(&colInfo, pBlock->info.rows, true);
int32_t code = blockDataAppendColInfo(pBlock, &colInfo);
int32_t code = colInfoDataEnsureCapacity(&colInfo, pBlock->info.rows, true);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
code = blockDataAppendColInfo(pBlock, &colInfo);
if (code != TSDB_CODE_SUCCESS) {
return code;
}
@ -964,7 +1058,7 @@ int32_t seqStableJoin(SOperatorInfo* pOperator, SSDataBlock** pRes) {
_return:
if (pOperator->cost.openCost == 0) {
pOperator->cost.openCost = (taosGetTimestampUs() - st) / 1000.0;
pOperator->cost.openCost = (double)(taosGetTimestampUs() - st) / 1000.0;
}
if (code) {
@ -977,6 +1071,354 @@ _return:
return code;
}
static int32_t buildVtbScanOperatorParam(SDynQueryCtrlOperatorInfo* pInfo, SOperatorParam** ppRes) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SVTableScanOperatorParam* pVScan = NULL;
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
QUERY_CHECK_NULL(*ppRes, code, lino, _return, terrno);
(*ppRes)->pChildren = taosArrayInit(1, POINTER_BYTES);
QUERY_CHECK_NULL((*ppRes)->pChildren, code, lino, _return, terrno);
pVScan = taosMemoryMalloc(sizeof(SVTableScanOperatorParam));
QUERY_CHECK_NULL(pVScan, code, lino, _return, terrno);
pVScan->pOpParamArray = taosArrayInit(1, POINTER_BYTES);
QUERY_CHECK_NULL(pVScan->pOpParamArray, code, lino, _return, terrno);
(*ppRes)->opType = QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN;
(*ppRes)->downstreamIdx = 0;
(*ppRes)->value = pVScan;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
_return:
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
if (pVScan) {
taosArrayDestroy(pVScan->pOpParamArray);
taosMemoryFreeClear(pVScan);
}
if (*ppRes) {
taosArrayDestroy((*ppRes)->pChildren);
taosMemoryFreeClear(*ppRes);
}
return code;
}
int32_t dynProcessUseDbRsp(void* param, SDataBuf* pMsg, int32_t code) {
int32_t lino = 0;
SOperatorInfo* operator=(SOperatorInfo*) param;
SDynQueryCtrlOperatorInfo* pScanResInfo = (SDynQueryCtrlOperatorInfo*)operator->info;
if (TSDB_CODE_SUCCESS != code) {
operator->pTaskInfo->code = rpcCvtErrCode(code);
if (operator->pTaskInfo->code != code) {
qError("load systable rsp received, error:%s, cvted error:%s", tstrerror(code),
tstrerror(operator->pTaskInfo->code));
} else {
qError("load systable rsp received, error:%s", tstrerror(code));
}
goto _return;
}
pScanResInfo->vtbScan.pRsp = taosMemoryMalloc(sizeof(SUseDbRsp));
QUERY_CHECK_NULL(pScanResInfo->vtbScan.pRsp, code, lino, _return, terrno);
QUERY_CHECK_CODE(tDeserializeSUseDbRsp(pMsg->pData, (int32_t)pMsg->len, pScanResInfo->vtbScan.pRsp), lino, _return);
taosMemoryFreeClear(pMsg->pData);
QUERY_CHECK_CODE(tsem_post(&pScanResInfo->vtbScan.ready), lino, _return);
return TSDB_CODE_SUCCESS;
_return:
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
return code;
}
static int32_t buildDbVgInfoMap(SOperatorInfo* pOperator, SReadHandle* pHandle, SName* name, SExecTaskInfo* pTaskInfo, SUseDbOutput* output) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
char* buf1 = NULL;
SUseDbReq* pReq = NULL;
SDynQueryCtrlOperatorInfo* pScanResInfo = (SDynQueryCtrlOperatorInfo*)pOperator->info;
pReq = taosMemoryMalloc(sizeof(SUseDbReq));
QUERY_CHECK_NULL(pReq, code, lino, _return, terrno);
QUERY_CHECK_CODE(tNameGetFullDbName(name, pReq->db), lino, _return);
int32_t contLen = tSerializeSUseDbReq(NULL, 0, pReq);
buf1 = taosMemoryCalloc(1, contLen);
QUERY_CHECK_NULL(buf1, code, lino, _return, terrno);
int32_t tempRes = tSerializeSUseDbReq(buf1, contLen, pReq);
if (tempRes < 0) {
QUERY_CHECK_CODE(terrno, lino, _return);
}
// send the fetch remote task result request
SMsgSendInfo* pMsgSendInfo = taosMemoryCalloc(1, sizeof(SMsgSendInfo));
QUERY_CHECK_NULL(pMsgSendInfo, code, lino, _return, terrno);
pMsgSendInfo->param = pOperator;
pMsgSendInfo->msgInfo.pData = buf1;
pMsgSendInfo->msgInfo.len = contLen;
pMsgSendInfo->msgType = TDMT_MND_GET_DB_INFO;
pMsgSendInfo->fp = dynProcessUseDbRsp;
pMsgSendInfo->requestId = pTaskInfo->id.queryId;
QUERY_CHECK_CODE(asyncSendMsgToServer(pHandle->pMsgCb->clientRpc, &pScanResInfo->vtbScan.epSet, NULL, pMsgSendInfo), lino, _return);
QUERY_CHECK_CODE(tsem_wait(&pScanResInfo->vtbScan.ready), lino, _return);
QUERY_CHECK_CODE(queryBuildUseDbOutput(output, pScanResInfo->vtbScan.pRsp), lino, _return);
_return:
if (code) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
taosMemoryFree(buf1);
}
taosMemoryFree(pReq);
tFreeSUsedbRsp(pScanResInfo->vtbScan.pRsp);
taosMemoryFreeClear(pScanResInfo->vtbScan.pRsp);
return code;
}
int dynVgInfoComp(const void* lp, const void* rp) {
SVgroupInfo* pLeft = (SVgroupInfo*)lp;
SVgroupInfo* pRight = (SVgroupInfo*)rp;
if (pLeft->hashBegin < pRight->hashBegin) {
return -1;
} else if (pLeft->hashBegin > pRight->hashBegin) {
return 1;
}
return 0;
}
int32_t dynMakeVgArraySortBy(SDBVgInfo* dbInfo, __compar_fn_t sort_func) {
if (NULL == dbInfo) {
return TSDB_CODE_SUCCESS;
}
if (dbInfo->vgHash && NULL == dbInfo->vgArray) {
int32_t vgSize = taosHashGetSize(dbInfo->vgHash);
dbInfo->vgArray = taosArrayInit(vgSize, sizeof(SVgroupInfo));
if (NULL == dbInfo->vgArray) {
return terrno;
}
void* pIter = taosHashIterate(dbInfo->vgHash, NULL);
while (pIter) {
if (NULL == taosArrayPush(dbInfo->vgArray, pIter)) {
taosHashCancelIterate(dbInfo->vgHash, pIter);
return terrno;
}
pIter = taosHashIterate(dbInfo->vgHash, pIter);
}
taosArraySort(dbInfo->vgArray, sort_func);
}
return TSDB_CODE_SUCCESS;
}
int32_t dynHashValueComp(void const* lp, void const* rp) {
uint32_t* key = (uint32_t*)lp;
SVgroupInfo* pVg = (SVgroupInfo*)rp;
if (*key < pVg->hashBegin) {
return -1;
} else if (*key > pVg->hashEnd) {
return 1;
}
return 0;
}
int32_t getVgId(SDBVgInfo* dbInfo, char* dbFName, int32_t* vgId, char *tbName) {
int32_t code = 0;
int32_t lino = 0;
QUERY_CHECK_CODE(dynMakeVgArraySortBy(dbInfo, dynVgInfoComp), lino, _return);
int32_t vgNum = (int32_t)taosArrayGetSize(dbInfo->vgArray);
if (vgNum <= 0) {
qError("db vgroup cache invalid, db:%s, vgroup number:%d", dbFName, vgNum);
QUERY_CHECK_CODE(TSDB_CODE_TSC_DB_NOT_SELECTED, lino, _return);
}
SVgroupInfo* vgInfo = NULL;
char tbFullName[TSDB_TABLE_FNAME_LEN];
(void)snprintf(tbFullName, sizeof(tbFullName), "%s.", dbFName);
int32_t offset = (int32_t)strlen(tbFullName);
(void)snprintf(tbFullName + offset, sizeof(tbFullName) - offset, "%s", tbName);
uint32_t hashValue = taosGetTbHashVal(tbFullName, (int32_t)strlen(tbFullName), dbInfo->hashMethod,
dbInfo->hashPrefix, dbInfo->hashSuffix);
vgInfo = taosArraySearch(dbInfo->vgArray, &hashValue, dynHashValueComp, TD_EQ);
if (NULL == vgInfo) {
qError("no hash range found for hash value [%u], db:%s, numOfVgId:%d", hashValue, dbFName,
(int32_t)taosArrayGetSize(dbInfo->vgArray));
return TSDB_CODE_CTG_INTERNAL_ERROR;
}
*vgId = vgInfo->vgId;
_return:
return code;
}
bool colNeedScan(SOperatorInfo* pOperator, col_id_t colId) {
SDynQueryCtrlOperatorInfo* pInfo = pOperator->info;
SVtbScanDynCtrlInfo* pVtbScan = (SVtbScanDynCtrlInfo*)&pInfo->vtbScan;
SArray * pColList = pVtbScan->readColList;
if (pVtbScan->scanAllCols) {
return true;
}
for (int32_t i = 0; i < taosArrayGetSize(pColList); i++) {
if (colId == *(col_id_t*)taosArrayGet(pColList, i)) {
return true;
}
}
return false;
}
void destroyOrgTbInfo(void *info) {
SOrgTbInfo *pOrgTbInfo = (SOrgTbInfo *)info;
if (pOrgTbInfo) {
taosArrayDestroy(pOrgTbInfo->colMap);
}
}
int32_t vtbScan(SOperatorInfo* pOperator, SSDataBlock** pRes) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t line = 0;
SDynQueryCtrlOperatorInfo* pInfo = pOperator->info;
SVtbScanDynCtrlInfo* pVtbScan = (SVtbScanDynCtrlInfo*)&pInfo->vtbScan;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SReadHandle* pHandle = &pVtbScan->readHandle;
SMetaReader mr = {0};
SHashObj* orgTbVgColMap = NULL;
QRY_PARAM_CHECK(pRes);
if (pOperator->status == OP_EXEC_DONE) {
return code;
}
int64_t st = 0;
if (pOperator->cost.openCost == 0) {
st = taosGetTimestampUs();
}
size_t num = taosArrayGetSize(pVtbScan->childTableList);
if (num == 0) {
setOperatorCompleted(pOperator);
return code;
}
// TODO(smj) : proper hash size
orgTbVgColMap = taosHashInit(num * 64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
QUERY_CHECK_NULL(orgTbVgColMap, code, line, _return, terrno);
taosHashSetFreeFp(orgTbVgColMap, destroyOrgTbInfo);
while (true) {
if (pVtbScan->readTableIdx == pVtbScan->lastTableIdx) {
QUERY_CHECK_CODE(pOperator->pDownstream[0]->fpSet.getNextFn(pOperator->pDownstream[0], pRes), line, _return);
} else {
uint64_t* id = taosArrayGet(pVtbScan->childTableList, pVtbScan->readTableIdx);
QUERY_CHECK_NULL(id, code, line, _return, terrno);
pHandle->api.metaReaderFn.initReader(&mr, pHandle->vnode, META_READER_LOCK, &pHandle->api.metaFn);
QUERY_CHECK_CODE(pHandle->api.metaReaderFn.getTableEntryByUid(&mr, *id), line, _return);
for (int32_t j = 0; j < mr.me.colRef.nCols; j++) {
if (mr.me.colRef.pColRef[j].hasRef && colNeedScan(pOperator, mr.me.colRef.pColRef[j].id)) {
SName name = {0};
toName(pInfo->vtbScan.acctId, mr.me.colRef.pColRef[j].refDbName, "", &name);
SUseDbOutput* output = NULL;
SUseDbOutput** find = (SUseDbOutput**)taosHashGet(pInfo->vtbScan.dbVgInfoMap, name.dbname, strlen(name.dbname));
if (find == NULL) {
output = taosMemoryMalloc(sizeof(SUseDbOutput));
QUERY_CHECK_CODE(buildDbVgInfoMap(pOperator, pHandle, &name, pTaskInfo, output), line, _return);
QUERY_CHECK_CODE(taosHashPut(pInfo->vtbScan.dbVgInfoMap, name.dbname, strlen(name.dbname), &output, sizeof(output)), line, _return);
} else {
output = *find;
}
int32_t vgId = 0;
char dbFname[TSDB_DB_FNAME_LEN] = {0};
QUERY_CHECK_CODE(tNameGetFullDbName(&name, dbFname), line, _return);
QUERY_CHECK_CODE(getVgId(output->dbVgroup, dbFname, &vgId, mr.me.colRef.pColRef[j].refTableName), line, _return);
char orgTbFName[TSDB_TABLE_FNAME_LEN] = {0};
TAOS_STRNCAT(orgTbFName, mr.me.colRef.pColRef[j].refDbName, TSDB_DB_NAME_LEN);
TAOS_STRNCAT(orgTbFName, ".", 2);
TAOS_STRNCAT(orgTbFName, mr.me.colRef.pColRef[j].refTableName, TSDB_TABLE_NAME_LEN);
void *tbVgCol = taosHashGet(orgTbVgColMap, orgTbFName, sizeof(orgTbFName));
if (!tbVgCol) {
SOrgTbInfo map = {0};
map.vgId = vgId;
tstrncpy(map.tbName, orgTbFName, sizeof(map.tbName));
map.colMap = taosArrayInit(10, sizeof(SColIdNameKV));
QUERY_CHECK_NULL(map.colMap, code, line, _return, terrno);
SColIdNameKV colIdNameKV = {0};
colIdNameKV.colId = mr.me.colRef.pColRef[j].id;
tstrncpy(colIdNameKV.colName, mr.me.colRef.pColRef[j].refColName, sizeof(colIdNameKV.colName));
QUERY_CHECK_NULL(taosArrayPush(map.colMap, &colIdNameKV), code, line, _return, terrno);
QUERY_CHECK_CODE(taosHashPut(orgTbVgColMap, orgTbFName, sizeof(orgTbFName), &map, sizeof(map)), line, _return);
} else {
SOrgTbInfo *map = (SOrgTbInfo *)tbVgCol;
SColIdNameKV colIdNameKV = {0};
colIdNameKV.colId = mr.me.colRef.pColRef[j].id;
tstrncpy(colIdNameKV.colName, mr.me.colRef.pColRef[j].refColName, sizeof(colIdNameKV.colName));
QUERY_CHECK_NULL(taosArrayPush(map->colMap, &colIdNameKV), code, line, _return, terrno);
}
}
}
pVtbScan->vtbScanParam = NULL;
QUERY_CHECK_CODE(buildVtbScanOperatorParam(pInfo, &pVtbScan->vtbScanParam), line, _return);
((SVTableScanOperatorParam*)pVtbScan->vtbScanParam->value)->uid = *id;
void* pIter = taosHashIterate(orgTbVgColMap, NULL);
while (pIter != NULL) {
SOrgTbInfo* pMap = (SOrgTbInfo*)pIter;
SOperatorParam* pExchangeParam = NULL;
QUERY_CHECK_CODE(buildExchangeOperatorParamForVScan(&pExchangeParam, 0, pMap), line, _return);
QUERY_CHECK_NULL(taosArrayPush(((SVTableScanOperatorParam*)pVtbScan->vtbScanParam->value)->pOpParamArray, &pExchangeParam), code, line, _return, terrno);
pIter = taosHashIterate(orgTbVgColMap, pIter);
}
pHandle->api.metaReaderFn.clearReader(&mr);
pOperator->pDownstream[0]->status = OP_NOT_OPENED;
QUERY_CHECK_CODE(pOperator->pDownstream[0]->fpSet.getNextExtFn(pOperator->pDownstream[0], pVtbScan->vtbScanParam, pRes), line, _return);
}
if (*pRes) {
pVtbScan->lastTableIdx = pVtbScan->readTableIdx;
break;
} else {
pVtbScan->readTableIdx++;
if (pVtbScan->readTableIdx >= taosArrayGetSize(pVtbScan->childTableList)) {
setOperatorCompleted(pOperator);
break;
}
}
}
_return:
taosHashCleanup(orgTbVgColMap);
if (pOperator->cost.openCost == 0) {
pOperator->cost.openCost = (double)(taosGetTimestampUs() - st) / 1000.0;
}
if (code) {
qError("%s failed since %s", __func__, tstrerror(code));
pOperator->pTaskInfo->code = code;
T_LONG_JMP(pOperator->pTaskInfo->env, code);
}
return code;
}
int32_t initSeqStbJoinTableHash(SStbJoinPrevJoinCtx* pPrev, bool batchFetch) {
if (batchFetch) {
pPrev->leftHash = tSimpleHashInit(20, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT));
@ -1005,9 +1447,43 @@ int32_t initSeqStbJoinTableHash(SStbJoinPrevJoinCtx* pPrev, bool batchFetch) {
return TSDB_CODE_SUCCESS;
}
static int32_t initVtbScanInfo(SOperatorInfo* pOperator, SDynQueryCtrlOperatorInfo* pInfo, SReadHandle* pHandle,
SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t line = 0;
QUERY_CHECK_CODE(tsem_init(&pInfo->vtbScan.ready, 0, 0), line, _return);
pInfo->vtbScan.scanAllCols = pPhyciNode->vtbScan.scanAllCols;
pInfo->vtbScan.suid = pPhyciNode->vtbScan.suid;
pInfo->vtbScan.epSet = pPhyciNode->vtbScan.mgmtEpSet;
pInfo->vtbScan.acctId = pPhyciNode->vtbScan.accountId;
pInfo->vtbScan.readHandle = *pHandle;
pInfo->vtbScan.readTableIdx = 0;
pInfo->vtbScan.lastTableIdx = -1;
pInfo->vtbScan.readColList = taosArrayInit(LIST_LENGTH(pPhyciNode->vtbScan.pScanCols), sizeof(col_id_t));
QUERY_CHECK_NULL(pInfo->vtbScan.readColList, code, line, _return, terrno);
for (int32_t i = 0; i < LIST_LENGTH(pPhyciNode->vtbScan.pScanCols); ++i) {
SColumnNode* pNode = (SColumnNode*)nodesListGetNode(pPhyciNode->vtbScan.pScanCols, i);
QUERY_CHECK_NULL(pNode, code, line, _return, terrno);
QUERY_CHECK_NULL(taosArrayPush(pInfo->vtbScan.readColList, &pNode->colId), code, line, _return, terrno);
}
pInfo->vtbScan.childTableList = taosArrayInit(10, sizeof(uint64_t));
QUERY_CHECK_CODE(pHandle->api.metaFn.getChildTableList(pHandle->vnode, pInfo->vtbScan.suid, pInfo->vtbScan.childTableList), line, _return);
pInfo->vtbScan.dbVgInfoMap = taosHashInit(taosArrayGetSize(pInfo->vtbScan.childTableList), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), false, HASH_ENTRY_LOCK);
QUERY_CHECK_NULL(pInfo->vtbScan.dbVgInfoMap, code, line, _return, terrno);
_return:
return code;
}
int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numOfDownstream,
SDynQueryCtrlPhysiNode* pPhyciNode, SExecTaskInfo* pTaskInfo,
SOperatorInfo** pOptrInfo) {
SReadHandle* pHandle, SOperatorInfo** pOptrInfo) {
QRY_PARAM_CHECK(pOptrInfo);
int32_t code = TSDB_CODE_SUCCESS;
@ -1025,13 +1501,16 @@ int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numO
goto _error;
}
pTaskInfo->dynamicTask = pPhyciNode->node.dynamicOp;
pTaskInfo->dynamicTask = (int8_t)pPhyciNode->node.dynamicOp;
code = appendDownstream(pOperator, pDownstream, numOfDownstream);
if (TSDB_CODE_SUCCESS != code) {
goto _error;
}
setOperatorInfo(pOperator, "DynQueryCtrlOperator", QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL, false, OP_NOT_OPENED,
pInfo, pTaskInfo);
pInfo->qType = pPhyciNode->qType;
switch (pInfo->qType) {
case DYN_QTYPE_STB_HASH:
@ -1043,15 +1522,16 @@ int32_t createDynQueryCtrlOperatorInfo(SOperatorInfo** pDownstream, int32_t numO
}
nextFp = seqStableJoin;
break;
case DYN_QTYPE_VTB_SCAN:
QUERY_CHECK_CODE(initVtbScanInfo(pOperator, pInfo, pHandle, pPhyciNode, pTaskInfo), code, _error);
nextFp = vtbScan;
break;
default:
qError("unsupported dynamic query ctrl type: %d", pInfo->qType);
code = TSDB_CODE_INVALID_PARA;
goto _error;
}
setOperatorInfo(pOperator, "DynQueryCtrlOperator", QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL, false, OP_NOT_OPENED,
pInfo, pTaskInfo);
pOperator->fpSet = createOperatorFpSet(optrDummyOpenFn, nextFp, NULL, destroyDynQueryCtrlOperator, optrDefaultBufFn,
NULL, optrDefaultGetNextExtFn, NULL);

View File

@ -43,6 +43,9 @@ typedef struct SSourceDataInfo {
bool tableSeq;
char* decompBuf;
int32_t decompBufSize;
SOrgTbInfo* colMap;
bool isVtbRefScan;
STimeWindow window;
} SSourceDataInfo;
static void destroyExchangeOperatorInfo(void* param);
@ -112,7 +115,7 @@ static void concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeIn
// todo
SLoadRemoteDataInfo* pLoadInfo = &pExchangeInfo->loadInfo;
if (pRsp->numOfRows == 0) {
if (NULL != pDataInfo->pSrcUidList) {
if (NULL != pDataInfo->pSrcUidList && (!pDataInfo->isVtbRefScan)) {
pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
if (code != TSDB_CODE_SUCCESS) {
@ -156,7 +159,7 @@ static void concurrentlyLoadRemoteDataImpl(SOperatorInfo* pOperator, SExchangeIn
taosMemoryFreeClear(pDataInfo->pRsp);
if (pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED || NULL != pDataInfo->pSrcUidList) {
if ((pDataInfo->status != EX_SOURCE_DATA_EXHAUSTED || NULL != pDataInfo->pSrcUidList) && !pDataInfo->isVtbRefScan) {
pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
code = doSendFetchDataRequest(pExchangeInfo, pTaskInfo, i);
if (code != TSDB_CODE_SUCCESS) {
@ -603,15 +606,67 @@ int32_t buildTableScanOperatorParam(SOperatorParam** ppRes, SArray* pUidList, in
return terrno;
}
pScan->tableSeq = tableSeq;
pScan->pOrgTbInfo = NULL;
pScan->window.skey = INT64_MAX;
pScan->window.ekey = INT64_MIN;
(*ppRes)->opType = srcOpType;
(*ppRes)->downstreamIdx = 0;
(*ppRes)->value = pScan;
(*ppRes)->pChildren = NULL;
(*ppRes)->reUse = false;
return TSDB_CODE_SUCCESS;
}
int32_t buildTableScanOperatorParamEx(SOperatorParam** ppRes, SArray* pUidList, int32_t srcOpType, SOrgTbInfo *pMap, bool tableSeq, STimeWindow *window) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
STableScanOperatorParam* pScan = NULL;
*ppRes = taosMemoryMalloc(sizeof(SOperatorParam));
QUERY_CHECK_NULL(*ppRes, code, lino, _return, terrno);
pScan = taosMemoryMalloc(sizeof(STableScanOperatorParam));
QUERY_CHECK_NULL(pScan, code, lino, _return, terrno);
pScan->pUidList = taosArrayDup(pUidList, NULL);
QUERY_CHECK_NULL(pScan->pUidList, code, lino, _return, terrno);
pScan->pOrgTbInfo = taosMemoryMalloc(sizeof(SOrgTbInfo));
QUERY_CHECK_NULL(pScan->pOrgTbInfo, code, lino, _return, terrno);
pScan->pOrgTbInfo->vgId = pMap->vgId;
tstrncpy(pScan->pOrgTbInfo->tbName, pMap->tbName, TSDB_TABLE_FNAME_LEN);
pScan->pOrgTbInfo->colMap = taosArrayDup(pMap->colMap, NULL);
QUERY_CHECK_NULL(pScan->pOrgTbInfo->colMap, code, lino, _return, terrno);
pScan->tableSeq = tableSeq;
pScan->window.skey = window->skey;
pScan->window.ekey = window->ekey;
(*ppRes)->opType = srcOpType;
(*ppRes)->downstreamIdx = 0;
(*ppRes)->value = pScan;
(*ppRes)->pChildren = NULL;
(*ppRes)->reUse = false;
return code;
_return:
qError("%s failed at %d, failed to build scan operator msg:%s", __FUNCTION__, lino, tstrerror(code));
taosMemoryFreeClear(*ppRes);
if (pScan) {
taosArrayDestroy(pScan->pUidList);
if (pScan->pOrgTbInfo) {
taosArrayDestroy(pScan->pOrgTbInfo->colMap);
taosMemoryFreeClear(pScan->pOrgTbInfo);
}
taosMemoryFree(pScan);
}
return code;
}
int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInfo* pTaskInfo, int32_t sourceIndex) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
@ -654,9 +709,10 @@ int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInfo* pTas
req.taskId = pSource->taskId;
req.queryId = pTaskInfo->id.queryId;
req.execId = pSource->execId;
if (pDataInfo->pSrcUidList) {
int32_t code =
buildTableScanOperatorParam(&req.pOpParam, pDataInfo->pSrcUidList, pDataInfo->srcOpType, pDataInfo->tableSeq);
if (pDataInfo->isVtbRefScan) {
code = buildTableScanOperatorParamEx(&req.pOpParam, pDataInfo->pSrcUidList, pDataInfo->srcOpType, pDataInfo->colMap, pDataInfo->tableSeq, &pDataInfo->window);
taosArrayDestroy(pDataInfo->colMap->colMap);
taosMemoryFreeClear(pDataInfo->colMap);
taosArrayDestroy(pDataInfo->pSrcUidList);
pDataInfo->pSrcUidList = NULL;
if (TSDB_CODE_SUCCESS != code) {
@ -664,6 +720,17 @@ int32_t doSendFetchDataRequest(SExchangeInfo* pExchangeInfo, SExecTaskInfo* pTas
taosMemoryFree(pWrapper);
return pTaskInfo->code;
}
} else {
if (pDataInfo->pSrcUidList) {
code = buildTableScanOperatorParam(&req.pOpParam, pDataInfo->pSrcUidList, pDataInfo->srcOpType, pDataInfo->tableSeq);
taosArrayDestroy(pDataInfo->pSrcUidList);
pDataInfo->pSrcUidList = NULL;
if (TSDB_CODE_SUCCESS != code) {
pTaskInfo->code = code;
taosMemoryFree(pWrapper);
return pTaskInfo->code;
}
}
}
int32_t msgSize = tSerializeSResFetchReq(NULL, 0, &req);
@ -995,7 +1062,11 @@ int32_t seqLoadRemoteData(SOperatorInfo* pOperator) {
pExchangeInfo->current + 1, pDataInfo->totalRows, pLoadInfo->totalRows);
pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
pExchangeInfo->current += 1;
if (pDataInfo->isVtbRefScan) {
pExchangeInfo->current = totalSources;
} else {
pExchangeInfo->current += 1;
}
taosMemoryFreeClear(pDataInfo->pRsp);
continue;
}
@ -1014,14 +1085,20 @@ int32_t seqLoadRemoteData(SOperatorInfo* pOperator) {
pExchangeInfo->current + 1, totalSources);
pDataInfo->status = EX_SOURCE_DATA_EXHAUSTED;
pExchangeInfo->current += 1;
if (pDataInfo->isVtbRefScan) {
pExchangeInfo->current = totalSources;
} else {
pExchangeInfo->current += 1;
}
} else {
qDebug("%s fetch msg rsp from vgId:%d, clientId:0x%" PRIx64 " taskId:0x%" PRIx64 " execId:%d numOfRows:%" PRId64
", totalRows:%" PRIu64 ", totalBytes:%" PRIu64,
GET_TASKID(pTaskInfo), pSource->addr.nodeId, pSource->clientId, pSource->taskId, pSource->execId,
pRetrieveRsp->numOfRows, pLoadInfo->totalRows, pLoadInfo->totalSize);
}
if (pExchangeInfo->dynamicOp && pExchangeInfo->seqLoadData) {
taosArrayClear(pExchangeInfo->pSourceDataInfo);
}
updateLoadRemoteInfo(pLoadInfo, pRetrieveRsp->numOfRows, pRetrieveRsp->compLen, startTs, pOperator);
pDataInfo->totalRows += pRetrieveRsp->numOfRows;
@ -1034,6 +1111,15 @@ _error:
return code;
}
void clearVtbScanDataInfo(void* pItem) {
SSourceDataInfo *pInfo = (SSourceDataInfo *)pItem;
if (pInfo->colMap) {
taosArrayDestroy(pInfo->colMap->colMap);
taosMemoryFreeClear(pInfo->colMap);
}
taosArrayDestroy(pInfo->pSrcUidList);
}
int32_t addSingleExchangeSource(SOperatorInfo* pOperator, SExchangeOperatorBasicParam* pBasicParam) {
SExchangeInfo* pExchangeInfo = pOperator->info;
SExchangeSrcIndex* pIdx = tSimpleHashGet(pExchangeInfo->pHashSources, &pBasicParam->vgId, sizeof(pBasicParam->vgId));
@ -1042,40 +1128,90 @@ int32_t addSingleExchangeSource(SOperatorInfo* pOperator, SExchangeOperatorBasic
return TSDB_CODE_INVALID_PARA;
}
if (pIdx->inUseIdx < 0) {
if (pBasicParam->isVtbRefScan) {
SSourceDataInfo dataInfo = {0};
dataInfo.status = EX_SOURCE_DATA_NOT_READY;
dataInfo.taskId = pExchangeInfo->pTaskId;
dataInfo.index = pIdx->srcIdx;
dataInfo.window = pBasicParam->window;
dataInfo.colMap = taosMemoryMalloc(sizeof(SOrgTbInfo));
dataInfo.colMap->vgId = pBasicParam->colMap->vgId;
tstrncpy(dataInfo.colMap->tbName, pBasicParam->colMap->tbName, TSDB_TABLE_FNAME_LEN);
dataInfo.colMap->colMap = taosArrayDup(pBasicParam->colMap->colMap, NULL);
dataInfo.pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
if (dataInfo.pSrcUidList == NULL) {
return terrno;
}
dataInfo.isVtbRefScan = pBasicParam->isVtbRefScan;
dataInfo.srcOpType = pBasicParam->srcOpType;
dataInfo.tableSeq = pBasicParam->tableSeq;
taosArrayClearEx(pExchangeInfo->pSourceDataInfo, clearVtbScanDataInfo);
void* tmp = taosArrayPush(pExchangeInfo->pSourceDataInfo, &dataInfo);
if (!tmp) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return terrno;
}
pIdx->inUseIdx = taosArrayGetSize(pExchangeInfo->pSourceDataInfo) - 1;
} else {
SSourceDataInfo* pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, pIdx->inUseIdx);
if (!pDataInfo) {
return terrno;
}
if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
}
pDataInfo->pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
if (pDataInfo->pSrcUidList == NULL) {
return terrno;
}
if (pIdx->inUseIdx < 0) {
SSourceDataInfo dataInfo = {0};
dataInfo.status = EX_SOURCE_DATA_NOT_READY;
dataInfo.taskId = pExchangeInfo->pTaskId;
dataInfo.index = pIdx->srcIdx;
if (pBasicParam->isVtbRefScan) {
dataInfo.window = pBasicParam->window;
dataInfo.colMap = taosMemoryMalloc(sizeof(SOrgTbInfo));
dataInfo.colMap->vgId = pBasicParam->colMap->vgId;
tstrncpy(dataInfo.colMap->tbName, pBasicParam->colMap->tbName, TSDB_TABLE_FNAME_LEN);
dataInfo.colMap->colMap = taosArrayDup(pBasicParam->colMap->colMap, NULL);
}
pDataInfo->srcOpType = pBasicParam->srcOpType;
pDataInfo->tableSeq = pBasicParam->tableSeq;
dataInfo.pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
if (dataInfo.pSrcUidList == NULL) {
return terrno;
}
dataInfo.isVtbRefScan = pBasicParam->isVtbRefScan;
dataInfo.srcOpType = pBasicParam->srcOpType;
dataInfo.tableSeq = pBasicParam->tableSeq;
void* tmp = taosArrayPush(pExchangeInfo->pSourceDataInfo, &dataInfo);
if (!tmp) {
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return terrno;
}
pIdx->inUseIdx = taosArrayGetSize(pExchangeInfo->pSourceDataInfo) - 1;
} else {
SSourceDataInfo* pDataInfo = taosArrayGet(pExchangeInfo->pSourceDataInfo, pIdx->inUseIdx);
if (!pDataInfo) {
return terrno;
}
if (pDataInfo->status == EX_SOURCE_DATA_EXHAUSTED) {
pDataInfo->status = EX_SOURCE_DATA_NOT_READY;
}
if (pBasicParam->isVtbRefScan) {
pDataInfo->window = pBasicParam->window;
if (!pDataInfo->colMap) {
pDataInfo->colMap = taosMemoryMalloc(sizeof(SOrgTbInfo));
}
pDataInfo->colMap->vgId = pBasicParam->colMap->vgId;
tstrncpy(pDataInfo->colMap->tbName, pBasicParam->colMap->tbName, TSDB_TABLE_FNAME_LEN);
pDataInfo->colMap->colMap = taosArrayDup(pBasicParam->colMap->colMap, NULL);
}
pDataInfo->pSrcUidList = taosArrayDup(pBasicParam->uidList, NULL);
if (pDataInfo->pSrcUidList == NULL) {
return terrno;
}
pDataInfo->isVtbRefScan = pBasicParam->isVtbRefScan;
pDataInfo->srcOpType = pBasicParam->srcOpType;
pDataInfo->tableSeq = pBasicParam->tableSeq;
}
}
return TSDB_CODE_SUCCESS;
@ -1120,6 +1256,10 @@ int32_t prepareLoadRemoteData(SOperatorInfo* pOperator) {
QUERY_CHECK_CODE(code, lino, _end);
}
if (pOperator->status == OP_NOT_OPENED && pExchangeInfo->dynamicOp && pExchangeInfo->seqLoadData) {
pExchangeInfo->current = 0;
}
int64_t st = taosGetTimestampUs();
if (!pExchangeInfo->seqLoadData) {

View File

@ -2403,6 +2403,54 @@ int32_t initQueryTableDataCond(SQueryTableDataCond* pCond, const STableScanPhysi
return TSDB_CODE_SUCCESS;
}
int32_t initQueryTableDataCondWithColArray(SQueryTableDataCond* pCond, SQueryTableDataCond* pOrgCond,
const SReadHandle* readHandle, SArray* colArray) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
pCond->order = TSDB_ORDER_ASC;
pCond->numOfCols = (int32_t)taosArrayGetSize(colArray);
pCond->colList = taosMemoryCalloc(pCond->numOfCols, sizeof(SColumnInfo));
QUERY_CHECK_NULL(pCond->colList, code, lino, _return, terrno);
pCond->pSlotList = taosMemoryMalloc(sizeof(int32_t) * pCond->numOfCols);
QUERY_CHECK_NULL(pCond->pSlotList, code, lino, _return, terrno);
pCond->twindows = pOrgCond->twindows;
pCond->type = pOrgCond->type;
pCond->startVersion = -1;
pCond->endVersion = -1;
pCond->skipRollup = true;
pCond->notLoadData = false;
for (int32_t i = 0; i < pCond->numOfCols; ++i) {
SColIdPair* pColPair = taosArrayGet(colArray, i);
QUERY_CHECK_NULL(pColPair, code, lino, _return, terrno);
bool find = false;
for (int32_t j = 0; j < pOrgCond->numOfCols; ++j) {
if (pOrgCond->colList[j].colId == pColPair->vtbColId) {
pCond->colList[i].type = pOrgCond->colList[j].type;
pCond->colList[i].bytes = pOrgCond->colList[j].bytes;
pCond->colList[i].colId = pColPair->orgColId;
pCond->colList[i].pk = pOrgCond->colList[j].pk;
pCond->pSlotList[i] = i;
find = true;
break;
}
}
QUERY_CHECK_CONDITION(find, code, lino, _return, TSDB_CODE_NOT_FOUND);
}
return code;
_return:
qError("%s failed at line %d since %s", __func__, lino, tstrerror(terrno));
taosMemoryFreeClear(pCond->colList);
taosMemoryFreeClear(pCond->pSlotList);
return code;
}
void cleanupQueryTableDataCond(SQueryTableDataCond* pCond) {
taosMemoryFreeClear(pCond->colList);
taosMemoryFreeClear(pCond->pSlotList);
@ -2995,17 +3043,17 @@ char* getStreamOpName(uint16_t opType) {
void printDataBlock(SSDataBlock* pBlock, const char* flag, const char* taskIdStr) {
if (!pBlock) {
qDebug("%s===stream===%s: Block is Null", taskIdStr, flag);
qInfo("%s===stream===%s: Block is Null", taskIdStr, flag);
return;
} else if (pBlock->info.rows == 0) {
qDebug("%s===stream===%s: Block is Empty. block type %d", taskIdStr, flag, pBlock->info.type);
qInfo("%s===stream===%s: Block is Empty. block type %d", taskIdStr, flag, pBlock->info.type);
return;
}
if (qDebugFlag & DEBUG_DEBUG) {
char* pBuf = NULL;
int32_t code = dumpBlockData(pBlock, flag, &pBuf, taskIdStr);
if (code == 0) {
qDebug("%s", pBuf);
qInfo("%s", pBuf);
taosMemoryFree(pBuf);
}
}

View File

@ -678,7 +678,7 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId,
}
// pSinkParam has been freed during create sinker.
code = dsCreateDataSinker(pSinkManager, readHandle->localExec ? &pSink : &pSubplan->pDataSink, handle, pSinkParam, (*pTask)->id.str);
code = dsCreateDataSinker(pSinkManager, readHandle->localExec ? &pSink : &pSubplan->pDataSink, handle, pSinkParam, (*pTask)->id.str, pSubplan->processOneBlock);
if (code) {
qError("s-task:%s failed to create data sinker, code:%s", (*pTask)->id.str, tstrerror(code));
}
@ -697,7 +697,7 @@ static void freeBlock(void* param) {
blockDataDestroy(pBlock);
}
int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal) {
int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bool* hasMore, SLocalFetch* pLocal, bool processOneBlock) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
@ -792,7 +792,7 @@ int32_t qExecTaskOpt(qTaskInfo_t tinfo, SArray* pResList, uint64_t* useconds, bo
void* tmp = taosArrayPush(pResList, &p);
QUERY_CHECK_NULL(tmp, code, lino, _end, terrno);
if (current >= rowsThreshold) {
if (current >= rowsThreshold || processOneBlock) {
break;
}

View File

@ -1202,6 +1202,10 @@ void freeOperatorParamImpl(SOperatorParam* pParam, SOperatorParamType type) {
void freeExchangeGetBasicOperatorParam(void* pParam) {
SExchangeOperatorBasicParam* pBasic = (SExchangeOperatorBasicParam*)pParam;
taosArrayDestroy(pBasic->uidList);
if (pBasic->colMap) {
taosArrayDestroy(pBasic->colMap->colMap);
taosMemoryFreeClear(pBasic->colMap);
}
}
void freeExchangeGetOperatorParam(SOperatorParam* pParam) {
@ -1229,13 +1233,31 @@ void freeMergeJoinNotifyOperatorParam(SOperatorParam* pParam) { freeOperatorPara
void freeTableScanGetOperatorParam(SOperatorParam* pParam) {
STableScanOperatorParam* pTableScanParam = (STableScanOperatorParam*)pParam->value;
taosArrayDestroy(pTableScanParam->pUidList);
if (pTableScanParam->pOrgTbInfo) {
taosArrayDestroy(pTableScanParam->pOrgTbInfo->colMap);
taosMemoryFreeClear(pTableScanParam->pOrgTbInfo);
}
freeOperatorParamImpl(pParam, OP_GET_PARAM);
}
void freeTableScanNotifyOperatorParam(SOperatorParam* pParam) { freeOperatorParamImpl(pParam, OP_NOTIFY_PARAM); }
void freeOpParamItem(void* pItem) {
SOperatorParam* pParam = *(SOperatorParam**)pItem;
pParam->reUse = false;
freeOperatorParam(pParam, OP_GET_PARAM);
}
void freeVirtualTableScanGetOperatorParam(SOperatorParam* pParam) {
SVTableScanOperatorParam* pVTableScanParam = (SVTableScanOperatorParam*)pParam->value;
taosArrayDestroyEx(pVTableScanParam->pOpParamArray, freeOpParamItem);
freeOperatorParamImpl(pParam, OP_GET_PARAM);
}
void freeVTableScanNotifyOperatorParam(SOperatorParam* pParam) { freeOperatorParamImpl(pParam, OP_NOTIFY_PARAM); }
void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type) {
if (NULL == pParam) {
if (NULL == pParam || pParam->reUse) {
return;
}
@ -1252,6 +1274,9 @@ void freeOperatorParam(SOperatorParam* pParam, SOperatorParamType type) {
case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN:
type == OP_GET_PARAM ? freeTableScanGetOperatorParam(pParam) : freeTableScanNotifyOperatorParam(pParam);
break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
type == OP_GET_PARAM ? freeVirtualTableScanGetOperatorParam(pParam) : freeVTableScanNotifyOperatorParam(pParam);
break;
default:
qError("unsupported op %d param, type %d", pParam->opType, type);
break;

View File

@ -962,6 +962,7 @@ static int32_t handleGroupCacheRetrievedBlk(struct SOperatorInfo* pOperator, SSD
fakeGcParam.needCache = true;
fakeParam.downstreamIdx = pSession->downstreamIdx;
fakeParam.value = &fakeGcParam;
fakeParam.reUse = false;
code = addNewGroupData(pOperator, &fakeParam, &pGroup, GROUP_CACHE_DEFAULT_VGID, pBlock->info.id.groupId);
if (TSDB_CODE_SUCCESS != code) {
return code;

View File

@ -39,7 +39,8 @@ typedef struct SNonSortMergeInfo {
typedef struct SColsMergeInfo {
SNodeList* pTargets;
uint64_t srcBlkIds[2];
size_t sourceNum;
uint64_t* srcBlkIds;
} SColsMergeInfo;
typedef struct SMultiwayMergeOperatorInfo {
@ -437,7 +438,7 @@ int32_t doColsMerge(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
qDebug("start to merge columns, %s", GET_TASKID(pTaskInfo));
for (int32_t i = 0; i < 2; ++i) {
for (int32_t i = 0; i < pColsMerge->sourceNum; ++i) {
pBlock = getNextBlockFromDownstream(pOperator, i);
if (pBlock && pBlock->info.rows > 1) {
qError("more than 1 row returned from downstream, rows:%" PRId64, pBlock->info.rows);
@ -453,7 +454,7 @@ int32_t doColsMerge(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
}
setOperatorCompleted(pOperator);
if (2 == nullBlkNum) {
if (pColsMerge->sourceNum == nullBlkNum) {
return code;
}
@ -464,6 +465,8 @@ int32_t doColsMerge(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
}
void destroyColsMergeOperatorInfo(void* param) {
SColsMergeInfo* pColsMergeInfo = param;
taosMemoryFreeClear(pColsMergeInfo->srcBlkIds);
}
int32_t getColsMergeExplainExecInfo(SOperatorInfo* pOptr, void** pOptrExplain, uint32_t* len) {
@ -640,8 +643,11 @@ int32_t createMultiwayMergeOperatorInfo(SOperatorInfo** downStreams, size_t numS
TSDB_CHECK_CODE(code, lino, _error);
pColsMerge->pTargets = pMergePhyNode->pTargets;
pColsMerge->srcBlkIds[0] = getOperatorResultBlockId(downStreams[0], 0);
pColsMerge->srcBlkIds[1] = getOperatorResultBlockId(downStreams[1], 0);
pColsMerge->sourceNum = numStreams;
pColsMerge->srcBlkIds = taosMemoryCalloc(numStreams, sizeof(uint64_t));
for (size_t i = 0; i < numStreams; ++i) {
pColsMerge->srcBlkIds[i] = getOperatorResultBlockId(downStreams[i], 0);
}
break;
}
default:

View File

@ -512,6 +512,8 @@ int32_t createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHand
}
} else if (QUERY_NODE_PHYSICAL_PLAN_PROJECT == type) {
code = createProjectOperatorInfo(NULL, (SProjectPhysiNode*)pPhyNode, pTaskInfo, &pOperator);
} else if (QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN == type) {
code = createVirtualTableMergeOperatorInfo(NULL, pHandle, NULL, 0, (SVirtualScanPhysiNode*)pPhyNode, pTaskInfo, &pOperator);
} else {
code = TSDB_CODE_INVALID_PARA;
pTaskInfo->code = code;
@ -630,7 +632,7 @@ int32_t createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHand
} else if (QUERY_NODE_PHYSICAL_PLAN_GROUP_CACHE == type) {
code = createGroupCacheOperatorInfo(ops, size, (SGroupCachePhysiNode*)pPhyNode, pTaskInfo, &pOptr);
} else if (QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL == type) {
code = createDynQueryCtrlOperatorInfo(ops, size, (SDynQueryCtrlPhysiNode*)pPhyNode, pTaskInfo, &pOptr);
code = createDynQueryCtrlOperatorInfo(ops, size, (SDynQueryCtrlPhysiNode*)pPhyNode, pTaskInfo, pHandle, &pOptr);
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_COUNT == type) {
code = createStreamCountAggOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle, &pOptr);
} else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT == type) {
@ -651,6 +653,39 @@ int32_t createOperator(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo, SReadHand
code = createEventNonblockOperatorInfo(ops[0], pPhyNode, pTaskInfo, pHandle, &pOptr);
} else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_CONTINUE_COUNT == type) {
//todo (liuyao) add
} else if (QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN == type) {
SVirtualScanPhysiNode* pVirtualTableScanNode = (SVirtualScanPhysiNode*)pPhyNode;
// NOTE: this is an patch to fix the physical plan
if (pVirtualTableScanNode->scan.node.pLimit != NULL) {
pVirtualTableScanNode->groupSort = true;
}
STableListInfo* pTableListInfo = tableListCreate();
if (!pTableListInfo) {
pTaskInfo->code = terrno;
qError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(terrno));
return terrno;
}
code = initQueriedTableSchemaInfo(pHandle, &pVirtualTableScanNode->scan, dbname, pTaskInfo);
if (code) {
pTaskInfo->code = code;
tableListDestroy(pTableListInfo);
return code;
}
code = createScanTableListInfo(&pVirtualTableScanNode->scan, pVirtualTableScanNode->pGroupTags, pVirtualTableScanNode->groupSort,
pHandle, pTableListInfo, pTagCond, pTagIndexCond, pTaskInfo);
if (code) {
pTaskInfo->code = code;
tableListDestroy(pTableListInfo);
qError("failed to createScanTableListInfo, code:%s, %s", tstrerror(code), idstr);
return code;
}
code = createVirtualTableMergeOperatorInfo(ops, pHandle, pTableListInfo, size, (SVirtualScanPhysiNode*)pPhyNode, pTaskInfo, &pOptr);
} else {
code = TSDB_CODE_INVALID_PARA;
pTaskInfo->code = code;

View File

@ -176,7 +176,7 @@ int32_t initQueriedTableSchemaInfo(SReadHandle* pHandle, SScanPhysiNode* pScanNo
if (mr.me.type == TSDB_SUPER_TABLE) {
schemaInfo.sw = tCloneSSchemaWrapper(&mr.me.stbEntry.schemaRow);
schemaInfo.tversion = mr.me.stbEntry.schemaTag.version;
} else if (mr.me.type == TSDB_CHILD_TABLE) {
} else if (mr.me.type == TSDB_CHILD_TABLE || mr.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
tDecoderClear(&mr.coder);
tb_uid_t suid = mr.me.ctbEntry.suid;

View File

@ -332,6 +332,10 @@ bool applyLimitOffset(SLimitInfo* pLimitInfo, SSDataBlock* pBlock, SExecTaskInfo
return false;
}
static bool isDynVtbScan(SOperatorInfo* pOperator) {
return pOperator->dynamicTask && ((STableScanInfo*)(pOperator->info))->virtualStableScan;
}
static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableScanInfo, SSDataBlock* pBlock,
uint32_t* status) {
int32_t code = TSDB_CODE_SUCCESS;
@ -474,9 +478,14 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanBase* pTableSca
return code;
}
code = doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, pBlock->info.rows);
if (code) {
return code;
if ((pOperator->operatorType == QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN) && ((STableScanInfo *)pOperator->info)->ignoreTag) {
// do nothing
} else {
// dyn vtb scan do not read tag from origin tables.
code = doSetTagColumnData(pTableScanInfo, pBlock, pTaskInfo, pBlock->info.rows);
if (code) {
return code;
}
}
// restore the previous value
@ -549,7 +558,7 @@ static int32_t createTableCacheVal(const SMetaReader* pMetaReader, STableCachedV
QUERY_CHECK_NULL(pVal->pName, code, lino, _end, terrno);
// only child table has tag value
if (pMetaReader->me.type == TSDB_CHILD_TABLE) {
if (pMetaReader->me.type == TSDB_CHILD_TABLE || pMetaReader->me.type == TSDB_VIRTUAL_CHILD_TABLE) {
STag* pTag = (STag*)pMetaReader->me.ctbEntry.pTags;
pVal->pTags = taosMemoryMalloc(pTag->len);
QUERY_CHECK_NULL(pVal->pTags, code, lino, _end, terrno);
@ -1183,6 +1192,145 @@ static int32_t createTableListInfoFromParam(SOperatorInfo* pOperator) {
return code;
}
static int32_t doInitReader(STableScanInfo* pInfo, SExecTaskInfo* pTaskInfo, SStorageAPI* pAPI, int32_t* pNum,
STableKeyInfo** pList) {
const char* idStr = GET_TASKID(pTaskInfo);
int32_t code = initNextGroupScan(pInfo, pList, pNum);
if (code) {
qError("%s failed to init groupScan Info, code:%s at line:%d", idStr, tstrerror(code), __LINE__);
return code;
}
if (pInfo->base.dataReader != NULL) {
qError("%s tsdb reader should be null", idStr);
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
code = pAPI->tsdReader.tsdReaderOpen(pInfo->base.readHandle.vnode, &pInfo->base.cond, *pList, *pNum, pInfo->pResBlock,
(void**)&pInfo->base.dataReader, idStr, &pInfo->pIgnoreTables);
if (code) {
qError("%s failed to open tsdbReader, code:%s at line:%d", idStr, tstrerror(code), __LINE__);
}
return code;
}
static int32_t createVTableScanInfoFromParam(SOperatorInfo* pOperator) {
int32_t code = 0;
int32_t lino = 0;
STableScanInfo* pInfo = pOperator->info;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SStorageAPI* pAPI = &pTaskInfo->storageAPI;
STableListInfo* pListInfo = pInfo->base.pTableListInfo;
STableScanOperatorParam* pParam = (STableScanOperatorParam*)pOperator->pOperatorGetParam->value;
SMetaReader orgTable = {0};
SMetaReader superTable = {0};
SSchemaWrapper* schema = NULL;
SArray* pColArray = NULL;
SArray* pBlockColArray = NULL;
int32_t num = 0;
STableKeyInfo* pList = NULL;
cleanupQueryTableDataCond(&pInfo->base.cond);
if (pAPI->tsdReader.tsdReaderClose) {
pAPI->tsdReader.tsdReaderClose(pInfo->base.dataReader);
}
pAPI->metaReaderFn.initReader(&orgTable, pInfo->base.readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
QUERY_CHECK_CODE(pAPI->metaReaderFn.getTableEntryByName(&orgTable, strstr(pParam->pOrgTbInfo->tbName, ".") + 1), lino, _return);
switch (orgTable.me.type) {
case TSDB_CHILD_TABLE:
pAPI->metaReaderFn.initReader(&superTable, pInfo->base.readHandle.vnode, META_READER_LOCK, &pAPI->metaFn);
QUERY_CHECK_CODE(pAPI->metaReaderFn.getTableEntryByUid(&superTable, orgTable.me.ctbEntry.suid), lino, _return);
schema = &superTable.me.stbEntry.schemaRow;
break;
case TSDB_NORMAL_TABLE:
schema = &orgTable.me.ntbEntry.schemaRow;
break;
default:
qError("invalid table type:%d", orgTable.me.type);
return TSDB_CODE_INVALID_PARA;
break;
}
pColArray = taosArrayInit(schema->nCols, sizeof(SColIdPair));
QUERY_CHECK_NULL(pColArray, code, lino, _return, terrno);
pBlockColArray = taosArrayInit(schema->nCols, sizeof(int32_t));
QUERY_CHECK_NULL(pBlockColArray, code, lino, _return, terrno);
// virtual table's origin table scan do not has ts column.
SColIdPair tsPair = {.vtbColId = PRIMARYKEY_TIMESTAMP_COL_ID, .orgColId = PRIMARYKEY_TIMESTAMP_COL_ID};
QUERY_CHECK_NULL(taosArrayPush(pColArray, &tsPair), code, lino, _return, terrno);
for (int32_t i = 0; i < taosArrayGetSize(pParam->pOrgTbInfo->colMap); ++i) {
SColIdNameKV *kv = taosArrayGet(pParam->pOrgTbInfo->colMap, i);
for (int32_t j = 0; j < schema->nCols; j++) {
if (strncmp(kv->colName, schema->pSchema[j].name, strlen(schema->pSchema[j].name)) == 0) {
SColIdPair pPair = {.vtbColId = kv->colId, .orgColId = (col_id_t)(j + 1)};
QUERY_CHECK_NULL(taosArrayPush(pColArray, &pPair), code, lino, _return, terrno);
break;
}
}
}
for (int32_t i = 0; i < taosArrayGetSize(pColArray); i++) {
SColIdPair *pPair = (SColIdPair*)taosArrayGet(pColArray, i);
for (int32_t j = 0; j < taosArrayGetSize(pInfo->base.matchInfo.pList); j++) {
SColMatchItem *pItem = taosArrayGet(pInfo->base.matchInfo.pList, j);
if (pItem->colId == pPair->vtbColId) {
SColIdPair tmpPair = {.orgColId = pPair->orgColId, .vtbColId = pItem->dstSlotId};
QUERY_CHECK_NULL(taosArrayPush(pBlockColArray, &tmpPair), code, lino, _return, terrno);
break;
}
}
}
if (pInfo->pResBlock) {
blockDataDestroy(pInfo->pResBlock);
pInfo->pResBlock = NULL;
}
QUERY_CHECK_CODE(createOneDataBlockWithColArray(pInfo->pOrgBlock, pBlockColArray, &pInfo->pResBlock), lino, _return);
QUERY_CHECK_CODE(initQueryTableDataCondWithColArray(&pInfo->base.cond, &pInfo->base.orgCond, &pInfo->base.readHandle, pColArray), lino, _return);
pInfo->base.cond.twindows.skey = pParam->window.ekey + 1;
pInfo->base.cond.suid = orgTable.me.type == TSDB_CHILD_TABLE ? superTable.me.uid : 0;
pInfo->currentGroupId = 0;
pInfo->base.dataReader = NULL;
pInfo->ignoreTag = true;
pListInfo->oneTableForEachGroup = true;
taosHashClear(pListInfo->map);
taosArrayClear(pListInfo->pTableList);
uint64_t pUid = orgTable.me.uid;
STableKeyInfo info = {.groupId = 0, .uid = pUid};
int32_t tableIdx = 0;
QUERY_CHECK_CODE(taosHashPut(pListInfo->map, &pUid, sizeof(uint64_t), &tableIdx, sizeof(int32_t)), lino, _return);
QUERY_CHECK_NULL(taosArrayPush(pListInfo->pTableList, &info), code, lino, _return, terrno);
qDebug("add dynamic table scan uid:%" PRIu64 ", %s", info.uid, GET_TASKID(pTaskInfo));
pOperator->status = OP_OPENED;
taosRLockLatch(&pTaskInfo->lock);
code = doInitReader(pInfo, pTaskInfo, pAPI, &num, &pList);
taosRUnLockLatch(&pTaskInfo->lock);
QUERY_CHECK_CODE(code, lino, _return);
if (pInfo->pResBlock->info.capacity > pOperator->resultInfo.capacity) {
pOperator->resultInfo.capacity = pInfo->pResBlock->info.capacity;
}
pInfo->currentGroupId = -1;
_return:
if (code) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
taosArrayDestroy(pColArray);
taosArrayDestroy(pBlockColArray);
pAPI->metaReaderFn.clearReader(&superTable);
pAPI->metaReaderFn.clearReader(&orgTable);
return code;
}
static int32_t startNextGroupScan(SOperatorInfo* pOperator, SSDataBlock** pResult) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
@ -1239,29 +1387,6 @@ _end:
return code;
}
static int32_t doInitReader(STableScanInfo* pInfo, SExecTaskInfo* pTaskInfo, SStorageAPI* pAPI, int32_t* pNum,
STableKeyInfo** pList) {
const char* idStr = GET_TASKID(pTaskInfo);
int32_t code = initNextGroupScan(pInfo, pList, pNum);
if (code) {
qError("%s failed to init groupScan Info, code:%s at line:%d", idStr, tstrerror(code), __LINE__);
return code;
}
if (pInfo->base.dataReader != NULL) {
qError("%s tsdb reader should be null", idStr);
return TSDB_CODE_QRY_EXECUTOR_INTERNAL_ERROR;
}
code = pAPI->tsdReader.tsdReaderOpen(pInfo->base.readHandle.vnode, &pInfo->base.cond, *pList, *pNum, pInfo->pResBlock,
(void**)&pInfo->base.dataReader, idStr, &pInfo->pIgnoreTables);
if (code) {
qError("%s failed to open tsdbReader, code:%s at line:%d", idStr, tstrerror(code), __LINE__);
}
return code;
}
static int32_t groupSeqTableScan(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
@ -1336,25 +1461,49 @@ int32_t doTableScanNext(SOperatorInfo* pOperator, SSDataBlock** ppRes) {
if (pOperator->pOperatorGetParam) {
pOperator->dynamicTask = true;
code = createTableListInfoFromParam(pOperator);
freeOperatorParam(pOperator->pOperatorGetParam, OP_GET_PARAM);
pOperator->pOperatorGetParam = NULL;
QUERY_CHECK_CODE(code, lino, _end);
if (isDynVtbScan(pOperator)) {
code = createVTableScanInfoFromParam(pOperator);
freeOperatorParam(pOperator->pOperatorGetParam, OP_GET_PARAM);
pOperator->pOperatorGetParam = NULL;
QUERY_CHECK_CODE(code, lino, _end);
if (pOperator->status == OP_EXEC_DONE) {
pInfo->currentGroupId = -1;
pOperator->status = OP_OPENED;
SSDataBlock* result = NULL;
while (true) {
code = startNextGroupScan(pOperator, &result);
QUERY_CHECK_CODE(code, lino, _end);
QUERY_CHECK_CODE(startNextGroupScan(pOperator, &result), lino, _end);
if (result || pOperator->status == OP_EXEC_DONE) {
(*ppRes) = result;
SSDataBlock* res = NULL;
if (result) {
QUERY_CHECK_CODE(createOneDataBlockWithTwoBlock(result, pInfo->pOrgBlock, &res), lino, _end);
pInfo->pResBlock = res;
blockDataDestroy(result);
}
(*ppRes) = res;
return code;
}
}
} else {
code = createTableListInfoFromParam(pOperator);
freeOperatorParam(pOperator->pOperatorGetParam, OP_GET_PARAM);
pOperator->pOperatorGetParam = NULL;
QUERY_CHECK_CODE(code, lino, _end);
if (pOperator->status == OP_EXEC_DONE) {
pInfo->currentGroupId = -1;
pOperator->status = OP_OPENED;
SSDataBlock* result = NULL;
while (true) {
code = startNextGroupScan(pOperator, &result);
QUERY_CHECK_CODE(code, lino, _end);
if (result || pOperator->status == OP_EXEC_DONE) {
(*ppRes) = result;
return code;
}
}
}
}
}
@ -1440,6 +1589,7 @@ static int32_t getTableScannerExecInfo(struct SOperatorInfo* pOptr, void** pOptr
static void destroyTableScanBase(STableScanBase* pBase, TsdReader* pAPI) {
cleanupQueryTableDataCond(&pBase->cond);
cleanupQueryTableDataCond(&pBase->orgCond);
if (pAPI->tsdReaderClose) {
pAPI->tsdReaderClose(pBase->dataReader);
@ -1458,6 +1608,7 @@ static void destroyTableScanBase(STableScanBase* pBase, TsdReader* pAPI) {
static void destroyTableScanOperatorInfo(void* param) {
STableScanInfo* pTableScanInfo = (STableScanInfo*)param;
blockDataDestroy(pTableScanInfo->pResBlock);
blockDataDestroy(pTableScanInfo->pOrgBlock);
taosHashCleanup(pTableScanInfo->pIgnoreTables);
destroyTableScanBase(&pTableScanInfo->base, &pTableScanInfo->base.readerAPI);
taosMemoryFreeClear(param);
@ -1531,6 +1682,14 @@ int32_t createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHa
code = prepareDataBlockBuf(pInfo->pResBlock, &pInfo->base.matchInfo);
QUERY_CHECK_CODE(code, lino, _error);
pInfo->virtualStableScan = pScanNode->virtualStableScan;
if (pScanNode->node.dynamicOp && pScanNode->virtualStableScan) {
TSWAP(pInfo->pOrgBlock, pInfo->pResBlock);
pInfo->pResBlock = NULL;
memcpy(&pInfo->base.orgCond, &pInfo->base.cond, sizeof(SQueryTableDataCond));
memset(&pInfo->base.cond, 0, sizeof(SQueryTableDataCond));
}
code = filterInitFromNode((SNode*)pTableScanNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0);
QUERY_CHECK_CODE(code, lino, _error);
@ -1545,6 +1704,7 @@ int32_t createTableScanOperatorInfo(STableScanPhysiNode* pTableScanNode, SReadHa
pOperator->exprSupp.numOfExprs = numOfCols;
pInfo->needCountEmptyTable = tsCountAlwaysReturnValue && pTableScanNode->needCountEmptyTable;
pInfo->ignoreTag = false;
pInfo->base.pTableListInfo = pTableListInfo;
pInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5);

View File

@ -156,7 +156,7 @@ static int32_t sysTableUserTagsFillOneTableTags(const SSysTableScanInfo* pInfo,
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname, int32_t* pNumOfRows,
const SSDataBlock* dataBlock, char* tName, SSchemaWrapper* schemaRow,
char* tableType);
char* tableType, SColRefWrapper *colRef);
static void relocateAndFilterSysTagsScanResult(SSysTableScanInfo* pInfo, int32_t numOfRows, SSDataBlock* dataBlock,
SFilterInfo* pFilterInfo, SExecTaskInfo* pTaskInfo);
@ -509,15 +509,23 @@ static SSDataBlock* doOptimizeTableNameFilter(SOperatorInfo* pOperator, SSDataBl
char typeName[TSDB_TABLE_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
SSchemaWrapper* schemaRow = NULL;
SColRefWrapper* colRef = NULL;
if (smrTable.me.type == TSDB_SUPER_TABLE) {
schemaRow = &smrTable.me.stbEntry.schemaRow;
STR_TO_VARSTR(typeName, "CHILD_TABLE");
} else if (smrTable.me.type == TSDB_NORMAL_TABLE) {
schemaRow = &smrTable.me.ntbEntry.schemaRow;
STR_TO_VARSTR(typeName, "NORMAL_TABLE");
} else if (smrTable.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
schemaRow = &smrTable.me.ntbEntry.schemaRow;
colRef = &smrTable.me.colRef;
STR_TO_VARSTR(typeName, "VIRTUAL_NORMAL_TABLE");
} else if (smrTable.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
colRef = &smrTable.me.colRef;
STR_TO_VARSTR(typeName, "VIRTUAL_CHILD_TABLE");
}
code = sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, dataBlock, tableName, schemaRow, typeName);
code = sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, dataBlock, tableName, schemaRow, typeName, colRef);
if (code != TSDB_CODE_SUCCESS) {
pAPI->metaReaderFn.clearReader(&smrTable);
pInfo->loadInfo.totalRows = 0;
@ -623,6 +631,7 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
char tableName[TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE] = {0};
SSchemaWrapper* schemaRow = NULL;
SColRefWrapper* colRef = NULL;
if (pInfo->pCur->mr.me.type == TSDB_SUPER_TABLE) {
qDebug("sysTableScanUserCols cursor get super table, %s", GET_TASKID(pTaskInfo));
@ -684,6 +693,53 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
STR_TO_VARSTR(typeName, "NORMAL_TABLE");
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
} else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_NORMAL_TABLE) {
qDebug("sysTableScanUserCols cursor get virtual normal table, %s", GET_TASKID(pTaskInfo));
schemaRow = &pInfo->pCur->mr.me.ntbEntry.schemaRow;
STR_TO_VARSTR(typeName, "VIRTUAL_NORMAL_TABLE");
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
colRef = &pInfo->pCur->mr.me.colRef;
} else if (pInfo->pCur->mr.me.type == TSDB_VIRTUAL_CHILD_TABLE) {
qDebug("sysTableScanUserCols cursor get virtual child table, %s", GET_TASKID(pTaskInfo));
STR_TO_VARSTR(typeName, "VIRTUAL_CHILD_TABLE");
STR_TO_VARSTR(tableName, pInfo->pCur->mr.me.name);
colRef = &pInfo->pCur->mr.me.colRef;
int64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
void* schema = taosHashGet(pInfo->pSchema, &pInfo->pCur->mr.me.ctbEntry.suid, sizeof(int64_t));
if (schema != NULL) {
schemaRow = *(SSchemaWrapper**)schema;
} else {
SMetaReader smrSuperTable = {0};
pAPI->metaReaderFn.initReader(&smrSuperTable, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
code = pAPI->metaReaderFn.getTableEntryByUid(&smrSuperTable, suid);
if (code != TSDB_CODE_SUCCESS) {
// terrno has been set by pAPI->metaReaderFn.getTableEntryByName, therefore, return directly
qError("sysTableScanUserCols get meta by suid:%" PRId64 " error, code:%d, %s", suid, code,
GET_TASKID(pTaskInfo));
pAPI->metaReaderFn.clearReader(&smrSuperTable);
blockDataDestroy(pDataBlock);
pInfo->loadInfo.totalRows = 0;
return NULL;
}
SSchemaWrapper* schemaWrapper = tCloneSSchemaWrapper(&smrSuperTable.me.stbEntry.schemaRow);
if (smrSuperTable.me.stbEntry.schemaRow.pSchema) {
if (schemaWrapper == NULL) {
code = terrno;
lino = __LINE__;
pAPI->metaReaderFn.clearReader(&smrSuperTable);
goto _end;
}
}
code = taosHashPut(pInfo->pSchema, &suid, sizeof(int64_t), &schemaWrapper, POINTER_BYTES);
if (code == TSDB_CODE_DUP_KEY) {
code = TSDB_CODE_SUCCESS;
}
schemaRow = schemaWrapper;
pAPI->metaReaderFn.clearReader(&smrSuperTable);
QUERY_CHECK_CODE(code, lino, _end);
}
} else {
qDebug("sysTableScanUserCols cursor get invalid table, %s", GET_TASKID(pTaskInfo));
continue;
@ -699,7 +755,7 @@ static SSDataBlock* sysTableScanUserCols(SOperatorInfo* pOperator) {
}
}
// if pInfo->pRes->info.rows == 0, also need to add the meta to pDataBlock
code = sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, pDataBlock, tableName, schemaRow, typeName);
code = sysTableUserColsFillOneTableCols(pInfo, dbname, &numOfRows, pDataBlock, tableName, schemaRow, typeName, colRef);
QUERY_CHECK_CODE(code, lino, _end);
}
@ -782,7 +838,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
return NULL;
}
if (smrChildTable.me.type != TSDB_CHILD_TABLE) {
if (smrChildTable.me.type != TSDB_CHILD_TABLE && smrChildTable.me.type != TSDB_VIRTUAL_CHILD_TABLE) {
pAPI->metaReaderFn.clearReader(&smrChildTable);
blockDataDestroy(dataBlock);
pInfo->loadInfo.totalRows = 0;
@ -828,7 +884,7 @@ static SSDataBlock* sysTableScanUserTags(SOperatorInfo* pOperator) {
}
while ((ret = pAPI->metaFn.cursorNext(pInfo->pCur, TSDB_SUPER_TABLE)) == 0) {
if (pInfo->pCur->mr.me.type != TSDB_CHILD_TABLE) {
if (pInfo->pCur->mr.me.type != TSDB_CHILD_TABLE && pInfo->pCur->mr.me.type != TSDB_VIRTUAL_CHILD_TABLE) {
continue;
}
@ -1181,7 +1237,7 @@ _end:
static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo, const char* dbname, int32_t* pNumOfRows,
const SSDataBlock* dataBlock, char* tName, SSchemaWrapper* schemaRow,
char* tableType) {
char* tableType, SColRefWrapper *colRef) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
if (schemaRow == NULL) {
@ -1252,6 +1308,25 @@ static int32_t sysTableUserColsFillOneTableCols(const SSysTableScanInfo* pInfo,
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
}
// col data source
pColInfoData = taosArrayGet(dataBlock->pDataBlock, 9);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
if (!colRef || !colRef->pColRef[i].hasRef) {
colDataSetNULL(pColInfoData, numOfRows);
} else {
char refColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN + VARSTR_HEADER_SIZE] = {0};
char tmpColName[TSDB_DB_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_COL_FNAME_LEN] = {0};
strcat(tmpColName, colRef->pColRef[i].refDbName);
strcat(tmpColName, ".");
strcat(tmpColName, colRef->pColRef[i].refTableName);
strcat(tmpColName, ".");
strcat(tmpColName, colRef->pColRef[i].refColName);
STR_TO_VARSTR(refColName, tmpColName);
code = colDataSetVal(pColInfoData, numOfRows, (char *)refColName, false);
QUERY_CHECK_CODE(code, lino, _end);
}
++numOfRows;
}
@ -1560,6 +1635,104 @@ static int32_t doSetUserTableMetaInfo(SStoreMetaReader* pMetaReaderFn, SStoreMet
STR_TO_VARSTR(n, "NORMAL_TABLE");
// impl later
} else if (tableType == TSDB_VIRTUAL_NORMAL_TABLE) {
// create time
pColInfoData = taosArrayGet(p->pDataBlock, 2);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.btime, false);
QUERY_CHECK_CODE(code, lino, _end);
// number of columns
pColInfoData = taosArrayGet(p->pDataBlock, 3);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.ntbEntry.schemaRow.nCols, false);
QUERY_CHECK_CODE(code, lino, _end);
// super table name
pColInfoData = taosArrayGet(p->pDataBlock, 4);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
// table comment
pColInfoData = taosArrayGet(p->pDataBlock, 8);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
// uid
pColInfoData = taosArrayGet(p->pDataBlock, 5);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.uid, false);
QUERY_CHECK_CODE(code, lino, _end);
// ttl
pColInfoData = taosArrayGet(p->pDataBlock, 7);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
STR_TO_VARSTR(n, "VIRTUAL_NORMAL_TABLE");
// impl later
} else if (tableType == TSDB_VIRTUAL_CHILD_TABLE) {
// create time
int64_t ts = pMReader->me.ctbEntry.btime;
pColInfoData = taosArrayGet(p->pDataBlock, 2);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&ts, false);
QUERY_CHECK_CODE(code, lino, _end);
SMetaReader mr1 = {0};
pMetaReaderFn->initReader(&mr1, pVnode, META_READER_NOLOCK, pMetaFn);
int64_t suid = pMReader->me.ctbEntry.suid;
code = pMetaReaderFn->getTableEntryByUid(&mr1, suid);
if (code != TSDB_CODE_SUCCESS) {
qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pMReader->me.name, suid,
tstrerror(code), idStr);
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_CODE(code, lino, _end);
}
pColInfoData = taosArrayGet(p->pDataBlock, 3);
if (pColInfoData == NULL) {
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
}
code = colDataSetVal(pColInfoData, rowIndex, (char*)&mr1.me.stbEntry.schemaRow.nCols, false);
if (code != 0) {
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_CODE(code, lino, _end);
}
// super table name
STR_TO_VARSTR(n, mr1.me.name);
pColInfoData = taosArrayGet(p->pDataBlock, 4);
if (pColInfoData == NULL) {
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
}
code = colDataSetVal(pColInfoData, rowIndex, n, false);
pMetaReaderFn->clearReader(&mr1);
QUERY_CHECK_CODE(code, lino, _end);
// table comment
pColInfoData = taosArrayGet(p->pDataBlock, 8);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
// uid
pColInfoData = taosArrayGet(p->pDataBlock, 5);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, rowIndex, (char*)&pMReader->me.uid, false);
QUERY_CHECK_CODE(code, lino, _end);
// ttl
pColInfoData = taosArrayGet(p->pDataBlock, 7);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, rowIndex);
STR_TO_VARSTR(n, "VIRTUAL_CHILD_TABLE");
}
_end:
@ -1866,6 +2039,100 @@ static SSDataBlock* sysTableBuildUserTables(SOperatorInfo* pOperator) {
QUERY_CHECK_CODE(code, lino, _end);
STR_TO_VARSTR(n, "NORMAL_TABLE");
} else if (tableType == TSDB_VIRTUAL_NORMAL_TABLE) {
// create time
pColInfoData = taosArrayGet(p->pDataBlock, 2);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.btime, false);
QUERY_CHECK_CODE(code, lino, _end);
// number of columns
pColInfoData = taosArrayGet(p->pDataBlock, 3);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.ntbEntry.schemaRow.nCols, false);
QUERY_CHECK_CODE(code, lino, _end);
// super table name
pColInfoData = taosArrayGet(p->pDataBlock, 4);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
// table comment
pColInfoData = taosArrayGet(p->pDataBlock, 8);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
// uid
pColInfoData = taosArrayGet(p->pDataBlock, 5);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
QUERY_CHECK_CODE(code, lino, _end);
// ttl
pColInfoData = taosArrayGet(p->pDataBlock, 7);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
STR_TO_VARSTR(n, "VIRTUAL_NORMAL_TABLE");
} else if (tableType == TSDB_VIRTUAL_CHILD_TABLE) {
// create time
int64_t ts = pInfo->pCur->mr.me.ctbEntry.btime;
pColInfoData = taosArrayGet(p->pDataBlock, 2);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&ts, false);
QUERY_CHECK_CODE(code, lino, _end);
SMetaReader mr = {0};
pAPI->metaReaderFn.initReader(&mr, pInfo->readHandle.vnode, META_READER_NOLOCK, &pAPI->metaFn);
uint64_t suid = pInfo->pCur->mr.me.ctbEntry.suid;
code = pAPI->metaReaderFn.getTableEntryByUid(&mr, suid);
if (code != TSDB_CODE_SUCCESS) {
qError("failed to get super table meta, cname:%s, suid:0x%" PRIx64 ", code:%s, %s", pInfo->pCur->mr.me.name,
suid, tstrerror(terrno), GET_TASKID(pTaskInfo));
pAPI->metaReaderFn.clearReader(&mr);
pAPI->metaFn.closeTableMetaCursor(pInfo->pCur);
pInfo->pCur = NULL;
blockDataDestroy(p);
T_LONG_JMP(pTaskInfo->env, terrno);
}
if (isTsmaResSTb(mr.me.name)) {
pAPI->metaReaderFn.clearReader(&mr);
continue;
}
// number of columns
pColInfoData = taosArrayGet(p->pDataBlock, 3);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&mr.me.stbEntry.schemaRow.nCols, false);
QUERY_CHECK_CODE(code, lino, _end);
// super table name
STR_TO_VARSTR(n, mr.me.name);
pColInfoData = taosArrayGet(p->pDataBlock, 4);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, n, false);
QUERY_CHECK_CODE(code, lino, _end);
pAPI->metaReaderFn.clearReader(&mr);
// table comment
pColInfoData = taosArrayGet(p->pDataBlock, 8);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
// uid
pColInfoData = taosArrayGet(p->pDataBlock, 5);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
code = colDataSetVal(pColInfoData, numOfRows, (char*)&pInfo->pCur->mr.me.uid, false);
QUERY_CHECK_CODE(code, lino, _end);
// ttl
pColInfoData = taosArrayGet(p->pDataBlock, 7);
QUERY_CHECK_NULL(pColInfoData, code, lino, _end, terrno);
colDataSetNULL(pColInfoData, numOfRows);
STR_TO_VARSTR(n, "VIRTUAL_CHILD_TABLE");
}
pColInfoData = taosArrayGet(p->pDataBlock, 9);

View File

@ -2929,6 +2929,11 @@ void tsortGetValue(STupleHandle* pVHandle, int32_t colIndex, void** pVal) {
}
}
void tsortGetColumnInfo(STupleHandle* pVHandle, int32_t colIndex, SColumnInfoData** pColInfo) {
*pColInfo = TARRAY_GET_ELEM(pVHandle->pBlock->pDataBlock, colIndex);
}
size_t tsortGetColNum(STupleHandle* pVHandle) { return blockDataGetNumOfCols(pVHandle->pBlock); }
uint64_t tsortGetGroupId(STupleHandle* pVHandle) { return pVHandle->pBlock->info.id.groupId; }
void tsortGetBlockInfo(STupleHandle* pVHandle, SDataBlockInfo* pBlockInfo) { *pBlockInfo = pVHandle->pBlock->info; }

View File

@ -0,0 +1,761 @@
/*
* 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/>.
*/
#include "executorInt.h"
#include "filter.h"
#include "operator.h"
#include "querytask.h"
#include "tdatablock.h"
#include "virtualtablescan.h"
#include "tsort.h"
typedef struct SVirtualTableScanInfo {
STableScanBase base;
SArray* pSortInfo;
SSortHandle* pSortHandle;
int32_t bufPageSize;
uint32_t sortBufSize; // max buffer size for in-memory sort
SSDataBlock* pIntermediateBlock; // to hold the intermediate result
SSDataBlock* pInputBlock;
SHashObj* dataSlotMap;
int32_t tsSlotId;
bool scanAllCols;
SArray* pSortCtxList;
} SVirtualTableScanInfo;
typedef struct SVirtualScanMergeOperatorInfo {
SOptrBasicInfo binfo;
EMergeType type;
SVirtualTableScanInfo virtualScanInfo;
SLimitInfo limitInfo;
bool ignoreGroupId;
uint64_t groupId;
STupleHandle* pSavedTuple;
} SVirtualScanMergeOperatorInfo;
typedef struct SLoadNextCtx {
SOperatorInfo* pOperator;
SOperatorParam* pOperatorGetParam;
int32_t blockId;
STimeWindow window;
SSDataBlock* pIntermediateBlock;
col_id_t tsSlotId;
} SLoadNextCtx;
int32_t virtualScanloadNextDataBlock(void* param, SSDataBlock** ppBlock) {
SOperatorInfo* pOperator = (SOperatorInfo*)param;
int32_t code = TSDB_CODE_SUCCESS;
VTS_ERR_JRET(pOperator->fpSet.getNextFn(pOperator, ppBlock));
VTS_ERR_JRET(blockDataCheck(*ppBlock));
return code;
_return:
qError("failed to load data block from downstream, %s code:%s", __func__, tstrerror(code));
return code;
}
int32_t getTimeWindowOfBlock(SSDataBlock *pBlock, col_id_t tsSlotId, int64_t *startTs, int64_t *endTs) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
int32_t tsIndex = -1;
for (int32_t i = 0; i < taosArrayGetSize(pBlock->pDataBlock); i++) {
if (((SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i))->info.colId == tsSlotId) {
tsIndex = i;
break;
}
}
if (tsIndex == -1) {
tsIndex = (int32_t)taosArrayGetSize(pBlock->pDataBlock) - 1;
}
SColumnInfoData *pColData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, tsIndex);
QUERY_CHECK_NULL(pColData, code, lino, _return, terrno);
GET_TYPED_DATA(*startTs, int64_t, TSDB_DATA_TYPE_TIMESTAMP, colDataGetNumData(pColData, 0), 0);
GET_TYPED_DATA(*endTs, int64_t, TSDB_DATA_TYPE_TIMESTAMP, colDataGetNumData(pColData, pBlock->info.rows - 1), 0);
return code;
_return:
qError("failed to get time window of block, %s code:%s", __func__, tstrerror(code));
return code;
}
int32_t virtualScanloadNextDataBlockFromParam(void* param, SSDataBlock** ppBlock) {
SLoadNextCtx* pCtx = (SLoadNextCtx*)param;
SOperatorInfo* pOperator = pCtx->pOperator;
SOperatorParam* pOperatorGetParam = pCtx->pOperatorGetParam;
int32_t code = TSDB_CODE_SUCCESS;
SSDataBlock* pRes = NULL;
SExchangeOperatorParam* pParam = (SExchangeOperatorParam*)pOperatorGetParam->value;
pParam->basic.window = pCtx->window;
pOperator->status = OP_NOT_OPENED;
if (pCtx->pIntermediateBlock) {
blockDataDestroy(pCtx->pIntermediateBlock);
pCtx->pIntermediateBlock = NULL;
}
VTS_ERR_JRET(pOperator->fpSet.getNextExtFn(pOperator, pOperatorGetParam, &pRes));
VTS_ERR_JRET(blockDataCheck(pRes));
if ((pRes)) {
qInfo("load from downstream, blockId:%d", pCtx->blockId);
//printDataBlock(pRes, "load from downstream", "task");
(pRes)->info.id.blockId = pCtx->blockId;
getTimeWindowOfBlock(pRes, pCtx->tsSlotId, &pCtx->window.skey, &pCtx->window.ekey);
VTS_ERR_JRET(createOneDataBlock(pRes, true, &pCtx->pIntermediateBlock));
*ppBlock = pCtx->pIntermediateBlock;
} else {
pCtx->window.ekey = INT64_MAX;
*ppBlock = NULL;
}
return code;
_return:
qError("failed to load data block from downstream, %s code:%s", __func__, tstrerror(code));
return code;
}
int32_t makeTSMergeKey(SNodeList** pMergeKeys, col_id_t tsSlotId) {
int32_t code = TSDB_CODE_SUCCESS;
SNodeList *pNodeList = NULL;
SColumnNode *pColumnNode = NULL;
SOrderByExprNode *pOrderByExprNode = NULL;
VTS_ERR_JRET(nodesMakeList(&pNodeList));
VTS_ERR_JRET(nodesMakeNode(QUERY_NODE_COLUMN, (SNode**)&pColumnNode));
pColumnNode->slotId = tsSlotId;
VTS_ERR_JRET(nodesMakeNode(QUERY_NODE_ORDER_BY_EXPR, (SNode**)&pOrderByExprNode));
pOrderByExprNode->pExpr = (SNode*)pColumnNode;
pOrderByExprNode->order = ORDER_ASC;
pOrderByExprNode->nullOrder = NULL_ORDER_FIRST;
VTS_ERR_JRET(nodesListAppend(pNodeList, (SNode*)pOrderByExprNode));
*pMergeKeys = pNodeList;
return code;
_return:
nodesDestroyNode((SNode*)pColumnNode);
nodesDestroyNode((SNode*)pOrderByExprNode);
nodesDestroyList(pNodeList);
return code;
}
void cleanUpVirtualScanInfo(SVirtualTableScanInfo* pVirtualScanInfo) {
if (pVirtualScanInfo->pSortInfo) {
taosArrayDestroy(pVirtualScanInfo->pSortInfo);
pVirtualScanInfo->pSortInfo = NULL;
}
if (pVirtualScanInfo->pSortHandle) {
tsortDestroySortHandle(pVirtualScanInfo->pSortHandle);
pVirtualScanInfo->pSortHandle = NULL;
}
if (pVirtualScanInfo->pSortCtxList) {
for (int32_t i = 0; i < taosArrayGetSize(pVirtualScanInfo->pSortCtxList); i++) {
SLoadNextCtx* pCtx = *(SLoadNextCtx**)taosArrayGet(pVirtualScanInfo->pSortCtxList, i);
blockDataDestroy(pCtx->pIntermediateBlock);
taosMemoryFree(pCtx);
}
taosArrayDestroy(pVirtualScanInfo->pSortCtxList);
}
}
int32_t createSortHandleFromParam(SOperatorInfo* pOperator) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SVirtualScanMergeOperatorInfo* pInfo = pOperator->info;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
SVTableScanOperatorParam * pParam = (SVTableScanOperatorParam*)pOperator->pOperatorGetParam->value;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
pVirtualScanInfo->sortBufSize = pVirtualScanInfo->bufPageSize * (taosArrayGetSize((pParam)->pOpParamArray) + 1);
int32_t numOfBufPage = (int32_t)pVirtualScanInfo->sortBufSize / pVirtualScanInfo->bufPageSize;
SNodeList* pMergeKeys = NULL;
SSortSource* ps = NULL;
cleanUpVirtualScanInfo(pVirtualScanInfo);
VTS_ERR_JRET(makeTSMergeKey(&pMergeKeys, pVirtualScanInfo->tsSlotId));
pVirtualScanInfo->pSortInfo = createSortInfo(pMergeKeys);
TSDB_CHECK_NULL(pVirtualScanInfo->pSortInfo, code, lino, _return, terrno);
nodesDestroyList(pMergeKeys);
VTS_ERR_JRET(tsortCreateSortHandle(pVirtualScanInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pVirtualScanInfo->bufPageSize,
numOfBufPage, pVirtualScanInfo->pInputBlock, pTaskInfo->id.str, 0, 0, 0, &pVirtualScanInfo->pSortHandle));
tsortSetForceUsePQSort(pVirtualScanInfo->pSortHandle);
tsortSetFetchRawDataFp(pVirtualScanInfo->pSortHandle, virtualScanloadNextDataBlockFromParam, NULL, NULL);
pOperator->pDownstream[0]->status = OP_NOT_OPENED;
pVirtualScanInfo->pSortCtxList = taosArrayInit(taosArrayGetSize((pParam)->pOpParamArray), POINTER_BYTES);
TSDB_CHECK_NULL(pVirtualScanInfo->pSortCtxList, code, lino, _return, terrno);
for (int32_t i = 0; i < taosArrayGetSize((pParam)->pOpParamArray); i++) {
SOperatorParam* pOpParam = *(SOperatorParam**)taosArrayGet((pParam)->pOpParamArray, i);
SLoadNextCtx* pCtx = NULL;
ps = NULL;
pCtx = taosMemoryMalloc(sizeof(SLoadNextCtx));
QUERY_CHECK_NULL(pCtx, code, lino, _return, terrno);
pCtx->blockId = i;
pCtx->pOperator = pOperator->pDownstream[0];
pCtx->pOperatorGetParam = pOpParam;
pCtx->window = (STimeWindow){.skey = INT64_MAX, .ekey = INT64_MIN};
pCtx->pIntermediateBlock = NULL;
pCtx->tsSlotId = (col_id_t)pVirtualScanInfo->tsSlotId;
ps = taosMemoryCalloc(1, sizeof(SSortSource));
QUERY_CHECK_NULL(ps, code, lino, _return, terrno);
ps->param = pCtx;
ps->onlyRef = true;
VTS_ERR_JRET(tsortAddSource(pVirtualScanInfo->pSortHandle, ps));
QUERY_CHECK_NULL(taosArrayPush(pVirtualScanInfo->pSortCtxList, &pCtx), code, lino, _return, terrno);
}
VTS_ERR_JRET(tsortOpen(pVirtualScanInfo->pSortHandle));
return code;
_return:
if (code != 0){
qError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code));
}
nodesDestroyList(pMergeKeys);
if (ps != NULL) {
taosMemoryFree(ps);
}
return code;
}
int32_t createSortHandle(SOperatorInfo* pOperator) {
SVirtualScanMergeOperatorInfo * pInfo = pOperator->info;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
int32_t numOfBufPage = (int32_t)pVirtualScanInfo->sortBufSize / pVirtualScanInfo->bufPageSize;
SSortSource* ps = NULL;
int32_t code = 0;
int32_t lino = 0;
VTS_ERR_JRET(tsortCreateSortHandle(pVirtualScanInfo->pSortInfo, SORT_MULTISOURCE_MERGE, pVirtualScanInfo->bufPageSize,
numOfBufPage, pVirtualScanInfo->pInputBlock, pTaskInfo->id.str, 0, 0, 0, &pVirtualScanInfo->pSortHandle));
tsortSetForceUsePQSort(pVirtualScanInfo->pSortHandle);
tsortSetFetchRawDataFp(pVirtualScanInfo->pSortHandle, virtualScanloadNextDataBlock, NULL, NULL);
for (int32_t i = 0; i < pOperator->numOfDownstream; ++i) {
SOperatorInfo* pDownstream = pOperator->pDownstream[i];
if (pDownstream->operatorType == QUERY_NODE_PHYSICAL_PLAN_EXCHANGE) {
VTS_ERR_JRET(pDownstream->fpSet._openFn(pDownstream));
} else {
VTS_ERR_JRET(TSDB_CODE_VTABLE_SCAN_INVALID_DOWNSTREAM);
}
ps = taosMemoryCalloc(1, sizeof(SSortSource));
TSDB_CHECK_NULL(ps, code, lino, _return, terrno);
ps->param = pDownstream;
ps->onlyRef = true;
VTS_ERR_JRET(tsortAddSource(pVirtualScanInfo->pSortHandle, ps));
ps = NULL;
}
VTS_ERR_JRET(tsortOpen(pVirtualScanInfo->pSortHandle));
_return:
if (code != 0){
qError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code));
}
if (ps != NULL) {
taosMemoryFree(ps);
}
return code;
}
int32_t openVirtualTableScanOperatorImpl(SOperatorInfo* pOperator) {
SVirtualScanMergeOperatorInfo * pInfo = pOperator->info;
int32_t code = 0;
int32_t lino = 0;
if (pOperator->numOfDownstream == 0) {
return code;
}
if (pOperator->pOperatorGetParam) {
VTS_ERR_JRET(createSortHandleFromParam(pOperator));
} else {
VTS_ERR_JRET(createSortHandle(pOperator));
}
return code;
_return:
qError("%s failed at line %d with msg:%s", __func__, lino, tstrerror(code));
return code;
}
int32_t openVirtualTableScanOperator(SOperatorInfo* pOperator) {
int32_t code = 0;
if (OPTR_IS_OPENED(pOperator)) {
return TSDB_CODE_SUCCESS;
}
int64_t startTs = taosGetTimestampUs();
code = openVirtualTableScanOperatorImpl(pOperator);
pOperator->cost.openCost = (double)(taosGetTimestampUs() - startTs) / 1000.0;
pOperator->status = OP_RES_TO_RETURN;
VTS_ERR_RET(code);
OPTR_SET_OPENED(pOperator);
return code;
}
static int32_t doGetVtableMergedBlockData(SVirtualScanMergeOperatorInfo* pInfo, SSortHandle* pHandle, int32_t capacity,
SSDataBlock* p) {
int32_t code = 0;
int64_t lastTs = 0;
int64_t rowNums = -1;
blockDataEmpty(p);
while (1) {
STupleHandle* pTupleHandle = NULL;
if (!pInfo->pSavedTuple) {
code = tsortNextTuple(pHandle, &pTupleHandle);
if (pTupleHandle == NULL || (code != 0)) {
break;
}
} else {
pTupleHandle = pInfo->pSavedTuple;
pInfo->pSavedTuple = NULL;
}
SDataBlockInfo info = {0};
tsortGetBlockInfo(pTupleHandle, &info);
int32_t blockId = (int32_t)info.id.blockId;
for (int32_t i = 0; i < (pInfo->virtualScanInfo.scanAllCols ? 1 : tsortGetColNum(pTupleHandle)); i++) {
bool isNull = tsortIsNullVal(pTupleHandle, i);
if (isNull) {
colDataSetNULL(taosArrayGet(p->pDataBlock, i), rowNums);
} else {
char* pData = NULL;
tsortGetValue(pTupleHandle, i, (void**)&pData);
if (pData != NULL) {
if (i == 0) {
if (lastTs != *(int64_t*)pData) {
if (rowNums >= capacity - 1) {
pInfo->pSavedTuple = pTupleHandle;
goto _return;
}
rowNums++;
for (int32_t j = 0; j < taosArrayGetSize(p->pDataBlock); j++) {
colDataSetNULL(taosArrayGet(p->pDataBlock, j), rowNums);
}
if (pInfo->virtualScanInfo.tsSlotId != -1) {
VTS_ERR_RET(colDataSetVal(taosArrayGet(p->pDataBlock, pInfo->virtualScanInfo.tsSlotId), rowNums, pData, false));
}
lastTs = *(int64_t*)pData;
}
continue;
}
int32_t slotKey = blockId << 16 | i;
void *slotId = taosHashGet(pInfo->virtualScanInfo.dataSlotMap, &slotKey, sizeof(slotKey));
if (slotId == NULL) {
qError("failed to get slotId from dataSlotMap, blockId:%d, slotId:%d", blockId, i);
VTS_ERR_RET(TSDB_CODE_VTABLE_SCAN_INTERNAL_ERROR);
}
VTS_ERR_RET(colDataSetVal(taosArrayGet(p->pDataBlock, *(int32_t *)slotId), rowNums, pData, false));
}
}
}
}
_return:
p->info.rows = rowNums + 1;
p->info.dataLoad = 1;
p->info.scanFlag = MAIN_SCAN;
return code;
}
static int32_t doGetVStableMergedBlockData(SVirtualScanMergeOperatorInfo* pInfo, SSortHandle* pHandle, int32_t capacity,
SSDataBlock* p) {
int32_t code = 0;
int64_t lastTs = 0;
int64_t rowNums = -1;
blockDataEmpty(p);
while (1) {
STupleHandle* pTupleHandle = NULL;
if (!pInfo->pSavedTuple) {
code = tsortNextTuple(pHandle, &pTupleHandle);
if (pTupleHandle == NULL || (code != 0)) {
break;
}
} else {
pTupleHandle = pInfo->pSavedTuple;
pInfo->pSavedTuple = NULL;
}
int32_t tsIndex = -1;
for (int32_t i = 0; i < tsortGetColNum(pTupleHandle); i++) {
if (tsortIsNullVal(pTupleHandle, i)) {
continue;
} else {
SColumnInfoData *pColInfo = NULL;
tsortGetColumnInfo(pTupleHandle, i, &pColInfo);
if (pColInfo->info.slotId == pInfo->virtualScanInfo.tsSlotId) {
tsIndex = i;
break;
}
}
}
if (tsIndex == -1) {
tsIndex = (int32_t)tsortGetColNum(pTupleHandle) - 1;
}
char* pData = NULL;
// first, set ts slot's data
// then, set other slots' data
tsortGetValue(pTupleHandle, tsIndex, (void**)&pData);
if (pData != NULL) {
if (lastTs != *(int64_t*)pData) {
if (rowNums >= capacity - 1) {
pInfo->pSavedTuple = pTupleHandle;
goto _return;
}
rowNums++;
for (int32_t j = 0; j < taosArrayGetSize(p->pDataBlock); j++) {
colDataSetNULL(taosArrayGet(p->pDataBlock, j), rowNums);
}
if (pInfo->virtualScanInfo.tsSlotId != -1) {
VTS_ERR_RET(colDataSetVal(taosArrayGet(p->pDataBlock, pInfo->virtualScanInfo.tsSlotId), rowNums, pData, false));
}
lastTs = *(int64_t*)pData;
}
}
if (pInfo->virtualScanInfo.scanAllCols) {
continue;
}
for (int32_t i = 0; i < tsortGetColNum(pTupleHandle); i++) {
if (i == tsIndex || tsortIsNullVal(pTupleHandle, i)) {
continue;
}
SColumnInfoData *pColInfo = NULL;
tsortGetColumnInfo(pTupleHandle, i, &pColInfo);
tsortGetValue(pTupleHandle, i, (void**)&pData);
if (pData != NULL) {
VTS_ERR_RET(colDataSetVal(taosArrayGet(p->pDataBlock, i), rowNums, pData, false));
}
}
}
_return:
p->info.rows = rowNums + 1;
p->info.dataLoad = 1;
p->info.scanFlag = MAIN_SCAN;
return code;
}
int32_t doVirtualTableMerge(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
int32_t code = 0;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
SVirtualScanMergeOperatorInfo* pInfo = pOperator->info;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
SSortHandle* pHandle = pVirtualScanInfo->pSortHandle;
SSDataBlock* pDataBlock = pInfo->binfo.pRes;
int32_t capacity = pOperator->resultInfo.capacity;
qDebug("start to merge final sorted rows, %s", GET_TASKID(pTaskInfo));
blockDataCleanup(pDataBlock);
if (pHandle == NULL) {
return TSDB_CODE_SUCCESS;
}
if (pVirtualScanInfo->pIntermediateBlock == NULL) {
VTS_ERR_RET(tsortGetSortedDataBlock(pHandle, &pVirtualScanInfo->pIntermediateBlock));
if (pVirtualScanInfo->pIntermediateBlock == NULL) {
return TSDB_CODE_SUCCESS;
}
VTS_ERR_RET(blockDataEnsureCapacity(pVirtualScanInfo->pIntermediateBlock, capacity));
} else {
blockDataCleanup(pVirtualScanInfo->pIntermediateBlock);
}
SSDataBlock* p = pVirtualScanInfo->pIntermediateBlock;
if (pOperator->pOperatorGetParam) {
VTS_ERR_RET(doGetVStableMergedBlockData(pInfo, pHandle, capacity, p));
} else {
VTS_ERR_RET(doGetVtableMergedBlockData(pInfo, pHandle, capacity, p));
}
VTS_ERR_RET(copyDataBlock(pDataBlock, p));
qDebug("%s get sorted block, groupId:0x%" PRIx64 " rows:%" PRId64 , GET_TASKID(pTaskInfo), pDataBlock->info.id.groupId,
pDataBlock->info.rows);
*pResBlock = (pDataBlock->info.rows > 0) ? pDataBlock : NULL;
return code;
}
static int32_t doSetTagColumnData(STableScanBase * pTableScanInfo, SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo,
int32_t rows) {
int32_t code = 0;
SExprSupp* pSup = &pTableScanInfo->pseudoSup;
if (pSup->numOfExprs > 0) {
code = addTagPseudoColumnData(&pTableScanInfo->readHandle, pSup->pExprInfo, pSup->numOfExprs, pBlock, rows,
pTaskInfo, &pTableScanInfo->metaCache);
// ignore the table not exists error, since this table may have been dropped during the scan procedure.
if (code == TSDB_CODE_PAR_TABLE_NOT_EXIST) {
if (pTaskInfo->streamInfo.pState) blockDataCleanup(pBlock);
code = 0;
}
}
return code;
}
int32_t virtualTableGetNext(SOperatorInfo* pOperator, SSDataBlock** pResBlock) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SVirtualScanMergeOperatorInfo* pInfo = pOperator->info;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo;
if (pOperator->status == OP_EXEC_DONE && !pOperator->pOperatorGetParam) {
pResBlock = NULL;
return code;
}
VTS_ERR_JRET(pOperator->fpSet._openFn(pOperator));
while(1) {
VTS_ERR_JRET(doVirtualTableMerge(pOperator, pResBlock));
if (*pResBlock == NULL) {
setOperatorCompleted(pOperator);
break;
}
if (pOperator->pOperatorGetParam) {
uint64_t uid = ((SVTableScanOperatorParam*)pOperator->pOperatorGetParam->value)->uid;
STableKeyInfo* tbInfo = tableListGetInfo(pVirtualScanInfo->base.pTableListInfo, tableListFind(pVirtualScanInfo->base.pTableListInfo, uid, 0));
QUERY_CHECK_NULL(tbInfo, code, lino, _return, terrno);
(*pResBlock)->info.id.uid = tbInfo->uid;
} else {
STableKeyInfo* tbInfo = tableListGetInfo(pVirtualScanInfo->base.pTableListInfo, 0);
QUERY_CHECK_NULL(tbInfo, code, lino, _return, terrno);
(*pResBlock)->info.id.uid = tbInfo->uid;
}
VTS_ERR_JRET(doSetTagColumnData(&pVirtualScanInfo->base, (*pResBlock), pTaskInfo, (*pResBlock)->info.rows));
VTS_ERR_JRET(doFilter(*pResBlock, pOperator->exprSupp.pFilterInfo, NULL));
if ((*pResBlock)->info.rows > 0) {
break;
}
}
return code;
_return:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
pTaskInfo->code = code;
T_LONG_JMP(pTaskInfo->env, code);
}
return code;
}
static void destroyTableScanBase(STableScanBase* pBase, TsdReader* pAPI) {
cleanupQueryTableDataCond(&pBase->cond);
if (pAPI->tsdReaderClose) {
pAPI->tsdReaderClose(pBase->dataReader);
}
pBase->dataReader = NULL;
if (pBase->matchInfo.pList != NULL) {
taosArrayDestroy(pBase->matchInfo.pList);
}
tableListDestroy(pBase->pTableListInfo);
taosLRUCacheCleanup(pBase->metaCache.pTableMetaEntryCache);
cleanupExprSupp(&pBase->pseudoSup);
}
void destroyVirtualTableScanOperatorInfo(void* param) {
if (!param) {
return;
}
SVirtualScanMergeOperatorInfo* pOperatorInfo = (SVirtualScanMergeOperatorInfo*)param;
SVirtualTableScanInfo* pInfo = &pOperatorInfo->virtualScanInfo;
blockDataDestroy(pOperatorInfo->binfo.pRes);
pOperatorInfo->binfo.pRes = NULL;
tsortDestroySortHandle(pInfo->pSortHandle);
pInfo->pSortHandle = NULL;
taosArrayDestroy(pInfo->pSortInfo);
pInfo->pSortHandle = NULL;
blockDataDestroy(pInfo->pIntermediateBlock);
pInfo->pIntermediateBlock = NULL;
blockDataDestroy(pInfo->pInputBlock);
pInfo->pInputBlock = NULL;
destroyTableScanBase(&pInfo->base, &pInfo->base.readerAPI);
taosHashCleanup(pInfo->dataSlotMap);
if (pInfo->pSortCtxList) {
for (int32_t i = 0; i < taosArrayGetSize(pInfo->pSortCtxList); i++) {
SLoadNextCtx* pCtx = *(SLoadNextCtx**)taosArrayGet(pInfo->pSortCtxList, i);
blockDataDestroy(pCtx->pIntermediateBlock);
taosMemoryFree(pCtx);
}
taosArrayDestroy(pInfo->pSortCtxList);
}
taosMemoryFreeClear(param);
}
int32_t extractColMap(SNodeList* pNodeList, SHashObj** pSlotMap, int32_t *tsSlotId) {
size_t numOfCols = LIST_LENGTH(pNodeList);
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
if (numOfCols == 0) {
return code;
}
*tsSlotId = -1;
*pSlotMap = taosHashInit(numOfCols, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), false, HASH_NO_LOCK);
TSDB_CHECK_NULL(*pSlotMap, code, lino, _return, terrno);
for (int32_t i = 0; i < numOfCols; ++i) {
SColumnNode* pColNode = (SColumnNode*)nodesListGetNode(pNodeList, i);
TSDB_CHECK_NULL(pColNode, code, lino, _return, terrno);
if (pColNode->isPrimTs) {
*tsSlotId = i;
} else if (pColNode->hasRef) {
int32_t slotKey = pColNode->dataBlockId << 16 | pColNode->slotId;
VTS_ERR_JRET(taosHashPut(*pSlotMap, &slotKey, sizeof(slotKey), &i, sizeof(i)));
}
}
return code;
_return:
taosHashCleanup(*pSlotMap);
*pSlotMap = NULL;
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
return code;
}
int32_t createVirtualTableMergeOperatorInfo(SOperatorInfo** pDownstream, SReadHandle* readHandle,
STableListInfo* pTableListInfo, int32_t numOfDownstream,
SVirtualScanPhysiNode* pVirtualScanPhyNode, SExecTaskInfo* pTaskInfo,
SOperatorInfo** pOptrInfo) {
SPhysiNode* pPhyNode = (SPhysiNode*)pVirtualScanPhyNode;
int32_t lino = 0;
int32_t code = TSDB_CODE_SUCCESS;
SVirtualScanMergeOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SVirtualScanMergeOperatorInfo));
SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo));
SDataBlockDescNode* pDescNode = pPhyNode->pOutputDataBlockDesc;
SNodeList* pMergeKeys = NULL;
QUERY_CHECK_NULL(pInfo, code, lino, _return, terrno);
QUERY_CHECK_NULL(pOperator, code, lino, _return, terrno);
pInfo->binfo.inputTsOrder = pVirtualScanPhyNode->scan.node.inputTsOrder;
pInfo->binfo.outputTsOrder = pVirtualScanPhyNode->scan.node.outputTsOrder;
SVirtualTableScanInfo* pVirtualScanInfo = &pInfo->virtualScanInfo;
pInfo->binfo.pRes = createDataBlockFromDescNode(pDescNode);
TSDB_CHECK_NULL(pInfo->binfo.pRes, code, lino, _return, terrno);
SSDataBlock* pInputBlock = createDataBlockFromDescNode(pPhyNode->pOutputDataBlockDesc);
TSDB_CHECK_NULL(pInputBlock, code, lino, _return, terrno);
pVirtualScanInfo->pInputBlock = pInputBlock;
if (pVirtualScanPhyNode->scan.pScanPseudoCols != NULL) {
SExprSupp* pSup = &pVirtualScanInfo->base.pseudoSup;
pSup->pExprInfo = NULL;
VTS_ERR_JRET(createExprInfo(pVirtualScanPhyNode->scan.pScanPseudoCols, NULL, &pSup->pExprInfo, &pSup->numOfExprs));
pSup->pCtx = createSqlFunctionCtx(pSup->pExprInfo, pSup->numOfExprs, &pSup->rowEntryInfoOffset,
&pTaskInfo->storageAPI.functionStore);
TSDB_CHECK_NULL(pSup->pCtx, code, lino, _return, terrno);
}
initResultSizeInfo(&pOperator->resultInfo, 1024);
TSDB_CHECK_CODE(blockDataEnsureCapacity(pInfo->binfo.pRes, pOperator->resultInfo.capacity), lino, _return);
size_t numOfCols = taosArrayGetSize(pInfo->binfo.pRes->pDataBlock);
int32_t rowSize = pInfo->binfo.pRes->info.rowSize;
if (!pVirtualScanPhyNode->scan.node.dynamicOp) {
VTS_ERR_JRET(makeTSMergeKey(&pMergeKeys, 0));
pVirtualScanInfo->pSortInfo = createSortInfo(pMergeKeys);
TSDB_CHECK_NULL(pVirtualScanInfo->pSortInfo, code, lino, _return, terrno);
}
pVirtualScanInfo->bufPageSize = getProperSortPageSize(rowSize, numOfCols);
pVirtualScanInfo->sortBufSize =
pVirtualScanInfo->bufPageSize * (numOfDownstream + 1); // one additional is reserved for merged result.
VTS_ERR_JRET(extractColMap(pVirtualScanPhyNode->pTargets, &pVirtualScanInfo->dataSlotMap, &pVirtualScanInfo->tsSlotId));
pVirtualScanInfo->scanAllCols = pVirtualScanPhyNode->scanAllCols;
VTS_ERR_JRET(filterInitFromNode((SNode*)pVirtualScanPhyNode->scan.node.pConditions, &pOperator->exprSupp.pFilterInfo, 0));
pVirtualScanInfo->base.metaCache.pTableMetaEntryCache = taosLRUCacheInit(1024 * 128, -1, .5);
QUERY_CHECK_NULL(pVirtualScanInfo->base.metaCache.pTableMetaEntryCache, code, lino, _return, terrno);
pVirtualScanInfo->base.readHandle = *readHandle;
pVirtualScanInfo->base.pTableListInfo = pTableListInfo;
setOperatorInfo(pOperator, "VirtualTableScanOperator", QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN, false,
OP_NOT_OPENED, pInfo, pTaskInfo);
pOperator->fpSet =
createOperatorFpSet(openVirtualTableScanOperator, virtualTableGetNext, NULL, destroyVirtualTableScanOperatorInfo,
optrDefaultBufFn, NULL, optrDefaultGetNextExtFn, NULL);
if (NULL != pDownstream) {
VTS_ERR_JRET(appendDownstream(pOperator, pDownstream, numOfDownstream));
}
nodesDestroyList(pMergeKeys);
*pOptrInfo = pOperator;
return TSDB_CODE_SUCCESS;
_return:
if (code != TSDB_CODE_SUCCESS) {
qError("%s failed at line %d since %s", __func__, lino, tstrerror(code));
}
if (pInfo != NULL) {
destroyVirtualTableScanOperatorInfo(pInfo);
}
nodesDestroyList(pMergeKeys);
pTaskInfo->code = code;
destroyOperatorAndDownstreams(pOperator, pDownstream, numOfDownstream);
return code;
}

View File

@ -3146,7 +3146,7 @@ void qptExecPlan(SReadHandle* pReadHandle, SNode* pNode, SExecTaskInfo* pTaskInf
case QUERY_NODE_PHYSICAL_PLAN_QUERY_INSERT:
case QUERY_NODE_PHYSICAL_PLAN_DELETE: {
DataSinkHandle handle = NULL;
qptCtx.result.code = dsCreateDataSinker(NULL, (SDataSinkNode**)&pNode, &handle, NULL, NULL);
qptCtx.result.code = dsCreateDataSinker(NULL, (SDataSinkNode**)&pNode, &handle, NULL, NULL, false);
dsDestroyDataSinker(handle);
break;
}
@ -3176,7 +3176,7 @@ void qptExecPlan(SReadHandle* pReadHandle, SNode* pNode, SExecTaskInfo* pTaskInf
qptCtx.result.code = createGroupCacheOperatorInfo(NULL, 0, (SGroupCachePhysiNode*)pNode, pTaskInfo, ppOperaotr);
break;
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
qptCtx.result.code = createDynQueryCtrlOperatorInfo(NULL, 0, (SDynQueryCtrlPhysiNode*)pNode, pTaskInfo, ppOperaotr);
qptCtx.result.code = createDynQueryCtrlOperatorInfo(NULL, 0, (SDynQueryCtrlPhysiNode*)pNode, pTaskInfo, pReadHandle, ppOperaotr);
break;
case QUERY_NODE_PHYSICAL_PLAN_MERGE_COUNT:
qptCtx.result.code = createCountwindowOperatorInfo(NULL, (SPhysiNode*)pNode, pTaskInfo, ppOperaotr);

View File

@ -276,8 +276,6 @@ static SDataType* getSDataTypeFromNode(SNode* pNode) {
if (pNode == NULL) return NULL;
if (nodesIsExprNode(pNode)) {
return &((SExprNode*)pNode)->resType;
} else if (QUERY_NODE_COLUMN_REF == pNode->type) {
return &((SColumnRefNode*)pNode)->resType;
} else {
return NULL;
}

View File

@ -254,6 +254,13 @@ bool fmIsLastRowFunc(int32_t funcId) {
return FUNCTION_TYPE_LAST_ROW == funcMgtBuiltins[funcId].type;
}
bool fmIsLastFunc(int32_t funcId) {
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
return false;
}
return FUNCTION_TYPE_LAST == funcMgtBuiltins[funcId].type;
}
bool fmIsNotNullOutputFunc(int32_t funcId) {
if (funcId < 0 || funcId >= funcMgtBuiltinsNum) {
return false;

View File

@ -133,6 +133,11 @@ static int32_t columnNodeCopy(const SColumnNode* pSrc, SColumnNode* pDst) {
COPY_SCALAR_FIELD(numOfPKs);
COPY_SCALAR_FIELD(projRefIdx);
COPY_SCALAR_FIELD(resIdx);
COPY_SCALAR_FIELD(hasDep);
COPY_SCALAR_FIELD(hasRef);
COPY_CHAR_ARRAY_FIELD(refDbName);
COPY_CHAR_ARRAY_FIELD(refTableName);
COPY_CHAR_ARRAY_FIELD(refColName);
return TSDB_CODE_SUCCESS;
}
@ -467,6 +472,13 @@ static int32_t windowOffsetCopy(const SWindowOffsetNode* pSrc, SWindowOffsetNode
return TSDB_CODE_SUCCESS;
}
static int32_t virtualTableNodeCopy(const SVirtualTableNode * pSrc, SVirtualTableNode* pDst) {
COPY_BASE_OBJECT_FIELD(table, tableNodeCopy);
CLONE_OBJECT_FIELD(pMeta, tableMetaClone);
CLONE_OBJECT_FIELD(pVgroupList, vgroupsInfoClone);
CLONE_NODE_LIST_FIELD(refTables);
return TSDB_CODE_SUCCESS;
}
static int32_t logicNodeCopy(const SLogicNode* pSrc, SLogicNode* pDst) {
CLONE_NODE_LIST_FIELD(pTargets);
@ -530,6 +542,21 @@ static int32_t logicScanCopy(const SScanLogicNode* pSrc, SScanLogicNode* pDst) {
COPY_SCALAR_FIELD(smallDataTsSort);
COPY_SCALAR_FIELD(needSplit);
COPY_SCALAR_FIELD(noPseudoRefAfterGrp);
COPY_SCALAR_FIELD(virtualStableScan);
return TSDB_CODE_SUCCESS;
}
static int32_t logicVirtualScanCopy(const SVirtualScanLogicNode * pSrc, SVirtualScanLogicNode* pDst) {
COPY_BASE_OBJECT_FIELD(node, logicNodeCopy);
COPY_SCALAR_FIELD(scanAllCols);
CLONE_NODE_LIST_FIELD(pScanCols);
CLONE_NODE_LIST_FIELD(pScanPseudoCols);
COPY_SCALAR_FIELD(tableType);
COPY_SCALAR_FIELD(tableId);
COPY_SCALAR_FIELD(stableId);
CLONE_OBJECT_FIELD(pVgroupList, vgroupsInfoClone);
COPY_SCALAR_FIELD(scanType);
COPY_OBJECT_FIELD(tableName, sizeof(SName));
return TSDB_CODE_SUCCESS;
}
@ -744,6 +771,9 @@ static int32_t logicDynQueryCtrlCopy(const SDynQueryCtrlLogicNode* pSrc, SDynQue
CLONE_NODE_LIST_FIELD(stbJoin.pVgList);
CLONE_NODE_LIST_FIELD(stbJoin.pUidList);
COPY_OBJECT_FIELD(stbJoin.srcScan, sizeof(pDst->stbJoin.srcScan));
COPY_SCALAR_FIELD(vtbScan.scanAllCols);
COPY_SCALAR_FIELD(vtbScan.suid);
CLONE_OBJECT_FIELD(vtbScan.pVgroupList, vgroupsInfoClone);
return TSDB_CODE_SUCCESS;
}
@ -753,6 +783,7 @@ static int32_t logicSubplanCopy(const SLogicSubplan* pSrc, SLogicSubplan* pDst)
COPY_SCALAR_FIELD(subplanType);
COPY_SCALAR_FIELD(level);
COPY_SCALAR_FIELD(splitFlag);
COPY_SCALAR_FIELD(processOneBlock);
return TSDB_CODE_SUCCESS;
}
@ -779,6 +810,15 @@ static int32_t physiScanCopy(const SScanPhysiNode* pSrc, SScanPhysiNode* pDst) {
return TSDB_CODE_SUCCESS;
}
static int32_t physiVirtualTableScanCopy(const SVirtualScanPhysiNode* pSrc, SVirtualScanPhysiNode* pDst) {
COPY_BASE_OBJECT_FIELD(scan, physiScanCopy);
CLONE_NODE_LIST_FIELD(pGroupTags);
COPY_SCALAR_FIELD(groupSort);
COPY_SCALAR_FIELD(scanAllCols);
CLONE_NODE_LIST_FIELD(pTargets);
return TSDB_CODE_SUCCESS;
}
static int32_t physiTagScanCopy(const STagScanPhysiNode* pSrc, STagScanPhysiNode* pDst) {
COPY_BASE_OBJECT_FIELD(scan, physiScanCopy);
COPY_SCALAR_FIELD(onlyMetaCtbIdx);
@ -1067,6 +1107,9 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) {
case QUERY_NODE_WINDOW_OFFSET:
code = windowOffsetCopy((const SWindowOffsetNode*)pNode, (SWindowOffsetNode*)pDst);
break;
case QUERY_NODE_VIRTUAL_TABLE:
code = virtualTableNodeCopy((const SVirtualTableNode*)pNode, (SVirtualTableNode*)pDst);
break;
case QUERY_NODE_SET_OPERATOR:
code = setOperatorCopy((const SSetOperator*)pNode, (SSetOperator*)pDst);
break;
@ -1121,6 +1164,9 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) {
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
code = logicDynQueryCtrlCopy((const SDynQueryCtrlLogicNode*)pNode, (SDynQueryCtrlLogicNode*)pDst);
break;
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
code = logicVirtualScanCopy((const SVirtualScanLogicNode *)pNode, (SVirtualScanLogicNode*)pDst);
break;
case QUERY_NODE_LOGIC_SUBPLAN:
code = logicSubplanCopy((const SLogicSubplan*)pNode, (SLogicSubplan*)pDst);
break;
@ -1156,6 +1202,9 @@ int32_t nodesCloneNode(const SNode* pNode, SNode** ppNode) {
case QUERY_NODE_PHYSICAL_PLAN_STREAM_PARTITION:
code = physiPartitionCopy((const SPartitionPhysiNode*)pNode, (SPartitionPhysiNode*)pDst);
break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
code = physiVirtualTableScanCopy((const SVirtualScanPhysiNode*)pNode, (SVirtualScanPhysiNode*)pDst);
break;
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
code = physiProjectCopy((const SProjectPhysiNode*)pNode, (SProjectPhysiNode*)pDst);
break;

View File

@ -41,6 +41,8 @@ const char* nodesNodeName(ENodeType type) {
return "Function";
case QUERY_NODE_REAL_TABLE:
return "RealTable";
case QUERY_NODE_VIRTUAL_TABLE:
return "VirtualTable";
case QUERY_NODE_TEMP_TABLE:
return "TempTable";
case QUERY_NODE_JOIN_TABLE:
@ -87,6 +89,8 @@ const char* nodesNodeName(ENodeType type) {
return "StreamOptions";
case QUERY_NODE_LEFT_VALUE:
return "LeftValue";
case QUERY_NODE_COLUMN_REF:
return "ColumnReference";
case QUERY_NODE_WHEN_THEN:
return "WhenThen";
case QUERY_NODE_CASE_WHEN:
@ -123,6 +127,10 @@ const char* nodesNodeName(ENodeType type) {
return "CreateTableStmt";
case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
return "CreateSubtableClause";
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return "CreateVirtualtableStmt";
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return "CreateVirtualsubtableStmt";
case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return "CreateMultiTableStmt";
case QUERY_NODE_DROP_TABLE_CLAUSE:
@ -131,10 +139,14 @@ const char* nodesNodeName(ENodeType type) {
return "DropTableStmt";
case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return "DropSuperTableStmt";
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return "DropVirtualTableStmt";
case QUERY_NODE_ALTER_TABLE_STMT:
return "AlterTableStmt";
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
return "AlterSuperTableStmt";
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
return "AlterVirtualTableStmt";
case QUERY_NODE_CREATE_USER_STMT:
return "CreateUserStmt";
case QUERY_NODE_ALTER_USER_STMT:
@ -202,7 +214,6 @@ const char* nodesNodeName(ENodeType type) {
case QUERY_NODE_ASSIGN_LEADER_STMT:
return "AssignLeaderStmt";
case QUERY_NODE_BALANCE_VGROUP_LEADER_STMT:
return "BalanceVgroupLeaderStmt";
case QUERY_NODE_BALANCE_VGROUP_LEADER_DATABASE_STMT:
return "BalanceVgroupLeaderStmt";
case QUERY_NODE_MERGE_VGROUP_STMT:
@ -253,6 +264,8 @@ const char* nodesNodeName(ENodeType type) {
return "ShowStreamsStmt";
case QUERY_NODE_SHOW_TABLES_STMT:
return "ShowTablesStmt";
case QUERY_NODE_SHOW_VTABLES_STMT:
return "ShowVtablesStmt";
case QUERY_NODE_SHOW_TAGS_STMT:
return "ShowTagsStmt";
case QUERY_NODE_SHOW_USERS_STMT:
@ -284,6 +297,8 @@ const char* nodesNodeName(ENodeType type) {
return "ShowCreateDatabasesStmt";
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
return "ShowCreateTablesStmt";
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
return "ShowCreateVtablesstmt";
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return "ShowCreateStablesStmt";
case QUERY_NODE_SHOW_CREATE_VIEW_STMT:
@ -358,6 +373,8 @@ const char* nodesNodeName(ENodeType type) {
return "LogicGroupCache";
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
return "LogicDynamicQueryCtrl";
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
return "LogicVirtualTableScan";
case QUERY_NODE_LOGIC_SUBPLAN:
return "LogicSubplan";
case QUERY_NODE_LOGIC_PLAN:
@ -465,6 +482,8 @@ const char* nodesNodeName(ENodeType type) {
return "PhysiGroupCache";
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
return "PhysiDynamicQueryCtrl";
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
return "PhysiVirtualTableScan";
case QUERY_NODE_PHYSICAL_SUBPLAN:
return "PhysiSubplan";
case QUERY_NODE_PHYSICAL_PLAN:
@ -1867,6 +1886,72 @@ static int32_t jsonToLogicJoinNode(const SJson* pJson, void* pObj) {
return code;
}
static const char* jkVirtualTableScanLogicPlanScanCols = "ScanCols";
static const char* jkVirtualTableScanLogicPlanScanPseudoCols = "ScanPseudoCols";
static const char* jkVirtualTableScanLogicPlanTableType = "TableType";
static const char* jkVirtualTableScanLogicPlanTableId = "TableId";
static const char* jkVirtualTableScanLogicPlanStableId = "StableId";
static const char* jkVirtualTableScanLogicPlanScanType = "ScanType";
static const char* jkVirtualTableScanLogicPlanscanAllCols = "scanAllCols";
static int32_t logicVirtualTableScanNodeToJson(const void* pObj, SJson* pJson) {
const SVirtualScanLogicNode* pNode = (const SVirtualScanLogicNode*)pObj;
int32_t code = logicPlanNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkVirtualTableScanLogicPlanscanAllCols, pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtualTableScanLogicPlanScanCols, pNode->pScanCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtualTableScanLogicPlanScanPseudoCols, pNode->pScanPseudoCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableScanLogicPlanTableType, pNode->tableType);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableScanLogicPlanTableId, pNode->tableId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableScanLogicPlanStableId, pNode->stableId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableScanLogicPlanScanType, pNode->scanType);
}
return code;
}
static int32_t jsonToLogicVirtualTableScanNode(const SJson* pJson, void* pObj) {
SVirtualScanLogicNode* pNode = (SVirtualScanLogicNode *)pObj;
int32_t objSize = 0;
int32_t code = jsonToLogicPlanNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkVirtualTableScanLogicPlanscanAllCols, &pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtualTableScanLogicPlanScanCols, &pNode->pScanCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtualTableScanLogicPlanScanPseudoCols, &pNode->pScanPseudoCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetTinyIntValue(pJson, jkVirtualTableScanLogicPlanTableType, &pNode->tableType);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUBigIntValue(pJson, jkVirtualTableScanLogicPlanTableId, &pNode->tableId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetUBigIntValue(pJson, jkVirtualTableScanLogicPlanStableId, &pNode->stableId);
}
if (TSDB_CODE_SUCCESS == code) {
tjsonGetNumberValue(pJson, jkVirtualTableScanLogicPlanScanType, pNode->scanType, code);
}
return code;
}
static const char* jkPhysiPlanOutputDataBlockDesc = "OutputDataBlockDesc";
static const char* jkPhysiPlanConditions = "Conditions";
static const char* jkPhysiPlanChildren = "Children";
@ -2326,6 +2411,54 @@ static int32_t jsonToPhysiTableScanNode(const SJson* pJson, void* pObj) {
}
return code;
}
static const char* jkVirtualTableScanPhysiPlanGroupTags = "GroupTags";
static const char* jkVirtualTableScanPhysiPlanGroupSort = "GroupSort";
static const char* jkVirtualTableScanPhysiPlanscanAllCols= "scanAllCols";
static const char* jkVirtualTableScanPhysiPlanTargets = "Targets";
static int32_t physiVirtualTableScanNodeToJson(const void* pObj, SJson* pJson) {
const SVirtualScanPhysiNode* pNode = (const SVirtualScanPhysiNode*)pObj;
int32_t code = physiScanNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtualTableScanPhysiPlanTargets, pNode->pGroupTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkVirtualTableScanPhysiPlanTargets, pNode->groupSort);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkVirtualTableScanPhysiPlanscanAllCols, pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtualTableScanPhysiPlanTargets, pNode->pTargets);
}
return code;
}
static int32_t jsonToPhysiVirtualTableScanNode(const SJson* pJson, void* pObj) {
SVirtualScanPhysiNode* pNode = (SVirtualScanPhysiNode*)pObj;
int32_t code = jsonToPhysicPlanNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtualTableScanPhysiPlanGroupTags, &pNode->pGroupTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkVirtualTableScanPhysiPlanGroupSort, &pNode->groupSort);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkVirtualTableScanPhysiPlanscanAllCols, &pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtualTableScanPhysiPlanTargets, &pNode->pTargets);
}
return code;
}
static const char* jkSysTableScanPhysiPlanMnodeEpSet = "MnodeEpSet";
static const char* jkSysTableScanPhysiPlanShowRewrite = "ShowRewrite";
@ -4965,6 +5098,61 @@ static int32_t jsonToJoinTableNode(const SJson* pJson, void* pObj) {
return code;
}
static const char* jkVirtualTableMetaSize = "MetaSize";
static const char* jkVirtuaTableMeta = "Meta";
static const char* jkVirtuaTableVgroupsInfoSize = "VgroupsInfoSize";
static const char* jkVirtuaTableVgroupsInfo = "VgroupsInfo";
static const char* jkVirtuaTableRefTables = "RefTables";
static int32_t virtualTableNodeToJson(const void* pObj, SJson* pJson) {
const SVirtualTableNode* pNode = (const SVirtualTableNode*)pObj;
int32_t code = tableNodeToJson(pObj, pJson);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtualTableMetaSize, TABLE_META_SIZE(pNode->pMeta));
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkVirtuaTableMeta, tableMetaToJson, pNode->pMeta);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddIntegerToObject(pJson, jkVirtuaTableVgroupsInfoSize, VGROUPS_INFO_SIZE(pNode->pVgroupList));
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddObject(pJson, jkVirtuaTableVgroupsInfo, vgroupsInfoToJson, pNode->pVgroupList);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkVirtuaTableRefTables, pNode->refTables);
}
return code;
}
static int32_t jsonToVirtualTableNode(const SJson* pJson, void* pObj) {
SVirtualTableNode* pNode = (SVirtualTableNode*)pObj;
int32_t objSize = 0;
int32_t code = jsonToTableNode(pJson, pObj);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkVirtualTableMetaSize, &objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonMakeObject(pJson, jkVirtuaTableMeta, jsonToTableMeta, (void**)&pNode->pMeta, objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetIntValue(pJson, jkVirtuaTableVgroupsInfoSize, &objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonMakeObject(pJson, jkVirtuaTableVgroupsInfo, jsonToVgroupsInfo, (void**)&pNode->pVgroupList, objSize);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkVirtuaTableRefTables, &pNode->refTables);
}
return code;
}
static const char* jkGroupingSetType = "GroupingSetType";
static const char* jkGroupingSetParameter = "Parameters";
@ -5961,6 +6149,42 @@ static int32_t jsonToStreamNotifyOptions(const SJson* pJson, void* pObj) {
if (code == TSDB_CODE_SUCCESS) {
code = tjsonGetBoolValue(pJson, jkStreamNotifyOptionsNotifyHistory, &pNotifyOption->notifyHistory);
}
return code;
}
static const char* jkColumnReferenceColumnName = "ColumnName";
static const char* jkColumnReferenceRefDbName = "RefDbName";
static const char* jkColumnReferenceRefTableName = "RefTableName";
static const char* jkColumnReferenceRefColumnName = "RefColumnName";
static int32_t columnReferenceToJson(const void* pObj, SJson* pJson) {
const SColumnRefNode* pNode = (const SColumnRefNode*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkColumnReferenceColumnName, pNode->colName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkColumnReferenceRefDbName, pNode->refDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkColumnReferenceRefTableName, pNode->refTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkColumnReferenceRefColumnName, pNode->refColName);
}
return code;
}
static int32_t jsonToColumnReference(const SJson* pJson, void* pObj) {
SColumnRefNode* pNode = (SColumnRefNode*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkColumnReferenceColumnName, pNode->colName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkColumnReferenceRefDbName, pNode->refDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkColumnReferenceRefTableName, pNode->refTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkColumnReferenceRefColumnName, pNode->refColName);
}
return code;
}
@ -6542,6 +6766,117 @@ static int32_t jsonToCreateMultiTablesStmt(const SJson* pJson, void* pObj) {
return jsonToNodeList(pJson, jkCreateMultiTablesStmtSubTables, &pNode->pSubTables);
}
static const char* jkCreateVTableStmtDbName = "DbName";
static const char* jkCreateVTableStmtTableName = "TableName";
static const char* jkCreateVTableStmtIgnoreExists = "IgnoreExists";
static const char* jkCreateVTableStmtCols = "Cols";
static int32_t createVTableStmtToJson(const void* pObj, SJson* pJson) {
const SCreateVTableStmt* pNode = (const SCreateVTableStmt*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkCreateVTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkCreateVTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkCreateVTableStmtIgnoreExists, pNode->ignoreExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVTableStmtCols, pNode->pCols);
}
return code;
}
static int32_t jsonToCreateVTableStmt(const SJson* pJson, void* pObj) {
SCreateVTableStmt* pNode = (SCreateVTableStmt*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkCreateTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkCreateTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkCreateTableStmtIgnoreExists, &pNode->ignoreExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateTableStmtCols, &pNode->pCols);
}
return code;
}
static const char* jkCreateVSubTableStmtDbName = "DbName";
static const char* jkCreateVSubTableStmtTableName = "TableName";
static const char* jkCreateVSubTableStmtUseDbName = "UseDbName";
static const char* jkCreateVSubTableStmtUseTableName = "UseTableName";
static const char* jkCreateVSubTableStmtIgnoreExists = "IgnoreExists";
static const char* jkCreateVSubTableStmtSpecificTags = "SpecificTags";
static const char* jkCreateVSubTableStmtValsOfTags = "ValsOfTags";
static const char* jkCreateVSubTableStmtSpecificColRefs = "SpecificColRefs";
static const char* jkCreateVSubTableStmtValsOfColRefs = "ValsOfColRefs";
static int32_t createVSubTableStmtToJson(const void* pObj, SJson* pJson) {
const SCreateVSubTableStmt* pNode = (const SCreateVSubTableStmt*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkCreateVSubTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkCreateVSubTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkCreateVSubTableStmtUseDbName, pNode->useDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkCreateVSubTableStmtUseTableName, pNode->useTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkCreateVSubTableStmtIgnoreExists, pNode->ignoreExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVSubTableStmtSpecificTags, pNode->pSpecificTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVSubTableStmtValsOfTags, pNode->pValsOfTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVSubTableStmtSpecificColRefs, pNode->pSpecificColRefs);
}
if (TSDB_CODE_SUCCESS == code) {
code = nodeListToJson(pJson, jkCreateVSubTableStmtValsOfColRefs, pNode->pColRefs);
}
return code;
}
static int32_t jsonToCreateVSubTableStmt(const SJson* pJson, void* pObj) {
SCreateVSubTableStmt* pNode = (SCreateVSubTableStmt*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkCreateVSubTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkCreateVSubTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkCreateVSubTableStmtUseDbName, pNode->useDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkCreateVSubTableStmtUseTableName, pNode->useTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkCreateVSubTableStmtIgnoreExists, &pNode->ignoreExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateVSubTableStmtSpecificTags, &pNode->pSpecificTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateVSubTableStmtValsOfTags, &pNode->pValsOfTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateVSubTableStmtSpecificColRefs, &pNode->pSpecificColRefs);
}
if (TSDB_CODE_SUCCESS == code) {
code = jsonToNodeList(pJson, jkCreateVSubTableStmtValsOfColRefs, &pNode->pColRefs);
}
return code;
}
static const char* jkDropTableClauseDbName = "DbName";
static const char* jkDropTableClauseTableName = "TableName";
static const char* jkDropTableClauseIgnoreNotExists = "IgnoreNotExists";
@ -6625,6 +6960,45 @@ static int32_t jsonToDropStableStmt(const SJson* pJson, void* pObj) {
return code;
}
static const char* jkDropVirtualTableStmtDbName = "DbName";
static const char* jkDropVirtualTableStmtTableName = "TableName";
static const char* jkDropVirtualTableStmtIgnoreNotExists = "IgnoreNotExists";
static const char* jkDropVirtualTableStmtwithOpt = "withOpt";
static int32_t dropVtableStmtToJson(const void* pObj, SJson* pJson) {
const SDropVirtualTableStmt* pNode = (const SDropVirtualTableStmt*)pObj;
int32_t code = tjsonAddStringToObject(pJson, jkDropVirtualTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddStringToObject(pJson, jkDropVirtualTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkDropVirtualTableStmtIgnoreNotExists, pNode->ignoreNotExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonAddBoolToObject(pJson, jkDropVirtualTableStmtwithOpt, pNode->withOpt);
}
return code;
}
static int32_t jsonToDropVtableStmt(const SJson* pJson, void* pObj) {
SDropVirtualTableStmt* pNode = (SDropVirtualTableStmt*)pObj;
int32_t code = tjsonGetStringValue(pJson, jkDropSuperTableStmtDbName, pNode->dbName);
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetStringValue(pJson, jkDropVirtualTableStmtTableName, pNode->tableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkDropVirtualTableStmtIgnoreNotExists, &pNode->ignoreNotExists);
}
if (TSDB_CODE_SUCCESS == code) {
code = tjsonGetBoolValue(pJson, jkDropVirtualTableStmtwithOpt, &pNode->withOpt);
}
return code;
}
static const char* jkAlterTableStmtDbName = "DbName";
static const char* jkAlterTableStmtTableName = "TableName";
static const char* jkAlterTableStmtAlterType = "AlterType";
@ -8134,6 +8508,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return tempTableNodeToJson(pObj, pJson);
case QUERY_NODE_JOIN_TABLE:
return joinTableNodeToJson(pObj, pJson);
case QUERY_NODE_VIRTUAL_TABLE:
return virtualTableNodeToJson(pObj, pJson);
case QUERY_NODE_GROUPING_SET:
return groupingSetNodeToJson(pObj, pJson);
case QUERY_NODE_ORDER_BY_EXPR:
@ -8176,6 +8552,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return streamOptionsToJson(pObj, pJson);
case QUERY_NODE_LEFT_VALUE:
return TSDB_CODE_SUCCESS; // SLeftValueNode has no fields to serialize.
case QUERY_NODE_COLUMN_REF:
return columnReferenceToJson(pObj, pJson);
case QUERY_NODE_WHEN_THEN:
return whenThenNodeToJson(pObj, pJson);
case QUERY_NODE_CASE_WHEN:
@ -8208,6 +8586,10 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return createTableStmtToJson(pObj, pJson);
case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
return createSubTableClauseToJson(pObj, pJson);
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return createVTableStmtToJson(pObj, pJson);
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return createVSubTableStmtToJson(pObj, pJson);
case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return createMultiTablesStmtToJson(pObj, pJson);
case QUERY_NODE_DROP_TABLE_CLAUSE:
@ -8216,6 +8598,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return dropTableStmtToJson(pObj, pJson);
case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return dropStableStmtToJson(pObj, pJson);
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return dropVtableStmtToJson(pObj, pJson);
case QUERY_NODE_ALTER_TABLE_STMT:
return alterTableStmtToJson(pObj, pJson);
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
@ -8321,6 +8705,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_SHOW_STREAMS_STMT:
return showStreamsStmtToJson(pObj, pJson);
case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
return showTablesStmtToJson(pObj, pJson);
case QUERY_NODE_SHOW_TAGS_STMT:
return showTagsStmtToJson(pObj, pJson);
@ -8354,6 +8739,7 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
return showCreateDatabaseStmtToJson(pObj, pJson);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
return showCreateTableStmtToJson(pObj, pJson);
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return showCreateStableStmtToJson(pObj, pJson);
@ -8375,6 +8761,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
return logicScanNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_JOIN:
return logicJoinNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
return logicVirtualTableScanNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_AGG:
return logicAggNodeToJson(pObj, pJson);
case QUERY_NODE_LOGIC_PLAN_PROJECT:
@ -8418,6 +8806,8 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) {
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
return physiTableScanNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
return physiVirtualTableScanNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
return physiSysTableScanNodeToJson(pObj, pJson);
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:
@ -8522,6 +8912,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToTempTableNode(pJson, pObj);
case QUERY_NODE_JOIN_TABLE:
return jsonToJoinTableNode(pJson, pObj);
case QUERY_NODE_VIRTUAL_TABLE:
return jsonToVirtualTableNode(pJson, pObj);
case QUERY_NODE_GROUPING_SET:
return jsonToGroupingSetNode(pJson, pObj);
case QUERY_NODE_ORDER_BY_EXPR:
@ -8562,6 +8954,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToStreamOptions(pJson, pObj);
case QUERY_NODE_LEFT_VALUE:
return TSDB_CODE_SUCCESS; // SLeftValueNode has no fields to deserialize.
case QUERY_NODE_COLUMN_REF:
return jsonToColumnReference(pJson, pObj);
case QUERY_NODE_WHEN_THEN:
return jsonToWhenThenNode(pJson, pObj);
case QUERY_NODE_CASE_WHEN:
@ -8594,6 +8988,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToCreateTableStmt(pJson, pObj);
case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
return jsonToCreateSubTableClause(pJson, pObj);
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return jsonToCreateVTableStmt(pJson, pObj);
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return jsonToCreateVSubTableStmt(pJson, pObj);
case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return jsonToCreateMultiTablesStmt(pJson, pObj);
case QUERY_NODE_DROP_TABLE_CLAUSE:
@ -8602,6 +9000,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToDropTableStmt(pJson, pObj);
case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return jsonToDropStableStmt(pJson, pObj);
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return jsonToDropVtableStmt(pJson, pObj);
case QUERY_NODE_ALTER_TABLE_STMT:
return jsonToAlterTableStmt(pJson, pObj);
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
@ -8701,6 +9101,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
case QUERY_NODE_SHOW_STREAMS_STMT:
return jsonToShowStreamsStmt(pJson, pObj);
case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
return jsonToShowTablesStmt(pJson, pObj);
case QUERY_NODE_SHOW_TAGS_STMT:
return jsonToShowTagsStmt(pJson, pObj);
@ -8734,6 +9135,7 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
return jsonToShowCreateDatabaseStmt(pJson, pObj);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
return jsonToShowCreateTableStmt(pJson, pObj);
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return jsonToShowCreateStableStmt(pJson, pObj);
@ -8763,6 +9165,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
return jsonToLogicScanNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_JOIN:
return jsonToLogicJoinNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
return jsonToLogicVirtualTableScanNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_AGG:
return jsonToLogicAggNode(pJson, pObj);
case QUERY_NODE_LOGIC_PLAN_PROJECT:
@ -8806,6 +9210,8 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) {
case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN:
return jsonToPhysiTableScanNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
return jsonToPhysiVirtualTableScanNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN:
return jsonToPhysiSysTableScanNode(pJson, pObj);
case QUERY_NODE_PHYSICAL_PLAN_PROJECT:

View File

@ -200,6 +200,7 @@ bool nodesEqualNode(const SNode* a, const SNode* b) {
case QUERY_NODE_GROUPING_SET:
return groupingSetNodeEqual((const SGroupingSetNode*)a, (const SGroupingSetNode*)b);
case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_VIRTUAL_TABLE:
case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_JOIN_TABLE:
case QUERY_NODE_ORDER_BY_EXPR:

View File

@ -168,6 +168,7 @@ bool nodesMatchNode(const SNode* pSub, const SNode* p) {
case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_JOIN_TABLE:
case QUERY_NODE_VIRTUAL_TABLE:
case QUERY_NODE_GROUPING_SET:
case QUERY_NODE_ORDER_BY_EXPR:
case QUERY_NODE_LIMIT:

View File

@ -757,7 +757,25 @@ static int32_t columnNodeInlineToMsg(const void* pObj, STlvEncoder* pEncoder) {
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueI16(pEncoder, pNode->numOfPKs);
}
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->isPrimTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->hasDep);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->hasRef);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueCStr(pEncoder, pNode->refDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueCStr(pEncoder, pNode->refTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueCStr(pEncoder, pNode->refColName);
}
return code;
}
@ -813,7 +831,25 @@ static int32_t msgToColumnNodeInline(STlvDecoder* pDecoder, void* pObj) {
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueI16(pDecoder, &pNode->numOfPKs);
}
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->isPrimTs);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->hasDep);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->hasRef);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueCStr(pDecoder, pNode->refDbName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueCStr(pDecoder, pNode->refTableName);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueCStr(pDecoder, pNode->refColName);
}
return code;
}
@ -2088,7 +2124,8 @@ enum {
PHY_SCAN_CODE_BASE_SUID,
PHY_SCAN_CODE_BASE_TABLE_TYPE,
PHY_SCAN_CODE_BASE_TABLE_NAME,
PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN
PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN,
PHY_SCAN_CODE_BASE_VIRTUAL_STABLE_SCAN
};
static int32_t physiScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
@ -2116,6 +2153,9 @@ static int32_t physiScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeBool(pEncoder, PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN, pNode->groupOrderScan);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeBool(pEncoder, PHY_SCAN_CODE_BASE_VIRTUAL_STABLE_SCAN, pNode->virtualStableScan);
}
return code;
}
@ -2151,6 +2191,69 @@ static int32_t msgToPhysiScanNode(STlvDecoder* pDecoder, void* pObj) {
case PHY_SCAN_CODE_BASE_GROUP_ORDER_SCAN:
code = tlvDecodeBool(pTlv, &pNode->groupOrderScan);
break;
case PHY_SCAN_CODE_BASE_VIRTUAL_STABLE_SCAN:
code = tlvDecodeBool(pTlv, &pNode->virtualStableScan);
default:
break;
}
}
return code;
}
enum {
PHY_VIRTUAL_TABLE_SCAN_CODE_SCAN = 1,
PHY_VIRTUAL_TABLE_SCAN_CODE_GROUPTAGS,
PHY_VIRTUAL_TABLE_SCAN_CODE_GROUP_SORT,
PHY_VIRTUAL_TABLE_SCAN_CODE_ONLY_TS,
PHY_VIRTUAL_TABLE_SCAN_CODE_TARGETS,
};
static int32_t physiVirtualTableScanNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
const SVirtualScanPhysiNode* pNode = (const SVirtualScanPhysiNode *)pObj;
int32_t code = tlvEncodeObj(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_SCAN, physiScanNodeToMsg, &pNode->scan);
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_GROUPTAGS, nodeListToMsg, pNode->pGroupTags);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeBool(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_GROUP_SORT, pNode->groupSort);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeBool(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_ONLY_TS, pNode->scanAllCols);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_VIRTUAL_TABLE_SCAN_CODE_TARGETS, nodeListToMsg, pNode->pTargets);
}
return code;
}
static int32_t msgToPhysiVirtualTableScanNode(STlvDecoder* pDecoder, void* pObj) {
SVirtualScanPhysiNode* pNode = (SVirtualScanPhysiNode*)pObj;
int32_t code = TSDB_CODE_SUCCESS;
STlv* pTlv = NULL;
tlvForEach(pDecoder, pTlv, code) {
switch (pTlv->type) {
case PHY_VIRTUAL_TABLE_SCAN_CODE_SCAN:
code = tlvDecodeObjFromTlv(pTlv, msgToPhysiScanNode, &pNode->scan);
break;
case PHY_VIRTUAL_TABLE_SCAN_CODE_GROUPTAGS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pGroupTags);
break;
case PHY_VIRTUAL_TABLE_SCAN_CODE_GROUP_SORT:
code = tlvDecodeBool(pTlv, &pNode->groupSort);
break;
case PHY_VIRTUAL_TABLE_SCAN_CODE_ONLY_TS:
code = tlvDecodeBool(pTlv, &pNode->scanAllCols);
break;
case PHY_VIRTUAL_TABLE_SCAN_CODE_TARGETS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->pTargets);
break;
default:
break;
}
@ -4248,6 +4351,11 @@ enum {
PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_UID_SLOT1,
PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN0,
PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN1,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_ALL_COLS,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SUID,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_ACCOUNT_ID,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_EP_SET,
PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_COLS,
};
static int32_t physiDynQueryCtrlNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
@ -4281,6 +4389,22 @@ static int32_t physiDynQueryCtrlNodeToMsg(const void* pObj, STlvEncoder* pEncode
}
break;
}
case DYN_QTYPE_VTB_SCAN: {
code = tlvEncodeBool(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_ALL_COLS, pNode->vtbScan.scanAllCols);
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeU64(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SUID, pNode->vtbScan.suid);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeI32(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_ACCOUNT_ID, pNode->vtbScan.accountId);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_EP_SET, epSetToMsg, &pNode->vtbScan.mgmtEpSet);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeObj(pEncoder, PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_COLS, nodeListToMsg, pNode->vtbScan.pScanCols);
}
break;
}
default:
return TSDB_CODE_INVALID_PARA;
}
@ -4321,7 +4445,21 @@ static int32_t msgToPhysiDynQueryCtrlNode(STlvDecoder* pDecoder, void* pObj) {
break;
case PHY_DYN_QUERY_CTRL_CODE_STB_JOIN_SRC_SCAN1:
code = tlvDecodeBool(pTlv, &pNode->stbJoin.srcScan[1]);
break;
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_ALL_COLS:
code = tlvDecodeBool(pTlv, &pNode->vtbScan.scanAllCols);
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SUID:
code = tlvDecodeU64(pTlv, &pNode->vtbScan.suid);
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_ACCOUNT_ID:
code = tlvDecodeI32(pTlv, &pNode->vtbScan.accountId);
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_EP_SET:
code = tlvDecodeObjFromTlv(pTlv, msgToEpSet, &pNode->vtbScan.mgmtEpSet);
break;
case PHY_DYN_QUERY_CTRL_CODE_VTB_SCAN_SCAN_COLS:
code = msgToNodeListFromTlv(pTlv, (void**)&pNode->vtbScan.pScanCols);
default:
break;
}
@ -4445,7 +4583,9 @@ static int32_t subplanInlineToMsg(const void* pObj, STlvEncoder* pEncoder) {
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->isAudit);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvEncodeValueBool(pEncoder, pNode->processOneBlock);
}
return code;
}
@ -4506,6 +4646,9 @@ static int32_t msgToSubplanInline(STlvDecoder* pDecoder, void* pObj) {
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->isAudit);
}
if (TSDB_CODE_SUCCESS == code) {
code = tlvDecodeValueBool(pDecoder, &pNode->processOneBlock);
}
return code;
}
@ -4759,6 +4902,9 @@ static int32_t specificNodeToMsg(const void* pObj, STlvEncoder* pEncoder) {
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
code = physiDynQueryCtrlNodeToMsg(pObj, pEncoder);
break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
code = physiVirtualTableScanNodeToMsg(pObj, pEncoder);
break;
case QUERY_NODE_PHYSICAL_SUBPLAN:
code = subplanToMsg(pObj, pEncoder);
break;
@ -4937,6 +5083,9 @@ static int32_t msgToSpecificNode(STlvDecoder* pDecoder, void* pObj) {
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL:
code = msgToPhysiDynQueryCtrlNode(pDecoder, pObj);
break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
code = msgToPhysiVirtualTableScanNode(pDecoder, pObj);
break;
case QUERY_NODE_PHYSICAL_SUBPLAN:
code = msgToSubplan(pDecoder, pObj);
break;

View File

@ -78,6 +78,7 @@ static EDealRes dispatchExpr(SNode* pNode, ETraversalOrder order, FNodeWalker wa
break;
case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_VIRTUAL_TABLE:
break; // todo
case QUERY_NODE_JOIN_TABLE: {
SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode;
@ -295,6 +296,7 @@ static EDealRes rewriteExpr(SNode** pRawNode, ETraversalOrder order, FNodeRewrit
}
case QUERY_NODE_REAL_TABLE:
case QUERY_NODE_TEMP_TABLE:
case QUERY_NODE_VIRTUAL_TABLE:
break; // todo
case QUERY_NODE_JOIN_TABLE: {
SJoinTableNode* pJoinTableNode = (SJoinTableNode*)pNode;

View File

@ -382,6 +382,9 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_REAL_TABLE:
code = makeNode(type, sizeof(SRealTableNode), &pNode);
break;
case QUERY_NODE_VIRTUAL_TABLE:
code = makeNode(type, sizeof(SVirtualTableNode), &pNode);
break;
case QUERY_NODE_TEMP_TABLE:
code = makeNode(type, sizeof(STempTableNode), &pNode);
break;
@ -517,6 +520,12 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_CREATE_SUBTABLE_CLAUSE:
code = makeNode(type, sizeof(SCreateSubTableClause), &pNode);
break;
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
code = makeNode(type, sizeof(SCreateVTableStmt), &pNode);
break;
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
code = makeNode(type, sizeof(SCreateVSubTableStmt), &pNode);
break;
case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE:
code = makeNode(type, sizeof(SCreateSubTableFromFileClause), &pNode);
break;
@ -532,8 +541,12 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_DROP_SUPER_TABLE_STMT:
code = makeNode(type, sizeof(SDropSuperTableStmt), &pNode);
break;
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
code = makeNode(type, sizeof(SDropVirtualTableStmt), &pNode);
break;
case QUERY_NODE_ALTER_TABLE_STMT:
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
code = makeNode(type, sizeof(SAlterTableStmt), &pNode);
break;
case QUERY_NODE_CREATE_USER_STMT:
@ -680,6 +693,7 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_SHOW_STABLES_STMT:
case QUERY_NODE_SHOW_STREAMS_STMT:
case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
case QUERY_NODE_SHOW_USERS_STMT:
case QUERY_NODE_SHOW_USERS_FULL_STMT:
case QUERY_NODE_SHOW_LICENCES_STMT:
@ -720,6 +734,7 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
code = makeNode(type, sizeof(SShowAliveStmt), &pNode);
break;
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
code = makeNode(type, sizeof(SShowCreateTableStmt), &pNode);
break;
@ -824,6 +839,9 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
code = makeNode(type, sizeof(SDynQueryCtrlLogicNode), &pNode);
break;
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
code = makeNode(type, sizeof(SVirtualScanLogicNode), &pNode);
break;
case QUERY_NODE_LOGIC_SUBPLAN:
code = makeNode(type, sizeof(SLogicSubplan), &pNode);
break;
@ -990,6 +1008,9 @@ int32_t nodesMakeNode(ENodeType type, SNode** ppNodeOut) {
case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERP_FUNC:
code = makeNode(type, sizeof(SStreamInterpFuncPhysiNode), &pNode);
break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN:
code = makeNode(type, sizeof(SVirtualScanPhysiNode), &pNode);
break;
default:
break;
}
@ -1061,6 +1082,7 @@ static void destroyTableCfg(STableCfg* pCfg) {
taosMemoryFree(pCfg->pComment);
taosMemoryFree(pCfg->pSchemas);
taosMemoryFree(pCfg->pSchemaExt);
taosMemoryFree(pCfg->pColRefs);
taosMemoryFree(pCfg->pTags);
taosMemoryFree(pCfg);
}
@ -1120,6 +1142,13 @@ void nodesDestroyNode(SNode* pNode) {
taosArrayDestroy(pReal->tsmaTargetTbInfo);
break;
}
case QUERY_NODE_VIRTUAL_TABLE: {
SVirtualTableNode *pVirtual = (SVirtualTableNode*)pNode;
taosMemoryFreeClear(pVirtual->pMeta);
taosMemoryFreeClear(pVirtual->pVgroupList);
nodesDestroyList(pVirtual->refTables);
break;
}
case QUERY_NODE_TEMP_TABLE:
nodesDestroyNode(((STempTableNode*)pNode)->pSubquery);
break;
@ -1409,6 +1438,19 @@ void nodesDestroyNode(SNode* pNode) {
nodesDestroyNode((SNode*)pStmt->pOptions);
break;
}
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT: {
SCreateVTableStmt* pStmt = (SCreateVTableStmt*)pNode;
nodesDestroyList(pStmt->pCols);
break;
}
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT: {
SCreateVSubTableStmt* pStmt = (SCreateVSubTableStmt*)pNode;
nodesDestroyList(pStmt->pSpecificColRefs);
nodesDestroyList(pStmt->pColRefs);
nodesDestroyList(pStmt->pSpecificTags);
nodesDestroyList(pStmt->pValsOfTags);
break;
}
case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE: {
SCreateSubTableFromFileClause* pStmt = (SCreateSubTableFromFileClause*)pNode;
nodesDestroyList(pStmt->pSpecificTags);
@ -1422,10 +1464,12 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_DROP_TABLE_STMT:
nodesDestroyList(((SDropTableStmt*)pNode)->pTables);
break;
case QUERY_NODE_DROP_SUPER_TABLE_STMT: // no pointer field
case QUERY_NODE_DROP_SUPER_TABLE_STMT:
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT: // no pointer field
break;
case QUERY_NODE_ALTER_TABLE_STMT:
case QUERY_NODE_ALTER_SUPER_TABLE_STMT: {
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT: {
SAlterTableStmt* pStmt = (SAlterTableStmt*)pNode;
nodesDestroyNode((SNode*)pStmt->pOptions);
nodesDestroyNode((SNode*)pStmt->pVal);
@ -1567,6 +1611,7 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_SHOW_STABLES_STMT:
case QUERY_NODE_SHOW_STREAMS_STMT:
case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
case QUERY_NODE_SHOW_USERS_STMT:
case QUERY_NODE_SHOW_USERS_FULL_STMT:
case QUERY_NODE_SHOW_LICENCES_STMT:
@ -1623,6 +1668,7 @@ void nodesDestroyNode(SNode* pNode) {
taosMemoryFreeClear(((SShowCreateDatabaseStmt*)pNode)->pCfg);
break;
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
taosMemoryFreeClear(((SShowCreateTableStmt*)pNode)->pDbCfg);
destroyTableCfg((STableCfg*)(((SShowCreateTableStmt*)pNode)->pTableCfg));
@ -1728,6 +1774,14 @@ void nodesDestroyNode(SNode* pNode) {
nodesDestroyNode(pLogicNode->pRightOnCond);
break;
}
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN: {
SVirtualScanLogicNode * pLogicNode = (SVirtualScanLogicNode*)pNode;
destroyLogicNode((SLogicNode*)pLogicNode);
nodesDestroyList(pLogicNode->pScanCols);
nodesDestroyList(pLogicNode->pScanPseudoCols);
taosMemoryFreeClear(pLogicNode->pVgroupList);
break;
}
case QUERY_NODE_LOGIC_PLAN_AGG: {
SAggLogicNode* pLogicNode = (SAggLogicNode*)pNode;
destroyLogicNode((SLogicNode*)pLogicNode);
@ -1828,6 +1882,9 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL: {
SDynQueryCtrlLogicNode* pLogicNode = (SDynQueryCtrlLogicNode*)pNode;
destroyLogicNode((SLogicNode*)pLogicNode);
if (pLogicNode->qType == DYN_QTYPE_VTB_SCAN) {
taosMemoryFreeClear(pLogicNode->vtbScan.pVgroupList);
}
break;
}
case QUERY_NODE_LOGIC_SUBPLAN: {
@ -1846,6 +1903,13 @@ void nodesDestroyNode(SNode* pNode) {
case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN:
destroyScanPhysiNode((SScanPhysiNode*)pNode);
break;
case QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN: {
SVirtualScanPhysiNode* pPhyNode = (SVirtualScanPhysiNode*)pNode;
destroyScanPhysiNode((SScanPhysiNode*)pNode);
nodesDestroyList(pPhyNode->pGroupTags);
nodesDestroyList(pPhyNode->pTargets);
break;
}
case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN:
case QUERY_NODE_PHYSICAL_PLAN_TABLE_COUNT_SCAN: {
SLastRowScanPhysiNode* pPhyNode = (SLastRowScanPhysiNode*)pNode;
@ -2066,6 +2130,9 @@ void nodesDestroyNode(SNode* pNode) {
}
case QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL: {
SDynQueryCtrlPhysiNode* pPhyNode = (SDynQueryCtrlPhysiNode*)pNode;
if (pPhyNode->qType == DYN_QTYPE_VTB_SCAN) {
nodesDestroyList(pPhyNode->vtbScan.pScanCols);
}
destroyPhysiNode((SPhysiNode*)pPhyNode);
break;
}

View File

@ -83,7 +83,8 @@ typedef enum ETableOptionType {
TABLE_OPTION_TTL,
TABLE_OPTION_SMA,
TABLE_OPTION_DELETE_MARK,
TABLE_OPTION_KEEP
TABLE_OPTION_KEEP,
TABLE_OPTION_VIRTUAL
} ETableOptionType;
typedef enum EColumnOptionType {
@ -105,6 +106,12 @@ typedef struct STokenPair {
SToken second;
} STokenPair;
typedef struct STokenTriplet {
ENodeType type;
int32_t numOfName;
SToken name[3];
} STokenTriplet;
typedef struct SShowTablesOption {
EShowKind kind;
SToken dbName;
@ -210,20 +217,31 @@ SNode* createCompactVgroupsStmt(SAstCreateContext* pCxt, SNode* pDbName, SNodeLi
SNode* createDefaultTableOptions(SAstCreateContext* pCxt);
SNode* createAlterTableOptions(SAstCreateContext* pCxt);
SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType type, void* pVal);
STokenTriplet* createTokenTriplet(SAstCreateContext* pCxt, SToken pName);
STokenTriplet* setColumnName(SAstCreateContext* pCxt, STokenTriplet* pTokenTri, SToken pName);
SNode* createColumnRefNodeByName(SAstCreateContext* pCxt, STokenTriplet* pTokenTri);
SNode* createColumnRefNodeByNode(SAstCreateContext* pCxt, SToken* pColName, SNode* pRef);
SNode* createColumnDefNode(SAstCreateContext* pCxt, SToken* pColName, SDataType dataType, SNode* pOptions);
SNode* setColumnOptions(SAstCreateContext* pCxt, SNode* pOptions, const SToken* pVal1, void* pVal2);
SNode* setColumnOptionsPK(SAstCreateContext* pCxt, SNode* pOptions);
SNode* setColumnReference(SAstCreateContext* pCxt, SNode* pOptions, SNode* pRef);
SNode* createDefaultColumnOptions(SAstCreateContext* pCxt);
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols,
SNodeList* pTags, SNode* pOptions);
SNode* createCreateSubTableClause(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNode* pUseRealTable,
SNodeList* pSpecificTags, SNodeList* pValsOfTags, SNode* pOptions);
SNode* createCreateVTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols);
SNode* createCreateVSubTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable,
SNodeList* pSpecificColRefs, SNodeList* pColRefs, SNode* pUseRealTable,
SNodeList* pSpecificTags, SNodeList* pValsOfTags);
SNode* createCreateSubTableFromFileClause(SAstCreateContext* pCxt, bool ignoreExists, SNode* pUseRealTable,
SNodeList* pSpecificTags, const SToken* pFilePath);
SNode* createCreateMultiTableStmt(SAstCreateContext* pCxt, SNodeList* pSubTables);
SNode* createDropTableClause(SAstCreateContext* pCxt, bool ignoreNotExists, SNode* pRealTable);
SNode* createDropTableStmt(SAstCreateContext* pCxt, bool withOpt, SNodeList* pTables);
SNode* createDropSuperTableStmt(SAstCreateContext* pCxt, bool withOpt, bool ignoreNotExists, SNode* pRealTable);
SNode* createDropVirtualTableStmt(SAstCreateContext* pCxt, bool withOpt, bool ignoreNotExists, SNode* pRealTable);
SNode* createAlterTableModifyOptions(SAstCreateContext* pCxt, SNode* pRealTable, SNode* pOptions);
SNode* createAlterTableAddModifyCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
SDataType dataType);
@ -236,9 +254,14 @@ SNode* createAlterTableAddModifyColOptions(SAstCreateContext* pCxt, SNode* pReal
SNode* createAlterTableDropCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName);
SNode* createAlterTableRenameCol(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pOldColName,
SToken* pNewColName);
SNode* createAlterTableAlterColRef(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
SNode* pRef);
SNode* createAlterTableRemoveColRef(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
const SToken* pLiteral);
SNode* createAlterTableSetTag(SAstCreateContext* pCxt, SNode* pRealTable, SToken* pTagName, SNode* pVal);
SNode* createAlterTableSetMultiTagValue(SAstCreateContext* pCxt, SNode* pRealTable, SNodeList* singleNode);
SNode* setAlterSuperTableType(SNode* pStmt);
SNode* setAlterVirtualTableType(SNode* pStmt);
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName);
SNode* setShowKind(SAstCreateContext* pCxt, SNode* pStmt, EShowKind showKind);
SNode* createShowStmt(SAstCreateContext* pCxt, ENodeType type);
@ -248,9 +271,14 @@ SNode* createShowStmtWithCond(SAstCreateContext* pCxt, ENodeType type, SNode* pD
EOperatorType tableCondType);
SNode* createShowTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType);
SNode* createShowVTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType);
SNode* createShowSTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType);
SNode* createShowCreateDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName);
SNode* createShowAliveStmt(SAstCreateContext* pCxt, SNode* pDbName, ENodeType type);
SNode* createShowCreateTableStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable);
SNode* createShowCreateVTableStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable);
SNode* createShowCreateViewStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable);
SNode* createShowTableDistributedStmt(SAstCreateContext* pCxt, SNode* pRealTable);
SNode* createShowDnodeVariablesStmt(SAstCreateContext* pCxt, SNode* pDnodeId, SNode* pLikePattern);

View File

@ -48,6 +48,7 @@ typedef struct STranslateContext {
SNode* pPostRoot;
bool dual; // whether select stmt without from stmt, true for without.
bool skipCheck;
bool refTable;
} STranslateContext;
int32_t biRewriteToTbnameFunc(STranslateContext* pCxt, SNode** ppNode, bool* pRet);

View File

@ -403,16 +403,28 @@ cmd ::= CREATE TABLE not_exists_opt(B) USING full_table_name(C)
NK_LP tag_list_opt(D) NK_RP FILE NK_STRING(E). { pCxt->pRootNode = createCreateSubTableFromFileClause(pCxt, B, C, D, &E); }
cmd ::= CREATE STABLE not_exists_opt(A) full_table_name(B)
NK_LP column_def_list(C) NK_RP tags_def(D) table_options(E). { pCxt->pRootNode = createCreateTableStmt(pCxt, A, B, C, D, E); }
cmd ::= CREATE VTABLE not_exists_opt(A) full_table_name(B)
NK_LP column_def_list(C) NK_RP. { pCxt->pRootNode = createCreateVTableStmt(pCxt, A, B, C); }
cmd ::= CREATE VTABLE not_exists_opt(A) full_table_name(B)
NK_LP specific_column_ref_list(C) NK_RP USING full_table_name(D)
specific_cols_opt(E) TAGS NK_LP tags_literal_list(F) NK_RP. { pCxt->pRootNode = createCreateVSubTableStmt(pCxt, A, B, C, NULL, D, E, F); }
cmd ::= CREATE VTABLE not_exists_opt(A) full_table_name(B)
NK_LP column_ref_list(C) NK_RP USING full_table_name(D)
specific_cols_opt(E) TAGS NK_LP tags_literal_list(F) NK_RP. { pCxt->pRootNode = createCreateVSubTableStmt(pCxt, A, B, NULL, C, D, E, F); }
cmd ::= CREATE VTABLE not_exists_opt(A) full_table_name(B) USING full_table_name(C)
specific_cols_opt(D) TAGS NK_LP tags_literal_list(E) NK_RP. { pCxt->pRootNode = createCreateVSubTableStmt(pCxt, A, B, NULL, NULL, C, D, E); }
cmd ::= DROP TABLE with_opt(A) multi_drop_clause(B). { pCxt->pRootNode = createDropTableStmt(pCxt, A, B); }
cmd ::= DROP STABLE with_opt(A) exists_opt(B) full_table_name(C). { pCxt->pRootNode = createDropSuperTableStmt(pCxt, A, B, C); }
cmd ::= DROP VTABLE with_opt(A) exists_opt(B) full_table_name(C). { pCxt->pRootNode = createDropVirtualTableStmt(pCxt, A, B, C); }
cmd ::= ALTER TABLE alter_table_clause(A). { pCxt->pRootNode = A; }
cmd ::= ALTER STABLE alter_table_clause(A). { pCxt->pRootNode = setAlterSuperTableType(A); }
cmd ::= ALTER VTABLE alter_table_clause(A). { pCxt->pRootNode = setAlterVirtualTableType(A); }
alter_table_clause(A) ::= full_table_name(B) alter_table_options(C). { A = createAlterTableModifyOptions(pCxt, B, C); }
alter_table_clause(A) ::=
full_table_name(B) ADD COLUMN column_name(C) type_name(D) column_options(E). { A = createAlterTableAddModifyColOptions2(pCxt, B, TSDB_ALTER_TABLE_ADD_COLUMN, &C, D, E); }
full_table_name(B) ADD COLUMN column_name(C) type_name(D) column_options(E). { A = createAlterTableAddModifyColOptions2(pCxt, B, TSDB_ALTER_TABLE_ADD_COLUMN, &C, D, E); }
alter_table_clause(A) ::= full_table_name(B) DROP COLUMN column_name(C). { A = createAlterTableDropCol(pCxt, B, TSDB_ALTER_TABLE_DROP_COLUMN, &C); }
alter_table_clause(A) ::=
full_table_name(B) MODIFY COLUMN column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &C, D); }
@ -427,16 +439,21 @@ alter_table_clause(A) ::=
full_table_name(B) MODIFY TAG column_name(C) type_name(D). { A = createAlterTableAddModifyCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &C, D); }
alter_table_clause(A) ::=
full_table_name(B) RENAME TAG column_name(C) column_name(D). { A = createAlterTableRenameCol(pCxt, B, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &C, &D); }
%type column_tag_value_list { SNodeList* }
%destructor column_tag_value_list { nodesDestroyList($$); }
column_tag_value(A) ::= column_name(C) NK_EQ tags_literal(D). { A = createAlterSingleTagColumnNode(pCxt, &C, D); }
column_tag_value_list(A) ::= column_tag_value(B). { A = createNodeList(pCxt, B); }
column_tag_value_list(A) ::= column_tag_value_list(B) NK_COMMA column_tag_value(C). { A = addNodeToList(pCxt, B, C);}
alter_table_clause(A) ::=
full_table_name(B) ALTER COLUMN column_name(C) SET column_ref(D).
{ A = createAlterTableAlterColRef(pCxt, B, TSDB_ALTER_TABLE_ALTER_COLUMN_REF, &C, D); }
alter_table_clause(A) ::=
full_table_name(B) SET TAG column_tag_value_list(C). { A = createAlterTableSetMultiTagValue(pCxt, B, C); }
full_table_name(B) ALTER COLUMN column_name(C) SET NULL(D). { A = createAlterTableRemoveColRef(pCxt, B, TSDB_ALTER_TABLE_REMOVE_COLUMN_REF, &C, &D); }
%type column_tag_value_list { SNodeList* }
%destructor column_tag_value_list { nodesDestroyList($$); }
column_tag_value(A) ::= column_name(C) NK_EQ tags_literal(D). { A = createAlterSingleTagColumnNode(pCxt, &C, D); }
column_tag_value_list(A) ::= column_tag_value(B). { A = createNodeList(pCxt, B); }
column_tag_value_list(A) ::= column_tag_value_list(B) NK_COMMA column_tag_value(C). { A = addNodeToList(pCxt, B, C);}
alter_table_clause(A) ::=
full_table_name(B) SET TAG column_tag_value_list(C). { A = createAlterTableSetMultiTagValue(pCxt, B, C); }
%type multi_create_clause { SNodeList* }
%destructor multi_create_clause { nodesDestroyList($$); }
@ -481,6 +498,18 @@ column_def_list(A) ::= column_def_list(B) NK_COMMA column_def(C).
// column_def(A) ::= column_name(B) type_name(C). { A = createColumnDefNode(pCxt, &B, C, NULL); }
column_def(A) ::= column_name(B) type_name(C) column_options(D). { A = createColumnDefNode(pCxt, &B, C, D); }
%type specific_column_ref_list { SNodeList* }
%destructor specific_column_ref_list { nodesDestroyList($$); }
specific_column_ref_list(A) ::= specific_column_ref(B). { A = createNodeList(pCxt, B); }
specific_column_ref_list(A) ::= specific_column_ref_list(B) NK_COMMA specific_column_ref(C). { A = addNodeToList(pCxt, B, C); }
specific_column_ref(A) ::= column_name(B) FROM column_ref(C). { A = createColumnRefNodeByNode(pCxt, &B, C); }
%type column_ref_list { SNodeList* }
%destructor column_ref_list { nodesDestroyList($$); }
column_ref_list(A) ::= column_ref(B). { A = createNodeList(pCxt, B); }
column_ref_list(A) ::= column_ref_list(B) NK_COMMA column_ref(C). { A = addNodeToList(pCxt, B, C); }
%type type_name { SDataType }
%destructor type_name { }
type_name(A) ::= BOOL. { A = createDataType(TSDB_DATA_TYPE_BOOL); }
@ -534,6 +563,7 @@ table_options(A) ::= table_options(B) SMA NK_LP col_name_list(C) NK_RP.
table_options(A) ::= table_options(B) DELETE_MARK duration_list(C). { A = setTableOption(pCxt, B, TABLE_OPTION_DELETE_MARK, C); }
table_options(A) ::= table_options(B) KEEP NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); }
table_options(A) ::= table_options(B) KEEP NK_VARIABLE(C). { A = setTableOption(pCxt, B, TABLE_OPTION_KEEP, &C); }
table_options(A) ::= table_options(B) VIRTUAL NK_INTEGER(C). { A = setTableOption(pCxt, B, TABLE_OPTION_VIRTUAL, &C); }
alter_table_options(A) ::= alter_table_option(B). { A = createAlterTableOptions(pCxt); A = setTableOption(pCxt, A, B.type, &B.val); }
alter_table_options(A) ::= alter_table_options(B) alter_table_option(C). { A = setTableOption(pCxt, B, C.type, &C.val); }
@ -579,7 +609,12 @@ cmd ::= SHOW db_kind_opt(A) DATABASES.
cmd ::= SHOW table_kind_db_name_cond_opt(A) TABLES like_pattern_opt(B). {
pCxt->pRootNode = createShowTablesStmt(pCxt, A, B, OP_TYPE_LIKE);
}
cmd ::= SHOW db_name_cond_opt(A) STABLES like_pattern_opt(B). { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, A, B, OP_TYPE_LIKE); }
cmd ::= SHOW table_kind_db_name_cond_opt(A) VTABLES like_pattern_opt(B). {
pCxt->pRootNode = createShowVTablesStmt(pCxt, A, B, OP_TYPE_LIKE);
}
cmd ::= SHOW table_kind_db_name_cond_opt(A) STABLES like_pattern_opt(B). {
pCxt->pRootNode = createShowSTablesStmt(pCxt, A, B, OP_TYPE_LIKE);
}
cmd ::= SHOW db_name_cond_opt(A) VGROUPS. { pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, A, NULL, OP_TYPE_LIKE); }
cmd ::= SHOW MNODES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); }
//cmd ::= SHOW MODULES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MODULES_STMT); }
@ -601,6 +636,7 @@ cmd ::= SHOW GRANTS LOGS.
cmd ::= SHOW CLUSTER MACHINES. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CLUSTER_MACHINES_STMT); }
cmd ::= SHOW CREATE DATABASE db_name(A). { pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &A); }
cmd ::= SHOW CREATE TABLE full_table_name(A). { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, A); }
cmd ::= SHOW CREATE VTABLE full_table_name(A). { pCxt->pRootNode = createShowCreateVTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_VTABLE_STMT, A); }
cmd ::= SHOW CREATE STABLE full_table_name(A). { pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT,
A); }
cmd ::= SHOW ENCRYPTIONS. { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_ENCRYPTIONS_STMT); }
@ -645,6 +681,7 @@ table_kind_db_name_cond_opt(A) ::= table_kind(B) db_name(C) NK_DOT.
%destructor table_kind { }
table_kind(A) ::= NORMAL. { A = SHOW_KIND_TABLES_NORMAL; }
table_kind(A) ::= CHILD. { A = SHOW_KIND_TABLES_CHILD; }
table_kind(A) ::= VIRTUAL. { A = SHOW_KIND_TABLES_VIRTUAL; }
db_name_cond_opt(A) ::= . { A = createDefaultDatabaseCondValue(pCxt); }
db_name_cond_opt(A) ::= db_name(B) NK_DOT. { A = createIdentifierValueNode(pCxt, &B); }
@ -1834,3 +1871,11 @@ null_ordering_opt(A) ::= NULLS LAST.
column_options(A) ::= . { A = createDefaultColumnOptions(pCxt); }
column_options(A) ::= column_options(B) PRIMARY KEY. { A = setColumnOptionsPK(pCxt, B); }
column_options(A) ::= column_options(B) NK_ID(C) NK_STRING(D). { A = setColumnOptions(pCxt, B, &C, &D); }
column_options(A) ::= column_options(B) FROM column_ref(C). { A = setColumnReference(pCxt, B, C); }
column_ref(A) ::= column_name_list(B). { A = createColumnRefNodeByName(pCxt, B); }
%type column_name_list { STokenTriplet* }
%destructor column_name_list { }
column_name_list(A) ::= NK_ID(B). { A = createTokenTriplet(pCxt, B); }
column_name_list(A) ::= column_name_list(B) NK_DOT NK_ID(C). { A = setColumnName(pCxt, B, C); }

View File

@ -2380,6 +2380,15 @@ SNode* setTableOption(SAstCreateContext* pCxt, SNode* pOptions, ETableOptionType
((STableOptions*)pOptions)->pKeepNode = (SValueNode*)createDurationValueNode(pCxt, (SToken*)pVal);
}
break;
case TABLE_OPTION_VIRTUAL: {
int64_t virtualStb = taosStr2Int64(((SToken*)pVal)->z, NULL, 10);
if (virtualStb != 0 && virtualStb != 1) {
pCxt->errCode = TSDB_CODE_TSC_VALUE_OUT_OF_RANGE;
} else {
((STableOptions*)pOptions)->virtualStb = virtualStb;
}
break;
}
default:
break;
}
@ -2396,6 +2405,7 @@ SNode* createDefaultColumnOptions(SAstCreateContext* pCxt) {
CHECK_MAKE_NODE(pOptions);
pOptions->commentNull = true;
pOptions->bPrimaryKey = false;
pOptions->hasRef = false;
return (SNode*)pOptions;
_err:
return NULL;
@ -2411,6 +2421,20 @@ EColumnOptionType getColumnOptionType(const char* optionType) {
}
return 0;
}
SNode* setColumnReference(SAstCreateContext* pCxt, SNode* pOptions, SNode* pRef) {
CHECK_PARSER_STATUS(pCxt);
((SColumnOptions*)pOptions)->hasRef = true;
tstrncpy(((SColumnOptions*)pOptions)->refDb, ((SColumnRefNode*)pRef)->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(((SColumnOptions*)pOptions)->refTable, ((SColumnRefNode*)pRef)->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(((SColumnOptions*)pOptions)->refColumn, ((SColumnRefNode*)pRef)->refColName, TSDB_COL_NAME_LEN);
return pOptions;
_err:
nodesDestroyNode(pOptions);
return NULL;
}
SNode* setColumnOptionsPK(SAstCreateContext* pCxt, SNode* pOptions) {
CHECK_PARSER_STATUS(pCxt);
((SColumnOptions*)pOptions)->bPrimaryKey = true;
@ -2463,6 +2487,90 @@ _err:
return NULL;
}
SNode* createColumnRefNodeByNode(SAstCreateContext* pCxt, SToken* pColName, SNode* pRef) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkColumnName(pCxt, pColName));
SColumnRefNode* pCol = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_COLUMN_REF, (SNode**)&pCol);
CHECK_MAKE_NODE(pCol);
if (pColName) {
COPY_STRING_FORM_ID_TOKEN(pCol->colName, pColName);
}
tstrncpy(pCol->refDbName, ((SColumnRefNode*)pRef)->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pCol->refTableName, ((SColumnRefNode*)pRef)->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pCol->refColName, ((SColumnRefNode*)pRef)->refColName, TSDB_COL_NAME_LEN);
return (SNode*)pCol;
_err:
return NULL;
}
STokenTriplet* createTokenTriplet(SAstCreateContext* pCxt, SToken pName) {
CHECK_PARSER_STATUS(pCxt);
STokenTriplet *pTokenTri = taosMemoryMalloc(sizeof(STokenTriplet));
CHECK_OUT_OF_MEM(pTokenTri);
pTokenTri->name[0] = pName;
pTokenTri->numOfName = 1;
return pTokenTri;
_err:
return NULL;
}
STokenTriplet* setColumnName(SAstCreateContext* pCxt, STokenTriplet* pTokenTri, SToken pName) {
CHECK_PARSER_STATUS(pCxt);
if (pTokenTri->numOfName >= 3) {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
goto _err;
}
pTokenTri->name[pTokenTri->numOfName] = pName;
pTokenTri->numOfName++;
return pTokenTri;
_err:
return NULL;
}
SNode* createColumnRefNodeByName(SAstCreateContext* pCxt, STokenTriplet* pTokenTri) {
SColumnRefNode* pCol = NULL;
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesMakeNode(QUERY_NODE_COLUMN_REF, (SNode**)&pCol);
CHECK_MAKE_NODE(pCol);
switch(pTokenTri->numOfName) {
case 2: {
CHECK_NAME(checkTableName(pCxt, &pTokenTri->name[0]));
CHECK_NAME(checkColumnName(pCxt, &pTokenTri->name[1]));
snprintf(pCol->refDbName, TSDB_DB_NAME_LEN, "%s", pCxt->pQueryCxt->db);
COPY_STRING_FORM_ID_TOKEN(pCol->refTableName, &pTokenTri->name[0]);
COPY_STRING_FORM_ID_TOKEN(pCol->refColName, &pTokenTri->name[1]);
break;
}
case 3: {
CHECK_NAME(checkDbName(pCxt, &pTokenTri->name[0], true));
CHECK_NAME(checkTableName(pCxt, &pTokenTri->name[1]));
CHECK_NAME(checkColumnName(pCxt, &pTokenTri->name[2]));
COPY_STRING_FORM_ID_TOKEN(pCol->refDbName, &pTokenTri->name[0]);
COPY_STRING_FORM_ID_TOKEN(pCol->refTableName, &pTokenTri->name[1]);
COPY_STRING_FORM_ID_TOKEN(pCol->refColName, &pTokenTri->name[2]);
break;
}
default: {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
goto _err;
}
}
taosMemFree(pTokenTri);
return (SNode*)pCol;
_err:
taosMemFree(pTokenTri);
nodesDestroyNode((SNode*)pCol);
return NULL;
}
SNode* createColumnDefNode(SAstCreateContext* pCxt, SToken* pColName, SDataType dataType, SNode* pNode) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkColumnName(pCxt, pColName));
@ -2505,6 +2613,52 @@ SDataType createDecimalDataType(uint8_t type, const SToken* pPrecisionToken, con
return dt;
}
SNode* createCreateVTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols) {
SCreateVTableStmt * pStmt = NULL;
CHECK_PARSER_STATUS(pCxt);
pCxt->errCode = nodesMakeNode(QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
strcpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName);
strcpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName);
pStmt->ignoreExists = ignoreExists;
pStmt->pCols = pCols;
nodesDestroyNode(pRealTable);
return (SNode*)pStmt;
_err:
nodesDestroyNode(pRealTable);
nodesDestroyList(pCols);
return NULL;
}
SNode* createCreateVSubTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable,
SNodeList* pSpecificColRefs, SNodeList* pColRefs, SNode* pUseRealTable,
SNodeList* pSpecificTags, SNodeList* pValsOfTags) {
CHECK_PARSER_STATUS(pCxt);
SCreateVSubTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
strcpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName);
strcpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName);
strcpy(pStmt->useDbName, ((SRealTableNode*)pUseRealTable)->table.dbName);
strcpy(pStmt->useTableName, ((SRealTableNode*)pUseRealTable)->table.tableName);
pStmt->ignoreExists = ignoreExists;
pStmt->pSpecificTags = pSpecificTags;
pStmt->pValsOfTags = pValsOfTags;
pStmt->pSpecificColRefs = pSpecificColRefs;
pStmt->pColRefs = pColRefs;
nodesDestroyNode(pRealTable);
nodesDestroyNode(pUseRealTable);
return (SNode*)pStmt;
_err:
nodesDestroyNode(pRealTable);
nodesDestroyNode(pUseRealTable);
nodesDestroyList(pSpecificTags);
nodesDestroyList(pValsOfTags);
nodesDestroyList(pSpecificColRefs);
nodesDestroyList(pColRefs);
return NULL;
}
SNode* createCreateTableStmt(SAstCreateContext* pCxt, bool ignoreExists, SNode* pRealTable, SNodeList* pCols,
SNodeList* pTags, SNode* pOptions) {
CHECK_PARSER_STATUS(pCxt);
@ -2633,6 +2787,22 @@ _err:
return NULL;
}
SNode* createDropVirtualTableStmt(SAstCreateContext* pCxt, bool withOpt, bool ignoreNotExists, SNode* pRealTable) {
CHECK_PARSER_STATUS(pCxt);
SDropVirtualTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_DROP_VIRTUAL_TABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
tstrncpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName, TSDB_TABLE_NAME_LEN);
pStmt->ignoreNotExists = ignoreNotExists;
pStmt->withOpt = withOpt;
nodesDestroyNode(pRealTable);
return (SNode*)pStmt;
_err:
nodesDestroyNode(pRealTable);
return NULL;
}
static SNode* createAlterTableStmtFinalize(SNode* pRealTable, SAlterTableStmt* pStmt) {
tstrncpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName, TSDB_TABLE_NAME_LEN);
@ -2669,6 +2839,7 @@ _err:
nodesDestroyNode(pRealTable);
return NULL;
}
SNode* createAlterTableAddModifyColOptions2(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType,
SToken* pColName, SDataType dataType, SNode* pOptions) {
SAlterTableStmt* pStmt = NULL;
@ -2683,7 +2854,17 @@ SNode* createAlterTableAddModifyColOptions2(SAstCreateContext* pCxt, SNode* pRea
if (pOptions != NULL) {
SColumnOptions* pOption = (SColumnOptions*)pOptions;
if (pOption->bPrimaryKey == false && pOption->commentNull == true) {
if (pOption->hasRef) {
if (!pOption->commentNull || pOption->bPrimaryKey || 0 != strcmp(pOption->compress, "") ||
0 != strcmp(pOption->encode, "") || 0 != strcmp(pOption->compressLevel, "")) {
pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ALTER_TABLE);
}
pStmt->alterType = TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF;
tstrncpy(pStmt->refDbName, pOption->refDb, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->refTableName, pOption->refTable, TSDB_TABLE_NAME_LEN);
tstrncpy(pStmt->refColName, pOption->refColumn, TSDB_COL_NAME_LEN);
CHECK_PARSER_STATUS(pCxt);
} else if (pOption->bPrimaryKey == false && pOption->commentNull == true) {
if (strlen(pOption->compress) != 0 || strlen(pOption->compressLevel) || strlen(pOption->encode) != 0) {
pStmt->alterType = TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COMPRESS_OPTION;
} else {
@ -2753,6 +2934,39 @@ _err:
return NULL;
}
SNode* createAlterTableAlterColRef(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
SNode* pRef) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkColumnName(pCxt, pColName));
SAlterTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_ALTER_TABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
pStmt->alterType = alterType;
COPY_STRING_FORM_ID_TOKEN(pStmt->colName, pColName);
tstrncpy(pStmt->refDbName, ((SColumnRefNode*)pRef)->refDbName, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->refTableName, ((SColumnRefNode*)pRef)->refTableName, TSDB_TABLE_NAME_LEN);
tstrncpy(pStmt->refColName, ((SColumnRefNode*)pRef)->refColName, TSDB_COL_NAME_LEN);
return createAlterTableStmtFinalize(pRealTable, pStmt);
_err:
nodesDestroyNode(pRealTable);
return NULL;
}
SNode* createAlterTableRemoveColRef(SAstCreateContext* pCxt, SNode* pRealTable, int8_t alterType, SToken* pColName,
const SToken* pLiteral) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkColumnName(pCxt, pColName));
SAlterTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(QUERY_NODE_ALTER_TABLE_STMT, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
pStmt->alterType = alterType;
COPY_STRING_FORM_ID_TOKEN(pStmt->colName, pColName);
return createAlterTableStmtFinalize(pRealTable, pStmt);
_err:
nodesDestroyNode(pRealTable);
return NULL;
}
SNode* createAlterSingleTagColumnNode(SAstCreateContext* pCtx, SToken* pTagName, SNode* pVal) {
CHECK_PARSER_STATUS(pCtx);
SAlterTableStmt* pStmt = NULL;
@ -2803,6 +3017,12 @@ SNode* setAlterSuperTableType(SNode* pStmt) {
return pStmt;
}
SNode* setAlterVirtualTableType(SNode* pStmt) {
if (!pStmt) return NULL;
setNodeType(pStmt, QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT);
return pStmt;
}
SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkDbName(pCxt, pDbName, false));
@ -2819,7 +3039,8 @@ static bool needDbShowStmt(ENodeType type) {
return QUERY_NODE_SHOW_TABLES_STMT == type || QUERY_NODE_SHOW_STABLES_STMT == type ||
QUERY_NODE_SHOW_VGROUPS_STMT == type || QUERY_NODE_SHOW_INDEXES_STMT == type ||
QUERY_NODE_SHOW_TAGS_STMT == type || QUERY_NODE_SHOW_TABLE_TAGS_STMT == type ||
QUERY_NODE_SHOW_VIEWS_STMT == type || QUERY_NODE_SHOW_TSMAS_STMT == type || QUERY_NODE_SHOW_USAGE_STMT == type;
QUERY_NODE_SHOW_VIEWS_STMT == type || QUERY_NODE_SHOW_TSMAS_STMT == type ||
QUERY_NODE_SHOW_USAGE_STMT == type || QUERY_NODE_SHOW_VTABLES_STMT == type;
}
SNode* createShowStmtWithLike(SAstCreateContext* pCxt, ENodeType type, SNode* pLikePattern) {
@ -2909,6 +3130,12 @@ SNode* createShowTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, S
} else {
pDbName = createIdentifierValueNode(pCxt, &option.dbName);
}
if (option.kind != SHOW_KIND_TABLES_NORMAL && option.kind != SHOW_KIND_TABLES_CHILD && option.kind != SHOW_KIND_ALL) {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return NULL;
}
SNode* pStmt = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, pDbName, pTbName, tableCondType);
CHECK_PARSER_STATUS(pCxt);
(void)setShowKind(pCxt, pStmt, option.kind);
@ -2918,6 +3145,54 @@ _err:
return NULL;
}
SNode* createShowVTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType) {
CHECK_PARSER_STATUS(pCxt);
SNode* pDbName = NULL;
if (option.dbName.type == TK_NK_NIL) {
pDbName = createDefaultDatabaseCondValue(pCxt);
} else {
pDbName = createIdentifierValueNode(pCxt, &option.dbName);
}
if (option.kind != SHOW_KIND_TABLES_NORMAL && option.kind != SHOW_KIND_TABLES_CHILD && option.kind != SHOW_KIND_ALL) {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return NULL;
}
SNode* pStmt = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VTABLES_STMT, pDbName, pTbName, tableCondType);
CHECK_PARSER_STATUS(pCxt);
(void)setShowKind(pCxt, pStmt, option.kind);
return pStmt;
_err:
nodesDestroyNode(pTbName);
return NULL;
}
SNode* createShowSTablesStmt(SAstCreateContext* pCxt, SShowTablesOption option, SNode* pTbName,
EOperatorType tableCondType) {
CHECK_PARSER_STATUS(pCxt);
SNode* pDbName = NULL;
if (option.dbName.type == TK_NK_NIL) {
pDbName = createDefaultDatabaseCondValue(pCxt);
} else {
pDbName = createIdentifierValueNode(pCxt, &option.dbName);
}
if (option.kind != SHOW_KIND_TABLES_NORMAL && option.kind != SHOW_KIND_TABLES_VIRTUAL && option.kind != SHOW_KIND_ALL) {
pCxt->errCode = TSDB_CODE_PAR_SYNTAX_ERROR;
return NULL;
}
SNode* pStmt = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, pDbName, pTbName, tableCondType);
CHECK_PARSER_STATUS(pCxt);
(void)setShowKind(pCxt, pStmt, option.kind);
return pStmt;
_err:
nodesDestroyNode(pTbName);
return NULL;
}
SNode* createShowCreateDatabaseStmt(SAstCreateContext* pCxt, SToken* pDbName) {
CHECK_PARSER_STATUS(pCxt);
CHECK_NAME(checkDbName(pCxt, pDbName, true));
@ -2979,6 +3254,20 @@ _err:
return NULL;
}
SNode* createShowCreateVTableStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable) {
CHECK_PARSER_STATUS(pCxt);
SShowCreateTableStmt* pStmt = NULL;
pCxt->errCode = nodesMakeNode(type, (SNode**)&pStmt);
CHECK_MAKE_NODE(pStmt);
tstrncpy(pStmt->dbName, ((SRealTableNode*)pRealTable)->table.dbName, TSDB_DB_NAME_LEN);
tstrncpy(pStmt->tableName, ((SRealTableNode*)pRealTable)->table.tableName, TSDB_TABLE_NAME_LEN);
nodesDestroyNode(pRealTable);
return (SNode*)pStmt;
_err:
nodesDestroyNode(pRealTable);
return NULL;
}
SNode* createShowCreateViewStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pRealTable) {
CHECK_PARSER_STATUS(pCxt);
SShowCreateViewStmt* pStmt = NULL;

View File

@ -320,6 +320,76 @@ static int32_t collectMetaKeyFromCreateTable(SCollectMetaKeyCxt* pCxt, SCreateTa
return code;
}
static int32_t collectMetaKeyFromCreateVTable(SCollectMetaKeyCxt* pCxt, SCreateVTableStmt* pStmt) {
int32_t code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
code = reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, NULL, AUTH_TYPE_WRITE,
pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
SNode *pNode = NULL;
FOREACH(pNode, pStmt->pCols) {
SColumnDefNode *pCol = (SColumnDefNode*)pNode;
if (NULL == pCol) {
code = TSDB_CODE_PAR_INVALID_COLUMN;
break;
}
SColumnOptions *pOptions = (SColumnOptions*)pCol->pOptions;
if (pOptions && pOptions->hasRef) {
code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, pOptions->refDb, pOptions->refTable, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
code = reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pOptions->refDb, pOptions->refTable, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pOptions->refDb,
pOptions->refTable, AUTH_TYPE_READ, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS != code) {
break;
}
}
}
}
return code;
}
static int32_t collectMetaKeyFromCreateVSubTable(SCollectMetaKeyCxt* pCxt, SCreateVSubTableStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
PAR_ERR_RET(reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache));
// super table's meta
PAR_ERR_RET(reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->useDbName, pStmt->useTableName,pCxt->pMetaCache));
// child table's meta
PAR_ERR_RET(reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache));
// check db's write auth
PAR_ERR_RET(reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, NULL,
AUTH_TYPE_WRITE, pCxt->pMetaCache));
// check org table's read auth
SNode *pNode = NULL;
SNodeList *pTmpNodeList = pStmt->pSpecificColRefs ? pStmt->pSpecificColRefs : pStmt->pColRefs;
if (NULL == pTmpNodeList) {
// no column reference
return TSDB_CODE_SUCCESS;
}
FOREACH(pNode, pTmpNodeList) {
SColumnRefNode *pColRef = (SColumnRefNode*)pNode;
if (NULL == pColRef) {
code = TSDB_CODE_PAR_INVALID_COLUMN;
break;
}
PAR_ERR_RET(reserveTableMetaInCache(pCxt->pParseCxt->acctId, pColRef->refDbName, pColRef->refTableName,
pCxt->pMetaCache));
PAR_ERR_RET(reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pColRef->refDbName, pColRef->refTableName,
pCxt->pMetaCache));
PAR_ERR_RET(reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pColRef->refDbName,
pColRef->refTableName, AUTH_TYPE_READ, pCxt->pMetaCache));
}
return code;
}
static int32_t collectMetaKeyFromCreateMultiTable(SCollectMetaKeyCxt* pCxt, SCreateMultiTablesStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
SNode* pNode = NULL;
@ -416,6 +486,30 @@ static int32_t collectMetaKeyFromDropStable(SCollectMetaKeyCxt* pCxt, SDropSuper
AUTH_TYPE_WRITE, pCxt->pMetaCache);
}
static int32_t collectMetaKeyFromDropVtable(SCollectMetaKeyCxt* pCxt, SDropVirtualTableStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
if (pStmt->withOpt) {
code = reserveTableUidInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
code = reserveDbVgInfoInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
}
} else {
code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
code =
reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache);
}
if (TSDB_CODE_SUCCESS == code) {
code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName,
pStmt->tableName, AUTH_TYPE_WRITE, pCxt->pMetaCache);
}
}
return code;
}
static int32_t collectMetaKeyFromAlterTable(SCollectMetaKeyCxt* pCxt, SAlterTableStmt* pStmt) {
int32_t code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
if (TSDB_CODE_SUCCESS == code) {
@ -443,6 +537,20 @@ static int32_t collectMetaKeyFromAlterStable(SCollectMetaKeyCxt* pCxt, SAlterTab
return code;
}
static int32_t collectMetaKeyFromAlterVtable(SCollectMetaKeyCxt* pCxt, SAlterTableStmt* pStmt) {
PAR_ERR_RET(reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache));
PAR_ERR_RET(reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache));
PAR_ERR_RET(reserveTableVgroupInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pStmt->tableName, pCxt->pMetaCache));
PAR_ERR_RET(reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->dbName, pStmt->tableName,
AUTH_TYPE_WRITE, pCxt->pMetaCache));
if (pStmt->alterType == TSDB_ALTER_TABLE_ALTER_COLUMN_REF || pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF) {
PAR_ERR_RET(reserveTableMetaInCache(pCxt->pParseCxt->acctId, pStmt->refDbName, pStmt->refTableName, pCxt->pMetaCache));
PAR_ERR_RET(reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pStmt->refDbName, pStmt->refTableName,
AUTH_TYPE_READ, pCxt->pMetaCache));
}
return TSDB_CODE_SUCCESS;
}
static int32_t collectMetaKeyFromUseDatabase(SCollectMetaKeyCxt* pCxt, SUseDatabaseStmt* pStmt) {
return reserveDbVgVersionInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache);
}
@ -1000,6 +1108,10 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
return collectMetaKeyFromFlushDatabase(pCxt, (SFlushDatabaseStmt*)pStmt);
case QUERY_NODE_CREATE_TABLE_STMT:
return collectMetaKeyFromCreateTable(pCxt, (SCreateTableStmt*)pStmt);
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return collectMetaKeyFromCreateVTable(pCxt, (SCreateVTableStmt*)pStmt);
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return collectMetaKeyFromCreateVSubTable(pCxt, (SCreateVSubTableStmt*)pStmt);
case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return collectMetaKeyFromCreateMultiTable(pCxt, (SCreateMultiTablesStmt*)pStmt);
case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE:
@ -1008,10 +1120,14 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
return collectMetaKeyFromDropTable(pCxt, (SDropTableStmt*)pStmt);
case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return collectMetaKeyFromDropStable(pCxt, (SDropSuperTableStmt*)pStmt);
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return collectMetaKeyFromDropVtable(pCxt, (SDropVirtualTableStmt*)pStmt);
case QUERY_NODE_ALTER_TABLE_STMT:
return collectMetaKeyFromAlterTable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
return collectMetaKeyFromAlterStable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
return collectMetaKeyFromAlterVtable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_USE_DATABASE_STMT:
return collectMetaKeyFromUseDatabase(pCxt, (SUseDatabaseStmt*)pStmt);
case QUERY_NODE_CREATE_INDEX_STMT:
@ -1063,6 +1179,7 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
case QUERY_NODE_SHOW_STREAMS_STMT:
return collectMetaKeyFromShowStreams(pCxt, (SShowStmt*)pStmt);
case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_VTABLES_STMT:
return collectMetaKeyFromShowTables(pCxt, (SShowStmt*)pStmt);
case QUERY_NODE_SHOW_FILESETS_STMT:
return collectMetaKeyFromShowFilesets(pCxt, (SShowStmt*)pStmt);
@ -1113,6 +1230,7 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) {
case QUERY_NODE_SHOW_CREATE_DATABASE_STMT:
return collectMetaKeyFromShowCreateDatabase(pCxt, (SShowCreateDatabaseStmt*)pStmt);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return collectMetaKeyFromShowCreateTable(pCxt, (SShowCreateTableStmt*)pStmt);
case QUERY_NODE_SHOW_CREATE_VIEW_STMT:

View File

@ -250,6 +250,10 @@ static int32_t authShowTables(SAuthCxt* pCxt, SShowStmt* pStmt) {
return checkAuth(pCxt, ((SValueNode*)pStmt->pDbName)->literal, NULL, AUTH_TYPE_READ_OR_WRITE, NULL);
}
static int32_t authShowVtables(SAuthCxt* pCxt, SShowStmt* pStmt) {
return authShowTables(pCxt, pStmt);
}
static int32_t authShowUsage(SAuthCxt* pCxt, SShowStmt* pStmt) {
return checkAuth(pCxt, ((SValueNode*)pStmt->pDbName)->literal, NULL, AUTH_TYPE_READ_OR_WRITE, NULL);
}
@ -274,6 +278,42 @@ static int32_t authCreateTable(SAuthCxt* pCxt, SCreateTableStmt* pStmt) {
return checkAuth(pCxt, pStmt->dbName, NULL, AUTH_TYPE_WRITE, &pTagCond);
}
static int32_t authCreateVTable(SAuthCxt* pCxt, SCreateVTableStmt* pStmt) {
PAR_ERR_RET(checkAuth(pCxt, pStmt->dbName, NULL, AUTH_TYPE_WRITE, NULL));
SNode *pCol = NULL;
FOREACH(pCol, pStmt->pCols) {
SColumnDefNode *pColDef = (SColumnDefNode*)pCol;
if (NULL == pColDef) {
PAR_ERR_RET(TSDB_CODE_PAR_INVALID_COLUMN);
}
SColumnOptions *pOptions = (SColumnOptions*)pColDef->pOptions;
if (pOptions && pOptions->hasRef) {
PAR_ERR_RET(checkAuth(pCxt, pOptions->refDb, pOptions->refTable, AUTH_TYPE_READ, NULL));
}
}
return TSDB_CODE_SUCCESS;
}
static int32_t authCreateVSubTable(SAuthCxt* pCxt, SCreateVSubTableStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
SNode *pNode = NULL;
SNodeList* pTmpList = pStmt->pSpecificColRefs ? pStmt->pSpecificColRefs : pStmt->pColRefs;
PAR_ERR_RET(checkAuth(pCxt, pStmt->dbName, NULL, AUTH_TYPE_WRITE, NULL));
if (NULL == pTmpList) {
// no column reference
return TSDB_CODE_SUCCESS;
}
FOREACH(pNode, pTmpList) {
SColumnRefNode *pColRef = (SColumnRefNode*)pNode;
if (NULL == pColRef) {
PAR_ERR_RET(TSDB_CODE_PAR_INVALID_COLUMN);
}
PAR_ERR_RET(checkAuth(pCxt, pColRef->refDbName, pColRef->refTableName, AUTH_TYPE_READ, NULL));
}
return code;
}
static int32_t authCreateMultiTable(SAuthCxt* pCxt, SCreateMultiTablesStmt* pStmt) {
int32_t code = TSDB_CODE_SUCCESS;
SNode* pNode = NULL;
@ -318,12 +358,28 @@ static int32_t authDropStable(SAuthCxt* pCxt, SDropSuperTableStmt* pStmt) {
return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL);
}
static int32_t authDropVtable(SAuthCxt* pCxt, SDropVirtualTableStmt* pStmt) {
if (pStmt->withOpt && !pCxt->pParseCxt->isSuperUser) {
return TSDB_CODE_PAR_PERMISSION_DENIED;
}
return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL);
}
static int32_t authAlterTable(SAuthCxt* pCxt, SAlterTableStmt* pStmt) {
SNode* pTagCond = NULL;
// todo check tag condition for subtable
return checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL);
}
static int32_t authAlterVTable(SAuthCxt* pCxt, SAlterTableStmt* pStmt) {
PAR_ERR_RET(checkAuth(pCxt, pStmt->dbName, pStmt->tableName, AUTH_TYPE_WRITE, NULL));
if (pStmt->alterType == TSDB_ALTER_TABLE_ADD_COLUMN_WITH_COLUMN_REF ||
pStmt->alterType == TSDB_ALTER_TABLE_ALTER_COLUMN_REF) {
PAR_ERR_RET(checkAuth(pCxt, pStmt->dbName, pStmt->refTableName, AUTH_TYPE_READ, NULL));
}
PAR_RET(TSDB_CODE_SUCCESS);
}
static int32_t authCreateView(SAuthCxt* pCxt, SCreateViewStmt* pStmt) {
#ifndef TD_ENTERPRISE
return TSDB_CODE_OPS_NOT_SUPPORT;
@ -352,15 +408,23 @@ static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) {
return authInsert(pCxt, (SInsertStmt*)pStmt);
case QUERY_NODE_CREATE_TABLE_STMT:
return authCreateTable(pCxt, (SCreateTableStmt*)pStmt);
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
return authCreateVTable(pCxt, (SCreateVTableStmt*)pStmt);
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return authCreateVSubTable(pCxt, (SCreateVSubTableStmt*)pStmt);
case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
return authCreateMultiTable(pCxt, (SCreateMultiTablesStmt*)pStmt);
case QUERY_NODE_DROP_TABLE_STMT:
return authDropTable(pCxt, (SDropTableStmt*)pStmt);
case QUERY_NODE_DROP_SUPER_TABLE_STMT:
return authDropStable(pCxt, (SDropSuperTableStmt*)pStmt);
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return authDropVtable(pCxt, (SDropVirtualTableStmt*)pStmt);
case QUERY_NODE_ALTER_TABLE_STMT:
case QUERY_NODE_ALTER_SUPER_TABLE_STMT:
return authAlterTable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
return authAlterVTable(pCxt, (SAlterTableStmt*)pStmt);
case QUERY_NODE_SHOW_DNODES_STMT:
case QUERY_NODE_SHOW_MNODES_STMT:
case QUERY_NODE_SHOW_MODULES_STMT:
@ -392,7 +456,10 @@ static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) {
case QUERY_NODE_SHOW_TABLES_STMT:
case QUERY_NODE_SHOW_STABLES_STMT:
return authShowTables(pCxt, (SShowStmt*)pStmt);
case QUERY_NODE_SHOW_VTABLES_STMT:
return authShowVtables(pCxt, (SShowStmt*)pStmt);
case QUERY_NODE_SHOW_CREATE_TABLE_STMT:
case QUERY_NODE_SHOW_CREATE_VTABLE_STMT:
case QUERY_NODE_SHOW_CREATE_STABLE_STMT:
return authShowCreateTable(pCxt, (SShowCreateTableStmt*)pStmt);
// case QUERY_NODE_SHOW_CREATE_VIEW_STMT:

View File

@ -365,7 +365,7 @@ static int32_t createConstantValue(SValueNode** ppNode) {
static int32_t calcConstProjections(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) {
SNode* pProj = NULL;
WHERE_EACH(pProj, pSelect->pProjectionList) {
if (subquery && !pSelect->isDistinct && !pSelect->tagScan && isUselessCol((SExprNode*)pProj)) {
if (subquery && !pSelect->isDistinct && !pSelect->tagScan && isUselessCol((SExprNode*)pProj) && (pSelect->pFromTable && nodeType(pSelect->pFromTable) != QUERY_NODE_VIRTUAL_TABLE)) {
ERASE_NODE(pSelect->pProjectionList);
continue;
}

View File

@ -313,8 +313,10 @@ static SKeyword keywordTable[] = {
{"VGROUPS", TK_VGROUPS},
{"VIEW", TK_VIEW},
{"VIEWS", TK_VIEWS},
{"VIRTUAL", TK_VIRTUAL},
{"VNODE", TK_VNODE},
{"VNODES", TK_VNODES},
{"VTABLE", TK_VTABLE},
{"WAL_FSYNC_PERIOD", TK_WAL_FSYNC_PERIOD},
{"WAL_LEVEL", TK_WAL_LEVEL},
{"WAL_RETENTION_PERIOD", TK_WAL_RETENTION_PERIOD},
@ -366,6 +368,8 @@ static SKeyword keywordTable[] = {
{"META_ONLY", TK_META_ONLY},
{"CONTINUOUS_WINDOW_CLOSE", TK_CONTINUOUS_WINDOW_CLOSE},
{"RECALCULATE", TK_RECALCULATE},
{"VTABLES", TK_VTABLES},
{"META_ONLY", TK_META_ONLY}
};
// clang-format on

File diff suppressed because it is too large Load Diff

View File

@ -232,6 +232,14 @@ static char* getSyntaxErrFormat(int32_t errCode) {
return "True_for duration cannot be negative";
case TSDB_CODE_PAR_TRUE_FOR_UNIT:
return "Cannot use 'year' or 'month' as true_for duration";
case TSDB_CODE_PAR_INVALID_REF_COLUMN:
return "Invalid virtual table's ref column";
case TSDB_CODE_PAR_INVALID_TABLE_TYPE:
return "Invalid table type";
case TSDB_CODE_PAR_INVALID_REF_COLUMN_TYPE:
return "Invalid virtual table's ref column type";
case TSDB_CODE_PAR_MISMATCH_STABLE_TYPE:
return "Create child table using virtual super table";
default:
return "Unknown error";
}
@ -334,17 +342,24 @@ STableMeta* tableMetaDup(const STableMeta* pTableMeta) {
bool hasSchemaExt = pTableMeta->schemaExt == NULL ? false : true;
size_t schemaExtSize = hasSchemaExt ? pTableMeta->tableInfo.numOfColumns * sizeof(SSchemaExt) : 0;
bool hasColRef = pTableMeta->colRef == NULL ? false : true;
size_t colRefSize = hasColRef ? pTableMeta->numOfColRefs * sizeof(SColRef) : 0;
size_t size = sizeof(STableMeta) + numOfFields * sizeof(SSchema);
STableMeta* p = taosMemoryMalloc(size + schemaExtSize);
STableMeta* p = taosMemoryMalloc(size + schemaExtSize + colRefSize);
if (NULL == p) return NULL;
memcpy(p, pTableMeta, schemaExtSize + size);
memcpy(p, pTableMeta, colRefSize + schemaExtSize + size);
if (hasSchemaExt) {
p->schemaExt = (SSchemaExt*)(((char*)p) + size);
} else {
p->schemaExt = NULL;
}
if (hasColRef) {
p->colRef = (SColRef*)(((char*)p) + size + schemaExtSize);
} else {
p->colRef = NULL;
}
return p;
}
@ -1074,7 +1089,8 @@ int32_t getTableNameFromCache(SParseMetaCache* pMetaCache, const SName* pName, c
sizeof(STableMeta) + sizeof(SSchema) * (pMeta->tableInfo.numOfColumns + pMeta->tableInfo.numOfTags);
int32_t schemaExtSize =
(withExtSchema(pMeta->tableType) && pMeta->schemaExt) ? sizeof(SSchemaExt) * pMeta->tableInfo.numOfColumns : 0;
const char* pTableName = (const char*)pMeta + metaSize + schemaExtSize;
int32_t colRefSize = (hasRefCol(pMeta->tableType) && pMeta->colRef) ? sizeof(SColRef) * pMeta->numOfColRefs : 0;
const char* pTableName = (const char*)pMeta + metaSize + schemaExtSize + colRefSize;
tstrncpy(pTbName, pTableName, TSDB_TABLE_NAME_LEN);
}
@ -1381,6 +1397,7 @@ STableCfg* tableCfgDup(STableCfg* pCfg) {
pNew->pTags = NULL;
pNew->pSchemas = NULL;
pNew->pSchemaExt = NULL;
pNew->pColRefs = NULL;
if (NULL != pCfg->pComment) {
pNew->pComment = taosMemoryCalloc(pNew->commentLen + 1, 1);
if (!pNew->pComment) goto err;
@ -1413,6 +1430,16 @@ STableCfg* tableCfgDup(STableCfg* pCfg) {
pNew->pSchemaExt = pSchemaExt;
SColRef *pColRef = NULL;
if (hasRefCol(pCfg->tableType) && pCfg->pColRefs) {
int32_t colRefSize = pCfg->numOfColumns * sizeof(SColRef);
pColRef = taosMemoryMalloc(colRefSize);
if (!pColRef) goto err;
memcpy(pColRef, pCfg->pColRefs, colRefSize);
}
pNew->pColRefs = pColRef;
return pNew;
err:
if (pNew->pComment) taosMemoryFreeClear(pNew->pComment);

View File

@ -0,0 +1 @@
---

View File

@ -65,10 +65,11 @@ void generateInformationSchema(MockCatalogService* mcs) {
.addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN)
.addColumn("stable_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN)
.done();
mcs->createTableBuilder(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_TABLES, TSDB_SYSTEM_TABLE, 3)
mcs->createTableBuilder(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_TABLES, TSDB_SYSTEM_TABLE, 4)
.addColumn("table_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN)
.addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN)
.addColumn("stable_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN)
.addColumn("type", TSDB_DATA_TYPE_BINARY, 23)
.done();
mcs->createTableBuilder(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_TABLE_DISTRIBUTED, TSDB_SYSTEM_TABLE, 2)
.addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN)

View File

@ -122,7 +122,7 @@ TEST_F(ParserSelectTest, timelineFunc) {
run("select diff(ts) from (select _wstart as ts, count(*) from st1 partition by tbname interval(1d) order by ts)");
run("select t1.* from st1s1 t1, (select _wstart as ts, count(*) from st1s2 partition by tbname interval(1d)) WHERE t1.ts = t2.ts", TSDB_CODE_PAR_NOT_SUPPORT_JOIN);
run("select t1.* from st1s1 t1, (select _wstart as ts, count(*) from st1s2 partition by tbname interval(1d)) t2 WHERE t1.ts = t2.ts");
run("select t1.* from st1s1 t1, (select _wstart as ts, count(*) from st1s2 partition by tbname interval(1d) order by ts) t2 WHERE t1.ts = t2.ts");
@ -505,8 +505,7 @@ TEST_F(ParserSelectTest, withoutFromSemanticCheck) {
TEST_F(ParserSelectTest, joinSemanticCheck) {
useDb("root", "test");
run("SELECT * FROM (SELECT tag1, SUM(c1) s FROM st1 GROUP BY tag1) t1, st1 t2 where t1.tag1 = t2.tag1",
TSDB_CODE_PAR_NOT_SUPPORT_JOIN);
run("SELECT * FROM (SELECT tag1, SUM(c1) s FROM st1 GROUP BY tag1) t1, st1 t2 where t1.tag1 = t2.tag1");
run("SELECT count(*) FROM t1 a join t1 b on a.ts=b.ts where a.ts=b.ts");
}

View File

@ -44,6 +44,32 @@ typedef struct SPhysiPlanContext {
#define planDebugL(param, ...) qDebugL("PLAN: " param, ##__VA_ARGS__)
#define planTrace(param, ...) qTrace("PLAN: " param, ##__VA_ARGS__)
#define PLAN_ERR_RET(c) \
do { \
int32_t _code = c; \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
return _code; \
} \
} while (0)
#define PLAN_RET(c) \
do { \
int32_t _code = c; \
if (_code != TSDB_CODE_SUCCESS) { \
terrno = _code; \
} \
return _code; \
} while (0)
#define PLAN_ERR_JRET(c) \
do { \
code = c; \
if (code != TSDB_CODE_SUCCESS) { \
terrno = code; \
goto _return; \
} \
} while (0)
int32_t generateUsageErrMsg(char* pBuf, int32_t len, int32_t errCode, ...);
int32_t createColumnByRewriteExprs(SNodeList* pExprs, SNodeList** pList);
int32_t createColumnByRewriteExpr(SNode* pExpr, SNodeList** pList);

View File

@ -324,6 +324,44 @@ static SNode* createFirstCol(SRealTableNode* pTable, const SSchema* pSchema) {
return (SNode*)pCol;
}
static SNode* createVtbFirstCol(SVirtualTableNode* pTable, const SSchema* pSchema) {
SColumnNode* pCol = NULL;
terrno = nodesMakeNode(QUERY_NODE_COLUMN, (SNode**)&pCol);
if (NULL == pCol) {
return NULL;
}
pCol->node.resType.type = pSchema->type;
pCol->node.resType.bytes = pSchema->bytes;
pCol->tableId = pTable->pMeta->uid;
pCol->colId = pSchema->colId;
pCol->colType = COLUMN_TYPE_COLUMN;
tstrncpy(pCol->tableAlias, pTable->table.tableAlias, TSDB_TABLE_NAME_LEN);
tstrncpy(pCol->tableName, pTable->table.tableName, TSDB_TABLE_NAME_LEN);
pCol->isPk = pSchema->flags & COL_IS_KEY;
pCol->tableHasPk = false;
pCol->numOfPKs = 0;
pCol->isPrimTs = true;
tstrncpy(pCol->colName, pSchema->name, TSDB_COL_NAME_LEN);
return (SNode*)pCol;
}
static int32_t addVtbPrimaryTsCol(SVirtualTableNode* pTable, SNodeList** pCols) {
bool found = false;
SNode* pCol = NULL;
SSchema* pSchema = &pTable->pMeta->schema[0];
FOREACH(pCol, *pCols) {
if (pSchema->colId == ((SColumnNode*)pCol)->colId) {
found = true;
break;
}
}
if (!found) {
return nodesListMakeStrictAppend(pCols, createVtbFirstCol(pTable, pSchema));
}
return TSDB_CODE_SUCCESS;
}
static int32_t addPrimaryTsCol(SRealTableNode* pTable, SNodeList** pCols) {
bool found = false;
SNode* pCol = NULL;
@ -492,7 +530,6 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
// rewrite the expression in subsequent clauses
if (TSDB_CODE_SUCCESS == code) {
SNodeList* pNewScanPseudoCols = NULL;
code = rewriteExprsForSelect(pScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM, NULL);
/*
if (TSDB_CODE_SUCCESS == code && NULL != pScan->pScanPseudoCols) {
@ -554,6 +591,28 @@ static int32_t createScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
} else {
nodesDestroyNode((SNode*)pScan);
}
pScan->virtualStableScan = false;
return code;
}
static int32_t createRefScanLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SRealTableNode* pRealTable,
SLogicNode** pLogicNode) {
SScanLogicNode* pScan = NULL;
int32_t code = makeScanLogicNode(pCxt, pRealTable, pSelect->hasRepeatScanFuncs, (SLogicNode**)&pScan);
pScan->node.groupAction = GROUP_ACTION_NONE;
pScan->node.resultDataOrder = DATA_ORDER_LEVEL_GLOBAL;
if (TSDB_CODE_SUCCESS == code) {
pScan->scanType = getScanType(pCxt, pScan->pScanPseudoCols, pScan->pScanCols, pScan->tableType, pSelect->tagScan);
}
if (TSDB_CODE_SUCCESS == code) {
code = addDefaultScanCol(pRealTable, &pScan->pScanCols);
}
*pLogicNode = (SLogicNode*)pScan;
pCxt->hasScan = true;
return code;
}
@ -720,8 +779,377 @@ static int32_t createJoinLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect
return code;
}
static int32_t findRefTableNode(SNodeList *refTableList, const char *dbName, const char *tableName, SNode **pRefTable) {
SNode *pRef = NULL;
FOREACH(pRef, refTableList) {
if (0 == strcasecmp(((SRealTableNode*)pRef)->table.tableName, tableName) &&
0 == strcasecmp(((SRealTableNode*)pRef)->table.dbName, dbName)) {
PLAN_RET(nodesCloneNode(pRef, pRefTable));
}
}
return TSDB_CODE_NOT_FOUND;
}
static int32_t findRefColId(SNode *pRefTable, const char *colName, col_id_t *colId) {
SRealTableNode *pRealTable = (SRealTableNode*)pRefTable;
for (int32_t i = 0; i < pRealTable->pMeta->tableInfo.numOfColumns; ++i) {
if (0 == strcasecmp(pRealTable->pMeta->schema[i].name, colName)) {
*colId = pRealTable->pMeta->schema[i].colId;
return TSDB_CODE_SUCCESS;
}
}
return TSDB_CODE_NOT_FOUND;
}
static int32_t scanAddCol(SLogicNode* pLogicNode, SColRef* colRef, STableNode* pVirtualTableNode, const SSchema* pSchema, col_id_t colId) {
int32_t code = TSDB_CODE_SUCCESS;
SColumnNode *pRefTableScanCol = NULL;
SScanLogicNode *pLogicScan = (SScanLogicNode*)pLogicNode;
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_COLUMN, (SNode**)&pRefTableScanCol));
if (colRef) {
tstrncpy(pRefTableScanCol->tableAlias, colRef->refTableName, sizeof(pRefTableScanCol->tableAlias));
tstrncpy(pRefTableScanCol->dbName, colRef->refDbName, sizeof(pRefTableScanCol->dbName));
tstrncpy(pRefTableScanCol->tableName, colRef->refTableName, sizeof(pRefTableScanCol->tableName));
tstrncpy(pRefTableScanCol->colName, colRef->refColName, sizeof(pRefTableScanCol->colName));
} else {
tstrncpy(pRefTableScanCol->tableAlias, pVirtualTableNode->tableAlias, sizeof(pRefTableScanCol->tableAlias));
tstrncpy(pRefTableScanCol->dbName, pVirtualTableNode->dbName, sizeof(pRefTableScanCol->dbName));
tstrncpy(pRefTableScanCol->tableName, pVirtualTableNode->tableName, sizeof(pRefTableScanCol->tableName));
tstrncpy(pRefTableScanCol->colName, pSchema->name, sizeof(pRefTableScanCol->colName));
}
// eliminate duplicate scan cols.
SNode *pCol = NULL;
FOREACH(pCol, pLogicScan->pScanCols) {
if (0 == strncmp(((SColumnNode*)pCol)->colName, pRefTableScanCol->colName, TSDB_COL_NAME_LEN) &&
0 == strncmp(((SColumnNode*)pCol)->tableName, pRefTableScanCol->tableName, TSDB_TABLE_NAME_LEN) &&
0 == strncmp(((SColumnNode*)pCol)->dbName, pRefTableScanCol->dbName, TSDB_DB_NAME_LEN)) {
nodesDestroyNode((SNode*)pRefTableScanCol);
return TSDB_CODE_SUCCESS;
}
}
pRefTableScanCol->colId = colId;
pRefTableScanCol->tableId = pLogicScan->tableId;
pRefTableScanCol->tableType = pLogicScan->tableType;
pRefTableScanCol->node.resType.type = pSchema->type;
pRefTableScanCol->node.resType.bytes = pSchema->bytes;
pRefTableScanCol->colType = COLUMN_TYPE_COLUMN;
pRefTableScanCol->isPk = false;
pRefTableScanCol->tableHasPk = false;
pRefTableScanCol->numOfPKs = 0;
pRefTableScanCol->hasRef = false;
pRefTableScanCol->hasDep = true;
PLAN_ERR_JRET(nodesListMakeAppend(&pLogicScan->pScanCols, (SNode*)pRefTableScanCol));
return code;
_return:
nodesDestroyNode((SNode*)pRefTableScanCol);
return code;
}
static int32_t checkColRefType(const SSchema* vtbSchema, const SSchema* refSchema) {
if (vtbSchema->type != refSchema->type || vtbSchema->bytes != refSchema->bytes) {
qError("virtual table column:%s type mismatch, virtual table column type:%d, bytes:%d, "
"ref table column:%s, type:%d, bytes:%d",
vtbSchema->name, vtbSchema->type, vtbSchema->bytes, refSchema->name, refSchema->type, refSchema->bytes);
return TSDB_CODE_PAR_INVALID_REF_COLUMN_TYPE;
}
return TSDB_CODE_SUCCESS;
}
static int32_t addSubScanNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SVirtualTableNode* pVirtualTable,
int32_t colRefIndex, int32_t schemaIndex, SHashObj *refTablesMap) {
int32_t code = TSDB_CODE_SUCCESS;
col_id_t colId = 0;
SColRef *pColRef = &pVirtualTable->pMeta->colRef[colRefIndex];
SNode *pRefTable = NULL;
SLogicNode *pRefScan = NULL;
bool put = false;
PLAN_ERR_JRET(findRefTableNode(pVirtualTable->refTables, pColRef->refDbName, pColRef->refTableName, &pRefTable));
PLAN_ERR_JRET(findRefColId(pRefTable, pColRef->refColName, &colId));
char tableNameKey[TSDB_TABLE_FNAME_LEN] = {0};
strcat(tableNameKey, pColRef->refDbName);
strcat(tableNameKey, ".");
strcat(tableNameKey, pColRef->refTableName);
SLogicNode **ppRefScan = (SLogicNode **)taosHashGet(refTablesMap, &tableNameKey, strlen(tableNameKey));
if (NULL == ppRefScan) {
PLAN_ERR_JRET(createRefScanLogicNode(pCxt, pSelect, (SRealTableNode*)pRefTable, &pRefScan));
PLAN_ERR_JRET(checkColRefType(&pVirtualTable->pMeta->schema[schemaIndex], &((SRealTableNode*)pRefTable)->pMeta->schema[colId - 1]));
PLAN_ERR_JRET(scanAddCol(pRefScan, pColRef, &pVirtualTable->table, &pVirtualTable->pMeta->schema[schemaIndex], colId));
PLAN_ERR_JRET(taosHashPut(refTablesMap, &tableNameKey, strlen(tableNameKey), &pRefScan, POINTER_BYTES));
put = true;
} else {
pRefScan = *ppRefScan;
PLAN_ERR_JRET(checkColRefType(&pVirtualTable->pMeta->schema[schemaIndex], &((SRealTableNode*)pRefTable)->pMeta->schema[colId - 1]));
PLAN_ERR_JRET(scanAddCol(pRefScan, pColRef, &pVirtualTable->table, &pVirtualTable->pMeta->schema[schemaIndex], colId));
}
nodesDestroyNode((SNode*)pRefTable);
return code;
_return:
nodesDestroyNode((SNode*)pRefTable);
if (!put) {
nodesDestroyNode((SNode*)pRefScan);
}
return code;
}
static int32_t makeVirtualScanLogicNode(SLogicPlanContext* pCxt, SVirtualTableNode* pVirtualTable,
SVirtualScanLogicNode* pScan) {
TSWAP(pScan->pVgroupList, pVirtualTable->pVgroupList);
pScan->tableId = pVirtualTable->pMeta->uid;
pScan->stableId = pVirtualTable->pMeta->suid;
pScan->tableType = pVirtualTable->pMeta->tableType;
pScan->tableName.type = TSDB_TABLE_NAME_T;
pScan->tableName.acctId = pCxt->pPlanCxt->acctId;
tstrncpy(pScan->tableName.dbname, pVirtualTable->table.dbName, TSDB_DB_NAME_LEN);
tstrncpy(pScan->tableName.tname, pVirtualTable->table.tableName, TSDB_TABLE_NAME_LEN);
return TSDB_CODE_SUCCESS;
}
static void destroyScanLogicNode(void* data) {
if (data == NULL) {
return;
}
SScanLogicNode* pNode = *(SScanLogicNode **)data;
nodesDestroyNode((SNode*)pNode);
}
static int32_t findColRefIndex(SColRef* pColRef, SVirtualTableNode* pVirtualTable, col_id_t colId) {
for (int32_t i = 0; i < pVirtualTable->pMeta->numOfColRefs; i++) {
if (pColRef[i].hasRef && pColRef[i].id == colId) {
return i;
}
}
return -1;
}
static int32_t findSchemaIndex(const SSchema* pSchema, int32_t numOfColumns, col_id_t colId) {
for (int32_t i = 0; i < numOfColumns; i++) {
if (pSchema[i].colId == colId) {
return i;
}
}
return -1;
}
static int32_t eliminateDupScanCols(SNodeList* pScanCols) {
int32_t code = TSDB_CODE_SUCCESS;
SNode* pCols = NULL;
SHashObj* colsMap = taosHashInit(LIST_LENGTH(pScanCols), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
if (NULL == colsMap) {
return terrno;
}
FOREACH(pCols, pScanCols) {
SColumnNode* pCol = (SColumnNode*)pCols;
if (!pCol->hasRef) {
continue;
}
char key[TSDB_COL_FNAME_EX_LEN] = {0};
strcat(key, pCol->refDbName);
strcat(key, ".");
strcat(key, pCol->refTableName);
strcat(key, ".");
strcat(key, pCol->refColName);
if (NULL != taosHashGet(colsMap, key, strlen(key))) {
ERASE_NODE(pScanCols);
} else {
PLAN_ERR_JRET(taosHashPut(colsMap, key, strlen(key), NULL, 0));
}
}
_return:
taosHashCleanup(colsMap);
return code;
}
static int32_t createVirtualSuperTableLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
SVirtualTableNode* pVirtualTable, SVirtualScanLogicNode* pVtableScan,
SLogicNode** pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
SLogicNode* pRealTableScan = NULL;
SDynQueryCtrlLogicNode* pDynCtrl = NULL;
SNode* pNode = NULL;
bool scanAllCols = true;
// Virtual table scan node -> Real table scan node
PLAN_ERR_JRET(createScanLogicNode(pCxt, pSelect, (SRealTableNode*)nodesListGetNode(pVirtualTable->refTables, 0), &pRealTableScan));
PLAN_ERR_JRET(addVtbPrimaryTsCol(pVirtualTable, &pVtableScan->pScanCols));
FOREACH(pNode, pVtableScan->pScanCols) {
SColumnNode *pCol = (SColumnNode*)pNode;
if (pCol->isPrimTs || pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
// do nothing
} else {
scanAllCols &= false;
}
}
if (scanAllCols) {
nodesDestroyList(((SScanLogicNode*)pRealTableScan)->node.pTargets);
((SScanLogicNode*)pRealTableScan)->node.pTargets = NULL;
pVtableScan->scanAllCols = true;
for (int32_t i = 0; i < pVirtualTable->pMeta->tableInfo.numOfColumns; i++) {
if (pVirtualTable->pMeta->schema[i].colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
continue;
} else {
PLAN_ERR_JRET(scanAddCol(pRealTableScan, NULL, &pVirtualTable->table, &pVirtualTable->pMeta->schema[i], pVirtualTable->pMeta->schema[i].colId));
}
}
PLAN_ERR_JRET(createColumnByRewriteExprs(((SScanLogicNode*)pRealTableScan)->pScanCols, &((SScanLogicNode*)pRealTableScan)->node.pTargets));
}
((SScanLogicNode *)pRealTableScan)->node.dynamicOp = true;
((SScanLogicNode *)pRealTableScan)->virtualStableScan = true;
PLAN_ERR_JRET(nodesListStrictAppend(pVtableScan->node.pChildren, (SNode*)(pRealTableScan)));
pRealTableScan->pParent = (SLogicNode *)pVtableScan;
PLAN_ERR_JRET(createColumnByRewriteExprs(pVtableScan->pScanCols, &pVtableScan->node.pTargets));
PLAN_ERR_JRET(createColumnByRewriteExprs(pVtableScan->pScanPseudoCols, &pVtableScan->node.pTargets));
// Dynamic query control node -> Virtual table scan node -> Real table scan node
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL, (SNode**)&pDynCtrl));
pDynCtrl->qType = DYN_QTYPE_VTB_SCAN;
pDynCtrl->vtbScan.scanAllCols = pVtableScan->scanAllCols;
pDynCtrl->vtbScan.suid = pVtableScan->stableId;
PLAN_ERR_JRET(nodesListMakeStrictAppend(&pDynCtrl->node.pChildren, (SNode*)pVtableScan));
PLAN_ERR_JRET(nodesCloneList(pVtableScan->node.pTargets, &pDynCtrl->node.pTargets));
TSWAP(pVtableScan->pVgroupList, pDynCtrl->vtbScan.pVgroupList);
pVtableScan->node.pParent = (SLogicNode*)pDynCtrl;
pVtableScan->node.dynamicOp = true;
*pLogicNode = (SLogicNode*)pDynCtrl;
pCxt->pPlanCxt->virtualStableQuery = true;
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
nodesDestroyNode((SNode*)pRealTableScan);
nodesDestroyNode((SNode*)pDynCtrl);
return code;
}
static int32_t createVirtualNormalChildTableLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
SVirtualTableNode* pVirtualTable, SVirtualScanLogicNode* pVtableScan,
SLogicNode** pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
SNode* pNode = NULL;
int32_t slotId = 0;
bool scanAllCols = true;
SHashObj* pRefTablesMap = NULL;
pRefTablesMap = taosHashInit(LIST_LENGTH(pVtableScan->pScanCols), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
if (NULL == pRefTablesMap) {
PLAN_ERR_JRET(terrno);
}
PLAN_ERR_JRET(eliminateDupScanCols(pVtableScan->pScanCols));
FOREACH(pNode, pVtableScan->pScanCols) {
SColumnNode *pCol = (SColumnNode*)pNode;
int32_t colRefIndex = findColRefIndex(pVirtualTable->pMeta->colRef, pVirtualTable, pCol->colId);
int32_t schemaIndex = findSchemaIndex(pVirtualTable->pMeta->schema, pVirtualTable->pMeta->tableInfo.numOfColumns, pCol->colId);
if (colRefIndex != -1 && pVirtualTable->pMeta->colRef[colRefIndex].hasRef) {
if (pCol->isPrimTs || pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
PLAN_ERR_JRET(TSDB_CODE_VTABLE_PRIMTS_HAS_REF);
}
scanAllCols &= false;
PLAN_ERR_JRET(addSubScanNode(pCxt, pSelect, pVirtualTable, colRefIndex, schemaIndex, pRefTablesMap));
} else if (pCol->isPrimTs || pCol->colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
// do nothing
} else {
scanAllCols &= false;
}
}
if (scanAllCols) {
pVtableScan->scanAllCols = true;
taosHashClear(pRefTablesMap);
for (int32_t i = 0; i < pVirtualTable->pMeta->tableInfo.numOfColumns; i++) {
if (pVirtualTable->pMeta->schema[i].colId == PRIMARYKEY_TIMESTAMP_COL_ID) {
continue;
} else {
col_id_t colRefIndex = (col_id_t)findColRefIndex(pVirtualTable->pMeta->colRef, pVirtualTable, pVirtualTable->pMeta->schema[i].colId);
if (colRefIndex != -1 && pVirtualTable->pMeta->colRef[colRefIndex].hasRef) {
PLAN_ERR_JRET(addSubScanNode(pCxt, pSelect, pVirtualTable, colRefIndex, i, pRefTablesMap));
}
}
}
}
// Iterate the table map, build scan logic node for each origin table and add these node to vtable scan's child list.
void* pIter = NULL;
while ((pIter = taosHashIterate(pRefTablesMap, pIter))) {
SScanLogicNode **pRefScanNode = (SScanLogicNode**)pIter;
PLAN_ERR_JRET(createColumnByRewriteExprs((*pRefScanNode)->pScanCols, &(*pRefScanNode)->node.pTargets));
PLAN_ERR_JRET(nodesListStrictAppend(pVtableScan->node.pChildren, (SNode*)(*pRefScanNode)));
}
// set output
PLAN_ERR_JRET(createColumnByRewriteExprs(pVtableScan->pScanCols, &pVtableScan->node.pTargets));
PLAN_ERR_JRET(createColumnByRewriteExprs(pVtableScan->pScanPseudoCols, &pVtableScan->node.pTargets));
*pLogicNode = (SLogicNode*)pVtableScan;
taosHashCleanup(pRefTablesMap);
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
taosHashSetFreeFp(pRefTablesMap, destroyScanLogicNode);
taosHashCleanup(pRefTablesMap);
return code;
}
static int32_t createVirtualTableLogicNode(SLogicPlanContext* pCxt, SSelectStmt* pSelect,
SVirtualTableNode* pVirtualTable, SLogicNode** pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
SVirtualScanLogicNode *pVtableScan = NULL;
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN, (SNode**)&pVtableScan));
PLAN_ERR_JRET(nodesMakeList(&pVtableScan->node.pChildren));
PLAN_ERR_JRET(makeVirtualScanLogicNode(pCxt, pVirtualTable, pVtableScan));
PLAN_ERR_JRET(nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pVirtualTable->table.tableAlias, COLLECT_COL_TYPE_COL,
&pVtableScan->pScanCols));
PLAN_ERR_JRET(nodesCollectColumns(pSelect, SQL_CLAUSE_FROM, pVirtualTable->table.tableAlias, COLLECT_COL_TYPE_TAG,
&pVtableScan->pScanPseudoCols));
PLAN_ERR_JRET(nodesCollectFuncs(pSelect, SQL_CLAUSE_FROM, pVirtualTable->table.tableAlias, fmIsScanPseudoColumnFunc,
&pVtableScan->pScanPseudoCols));
PLAN_ERR_JRET(rewriteExprsForSelect(pVtableScan->pScanPseudoCols, pSelect, SQL_CLAUSE_FROM, NULL));
switch (pVtableScan->tableType) {
case TSDB_SUPER_TABLE:
PLAN_ERR_JRET(createVirtualSuperTableLogicNode(pCxt, pSelect, pVirtualTable, pVtableScan, pLogicNode));
break;
case TSDB_VIRTUAL_NORMAL_TABLE:
case TSDB_VIRTUAL_CHILD_TABLE:
PLAN_ERR_JRET(createVirtualNormalChildTableLogicNode(pCxt, pSelect, pVirtualTable, pVtableScan, pLogicNode));
break;
default:
PLAN_ERR_JRET(TSDB_CODE_PLAN_INVALID_TABLE_TYPE);
}
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
nodesDestroyNode((SNode*)pVtableScan);
return code;
}
static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
SLogicNode** pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
switch (nodeType(pTable)) {
case QUERY_NODE_REAL_TABLE:
return createScanLogicNode(pCxt, pSelect, (SRealTableNode*)pTable, pLogicNode);
@ -729,27 +1157,38 @@ static int32_t doCreateLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pS
return createSubqueryLogicNode(pCxt, pSelect, (STempTableNode*)pTable, pLogicNode);
case QUERY_NODE_JOIN_TABLE:
return createJoinLogicNode(pCxt, pSelect, (SJoinTableNode*)pTable, pLogicNode);
case QUERY_NODE_VIRTUAL_TABLE:
return createVirtualTableLogicNode(pCxt, pSelect, (SVirtualTableNode*)pTable, pLogicNode);
default:
code = TSDB_CODE_PLAN_INVALID_TABLE_TYPE;
break;
}
return TSDB_CODE_FAILED;
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
return code;
}
static int32_t createLogicNodeByTable(SLogicPlanContext* pCxt, SSelectStmt* pSelect, SNode* pTable,
SLogicNode** pLogicNode) {
SLogicNode* pNode = NULL;
int32_t code = doCreateLogicNodeByTable(pCxt, pSelect, pTable, &pNode);
if (TSDB_CODE_SUCCESS == code) {
int32_t code = TSDB_CODE_SUCCESS;
PLAN_ERR_JRET(doCreateLogicNodeByTable(pCxt, pSelect, pTable, &pNode));
if (nodeType(pNode) == QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL) {
SLogicNode* pVScan = (SLogicNode*)nodesListGetNode(((SDynQueryCtrlLogicNode*)pNode)->node.pChildren, 0);
pVScan->pConditions = NULL;
PLAN_ERR_JRET(nodesCloneNode(pSelect->pWhere, &pVScan->pConditions));
} else {
pNode->pConditions = NULL;
code = nodesCloneNode(pSelect->pWhere, &pNode->pConditions);
if (NULL != pSelect->pWhere && NULL == pNode->pConditions) {
nodesDestroyNode((SNode*)pNode);
return code;
}
pNode->precision = pSelect->precision;
*pLogicNode = pNode;
pCxt->pCurrRoot = pNode;
PLAN_ERR_JRET(nodesCloneNode(pSelect->pWhere, &pNode->pConditions));
}
pNode->precision = pSelect->precision;
*pLogicNode = pNode;
pCxt->pCurrRoot = pNode;
return code;
_return:
planError("%s failed since %s", __func__, tstrerror(code));
nodesDestroyNode((SNode*)pNode);
return code;
}
@ -2065,10 +2504,14 @@ static int32_t getMsgType(ENodeType sqlType) {
case QUERY_NODE_CREATE_TABLE_STMT:
case QUERY_NODE_CREATE_MULTI_TABLES_STMT:
case QUERY_NODE_CREATE_SUBTABLE_FROM_FILE_CLAUSE:
case QUERY_NODE_CREATE_VIRTUAL_TABLE_STMT:
case QUERY_NODE_CREATE_VIRTUAL_SUBTABLE_STMT:
return TDMT_VND_CREATE_TABLE;
case QUERY_NODE_DROP_TABLE_STMT:
case QUERY_NODE_DROP_VIRTUAL_TABLE_STMT:
return TDMT_VND_DROP_TABLE;
case QUERY_NODE_ALTER_TABLE_STMT:
case QUERY_NODE_ALTER_VIRTUAL_TABLE_STMT:
return TDMT_VND_ALTER_TABLE;
case QUERY_NODE_FLUSH_DATABASE_STMT:
return TDMT_VND_COMMIT;

View File

@ -2190,6 +2190,14 @@ static int32_t pdcTrivialPushDown(SOptimizeContext* pCxt, SLogicNode* pLogicNode
return code;
}
static int32_t pdcDealVirtualTable(SOptimizeContext* pCxt, SVirtualScanLogicNode* pVScan) {
// TODO: remove it after full implementation of pushing down to child
if (1 != LIST_LENGTH(pVScan->node.pChildren) || 0 != LIST_LENGTH(pVScan->pScanPseudoCols) || pVScan->tableType == TSDB_SUPER_TABLE) {
return TSDB_CODE_SUCCESS;
}
return pdcTrivialPushDown(pCxt, (SLogicNode*)pVScan);
}
static int32_t pdcOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
int32_t code = TSDB_CODE_SUCCESS;
switch (nodeType(pLogicNode)) {
@ -2209,6 +2217,9 @@ static int32_t pdcOptimizeImpl(SOptimizeContext* pCxt, SLogicNode* pLogicNode) {
case QUERY_NODE_LOGIC_PLAN_PARTITION:
code = pdcTrivialPushDown(pCxt, pLogicNode);
break;
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
code = pdcDealVirtualTable(pCxt, (SVirtualScanLogicNode*)pLogicNode);
break;
default:
break;
}
@ -3525,7 +3536,8 @@ static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode, void* pCtx) {
if (NULL != pNode->pParent &&
(QUERY_NODE_LOGIC_PLAN_PROJECT != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) ||
QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0)) ||
QUERY_NODE_LOGIC_PLAN_JOIN != nodeType(pNode->pParent))) {
QUERY_NODE_LOGIC_PLAN_JOIN != nodeType(pNode->pParent) ||
QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN != nodeType(pNode->pParent))) {
return false;
}
@ -3538,6 +3550,9 @@ static bool eliminateProjOptMayBeOptimized(SLogicNode* pNode, void* pCtx) {
if (LIST_LENGTH(pChild->pTargets) != LIST_LENGTH(pNode->pTargets)) {
return false;
}
if (((SDynQueryCtrlLogicNode*)pChild)->qType == DYN_QTYPE_VTB_SCAN) {
return false;
}
}
SProjectLogicNode* pProjectNode = (SProjectLogicNode*)pNode;
@ -3594,6 +3609,9 @@ static bool eliminateProjOptCanChildConditionUseChildTargets(SLogicNode* pChild,
if (!cxt.canUse) return false;
}
if (QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN == nodeType(pChild)) {
return false;
}
if (QUERY_NODE_LOGIC_PLAN_JOIN == nodeType(pChild) && ((SJoinLogicNode*)pChild)->joinAlgo != JOIN_ALGO_UNKNOWN) {
return false;
}
@ -4161,8 +4179,7 @@ static int32_t rewriteUniqueOptCreateProjectCol(SFunctionNode* pFunc, SNode** pp
if (FUNCTION_TYPE_UNIQUE == pFunc->funcType) {
SExprNode* pExpr = (SExprNode*)nodesListGetNode(pFunc->pParameterList, 0);
if (QUERY_NODE_COLUMN == nodeType(pExpr)) {
tstrncpy(pCol->tableAlias, ((SColumnNode*)pExpr)->tableAlias, TSDB_TABLE_NAME_LEN);
tstrncpy(pCol->colName, ((SColumnNode*)pExpr)->colName, TSDB_COL_NAME_LEN);
PLAN_ERR_RET(nodesCloneNode((SNode*)pExpr, (SNode**)&pCol));
} else {
tstrncpy(pCol->colName, pExpr->aliasName, TSDB_COL_NAME_LEN);
}
@ -6207,6 +6224,7 @@ static int32_t stbJoinOptCreateTagScanNode(SLogicNode* pJoin, SNodeList** ppList
}
SScanLogicNode* pScan = (SScanLogicNode*)pNode;
// If join node's two children are scan on same table and on only one vgroup, don't need to split. Vice versa.
if (pScan->pVgroupList && 1 == pScan->pVgroupList->numOfVgroups) {
if (NULL == pPrev || 0 == strcmp(pPrev->dbname, pScan->tableName.dbname)) {
pPrev = &pScan->tableName;
@ -7707,6 +7725,289 @@ static int32_t tsmaOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan
return code;
}
static bool eliminateVirtualScanMayBeOptimized(SLogicNode* pNode, void* pCtx) {
if (NULL == pNode->pParent) {
return false;
}
if (nodeType(pNode) != QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN || LIST_LENGTH(pNode->pChildren) != 1) {
return false;
}
if (pNode->pConditions || ((SVirtualScanLogicNode *)pNode)->pScanPseudoCols) {
return false;
}
SVirtualScanLogicNode* pVScan = (SVirtualScanLogicNode *)pNode;
SNode* pCol;
FOREACH(pCol, pVScan->pScanCols) {
SColumnNode* pScanCol = (SColumnNode* )pCol;
if (!pScanCol->hasRef) {
// if col don't have ref, it can't be eliminated. If the vscan operator is eliminated,
// the upper operator can't find the right slot id.
return false;
}
}
return true;
}
static int32_t eliminateVirtualScanOptimizeImpl(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan,
SLogicNode* pVirtualScanNode) {
SNode* pTargets = NULL;
SNode* pSibling = NULL;
FOREACH(pSibling, pVirtualScanNode->pParent->pChildren) {
if (nodesEqualNode(pSibling, (SNode*)pVirtualScanNode)) {
SNode* pChild;
FOREACH(pChild, pVirtualScanNode->pChildren) {
// clear the mask to try scanPathOptimize again.
OPTIMIZE_FLAG_CLEAR_MASK(((SScanLogicNode*)pChild)->node.optimizedFlag, OPTIMIZE_FLAG_SCAN_PATH);
((SLogicNode*)pChild)->pParent = pVirtualScanNode->pParent;
}
INSERT_LIST(pVirtualScanNode->pParent->pChildren, pVirtualScanNode->pChildren);
pVirtualScanNode->pChildren = NULL;
ERASE_NODE(pVirtualScanNode->pParent->pChildren);
pCxt->optimized = true;
return TSDB_CODE_SUCCESS;
}
}
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
// eliminate virtual scan node when it has only one child
static int32_t eliminateVirtualScanOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
SLogicNode* pVirtualScanNode = optFindPossibleNode(pLogicSubplan->pNode, eliminateVirtualScanMayBeOptimized, NULL);
if (NULL == pVirtualScanNode) {
return TSDB_CODE_SUCCESS;
}
return eliminateVirtualScanOptimizeImpl(pCxt, pLogicSubplan, pVirtualScanNode);
}
static bool pdaMayBeOptimized(SLogicNode* pNode, void* pCtx) {
if (QUERY_NODE_LOGIC_PLAN_AGG != nodeType(pNode) || 1 != LIST_LENGTH(pNode->pChildren) ||
QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN != nodeType(nodesListGetNode(pNode->pChildren, 0))) {
return false;
}
// virtual table scan should have more than one child.
if (LIST_LENGTH(((SVirtualScanLogicNode *)nodesListGetNode(pNode->pChildren, 0))->node.pChildren) < 2) {
return false;
}
SVirtualScanLogicNode* pVScan = (SVirtualScanLogicNode *)nodesListGetNode(pNode->pChildren, 0);
SNode* pCol;
FOREACH(pCol, pVScan->pScanCols) {
SColumnNode* pScanCol = (SColumnNode* )pCol;
if (!pScanCol->hasRef) {
// if col don't have ref, it can't be eliminated. If the vscan operator is eliminated,
// the upper operator can't find the right slot id.
return false;
}
}
SAggLogicNode* pAgg = (SAggLogicNode*)pNode;
SNode* pAggFunc = NULL;
FOREACH(pAggFunc, pAgg->pAggFuncs) {
SFunctionNode *pFunc = (SFunctionNode *)pAggFunc;
if (fmIsSelectFunc(pFunc->funcId) || fmIsGroupKeyFunc(pFunc->funcId)) {
return false;
}
}
if (pAgg->hasGroup || 0 != LIST_LENGTH(pAgg->pTsmaSubplans) || NULL != pAgg->node.pConditions ||
NULL != pAgg->node.pLimit || NULL != pAgg->node.pSlimit) {
return false;
}
return true;
}
static int32_t findDepTableScanNode(SColumnNode* pCol, SVirtualScanLogicNode *pVScan, SNode **ppNode) {
int32_t code = TSDB_CODE_SUCCESS;
SNode *pScan = NULL;
FOREACH(pScan, pVScan->node.pChildren) {
SScanLogicNode *pScanNode = (SScanLogicNode *)pScan;
SNode *pScanCol = NULL;
FOREACH(pScanCol, pScanNode->pScanCols) {
if (QUERY_NODE_COLUMN == nodeType(pScanCol)) {
SColumnNode *pScanColNode = (SColumnNode *)pScanCol;
if (pScanColNode->hasDep && pCol->hasRef) {
if (strcmp(pScanColNode->dbName, pCol->refDbName) == 0 &&
strcmp(pScanColNode->tableAlias, pCol->refTableName) == 0 &&
strcmp(pScanColNode->colName, pCol->refColName) == 0) {
PLAN_RET(nodesCloneNode(pScan, ppNode));
}
} else {
// TODO(smj): make a proper error code.
*ppNode = NULL;
planError("column %s.%s has no depend column", pCol->tableAlias, pCol->colName);
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
}
}
}
*ppNode = NULL;
planError("column %s.%s's depend column not found in virtual scan node", pCol->tableAlias, pCol->colName);
// TODO(smj): make a proper error code.
return TSDB_CODE_PLAN_INTERNAL_ERROR;
}
static int32_t mergeAggFuncToAggNode(SAggLogicNode* pAgg, SFunctionNode* pFunc) {
int32_t code = TSDB_CODE_SUCCESS;
SNode *ppFuncNode = NULL;
PLAN_ERR_JRET(nodesCloneNode((SNode *)pFunc, &ppFuncNode));
PLAN_ERR_JRET(nodesListMakeAppend(&pAgg->pAggFuncs, (SNode *)ppFuncNode));
pAgg->hasLast |= fmIsLastFunc(((SFunctionNode *)ppFuncNode)->funcId);
pAgg->hasLastRow |= fmIsLastRowFunc(((SFunctionNode *)ppFuncNode)->funcId);
pAgg->hasTimeLineFunc |= fmIsTimelineFunc(((SFunctionNode *)ppFuncNode)->funcId);
pAgg->onlyHasKeepOrderFunc &= fmIsKeepOrderFunc(((SFunctionNode *)ppFuncNode)->funcId);
pAgg->hasGroupKeyOptimized = false;
pAgg->hasGroup = false;
pAgg->isGroupTb = false;
pAgg->isPartTb = false;
return code;
_return:
nodesDestroyNode(ppFuncNode);
return code;
}
static int32_t rebuildPlanForPdaOptimize(SColumnNode* pCol, SFunctionNode* pAggFunc, SVirtualScanLogicNode* pVScan,
SHashObj* pAggNodeMap) {
int32_t code = TSDB_CODE_SUCCESS;
SScanLogicNode* pDepScan = NULL;
SAggLogicNode* pAggNode = NULL;
bool append = false;
SAggLogicNode** pNodeFound = NULL;
// pAggNodeMap is a hash map, the key is the vtable's origin table's name, the value is the SAggLogicNode ptr.
// if 2 more agg func has the same origin table, we should merge them into one agg node.
PLAN_ERR_JRET(findDepTableScanNode(pCol, pVScan, (SNode**)&pDepScan));
char tableFNameKey[TSDB_COL_FNAME_LEN + 1] = {0};
TAOS_STRNCAT(tableFNameKey, pDepScan->tableName.tname, TSDB_TABLE_NAME_LEN);
TAOS_STRNCAT(tableFNameKey, ".", 2);
TAOS_STRNCAT(tableFNameKey, pCol->colName, TSDB_COL_NAME_LEN);
pNodeFound = (SAggLogicNode **)taosHashGet(pAggNodeMap, &tableFNameKey, strlen(tableFNameKey));
if (NULL == pNodeFound) {
// make new agg node.
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_LOGIC_PLAN_AGG, (SNode**)&pAggNode));
PLAN_ERR_JRET(mergeAggFuncToAggNode(pAggNode, pAggFunc));
PLAN_ERR_JRET(nodesListMakeAppend(&pAggNode->node.pChildren, (SNode*)pDepScan));
append = true;
PLAN_ERR_JRET(taosHashPut(pAggNodeMap, &tableFNameKey, strlen(tableFNameKey), &pAggNode, POINTER_BYTES));
} else {
pAggNode = *pNodeFound;
// merge the agg func to the existed agg node.
PLAN_ERR_JRET(mergeAggFuncToAggNode(pAggNode, pAggFunc));
nodesDestroyNode((SNode*)pDepScan);
}
return code;
_return:
if (!append) {
nodesDestroyNode((SNode*)pDepScan);
}
return code;
}
static void destroyAggLogicNode(void* data) {
if (data == NULL) {
return;
}
SAggLogicNode* pNode = *(SAggLogicNode **)data;
nodesDestroyNode((SNode*)pNode);
}
// This optimization rule will optimize plan tree from
// Agg -> VirtualScan -> TableScan
// \> TableScan
// \> TableScan
// to
// Merge -> Agg -> TableScan
// \> Agg -> TableScan
// \> Agg -> TableScan
static int32_t pdaOptimize(SOptimizeContext* pCxt, SLogicSubplan* pLogicSubplan) {
int32_t code = TSDB_CODE_SUCCESS;
SMergeLogicNode* pMerge = NULL;
SAggLogicNode* pAgg = (SAggLogicNode*)optFindPossibleNode(pLogicSubplan->pNode, pdaMayBeOptimized, &code);
if (NULL == pAgg) {
return code;
}
SVirtualScanLogicNode *pVScan = (SVirtualScanLogicNode*)nodesListGetNode(pAgg->node.pChildren, 0);
SNode *pAggFunc = NULL;
SHashObj *pAggNodeMap = taosHashInit(LIST_LENGTH(pAgg->pAggFuncs), taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK);
if (NULL == pAggNodeMap) {
PLAN_ERR_JRET(terrno);
}
FOREACH(pAggFunc, pAgg->pAggFuncs) {
SFunctionNode *pFunc = (SFunctionNode *)pAggFunc;
SNode *pParam = NULL;
FOREACH(pParam, pFunc->pParameterList) {
if (QUERY_NODE_COLUMN == nodeType(pParam)) {
SColumnNode *pCol = (SColumnNode *)pParam;
if (pCol->colType == COLUMN_TYPE_TAG) {
// If the column is a tag column, we should not optimize the aggregation. Since tag will be read from the
// virtual tablescan operator.
goto _return;
}
PLAN_ERR_JRET(rebuildPlanForPdaOptimize(pCol, pFunc, pVScan, pAggNodeMap));
}
}
}
if (taosHashGetSize(pAggNodeMap) != LIST_LENGTH(pVScan->node.pChildren)) {
// The number of agg nodes should be equal to the number of virtual scan nodes.
// If not, it means that some virtual scan nodes are not used in the aggregation.
// In this case, we should not optimize the aggregation.
goto _return;
}
PLAN_ERR_JRET(nodesMakeNode(QUERY_NODE_LOGIC_PLAN_MERGE, (SNode**)&pMerge));
pMerge->colsMerge = true;
pMerge->numOfChannels = LIST_LENGTH(pAgg->pAggFuncs);
pMerge->srcGroupId = -1;
pMerge->node.precision = pAgg->node.precision;
void *pIter = NULL;
while ((pIter = taosHashIterate(pAggNodeMap, pIter))) {
SAggLogicNode **pAggNode = (SAggLogicNode**)pIter;
(*pAggNode)->node.pParent = (SLogicNode*)pMerge;
SNode* pNode = NULL;
FOREACH(pNode, (*pAggNode)->node.pChildren) {
// clear the mask to try scanPathOptimize again.
OPTIMIZE_FLAG_CLEAR_MASK(((SScanLogicNode*)pNode)->node.optimizedFlag, OPTIMIZE_FLAG_SCAN_PATH);
((SLogicNode*)pNode)->pParent = (SLogicNode*)*pAggNode;
}
PLAN_ERR_JRET(createColumnByRewriteExprs((*pAggNode)->pAggFuncs, &(*pAggNode)->node.pTargets));
PLAN_ERR_JRET(nodesListMakeAppend(&pMerge->node.pChildren, (SNode*)*pAggNode));
FOREACH(pNode, (*pAggNode)->node.pTargets) {
PLAN_ERR_JRET(nodesListMakeStrictAppend(&pMerge->node.pTargets, pNode));
}
}
PLAN_ERR_JRET(replaceLogicNode(pLogicSubplan, (SLogicNode*)pAgg, (SLogicNode*)pMerge));
nodesDestroyNode((SNode*)pVScan);
nodesDestroyNode((SNode*)pAgg);
taosHashCleanup(pAggNodeMap);
pCxt->optimized = true;
return code;
_return:
nodesDestroyNode((SNode*)pMerge);
taosHashSetFreeFp(pAggNodeMap, destroyAggLogicNode);
taosHashCleanup(pAggNodeMap);
return code;
}
// clang-format off
static const SOptimizeRule optimizeRuleSet[] = {
{.pName = "ScanPath", .optimizeFunc = scanPathOptimize},
@ -7733,6 +8034,8 @@ static const SOptimizeRule optimizeRuleSet[] = {
{.pName = "EliminateSetOperator", .optimizeFunc = eliminateSetOpOptimize},
{.pName = "PartitionCols", .optimizeFunc = partitionColsOpt},
{.pName = "Tsma", .optimizeFunc = tsmaOptimize},
{.pName = "EliminateVirtualScan", .optimizeFunc = eliminateVirtualScanOptimize},
{.pName = "PushDownAgg", .optimizeFunc = pdaOptimize},
};
// clang-format on

View File

@ -34,6 +34,7 @@ typedef struct SSlotIndex {
enum {
SLOT_KEY_TYPE_ALL = 1,
SLOT_KEY_TYPE_COLNAME = 2,
SLOT_KEY_TYPE_REF = 3,
};
static int32_t getSlotKeyHelper(SNode* pNode, const char* pPreName, const char* name, char** ppKey, int32_t callocLen,
@ -77,6 +78,32 @@ static int32_t getSlotKey(SNode* pNode, const char* pStmtName, char** ppKey, int
return getSlotKeyHelper(pNode, pStmtName, pCol->colName, ppKey, callocLen, pLen, extraBufLen,
SLOT_KEY_TYPE_COLNAME);
}
if (pCol->hasRef) {
*ppKey = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN + 1 + TSDB_COL_NAME_LEN + 1 + extraBufLen);
if (!*ppKey) {
return terrno;
}
TAOS_STRNCAT(*ppKey, pCol->refDbName, TSDB_DB_NAME_LEN);
TAOS_STRNCAT(*ppKey, ".", 2);
TAOS_STRNCAT(*ppKey, pCol->refTableName, TSDB_TABLE_NAME_LEN);
TAOS_STRNCAT(*ppKey, ".", 2);
TAOS_STRNCAT(*ppKey, pCol->refColName, TSDB_COL_NAME_LEN);
*pLen = taosHashBinary(*ppKey, strlen(*ppKey));
return code;
}
if (pCol->hasDep) {
*ppKey = taosMemoryCalloc(1, TSDB_TABLE_FNAME_LEN + 1 + TSDB_COL_NAME_LEN + 1 + extraBufLen);
if (!*ppKey) {
return terrno;
}
TAOS_STRNCAT(*ppKey, pCol->dbName, TSDB_DB_NAME_LEN);
TAOS_STRNCAT(*ppKey, ".", 2);
TAOS_STRNCAT(*ppKey, pCol->tableAlias, TSDB_TABLE_NAME_LEN);
TAOS_STRNCAT(*ppKey, ".", 2);
TAOS_STRNCAT(*ppKey, pCol->colName, TSDB_COL_NAME_LEN);
*pLen = taosHashBinary(*ppKey, strlen(*ppKey));
return code;
}
callocLen = TSDB_TABLE_NAME_LEN + 1 + TSDB_COL_NAME_LEN + 1 + extraBufLen;
return getSlotKeyHelper(pNode, pCol->tableAlias, pCol->colName, ppKey, callocLen, pLen, extraBufLen,
SLOT_KEY_TYPE_ALL);
@ -354,6 +381,14 @@ typedef struct SSetSlotIdCxt {
SHashObj* pRightProdIdxHash;
} SSetSlotIdCxt;
typedef struct SMultiTableSetSlotIdCxt {
int32_t errCode;
SArray* hashArray;
SArray* projIdxHashArray;
SNodeList* pChild;
bool isVtb;
} SMultiTableSetSlotIdCxt;
static void dumpSlots(const char* pName, SHashObj* pHash) {
if (NULL == pHash) {
return;
@ -400,7 +435,58 @@ static EDealRes doSetSlotId(SNode* pNode, void* pContext) {
planError("doSetSlotId failed, invalid slot name %s", name);
dumpSlots("left datablock desc", pCxt->pLeftHash);
dumpSlots("right datablock desc", pCxt->pRightHash);
pCxt->errCode = TSDB_CODE_PLAN_INTERNAL_ERROR;
pCxt->errCode = TSDB_CODE_PLAN_SLOT_NOT_FOUND;
taosMemoryFree(name);
return DEAL_RES_ERROR;
}
((SColumnNode*)pNode)->dataBlockId = pIndex->dataBlockId;
((SColumnNode*)pNode)->slotId = ((SSlotIdInfo*)taosArrayGet(pIndex->pSlotIdsInfo, 0))->slotId;
taosMemoryFree(name);
return DEAL_RES_IGNORE_CHILD;
}
return DEAL_RES_CONTINUE;
}
static EDealRes doSetMultiTableSlotId(SNode* pNode, void* pContext) {
if (QUERY_NODE_COLUMN == nodeType(pNode) && 0 != strcmp(((SColumnNode*)pNode)->colName, "*")) {
SMultiTableSetSlotIdCxt* pCxt = (SMultiTableSetSlotIdCxt*)pContext;
char* name = NULL;
int32_t len = 0;
if (pCxt->isVtb && !((SColumnNode*)pNode)->hasRef) {
return DEAL_RES_CONTINUE;
}
pCxt->errCode = getSlotKey(pNode, NULL, &name, &len, 16);
if (TSDB_CODE_SUCCESS != pCxt->errCode) {
return DEAL_RES_ERROR;
}
SSlotIndex* pIndex = NULL;
int32_t idx = 0;
if (((SColumnNode*)pNode)->projRefIdx > 0) {
sprintf(name + strlen(name), "_%d", ((SColumnNode*)pNode)->projRefIdx);
while (!pIndex && idx < LIST_LENGTH(pCxt->pChild)) {
SHashObj *tmpHash =
taosArrayGetP(pCxt->projIdxHashArray,
((SPhysiNode*)nodesListGetNode(pCxt->pChild, idx))->pOutputDataBlockDesc->dataBlockId);
pIndex = taosHashGet(tmpHash, name, strlen(name));
idx++;
}
} else {
while (!pIndex && idx < LIST_LENGTH(pCxt->pChild)) {
SHashObj *tmpHash =
taosArrayGetP(pCxt->hashArray,
((SPhysiNode*)nodesListGetNode(pCxt->pChild, idx))->pOutputDataBlockDesc->dataBlockId);
pIndex = taosHashGet(tmpHash, name, len);
idx++;
}
}
// pIndex is definitely not NULL, otherwise it is a bug
if (NULL == pIndex) {
planError("doSetMultiTableSlotId failed, invalid slot name %s", name);
for (int32_t i = 0; i < taosArrayGetSize(pCxt->hashArray); i++) {
//dumpSlots("vtable datablock desc", taosArrayGetP(pCxt->hashArray, i));
}
pCxt->errCode = TSDB_CODE_PLAN_SLOT_NOT_FOUND;
taosMemoryFree(name);
return DEAL_RES_ERROR;
}
@ -440,6 +526,33 @@ static int32_t setNodeSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, i
return TSDB_CODE_SUCCESS;
}
static int32_t setVtableNodeSlotId(SPhysiPlanContext* pCxt, SNodeList* pChild, SNode* pNode,
SNode** pOutput) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == pNode) {
PLAN_RET(code);
}
SNode* pRes = NULL;
PLAN_ERR_JRET(nodesCloneNode(pNode, &pRes));
SMultiTableSetSlotIdCxt cxt = {
.errCode = TSDB_CODE_SUCCESS,
.hashArray = pCxt->pLocationHelper,
.projIdxHashArray = pCxt->pProjIdxLocHelper,
.pChild = pChild
};
nodesWalkExpr(pRes, doSetMultiTableSlotId, &cxt);
PLAN_ERR_JRET(cxt.errCode);
*pOutput = pRes;
return code;
_return:
nodesDestroyNode(pRes);
return code;
}
static int32_t setListSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, int16_t rightDataBlockId,
const SNodeList* pList, SNodeList** pOutput) {
if (NULL == pList) {
@ -467,6 +580,34 @@ static int32_t setListSlotId(SPhysiPlanContext* pCxt, int16_t leftDataBlockId, i
return TSDB_CODE_SUCCESS;
}
static int32_t setMultiBlockSlotId(SPhysiPlanContext* pCxt, SNodeList* pChild, bool isVtb, const SNodeList* pList,
SNodeList** pOutput) {
int32_t code = TSDB_CODE_SUCCESS;
if (NULL == pList) {
PLAN_RET(code);
}
SNodeList* pRes = NULL;
PLAN_ERR_JRET(nodesCloneList(pList, &pRes));
SMultiTableSetSlotIdCxt cxt = {
.errCode = TSDB_CODE_SUCCESS,
.hashArray = pCxt->pLocationHelper,
.projIdxHashArray = pCxt->pProjIdxLocHelper,
.pChild = pChild,
.isVtb = isVtb
};
nodesWalkExprs(pRes, doSetMultiTableSlotId, &cxt);
PLAN_ERR_JRET(cxt.errCode);
*pOutput = pRes;
return code;
_return:
nodesDestroyList(pRes);
return code;
}
static SPhysiNode* makePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode, ENodeType type) {
SPhysiNode* pPhysiNode = NULL;
int32_t code = nodesMakeNode(type, (SNode**)&pPhysiNode);
@ -570,6 +711,7 @@ static int32_t createScanPhysiNodeFinalize(SPhysiPlanContext* pCxt, SSubplan* pS
pScanPhysiNode->suid = pScanLogicNode->stableId;
pScanPhysiNode->tableType = pScanLogicNode->tableType;
pScanPhysiNode->groupOrderScan = pScanLogicNode->groupOrderScan;
pScanPhysiNode->virtualStableScan = pScanLogicNode->virtualStableScan;
memcpy(&pScanPhysiNode->tableName, &pScanLogicNode->tableName, sizeof(SName));
if (NULL != pScanLogicNode->pTagCond) {
pSubplan->pTagCond = NULL;
@ -1642,6 +1784,69 @@ static int32_t createJoinPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren
return TSDB_CODE_FAILED;
}
static int32_t createVirtualScanCols(SPhysiPlanContext* pCxt, SVirtualScanPhysiNode* pScanPhysiNode, SNodeList* pScanCols) {
if (NULL == pScanCols) {
return TSDB_CODE_SUCCESS;
}
pScanPhysiNode->scan.pScanCols = NULL;
int32_t code = nodesCloneList(pScanCols, &pScanPhysiNode->scan.pScanCols);
if (NULL == pScanPhysiNode->scan.pScanCols) {
return code;
}
return sortScanCols(pScanPhysiNode->scan.pScanCols);
}
static int32_t createVirtualTableScanPhysiNodeFinalize(SPhysiPlanContext* pCxt,
SNodeList* pChild,
SVirtualScanLogicNode* pScanLogicNode,
SVirtualScanPhysiNode* pScanPhysiNode,
SPhysiNode** pPhyNode) {
int32_t code = TSDB_CODE_SUCCESS;
PLAN_ERR_JRET(createVirtualScanCols(pCxt, pScanPhysiNode, pScanLogicNode->pScanCols));
PLAN_ERR_JRET(addDataBlockSlots(pCxt, pScanPhysiNode->scan.pScanCols, pScanPhysiNode->scan.node.pOutputDataBlockDesc));
if (NULL != pScanLogicNode->pScanPseudoCols) {
pScanPhysiNode->scan.pScanPseudoCols = NULL;
PLAN_ERR_JRET(nodesCloneList(pScanLogicNode->pScanPseudoCols, &pScanPhysiNode->scan.pScanPseudoCols));
PLAN_ERR_JRET(addDataBlockSlots(pCxt, pScanPhysiNode->scan.pScanPseudoCols, pScanPhysiNode->scan.node.pOutputDataBlockDesc));
}
PLAN_ERR_JRET(setConditionsSlotId(pCxt, (const SLogicNode*)pScanLogicNode, (SPhysiNode*)pScanPhysiNode));
pScanPhysiNode->scan.uid = pScanLogicNode->tableId;
pScanPhysiNode->scan.suid = pScanLogicNode->stableId;
pScanPhysiNode->scan.tableType = pScanLogicNode->tableType;
memcpy(&pScanPhysiNode->scan.tableName, &pScanLogicNode->tableName, sizeof(SName));
pScanPhysiNode->scanAllCols = pScanLogicNode->scanAllCols;
*pPhyNode = (SPhysiNode*)pScanPhysiNode;
return code;
_return:
nodesDestroyNode((SNode*)pScanPhysiNode);
return code;
}
static int32_t createVirtualTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SNodeList* pChildren,
SVirtualScanLogicNode* pScanLogicNode, SPhysiNode** pPhyNode) {
int32_t code = TSDB_CODE_SUCCESS;
SVirtualScanPhysiNode * pVirtualScan =
(SVirtualScanPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pScanLogicNode, QUERY_NODE_PHYSICAL_PLAN_VIRTUAL_TABLE_SCAN);
if (NULL == pVirtualScan) {
return terrno;
}
if (pScanLogicNode->pVgroupList) {
vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode);
pSubplan->execNodeStat.tableNum = pScanLogicNode->pVgroupList->vgroups[0].numOfTable;
}
PLAN_ERR_RET(createVirtualTableScanPhysiNodeFinalize(pCxt, pChildren, pScanLogicNode, (SVirtualScanPhysiNode*)pVirtualScan, pPhyNode));
PLAN_ERR_RET(setMultiBlockSlotId(pCxt, pChildren, true, pScanLogicNode->node.pTargets, &pVirtualScan->pTargets));
return code;
}
static int32_t createGroupCachePhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SGroupCacheLogicNode* pLogicNode, SPhysiNode** pPhyNode) {
SGroupCachePhysiNode* pGrpCache =
@ -1698,29 +1903,55 @@ static int32_t updateDynQueryCtrlStbJoinInfo(SPhysiPlanContext* pCxt, SNodeList*
return code;
}
static int32_t updateDynQueryCtrlVtbScanInfo(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SDynQueryCtrlLogicNode* pLogicNode, SDynQueryCtrlPhysiNode* pDynCtrl,
SSubplan* pSubPlan) {
int32_t code = TSDB_CODE_SUCCESS;
if (pLogicNode->vtbScan.pVgroupList) {
vgroupInfoToNodeAddr(pLogicNode->vtbScan.pVgroupList->vgroups, &pSubPlan->execNode);
pSubPlan->execNodeStat.tableNum = pLogicNode->vtbScan.pVgroupList->vgroups[0].numOfTable;
}
PLAN_ERR_JRET(nodesCloneList(pLogicNode->node.pTargets, &pDynCtrl->vtbScan.pScanCols));
pDynCtrl->vtbScan.scanAllCols = pLogicNode->vtbScan.scanAllCols;
pDynCtrl->vtbScan.suid = pLogicNode->vtbScan.suid;
pDynCtrl->vtbScan.mgmtEpSet = pCxt->pPlanCxt->mgmtEpSet;
pDynCtrl->vtbScan.accountId = pCxt->pPlanCxt->acctId;
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
return code;
}
static int32_t createDynQueryCtrlPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren,
SDynQueryCtrlLogicNode* pLogicNode, SPhysiNode** pPhyNode) {
SDynQueryCtrlLogicNode* pLogicNode, SPhysiNode** pPhyNode, SSubplan* pSubPlan) {
int32_t code = TSDB_CODE_SUCCESS;
int32_t lino = 0;
SDynQueryCtrlPhysiNode* pDynCtrl =
(SDynQueryCtrlPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pLogicNode, QUERY_NODE_PHYSICAL_PLAN_DYN_QUERY_CTRL);
if (NULL == pDynCtrl) {
return terrno;
}
QUERY_CHECK_NULL(pDynCtrl, code, lino, _return, terrno);
switch (pLogicNode->qType) {
case DYN_QTYPE_STB_HASH:
code = updateDynQueryCtrlStbJoinInfo(pCxt, pChildren, pLogicNode, pDynCtrl);
PLAN_ERR_JRET(updateDynQueryCtrlStbJoinInfo(pCxt, pChildren, pLogicNode, pDynCtrl));
break;
case DYN_QTYPE_VTB_SCAN:
PLAN_ERR_JRET(updateDynQueryCtrlVtbScanInfo(pCxt, pChildren, pLogicNode, pDynCtrl, pSubPlan));
break;
default:
planError("Invalid dyn query ctrl type:%d", pLogicNode->qType);
return TSDB_CODE_PLAN_INTERNAL_ERROR;
PLAN_ERR_JRET(TSDB_CODE_PLAN_INVALID_DYN_CTRL_TYPE);
}
if (TSDB_CODE_SUCCESS == code) {
pDynCtrl->qType = pLogicNode->qType;
*pPhyNode = (SPhysiNode*)pDynCtrl;
}
pDynCtrl->qType = pLogicNode->qType;
*pPhyNode = (SPhysiNode*)pDynCtrl;
return code;
_return:
planError("%s failed at line %d since %s", __func__, __LINE__, tstrerror(code));
return code;
}
@ -2828,49 +3059,31 @@ static int32_t createMergePhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildre
pMerge->inputWithGroupId = pMergeLogicNode->inputWithGroupId;
if (!pMergeLogicNode->colsMerge) {
code = addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc);
PLAN_ERR_JRET(addDataBlockSlots(pCxt, pMergeLogicNode->pInputs, pMerge->node.pOutputDataBlockDesc));
if (TSDB_CODE_SUCCESS == code) {
for (int32_t j = 0; j < pMergeLogicNode->numOfSubplans; ++j) {
for (int32_t i = 0; i < pMerge->numOfChannels; ++i) {
code = createExchangePhysiNodeByMerge(pMerge, j);
if (TSDB_CODE_SUCCESS != code) {
break;
}
}
if (code) break;
for (int32_t j = 0; j < pMergeLogicNode->numOfSubplans; ++j) {
for (int32_t i = 0; i < pMerge->numOfChannels; ++i) {
PLAN_ERR_JRET(createExchangePhysiNodeByMerge(pMerge, j));
}
}
if (TSDB_CODE_SUCCESS == code && NULL != pMergeLogicNode->pMergeKeys) {
code = setListSlotId(pCxt, pMerge->node.pOutputDataBlockDesc->dataBlockId, -1, pMergeLogicNode->pMergeKeys,
&pMerge->pMergeKeys);
if (NULL != pMergeLogicNode->pMergeKeys) {
PLAN_ERR_JRET(setListSlotId(pCxt, pMerge->node.pOutputDataBlockDesc->dataBlockId, -1, pMergeLogicNode->pMergeKeys,
&pMerge->pMergeKeys));
}
if (TSDB_CODE_SUCCESS == code) {
code = setListSlotId(pCxt, pMerge->node.pOutputDataBlockDesc->dataBlockId, -1, pMergeLogicNode->node.pTargets,
&pMerge->pTargets);
}
if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc);
}
PLAN_ERR_JRET(setListSlotId(pCxt, pMerge->node.pOutputDataBlockDesc->dataBlockId, -1, pMergeLogicNode->node.pTargets,
&pMerge->pTargets));
PLAN_ERR_JRET(addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc));
} else {
SDataBlockDescNode* pLeftDesc = ((SPhysiNode*)nodesListGetNode(pChildren, 0))->pOutputDataBlockDesc;
SDataBlockDescNode* pRightDesc = ((SPhysiNode*)nodesListGetNode(pChildren, 1))->pOutputDataBlockDesc;
code = setListSlotId(pCxt, pLeftDesc->dataBlockId, pRightDesc->dataBlockId, pMergeLogicNode->node.pTargets,
&pMerge->pTargets);
if (TSDB_CODE_SUCCESS == code) {
code = addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc);
}
}
if (TSDB_CODE_SUCCESS == code) {
*pPhyNode = (SPhysiNode*)pMerge;
} else {
nodesDestroyNode((SNode*)pMerge);
PLAN_ERR_JRET(setMultiBlockSlotId(pCxt, pChildren, false, pMergeLogicNode->node.pTargets, &pMerge->pTargets));
PLAN_ERR_JRET(addDataBlockSlots(pCxt, pMerge->pTargets, pMerge->node.pOutputDataBlockDesc));
}
*pPhyNode = (SPhysiNode*)pMerge;
return code;
_return:
nodesDestroyNode((SNode*)pMerge);
return code;
}
@ -2906,7 +3119,9 @@ static int32_t doCreatePhysiNode(SPhysiPlanContext* pCxt, SLogicNode* pLogicNode
case QUERY_NODE_LOGIC_PLAN_GROUP_CACHE:
return createGroupCachePhysiNode(pCxt, pChildren, (SGroupCacheLogicNode*)pLogicNode, pPhyNode);
case QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL:
return createDynQueryCtrlPhysiNode(pCxt, pChildren, (SDynQueryCtrlLogicNode*)pLogicNode, pPhyNode);
return createDynQueryCtrlPhysiNode(pCxt, pChildren, (SDynQueryCtrlLogicNode*)pLogicNode, pPhyNode, pSubplan);
case QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN:
return createVirtualTableScanPhysiNode(pCxt, pSubplan, pChildren, (SVirtualScanLogicNode*)pLogicNode, pPhyNode);
default:
break;
}
@ -3000,6 +3215,7 @@ static int32_t makeSubplan(SPhysiPlanContext* pCxt, SLogicSubplan* pLogicSubplan
pSubplan->dynamicRowThreshold = false;
pSubplan->isView = pCxt->pPlanCxt->isView;
pSubplan->isAudit = pCxt->pPlanCxt->isAudit;
pSubplan->processOneBlock = pLogicSubplan->processOneBlock;
if (NULL != pCxt->pPlanCxt->pUser) {
snprintf(pSubplan->user, sizeof(pSubplan->user), "%s", pCxt->pPlanCxt->pUser);
}

View File

@ -39,6 +39,7 @@ static SLogicSubplan* singleCloneSubLogicPlan(SScaleOutContext* pCxt, SLogicSubp
pDst->id.queryId = pSrc->id.queryId;
pDst->id.groupId = pSrc->id.groupId;
pDst->id.subplanId = pCxt->subplanId++;
pDst->processOneBlock = pSrc->processOneBlock;
return pDst;
}
@ -52,6 +53,17 @@ static int32_t doSetScanVgroup(SLogicNode* pNode, const SVgroupInfo* pVgroup, bo
memcpy(pScan->pVgroupList->vgroups, pVgroup, sizeof(SVgroupInfo));
*pFound = true;
return TSDB_CODE_SUCCESS;
} else if (QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL == nodeType(pNode)) {
SDynQueryCtrlLogicNode* pCtrl = (SDynQueryCtrlLogicNode*)pNode;
if (DYN_QTYPE_VTB_SCAN == pCtrl->qType) {
pCtrl->vtbScan.pVgroupList = taosMemoryCalloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo));
if (NULL == pCtrl->vtbScan.pVgroupList) {
return terrno;
}
memcpy(pCtrl->vtbScan.pVgroupList->vgroups, pVgroup, sizeof(SVgroupInfo));
*pFound = true;
return TSDB_CODE_SUCCESS;
}
}
SNode* pChild = NULL;
FOREACH(pChild, pNode->pChildren) {
@ -87,7 +99,12 @@ static int32_t scaleOutByVgroups(SScaleOutContext* pCxt, SLogicSubplan* pSubplan
}
static int32_t scaleOutForMerge(SScaleOutContext* pCxt, SLogicSubplan* pSubplan, int32_t level, SNodeList* pGroup) {
return nodesListStrictAppend(pGroup, (SNode*)singleCloneSubLogicPlan(pCxt, pSubplan, level));
if (QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL == nodeType(pSubplan->pNode) &&
((SDynQueryCtrlLogicNode*)pSubplan->pNode)->qType == DYN_QTYPE_VTB_SCAN) {
return scaleOutByVgroups(pCxt, pSubplan, level, pGroup);
} else {
return nodesListStrictAppend(pGroup, (SNode*)singleCloneSubLogicPlan(pCxt, pSubplan, level));
}
}
static int32_t scaleOutForInsertValues(SScaleOutContext* pCxt, SLogicSubplan* pSubplan, int32_t level,

View File

@ -51,6 +51,10 @@ static int32_t stbSplCreateMergeKeys(SNodeList* pSortKeys, SNodeList* pTargets,
static void splSetSubplanVgroups(SLogicSubplan* pSubplan, SLogicNode* pNode) {
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
TSWAP(pSubplan->pVgroupList, ((SScanLogicNode*)pNode)->pVgroupList);
} else if (QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN == nodeType(pNode)) {
// do nothing, since virtual table scan node is SUBPLAN_TYPE_MERGE
} else if (QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL == nodeType(pNode) && ((SDynQueryCtrlLogicNode *)pNode)->qType == DYN_QTYPE_VTB_SCAN) {
TSWAP(pSubplan->pVgroupList, ((SDynQueryCtrlLogicNode*)pNode)->vtbScan.pVgroupList);
} else {
if (1 == LIST_LENGTH(pNode->pChildren)) {
splSetSubplanVgroups(pSubplan, (SLogicNode*)nodesListGetNode(pNode->pChildren, 0));
@ -66,7 +70,8 @@ static SLogicSubplan* splCreateScanSubplan(SSplitContext* pCxt, SLogicNode* pNod
}
pSubplan->id.queryId = pCxt->queryId;
pSubplan->id.groupId = pCxt->groupId;
pSubplan->subplanType = SUBPLAN_TYPE_SCAN;
// TODO(smj):refact here.
pSubplan->subplanType = nodeType(pNode) == QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN ? SUBPLAN_TYPE_MERGE : SUBPLAN_TYPE_SCAN;
pSubplan->pNode = pNode;
pSubplan->pNode->pParent = NULL;
splSetSubplanVgroups(pSubplan, pNode);
@ -146,10 +151,11 @@ static int32_t splCreateExchangeNode(SSplitContext* pCxt, SLogicNode* pChild, SE
}
static int32_t splCreateExchangeNodeForSubplan(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pSplitNode,
ESubplanType subplanType) {
ESubplanType subplanType, bool seqScan) {
SExchangeLogicNode* pExchange = NULL;
int32_t code = splCreateExchangeNode(pCxt, pSplitNode, &pExchange);
if (TSDB_CODE_SUCCESS == code) {
pExchange->seqRecvData = seqScan;
code = replaceLogicNode(pSubplan, pSplitNode, (SLogicNode*)pExchange);
}
if (TSDB_CODE_SUCCESS == code) {
@ -338,6 +344,9 @@ static bool stbSplIsTableCountQuery(SLogicNode* pNode) {
}
static bool stbSplNeedSplit(SFindSplitNodeCtx* pCtx, SLogicNode* pNode) {
if (pCtx->pSplitCtx->pPlanCxt->virtualStableQuery) {
return false;
}
bool streamQuery = pCtx->pSplitCtx->pPlanCxt->streamQuery;
switch (nodeType(pNode)) {
case QUERY_NODE_LOGIC_PLAN_SCAN:
@ -1083,7 +1092,7 @@ static int32_t stbSplCreatePartAggNode(SAggLogicNode* pMergeAgg, SLogicNode** pO
}
static int32_t stbSplSplitAggNodeForPartTable(SSplitContext* pCxt, SStableSplitInfo* pInfo) {
int32_t code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pInfo->pSplitNode, SUBPLAN_TYPE_MERGE);
int32_t code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pInfo->pSplitNode, SUBPLAN_TYPE_MERGE, false);
if (TSDB_CODE_SUCCESS == code) {
code = nodesListMakeStrictAppend(&pInfo->pSubplan->pChildren,
(SNode*)splCreateScanSubplan(pCxt, pInfo->pSplitNode, SPLIT_FLAG_STABLE_SPLIT));
@ -1461,7 +1470,7 @@ static int32_t stbSplSplitScanNodeWithoutPartTags(SSplitContext* pCxt, SStableSp
SLogicNode* pSplitNode = NULL;
int32_t code = stbSplGetSplitNodeForScan(pInfo, &pSplitNode);
if (TSDB_CODE_SUCCESS == code) {
code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pSplitNode, pInfo->pSubplan->subplanType);
code = splCreateExchangeNodeForSubplan(pCxt, pInfo->pSubplan, pSplitNode, pInfo->pSubplan->subplanType, false);
}
if (TSDB_CODE_SUCCESS == code) {
splSetSubplanType(pInfo->pSubplan);
@ -1781,7 +1790,7 @@ static int32_t singleTableJoinSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan
if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)sigTbJoinSplFindSplitNode, &info)) {
return TSDB_CODE_SUCCESS;
}
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, info.pSubplan->subplanType);
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, info.pSubplan->subplanType, false);
if (TSDB_CODE_SUCCESS == code) {
code = nodesListMakeStrictAppend(&info.pSubplan->pChildren, (SNode*)splCreateScanSubplan(pCxt, info.pSplitNode, 0));
}
@ -2009,7 +2018,7 @@ static int32_t insertSelectSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
SLogicSubplan* pNewSubplan = NULL;
SNodeList* pSubplanChildren = info.pSubplan->pChildren;
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pQueryRoot, SUBPLAN_TYPE_MODIFY);
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pQueryRoot, SUBPLAN_TYPE_MODIFY, false);
if (TSDB_CODE_SUCCESS == code) {
code = splCreateSubplan(pCxt, info.pQueryRoot, &pNewSubplan);
}
@ -2026,6 +2035,87 @@ static int32_t insertSelectSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
return code;
}
typedef struct SVirtualTableSplitInfo {
SVirtualScanLogicNode *pVirtual;
SLogicSubplan *pSubplan;
} SVirtualTableSplitInfo;
static bool virtualTableFindSplitNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pNode,
SVirtualTableSplitInfo* pInfo) {
if (QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN == nodeType(pNode) && 0 != LIST_LENGTH(pNode->pChildren) &&
QUERY_NODE_LOGIC_PLAN_EXCHANGE != nodeType(nodesListGetNode(pNode->pChildren, 0))) {
pInfo->pVirtual = (SVirtualScanLogicNode*)pNode;
pInfo->pSubplan = pSubplan;
return true;
}
return false;
}
static int32_t virtualTableSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
int32_t code = TSDB_CODE_SUCCESS;
SVirtualTableSplitInfo info = {0};
if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)virtualTableFindSplitNode, &info)) {
return TSDB_CODE_SUCCESS;
}
int32_t startGroupId = pCxt->groupId;
SNode* pChild = NULL;
FOREACH(pChild, info.pVirtual->node.pChildren) {
PLAN_ERR_JRET(splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, (SLogicNode*)pChild, info.pSubplan->subplanType, info.pVirtual->tableType == TSDB_SUPER_TABLE));
SLogicSubplan *sub = splCreateScanSubplan(pCxt, (SLogicNode*)pChild, 0);
sub->processOneBlock = (info.pVirtual->tableType == TSDB_SUPER_TABLE);
PLAN_ERR_JRET(nodesListMakeStrictAppend(&info.pSubplan->pChildren, (SNode*)sub));
++(pCxt->groupId);
}
info.pSubplan->subplanType = SUBPLAN_TYPE_MERGE;
_return:
pCxt->split = true;
return code;
}
typedef struct SMergeAggColsSplitInfo {
SAggLogicNode *pAgg;
SLogicNode *pSplitNode;
SLogicSubplan *pSubplan;
} SMergeAggColsSplitInfo;
static bool mergeAggColsNeedSplit(SLogicNode* pNode) {
if (QUERY_NODE_LOGIC_PLAN_AGG == nodeType(pNode) && 1 == LIST_LENGTH(pNode->pChildren) &&
NULL != pNode->pParent &&
QUERY_NODE_LOGIC_PLAN_MERGE == nodeType(pNode->pParent) &&
((SMergeLogicNode *)pNode->pParent)->colsMerge &&
QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(nodesListGetNode(pNode->pChildren, 0))) {
return true;
}
return false;
}
static bool mergeAggColsFindSplitNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pNode,
SMergeAggColsSplitInfo* pInfo) {
if (mergeAggColsNeedSplit(pNode)) {
pInfo->pAgg = (SAggLogicNode *)pNode;
pInfo->pSplitNode = (SLogicNode*)nodesListGetNode(pNode->pChildren, 0);
pInfo->pSubplan = pSubplan;
return true;
}
return false;
}
static int32_t mergeAggColsSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
int32_t code = TSDB_CODE_SUCCESS;
SMergeAggColsSplitInfo info = {0};
if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)mergeAggColsFindSplitNode, &info)) {
return TSDB_CODE_SUCCESS;
}
PLAN_ERR_RET(splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, SUBPLAN_TYPE_MERGE, false));
PLAN_ERR_RET(nodesListMakeStrictAppend(&info.pSubplan->pChildren, (SNode*)splCreateScanSubplan(pCxt, info.pSplitNode, 0)));
++(pCxt->groupId);
pCxt->split = true;
return code;
}
typedef struct SQnodeSplitInfo {
SLogicNode* pSplitNode;
SLogicSubplan* pSubplan;
@ -2054,7 +2144,7 @@ static int32_t qnodeSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
return TSDB_CODE_SUCCESS;
}
((SScanLogicNode*)info.pSplitNode)->dataRequired = FUNC_DATA_REQUIRED_DATA_LOAD;
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, info.pSubplan->subplanType);
int32_t code = splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, info.pSplitNode, info.pSubplan->subplanType, false);
if (TSDB_CODE_SUCCESS == code) {
SLogicSubplan* pScanSubplan = splCreateScanSubplan(pCxt, info.pSplitNode, 0);
if (NULL != pScanSubplan) {
@ -2075,6 +2165,45 @@ static int32_t qnodeSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
return code;
}
typedef struct SDynVirtualScanSplitInfo {
SDynQueryCtrlLogicNode *pDyn;
SLogicSubplan *pSubplan;
} SDynVirtualScanSplitInfo;
static bool dynVirtualScanFindSplitNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pNode,
SDynVirtualScanSplitInfo* pInfo) {
if (QUERY_NODE_LOGIC_PLAN_DYN_QUERY_CTRL == nodeType(pNode) && NULL != pNode->pParent &&
QUERY_NODE_LOGIC_PLAN_EXCHANGE != nodeType(pNode->pParent) &&
((SDynQueryCtrlLogicNode*)pNode)->qType == DYN_QTYPE_VTB_SCAN) {
pInfo->pDyn = (SDynQueryCtrlLogicNode*)pNode;
pInfo->pSubplan = pSubplan;
return true;
}
return false;
}
static int32_t dynVirtualScanSplit(SSplitContext* pCxt, SLogicSubplan* pSubplan) {
int32_t code = TSDB_CODE_SUCCESS;
SDynVirtualScanSplitInfo info = {0};
if (!splMatch(pCxt, pSubplan, 0, (FSplFindSplitNode)dynVirtualScanFindSplitNode, &info)) {
return TSDB_CODE_SUCCESS;
}
SNode *pSub = NULL;
SNodeList *pSubplanChildren = info.pSubplan->pChildren;
PLAN_ERR_JRET(splCreateExchangeNodeForSubplan(pCxt, info.pSubplan, (SLogicNode*)info.pDyn, info.pSubplan->subplanType, true));
PLAN_ERR_JRET(splCreateSubplan(pCxt, (SLogicNode*)info.pDyn, (SLogicSubplan**)&pSub));
((SLogicSubplan*)pSub)->subplanType = SUBPLAN_TYPE_MERGE;
splSetSubplanVgroups((SLogicSubplan*)pSub, (SLogicNode*)info.pDyn);
PLAN_ERR_JRET(nodesListMakeStrictAppend(&info.pSubplan->pChildren, pSub));
PLAN_ERR_JRET(splMountSubplan((SLogicSubplan*)pSub, pSubplanChildren));
++(pCxt->groupId);
_return:
pCxt->split = true;
return code;
}
// clang-format off
static const SSplitRule splitRuleSet[] = {
{.pName = "SuperTableSplit", .splitFunc = stableSplit},
@ -2082,7 +2211,10 @@ static const SSplitRule splitRuleSet[] = {
{.pName = "UnionAllSplit", .splitFunc = unionAllSplit},
{.pName = "UnionDistinctSplit", .splitFunc = unionDistinctSplit},
{.pName = "SmaIndexSplit", .splitFunc = smaIndexSplit}, // not used yet
{.pName = "InsertSelectSplit", .splitFunc = insertSelectSplit}
{.pName = "InsertSelectSplit", .splitFunc = insertSelectSplit},
{.pName = "VirtualtableSplit", .splitFunc = virtualTableSplit},
{.pName = "MergeAggColsSplit", .splitFunc = mergeAggColsSplit},
{.pName = "DynVirtualScanSplit", .splitFunc = dynVirtualScanSplit},
};
// clang-format on
@ -2138,6 +2270,9 @@ static void setVgroupsInfo(SLogicNode* pNode, SLogicSubplan* pSubplan) {
if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode)) {
TSWAP(((SScanLogicNode*)pNode)->pVgroupList, pSubplan->pVgroupList);
return;
} else if (QUERY_NODE_LOGIC_PLAN_VIRTUAL_TABLE_SCAN == nodeType(pNode)) {
// do nothing, since virtual table scan node is SUBPLAN_TYPE_MERGE
return;
}
SNode* pChild;

Some files were not shown because too many files have changed in this diff Show More