Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
taosdata
TDengine
提交
aa93f393
T
TDengine
项目概览
taosdata
/
TDengine
1 年多 前同步成功
通知
1185
Star
22016
Fork
4786
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
1
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
TDengine
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
1
Issue
1
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
aa93f393
编写于
5月 11, 2022
作者:
D
dapan1121
浏览文件
操作
浏览文件
下载
差异文件
Merge remote-tracking branch 'origin/3.0' into feature/qnode
上级
cc9983ab
2655d3bb
变更
13
隐藏空白更改
内联
并排
Showing
13 changed file
with
587 addition
and
414 deletion
+587
-414
include/common/tvariant.h
include/common/tvariant.h
+4
-5
include/libs/planner/planner.h
include/libs/planner/planner.h
+2
-1
source/client/src/clientStmt.c
source/client/src/clientStmt.c
+73
-80
source/common/src/tvariant.c
source/common/src/tvariant.c
+22
-90
source/common/test/commonTests.cpp
source/common/test/commonTests.cpp
+40
-51
source/libs/function/src/builtins.c
source/libs/function/src/builtins.c
+1
-21
source/libs/parser/src/parAstCreater.c
source/libs/parser/src/parAstCreater.c
+14
-7
source/libs/parser/src/parInsert.c
source/libs/parser/src/parInsert.c
+74
-74
source/libs/parser/src/parTranslater.c
source/libs/parser/src/parTranslater.c
+3
-0
source/libs/parser/test/parInitialCTest.cpp
source/libs/parser/test/parInitialCTest.cpp
+217
-70
source/libs/planner/src/planner.c
source/libs/planner/src/planner.c
+132
-9
tests/script/tsim/db/alter_option.sim
tests/script/tsim/db/alter_option.sim
+2
-2
tests/script/tsim/db/basic6.sim
tests/script/tsim/db/basic6.sim
+3
-4
未找到文件。
include/common/tvariant.h
浏览文件 @
aa93f393
...
...
@@ -36,12 +36,11 @@ typedef struct SVariant {
};
}
SVariant
;
int32_t
toInteger
(
const
char
*
z
,
int32_t
n
,
int32_t
base
,
int64_t
*
value
,
bool
*
issigned
);
int32_t
toInteger
(
const
char
*
z
,
int32_t
n
,
int32_t
base
,
int64_t
*
value
);
int32_t
toUInteger
(
const
char
*
z
,
int32_t
n
,
int32_t
base
,
uint64_t
*
value
);
bool
taosVariantIsValid
(
SVariant
*
pVar
);
void
taosVariantCreate
(
SVariant
*
pVar
,
const
char
*
z
,
int32_t
n
,
int32_t
type
);
void
taosVariantCreateFromBinary
(
SVariant
*
pVar
,
const
char
*
pz
,
size_t
len
,
uint32_t
type
);
void
taosVariantDestroy
(
SVariant
*
pV
);
...
...
@@ -59,10 +58,10 @@ int32_t taosVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool
#endif
int32_t
taosVariantTypeSetType
(
SVariant
*
pVariant
,
char
type
);
char
*
taosVariantGet
(
SVariant
*
pVar
,
int32_t
type
);
char
*
taosVariantGet
(
SVariant
*
pVar
,
int32_t
type
);
#ifdef __cplusplus
}
#endif
#endif
/*_TD_COMMON_VARIANT_H_*/
#endif
/*_TD_COMMON_VARIANT_H_*/
include/libs/planner/planner.h
浏览文件 @
aa93f393
...
...
@@ -48,7 +48,8 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo
// @pSource one execution location of this group of datasource subplans
int32_t
qSetSubplanExecutionNode
(
SSubplan
*
pSubplan
,
int32_t
groupId
,
SDownstreamSourceNode
*
pSource
);
int32_t
qStmtBindParam
(
SQueryPlan
*
pPlan
,
TAOS_MULTI_BIND
*
pParams
,
int32_t
colIdx
,
uint64_t
queryId
);
int32_t
qStmtBindParam
(
SQueryPlan
*
pPlan
,
TAOS_MULTI_BIND
*
pParams
,
int32_t
colIdx
,
uint64_t
queryId
,
bool
*
pEmptyResult
);
// Convert to subplan to string for the scheduler to send to the executor
int32_t
qSubPlanToString
(
const
SSubplan
*
pSubplan
,
char
**
pStr
,
int32_t
*
pLen
);
...
...
source/client/src/clientStmt.c
浏览文件 @
aa93f393
#include "clientInt.h"
#include "clientLog.h"
#include "clientStmt.h"
#include "tdef.h"
#include "clientStmt.h"
int32_t
stmtSwitchStatus
(
STscStmt
*
pStmt
,
STMT_STATUS
newStatus
)
{
int32_t
code
=
0
;
switch
(
newStatus
)
{
case
STMT_PREPARE
:
break
;
...
...
@@ -29,11 +30,11 @@ int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) {
if
(
STMT_STATUS_EQ
(
INIT
)
||
STMT_STATUS_EQ
(
BIND_COL
))
{
code
=
TSDB_CODE_TSC_STMT_API_ERROR
;
}
/*
if ((pStmt->sql.type == STMT_TYPE_MULTI_INSERT) && ()) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
*/
/*
if ((pStmt->sql.type == STMT_TYPE_MULTI_INSERT) && ()) {
code = TSDB_CODE_TSC_STMT_API_ERROR;
}
*/
break
;
case
STMT_BIND_COL
:
if
(
STMT_STATUS_EQ
(
INIT
)
||
STMT_STATUS_EQ
(
BIND
))
{
...
...
@@ -62,8 +63,7 @@ int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) {
return
TSDB_CODE_SUCCESS
;
}
int32_t
stmtGetTbName
(
TAOS_STMT
*
stmt
,
char
**
tbName
)
{
int32_t
stmtGetTbName
(
TAOS_STMT
*
stmt
,
char
**
tbName
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
pStmt
->
sql
.
type
=
STMT_TYPE_MULTI_INSERT
;
...
...
@@ -79,10 +79,10 @@ int32_t stmtGetTbName(TAOS_STMT *stmt, char **tbName) {
}
int32_t
stmtBackupQueryFields
(
STscStmt
*
pStmt
)
{
SStmtQueryResInfo
*
pRes
=
&
pStmt
->
sql
.
queryRes
;
SStmtQueryResInfo
*
pRes
=
&
pStmt
->
sql
.
queryRes
;
pRes
->
numOfCols
=
pStmt
->
exec
.
pRequest
->
body
.
resInfo
.
numOfCols
;
pRes
->
precision
=
pStmt
->
exec
.
pRequest
->
body
.
resInfo
.
precision
;
int32_t
size
=
pRes
->
numOfCols
*
sizeof
(
TAOS_FIELD
);
pRes
->
fields
=
taosMemoryMalloc
(
size
);
pRes
->
userFields
=
taosMemoryMalloc
(
size
);
...
...
@@ -96,9 +96,9 @@ int32_t stmtBackupQueryFields(STscStmt* pStmt) {
}
int32_t
stmtRestoreQueryFields
(
STscStmt
*
pStmt
)
{
SStmtQueryResInfo
*
pRes
=
&
pStmt
->
sql
.
queryRes
;
int32_t
size
=
pRes
->
numOfCols
*
sizeof
(
TAOS_FIELD
);
SStmtQueryResInfo
*
pRes
=
&
pStmt
->
sql
.
queryRes
;
int32_t
size
=
pRes
->
numOfCols
*
sizeof
(
TAOS_FIELD
);
pStmt
->
exec
.
pRequest
->
body
.
resInfo
.
numOfCols
=
pRes
->
numOfCols
;
pStmt
->
exec
.
pRequest
->
body
.
resInfo
.
precision
=
pRes
->
precision
;
...
...
@@ -167,7 +167,7 @@ int32_t stmtGetExecInfo(TAOS_STMT* stmt, SHashObj** pVgHash, SHashObj** pBlockHa
return
TSDB_CODE_SUCCESS
;
}
int32_t
stmtCacheBlock
(
STscStmt
*
pStmt
)
{
int32_t
stmtCacheBlock
(
STscStmt
*
pStmt
)
{
if
(
pStmt
->
sql
.
type
!=
STMT_TYPE_MULTI_INSERT
)
{
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -185,8 +185,8 @@ int32_t stmtCacheBlock(STscStmt *pStmt) {
STMT_ERR_RET
(
qCloneStmtDataBlock
(
&
pDst
,
*
pSrc
));
SStmtTableCache
cache
=
{
.
pDataBlock
=
pDst
,
.
boundTags
=
pStmt
->
bInfo
.
boundTags
,
.
pDataBlock
=
pDst
,
.
boundTags
=
pStmt
->
bInfo
.
boundTags
,
};
if
(
taosHashPut
(
pStmt
->
sql
.
pTableCache
,
&
cacheUid
,
sizeof
(
cacheUid
),
&
cache
,
sizeof
(
cache
)))
{
...
...
@@ -213,11 +213,11 @@ int32_t stmtParseSql(STscStmt* pStmt) {
if
(
NULL
==
pStmt
->
exec
.
pRequest
)
{
STMT_ERR_RET
(
buildRequest
(
pStmt
->
taos
,
pStmt
->
sql
.
sqlStr
,
pStmt
->
sql
.
sqlLen
,
&
pStmt
->
exec
.
pRequest
));
}
STMT_ERR_RET
(
parseSql
(
pStmt
->
exec
.
pRequest
,
false
,
&
pStmt
->
sql
.
pQuery
,
&
stmtCb
));
pStmt
->
bInfo
.
needParse
=
false
;
switch
(
nodeType
(
pStmt
->
sql
.
pQuery
->
pRoot
))
{
case
QUERY_NODE_VNODE_MODIF_STMT
:
if
(
0
==
pStmt
->
sql
.
type
)
{
...
...
@@ -267,7 +267,7 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool freeRequest) {
if
(
keepTable
&&
(
strlen
(
pStmt
->
bInfo
.
tbFName
)
==
keyLen
)
&&
strncmp
(
pStmt
->
bInfo
.
tbFName
,
key
,
keyLen
)
==
0
)
{
STMT_ERR_RET
(
qResetStmtDataBlock
(
pBlocks
,
true
));
pIter
=
taosHashIterate
(
pStmt
->
exec
.
pBlockHash
,
pIter
);
continue
;
}
...
...
@@ -299,15 +299,15 @@ int32_t stmtCleanSQLInfo(STscStmt* pStmt) {
qDestroyQuery
(
pStmt
->
sql
.
pQuery
);
qDestroyQueryPlan
(
pStmt
->
sql
.
pQueryPlan
);
taosArrayDestroy
(
pStmt
->
sql
.
nodeList
);
void
*
pIter
=
taosHashIterate
(
pStmt
->
sql
.
pTableCache
,
NULL
);
void
*
pIter
=
taosHashIterate
(
pStmt
->
sql
.
pTableCache
,
NULL
);
while
(
pIter
)
{
SStmtTableCache
*
pCache
=
(
SStmtTableCache
*
)
pIter
;
SStmtTableCache
*
pCache
=
(
SStmtTableCache
*
)
pIter
;
qDestroyStmtDataBlock
(
pCache
->
pDataBlock
);
destroyBoundColumnInfo
(
pCache
->
boundTags
);
taosMemoryFreeClear
(
pCache
->
boundTags
);
pIter
=
taosHashIterate
(
pStmt
->
sql
.
pTableCache
,
pIter
);
}
taosHashCleanup
(
pStmt
->
sql
.
pTableCache
);
...
...
@@ -388,15 +388,15 @@ int32_t stmtGetFromCache(STscStmt* pStmt) {
int32_t
code
=
catalogGetTableMeta
(
pStmt
->
pCatalog
,
pStmt
->
taos
->
pAppInfo
->
pTransporter
,
&
ep
,
&
pStmt
->
bInfo
.
sname
,
&
pTableMeta
);
if
(
TSDB_CODE_PAR_TABLE_NOT_EXIST
==
code
)
{
STMT_ERR_RET
(
stmtCleanBindInfo
(
pStmt
));
return
TSDB_CODE_SUCCESS
;
}
STMT_ERR_RET
(
code
);
uint64_t
uid
=
pTableMeta
->
uid
;
uint64_t
suid
=
pTableMeta
->
suid
;
int8_t
tableType
=
pTableMeta
->
tableType
;
int8_t
tableType
=
pTableMeta
->
tableType
;
taosMemoryFree
(
pTableMeta
);
uint64_t
cacheUid
=
(
TSDB_CHILD_TABLE
==
tableType
)
?
suid
:
uid
;
...
...
@@ -413,9 +413,9 @@ int32_t stmtGetFromCache(STscStmt* pStmt) {
STMT_ERR_RET
(
TSDB_CODE_TSC_APP_ERROR
);
}
pStmt
->
bInfo
.
needParse
=
false
;
pStmt
->
bInfo
.
tbUid
=
uid
;
pStmt
->
bInfo
.
tbSuid
=
suid
;
pStmt
->
bInfo
.
tbType
=
tableType
;
...
...
@@ -441,7 +441,7 @@ int32_t stmtGetFromCache(STscStmt* pStmt) {
if
(
taosHashPut
(
pStmt
->
exec
.
pBlockHash
,
pStmt
->
bInfo
.
tbFName
,
strlen
(
pStmt
->
bInfo
.
tbFName
),
&
pNewBlock
,
POINTER_BYTES
))
{
STMT_ERR_RET
(
TSDB_CODE_OUT_OF_MEMORY
);
}
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -464,9 +464,8 @@ int32_t stmtResetStmt(STscStmt* pStmt) {
return
TSDB_CODE_SUCCESS
;
}
TAOS_STMT
*
stmtInit
(
TAOS
*
taos
)
{
STscObj
*
pObj
=
(
STscObj
*
)
taos
;
TAOS_STMT
*
stmtInit
(
TAOS
*
taos
)
{
STscObj
*
pObj
=
(
STscObj
*
)
taos
;
STscStmt
*
pStmt
=
NULL
;
pStmt
=
taosMemoryCalloc
(
1
,
sizeof
(
STscStmt
));
...
...
@@ -485,11 +484,11 @@ TAOS_STMT *stmtInit(TAOS *taos) {
pStmt
->
taos
=
pObj
;
pStmt
->
bInfo
.
needParse
=
true
;
pStmt
->
sql
.
status
=
STMT_INIT
;
return
pStmt
;
}
int
stmtPrepare
(
TAOS_STMT
*
stmt
,
const
char
*
sql
,
unsigned
long
length
)
{
int
stmtPrepare
(
TAOS_STMT
*
stmt
,
const
char
*
sql
,
unsigned
long
length
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
if
(
pStmt
->
sql
.
status
>=
STMT_PREPARE
)
{
...
...
@@ -501,15 +500,14 @@ int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length) {
if
(
length
<=
0
)
{
length
=
strlen
(
sql
);
}
pStmt
->
sql
.
sqlStr
=
strndup
(
sql
,
length
);
pStmt
->
sql
.
sqlLen
=
length
;
return
TSDB_CODE_SUCCESS
;
}
int
stmtSetTbName
(
TAOS_STMT
*
stmt
,
const
char
*
tbName
)
{
int
stmtSetTbName
(
TAOS_STMT
*
stmt
,
const
char
*
tbName
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
STMT_ERR_RET
(
stmtSwitchStatus
(
pStmt
,
STMT_SETTBNAME
));
...
...
@@ -538,7 +536,7 @@ int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) {
return
TSDB_CODE_SUCCESS
;
}
int
stmtSetTbTags
(
TAOS_STMT
*
stmt
,
TAOS_MULTI_BIND
*
tags
)
{
int
stmtSetTbTags
(
TAOS_STMT
*
stmt
,
TAOS_MULTI_BIND
*
tags
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
STMT_ERR_RET
(
stmtSwitchStatus
(
pStmt
,
STMT_SETTAGS
));
...
...
@@ -556,14 +554,14 @@ int stmtSetTbTags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) {
tscError
(
"table %s not found in exec blockHash"
,
pStmt
->
bInfo
.
tbFName
);
STMT_ERR_RET
(
TSDB_CODE_QRY_APP_ERROR
);
}
STMT_ERR_RET
(
qBindStmtTagsValue
(
*
pDataBlock
,
pStmt
->
bInfo
.
boundTags
,
pStmt
->
bInfo
.
tbSuid
,
pStmt
->
bInfo
.
sname
.
tname
,
tags
,
pStmt
->
exec
.
pRequest
->
msgBuf
,
pStmt
->
exec
.
pRequest
->
msgBufLen
));
STMT_ERR_RET
(
qBindStmtTagsValue
(
*
pDataBlock
,
pStmt
->
bInfo
.
boundTags
,
pStmt
->
bInfo
.
tbSuid
,
pStmt
->
bInfo
.
sname
.
tname
,
tags
,
pStmt
->
exec
.
pRequest
->
msgBuf
,
pStmt
->
exec
.
pRequest
->
msgBufLen
));
return
TSDB_CODE_SUCCESS
;
}
int32_t
stmtFetchTagFields
(
STscStmt
*
pStmt
,
int32_t
*
fieldNum
,
TAOS_FIELD
**
fields
)
{
int32_t
stmtFetchTagFields
(
STscStmt
*
pStmt
,
int32_t
*
fieldNum
,
TAOS_FIELD
**
fields
)
{
if
(
STMT_TYPE_QUERY
==
pStmt
->
sql
.
type
)
{
tscError
(
"invalid operation to get query tag fileds"
);
STMT_ERR_RET
(
TSDB_CODE_TSC_STMT_API_ERROR
);
...
...
@@ -580,7 +578,7 @@ int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fiel
return
TSDB_CODE_SUCCESS
;
}
int32_t
stmtFetchColFields
(
STscStmt
*
pStmt
,
int32_t
*
fieldNum
,
TAOS_FIELD
**
fields
)
{
int32_t
stmtFetchColFields
(
STscStmt
*
pStmt
,
int32_t
*
fieldNum
,
TAOS_FIELD
**
fields
)
{
if
(
STMT_TYPE_QUERY
==
pStmt
->
sql
.
type
)
{
tscError
(
"invalid operation to get query column fileds"
);
STMT_ERR_RET
(
TSDB_CODE_TSC_STMT_API_ERROR
);
...
...
@@ -594,13 +592,14 @@ int32_t stmtFetchColFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fiel
STMT_ERR_RET
(
qBuildStmtColFields
(
*
pDataBlock
,
fieldNum
,
fields
));
return
TSDB_CODE_SUCCESS
;
return
TSDB_CODE_SUCCESS
;
}
int
stmtBindBatch
(
TAOS_STMT
*
stmt
,
TAOS_MULTI_BIND
*
bind
,
int32_t
colIdx
)
{
int
stmtBindBatch
(
TAOS_STMT
*
stmt
,
TAOS_MULTI_BIND
*
bind
,
int32_t
colIdx
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
if
(
pStmt
->
bInfo
.
needParse
&&
pStmt
->
sql
.
runTimes
&&
pStmt
->
sql
.
type
>
0
&&
STMT_TYPE_MULTI_INSERT
!=
pStmt
->
sql
.
type
)
{
if
(
pStmt
->
bInfo
.
needParse
&&
pStmt
->
sql
.
runTimes
&&
pStmt
->
sql
.
type
>
0
&&
STMT_TYPE_MULTI_INSERT
!=
pStmt
->
sql
.
type
)
{
pStmt
->
bInfo
.
needParse
=
false
;
}
...
...
@@ -608,7 +607,7 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
taos_free_result
(
pStmt
->
exec
.
pRequest
);
pStmt
->
exec
.
pRequest
=
NULL
;
}
if
(
NULL
==
pStmt
->
exec
.
pRequest
)
{
STMT_ERR_RET
(
buildRequest
(
pStmt
->
taos
,
pStmt
->
sql
.
sqlStr
,
pStmt
->
sql
.
sqlLen
,
&
pStmt
->
exec
.
pRequest
));
}
...
...
@@ -628,8 +627,9 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
}
else
{
STMT_ERR_RET
(
stmtRestoreQueryFields
(
pStmt
));
}
STMT_RET
(
qStmtBindParam
(
pStmt
->
sql
.
pQueryPlan
,
bind
,
colIdx
,
pStmt
->
exec
.
pRequest
->
requestId
));
bool
emptyResult
=
false
;
STMT_RET
(
qStmtBindParam
(
pStmt
->
sql
.
pQueryPlan
,
bind
,
colIdx
,
pStmt
->
exec
.
pRequest
->
requestId
,
&
emptyResult
));
}
STableDataBlocks
**
pDataBlock
=
(
STableDataBlocks
**
)
taosHashGet
(
pStmt
->
exec
.
pBlockHash
,
pStmt
->
bInfo
.
tbFName
,
strlen
(
pStmt
->
bInfo
.
tbFName
));
...
...
@@ -651,25 +651,25 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) {
}
pStmt
->
bInfo
.
sBindLastIdx
=
colIdx
;
if
(
0
==
colIdx
)
{
pStmt
->
bInfo
.
sBindRowNum
=
bind
->
num
;
}
qBindStmtSingleColValue
(
*
pDataBlock
,
bind
,
pStmt
->
exec
.
pRequest
->
msgBuf
,
pStmt
->
exec
.
pRequest
->
msgBufLen
,
colIdx
,
pStmt
->
bInfo
.
sBindRowNum
);
qBindStmtSingleColValue
(
*
pDataBlock
,
bind
,
pStmt
->
exec
.
pRequest
->
msgBuf
,
pStmt
->
exec
.
pRequest
->
msgBufLen
,
colIdx
,
pStmt
->
bInfo
.
sBindRowNum
);
}
return
TSDB_CODE_SUCCESS
;
}
int
stmtAddBatch
(
TAOS_STMT
*
stmt
)
{
int
stmtAddBatch
(
TAOS_STMT
*
stmt
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
STMT_ERR_RET
(
stmtSwitchStatus
(
pStmt
,
STMT_ADD_BATCH
));
STMT_ERR_RET
(
stmtCacheBlock
(
pStmt
));
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -751,7 +751,7 @@ int stmtExec(TAOS_STMT *stmt) {
STMT_ERR_RET
(
TSDB_CODE_NEED_RETRY
);
}
}
STMT_ERR_JRET
(
pStmt
->
exec
.
pRequest
->
code
);
pStmt
->
exec
.
affectedRows
=
taos_affected_rows
(
pStmt
->
exec
.
pRequest
);
...
...
@@ -771,12 +771,11 @@ _return:
}
++
pStmt
->
sql
.
runTimes
;
STMT_RET
(
code
);
}
int
stmtClose
(
TAOS_STMT
*
stmt
)
{
int
stmtClose
(
TAOS_STMT
*
stmt
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
STMT_RET
(
stmtCleanSQLInfo
(
pStmt
));
...
...
@@ -784,11 +783,11 @@ int stmtClose(TAOS_STMT *stmt) {
taosMemoryFree
(
stmt
);
}
const
char
*
stmtErrstr
(
TAOS_STMT
*
stmt
)
{
const
char
*
stmtErrstr
(
TAOS_STMT
*
stmt
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
if
(
stmt
==
NULL
||
NULL
==
pStmt
->
exec
.
pRequest
)
{
return
(
char
*
)
tstrerror
(
terrno
);
return
(
char
*
)
tstrerror
(
terrno
);
}
pStmt
->
exec
.
pRequest
->
code
=
terrno
;
...
...
@@ -796,15 +795,11 @@ const char *stmtErrstr(TAOS_STMT *stmt) {
return
taos_errstr
(
pStmt
->
exec
.
pRequest
);
}
int
stmtAffectedRows
(
TAOS_STMT
*
stmt
)
{
return
((
STscStmt
*
)
stmt
)
->
affectedRows
;
}
int
stmtAffectedRows
(
TAOS_STMT
*
stmt
)
{
return
((
STscStmt
*
)
stmt
)
->
affectedRows
;
}
int
stmtAffectedRowsOnce
(
TAOS_STMT
*
stmt
)
{
return
((
STscStmt
*
)
stmt
)
->
exec
.
affectedRows
;
}
int
stmtAffectedRowsOnce
(
TAOS_STMT
*
stmt
)
{
return
((
STscStmt
*
)
stmt
)
->
exec
.
affectedRows
;
}
int
stmtIsInsert
(
TAOS_STMT
*
stmt
,
int
*
insert
)
{
int
stmtIsInsert
(
TAOS_STMT
*
stmt
,
int
*
insert
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
if
(
pStmt
->
sql
.
type
)
{
...
...
@@ -812,16 +807,17 @@ int stmtIsInsert(TAOS_STMT *stmt, int *insert) {
}
else
{
*
insert
=
isInsertSql
(
pStmt
->
sql
.
sqlStr
,
0
);
}
return
TSDB_CODE_SUCCESS
;
}
int
stmtGetParamNum
(
TAOS_STMT
*
stmt
,
int
*
nums
)
{
int
stmtGetParamNum
(
TAOS_STMT
*
stmt
,
int
*
nums
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
STMT_ERR_RET
(
stmtSwitchStatus
(
pStmt
,
STMT_FETCH_FIELDS
));
if
(
pStmt
->
bInfo
.
needParse
&&
pStmt
->
sql
.
runTimes
&&
pStmt
->
sql
.
type
>
0
&&
STMT_TYPE_MULTI_INSERT
!=
pStmt
->
sql
.
type
)
{
if
(
pStmt
->
bInfo
.
needParse
&&
pStmt
->
sql
.
runTimes
&&
pStmt
->
sql
.
type
>
0
&&
STMT_TYPE_MULTI_INSERT
!=
pStmt
->
sql
.
type
)
{
pStmt
->
bInfo
.
needParse
=
false
;
}
...
...
@@ -829,7 +825,7 @@ int stmtGetParamNum(TAOS_STMT *stmt, int *nums) {
taos_free_result
(
pStmt
->
exec
.
pRequest
);
pStmt
->
exec
.
pRequest
=
NULL
;
}
if
(
NULL
==
pStmt
->
exec
.
pRequest
)
{
STMT_ERR_RET
(
buildRequest
(
pStmt
->
taos
,
pStmt
->
sql
.
sqlStr
,
pStmt
->
sql
.
sqlLen
,
&
pStmt
->
exec
.
pRequest
));
}
...
...
@@ -847,16 +843,16 @@ int stmtGetParamNum(TAOS_STMT *stmt, int *nums) {
}
else
{
STMT_ERR_RET
(
stmtRestoreQueryFields
(
pStmt
));
}
*
nums
=
taosArrayGetSize
(
pStmt
->
sql
.
pQueryPlan
->
pPlaceholderValues
);
}
else
{
STMT_ERR_RET
(
stmtFetchColFields
(
stmt
,
nums
,
NULL
));
}
return
TSDB_CODE_SUCCESS
;
}
TAOS_RES
*
stmtUseResult
(
TAOS_STMT
*
stmt
)
{
TAOS_RES
*
stmtUseResult
(
TAOS_STMT
*
stmt
)
{
STscStmt
*
pStmt
=
(
STscStmt
*
)
stmt
;
if
(
STMT_TYPE_QUERY
!=
pStmt
->
sql
.
type
)
{
...
...
@@ -866,6 +862,3 @@ TAOS_RES *stmtUseResult(TAOS_STMT *stmt) {
return
pStmt
->
exec
.
pRequest
;
}
source/common/src/tvariant.c
浏览文件 @
aa93f393
...
...
@@ -35,104 +35,36 @@
assert(0); \
} while (0)
int32_t
toInteger
(
const
char
*
z
,
int32_t
n
,
int32_t
base
,
int64_t
*
value
,
bool
*
isSigned
)
{
int32_t
toInteger
(
const
char
*
z
,
int32_t
n
,
int32_t
base
,
int64_t
*
value
)
{
errno
=
0
;
char
*
endPtr
=
NULL
;
int32_t
index
=
0
;
bool
specifiedSign
=
(
z
[
0
]
==
'+'
||
z
[
0
]
==
'-'
);
if
(
specifiedSign
)
{
*
isSigned
=
true
;
index
=
1
;
}
uint64_t
val
=
strtoull
(
&
z
[
index
],
&
endPtr
,
base
);
if
(
errno
==
ERANGE
||
errno
==
EINVAL
)
{
*
value
=
strtoll
(
z
,
&
endPtr
,
base
);
if
(
errno
==
ERANGE
||
errno
==
EINVAL
||
endPtr
-
z
!=
n
)
{
errno
=
0
;
return
-
1
;
}
if
(
specifiedSign
&&
val
>
INT64_MAX
)
{
return
-
1
;
}
if
(
endPtr
-
&
z
[
index
]
!=
n
-
index
)
{
return
-
1
;
}
*
isSigned
=
specifiedSign
||
(
val
<=
INT64_MAX
);
if
(
*
isSigned
)
{
*
value
=
(
z
[
0
]
==
'-'
)
?
-
val
:
val
;
}
else
{
*
(
uint64_t
*
)
value
=
val
;
}
return
0
;
}
void
taosVariantCreate
(
SVariant
*
pVar
,
const
char
*
z
,
int32_t
n
,
int32_t
type
)
{
int32_t
ret
=
0
;
memset
(
pVar
,
0
,
sizeof
(
SVariant
));
switch
(
type
)
{
case
TSDB_DATA_TYPE_BOOL
:
{
if
(
strncasecmp
(
z
,
"true"
,
4
)
==
0
)
{
pVar
->
i
=
TSDB_TRUE
;
}
else
if
(
strncasecmp
(
z
,
"false"
,
5
)
==
0
)
{
pVar
->
i
=
TSDB_FALSE
;
}
else
{
return
;
}
break
;
}
case
TSDB_DATA_TYPE_TINYINT
:
case
TSDB_DATA_TYPE_SMALLINT
:
case
TSDB_DATA_TYPE_BIGINT
:
case
TSDB_DATA_TYPE_INT
:
{
bool
sign
=
true
;
int32_t
base
=
10
;
if
(
type
==
TK_NK_HEX
)
{
base
=
16
;
}
else
if
(
type
==
TK_NK_OCT
)
{
base
=
8
;
}
else
if
(
type
==
TK_NK_BIN
)
{
base
=
2
;
}
ret
=
toInteger
(
z
,
n
,
base
,
&
pVar
->
i
,
&
sign
);
if
(
ret
!=
0
)
{
pVar
->
nType
=
-
1
;
// -1 means error type
return
;
}
int32_t
toUInteger
(
const
char
*
z
,
int32_t
n
,
int32_t
base
,
uint64_t
*
value
)
{
errno
=
0
;
char
*
endPtr
=
NULL
;
pVar
->
nType
=
(
sign
)
?
TSDB_DATA_TYPE_BIGINT
:
TSDB_DATA_TYPE_UBIGINT
;
break
;
}
case
TSDB_DATA_TYPE_DOUBLE
:
case
TSDB_DATA_TYPE_FLOAT
:
{
pVar
->
d
=
strtod
(
z
,
NULL
);
break
;
}
case
TSDB_DATA_TYPE_BINARY
:
{
pVar
->
pz
=
strndup
(
z
,
n
);
//pVar->nLen = strRmquote(pVar->pz, n);
break
;
}
case
TSDB_DATA_TYPE_TIMESTAMP
:
{
assert
(
0
);
pVar
->
i
=
taosGetTimestamp
(
TSDB_TIME_PRECISION_NANO
);
break
;
}
const
char
*
p
=
z
;
while
(
*
p
!=
0
&&
*
p
==
' '
)
p
++
;
if
(
*
p
!=
0
&&
*
p
==
'-'
)
{
return
-
1
;
}
default:
{
// nType == 0 means the null value
type
=
TSDB_DATA_TYPE_NULL
;
}
*
value
=
strtoull
(
z
,
&
endPtr
,
base
);
if
(
errno
==
ERANGE
||
errno
==
EINVAL
||
endPtr
-
z
!=
n
)
{
errno
=
0
;
return
-
1
;
}
pVar
->
nType
=
type
;
return
0
;
}
/**
...
...
@@ -461,7 +393,7 @@ static int32_t toNchar(SVariant *pVariant, char **pDest, int32_t *pDestSize) {
if
(
*
pDest
==
pVariant
->
pz
)
{
TdUcs4
*
pWStr
=
taosMemoryCalloc
(
1
,
(
nLen
+
1
)
*
TSDB_NCHAR_SIZE
);
bool
ret
=
taosMbsToUcs4
(
pDst
,
nLen
,
pWStr
,
(
nLen
+
1
)
*
TSDB_NCHAR_SIZE
,
NULL
);
bool
ret
=
taosMbsToUcs4
(
pDst
,
nLen
,
pWStr
,
(
nLen
+
1
)
*
TSDB_NCHAR_SIZE
,
NULL
);
if
(
!
ret
)
{
taosMemoryFreeClear
(
pWStr
);
return
-
1
;
...
...
@@ -483,7 +415,7 @@ static int32_t toNchar(SVariant *pVariant, char **pDest, int32_t *pDestSize) {
}
else
{
int32_t
output
=
0
;
bool
ret
=
taosMbsToUcs4
(
pDst
,
nLen
,
(
TdUcs4
*
)
*
pDest
,
(
nLen
+
1
)
*
TSDB_NCHAR_SIZE
,
&
output
);
bool
ret
=
taosMbsToUcs4
(
pDst
,
nLen
,
(
TdUcs4
*
)
*
pDest
,
(
nLen
+
1
)
*
TSDB_NCHAR_SIZE
,
&
output
);
if
(
!
ret
)
{
return
-
1
;
}
...
...
@@ -518,9 +450,9 @@ static FORCE_INLINE int32_t convertToInteger(SVariant *pVariant, int64_t *result
}
else
if
(
IS_UNSIGNED_NUMERIC_TYPE
(
pVariant
->
nType
))
{
*
result
=
pVariant
->
u
;
}
else
if
(
IS_FLOAT_TYPE
(
pVariant
->
nType
))
{
*
result
=
(
int64_t
)
pVariant
->
d
;
*
result
=
(
int64_t
)
pVariant
->
d
;
}
else
{
//TODO: handling var types
//
TODO: handling var types
}
#if 0
errno = 0;
...
...
@@ -909,7 +841,7 @@ int32_t tVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool inc
return
-
1
;
}
}
else
{
tasoUcs4Copy
((
TdUcs4
*
)
payload
,
pVariant
->
ucs4
,
pVariant
->
nLen
);
tasoUcs4Copy
((
TdUcs4
*
)
payload
,
pVariant
->
ucs4
,
pVariant
->
nLen
);
}
}
}
else
{
...
...
@@ -1026,7 +958,7 @@ int32_t taosVariantTypeSetType(SVariant *pVariant, char type) {
return
0
;
}
char
*
taosVariantGet
(
SVariant
*
pVar
,
int32_t
type
)
{
char
*
taosVariantGet
(
SVariant
*
pVar
,
int32_t
type
)
{
switch
(
type
)
{
case
TSDB_DATA_TYPE_BOOL
:
case
TSDB_DATA_TYPE_TINYINT
:
...
...
source/common/test/commonTests.cpp
浏览文件 @
aa93f393
...
...
@@ -8,12 +8,11 @@
#pragma GCC diagnostic ignored "-Wsign-compare"
#include "os.h"
#include "taos.h"
#include "tcommon.h"
#include "tdatablock.h"
#include "tcommon.h"
#include "taos.h"
#include "tvariant.h"
#include "tdef.h"
#include "tvariant.h"
namespace
{
//
...
...
@@ -29,72 +28,62 @@ TEST(testCase, toInteger_test) {
uint32_t
type
=
0
;
int64_t
val
=
0
;
bool
sign
=
true
;
int32_t
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
int32_t
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
123
);
ASSERT_EQ
(
sign
,
true
);
s
=
"9223372036854775807"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
9223372036854775807
);
ASSERT_EQ
(
sign
,
true
);
s
=
"9323372036854775807"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
9323372036854775807u
);
ASSERT_EQ
(
sign
,
false
);
s
=
"-9323372036854775807"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
-
1
);
s
=
"-1"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
-
1
);
ASSERT_EQ
(
sign
,
true
);
s
=
"-9223372036854775807"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
-
9223372036854775807
);
ASSERT_EQ
(
sign
,
true
);
s
=
"1000u"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
-
1
);
s
=
"0x10"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
16
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
16
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
16
);
ASSERT_EQ
(
sign
,
true
);
s
=
"110"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
2
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
2
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
6
);
ASSERT_EQ
(
sign
,
true
);
s
=
"110"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
8
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
8
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
72
);
ASSERT_EQ
(
sign
,
true
);
//18446744073709551615 UINT64_MAX
//
18446744073709551615 UINT64_MAX
s
=
"18446744073709551615"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
0
);
ASSERT_EQ
(
val
,
18446744073709551615u
);
ASSERT_EQ
(
sign
,
false
);
s
=
"18446744073709551616"
;
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
,
&
sign
);
ret
=
toInteger
(
s
,
strlen
(
s
),
10
,
&
val
);
ASSERT_EQ
(
ret
,
-
1
);
}
...
...
@@ -108,8 +97,8 @@ TEST(testCase, Datablock_test) {
infoData
.
info
.
type
=
TSDB_DATA_TYPE_INT
;
infoData
.
info
.
colId
=
1
;
infoData
.
pData
=
(
char
*
)
taosMemoryCalloc
(
40
,
infoData
.
info
.
bytes
);
infoData
.
nullbitmap
=
(
char
*
)
taosMemoryCalloc
(
1
,
sizeof
(
char
)
*
(
40
/
8
));
infoData
.
pData
=
(
char
*
)
taosMemoryCalloc
(
40
,
infoData
.
info
.
bytes
);
infoData
.
nullbitmap
=
(
char
*
)
taosMemoryCalloc
(
1
,
sizeof
(
char
)
*
(
40
/
8
));
taosArrayPush
(
b
->
pDataBlock
,
&
infoData
);
SColumnInfoData
infoData1
=
{
0
};
...
...
@@ -117,36 +106,36 @@ TEST(testCase, Datablock_test) {
infoData1
.
info
.
type
=
TSDB_DATA_TYPE_BINARY
;
infoData1
.
info
.
colId
=
2
;
infoData1
.
varmeta
.
offset
=
(
int32_t
*
)
taosMemoryCalloc
(
40
,
sizeof
(
uint32_t
));
infoData1
.
varmeta
.
offset
=
(
int32_t
*
)
taosMemoryCalloc
(
40
,
sizeof
(
uint32_t
));
taosArrayPush
(
b
->
pDataBlock
,
&
infoData1
);
char
*
str
=
"the value of: %d"
;
char
buf
[
128
]
=
{
0
};
char
varbuf
[
128
]
=
{
0
};
char
buf
[
128
]
=
{
0
};
char
varbuf
[
128
]
=
{
0
};
for
(
int32_t
i
=
0
;
i
<
40
;
++
i
)
{
SColumnInfoData
*
p0
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
0
);
SColumnInfoData
*
p1
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
1
);
for
(
int32_t
i
=
0
;
i
<
40
;
++
i
)
{
SColumnInfoData
*
p0
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
0
);
SColumnInfoData
*
p1
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
1
);
if
(
i
&
0x01
)
{
if
(
i
&
0x01
)
{
int32_t
len
=
sprintf
(
buf
,
str
,
i
);
STR_TO_VARSTR
(
varbuf
,
buf
)
colDataAppend
(
p0
,
i
,
(
const
char
*
)
&
i
,
false
);
colDataAppend
(
p1
,
i
,
(
const
char
*
)
varbuf
,
false
);
colDataAppend
(
p0
,
i
,
(
const
char
*
)
&
i
,
false
);
colDataAppend
(
p1
,
i
,
(
const
char
*
)
varbuf
,
false
);
memset
(
varbuf
,
0
,
sizeof
(
varbuf
));
memset
(
buf
,
0
,
sizeof
(
buf
));
}
else
{
colDataAppend
(
p0
,
i
,
(
const
char
*
)
&
i
,
true
);
colDataAppend
(
p1
,
i
,
(
const
char
*
)
varbuf
,
true
);
colDataAppend
(
p0
,
i
,
(
const
char
*
)
&
i
,
true
);
colDataAppend
(
p1
,
i
,
(
const
char
*
)
varbuf
,
true
);
}
b
->
info
.
rows
++
;
}
SColumnInfoData
*
p0
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
0
);
SColumnInfoData
*
p1
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
1
);
for
(
int32_t
i
=
0
;
i
<
40
;
++
i
)
{
SColumnInfoData
*
p0
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
0
);
SColumnInfoData
*
p1
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
1
);
for
(
int32_t
i
=
0
;
i
<
40
;
++
i
)
{
if
(
i
&
0x01
)
{
ASSERT_EQ
(
colDataIsNull_f
(
p0
->
nullbitmap
,
i
),
false
);
ASSERT_EQ
(
colDataIsNull
(
p1
,
b
->
info
.
rows
,
i
,
nullptr
),
false
);
...
...
@@ -158,7 +147,7 @@ TEST(testCase, Datablock_test) {
}
}
printf
(
"binary column length:%d
\n
"
,
*
(
int32_t
*
)
p1
->
pData
);
printf
(
"binary column length:%d
\n
"
,
*
(
int32_t
*
)
p1
->
pData
);
ASSERT_EQ
(
blockDataGetNumOfCols
(
b
),
2
);
ASSERT_EQ
(
blockDataGetNumOfRows
(
b
),
40
);
...
...
@@ -166,8 +155,8 @@ TEST(testCase, Datablock_test) {
char
*
pData
=
colDataGetData
(
p1
,
3
);
printf
(
"the second row of binary:%s, length:%d
\n
"
,
(
char
*
)
varDataVal
(
pData
),
varDataLen
(
pData
));
SArray
*
pOrderInfo
=
taosArrayInit
(
3
,
sizeof
(
SBlockOrderInfo
));
SBlockOrderInfo
order
=
{
true
,
TSDB_ORDER_ASC
,
0
,
NULL
};
SArray
*
pOrderInfo
=
taosArrayInit
(
3
,
sizeof
(
SBlockOrderInfo
));
SBlockOrderInfo
order
=
{
true
,
TSDB_ORDER_ASC
,
0
,
NULL
};
taosArrayPush
(
pOrderInfo
,
&
order
);
blockDataSort
(
b
,
pOrderInfo
);
...
...
@@ -244,8 +233,8 @@ TEST(testCase, var_dataBlock_split_test) {
infoData
.
info
.
type
=
TSDB_DATA_TYPE_INT
;
infoData
.
info
.
colId
=
1
;
infoData
.
pData
=
(
char
*
)
taosMemoryCalloc
(
numOfRows
,
infoData
.
info
.
bytes
);
infoData
.
nullbitmap
=
(
char
*
)
taosMemoryCalloc
(
1
,
sizeof
(
char
)
*
(
numOfRows
/
8
));
infoData
.
pData
=
(
char
*
)
taosMemoryCalloc
(
numOfRows
,
infoData
.
info
.
bytes
);
infoData
.
nullbitmap
=
(
char
*
)
taosMemoryCalloc
(
1
,
sizeof
(
char
)
*
(
numOfRows
/
8
));
taosArrayPush
(
b
->
pDataBlock
,
&
infoData
);
SColumnInfoData
infoData1
=
{
0
};
...
...
@@ -253,13 +242,13 @@ TEST(testCase, var_dataBlock_split_test) {
infoData1
.
info
.
type
=
TSDB_DATA_TYPE_BINARY
;
infoData1
.
info
.
colId
=
2
;
infoData1
.
varmeta
.
offset
=
(
int32_t
*
)
taosMemoryCalloc
(
numOfRows
,
sizeof
(
uint32_t
));
infoData1
.
varmeta
.
offset
=
(
int32_t
*
)
taosMemoryCalloc
(
numOfRows
,
sizeof
(
uint32_t
));
taosArrayPush
(
b
->
pDataBlock
,
&
infoData1
);
char
buf
[
41
]
=
{
0
};
char
buf1
[
100
]
=
{
0
};
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
for
(
int32_t
i
=
0
;
i
<
numOfRows
;
++
i
)
{
SColumnInfoData
*
p0
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
0
);
SColumnInfoData
*
p1
=
(
SColumnInfoData
*
)
taosArrayGet
(
b
->
pDataBlock
,
1
);
...
...
@@ -278,10 +267,10 @@ TEST(testCase, var_dataBlock_split_test) {
int32_t
pageSize
=
64
*
1024
;
int32_t
startIndex
=
0
;
int32_t
startIndex
=
0
;
int32_t
stopIndex
=
0
;
int32_t
count
=
1
;
while
(
1
)
{
while
(
1
)
{
blockDataSplitRows
(
b
,
true
,
startIndex
,
&
stopIndex
,
pageSize
);
printf
(
"the %d split, from: %d to %d
\n
"
,
count
++
,
startIndex
,
stopIndex
);
...
...
source/libs/function/src/builtins.c
浏览文件 @
aa93f393
...
...
@@ -239,7 +239,7 @@ static int32_t translateLeastSQR(SFunctionNode* pFunc, char* pErrBuf, int32_t le
}
}
pFunc
->
node
.
resType
=
(
SDataType
)
{
.
bytes
=
64
,
.
type
=
TSDB_DATA_TYPE_BINARY
};
pFunc
->
node
.
resType
=
(
SDataType
)
{.
bytes
=
64
,
.
type
=
TSDB_DATA_TYPE_BINARY
};
return
TSDB_CODE_SUCCESS
;
}
...
...
@@ -1042,26 +1042,6 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = {
.
sprocessFunc
=
timezoneFunction
,
.
finalizeFunc
=
NULL
},
{
.
name
=
"_rowts"
,
.
type
=
FUNCTION_TYPE_ROWTS
,
.
classification
=
FUNC_MGT_PSEUDO_COLUMN_FUNC
,
.
translateFunc
=
translateTimePseudoColumn
,
.
getEnvFunc
=
getTimePseudoFuncEnv
,
.
initFunc
=
NULL
,
.
sprocessFunc
=
NULL
,
.
finalizeFunc
=
NULL
},
{
.
name
=
"_c0"
,
.
type
=
FUNCTION_TYPE_ROWTS
,
.
classification
=
FUNC_MGT_PSEUDO_COLUMN_FUNC
,
.
translateFunc
=
translateTimePseudoColumn
,
.
getEnvFunc
=
getTimePseudoFuncEnv
,
.
initFunc
=
NULL
,
.
sprocessFunc
=
NULL
,
.
finalizeFunc
=
NULL
},
{
.
name
=
"tbname"
,
.
type
=
FUNCTION_TYPE_TBNAME
,
...
...
source/libs/parser/src/parAstCreater.c
浏览文件 @
aa93f393
...
...
@@ -350,7 +350,18 @@ SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft,
createOperatorNode
(
pCxt
,
OP_TYPE_GREATER_THAN
,
nodesCloneNode
(
pExpr
),
pRight
));
}
static
SNode
*
createPrimaryKeyCol
(
SAstCreateContext
*
pCxt
)
{
SColumnNode
*
pCol
=
nodesMakeNode
(
QUERY_NODE_COLUMN
);
CHECK_OUT_OF_MEM
(
pCol
);
pCol
->
colId
=
PRIMARYKEY_TIMESTAMP_COL_ID
;
strcpy
(
pCol
->
colName
,
PK_TS_COL_INTERNAL_NAME
);
return
(
SNode
*
)
pCol
;
}
SNode
*
createFunctionNode
(
SAstCreateContext
*
pCxt
,
const
SToken
*
pFuncName
,
SNodeList
*
pParameterList
)
{
if
(
0
==
strncasecmp
(
"_rowts"
,
pFuncName
->
z
,
pFuncName
->
n
)
||
0
==
strncasecmp
(
"_c0"
,
pFuncName
->
z
,
pFuncName
->
n
))
{
return
createPrimaryKeyCol
(
pCxt
);
}
SFunctionNode
*
func
=
(
SFunctionNode
*
)
nodesMakeNode
(
QUERY_NODE_FUNCTION
);
CHECK_OUT_OF_MEM
(
func
);
strncpy
(
func
->
functionName
,
pFuncName
->
z
,
pFuncName
->
n
);
...
...
@@ -467,13 +478,11 @@ SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode* pGap
SNode
*
createStateWindowNode
(
SAstCreateContext
*
pCxt
,
SNode
*
pExpr
)
{
SStateWindowNode
*
state
=
(
SStateWindowNode
*
)
nodesMakeNode
(
QUERY_NODE_STATE_WINDOW
);
CHECK_OUT_OF_MEM
(
state
);
state
->
pCol
=
nodesMakeNode
(
QUERY_NODE_COLUMN
);
state
->
pCol
=
createPrimaryKeyCol
(
pCxt
);
if
(
NULL
==
state
->
pCol
)
{
nodesDestroyNode
(
state
);
CHECK_OUT_OF_MEM
(
state
->
pCol
);
}
((
SColumnNode
*
)
state
->
pCol
)
->
colId
=
PRIMARYKEY_TIMESTAMP_COL_ID
;
strcpy
(((
SColumnNode
*
)
state
->
pCol
)
->
colName
,
PK_TS_COL_INTERNAL_NAME
);
state
->
pExpr
=
pExpr
;
return
(
SNode
*
)
state
;
}
...
...
@@ -482,13 +491,11 @@ SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode
SNode
*
pFill
)
{
SIntervalWindowNode
*
interval
=
(
SIntervalWindowNode
*
)
nodesMakeNode
(
QUERY_NODE_INTERVAL_WINDOW
);
CHECK_OUT_OF_MEM
(
interval
);
interval
->
pCol
=
nodesMakeNode
(
QUERY_NODE_COLUMN
);
interval
->
pCol
=
createPrimaryKeyCol
(
pCxt
);
if
(
NULL
==
interval
->
pCol
)
{
nodesDestroyNode
(
interval
);
CHECK_OUT_OF_MEM
(
interval
->
pCol
);
}
((
SColumnNode
*
)
interval
->
pCol
)
->
colId
=
PRIMARYKEY_TIMESTAMP_COL_ID
;
strcpy
(((
SColumnNode
*
)
interval
->
pCol
)
->
colName
,
PK_TS_COL_INTERNAL_NAME
);
interval
->
pInterval
=
pInterval
;
interval
->
pOffset
=
pOffset
;
interval
->
pSliding
=
pSliding
;
...
...
@@ -667,7 +674,7 @@ SNode* setDatabaseOption(SAstCreateContext* pCxt, SNode* pOptions, EDatabaseOpti
case
DB_OPTION_DAYS
:
{
SToken
*
pToken
=
pVal
;
if
(
TK_NK_INTEGER
==
pToken
->
type
)
{
((
SDatabaseOptions
*
)
pOptions
)
->
daysPerFile
=
strtol
(
pToken
->
z
,
NULL
,
10
);
((
SDatabaseOptions
*
)
pOptions
)
->
daysPerFile
=
strtol
(
pToken
->
z
,
NULL
,
10
)
*
1440
;
}
else
{
((
SDatabaseOptions
*
)
pOptions
)
->
pDaysPerFile
=
(
SValueNode
*
)
createDurationValueNode
(
pCxt
,
pToken
);
}
...
...
source/libs/parser/src/parInsert.c
浏览文件 @
aa93f393
...
...
@@ -241,7 +241,8 @@ static int32_t getTableMetaImpl(SInsertParseContext* pCxt, SName* name, char *db
SParseContext
*
pBasicCtx
=
pCxt
->
pComCxt
;
bool
pass
=
false
;
CHECK_CODE
(
catalogChkAuth
(
pBasicCtx
->
pCatalog
,
pBasicCtx
->
pTransporter
,
&
pBasicCtx
->
mgmtEpSet
,
pBasicCtx
->
pUser
,
dbFname
,
AUTH_TYPE_WRITE
,
&
pass
));
CHECK_CODE
(
catalogChkAuth
(
pBasicCtx
->
pCatalog
,
pBasicCtx
->
pTransporter
,
&
pBasicCtx
->
mgmtEpSet
,
pBasicCtx
->
pUser
,
dbFname
,
AUTH_TYPE_WRITE
,
&
pass
));
if
(
!
pass
)
{
return
TSDB_CODE_PAR_PERMISSION_DENIED
;
}
...
...
@@ -344,8 +345,7 @@ static int parseTime(char** end, SToken* pToken, int16_t timePrec, int64_t* time
}
else
if
(
pToken
->
type
==
TK_TODAY
)
{
ts
=
taosGetTimestampToday
(
timePrec
);
}
else
if
(
pToken
->
type
==
TK_NK_INTEGER
)
{
bool
isSigned
=
false
;
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
ts
,
&
isSigned
);
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
ts
);
}
else
{
// parse the RFC-3339/ISO-8601 timestamp format string
if
(
taosParseTime
(
pToken
->
z
,
time
,
pToken
->
n
,
timePrec
,
tsDaylight
)
!=
TSDB_CODE_SUCCESS
)
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid timestamp format"
,
pToken
->
z
);
...
...
@@ -448,9 +448,9 @@ static FORCE_INLINE int32_t toDouble(SToken* pToken, double* value, char** endPt
static
int32_t
parseValueToken
(
char
**
end
,
SToken
*
pToken
,
SSchema
*
pSchema
,
int16_t
timePrec
,
char
*
tmpTokenBuf
,
_row_append_fn_t
func
,
void
*
param
,
SMsgBuf
*
pMsgBuf
)
{
int64_t
iv
;
char
*
endptr
=
NULL
;
bool
isSigned
=
false
;
int64_t
iv
;
uint64_t
uv
;
char
*
endptr
=
NULL
;
int32_t
code
=
checkAndTrimValue
(
pToken
,
pSchema
->
type
,
tmpTokenBuf
,
pMsgBuf
);
if
(
code
!=
TSDB_CODE_SUCCESS
)
{
...
...
@@ -485,7 +485,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
}
case
TSDB_DATA_TYPE_TINYINT
:
{
if
(
TSDB_CODE_SUCCESS
!=
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
,
&
isSigned
))
{
if
(
TSDB_CODE_SUCCESS
!=
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid tinyint data"
,
pToken
->
z
);
}
else
if
(
!
IS_VALID_TINYINT
(
iv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"tinyint data overflow"
,
pToken
->
z
);
...
...
@@ -496,17 +496,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
}
case
TSDB_DATA_TYPE_UTINYINT
:
{
if
(
TSDB_CODE_SUCCESS
!=
to
Integer
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
,
&
isSigned
))
{
if
(
TSDB_CODE_SUCCESS
!=
to
UInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
uv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid unsigned tinyint data"
,
pToken
->
z
);
}
else
if
(
!
IS_VALID_UTINYINT
(
i
v
))
{
}
else
if
(
!
IS_VALID_UTINYINT
(
u
v
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"unsigned tinyint data overflow"
,
pToken
->
z
);
}
uint8_t
tmpVal
=
(
uint8_t
)
i
v
;
uint8_t
tmpVal
=
(
uint8_t
)
u
v
;
return
func
(
pMsgBuf
,
&
tmpVal
,
pSchema
->
bytes
,
param
);
}
case
TSDB_DATA_TYPE_SMALLINT
:
{
if
(
TSDB_CODE_SUCCESS
!=
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
,
&
isSigned
))
{
if
(
TSDB_CODE_SUCCESS
!=
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid smallint data"
,
pToken
->
z
);
}
else
if
(
!
IS_VALID_SMALLINT
(
iv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"smallint data overflow"
,
pToken
->
z
);
...
...
@@ -516,17 +516,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
}
case
TSDB_DATA_TYPE_USMALLINT
:
{
if
(
TSDB_CODE_SUCCESS
!=
to
Integer
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
,
&
isSigned
))
{
if
(
TSDB_CODE_SUCCESS
!=
to
UInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
uv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid unsigned smallint data"
,
pToken
->
z
);
}
else
if
(
!
IS_VALID_USMALLINT
(
i
v
))
{
}
else
if
(
!
IS_VALID_USMALLINT
(
u
v
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"unsigned smallint data overflow"
,
pToken
->
z
);
}
uint16_t
tmpVal
=
(
uint16_t
)
i
v
;
uint16_t
tmpVal
=
(
uint16_t
)
u
v
;
return
func
(
pMsgBuf
,
&
tmpVal
,
pSchema
->
bytes
,
param
);
}
case
TSDB_DATA_TYPE_INT
:
{
if
(
TSDB_CODE_SUCCESS
!=
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
,
&
isSigned
))
{
if
(
TSDB_CODE_SUCCESS
!=
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid int data"
,
pToken
->
z
);
}
else
if
(
!
IS_VALID_INT
(
iv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"int data overflow"
,
pToken
->
z
);
...
...
@@ -536,17 +536,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
}
case
TSDB_DATA_TYPE_UINT
:
{
if
(
TSDB_CODE_SUCCESS
!=
to
Integer
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
,
&
isSigned
))
{
if
(
TSDB_CODE_SUCCESS
!=
to
UInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
uv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid unsigned int data"
,
pToken
->
z
);
}
else
if
(
!
IS_VALID_UINT
(
i
v
))
{
}
else
if
(
!
IS_VALID_UINT
(
u
v
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"unsigned int data overflow"
,
pToken
->
z
);
}
uint32_t
tmpVal
=
(
uint32_t
)
i
v
;
uint32_t
tmpVal
=
(
uint32_t
)
u
v
;
return
func
(
pMsgBuf
,
&
tmpVal
,
pSchema
->
bytes
,
param
);
}
case
TSDB_DATA_TYPE_BIGINT
:
{
if
(
TSDB_CODE_SUCCESS
!=
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
,
&
isSigned
))
{
if
(
TSDB_CODE_SUCCESS
!=
toInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid bigint data"
,
pToken
->
z
);
}
else
if
(
!
IS_VALID_BIGINT
(
iv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"bigint data overflow"
,
pToken
->
z
);
...
...
@@ -555,13 +555,12 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int
}
case
TSDB_DATA_TYPE_UBIGINT
:
{
if
(
TSDB_CODE_SUCCESS
!=
to
Integer
(
pToken
->
z
,
pToken
->
n
,
10
,
&
iv
,
&
isSigned
))
{
if
(
TSDB_CODE_SUCCESS
!=
to
UInteger
(
pToken
->
z
,
pToken
->
n
,
10
,
&
uv
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"invalid unsigned bigint data"
,
pToken
->
z
);
}
else
if
(
!
IS_VALID_UBIGINT
(
(
uint64_t
)
i
v
))
{
}
else
if
(
!
IS_VALID_UBIGINT
(
u
v
))
{
return
buildSyntaxErrMsg
(
pMsgBuf
,
"unsigned bigint data overflow"
,
pToken
->
z
);
}
uint64_t
tmpVal
=
(
uint64_t
)
iv
;
return
func
(
pMsgBuf
,
&
tmpVal
,
pSchema
->
bytes
,
param
);
return
func
(
pMsgBuf
,
&
uv
,
pSchema
->
bytes
,
param
);
}
case
TSDB_DATA_TYPE_FLOAT
:
{
...
...
@@ -766,7 +765,7 @@ static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void* value, int32_t len, voi
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
buildCreateTbReq
(
SVCreateTbReq
*
pTbReq
,
const
char
*
tname
,
SKVRow
row
,
int64_t
suid
)
{
static
int32_t
buildCreateTbReq
(
SVCreateTbReq
*
pTbReq
,
const
char
*
tname
,
SKVRow
row
,
int64_t
suid
)
{
pTbReq
->
type
=
TD_CHILD_TABLE
;
pTbReq
->
name
=
strdup
(
tname
);
pTbReq
->
ctb
.
suid
=
suid
;
...
...
@@ -1277,9 +1276,10 @@ int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash
return
TSDB_CODE_SUCCESS
;
}
int32_t
qBindStmtTagsValue
(
void
*
pBlock
,
void
*
boundTags
,
int64_t
suid
,
char
*
tName
,
TAOS_MULTI_BIND
*
bind
,
char
*
msgBuf
,
int32_t
msgBufLen
){
STableDataBlocks
*
pDataBlock
=
(
STableDataBlocks
*
)
pBlock
;
SMsgBuf
pBuf
=
{.
buf
=
msgBuf
,
.
len
=
msgBufLen
};
int32_t
qBindStmtTagsValue
(
void
*
pBlock
,
void
*
boundTags
,
int64_t
suid
,
char
*
tName
,
TAOS_MULTI_BIND
*
bind
,
char
*
msgBuf
,
int32_t
msgBufLen
)
{
STableDataBlocks
*
pDataBlock
=
(
STableDataBlocks
*
)
pBlock
;
SMsgBuf
pBuf
=
{.
buf
=
msgBuf
,
.
len
=
msgBufLen
};
SParsedDataColInfo
*
tags
=
(
SParsedDataColInfo
*
)
boundTags
;
if
(
NULL
==
tags
)
{
return
TSDB_CODE_QRY_APP_ERROR
;
...
...
@@ -1554,16 +1554,16 @@ int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD** fields
// schemaless logic start
typedef
struct
SmlExecHandle
{
SHashObj
*
pBlockHash
;
SHashObj
*
pBlockHash
;
SParsedDataColInfo
tags
;
// each table
SKVRowBuilder
tagsBuilder
;
// each table
SVCreateTbReq
createTblReq
;
// each table
SParsedDataColInfo
tags
;
// each table
SKVRowBuilder
tagsBuilder
;
// each table
SVCreateTbReq
createTblReq
;
// each table
SQuery
*
pQuery
;
}
SSmlExecHandle
;
static
int32_t
smlBoundColumnData
(
SArray
*
cols
,
SParsedDataColInfo
*
pColList
,
SSchema
*
pSchema
)
{
static
int32_t
smlBoundColumnData
(
SArray
*
cols
,
SParsedDataColInfo
*
pColList
,
SSchema
*
pSchema
)
{
col_id_t
nCols
=
pColList
->
numOfCols
;
pColList
->
numOfBound
=
0
;
...
...
@@ -1576,8 +1576,8 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS
bool
isOrdered
=
true
;
col_id_t
lastColIdx
=
-
1
;
// last column found
for
(
int
i
=
0
;
i
<
taosArrayGetSize
(
cols
);
++
i
)
{
SSmlKv
*
kv
=
taosArrayGetP
(
cols
,
i
);
SToken
sToken
=
{.
n
=
kv
->
keyLen
,
.
z
=
(
char
*
)
kv
->
key
};
SSmlKv
*
kv
=
taosArrayGetP
(
cols
,
i
);
SToken
sToken
=
{.
n
=
kv
->
keyLen
,
.
z
=
(
char
*
)
kv
->
key
};
col_id_t
t
=
lastColIdx
+
1
;
col_id_t
index
=
findCol
(
&
sToken
,
t
,
nCols
,
pSchema
);
if
(
index
<
0
&&
t
>
0
)
{
...
...
@@ -1626,7 +1626,7 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS
qsort
(
pColIdx
,
pColList
->
numOfBound
,
sizeof
(
SBoundIdxInfo
),
boundIdxCompar
);
}
if
(
pColList
->
numOfCols
>
pColList
->
numOfBound
)
{
if
(
pColList
->
numOfCols
>
pColList
->
numOfBound
)
{
memset
(
&
pColList
->
boundColumns
[
pColList
->
numOfBound
],
0
,
sizeof
(
col_id_t
)
*
(
pColList
->
numOfCols
-
pColList
->
numOfBound
));
}
...
...
@@ -1634,43 +1634,43 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
smlBuildTagRow
(
SArray
*
cols
,
SKVRowBuilder
*
tagsBuilder
,
SParsedDataColInfo
*
tags
,
SSchema
*
pSchema
,
SKVRow
*
row
,
SMsgBuf
*
msg
)
{
static
int32_t
smlBuildTagRow
(
SArray
*
cols
,
SKVRowBuilder
*
tagsBuilder
,
SParsedDataColInfo
*
tags
,
SSchema
*
pSchema
,
SKVRow
*
row
,
SMsgBuf
*
msg
)
{
if
(
tdInitKVRowBuilder
(
tagsBuilder
)
<
0
)
{
return
TSDB_CODE_TSC_OUT_OF_MEMORY
;
}
SKvParam
param
=
{.
builder
=
tagsBuilder
};
for
(
int
i
=
0
;
i
<
tags
->
numOfBound
;
++
i
)
{
SSchema
*
pTagSchema
=
&
pSchema
[
tags
->
boundColumns
[
i
]
-
1
];
// colId starts with 1
SSchema
*
pTagSchema
=
&
pSchema
[
tags
->
boundColumns
[
i
]
-
1
];
// colId starts with 1
param
.
schema
=
pTagSchema
;
SSmlKv
*
kv
=
taosArrayGetP
(
cols
,
i
);
KvRowAppend
(
msg
,
kv
->
value
,
kv
->
valueLen
,
&
param
)
;
SSmlKv
*
kv
=
taosArrayGetP
(
cols
,
i
);
KvRowAppend
(
msg
,
kv
->
value
,
kv
->
valueLen
,
&
param
);
}
*
row
=
tdGetKVRowFromBuilder
(
tagsBuilder
);
if
(
*
row
==
NULL
)
{
if
(
*
row
==
NULL
)
{
return
TSDB_CODE_SML_INVALID_DATA
;
}
tdSortKVRowByColIdx
(
*
row
);
return
TSDB_CODE_SUCCESS
;
}
int32_t
smlBindData
(
void
*
handle
,
SArray
*
tags
,
SArray
*
colsFormat
,
SArray
*
colsSchema
,
SArray
*
cols
,
bool
format
,
STableMeta
*
pTableMeta
,
char
*
tableName
,
char
*
msgBuf
,
int16_t
msgBufLen
)
{
int32_t
smlBindData
(
void
*
handle
,
SArray
*
tags
,
SArray
*
colsFormat
,
SArray
*
colsSchema
,
SArray
*
cols
,
bool
format
,
STableMeta
*
pTableMeta
,
char
*
tableName
,
char
*
msgBuf
,
int16_t
msgBufLen
)
{
SMsgBuf
pBuf
=
{.
buf
=
msgBuf
,
.
len
=
msgBufLen
};
SSmlExecHandle
*
smlHandle
=
(
SSmlExecHandle
*
)
handle
;
SSchema
*
pTagsSchema
=
getTableTagSchema
(
pTableMeta
);
SSmlExecHandle
*
smlHandle
=
(
SSmlExecHandle
*
)
handle
;
SSchema
*
pTagsSchema
=
getTableTagSchema
(
pTableMeta
);
setBoundColumnInfo
(
&
smlHandle
->
tags
,
pTagsSchema
,
getNumOfTags
(
pTableMeta
));
int
ret
=
smlBoundColumnData
(
tags
,
&
smlHandle
->
tags
,
pTagsSchema
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
buildInvalidOperationMsg
(
&
pBuf
,
"bound tags error"
);
return
ret
;
}
SKVRow
row
=
NULL
;
ret
=
smlBuildTagRow
(
tags
,
&
smlHandle
->
tagsBuilder
,
&
smlHandle
->
tags
,
pTagsSchema
,
&
row
,
&
pBuf
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
return
ret
;
}
...
...
@@ -1688,35 +1688,35 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols
SSchema
*
pSchema
=
getTableColumnSchema
(
pTableMeta
);
ret
=
smlBoundColumnData
(
colsSchema
,
&
pDataBlock
->
boundColumnInfo
,
pSchema
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
buildInvalidOperationMsg
(
&
pBuf
,
"bound cols error"
);
return
ret
;
}
int32_t
extendedRowSize
=
getExtendedRowSize
(
pDataBlock
);
int32_t
extendedRowSize
=
getExtendedRowSize
(
pDataBlock
);
SParsedDataColInfo
*
spd
=
&
pDataBlock
->
boundColumnInfo
;
SRowBuilder
*
pBuilder
=
&
pDataBlock
->
rowBuilder
;
SMemParam
param
=
{.
rb
=
pBuilder
};
SMemParam
param
=
{.
rb
=
pBuilder
};
initRowBuilder
(
&
pDataBlock
->
rowBuilder
,
pDataBlock
->
pTableMeta
->
sversion
,
&
pDataBlock
->
boundColumnInfo
);
int32_t
rowNum
=
format
?
taosArrayGetSize
(
colsFormat
)
:
taosArrayGetSize
(
cols
);
if
(
rowNum
<=
0
)
{
if
(
rowNum
<=
0
)
{
return
buildInvalidOperationMsg
(
&
pBuf
,
"cols size <= 0"
);
}
ret
=
allocateMemForSize
(
pDataBlock
,
extendedRowSize
*
rowNum
);
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
if
(
ret
!=
TSDB_CODE_SUCCESS
)
{
buildInvalidOperationMsg
(
&
pBuf
,
"allocate memory error"
);
return
ret
;
}
for
(
int32_t
r
=
0
;
r
<
rowNum
;
++
r
)
{
STSRow
*
row
=
(
STSRow
*
)(
pDataBlock
->
pData
+
pDataBlock
->
size
);
// skip the SSubmitBlk header
tdSRowResetBuf
(
pBuilder
,
row
);
void
*
rowData
=
NULL
;
void
*
rowData
=
NULL
;
size_t
rowDataSize
=
0
;
if
(
format
)
{
if
(
format
)
{
rowData
=
taosArrayGetP
(
colsFormat
,
r
);
rowDataSize
=
taosArrayGetSize
(
rowData
);
}
else
{
}
else
{
rowData
=
taosArrayGetP
(
cols
,
r
);
}
...
...
@@ -1727,19 +1727,20 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols
param
.
schema
=
pColSchema
;
getSTSRowAppendInfo
(
pBuilder
->
rowType
,
spd
,
c
,
&
param
.
toffset
,
&
param
.
colIdx
);
SSmlKv
*
kv
=
NULL
;
if
(
format
)
{
if
(
j
<
rowDataSize
)
{
SSmlKv
*
kv
=
NULL
;
if
(
format
)
{
if
(
j
<
rowDataSize
)
{
kv
=
taosArrayGetP
(
rowData
,
j
);
if
(
rowDataSize
!=
spd
->
numOfBound
&&
(
kv
->
keyLen
!=
strlen
(
pColSchema
->
name
)
||
strncmp
(
kv
->
key
,
pColSchema
->
name
,
kv
->
keyLen
)
!=
0
)){
if
(
rowDataSize
!=
spd
->
numOfBound
&&
(
kv
->
keyLen
!=
strlen
(
pColSchema
->
name
)
||
strncmp
(
kv
->
key
,
pColSchema
->
name
,
kv
->
keyLen
)
!=
0
))
{
kv
=
NULL
;
}
else
{
}
else
{
j
++
;
}
}
}
else
{
void
**
p
=
taosHashGet
(
rowData
,
pColSchema
->
name
,
strlen
(
pColSchema
->
name
));
if
(
p
)
kv
=
*
p
;
}
else
{
void
**
p
=
taosHashGet
(
rowData
,
pColSchema
->
name
,
strlen
(
pColSchema
->
name
));
if
(
p
)
kv
=
*
p
;
}
if
(
!
kv
||
kv
->
length
==
0
)
{
...
...
@@ -1748,7 +1749,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols
int32_t
colLen
=
pColSchema
->
bytes
;
if
(
IS_VAR_DATA_TYPE
(
pColSchema
->
type
))
{
colLen
=
kv
->
length
;
}
else
if
(
pColSchema
->
type
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
}
else
if
(
pColSchema
->
type
==
TSDB_DATA_TYPE_TIMESTAMP
)
{
kv
->
i
=
convertTimePrecision
(
kv
->
i
,
TSDB_TIME_PRECISION_NANO
,
pTableMeta
->
tableInfo
.
precision
);
}
...
...
@@ -1757,7 +1758,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols
if
(
PRIMARYKEY_TIMESTAMP_COL_ID
==
pColSchema
->
colId
)
{
TSKEY
tsKey
=
TD_ROW_KEY
(
row
);
checkTimestamp
(
pDataBlock
,
(
const
char
*
)
&
tsKey
);
checkTimestamp
(
pDataBlock
,
(
const
char
*
)
&
tsKey
);
}
}
...
...
@@ -1774,7 +1775,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols
pDataBlock
->
size
+=
extendedRowSize
;
}
SSubmitBlk
*
pBlocks
=
(
SSubmitBlk
*
)(
pDataBlock
->
pData
);
SSubmitBlk
*
pBlocks
=
(
SSubmitBlk
*
)(
pDataBlock
->
pData
);
if
(
TSDB_CODE_SUCCESS
!=
setBlockInfo
(
pBlocks
,
pDataBlock
,
rowNum
))
{
return
buildInvalidOperationMsg
(
&
pBuf
,
"too many rows in sql, total number of rows should be less than 32767"
);
}
...
...
@@ -1782,25 +1783,24 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols
return
TSDB_CODE_SUCCESS
;
}
void
*
smlInitHandle
(
SQuery
*
pQuery
)
{
SSmlExecHandle
*
handle
=
taosMemoryCalloc
(
1
,
sizeof
(
SSmlExecHandle
));
if
(
!
handle
)
return
NULL
;
void
*
smlInitHandle
(
SQuery
*
pQuery
)
{
SSmlExecHandle
*
handle
=
taosMemoryCalloc
(
1
,
sizeof
(
SSmlExecHandle
));
if
(
!
handle
)
return
NULL
;
handle
->
pBlockHash
=
taosHashInit
(
16
,
taosGetDefaultHashFunction
(
TSDB_DATA_TYPE_BIGINT
),
true
,
false
);
handle
->
pQuery
=
pQuery
;
return
handle
;
}
void
smlDestroyHandle
(
void
*
pHandle
)
{
if
(
!
pHandle
)
return
;
SSmlExecHandle
*
handle
=
(
SSmlExecHandle
*
)
pHandle
;
void
smlDestroyHandle
(
void
*
pHandle
)
{
if
(
!
pHandle
)
return
;
SSmlExecHandle
*
handle
=
(
SSmlExecHandle
*
)
pHandle
;
destroyBlockHashmap
(
handle
->
pBlockHash
);
taosMemoryFree
(
handle
);
}
int32_t
smlBuildOutput
(
void
*
handle
,
SHashObj
*
pVgHash
)
{
SSmlExecHandle
*
smlHandle
=
(
SSmlExecHandle
*
)
handle
;
SSmlExecHandle
*
smlHandle
=
(
SSmlExecHandle
*
)
handle
;
return
qBuildStmtOutput
(
smlHandle
->
pQuery
,
pVgHash
,
smlHandle
->
pBlockHash
);
}
// schemaless logic end
source/libs/parser/src/parTranslater.c
浏览文件 @
aa93f393
...
...
@@ -1886,6 +1886,9 @@ static int32_t checkDbKeepOption(STranslateContext* pCxt, SDatabaseOptions* pOpt
TIME_UNIT_DAY
!=
pVal
->
unit
)
{
return
generateSyntaxErrMsg
(
&
pCxt
->
msgBuf
,
TSDB_CODE_PAR_INVALID_KEEP_UNIT
,
pVal
->
unit
);
}
if
(
!
pVal
->
isDuration
)
{
pVal
->
datum
.
i
=
pVal
->
datum
.
i
*
1440
;
}
}
pOptions
->
keep
[
0
]
=
getBigintFromValueNode
((
SValueNode
*
)
nodesListGetNode
(
pOptions
->
pKeep
,
0
));
...
...
source/libs/parser/test/parInitialCTest.cpp
浏览文件 @
aa93f393
...
...
@@ -3,7 +3,7 @@
*
* This program is free software: you can use, redistribute, and/or modify
* it under the terms of the GNU Affero General Public License, version 3
* or later ("AGPL"),
as
published by the Free Software Foundation.
* or later ("AGPL"),
AS
published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
...
...
@@ -14,6 +14,7 @@
*/
#include "parTestUtil.h"
#include "ttime.h"
using
namespace
std
;
...
...
@@ -26,72 +27,226 @@ class ParserInitialCTest : public ParserDdlTest {};
TEST_F
(
ParserInitialCTest
,
createAccount
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create account ac_wxy pass
'123456'"
,
TSDB_CODE_PAR_EXPRIE_STATEMENT
);
run
(
"
CREATE ACCOUNT ac_wxy PASS
'123456'"
,
TSDB_CODE_PAR_EXPRIE_STATEMENT
);
}
TEST_F
(
ParserInitialCTest
,
createBnode
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create bnode on dnode
1"
);
run
(
"
CREATE BNODE ON DNODE
1"
);
}
/*
* CREATE DATABASE [IF NOT EXISTS] db_name [database_options]
*
* database_options:
* database_option ...
*
* database_option: {
* BUFFER value
* | CACHELAST value
* | COMP {0 | 1 | 2}
* | DAYS value
* | FSYNC value
* | MAXROWS value
* | MINROWS value
* | KEEP value
* | PAGES value
* | PAGESIZE value
* | PRECISION {'ms' | 'us' | 'ns'}
* | REPLICA value
* | RETENTIONS ingestion_duration:keep_duration ...
* | STRICT value
* | WAL value
* | VGROUPS value
* | SINGLE_STABLE {0 | 1}
* }
*/
TEST_F
(
ParserInitialCTest
,
createDatabase
)
{
useDb
(
"root"
,
"test"
);
run
(
"create database wxy_db"
);
run
(
"create database if not exists wxy_db "
"cachelast 2 "
"comp 1 "
"days 100 "
"fsync 100 "
"maxrows 1000 "
"minrows 100 "
"keep 1440 "
"precision 'ms' "
"replica 3 "
"wal 2 "
"vgroups 100 "
"single_stable 0 "
"retentions 15s:7d,1m:21d,15m:5y"
);
run
(
"create database if not exists wxy_db "
"days 100m "
"keep 1440m,300h,400d "
);
SCreateDbReq
expect
=
{
0
};
auto
setCreateDbReqFunc
=
[
&
](
const
char
*
pDbname
,
int8_t
igExists
=
0
)
{
memset
(
&
expect
,
0
,
sizeof
(
SCreateDbReq
));
int32_t
len
=
snprintf
(
expect
.
db
,
sizeof
(
expect
.
db
),
"0.%s"
,
pDbname
);
expect
.
db
[
len
]
=
'\0'
;
expect
.
ignoreExist
=
igExists
;
expect
.
buffer
=
TSDB_DEFAULT_BUFFER_PER_VNODE
;
expect
.
cacheLastRow
=
TSDB_DEFAULT_CACHE_LAST_ROW
;
expect
.
compression
=
TSDB_DEFAULT_COMP_LEVEL
;
expect
.
daysPerFile
=
TSDB_DEFAULT_DAYS_PER_FILE
;
expect
.
fsyncPeriod
=
TSDB_DEFAULT_FSYNC_PERIOD
;
expect
.
maxRows
=
TSDB_DEFAULT_MAXROWS_FBLOCK
;
expect
.
minRows
=
TSDB_DEFAULT_MINROWS_FBLOCK
;
expect
.
daysToKeep0
=
TSDB_DEFAULT_KEEP
;
expect
.
daysToKeep1
=
TSDB_DEFAULT_KEEP
;
expect
.
daysToKeep2
=
TSDB_DEFAULT_KEEP
;
expect
.
pages
=
TSDB_DEFAULT_PAGES_PER_VNODE
;
expect
.
pageSize
=
TSDB_DEFAULT_PAGESIZE_PER_VNODE
;
expect
.
precision
=
TSDB_DEFAULT_PRECISION
;
expect
.
replications
=
TSDB_DEFAULT_DB_REPLICA
;
expect
.
strict
=
TSDB_DEFAULT_DB_STRICT
;
expect
.
walLevel
=
TSDB_DEFAULT_WAL_LEVEL
;
expect
.
numOfVgroups
=
TSDB_DEFAULT_VN_PER_DB
;
expect
.
numOfStables
=
TSDB_DEFAULT_DB_SINGLE_STABLE
;
};
auto
setDbBufferFunc
=
[
&
](
int32_t
buffer
)
{
expect
.
buffer
=
buffer
;
};
auto
setDbCachelastFunc
=
[
&
](
int8_t
CACHELAST
)
{
expect
.
cacheLastRow
=
CACHELAST
;
};
auto
setDbCompressionFunc
=
[
&
](
int8_t
compressionLevel
)
{
expect
.
compression
=
compressionLevel
;
};
auto
setDbDaysFunc
=
[
&
](
int32_t
daysPerFile
)
{
expect
.
daysPerFile
=
daysPerFile
;
};
auto
setDbFsyncFunc
=
[
&
](
int32_t
fsyncPeriod
)
{
expect
.
fsyncPeriod
=
fsyncPeriod
;
};
auto
setDbMaxRowsFunc
=
[
&
](
int32_t
maxRowsPerBlock
)
{
expect
.
maxRows
=
maxRowsPerBlock
;
};
auto
setDbMinRowsFunc
=
[
&
](
int32_t
minRowsPerBlock
)
{
expect
.
minRows
=
minRowsPerBlock
;
};
auto
setDbKeepFunc
=
[
&
](
int32_t
keep0
,
int32_t
keep1
=
0
,
int32_t
keep2
=
0
)
{
expect
.
daysToKeep0
=
keep0
;
expect
.
daysToKeep1
=
0
==
keep1
?
expect
.
daysToKeep0
:
keep1
;
expect
.
daysToKeep2
=
0
==
keep2
?
expect
.
daysToKeep1
:
keep2
;
};
auto
setDbPagesFunc
=
[
&
](
int32_t
pages
)
{
expect
.
pages
=
pages
;
};
auto
setDbPageSizeFunc
=
[
&
](
int32_t
pagesize
)
{
expect
.
pageSize
=
pagesize
;
};
auto
setDbPrecisionFunc
=
[
&
](
int8_t
precision
)
{
expect
.
precision
=
precision
;
};
auto
setDbReplicaFunc
=
[
&
](
int8_t
replica
)
{
expect
.
replications
=
replica
;
};
auto
setDbStrictaFunc
=
[
&
](
int8_t
strict
)
{
expect
.
strict
=
strict
;
};
auto
setDbWalLevelFunc
=
[
&
](
int8_t
walLevel
)
{
expect
.
walLevel
=
walLevel
;
};
auto
setDbVgroupsFunc
=
[
&
](
int32_t
numOfVgroups
)
{
expect
.
numOfVgroups
=
numOfVgroups
;
};
auto
setDbSingleStableFunc
=
[
&
](
int8_t
singleStable
)
{
expect
.
numOfStables
=
singleStable
;
};
auto
addDbRetentionFunc
=
[
&
](
int64_t
freq
,
int64_t
keep
,
int8_t
freqUnit
,
int8_t
keepUnit
)
{
SRetention
retention
=
{
0
};
retention
.
freq
=
freq
;
retention
.
keep
=
keep
;
retention
.
freqUnit
=
freqUnit
;
retention
.
keepUnit
=
keepUnit
;
if
(
NULL
==
expect
.
pRetensions
)
{
expect
.
pRetensions
=
taosArrayInit
(
TARRAY_MIN_SIZE
,
sizeof
(
SRetention
));
}
taosArrayPush
(
expect
.
pRetensions
,
&
retention
);
++
expect
.
numOfRetensions
;
};
setCheckDdlFunc
([
&
](
const
SQuery
*
pQuery
,
ParserStage
stage
)
{
ASSERT_EQ
(
nodeType
(
pQuery
->
pRoot
),
QUERY_NODE_CREATE_DATABASE_STMT
);
SCreateDbReq
req
=
{
0
};
ASSERT_TRUE
(
TSDB_CODE_SUCCESS
==
tDeserializeSCreateDbReq
(
pQuery
->
pCmdMsg
->
pMsg
,
pQuery
->
pCmdMsg
->
msgLen
,
&
req
));
ASSERT_EQ
(
std
::
string
(
req
.
db
),
std
::
string
(
expect
.
db
));
ASSERT_EQ
(
req
.
numOfVgroups
,
expect
.
numOfVgroups
);
ASSERT_EQ
(
req
.
numOfStables
,
expect
.
numOfStables
);
ASSERT_EQ
(
req
.
buffer
,
expect
.
buffer
);
ASSERT_EQ
(
req
.
pageSize
,
expect
.
pageSize
);
ASSERT_EQ
(
req
.
pages
,
expect
.
pages
);
ASSERT_EQ
(
req
.
daysPerFile
,
expect
.
daysPerFile
);
ASSERT_EQ
(
req
.
daysToKeep0
,
expect
.
daysToKeep0
);
ASSERT_EQ
(
req
.
daysToKeep1
,
expect
.
daysToKeep1
);
ASSERT_EQ
(
req
.
daysToKeep2
,
expect
.
daysToKeep2
);
ASSERT_EQ
(
req
.
minRows
,
expect
.
minRows
);
ASSERT_EQ
(
req
.
maxRows
,
expect
.
maxRows
);
ASSERT_EQ
(
req
.
fsyncPeriod
,
expect
.
fsyncPeriod
);
ASSERT_EQ
(
req
.
walLevel
,
expect
.
walLevel
);
ASSERT_EQ
(
req
.
precision
,
expect
.
precision
);
ASSERT_EQ
(
req
.
compression
,
expect
.
compression
);
ASSERT_EQ
(
req
.
replications
,
expect
.
replications
);
ASSERT_EQ
(
req
.
strict
,
expect
.
strict
);
ASSERT_EQ
(
req
.
cacheLastRow
,
expect
.
cacheLastRow
);
ASSERT_EQ
(
req
.
ignoreExist
,
expect
.
ignoreExist
);
ASSERT_EQ
(
req
.
numOfRetensions
,
expect
.
numOfRetensions
);
if
(
expect
.
numOfRetensions
>
0
)
{
ASSERT_EQ
(
taosArrayGetSize
(
req
.
pRetensions
),
expect
.
numOfRetensions
);
ASSERT_EQ
(
taosArrayGetSize
(
req
.
pRetensions
),
taosArrayGetSize
(
expect
.
pRetensions
));
for
(
int32_t
i
=
0
;
i
<
expect
.
numOfRetensions
;
++
i
)
{
SRetention
*
pReten
=
(
SRetention
*
)
taosArrayGet
(
req
.
pRetensions
,
i
);
SRetention
*
pExpectReten
=
(
SRetention
*
)
taosArrayGet
(
expect
.
pRetensions
,
i
);
ASSERT_EQ
(
pReten
->
freq
,
pExpectReten
->
freq
);
ASSERT_EQ
(
pReten
->
keep
,
pExpectReten
->
keep
);
ASSERT_EQ
(
pReten
->
freqUnit
,
pExpectReten
->
freqUnit
);
ASSERT_EQ
(
pReten
->
keepUnit
,
pExpectReten
->
keepUnit
);
}
}
});
setCreateDbReqFunc
(
"wxy_db"
);
run
(
"CREATE DATABASE wxy_db"
);
setCreateDbReqFunc
(
"wxy_db"
,
1
);
setDbBufferFunc
(
64
);
setDbCachelastFunc
(
2
);
setDbCompressionFunc
(
1
);
setDbDaysFunc
(
100
*
1440
);
setDbFsyncFunc
(
100
);
setDbMaxRowsFunc
(
1000
);
setDbMinRowsFunc
(
100
);
setDbKeepFunc
(
1440
*
1440
);
setDbPagesFunc
(
96
);
setDbPageSizeFunc
(
8
);
setDbPrecisionFunc
(
TSDB_TIME_PRECISION_NANO
);
setDbReplicaFunc
(
3
);
addDbRetentionFunc
(
15
*
MILLISECOND_PER_SECOND
,
7
*
MILLISECOND_PER_DAY
,
TIME_UNIT_SECOND
,
TIME_UNIT_DAY
);
addDbRetentionFunc
(
1
*
MILLISECOND_PER_MINUTE
,
21
*
MILLISECOND_PER_DAY
,
TIME_UNIT_MINUTE
,
TIME_UNIT_DAY
);
addDbRetentionFunc
(
15
*
MILLISECOND_PER_MINUTE
,
5
,
TIME_UNIT_MINUTE
,
TIME_UNIT_YEAR
);
setDbStrictaFunc
(
1
);
setDbWalLevelFunc
(
2
);
setDbVgroupsFunc
(
100
);
setDbSingleStableFunc
(
1
);
run
(
"CREATE DATABASE IF NOT EXISTS wxy_db "
"BUFFER 64 "
"CACHELAST 2 "
"COMP 1 "
"DAYS 100 "
"FSYNC 100 "
"MAXROWS 1000 "
"MINROWS 100 "
"KEEP 1440 "
"PAGES 96 "
"PAGESIZE 8 "
"PRECISION 'ns' "
"REPLICA 3 "
"RETENTIONS 15s:7d,1m:21d,15m:5y "
"STRICT 1 "
"WAL 2 "
"VGROUPS 100 "
"SINGLE_STABLE 1 "
);
setCreateDbReqFunc
(
"wxy_db"
,
1
);
setDbDaysFunc
(
100
);
setDbKeepFunc
(
1440
,
300
*
60
,
400
*
1440
);
run
(
"CREATE DATABASE IF NOT EXISTS wxy_db "
"DAYS 100m "
"KEEP 1440m,300h,400d "
);
}
TEST_F
(
ParserInitialCTest
,
createDnode
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create dnode abc1 port
7000"
);
run
(
"
CREATE DNODE abc1 PORT
7000"
);
run
(
"
create dnode 1.1.1.1 port
9000"
);
run
(
"
CREATE DNODE 1.1.1.1 PORT
9000"
);
}
// todo
create function
// todo
CREATE FUNCTION
TEST_F
(
ParserInitialCTest
,
createIndexSma
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create sma index index1 on t1 function(max(c1), min(c3 + 10), sum
(c4)) INTERVAL(10s)"
);
run
(
"
CREATE SMA INDEX index1 ON t1 FUNCTION(MAX(c1), MIN(c3 + 10), SUM
(c4)) INTERVAL(10s)"
);
}
TEST_F
(
ParserInitialCTest
,
createMnode
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create mnode on dnode
1"
);
run
(
"
CREATE MNODE ON DNODE
1"
);
}
TEST_F
(
ParserInitialCTest
,
createQnode
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create qnode on dnode
1"
);
run
(
"
CREATE QNODE ON DNODE
1"
);
}
TEST_F
(
ParserInitialCTest
,
createSnode
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create snode on dnode
1"
);
run
(
"
CREATE SNODE ON DNODE
1"
);
}
TEST_F
(
ParserInitialCTest
,
createStable
)
{
...
...
@@ -194,7 +349,7 @@ TEST_F(ParserInitialCTest, createStable) {
addFieldToCreateStbReqFunc
(
true
,
"ts"
,
TSDB_DATA_TYPE_TIMESTAMP
);
addFieldToCreateStbReqFunc
(
true
,
"c1"
,
TSDB_DATA_TYPE_INT
);
addFieldToCreateStbReqFunc
(
false
,
"id"
,
TSDB_DATA_TYPE_INT
);
run
(
"
create stable t1(ts timestamp, c1 int) TAGS(id int
)"
);
run
(
"
CREATE STABLE t1(ts TIMESTAMP, c1 INT) TAGS(id INT
)"
);
setCreateStbReqFunc
(
"t1"
,
1
,
0.1
,
2
,
100
,
"test create table"
);
addFieldToCreateStbReqFunc
(
true
,
"ts"
,
TSDB_DATA_TYPE_TIMESTAMP
,
0
,
0
);
...
...
@@ -227,80 +382,72 @@ TEST_F(ParserInitialCTest, createStable) {
addFieldToCreateStbReqFunc
(
false
,
"a13"
,
TSDB_DATA_TYPE_BOOL
);
addFieldToCreateStbReqFunc
(
false
,
"a14"
,
TSDB_DATA_TYPE_NCHAR
,
30
*
TSDB_NCHAR_SIZE
+
VARSTR_HEADER_SIZE
);
addFieldToCreateStbReqFunc
(
false
,
"a15"
,
TSDB_DATA_TYPE_VARCHAR
,
50
+
VARSTR_HEADER_SIZE
);
run
(
"
create stable if not exists
test.t1("
run
(
"
CREATE STABLE IF NOT EXISTS
test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), "
"c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, "
"c13 NCHAR(30), c14 VARCHAR(50)) "
"TAGS (a1 TIMESTAMP, a2 INT, a3 INT UNSIGNED, a4 BIGINT, a5 BIGINT UNSIGNED, a6 FLOAT, a7 DOUBLE, "
"a8 BINARY(20), a9 SMALLINT, a10 SMALLINT UNSIGNED COMMENT 'test column comment', a11 TINYINT, "
"a12 TINYINT UNSIGNED, a13 BOOL, a14 NCHAR(30), a15 VARCHAR(50)) "
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (
min
) FILE_FACTOR 0.1 DELAY 2"
);
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (
MIN
) FILE_FACTOR 0.1 DELAY 2"
);
}
TEST_F
(
ParserInitialCTest
,
createStream
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create stream s1 as select * from
t1"
);
run
(
"
CREATE STREAM s1 AS SELECT * FROM
t1"
);
run
(
"
create stream if not exists s1 as select * from
t1"
);
run
(
"
CREATE STREAM IF NOT EXISTS s1 AS SELECT * FROM
t1"
);
run
(
"
create stream s1 into st1 as select * from
t1"
);
run
(
"
CREATE STREAM s1 INTO st1 AS SELECT * FROM
t1"
);
run
(
"
create stream if not exists s1 trigger window_close watermark 10s into st1 as select * from
t1"
);
run
(
"
CREATE STREAM IF NOT EXISTS s1 TRIGGER WINDOW_CLOSE WATERMARK 10s INTO st1 AS SELECT * FROM
t1"
);
}
TEST_F
(
ParserInitialCTest
,
createTable
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create table t1(ts timestamp, c1 int
)"
);
run
(
"
CREATE TABLE t1(ts TIMESTAMP, c1 INT
)"
);
run
(
"create table if not exists test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
"SMALLINT, "
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 "
"NCHAR(30), "
"c15 VARCHAR(50)) "
run
(
"CREATE TABLE IF NOT EXISTS test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), "
"c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, "
"c13 NCHAR(30), c15 VARCHAR(50)) "
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)"
);
run
(
"create table if not exists test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
"SMALLINT, "
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 "
"NCHAR(30), "
"c15 VARCHAR(50)) "
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, "
"a5 FLOAT, a6 DOUBLE, a7 "
"BINARY(20), a8 SMALLINT, "
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 "
"TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), "
"a15 VARCHAR(50)) "
"TTL 100 COMMENT 'test create "
"table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2"
);
run
(
"create table if not exists t1 using st1 tags(1, 'wxy')"
);
run
(
"create table "
"if not exists test.t1 using test.st1 (tag1, tag2) tags(1, 'abc') "
"if not exists test.t2 using test.st1 (tag1, tag2) tags(2, 'abc') "
"if not exists test.t3 using test.st1 (tag1, tag2) tags(3, 'abc') "
);
run
(
"CREATE TABLE IF NOT EXISTS test.t1("
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), "
"c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, "
"c13 NCHAR(30), c14 VARCHAR(50)) "
"TAGS (a1 TIMESTAMP, a2 INT, a3 INT UNSIGNED, a4 BIGINT, a5 BIGINT UNSIGNED, a6 FLOAT, a7 DOUBLE, a8 BINARY(20), "
"a9 SMALLINT, a10 SMALLINT UNSIGNED COMMENT 'test column comment', a11 TINYINT, a12 TINYINT UNSIGNED, a13 BOOL, "
"a14 NCHAR(30), a15 VARCHAR(50)) "
"TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (MIN) FILE_FACTOR 0.1 DELAY 2"
);
run
(
"CREATE TABLE IF NOT EXISTS t1 USING st1 TAGS(1, 'wxy')"
);
run
(
"CREATE TABLE "
"IF NOT EXISTS test.t1 USING test.st1 (tag1, tag2) TAGS(1, 'abc') "
"IF NOT EXISTS test.t2 USING test.st1 (tag1, tag2) TAGS(2, 'abc') "
"IF NOT EXISTS test.t3 USING test.st1 (tag1, tag2) TAGS(3, 'abc') "
);
}
TEST_F
(
ParserInitialCTest
,
createTopic
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create topic tp1 as select * from
t1"
);
run
(
"
CREATE TOPIC tp1 AS SELECT * FROM
t1"
);
run
(
"
create topic if not exists tp1 as select * from
t1"
);
run
(
"
CREATE TOPIC IF NOT EXISTS tp1 AS SELECT * FROM
t1"
);
run
(
"
create topic tp1 as
test"
);
run
(
"
CREATE TOPIC tp1 AS
test"
);
run
(
"
create topic if not exists tp1 as
test"
);
run
(
"
CREATE TOPIC IF NOT EXISTS tp1 AS
test"
);
}
TEST_F
(
ParserInitialCTest
,
createUser
)
{
useDb
(
"root"
,
"test"
);
run
(
"
create user wxy pass
'123456'"
);
run
(
"
CREATE USER wxy PASS
'123456'"
);
}
}
// namespace ParserTest
source/libs/planner/src/planner.c
浏览文件 @
aa93f393
...
...
@@ -16,9 +16,10 @@
#include "planner.h"
#include "planInt.h"
#include "scalar.h"
typedef
struct
SCollectPlaceholderValuesCxt
{
int32_t
errCode
;
int32_t
errCode
;
SArray
*
pValues
;
}
SCollectPlaceholderValuesCxt
;
...
...
@@ -144,9 +145,10 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
if
(
NULL
==
pVal
->
datum
.
p
)
{
return
TSDB_CODE_OUT_OF_MEMORY
;
}
int32_t
output
=
0
;
if
(
!
taosMbsToUcs4
(
pParam
->
buffer
,
inputSize
,
(
TdUcs4
*
)
varDataVal
(
pVal
->
datum
.
p
),
pVal
->
node
.
resType
.
bytes
,
&
output
))
{
if
(
!
taosMbsToUcs4
(
pParam
->
buffer
,
inputSize
,
(
TdUcs4
*
)
varDataVal
(
pVal
->
datum
.
p
),
pVal
->
node
.
resType
.
bytes
,
&
output
))
{
return
errno
;
}
varDataSetLen
(
pVal
->
datum
.
p
,
output
);
...
...
@@ -181,8 +183,8 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) {
}
static
EDealRes
updatePlanQueryId
(
SNode
*
pNode
,
void
*
pContext
)
{
int64_t
queryId
=
*
(
uint64_t
*
)
pContext
;
int64_t
queryId
=
*
(
uint64_t
*
)
pContext
;
if
(
QUERY_NODE_PHYSICAL_PLAN
==
nodeType
(
pNode
))
{
SQueryPlan
*
planNode
=
(
SQueryPlan
*
)
pNode
;
planNode
->
queryId
=
queryId
;
...
...
@@ -194,10 +196,130 @@ static EDealRes updatePlanQueryId(SNode* pNode, void* pContext) {
return
DEAL_RES_CONTINUE
;
}
int32_t
qStmtBindParam
(
SQueryPlan
*
pPlan
,
TAOS_MULTI_BIND
*
pParams
,
int32_t
colIdx
,
uint64_t
queryId
)
{
static
int32_t
calcConstNode
(
SNode
**
pNode
)
{
if
(
NULL
==
*
pNode
)
{
return
TSDB_CODE_SUCCESS
;
}
SNode
*
pNew
=
NULL
;
int32_t
code
=
scalarCalculateConstants
(
*
pNode
,
&
pNew
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
*
pNode
=
pNew
;
}
return
code
;
}
static
int32_t
calcConstList
(
SNodeList
*
pList
)
{
SNode
*
pNode
=
NULL
;
FOREACH
(
pNode
,
pList
)
{
SNode
*
pNew
=
NULL
;
int32_t
code
=
scalarCalculateConstants
(
pNode
,
&
pNew
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
REPLACE_NODE
(
pNew
);
}
else
{
return
code
;
}
}
return
TSDB_CODE_SUCCESS
;
}
static
bool
isEmptyResultCond
(
SNode
**
pCond
)
{
if
(
QUERY_NODE_VALUE
!=
nodeType
(
*
pCond
))
{
return
false
;
}
if
(((
SValueNode
*
)
*
pCond
)
->
datum
.
b
)
{
nodesDestroyNode
(
*
pCond
);
*
pCond
=
NULL
;
return
false
;
}
return
true
;
}
static
int32_t
calcConstSpecificPhysiNode
(
SPhysiNode
*
pPhyNode
)
{
switch
(
nodeType
(
pPhyNode
))
{
case
QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN
:
case
QUERY_NODE_PHYSICAL_PLAN_EXCHANGE
:
case
QUERY_NODE_PHYSICAL_PLAN_FILL
:
return
TSDB_CODE_SUCCESS
;
case
QUERY_NODE_PHYSICAL_PLAN_PROJECT
:
return
calcConstList
(((
SProjectPhysiNode
*
)
pPhyNode
)
->
pProjections
);
case
QUERY_NODE_PHYSICAL_PLAN_JOIN
:
return
calcConstNode
(
&
(((
SJoinPhysiNode
*
)
pPhyNode
)
->
pOnConditions
));
case
QUERY_NODE_PHYSICAL_PLAN_AGG
:
return
calcConstList
(((
SAggPhysiNode
*
)
pPhyNode
)
->
pExprs
);
case
QUERY_NODE_PHYSICAL_PLAN_SORT
:
return
calcConstList
(((
SSortPhysiNode
*
)
pPhyNode
)
->
pExprs
);
case
QUERY_NODE_PHYSICAL_PLAN_INTERVAL
:
case
QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL
:
case
QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW
:
case
QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW
:
return
calcConstList
(((
SWinodwPhysiNode
*
)
pPhyNode
)
->
pExprs
);
case
QUERY_NODE_PHYSICAL_PLAN_PARTITION
:
return
calcConstList
(((
SPartitionPhysiNode
*
)
pPhyNode
)
->
pExprs
);
default:
break
;
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
calcConstSubplan
(
SPhysiNode
*
pPhyNode
,
bool
*
pEmptyResult
)
{
int32_t
code
=
calcConstNode
(
&
pPhyNode
->
pConditions
);
if
(
TSDB_CODE_SUCCESS
==
code
)
{
code
=
calcConstSpecificPhysiNode
(
pPhyNode
);
}
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
*
pEmptyResult
=
isEmptyResultCond
(
&
pPhyNode
->
pConditions
);
if
(
*
pEmptyResult
)
{
return
TSDB_CODE_SUCCESS
;
}
*
pEmptyResult
=
true
;
bool
subEmptyResult
=
false
;
SNode
*
pChild
=
NULL
;
FOREACH
(
pChild
,
pPhyNode
->
pChildren
)
{
code
=
calcConstSubplan
((
SPhysiNode
*
)
pChild
,
&
subEmptyResult
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
if
(
!
subEmptyResult
)
{
*
pEmptyResult
=
false
;
}
}
return
TSDB_CODE_SUCCESS
;
}
static
int32_t
calcConstPhysiPlan
(
SQueryPlan
*
pPlan
,
bool
*
pEmptyResult
)
{
*
pEmptyResult
=
true
;
bool
subEmptyResult
=
false
;
SNodeListNode
*
pNode
=
nodesListGetNode
(
pPlan
->
pSubplans
,
0
);
SNode
*
pSubplan
=
NULL
;
FOREACH
(
pSubplan
,
pNode
->
pNodeList
)
{
int32_t
code
=
calcConstSubplan
(((
SSubplan
*
)
pSubplan
)
->
pNode
,
pEmptyResult
);
if
(
TSDB_CODE_SUCCESS
!=
code
)
{
return
code
;
}
if
(
!
subEmptyResult
)
{
*
pEmptyResult
=
false
;
}
}
return
TSDB_CODE_SUCCESS
;
}
int32_t
qStmtBindParam
(
SQueryPlan
*
pPlan
,
TAOS_MULTI_BIND
*
pParams
,
int32_t
colIdx
,
uint64_t
queryId
,
bool
*
pEmptyResult
)
{
int32_t
size
=
taosArrayGetSize
(
pPlan
->
pPlaceholderValues
);
int32_t
code
=
0
;
if
(
colIdx
<
0
)
{
for
(
int32_t
i
=
0
;
i
<
size
;
++
i
)
{
code
=
setValueByBindParam
((
SValueNode
*
)
taosArrayGetP
(
pPlan
->
pPlaceholderValues
,
i
),
pParams
+
i
);
...
...
@@ -214,9 +336,10 @@ int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colI
if
(
colIdx
<
0
||
((
colIdx
+
1
)
==
size
))
{
nodesWalkPhysiPlan
((
SNode
*
)
pPlan
,
updatePlanQueryId
,
&
queryId
);
code
=
calcConstPhysiPlan
(
pPlan
,
pEmptyResult
);
}
return
TSDB_CODE_SUCCESS
;
return
code
;
}
int32_t
qSubPlanToString
(
const
SSubplan
*
pSubplan
,
char
**
pStr
,
int32_t
*
pLen
)
{
...
...
tests/script/tsim/db/alter_option.sim
浏览文件 @
aa93f393
...
...
@@ -66,7 +66,7 @@ print ============= create database
# | REPLICA value [1 | 3]
# | WAL value [1 | 2]
sql create database db CACHELAST 3 COMP 0 DAYS
345600 FSYNC 1000 MAXROWS 8000 MINROWS 10 KEEP 1440
000 PRECISION 'ns' REPLICA 3 WAL 2 VGROUPS 6 SINGLE_STABLE 1
sql create database db CACHELAST 3 COMP 0 DAYS
240 FSYNC 1000 MAXROWS 8000 MINROWS 10 KEEP 1
000 PRECISION 'ns' REPLICA 3 WAL 2 VGROUPS 6 SINGLE_STABLE 1
sql show databases
print rows: $rows
print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09
...
...
@@ -229,7 +229,7 @@ sql_error alter database db days 0
sql_error alter database db days 14400 # set over than keep
print ============== modify keep
sql alter database db keep
34560
00
sql alter database db keep
24
00
sql show databases
print keep $data7_db
if $data7_db != 3456000,3456000,3456000 then
...
...
tests/script/tsim/db/basic6.sim
浏览文件 @
aa93f393
...
...
@@ -15,8 +15,7 @@ $tb = $tbPrefix . $i
print =============== step1
# quorum presicion
#sql create database $db vgroups 8 replica 1 days 2880 keep 3650 cache 32 blocks 12 minrows 80 maxrows 10000 wal 2 fsync 1000 comp 0 cachelast 2 precision 'us'
sql create database $db vgroups 8 replica 1 days 2880 keep 3650 minrows 80 maxrows 10000 wal 2 fsync 1000 comp 0 cachelast 2 precision 'us'
sql create database $db vgroups 8 replica 1 days 2 keep 10 minrows 80 maxrows 10000 wal 2 fsync 1000 comp 0 cachelast 2 precision 'us'
sql show databases
print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09
...
...
@@ -38,7 +37,7 @@ endi
if $data26 != 2880 then
return -1
endi
if $data27 !=
3650,3650,365
0 then
if $data27 !=
14400,14400,1440
0 then
return -1
endi
#if $data28 != 32 then
...
...
@@ -67,7 +66,7 @@ print =============== step4
sql_error drop database $db
print =============== step5
sql create database $db replica 1 days
21600 keep 21600
00
sql create database $db replica 1 days
15 keep 15
00
sql show databases
print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07
if $data20 != $db then
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录