diff --git a/docs/en/14-reference/03-taos-sql/10-function.md b/docs/en/14-reference/03-taos-sql/10-function.md index 80596621bf..2292e40f75 100644 --- a/docs/en/14-reference/03-taos-sql/10-function.md +++ b/docs/en/14-reference/03-taos-sql/10-function.md @@ -2128,10 +2128,10 @@ UNIQUE(expr) ### COLS​ ```sql​ -COLS​(select_function(expr), output_expr1, [, output_expr2] ... )​ +COLS​(func(expr), output_expr1, [, output_expr2] ... )​ ``` -**Function Description**: On the data row where the execution result of function func (expr) is located, execute the expression output_expr1, [, output_expr2], return its result, and the result of func (expr) is not output.​ +**Function Description**: On the data row where the execution result of function func(expr) is located, execute the expression output_expr1, [, output_expr2], return its result, and the result of func (expr) is not output.​ **Return Data Type**: Returns multiple columns of data, and the data type of each column is the type of the result returned by the corresponding expression.​ @@ -2141,7 +2141,8 @@ COLS​(select_function(expr), output_expr1, [, output_expr2] ... )​ **Usage Instructions**: - Func function type: must be a single-line selection function (output result is a single-line selection function, for example, last is a single-line selection function, but top is a multi-line selection function).​ -- The result of the parameter func is not returned. If you want to output the result of func, you need to add the corresponding output_expr parameter to the letter. +- Mainly used to obtain the associated columns of multiple selection function results in a single SQL query. For example: select cols(max(c0), ts), cols(max(c1), ts) from ... can be used to get the different ts values of the maximum values of columns c0 and c1. +- The result of the parameter func is not returned. If you need to output the result of func, you can add additional output columns, such as: select first(ts), cols(first(ts), c1) from .. - When there is only one column in the output, you can set an alias for the function. For example, you can do it like this: "select cols(first (ts), c1) as c11 from ...". - Output one or more columns, and you can set an alias for each output column of the function. For example, you can do it like this: "select (first (ts), c1 as c11, c2 as c22) from ...". diff --git a/docs/en/14-reference/09-error-code.md b/docs/en/14-reference/09-error-code.md index 857f84da34..38ce3a4d39 100644 --- a/docs/en/14-reference/09-error-code.md +++ b/docs/en/14-reference/09-error-code.md @@ -459,7 +459,7 @@ This document details the server error codes that may be encountered when using | 0x80002666 | Subquery does not output primary timestamp column | Check and correct the SQL statement | | | 0x80002667 | Invalid usage of expr: %s | Illegal expression | Check and correct the SQL statement | | 0x80002687 | Invalid using cols function | Illegal using cols function | Check and correct the SQL statement | -| 0x80002688 | Cols function's first param must be a select function | The first parameter of the cols function should be a selection function | Check and correct the SQL statement | +| 0x80002688 | 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 | | 0x80002689 | Invalid using cols function with multiple output columns | Illegal using the cols function for multiple column output | Check and correct the SQL statement | | 0x8000268A | Invalid using alias for cols function | Illegal cols function alias | Check and correct the SQL statement | | 0x800026FF | Parser internal error | Internal error in parser | Preserve the scene and logs, report issue on GitHub | diff --git a/docs/zh/14-reference/03-taos-sql/10-function.md b/docs/zh/14-reference/03-taos-sql/10-function.md index 6c68d8f62c..2e0fd41dc4 100644 --- a/docs/zh/14-reference/03-taos-sql/10-function.md +++ b/docs/zh/14-reference/03-taos-sql/10-function.md @@ -2054,7 +2054,7 @@ UNIQUE(expr) ### COLS ```sql -COLS(select_function(expr), output_expr1, [, output_expr2] ... ) +COLS(func(expr), output_expr1, [, output_expr2] ... ) ``` **功能说明**:在选择函数 func(expr) 执行结果所在数据行上,执行表达式 output_expr1, [,output_expr2],返回其结果,func(expr)结果不输出. @@ -2067,7 +2067,8 @@ COLS(select_function(expr), output_expr1, [, output_expr2] ... ) **使用说明:** - func 函数类型:必须是单行选择函数(输出结果为一行的选择函数,例如 last 是单行选择函数, 但 top 是多行选择函数)。 -- 注意, 参数 func 的结果并没有返回,如需输出 func 结果,需要在 cols 中加上相应的 output_expr 参数。 +- 主要用于一个 sql 中获取多个选择函数结果关联列的场景,例如: select cols(max(c0), ts), cols(max(c1), ts) from ...可用于获取 c0, c1 列最大值的不同 ts 值。 +- 注意, 参数 func 的结果并没有返回,如需输出func结果,可额外增加输出列,如: select fist(ts), cols(first(ts), c1) from ... - 输出只有一列时,可以对 cols 函数设置别名。例如: "select cols(first(ts), c1) as c11 from ..." - 输出一列或者多列,可以对 cols 函数的每个输出列设置命名。例如: "select cols(first(ts), c1 as c11, c2 as c22)" diff --git a/docs/zh/14-reference/09-error-code.md b/docs/zh/14-reference/09-error-code.md index 74fe39421d..7481903397 100644 --- a/docs/zh/14-reference/09-error-code.md +++ b/docs/zh/14-reference/09-error-code.md @@ -476,7 +476,7 @@ description: TDengine 服务端的错误码列表和详细说明 | 0x80002666 | 子查询不含主键时间戳列输出 | 检查并修正SQL语句 | | 0x80002667 | Invalid usage of expr: %s | 非法表达式 | 检查并修正SQL语句 | | 0x80002687 | Invalid using cols function | cols函数使用错误 | 检查并修正SQL语句 | -| 0x80002688 | Cols function's first param must be a select function | cols函数第一个参数应该为选择函数 | 检查并修正SQL语句 | +| 0x80002688 | Cols function's first param must be a select function that output a single row | cols函数第一个参数应该为选择函数 | 检查并修正SQL语句 | | 0x80002689 | Invalid using cols function with multiple output columns | 多列输出的 cols 函数使用错误 | 检查并修正SQL语句 | | 0x8000268A | Invalid using alias for cols function | cols 函数输出列重命名错误 | 检查并修正SQL语句 | | 0x800026FF | Parser internal error | 解析器内部错误 | 保留现场和日志,github上报issue | diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 26857403e2..c776fc6eee 100755 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1109,7 +1109,8 @@ static bool isColsFunctionResult(const SNode* pNode) { } static bool isInvalidColsBindFunction(const SFunctionNode* pFunc) { - return (!fmIsSelectFunc(pFunc->funcId) && pFunc->node.bindExprID != 0); + return (pFunc->node.bindExprID != 0 && (!fmIsSelectFunc(pFunc->funcId) || fmIsMultiRowsFunc(pFunc->funcId) || + fmIsIndefiniteRowsFunc(pFunc->funcId))); } #ifdef BUILD_NO_CALL diff --git a/source/util/src/terror.c b/source/util/src/terror.c index 57150cdc9d..82c48a1fc2 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -753,7 +753,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_FORECAST_CLAUSE, "Invalid forecast cl TAOS_DEFINE_ERROR(TSDB_CODE_PAR_REGULAR_EXPRESSION_ERROR, "Syntax error in regular expression") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_VGID_LIST, "Invalid vgid list") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COLS_FUNCTION, "Invalid cols function") -TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC, "cols function's first param must be a select function") +TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COLS_SELECTFUNC, "cols function's first param must be a select function that output a single row") TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_MULITI_COLS_FUNC, "Improper use of cols function with multiple output columns") TAOS_DEFINE_ERROR(TSDB_CODE_INVALID_COLS_ALIAS, "Invalid using alias for cols function") diff --git a/tests/system-test/2-query/cols_function.py b/tests/system-test/2-query/cols_function.py index 53c7f33174..bacab811ea 100644 --- a/tests/system-test/2-query/cols_function.py +++ b/tests/system-test/2-query/cols_function.py @@ -288,7 +288,6 @@ class TDTestCase: tdSql.checkData(0, 2, 4) tdSql.checkData(0, 3, 1) - # there's some error on last_row func when using sub query. tdSql.query(f'select count(1), cols(last_row(ts), ts, c0), min(c0) from test.meters') tdSql.checkRows(1) tdSql.checkCols(4) @@ -297,7 +296,6 @@ class TDTestCase: tdSql.checkData(0, 2, 4) tdSql.checkData(0, 3, 1) - # there's some error on last_row func when using sub query. tdSql.query(f'select count(1), cols(last_row(ts), ts, c0), last_row(c1), last_row(c3) from test.meters') tdSql.checkRows(1) tdSql.checkCols(5) @@ -896,6 +894,12 @@ class TDTestCase: tdSql.error(f'select cols(first(ts+1), c0+2 cc0, c1 cc1) cc from {self.dbname}.meters') tdSql.error(f'select cols(last(ts)+1, c0+2 as cc0) as cc from {self.dbname}.meters') tdSql.error(f'select cols(ABS(c0), c1) from {self.dbname}.meters group by tbname') + tdSql.error(f'select cols(top(c0, 5), c1) from {self.dbname}.meters') + tdSql.error(f'select cols(tail(c0, 5),c1) from {self.dbname}.meters') + tdSql.error(f'select cols(BOTTOM(c0, 5),c1) from {self.dbname}.meters') + tdSql.error(f'select cols(tail(ts, 5),c1) from {self.dbname}.meters') + tdSql.error(f'select cols(UNIQUE(ts),c1) from {self.dbname}.meters') + tdSql.error(f'select cols(sample(ts, 5),c1) from {self.dbname}.meters') tdSql.error(f'select cols(last(ts)+1, ts) from {self.dbname}.meters') tdSql.error(f'select cols(last(ts)+10, c1+10) from {self.dbname}.meters group by tbname')