Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
69e3a806
TDengine
项目概览
taosdata
/
TDengine
大约 2 年 前同步成功
通知
1193
Star
22018
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
69e3a806
编写于
12月 29, 2021
作者:
A
Alex Duan
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
[TS-802]<bug>(query): fixed first last problem with order by
上级
4801f785
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
43 addition
and
30 deletion
+43
-30
src/client/src/tscUtil.c
src/client/src/tscUtil.c
+12
-0
src/query/src/qAggMain.c
src/query/src/qAggMain.c
+24
-23
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+7
-7
未找到文件。
src/client/src/tscUtil.c
浏览文件 @
69e3a806
...
@@ -1340,6 +1340,18 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
...
@@ -1340,6 +1340,18 @@ void handleDownstreamOperator(SSqlObj** pSqlObjList, int32_t numOfUpstream, SQue
break
;
break
;
}
}
}
}
// set input data order to param[1]
if
(
pex
->
base
.
functionId
==
TSDB_FUNC_FIRST
||
pex
->
base
.
functionId
==
TSDB_FUNC_FIRST_DST
||
pex
->
base
.
functionId
==
TSDB_FUNC_LAST
||
pex
->
base
.
functionId
==
TSDB_FUNC_LAST
)
{
// set input order
SQueryInfo
*
pInputQI
=
pSqlObjList
[
0
]
->
cmd
.
pQueryInfo
;
if
(
pInputQI
)
{
pex
->
base
.
numOfParams
=
2
;
pex
->
base
.
param
[
1
].
nType
=
TSDB_DATA_TYPE_INT
;
pex
->
base
.
param
[
1
].
i64
=
pInputQI
->
order
.
order
;
}
}
}
}
tscDebug
(
"0x%"
PRIx64
" create QInfo 0x%"
PRIx64
" to execute the main query while all nest queries are ready"
,
pSql
->
self
,
pSql
->
self
);
tscDebug
(
"0x%"
PRIx64
" create QInfo 0x%"
PRIx64
" to execute the main query while all nest queries are ready"
,
pSql
->
self
,
pSql
->
self
);
...
...
src/query/src/qAggMain.c
浏览文件 @
69e3a806
...
@@ -698,10 +698,6 @@ static int32_t dataBlockRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t c
...
@@ -698,10 +698,6 @@ static int32_t dataBlockRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t c
// todo: if column in current data block are null, opt for this case
// todo: if column in current data block are null, opt for this case
static
int32_t
firstFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
static
int32_t
firstFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
return
BLK_DATA_NO_NEEDED
;
}
// no result for first query, data block is required
// no result for first query, data block is required
if
(
GET_RES_INFO
(
pCtx
)
==
NULL
||
GET_RES_INFO
(
pCtx
)
->
numOfRes
<=
0
)
{
if
(
GET_RES_INFO
(
pCtx
)
==
NULL
||
GET_RES_INFO
(
pCtx
)
->
numOfRes
<=
0
)
{
return
BLK_DATA_ALL_NEEDED
;
return
BLK_DATA_ALL_NEEDED
;
...
@@ -710,11 +706,7 @@ static int32_t firstFuncRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t c
...
@@ -710,11 +706,7 @@ static int32_t firstFuncRequired(SQLFunctionCtx *pCtx, STimeWindow* w, int32_t c
}
}
}
}
static
int32_t
lastFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
static
int32_t
lastFuncRequired
(
SQLFunctionCtx
*
pCtx
,
STimeWindow
*
w
,
int32_t
colId
)
{
if
(
pCtx
->
order
!=
pCtx
->
param
[
0
].
i64
)
{
return
BLK_DATA_NO_NEEDED
;
}
if
(
GET_RES_INFO
(
pCtx
)
==
NULL
||
GET_RES_INFO
(
pCtx
)
->
numOfRes
<=
0
)
{
if
(
GET_RES_INFO
(
pCtx
)
==
NULL
||
GET_RES_INFO
(
pCtx
)
->
numOfRes
<=
0
)
{
return
BLK_DATA_ALL_NEEDED
;
return
BLK_DATA_ALL_NEEDED
;
}
else
{
}
else
{
...
@@ -1523,15 +1515,20 @@ static bool first_last_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo*
...
@@ -1523,15 +1515,20 @@ static bool first_last_function_setup(SQLFunctionCtx *pCtx, SResultRowCellInfo*
}
}
// todo opt for null block
// todo opt for null block
static
void
first_function
(
SQLFunctionCtx
*
pCtx
)
{
static
void
first_function
(
SQLFunctionCtx
*
pCtx
)
{
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
return
;
}
int32_t
notNullElems
=
0
;
int32_t
notNullElems
=
0
;
int32_t
step
=
1
;
int32_t
i
=
0
;
if
(
pCtx
->
numOfParams
==
2
)
{
if
(
pCtx
->
param
[
1
].
nType
==
TSDB_DATA_TYPE_INT
&&
pCtx
->
param
[
1
].
i64
==
TSDB_ORDER_DESC
)
{
step
=
-
1
;
i
=
pCtx
->
size
-
1
;
}
}
// handle the null value
// handle the null value
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
for
(
int32_t
m
=
0
;
m
<
pCtx
->
size
;
++
m
,
i
+=
step
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
continue
;
continue
;
...
@@ -1634,16 +1631,20 @@ static void first_dist_func_merge(SQLFunctionCtx *pCtx) {
...
@@ -1634,16 +1631,20 @@ static void first_dist_func_merge(SQLFunctionCtx *pCtx) {
* least one data in this block that is not null.(TODO opt for this case)
* least one data in this block that is not null.(TODO opt for this case)
*/
*/
static
void
last_function
(
SQLFunctionCtx
*
pCtx
)
{
static
void
last_function
(
SQLFunctionCtx
*
pCtx
)
{
if
(
pCtx
->
order
!=
pCtx
->
param
[
0
].
i64
)
{
return
;
}
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
int32_t
notNullElems
=
0
;
int32_t
notNullElems
=
0
;
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
int32_t
step
=
-
1
;
int32_t
i
=
pCtx
->
size
-
1
;
for
(
int32_t
i
=
pCtx
->
size
-
1
;
i
>=
0
;
--
i
)
{
if
(
pCtx
->
numOfParams
==
2
)
{
if
(
pCtx
->
param
[
1
].
nType
==
TSDB_DATA_TYPE_INT
&&
pCtx
->
param
[
1
].
i64
==
TSDB_ORDER_DESC
)
{
step
=
1
;
i
=
0
;
}
}
if
(
pCtx
->
order
==
TSDB_ORDER_DESC
)
{
for
(
int32_t
m
=
pCtx
->
size
-
1
;
m
>=
0
;
--
m
,
i
+=
step
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
)
&&
(
!
pCtx
->
requireNull
))
{
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
)
&&
(
!
pCtx
->
requireNull
))
{
continue
;
continue
;
...
@@ -1660,7 +1661,7 @@ static void last_function(SQLFunctionCtx *pCtx) {
...
@@ -1660,7 +1661,7 @@ static void last_function(SQLFunctionCtx *pCtx) {
break
;
break
;
}
}
}
else
{
// ascending order
}
else
{
// ascending order
for
(
int32_t
i
=
pCtx
->
size
-
1
;
i
>=
0
;
--
i
)
{
for
(
int32_t
m
=
pCtx
->
size
-
1
;
m
>=
0
;
--
m
,
i
+=
step
)
{
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
char
*
data
=
GET_INPUT_DATA
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
)
&&
(
!
pCtx
->
requireNull
))
{
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
)
&&
(
!
pCtx
->
requireNull
))
{
continue
;
continue
;
...
...
src/query/src/qExecutor.c
浏览文件 @
69e3a806
...
@@ -1910,7 +1910,7 @@ static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pD
...
@@ -1910,7 +1910,7 @@ static int32_t getGroupbyColumnIndex(SGroupbyExpr *pGroupbyExpr, SSDataBlock* pD
static
bool
functionNeedToExecute
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SQLFunctionCtx
*
pCtx
)
{
static
bool
functionNeedToExecute
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SQLFunctionCtx
*
pCtx
)
{
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SResultRowCellInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SQueryAttr
*
pQueryAttr
=
pRuntimeEnv
->
pQueryAttr
;
//
SQueryAttr* pQueryAttr = pRuntimeEnv->pQueryAttr;
// in case of timestamp column, always generated results.
// in case of timestamp column, always generated results.
int32_t
functionId
=
pCtx
->
functionId
;
int32_t
functionId
=
pCtx
->
functionId
;
...
@@ -1922,14 +1922,14 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
...
@@ -1922,14 +1922,14 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx
return
false
;
return
false
;
}
}
if
(
functionId
==
TSDB_FUNC_FIRST_DST
||
functionId
==
TSDB_FUNC_FIRST
)
{
//
if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_FIRST) {
return
QUERY_IS_ASC_QUERY
(
pQueryAttr
);
//
return QUERY_IS_ASC_QUERY(pQueryAttr);
}
//
}
// denote the order type
// denote the order type
if
((
functionId
==
TSDB_FUNC_LAST_DST
||
functionId
==
TSDB_FUNC_LAST
))
{
//
if ((functionId == TSDB_FUNC_LAST_DST || functionId == TSDB_FUNC_LAST)) {
return
pCtx
->
param
[
0
].
i64
==
pQueryAttr
->
order
.
order
;
//
return pCtx->param[0].i64 == pQueryAttr->order.order;
}
//
}
// in the reverse table scan, only the following functions need to be executed
// in the reverse table scan, only the following functions need to be executed
if
(
IS_REVERSE_SCAN
(
pRuntimeEnv
)
||
if
(
IS_REVERSE_SCAN
(
pRuntimeEnv
)
||
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录