Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
e633174a
T
TDengine
项目概览
慢慢CG
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
未验证
提交
e633174a
编写于
7月 18, 2020
作者:
S
Shengliang Guan
提交者:
GitHub
7月 18, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #2703 from taosdata/feature/query
[td-225] fix bugs in first/last query
上级
3fb51717
3d16404e
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
110 addition
and
62 deletion
+110
-62
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+84
-62
tests/script/general/parser/first_last_query.sim
tests/script/general/parser/first_last_query.sim
+11
-0
tests/script/general/parser/null_char.sim
tests/script/general/parser/null_char.sim
+15
-0
未找到文件。
src/query/src/qExecutor.c
浏览文件 @
e633174a
...
...
@@ -2236,6 +2236,27 @@ static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pB
}
}
static
void
doSetInitialTimewindow
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SDataBlockInfo
*
pBlockInfo
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
pRuntimeEnv
->
windowResInfo
.
prevSKey
==
TSKEY_INITIAL_VAL
)
{
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
SWindowResInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowResInfo
;
if
(
QUERY_IS_ASC_QUERY
(
pQuery
))
{
getAlignQueryTimeWindow
(
pQuery
,
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
skey
,
pQuery
->
window
.
ekey
,
&
w
);
pWindowResInfo
->
startTime
=
w
.
skey
;
pWindowResInfo
->
prevSKey
=
w
.
skey
;
}
else
{
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
getAlignQueryTimeWindow
(
pQuery
,
pBlockInfo
->
window
.
ekey
,
pQuery
->
window
.
ekey
,
pBlockInfo
->
window
.
ekey
,
&
w
);
pWindowResInfo
->
startTime
=
pQuery
->
window
.
skey
;
pWindowResInfo
->
prevSKey
=
w
.
skey
;
}
}
}
static
int64_t
doScanAllDataBlocks
(
SQueryRuntimeEnv
*
pRuntimeEnv
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
STableQueryInfo
*
pTableQueryInfo
=
pQuery
->
current
;
...
...
@@ -2263,24 +2284,7 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
}
tsdbRetrieveDataBlockInfo
(
pQueryHandle
,
&
blockInfo
);
// todo extract methods
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
pRuntimeEnv
->
windowResInfo
.
prevSKey
==
TSKEY_INITIAL_VAL
)
{
STimeWindow
w
=
TSWINDOW_INITIALIZER
;
SWindowResInfo
*
pWindowResInfo
=
&
pRuntimeEnv
->
windowResInfo
;
if
(
QUERY_IS_ASC_QUERY
(
pQuery
))
{
getAlignQueryTimeWindow
(
pQuery
,
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
skey
,
pQuery
->
window
.
ekey
,
&
w
);
pWindowResInfo
->
startTime
=
w
.
skey
;
pWindowResInfo
->
prevSKey
=
w
.
skey
;
}
else
{
// the start position of the first time window in the endpoint that spreads beyond the queried last timestamp
getAlignQueryTimeWindow
(
pQuery
,
blockInfo
.
window
.
ekey
,
pQuery
->
window
.
ekey
,
blockInfo
.
window
.
ekey
,
&
w
);
pWindowResInfo
->
startTime
=
pQuery
->
window
.
skey
;
pWindowResInfo
->
prevSKey
=
w
.
skey
;
}
}
doSetInitialTimewindow
(
pRuntimeEnv
,
&
blockInfo
);
// in case of prj/diff query, ensure the output buffer is sufficient to accommodate the results of current block
ensureOutputBuffer
(
pRuntimeEnv
,
&
blockInfo
);
...
...
@@ -2314,7 +2318,6 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
IS_MASTER_SCAN
(
pRuntimeEnv
))
{
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
closeAllTimeWindow
(
&
pRuntimeEnv
->
windowResInfo
);
// removeRedundantWindow(&pRuntimeEnv->windowResInfo, pTableQueryInfo->lastKey - step, step);
pRuntimeEnv
->
windowResInfo
.
curIndex
=
pRuntimeEnv
->
windowResInfo
.
size
-
1
;
// point to the last time window
}
else
{
assert
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
));
...
...
@@ -3223,6 +3226,13 @@ static void setEnvBeforeReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatusI
SWAP
(
pQuery
->
window
.
skey
,
pQuery
->
window
.
ekey
,
TSKEY
);
SWITCH_ORDER
(
pQuery
->
order
.
order
);
if
(
QUERY_IS_ASC_QUERY
(
pQuery
))
{
assert
(
pQuery
->
window
.
skey
<=
pQuery
->
window
.
ekey
);
}
else
{
assert
(
pQuery
->
window
.
skey
>=
pQuery
->
window
.
ekey
);
}
SET_REVERSE_SCAN_FLAG
(
pRuntimeEnv
);
STsdbQueryCond
cond
=
{
...
...
@@ -3262,8 +3272,7 @@ static void clearEnvAfterReverseScan(SQueryRuntimeEnv *pRuntimeEnv, SQueryStatus
SET_MASTER_SCAN_FLAG
(
pRuntimeEnv
);
// update the pQuery->window.skey and pQuery->window.ekey to limit the scan scope of sliding query
// during reverse scan
// update the pQuery->window.skey and pQuery->window.ekey to limit the scan scope of sliding query during reverse scan
pTableQueryInfo
->
lastKey
=
pStatus
->
lastKey
;
pQuery
->
status
=
pStatus
->
status
;
...
...
@@ -3289,7 +3298,12 @@ void scanOneTableDataBlocks(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) {
if
(
pRuntimeEnv
->
scanFlag
==
MASTER_SCAN
)
{
qstatus
.
status
=
pQuery
->
status
;
qstatus
.
curWindow
.
ekey
=
pTableQueryInfo
->
lastKey
-
step
;
// do nothing if no data blocks are found qualified during scan
if
(
qstatus
.
lastKey
!=
pTableQueryInfo
->
lastKey
)
{
qstatus
.
curWindow
.
ekey
=
pTableQueryInfo
->
lastKey
-
step
;
}
qstatus
.
lastKey
=
pTableQueryInfo
->
lastKey
;
}
...
...
@@ -6282,7 +6296,7 @@ void qTableQuery(qinfo_t qinfo) {
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
if
(
onlyQueryTags
(
pQInfo
->
runtimeEnv
.
pQuery
))
{
assert
(
pQInfo
->
runtimeEnv
.
pQueryHandle
==
NULL
);
buildTagQueryResult
(
pQInfo
);
// todo support the limit/offset
buildTagQueryResult
(
pQInfo
);
}
else
if
(
pQInfo
->
runtimeEnv
.
stableQuery
)
{
stableQueryImpl
(
pQInfo
);
}
else
{
...
...
@@ -6403,6 +6417,22 @@ int32_t qKillQuery(qinfo_t qinfo) {
return
TSDB_CODE_SUCCESS
;
}
static
void
doSetTagValueToResultBuf
(
char
*
output
,
const
char
*
val
,
int16_t
type
,
int16_t
bytes
)
{
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
val
==
NULL
)
{
setVardataNull
(
output
,
type
);
}
else
{
memcpy
(
output
,
val
,
varDataTLen
(
val
));
}
}
else
{
if
(
val
==
NULL
)
{
setNull
(
output
,
type
,
bytes
);
}
else
{
// todo here stop will cause client crash
memcpy
(
output
,
val
,
bytes
);
}
}
}
static
void
buildTagQueryResult
(
SQInfo
*
pQInfo
)
{
SQueryRuntimeEnv
*
pRuntimeEnv
=
&
pQInfo
->
runtimeEnv
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
...
...
@@ -6459,25 +6489,11 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
output
+=
sizeof
(
pQInfo
->
vgId
);
if
(
pExprInfo
->
base
.
colInfo
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
char
*
data
=
tsdbGetTableName
(
item
->
pTable
);
char
*
data
=
tsdbGetTableName
(
item
->
pTable
);
memcpy
(
output
,
data
,
varDataTLen
(
data
));
}
else
{
char
*
val
=
tsdbGetTableTagVal
(
item
->
pTable
,
pExprInfo
->
base
.
colInfo
.
colId
,
type
,
bytes
);
// todo refactor
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
val
==
NULL
)
{
setVardataNull
(
output
,
type
);
}
else
{
memcpy
(
output
,
val
,
varDataTLen
(
val
));
}
}
else
{
if
(
val
==
NULL
)
{
setNull
(
output
,
type
,
bytes
);
}
else
{
// todo here stop will cause client crash
memcpy
(
output
,
val
,
bytes
);
}
}
char
*
data
=
tsdbGetTableTagVal
(
item
->
pTable
,
pExprInfo
->
base
.
colInfo
.
colId
,
type
,
bytes
);
doSetTagValueToResultBuf
(
output
,
data
,
type
,
bytes
);
}
count
+=
1
;
...
...
@@ -6494,38 +6510,44 @@ static void buildTagQueryResult(SQInfo* pQInfo) {
}
else
{
// return only the tags|table name etc.
count
=
0
;
SSchema
tbnameSchema
=
tGetTableNameColumnSchema
();
while
(
pQInfo
->
tableIndex
<
num
&&
count
<
pQuery
->
rec
.
capacity
)
{
int32_t
maxNumOfTables
=
pQuery
->
rec
.
capacity
;
if
(
pQuery
->
limit
.
limit
>=
0
&&
pQuery
->
limit
.
limit
<
pQuery
->
rec
.
capacity
)
{
maxNumOfTables
=
pQuery
->
limit
.
limit
;
}
while
(
pQInfo
->
tableIndex
<
num
&&
count
<
maxNumOfTables
)
{
int32_t
i
=
pQInfo
->
tableIndex
++
;
// discard current result due to offset
if
(
pQuery
->
limit
.
offset
>
0
)
{
pQuery
->
limit
.
offset
-=
1
;
continue
;
}
SExprInfo
*
pExprInfo
=
pQuery
->
pSelectExpr
;
STableQueryInfo
*
item
=
taosArrayGetP
(
pa
,
i
);
char
*
data
=
NULL
,
*
dst
=
NULL
;
int16_t
type
=
0
,
bytes
=
0
;
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
if
(
pExprInfo
[
j
].
base
.
colInfo
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
char
*
data
=
tsdbGetTableName
(
item
->
pTable
);
char
*
dst
=
pQuery
->
sdata
[
j
]
->
data
+
count
*
tbnameSchema
.
bytes
;
memcpy
(
dst
,
data
,
varDataTLen
(
data
));
}
else
{
// todo refactor
int16_t
type
=
pExprInfo
[
j
].
type
;
int16_t
bytes
=
pExprInfo
[
j
].
bytes
;
bytes
=
tbnameSchema
.
bytes
;
type
=
tbnameSchema
.
type
;
data
=
tsdbGetTableName
(
item
->
pTable
);
dst
=
pQuery
->
sdata
[
j
]
->
data
+
count
*
tbnameSchema
.
bytes
;
}
else
{
type
=
pExprInfo
[
j
].
type
;
bytes
=
pExprInfo
[
j
].
bytes
;
char
*
data
=
tsdbGetTableTagVal
(
item
->
pTable
,
pExprInfo
[
j
].
base
.
colInfo
.
colId
,
type
,
bytes
);
char
*
dst
=
pQuery
->
sdata
[
j
]
->
data
+
count
*
pExprInfo
[
j
].
bytes
;
data
=
tsdbGetTableTagVal
(
item
->
pTable
,
pExprInfo
[
j
].
base
.
colInfo
.
colId
,
type
,
bytes
);
dst
=
pQuery
->
sdata
[
j
]
->
data
+
count
*
pExprInfo
[
j
].
bytes
;
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
if
(
data
==
NULL
)
{
setVardataNull
(
dst
,
type
);
}
else
{
memcpy
(
dst
,
data
,
varDataTLen
(
data
));
}
}
else
{
if
(
data
==
NULL
)
{
setNull
(
dst
,
type
,
bytes
);
}
else
{
memcpy
(
dst
,
data
,
pExprInfo
[
j
].
bytes
);
}
}
}
doSetTagValueToResultBuf
(
dst
,
data
,
type
,
bytes
);
}
count
+=
1
;
}
...
...
tests/script/general/parser/first_last_query.sim
浏览文件 @
e633174a
...
...
@@ -126,3 +126,14 @@ endi
if $data01 != 0 then
return -1
endi
#add check for out of range first/last query
sql select first(ts),last(ts) from first_tb4 where ts>'2018-9-18 1:40:01';
if $row != 0 then
return -1
endi
sql select first(ts),last(ts) from first_tb4 where ts<'2018-9-17 8:50:0';
if $row != 0 then
return -1
endi
\ No newline at end of file
tests/script/general/parser/null_char.sim
浏览文件 @
e633174a
...
...
@@ -105,6 +105,21 @@ if $data03 != 1 then
return -1
endi
sql select tag1 from st2 limit 20 offset 1
if $rows != 0 then
return -1
endi
sql select tag1 from st2 limit 10 offset 2
if $rows != 0 then
return -1
endi
sql select tag1 from st2 limit 0 offset 0
if $rows != 0 then
return -1
endi
sql create table st3 using mt2 tags (NULL, 'ABC', 103, 'FALSE')
sql select tag1, tag2, tag3, tag5 from st3
if $rows != 1 then
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录