Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
慢慢CG
TDengine
提交
1a7786f3
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看板
提交
1a7786f3
编写于
9月 17, 2020
作者:
S
Shuduo Sang
浏览文件
操作
浏览文件
下载
差异文件
merged develop branch and fixed conflict.
上级
e7099d55
1487bc58
变更
52
展开全部
隐藏空白更改
内联
并排
Showing
52 changed file
with
1523 addition
and
920 deletion
+1523
-920
documentation20/webdocs/markdowndocs/Connections with other Tools-ch.md
...0/webdocs/markdowndocs/Connections with other Tools-ch.md
+1
-1
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
+3
-3
src/client/inc/tscUtil.h
src/client/inc/tscUtil.h
+1
-6
src/client/inc/tsclient.h
src/client/inc/tsclient.h
+12
-9
src/client/src/tscAsync.c
src/client/src/tscAsync.c
+10
-2
src/client/src/tscFunctionImpl.c
src/client/src/tscFunctionImpl.c
+127
-9
src/client/src/tscLocal.c
src/client/src/tscLocal.c
+1
-2
src/client/src/tscLocalMerge.c
src/client/src/tscLocalMerge.c
+0
-2
src/client/src/tscSQLParser.c
src/client/src/tscSQLParser.c
+128
-86
src/client/src/tscServer.c
src/client/src/tscServer.c
+67
-40
src/client/src/tscSql.c
src/client/src/tscSql.c
+74
-46
src/client/src/tscStream.c
src/client/src/tscStream.c
+2
-2
src/client/src/tscSubquery.c
src/client/src/tscSubquery.c
+26
-50
src/client/src/tscSystem.c
src/client/src/tscSystem.c
+11
-6
src/client/src/tscUtil.c
src/client/src/tscUtil.c
+89
-27
src/common/src/tglobal.c
src/common/src/tglobal.c
+0
-11
src/common/src/tname.c
src/common/src/tname.c
+2
-3
src/common/src/ttypes.c
src/common/src/ttypes.c
+3
-6
src/connector/jdbc/pom.xml
src/connector/jdbc/pom.xml
+0
-5
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java
...ctor/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java
+5
-7
src/inc/taosdef.h
src/inc/taosdef.h
+15
-12
src/kit/shell/src/shellEngine.c
src/kit/shell/src/shellEngine.c
+4
-2
src/plugins/http/src/httpContext.c
src/plugins/http/src/httpContext.c
+0
-2
src/plugins/http/src/httpRestJson.c
src/plugins/http/src/httpRestJson.c
+12
-16
src/plugins/http/src/httpServer.c
src/plugins/http/src/httpServer.c
+37
-34
src/plugins/http/src/httpSql.c
src/plugins/http/src/httpSql.c
+0
-12
src/query/inc/qAst.h
src/query/inc/qAst.h
+1
-0
src/query/inc/qExecutor.h
src/query/inc/qExecutor.h
+1
-1
src/query/inc/qPercentile.h
src/query/inc/qPercentile.h
+2
-2
src/query/inc/qUtil.h
src/query/inc/qUtil.h
+4
-2
src/query/inc/sql.y
src/query/inc/sql.y
+40
-40
src/query/inc/tsqlfunction.h
src/query/inc/tsqlfunction.h
+1
-1
src/query/src/qAst.c
src/query/src/qAst.c
+27
-9
src/query/src/qExecutor.c
src/query/src/qExecutor.c
+102
-63
src/query/src/qExtbuffer.c
src/query/src/qExtbuffer.c
+54
-39
src/query/src/qFilterfunc.c
src/query/src/qFilterfunc.c
+24
-0
src/query/src/qParserImpl.c
src/query/src/qParserImpl.c
+6
-1
src/query/src/qPercentile.c
src/query/src/qPercentile.c
+78
-13
src/query/src/qUtil.c
src/query/src/qUtil.c
+35
-12
src/query/src/sql.c
src/query/src/sql.c
+279
-269
src/tsdb/src/tsdbRead.c
src/tsdb/src/tsdbRead.c
+48
-23
src/util/src/tcache.c
src/util/src/tcache.c
+40
-15
src/util/src/tlog.c
src/util/src/tlog.c
+1
-1
src/util/src/tsocket.c
src/util/src/tsocket.c
+11
-2
src/util/tests/cacheTest.cpp
src/util/tests/cacheTest.cpp
+21
-21
tests/script/general/parser/groupby.sim
tests/script/general/parser/groupby.sim
+2
-0
tests/script/general/parser/join.sim
tests/script/general/parser/join.sim
+2
-0
tests/script/general/parser/lastrow_query.sim
tests/script/general/parser/lastrow_query.sim
+47
-0
tests/script/general/parser/testSuite.sim
tests/script/general/parser/testSuite.sim
+2
-0
tests/script/general/parser/timestamp_query.sim
tests/script/general/parser/timestamp_query.sim
+4
-0
tests/script/general/parser/topbot.sim
tests/script/general/parser/topbot.sim
+60
-5
tests/script/general/parser/where.sim
tests/script/general/parser/where.sim
+1
-0
未找到文件。
documentation20/webdocs/markdowndocs/Connections with other Tools-ch.md
浏览文件 @
1a7786f3
...
...
@@ -11,7 +11,7 @@ TDengine能够与开源数据可视化系统[Grafana](https://www.grafana.com/)
### 配置Grafana
TDengine的Grafana插件在安装包的/usr/local/taos/connector/grafana目录下。
TDengine的Grafana插件在安装包的/usr/local/taos/connector/grafana
plugin
目录下。
以CentOS 7.2操作系统为例,将tdengine目录拷贝到/var/lib/grafana/plugins目录下,重新启动grafana即可。
...
...
documentation20/webdocs/markdowndocs/Taos Error Code-ch.md
浏览文件 @
1a7786f3
# TDengine 2.0 错误码以及对应的十进制码
|
Code | bit | error code | 错误描述 | 十进制错误码
|
|
状态码 | 模 | 错误码(十六进制) | 错误描述 | 错误码(十进制)
|
|-----------------------| :---: | :---------: | :------------------------ | ---------------- |
|TSDB_CODE_RPC_ACTION_IN_PROGRESS| 0 | 0x0001| "Action in progress"| -2147483647|
|TSDB_CODE_RPC_AUTH_REQUIRED| 0 | 0x0002 | "Authentication required"| -2147483646|
...
...
@@ -87,7 +87,7 @@
|TSDB_CODE_MND_INVALID_ACCT_OPTION| 0 | 0x0342 | "Invalid account options"| -2147482814|
|TSDB_CODE_MND_USER_ALREADY_EXIST| 0 | 0x0350 | "User already exists"| -2147482800|
|TSDB_CODE_MND_INVALID_USER |0 | 0x0351 | "Invalid user" |-2147482799|
|TSDB_CODE_MND_INVALID_USER_FORMAT|
|
0 |0x0352 |"Invalid user format" |-2147482798|
|TSDB_CODE_MND_INVALID_USER_FORMAT|
0 |0x0352 |"Invalid user format" |-2147482798|
|TSDB_CODE_MND_INVALID_PASS_FORMAT| 0| 0x0353 | "Invalid password format"| -2147482797|
|TSDB_CODE_MND_NO_USER_FROM_CONN| 0 | 0x0354 | "Can not get user from conn"| -2147482796|
|TSDB_CODE_MND_TOO_MANY_USERS| 0 | 0x0355| "Too many users"| -2147482795|
...
...
@@ -107,7 +107,7 @@
|TSDB_CODE_MND_DB_NOT_SELECTED| 0 | 0x0380 | "Database not specified or available"| -2147482752|
|TSDB_CODE_MND_DB_ALREADY_EXIST| 0 | 0x0381 | "Database already exists"| -2147482751|
|TSDB_CODE_MND_INVALID_DB_OPTION| 0 | 0x0382 | "Invalid database options"| -2147482750|
|TSDB_CODE_MND_INVALID_DB|
|
0 | 0x0383 | "Invalid database name"| -2147482749|
|TSDB_CODE_MND_INVALID_DB| 0 | 0x0383 | "Invalid database name"| -2147482749|
|TSDB_CODE_MND_MONITOR_DB_FORBIDDEN| 0 | 0x0384 | "Cannot delete monitor database"| -2147482748|
|TSDB_CODE_MND_TOO_MANY_DATABASES| 0| 0x0385 | "Too many databases for account"| -2147482747|
|TSDB_CODE_MND_DB_IN_DROPPING| 0 | 0x0386| "Database not available" |-2147482746|
...
...
src/client/inc/tscUtil.h
浏览文件 @
1a7786f3
...
...
@@ -69,17 +69,12 @@ typedef struct SJoinSupporter {
SSubqueryState
*
pState
;
SSqlObj
*
pObj
;
// parent SqlObj
int32_t
subqueryIndex
;
// index of sub query
char
intervalTimeUnit
;
char
slidingTimeUnit
;
int64_t
intervalTime
;
// interval time
int64_t
slidingTime
;
// sliding time
SLimitVal
limit
;
// limit info
uint64_t
uid
;
// query
meter
uid
uint64_t
uid
;
// query
table
uid
SArray
*
colList
;
// previous query information, no need to use this attribute, and the corresponding attribution
SArray
*
exprList
;
SFieldInfo
fieldsInfo
;
STagCond
tagCond
;
SSqlGroupbyExpr
groupbyExpr
;
struct
STSBuf
*
pTSBuf
;
// the TSBuf struct that holds the compressed timestamp array
FILE
*
f
;
// temporary file in order to create TSBuf
char
path
[
PATH_MAX
];
// temporary file path, todo dynamic allocate memory
...
...
src/client/inc/tsclient.h
浏览文件 @
1a7786f3
...
...
@@ -29,6 +29,7 @@ extern "C" {
#include "tglobal.h"
#include "tsqlfunction.h"
#include "tutil.h"
#include "tcache.h"
#include "qExecutor.h"
#include "qSqlparser.h"
...
...
@@ -333,6 +334,7 @@ typedef struct STscObj {
struct
SSqlStream
*
streamList
;
void
*
pDnodeConn
;
pthread_mutex_t
mutex
;
T_REF_DECLARE
();
}
STscObj
;
typedef
struct
SSqlObj
{
...
...
@@ -359,6 +361,8 @@ typedef struct SSqlObj {
uint16_t
numOfSubs
;
struct
SSqlObj
**
pSubs
;
struct
SSqlObj
*
prev
,
*
next
;
struct
SSqlObj
**
self
;
}
SSqlObj
;
typedef
struct
SSqlStream
{
...
...
@@ -413,7 +417,6 @@ int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo *pQueryInfo);
void
tscRestoreSQLFuncForSTableQuery
(
SQueryInfo
*
pQueryInfo
);
int32_t
tscCreateResPointerInfo
(
SSqlRes
*
pRes
,
SQueryInfo
*
pQueryInfo
);
void
tscDestroyResPointerInfo
(
SSqlRes
*
pRes
);
void
tscResetSqlCmdObj
(
SSqlCmd
*
pCmd
,
bool
removeFromCache
);
...
...
@@ -425,17 +428,19 @@ void tscFreeSqlResult(SSqlObj *pSql);
/**
* only free part of resources allocated during query.
* TODO remove it later
* Note: this function is multi-thread safe.
* @param pObj
*/
void
tscPartiallyFreeSqlObj
(
SSqlObj
*
p
Obj
);
void
tscPartiallyFreeSqlObj
(
SSqlObj
*
p
Sql
);
/**
* free sql object, release allocated resource
* @param pObj Free metric/meta information, dynamically allocated payload, and
* response buffer, object itself
* @param pObj
*/
void
tscFreeSqlObj
(
SSqlObj
*
pObj
);
void
tscFreeSqlObj
(
SSqlObj
*
pSql
);
void
tscFreeSqlObjInCache
(
void
*
pSql
);
void
tscCloseTscObj
(
STscObj
*
pObj
);
...
...
@@ -451,9 +456,6 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen)
bool
tscIsUpdateQuery
(
SSqlObj
*
pSql
);
bool
tscHasReachLimitation
(
SQueryInfo
*
pQueryInfo
,
SSqlRes
*
pRes
);
// todo remove this function.
bool
tscResultsetFetchCompleted
(
TAOS_RES
*
result
);
char
*
tscGetErrorMsgPayload
(
SSqlCmd
*
pCmd
);
int32_t
tscInvalidSQLErrMsg
(
char
*
msg
,
const
char
*
additionalInfo
,
const
char
*
sql
);
...
...
@@ -502,7 +504,8 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField
}
}
extern
void
*
tscCacheHandle
;
extern
SCacheObj
*
tscMetaCache
;
extern
SCacheObj
*
tscObjCache
;
extern
void
*
tscTmr
;
extern
void
*
tscQhandle
;
extern
int
tscKeepConn
[];
...
...
src/client/src/tscAsync.c
浏览文件 @
1a7786f3
...
...
@@ -18,6 +18,7 @@
#include "tnote.h"
#include "trpc.h"
#include "tcache.h"
#include "tscLog.h"
#include "tscSubquery.h"
#include "tscLocalMerge.h"
...
...
@@ -40,6 +41,8 @@ static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows);
static
void
tscAsyncFetchSingleRowProxy
(
void
*
param
,
TAOS_RES
*
tres
,
int
numOfRows
);
void
doAsyncQuery
(
STscObj
*
pObj
,
SSqlObj
*
pSql
,
void
(
*
fp
)(),
void
*
param
,
const
char
*
sqlstr
,
size_t
sqlLen
)
{
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
pSql
->
signature
=
pSql
;
pSql
->
param
=
param
;
pSql
->
pTscObj
=
pObj
;
...
...
@@ -48,6 +51,11 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const
pSql
->
fp
=
fp
;
pSql
->
fetchFp
=
fp
;
uint64_t
handle
=
(
uint64_t
)
pSql
;
pSql
->
self
=
taosCachePut
(
tscObjCache
,
&
handle
,
sizeof
(
uint64_t
),
&
pSql
,
sizeof
(
uint64_t
),
2
*
3600
*
1000
);
T_REF_INC
(
pSql
->
pTscObj
);
pSql
->
sqlstr
=
calloc
(
1
,
sqlLen
+
1
);
if
(
pSql
->
sqlstr
==
NULL
)
{
tscError
(
"%p failed to malloc sql string buffer"
,
pSql
);
...
...
@@ -59,7 +67,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const
strntolower
(
pSql
->
sqlstr
,
sqlstr
,
(
int32_t
)
sqlLen
);
tscDebugL
(
"%p SQL: %s"
,
pSql
,
pSql
->
sqlstr
);
p
Sql
->
cmd
.
curSql
=
pSql
->
sqlstr
;
p
Cmd
->
curSql
=
pSql
->
sqlstr
;
int32_t
code
=
tsParseSql
(
pSql
,
true
);
if
(
code
==
TSDB_CODE_TSC_ACTION_IN_PROGRESS
)
return
;
...
...
@@ -69,7 +77,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const
tscQueueAsyncRes
(
pSql
);
return
;
}
tscDoQuery
(
pSql
);
}
...
...
src/client/src/tscFunctionImpl.c
浏览文件 @
1a7786f3
...
...
@@ -117,6 +117,10 @@ typedef struct SFirstLastInfo {
typedef
struct
SFirstLastInfo
SLastrowInfo
;
typedef
struct
SPercentileInfo
{
tMemBucket
*
pMemBucket
;
int32_t
stage
;
double
minval
;
double
maxval
;
int64_t
numOfElems
;
}
SPercentileInfo
;
typedef
struct
STopBotInfo
{
...
...
@@ -302,7 +306,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI
}
else
if
(
functionId
==
TSDB_FUNC_PERCT
)
{
*
type
=
(
int16_t
)
TSDB_DATA_TYPE_DOUBLE
;
*
bytes
=
(
int16_t
)
sizeof
(
double
);
*
interBytes
=
(
int16_t
)
sizeof
(
double
);
*
interBytes
=
(
int16_t
)
sizeof
(
SPercentileInfo
);
}
else
if
(
functionId
==
TSDB_FUNC_LEASTSQR
)
{
*
type
=
TSDB_DATA_TYPE_BINARY
;
*
bytes
=
TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE
;
// string
...
...
@@ -2428,12 +2432,14 @@ static bool percentile_function_setup(SQLFunctionCtx *pCtx) {
if
(
!
function_setup
(
pCtx
))
{
return
false
;
}
// in the first round, get the min-max value of all involved data
SResultInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SPercentileInfo
*
pInfo
=
pResInfo
->
interResultBuf
;
pInfo
->
minval
=
DBL_MAX
;
pInfo
->
maxval
=
-
DBL_MAX
;
pInfo
->
numOfElems
=
0
;
((
SPercentileInfo
*
)(
pResInfo
->
interResultBuf
))
->
pMemBucket
=
tMemBucketCreate
(
pCtx
->
inputBytes
,
pCtx
->
inputType
);
return
true
;
}
...
...
@@ -2442,7 +2448,65 @@ static void percentile_function(SQLFunctionCtx *pCtx) {
SResultInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SPercentileInfo
*
pInfo
=
pResInfo
->
interResultBuf
;
// the first stage, only acquire the min/max value
if
(
pInfo
->
stage
==
0
)
{
if
(
pCtx
->
preAggVals
.
isSet
)
{
if
(
pInfo
->
minval
>
pCtx
->
preAggVals
.
statis
.
min
)
{
pInfo
->
minval
=
pCtx
->
preAggVals
.
statis
.
min
;
}
if
(
pInfo
->
maxval
<
pCtx
->
preAggVals
.
statis
.
max
)
{
pInfo
->
maxval
=
pCtx
->
preAggVals
.
statis
.
max
;
}
pInfo
->
numOfElems
+=
(
pCtx
->
size
-
pCtx
->
preAggVals
.
statis
.
numOfNull
);
}
else
{
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
data
=
GET_INPUT_CHAR_INDEX
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
continue
;
}
// TODO extract functions
double
v
=
0
;
switch
(
pCtx
->
inputType
)
{
case
TSDB_DATA_TYPE_TINYINT
:
v
=
GET_INT8_VAL
(
data
);
break
;
case
TSDB_DATA_TYPE_SMALLINT
:
v
=
GET_INT16_VAL
(
data
);
break
;
case
TSDB_DATA_TYPE_BIGINT
:
v
=
(
double
)(
GET_INT64_VAL
(
data
));
break
;
case
TSDB_DATA_TYPE_FLOAT
:
v
=
GET_FLOAT_VAL
(
data
);
break
;
case
TSDB_DATA_TYPE_DOUBLE
:
v
=
GET_DOUBLE_VAL
(
data
);
break
;
default:
v
=
GET_INT32_VAL
(
data
);
break
;
}
if
(
v
<
pInfo
->
minval
)
{
pInfo
->
minval
=
v
;
}
if
(
v
>
pInfo
->
maxval
)
{
pInfo
->
maxval
=
v
;
}
pInfo
->
numOfElems
+=
1
;
}
}
return
;
}
// the second stage, calculate the true percentile value
for
(
int32_t
i
=
0
;
i
<
pCtx
->
size
;
++
i
)
{
char
*
data
=
GET_INPUT_CHAR_INDEX
(
pCtx
,
i
);
if
(
pCtx
->
hasNull
&&
isNull
(
data
,
pCtx
->
inputType
))
{
...
...
@@ -2462,10 +2526,47 @@ static void percentile_function_f(SQLFunctionCtx *pCtx, int32_t index) {
if
(
pCtx
->
hasNull
&&
isNull
(
pData
,
pCtx
->
inputType
))
{
return
;
}
SResultInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SPercentileInfo
*
pInfo
=
(
SPercentileInfo
*
)
pResInfo
->
interResultBuf
;
if
(
pInfo
->
stage
==
0
)
{
// TODO extract functions
double
v
=
0
;
switch
(
pCtx
->
inputType
)
{
case
TSDB_DATA_TYPE_TINYINT
:
v
=
GET_INT8_VAL
(
pData
);
break
;
case
TSDB_DATA_TYPE_SMALLINT
:
v
=
GET_INT16_VAL
(
pData
);
break
;
case
TSDB_DATA_TYPE_BIGINT
:
v
=
(
double
)(
GET_INT64_VAL
(
pData
));
break
;
case
TSDB_DATA_TYPE_FLOAT
:
v
=
GET_FLOAT_VAL
(
pData
);
break
;
case
TSDB_DATA_TYPE_DOUBLE
:
v
=
GET_DOUBLE_VAL
(
pData
);
break
;
default:
v
=
GET_INT32_VAL
(
pData
);
break
;
}
if
(
v
<
pInfo
->
minval
)
{
pInfo
->
minval
=
v
;
}
if
(
v
>
pInfo
->
maxval
)
{
pInfo
->
maxval
=
v
;
}
pInfo
->
numOfElems
+=
1
;
return
;
}
tMemBucketPut
(
pInfo
->
pMemBucket
,
pData
,
1
);
SET_VAL
(
pCtx
,
1
,
1
);
...
...
@@ -2488,6 +2589,23 @@ static void percentile_finalizer(SQLFunctionCtx *pCtx) {
doFinalizer
(
pCtx
);
}
static
void
percentile_next_step
(
SQLFunctionCtx
*
pCtx
)
{
SResultInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
SPercentileInfo
*
pInfo
=
pResInfo
->
interResultBuf
;
if
(
pInfo
->
stage
==
0
)
{
// all data are null, set it completed
if
(
pInfo
->
numOfElems
==
0
)
{
pResInfo
->
complete
=
true
;
}
pInfo
->
stage
+=
1
;
pInfo
->
pMemBucket
=
tMemBucketCreate
(
pCtx
->
inputBytes
,
pCtx
->
inputType
,
pInfo
->
minval
,
pInfo
->
maxval
);
}
else
{
pResInfo
->
complete
=
true
;
}
}
//////////////////////////////////////////////////////////////////////////////////
static
SAPercentileInfo
*
getAPerctInfo
(
SQLFunctionCtx
*
pCtx
)
{
SResultInfo
*
pResInfo
=
GET_RES_INFO
(
pCtx
);
...
...
@@ -4513,7 +4631,7 @@ SQLAggFuncElem aAggs[] = {{
percentile_function_setup
,
percentile_function
,
percentile_function_f
,
no
_next_step
,
percentile
_next_step
,
percentile_finalizer
,
noop1
,
noop1
,
...
...
src/client/src/tscLocal.c
浏览文件 @
1a7786f3
...
...
@@ -16,7 +16,6 @@
#include "os.h"
#include "taosmsg.h"
#include "qExtbuffer.h"
#include "taosdef.h"
#include "tcache.h"
#include "tname.h"
...
...
@@ -430,7 +429,7 @@ int tscProcessLocalCmd(SSqlObj *pSql) {
pRes
->
qhandle
=
0x1
;
pRes
->
numOfRows
=
0
;
}
else
if
(
pCmd
->
command
==
TSDB_SQL_RESET_CACHE
)
{
taosCacheEmpty
(
tsc
CacheHandl
e
);
taosCacheEmpty
(
tsc
MetaCach
e
);
pRes
->
code
=
TSDB_CODE_SUCCESS
;
}
else
if
(
pCmd
->
command
==
TSDB_SQL_SERV_VERSION
)
{
pRes
->
code
=
tscProcessServerVer
(
pSql
);
...
...
src/client/src/tscLocalMerge.c
浏览文件 @
1a7786f3
...
...
@@ -472,10 +472,8 @@ void tscDestroyLocalReducer(SSqlObj *pSql) {
return
;
}
tscDebug
(
"%p start to free local reducer"
,
pSql
);
SSqlRes
*
pRes
=
&
(
pSql
->
res
);
if
(
pRes
->
pLocalReducer
==
NULL
)
{
tscDebug
(
"%p local reducer has been freed, abort"
,
pSql
);
return
;
}
...
...
src/client/src/tscSQLParser.c
浏览文件 @
1a7786f3
此差异已折叠。
点击以展开。
src/client/src/tscServer.c
浏览文件 @
1a7786f3
...
...
@@ -27,10 +27,7 @@
#include "tutil.h"
#include "tlockfree.h"
#define TSC_MGMT_VNODE 999
SRpcCorEpSet
tscMgmtEpSet
;
SRpcEpSet
tscDnodeEpSet
;
int
(
*
tscBuildMsg
[
TSDB_SQL_MAX
])(
SSqlObj
*
pSql
,
SSqlInfo
*
pInfo
)
=
{
0
};
...
...
@@ -236,20 +233,27 @@ int tscSendMsgToServer(SSqlObj *pSql) {
}
void
tscProcessMsgFromServer
(
SRpcMsg
*
rpcMsg
,
SRpcEpSet
*
pEpSet
)
{
SSqlObj
*
pSql
=
(
SSqlObj
*
)
rpcMsg
->
ahandle
;
if
(
pSql
==
NULL
||
pSql
->
signature
!=
pSql
)
{
tscError
(
"%p sql is already released"
,
pSql
);
uint64_t
handle
=
(
uint64_t
)
rpcMsg
->
ahandle
;
void
**
p
=
taosCacheAcquireByKey
(
tscObjCache
,
&
handle
,
sizeof
(
uint64_t
));
if
(
p
==
NULL
)
{
rpcFreeCont
(
rpcMsg
->
pCont
);
return
;
}
SSqlObj
*
pSql
=
*
p
;
assert
(
pSql
!=
NULL
);
STscObj
*
pObj
=
pSql
->
pTscObj
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
assert
(
*
pSql
->
self
==
pSql
);
if
(
pObj
->
signature
!=
pObj
)
{
tscDebug
(
"%p DB connection is closed, cmd:%d pObj:%p signature:%p"
,
pSql
,
pCmd
->
command
,
pObj
,
pObj
->
signature
);
t
scFreeSqlObj
(
pSql
);
t
aosCacheRelease
(
tscObjCache
,
(
void
**
)
&
p
,
true
);
rpcFreeCont
(
rpcMsg
->
pCont
);
return
;
}
...
...
@@ -261,18 +265,21 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
tscDebug
(
"%p sqlObj needs to be released or DB connection is closed, cmd:%d type:%d, pObj:%p signature:%p"
,
pSql
,
pCmd
->
command
,
pQueryInfo
->
type
,
pObj
,
pObj
->
signature
);
tscFreeSqlObj
(
pSql
);
void
**
p1
=
p
;
taosCacheRelease
(
tscObjCache
,
(
void
**
)
&
p1
,
false
);
taosCacheRelease
(
tscObjCache
,
(
void
**
)
&
p
,
true
);
rpcFreeCont
(
rpcMsg
->
pCont
);
return
;
}
if
(
pEpSet
)
{
if
(
pEpSet
)
{
if
(
!
tscEpSetIsEqual
(
&
pSql
->
epSet
,
pEpSet
))
{
if
(
pCmd
->
command
<
TSDB_SQL_MGMT
)
{
tscUpdateVgroupInfo
(
pSql
,
pEpSet
);
if
(
pCmd
->
command
<
TSDB_SQL_MGMT
)
{
tscUpdateVgroupInfo
(
pSql
,
pEpSet
);
}
else
{
tscUpdateMgmtEpSet
(
pEpSet
);
}
}
}
}
...
...
@@ -294,7 +301,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
if
(
pSql
->
retry
>
pSql
->
maxRetry
)
{
tscError
(
"%p max retry %d reached, give up"
,
pSql
,
pSql
->
maxRetry
);
}
else
{
// wait for a little bit moment and then retry
// wait for a little bit moment and then retry
, todo do not sleep in rpc callback thread
if
(
rpcMsg
->
code
==
TSDB_CODE_APP_NOT_READY
||
rpcMsg
->
code
==
TSDB_CODE_VND_INVALID_VGROUP_ID
)
{
int32_t
duration
=
getWaitingTimeInterval
(
pSql
->
retry
);
taosMsleep
(
duration
);
...
...
@@ -304,6 +311,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
// if there is an error occurring, proceed to the following error handling procedure.
if
(
rpcMsg
->
code
==
TSDB_CODE_TSC_ACTION_IN_PROGRESS
)
{
taosCacheRelease
(
tscObjCache
,
(
void
**
)
&
p
,
false
);
rpcFreeCont
(
rpcMsg
->
pCont
);
return
;
}
...
...
@@ -365,16 +373,18 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) {
rpcMsg
->
code
=
(
*
tscProcessMsgRsp
[
pCmd
->
command
])(
pSql
);
}
bool
shouldFree
=
tscShouldBeFreed
(
pSql
);
if
(
rpcMsg
->
code
!=
TSDB_CODE_TSC_ACTION_IN_PROGRESS
)
{
rpcMsg
->
code
=
(
pRes
->
code
==
TSDB_CODE_SUCCESS
)
?
(
int32_t
)
pRes
->
numOfRows
:
pRes
->
code
;
bool
shouldFree
=
tscShouldBeFreed
(
pSql
);
(
*
pSql
->
fp
)(
pSql
->
param
,
pSql
,
rpcMsg
->
code
);
}
if
(
shouldFree
)
{
tscDebug
(
"%p sqlObj is automatically freed"
,
pSql
);
tscFreeSqlObj
(
pSql
);
}
void
**
p1
=
p
;
taosCacheRelease
(
tscObjCache
,
(
void
**
)
&
p1
,
false
);
if
(
shouldFree
)
{
// in case of table-meta/vgrouplist query, automatically free it
taosCacheRelease
(
tscObjCache
,
(
void
**
)
&
p
,
true
);
tscDebug
(
"%p sqlObj is automatically freed"
,
pSql
);
}
rpcFreeCont
(
rpcMsg
->
pCont
);
...
...
@@ -1667,8 +1677,10 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
pMetaMsg
->
contLen
=
htons
(
pMetaMsg
->
contLen
);
pMetaMsg
->
numOfColumns
=
htons
(
pMetaMsg
->
numOfColumns
);
if
(
pMetaMsg
->
sid
<
0
||
pMetaMsg
->
vgroup
.
numOfEps
<
0
)
{
tscError
(
"invalid meter vgId:%d, sid%d"
,
pMetaMsg
->
vgroup
.
numOfEps
,
pMetaMsg
->
sid
);
if
((
pMetaMsg
->
tableType
!=
TSDB_SUPER_TABLE
)
&&
(
pMetaMsg
->
sid
<=
0
||
pMetaMsg
->
vgroup
.
vgId
<
2
||
pMetaMsg
->
vgroup
.
numOfEps
<=
0
))
{
tscError
(
"invalid value in table numOfEps:%d, vgId:%d tid:%d, name:%s"
,
pMetaMsg
->
vgroup
.
numOfEps
,
pMetaMsg
->
vgroup
.
vgId
,
pMetaMsg
->
sid
,
pMetaMsg
->
tableId
);
return
TSDB_CODE_TSC_INVALID_VALUE
;
}
...
...
@@ -1708,7 +1720,7 @@ int tscProcessTableMetaRsp(SSqlObj *pSql) {
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
&
pSql
->
cmd
,
0
,
0
);
assert
(
pTableMetaInfo
->
pTableMeta
==
NULL
);
pTableMetaInfo
->
pTableMeta
=
(
STableMeta
*
)
taosCachePut
(
tsc
CacheHandl
e
,
pTableMetaInfo
->
name
,
pTableMetaInfo
->
pTableMeta
=
(
STableMeta
*
)
taosCachePut
(
tsc
MetaCach
e
,
pTableMetaInfo
->
name
,
strlen
(
pTableMetaInfo
->
name
),
pTableMeta
,
size
,
tsTableMetaKeepTimer
*
1000
);
// todo handle out of memory case
...
...
@@ -1820,7 +1832,7 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) {
// int32_t size = (int32_t)(rsp - ((char *)pMeta)); // Consistent with STableMeta in cache
//
// pMeta->index = 0;
// (void)taosCachePut(tsc
CacheHandl
e, pMeta->tableId, (char *)pMeta, size, tsTableMetaKeepTimer);
// (void)taosCachePut(tsc
MetaCach
e, pMeta->tableId, (char *)pMeta, size, tsTableMetaKeepTimer);
// }
}
...
...
@@ -1907,12 +1919,14 @@ int tscProcessShowRsp(SSqlObj *pSql) {
key
[
0
]
=
pCmd
->
msgType
+
'a'
;
strcpy
(
key
+
1
,
"showlist"
);
taosCacheRelease
(
tscCacheHandle
,
(
void
*
)
&
(
pTableMetaInfo
->
pTableMeta
),
false
);
if
(
pTableMetaInfo
->
pTableMeta
!=
NULL
)
{
taosCacheRelease
(
tscMetaCache
,
(
void
*
)
&
(
pTableMetaInfo
->
pTableMeta
),
false
);
}
size_t
size
=
0
;
STableMeta
*
pTableMeta
=
tscCreateTableMetaFromMsg
(
pMetaMsg
,
&
size
);
pTableMetaInfo
->
pTableMeta
=
taosCachePut
(
tsc
CacheHandl
e
,
key
,
strlen
(
key
),
(
char
*
)
pTableMeta
,
size
,
pTableMetaInfo
->
pTableMeta
=
taosCachePut
(
tsc
MetaCach
e
,
key
,
strlen
(
key
),
(
char
*
)
pTableMeta
,
size
,
tsTableMetaKeepTimer
*
1000
);
SSchema
*
pTableSchema
=
tscGetTableSchema
(
pTableMetaInfo
->
pTableMeta
);
...
...
@@ -1971,6 +1985,8 @@ static void createHBObj(STscObj* pObj) {
pSql
->
pTscObj
=
pObj
;
pSql
->
signature
=
pSql
;
pObj
->
pHb
=
pSql
;
T_REF_INC
(
pObj
);
tscAddSubqueryInfo
(
&
pObj
->
pHb
->
cmd
);
tscDebug
(
"%p HB is allocated, pObj:%p"
,
pObj
->
pHb
,
pObj
);
...
...
@@ -2000,7 +2016,7 @@ int tscProcessConnectRsp(SSqlObj *pSql) {
createHBObj
(
pObj
);
taosTmrReset
(
tscProcessActivityTimer
,
tsShellActivityTimer
*
500
,
pObj
,
tscTmr
,
&
pObj
->
pTimer
);
//
taosTmrReset(tscProcessActivityTimer, tsShellActivityTimer * 500, pObj, tscTmr, &pObj->pTimer);
return
0
;
}
...
...
@@ -2015,14 +2031,14 @@ int tscProcessUseDbRsp(SSqlObj *pSql) {
int
tscProcessDropDbRsp
(
SSqlObj
*
pSql
)
{
pSql
->
pTscObj
->
db
[
0
]
=
0
;
taosCacheEmpty
(
tsc
CacheHandl
e
);
taosCacheEmpty
(
tsc
MetaCach
e
);
return
0
;
}
int
tscProcessDropTableRsp
(
SSqlObj
*
pSql
)
{
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
&
pSql
->
cmd
,
0
,
0
);
STableMeta
*
pTableMeta
=
taosCacheAcquireByKey
(
tsc
CacheHandl
e
,
pTableMetaInfo
->
name
,
strlen
(
pTableMetaInfo
->
name
));
STableMeta
*
pTableMeta
=
taosCacheAcquireByKey
(
tsc
MetaCach
e
,
pTableMetaInfo
->
name
,
strlen
(
pTableMetaInfo
->
name
));
if
(
pTableMeta
==
NULL
)
{
/* not in cache, abort */
return
0
;
}
...
...
@@ -2035,10 +2051,10 @@ int tscProcessDropTableRsp(SSqlObj *pSql) {
* instead.
*/
tscDebug
(
"%p force release table meta after drop table:%s"
,
pSql
,
pTableMetaInfo
->
name
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
pTableMeta
,
true
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
pTableMeta
,
true
);
if
(
pTableMetaInfo
->
pTableMeta
)
{
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
true
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
true
);
}
return
0
;
...
...
@@ -2047,21 +2063,21 @@ int tscProcessDropTableRsp(SSqlObj *pSql) {
int
tscProcessAlterTableMsgRsp
(
SSqlObj
*
pSql
)
{
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
&
pSql
->
cmd
,
0
,
0
);
STableMeta
*
pTableMeta
=
taosCacheAcquireByKey
(
tsc
CacheHandl
e
,
pTableMetaInfo
->
name
,
strlen
(
pTableMetaInfo
->
name
));
STableMeta
*
pTableMeta
=
taosCacheAcquireByKey
(
tsc
MetaCach
e
,
pTableMetaInfo
->
name
,
strlen
(
pTableMetaInfo
->
name
));
if
(
pTableMeta
==
NULL
)
{
/* not in cache, abort */
return
0
;
}
tscDebug
(
"%p force release metermeta in cache after alter-table: %s"
,
pSql
,
pTableMetaInfo
->
name
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
pTableMeta
,
true
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
pTableMeta
,
true
);
if
(
pTableMetaInfo
->
pTableMeta
)
{
bool
isSuperTable
=
UTIL_TABLE_IS_SUPER_TABLE
(
pTableMetaInfo
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
true
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
true
);
if
(
isSuperTable
)
{
// if it is a super table, reset whole query cache
tscDebug
(
"%p reset query cache since table:%s is stable"
,
pSql
,
pTableMetaInfo
->
name
);
taosCacheEmpty
(
tsc
CacheHandl
e
);
taosCacheEmpty
(
tsc
MetaCach
e
);
}
}
...
...
@@ -2146,6 +2162,12 @@ static int32_t getTableMetaFromMgmt(SSqlObj *pSql, STableMetaInfo *pTableMetaInf
pNew
->
signature
=
pNew
;
pNew
->
cmd
.
command
=
TSDB_SQL_META
;
T_REF_INC
(
pNew
->
pTscObj
);
// TODO add test case on x86 platform
uint64_t
adr
=
(
uint64_t
)
pNew
;
pNew
->
self
=
taosCachePut
(
tscObjCache
,
&
adr
,
sizeof
(
uint64_t
),
&
pNew
,
sizeof
(
uint64_t
),
2
*
60
*
1000
);
tscAddSubqueryInfo
(
&
pNew
->
cmd
);
SQueryInfo
*
pNewQueryInfo
=
tscGetQueryInfoDetailSafely
(
&
pNew
->
cmd
,
0
);
...
...
@@ -2182,10 +2204,10 @@ int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) {
// If this STableMetaInfo owns a table meta, release it first
if
(
pTableMetaInfo
->
pTableMeta
!=
NULL
)
{
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
false
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
false
);
}
pTableMetaInfo
->
pTableMeta
=
(
STableMeta
*
)
taosCacheAcquireByKey
(
tsc
CacheHandl
e
,
pTableMetaInfo
->
name
,
strlen
(
pTableMetaInfo
->
name
));
pTableMetaInfo
->
pTableMeta
=
(
STableMeta
*
)
taosCacheAcquireByKey
(
tsc
MetaCach
e
,
pTableMetaInfo
->
name
,
strlen
(
pTableMetaInfo
->
name
));
if
(
pTableMetaInfo
->
pTableMeta
!=
NULL
)
{
STableComInfo
tinfo
=
tscGetTableInfo
(
pTableMetaInfo
->
pTableMeta
);
tscDebug
(
"%p retrieve table Meta from cache, the number of columns:%d, numOfTags:%d, %p"
,
pSql
,
tinfo
.
numOfColumns
,
...
...
@@ -2220,7 +2242,7 @@ int tscRenewTableMeta(SSqlObj *pSql, int32_t tableIndex) {
tscGetNumOfTags
(
pTableMeta
),
tscGetNumOfColumns
(
pTableMeta
),
pTableMeta
->
id
.
uid
,
pTableMeta
);
}
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
true
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
true
);
return
getTableMetaFromMgmt
(
pSql
,
pTableMetaInfo
);
}
...
...
@@ -2250,7 +2272,8 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
pNew
->
signature
=
pNew
;
pNew
->
cmd
.
command
=
TSDB_SQL_STABLEVGROUP
;
// TODO TEST IT
SQueryInfo
*
pNewQueryInfo
=
tscGetQueryInfoDetailSafely
(
&
pNew
->
cmd
,
0
);
if
(
pNewQueryInfo
==
NULL
)
{
tscFreeSqlObj
(
pNew
);
...
...
@@ -2260,7 +2283,7 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
clauseIndex
);
for
(
int32_t
i
=
0
;
i
<
pQueryInfo
->
numOfTables
;
++
i
)
{
STableMetaInfo
*
pMInfo
=
tscGetMetaInfo
(
pQueryInfo
,
i
);
STableMeta
*
pTableMeta
=
taosCacheAcquireByData
(
tsc
CacheHandl
e
,
pMInfo
->
pTableMeta
);
STableMeta
*
pTableMeta
=
taosCacheAcquireByData
(
tsc
MetaCach
e
,
pMInfo
->
pTableMeta
);
tscAddTableMetaInfo
(
pNewQueryInfo
,
pMInfo
->
name
,
pTableMeta
,
NULL
,
pMInfo
->
tagColList
);
}
...
...
@@ -2270,6 +2293,10 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) {
}
pNewQueryInfo
->
numOfTables
=
pQueryInfo
->
numOfTables
;
T_REF_INC
(
pNew
->
pTscObj
);
uint64_t
p
=
(
uint64_t
)
pNew
;
pNew
->
self
=
taosCachePut
(
tscObjCache
,
&
p
,
sizeof
(
uint64_t
),
&
pNew
,
sizeof
(
uint64_t
),
2
*
600
*
1000
);
tscDebug
(
"%p new sqlObj:%p to get vgroupInfo, numOfTables:%d"
,
pSql
,
pNew
,
pNewQueryInfo
->
numOfTables
);
pNew
->
fp
=
tscTableMetaCallBack
;
...
...
src/client/src/tscSql.c
浏览文件 @
1a7786f3
...
...
@@ -26,6 +26,7 @@
#include "tsclient.h"
#include "ttokendef.h"
#include "tutil.h"
#include "tscProfile.h"
static
bool
validImpl
(
const
char
*
str
,
size_t
maxsize
)
{
if
(
str
==
NULL
)
{
...
...
@@ -100,6 +101,8 @@ SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pass, con
}
pObj
->
signature
=
pObj
;
pObj
->
pDnodeConn
=
pDnodeConn
;
T_REF_INIT_VAL
(
pObj
,
1
);
tstrncpy
(
pObj
->
user
,
user
,
sizeof
(
pObj
->
user
));
secretEncryptLen
=
MIN
(
secretEncryptLen
,
sizeof
(
pObj
->
pass
));
...
...
@@ -132,20 +135,15 @@ SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pass, con
return
NULL
;
}
pSql
->
pTscObj
=
pObj
;
pSql
->
pTscObj
=
pObj
;
pSql
->
signature
=
pSql
;
pSql
->
maxRetry
=
TSDB_MAX_REPLICA
;
pSql
->
maxRetry
=
TSDB_MAX_REPLICA
;
pSql
->
fp
=
fp
;
pSql
->
param
=
param
;
pSql
->
cmd
.
command
=
TSDB_SQL_CONNECT
;
tsem_init
(
&
pSql
->
rspSem
,
0
,
0
);
pObj
->
pDnodeConn
=
pDnodeConn
;
pSql
->
fp
=
fp
;
pSql
->
param
=
param
;
if
(
taos
!=
NULL
)
{
*
taos
=
pObj
;
}
pSql
->
cmd
.
command
=
TSDB_SQL_CONNECT
;
if
(
TSDB_CODE_SUCCESS
!=
tscAllocPayload
(
&
pSql
->
cmd
,
TSDB_DEFAULT_PAYLOAD_SIZE
))
{
terrno
=
TSDB_CODE_TSC_OUT_OF_MEMORY
;
rpcClose
(
pDnodeConn
);
...
...
@@ -154,7 +152,16 @@ SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pass, con
return
NULL
;
}
if
(
taos
!=
NULL
)
{
*
taos
=
pObj
;
}
T_REF_INC
(
pSql
->
pTscObj
);
uint64_t
key
=
(
uint64_t
)
pSql
;
pSql
->
self
=
taosCachePut
(
tscObjCache
,
&
key
,
sizeof
(
uint64_t
),
&
pSql
,
sizeof
(
uint64_t
),
2
*
3600
*
1000
);
tsInsertHeadSize
=
sizeof
(
SMsgDesc
)
+
sizeof
(
SSubmitMsg
);
return
pSql
;
}
...
...
@@ -257,6 +264,33 @@ void taos_close(TAOS *taos) {
tscFreeSqlObj
(
pObj
->
pHb
);
}
// free all sqlObjs created by using this connect before free the STscObj
// while(1) {
// pthread_mutex_lock(&pObj->mutex);
// void* p = pObj->sqlList;
// pthread_mutex_unlock(&pObj->mutex);
//
// if (p == NULL) {
// break;
// }
//
// tscDebug("%p waiting for sqlObj to be freed, %p", pObj, p);
// taosMsleep(100);
//
// // todo fix me!! two threads call taos_free_result will cause problem.
// tscDebug("%p free :%p", pObj, p);
// taos_free_result(p);
// }
int32_t
ref
=
T_REF_DEC
(
pObj
);
assert
(
ref
>=
0
);
if
(
ref
>
0
)
{
tscDebug
(
"%p %d remain sqlObjs, not free tscObj and dnodeConn:%p"
,
pObj
,
ref
,
pObj
->
pDnodeConn
);
return
;
}
tscDebug
(
"%p all sqlObj are freed, free tscObj and close dnodeConn:%p"
,
pObj
,
pObj
->
pDnodeConn
);
tscCloseTscObj
(
pObj
);
}
...
...
@@ -533,57 +567,51 @@ int taos_select_db(TAOS *taos, const char *db) {
}
// send free message to vnode to free qhandle and corresponding resources in vnode
static
bool
tscKillQueryInV
node
(
SSqlObj
*
pSql
)
{
static
UNUSED_FUNC
bool
tscKillQueryInD
node
(
SSqlObj
*
pSql
)
{
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
SSqlRes
*
pRes
=
&
pSql
->
res
;
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
0
);
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
if
(
pRes
==
NULL
||
pRes
->
qhandle
==
0
)
{
return
true
;
}
if
(
pRes
->
code
==
TSDB_CODE_SUCCESS
&&
pRes
->
completed
==
false
&&
!
tscIsTwoStageSTableQuery
(
pQueryInfo
,
0
)
&&
(
pCmd
->
command
==
TSDB_SQL_SELECT
||
pCmd
->
command
==
TSDB_SQL_SHOW
||
pCmd
->
command
==
TSDB_SQL_RETRIEVE
||
pCmd
->
command
==
TSDB_SQL_FETCH
)
&&
(
pSql
->
pStream
==
NULL
&&
pTableMetaInfo
->
pTableMeta
!=
NULL
))
{
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
pCmd
,
0
);
if
((
pQueryInfo
==
NULL
)
||
tscIsTwoStageSTableQuery
(
pQueryInfo
,
0
))
{
return
true
;
}
STableMetaInfo
*
pTableMetaInfo
=
tscGetMetaInfo
(
pQueryInfo
,
0
);
tscRemoveFromSqlList
(
pSql
);
int32_t
cmd
=
pCmd
->
command
;
if
(
pRes
->
code
==
TSDB_CODE_SUCCESS
&&
pRes
->
completed
==
false
&&
pSql
->
pStream
==
NULL
&&
(
pTableMetaInfo
->
pTableMeta
!=
NULL
)
&&
(
cmd
==
TSDB_SQL_SELECT
||
cmd
==
TSDB_SQL_SHOW
||
cmd
==
TSDB_SQL_RETRIEVE
||
cmd
==
TSDB_SQL_FETCH
))
{
pQueryInfo
->
type
=
TSDB_QUERY_TYPE_FREE_RESOURCE
;
pCmd
->
command
=
(
pCmd
->
command
>
TSDB_SQL_MGMT
)
?
TSDB_SQL_RETRIEVE
:
TSDB_SQL_FETCH
;
tscDebug
(
"%p send msg to dnode to free qhandle ASAP, command:%s, "
,
pSql
,
sqlCmd
[
pCmd
->
command
]);
tscDebug
(
"%p send msg to dnode to free qhandle ASAP before free sqlObj, command:%s"
,
pSql
,
sqlCmd
[
pCmd
->
command
]);
tscProcessSql
(
pSql
);
return
tru
e
;
return
fals
e
;
}
return
fals
e
;
return
tru
e
;
}
void
taos_free_result
(
TAOS_RES
*
res
)
{
SSqlObj
*
pSql
=
(
SSqlObj
*
)
res
;
SSqlObj
*
pSql
=
(
SSqlObj
*
)
res
;
if
(
pSql
==
NULL
||
pSql
->
signature
!=
pSql
)
{
tscDebug
(
"%p sqlObj has been freed"
,
pSql
);
return
;
}
// The semaphore can not be changed while freeing async sub query objects.
SSqlRes
*
pRes
=
&
pSql
->
res
;
if
(
pRes
==
NULL
||
pRes
->
qhandle
==
0
)
{
tscFreeSqlObj
(
pSql
);
tscDebug
(
"%p SqlObj is freed by app, qhandle is null"
,
pSql
);
return
;
}
// set freeFlag to 1 in retrieve message if there are un-retrieved results data in node
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
&
pSql
->
cmd
,
0
);
if
(
pQueryInfo
==
NULL
)
{
tscFreeSqlObj
(
pSql
);
tscDebug
(
"%p SqlObj is freed by app"
,
pSql
);
tscError
(
"%p already released sqlObj"
,
res
);
return
;
}
pQueryInfo
->
type
=
TSDB_QUERY_TYPE_FREE_RESOURCE
;
if
(
!
tscKillQueryInVnode
(
pSql
))
{
tscFreeSqlObj
(
pSql
);
tscDebug
(
"%p sqlObj is freed by app"
,
pSql
);
bool
freeNow
=
tscKillQueryInDnode
(
pSql
);
if
(
freeNow
)
{
tscDebug
(
"%p free sqlObj in cache"
,
pSql
);
SSqlObj
**
p
=
pSql
->
self
;
taosCacheRelease
(
tscObjCache
,
(
void
**
)
&
p
,
true
);
}
}
...
...
src/client/src/tscStream.c
浏览文件 @
1a7786f3
...
...
@@ -167,7 +167,7 @@ static void tscProcessStreamQueryCallback(void *param, TAOS_RES *tres, int numOf
retryDelay
);
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
&
pStream
->
pSql
->
cmd
,
0
,
0
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
true
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
true
);
taosTFree
(
pTableMetaInfo
->
vgroupList
);
tscSetRetryTimer
(
pStream
,
pStream
->
pSql
,
retryDelay
);
...
...
@@ -275,7 +275,7 @@ static void tscProcessStreamRetrieveResult(void *param, TAOS_RES *res, int numOf
// release the metric/meter meta information reference, so data in cache can be updated
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
false
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
false
);
tscFreeSqlResult
(
pSql
);
taosTFree
(
pSql
->
pSubs
);
pSql
->
numOfSubs
=
0
;
...
...
src/client/src/tscSubquery.c
浏览文件 @
1a7786f3
...
...
@@ -92,7 +92,7 @@ static int64_t doTSBlockIntersect(SSqlObj* pSql, SJoinSupporter* pSupporter1, SJ
STSElem
elem2
=
tsBufGetElem
(
pSupporter2
->
pTSBuf
);
#ifdef _DEBUG_VIEW
tscInfo
(
"%"
PRId64
", tags:%
d
\t
%"
PRId64
", tags:%d"
,
elem1
.
ts
,
elem1
.
tag
,
elem2
.
ts
,
elem2
.
tag
);
tscInfo
(
"%"
PRId64
", tags:%
"
PRId64
"
\t
%"
PRId64
", tags:%"
PRId64
,
elem1
.
ts
,
elem1
.
tag
.
i64Key
,
elem2
.
ts
,
elem2
.
tag
.
i64Key
);
#endif
int32_t
res
=
tVariantCompare
(
&
elem1
.
tag
,
&
elem2
.
tag
);
...
...
@@ -178,10 +178,6 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, SSubqueryState* pState, in
pSupporter
->
subqueryIndex
=
index
;
SQueryInfo
*
pQueryInfo
=
tscGetQueryInfoDetail
(
&
pSql
->
cmd
,
pSql
->
cmd
.
clauseIndex
);
pSupporter
->
intervalTimeUnit
=
pQueryInfo
->
intervalTimeUnit
;
pSupporter
->
slidingTime
=
pQueryInfo
->
slidingTimeUnit
;
pSupporter
->
intervalTime
=
pQueryInfo
->
intervalTime
;
pSupporter
->
slidingTime
=
pQueryInfo
->
slidingTime
;
pSupporter
->
limit
=
pQueryInfo
->
limit
;
STableMetaInfo
*
pTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
&
pSql
->
cmd
,
pSql
->
cmd
.
clauseIndex
,
index
);
...
...
@@ -311,18 +307,12 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
// set the second stage sub query for join process
TSDB_QUERY_SET_TYPE
(
pQueryInfo
->
type
,
TSDB_QUERY_TYPE_JOIN_SEC_STAGE
);
pQueryInfo
->
intervalTimeUnit
=
pSupporter
->
intervalTimeUnit
;
pQueryInfo
->
slidingTimeUnit
=
pSupporter
->
slidingTimeUnit
;
pQueryInfo
->
intervalTime
=
pSupporter
->
intervalTime
;
pQueryInfo
->
slidingTime
=
pSupporter
->
slidingTime
;
pQueryInfo
->
groupbyExpr
=
pSupporter
->
groupbyExpr
;
tscTagCondCopy
(
&
pQueryInfo
->
tagCond
,
&
pSupporter
->
tagCond
);
pQueryInfo
->
colList
=
pSupporter
->
colList
;
pQueryInfo
->
exprList
=
pSupporter
->
exprList
;
pQueryInfo
->
fieldsInfo
=
pSupporter
->
fieldsInfo
;
pSupporter
->
exprList
=
NULL
;
pSupporter
->
colList
=
NULL
;
memset
(
&
pSupporter
->
fieldsInfo
,
0
,
sizeof
(
SFieldInfo
));
...
...
@@ -1221,7 +1211,6 @@ int32_t tscCreateJoinSubquery(SSqlObj *pSql, int16_t tableIndex, SJoinSupporter
pNewQueryInfo
->
limit
.
offset
=
0
;
// backup the data and clear it in the sqlcmd object
pSupporter
->
groupbyExpr
=
pNewQueryInfo
->
groupbyExpr
;
memset
(
&
pNewQueryInfo
->
groupbyExpr
,
0
,
sizeof
(
SSqlGroupbyExpr
));
tscInitQueryInfo
(
pNewQueryInfo
);
...
...
@@ -1523,9 +1512,9 @@ static void tscFreeSubSqlObj(SRetrieveSupport *trsupport, SSqlObj *pSql) {
SSqlObj
*
pParentSql
=
trsupport
->
pParentSql
;
assert
(
pSql
==
pParentSql
->
pSubs
[
index
]);
pParentSql
->
pSubs
[
index
]
=
NULL
;
taos_free_result
(
pSql
);
//
pParentSql->pSubs[index] = NULL;
//
//
taos_free_result(pSql);
taosTFree
(
trsupport
->
localBuffer
);
taosTFree
(
trsupport
);
}
...
...
@@ -1739,10 +1728,6 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR
assert
(
tres
!=
NULL
);
SSqlObj
*
pSql
=
(
SSqlObj
*
)
tres
;
// if (pSql == NULL) { // sql object has been released in error process, return immediately
// tscDebug("%p subquery has been released, idx:%d, abort", pParentSql, idx);
// return;
// }
SSubqueryState
*
pState
=
trsupport
->
pState
;
assert
(
pState
->
numOfRemain
<=
pState
->
numOfTotal
&&
pState
->
numOfRemain
>=
0
&&
pParentSql
->
numOfSubs
==
pState
->
numOfTotal
);
...
...
@@ -1918,9 +1903,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows)
pParentObj
->
res
.
code
=
pSql
->
res
.
code
;
}
taos_free_result
(
tres
);
taosTFree
(
pSupporter
);
if
(
atomic_sub_fetch_32
(
&
pState
->
numOfRemain
,
1
)
>
0
)
{
return
;
}
...
...
@@ -1964,28 +1947,27 @@ int32_t tscHandleInsertRetry(SSqlObj* pSql) {
}
int32_t
tscHandleMultivnodeInsert
(
SSqlObj
*
pSql
)
{
SSqlRes
*
pRes
=
&
pSql
->
res
;
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
size_t
size
=
taosArrayGetSize
(
pCmd
->
pDataBlocks
);
assert
(
size
>
0
);
SSqlRes
*
pRes
=
&
pSql
->
res
;
pSql
->
numOfSubs
=
taosArrayGetSize
(
pCmd
->
pDataBlocks
);
assert
(
pSql
->
numOfSubs
>
0
);
pRes
->
code
=
TSDB_CODE_SUCCESS
;
// the number of already initialized subqueries
int32_t
numOfSub
=
0
;
pSql
->
numOfSubs
=
(
uint16_t
)
size
;
pSql
->
pSubs
=
calloc
(
size
,
POINTER_BYTES
);
SSubqueryState
*
pState
=
calloc
(
1
,
sizeof
(
SSubqueryState
));
pState
->
numOfTotal
=
pSql
->
numOfSubs
;
pState
->
numOfRemain
=
pSql
->
numOfSubs
;
pSql
->
pSubs
=
calloc
(
pSql
->
numOfSubs
,
POINTER_BYTES
);
if
(
pSql
->
pSubs
==
NULL
)
{
goto
_error
;
}
tscDebug
(
"%p submit data to %"
PRIzu
" vnode(s)"
,
pSql
,
size
);
SSubqueryState
*
pState
=
calloc
(
1
,
sizeof
(
SSubqueryState
));
pState
->
numOfTotal
=
pSql
->
numOfSubs
;
pState
->
numOfRemain
=
pSql
->
numOfSubs
;
pRes
->
code
=
TSDB_CODE_SUCCESS
;
tscDebug
(
"%p submit data to %d vnode(s)"
,
pSql
,
pSql
->
numOfSubs
);
while
(
numOfSub
<
pSql
->
numOfSubs
)
{
SInsertSupporter
*
pSupporter
=
calloc
(
1
,
sizeof
(
SInsertSupporter
));
...
...
@@ -2016,8 +1998,8 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) {
tscDebug
(
"%p sub:%p create subObj success. orderOfSub:%d"
,
pSql
,
pNew
,
numOfSub
);
numOfSub
++
;
}
else
{
tscDebug
(
"%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%
"
PRIzu
"
, code:%s"
,
pSql
,
numOfSub
,
size
,
tstrerror
(
pRes
->
code
));
tscDebug
(
"%p prepare submit data block failed in async insertion, vnodeIdx:%d, total:%
d
, code:%s"
,
pSql
,
numOfSub
,
pSql
->
numOfSubs
,
tstrerror
(
pRes
->
code
));
goto
_error
;
}
}
...
...
@@ -2040,11 +2022,6 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql) {
return
TSDB_CODE_SUCCESS
;
_error:
for
(
int32_t
j
=
0
;
j
<
numOfSub
;
++
j
)
{
taosTFree
(
pSql
->
pSubs
[
j
]
->
param
);
taos_free_result
(
pSql
->
pSubs
[
j
]);
}
taosTFree
(
pState
);
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
...
...
@@ -2220,16 +2197,15 @@ void **doSetResultRowData(SSqlObj *pSql, bool finalResult) {
// calculate the result from several other columns
if
(
pSup
->
pArithExprInfo
!=
NULL
)
{
if
(
pRes
->
pArithSup
==
NULL
)
{
SArithmeticSupport
*
sas
=
(
SArithmeticSupport
*
)
calloc
(
1
,
sizeof
(
SArithmeticSupport
));
sas
->
offset
=
0
;
sas
->
pArithExpr
=
pSup
->
pArithExprInfo
;
sas
->
numOfCols
=
(
int32_t
)
tscSqlExprNumOfExprs
(
pQueryInfo
);
sas
->
exprList
=
pQueryInfo
->
exprList
;
sas
->
data
=
calloc
(
sas
->
numOfCols
,
POINTER_BYTES
);
pRes
->
pArithSup
=
sas
;
pRes
->
pArithSup
=
(
SArithmeticSupport
*
)
calloc
(
1
,
sizeof
(
SArithmeticSupport
));
}
pRes
->
pArithSup
->
offset
=
0
;
pRes
->
pArithSup
->
pArithExpr
=
pSup
->
pArithExprInfo
;
pRes
->
pArithSup
->
numOfCols
=
(
int32_t
)
tscSqlExprNumOfExprs
(
pQueryInfo
);
pRes
->
pArithSup
->
exprList
=
pQueryInfo
->
exprList
;
pRes
->
pArithSup
->
data
=
calloc
(
pRes
->
pArithSup
->
numOfCols
,
POINTER_BYTES
);
if
(
pRes
->
buffer
[
i
]
==
NULL
)
{
TAOS_FIELD
*
field
=
tscFieldInfoGetField
(
&
pQueryInfo
->
fieldsInfo
,
i
);
pRes
->
buffer
[
i
]
=
malloc
(
field
->
bytes
);
...
...
src/client/src/tscSystem.c
浏览文件 @
1a7786f3
...
...
@@ -30,7 +30,8 @@
#include "tlocale.h"
// global, not configurable
void
*
tscCacheHandle
;
SCacheObj
*
tscMetaCache
;
SCacheObj
*
tscObjCache
;
void
*
tscTmr
;
void
*
tscQhandle
;
void
*
tscCheckDiskUsageTmr
;
...
...
@@ -144,8 +145,9 @@ void taos_init_imp(void) {
refreshTime
=
refreshTime
>
10
?
10
:
refreshTime
;
refreshTime
=
refreshTime
<
10
?
10
:
refreshTime
;
if
(
tscCacheHandle
==
NULL
)
{
tscCacheHandle
=
taosCacheInit
(
TSDB_DATA_TYPE_BINARY
,
refreshTime
,
false
,
NULL
,
"tableMeta"
);
if
(
tscMetaCache
==
NULL
)
{
tscMetaCache
=
taosCacheInit
(
TSDB_DATA_TYPE_BINARY
,
refreshTime
,
false
,
NULL
,
"tableMeta"
);
tscObjCache
=
taosCacheInit
(
TSDB_DATA_TYPE_BIGINT
,
refreshTime
/
2
,
false
,
tscFreeSqlObjInCache
,
"sqlObj"
);
}
tscDebug
(
"client is initialized successfully"
);
...
...
@@ -154,9 +156,12 @@ void taos_init_imp(void) {
void
taos_init
()
{
pthread_once
(
&
tscinit
,
taos_init_imp
);
}
void
taos_cleanup
()
{
if
(
tscCacheHandle
!=
NULL
)
{
taosCacheCleanup
(
tscCacheHandle
);
tscCacheHandle
=
NULL
;
if
(
tscMetaCache
!=
NULL
)
{
taosCacheCleanup
(
tscMetaCache
);
tscMetaCache
=
NULL
;
taosCacheCleanup
(
tscObjCache
);
tscObjCache
=
NULL
;
}
if
(
tscQhandle
!=
NULL
)
{
...
...
src/client/src/tscUtil.c
浏览文件 @
1a7786f3
...
...
@@ -252,11 +252,11 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
if
(
pRes
->
tsrow
==
NULL
)
{
int32_t
numOfOutput
=
pQueryInfo
->
fieldsInfo
.
numOfOutput
;
pRes
->
numOfCols
=
numOfOutput
;
pRes
->
tsrow
=
calloc
(
numOfOutput
,
POINTER_BYTES
);
pRes
->
length
=
calloc
(
numOfOutput
,
sizeof
(
int32_t
));
pRes
->
buffer
=
calloc
(
numOfOutput
,
POINTER_BYTES
);
// not enough memory
if
(
pRes
->
tsrow
==
NULL
||
(
pRes
->
buffer
==
NULL
&&
pRes
->
numOfCols
>
0
))
{
taosTFree
(
pRes
->
tsrow
);
...
...
@@ -268,7 +268,7 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) {
return
TSDB_CODE_SUCCESS
;
}
void
tscDestroyResPointerInfo
(
SSqlRes
*
pRes
)
{
static
void
tscDestroyResPointerInfo
(
SSqlRes
*
pRes
)
{
if
(
pRes
->
buffer
!=
NULL
)
{
// free all buffers containing the multibyte string
for
(
int
i
=
0
;
i
<
pRes
->
numOfCols
;
i
++
)
{
taosTFree
(
pRes
->
buffer
[
i
]);
...
...
@@ -344,8 +344,6 @@ void tscPartiallyFreeSqlObj(SSqlObj* pSql) {
}
SSqlCmd
*
pCmd
=
&
pSql
->
cmd
;
STscObj
*
pObj
=
pSql
->
pTscObj
;
int32_t
cmd
=
pCmd
->
command
;
if
(
cmd
<
TSDB_SQL_INSERT
||
cmd
==
TSDB_SQL_RETRIEVE_LOCALMERGE
||
cmd
==
TSDB_SQL_RETRIEVE_EMPTY_RESULT
||
cmd
==
TSDB_SQL_TABLE_JOIN_RETRIEVE
)
{
...
...
@@ -353,26 +351,61 @@ void tscPartiallyFreeSqlObj(SSqlObj* pSql) {
}
// pSql->sqlstr will be used by tscBuildQueryStreamDesc
if
(
pObj
->
signature
==
pObj
)
{
//
if (pObj->signature == pObj) {
//pthread_mutex_lock(&pObj->mutex);
taosTFree
(
pSql
->
sqlstr
);
//pthread_mutex_unlock(&pObj->mutex);
}
//
}
tscFreeSqlResult
(
pSql
);
taosTFree
(
pSql
->
pSubs
);
pSql
->
numOfSubs
=
0
;
pSql
->
self
=
0
;
tscResetSqlCmdObj
(
pCmd
,
false
);
}
static
UNUSED_FUNC
void
tscFreeSubobj
(
SSqlObj
*
pSql
)
{
if
(
pSql
->
numOfSubs
==
0
)
{
return
;
}
tscDebug
(
"%p start to free sub SqlObj, numOfSub:%d"
,
pSql
,
pSql
->
numOfSubs
);
for
(
int32_t
i
=
0
;
i
<
pSql
->
numOfSubs
;
++
i
)
{
tscDebug
(
"%p free sub SqlObj:%p, index:%d"
,
pSql
,
pSql
->
pSubs
[
i
],
i
);
taos_free_result
(
pSql
->
pSubs
[
i
]);
pSql
->
pSubs
[
i
]
=
NULL
;
}
pSql
->
numOfSubs
=
0
;
}
/**
* The free operation will cause the pSql to be removed from hash table and free it in
* the function of processmsgfromserver is impossible in this case, since it will fail
* to retrieve pSqlObj in hashtable.
*
* @param pSql
*/
void
tscFreeSqlObjInCache
(
void
*
pSql
)
{
assert
(
pSql
!=
NULL
);
SSqlObj
**
p
=
(
SSqlObj
**
)
pSql
;
assert
((
*
p
)
->
self
!=
0
&&
(
*
p
)
->
self
==
(
p
));
tscFreeSqlObj
(
*
p
);
}
void
tscFreeSqlObj
(
SSqlObj
*
pSql
)
{
if
(
pSql
==
NULL
||
pSql
->
signature
!=
pSql
)
{
return
;
}
tscDebug
(
"%p start to free sql object"
,
pSql
);
tscDebug
(
"%p start to free sqlObj"
,
pSql
);
STscObj
*
pTscObj
=
pSql
->
pTscObj
;
tscFreeSubobj
(
pSql
);
tscPartiallyFreeSqlObj
(
pSql
);
pSql
->
signature
=
NULL
;
...
...
@@ -388,6 +421,14 @@ void tscFreeSqlObj(SSqlObj* pSql) {
tsem_destroy
(
&
pSql
->
rspSem
);
free
(
pSql
);
tscDebug
(
"%p free sqlObj completed"
,
pSql
);
int32_t
ref
=
T_REF_DEC
(
pTscObj
);
assert
(
ref
>=
0
);
if
(
ref
==
0
)
{
tscCloseTscObj
(
pTscObj
);
}
}
void
tscDestroyDataBlock
(
STableDataBlocks
*
pDataBlock
)
{
...
...
@@ -399,7 +440,10 @@ void tscDestroyDataBlock(STableDataBlocks* pDataBlock) {
taosTFree
(
pDataBlock
->
params
);
// free the refcount for metermeta
taosCacheRelease
(
tscCacheHandle
,
(
void
**
)
&
(
pDataBlock
->
pTableMeta
),
false
);
if
(
pDataBlock
->
pTableMeta
!=
NULL
)
{
taosCacheRelease
(
tscMetaCache
,
(
void
**
)
&
(
pDataBlock
->
pTableMeta
),
false
);
}
taosTFree
(
pDataBlock
);
}
...
...
@@ -454,9 +498,12 @@ int32_t tscCopyDataBlockToPayload(SSqlObj* pSql, STableDataBlocks* pDataBlock) {
// set the correct table meta object, the table meta has been locked in pDataBlocks, so it must be in the cache
if
(
pTableMetaInfo
->
pTableMeta
!=
pDataBlock
->
pTableMeta
)
{
tstrncpy
(
pTableMetaInfo
->
name
,
pDataBlock
->
tableId
,
sizeof
(
pTableMetaInfo
->
name
));
taosCacheRelease
(
tscCacheHandle
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
false
);
pTableMetaInfo
->
pTableMeta
=
taosCacheTransfer
(
tscCacheHandle
,
(
void
**
)
&
pDataBlock
->
pTableMeta
);
if
(
pTableMetaInfo
->
pTableMeta
!=
NULL
)
{
taosCacheRelease
(
tscMetaCache
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
false
);
}
pTableMetaInfo
->
pTableMeta
=
taosCacheTransfer
(
tscMetaCache
,
(
void
**
)
&
pDataBlock
->
pTableMeta
);
}
else
{
assert
(
strncmp
(
pTableMetaInfo
->
name
,
pDataBlock
->
tableId
,
tListLen
(
pDataBlock
->
tableId
))
==
0
);
}
...
...
@@ -527,7 +574,7 @@ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOff
* due to operation such as drop database. So here we add the reference count directly instead of invoke
* taosGetDataFromCache, which may return NULL value.
*/
dataBuf
->
pTableMeta
=
taosCacheAcquireByData
(
tsc
CacheHandl
e
,
pTableMeta
);
dataBuf
->
pTableMeta
=
taosCacheAcquireByData
(
tsc
MetaCach
e
,
pTableMeta
);
assert
(
initialSize
>
0
&&
pTableMeta
!=
NULL
&&
dataBuf
->
pTableMeta
!=
NULL
);
*
dataBlocks
=
dataBuf
;
...
...
@@ -721,17 +768,19 @@ int32_t tscMergeTableDataBlocks(SSqlObj* pSql, SArray* pTableDataBlockList) {
// TODO: all subqueries should be freed correctly before close this connection.
void
tscCloseTscObj
(
STscObj
*
pObj
)
{
assert
(
pObj
!=
NULL
);
pObj
->
signature
=
NULL
;
taosTmrStopA
(
&
(
pObj
->
pTimer
));
pthread_mutex_destroy
(
&
pObj
->
mutex
);
void
*
p
=
pObj
->
pDnodeConn
;
if
(
pObj
->
pDnodeConn
!=
NULL
)
{
rpcClose
(
pObj
->
pDnodeConn
);
pObj
->
pDnodeConn
=
NULL
;
}
tscDebug
(
"%p DB connection is closed, dnodeConn:%p"
,
pObj
,
pObj
->
pDnodeConn
);
pthread_mutex_destroy
(
&
pObj
->
mutex
);
tscDebug
(
"%p DB connection is closed, dnodeConn:%p"
,
pObj
,
p
);
taosTFree
(
pObj
);
}
...
...
@@ -1531,8 +1580,8 @@ void tscInitQueryInfo(SQueryInfo* pQueryInfo) {
pQueryInfo
->
fieldsInfo
.
pSupportInfo
=
taosArrayInit
(
4
,
sizeof
(
SFieldSupInfo
));
assert
(
pQueryInfo
->
exprList
==
NULL
);
pQueryInfo
->
exprList
=
taosArrayInit
(
4
,
POINTER_BYTES
);
pQueryInfo
->
colList
=
taosArrayInit
(
4
,
POINTER_BYTES
);
pQueryInfo
->
exprList
=
taosArrayInit
(
4
,
POINTER_BYTES
);
pQueryInfo
->
colList
=
taosArrayInit
(
4
,
POINTER_BYTES
);
pQueryInfo
->
udColumnId
=
TSDB_UD_COLUMN_INDEX
;
}
...
...
@@ -1554,6 +1603,8 @@ int32_t tscAddSubqueryInfo(SSqlCmd* pCmd) {
}
tscInitQueryInfo
(
pQueryInfo
);
pQueryInfo
->
window
=
TSWINDOW_INITIALIZER
;
pQueryInfo
->
msg
=
pCmd
->
payload
;
// pointer to the parent error message buffer
pCmd
->
pQueryInfo
[
pCmd
->
numOfClause
++
]
=
pQueryInfo
;
...
...
@@ -1665,7 +1716,10 @@ void tscClearTableMetaInfo(STableMetaInfo* pTableMetaInfo, bool removeFromCache)
return
;
}
taosCacheRelease
(
tscCacheHandle
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
removeFromCache
);
if
(
pTableMetaInfo
->
pTableMeta
!=
NULL
)
{
taosCacheRelease
(
tscMetaCache
,
(
void
**
)
&
(
pTableMetaInfo
->
pTableMeta
),
removeFromCache
);
}
taosTFree
(
pTableMetaInfo
->
vgroupList
);
tscColumnListDestroy
(
pTableMetaInfo
->
tagColList
);
...
...
@@ -1689,6 +1743,8 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cm
}
pNew
->
pTscObj
=
pSql
->
pTscObj
;
T_REF_INC
(
pNew
->
pTscObj
);
pNew
->
signature
=
pNew
;
SSqlCmd
*
pCmd
=
&
pNew
->
cmd
;
...
...
@@ -1719,6 +1775,11 @@ SSqlObj* createSimpleSubObj(SSqlObj* pSql, void (*fp)(), void* param, int32_t cm
STableMetaInfo
*
pMasterTableMetaInfo
=
tscGetTableMetaInfoFromCmd
(
&
pSql
->
cmd
,
pSql
->
cmd
.
clauseIndex
,
0
);
tscAddTableMetaInfo
(
pQueryInfo
,
pMasterTableMetaInfo
->
name
,
NULL
,
NULL
,
NULL
);
T_REF_INC
(
pNew
->
pTscObj
);
uint64_t
p
=
(
uint64_t
)
pNew
;
pNew
->
self
=
taosCachePut
(
tscObjCache
,
&
p
,
sizeof
(
uint64_t
),
&
pNew
,
sizeof
(
uint64_t
),
2
*
600
*
1000
);
return
pNew
;
}
...
...
@@ -1808,6 +1869,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
pNew
->
pTscObj
=
pSql
->
pTscObj
;
pNew
->
signature
=
pNew
;
T_REF_INC
(
pNew
->
pTscObj
);
pNew
->
sqlstr
=
strdup
(
pSql
->
sqlstr
);
if
(
pNew
->
sqlstr
==
NULL
)
{
...
...
@@ -1912,14 +1974,14 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
STableMetaInfo
*
pFinalInfo
=
NULL
;
if
(
pPrevSql
==
NULL
)
{
STableMeta
*
pTableMeta
=
taosCacheAcquireByData
(
tsc
CacheHandl
e
,
pTableMetaInfo
->
pTableMeta
);
// get by name may failed due to the cache cleanup
STableMeta
*
pTableMeta
=
taosCacheAcquireByData
(
tsc
MetaCach
e
,
pTableMetaInfo
->
pTableMeta
);
// get by name may failed due to the cache cleanup
assert
(
pTableMeta
!=
NULL
);
pFinalInfo
=
tscAddTableMetaInfo
(
pNewQueryInfo
,
name
,
pTableMeta
,
pTableMetaInfo
->
vgroupList
,
pTableMetaInfo
->
tagColList
);
}
else
{
// transfer the ownership of pTableMeta to the newly create sql object.
STableMetaInfo
*
pPrevInfo
=
tscGetTableMetaInfoFromCmd
(
&
pPrevSql
->
cmd
,
pPrevSql
->
cmd
.
clauseIndex
,
0
);
STableMeta
*
pPrevTableMeta
=
taosCacheTransfer
(
tsc
CacheHandl
e
,
(
void
**
)
&
pPrevInfo
->
pTableMeta
);
STableMeta
*
pPrevTableMeta
=
taosCacheTransfer
(
tsc
MetaCach
e
,
(
void
**
)
&
pPrevInfo
->
pTableMeta
);
SVgroupsInfo
*
pVgroupsInfo
=
pPrevInfo
->
vgroupList
;
pFinalInfo
=
tscAddTableMetaInfo
(
pNewQueryInfo
,
name
,
pPrevTableMeta
,
pVgroupsInfo
,
pTableMetaInfo
->
tagColList
);
...
...
@@ -1959,6 +2021,10 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, void (*fp)(), void
tscDebug
(
"%p new sub insertion: %p, vnodeIdx:%d"
,
pSql
,
pNew
,
pTableMetaInfo
->
vgroupIndex
);
}
T_REF_INC
(
pNew
->
pTscObj
);
uint64_t
p
=
(
uint64_t
)
pNew
;
pNew
->
self
=
taosCachePut
(
tscObjCache
,
&
p
,
sizeof
(
uint64_t
),
&
pNew
,
sizeof
(
uint64_t
),
2
*
600
*
10
);
return
pNew
;
_error:
...
...
@@ -2070,6 +2136,7 @@ int32_t tscSQLSyntaxErrMsg(char* msg, const char* additionalInfo, const char* s
return
TSDB_CODE_TSC_SQL_SYNTAX_ERROR
;
}
int32_t
tscInvalidSQLErrMsg
(
char
*
msg
,
const
char
*
additionalInfo
,
const
char
*
sql
)
{
const
char
*
msgFormat1
=
"invalid SQL: %s"
;
const
char
*
msgFormat2
=
"invalid SQL:
\'
%s
\'
(%s)"
;
...
...
@@ -2100,11 +2167,6 @@ bool tscHasReachLimitation(SQueryInfo* pQueryInfo, SSqlRes* pRes) {
return
(
pQueryInfo
->
clauseLimit
>
0
&&
pRes
->
numOfClauseTotal
>=
pQueryInfo
->
clauseLimit
);
}
bool
tscResultsetFetchCompleted
(
TAOS_RES
*
result
)
{
SSqlRes
*
pRes
=
result
;
return
pRes
->
completed
;
}
char
*
tscGetErrorMsgPayload
(
SSqlCmd
*
pCmd
)
{
return
pCmd
->
payload
;
}
/**
...
...
src/common/src/tglobal.c
浏览文件 @
1a7786f3
...
...
@@ -957,17 +957,6 @@ static void doInitGlobalConfig(void) {
cfg
.
unitType
=
TAOS_CFG_UTYPE_NONE
;
taosInitConfigOption
(
cfg
);
// http configs
cfg
.
option
=
"httpCacheSessions"
;
cfg
.
ptr
=
&
tsHttpCacheSessions
;
cfg
.
valType
=
TAOS_CFG_VTYPE_INT32
;
cfg
.
cfgType
=
TSDB_CFG_CTYPE_B_CONFIG
;
cfg
.
minValue
=
1
;
cfg
.
maxValue
=
100000
;
cfg
.
ptrLength
=
0
;
cfg
.
unitType
=
TAOS_CFG_UTYPE_NONE
;
taosInitConfigOption
(
cfg
);
cfg
.
option
=
"httpEnableRecordSql"
;
cfg
.
ptr
=
&
tsHttpEnableRecordSql
;
cfg
.
valType
=
TAOS_CFG_VTYPE_INT32
;
...
...
src/common/src/tname.c
浏览文件 @
1a7786f3
...
...
@@ -62,10 +62,9 @@ SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, SStrToken* exprStr, const
if
(
name
!=
NULL
)
{
tstrncpy
(
s
.
name
,
name
,
sizeof
(
s
.
name
));
}
else
{
size_t
len
=
strdequote
(
exprStr
->
z
);
size_t
tlen
=
MIN
(
sizeof
(
s
.
name
),
len
+
1
);
size_t
tlen
=
MIN
(
sizeof
(
s
.
name
),
exprStr
->
n
+
1
);
tstrncpy
(
s
.
name
,
exprStr
->
z
,
tlen
);
strdequote
(
s
.
name
);
}
return
s
;
...
...
src/common/src/ttypes.c
浏览文件 @
1a7786f3
...
...
@@ -540,9 +540,7 @@ void assignVal(char *val, const char *src, int32_t len, int32_t type) {
}
}
void
tsDataSwap
(
void
*
pLeft
,
void
*
pRight
,
int32_t
type
,
int32_t
size
)
{
char
tmpBuf
[
4096
]
=
{
0
};
void
tsDataSwap
(
void
*
pLeft
,
void
*
pRight
,
int32_t
type
,
int32_t
size
,
void
*
buf
)
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_INT
:
{
SWAP
(
*
(
int32_t
*
)(
pLeft
),
*
(
int32_t
*
)(
pRight
),
int32_t
);
...
...
@@ -575,10 +573,9 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size) {
}
default:
{
assert
(
size
<=
4096
);
memcpy
(
tmpBuf
,
pLeft
,
size
);
memcpy
(
buf
,
pLeft
,
size
);
memcpy
(
pLeft
,
pRight
,
size
);
memcpy
(
pRight
,
tmpB
uf
,
size
);
memcpy
(
pRight
,
b
uf
,
size
);
break
;
}
}
...
...
src/connector/jdbc/pom.xml
浏览文件 @
1a7786f3
...
...
@@ -48,11 +48,6 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>
org.apache.commons
</groupId>
<artifactId>
commons-lang3
</artifactId>
<version>
${commons-lang3.version}
</version>
</dependency>
<dependency>
<groupId>
junit
</groupId>
<artifactId>
junit
</artifactId>
...
...
src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java
浏览文件 @
1a7786f3
...
...
@@ -14,8 +14,6 @@
*****************************************************************************/
package
com.taosdata.jdbc
;
import
org.apache.commons.lang3.StringUtils
;
import
java.sql.*
;
import
java.util.Properties
;
import
java.util.logging.Logger
;
...
...
@@ -42,9 +40,8 @@ import java.util.logging.Logger;
public
class
TSDBDriver
implements
java
.
sql
.
Driver
{
@Deprecated
private
static
final
String
URL_PREFIX1
=
"jdbc:TSDB://"
;
private
static
final
String
URL_PREFIX
=
"jdbc:TAOS://"
;
private
static
final
String
URL_PREFIX1
=
"jdbc:tsdb://"
;
private
static
final
String
URL_PREFIX
=
"jdbc:taos://"
;
/**
* Key used to retrieve the database value from the properties instance passed
...
...
@@ -188,7 +185,7 @@ public class TSDBDriver implements java.sql.Driver {
}
public
boolean
acceptsURL
(
String
url
)
throws
SQLException
{
return
StringUtils
.
isNotBlank
(
url
)
&&
url
.
startsWith
(
URL_PREFIX
);
return
(
url
!=
null
&&
url
.
length
()
>
0
&&
url
.
trim
().
length
()
>
0
)
&&
url
.
toLowerCase
()
.
startsWith
(
URL_PREFIX
);
}
public
DriverPropertyInfo
[]
getPropertyInfo
(
String
url
,
Properties
info
)
throws
SQLException
{
...
...
@@ -238,7 +235,8 @@ public class TSDBDriver implements java.sql.Driver {
return
null
;
}
if
(!
StringUtils
.
startsWithIgnoreCase
(
url
,
URL_PREFIX
)
&&
!
StringUtils
.
startsWithIgnoreCase
(
url
,
URL_PREFIX1
))
{
String
lowerUrl
=
url
.
toLowerCase
();
if
(!
lowerUrl
.
startsWith
(
URL_PREFIX
)
&&
!
lowerUrl
.
startsWith
(
URL_PREFIX1
))
{
return
null
;
}
...
...
src/inc/taosdef.h
浏览文件 @
1a7786f3
...
...
@@ -198,7 +198,7 @@ void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems);
void
*
getNullValue
(
int32_t
type
);
void
assignVal
(
char
*
val
,
const
char
*
src
,
int32_t
len
,
int32_t
type
);
void
tsDataSwap
(
void
*
pLeft
,
void
*
pRight
,
int32_t
type
,
int32_t
size
);
void
tsDataSwap
(
void
*
pLeft
,
void
*
pRight
,
int32_t
type
,
int32_t
size
,
void
*
buf
);
// TODO: check if below is necessary
#define TSDB_RELATION_INVALID 0
...
...
@@ -209,21 +209,24 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
#define TSDB_RELATION_GREATER_EQUAL 5
#define TSDB_RELATION_NOT_EQUAL 6
#define TSDB_RELATION_LIKE 7
#define TSDB_RELATION_IN 8
#define TSDB_RELATION_AND 9
#define TSDB_RELATION_OR 10
#define TSDB_RELATION_NOT 11
#define TSDB_BINARY_OP_ADD 12
#define TSDB_BINARY_OP_SUBTRACT 13
#define TSDB_BINARY_OP_MULTIPLY 14
#define TSDB_BINARY_OP_DIVIDE 15
#define TSDB_BINARY_OP_REMAINDER 16
#define TSDB_RELATION_ISNULL 8
#define TSDB_RELATION_NOTNULL 9
#define TSDB_RELATION_IN 10
#define TSDB_RELATION_AND 11
#define TSDB_RELATION_OR 12
#define TSDB_RELATION_NOT 13
#define TSDB_BINARY_OP_ADD 30
#define TSDB_BINARY_OP_SUBTRACT 31
#define TSDB_BINARY_OP_MULTIPLY 32
#define TSDB_BINARY_OP_DIVIDE 33
#define TSDB_BINARY_OP_REMAINDER 34
#define TS_PATH_DELIMITER_LEN 1
#define TSDB_UNI_LEN 24
#define TSDB_USER_LEN TSDB_UNI_LEN
// ACCOUNT is a 32 bit positive integer
// this is the length of its string representation
// including the terminator zero
...
...
src/kit/shell/src/shellEngine.c
浏览文件 @
1a7786f3
...
...
@@ -765,7 +765,9 @@ void read_history() {
FILE
*
f
=
fopen
(
f_history
,
"r"
);
if
(
f
==
NULL
)
{
#ifndef WINDOWS
fprintf
(
stderr
,
"Failed to open file %s
\n
"
,
f_history
);
if
(
errno
!=
ENOENT
)
{
fprintf
(
stderr
,
"Failed to open file %s, reason:%s
\n
"
,
f_history
,
strerror
(
errno
));
}
#endif
return
;
}
...
...
@@ -792,7 +794,7 @@ void write_history() {
FILE
*
f
=
fopen
(
f_history
,
"w"
);
if
(
f
==
NULL
)
{
#ifndef WINDOWS
fprintf
(
stderr
,
"Failed to open file %s for write
\n
"
,
f_history
);
fprintf
(
stderr
,
"Failed to open file %s for write
, reason:%s
\n
"
,
f_history
,
strerror
(
errno
)
);
#endif
return
;
}
...
...
src/plugins/http/src/httpContext.c
浏览文件 @
1a7786f3
...
...
@@ -131,8 +131,6 @@ HttpContext *httpCreateContext(int32_t fd) {
HttpContext
*
httpGetContext
(
void
*
ptr
)
{
uint64_t
handleVal
=
(
uint64_t
)
ptr
;
HttpContext
**
ppContext
=
taosCacheAcquireByKey
(
tsHttpServer
.
contextCache
,
&
handleVal
,
sizeof
(
HttpContext
*
));
ASSERT
(
ppContext
);
ASSERT
(
*
ppContext
);
if
(
ppContext
)
{
HttpContext
*
pContext
=
*
ppContext
;
...
...
src/plugins/http/src/httpRestJson.c
浏览文件 @
1a7786f3
...
...
@@ -87,15 +87,12 @@ bool restBuildSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result,
JsonBuf
*
jsonBuf
=
httpMallocJsonBuf
(
pContext
);
if
(
jsonBuf
==
NULL
)
return
false
;
cmd
->
numOfRows
+=
numOfRows
;
int32_t
num_fields
=
taos_num_fields
(
result
);
TAOS_FIELD
*
fields
=
taos_fetch_fields
(
result
);
for
(
int32_t
k
=
0
;
k
<
numOfRows
;
++
k
)
{
TAOS_ROW
row
=
taos_fetch_row
(
result
);
if
(
row
==
NULL
)
{
cmd
->
numOfRows
--
;
continue
;
}
int32_t
*
length
=
taos_fetch_lengths
(
result
);
...
...
@@ -151,24 +148,23 @@ bool restBuildSqlJson(HttpContext *pContext, HttpSqlCmd *cmd, TAOS_RES *result,
}
// data row array end
httpJsonToken
(
jsonBuf
,
JsonArrEnd
);
}
httpJsonToken
(
jsonBuf
,
JsonArrEnd
);
cmd
->
numOfRows
++
;
if
(
cmd
->
numOfRows
>=
tsRestRowLimit
)
{
httpDebug
(
"context:%p, fd:%d, user:%s, retrieve rows:%d larger than limit:%d, abort retrieve"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
cmd
->
numOfRows
,
tsRestRowLimit
);
return
false
;
}
else
{
if
(
pContext
->
fd
<=
0
)
{
httpError
(
"context:%p, fd:%d, user:%s, connection is closed, abort retrieve"
,
pContext
,
pContext
->
fd
,
pContext
->
user
);
httpError
(
"context:%p, fd:%d, user:%s, conn closed, abort retrieve"
,
pContext
,
pContext
->
fd
,
pContext
->
user
);
return
false
;
}
if
(
cmd
->
numOfRows
>=
tsRestRowLimit
)
{
httpDebug
(
"context:%p, fd:%d, user:%s, retrieve rows:%d larger than limit:%d, abort retrieve"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
cmd
->
numOfRows
,
tsRestRowLimit
);
return
false
;
}
else
{
httpDebug
(
"context:%p, fd:%d, user:%s, total rows:%d retrieved"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
cmd
->
numOfRows
);
return
true
;
}
}
httpDebug
(
"context:%p, fd:%d, user:%s, retrieved row:%d"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
cmd
->
numOfRows
);
return
true
;
}
bool
restBuildSqlTimestampJson
(
HttpContext
*
pContext
,
HttpSqlCmd
*
cmd
,
TAOS_RES
*
result
,
int32_t
numOfRows
)
{
...
...
src/plugins/http/src/httpServer.c
浏览文件 @
1a7786f3
...
...
@@ -315,45 +315,48 @@ static bool httpReadData(HttpContext *pContext) {
pContext
->
accessTimes
++
;
pContext
->
lastAccessTime
=
taosGetTimestampSec
();
char
buf
[
HTTP_STEP_SIZE
+
1
]
=
{
0
};
char
buf
[
HTTP_STEP_SIZE
+
1
]
=
{
0
};
int32_t
nread
=
(
int32_t
)
taosReadSocket
(
pContext
->
fd
,
buf
,
HTTP_STEP_SIZE
);
if
(
nread
>
0
)
{
buf
[
nread
]
=
'\0'
;
httpTraceL
(
"context:%p, fd:%d, nread:%d content:%s"
,
pContext
,
pContext
->
fd
,
nread
,
buf
);
int32_t
ok
=
httpParseBuf
(
pParser
,
buf
,
nread
);
if
(
ok
)
{
httpError
(
"context:%p, fd:%d, parse failed, ret:%d code:%d close connect"
,
pContext
,
pContext
->
fd
,
ok
,
pParser
->
parseCode
);
httpSendErrorResp
(
pContext
,
pParser
->
parseCode
);
httpNotifyContextClose
(
pContext
);
return
false
;
}
while
(
1
)
{
int32_t
nread
=
(
int32_t
)
taosReadSocket
(
pContext
->
fd
,
buf
,
HTTP_STEP_SIZE
);
if
(
nread
>
0
)
{
buf
[
nread
]
=
'\0'
;
httpTraceL
(
"context:%p, fd:%d, nread:%d content:%s"
,
pContext
,
pContext
->
fd
,
nread
,
buf
);
int32_t
ok
=
httpParseBuf
(
pParser
,
buf
,
nread
);
if
(
ok
)
{
httpError
(
"context:%p, fd:%d, parse failed, ret:%d code:%d close connect"
,
pContext
,
pContext
->
fd
,
ok
,
pParser
->
parseCode
);
httpSendErrorResp
(
pContext
,
pParser
->
parseCode
);
httpNotifyContextClose
(
pContext
);
return
false
;
}
if
(
pParser
->
parseCode
)
{
httpError
(
"context:%p, fd:%d, parse failed, code:%d close connect"
,
pContext
,
pContext
->
fd
,
pParser
->
parseCode
);
httpSendErrorResp
(
pContext
,
pParser
->
parseCode
);
httpNotifyContextClose
(
pContext
);
return
false
;
}
if
(
pParser
->
parseCode
)
{
httpError
(
"context:%p, fd:%d, parse failed, code:%d close connect"
,
pContext
,
pContext
->
fd
,
pParser
->
parseCode
);
httpSendErrorResp
(
pContext
,
pParser
->
parseCode
);
httpNotifyContextClose
(
pContext
);
return
false
;
}
if
(
!
pParser
->
parsed
)
{
httpTrace
(
"context:%p, fd:%d, read not over yet, len:%d"
,
pContext
,
pContext
->
fd
,
pParser
->
body
.
pos
);
return
false
;
}
else
{
httpDebug
(
"context:%p, fd:%d, totalLen:%d"
,
pContext
,
pContext
->
fd
,
pParser
->
body
.
pos
);
return
true
;
}
}
else
if
(
nread
<
0
)
{
if
(
errno
==
EINTR
||
errno
==
EAGAIN
||
errno
==
EWOULDBLOCK
)
{
httpDebug
(
"context:%p, fd:%d, read from socket error:%d, wait another event"
,
pContext
,
pContext
->
fd
,
errno
);
return
false
;
// later again
if
(
!
pParser
->
parsed
)
{
httpTrace
(
"context:%p, fd:%d, read not finished"
,
pContext
,
pContext
->
fd
);
continue
;
}
else
{
httpDebug
(
"context:%p, fd:%d, bodyLen:%d"
,
pContext
,
pContext
->
fd
,
pParser
->
body
.
pos
);
return
true
;
}
}
else
if
(
nread
<
0
)
{
if
(
errno
==
EINTR
||
errno
==
EAGAIN
||
errno
==
EWOULDBLOCK
)
{
httpDebug
(
"context:%p, fd:%d, read from socket error:%d, wait another event"
,
pContext
,
pContext
->
fd
,
errno
);
return
false
;
// later again
}
else
{
httpError
(
"context:%p, fd:%d, read from socket error:%d, close connect"
,
pContext
,
pContext
->
fd
,
errno
);
return
false
;
}
}
else
{
httpError
(
"context:%p, fd:%d,
read from socket error:%d, close connect"
,
pContext
,
pContext
->
fd
,
errno
);
httpError
(
"context:%p, fd:%d,
nread:%d, wait another event"
,
pContext
,
pContext
->
fd
,
nread
);
return
false
;
}
}
else
{
httpError
(
"context:%p, fd:%d, nread:%d, wait another event"
,
pContext
,
pContext
->
fd
,
nread
);
return
false
;
}
}
src/plugins/http/src/httpSql.c
浏览文件 @
1a7786f3
...
...
@@ -51,10 +51,6 @@ void httpProcessMultiSqlRetrieveCallBackImp(void *param, TAOS_RES *result, int n
}
}
// if (tscResultsetFetchCompleted(result)) {
// isContinue = false;
// }
if
(
isContinue
)
{
// retrieve next batch of rows
httpDebug
(
"context:%p, fd:%d, user:%s, process pos:%d, continue retrieve, numOfRows:%d, sql:%s"
,
pContext
,
...
...
@@ -224,14 +220,6 @@ void httpProcessSingleSqlRetrieveCallBackImp(void *param, TAOS_RES *result, int
}
}
#if 0
// todo refactor
if (tscResultsetFetchCompleted(result)) {
httpDebug("context:%p, fd:%d, user:%s, resultset fetch completed", pContext, pContext->fd, pContext->user);
isContinue = false;
}
#endif
if
(
isContinue
)
{
// retrieve next batch of rows
httpDebug
(
"context:%p, fd:%d, user:%s, continue retrieve, numOfRows:%d"
,
pContext
,
pContext
->
fd
,
pContext
->
user
,
...
...
src/query/inc/qAst.h
浏览文件 @
1a7786f3
...
...
@@ -32,6 +32,7 @@ struct tExprNode;
struct
SSchema
;
enum
{
TSQL_NODE_DUMMY
=
0x0
,
TSQL_NODE_EXPR
=
0x1
,
TSQL_NODE_COL
=
0x2
,
TSQL_NODE_VALUE
=
0x4
,
...
...
src/query/inc/qExecutor.h
浏览文件 @
1a7786f3
...
...
@@ -57,7 +57,7 @@ typedef struct SWindowResult {
uint16_t
numOfRows
;
// number of rows of current time window
bool
closed
;
// this result status: closed or opened
SResultInfo
*
resultInfo
;
// For each result column, there is a resultInfo
TSKEY
skey
;
// start key of current time window
union
{
STimeWindow
win
;
char
*
key
;};
// start key of current time window
}
SWindowResult
;
/**
...
...
src/query/inc/qPercentile.h
浏览文件 @
1a7786f3
...
...
@@ -64,11 +64,11 @@ typedef struct tMemBucket {
__perc_hash_func_t
hashFunc
;
}
tMemBucket
;
tMemBucket
*
tMemBucketCreate
(
int16_t
nElemSize
,
int16_t
dataType
);
tMemBucket
*
tMemBucketCreate
(
int16_t
nElemSize
,
int16_t
dataType
,
double
minval
,
double
maxval
);
void
tMemBucketDestroy
(
tMemBucket
*
pBucket
);
void
tMemBucketPut
(
tMemBucket
*
pBucket
,
const
void
*
data
,
size_t
size
);
int32_t
tMemBucketPut
(
tMemBucket
*
pBucket
,
const
void
*
data
,
size_t
size
);
double
getPercentile
(
tMemBucket
*
pMemBucket
,
double
percent
);
...
...
src/query/inc/qUtil.h
浏览文件 @
1a7786f3
...
...
@@ -50,14 +50,16 @@ static FORCE_INLINE char *getPosInResultPage(SQueryRuntimeEnv *pRuntimeEnv, int3
tFilePage
*
page
)
{
assert
(
pResult
!=
NULL
&&
pRuntimeEnv
!=
NULL
);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
// tFilePage *page = getResBufPage(pRuntimeEnv->pResultBuf, pResult->pos.pageId);
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
int32_t
realRowId
=
(
int32_t
)(
pResult
->
pos
.
rowId
*
GET_ROW_PARAM_FOR_MULTIOUTPUT
(
pQuery
,
pRuntimeEnv
->
topBotQuery
,
pRuntimeEnv
->
stableQuery
));
return
((
char
*
)
page
->
data
)
+
pRuntimeEnv
->
offset
[
columnIndex
]
*
pRuntimeEnv
->
numOfRowsPerPage
+
pQuery
->
pSelectExpr
[
columnIndex
].
bytes
*
realRowId
;
}
bool
isNull_filter
(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
);
bool
notNull_filter
(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
);
__filter_func_t
*
getRangeFilterFuncArray
(
int32_t
type
);
__filter_func_t
*
getValueFilterFuncArray
(
int32_t
type
);
...
...
src/query/inc/sql.y
浏览文件 @
1a7786f3
...
...
@@ -567,53 +567,53 @@ where_opt(A) ::= WHERE expr(X). {A = X;}
%type expr {tSQLExpr*}
%destructor expr {tSQLExprDestroy($$);}
expr(A) ::= LP expr(X) RP. {A = X; }
expr(A) ::= LP expr(X) RP.
{A = X; }
expr(A) ::= ID(X). {A = tSQLExprIdValueCreate(&X, TK_ID);}
expr(A) ::= ID(X) DOT ID(Y). {X.n += (1+Y.n); A = tSQLExprIdValueCreate(&X, TK_ID);}
expr(A) ::= ID(X) DOT STAR(Y). {X.n += (1+Y.n); A = tSQLExprIdValueCreate(&X, TK_ALL);}
expr(A) ::= ID(X).
{A = tSQLExprIdValueCreate(&X, TK_ID);}
expr(A) ::= ID(X) DOT ID(Y).
{X.n += (1+Y.n); A = tSQLExprIdValueCreate(&X, TK_ID);}
expr(A) ::= ID(X) DOT STAR(Y).
{X.n += (1+Y.n); A = tSQLExprIdValueCreate(&X, TK_ALL);}
expr(A) ::= INTEGER(X). {A = tSQLExprIdValueCreate(&X, TK_INTEGER);}
expr(A) ::= INTEGER(X).
{A = tSQLExprIdValueCreate(&X, TK_INTEGER);}
expr(A) ::= MINUS(X) INTEGER(Y). {X.n += Y.n; X.type = TK_INTEGER; A = tSQLExprIdValueCreate(&X, TK_INTEGER);}
expr(A) ::= PLUS(X) INTEGER(Y). {X.n += Y.n; X.type = TK_INTEGER; A = tSQLExprIdValueCreate(&X, TK_INTEGER);}
expr(A) ::= FLOAT(X). {A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
expr(A) ::= MINUS(X) FLOAT(Y).
{X.n += Y.n; X.type = TK_FLOAT; A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
expr(A) ::= PLUS(X) FLOAT(Y).
{X.n += Y.n; X.type = TK_FLOAT; A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
expr(A) ::= STRING(X). {A = tSQLExprIdValueCreate(&X, TK_STRING);}
expr(A) ::= NOW(X). {A = tSQLExprIdValueCreate(&X, TK_NOW); }
expr(A) ::= VARIABLE(X). {A = tSQLExprIdValueCreate(&X, TK_VARIABLE);}
expr(A) ::= BOOL(X). {A = tSQLExprIdValueCreate(&X, TK_BOOL);}
// normal functions: min(x)
expr(A) ::= ID(X) LP exprlist(Y) RP(E). {
A = tSQLExprCreateFunction(Y, &X, &E, X.type);
}
// this is for: count(*)/first(*)/last(*) operation
expr(A) ::= ID(X) LP STAR RP(Y). {
A = tSQLExprCreateFunction(NULL, &X, &Y, X.type);
}
//binary expression: a+2, b+3
expr(A) ::= expr(X) AND expr(Y). {A = tSQLExprCreate(X, Y, TK_AND);}
expr(A) ::= expr(X)
OR expr(Y). {A = tSQLExprCreate(X, Y, TK_OR);
}
//binary relational expression
expr(A) ::= expr(X)
LT expr(Y). {A = tSQLExprCreate(X, Y, TK_LT
);}
expr(A) ::= expr(X)
GT expr(Y). {A = tSQLExprCreate(X, Y, TK_GT
);}
expr(A) ::= expr(X)
LE expr(Y). {A = tSQLExprCreate(X, Y, TK_LE
);}
expr(A) ::= expr(X) GE expr(Y). {A = tSQLExprCreate(X, Y, TK_GE);}
expr(A) ::= expr(X)
NE expr(Y). {A = tSQLExprCreate(X, Y, TK_NE
);}
expr(A) ::= expr(X)
EQ expr(Y). {A = tSQLExprCreate(X, Y, TK_EQ);
}
//binary arithmetic expression
expr(A) ::= FLOAT(X).
{A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
expr(A) ::= MINUS(X) FLOAT(Y). {X.n += Y.n; X.type = TK_FLOAT; A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
expr(A) ::= PLUS(X) FLOAT(Y). {X.n += Y.n; X.type = TK_FLOAT; A = tSQLExprIdValueCreate(&X, TK_FLOAT);}
expr(A) ::= STRING(X).
{A = tSQLExprIdValueCreate(&X, TK_STRING);}
expr(A) ::= NOW(X).
{A = tSQLExprIdValueCreate(&X, TK_NOW); }
expr(A) ::= VARIABLE(X).
{A = tSQLExprIdValueCreate(&X, TK_VARIABLE);}
expr(A) ::= BOOL(X).
{A = tSQLExprIdValueCreate(&X, TK_BOOL);}
// ordinary functions: min(x), max(x), top(k, 20)
expr(A) ::= ID(X) LP exprlist(Y) RP(E). { A = tSQLExprCreateFunction(Y, &X, &E, X.type); }
// for parsing sql functions with wildcard for parameters. e.g., count(*)/first(*)/last(*) operation
expr(A) ::= ID(X) LP STAR RP(Y). { A = tSQLExprCreateFunction(NULL, &X, &Y, X.type); }
// is (not) null expression
expr(A) ::= expr(X) IS NULL. {A = tSQLExprCreate(X, NULL, TK_ISNULL);
}
expr(A) ::= expr(X) IS NOT NULL. {A = tSQLExprCreate(X, NULL, TK_NOTNULL);}
// relational expression
expr(A) ::= expr(X)
LT expr(Y). {A = tSQLExprCreate(X, Y, TK_LT);
}
expr(A) ::= expr(X) GT expr(Y). {A = tSQLExprCreate(X, Y, TK_GT);}
expr(A) ::= expr(X) LE expr(Y). {A = tSQLExprCreate(X, Y, TK_LE);}
expr(A) ::= expr(X)
GE expr(Y). {A = tSQLExprCreate(X, Y, TK_GE
);}
expr(A) ::= expr(X)
NE expr(Y). {A = tSQLExprCreate(X, Y, TK_NE
);}
expr(A) ::= expr(X)
EQ expr(Y). {A = tSQLExprCreate(X, Y, TK_EQ
);}
expr(A) ::= expr(X)
AND expr(Y). {A = tSQLExprCreate(X, Y, TK_AND
);}
expr(A) ::= expr(X)
OR expr(Y). {A = tSQLExprCreate(X, Y, TK_OR);
}
//
binary arithmetic expression
expr(A) ::= expr(X) PLUS expr(Y). {A = tSQLExprCreate(X, Y, TK_PLUS); }
expr(A) ::= expr(X) MINUS expr(Y). {A = tSQLExprCreate(X, Y, TK_MINUS); }
expr(A) ::= expr(X) STAR expr(Y). {A = tSQLExprCreate(X, Y, TK_STAR); }
expr(A) ::= expr(X) SLASH expr(Y). {A = tSQLExprCreate(X, Y, TK_DIVIDE);}
expr(A) ::= expr(X) REM expr(Y). {A = tSQLExprCreate(X, Y, TK_REM); }
//like expression
expr(A) ::= expr(X) LIKE
expr(Y).
{A = tSQLExprCreate(X, Y, TK_LIKE); }
//
like expression
expr(A) ::= expr(X) LIKE
expr(Y).
{A = tSQLExprCreate(X, Y, TK_LIKE); }
//in expression
expr(A) ::= expr(X) IN LP exprlist(Y) RP. {A = tSQLExprCreate(X, (tSQLExpr*)Y, TK_IN); }
...
...
@@ -625,9 +625,9 @@ expr(A) ::= expr(X) IN LP exprlist(Y) RP. {A = tSQLExprCreate(X, (tSQLExpr*)Y,
%destructor expritem {tSQLExprDestroy($$);}
exprlist(A) ::= exprlist(X) COMMA expritem(Y). {A = tSQLExprListAppend(X,Y,0);}
exprlist(A) ::= expritem(X). {A = tSQLExprListAppend(0,X,0);}
expritem(A) ::= expr(X). {A = X;}
expritem(A) ::= . {A = 0;}
exprlist(A) ::= expritem(X).
{A = tSQLExprListAppend(0,X,0);}
expritem(A) ::= expr(X).
{A = X;}
expritem(A) ::= .
{A = 0;}
///////////////////////////////////reset query cache//////////////////////////////////////
cmd ::= RESET QUERY CACHE. { setDCLSQLElems(pInfo, TSDB_SQL_RESET_CACHE, 0);}
...
...
src/query/inc/tsqlfunction.h
浏览文件 @
1a7786f3
...
...
@@ -177,7 +177,7 @@ typedef struct SQLFunctionCtx {
int16_t
outputType
;
int16_t
outputBytes
;
// size of results, determined by function and input column data type
bool
hasNull
;
// null value exist in current block
bool
requireNull
;
// require null in some function
bool
requireNull
;
// require null in some function
int16_t
functionId
;
// function id
void
*
aInputElemBuf
;
char
*
aOutputBuf
;
// final result output buffer, point to sdata->data
...
...
src/query/src/qAst.c
浏览文件 @
1a7786f3
...
...
@@ -188,6 +188,10 @@ uint8_t getBinaryExprOptr(SStrToken *pToken) {
return
TSDB_BINARY_OP_REMAINDER
;
case
TK_LIKE
:
return
TSDB_RELATION_LIKE
;
case
TK_ISNULL
:
return
TSDB_RELATION_ISNULL
;
case
TK_NOTNULL
:
return
TSDB_RELATION_NOTNULL
;
default:
{
return
0
;
}
}
}
...
...
@@ -486,29 +490,42 @@ static void tQueryIndexColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo, SArr
}
else
{
int32_t
optr
=
cond
.
end
?
cond
.
end
->
optr
:
TSDB_RELATION_INVALID
;
if
(
optr
==
TSDB_RELATION_LESS
||
optr
==
TSDB_RELATION_LESS_EQUAL
)
{
bool
comp
=
true
;
bool
comp
=
true
;
int32_t
ret
=
0
;
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
if
(
comp
)
{
ret
=
pQueryInfo
->
compare
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
cond
.
end
->
v
);
assert
(
ret
<=
0
);
}
if
(
ret
==
0
&&
optr
==
TSDB_RELATION_LESS
)
{
continue
;
}
else
{
STableKeyInfo
info
=
{.
pTable
=
*
(
void
**
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
STableKeyInfo
info
=
{.
pTable
=
*
(
void
**
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
comp
=
false
;
// no need to compare anymore
}
}
}
else
{
assert
(
pQueryInfo
->
optr
==
TSDB_RELATION_ISNULL
||
pQueryInfo
->
optr
==
TSDB_RELATION_NOTNULL
);
while
(
tSkipListIterNext
(
iter
))
{
SSkipListNode
*
pNode
=
tSkipListIterGet
(
iter
);
bool
isnull
=
isNull
(
SL_GET_NODE_KEY
(
pSkipList
,
pNode
),
pQueryInfo
->
sch
.
type
);
if
((
pQueryInfo
->
optr
==
TSDB_RELATION_ISNULL
&&
isnull
)
||
(
pQueryInfo
->
optr
==
TSDB_RELATION_NOTNULL
&&
(
!
isnull
)))
{
STableKeyInfo
info
=
{.
pTable
=
*
(
void
**
)
SL_GET_NODE_DATA
(
pNode
),
.
lastKey
=
TSKEY_INITIAL_VAL
};
taosArrayPush
(
result
,
&
info
);
}
}
}
}
free
(
cond
.
start
);
free
(
cond
.
start
);
free
(
cond
.
end
);
tSkipListDestroyIter
(
iter
);
}
...
...
@@ -683,6 +700,7 @@ static void tQueryIndexlessColumn(SSkipList* pSkipList, tQueryInfo* pQueryInfo,
char
*
pData
=
SL_GET_NODE_DATA
(
pNode
);
tstr
*
name
=
(
tstr
*
)
tsdbGetTableName
(
*
(
void
**
)
pData
);
// todo speed up by using hash
if
(
pQueryInfo
->
sch
.
colId
==
TSDB_TBNAME_COLUMN_INDEX
)
{
if
(
pQueryInfo
->
optr
==
TSDB_RELATION_IN
)
{
...
...
@@ -714,7 +732,7 @@ void tExprTreeTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, S
// column project
if
(
pLeft
->
nodeType
!=
TSQL_NODE_EXPR
&&
pRight
->
nodeType
!=
TSQL_NODE_EXPR
)
{
assert
(
pLeft
->
nodeType
==
TSQL_NODE_COL
&&
pRight
->
nodeType
==
TSQL_NODE_VALUE
);
assert
(
pLeft
->
nodeType
==
TSQL_NODE_COL
&&
(
pRight
->
nodeType
==
TSQL_NODE_VALUE
||
pRight
->
nodeType
==
TSQL_NODE_DUMMY
)
);
param
->
setupInfoFn
(
pExpr
,
param
->
pExtInfo
);
if
(
pSkipList
==
NULL
)
{
...
...
src/query/src/qExecutor.c
浏览文件 @
1a7786f3
...
...
@@ -200,14 +200,28 @@ bool doFilterData(SQuery *pQuery, int32_t elemPos) {
SSingleColumnFilterInfo
*
pFilterInfo
=
&
pQuery
->
pFilterInfo
[
k
];
char
*
pElem
=
(
char
*
)
pFilterInfo
->
pData
+
pFilterInfo
->
info
.
bytes
*
elemPos
;
if
(
isNull
(
pElem
,
pFilterInfo
->
info
.
type
))
{
return
false
;
}
bool
qualified
=
false
;
for
(
int32_t
j
=
0
;
j
<
pFilterInfo
->
numOfFilters
;
++
j
)
{
SColumnFilterElem
*
pFilterElem
=
&
pFilterInfo
->
pFilters
[
j
];
bool
isnull
=
isNull
(
pElem
,
pFilterInfo
->
info
.
type
);
if
(
isnull
)
{
if
(
pFilterElem
->
fp
==
isNull_filter
)
{
qualified
=
true
;
break
;
}
else
{
continue
;
}
}
else
{
if
(
pFilterElem
->
fp
==
notNull_filter
)
{
qualified
=
true
;
break
;
}
else
if
(
pFilterElem
->
fp
==
isNull_filter
)
{
continue
;
}
}
if
(
pFilterElem
->
fp
(
pFilterElem
,
pElem
,
pElem
))
{
qualified
=
true
;
break
;
...
...
@@ -504,7 +518,7 @@ static STimeWindow getActiveTimeWindow(SWindowResInfo *pWindowResInfo, int64_t t
}
else
{
int32_t
slot
=
curTimeWindowIndex
(
pWindowResInfo
);
SWindowResult
*
pWindowRes
=
getWindowResult
(
pWindowResInfo
,
slot
);
w
=
GET_TIMEWINDOW
(
pWindowResInfo
,
pWindowRes
)
;
w
=
pWindowRes
->
win
;
}
if
(
w
.
skey
>
ts
||
w
.
ekey
<
ts
)
{
...
...
@@ -610,7 +624,7 @@ static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowRes
}
// set time window for current result
pWindowRes
->
skey
=
win
->
skey
;
pWindowRes
->
win
=
(
*
win
)
;
setWindowResOutputBufInitCtx
(
pRuntimeEnv
,
pWindowRes
);
return
TSDB_CODE_SUCCESS
;
...
...
@@ -683,12 +697,12 @@ static int32_t doCheckQueryCompleted(SQueryRuntimeEnv *pRuntimeEnv, TSKEY lastKe
continue
;
}
TSKEY
ekey
=
pResult
->
skey
+
pWindowResInfo
->
interval
;
TSKEY
ekey
=
pResult
->
win
.
ekey
;
if
((
ekey
<=
lastKey
&&
QUERY_IS_ASC_QUERY
(
pQuery
))
||
(
pResult
->
skey
>=
lastKey
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)))
{
(
pResult
->
win
.
skey
>=
lastKey
&&
!
QUERY_IS_ASC_QUERY
(
pQuery
)))
{
closeTimeWindow
(
pWindowResInfo
,
i
);
}
else
{
skey
=
pResult
->
skey
;
skey
=
pResult
->
win
.
skey
;
break
;
}
}
...
...
@@ -701,7 +715,7 @@ static int32_t doCheckQueryCompleted(SQueryRuntimeEnv *pRuntimeEnv, TSKEY lastKe
pWindowResInfo
->
curIndex
=
i
;
}
pWindowResInfo
->
prevSKey
=
pWindowResInfo
->
pResult
[
pWindowResInfo
->
curIndex
].
skey
;
pWindowResInfo
->
prevSKey
=
pWindowResInfo
->
pResult
[
pWindowResInfo
->
curIndex
].
win
.
skey
;
// the number of completed slots are larger than the threshold, return current generated results to client.
if
(
numOfClosed
>
pWindowResInfo
->
threshold
)
{
...
...
@@ -729,9 +743,9 @@ static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlo
int32_t
startPos
,
TSKEY
ekey
,
__block_search_fn_t
searchFn
,
bool
updateLastKey
)
{
assert
(
startPos
>=
0
&&
startPos
<
pDataBlockInfo
->
rows
);
int32_t
num
=
-
1
;
int32_t
num
=
-
1
;
int32_t
order
=
pQuery
->
order
.
order
;
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
order
);
STableQueryInfo
*
item
=
pQuery
->
current
;
...
...
@@ -765,27 +779,24 @@ static int32_t getNumOfRowsInTimeWindow(SQuery *pQuery, SDataBlockInfo *pDataBlo
return
num
;
}
static
void
doBlockwiseApplyFunctions
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
bool
closed
,
STimeWindow
*
pWin
,
int32_t
offset
,
int32_t
forwardStep
,
TSKEY
*
tsBuf
,
int32_t
numOfTotal
)
{
static
void
doBlockwiseApplyFunctions
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
bool
closed
,
STimeWindow
*
pWin
,
int32_t
offset
,
int32_t
forwardStep
,
TSKEY
*
tsCol
,
int32_t
numOfTotal
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQLFunctionCtx
*
pCtx
=
pRuntimeEnv
->
pCtx
;
if
(
IS_MASTER_SCAN
(
pRuntimeEnv
)
||
closed
)
{
for
(
int32_t
k
=
0
;
k
<
pQuery
->
numOfOutput
;
++
k
)
{
int32_t
functionId
=
pQuery
->
pSelectExpr
[
k
].
base
.
functionId
;
pCtx
[
k
].
nStartQueryTimestamp
=
pWin
->
skey
;
pCtx
[
k
].
size
=
forwardStep
;
pCtx
[
k
].
startOffset
=
(
QUERY_IS_ASC_QUERY
(
pQuery
))
?
offset
:
offset
-
(
forwardStep
-
1
);
int32_t
functionId
=
pQuery
->
pSelectExpr
[
k
].
base
.
functionId
;
if
((
aAggs
[
functionId
].
nStatus
&
TSDB_FUNCSTATE_SELECTIVITY
)
!=
0
)
{
pCtx
[
k
].
ptsList
=
&
ts
Buf
[
o
ffset
];
pCtx
[
k
].
ptsList
=
&
ts
Col
[
pCtx
[
k
].
startO
ffset
];
}
// not a whole block involved in query processing, statistics data can not be used
if
(
forwardStep
!=
numOfTotal
)
{
pCtx
[
k
].
preAggVals
.
isSet
=
false
;
}
pCtx
[
k
].
preAggVals
.
isSet
=
(
forwardStep
==
numOfTotal
);
if
(
functionNeedToExecute
(
pRuntimeEnv
,
&
pCtx
[
k
],
functionId
))
{
aAggs
[
functionId
].
xFunction
(
&
pCtx
[
k
]);
...
...
@@ -910,19 +921,11 @@ static char *getDataBlock(SQueryRuntimeEnv *pRuntimeEnv, SArithmeticSupport *sas
char
*
dataBlock
=
NULL
;
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
SQLFunctionCtx
*
pCtx
=
pRuntimeEnv
->
pCtx
;
int32_t
functionId
=
pQuery
->
pSelectExpr
[
col
].
base
.
functionId
;
if
(
functionId
==
TSDB_FUNC_ARITHM
)
{
sas
->
pArithExpr
=
&
pQuery
->
pSelectExpr
[
col
];
// set the start offset to be the lowest start position, no matter asc/desc query order
if
(
QUERY_IS_ASC_QUERY
(
pQuery
))
{
pCtx
->
startOffset
=
pQuery
->
pos
;
}
else
{
pCtx
->
startOffset
=
pQuery
->
pos
-
(
size
-
1
);
}
sas
->
offset
=
0
;
sas
->
colList
=
pQuery
->
colList
;
sas
->
numOfCols
=
pQuery
->
numOfCols
;
...
...
@@ -1002,7 +1005,7 @@ static void blockwiseApplyFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStatis *
}
int32_t
step
=
GET_FORWARD_DIRECTION_FACTOR
(
pQuery
->
order
.
order
);
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
/* && tsCols != NULL*/
)
{
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
))
{
TSKEY
ts
=
TSKEY_INITIAL_VAL
;
if
(
tsCols
==
NULL
)
{
...
...
@@ -1094,8 +1097,25 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
SDiskbasedResultBuf
*
pResultBuf
=
pRuntimeEnv
->
pResultBuf
;
int64_t
v
=
-
1
;
// not assign result buffer yet, add new result buffer
char
*
d
=
pData
;
int16_t
len
=
bytes
;
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
d
=
varDataVal
(
pData
);
len
=
varDataLen
(
pData
);
}
else
if
(
type
==
TSDB_DATA_TYPE_FLOAT
||
type
==
TSDB_DATA_TYPE_DOUBLE
)
{
SQInfo
*
pQInfo
=
GET_QINFO_ADDR
(
pRuntimeEnv
);
qError
(
"QInfo:%p group by not supported on double/float/binary/nchar columns, abort"
,
pQInfo
);
longjmp
(
pRuntimeEnv
->
env
,
TSDB_CODE_QRY_APP_ERROR
);
}
SWindowResult
*
pWindowRes
=
doSetTimeWindowFromKey
(
pRuntimeEnv
,
&
pRuntimeEnv
->
windowResInfo
,
d
,
len
,
true
);
if
(
pWindowRes
==
NULL
)
{
return
-
1
;
}
int64_t
v
=
-
1
;
switch
(
type
)
{
case
TSDB_DATA_TYPE_BOOL
:
case
TSDB_DATA_TYPE_TINYINT
:
v
=
GET_INT8_VAL
(
pData
);
break
;
...
...
@@ -1104,12 +1124,14 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
case
TSDB_DATA_TYPE_BIGINT
:
v
=
GET_INT64_VAL
(
pData
);
break
;
}
SWindowResult
*
pWindowRes
=
doSetTimeWindowFromKey
(
pRuntimeEnv
,
&
pRuntimeEnv
->
windowResInfo
,
pData
,
bytes
,
true
);
if
(
pWindowRes
==
NULL
)
{
return
-
1
;
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
pWindowRes
->
key
=
malloc
(
varDataTLen
(
pData
));
varDataCopy
(
pWindowRes
->
key
,
pData
);
}
else
{
pWindowRes
->
win
.
skey
=
v
;
pWindowRes
->
win
.
ekey
=
v
;
}
pWindowRes
->
skey
=
v
;
assert
(
pRuntimeEnv
->
windowResInfo
.
interval
==
0
);
if
(
pWindowRes
->
pos
.
pageId
==
-
1
)
{
...
...
@@ -1180,7 +1202,7 @@ static int32_t doTSJoinFilter(SQueryRuntimeEnv *pRuntimeEnv, int32_t offset) {
#if defined(_DEBUG_VIEW)
printf
(
"elem in comp ts file:%"
PRId64
", key:%"
PRId64
", tag:%"
PRIu64
", query order:%d, ts order:%d, traverse:%d, index:%d
\n
"
,
elem
.
ts
,
key
,
elem
.
tag
,
pQuery
->
order
.
order
,
pRuntimeEnv
->
pTSBuf
->
tsOrder
,
elem
.
ts
,
key
,
elem
.
tag
.
i64Key
,
pQuery
->
order
.
order
,
pRuntimeEnv
->
pTSBuf
->
tsOrder
,
pRuntimeEnv
->
pTSBuf
->
cur
.
order
,
pRuntimeEnv
->
pTSBuf
->
cur
.
tsIndex
);
#endif
...
...
@@ -1461,12 +1483,15 @@ void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData, TSKEY
pCtx
->
preAggVals
.
dataBlockLoaded
=
(
inputData
!=
NULL
);
// limit/offset query will affect this value
pCtx
->
startOffset
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
pQuery
->
pos
:
0
;
pCtx
->
size
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
pBlockInfo
->
rows
-
pQuery
->
pos
:
pQuery
->
pos
+
1
;
// minimum value no matter ascending/descending order query
pCtx
->
startOffset
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
pQuery
->
pos
:
(
pQuery
->
pos
-
pCtx
->
size
+
1
);
assert
(
pCtx
->
startOffset
>=
0
);
uint32_t
status
=
aAggs
[
functionId
].
nStatus
;
if
(((
status
&
(
TSDB_FUNCSTATE_SELECTIVITY
|
TSDB_FUNCSTATE_NEED_TS
))
!=
0
)
&&
(
tsCol
!=
NULL
))
{
pCtx
->
ptsList
=
tsCol
;
pCtx
->
ptsList
=
&
tsCol
[
pCtx
->
startOffset
]
;
}
if
(
functionId
>=
TSDB_FUNC_FIRST_DST
&&
functionId
<=
TSDB_FUNC_LAST_DST
)
{
...
...
@@ -2185,43 +2210,43 @@ static bool overlapWithTimeWindow(SQuery* pQuery, SDataBlockInfo* pBlockInfo) {
return
false
;
}
int32_t
loadDataBlockOnDemand
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
void
*
pQueryHandle
,
SDataBlockInfo
*
pBlockInfo
,
SDataStatis
**
pStatis
,
SArray
**
pDataBlock
)
{
int32_t
loadDataBlockOnDemand
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
void
*
pQueryHandle
,
SDataBlockInfo
*
pBlockInfo
,
SDataStatis
**
pStatis
,
SArray
**
pDataBlock
,
uint32_t
*
status
)
{
SQuery
*
pQuery
=
pRuntimeEnv
->
pQuery
;
uint32_t
status
=
0
;
*
status
=
0
;
if
(
pQuery
->
numOfFilterCols
>
0
||
pRuntimeEnv
->
pTSBuf
>
0
)
{
status
=
BLK_DATA_ALL_NEEDED
;
*
status
=
BLK_DATA_ALL_NEEDED
;
}
else
{
// check if this data block is required to load
// Calculate all time windows that are overlapping or contain current data block.
// If current data block is contained by all possible time window, do not load current data block.
if
(
QUERY_IS_INTERVAL_QUERY
(
pQuery
)
&&
overlapWithTimeWindow
(
pQuery
,
pBlockInfo
))
{
status
=
BLK_DATA_ALL_NEEDED
;
*
status
=
BLK_DATA_ALL_NEEDED
;
}
if
(
status
!=
BLK_DATA_ALL_NEEDED
)
{
if
(
(
*
status
)
!=
BLK_DATA_ALL_NEEDED
)
{
for
(
int32_t
i
=
0
;
i
<
pQuery
->
numOfOutput
;
++
i
)
{
SSqlFuncMsg
*
pSqlFunc
=
&
pQuery
->
pSelectExpr
[
i
].
base
;
int32_t
functionId
=
pSqlFunc
->
functionId
;
int32_t
colId
=
pSqlFunc
->
colInfo
.
colId
;
status
|=
aAggs
[
functionId
].
dataReqFunc
(
&
pRuntimeEnv
->
pCtx
[
i
],
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
ekey
,
colId
);
if
((
status
&
BLK_DATA_ALL_NEEDED
)
==
BLK_DATA_ALL_NEEDED
)
{
(
*
status
)
|=
aAggs
[
functionId
].
dataReqFunc
(
&
pRuntimeEnv
->
pCtx
[
i
],
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
ekey
,
colId
);
if
((
(
*
status
)
&
BLK_DATA_ALL_NEEDED
)
==
BLK_DATA_ALL_NEEDED
)
{
break
;
}
}
}
}
if
(
status
==
BLK_DATA_NO_NEEDED
)
{
if
(
(
*
status
)
==
BLK_DATA_NO_NEEDED
)
{
qDebug
(
"QInfo:%p data block discard, brange:%"
PRId64
"-%"
PRId64
", rows:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
ekey
,
pBlockInfo
->
rows
);
pRuntimeEnv
->
summary
.
discardBlocks
+=
1
;
}
else
if
(
status
==
BLK_DATA_STATIS_NEEDED
)
{
if
(
tsdbRetrieveDataBlockStatisInfo
(
pQueryHandle
,
pStatis
)
!=
TSDB_CODE_SUCCESS
)
{
// return DISK_DATA_LOAD_FAILED;
}
}
else
if
(
(
*
status
)
==
BLK_DATA_STATIS_NEEDED
)
{
// this function never returns error?
tsdbRetrieveDataBlockStatisInfo
(
pQueryHandle
,
pStatis
);
pRuntimeEnv
->
summary
.
loadBlockStatis
+=
1
;
...
...
@@ -2230,24 +2255,26 @@ int32_t loadDataBlockOnDemand(SQueryRuntimeEnv *pRuntimeEnv, void* pQueryHandle,
pRuntimeEnv
->
summary
.
totalCheckedRows
+=
pBlockInfo
->
rows
;
}
}
else
{
assert
(
status
==
BLK_DATA_ALL_NEEDED
);
assert
(
(
*
status
)
==
BLK_DATA_ALL_NEEDED
);
// load the data block statistics to perform further filter
pRuntimeEnv
->
summary
.
loadBlockStatis
+=
1
;
if
(
tsdbRetrieveDataBlockStatisInfo
(
pQueryHandle
,
pStatis
)
!=
TSDB_CODE_SUCCESS
)
{
}
tsdbRetrieveDataBlockStatisInfo
(
pQueryHandle
,
pStatis
);
if
(
!
needToLoadDataBlock
(
pRuntimeEnv
,
*
pStatis
,
pRuntimeEnv
->
pCtx
,
pBlockInfo
->
rows
))
{
// current block has been discard due to filter applied
pRuntimeEnv
->
summary
.
discardBlocks
+=
1
;
qDebug
(
"QInfo:%p data block discard, brange:%"
PRId64
"-%"
PRId64
", rows:%d"
,
GET_QINFO_ADDR
(
pRuntimeEnv
),
pBlockInfo
->
window
.
skey
,
pBlockInfo
->
window
.
ekey
,
pBlockInfo
->
rows
);
return
BLK_DATA_DISCARD
;
(
*
status
)
=
BLK_DATA_DISCARD
;
}
pRuntimeEnv
->
summary
.
totalCheckedRows
+=
pBlockInfo
->
rows
;
pRuntimeEnv
->
summary
.
loadBlocks
+=
1
;
*
pDataBlock
=
tsdbRetrieveDataBlock
(
pQueryHandle
,
NULL
);
if
(
*
pDataBlock
==
NULL
)
{
return
terrno
;
}
}
return
TSDB_CODE_SUCCESS
;
...
...
@@ -2431,17 +2458,20 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) {
ensureOutputBuffer
(
pRuntimeEnv
,
&
blockInfo
);
SDataStatis
*
pStatis
=
NULL
;
SArray
*
pDataBlock
=
NULL
;
if
(
loadDataBlockOnDemand
(
pRuntimeEnv
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
)
==
BLK_DATA_DISCARD
)
{
pQuery
->
current
->
lastKey
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
blockInfo
.
window
.
ekey
+
step
:
blockInfo
.
window
.
skey
+
step
;
continue
;
}
SArray
*
pDataBlock
=
NULL
;
uint32_t
status
=
0
;
i
f
(
terrno
!=
TSDB_CODE_SUCCESS
)
{
// load data block failed, abort query
longjmp
(
pRuntimeEnv
->
env
,
terrno
);
i
nt32_t
ret
=
loadDataBlockOnDemand
(
pRuntimeEnv
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
,
&
status
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
break
;
}
if
(
status
==
BLK_DATA_DISCARD
)
{
pQuery
->
current
->
lastKey
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
blockInfo
.
window
.
ekey
+
step
:
blockInfo
.
window
.
skey
+
step
;
continue
;
}
// query start position can not move into tableApplyFunctionsOnBlock due to limit/offset condition
pQuery
->
pos
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
0
:
blockInfo
.
rows
-
1
;
int32_t
numOfRes
=
tableApplyFunctionsOnBlock
(
pRuntimeEnv
,
&
blockInfo
,
pStatis
,
binarySearchForKey
,
pDataBlock
);
...
...
@@ -2806,6 +2836,7 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
// all results have been return to client, try next group
if
(
pGroupResInfo
->
pos
.
pageId
==
pGroupResInfo
->
numOfDataPages
)
{
pGroupResInfo
->
numOfDataPages
=
0
;
pGroupResInfo
->
pos
.
pageId
=
0
;
pGroupResInfo
->
pos
.
rowId
=
0
;
// current results of group has been sent to client, try next group
...
...
@@ -2993,7 +3024,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
char
*
b
=
getPosInResultPage
(
pRuntimeEnv
,
PRIMARYKEY_TIMESTAMP_COL_INDEX
,
pWindowRes
,
page
);
TSKEY
ts
=
GET_INT64_VAL
(
b
);
assert
(
ts
==
pWindowRes
->
skey
);
assert
(
ts
==
pWindowRes
->
win
.
skey
);
int64_t
num
=
getNumOfResultWindowRes
(
pQuery
,
pWindowRes
);
if
(
num
<=
0
)
{
cs
.
position
[
pos
]
+=
1
;
...
...
@@ -4617,9 +4648,17 @@ static int64_t scanMultiTableDataBlocks(SQInfo *pQInfo) {
}
SDataStatis
*
pStatis
=
NULL
;
SArray
*
pDataBlock
=
NULL
;
if
(
loadDataBlockOnDemand
(
pRuntimeEnv
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
)
==
BLK_DATA_DISCARD
)
{
pQuery
->
current
->
lastKey
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
blockInfo
.
window
.
ekey
+
step
:
blockInfo
.
window
.
skey
+
step
;
SArray
*
pDataBlock
=
NULL
;
uint32_t
status
=
0
;
int32_t
ret
=
loadDataBlockOnDemand
(
pRuntimeEnv
,
pQueryHandle
,
&
blockInfo
,
&
pStatis
,
&
pDataBlock
,
&
status
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
break
;
}
if
(
status
==
BLK_DATA_DISCARD
)
{
pQuery
->
current
->
lastKey
=
QUERY_IS_ASC_QUERY
(
pQuery
)
?
blockInfo
.
window
.
ekey
+
step
:
blockInfo
.
window
.
skey
+
step
;
continue
;
}
...
...
src/query/src/qExtbuffer.c
浏览文件 @
1a7786f3
...
...
@@ -502,22 +502,22 @@ FORCE_INLINE int32_t compare_sd(tOrderDescriptor *pDescriptor, int32_t numOfRows
return
compare_d
(
pDescriptor
,
numOfRows
,
idx1
,
data
,
numOfRows
,
idx2
,
data
);
}
static
void
swap
(
SColumnModel
*
pColumnModel
,
int32_t
count
,
int32_t
s1
,
char
*
data1
,
int32_t
s2
)
{
static
void
swap
(
SColumnModel
*
pColumnModel
,
int32_t
count
,
int32_t
s1
,
char
*
data1
,
int32_t
s2
,
void
*
buf
)
{
for
(
int32_t
i
=
0
;
i
<
pColumnModel
->
numOfCols
;
++
i
)
{
void
*
first
=
COLMODEL_GET_VAL
(
data1
,
pColumnModel
,
count
,
s1
,
i
);
void
*
second
=
COLMODEL_GET_VAL
(
data1
,
pColumnModel
,
count
,
s2
,
i
);
SSchema
*
pSchema
=
&
pColumnModel
->
pFields
[
i
].
field
;
tsDataSwap
(
first
,
second
,
pSchema
->
type
,
pSchema
->
bytes
);
tsDataSwap
(
first
,
second
,
pSchema
->
type
,
pSchema
->
bytes
,
buf
);
}
}
static
void
tColDataInsertSort
(
tOrderDescriptor
*
pDescriptor
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
,
char
*
data
,
__col_compar_fn_t
compareFn
)
{
__col_compar_fn_t
compareFn
,
void
*
buf
)
{
for
(
int32_t
i
=
start
+
1
;
i
<=
end
;
++
i
)
{
for
(
int32_t
j
=
i
;
j
>
start
;
--
j
)
{
if
(
compareFn
(
pDescriptor
,
numOfRows
,
j
,
j
-
1
,
data
)
==
-
1
)
{
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
j
-
1
,
data
,
j
);
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
j
-
1
,
data
,
j
,
buf
);
}
else
{
break
;
}
...
...
@@ -553,7 +553,7 @@ static void UNUSED_FUNC tSortDataPrint(int32_t type, char *prefix, char *startx,
}
static
void
median
(
tOrderDescriptor
*
pDescriptor
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
,
char
*
data
,
__col_compar_fn_t
compareFn
)
{
__col_compar_fn_t
compareFn
,
void
*
buf
)
{
int32_t
midIdx
=
((
end
-
start
)
>>
1
)
+
start
;
#if defined(_DEBUG_VIEW)
...
...
@@ -567,15 +567,16 @@ static void median(tOrderDescriptor *pDescriptor, int32_t numOfRows, int32_t sta
tSortDataPrint
(
pDescriptor
->
pColumnModel
->
pFields
[
colIdx
].
field
.
type
,
"before"
,
startx
,
midx
,
endx
);
#endif
SColumnModel
*
pModel
=
pDescriptor
->
pColumnModel
;
if
(
compareFn
(
pDescriptor
,
numOfRows
,
midIdx
,
start
,
data
)
==
1
)
{
swap
(
p
Descriptor
->
pColumnModel
,
numOfRows
,
start
,
data
,
midIdx
);
swap
(
p
Model
,
numOfRows
,
start
,
data
,
midIdx
,
buf
);
}
if
(
compareFn
(
pDescriptor
,
numOfRows
,
midIdx
,
end
,
data
)
==
1
)
{
swap
(
p
Descriptor
->
pColumnModel
,
numOfRows
,
midIdx
,
data
,
start
);
swap
(
p
Descriptor
->
pColumnModel
,
numOfRows
,
midIdx
,
data
,
end
);
swap
(
p
Model
,
numOfRows
,
midIdx
,
data
,
start
,
buf
);
swap
(
p
Model
,
numOfRows
,
midIdx
,
data
,
end
,
buf
);
}
else
if
(
compareFn
(
pDescriptor
,
numOfRows
,
start
,
end
,
data
)
==
1
)
{
swap
(
p
Descriptor
->
pColumnModel
,
numOfRows
,
start
,
data
,
end
);
swap
(
p
Model
,
numOfRows
,
start
,
data
,
end
,
buf
);
}
assert
(
compareFn
(
pDescriptor
,
numOfRows
,
midIdx
,
start
,
data
)
<=
0
&&
...
...
@@ -626,32 +627,20 @@ static UNUSED_FUNC void tRowModelDisplay(tOrderDescriptor *pDescriptor, int32_t
printf
(
"
\n
"
);
}
static
int32_t
qsort_call
=
0
;
void
tColDataQSort
(
tOrderDescriptor
*
pDescriptor
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
,
char
*
data
,
int32_t
orderType
)
{
// short array sort, incur another sort procedure instead of quick sort process
__col_compar_fn_t
compareFn
=
(
orderType
==
TSDB_ORDER_ASC
)
?
compare_sa
:
compare_sd
;
if
(
end
-
start
+
1
<=
8
)
{
tColDataInsertSort
(
pDescriptor
,
numOfRows
,
start
,
end
,
data
,
compareFn
);
return
;
}
static
void
columnwiseQSortImpl
(
tOrderDescriptor
*
pDescriptor
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
,
char
*
data
,
int32_t
orderType
,
__col_compar_fn_t
compareFn
,
void
*
buf
)
{
#ifdef _DEBUG_VIEW
//
printf("before sort:\n");
//
tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
printf
(
"before sort:
\n
"
);
tRowModelDisplay
(
pDescriptor
,
numOfRows
,
data
,
end
-
start
+
1
);
#endif
int32_t
s
=
start
,
e
=
end
;
median
(
pDescriptor
,
numOfRows
,
start
,
end
,
data
,
compareFn
);
median
(
pDescriptor
,
numOfRows
,
start
,
end
,
data
,
compareFn
,
buf
);
#ifdef _DEBUG_VIEW
// printf("%s called: %d\n", __FUNCTION__, qsort_call++);
// printf("%s called: %d\n", __FUNCTION__, qsort_call++);
#endif
UNUSED
(
qsort_call
);
int32_t
end_same
=
end
;
int32_t
start_same
=
start
;
...
...
@@ -663,17 +652,17 @@ void tColDataQSort(tOrderDescriptor *pDescriptor, int32_t numOfRows, int32_t sta
}
if
(
ret
==
0
&&
e
!=
end_same
)
{
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
e
,
data
,
end_same
--
);
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
e
,
data
,
end_same
--
,
buf
);
}
e
--
;
}
if
(
e
!=
s
)
{
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
s
,
data
,
e
);
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
s
,
data
,
e
,
buf
);
}
#ifdef _DEBUG_VIEW
// tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
// tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
#endif
while
(
s
<
e
)
{
...
...
@@ -683,16 +672,16 @@ void tColDataQSort(tOrderDescriptor *pDescriptor, int32_t numOfRows, int32_t sta
}
if
(
ret
==
0
&&
s
!=
start_same
)
{
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
s
,
data
,
start_same
++
);
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
s
,
data
,
start_same
++
,
buf
);
}
s
++
;
}
if
(
s
!=
e
)
{
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
s
,
data
,
e
);
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
s
,
data
,
e
,
buf
);
}
#ifdef _DEBUG_VIEW
// tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
// tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
#endif
}
...
...
@@ -702,14 +691,14 @@ void tColDataQSort(tOrderDescriptor *pDescriptor, int32_t numOfRows, int32_t sta
int32_t
right
=
end
;
while
(
right
>
end_same
&&
left
<=
end_same
)
{
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
left
++
,
data
,
right
--
);
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
left
++
,
data
,
right
--
,
buf
);
}
// (pivotal+1) + steps of number that are identical pivotal
rightx
+=
(
end
-
end_same
);
#ifdef _DEBUG_VIEW
// tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
// tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
#endif
}
...
...
@@ -719,26 +708,52 @@ void tColDataQSort(tOrderDescriptor *pDescriptor, int32_t numOfRows, int32_t sta
int32_t
right
=
e
-
1
;
while
(
left
<
start_same
&&
right
>=
start_same
)
{
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
left
++
,
data
,
right
--
);
swap
(
pDescriptor
->
pColumnModel
,
numOfRows
,
left
++
,
data
,
right
--
,
buf
);
}
// (pivotal-1) - steps of number that are identical pivotal
leftx
-=
(
start_same
-
start
);
#ifdef _DEBUG_VIEW
// tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
// tRowModelDisplay(pDescriptor, numOfRows, data, end - start + 1);
#endif
}
if
(
leftx
>
start
)
{
tColDataQSort
(
pDescriptor
,
numOfRows
,
start
,
leftx
,
data
,
orderType
);
columnwiseQSortImpl
(
pDescriptor
,
numOfRows
,
start
,
leftx
,
data
,
orderType
,
compareFn
,
buf
);
}
if
(
rightx
<
end
)
{
tColDataQSort
(
pDescriptor
,
numOfRows
,
rightx
,
end
,
data
,
orderType
);
columnwiseQSortImpl
(
pDescriptor
,
numOfRows
,
rightx
,
end
,
data
,
orderType
,
compareFn
,
buf
);
}
}
void
tColDataQSort
(
tOrderDescriptor
*
pDescriptor
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
,
char
*
data
,
int32_t
order
)
{
// short array sort, incur another sort procedure instead of quick sort process
__col_compar_fn_t
compareFn
=
(
order
==
TSDB_ORDER_ASC
)
?
compare_sa
:
compare_sd
;
SColumnModel
*
pModel
=
pDescriptor
->
pColumnModel
;
size_t
width
=
0
;
for
(
int32_t
i
=
0
;
i
<
pModel
->
numOfCols
;
++
i
)
{
SSchema
*
pSchema
=
&
pModel
->
pFields
[
i
].
field
;
if
(
width
<
pSchema
->
bytes
)
{
width
=
pSchema
->
bytes
;
}
}
char
*
buf
=
malloc
(
width
);
assert
(
width
>
0
&&
buf
!=
NULL
);
if
(
end
-
start
+
1
<=
8
)
{
tColDataInsertSort
(
pDescriptor
,
numOfRows
,
start
,
end
,
data
,
compareFn
,
buf
);
}
else
{
columnwiseQSortImpl
(
pDescriptor
,
numOfRows
,
start
,
end
,
data
,
order
,
compareFn
,
buf
);
}
free
(
buf
);
}
/*
* deep copy of sschema
*/
...
...
src/query/src/qFilterfunc.c
浏览文件 @
1a7786f3
...
...
@@ -284,6 +284,14 @@ bool nequal_nchar(SColumnFilterElem *pFilter, char* minval, char *maxval) {
return
wcsncmp
((
wchar_t
*
)
pFilter
->
filterInfo
.
pz
,
varDataVal
(
minval
),
varDataLen
(
minval
)
/
TSDB_NCHAR_SIZE
)
!=
0
;
}
////////////////////////////////////////////////////////////////
bool
isNull_filter
(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
{
return
true
;
}
bool
notNull_filter
(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
{
return
true
;
}
////////////////////////////////////////////////////////////////
...
...
@@ -398,6 +406,8 @@ bool (*filterFunc_i8[])(SColumnFilterElem *pFilter, char *minval, char *maxval)
largeEqual_i8
,
nequal_i8
,
NULL
,
isNull_filter
,
notNull_filter
,
};
bool
(
*
filterFunc_i16
[])(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
=
{
...
...
@@ -409,6 +419,8 @@ bool (*filterFunc_i16[])(SColumnFilterElem *pFilter, char *minval, char *maxval)
largeEqual_i16
,
nequal_i16
,
NULL
,
isNull_filter
,
notNull_filter
,
};
bool
(
*
filterFunc_i32
[])(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
=
{
...
...
@@ -420,6 +432,8 @@ bool (*filterFunc_i32[])(SColumnFilterElem *pFilter, char *minval, char *maxval)
largeEqual_i32
,
nequal_i32
,
NULL
,
isNull_filter
,
notNull_filter
,
};
bool
(
*
filterFunc_i64
[])(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
=
{
...
...
@@ -431,6 +445,8 @@ bool (*filterFunc_i64[])(SColumnFilterElem *pFilter, char *minval, char *maxval)
largeEqual_i64
,
nequal_i64
,
NULL
,
isNull_filter
,
notNull_filter
,
};
bool
(
*
filterFunc_ds
[])(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
=
{
...
...
@@ -442,6 +458,8 @@ bool (*filterFunc_ds[])(SColumnFilterElem *pFilter, char *minval, char *maxval)
largeEqual_ds
,
nequal_ds
,
NULL
,
isNull_filter
,
notNull_filter
,
};
bool
(
*
filterFunc_dd
[])(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
=
{
...
...
@@ -453,6 +471,8 @@ bool (*filterFunc_dd[])(SColumnFilterElem *pFilter, char *minval, char *maxval)
largeEqual_dd
,
nequal_dd
,
NULL
,
isNull_filter
,
notNull_filter
,
};
bool
(
*
filterFunc_str
[])(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
=
{
...
...
@@ -464,6 +484,8 @@ bool (*filterFunc_str[])(SColumnFilterElem* pFilter, char* minval, char *maxval)
NULL
,
nequal_str
,
like_str
,
isNull_filter
,
notNull_filter
,
};
bool
(
*
filterFunc_nchar
[])(
SColumnFilterElem
*
pFitler
,
char
*
minval
,
char
*
maxval
)
=
{
...
...
@@ -475,6 +497,8 @@ bool (*filterFunc_nchar[])(SColumnFilterElem* pFitler, char* minval, char* maxva
NULL
,
nequal_nchar
,
like_nchar
,
isNull_filter
,
notNull_filter
,
};
bool
(
*
rangeFilterFunc_i8
[])(
SColumnFilterElem
*
pFilter
,
char
*
minval
,
char
*
maxval
)
=
{
...
...
src/query/src/qParserImpl.c
浏览文件 @
1a7786f3
...
...
@@ -179,7 +179,7 @@ tSQLExpr *tSQLExprCreateFunction(tSQLExprList *pList, SStrToken *pFuncToken, SSt
tSQLExpr
*
tSQLExprCreate
(
tSQLExpr
*
pLeft
,
tSQLExpr
*
pRight
,
int32_t
optrType
)
{
tSQLExpr
*
pExpr
=
calloc
(
1
,
sizeof
(
tSQLExpr
));
if
(
p
Right
!=
NULL
&&
pLeft
!=
NULL
)
{
if
(
p
Left
!=
NULL
&&
pRight
!=
NULL
&&
(
optrType
!=
TK_IN
)
)
{
char
*
endPos
=
pRight
->
token
.
z
+
pRight
->
token
.
n
;
pExpr
->
token
.
z
=
pLeft
->
token
.
z
;
pExpr
->
token
.
n
=
(
uint32_t
)(
endPos
-
pExpr
->
token
.
z
);
...
...
@@ -275,6 +275,11 @@ tSQLExpr *tSQLExprCreate(tSQLExpr *pLeft, tSQLExpr *pRight, int32_t optrType) {
}
else
{
pExpr
->
nSQLOptr
=
optrType
;
pExpr
->
pLeft
=
pLeft
;
if
(
pRight
==
NULL
)
{
pRight
=
calloc
(
1
,
sizeof
(
tSQLExpr
));
}
pExpr
->
pRight
=
pRight
;
}
...
...
src/query/src/qPercentile.c
浏览文件 @
1a7786f3
...
...
@@ -70,6 +70,33 @@ static void resetBoundingBox(MinMaxEntry* range, int32_t type) {
}
}
static
int32_t
setBoundingBox
(
MinMaxEntry
*
range
,
int16_t
type
,
double
minval
,
double
maxval
)
{
if
(
minval
>
maxval
)
{
return
-
1
;
}
switch
(
type
)
{
case
TSDB_DATA_TYPE_TINYINT
:
case
TSDB_DATA_TYPE_SMALLINT
:
case
TSDB_DATA_TYPE_INT
:
range
->
iMinVal
=
(
int32_t
)
minval
;
range
->
iMaxVal
=
(
int32_t
)
maxval
;
break
;
case
TSDB_DATA_TYPE_BIGINT
:
range
->
i64MinVal
=
(
int64_t
)
minval
;
range
->
i64MaxVal
=
(
int64_t
)
maxval
;
break
;
case
TSDB_DATA_TYPE_FLOAT
:
case
TSDB_DATA_TYPE_DOUBLE
:
range
->
dMinVal
=
minval
;
range
->
dMaxVal
=
maxval
;
break
;
}
return
0
;
}
static
void
resetPosInfo
(
SSlotInfo
*
pInfo
)
{
pInfo
->
size
=
0
;
pInfo
->
pageId
=
-
1
;
...
...
@@ -135,6 +162,11 @@ int32_t tBucketBigIntHash(tMemBucket *pBucket, const void *value) {
return
index
;
}
else
{
// out of range
if
(
v
<
pBucket
->
range
.
i64MinVal
||
v
>
pBucket
->
range
.
i64MaxVal
)
{
return
-
1
;
}
// todo hash for bigint and float and double
int64_t
span
=
pBucket
->
range
.
i64MaxVal
-
pBucket
->
range
.
i64MinVal
;
if
(
span
<
pBucket
->
numOfSlots
)
{
...
...
@@ -179,6 +211,11 @@ int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) {
return
index
;
}
else
{
// out of range
if
(
v
<
pBucket
->
range
.
iMinVal
||
v
>
pBucket
->
range
.
iMaxVal
)
{
return
-
1
;
}
// divide a range of [iMinVal, iMaxVal] into 1024 buckets
int32_t
span
=
pBucket
->
range
.
iMaxVal
-
pBucket
->
range
.
iMinVal
;
if
(
span
<
pBucket
->
numOfSlots
)
{
...
...
@@ -209,6 +246,12 @@ int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) {
double
posx
=
(
v
+
DBL_MAX
)
/
x
;
return
((
int32_t
)
posx
)
%
pBucket
->
numOfSlots
;
}
else
{
// out of range
if
(
v
<
pBucket
->
range
.
dMinVal
||
v
>
pBucket
->
range
.
dMaxVal
)
{
return
-
1
;
}
// divide a range of [dMinVal, dMaxVal] into 1024 buckets
double
span
=
pBucket
->
range
.
dMaxVal
-
pBucket
->
range
.
dMinVal
;
if
(
span
<
pBucket
->
numOfSlots
)
{
...
...
@@ -262,7 +305,7 @@ static void resetSlotInfo(tMemBucket* pBucket) {
}
}
tMemBucket
*
tMemBucketCreate
(
int16_t
nElemSize
,
int16_t
dataType
)
{
tMemBucket
*
tMemBucketCreate
(
int16_t
nElemSize
,
int16_t
dataType
,
double
minval
,
double
maxval
)
{
tMemBucket
*
pBucket
=
(
tMemBucket
*
)
calloc
(
1
,
sizeof
(
tMemBucket
));
if
(
pBucket
==
NULL
)
{
return
NULL
;
...
...
@@ -278,9 +321,14 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType) {
pBucket
->
maxCapacity
=
200000
;
if
(
setBoundingBox
(
&
pBucket
->
range
,
pBucket
->
type
,
minval
,
maxval
)
!=
0
)
{
uError
(
"MemBucket:%p, invalid value range: %f-%f"
,
pBucket
,
minval
,
maxval
);
free
(
pBucket
);
return
NULL
;
}
pBucket
->
elemPerPage
=
(
pBucket
->
bufPageSize
-
sizeof
(
tFilePage
))
/
pBucket
->
bytes
;
pBucket
->
comparFn
=
getKeyComparFunc
(
pBucket
->
type
);
resetBoundingBox
(
&
pBucket
->
range
,
pBucket
->
type
);
pBucket
->
hashFunc
=
getHashFunc
(
pBucket
->
type
);
if
(
pBucket
->
hashFunc
==
NULL
)
{
...
...
@@ -395,23 +443,25 @@ void tMemBucketUpdateBoundingBox(MinMaxEntry *r, char *data, int32_t dataType) {
/*
* in memory bucket, we only accept data array list
*/
void
tMemBucketPut
(
tMemBucket
*
pBucket
,
const
void
*
data
,
size_t
size
)
{
int32_t
tMemBucketPut
(
tMemBucket
*
pBucket
,
const
void
*
data
,
size_t
size
)
{
assert
(
pBucket
!=
NULL
&&
data
!=
NULL
&&
size
>
0
);
pBucket
->
total
+=
(
int32_t
)
size
;
int32_t
bytes
=
pBucket
->
bytes
;
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
char
*
d
=
(
char
*
)
data
+
i
*
bytes
;
int32_t
slotIdx
=
(
pBucket
->
hashFunc
)(
pBucket
,
d
);
assert
(
slotIdx
>=
0
);
int32_t
index
=
(
pBucket
->
hashFunc
)(
pBucket
,
d
);
if
(
index
==
-
1
)
{
// the value is out of range, do not add it into bucket
return
-
1
;
}
tMemBucketSlot
*
pSlot
=
&
pBucket
->
pSlots
[
slotId
x
];
tMemBucketSlot
*
pSlot
=
&
pBucket
->
pSlots
[
inde
x
];
tMemBucketUpdateBoundingBox
(
&
pSlot
->
range
,
d
,
pBucket
->
type
);
// ensure available memory pages to allocate
int32_t
groupId
=
getGroupId
(
pBucket
->
numOfSlots
,
slotId
x
,
pBucket
->
times
);
int32_t
groupId
=
getGroupId
(
pBucket
->
numOfSlots
,
inde
x
,
pBucket
->
times
);
int32_t
pageId
=
-
1
;
if
(
pSlot
->
info
.
data
==
NULL
||
pSlot
->
info
.
data
->
num
>=
pBucket
->
elemPerPage
)
{
...
...
@@ -432,10 +482,12 @@ void tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) {
pSlot
->
info
.
data
->
num
+=
1
;
pSlot
->
info
.
size
+=
1
;
}
return
0
;
}
////////////////////////////////////////////////////////////////////////////////////////////
static
void
findMaxMinValue
(
tMemBucket
*
pMemBucket
,
double
*
maxVal
,
double
*
minVal
)
{
static
UNUSED_FUNC
void
findMaxMinValue
(
tMemBucket
*
pMemBucket
,
double
*
maxVal
,
double
*
minVal
)
{
*
minVal
=
DBL_MAX
;
*
maxVal
=
-
DBL_MAX
;
...
...
@@ -681,16 +733,29 @@ double getPercentile(tMemBucket *pMemBucket, double percent) {
// find the min/max value, no need to scan all data in bucket
if
(
fabs
(
percent
-
100
.
0
)
<
DBL_EPSILON
||
(
percent
<
DBL_EPSILON
))
{
double
minx
=
0
,
maxx
=
0
;
findMaxMinValue
(
pMemBucket
,
&
maxx
,
&
minx
);
MinMaxEntry
*
pRange
=
&
pMemBucket
->
range
;
return
fabs
(
percent
-
100
)
<
DBL_EPSILON
?
maxx
:
minx
;
switch
(
pMemBucket
->
type
)
{
case
TSDB_DATA_TYPE_TINYINT
:
case
TSDB_DATA_TYPE_SMALLINT
:
case
TSDB_DATA_TYPE_INT
:
return
fabs
(
percent
-
100
)
<
DBL_EPSILON
?
pRange
->
iMaxVal
:
pRange
->
iMinVal
;
case
TSDB_DATA_TYPE_BIGINT
:
{
double
v
=
(
double
)(
fabs
(
percent
-
100
)
<
DBL_EPSILON
?
pRange
->
i64MaxVal
:
pRange
->
i64MinVal
);
return
v
;
}
case
TSDB_DATA_TYPE_FLOAT
:
case
TSDB_DATA_TYPE_DOUBLE
:
return
fabs
(
percent
-
100
)
<
DBL_EPSILON
?
pRange
->
dMaxVal
:
pRange
->
dMinVal
;
default:
return
-
1
;
}
}
double
percentVal
=
(
percent
*
(
pMemBucket
->
total
-
1
))
/
((
double
)
100
.
0
);
int32_t
orderIdx
=
(
int32_t
)
percentVal
;
// do put data by using buckets
int32_t
orderIdx
=
(
int32_t
)
percentVal
;
return
getPercentileImpl
(
pMemBucket
,
orderIdx
,
percentVal
-
orderIdx
);
}
...
...
src/query/src/qUtil.c
浏览文件 @
1a7786f3
...
...
@@ -126,11 +126,26 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
int32_t
numOfClosed
=
numOfClosedTimeWindow
(
pWindowResInfo
);
assert
(
num
>=
0
&&
num
<=
numOfClosed
);
int16_t
type
=
pWindowResInfo
->
type
;
char
*
key
=
NULL
;
int16_t
bytes
=
-
1
;
for
(
int32_t
i
=
0
;
i
<
num
;
++
i
)
{
SWindowResult
*
pResult
=
&
pWindowResInfo
->
pResult
[
i
];
if
(
pResult
->
closed
)
{
// remove the window slot from hash table
taosHashRemove
(
pWindowResInfo
->
hashList
,
(
const
char
*
)
&
pResult
->
skey
,
pWindowResInfo
->
type
);
// todo refactor
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
key
=
varDataVal
(
pResult
->
key
);
bytes
=
varDataLen
(
pResult
->
key
);
}
else
{
key
=
(
char
*
)
&
pResult
->
win
.
skey
;
bytes
=
tDataTypeDesc
[
pWindowResInfo
->
type
].
nSize
;
}
taosHashRemove
(
pWindowResInfo
->
hashList
,
(
const
char
*
)
key
,
bytes
);
}
else
{
break
;
}
...
...
@@ -150,15 +165,24 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
}
pWindowResInfo
->
size
=
remain
;
for
(
int32_t
k
=
0
;
k
<
pWindowResInfo
->
size
;
++
k
)
{
SWindowResult
*
pResult
=
&
pWindowResInfo
->
pResult
[
k
];
int32_t
*
p
=
(
int32_t
*
)
taosHashGet
(
pWindowResInfo
->
hashList
,
(
const
char
*
)
&
pResult
->
skey
,
tDataTypeDesc
[
pWindowResInfo
->
type
].
nSize
);
if
(
type
==
TSDB_DATA_TYPE_BINARY
||
type
==
TSDB_DATA_TYPE_NCHAR
)
{
key
=
varDataVal
(
pResult
->
key
);
bytes
=
varDataLen
(
pResult
->
key
);
}
else
{
key
=
(
char
*
)
&
pResult
->
win
.
skey
;
bytes
=
tDataTypeDesc
[
pWindowResInfo
->
type
].
nSize
;
}
int32_t
*
p
=
(
int32_t
*
)
taosHashGet
(
pWindowResInfo
->
hashList
,
(
const
char
*
)
key
,
bytes
);
assert
(
p
!=
NULL
);
int32_t
v
=
(
*
p
-
num
);
assert
(
v
>=
0
&&
v
<=
pWindowResInfo
->
size
);
taosHashPut
(
pWindowResInfo
->
hashList
,
(
char
*
)
&
pResult
->
skey
,
tDataTypeDesc
[
pWindowResInfo
->
type
].
nSize
,
(
char
*
)
&
v
,
sizeof
(
int32_t
));
taosHashPut
(
pWindowResInfo
->
hashList
,
(
char
*
)
key
,
bytes
,
(
char
*
)
&
v
,
sizeof
(
int32_t
));
}
pWindowResInfo
->
curIndex
=
-
1
;
...
...
@@ -207,20 +231,19 @@ void removeRedundantWindow(SWindowResInfo *pWindowResInfo, TSKEY lastKey, int32_
}
// get the result order
int32_t
resultOrder
=
(
pWindowResInfo
->
pResult
[
0
].
skey
<
pWindowResInfo
->
pResult
[
1
].
skey
)
?
1
:-
1
;
int32_t
resultOrder
=
(
pWindowResInfo
->
pResult
[
0
].
win
.
skey
<
pWindowResInfo
->
pResult
[
1
].
win
.
skey
)
?
1
:-
1
;
if
(
order
!=
resultOrder
)
{
return
;
}
int32_t
i
=
0
;
if
(
order
==
QUERY_ASC_FORWARD_STEP
)
{
TSKEY
ekey
=
pWindowResInfo
->
pResult
[
i
].
skey
+
pWindowResInfo
->
interval
;
TSKEY
ekey
=
pWindowResInfo
->
pResult
[
i
].
win
.
ekey
;
while
(
i
<
pWindowResInfo
->
size
&&
(
ekey
<
lastKey
))
{
++
i
;
}
}
else
if
(
order
==
QUERY_DESC_FORWARD_STEP
)
{
while
(
i
<
pWindowResInfo
->
size
&&
(
pWindowResInfo
->
pResult
[
i
].
skey
>
lastKey
))
{
while
(
i
<
pWindowResInfo
->
size
&&
(
pWindowResInfo
->
pResult
[
i
].
win
.
skey
>
lastKey
))
{
++
i
;
}
}
...
...
@@ -258,7 +281,7 @@ void clearTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pWindow
pWindowRes
->
numOfRows
=
0
;
pWindowRes
->
pos
=
(
SPosInfo
){
-
1
,
-
1
};
pWindowRes
->
closed
=
false
;
pWindowRes
->
skey
=
TSKEY_INITIAL_VAL
;
pWindowRes
->
win
=
TSWINDOW_INITIALIZER
;
}
/**
...
...
@@ -268,7 +291,7 @@ void clearTimeWindowResBuf(SQueryRuntimeEnv *pRuntimeEnv, SWindowResult *pWindow
*/
void
copyTimeWindowResBuf
(
SQueryRuntimeEnv
*
pRuntimeEnv
,
SWindowResult
*
dst
,
const
SWindowResult
*
src
)
{
dst
->
numOfRows
=
src
->
numOfRows
;
dst
->
skey
=
src
->
skey
;
dst
->
win
=
src
->
win
;
dst
->
closed
=
src
->
closed
;
int32_t
nOutputCols
=
pRuntimeEnv
->
pQuery
->
numOfOutput
;
...
...
src/query/src/sql.c
浏览文件 @
1a7786f3
此差异已折叠。
点击以展开。
src/tsdb/src/tsdbRead.c
浏览文件 @
1a7786f3
...
...
@@ -248,6 +248,7 @@ TsdbQueryHandleT* tsdbQueryTables(TSDB_REPO_T* tsdb, STsdbQueryCond* pCond, STab
STsdbMeta
*
pMeta
=
tsdbGetMeta
(
tsdb
);
assert
(
pMeta
!=
NULL
&&
sizeOfGroup
>=
1
&&
pCond
!=
NULL
&&
pCond
->
numOfCols
>
0
);
// todo apply the lastkey of table check to avoid to load header file
for
(
int32_t
i
=
0
;
i
<
sizeOfGroup
;
++
i
)
{
SArray
*
group
=
*
(
SArray
**
)
taosArrayGet
(
groupList
->
pGroupList
,
i
);
...
...
@@ -388,9 +389,9 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
SDataRow
row
=
*
(
SDataRow
*
)
SL_GET_NODE_DATA
(
node
);
TSKEY
key
=
dataRowKey
(
row
);
// first timestamp in buffer
tsdbDebug
(
"%p uid:%"
PRId64
", tid:%d check data in mem from skey:%"
PRId64
", order:%d, ts range in buf:%"
PRId64
"-%"
PRId64
", lastKey:%"
PRId64
", %p"
,
"-%"
PRId64
", lastKey:%"
PRId64
",
numOfRows:%"
PRId64
",
%p"
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
key
,
order
,
pMem
->
keyFirst
,
pMem
->
keyLast
,
pCheckInfo
->
lastKey
,
pHandle
->
qinfo
);
pCheckInfo
->
lastKey
,
p
Mem
->
numOfRows
,
p
Handle
->
qinfo
);
if
(
ASCENDING_TRAVERSE
(
order
))
{
assert
(
pCheckInfo
->
lastKey
<=
key
);
...
...
@@ -410,9 +411,9 @@ static bool initTableMemIterator(STsdbQueryHandle* pHandle, STableCheckInfo* pCh
SDataRow
row
=
*
(
SDataRow
*
)
SL_GET_NODE_DATA
(
node
);
TSKEY
key
=
dataRowKey
(
row
);
// first timestamp in buffer
tsdbDebug
(
"%p uid:%"
PRId64
", tid:%d check data in imem from skey:%"
PRId64
", order:%d, ts range in buf:%"
PRId64
"-%"
PRId64
", lastKey:%"
PRId64
", %p"
,
"-%"
PRId64
", lastKey:%"
PRId64
",
numOfRows:%"
PRId64
",
%p"
,
pHandle
,
pCheckInfo
->
tableId
.
uid
,
pCheckInfo
->
tableId
.
tid
,
key
,
order
,
pIMem
->
keyFirst
,
pIMem
->
keyLast
,
pCheckInfo
->
lastKey
,
pHandle
->
qinfo
);
pCheckInfo
->
lastKey
,
p
IMem
->
numOfRows
,
p
Handle
->
qinfo
);
if
(
ASCENDING_TRAVERSE
(
order
))
{
assert
(
pCheckInfo
->
lastKey
<=
key
);
...
...
@@ -734,6 +735,7 @@ static int32_t doLoadFileDataBlock(STsdbQueryHandle* pQueryHandle, SCompBlock* p
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
getEndPosInDataBlock
(
STsdbQueryHandle
*
pQueryHandle
,
SDataBlockInfo
*
pBlockInfo
);
static
int32_t
doCopyRowsFromFileBlock
(
STsdbQueryHandle
*
pQueryHandle
,
int32_t
capacity
,
int32_t
numOfRows
,
int32_t
start
,
int32_t
end
);
static
void
moveDataToFront
(
STsdbQueryHandle
*
pQueryHandle
,
int32_t
numOfRows
,
int32_t
numOfCols
);
static
void
doCheckGeneratedBlockRange
(
STsdbQueryHandle
*
pQueryHandle
);
...
...
@@ -790,9 +792,10 @@ static int32_t handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SCompBloc
* Here the buffer is not enough, so only part of file block can be loaded into memory buffer
*/
assert
(
pQueryHandle
->
outputCapacity
>=
binfo
.
rows
);
int32_t
endPos
=
getEndPosInDataBlock
(
pQueryHandle
,
&
binfo
);
if
((
cur
->
pos
==
0
&&
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
))
||
(
cur
->
pos
==
(
binfo
.
rows
-
1
)
&&
(
!
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
))))
{
if
((
cur
->
pos
==
0
&&
endPos
==
binfo
.
rows
-
1
&&
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
))
||
(
cur
->
pos
==
(
binfo
.
rows
-
1
)
&&
endPos
==
0
&&
(
!
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
))))
{
pQueryHandle
->
realNumOfRows
=
binfo
.
rows
;
cur
->
rows
=
binfo
.
rows
;
...
...
@@ -808,7 +811,6 @@ static int32_t handleDataMergeIfNeeded(STsdbQueryHandle* pQueryHandle, SCompBloc
cur
->
pos
=
-
1
;
}
}
else
{
// partially copy to dest buffer
int32_t
endPos
=
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
)
?
(
binfo
.
rows
-
1
)
:
0
;
copyAllRemainRowsFromFileBlock
(
pQueryHandle
,
pCheckInfo
,
&
binfo
,
endPos
);
cur
->
mixBlock
=
true
;
}
...
...
@@ -1203,6 +1205,29 @@ static void copyAllRemainRowsFromFileBlock(STsdbQueryHandle* pQueryHandle, STabl
cur
->
win
.
ekey
,
cur
->
rows
,
pQueryHandle
->
qinfo
);
}
int32_t
getEndPosInDataBlock
(
STsdbQueryHandle
*
pQueryHandle
,
SDataBlockInfo
*
pBlockInfo
)
{
// NOTE: reverse the order to find the end position in data block
int32_t
endPos
=
-
1
;
int32_t
order
=
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
)
?
TSDB_ORDER_DESC
:
TSDB_ORDER_ASC
;
SQueryFilePos
*
cur
=
&
pQueryHandle
->
cur
;
SDataCols
*
pCols
=
pQueryHandle
->
rhelper
.
pDataCols
[
0
];
if
(
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
)
&&
pQueryHandle
->
window
.
ekey
>=
pBlockInfo
->
window
.
ekey
)
{
endPos
=
pBlockInfo
->
rows
-
1
;
cur
->
mixBlock
=
(
cur
->
pos
!=
0
);
}
else
if
(
!
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
)
&&
pQueryHandle
->
window
.
ekey
<=
pBlockInfo
->
window
.
skey
)
{
endPos
=
0
;
cur
->
mixBlock
=
(
cur
->
pos
!=
pBlockInfo
->
rows
-
1
);
}
else
{
assert
(
pCols
->
numOfRows
>
0
);
endPos
=
doBinarySearchKey
(
pCols
->
cols
[
0
].
pData
,
pCols
->
numOfRows
,
pQueryHandle
->
window
.
ekey
,
order
);
cur
->
mixBlock
=
true
;
}
return
endPos
;
}
// only return the qualified data to client in terms of query time window, data rows in the same block but do not
// be included in the query time window will be discarded
static
void
doMergeTwoLevelData
(
STsdbQueryHandle
*
pQueryHandle
,
STableCheckInfo
*
pCheckInfo
,
SCompBlock
*
pBlock
)
{
...
...
@@ -1224,19 +1249,7 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
int32_t
numOfCols
=
(
int32_t
)(
QH_GET_NUM_OF_COLS
(
pQueryHandle
));
STable
*
pTable
=
pCheckInfo
->
pTableObj
;
int32_t
endPos
=
cur
->
pos
;
if
(
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
)
&&
pQueryHandle
->
window
.
ekey
>
blockInfo
.
window
.
ekey
)
{
endPos
=
blockInfo
.
rows
-
1
;
cur
->
mixBlock
=
(
cur
->
pos
!=
0
);
}
else
if
(
!
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
)
&&
pQueryHandle
->
window
.
ekey
<
blockInfo
.
window
.
skey
)
{
endPos
=
0
;
cur
->
mixBlock
=
(
cur
->
pos
!=
blockInfo
.
rows
-
1
);
}
else
{
assert
(
pCols
->
numOfRows
>
0
);
endPos
=
doBinarySearchKey
(
pCols
->
cols
[
0
].
pData
,
pCols
->
numOfRows
,
pQueryHandle
->
window
.
ekey
,
order
);
cur
->
mixBlock
=
true
;
}
int32_t
endPos
=
getEndPosInDataBlock
(
pQueryHandle
,
&
blockInfo
);
tsdbDebug
(
"%p uid:%"
PRIu64
",tid:%d start merge data block, file block range:%"
PRIu64
"-%"
PRIu64
" rows:%d, start:%d,"
"end:%d, %p"
,
...
...
@@ -1338,8 +1351,8 @@ static void doMergeTwoLevelData(STsdbQueryHandle* pQueryHandle, STableCheckInfo*
}
cur
->
blockCompleted
=
(((
pos
>
=
endPos
||
cur
->
lastKey
>
pQueryHandle
->
window
.
ekey
)
&&
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
))
||
((
pos
<
=
endPos
||
cur
->
lastKey
<
pQueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
)));
(((
pos
>
endPos
||
cur
->
lastKey
>
pQueryHandle
->
window
.
ekey
)
&&
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
))
||
((
pos
<
endPos
||
cur
->
lastKey
<
pQueryHandle
->
window
.
ekey
)
&&
!
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
)));
if
(
!
ASCENDING_TRAVERSE
(
pQueryHandle
->
order
))
{
SWAP
(
cur
->
win
.
skey
,
cur
->
win
.
ekey
,
TSKEY
);
...
...
@@ -2071,13 +2084,17 @@ STimeWindow changeTableGroupByLastrow(STableGroupInfo *groupList) {
if
(
keyInfo
.
pTable
!=
NULL
)
{
totalNumOfTable
++
;
taosArrayPush
(
pGroup
,
&
keyInfo
);
}
else
{
taosArrayRemove
(
groupList
->
pGroupList
,
j
);
numOfGroups
-=
1
;
j
-=
1
;
}
}
// window does not being updated, so set the original
if
(
window
.
skey
==
INT64_MAX
&&
window
.
ekey
==
INT64_MIN
)
{
window
=
TSWINDOW_INITIALIZER
;
assert
(
totalNumOfTable
==
0
);
assert
(
totalNumOfTable
==
0
&&
taosArrayGetSize
(
groupList
->
pGroupList
)
==
0
);
}
groupList
->
numOfTables
=
totalNumOfTable
;
...
...
@@ -2398,6 +2415,14 @@ static bool indexedNodeFilterFp(const void* pNode, void* param) {
val
=
tdGetKVRowValOfCol
(
pTable
->
tagVal
,
pInfo
->
sch
.
colId
);
}
if
(
pInfo
->
optr
==
TSDB_RELATION_ISNULL
||
pInfo
->
optr
==
TSDB_RELATION_NOTNULL
)
{
if
(
pInfo
->
optr
==
TSDB_RELATION_ISNULL
)
{
return
(
val
==
NULL
)
||
isNull
(
val
,
pInfo
->
sch
.
type
);
}
else
if
(
pInfo
->
optr
==
TSDB_RELATION_NOTNULL
)
{
return
(
val
!=
NULL
)
&&
(
!
isNull
(
val
,
pInfo
->
sch
.
type
));
}
}
int32_t
ret
=
0
;
if
(
val
==
NULL
)
{
//the val is possible to be null, so check it out carefully
ret
=
-
1
;
// val is missing in table tags value pairs
...
...
src/util/src/tcache.c
浏览文件 @
1a7786f3
...
...
@@ -71,7 +71,7 @@ static SCacheDataNode *taosCreateCacheNode(const char *key, size_t keyLen, const
* @param pCacheObj Cache object
* @param pNode Cache slot object
*/
static
void
taosAddToTrash
(
SCacheObj
*
pCacheObj
,
SCacheDataNode
*
pNode
);
static
void
taosAddToTrash
can
(
SCacheObj
*
pCacheObj
,
SCacheDataNode
*
pNode
);
/**
* remove nodes in trash with refCount == 0 in cache
...
...
@@ -80,7 +80,7 @@ static void taosAddToTrash(SCacheObj *pCacheObj, SCacheDataNode *pNode);
* @param force force model, if true, remove data in trash without check refcount.
* may cause corruption. So, forece model only applys before cache is closed
*/
static
void
taosTrash
C
anEmpty
(
SCacheObj
*
pCacheObj
,
bool
force
);
static
void
taosTrash
c
anEmpty
(
SCacheObj
*
pCacheObj
,
bool
force
);
/**
* release node
...
...
@@ -165,7 +165,7 @@ SCacheObj *taosCacheInit(int32_t keyType, int64_t refreshTimeInSeconds, bool ext
return
NULL
;
}
// set free cache node callback function
for hash table
// set free cache node callback function
pCacheObj
->
freeFp
=
fn
;
pCacheObj
->
refreshTime
=
refreshTimeInSeconds
*
1000
;
pCacheObj
->
extendLifespan
=
extendLifespan
;
...
...
@@ -222,7 +222,7 @@ void *taosCachePut(SCacheObj *pCacheObj, const void *key, size_t keyLen, const v
taosTFree
(
p
);
}
else
{
taosAddToTrash
(
pCacheObj
,
p
);
taosAddToTrash
can
(
pCacheObj
,
p
);
uDebug
(
"cache:%s, key:%p, %p exist in cache, updated old:%p"
,
pCacheObj
->
name
,
key
,
pNode1
->
data
,
p
->
data
);
}
}
...
...
@@ -322,7 +322,12 @@ void *taosCacheTransfer(SCacheObj *pCacheObj, void **data) {
}
void
taosCacheRelease
(
SCacheObj
*
pCacheObj
,
void
**
data
,
bool
_remove
)
{
if
(
pCacheObj
==
NULL
||
(
*
data
)
==
NULL
||
(
taosHashGetSize
(
pCacheObj
->
pHashTable
)
+
pCacheObj
->
numOfElemsInTrash
==
0
))
{
if
(
pCacheObj
==
NULL
||
taosHashGetSize
(
pCacheObj
->
pHashTable
)
+
pCacheObj
->
numOfElemsInTrash
==
0
)
{
return
;
}
if
((
*
data
)
==
NULL
)
{
uError
(
"cache:%s, NULL data to release"
,
pCacheObj
->
name
);
return
;
}
...
...
@@ -394,19 +399,19 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
"others already"
,
pCacheObj
->
name
,
pNode
->
key
,
p
->
data
,
T_REF_VAL_GET
(
p
),
pNode
->
data
);
assert
(
p
->
pTNodeHeader
==
NULL
);
taosAddToTrash
(
pCacheObj
,
p
);
taosAddToTrash
can
(
pCacheObj
,
p
);
}
else
{
uDebug
(
"cache:%s, key:%p, %p successfully removed from hash table, refcnt:%d"
,
pCacheObj
->
name
,
pNode
->
key
,
pNode
->
data
,
ref
);
if
(
ref
>
0
)
{
assert
(
pNode
->
pTNodeHeader
==
NULL
);
taosAddToTrash
(
pCacheObj
,
pNode
);
taosAddToTrash
can
(
pCacheObj
,
pNode
);
}
else
{
// ref == 0
atomic_sub_fetch_64
(
&
pCacheObj
->
totalSize
,
pNode
->
size
);
int32_t
size
=
(
int32_t
)
taosHashGetSize
(
pCacheObj
->
pHashTable
);
uDebug
(
"cache:%s, key:%p, %p is destroyed from cache, size:%dbytes,
n
um:%d size:%"
PRId64
"bytes"
,
uDebug
(
"cache:%s, key:%p, %p is destroyed from cache, size:%dbytes,
totalN
um:%d size:%"
PRId64
"bytes"
,
pCacheObj
->
name
,
pNode
->
key
,
pNode
->
data
,
pNode
->
size
,
size
,
pCacheObj
->
totalSize
);
if
(
pCacheObj
->
freeFp
)
{
...
...
@@ -427,6 +432,26 @@ void taosCacheRelease(SCacheObj *pCacheObj, void **data, bool _remove) {
char
*
key
=
pNode
->
key
;
char
*
p
=
pNode
->
data
;
// int32_t ref = T_REF_VAL_GET(pNode);
//
// if (ref == 1 && inTrashcan) {
// // If it is the last ref, remove it from trashcan linked-list first, and then destroy it.Otherwise, it may be
// // destroyed by refresh worker if decrease ref count before removing it from linked-list.
// assert(pNode->pTNodeHeader->pData == pNode);
//
// __cache_wr_lock(pCacheObj);
// doRemoveElemInTrashcan(pCacheObj, pNode->pTNodeHeader);
// __cache_unlock(pCacheObj);
//
// ref = T_REF_DEC(pNode);
// assert(ref == 0);
//
// doDestroyTrashcanElem(pCacheObj, pNode->pTNodeHeader);
// } else {
// ref = T_REF_DEC(pNode);
// assert(ref >= 0);
// }
int32_t
ref
=
T_REF_DEC
(
pNode
);
uDebug
(
"cache:%s, key:%p, %p released, refcnt:%d, data in trashcan:%d"
,
pCacheObj
->
name
,
key
,
p
,
ref
,
inTrashcan
);
}
...
...
@@ -447,7 +472,7 @@ static bool travHashTableEmptyFn(void* param, void* data) {
if
(
T_REF_VAL_GET
(
pNode
)
==
0
)
{
taosCacheReleaseNode
(
pCacheObj
,
pNode
);
}
else
{
// do add to trashcan
taosAddToTrash
(
pCacheObj
,
pNode
);
taosAddToTrash
can
(
pCacheObj
,
pNode
);
}
// this node should be remove from hash table
...
...
@@ -458,7 +483,7 @@ void taosCacheEmpty(SCacheObj *pCacheObj) {
SHashTravSupp
sup
=
{.
pCacheObj
=
pCacheObj
,
.
fp
=
NULL
,
.
time
=
taosGetTimestampMs
()};
taosHashCondTraverse
(
pCacheObj
->
pHashTable
,
travHashTableEmptyFn
,
&
sup
);
taosTrash
C
anEmpty
(
pCacheObj
,
false
);
taosTrash
c
anEmpty
(
pCacheObj
,
false
);
}
void
taosCacheCleanup
(
SCacheObj
*
pCacheObj
)
{
...
...
@@ -498,7 +523,7 @@ SCacheDataNode *taosCreateCacheNode(const char *key, size_t keyLen, const char *
return
pNewNode
;
}
void
taosAddToTrash
(
SCacheObj
*
pCacheObj
,
SCacheDataNode
*
pNode
)
{
void
taosAddToTrash
can
(
SCacheObj
*
pCacheObj
,
SCacheDataNode
*
pNode
)
{
if
(
pNode
->
inTrashcan
)
{
/* node is already in trash */
assert
(
pNode
->
pTNodeHeader
!=
NULL
&&
pNode
->
pTNodeHeader
->
pData
==
pNode
);
return
;
...
...
@@ -520,11 +545,11 @@ void taosAddToTrash(SCacheObj *pCacheObj, SCacheDataNode *pNode) {
pCacheObj
->
numOfElemsInTrash
++
;
__cache_unlock
(
pCacheObj
);
uDebug
(
"cache:%s key:%p, %p move to trash
, numOfElem in trash
:%d"
,
pCacheObj
->
name
,
pNode
->
key
,
pNode
->
data
,
uDebug
(
"cache:%s key:%p, %p move to trash
can, numOfElem in trashcan
:%d"
,
pCacheObj
->
name
,
pNode
->
key
,
pNode
->
data
,
pCacheObj
->
numOfElemsInTrash
);
}
void
taosTrash
C
anEmpty
(
SCacheObj
*
pCacheObj
,
bool
force
)
{
void
taosTrash
c
anEmpty
(
SCacheObj
*
pCacheObj
,
bool
force
)
{
__cache_wr_lock
(
pCacheObj
);
if
(
pCacheObj
->
numOfElemsInTrash
==
0
)
{
...
...
@@ -568,7 +593,7 @@ void doCleanupDataCache(SCacheObj *pCacheObj) {
// todo memory leak if there are object with refcount greater than 0 in hash table?
taosHashCleanup
(
pCacheObj
->
pHashTable
);
taosTrash
C
anEmpty
(
pCacheObj
,
true
);
taosTrash
c
anEmpty
(
pCacheObj
,
true
);
__cache_lock_destroy
(
pCacheObj
);
...
...
@@ -643,7 +668,7 @@ void* taosCacheTimedRefresh(void *handle) {
doCacheRefresh
(
pCacheObj
,
now
,
NULL
);
}
taosTrash
C
anEmpty
(
pCacheObj
,
false
);
taosTrash
c
anEmpty
(
pCacheObj
,
false
);
}
return
NULL
;
...
...
src/util/src/tlog.c
浏览文件 @
1a7786f3
...
...
@@ -433,7 +433,7 @@ void taosPrintLongString(const char *flags, int32_t dflag, const char *format, .
va_list
argpointer
;
char
buffer
[
MAX_LOGLINE_DUMP_BUFFER_SIZE
];
int32_t
len
;
int32_t
len
;
struct
tm
Tm
,
*
ptm
;
struct
timeval
timeSecs
;
time_t
curTime
;
...
...
src/util/src/tsocket.c
浏览文件 @
1a7786f3
...
...
@@ -16,7 +16,7 @@
#include "os.h"
#include "tulog.h"
#include "tsocket.h"
#include "t
util
.h"
#include "t
aoserror
.h"
int
taosGetFqdn
(
char
*
fqdn
)
{
char
hostname
[
1024
];
...
...
@@ -56,7 +56,16 @@ uint32_t taosGetIpFromFqdn(const char *fqdn) {
freeaddrinfo
(
result
);
return
ip
;
}
else
{
uError
(
"failed get the ip address, fqdn:%s, code:%d, reason:%s"
,
fqdn
,
ret
,
gai_strerror
(
ret
));
#ifdef EAI_SYSTEM
if
(
ret
==
EAI_SYSTEM
)
{
uError
(
"failed to get the ip address, fqdn:%s, code:%d, reason:%s"
,
fqdn
,
ret
,
strerror
(
errno
));
terrno
=
TAOS_SYSTEM_ERROR
(
errno
);
}
else
{
uError
(
"failed to get the ip address, fqdn:%s, code:%d, reason:%s"
,
fqdn
,
ret
,
gai_strerror
(
ret
));
}
#else
uError
(
"failed to get the ip address, fqdn:%s, code:%d, reason:%s"
,
fqdn
,
ret
,
gai_strerror
(
ret
));
#endif
return
0xFFFFFFFF
;
}
}
...
...
src/util/tests/cacheTest.cpp
浏览文件 @
1a7786f3
...
...
@@ -12,65 +12,65 @@ int32_t tsMaxMeterConnections = 200;
// test cache
TEST
(
testCase
,
client_cache_test
)
{
const
int32_t
REFRESH_TIME_IN_SEC
=
2
;
SCacheObj
*
tsc
CacheHandl
e
=
taosCacheInit
(
TSDB_DATA_TYPE_BINARY
,
REFRESH_TIME_IN_SEC
,
0
,
NULL
,
"test"
);
SCacheObj
*
tsc
MetaCach
e
=
taosCacheInit
(
TSDB_DATA_TYPE_BINARY
,
REFRESH_TIME_IN_SEC
,
0
,
NULL
,
"test"
);
const
char
*
key1
=
"test1"
;
char
data1
[]
=
"test11"
;
char
*
cachedObj
=
(
char
*
)
taosCachePut
(
tsc
CacheHandl
e
,
key1
,
strlen
(
key1
),
data1
,
strlen
(
data1
)
+
1
,
1
);
char
*
cachedObj
=
(
char
*
)
taosCachePut
(
tsc
MetaCach
e
,
key1
,
strlen
(
key1
),
data1
,
strlen
(
data1
)
+
1
,
1
);
sleep
(
REFRESH_TIME_IN_SEC
+
1
);
printf
(
"obj is still valid: %s
\n
"
,
cachedObj
);
char
data2
[]
=
"test22"
;
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
cachedObj
,
false
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
cachedObj
,
false
);
/* the object is cleared by cache clean operation */
cachedObj
=
(
char
*
)
taosCachePut
(
tsc
CacheHandl
e
,
key1
,
strlen
(
key1
),
data2
,
strlen
(
data2
)
+
1
,
20
);
cachedObj
=
(
char
*
)
taosCachePut
(
tsc
MetaCach
e
,
key1
,
strlen
(
key1
),
data2
,
strlen
(
data2
)
+
1
,
20
);
printf
(
"after updated: %s
\n
"
,
cachedObj
);
printf
(
"start to remove data from cache
\n
"
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
cachedObj
,
false
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
cachedObj
,
false
);
printf
(
"end of removing data from cache
\n
"
);
const
char
*
key3
=
"test2"
;
const
char
*
data3
=
"kkkkkkk"
;
char
*
cachedObj2
=
(
char
*
)
taosCachePut
(
tsc
CacheHandl
e
,
key3
,
strlen
(
key3
),
data3
,
strlen
(
data3
)
+
1
,
1
);
char
*
cachedObj2
=
(
char
*
)
taosCachePut
(
tsc
MetaCach
e
,
key3
,
strlen
(
key3
),
data3
,
strlen
(
data3
)
+
1
,
1
);
printf
(
"%s
\n
"
,
cachedObj2
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
cachedObj2
,
false
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
cachedObj2
,
false
);
sleep
(
3
);
char
*
d
=
(
char
*
)
taosCacheAcquireByKey
(
tsc
CacheHandl
e
,
key3
,
strlen
(
key3
));
char
*
d
=
(
char
*
)
taosCacheAcquireByKey
(
tsc
MetaCach
e
,
key3
,
strlen
(
key3
));
// assert(d == NULL);
char
key5
[]
=
"test5"
;
char
data5
[]
=
"data5kkkkk"
;
cachedObj2
=
(
char
*
)
taosCachePut
(
tsc
CacheHandl
e
,
key5
,
strlen
(
key5
),
data5
,
strlen
(
data5
)
+
1
,
20
);
cachedObj2
=
(
char
*
)
taosCachePut
(
tsc
MetaCach
e
,
key5
,
strlen
(
key5
),
data5
,
strlen
(
data5
)
+
1
,
20
);
const
char
*
data6
=
"new Data after updated"
;
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
cachedObj2
,
false
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
cachedObj2
,
false
);
cachedObj2
=
(
char
*
)
taosCachePut
(
tsc
CacheHandl
e
,
key5
,
strlen
(
key5
),
data6
,
strlen
(
data6
)
+
1
,
20
);
cachedObj2
=
(
char
*
)
taosCachePut
(
tsc
MetaCach
e
,
key5
,
strlen
(
key5
),
data6
,
strlen
(
data6
)
+
1
,
20
);
printf
(
"%s
\n
"
,
cachedObj2
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
cachedObj2
,
true
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
cachedObj2
,
true
);
const
char
*
data7
=
"add call update procedure"
;
cachedObj2
=
(
char
*
)
taosCachePut
(
tsc
CacheHandl
e
,
key5
,
strlen
(
key5
),
data7
,
strlen
(
data7
)
+
1
,
20
);
cachedObj2
=
(
char
*
)
taosCachePut
(
tsc
MetaCach
e
,
key5
,
strlen
(
key5
),
data7
,
strlen
(
data7
)
+
1
,
20
);
printf
(
"%s
\n
=======================================
\n\n
"
,
cachedObj2
);
char
*
cc
=
(
char
*
)
taosCacheAcquireByKey
(
tsc
CacheHandl
e
,
key5
,
strlen
(
key5
));
char
*
cc
=
(
char
*
)
taosCacheAcquireByKey
(
tsc
MetaCach
e
,
key5
,
strlen
(
key5
));
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
cachedObj2
,
true
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
cc
,
false
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
cachedObj2
,
true
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
cc
,
false
);
const
char
*
data8
=
"ttft"
;
const
char
*
key6
=
"key6"
;
char
*
ft
=
(
char
*
)
taosCachePut
(
tsc
CacheHandl
e
,
key6
,
strlen
(
key6
),
data8
,
strlen
(
data8
),
20
);
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
ft
,
false
);
char
*
ft
=
(
char
*
)
taosCachePut
(
tsc
MetaCach
e
,
key6
,
strlen
(
key6
),
data8
,
strlen
(
data8
),
20
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
ft
,
false
);
/**
* 140ns
...
...
@@ -78,14 +78,14 @@ TEST(testCase, client_cache_test) {
uint64_t
startTime
=
taosGetTimestampUs
();
printf
(
"Cache Performance Test
\n
start time:%"
PRIu64
"
\n
"
,
startTime
);
for
(
int32_t
i
=
0
;
i
<
1000
;
++
i
)
{
char
*
dd
=
(
char
*
)
taosCacheAcquireByKey
(
tsc
CacheHandl
e
,
key6
,
strlen
(
key6
));
char
*
dd
=
(
char
*
)
taosCacheAcquireByKey
(
tsc
MetaCach
e
,
key6
,
strlen
(
key6
));
if
(
dd
!=
NULL
)
{
// printf("get the data\n");
}
else
{
printf
(
"data has been released
\n
"
);
}
taosCacheRelease
(
tsc
CacheHandl
e
,
(
void
**
)
&
dd
,
false
);
taosCacheRelease
(
tsc
MetaCach
e
,
(
void
**
)
&
dd
,
false
);
}
uint64_t
endTime
=
taosGetTimestampUs
();
...
...
@@ -93,7 +93,7 @@ TEST(testCase, client_cache_test) {
printf
(
"End of Test, %"
PRIu64
"
\n
Total Elapsed Time:%"
PRIu64
" us.avg:%f us
\n
"
,
endTime
,
el
,
el
/
1000.0
);
taosCacheCleanup
(
tsc
CacheHandl
e
);
taosCacheCleanup
(
tsc
MetaCach
e
);
}
TEST
(
testCase
,
cache_resize_test
)
{
...
...
tests/script/general/parser/groupby.sim
浏览文件 @
1a7786f3
...
...
@@ -423,6 +423,8 @@ if $data97 != @group_tb0@ then
return -1
endi
print ---------------------------------> group by binary|nchar data add cases
#=========================== group by multi tags ======================
sql create table st (ts timestamp, c int) tags (t1 int, t2 int, t3 int, t4 int);
...
...
tests/script/general/parser/join.sim
浏览文件 @
1a7786f3
...
...
@@ -205,10 +205,12 @@ if $rows != 9 then
endi
if $data00 != @70-01-01 08:01:40.100@ then
print $data00
return -1
endi
if $data10 != @70-01-01 08:01:40.200@ then
print $data10
return -1
endi
...
...
tests/script/general/parser/lastrow_query.sim
浏览文件 @
1a7786f3
...
...
@@ -154,6 +154,7 @@ if $rows != 46 then
endi
print ========>td-1317, empty table last_row query crashed
sql drop table if exists m1;
sql create table m1(ts timestamp, k int) tags (a int);
sql create table t1 using m1 tags(1);
sql create table t2 using m1 tags(2);
...
...
@@ -172,3 +173,49 @@ sql select last_row(*) from m1 where tbname in ('t1')
if $rows != 0 then
return -1
endi
sql insert into t1 values('2019-1-1 1:1:1', 1);
print ===================> last_row query against normal table along with ts/tbname
sql select last_row(*),ts,'k' from t1;
if $rows != 1 then
return -1
endi
print ===================> last_row + user-defined column + normal tables
sql select last_row(ts), 'abc', 1234.9384, ts from t1
if $rows != 1 then
return -1
endi
if $data01 != @abc@ then
print expect abc, actual $data02
return -1
endi
if $data02 != 1234.938400000 then
return -1
endi
if $data03 != @19-01-01 01:01:01.000@ then
print expect 19-01-01 01:01:01.000, actual:$data03
return -1
endi
print ===================> last_row + stable + ts/tag column + condition + udf
sql select last_row(*), ts, 'abc', 123.981, tbname from m1
if $rows != 1 then
return -1
endi
if $data02 != @19-01-01 01:01:01.000@ then
return -1
endi
if $data03 != @abc@ then
return -1
endi
if $data04 != 123.981000000 then
print expect 123.981000000, actual: $data04
return -1
endi
\ No newline at end of file
tests/script/general/parser/testSuite.sim
浏览文件 @
1a7786f3
...
...
@@ -99,6 +99,8 @@ run general/parser/union.sim
sleep 2000
run general/parser/constCol.sim
sleep 2000
run general/parser/where.sim
sleep 2000
run general/parser/timestamp.sim
sleep 2000
run general/parser/sliding.sim
...
...
tests/script/general/parser/timestamp_query.sim
浏览文件 @
1a7786f3
...
...
@@ -21,6 +21,10 @@ $tsu = $rowNum * $delta
$tsu = $tsu - $delta
$tsu = $tsu + $ts0
print ==================>issue #3481, normal column not allowed,
sql_error select ts,c1,min(c2) from ts_stb0
##### select from supertable
$tb = $tbPrefix . 0
sql select first(c1), last(c1), (1537325400 - 1537146000)/(5*60) v from $tb where ts >= $ts0 and ts < $tsu interval(5m) fill(value, -1)
...
...
tests/script/general/parser/topbot.sim
浏览文件 @
1a7786f3
...
...
@@ -5,7 +5,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0
system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 200
system sh/exec.sh -n dnode1 -s start
sleep
3
000
sleep
1
000
sql connect
$dbPrefix = tb_db
...
...
@@ -25,7 +25,7 @@ $stb = $stbPrefix . $i
sql drop database $db -x step1
step1:
sql create database $db cache 16
sql create database $db cache 16
maxrows 4096 keep 36500
print ====== create tables
sql use $db
sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 smallint, c6 tinyint, c7 bool, c8 binary(10), c9 nchar(10)) tags(t1 int)
...
...
@@ -132,15 +132,15 @@ sleep 5000
system sh/exec.sh -n dnode1 -s start
print ================== server restart completed
sql connect
sleep
3
000
sleep
1
000
sql select count(*) from t1.test where ts>10000 and ts<90000 interval(5000a)
if $rows != 3 then
return -1
endi
print =========>td-1308
sql create database db;
print =========
=====
>td-1308
sql create database db
keep 36500
;
sql use db;
sql create table stb (ts timestamp, c1 int, c2 binary(10)) tags(t1 binary(10));
...
...
@@ -158,4 +158,59 @@ if $rows != 1 then
return -1
endi
print =======================>td-1446
sql create table t(ts timestamp, k int)
$ts = 6000
while $ts < 7000
sql insert into t values ( $ts , $ts )
$ts = $ts + 1
endw
system sh/exec.sh -n dnode1 -s stop -x SIGINT
system sh/exec.sh -n dnode1 -s start
sql connect
sleep 1000
sql use db;
$ts = 1000
while $ts < 5096
sql insert into t values ( $ts , $ts )
$ts = $ts + 1
endw
sql select * from t where ts < 6500
if $rows != 4596 then
print expect 4596, actual: $rows
return -1
endi
sql select * from t where ts < 7000
if $rows != 5096 then
return -1
endi
sql select * from t where ts <= 6000
if $rows != 4097 then
return -1
endi
sql select * from t where ts <= 6001
if $rows != 4098 then
return -1
endi
print ======================>td-1454
sql select count(*)/10, count(*)+99 from t
if $rows != 1 then
return -1
endi
if $data00 != 509.600000000 then
return -1
endi
if $data01 != 5195.000000000 then
return -1
endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT
\ No newline at end of file
tests/script/general/parser/where.sim
浏览文件 @
1a7786f3
...
...
@@ -2,6 +2,7 @@ system sh/stop_dnodes.sh
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c walLevel -v 0
system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4
system sh/exec.sh -n dnode1 -s start
sleep 3000
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录