提交 ba9ef137 编写于 作者: H Haojun Liao

[td-1151] add test cases and fix the found bugs.

上级 e4e4c7fc
...@@ -198,7 +198,7 @@ int32_t tscValidateName(SSQLToken* pToken); ...@@ -198,7 +198,7 @@ int32_t tscValidateName(SSQLToken* pToken);
void tscIncStreamExecutionCount(void* pStream); void tscIncStreamExecutionCount(void* pStream);
bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId); bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId, int32_t numOfParams);
// get starter position of metric query condition (query on tags) in SSqlCmd.payload // get starter position of metric query condition (query on tags) in SSqlCmd.payload
SCond* tsGetSTableQueryCond(STagCond* pCond, uint64_t uid); SCond* tsGetSTableQueryCond(STagCond* pCond, uint64_t uid);
......
...@@ -195,9 +195,9 @@ typedef struct STableDataBlocks { ...@@ -195,9 +195,9 @@ typedef struct STableDataBlocks {
typedef struct SQueryInfo { typedef struct SQueryInfo {
int16_t command; // the command may be different for each subclause, so keep it seperately. int16_t command; // the command may be different for each subclause, so keep it seperately.
uint32_t type; // query/insert/import type uint32_t type; // query/insert type
char slidingTimeUnit; char slidingTimeUnit;
STimeWindow window; STimeWindow window; // query time window
int64_t intervalTime; // aggregation time interval int64_t intervalTime; // aggregation time interval
int64_t slidingTime; // sliding window in mseconds int64_t slidingTime; // sliding window in mseconds
SSqlGroupbyExpr groupbyExpr; // group by tags info SSqlGroupbyExpr groupbyExpr; // group by tags info
...@@ -216,6 +216,7 @@ typedef struct SQueryInfo { ...@@ -216,6 +216,7 @@ typedef struct SQueryInfo {
char * msg; // pointer to the pCmd->payload to keep error message temporarily char * msg; // pointer to the pCmd->payload to keep error message temporarily
int64_t clauseLimit; // limit for current sub clause int64_t clauseLimit; // limit for current sub clause
int64_t prjOffset; // offset value in the original sql expression, only applied at client side int64_t prjOffset; // offset value in the original sql expression, only applied at client side
int32_t udColumnId; // current user-defined constant output field column id, monotonically decreases from TSDB_UD_COLUMN_INDEX
} SQueryInfo; } SQueryInfo;
typedef struct { typedef struct {
......
...@@ -2902,12 +2902,12 @@ static FORCE_INLINE void date_col_output_function_f(SQLFunctionCtx *pCtx, int32_ ...@@ -2902,12 +2902,12 @@ static FORCE_INLINE void date_col_output_function_f(SQLFunctionCtx *pCtx, int32_
} }
static void col_project_function(SQLFunctionCtx *pCtx) { static void col_project_function(SQLFunctionCtx *pCtx) {
if (pCtx->numOfParams == 1) { // the number of output rows should not affect the final number of rows, so set it to be 1 if (pCtx->numOfParams == 2) { // the number of output rows should not affect the final number of rows, so set it to be 0
INC_INIT_VAL(pCtx, 1); SET_VAL(pCtx, pCtx->size, 1);
char* output = pCtx->aOutputBuf; char* output = pCtx->aOutputBuf;
for(int32_t i = 0; i < pCtx->size; ++i) { for(int32_t i = 0; i < pCtx->size; ++i) {
tVariantDump(&pCtx->param[0], output, pCtx->outputType, true); tVariantDump(&pCtx->param[1], output, pCtx->outputType, true);
output += pCtx->outputBytes; output += pCtx->outputBytes;
} }
...@@ -2936,11 +2936,16 @@ static void col_project_function_f(SQLFunctionCtx *pCtx, int32_t index) { ...@@ -2936,11 +2936,16 @@ static void col_project_function_f(SQLFunctionCtx *pCtx, int32_t index) {
if (pCtx->param[0].i64Key == 1 && pResInfo->numOfRes >= 1) { if (pCtx->param[0].i64Key == 1 && pResInfo->numOfRes >= 1) {
return; return;
} }
INC_INIT_VAL(pCtx, 1); if (pCtx->numOfParams == 2) { // the number of output rows should not affect the final number of rows, so set it to be 0
char *pData = GET_INPUT_CHAR_INDEX(pCtx, index); SET_VAL(pCtx, pCtx->size, 1);
memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes); tVariantDump(&pCtx->param[1], pCtx->aOutputBuf, pCtx->outputType, true);
} else {
INC_INIT_VAL(pCtx, 1);
char *pData = GET_INPUT_CHAR_INDEX(pCtx, index);
memcpy(pCtx->aOutputBuf, pData, pCtx->inputBytes);
}
pCtx->aOutputBuf += pCtx->inputBytes; pCtx->aOutputBuf += pCtx->inputBytes;
} }
......
...@@ -1094,18 +1094,6 @@ int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQL ...@@ -1094,18 +1094,6 @@ int32_t setObjFullName(char* fullName, const char* account, SSQLToken* pDB, SSQL
return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL; return (totalLen < TSDB_TABLE_FNAME_LEN) ? TSDB_CODE_SUCCESS : TSDB_CODE_TSC_INVALID_SQL;
} }
static void extractColumnNameFromString(tSQLExprItem* pItem) {
if (pItem->pNode->nSQLOptr == TK_STRING) {
pItem->pNode->val.nLen = strdequote(pItem->pNode->val.pz);
pItem->pNode->nSQLOptr = TK_ID;
SSQLToken* pIdToken = &pItem->pNode->colInfo;
pIdToken->type = TK_ID;
pIdToken->z = pItem->pNode->val.pz;
pIdToken->n = pItem->pNode->val.nLen;
}
}
static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) { static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t exprIndex, tSQLExprItem* pItem) {
const char* msg1 = "invalid column name, or illegal column type"; const char* msg1 = "invalid column name, or illegal column type";
const char* msg2 = "invalid arithmetic expression in select clause"; const char* msg2 = "invalid arithmetic expression in select clause";
...@@ -1234,6 +1222,11 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t ...@@ -1234,6 +1222,11 @@ static int32_t handleArithmeticExpr(SSqlCmd* pCmd, int32_t clauseIndex, int32_t
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
tscColumnListInsert(pQueryInfo->colList, &tsCol);
}
int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) { int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSelection, bool isSTable) {
assert(pSelection != NULL && pCmd != NULL); assert(pSelection != NULL && pCmd != NULL);
...@@ -1254,15 +1247,12 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel ...@@ -1254,15 +1247,12 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
// project on all fields // project on all fields
int32_t optr = pItem->pNode->nSQLOptr; int32_t optr = pItem->pNode->nSQLOptr;
if (optr == TK_ALL || optr == TK_ID || optr == TK_STRING || (optr == TK_INTEGER || optr == TK_FLOAT)) { if (optr == TK_ALL || optr == TK_ID || optr == TK_STRING || optr == TK_INTEGER || optr == TK_FLOAT) {
// it is actually a function, but the function name is invalid // it is actually a function, but the function name is invalid
if (pItem->pNode->nSQLOptr == TK_ID && (pItem->pNode->colInfo.z == NULL && pItem->pNode->colInfo.n == 0)) { if (pItem->pNode->nSQLOptr == TK_ID && (pItem->pNode->colInfo.z == NULL && pItem->pNode->colInfo.n == 0)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5);
} }
// if the name of column is quoted, remove it and set the right information for later process
extractColumnNameFromString(pItem);
// select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2 // select table_name1.field_name1, table_name2.field_name2 from table_name1, table_name2
if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) { if (addProjectionExprAndResultField(pCmd, pQueryInfo, pItem) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_SQL; return TSDB_CODE_TSC_INVALID_SQL;
...@@ -1292,6 +1282,13 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel ...@@ -1292,6 +1282,13 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel
} }
} }
// there is only one user-defined column in the final result field, add the timestamp column.
size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo)) {
SColumnIndex index = {0};
tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
}
if (!functionCompatibleCheck(pQueryInfo)) { if (!functionCompatibleCheck(pQueryInfo)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
} }
...@@ -1431,17 +1428,11 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum ...@@ -1431,17 +1428,11 @@ static int32_t doAddProjectionExprAndResultFields(SQueryInfo* pQueryInfo, SColum
return numOfTotalColumns; return numOfTotalColumns;
} }
static void tscInsertPrimaryTSSourceColumn(SQueryInfo* pQueryInfo, SColumnIndex* pIndex) {
SColumnIndex tsCol = {.tableIndex = pIndex->tableIndex, .columnIndex = PRIMARYKEY_TIMESTAMP_COL_INDEX};
tscColumnListInsert(pQueryInfo->colList, &tsCol);
}
int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExprItem* pItem) { int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSQLExprItem* pItem) {
const char* msg0 = "invalid column name"; const char* msg0 = "invalid column name";
const char* msg1 = "tag for normal table query is not allowed"; const char* msg1 = "tag for normal table query is not allowed";
int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
int32_t startPos = (int32_t)tscSqlExprNumOfExprs(pQueryInfo);
int32_t optr = pItem->pNode->nSQLOptr; int32_t optr = pItem->pNode->nSQLOptr;
if (optr == TK_ALL) { // project on all fields if (optr == TK_ALL) { // project on all fields
...@@ -1465,40 +1456,43 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t ...@@ -1465,40 +1456,43 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
// add the primary timestamp column even though it is not required by user // add the primary timestamp column even though it is not required by user
tscInsertPrimaryTSSourceColumn(pQueryInfo, &index); tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
} else if (optr == TK_ID || optr == TK_INTEGER || optr == TK_FLOAT) { // simple column projection query } else if (optr == TK_STRING || optr == TK_INTEGER || optr == TK_FLOAT) { // simple column projection query
SColumnIndex index = COLUMN_INDEX_INITIALIZER; SColumnIndex index = COLUMN_INDEX_INITIALIZER;
// user-specified constant value as a new result column // user-specified constant value as a new result column
if ((optr == TK_INTEGER || optr == TK_FLOAT) || (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS)) { index.columnIndex = (pQueryInfo->udColumnId--);
index.columnIndex = TSDB_UD_COLUMN_INDEX; index.tableIndex = 0;
index.tableIndex = 0;
SSchema colSchema = tGetUserSpecifiedColumnSchema(pItem->pNode->val.pz, pItem->pNode->val.nType, pItem->aliasName); SSchema colSchema = tGetUserSpecifiedColumnSchema(&pItem->pNode->val, pItem->aliasName);
SSqlExpr* pExpr = tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC); SSqlExpr* pExpr =
pExpr->numOfParams = 1; tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_PRJ, &index, &colSchema, TSDB_COL_UDC);
tVariantAssign(&pExpr->param[0], &pItem->pNode->val);
} else { // columns from the queried table // NOTE: the first parameter is reserved for the tag column id during join query process.
TSDB_QUERY_SET_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_PROJECTION_QUERY); pExpr->numOfParams = 2;
tVariantAssign(&pExpr->param[1], &pItem->pNode->val);
} else if (optr == TK_ID) {
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { if (getColumnIndexByName(pCmd, &pItem->pNode->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) {
SSchema colSchema = tGetTableNameColumnSchema(); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg0);
tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG); }
} else {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) { if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); SSchema colSchema = tGetTableNameColumnSchema();
} tscAddSpecialColumnForSelect(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG);
} else {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
addProjectQueryCol(pQueryInfo, startPos, &index, pItem); if (index.columnIndex >= tscGetNumOfColumns(pTableMeta) && UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1);
} }
// add the primary timestamp column even though it is not required by user addProjectQueryCol(pQueryInfo, startPos, &index, pItem);
tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
} }
// add the primary timestamp column even though it is not required by user
tscInsertPrimaryTSSourceColumn(pQueryInfo, &index);
} else { } else {
return TSDB_CODE_TSC_INVALID_SQL; return TSDB_CODE_TSC_INVALID_SQL;
} }
...@@ -2069,7 +2063,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col ...@@ -2069,7 +2063,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col
// todo refactor // todo refactor
static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) { static SColumnList getColumnList(int32_t num, int16_t tableIndex, int32_t columnIndex) {
assert(num == 1 && columnIndex >= -2 && tableIndex >= 0); assert(num == 1 && tableIndex >= 0);
SColumnList columnList = {0}; SColumnList columnList = {0};
columnList.num = num; columnList.num = num;
...@@ -4706,7 +4700,7 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu ...@@ -4706,7 +4700,7 @@ int32_t validateFunctionsInIntervalOrGroupbyQuery(SSqlCmd* pCmd, SQueryInfo* pQu
} }
} }
if (pExpr->functionId == TSDB_FUNC_PRJ || pExpr->functionId == TSDB_FUNC_DIFF || if ((pExpr->functionId == TSDB_FUNC_PRJ && pExpr->numOfParams == 0) || pExpr->functionId == TSDB_FUNC_DIFF ||
pExpr->functionId == TSDB_FUNC_ARITHM) { pExpr->functionId == TSDB_FUNC_ARITHM) {
isProjectionFunction = true; isProjectionFunction = true;
} }
......
...@@ -628,9 +628,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { ...@@ -628,9 +628,12 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex);
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableMeta * pTableMeta = pTableMetaInfo->pTableMeta; STableMeta * pTableMeta = pTableMetaInfo->pTableMeta;
if (taosArrayGetSize(pQueryInfo->colList) <= 0 && !tscQueryTags(pQueryInfo)) { size_t numOfSrcCols = taosArrayGetSize(pQueryInfo->colList);
tscError("%p illegal value of numOfCols in query msg: %d", pSql, tscGetNumOfColumns(pTableMeta)); if (numOfSrcCols <= 0 && !tscQueryTags(pQueryInfo)) {
tscError("%p illegal value of numOfCols in query msg: %"PRIu64", table cols:%d", pSql, numOfSrcCols,
tscGetNumOfColumns(pTableMeta));
return TSDB_CODE_TSC_INVALID_SQL; return TSDB_CODE_TSC_INVALID_SQL;
} }
...@@ -728,7 +731,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { ...@@ -728,7 +731,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
for (int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) { for (int32_t i = 0; i < tscSqlExprNumOfExprs(pQueryInfo); ++i) {
SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i); SSqlExpr *pExpr = tscSqlExprGet(pQueryInfo, i);
if (!tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId)) { if (!tscValidateColumnId(pTableMetaInfo, pExpr->colInfo.colId, pExpr->numOfParams)) {
/* column id is not valid according to the cached table meta, the table meta is expired */ /* column id is not valid according to the cached table meta, the table meta is expired */
tscError("%p table schema is not matched with parsed sql", pSql); tscError("%p table schema is not matched with parsed sql", pSql);
return TSDB_CODE_TSC_INVALID_SQL; return TSDB_CODE_TSC_INVALID_SQL;
......
...@@ -353,11 +353,12 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) { ...@@ -353,11 +353,12 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
pExpr = tscSqlExprGet(pQueryInfo, 0); pExpr = tscSqlExprGet(pQueryInfo, 0);
} }
// set the join condition tag column info, to do extract method // set the join condition tag column info, todo extract method
if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
assert(pQueryInfo->tagCond.joinInfo.hasJoin); assert(pQueryInfo->tagCond.joinInfo.hasJoin);
int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid); int16_t colId = tscGetJoinTagColIdByUid(&pQueryInfo->tagCond, pTableMetaInfo->pTableMeta->id.uid);
// set the tag column id for executor to extract correct tag value
pExpr->param[0].i64Key = colId; pExpr->param[0].i64Key = colId;
pExpr->numOfParams = 1; pExpr->numOfParams = 1;
} }
......
...@@ -937,8 +937,8 @@ static SSqlExpr* doBuildSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SCol ...@@ -937,8 +937,8 @@ static SSqlExpr* doBuildSqlExpr(SQueryInfo* pQueryInfo, int16_t functionId, SCol
// set the correct columnIndex index // set the correct columnIndex index
if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) { if (pColIndex->columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
pExpr->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX; pExpr->colInfo.colId = TSDB_TBNAME_COLUMN_INDEX;
} else if (pColIndex->columnIndex == TSDB_UD_COLUMN_INDEX) { } else if (pColIndex->columnIndex <= TSDB_UD_COLUMN_INDEX) {
pExpr->colInfo.colId = TSDB_UD_COLUMN_INDEX; pExpr->colInfo.colId = pColIndex->columnIndex;
} else { } else {
if (TSDB_COL_IS_TAG(colType)) { if (TSDB_COL_IS_TAG(colType)) {
SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta); SSchema* pSchema = tscGetTableTagSchema(pTableMetaInfo->pTableMeta);
...@@ -1290,12 +1290,12 @@ void tscIncStreamExecutionCount(void* pStream) { ...@@ -1290,12 +1290,12 @@ void tscIncStreamExecutionCount(void* pStream) {
ps->num += 1; ps->num += 1;
} }
bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId) { bool tscValidateColumnId(STableMetaInfo* pTableMetaInfo, int32_t colId, int32_t numOfParams) {
if (pTableMetaInfo->pTableMeta == NULL) { if (pTableMetaInfo->pTableMeta == NULL) {
return false; return false;
} }
if (colId == TSDB_TBNAME_COLUMN_INDEX || colId == TSDB_UD_COLUMN_INDEX) { if (colId == TSDB_TBNAME_COLUMN_INDEX || (colId <= TSDB_UD_COLUMN_INDEX && numOfParams == 2)) {
return true; return true;
} }
...@@ -1511,6 +1511,7 @@ void tscInitQueryInfo(SQueryInfo* pQueryInfo) { ...@@ -1511,6 +1511,7 @@ void tscInitQueryInfo(SQueryInfo* pQueryInfo) {
assert(pQueryInfo->exprList == NULL); assert(pQueryInfo->exprList == NULL);
pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES); pQueryInfo->exprList = taosArrayInit(4, POINTER_BYTES);
pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES); pQueryInfo->colList = taosArrayInit(4, POINTER_BYTES);
pQueryInfo->udColumnId = TSDB_UD_COLUMN_INDEX;
} }
int32_t tscAddSubqueryInfo(SSqlCmd* pCmd) { int32_t tscAddSubqueryInfo(SSqlCmd* pCmd) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "os.h" #include "os.h"
#include "taosmsg.h" #include "taosmsg.h"
#include "tstoken.h" #include "tstoken.h"
#include "tvariant.h"
typedef struct SDataStatis { typedef struct SDataStatis {
int16_t colId; int16_t colId;
...@@ -28,7 +29,7 @@ void extractTableNameFromToken(SSQLToken *pToken, SSQLToken* pTable); ...@@ -28,7 +29,7 @@ void extractTableNameFromToken(SSQLToken *pToken, SSQLToken* pTable);
SSchema tGetTableNameColumnSchema(); SSchema tGetTableNameColumnSchema();
SSchema tGetUserSpecifiedColumnSchema(const char* v, int16_t type, const char* name); SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, const char* name);
bool tscValidateTableNameLength(size_t len); bool tscValidateTableNameLength(size_t len);
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include "tname.h" #include "tname.h"
#include "tstoken.h" #include "tstoken.h"
#include "ttokendef.h" #include "ttokendef.h"
#include "tvariant.h"
// todo refactor // todo refactor
UNUSED_FUNC static FORCE_INLINE const char* skipSegments(const char* input, char delim, int32_t num) { UNUSED_FUNC static FORCE_INLINE const char* skipSegments(const char* input, char delim, int32_t num) {
...@@ -47,19 +48,23 @@ SSchema tGetTableNameColumnSchema() { ...@@ -47,19 +48,23 @@ SSchema tGetTableNameColumnSchema() {
return s; return s;
} }
SSchema tGetUserSpecifiedColumnSchema(const char* v, int16_t type, const char* name) { SSchema tGetUserSpecifiedColumnSchema(tVariant* pVal, const char* name) {
SSchema s = {0}; SSchema s = {0};
s.type = type; s.type = pVal->nType;
if (s.type == TSDB_DATA_TYPE_BINARY || s.type == TSDB_DATA_TYPE_NCHAR) { if (s.type == TSDB_DATA_TYPE_BINARY || s.type == TSDB_DATA_TYPE_NCHAR) {
size_t len = strlen(v); s.bytes = pVal->nLen + VARSTR_HEADER_SIZE;
s.bytes = len + VARSTR_HEADER_SIZE;
} else { } else {
s.bytes = tDataTypeDesc[type].nSize; s.bytes = tDataTypeDesc[pVal->nType].nSize;
} }
s.colId = TSDB_UD_COLUMN_INDEX; s.colId = TSDB_UD_COLUMN_INDEX;
tstrncpy(s.name, name, sizeof(s.name)); if (name != NULL) {
tstrncpy(s.name, name, sizeof(s.name));
} else {
tVariantToString(pVal, s.name);
strdequote(s.name);
}
return s; return s;
} }
......
...@@ -287,7 +287,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size); ...@@ -287,7 +287,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size);
#define TSDB_MAX_REPLICA 5 #define TSDB_MAX_REPLICA 5
#define TSDB_TBNAME_COLUMN_INDEX (-1) #define TSDB_TBNAME_COLUMN_INDEX (-1)
#define TSDB_UD_COLUMN_INDEX (-2) #define TSDB_UD_COLUMN_INDEX (-100)
#define TSDB_MULTI_METERMETA_MAX_NUM 100000 // maximum batch size allowed to load metermeta #define TSDB_MULTI_METERMETA_MAX_NUM 100000 // maximum batch size allowed to load metermeta
#define TSDB_MIN_CACHE_BLOCK_SIZE 1 #define TSDB_MIN_CACHE_BLOCK_SIZE 1
......
...@@ -169,7 +169,7 @@ enum _mgmt_table { ...@@ -169,7 +169,7 @@ enum _mgmt_table {
#define TSDB_COL_NORMAL 0x0u // the normal column of the table #define TSDB_COL_NORMAL 0x0u // the normal column of the table
#define TSDB_COL_TAG 0x1u // the tag column type #define TSDB_COL_TAG 0x1u // the tag column type
#define TSDB_COL_UDC 0x2u // the user specified normal string column, it is a dummy column #define TSDB_COL_UDC 0x2u // the user specified normal string column, it is a dummy column
extern char *taosMsg[]; extern char *taosMsg[];
......
...@@ -210,6 +210,7 @@ typedef struct tSQLExprItem { ...@@ -210,6 +210,7 @@ typedef struct tSQLExprItem {
char * aliasName; // alias name, null-terminated string char * aliasName; // alias name, null-terminated string
} tSQLExprItem; } tSQLExprItem;
// todo refactor by using SArray
typedef struct tSQLExprList { typedef struct tSQLExprList {
int32_t nExpr; /* Number of expressions on the list */ int32_t nExpr; /* Number of expressions on the list */
int32_t nAlloc; /* Number of entries allocated below */ int32_t nAlloc; /* Number of entries allocated below */
......
...@@ -168,7 +168,7 @@ static void buildTagQueryResult(SQInfo *pQInfo); ...@@ -168,7 +168,7 @@ static void buildTagQueryResult(SQInfo *pQInfo);
static int32_t setAdditionalInfo(SQInfo *pQInfo, void *pTable, STableQueryInfo *pTableQueryInfo); static int32_t setAdditionalInfo(SQInfo *pQInfo, void *pTable, STableQueryInfo *pTableQueryInfo);
static int32_t flushFromResultBuf(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo); static int32_t flushFromResultBuf(SQueryRuntimeEnv* pRuntimeEnv, SGroupResInfo* pGroupResInfo);
bool doFilterData(SQuery *pQuery, int32_t elemPos) { bool doFilterData(SQuery *pQuery, int32_t elemPos) {
for (int32_t k = 0; k < pQuery->numOfFilterCols; ++k) { for (int32_t k = 0; k < pQuery->numOfFilterCols; ++k) {
SSingleColumnFilterInfo *pFilterInfo = &pQuery->pFilterInfo[k]; SSingleColumnFilterInfo *pFilterInfo = &pQuery->pFilterInfo[k];
...@@ -899,7 +899,7 @@ static char *getDataBlock(SQueryRuntimeEnv *pRuntimeEnv, SArithmeticSupport *sas ...@@ -899,7 +899,7 @@ static char *getDataBlock(SQueryRuntimeEnv *pRuntimeEnv, SArithmeticSupport *sas
} }
assert(dataBlock != NULL); assert(dataBlock != NULL);
sas->data[i] = dataBlock/* + pQuery->colList[i].bytes*/; // start from the offset sas->data[i] = dataBlock; // start from the offset
} }
} else { // other type of query function } else { // other type of query function
...@@ -1583,7 +1583,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order ...@@ -1583,7 +1583,7 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order
int16_t type = pSqlFuncMsg->arg[j].argType; int16_t type = pSqlFuncMsg->arg[j].argType;
int16_t bytes = pSqlFuncMsg->arg[j].argBytes; int16_t bytes = pSqlFuncMsg->arg[j].argBytes;
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
tVariantCreateFromBinary(&pCtx->param[j], pSqlFuncMsg->arg->argValue.pz, bytes, type); tVariantCreateFromBinary(&pCtx->param[j], pSqlFuncMsg->arg[j].argValue.pz, bytes, type);
} else { } else {
tVariantCreateFromBinary(&pCtx->param[j], (char *)&pSqlFuncMsg->arg[j].argValue.i64, bytes, type); tVariantCreateFromBinary(&pCtx->param[j], (char *)&pSqlFuncMsg->arg[j].argValue.i64, bytes, type);
} }
...@@ -5728,11 +5728,12 @@ static int32_t createQFunctionExprFromMsg(SQueryTableMsg *pQueryMsg, SExprInfo * ...@@ -5728,11 +5728,12 @@ static int32_t createQFunctionExprFromMsg(SQueryTableMsg *pQueryMsg, SExprInfo *
SSchema s = tGetTableNameColumnSchema(); SSchema s = tGetTableNameColumnSchema();
type = s.type; type = s.type;
bytes = s.bytes; bytes = s.bytes;
} else if (pExprs[i].base.colInfo.colId == TSDB_UD_COLUMN_INDEX) { } else if (pExprs[i].base.colInfo.colId <= TSDB_UD_COLUMN_INDEX) {
// it is a user-defined constant value column
assert(pExprs[i].base.functionId == TSDB_FUNC_PRJ); assert(pExprs[i].base.functionId == TSDB_FUNC_PRJ);
type = pExprs[i].base.arg[0].argType; type = pExprs[i].base.arg[1].argType;
bytes = pExprs[i].base.arg[0].argBytes; bytes = pExprs[i].base.arg[1].argBytes;
if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) {
bytes += VARSTR_HEADER_SIZE; bytes += VARSTR_HEADER_SIZE;
...@@ -5927,8 +5928,8 @@ static void doUpdateExprColumnIndex(SQuery *pQuery) { ...@@ -5927,8 +5928,8 @@ static void doUpdateExprColumnIndex(SQuery *pQuery) {
} }
assert(f < pQuery->numOfCols); assert(f < pQuery->numOfCols);
} else if (pColIndex->colId == TSDB_UD_COLUMN_INDEX) { } else if (pColIndex->colId <= TSDB_UD_COLUMN_INDEX) {
// do nothing // do nothing for user-defined constant value result columns
} else { } else {
int32_t f = 0; int32_t f = 0;
for (f = 0; f < pQuery->numOfTags; ++f) { for (f = 0; f < pQuery->numOfTags; ++f) {
......
...@@ -78,7 +78,7 @@ tSQLExprList *tSQLExprListAppend(tSQLExprList *pList, tSQLExpr *pNode, SSQLToken ...@@ -78,7 +78,7 @@ tSQLExprList *tSQLExprListAppend(tSQLExprList *pList, tSQLExpr *pNode, SSQLToken
pList = calloc(1, sizeof(tSQLExprList)); pList = calloc(1, sizeof(tSQLExprList));
} }
if (pList->nAlloc <= pList->nExpr) { // if (pList->nAlloc <= pList->nExpr) {
pList->nAlloc = (pList->nAlloc << 1) + 4; pList->nAlloc = (pList->nAlloc << 1) + 4;
pList->a = realloc(pList->a, pList->nAlloc * sizeof(pList->a[0])); pList->a = realloc(pList->a, pList->nAlloc * sizeof(pList->a[0]));
if (pList->a == 0) { if (pList->a == 0) {
......
...@@ -40,4 +40,278 @@ sql select st1.ts, st1.f1, st2.f2 from db.st1, db.st2 where st1.t1=st2.t2 and st ...@@ -40,4 +40,278 @@ sql select st1.ts, st1.f1, st2.f2 from db.st1, db.st2 where st1.t1=st2.t2 and st
system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'select st1.ts, st1.f1, st2.f2 from db.st1, db.st2 where st1.t1=st2.t2 and st1.ts=st2.ts' 127.0.0.1:7111/restful/sql system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'select st1.ts, st1.f1, st2.f2 from db.st1, db.st2 where st1.t1=st2.t2 and st1.ts=st2.ts' 127.0.0.1:7111/restful/sql
print ==============select with user-defined columns
sql select 'abc' as f, ts,f1 from t1
if $rows != 1 then
return -1
endi
if $data00 != @abc@ then
return -1
endi
if $data01 != @19-12-09 16:27:35.000@ then
return -1
endi
if $data02 != 1 then
return -1
endi
sql select 'abc', ts, f1 from t1
if $rows != 1 then
return -1
endi
if $data01 != @19-12-09 16:27:35.000@ then
return -1
endi
if $data02 != 1 then
return -1
endi
sql select 'abc' from t1
if $rows != 1 then
return -1
endi
if $data00 != @abc@ then
return -1
endi
sql select 'abc' as f1 from t1
if $rows != 1 then
return -1
endi
if $data00 != @abc@ then
return -1
endi
sql select 1 from t1
if $rows != 1 then
return -1
endi
if $data00 != 1 then
return -1
endi
sql select 1 as f1 from t1
if $rows != 1 then
return -1
endi
if $data00 != 1 then
return -1
endi
sql select 1 as f, f1 from t1
if $rows != 1 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != 1 then
return -1
endi
sql select 1.123 as f, f1 from t1
if $rows != 1 then
return -1
endi
if $data00 != 1.123000000 then
print expect 1.123000000 , actual:$data00
return -1
endi
sql select 1, f1 from t1
if $rows != 1 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != 1 then
return -1
endi
sql select 1.2391, f1 from t1
if $rows != 1 then
return -1
endi
if $data00 != 1.239100000 then
print expect 1.239100000 actual: $data00
return -1
endi
if $data01 != 1 then
return -1
endi
print ===================== user-defined columns with agg functions
sql select 1 as t, count(*) from t1
if $rows != 1 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != 1 then
return -1
endi
sql select 1, sum(f1) from t1
if $rows != 1 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != 1 then
return -1
endi
sql select 1,2,3, sum(f1)*99, 4,5,6,7,8,9,10 from t1
if $rows != 1 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != 2 then
return -1
endi
if $data02 != 3 then
return -1
endi
if $data03 != 99.000000000 then
print expect 99.000000000, actual:$data03
return -1
endi
sql select sum(f1)*avg(f1)+12, 1,2,3,4,5,6,7,8,9,10 from t1
if $rows != 1 then
return -1
endi
if $data00 != 13.000000000 then
print expect 13.000000000 actual:$data00
return -1
endi
if $data01 != 1 then
return -1
endi
if $data02 != 2 then
return -1
endi
sql select 1.2987, f1, 'k' from t1 where f1=1
if $rows != 1 then
return -1
endi
if $data00 != 1.298700000 then
print expect 1.298700000 actual:$data00
return -1
endi
if $data01 != 1 then
return -1
endi
if $data02 != @k@ then
return -1
endi
print ====================user-defined columns with union
sql select f1, 'f1' from t1 union all select f1, 'f1' from t1;
if $rows != 2 then
return -1
endi
if $data00 != 1 then
return -1
endi
if $data01 != @f1@ then
return -1
endi
if $data10 != 1 then
return -1
endi
if $data11 != @f1@ then
return -1
endi
print =====================udc with join
sql select st1.ts, st1.f1, st2.f2, 'abc', 1.9827 from db.st1, db.st2 where st1.t1=st2.t2 and st1.ts=st2.ts
if $rows != 1 then
return -1
endi
if $data00 != @19-12-09 16:27:35.000@ then
print expect @19-12-09 16:27:35.000@ actual:$data00
return -1
endi
if $data01 != 1 then
return -1
endi
if $data02 != 2 then
return -1
endi
if $data03 != @abc@ then
return -1
endi
if $data04 != 1.982700000 then
print expect 1.982700000 actual:$data04
return -1
endi
print ======================udc with interval
sql select count(*), 'uuu' from t1 interval(1s) order by ts desc;
if $rows != 1 then
return -1
endi
print ======================udc with tags
sql select t1,'abc',tbname from st1
if $rows != 1 then
return -1
endi
print ======================udc with arithmetic
sql select 1+1 from t1
if $rows != 1 then
return -1
endi
sql_error select from t1
sql_error select abc from t1
sql_error select abc as tu from t1
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册