Merge branch 'develop' into feature/TD-1413
This commit is contained in:
commit
f68b434356
|
@ -4,7 +4,7 @@ PROJECT(TDengine)
|
|||
IF (DEFINED VERNUMBER)
|
||||
SET(TD_VER_NUMBER ${VERNUMBER})
|
||||
ELSE ()
|
||||
SET(TD_VER_NUMBER "2.0.7.0")
|
||||
SET(TD_VER_NUMBER "2.0.8.0")
|
||||
ENDIF ()
|
||||
|
||||
IF (DEFINED VERCOMPATIBLE)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
name: tdengine
|
||||
base: core18
|
||||
version: '2.0.7.0'
|
||||
version: '2.0.8.0'
|
||||
icon: snap/gui/t-dengine.svg
|
||||
summary: an open-source big data platform designed and optimized for IoT.
|
||||
description: |
|
||||
|
@ -72,7 +72,7 @@ parts:
|
|||
- usr/bin/taosd
|
||||
- usr/bin/taos
|
||||
- usr/bin/taosdemo
|
||||
- usr/lib/libtaos.so.2.0.6.0
|
||||
- usr/lib/libtaos.so.2.0.8.0
|
||||
- usr/lib/libtaos.so.1
|
||||
- usr/lib/libtaos.so
|
||||
|
||||
|
|
|
@ -258,11 +258,7 @@ static char* normalStmtBuildSql(STscStmt* stmt) {
|
|||
|
||||
static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
||||
if (bind->is_null != NULL && *(bind->is_null)) {
|
||||
if (param->type == TSDB_DATA_TYPE_BINARY || param->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
setVardataNull(data + param->offset, param->type);
|
||||
} else {
|
||||
setNull(data + param->offset, param->type, param->bytes);
|
||||
}
|
||||
setNull(data + param->offset, param->type, param->bytes);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -312,13 +308,13 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.v1, sizeof(u.v1));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
|
@ -336,40 +332,40 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
u.v1 = (int8_t)v;
|
||||
if (v >= SCHAR_MIN && v <= SCHAR_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
int32_t v = *(int32_t*)bind->buffer;
|
||||
u.v1 = (int8_t)v;
|
||||
if (v >= SCHAR_MIN && v <= SCHAR_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t v = *(int64_t*)bind->buffer;
|
||||
u.v1 = (int8_t)v;
|
||||
if (v >= SCHAR_MIN && v <= SCHAR_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
int64_t v;
|
||||
int n,r;
|
||||
int n, r;
|
||||
r = sscanf((const char*)bind->buffer, "%" PRId64 "%n", &v, &n);
|
||||
if (r==1 && n==strlen((const char*)bind->buffer)) {
|
||||
if (r == 1 && n == strlen((const char*)bind->buffer)) {
|
||||
u.v1 = (int8_t)v;
|
||||
if (v >= SCHAR_MIN && v <= SCHAR_MAX) break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.v1, sizeof(u.v1));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_SMALLINT: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -383,34 +379,34 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
u.v2 = (int16_t)v;
|
||||
if (v >= SHRT_MIN && v <= SHRT_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BIGINT: {
|
||||
int64_t v = *(int64_t*)bind->buffer;
|
||||
u.v2 = (int16_t)v;
|
||||
if (v >= SHRT_MIN && v <= SHRT_MAX) break;
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BINARY:
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
int64_t v;
|
||||
int n,r;
|
||||
int n, r;
|
||||
r = sscanf((const char*)bind->buffer, "%" PRId64 "%n", &v, &n);
|
||||
if (r==1 && n==strlen((const char*)bind->buffer)) {
|
||||
if (r == 1 && n == strlen((const char*)bind->buffer)) {
|
||||
u.v2 = (int16_t)v;
|
||||
if (v >= SHRT_MIN && v <= SHRT_MAX) break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.v2, sizeof(u.v2));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_INT: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -514,17 +510,17 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_FLOAT:
|
||||
case TSDB_DATA_TYPE_DOUBLE:
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.v8, sizeof(u.v8));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_DOUBLE: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
|
@ -556,15 +552,15 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
break;
|
||||
}
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
memcpy(data + param->offset, &u.f8, sizeof(u.f8));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_TIMESTAMP: {
|
||||
|
@ -589,10 +585,10 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
} break;
|
||||
};
|
||||
memcpy(data + param->offset, &u.v8, sizeof(u.v8));
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_BINARY: {
|
||||
|
@ -602,7 +598,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
short size = (short)*bind->length;
|
||||
STR_WITH_SIZE_TO_VARSTR(data + param->offset, bind->buffer, size);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
|
@ -614,9 +610,9 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
case TSDB_DATA_TYPE_NCHAR:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
switch (bind->buffer_type) {
|
||||
case TSDB_DATA_TYPE_NCHAR: {
|
||||
|
@ -626,7 +622,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
}
|
||||
varDataSetLen(data + param->offset, output);
|
||||
return TSDB_CODE_SUCCESS;
|
||||
} break;
|
||||
}
|
||||
case TSDB_DATA_TYPE_BOOL:
|
||||
case TSDB_DATA_TYPE_TINYINT:
|
||||
case TSDB_DATA_TYPE_SMALLINT:
|
||||
|
@ -638,12 +634,12 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) {
|
|||
case TSDB_DATA_TYPE_BINARY:
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
}
|
||||
default: {
|
||||
return TSDB_CODE_TSC_INVALID_VALUE;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,6 @@ static int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprLis
|
|||
static bool validateIpAddress(const char* ip, size_t size);
|
||||
static bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
|
||||
static bool functionCompatibleCheck(SQueryInfo* pQueryInfo, bool joinQuery);
|
||||
static void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo);
|
||||
|
||||
static int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd);
|
||||
|
||||
|
@ -1768,10 +1767,10 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrToken* pToken) {
|
||||
void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrToken* pToken, bool multiCols) {
|
||||
if (pItem->aliasName != NULL) {
|
||||
tstrncpy(name, pItem->aliasName, TSDB_COL_NAME_LEN);
|
||||
} else {
|
||||
} else if (multiCols) {
|
||||
char uname[TSDB_COL_NAME_LEN] = {0};
|
||||
int32_t len = MIN(pToken->n + 1, TSDB_COL_NAME_LEN);
|
||||
tstrncpy(uname, pToken->z, len);
|
||||
|
@ -1782,6 +1781,9 @@ void setResultColName(char* name, tSQLExprItem* pItem, int32_t functionId, SStrT
|
|||
snprintf(tmp, size, "%s(%s)", aAggs[functionId].aName, uname);
|
||||
|
||||
tstrncpy(name, tmp, TSDB_COL_NAME_LEN);
|
||||
} else { // use the user-input result column name
|
||||
int32_t len = MIN(pItem->pNode->token.n + 1, TSDB_COL_NAME_LEN);
|
||||
tstrncpy(name, pItem->pNode->token.z, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2056,7 +2058,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
for (int32_t j = 0; j < tscGetNumOfColumns(pTableMetaInfo->pTableMeta); ++j) {
|
||||
index.columnIndex = j;
|
||||
SStrToken t = {.z = pSchema[j].name, .n = (uint32_t)strnlen(pSchema[j].name, TSDB_COL_NAME_LEN)};
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t);
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
|
||||
|
||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[j], cvtFunc, name, colIndex++, &index, finalResult) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
|
@ -2078,7 +2080,9 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
|
||||
SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, index.columnIndex);
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo);
|
||||
|
||||
bool multiColOutput = pItem->pNode->pParam->nExpr > 1;
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &pParamElem->pNode->colInfo, multiColOutput);
|
||||
|
||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, pSchema, cvtFunc, name, colIndex + i, &index, finalResult) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
|
@ -2120,7 +2124,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
|
|||
|
||||
char name[TSDB_COL_NAME_LEN] = {0};
|
||||
SStrToken t = {.z = pSchema[i].name, .n = (uint32_t)strnlen(pSchema[i].name, TSDB_COL_NAME_LEN)};
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t);
|
||||
setResultColName(name, pItem, cvtFunc.originFuncId, &t, true);
|
||||
|
||||
if (setExprInfoForFunctions(pCmd, pQueryInfo, &pSchema[index.columnIndex], cvtFunc, name, colIndex, &index, finalResult) != 0) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
|
@ -2951,14 +2955,6 @@ int32_t parseGroupbyClause(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd)
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void setColumnOffsetValueInResultset(SQueryInfo* pQueryInfo) {
|
||||
if (QUERY_IS_STABLE_QUERY(pQueryInfo->type)) {
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
} else {
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
}
|
||||
}
|
||||
|
||||
static SColumnFilterInfo* addColumnFilterInfo(SColumn* pColumn) {
|
||||
if (pColumn == NULL) {
|
||||
return NULL;
|
||||
|
@ -3537,7 +3533,7 @@ static int32_t validateSQLExpr(SSqlCmd* pCmd, tSQLExpr* pExpr, SQueryInfo* pQuer
|
|||
|
||||
if (i == 0) {
|
||||
id = p1->uid;
|
||||
} else if (id != p1->uid){
|
||||
} else if (id != p1->uid) {
|
||||
return TSDB_CODE_TSC_INVALID_SQL;
|
||||
}
|
||||
}
|
||||
|
@ -4252,6 +4248,9 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
|
|||
tExprTreeDestroy(&p, NULL);
|
||||
|
||||
taosArrayDestroy(colList);
|
||||
if (taosArrayGetSize(pQueryInfo->tagCond.pCond) > 0 && !UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
|
||||
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), "filter on tag not supported for normal table");
|
||||
}
|
||||
}
|
||||
|
||||
pCondExpr->pTagCond = NULL;
|
||||
|
@ -6531,7 +6530,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) {
|
|||
return code;
|
||||
}
|
||||
|
||||
setColumnOffsetValueInResultset(pQueryInfo);
|
||||
tscFieldInfoUpdateOffset(pQueryInfo);
|
||||
|
||||
/*
|
||||
* fill options are set at the end position, when all columns are set properly
|
||||
|
|
|
@ -62,7 +62,7 @@ static void tscSetDnodeEpSet(SSqlObj* pSql, SVgroupInfo* pVgroupInfo) {
|
|||
|
||||
pEpSet->numOfEps = pVgroupInfo->numOfEps;
|
||||
for(int32_t i = 0; i < pVgroupInfo->numOfEps; ++i) {
|
||||
strcpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn);
|
||||
tstrncpy(pEpSet->fqdn[i], pVgroupInfo->epAddr[i].fqdn, tListLen(pEpSet->fqdn[i]));
|
||||
pEpSet->port[i] = pVgroupInfo->epAddr[i].port;
|
||||
|
||||
if (!hasFqdn) {
|
||||
|
@ -669,6 +669,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
}
|
||||
|
||||
SQueryTableMsg *pQueryMsg = (SQueryTableMsg *)pCmd->payload;
|
||||
tstrncpy(pQueryMsg->version, version, tListLen(pQueryMsg->version));
|
||||
|
||||
int32_t numOfTags = (int32_t)taosArrayGetSize(pTableMetaInfo->tagColList);
|
||||
|
||||
|
@ -693,8 +694,8 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
|
|||
pQueryMsg->interval.slidingUnit = pQueryInfo->interval.slidingUnit;
|
||||
pQueryMsg->interval.offsetUnit = pQueryInfo->interval.offsetUnit;
|
||||
pQueryMsg->numOfGroupCols = htons(pQueryInfo->groupbyExpr.numOfGroupCols);
|
||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||
pQueryMsg->tagNameRelType = htons(pQueryInfo->tagCond.relType);
|
||||
pQueryMsg->numOfTags = htonl(numOfTags);
|
||||
pQueryMsg->queryType = htonl(pQueryInfo->type);
|
||||
|
||||
size_t numOfOutput = tscSqlExprNumOfExprs(pQueryInfo);
|
||||
|
@ -2030,7 +2031,8 @@ static void createHBObj(STscObj* pObj) {
|
|||
|
||||
SQueryInfo *pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0);
|
||||
if (pQueryInfo == NULL) {
|
||||
pSql->res.code = terrno;
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tfree(pSql);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2038,6 +2040,7 @@ static void createHBObj(STscObj* pObj) {
|
|||
|
||||
pSql->cmd.command = pQueryInfo->command;
|
||||
if (TSDB_CODE_SUCCESS != tscAllocPayload(&(pSql->cmd), TSDB_DEFAULT_PAYLOAD_SIZE)) {
|
||||
terrno = TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
tfree(pSql);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -420,7 +420,16 @@ TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) {
|
|||
for(int32_t i = 0; i < pFieldInfo->numOfOutput; ++i) {
|
||||
SInternalField* pField = tscFieldInfoGetInternalField(pFieldInfo, i);
|
||||
if (pField->visible) {
|
||||
f[j++] = pField->field;
|
||||
f[j] = pField->field;
|
||||
|
||||
// revise the length for binary and nchar fields
|
||||
if (f[j].type == TSDB_DATA_TYPE_BINARY) {
|
||||
f[j].bytes -= VARSTR_HEADER_SIZE;
|
||||
} else if (f[j].type == TSDB_DATA_TYPE_NCHAR) {
|
||||
f[j].bytes = (f[j].bytes - VARSTR_HEADER_SIZE)/TSDB_NCHAR_SIZE;
|
||||
}
|
||||
|
||||
j += 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -451,14 +451,16 @@ void tscFreeRegisteredSqlObj(void *pSql) {
|
|||
STscObj* pTscObj = (*p)->pTscObj;
|
||||
|
||||
assert((*p)->self != 0 && (*p)->self == (p));
|
||||
|
||||
SSqlObj* ptr = *p;
|
||||
tscFreeSqlObj(*p);
|
||||
|
||||
int32_t ref = T_REF_DEC(pTscObj);
|
||||
assert(ref >= 0);
|
||||
|
||||
tscDebug("%p free sqlObj completed, tscObj:%p ref:%d", *p, pTscObj, ref);
|
||||
tscDebug("%p free sqlObj completed, tscObj:%p ref:%d", ptr, pTscObj, ref);
|
||||
if (ref == 0) {
|
||||
tscDebug("%p all sqlObj freed, free tscObj:%p", *p, pTscObj);
|
||||
tscDebug("%p all sqlObj freed, free tscObj:%p", ptr, pTscObj);
|
||||
taosRemoveRef(tscRefId, pTscObj->rid);
|
||||
}
|
||||
}
|
||||
|
@ -644,6 +646,7 @@ int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOff
|
|||
dataBuf->pData = calloc(1, dataBuf->nAllocSize);
|
||||
if (dataBuf->pData == NULL) {
|
||||
tscError("failed to allocated memory, reason:%s", strerror(errno));
|
||||
tfree(dataBuf);
|
||||
return TSDB_CODE_TSC_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "taos.h"
|
||||
|
||||
namespace {
|
||||
static int64_t start_ts = 1433955661000;
|
||||
}
|
||||
/* test parse time function */
|
||||
TEST(testCase, result_field_test) {
|
||||
taos_options(TSDB_OPTION_CONFIGDIR, "~/first/cfg");
|
||||
taos_init();
|
||||
|
||||
TAOS* conn = taos_connect("ubuntu", "root", "taosdata", 0, 0);
|
||||
if (conn == NULL) {
|
||||
printf("Failed to connect to DB, reason:%s", taos_errstr(conn));
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
TAOS_RES* res = taos_query(conn, "create database if not exists test");
|
||||
ASSERT_EQ(taos_errno(res), 0);
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "use test");
|
||||
ASSERT_EQ(taos_errno(res), 0);
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "create table if not exists t1(ts timestamp, k int, a binary(11), b nchar(4))");
|
||||
ASSERT_EQ(taos_errno(res), 0);
|
||||
taos_free_result(res);
|
||||
|
||||
char sql[512] = {0};
|
||||
sprintf(sql, "insert into t1 values(%ld, 99, 'abc', 'test')", start_ts);
|
||||
|
||||
res = taos_query(conn, sql);
|
||||
ASSERT_EQ(taos_errno(res), 0);
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "select count(*), spread(ts)/(1000 * 3600 * 24), first(a), last(b) from t1");
|
||||
ASSERT_EQ(taos_num_fields(res), 4);
|
||||
|
||||
TAOS_FIELD* fields = taos_fetch_fields(res);
|
||||
ASSERT_EQ(fields[0].bytes, 8);
|
||||
ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_BIGINT);
|
||||
ASSERT_STREQ(fields[0].name, "count(*)");
|
||||
|
||||
ASSERT_EQ(fields[1].bytes, 8);
|
||||
ASSERT_EQ(fields[1].type, TSDB_DATA_TYPE_DOUBLE);
|
||||
ASSERT_STREQ(fields[1].name, "spread(ts)/(1000 * 3600 * 24)");
|
||||
|
||||
ASSERT_EQ(fields[2].bytes, 11);
|
||||
ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STREQ(fields[2].name, "first(a)");
|
||||
|
||||
ASSERT_EQ(fields[3].bytes, 4);
|
||||
ASSERT_EQ(fields[3].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[3].name, "last(b)");
|
||||
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "select last_row(*) from t1");
|
||||
ASSERT_EQ(taos_num_fields(res), 4);
|
||||
|
||||
fields = taos_fetch_fields(res);
|
||||
ASSERT_EQ(fields[0].bytes, 8);
|
||||
ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STREQ(fields[0].name, "last_row(ts)");
|
||||
|
||||
ASSERT_EQ(fields[1].bytes, 4);
|
||||
ASSERT_EQ(fields[1].type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STREQ(fields[1].name, "last_row(k)");
|
||||
|
||||
ASSERT_EQ(fields[2].bytes, 11);
|
||||
ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STREQ(fields[2].name, "last_row(a)");
|
||||
|
||||
ASSERT_EQ(fields[3].bytes, 4);
|
||||
ASSERT_EQ(fields[3].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[3].name, "last_row(b)");
|
||||
|
||||
taos_free_result(res);
|
||||
res = taos_query(conn, "select first(*), last(*) from t1");
|
||||
ASSERT_EQ(taos_num_fields(res), 8);
|
||||
|
||||
fields = taos_fetch_fields(res);
|
||||
ASSERT_EQ(fields[0].bytes, 8);
|
||||
ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STREQ(fields[0].name, "first(ts)");
|
||||
|
||||
ASSERT_EQ(fields[1].bytes, 4);
|
||||
ASSERT_EQ(fields[1].type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STREQ(fields[1].name, "first(k)");
|
||||
|
||||
ASSERT_EQ(fields[2].bytes, 11);
|
||||
ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STREQ(fields[2].name, "first(a)");
|
||||
|
||||
ASSERT_EQ(fields[3].bytes, 4);
|
||||
ASSERT_EQ(fields[3].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[3].name, "first(b)");
|
||||
|
||||
taos_free_result(res);
|
||||
|
||||
res = taos_query(conn, "select first(ts, a, k, k, b, b, ts) from t1");
|
||||
ASSERT_EQ(taos_num_fields(res), 7);
|
||||
|
||||
fields = taos_fetch_fields(res);
|
||||
ASSERT_EQ(fields[0].bytes, 8);
|
||||
ASSERT_EQ(fields[0].type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STREQ(fields[0].name, "first(ts)");
|
||||
|
||||
ASSERT_EQ(fields[1].bytes, 11);
|
||||
ASSERT_EQ(fields[1].type, TSDB_DATA_TYPE_BINARY);
|
||||
ASSERT_STREQ(fields[1].name, "first(a)");
|
||||
|
||||
ASSERT_EQ(fields[2].bytes, 4);
|
||||
ASSERT_EQ(fields[2].type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STREQ(fields[2].name, "first(k)");
|
||||
|
||||
ASSERT_EQ(fields[3].bytes, 4);
|
||||
ASSERT_EQ(fields[3].type, TSDB_DATA_TYPE_INT);
|
||||
ASSERT_STREQ(fields[3].name, "first(k)");
|
||||
|
||||
ASSERT_EQ(fields[4].bytes, 4);
|
||||
ASSERT_EQ(fields[4].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[4].name, "first(b)");
|
||||
|
||||
ASSERT_EQ(fields[5].bytes, 4);
|
||||
ASSERT_EQ(fields[5].type, TSDB_DATA_TYPE_NCHAR);
|
||||
ASSERT_STREQ(fields[5].name, "first(b)");
|
||||
|
||||
ASSERT_EQ(fields[6].bytes, 8);
|
||||
ASSERT_EQ(fields[6].type, TSDB_DATA_TYPE_TIMESTAMP);
|
||||
ASSERT_STREQ(fields[6].name, "first(ts)");
|
||||
|
||||
taos_free_result(res);
|
||||
taos_close(conn);
|
||||
}
|
|
@ -171,7 +171,9 @@ void tVariantAssign(tVariant *pDst, const tVariant *pSrc) {
|
|||
}
|
||||
}
|
||||
|
||||
pDst->nLen = tDataTypeDesc[pDst->nType].nSize;
|
||||
if (pDst->nType != TSDB_DATA_TYPE_ARRAY) {
|
||||
pDst->nLen = tDataTypeDesc[pDst->nType].nSize;
|
||||
}
|
||||
}
|
||||
|
||||
int32_t tVariantCompare(const tVariant* p1, const tVariant* p2) {
|
||||
|
|
|
@ -464,6 +464,8 @@ typedef struct STimeWindow {
|
|||
|
||||
typedef struct {
|
||||
SMsgHead head;
|
||||
char version[TSDB_VERSION_LEN];
|
||||
|
||||
STimeWindow window;
|
||||
int32_t numOfTables;
|
||||
int16_t order;
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
int32_t getOutputInterResultBufSize(SQuery* pQuery);
|
||||
|
||||
void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pRow);
|
||||
void clearResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* pRow, int16_t type);
|
||||
void copyResultRow(SQueryRuntimeEnv* pRuntimeEnv, SResultRow* dst, const SResultRow* src);
|
||||
SResultRowCellInfo* getResultCell(SQueryRuntimeEnv* pRuntimeEnv, const SResultRow* pRow, int32_t index);
|
||||
|
||||
|
@ -80,5 +80,8 @@ void* destroyResultRowPool(SResultRowPool* p);
|
|||
int32_t getNumOfAllocatedResultRows(SResultRowPool* p);
|
||||
int32_t getNumOfUsedResultRows(SResultRowPool* p);
|
||||
|
||||
uint64_t getResultInfoUId(SQueryRuntimeEnv* pRuntimeEnv);
|
||||
bool isPointInterpoQuery(SQuery *pQuery);
|
||||
|
||||
|
||||
#endif // TDENGINE_QUERYUTIL_H
|
||||
|
|
|
@ -556,11 +556,11 @@ having_opt(A) ::= HAVING expr(X). {A = X;}
|
|||
//limit-offset subclause
|
||||
%type limit_opt {SLimitVal}
|
||||
limit_opt(A) ::= . {A.limit = -1; A.offset = 0;}
|
||||
limit_opt(A) ::= LIMIT signed(X). {printf("aa1, %d\n", X); A.limit = X; A.offset = 0;}
|
||||
limit_opt(A) ::= LIMIT signed(X). {A.limit = X; A.offset = 0;}
|
||||
limit_opt(A) ::= LIMIT signed(X) OFFSET signed(Y).
|
||||
{printf("aa2\n, %d\n", X); A.limit = X; A.offset = Y;}
|
||||
{ A.limit = X; A.offset = Y;}
|
||||
limit_opt(A) ::= LIMIT signed(X) COMMA signed(Y).
|
||||
{printf("aa3\n, %d\n", X); A.limit = Y; A.offset = X;}
|
||||
{ A.limit = Y; A.offset = X;}
|
||||
|
||||
%type slimit_opt {SLimitVal}
|
||||
slimit_opt(A) ::= . {A.limit = -1; A.offset = 0;}
|
||||
|
@ -581,7 +581,7 @@ 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(X) expr(Y) RP(Z). {A = Y; A->token.z = X.z; A->token.n = (Z.z - X.z + 1);}
|
||||
|
||||
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);}
|
||||
|
|
|
@ -186,7 +186,7 @@ static void setExecParams(SQuery *pQuery, SQLFunctionCtx *pCtx, void* inputData,
|
|||
|
||||
static void initCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv);
|
||||
static void destroyTableQueryInfoImpl(STableQueryInfo *pTableQueryInfo);
|
||||
static void resetCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv);
|
||||
static void resetDefaultResInfoOutputBuf(SQueryRuntimeEnv *pRuntimeEnv);
|
||||
static bool hasMainOutput(SQuery *pQuery);
|
||||
static void buildTagQueryResult(SQInfo *pQInfo);
|
||||
|
||||
|
@ -283,8 +283,8 @@ void updateNumOfResult(SQueryRuntimeEnv *pRuntimeEnv, int32_t numOfRes) {
|
|||
}
|
||||
}
|
||||
|
||||
static UNUSED_FUNC int32_t getGroupResultId(int32_t groupIndex) {
|
||||
int32_t base = 20000000;
|
||||
static int32_t getMergeResultGroupId(int32_t groupIndex) {
|
||||
int32_t base = 50000000;
|
||||
return base + (groupIndex * 10000);
|
||||
}
|
||||
|
||||
|
@ -947,10 +947,10 @@ static char *getDataBlock(SQueryRuntimeEnv *pRuntimeEnv, SArithmeticSupport *sas
|
|||
if (functionId == TSDB_FUNC_ARITHM) {
|
||||
sas->pArithExpr = &pQuery->pExpr1[col];
|
||||
|
||||
sas->offset = 0;
|
||||
sas->colList = pQuery->colList;
|
||||
sas->offset = (QUERY_IS_ASC_QUERY(pQuery)) ? pQuery->pos : pQuery->pos - (size - 1);
|
||||
sas->colList = pQuery->colList;
|
||||
sas->numOfCols = pQuery->numOfCols;
|
||||
sas->data = calloc(pQuery->numOfCols, POINTER_BYTES);
|
||||
sas->data = calloc(pQuery->numOfCols, POINTER_BYTES);
|
||||
|
||||
if (sas->data == NULL) {
|
||||
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY);
|
||||
|
@ -1115,7 +1115,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
|
|||
|
||||
SDiskbasedResultBuf *pResultBuf = pRuntimeEnv->pResultBuf;
|
||||
|
||||
// not assign result buffer yet, add new result buffer
|
||||
// not assign result buffer yet, add new result buffer, TODO remove it
|
||||
char* d = pData;
|
||||
int16_t len = bytes;
|
||||
if (type == TSDB_DATA_TYPE_BINARY||type == TSDB_DATA_TYPE_NCHAR) {
|
||||
|
@ -1128,7 +1128,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat
|
|||
longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_APP_ERROR);
|
||||
}
|
||||
|
||||
uint64_t uid = groupIndex; // uid is always set to be 0.
|
||||
uint64_t uid = groupIndex;
|
||||
SResultRow *pResultRow = doPrepareResultRowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, d, len, true, uid);
|
||||
if (pResultRow == NULL) {
|
||||
return -1;
|
||||
|
@ -1714,7 +1714,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
|
|||
// if it is group by normal column, do not set output buffer, the output buffer is pResult
|
||||
// fixed output query/multi-output query for normal table
|
||||
if (!pRuntimeEnv->groupbyNormalCol && !pRuntimeEnv->stableQuery && !QUERY_IS_INTERVAL_QUERY(pRuntimeEnv->pQuery)) {
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
resetDefaultResInfoOutputBuf(pRuntimeEnv);
|
||||
}
|
||||
|
||||
if (setCtxTagColumnInfo(pRuntimeEnv, pRuntimeEnv->pCtx) != TSDB_CODE_SUCCESS) {
|
||||
|
@ -1825,7 +1825,7 @@ static bool isFixedOutputQuery(SQueryRuntimeEnv* pRuntimeEnv) {
|
|||
}
|
||||
|
||||
// todo refactor with isLastRowQuery
|
||||
static bool isPointInterpoQuery(SQuery *pQuery) {
|
||||
bool isPointInterpoQuery(SQuery *pQuery) {
|
||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||
int32_t functionID = pQuery->pExpr1[i].base.functionId;
|
||||
if (functionID == TSDB_FUNC_INTERP) {
|
||||
|
@ -2936,10 +2936,24 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) {
|
|||
assert(size == pGroupResInfo->numOfDataPages);
|
||||
|
||||
bool done = false;
|
||||
|
||||
//TODO add API for release none-dirty pages
|
||||
// SPageInfo* prev = NULL;
|
||||
|
||||
for (int32_t j = pGroupResInfo->pageId; j < size; ++j) {
|
||||
SPageInfo* pi = *(SPageInfo**) taosArrayGet(list, j);
|
||||
tFilePage* pData = getResBufPage(pResultBuf, pi->pageId);
|
||||
|
||||
// release previous buffer pages
|
||||
// if (prev == NULL) {
|
||||
// prev = pi;
|
||||
// } else {
|
||||
// if (prev->pageId != pi->pageId) {
|
||||
// releaseResBufPageInfo(pResultBuf, prev);
|
||||
// prev = pi;
|
||||
// }
|
||||
// }
|
||||
|
||||
assert(pData->num > 0 && pData->num <= pRuntimeEnv->numOfRowsPerPage && pGroupResInfo->rowId < pData->num);
|
||||
int32_t numOfRes = (int32_t)(pData->num - pGroupResInfo->rowId);
|
||||
|
||||
|
@ -3058,7 +3072,7 @@ int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *pGroup) {
|
|||
SResultRow* pRow = getNewResultRow(pRuntimeEnv->pool);
|
||||
resetMergeResultBuf(pRuntimeEnv, pRuntimeEnv->pCtx, pRow);
|
||||
|
||||
pQInfo->groupResInfo.groupId = getGroupResultId(pQInfo->groupIndex);
|
||||
pQInfo->groupResInfo.groupId = getMergeResultGroupId(pQInfo->groupIndex);
|
||||
|
||||
// todo add windowRes iterator
|
||||
int64_t lastTimestamp = -1;
|
||||
|
@ -3339,12 +3353,12 @@ int32_t initResultRow(SResultRow *pResultRow) {
|
|||
return TSDB_CODE_SUCCESS;
|
||||
}
|
||||
|
||||
void resetCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||
void resetDefaultResInfoOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) {
|
||||
SQuery *pQuery = pRuntimeEnv->pQuery;
|
||||
|
||||
int32_t groupIndex = 0;
|
||||
int32_t uid = 0;
|
||||
SResultRow* pRow = doPrepareResultRowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, (char *)&groupIndex, sizeof(groupIndex), true, uid);
|
||||
int32_t tid = 0;
|
||||
int64_t uid = getResultInfoUId(pRuntimeEnv);
|
||||
SResultRow* pRow = doPrepareResultRowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, (char *)&tid, sizeof(tid), true, uid);
|
||||
|
||||
for (int32_t i = 0; i < pQuery->numOfOutput; ++i) {
|
||||
SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i];
|
||||
|
@ -3427,7 +3441,7 @@ void skipResults(SQueryRuntimeEnv *pRuntimeEnv) {
|
|||
pQuery->limit.offset -= pQuery->rec.rows;
|
||||
pQuery->rec.rows = 0;
|
||||
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
resetDefaultResInfoOutputBuf(pRuntimeEnv);
|
||||
|
||||
// clear the buffer full flag if exists
|
||||
CLEAR_QUERY_STATUS(pQuery, QUERY_RESBUF_FULL);
|
||||
|
@ -3792,7 +3806,7 @@ void setExecutionContext(SQInfo *pQInfo, int32_t groupIndex, TSKEY nextKey) {
|
|||
return;
|
||||
}
|
||||
|
||||
uint64_t uid = 0; // uid is always set to be 0
|
||||
uint64_t uid = getResultInfoUId(pRuntimeEnv);
|
||||
SResultRow *pResultRow = doPrepareResultRowFromKey(pRuntimeEnv, pWindowResInfo, (char *)&groupIndex,
|
||||
sizeof(groupIndex), true, uid);
|
||||
if (pResultRow == NULL) {
|
||||
|
@ -4629,10 +4643,10 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
|
|||
int32_t ps = DEFAULT_PAGE_SIZE;
|
||||
int32_t rowsize = 0;
|
||||
getIntermediateBufInfo(pRuntimeEnv, &ps, &rowsize);
|
||||
int32_t TWOMB = 1024*1024*2;
|
||||
int32_t TENMB = 1024*1024*10;
|
||||
|
||||
if (isSTableQuery && !onlyQueryTags(pRuntimeEnv->pQuery)) {
|
||||
code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, rowsize, ps, TWOMB, pQInfo);
|
||||
code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, rowsize, ps, TENMB, pQInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -4660,7 +4674,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
|
|||
} else if (pRuntimeEnv->groupbyNormalCol || QUERY_IS_INTERVAL_QUERY(pQuery) || (!isSTableQuery)) {
|
||||
int32_t numOfResultRows = getInitialPageNum(pQInfo);
|
||||
getIntermediateBufInfo(pRuntimeEnv, &ps, &rowsize);
|
||||
code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, rowsize, ps, TWOMB, pQInfo);
|
||||
code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, rowsize, ps, TENMB, pQInfo);
|
||||
if (code != TSDB_CODE_SUCCESS) {
|
||||
return code;
|
||||
}
|
||||
|
@ -4930,7 +4944,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
|||
size_t numOfGroups = GET_NUM_OF_TABLEGROUP(pQInfo);
|
||||
|
||||
if (isPointInterpoQuery(pQuery)) {
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
resetDefaultResInfoOutputBuf(pRuntimeEnv);
|
||||
assert(pQuery->limit.offset == 0 && pQuery->limit.limit != 0);
|
||||
|
||||
while (pQInfo->groupIndex < numOfGroups) {
|
||||
|
@ -5096,7 +5110,7 @@ static void sequentialTableProcess(SQInfo *pQInfo) {
|
|||
return;
|
||||
}
|
||||
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
resetDefaultResInfoOutputBuf(pRuntimeEnv);
|
||||
resetTimeWindowInfo(pRuntimeEnv, &pRuntimeEnv->windowResInfo);
|
||||
|
||||
SArray *group = GET_TABLEGROUP(pQInfo, 0);
|
||||
|
@ -5456,7 +5470,7 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
|
|||
|
||||
// for ts_comp query, re-initialized is not allowed
|
||||
if (!isTSCompQuery(pQuery)) {
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
resetDefaultResInfoOutputBuf(pRuntimeEnv);
|
||||
}
|
||||
|
||||
// skip blocks without load the actual data block from file if no filter condition present
|
||||
|
@ -5486,7 +5500,7 @@ static void tableMultiOutputProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo)
|
|||
qDebug("QInfo:%p skip current result, offset:%" PRId64 ", next qrange:%" PRId64 "-%" PRId64,
|
||||
pQInfo, pQuery->limit.offset, pQuery->current->lastKey, pQuery->current->win.ekey);
|
||||
|
||||
resetCtxOutputBuf(pRuntimeEnv);
|
||||
resetDefaultResInfoOutputBuf(pRuntimeEnv);
|
||||
}
|
||||
|
||||
limitResults(pRuntimeEnv);
|
||||
|
@ -5811,6 +5825,10 @@ static int32_t convertQueryMsg(SQueryTableMsg *pQueryMsg, SArray **pTableIdList,
|
|||
char **tagCond, char** tbnameCond, SColIndex **groupbyCols, SColumnInfo** tagCols) {
|
||||
int32_t code = TSDB_CODE_SUCCESS;
|
||||
|
||||
if (taosCheckVersion(pQueryMsg->version, version, 3) != 0) {
|
||||
return TSDB_CODE_QRY_INVALID_MSG;
|
||||
}
|
||||
|
||||
pQueryMsg->numOfTables = htonl(pQueryMsg->numOfTables);
|
||||
|
||||
pQueryMsg->window.skey = htobe64(pQueryMsg->window.skey);
|
||||
|
@ -6796,7 +6814,7 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
|
|||
|
||||
qDebug("QInfo:%p ts comp data return, file:%s, size:%"PRId64, pQInfo, pQuery->sdata[0]->data, s);
|
||||
if (lseek(fd, 0, SEEK_SET) >= 0) {
|
||||
size_t sz = read(fd, data, (uint32_t)s);
|
||||
size_t sz = read(fd, data, (uint32_t) s);
|
||||
if(sz < s) { // todo handle error
|
||||
assert(0);
|
||||
}
|
||||
|
|
|
@ -187,7 +187,8 @@ tSQLExpr *tSQLExprCreate(tSQLExpr *pLeft, tSQLExpr *pRight, int32_t optrType) {
|
|||
pExpr->token.type = pLeft->token.type;
|
||||
}
|
||||
|
||||
if (optrType == TK_PLUS || optrType == TK_MINUS || optrType == TK_STAR || optrType == TK_DIVIDE || optrType == TK_REM) {
|
||||
if ((pLeft != NULL && pRight != NULL) &&
|
||||
(optrType == TK_PLUS || optrType == TK_MINUS || optrType == TK_STAR || optrType == TK_DIVIDE || optrType == TK_REM)) {
|
||||
/*
|
||||
* if a token is noted as the TK_TIMESTAMP, the time precision is microsecond
|
||||
* Otherwise, the time precision is adaptive, determined by the time precision from databases.
|
||||
|
|
|
@ -119,8 +119,11 @@ static char* doFlushPageToDisk(SDiskbasedResultBuf* pResultBuf, SPageInfo* pg) {
|
|||
pg->info.offset = allocatePositionInFile(pResultBuf, size);
|
||||
pResultBuf->nextPos += size;
|
||||
|
||||
fseek(pResultBuf->file, pg->info.offset, SEEK_SET);
|
||||
/*int32_t ret =*/ fwrite(t, 1, size, pResultBuf->file);
|
||||
int32_t ret = fseek(pResultBuf->file, pg->info.offset, SEEK_SET);
|
||||
assert(ret == 0);
|
||||
|
||||
ret = (int32_t) fwrite(t, 1, size, pResultBuf->file);
|
||||
assert(ret == size);
|
||||
|
||||
if (pResultBuf->fileSize < pg->info.offset + pg->info.length) {
|
||||
pResultBuf->fileSize = pg->info.offset + pg->info.length;
|
||||
|
@ -407,7 +410,7 @@ void destroyResultBuf(SDiskbasedResultBuf* pResultBuf) {
|
|||
}
|
||||
|
||||
if (pResultBuf->file != NULL) {
|
||||
qDebug("QInfo:%p res output buffer closed, total:%.2f Kb, inmem size:%.2f Kb, file size:%.2f",
|
||||
qDebug("QInfo:%p res output buffer closed, total:%.2f Kb, inmem size:%.2f Kb, file size:%.2f Kb",
|
||||
pResultBuf->handle, pResultBuf->totalBufSize/1024.0, listNEles(pResultBuf->lruList) * pResultBuf->pageSize / 1024.0,
|
||||
pResultBuf->fileSize/1024.0);
|
||||
|
||||
|
|
|
@ -341,8 +341,10 @@ STSBlock* readDataFromDisk(STSBuf* pTSBuf, int32_t order, bool decomp) {
|
|||
pBlock->tag.pz = tp;
|
||||
|
||||
sz = fread(pBlock->tag.pz, (size_t)pBlock->tag.nLen, 1, pTSBuf->f);
|
||||
} else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) {
|
||||
UNUSED(sz);
|
||||
} else if (pBlock->tag.nType != TSDB_DATA_TYPE_NULL) { //TODO check the return value
|
||||
sz = fread(&pBlock->tag.i64Key, (size_t) pBlock->tag.nLen, 1, pTSBuf->f);
|
||||
UNUSED(sz);
|
||||
}
|
||||
|
||||
sz = fread(&pBlock->numOfElem, sizeof(pBlock->numOfElem), 1, pTSBuf->f);
|
||||
|
|
|
@ -20,6 +20,18 @@
|
|||
#include "qExecutor.h"
|
||||
#include "qUtil.h"
|
||||
|
||||
static int32_t getResultRowKeyInfo(SResultRow* pResult, int16_t type, char** key, int16_t* bytes) {
|
||||
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[type].nSize;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t getOutputInterResultBufSize(SQuery* pQuery) {
|
||||
int32_t size = 0;
|
||||
|
||||
|
@ -56,6 +68,12 @@ void cleanupTimeWindowInfo(SWindowResInfo *pWindowResInfo) {
|
|||
assert(pWindowResInfo->pResult == NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
if (pWindowResInfo->type == TSDB_DATA_TYPE_BINARY || pWindowResInfo->type == TSDB_DATA_TYPE_NCHAR) {
|
||||
for(int32_t i = 0; i < pWindowResInfo->size; ++i) {
|
||||
tfree(pWindowResInfo->pResult[i]->key);
|
||||
}
|
||||
}
|
||||
|
||||
tfree(pWindowResInfo->pResult);
|
||||
}
|
||||
|
@ -69,7 +87,7 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR
|
|||
|
||||
for (int32_t i = 0; i < pWindowResInfo->size; ++i) {
|
||||
SResultRow *pWindowRes = pWindowResInfo->pResult[i];
|
||||
clearResultRow(pRuntimeEnv, pWindowRes);
|
||||
clearResultRow(pRuntimeEnv, pWindowRes, pWindowResInfo->type);
|
||||
|
||||
int32_t groupIndex = 0;
|
||||
int64_t uid = 0;
|
||||
|
@ -94,12 +112,8 @@ void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
|
|||
int32_t numOfClosed = numOfClosedTimeWindow(pWindowResInfo);
|
||||
assert(num >= 0 && num <= numOfClosed);
|
||||
|
||||
int16_t type = pWindowResInfo->type;
|
||||
STableId* id = TSDB_TABLEID(pRuntimeEnv->pQuery->current->pTable); // uid is always set to be 0.
|
||||
int64_t uid = id->uid;
|
||||
if (pRuntimeEnv->groupbyNormalCol) {
|
||||
uid = 0;
|
||||
}
|
||||
int16_t type = pWindowResInfo->type;
|
||||
int64_t uid = getResultInfoUId(pRuntimeEnv);
|
||||
|
||||
char *key = NULL;
|
||||
int16_t bytes = -1;
|
||||
|
@ -107,16 +121,7 @@ void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
|
|||
for (int32_t i = 0; i < num; ++i) {
|
||||
SResultRow *pResult = pWindowResInfo->pResult[i];
|
||||
if (pResult->closed) { // remove the window slot from hash table
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
getResultRowKeyInfo(pResult, type, &key, &bytes);
|
||||
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid);
|
||||
taosHashRemove(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
|
||||
} else {
|
||||
|
@ -134,23 +139,16 @@ void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) {
|
|||
// move the unclosed window in the front of the window list
|
||||
for (int32_t k = remain; k < pWindowResInfo->size; ++k) {
|
||||
SResultRow *pWindowRes = pWindowResInfo->pResult[k];
|
||||
clearResultRow(pRuntimeEnv, pWindowRes);
|
||||
clearResultRow(pRuntimeEnv, pWindowRes, pWindowResInfo->type);
|
||||
}
|
||||
|
||||
pWindowResInfo->size = remain;
|
||||
|
||||
for (int32_t k = 0; k < pWindowResInfo->size; ++k) {
|
||||
SResultRow *pResult = pWindowResInfo->pResult[k];
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
getResultRowKeyInfo(pResult, type, &key, &bytes);
|
||||
SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid);
|
||||
|
||||
int32_t *p = (int32_t *)taosHashGet(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes));
|
||||
assert(p != NULL);
|
||||
|
||||
|
@ -237,7 +235,7 @@ void closeTimeWindow(SWindowResInfo *pWindowResInfo, int32_t slot) {
|
|||
getResultRow(pWindowResInfo, slot)->closed = true;
|
||||
}
|
||||
|
||||
void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pWindowRes) {
|
||||
void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pWindowRes, int16_t type) {
|
||||
if (pWindowRes == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -261,7 +259,12 @@ void clearResultRow(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pWindowRes) {
|
|||
pWindowRes->pageId = -1;
|
||||
pWindowRes->rowId = -1;
|
||||
pWindowRes->closed = false;
|
||||
pWindowRes->win = TSWINDOW_INITIALIZER;
|
||||
|
||||
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
|
||||
tfree(pWindowRes->key);
|
||||
} else {
|
||||
pWindowRes->win = TSWINDOW_INITIALIZER;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -379,3 +382,18 @@ void* destroyResultRowPool(SResultRowPool* p) {
|
|||
tfree(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
uint64_t getResultInfoUId(SQueryRuntimeEnv* pRuntimeEnv) {
|
||||
if (!pRuntimeEnv->stableQuery) {
|
||||
return 0; // for simple table query, the uid is always set to be 0;
|
||||
}
|
||||
|
||||
SQuery* pQuery = pRuntimeEnv->pQuery;
|
||||
if ((pQuery->checkBuffer == 1 && pQuery->interval.interval == 0) || isPointInterpoQuery(pQuery) ||
|
||||
pRuntimeEnv->groupbyNormalCol) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
STableId* id = TSDB_TABLEID(pRuntimeEnv->pQuery->current);
|
||||
return id->uid;
|
||||
}
|
|
@ -2628,16 +2628,14 @@ static void yy_reduce(
|
|||
{yymsp[1].minor.yy216.limit = -1; yymsp[1].minor.yy216.offset = 0;}
|
||||
break;
|
||||
case 177: /* limit_opt ::= LIMIT signed */
|
||||
case 181: /* slimit_opt ::= SLIMIT signed */ yytestcase(yyruleno==181);
|
||||
{yymsp[-1].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-1].minor.yy216.offset = 0;}
|
||||
break;
|
||||
case 178: /* limit_opt ::= LIMIT signed OFFSET signed */
|
||||
{yymsp[-3].minor.yy216.limit = yymsp[-2].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[0].minor.yy207;}
|
||||
{ yymsp[-3].minor.yy216.limit = yymsp[-2].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[0].minor.yy207;}
|
||||
break;
|
||||
case 179: /* limit_opt ::= LIMIT signed COMMA signed */
|
||||
{yymsp[-3].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[-2].minor.yy207;}
|
||||
break;
|
||||
case 181: /* slimit_opt ::= SLIMIT signed */
|
||||
{yymsp[-1].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-1].minor.yy216.offset = 0;}
|
||||
{ yymsp[-3].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[-2].minor.yy207;}
|
||||
break;
|
||||
case 182: /* slimit_opt ::= SLIMIT signed SOFFSET signed */
|
||||
{yymsp[-3].minor.yy216.limit = yymsp[-2].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[0].minor.yy207;}
|
||||
|
@ -2646,7 +2644,8 @@ static void yy_reduce(
|
|||
{yymsp[-3].minor.yy216.limit = yymsp[0].minor.yy207; yymsp[-3].minor.yy216.offset = yymsp[-2].minor.yy207;}
|
||||
break;
|
||||
case 186: /* expr ::= LP expr RP */
|
||||
{yymsp[-2].minor.yy64 = yymsp[-1].minor.yy64; }
|
||||
{yylhsminor.yy64 = yymsp[-1].minor.yy64; yylhsminor.yy64->token.z = yymsp[-2].minor.yy0.z; yylhsminor.yy64->token.n = (yymsp[0].minor.yy0.z - yymsp[-2].minor.yy0.z + 1);}
|
||||
yymsp[-2].minor.yy64 = yylhsminor.yy64;
|
||||
break;
|
||||
case 187: /* expr ::= ID */
|
||||
{yylhsminor.yy64 = tSQLExprIdValueCreate(&yymsp[0].minor.yy0, TK_ID);}
|
||||
|
|
|
@ -172,6 +172,7 @@ typedef struct SSyncNode {
|
|||
// sync module global
|
||||
extern int32_t tsSyncNum;
|
||||
extern char tsNodeFqdn[TSDB_FQDN_LEN];
|
||||
extern char * syncStatus[];
|
||||
|
||||
void *syncRetrieveData(void *param);
|
||||
void *syncRestoreData(void *param);
|
||||
|
|
|
@ -73,6 +73,14 @@ char* syncRole[] = {
|
|||
"master"
|
||||
};
|
||||
|
||||
char *syncStatus[] = {
|
||||
"init",
|
||||
"start",
|
||||
"file",
|
||||
"cache",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
SYNC_STATUS_BROADCAST,
|
||||
SYNC_STATUS_BROADCAST_RSP,
|
||||
|
@ -282,7 +290,7 @@ void syncStop(int64_t rid) {
|
|||
pPeer = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA];
|
||||
if (pPeer) syncRemovePeer(pPeer);
|
||||
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
taosRemoveRef(tsSyncRefId, rid);
|
||||
|
@ -350,7 +358,7 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) {
|
|||
(*pNode->notifyRole)(pNode->vgId, nodeRole);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
sInfo("vgId:%d, %d replicas are configured, quorum:%d", pNode->vgId, pNode->replica, pNode->quorum);
|
||||
syncBroadcastStatus(pNode);
|
||||
|
@ -423,7 +431,7 @@ void syncRecover(int64_t rid) {
|
|||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
taosReleaseRef(tsSyncRefId, rid);
|
||||
}
|
||||
|
@ -498,6 +506,8 @@ int32_t syncDecPeerRef(SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
static void syncClosePeerConn(SSyncPeer *pPeer) {
|
||||
sDebug("%s, pfd:%d sfd:%d will be closed", pPeer->id, pPeer->peerFd, pPeer->syncFd);
|
||||
|
||||
taosTmrStopA(&pPeer->timer);
|
||||
taosClose(pPeer->syncFd);
|
||||
if (pPeer->peerFd >= 0) {
|
||||
|
@ -751,7 +761,7 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t new
|
|||
sDebug("vgId:%d, choose master", pNode->vgId);
|
||||
syncChooseMaster(pNode);
|
||||
} else {
|
||||
sDebug("vgId:%d, version inconsistent, cannot choose master", pNode->vgId);
|
||||
sDebug("vgId:%d, cannot choose master since roles inconsistent", pNode->vgId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -770,11 +780,12 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t new
|
|||
}
|
||||
|
||||
static void syncRestartPeer(SSyncPeer *pPeer) {
|
||||
sDebug("%s, restart peer connection", pPeer->id);
|
||||
sDebug("%s, restart peer connection, last sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
|
||||
syncClosePeerConn(pPeer);
|
||||
|
||||
pPeer->sstatus = TAOS_SYNC_STATUS_INIT;
|
||||
sDebug("%s, peer conn is restart and set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
|
||||
int32_t ret = strcmp(pPeer->fqdn, tsNodeFqdn);
|
||||
if (ret > 0 || (ret == 0 && pPeer->port > tsSyncPort)) {
|
||||
|
@ -803,7 +814,7 @@ static void syncProcessSyncRequest(char *msg, SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
if (pPeer->sstatus != TAOS_SYNC_STATUS_INIT) {
|
||||
sDebug("%s, sync is already started", pPeer->id);
|
||||
sDebug("%s, sync is already started for sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
return; // already started
|
||||
}
|
||||
|
||||
|
@ -821,7 +832,7 @@ static void syncProcessSyncRequest(char *msg, SSyncPeer *pPeer) {
|
|||
syncDecPeerRef(pPeer);
|
||||
} else {
|
||||
pPeer->sstatus = TAOS_SYNC_STATUS_START;
|
||||
sDebug("%s, thread is created to retrieve data", pPeer->id);
|
||||
sDebug("%s, thread is created to retrieve data, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -831,9 +842,10 @@ static void syncNotStarted(void *param, void *tmrId) {
|
|||
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
pPeer->timer = NULL;
|
||||
sInfo("%s, sync connection is still not up, restart", pPeer->id);
|
||||
pPeer->sstatus = TAOS_SYNC_STATUS_INIT;
|
||||
sInfo("%s, sync conn is still not up, restart and set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
syncRestartConnection(pPeer);
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
}
|
||||
|
||||
static void syncTryRecoverFromMaster(void *param, void *tmrId) {
|
||||
|
@ -842,14 +854,14 @@ static void syncTryRecoverFromMaster(void *param, void *tmrId) {
|
|||
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
syncRecoverFromMaster(pPeer);
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
}
|
||||
|
||||
static void syncRecoverFromMaster(SSyncPeer *pPeer) {
|
||||
SSyncNode *pNode = pPeer->pSyncNode;
|
||||
|
||||
if (nodeSStatus != TAOS_SYNC_STATUS_INIT) {
|
||||
sDebug("%s, sync is already started, status:%d", pPeer->id, nodeSStatus);
|
||||
sDebug("%s, sync is already started since sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -877,7 +889,7 @@ static void syncRecoverFromMaster(SSyncPeer *pPeer) {
|
|||
sError("%s, failed to send sync-req to peer", pPeer->id);
|
||||
} else {
|
||||
nodeSStatus = TAOS_SYNC_STATUS_START;
|
||||
sInfo("%s, sync-req is sent", pPeer->id);
|
||||
sInfo("%s, sync-req is sent to peer, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -915,7 +927,8 @@ static void syncProcessForwardFromPeer(char *cont, SSyncPeer *pPeer) {
|
|||
if (nodeSStatus != TAOS_SYNC_STATUS_INIT) {
|
||||
syncSaveIntoBuffer(pPeer, pHead);
|
||||
} else {
|
||||
sError("%s, forward discarded, hver:%" PRIu64, pPeer->id, pHead->version);
|
||||
sError("%s, forward discarded since sstatus:%s, hver:%" PRIu64, pPeer->id, syncStatus[nodeSStatus],
|
||||
pHead->version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -924,8 +937,9 @@ static void syncProcessPeersStatusMsg(char *cont, SSyncPeer *pPeer) {
|
|||
SSyncNode * pNode = pPeer->pSyncNode;
|
||||
SPeersStatus *pPeersStatus = (SPeersStatus *)cont;
|
||||
|
||||
sDebug("%s, status msg is received, self:%s sver:%" PRIu64 " peer:%s sver:%" PRIu64 ", ack:%d tranId:%u type:%s", pPeer->id,
|
||||
syncRole[nodeRole], nodeVersion, syncRole[pPeersStatus->role], pPeersStatus->version, pPeersStatus->ack, pPeersStatus->tranId, statusType[pPeersStatus->type]);
|
||||
sDebug("%s, status is received, self:%s:%s:%" PRIu64 ", peer:%s:%" PRIu64 ", ack:%d tranId:%u type:%s pfd:%d",
|
||||
pPeer->id, syncRole[nodeRole], syncStatus[nodeSStatus], nodeVersion, syncRole[pPeersStatus->role],
|
||||
pPeersStatus->version, pPeersStatus->ack, pPeersStatus->tranId, statusType[pPeersStatus->type], pPeer->peerFd);
|
||||
|
||||
pPeer->version = pPeersStatus->version;
|
||||
syncCheckRole(pPeer, pPeersStatus->peersStatus, pPeersStatus->role);
|
||||
|
@ -982,7 +996,7 @@ static int32_t syncProcessPeerMsg(void *param, void *buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
@ -1014,8 +1028,10 @@ static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type
|
|||
|
||||
int32_t retLen = taosWriteMsg(pPeer->peerFd, msg, statusMsgLen);
|
||||
if (retLen == statusMsgLen) {
|
||||
sDebug("%s, status msg is sent, self:%s sver:%" PRIu64 ", ack:%d tranId:%u type:%s", pPeer->id, syncRole[pPeersStatus->role],
|
||||
pPeersStatus->version, pPeersStatus->ack, pPeersStatus->tranId, statusType[pPeersStatus->type]);
|
||||
sDebug("%s, status is sent, self:%s:%s:%" PRIu64 ", peer:%s:%s:%" PRIu64 ", ack:%d tranId:%u type:%s pfd:%d",
|
||||
pPeer->id, syncRole[nodeRole], syncStatus[nodeSStatus], nodeVersion, syncRole[pPeer->role],
|
||||
syncStatus[pPeer->sstatus], pPeer->version, pPeersStatus->ack, pPeersStatus->tranId,
|
||||
statusType[pPeersStatus->type], pPeer->peerFd);
|
||||
} else {
|
||||
sDebug("%s, failed to send status msg, restart", pPeer->id);
|
||||
syncRestartConnection(pPeer);
|
||||
|
@ -1048,7 +1064,7 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) {
|
|||
firstPkt.sourceId = pNode->vgId; // tell arbitrator its vgId
|
||||
|
||||
if (taosWriteMsg(connFd, &firstPkt, sizeof(firstPkt)) == sizeof(firstPkt)) {
|
||||
sDebug("%s, connection to peer server is setup", pPeer->id);
|
||||
sDebug("%s, connection to peer server is setup, pfd:%d sfd:%d", pPeer->id, connFd, pPeer->syncFd);
|
||||
pPeer->peerFd = connFd;
|
||||
pPeer->role = TAOS_SYNC_ROLE_UNSYNCED;
|
||||
pPeer->pConn = taosAllocateTcpConn(tsTcpPool, pPeer, connFd);
|
||||
|
@ -1069,7 +1085,7 @@ static void syncCheckPeerConnection(void *param, void *tmrId) {
|
|||
sDebug("%s, check peer connection", pPeer->id);
|
||||
syncSetupPeerConnection(pPeer);
|
||||
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
}
|
||||
|
||||
static void syncCreateRestoreDataThread(SSyncPeer *pPeer) {
|
||||
|
@ -1135,7 +1151,8 @@ static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) {
|
|||
pPeer->syncFd = connFd;
|
||||
syncCreateRestoreDataThread(pPeer);
|
||||
} else {
|
||||
sDebug("%s, TCP connection is already up, close one", pPeer->id);
|
||||
sDebug("%s, TCP connection is already up(pfd:%d), close one, new pfd:%d sfd:%d", pPeer->id, pPeer->peerFd, connFd,
|
||||
pPeer->syncFd);
|
||||
syncClosePeerConn(pPeer);
|
||||
pPeer->peerFd = connFd;
|
||||
pPeer->pConn = taosAllocateTcpConn(tsTcpPool, pPeer, connFd);
|
||||
|
@ -1145,7 +1162,7 @@ static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) {
|
|||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
}
|
||||
|
||||
static void syncProcessBrokenLink(void *param) {
|
||||
|
@ -1156,14 +1173,14 @@ static void syncProcessBrokenLink(void *param) {
|
|||
if (taosAcquireRef(tsSyncRefId, pNode->rid) == NULL) return;
|
||||
pthread_mutex_lock(&pNode->mutex);
|
||||
|
||||
sDebug("%s, TCP link is broken since %s", pPeer->id, strerror(errno));
|
||||
sDebug("%s, TCP link is broken since %s, pfd:%d sfd:%d", pPeer->id, strerror(errno), pPeer->peerFd, pPeer->syncFd);
|
||||
pPeer->peerFd = -1;
|
||||
|
||||
if (syncDecPeerRef(pPeer) != 0) {
|
||||
syncRestartConnection(pPeer);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
taosReleaseRef(tsSyncRefId, pNode->rid);
|
||||
}
|
||||
|
||||
|
@ -1239,10 +1256,13 @@ static void syncMonitorNodeRole(void *param, void *tmrId) {
|
|||
if (index == pNode->selfIndex) continue;
|
||||
|
||||
SSyncPeer *pPeer = pNode->peerInfo[index];
|
||||
if (pPeer->role > TAOS_SYNC_ROLE_UNSYNCED && nodeRole > TAOS_SYNC_ROLE_UNSYNCED) continue;
|
||||
if (pPeer->sstatus > TAOS_SYNC_STATUS_INIT || nodeSStatus > TAOS_SYNC_STATUS_INIT) continue;
|
||||
if (/*pPeer->role > TAOS_SYNC_ROLE_UNSYNCED && */ nodeRole > TAOS_SYNC_ROLE_UNSYNCED) continue;
|
||||
if (/*pPeer->sstatus > TAOS_SYNC_STATUS_INIT || */ nodeSStatus > TAOS_SYNC_STATUS_INIT) continue;
|
||||
|
||||
sDebug("%s, check roles since self:%s sstatus:%s, peer:%s sstatus:%s", pPeer->id, syncRole[pPeer->role],
|
||||
syncStatus[pPeer->sstatus], syncRole[nodeRole], syncStatus[nodeSStatus]);
|
||||
syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_CHECK_ROLE, syncGenTranId());
|
||||
break;
|
||||
}
|
||||
|
||||
pNode->pRoleTimer = taosTmrStart(syncMonitorNodeRole, SYNC_ROLE_TIMER, (void *)pNode->rid, tsSyncTmrCtrl);
|
||||
|
@ -1271,7 +1291,7 @@ static void syncMonitorFwdInfos(void *param, void *tmrId) {
|
|||
}
|
||||
|
||||
syncRemoveConfirmedFwdInfo(pNode);
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
}
|
||||
|
||||
pNode->pFwdTimer = taosTmrStart(syncMonitorFwdInfos, SYNC_FWD_TIMER, (void *)pNode->rid, tsSyncTmrCtrl);
|
||||
|
@ -1339,7 +1359,7 @@ static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle
|
|||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&(pNode->mutex));
|
||||
pthread_mutex_unlock(&pNode->mutex);
|
||||
|
||||
return code;
|
||||
}
|
||||
|
|
|
@ -65,7 +65,10 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
|||
while (1) {
|
||||
// read file info
|
||||
int32_t ret = taosReadMsg(pPeer->syncFd, &(minfo), sizeof(minfo));
|
||||
if (ret < 0) break;
|
||||
if (ret < 0) {
|
||||
sError("%s, failed to read file info while restore file since %s", pPeer->id, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
// if no more file from master, break;
|
||||
if (minfo.name[0] == 0 || minfo.magic == 0) {
|
||||
|
@ -83,7 +86,7 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
|||
|
||||
// check the file info
|
||||
sinfo = minfo;
|
||||
sDebug("%s, get file info:%s", pPeer->id, minfo.name);
|
||||
sDebug("%s, get file:%s info size:%" PRId64, pPeer->id, minfo.name, minfo.size);
|
||||
sinfo.magic = (*pNode->getFileInfo)(pNode->vgId, sinfo.name, &sinfo.index, TAOS_SYNC_MAX_INDEX, &sinfo.size,
|
||||
&sinfo.fversion);
|
||||
|
||||
|
@ -92,8 +95,11 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
|||
fileAck.sync = (sinfo.magic != minfo.magic || sinfo.name[0] == 0) ? 1 : 0;
|
||||
|
||||
// send file ack
|
||||
ret = taosWriteMsg(pPeer->syncFd, &(fileAck), sizeof(fileAck));
|
||||
if (ret < 0) break;
|
||||
ret = taosWriteMsg(pPeer->syncFd, &fileAck, sizeof(fileAck));
|
||||
if (ret < 0) {
|
||||
sError("%s, failed to write file:%s ack while restore file since %s", pPeer->id, minfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
// if sync is not required, continue
|
||||
if (fileAck.sync == 0) {
|
||||
|
@ -108,14 +114,17 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
|||
|
||||
int32_t dfd = open(name, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO);
|
||||
if (dfd < 0) {
|
||||
sError("%s, failed to open file:%s", pPeer->id, name);
|
||||
sError("%s, failed to open file:%s while restore file since %s", pPeer->id, minfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
ret = taosCopyFds(pPeer->syncFd, dfd, minfo.size);
|
||||
fsync(dfd);
|
||||
close(dfd);
|
||||
if (ret < 0) break;
|
||||
if (ret < 0) {
|
||||
sError("%s, failed to copy file:%s while restore file since %s", pPeer->id, minfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
fileChanged = true;
|
||||
sDebug("%s, %s is received, size:%" PRId64, pPeer->id, minfo.name, minfo.size);
|
||||
|
@ -125,6 +134,7 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) {
|
|||
// data file is changed, code shall be set to 1
|
||||
*fversion = minfo.fversion;
|
||||
code = 1;
|
||||
sDebug("%s, file changed while restore file", pPeer->id);
|
||||
}
|
||||
|
||||
if (code < 0) {
|
||||
|
@ -146,15 +156,22 @@ static int32_t syncRestoreWal(SSyncPeer *pPeer) {
|
|||
|
||||
while (1) {
|
||||
ret = taosReadMsg(pPeer->syncFd, pHead, sizeof(SWalHead));
|
||||
if (ret < 0) break;
|
||||
if (ret < 0) {
|
||||
sError("%s, failed to read walhead while restore wal since %s", pPeer->id, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
if (pHead->len == 0) {
|
||||
sDebug("%s, wal is synced over", pPeer->id);
|
||||
code = 0;
|
||||
break;
|
||||
} // wal sync over
|
||||
|
||||
ret = taosReadMsg(pPeer->syncFd, pHead->cont, pHead->len);
|
||||
if (ret < 0) break;
|
||||
if (ret < 0) {
|
||||
sError("%s, failed to read walcont, len:%d while restore wal since %s", pPeer->id, pHead->len, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
sTrace("%s, restore a record, qtype:wal len:%d hver:%" PRIu64, pPeer->id, pHead->len, pHead->version);
|
||||
|
||||
|
@ -267,7 +284,7 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) {
|
|||
nodeSStatus = TAOS_SYNC_STATUS_FILE;
|
||||
uint64_t fversion = 0;
|
||||
|
||||
sDebug("%s, start to restore file", pPeer->id);
|
||||
sDebug("%s, start to restore file, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
|
||||
int32_t code = syncRestoreFile(pPeer, &fversion);
|
||||
if (code < 0) {
|
||||
sError("%s, failed to restore file", pPeer->id);
|
||||
|
@ -291,7 +308,7 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
nodeSStatus = TAOS_SYNC_STATUS_CACHE;
|
||||
sDebug("%s, start to insert buffered points", pPeer->id);
|
||||
sDebug("%s, start to insert buffered points, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
|
||||
if (syncProcessBufferedFwd(pPeer) < 0) {
|
||||
sError("%s, failed to insert buffered points", pPeer->id);
|
||||
return -1;
|
||||
|
@ -327,6 +344,8 @@ void *syncRestoreData(void *param) {
|
|||
(*pNode->notifyRole)(pNode->vgId, nodeRole);
|
||||
|
||||
nodeSStatus = TAOS_SYNC_STATUS_INIT;
|
||||
sInfo("%s, sync over, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]);
|
||||
|
||||
taosClose(pPeer->syncFd);
|
||||
syncCloseRecvBuffer(pNode);
|
||||
__sync_fetch_and_sub(&tsSyncNum, 1);
|
||||
|
|
|
@ -114,7 +114,10 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
|||
|
||||
// send the file info
|
||||
int32_t ret = taosWriteMsg(pPeer->syncFd, &(fileInfo), sizeof(fileInfo));
|
||||
if (ret < 0) break;
|
||||
if (ret < 0) {
|
||||
sError("%s, failed to write file:%s info while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
// if no file anymore, break
|
||||
if (fileInfo.magic == 0 || fileInfo.name[0] == 0) {
|
||||
|
@ -124,8 +127,11 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
// wait for the ack from peer
|
||||
ret = taosReadMsg(pPeer->syncFd, &(fileAck), sizeof(fileAck));
|
||||
if (ret < 0) break;
|
||||
ret = taosReadMsg(pPeer->syncFd, &fileAck, sizeof(fileAck));
|
||||
if (ret < 0) {
|
||||
sError("%s, failed to read file:%s ack while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
// set the peer sync version
|
||||
pPeer->sversion = fileInfo.fversion;
|
||||
|
@ -134,7 +140,10 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
|||
snprintf(name, sizeof(name), "%s/%s", pNode->path, fileInfo.name);
|
||||
|
||||
// add the file into watch list
|
||||
if (syncAddIntoWatchList(pPeer, name) < 0) break;
|
||||
if (syncAddIntoWatchList(pPeer, name) < 0) {
|
||||
sError("%s, failed to watch file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
// if sync is not required, continue
|
||||
if (fileAck.sync == 0) {
|
||||
|
@ -145,21 +154,30 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) {
|
|||
|
||||
// send the file to peer
|
||||
int32_t sfd = open(name, O_RDONLY);
|
||||
if (sfd < 0) break;
|
||||
if (sfd < 0) {
|
||||
sError("%s, failed to open file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
ret = taosSendFile(pPeer->syncFd, sfd, NULL, fileInfo.size);
|
||||
close(sfd);
|
||||
if (ret < 0) break;
|
||||
if (ret < 0) {
|
||||
sError("%s, failed to send file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
|
||||
sDebug("%s, %s is sent, size:%" PRId64, pPeer->id, name, fileInfo.size);
|
||||
fileInfo.index++;
|
||||
|
||||
// check if processed files are modified
|
||||
if (syncAreFilesModified(pPeer) != 0) break;
|
||||
if (syncAreFilesModified(pPeer) != 0) {
|
||||
sInfo("%s, file:%s are modified while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (code < 0) {
|
||||
sError("%s, failed to retrieve file since %s", pPeer->id, strerror(errno));
|
||||
sError("%s, failed to retrieve file", pPeer->id);
|
||||
}
|
||||
|
||||
return code;
|
||||
|
@ -318,6 +336,7 @@ static int32_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index)
|
|||
if (((event & IN_MODIFY) == 0) || once) {
|
||||
if (fversion == 0) {
|
||||
pPeer->sstatus = TAOS_SYNC_STATUS_CACHE; // start to forward pkt
|
||||
sDebug("%s, fversion is 0 then set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
fversion = nodeVersion; // must read data to fversion
|
||||
}
|
||||
}
|
||||
|
@ -416,8 +435,9 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) {
|
|||
}
|
||||
|
||||
if (code == 0) {
|
||||
sInfo("%s, wal retrieve is finished", pPeer->id);
|
||||
pPeer->sstatus = TAOS_SYNC_STATUS_CACHE;
|
||||
sInfo("%s, wal retrieve is finished, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
|
||||
SWalHead walHead;
|
||||
memset(&walHead, 0, sizeof(walHead));
|
||||
code = taosWriteMsg(pPeer->syncFd, &walHead, sizeof(walHead));
|
||||
|
@ -445,7 +465,7 @@ static int32_t syncRetrieveDataStepByStep(SSyncPeer *pPeer) {
|
|||
|
||||
pPeer->sversion = 0;
|
||||
pPeer->sstatus = TAOS_SYNC_STATUS_FILE;
|
||||
sInfo("%s, start to retrieve file", pPeer->id);
|
||||
sInfo("%s, start to retrieve file, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
|
||||
if (syncRetrieveFile(pPeer) < 0) {
|
||||
sError("%s, failed to retrieve file", pPeer->id);
|
||||
return -1;
|
||||
|
|
|
@ -107,7 +107,7 @@ int32_t taosWriteMsg(SOCKET fd, void *buf, int32_t nbytes) {
|
|||
while (nleft > 0) {
|
||||
nwritten = (int32_t)taosWriteSocket(fd, (char *)ptr, (size_t)nleft);
|
||||
if (nwritten <= 0) {
|
||||
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
|
||||
if (errno == EINTR /* || errno == EAGAIN || errno == EWOULDBLOCK */)
|
||||
continue;
|
||||
else
|
||||
return -1;
|
||||
|
@ -133,7 +133,7 @@ int32_t taosReadMsg(SOCKET fd, void *buf, int32_t nbytes) {
|
|||
if (nread == 0) {
|
||||
break;
|
||||
} else if (nread < 0) {
|
||||
if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
if (errno == EINTR/* || errno == EAGAIN || errno == EWOULDBLOCK*/) {
|
||||
continue;
|
||||
} else {
|
||||
return -1;
|
||||
|
|
|
@ -31,6 +31,23 @@ class Node:
|
|||
self.homeDir = homeDir
|
||||
self.conn = Connection("{}@{}".format(username, hostName), connect_kwargs={"password": "{}".format(password)})
|
||||
|
||||
def buildTaosd(self):
|
||||
try:
|
||||
self.conn.cd("/root/TDinternal/community")
|
||||
self.conn.run("git checkout develop")
|
||||
self.conn.run("git pull")
|
||||
self.conn.cd("/root/TDinternal")
|
||||
self.conn.run("git checkout develop")
|
||||
self.conn.run("git pull")
|
||||
self.conn.cd("/root/TDinternal/debug")
|
||||
self.conn.run("cmake ..")
|
||||
self.conn.run("make")
|
||||
self.conn.run("make install")
|
||||
except Exception as e:
|
||||
print("Build Taosd error for node %d " % self.index)
|
||||
logging.exception(e)
|
||||
pass
|
||||
|
||||
def startTaosd(self):
|
||||
try:
|
||||
self.conn.run("sudo systemctl start taosd")
|
||||
|
@ -50,7 +67,7 @@ class Node:
|
|||
self.conn.run("sudo systemctl restart taosd")
|
||||
except Exception as e:
|
||||
print("Stop Taosd error for node %d " % self.index)
|
||||
logging.exception(e)
|
||||
logging.exception(e)
|
||||
|
||||
def removeTaosd(self):
|
||||
try:
|
||||
|
@ -105,9 +122,11 @@ class Node:
|
|||
|
||||
class Nodes:
|
||||
def __init__(self):
|
||||
self.node1 = Node(1, 'ubuntu', '192.168.1.52', 'node1', 'tbase125!', '/home/ubuntu')
|
||||
self.node2 = Node(2, 'ubuntu', '192.168.1.53', 'node2', 'tbase125!', '/home/ubuntu')
|
||||
self.node3 = Node(3, 'ubuntu', '192.168.1.54', 'node3', 'tbase125!', '/home/ubuntu')
|
||||
self.node1 = Node(1, 'root', '52.151.60.239', 'node1', 'r', '/root/')
|
||||
self.node2 = Node(2, 'root', '52.183.32.246', 'node1', 'r', '/root/')
|
||||
self.node3 = Node(3, 'root', '51.143.46.79', 'node1', 'r', '/root/')
|
||||
self.node4 = Node(4, 'root', '52.183.2.76', 'node1', 'r', '/root/')
|
||||
self.node5 = Node(5, 'root', '13.66.225.87', 'node1', 'r', '/root/')
|
||||
|
||||
def stopAllTaosd(self):
|
||||
self.node1.stopTaosd()
|
||||
|
|
|
@ -141,6 +141,40 @@ class TDTestCase:
|
|||
tdSql.query("select * from meters1, meters3 where meters1.ts = meters3.ts and meters1.tag1 = meters3.tag1")
|
||||
tdSql.checkRows(0)
|
||||
|
||||
tdSql.execute("create table join_mt0(ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) tags(t1 int, t2 binary(12))")
|
||||
tdSql.execute("create table join_mt1(ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) tags(t1 int, t2 binary(12), t3 int)")
|
||||
|
||||
ts = 1538548685000
|
||||
for i in range(3):
|
||||
tdSql.execute("create table join_tb%d using join_mt0 tags(%d, 'abc')" % (i, i))
|
||||
sql = "insert into join_tb%d values" % i
|
||||
for j in range(500):
|
||||
val = j % 100
|
||||
sql += "(%d, %d, %f, %d, %d, %d, %f, %d, 'binary%d', 'nchar%d')" % (ts + j, val, val * 1.0, val, val, val, val * 1.0, val % 2, val, val)
|
||||
tdSql.execute(sql)
|
||||
sql = "insert into join_tb%d values" % i
|
||||
for j in range(500, 1000):
|
||||
val = j % 100
|
||||
sql += "(%d, %d, %f, %d, %d, %d, %f, %d, 'binary%d', 'nchar%d')" % (ts + 500 + j, val, val * 1.0, val, val, val, val * 1.0, val % 2, val, val)
|
||||
tdSql.execute(sql)
|
||||
|
||||
for i in range(3):
|
||||
tdSql.execute("create table join_1_tb%d using join_mt1 tags(%d, 'abc%d', %d)" % (i, i, i, i))
|
||||
sql = "insert into join_1_tb%d values" % i
|
||||
for j in range(500):
|
||||
val = j % 100
|
||||
sql += "(%d, %d, %f, %d, %d, %d, %f, %d, 'binary%d', 'nchar%d')" % (ts + j, val, val * 1.0, val, val, val, val * 1.0, val % 2, val, val)
|
||||
tdSql.execute(sql)
|
||||
sql = "insert into join_1_tb%d values" % i
|
||||
for j in range(500, 1000):
|
||||
val = j % 100
|
||||
sql += "(%d, %d, %f, %d, %d, %d, %f, %d, 'binary%d', 'nchar%d')" % (ts + 500 + j, val, val * 1.0, val, val, val, val * 1.0, val % 2, val, val)
|
||||
tdSql.execute(sql)
|
||||
|
||||
tdSql.error("select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1 order by join_mt0.ts desc")
|
||||
tdSql.error("select count(join_mt0.c1), first(join_mt0.c1)-first(join_mt1.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts")
|
||||
tdSql.error("select count(join_mt0.c1), first(join_mt0.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2 order by join_mt0.t1 desc slimit 3")
|
||||
tdSql.error("select count(join_mt0.c1), first(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2, join_mt1.t1 order by join_mt0.ts desc, join_mt1.ts asc limit 10;")
|
||||
|
||||
def stop(self):
|
||||
tdSql.close()
|
||||
|
|
|
@ -5,6 +5,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0
|
|||
system sh/exec.sh -n dnode1 -s start
|
||||
sleep 500
|
||||
sql connect
|
||||
#========================================= setup environment ================================
|
||||
|
||||
$dbPrefix = ca_db
|
||||
$tbPrefix = ca_tb
|
||||
|
@ -28,12 +29,41 @@ sql create table $stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5
|
|||
$i = 0
|
||||
$ts = $ts0
|
||||
$halfTbNum = $tbNum / 2
|
||||
while $i < $halfTbNum
|
||||
$tbId = $i + $halfTbNum
|
||||
$tb = $tbPrefix . $i
|
||||
$tb1 = $tbPrefix . $tbId
|
||||
sql create table $tb using $stb tags( $i )
|
||||
sql create table $tb1 using $stb tags( $tbId )
|
||||
#while $i < $halfTbNum
|
||||
$t1 = $i + 1
|
||||
$t2 = $i + 2
|
||||
$t3 = $i + 3
|
||||
$t4 = $i + 4
|
||||
|
||||
$t5 = $i + $halfTbNum
|
||||
$t6 = $t5 + 1
|
||||
$t7 = $t6 + 1
|
||||
$t8 = $t7 + 1
|
||||
$t9 = $t8 + 1
|
||||
|
||||
$tb0 = $tbPrefix . $i
|
||||
$tb1 = $tbPrefix . $t1
|
||||
$tb2 = $tbPrefix . $t2
|
||||
$tb3 = $tbPrefix . $t3
|
||||
$tb4 = $tbPrefix . $t4
|
||||
|
||||
$tb5 = $tbPrefix . $t5
|
||||
$tb6 = $tbPrefix . $t6
|
||||
$tb7 = $tbPrefix . $t7
|
||||
$tb8 = $tbPrefix . $t8
|
||||
$tb9 = $tbPrefix . $t9
|
||||
|
||||
sql create table $tb0 using $stb tags( $i )
|
||||
sql create table $tb1 using $stb tags( $t1 )
|
||||
sql create table $tb2 using $stb tags( $t2 )
|
||||
sql create table $tb3 using $stb tags( $t3 )
|
||||
sql create table $tb4 using $stb tags( $t4 )
|
||||
|
||||
sql create table $tb5 using $stb tags( $t5 )
|
||||
sql create table $tb6 using $stb tags( $t6 )
|
||||
sql create table $tb7 using $stb tags( $t7 )
|
||||
sql create table $tb8 using $stb tags( $t8 )
|
||||
sql create table $tb9 using $stb tags( $t9 )
|
||||
|
||||
$x = 0
|
||||
while $x < $rowNum
|
||||
|
@ -46,50 +76,61 @@ while $i < $halfTbNum
|
|||
$binary = $binary . '
|
||||
$nchar = 'nchar . $c
|
||||
$nchar = $nchar . '
|
||||
sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , NULL , $c , NULL , $c , NULL , $c , NULL, NULL , $nchar )
|
||||
sql insert into $tb0 values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb2 values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb3 values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb4 values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar )
|
||||
$x = $x + 1
|
||||
endw
|
||||
$i = $i + 1
|
||||
endw
|
||||
endw
|
||||
#$i = $i + 1
|
||||
|
||||
##### select from table
|
||||
$tb = $tbPrefix . 0
|
||||
## TBASE-344
|
||||
sql select c1*2 from $tb
|
||||
if $rows != $rowNum then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != 2.000000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data20 != 4.000000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data90 != 18.000000000 then
|
||||
return -1
|
||||
endi
|
||||
$x = 0
|
||||
while $x < $rowNum
|
||||
$xs = $x * $delta
|
||||
$ts = $ts0 + $xs
|
||||
$c = $x / 10
|
||||
$c = $c * 10
|
||||
$c = $x - $c
|
||||
$binary = 'binary . $c
|
||||
$binary = $binary . '
|
||||
$nchar = 'nchar . $c
|
||||
$nchar = $nchar . '
|
||||
|
||||
sql select c4*1+1/2 from $tb
|
||||
if $rows != $rowNum then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 0.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != 1.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data90 != 9.500000000 then
|
||||
return -1
|
||||
endi
|
||||
sql insert into $tb5 values ( $ts , NULL , $c , NULL , $c , NULL , $c , NULL, NULL , $nchar ) $tb6 values ( $ts , NULL , $c , NULL , $c , NULL , $c , NULL, NULL , $nchar ) $tb7 values ( $ts , NULL , $c , NULL , $c , NULL , $c , NULL, NULL , $nchar ) $tb8 values ( $ts , NULL , $c , NULL , $c , NULL , $c , NULL, NULL , $nchar ) $tb9 values ( $ts , NULL , $c , NULL , $c , NULL , $c , NULL, NULL , $nchar )
|
||||
$x = $x + 1
|
||||
endw
|
||||
|
||||
#### illegal operations
|
||||
#endw
|
||||
|
||||
#=================================== above are setup test environment =============================
|
||||
run general/parser/col_arithmetic_query.sim
|
||||
|
||||
#======================================= all in files query =======================================
|
||||
print ================== restart server to commit data into disk
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
||||
sleep 3000
|
||||
system sh/exec.sh -n dnode1 -s start
|
||||
|
||||
print ================== server restart completed
|
||||
sql connect
|
||||
sleep 500c
|
||||
|
||||
run general/parser/col_arithmetic_query.sim
|
||||
|
||||
# ================================================================================================
|
||||
|
||||
print ====================> crash
|
||||
# sql select spread(ts )/(1000*3600*24) from ca_stb0 interval(1y)
|
||||
|
||||
sql_error select first(c1, c2) - last(c1, c2) from stb interval(1y)
|
||||
sql_error select first(ts) - last(ts) from stb interval(1y)
|
||||
sql_error select top(c1, 2) - last(c1) from stb;
|
||||
sql_error select stddev(c1) - last(c1) from stb;
|
||||
sql_error select diff(c1) - last(c1) from stb;
|
||||
sql_error select first(c7) - last(c7) from stb;
|
||||
sql_error select first(c8) - last(c8) from stb;
|
||||
sql_error select first(c9) - last(c9) from stb;
|
||||
sql_error select max(c2*2) from $tb
|
||||
sql_error select max(c1-c2) from $tb
|
||||
|
||||
#========================================regression test cases====================================
|
||||
print =====================> td-1764
|
||||
sql select sum(c1)/count(*), sum(c1) as b, count(*) as b from $stb interval(1y)
|
||||
if $rows != 1 then
|
||||
|
@ -108,42 +149,4 @@ if $data02 != 225000 then
|
|||
return -1
|
||||
endi
|
||||
|
||||
sql select first(c1) - last(c1), first(c1) as b, last(c1) as b, min(c1) - max(c1), spread(c1) from ca_stb0 interval(1y)
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != @18-01-01 00:00:00.000@ then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != -9.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 9 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data04 != -9.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data05 != 9.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql_error select first(c1, c2) - last(c1, c2) from stb interval(1y)
|
||||
sql_error select first(ts) - last(ts) from stb interval(1y)
|
||||
sql_error select top(c1, 2) - last(c1) from stb;
|
||||
sql_error select stddev(c1) - last(c1) from stb;
|
||||
sql_error select diff(c1) - last(c1) from stb;
|
||||
sql_error select first(c7) - last(c7) from stb;
|
||||
sql_error select first(c8) - last(c8) from stb;
|
||||
sql_error select first(c9) - last(c9) from stb;
|
||||
|
||||
system sh/exec.sh -n dnode1 -s stop -x SIGINT
|
|
@ -0,0 +1,478 @@
|
|||
# ======================================= query test cases ========================================
|
||||
# select from table
|
||||
|
||||
$dbPrefix = ca_db
|
||||
$tbPrefix = ca_tb
|
||||
$stbPrefix = ca_stb
|
||||
$rowNum = 10000
|
||||
|
||||
$i = 0
|
||||
$db = $dbPrefix . $i
|
||||
sql use $db
|
||||
|
||||
$tb = $tbPrefix . 0
|
||||
$stb = $stbPrefix . $i
|
||||
|
||||
## TBASE-344
|
||||
sql select c1*2 from $tb
|
||||
if $rows != $rowNum then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != 2.000000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data20 != 4.000000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data90 != 18.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# asc/desc order [d.2] ======================================================
|
||||
sql select c1 *( 2 / 3 ), c1/c1 from $tb order by ts asc;
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != -nan then
|
||||
print expect -nan, actual: $data01
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != 0.666666667 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data11 != 1.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data90 != 6.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data91 != 1.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select (c1 * 2) % 7.9 from $tb order by ts desc;
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.100000000 then
|
||||
print expect 0.100000000, acutal:$data00
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != 2.100000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data90 != 6.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# [d.3]
|
||||
sql select c1 * c2 /4 from $tb where ts < 1537166000000 and ts > 1537156000000
|
||||
if $rows != 17 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 12.250000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != 16.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data20 != 20.250000000 then
|
||||
print expect 20.250000000, acutal:$data21
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data30 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# no result return [d.3] ==============================================================
|
||||
sql select c1 * 91- 7 from $tb where ts < 1537146000000
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# no result return [d.3]
|
||||
sql select c2 - c2 from $tb where ts > '2018-09-17 12:50:00.000' and ts<'2018-09-17 13:00:00.000'
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# single row result aggregation [d.4] =================================================
|
||||
# not available
|
||||
|
||||
# error cases
|
||||
# not available
|
||||
|
||||
# multi row result aggregation [d.4]
|
||||
sql_error select top(c1, 1) - bottom(c1, 1) from $tb
|
||||
sql_error select top(c1, 99) - bottom(c1, 99) from $tb
|
||||
sql_error select top(c1,1) - 88 from $tb
|
||||
|
||||
# all data types [d.6] ================================================================
|
||||
sql select c2-c1*1.1, c3/c2, c4*c3, c5%c4, (c6+c4)%22, c2-c2 from $tb
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != -nan then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data04 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data05 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data90 != -0.900000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data91 != 1.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data92 != 81.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data93 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data94 != 18.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# error case, ts/bool/binary/nchar not support arithmetic expression
|
||||
sql_error select ts+ts from $tb
|
||||
sql_error select ts+22 from $tb
|
||||
sql_error select c7*12 from $tb
|
||||
sql_error select c8/55 from $tb
|
||||
sql_error select c9+c8 from $tb
|
||||
sql_error select c7-c8, c9-c8 from $tb
|
||||
sql_error select ts-c9 from $tb
|
||||
sql_error select c8+c7, c9+c9+c8+c7/c6 from $tb
|
||||
|
||||
# arithmetic expression in join [d.7]==================================================
|
||||
|
||||
|
||||
# arithmetic expression in union [d.8]=================================================
|
||||
|
||||
|
||||
# arithmetic expression in group by [d.9]==============================================
|
||||
# in group by tag, not support for normal table
|
||||
sql_error select c5*99 from $tb group by t1
|
||||
|
||||
# in group by column
|
||||
sql_error select c6-(c6+c3)*12 from $tb group by c3;
|
||||
|
||||
|
||||
# limit offset [d.10]==================================================================
|
||||
sql select c6 * c1 + 12 from $tb limit 12 offset 99;
|
||||
if $rows != 12 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 93.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data90 != 76.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select c4 / 99.123 from $tb limit 10 offset 9999;
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.090796283 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# slimit/soffset not support for normal table query. [d.11]============================
|
||||
sql_error select sum(c1) from $tb slimit 1 soffset 19;
|
||||
|
||||
# fill [d.12]==========================================================================
|
||||
sql_error select c2-c2, c3-c4, c5%c3 from $tb fill(value, 12);
|
||||
|
||||
# constant column. [d.13]==============================================================
|
||||
sql select c1, c2+c6, 12.9876545678, 1, 1.1 from $tb
|
||||
if $rows != 10000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 12.987654568 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data04 != 1.100000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# column value filter [d.14]===========================================================
|
||||
sql select c1, c2+c6, 12.9876545678, 1, 1.1 from $tb where c1<2
|
||||
if $rows != 2000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 12.987654568 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data03 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data10 != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data20 != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# tag filter(not support for normal table). [d.15]=====================================
|
||||
sql_error select c2+99 from $tb where t1=12;
|
||||
|
||||
# multi-field output [d.16]============================================================
|
||||
sql select c4*1+1/2,c4*1+1/2,c4*1+1/2,c4*1+1/2,c4*1+1/2 from $tb
|
||||
if $rows != $rowNum then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 0.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != 1.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data90 != 9.500000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# interval query [d.17]==================================================================
|
||||
sql_error select c2*c2, c3-c3, c4+9 from $tb interval(1s)
|
||||
sql_error select c7-c9 from $tb interval(2y)
|
||||
|
||||
# aggregation query [d.18]===============================================================
|
||||
# see test cases below
|
||||
|
||||
# first/last query [d.19]===============================================================
|
||||
# see test cases below
|
||||
|
||||
# multiple retrieve [d.20]===============================================================
|
||||
sql select c2-c2, 911 from $tb
|
||||
|
||||
#======================================= aggregation function arithmetic query cases ================
|
||||
# asc/desc order [d.2]
|
||||
sql select first(c1) * ( 2 / 3 ) from $stb order by ts asc;
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select first(c1) * (2/99) from $stb order by ts desc;
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select (count(c1) * 2) % 7.9, (count(c1) * 2), ( count(1)*2) from $stb order by ts desc;
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 1.800000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 100000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 200000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
sql select spread( c1 )/44, spread(c1), 0.204545455 * 44 from $stb order by ts asc;
|
||||
if $rows != 1 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data00 != 0.204545455 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data01 != 9.000000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
if $data02 != 9.000000020 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# all possible function in the arithmetic expressioin
|
||||
sql select min(c1) * max(c2) /4, sum(c1) * percentile(c2, 20), apercentile(c4, 33) + 52/9, spread(c5)/min(c2) from $stb where ts < and ts >
|
||||
|
||||
# no result return [d.3]
|
||||
sql select first(c1) * 91 - 7, last(c3) from $stb where ts < 1537146000000
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# no result return [d.3]
|
||||
sql select sum(c2) - avg(c2) from $tb where ts>xxx
|
||||
if $rows != 0 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# single row result aggregation [d.4]
|
||||
sql select
|
||||
|
||||
# error cases
|
||||
sql_error select first(c1, c2) - last(c1, c2) from $tb
|
||||
|
||||
# multi row result aggregation [d.4]
|
||||
sql select top(c1, 1) - bottom(c1, 1) from $tb
|
||||
sql select top(c1, 99) - bottom(c1, 99) from $tb
|
||||
|
||||
# all data types [d.6]
|
||||
sql select c2-c1, c3/c2, c4*c3, c5%c4, c6+99%22 from $tb
|
||||
|
||||
# error case, ts/bool/binary/nchar not support arithmetic expression
|
||||
sql_error select ts+ts from $tb
|
||||
sql_error select ts+22 from $tb
|
||||
sql_error select c7*12 from $tb
|
||||
sql_error select c8/55 from $tb
|
||||
sql_error select c9+c8 from $tb
|
||||
|
||||
# arithmetic expression in join [d.7]
|
||||
|
||||
|
||||
# arithmetic expression in union [d.8]
|
||||
|
||||
|
||||
# arithmetic expression in group by [d.9]
|
||||
# in group by tag
|
||||
# not support for normal table
|
||||
sql_error select c5*99 from $tb group by t1
|
||||
|
||||
# in group by column
|
||||
sql_error select c6-c6+c3*12 from $tb group by c3;
|
||||
|
||||
sql select first(c6) - last(c6) *12 / count(*) from $tb group by c3;
|
||||
|
||||
# limit offset [d.10]
|
||||
sql select c6-c6+12 from $tb limit 12 offset 99;
|
||||
sql select c4/99.123 from $tb limit 1 offset 9999;
|
||||
|
||||
# slimit/soffset not suport for normal table query. [d.11]
|
||||
sql_error select sum(c1) from $tb slimit 1 soffset 19;
|
||||
|
||||
# fill [d.12]
|
||||
sql_error select c2-c2, c3-c4, c5%c6 from $tb fill(value, 12);
|
||||
|
||||
# constant column. [d.13]
|
||||
|
||||
|
||||
# column value filter [d.14]
|
||||
|
||||
|
||||
# tag filter(not support for normal table). [d.15]
|
||||
sql_error select sum(c2)+99 from $tb where t1=12;
|
||||
|
||||
# multi-field output [d.16]
|
||||
sql select count(*), sum(c1)*avg(c2), avg(c3)*count(c3), sum(c3), sum(c4), first(c7), last(c8), first(c9), first(c7), last(c8) from $tb
|
||||
|
||||
sql select c4*1+1/2 from $tb
|
||||
if $rows != $rowNum then
|
||||
return -1
|
||||
endi
|
||||
if $data00 != 0.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data10 != 1.500000000 then
|
||||
return -1
|
||||
endi
|
||||
if $data90 != 9.500000000 then
|
||||
return -1
|
||||
endi
|
||||
|
||||
# interval query [d.17]
|
||||
sql_error select c2*c2, c3-c3, c4+9 from $tb interval(1s)
|
||||
sql_error select c7-c9 from $tb interval(2y)
|
||||
|
||||
# aggregation query [d.18]
|
||||
# see test cases below
|
||||
|
||||
# first/last query [d.19]
|
||||
# see test cases below
|
||||
|
||||
# multiple retrieve [d.20]
|
||||
sql select c2-c2 from $tb;
|
||||
|
||||
|
||||
sql select first(c1)-last(c1), spread(c2), max(c3) - min(c3), avg(c4)*count(c4) from $tb
|
Loading…
Reference in New Issue