Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
codyshao
TDengine
提交
26ff7966
T
TDengine
项目概览
codyshao
/
TDengine
与 Fork 源项目一致
Fork自
taosdata / TDengine
通知
2
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看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
26ff7966
编写于
5月 21, 2020
作者:
S
Shengliang Guan
提交者:
GitHub
5月 21, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #1980 from taosdata/feature/query
Feature/query
上级
0d8027a0
1f83d525
变更
10
隐藏空白更改
内联
并排
Showing
10 changed file
with
244 addition
and
242 deletion
+244
-242
src/client/src/tscParseInsert.c
src/client/src/tscParseInsert.c
+13
-13
src/client/src/tscProfile.c
src/client/src/tscProfile.c
+0
-2
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+64
-39
src/query/src/qtokenizer.c
src/query/src/qtokenizer.c
+13
-130
src/tsdb/src/tsdbRead.c
src/tsdb/src/tsdbRead.c
+2
-0
src/util/inc/tstoken.h
src/util/inc/tstoken.h
+109
-4
src/util/src/hash.c
src/util/src/hash.c
+26
-28
src/util/src/thashutil.c
src/util/src/thashutil.c
+10
-19
tests/script/general/parser/limit1.sim
tests/script/general/parser/limit1.sim
+1
-1
tests/script/general/parser/limit1_tb.sim
tests/script/general/parser/limit1_tb.sim
+6
-6
未找到文件。
src/client/src/tscParseInsert.c
浏览文件 @
26ff7966
...
...
@@ -42,35 +42,35 @@ enum {
static
int32_t
tscAllocateMemIfNeed
(
STableDataBlocks
*
pDataBlock
,
int32_t
rowSize
,
int32_t
*
numOfRows
);
static
int32_t
tscToInteger
(
SSQLToken
*
pToken
,
int64_t
*
value
,
char
**
endPtr
)
{
int32_t
numType
=
isValidNumber
(
pToken
);
if
(
TK_ILLEGAL
==
numType
)
{
return
numType
;
}
//
int32_t numType = isValidNumber(pToken);
//
if (TK_ILLEGAL == numType) {
//
return numType;
//
}
int32_t
radix
=
10
;
if
(
numT
ype
==
TK_HEX
)
{
if
(
pToken
->
t
ype
==
TK_HEX
)
{
radix
=
16
;
}
else
if
(
numT
ype
==
TK_OCT
)
{
}
else
if
(
pToken
->
t
ype
==
TK_OCT
)
{
radix
=
8
;
}
else
if
(
numT
ype
==
TK_BIN
)
{
}
else
if
(
pToken
->
t
ype
==
TK_BIN
)
{
radix
=
2
;
}
errno
=
0
;
*
value
=
strtoll
(
pToken
->
z
,
endPtr
,
radix
);
return
numT
ype
;
return
pToken
->
t
ype
;
}
static
int32_t
tscToDouble
(
SSQLToken
*
pToken
,
double
*
value
,
char
**
endPtr
)
{
int32_t
numType
=
isValidNumber
(
pToken
);
if
(
TK_ILLEGAL
==
numType
)
{
return
numType
;
}
//
int32_t numType = isValidNumber(pToken);
//
if (TK_ILLEGAL == numType) {
//
return numType;
//
}
errno
=
0
;
*
value
=
strtod
(
pToken
->
z
,
endPtr
);
return
numT
ype
;
return
pToken
->
t
ype
;
}
int
tsParseTime
(
SSQLToken
*
pToken
,
int64_t
*
time
,
char
**
next
,
char
*
error
,
int16_t
timePrec
)
{
...
...
src/client/src/tscProfile.c
浏览文件 @
26ff7966
...
...
@@ -23,8 +23,6 @@
void
tscSaveSlowQueryFp
(
void
*
handle
,
void
*
tmrId
);
void
*
tscSlowQueryConn
=
NULL
;
bool
tscSlowQueryConnInitialized
=
false
;
TAOS
*
taos_connect_a
(
char
*
ip
,
char
*
user
,
char
*
pass
,
char
*
db
,
uint16_t
port
,
void
(
*
fp
)(
void
*
,
TAOS_RES
*
,
int
),
void
*
param
,
void
**
taos
);
void
tscInitConnCb
(
void
*
param
,
TAOS_RES
*
result
,
int
code
)
{
char
*
sql
=
param
;
...
...
src/query/src/qExecutor.c
浏览文件 @
26ff7966
...
...
@@ -97,7 +97,9 @@ typedef struct {
STSCursor
cur
;
}
SQueryStatusInfo
;
#define CLEAR_QUERY_STATUS(q, st) ((q)->status &= (~(st)))
static
void
setQueryStatus
(
SQuery
*
pQuery
,
int8_t
status
);
static
bool
isIntervalQuery
(
SQuery
*
pQuery
)
{
return
pQuery
->
intervalTime
>
0
;
}
// todo move to utility
...
...
@@ -278,6 +280,26 @@ int64_t getNumOfResult(SQueryRuntimeEnv *pRuntimeEnv) {
return
maxOutput
;
}
/*
* the value of number of result needs to be update due to offset value upated.
*/
void
updateNumOfResult
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
int32_t
numOfRes
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
for
(
int32_t
j
=
0
;
j
<
pQuery
->
numOfOutput
;
++
j
)
{
SResultInfo
*
pResInfo
=
GET_RES_INFO
(
&
pRuntimeEnv
->
pCtx
[
j
]);
int16_t
functionId
=
pRuntimeEnv
->
pCtx
[
j
].
functionId
;
if
(
functionId
==
TSDB_FUNC_TS
||
functionId
==
TSDB_FUNC_TAG
||
functionId
==
TSDB_FUNC_TAGPRJ
||
functionId
==
TSDB_FUNC_TS_DUMMY
)
{
continue
;
}
assert
(
pResInfo
->
numOfRes
>
numOfRes
);
pResInfo
->
numOfRes
=
numOfRes
;
}
}
static
int32_t
getGroupResultId
(
int32_t
groupIndex
)
{
int32_t
base
=
200000
;
return
base
+
(
groupIndex
*
10000
);
...
...
@@ -354,9 +376,7 @@ bool isSelectivityWithTagsQuery(SQuery *pQuery) {
bool
isTSCompQuery
(
SQuery
*
pQuery
)
{
return
pQuery
->
pSelectExpr
[
0
].
base
.
functionId
==
TSDB_FUNC_TS_COMP
;
}
static
bool
limitResults
(
SQInfo
*
pQInfo
)
{
SQuery
*
pQuery
=
pQInfo
->
runtimeEnv
.
pQuery
;
static
bool
limitResults
(
SQuery
*
pQuery
)
{
if
((
pQuery
->
limit
.
limit
>
0
)
&&
(
pQuery
->
rec
.
total
+
pQuery
->
rec
.
rows
>
pQuery
->
limit
.
limit
))
{
pQuery
->
rec
.
rows
=
pQuery
->
limit
.
limit
-
pQuery
->
rec
.
total
;
assert
(
pQuery
->
rec
.
rows
>
0
);
...
...
@@ -626,6 +646,7 @@ static void doCheckQueryCompleted(SQueryRuntimeEnv *pRuntimeEnv, TSKEY lastKey,
int32_t
i
=
0
;
int64_t
skey
=
TSKEY_INITIAL_VAL
;
// TODO opt performance: get the closed time window here
for
(
i
=
0
;
i
<
pWindowResInfo
->
size
;
++
i
)
{
SWindowResult
*
pResult
=
&
pWindowResInfo
->
pResult
[
i
];
if
(
pResult
->
status
.
closed
)
{
...
...
@@ -1303,6 +1324,10 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl
if
(
numOfRes
>=
pQuery
->
rec
.
threshold
)
{
setQueryStatus
(
pQuery
,
QUERY_RESBUF_FULL
);
}
if
((
pQuery
->
limit
.
limit
>=
0
)
&&
numOfRes
>=
(
pQuery
->
limit
.
limit
+
pQuery
->
limit
.
offset
))
{
setQueryStatus
(
pQuery
,
QUERY_COMPLETED
);
}
}
return
numOfRes
;
...
...
@@ -2408,6 +2433,7 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
char
*
tmp
=
realloc
(
pQuery
->
sdata
[
i
],
bytes
*
newSize
+
sizeof
(
tFilePage
));
if
(
tmp
==
NULL
)
{
// todo handle the oom
assert
(
0
);
}
else
{
pQuery
->
sdata
[
i
]
=
(
tFilePage
*
)
tmp
;
}
...
...
@@ -2421,7 +2447,7 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
}
}
qTrace
(
"QInfo:
%p realloc output buffer, new size: %d rows, old:%d, remain:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
qTrace
(
"QInfo:%p realloc output buffer, new size: %d rows, old:%d, remain:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
newSize
,
pRec
->
capacity
,
newSize
-
pRec
->
rows
);
pRec
->
capacity
=
newSize
;
...
...
@@ -2434,11 +2460,11 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
pQuery
->
pos
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
0
:
blockInfo
.
rows
-
1
;
int32_t
numOfRes
=
tableApplyFunctionsOnBlock
(
pRuntimeEnv
,
&
blockInfo
,
pStatis
,
binarySearchForKey
,
pDataBlock
);
qTrace
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", rows:%d,
r
es:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
qTrace
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", rows:%d,
numOfR
es:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
ekey
,
blockInfo
.
rows
,
numOfRes
);
//
save last access position
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
))
{
//
while the output buffer is full or limit/offset is applied, query may be paused here
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
|
QUERY_COMPLETED
))
{
break
;
}
}
...
...
@@ -3173,30 +3199,38 @@ void skipResults(SQueryRuntimeEnv *pRuntimeEnv) {
}
if
(
pQuery
->
rec
.
rows
<=
pQuery
->
limit
.
offset
)
{
qTrace
(
"QInfo:%p skip rows:%d, new offset:%"
PRIu64
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
pQuery
->
rec
.
rows
,
pQuery
->
limit
.
offset
-
pQuery
->
rec
.
rows
);
pQuery
->
limit
.
offset
-=
pQuery
->
rec
.
rows
;
pQuery
->
rec
.
rows
=
0
;
resetCtxOutputBuf
(
pRuntimeEnv
);
// clear the buffer
is
full flag if exists
pQuery
->
status
&=
(
~
QUERY_RESBUF_FULL
);
// clear the buffer full flag if exists
CLEAR_QUERY_STATUS
(
pQuery
,
QUERY_RESBUF_FULL
);
}
else
{
int
32_t
numOfSkip
=
(
int32_t
)
pQuery
->
limit
.
offset
;
int
64_t
numOfSkip
=
pQuery
->
limit
.
offset
;
pQuery
->
rec
.
rows
-=
numOfSkip
;
pQuery
->
limit
.
offset
=
0
;
qTrace
(
"QInfo:%p skip row:%"
PRId64
", new offset:%d, numOfRows remain:%"
PRIu64
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
numOfSkip
,
0
,
pQuery
->
rec
.
rows
);
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
int32_t
functionId
=
pQuery
->
pSelectExpr
[
i
].
base
.
functionId
;
int32_t
bytes
=
pRuntimeEnv
->
pCtx
[
i
].
outputBytes
;
memmove
(
pQuery
->
sdata
[
i
]
->
data
,
pQuery
->
sdata
[
i
]
->
data
+
bytes
*
numOfSkip
,
pQuery
->
rec
.
rows
*
bytes
);
pRuntimeEnv
->
pCtx
[
i
].
aOutputBuf
+=
bytes
*
numOfSkip
;
memmove
(
pQuery
->
sdata
[
i
]
->
data
,
(
char
*
)
pQuery
->
sdata
[
i
]
->
data
+
bytes
*
numOfSkip
,
pQuery
->
rec
.
rows
*
bytes
);
pRuntimeEnv
->
pCtx
[
i
].
aOutputBuf
=
((
char
*
)
pQuery
->
sdata
[
i
]
->
data
)
+
pQuery
->
rec
.
rows
*
bytes
;
if
(
functionId
==
TSDB_FUNC_DIFF
||
functionId
==
TSDB_FUNC_TOP
||
functionId
==
TSDB_FUNC_BOTTOM
)
{
pRuntimeEnv
->
pCtx
[
i
].
ptsOutputBuf
+=
TSDB_KEYSIZE
*
numOfSkip
;
pRuntimeEnv
->
pCtx
[
i
].
ptsOutputBuf
=
pRuntimeEnv
->
pCtx
[
0
].
aOutputBuf
;
}
}
pQuery
->
limit
.
offset
=
0
;
updateNumOfResult
(
pRuntimeEnv
,
pQuery
->
rec
.
rows
);
}
}
...
...
@@ -3205,7 +3239,7 @@ void setQueryStatus(SQuery *pQuery, int8_t status) {
pQuery
->
status
=
status
;
}
else
{
// QUERY_NOT_COMPLETED is not compatible with any other status, so clear its position first
pQuery
->
status
&=
(
~
QUERY_NOT_COMPLETED
);
CLEAR_QUERY_STATUS
(
pQuery
,
QUERY_NOT_COMPLETED
);
pQuery
->
status
|=
status
;
}
}
...
...
@@ -3957,7 +3991,7 @@ static void updateOffsetVal(SQueryRuntimeEnv *pRuntimeEnv, SDataBlockInfo *pBloc
int32_t
numOfRes
=
tableApplyFunctionsOnBlock
(
pRuntimeEnv
,
pBlockInfo
,
NULL
,
binarySearchForKey
,
pDataBlock
);
qTrace
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", rows:%d,
r
es:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
qTrace
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", rows:%d,
numOfR
es:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
ekey
,
pBlockInfo
->
rows
,
numOfRes
);
}
...
...
@@ -4075,7 +4109,7 @@ static bool skipTimeInterval(SQueryRuntimeEnv *pRuntimeEnv, TSKEY* start) {
int32_t
numOfRes
=
tableApplyFunctionsOnBlock
(
pRuntimeEnv
,
&
blockInfo
,
NULL
,
binarySearchForKey
,
pDataBlock
);
pRuntimeEnv
->
windowResInfo
.
curIndex
=
index
;
// restore the window index
qTrace
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", rows:%d,
r
es:%d"
,
qTrace
(
"QInfo:%p check data block, brange:%"
PRId64
"-%"
PRId64
", rows:%d,
numOfR
es:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
blockInfo
.
window
.
skey
,
blockInfo
.
window
.
ekey
,
blockInfo
.
rows
,
numOfRes
);
return
true
;
}
else
{
// do nothing
...
...
@@ -4532,8 +4566,6 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
continue
;
}
// SPointInterpoSupporter pointInterpSupporter = {0};
// TODO handle the limit offset problem
if
(
pQuery
->
numOfFilterCols
==
0
&&
pQuery
->
limit
.
offset
>
0
)
{
// skipBlocks(pRuntimeEnv);
...
...
@@ -4544,12 +4576,10 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
}
scanAllDataBlocks
(
pRuntimeEnv
,
pQuery
->
current
->
lastKey
);
pQuery
->
rec
.
rows
=
getNumOfResult
(
pRuntimeEnv
);
skipResults
(
pRuntimeEnv
);
// the limitation of output result is reached, set the query completed
if
(
limitResults
(
pQ
Info
))
{
if
(
limitResults
(
pQ
uery
))
{
pQInfo
->
tableIndex
=
pQInfo
->
groupInfo
.
numOfTables
;
break
;
}
...
...
@@ -4578,18 +4608,15 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
break
;
}
}
else
{
// forward query range
pQuery
->
window
.
skey
=
pQuery
->
current
->
lastKey
;
}
else
{
// all data in the result buffer are skipped due to the offset, continue to retrieve data from current meter
if
(
pQuery
->
rec
.
rows
==
0
)
{
assert
(
!
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
));
continue
;
}
else
{
// pQInfo->pTableQuerySupporter->pMeterSidExtInfo[k]->key = pQuery->lastKey;
// // buffer is full, wait for the next round to retrieve data from current meter
// assert(Q_STATUS_EQUAL(pQuery->over, QUERY_RESBUF_FULL));
// break;
// buffer is full, wait for the next round to retrieve data from current meter
assert
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
));
break
;
}
}
}
...
...
@@ -4633,10 +4660,8 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
copyFromWindowResToSData
(
pQInfo
,
pWindowResInfo
->
pResult
);
}
pQuery
->
rec
.
total
+=
pQuery
->
rec
.
rows
;
qTrace
(
"QInfo %p
,
numOfTables:%d, index:%d, numOfGroups:%d, %d points returned, total:%"
PRId64
", offset:%"
PRId64
,
"QInfo %p numOfTables:%d, index:%d, numOfGroups:%d, %d points returned, total:%"
PRId64
", offset:%"
PRId64
,
pQInfo
,
pQInfo
->
groupInfo
.
numOfTables
,
pQInfo
->
tableIndex
,
numOfGroups
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
,
pQuery
->
limit
.
offset
);
}
...
...
@@ -4809,7 +4834,7 @@ static void tableFixedOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
pQuery
->
rec
.
rows
=
getNumOfResult
(
pRuntimeEnv
);
skipResults
(
pRuntimeEnv
);
limitResults
(
pQ
Info
);
limitResults
(
pQ
uery
);
}
static
void
tableMultiOutputProcess
(
SQInfo
*
pQInfo
,
STableQueryInfo
*
pTableInfo
)
{
...
...
@@ -4857,7 +4882,7 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
resetCtxOutputBuf
(
pRuntimeEnv
);
}
limitResults
(
pQ
Info
);
limitResults
(
pQ
uery
);
if
(
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_RESBUF_FULL
))
{
qTrace
(
"QInfo:%p query paused due to output limitation, next qrange:%"
PRId64
"-%"
PRId64
,
pQInfo
,
pQuery
->
current
->
lastKey
,
pQuery
->
window
.
ekey
);
...
...
@@ -4935,7 +4960,7 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
// the offset is handled at prepare stage if no interpolation involved
if
(
pQuery
->
fillType
==
TSDB_FILL_NONE
||
pQuery
->
rec
.
rows
==
0
)
{
limitResults
(
pQ
Info
);
limitResults
(
pQ
uery
);
break
;
}
else
{
TSKEY
ekey
=
taosGetRevisedEndKey
(
pQuery
->
window
.
ekey
,
pQuery
->
order
.
order
,
pQuery
->
slidingTime
,
...
...
@@ -4947,7 +4972,7 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) {
qTrace
(
"QInfo: %p fill results completed, final:%d"
,
pQInfo
,
pQuery
->
rec
.
rows
);
if
(
pQuery
->
rec
.
rows
>
0
||
Q_STATUS_EQUAL
(
pQuery
->
status
,
QUERY_COMPLETED
))
{
limitResults
(
pQ
Info
);
limitResults
(
pQ
uery
);
break
;
}
...
...
@@ -4982,7 +5007,7 @@ static void tableQueryImpl(SQInfo *pQInfo) {
qTrace
(
"QInfo: %p fill results completed, final:%d"
,
pQInfo
,
pQuery
->
rec
.
rows
);
if
(
pQuery
->
rec
.
rows
>
0
)
{
limitResults
(
pQ
Info
);
limitResults
(
pQ
uery
);
}
qTrace
(
"QInfo:%p current:%d returned, total:%d"
,
pQInfo
,
pQuery
->
rec
.
rows
,
pQuery
->
rec
.
total
);
...
...
src/query/src/qtokenizer.c
浏览文件 @
26ff7966
...
...
@@ -282,11 +282,7 @@ int tSQLKeywordCode(const char* z, int n) {
}
SKeyword
**
pKey
=
(
SKeyword
**
)
taosHashGet
(
KeywordHashTable
,
key
,
n
);
if
(
pKey
!=
NULL
)
{
return
(
*
pKey
)
->
type
;
}
else
{
return
TK_ID
;
}
return
(
pKey
!=
NULL
)
?
(
*
pKey
)
->
type
:
TK_ID
;
}
/*
...
...
@@ -594,31 +590,28 @@ SSQLToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr, uint32_t numOfIgn
while
(
1
)
{
*
i
+=
t0
.
n
;
bool
hasComma
=
false
;
while
((
str
[
*
i
]
==
' '
||
str
[
*
i
]
==
'\n'
||
str
[
*
i
]
==
'\r'
||
str
[
*
i
]
==
'\t'
||
str
[
*
i
]
==
'\f'
)
||
str
[
*
i
]
==
','
)
{
if
(
str
[
*
i
]
==
','
)
{
if
(
false
==
hasComma
)
{
hasComma
=
true
;
}
else
{
// comma only allowed once
t0
.
n
=
0
;
return
t0
;
}
int32_t
numOfComma
=
0
;
char
t
=
str
[
*
i
];
while
(
t
==
' '
||
t
==
'\n'
||
t
==
'\r'
||
t
==
'\t'
||
t
==
'\f'
||
t
==
','
)
{
if
(
t
==
','
&&
(
++
numOfComma
>
1
))
{
// comma only allowed once
t0
.
n
=
0
;
return
t0
;
}
(
*
i
)
++
;
t
=
str
[
++
(
*
i
)];
}
t0
.
n
=
tSQLGetToken
(
&
str
[
*
i
],
&
t0
.
type
);
bool
ignore
Flag
=
false
;
bool
ignore
=
false
;
for
(
uint32_t
k
=
0
;
k
<
numOfIgnoreToken
;
k
++
)
{
if
(
t0
.
type
==
ignoreTokenTypes
[
k
])
{
ignore
Flag
=
true
;
ignore
=
true
;
break
;
}
}
if
(
!
ignore
Flag
)
{
if
(
!
ignore
)
{
break
;
}
}
...
...
@@ -662,114 +655,4 @@ SSQLToken tStrGetToken(char* str, int32_t* i, bool isPrevOptr, uint32_t numOfIgn
return
t0
;
}
FORCE_INLINE
bool
isKeyWord
(
const
char
*
z
,
int32_t
len
)
{
return
(
tSQLKeywordCode
((
char
*
)
z
,
len
)
!=
TK_ID
);
}
FORCE_INLINE
bool
isNumber
(
const
SSQLToken
*
pToken
)
{
return
(
pToken
->
type
==
TK_INTEGER
||
pToken
->
type
==
TK_FLOAT
||
pToken
->
type
==
TK_HEX
||
pToken
->
type
==
TK_BIN
);
}
int32_t
isValidNumber
(
const
SSQLToken
*
pToken
)
{
const
char
*
z
=
pToken
->
z
;
int32_t
type
=
TK_ILLEGAL
;
int32_t
i
=
0
;
for
(;
i
<
pToken
->
n
;
++
i
)
{
switch
(
z
[
i
])
{
case
'+'
:
case
'-'
:
{
break
;
}
case
'.'
:
{
/*
* handle the the float number with out integer part
* .123
* .123e4
*/
if
(
!
isdigit
(
z
[
i
+
1
]))
{
return
TK_ILLEGAL
;
}
for
(
i
+=
2
;
isdigit
(
z
[
i
]);
i
++
)
{
}
if
((
z
[
i
]
==
'e'
||
z
[
i
]
==
'E'
)
&&
(
isdigit
(
z
[
i
+
1
])
||
((
z
[
i
+
1
]
==
'+'
||
z
[
i
+
1
]
==
'-'
)
&&
isdigit
(
z
[
i
+
2
]))))
{
i
+=
2
;
while
(
isdigit
(
z
[
i
]))
{
i
++
;
}
}
type
=
TK_FLOAT
;
goto
_end
;
}
case
'0'
:
{
char
next
=
z
[
i
+
1
];
if
(
next
==
'b'
)
{
// bin number
type
=
TK_BIN
;
for
(
i
+=
2
;
(
z
[
i
]
==
'0'
||
z
[
i
]
==
'1'
);
++
i
)
{
}
goto
_end
;
}
else
if
(
next
==
'x'
)
{
//hex number
type
=
TK_HEX
;
for
(
i
+=
2
;
isdigit
(
z
[
i
])
||
(
z
[
i
]
>=
'a'
&&
z
[
i
]
<=
'f'
)
||
(
z
[
i
]
>=
'A'
&&
z
[
i
]
<=
'F'
);
++
i
)
{
}
goto
_end
;
}
}
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
{
type
=
TK_INTEGER
;
for
(;
isdigit
(
z
[
i
]);
i
++
)
{
}
int32_t
seg
=
0
;
while
(
z
[
i
]
==
'.'
&&
isdigit
(
z
[
i
+
1
]))
{
i
+=
2
;
while
(
isdigit
(
z
[
i
]))
{
i
++
;
}
seg
++
;
type
=
TK_FLOAT
;
}
if
(
seg
>
1
)
{
return
TK_ILLEGAL
;
}
if
((
z
[
i
]
==
'e'
||
z
[
i
]
==
'E'
)
&&
(
isdigit
(
z
[
i
+
1
])
||
((
z
[
i
+
1
]
==
'+'
||
z
[
i
+
1
]
==
'-'
)
&&
isdigit
(
z
[
i
+
2
]))))
{
i
+=
2
;
while
(
isdigit
(
z
[
i
]))
{
i
++
;
}
type
=
TK_FLOAT
;
}
goto
_end
;
}
default:
return
TK_ILLEGAL
;
}
}
_end:
if
(
i
<
pToken
->
n
)
{
return
TK_ILLEGAL
;
}
else
{
return
type
;
}
}
\ No newline at end of file
bool
isKeyWord
(
const
char
*
z
,
int32_t
len
)
{
return
(
tSQLKeywordCode
((
char
*
)
z
,
len
)
!=
TK_ID
);
}
\ No newline at end of file
src/tsdb/src/tsdbRead.c
浏览文件 @
26ff7966
...
...
@@ -395,6 +395,7 @@ static int32_t getFileCompInfo(STsdbQueryHandle* pQueryHandle, int32_t* numOfBlo
SCompIdx
*
compIndex
=
&
pQueryHandle
->
rhelper
.
pCompIdx
[
pCheckInfo
->
tableId
.
tid
];
if
(
compIndex
->
len
==
0
||
compIndex
->
numOfBlocks
==
0
)
{
// no data block in this file, try next file
pCheckInfo
->
numOfBlocks
=
0
;
continue
;
//no data blocks in the file belongs to pCheckInfo->pTable
}
else
{
if
(
pCheckInfo
->
compSize
<
compIndex
->
len
)
{
...
...
@@ -858,6 +859,7 @@ static void mergeDataInDataBlock(STsdbQueryHandle* pQueryHandle, STableCheckInfo
}
}
pos
+=
(
end
-
start
+
1
)
*
step
;
cur
->
blockCompleted
=
(((
pos
>=
endPos
||
cur
->
lastKey
>
pQueryHandle
->
window
.
ekey
)
&&
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
))
||
((
pos
<=
endPos
||
cur
->
lastKey
<
pQueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_ORDER_TRAVERSE
(
pQueryHandle
->
order
)));
...
...
src/util/inc/tstoken.h
浏览文件 @
26ff7966
...
...
@@ -21,6 +21,8 @@ extern "C" {
#endif
#include "os.h"
#include "tutil.h"
#include "ttokendef.h"
#define TK_SPACE 200
#define TK_COMMENT 201
...
...
@@ -31,7 +33,7 @@ extern "C" {
#define TK_FILE 206
#define TK_QUESTION 207 // denoting the placeholder of "?",when invoking statement bind query
#define TSQL_TBNAME "TBNAME"
#define TSQL_TBNAME
"TBNAME"
#define TSQL_TBNAME_L "tbname"
// used to denote the minimum unite in sql parsing
...
...
@@ -74,14 +76,117 @@ bool isKeyWord(const char *z, int32_t len);
* @param pToken
* @return
*/
bool
isNumber
(
const
SSQLToken
*
pToken
);
#define isNumber(tk) \
((tk)->type == TK_INTEGER || (tk)->type == TK_FLOAT || (tk)->type == TK_HEX || (tk)->type == TK_BIN)
/**
* check if it is a token or not
* @param pToken
* @return token type, if it is not a number, TK_ILLEGAL will return
* @return
token type, if it is not a number, TK_ILLEGAL will return
*/
int32_t
isValidNumber
(
const
SSQLToken
*
pToken
);
static
FORCE_INLINE
int32_t
isValidNumber
(
const
SSQLToken
*
pToken
)
{
const
char
*
z
=
pToken
->
z
;
int32_t
type
=
TK_ILLEGAL
;
int32_t
i
=
0
;
for
(;
i
<
pToken
->
n
;
++
i
)
{
switch
(
z
[
i
])
{
case
'+'
:
case
'-'
:
{
break
;
}
case
'.'
:
{
/*
* handle the the float number with out integer part
* .123
* .123e4
*/
if
(
!
isdigit
(
z
[
i
+
1
]))
{
return
TK_ILLEGAL
;
}
for
(
i
+=
2
;
isdigit
(
z
[
i
]);
i
++
)
{
}
if
((
z
[
i
]
==
'e'
||
z
[
i
]
==
'E'
)
&&
(
isdigit
(
z
[
i
+
1
])
||
((
z
[
i
+
1
]
==
'+'
||
z
[
i
+
1
]
==
'-'
)
&&
isdigit
(
z
[
i
+
2
]))))
{
i
+=
2
;
while
(
isdigit
(
z
[
i
]))
{
i
++
;
}
}
type
=
TK_FLOAT
;
goto
_end
;
}
case
'0'
:
{
char
next
=
z
[
i
+
1
];
if
(
next
==
'b'
)
{
// bin number
type
=
TK_BIN
;
for
(
i
+=
2
;
(
z
[
i
]
==
'0'
||
z
[
i
]
==
'1'
);
++
i
)
{
}
goto
_end
;
}
else
if
(
next
==
'x'
)
{
//hex number
type
=
TK_HEX
;
for
(
i
+=
2
;
isdigit
(
z
[
i
])
||
(
z
[
i
]
>=
'a'
&&
z
[
i
]
<=
'f'
)
||
(
z
[
i
]
>=
'A'
&&
z
[
i
]
<=
'F'
);
++
i
)
{
}
goto
_end
;
}
}
case
'1'
:
case
'2'
:
case
'3'
:
case
'4'
:
case
'5'
:
case
'6'
:
case
'7'
:
case
'8'
:
case
'9'
:
{
type
=
TK_INTEGER
;
for
(;
isdigit
(
z
[
i
]);
i
++
)
{
}
int32_t
seg
=
0
;
while
(
z
[
i
]
==
'.'
&&
isdigit
(
z
[
i
+
1
]))
{
i
+=
2
;
while
(
isdigit
(
z
[
i
]))
{
i
++
;
}
seg
++
;
type
=
TK_FLOAT
;
}
if
(
seg
>
1
)
{
return
TK_ILLEGAL
;
}
if
((
z
[
i
]
==
'e'
||
z
[
i
]
==
'E'
)
&&
(
isdigit
(
z
[
i
+
1
])
||
((
z
[
i
+
1
]
==
'+'
||
z
[
i
+
1
]
==
'-'
)
&&
isdigit
(
z
[
i
+
2
]))))
{
i
+=
2
;
while
(
isdigit
(
z
[
i
]))
{
i
++
;
}
type
=
TK_FLOAT
;
}
goto
_end
;
}
default:
return
TK_ILLEGAL
;
}
}
_end:
return
(
i
<
pToken
->
n
)
?
TK_ILLEGAL
:
type
;
}
#ifdef __cplusplus
}
...
...
src/util/src/hash.c
浏览文件 @
26ff7966
...
...
@@ -102,7 +102,32 @@ static void doUpdateHashTable(SHashObj *pHashObj, SHashNode *pNode);
* @param hashVal hash value by hash function
* @return
*/
static
SHashNode
*
doGetNodeFromHashTable
(
SHashObj
*
pHashObj
,
const
void
*
key
,
uint32_t
keyLen
,
uint32_t
*
hashVal
);
FORCE_INLINE
SHashNode
*
doGetNodeFromHashTable
(
SHashObj
*
pHashObj
,
const
void
*
key
,
uint32_t
keyLen
,
uint32_t
*
hashVal
)
{
uint32_t
hash
=
(
*
pHashObj
->
hashFp
)(
key
,
keyLen
);
int32_t
slot
=
HASH_INDEX
(
hash
,
pHashObj
->
capacity
);
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
slot
];
SHashNode
*
pNode
=
pEntry
->
next
;
while
(
pNode
)
{
if
((
pNode
->
keyLen
==
keyLen
)
&&
(
memcmp
(
pNode
->
key
,
key
,
keyLen
)
==
0
))
{
break
;
}
pNode
=
pNode
->
next
;
}
if
(
pNode
)
{
assert
(
HASH_INDEX
(
pNode
->
hashVal
,
pHashObj
->
capacity
)
==
slot
);
}
// return the calculated hash value, to avoid calculating it again in other functions
if
(
hashVal
!=
NULL
)
{
*
hashVal
=
hash
;
}
return
pNode
;
}
/**
* Resize the hash list if the threshold is reached
...
...
@@ -438,33 +463,6 @@ void doUpdateHashTable(SHashObj *pHashObj, SHashNode *pNode) {
}
}
SHashNode
*
doGetNodeFromHashTable
(
SHashObj
*
pHashObj
,
const
void
*
key
,
uint32_t
keyLen
,
uint32_t
*
hashVal
)
{
uint32_t
hash
=
(
*
pHashObj
->
hashFp
)(
key
,
keyLen
);
int32_t
slot
=
HASH_INDEX
(
hash
,
pHashObj
->
capacity
);
SHashEntry
*
pEntry
=
pHashObj
->
hashList
[
slot
];
SHashNode
*
pNode
=
pEntry
->
next
;
while
(
pNode
)
{
if
((
pNode
->
keyLen
==
keyLen
)
&&
(
memcmp
(
pNode
->
key
,
key
,
keyLen
)
==
0
))
{
break
;
}
pNode
=
pNode
->
next
;
}
if
(
pNode
)
{
assert
(
HASH_INDEX
(
pNode
->
hashVal
,
pHashObj
->
capacity
)
==
slot
);
}
// return the calculated hash value, to avoid calculating it again in other functions
if
(
hashVal
!=
NULL
)
{
*
hashVal
=
hash
;
}
return
pNode
;
}
void
taosHashTableResize
(
SHashObj
*
pHashObj
)
{
if
(
pHashObj
->
size
<
pHashObj
->
capacity
*
HASH_DEFAULT_LOAD_FACTOR
)
{
return
;
...
...
src/util/src/thashutil.c
浏览文件 @
26ff7966
...
...
@@ -10,7 +10,7 @@
#include "hashfunc.h"
#include "tutil.h"
#define ROTL32(x, r) ((x) << (r) | (x) >> (32 - (r)))
#define ROTL32(x, r) ((x) << (r) | (x) >> (32
u
- (r)))
#define FMIX32(h) \
do { \
...
...
@@ -20,12 +20,12 @@
(h) *= 0xc2b2ae35; \
(h) ^= (h) >> 16; \
} while (0)
static
void
MurmurHash3_32_s
(
const
void
*
key
,
int
len
,
uint32_t
seed
,
void
*
out
)
{
uint32_t
MurmurHash3_32
(
const
char
*
key
,
uint32_t
len
)
{
const
uint8_t
*
data
=
(
const
uint8_t
*
)
key
;
const
int
nblocks
=
len
/
4
;
const
int
nblocks
=
len
>>
2u
;
uint32_t
h1
=
seed
;
uint32_t
h1
=
0x12345678
;
const
uint32_t
c1
=
0xcc9e2d51
;
const
uint32_t
c2
=
0x1b873593
;
...
...
@@ -36,11 +36,11 @@ static void MurmurHash3_32_s(const void *key, int len, uint32_t seed, void *out)
uint32_t
k1
=
blocks
[
i
];
k1
*=
c1
;
k1
=
ROTL32
(
k1
,
15
);
k1
=
ROTL32
(
k1
,
15
u
);
k1
*=
c2
;
h1
^=
k1
;
h1
=
ROTL32
(
h1
,
13
);
h1
=
ROTL32
(
h1
,
13
u
);
h1
=
h1
*
5
+
0xe6546b64
;
}
...
...
@@ -48,7 +48,7 @@ static void MurmurHash3_32_s(const void *key, int len, uint32_t seed, void *out)
uint32_t
k1
=
0
;
switch
(
len
&
3
)
{
switch
(
len
&
3
u
)
{
case
3
:
k1
^=
tail
[
2
]
<<
16
;
case
2
:
...
...
@@ -56,7 +56,7 @@ static void MurmurHash3_32_s(const void *key, int len, uint32_t seed, void *out)
case
1
:
k1
^=
tail
[
0
];
k1
*=
c1
;
k1
=
ROTL32
(
k1
,
15
);
k1
=
ROTL32
(
k1
,
15
u
);
k1
*=
c2
;
h1
^=
k1
;
};
...
...
@@ -65,16 +65,7 @@ static void MurmurHash3_32_s(const void *key, int len, uint32_t seed, void *out)
FMIX32
(
h1
);
*
(
uint32_t
*
)
out
=
h1
;
}
uint32_t
MurmurHash3_32
(
const
char
*
key
,
uint32_t
len
)
{
const
int32_t
hashSeed
=
0x12345678
;
uint32_t
val
=
0
;
MurmurHash3_32_s
(
key
,
len
,
hashSeed
,
&
val
);
return
val
;
return
h1
;
}
uint32_t
taosIntHash_32
(
const
char
*
key
,
uint32_t
UNUSED_PARAM
(
len
))
{
return
*
(
uint32_t
*
)
key
;
}
...
...
tests/script/general/parser/limit1.sim
浏览文件 @
26ff7966
...
...
@@ -65,7 +65,7 @@ sleep 2000
system sh/exec.sh -n dnode1 -s start
print ================== server restart completed
run general/parser/limit1_tb.sim
#
run general/parser/limit1_tb.sim
run general/parser/limit1_stb.sim
system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
tests/script/general/parser/limit1_tb.sim
浏览文件 @
26ff7966
...
...
@@ -111,16 +111,16 @@ endi
if $data09 != nchar0 then
return -1
endi
if $data11 !=
NULL
then
if $data11 !=
null
then
return -1
endi
if $data12 !=
NULL
then
if $data12 !=
null
then
return -1
endi
if $data13 !=
NULL
then
if $data13 !=
null
then
return -1
endi
if $data14 !=
NULL
then
if $data14 !=
null
then
return -1
endi
...
...
@@ -543,7 +543,7 @@ endi
if $data14 != 8.000000000 then
return -1
endi
if $data21 !=
NULL
then
if $data21 !=
null
then
return -1
endi
...
...
@@ -613,7 +613,7 @@ endi
if $data21 != 7.000000000 then
return -1
endi
if $data31 !=
NULL
then
if $data31 !=
null
then
return -1
endi
sql select avg(c1), avg(c2), avg(c3), avg(c4), avg(c5), avg(c6) from $tb where ts >= $ts0 and ts <= $tsu interval(30m) limit 3 offset 1
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录