diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 34768b00dfa0da5fbb20e8e2c22fa0294e6864ba..81df1196f9b1c8378e5ca2bcacd5032725a4406d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,4 +11,5 @@ ADD_SUBDIRECTORY(sdb) ADD_SUBDIRECTORY(mnode) ADD_SUBDIRECTORY(vnode) ADD_SUBDIRECTORY(dnode) +ADD_SUBDIRECTORY(query) #ADD_SUBDIRECTORY(connector/jdbc) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 55d6cb251caa839e85b023ea24193d1074262ba4..827c65435dc7e7c2267d2448b6e59aab753171b7 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -5,6 +5,7 @@ INCLUDE_DIRECTORIES(inc) INCLUDE_DIRECTORIES(jni) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc) +INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc) INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc) AUX_SOURCE_DIRECTORY(src SRC) @@ -14,7 +15,7 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) # set the static lib name ADD_LIBRARY(taos_static STATIC ${SRC}) - TARGET_LINK_LIBRARIES(taos_static trpc tutil pthread m rt) + TARGET_LINK_LIBRARIES(taos_static query trpc tutil pthread m rt) SET_TARGET_PROPERTIES(taos_static PROPERTIES OUTPUT_NAME "taos_static") SET_TARGET_PROPERTIES(taos_static PROPERTIES CLEAN_DIRECT_OUTPUT 1) diff --git a/src/client/inc/tscSQLParser.h b/src/client/inc/tscSQLParser.h index 0e4ad279dc0beaf0c56109583d3d02f5ae60b4f3..87c193de75a81c690a2580c220e13212b3b4b384 100644 --- a/src/client/inc/tscSQLParser.h +++ b/src/client/inc/tscSQLParser.h @@ -22,69 +22,10 @@ extern "C" { #include "taos.h" #include "taosmsg.h" -#include "tsqldef.h" +#include "ttokendef.h" #include "ttypes.h" - -enum _sql_cmd { - TSDB_SQL_SELECT = 1, - TSDB_SQL_FETCH, - TSDB_SQL_INSERT, - - TSDB_SQL_MGMT, // the SQL below is for mgmt node - TSDB_SQL_CREATE_DB, - TSDB_SQL_CREATE_TABLE, - TSDB_SQL_DROP_DB, - TSDB_SQL_DROP_TABLE, - TSDB_SQL_CREATE_ACCT, - TSDB_SQL_CREATE_USER, //10 - TSDB_SQL_DROP_ACCT, - TSDB_SQL_DROP_USER, - TSDB_SQL_ALTER_USER, - TSDB_SQL_ALTER_ACCT, - TSDB_SQL_ALTER_TABLE, - TSDB_SQL_ALTER_DB, - TSDB_SQL_CREATE_MNODE, - TSDB_SQL_DROP_MNODE, - TSDB_SQL_CREATE_DNODE, - TSDB_SQL_DROP_DNODE, // 20 - TSDB_SQL_CFG_DNODE, - TSDB_SQL_CFG_MNODE, - TSDB_SQL_SHOW, - TSDB_SQL_RETRIEVE, - TSDB_SQL_KILL_QUERY, - TSDB_SQL_KILL_STREAM, - TSDB_SQL_KILL_CONNECTION, - - TSDB_SQL_READ, // SQL below is for read operation - TSDB_SQL_CONNECT, - TSDB_SQL_USE_DB, // 30 - TSDB_SQL_META, - TSDB_SQL_METRIC, - TSDB_SQL_MULTI_META, - TSDB_SQL_HB, - - TSDB_SQL_LOCAL, // SQL below for client local - TSDB_SQL_DESCRIBE_TABLE, - TSDB_SQL_RETRIEVE_METRIC, - TSDB_SQL_METRIC_JOIN_RETRIEVE, - TSDB_SQL_RETRIEVE_TAGS, - - /* - * build empty result instead of accessing dnode to fetch result - * reset the client cache - */ - TSDB_SQL_RETRIEVE_EMPTY_RESULT, //40 - - TSDB_SQL_RESET_CACHE, - TSDB_SQL_SERV_STATUS, - TSDB_SQL_CURRENT_DB, - TSDB_SQL_SERV_VERSION, - TSDB_SQL_CLI_VERSION, - TSDB_SQL_CURRENT_USER, - TSDB_SQL_CFG_LOCAL, - - TSDB_SQL_MAX //48 -}; +#include "tvariant.h" +#include "qsqlparser.h" enum { TSQL_NODE_TYPE_EXPR = 0x1, @@ -96,321 +37,6 @@ enum { #define NORMAL_ARITHMETIC 1 #define AGG_ARIGHTMEIC 2 -extern char tTokenTypeSwitcher[13]; - -#define toTSDBType(x) \ - do { \ - if ((x) >= tListLen(tTokenTypeSwitcher)) { \ - (x) = TSDB_DATA_TYPE_BINARY; \ - } else { \ - (x) = tTokenTypeSwitcher[(x)]; \ - } \ - } while (0) - -typedef struct SLimitVal { - int64_t limit; - int64_t offset; -} SLimitVal; - -typedef struct SOrderVal { - uint32_t order; - int32_t orderColId; -} SOrderVal; - -typedef struct tVariantListItem { - tVariant pVar; - uint8_t sortOrder; -} tVariantListItem; - -typedef struct tVariantList { - int32_t nExpr; /* Number of expressions on the list */ - int32_t nAlloc; /* Number of entries allocated below */ - tVariantListItem *a; /* One entry for each expression */ -} tVariantList; - -typedef struct tFieldList { - int32_t nField; - int32_t nAlloc; - TAOS_FIELD *p; -} tFieldList; - -// create table operation type -enum TSQL_TYPE { - TSQL_CREATE_TABLE = 0x1, - TSQL_CREATE_STABLE = 0x2, - TSQL_CREATE_TABLE_FROM_STABLE = 0x3, - TSQL_CREATE_STREAM = 0x4, -}; - -typedef struct SQuerySQL { - struct tSQLExprList *pSelection; // select clause - tVariantList * from; // from clause - struct tSQLExpr * pWhere; // where clause [optional] - tVariantList * pGroupby; // groupby clause, only for tags[optional] - tVariantList * pSortOrder; // orderby [optional] - SSQLToken interval; // interval [optional] - SSQLToken sliding; // sliding window [optional] - SLimitVal limit; // limit offset [optional] - SLimitVal slimit; // group limit offset [optional] - tVariantList * fillType; // fill type[optional] - SSQLToken selectToken; // sql string -} SQuerySQL; - -typedef struct SCreateTableSQL { - struct SSQLToken name; // meter name, create table [meterName] xxx - bool existCheck; - - int8_t type; // create normal table/from super table/ stream - struct { - tFieldList *pTagColumns; // for normal table, pTagColumns = NULL; - tFieldList *pColumns; - } colInfo; - - struct { - SSQLToken stableName; // super table name, for using clause - tVariantList *pTagVals; // create by using metric, tag value - STagData tagdata; - } usingInfo; - - SQuerySQL *pSelect; -} SCreateTableSQL; - -typedef struct SAlterTableSQL { - SSQLToken name; - int16_t type; - STagData tagData; - - tFieldList * pAddColumns; - tVariantList *varList; // set t=val or: change src dst -} SAlterTableSQL; - -typedef struct SCreateDBInfo { - SSQLToken dbname; - int32_t replica; - int32_t cacheBlockSize; - int32_t tablesPerVnode; - int32_t daysPerFile; - int32_t rowPerFileBlock; - - float numOfAvgCacheBlocks; - int32_t numOfBlocksPerTable; - - int64_t commitTime; - int32_t commitLog; - int32_t compressionLevel; - SSQLToken precision; - - tVariantList *keep; -} SCreateDBInfo; - -typedef struct SCreateAcctSQL { - int32_t maxUsers; - int32_t maxDbs; - int32_t maxTimeSeries; - int32_t maxStreams; - int32_t maxPointsPerSecond; - int64_t maxStorage; - int64_t maxQueryTime; - int32_t maxConnections; - SSQLToken stat; -} SCreateAcctSQL; - -typedef struct SShowInfo { - uint8_t showType; - SSQLToken prefix; - SSQLToken pattern; -} SShowInfo; - -typedef struct SUserInfo { - SSQLToken user; - SSQLToken passwd; -// bool hasPasswd; - - SSQLToken privilege; -// bool hasPrivilege; - - int16_t type; -} SUserInfo; - -typedef struct tDCLSQL { - int32_t nTokens; /* Number of expressions on the list */ - int32_t nAlloc; /* Number of entries allocated below */ - SSQLToken *a; /* one entry for element */ - bool existsCheck; - - union { - SCreateDBInfo dbOpt; - SCreateAcctSQL acctOpt; - SShowInfo showOpt; - SSQLToken ip; - }; - - SUserInfo user; - -} tDCLSQL; - -typedef struct SSubclauseInfo { // "UNION" multiple select sub-clause - SQuerySQL **pClause; - int32_t numOfClause; -} SSubclauseInfo; - -typedef struct SSqlInfo { - int32_t type; - bool valid; - - union { - SCreateTableSQL *pCreateTableInfo; - SAlterTableSQL * pAlterInfo; - tDCLSQL * pDCLInfo; - }; - - SSubclauseInfo subclauseInfo; - char pzErrMsg[256]; -} SSqlInfo; - -typedef struct tSQLExpr { - /* - * for single operand: - * TK_ALL - * TK_ID - * TK_SUM - * TK_AVG - * TK_MIN - * TK_MAX - * TK_FIRST - * TK_LAST - * TK_BOTTOM - * TK_TOP - * TK_STDDEV - * TK_PERCENTILE - * - * for binary operand: - * TK_LESS - * TK_LARGE - * TK_EQUAL etc... - */ - uint32_t nSQLOptr; // TK_FUNCTION: sql function, TK_LE: less than(binary expr) - - // the full sql string of function(col, param), which is actually the raw - // field name, since the function name is kept in nSQLOptr already - SSQLToken operand; - struct tSQLExprList *pParam; // function parameters - - SSQLToken colInfo; // field id - tVariant val; // value only for string, float, int - - struct tSQLExpr *pLeft; // left child - struct tSQLExpr *pRight; // right child -} tSQLExpr; - -// used in select clause. select from xxx -typedef struct tSQLExprItem { - tSQLExpr *pNode; // The list of expressions - char * aliasName; // alias name, null-terminated string -} tSQLExprItem; - -typedef struct tSQLExprList { - int32_t nExpr; /* Number of expressions on the list */ - int32_t nAlloc; /* Number of entries allocated below */ - tSQLExprItem *a; /* One entry for each expression */ -} tSQLExprList; - -typedef struct tSQLExprListList { - int32_t nList; /* Number of expressions on the list */ - int32_t nAlloc; /* Number of entries allocated below */ - tSQLExprList **a; /* one entry for each row */ -} tSQLExprListList; - -#define ParseTOKENTYPE SSQLToken - -void *ParseAlloc(void *(*mallocProc)(size_t)); - -/** - * - * @param yyp The parser - * @param yymajor The major token code number - * @param yyminor The value for the token - */ -void Parse(void *yyp, int yymajor, ParseTOKENTYPE yyminor, SSqlInfo *); - -/** - * - * @param p The parser to be deleted - * @param freeProc Function used to reclaim memory - */ -void ParseFree(void *p, void (*freeProc)(void *)); - -tVariantList *tVariantListAppend(tVariantList *pList, tVariant *pVar, uint8_t sortOrder); - -tVariantList *tVariantListInsert(tVariantList *pList, tVariant *pVar, uint8_t sortOrder, int32_t index); - -tVariantList *tVariantListAppendToken(tVariantList *pList, SSQLToken *pAliasToken, uint8_t sortOrder); -void tVariantListDestroy(tVariantList *pList); - -tFieldList *tFieldListAppend(tFieldList *pList, TAOS_FIELD *pField); - -void tFieldListDestroy(tFieldList *pList); - -tSQLExpr *tSQLExprCreate(tSQLExpr *pLeft, tSQLExpr *pRight, int32_t optType); - -void tSQLExprDestroy(tSQLExpr *); - -tSQLExprList *tSQLExprListAppend(tSQLExprList *pList, tSQLExpr *pNode, SSQLToken *pToken); - -void tSQLExprListDestroy(tSQLExprList *pList); - -SQuerySQL *tSetQuerySQLElems(SSQLToken *pSelectToken, tSQLExprList *pSelection, tVariantList *pFrom, tSQLExpr *pWhere, - tVariantList *pGroupby, tVariantList *pSortOrder, SSQLToken *pInterval, - SSQLToken *pSliding, tVariantList *pFill, SLimitVal *pLimit, SLimitVal *pGLimit); - -SCreateTableSQL *tSetCreateSQLElems(tFieldList *pCols, tFieldList *pTags, SSQLToken *pMetricName, - tVariantList *pTagVals, SQuerySQL *pSelect, int32_t type); - -void tSQLExprNodeDestroy(tSQLExpr *pExpr); -tSQLExpr *tSQLExprNodeClone(tSQLExpr *pExpr); - -SAlterTableSQL *tAlterTableSQLElems(SSQLToken *pMeterName, tFieldList *pCols, tVariantList *pVals, int32_t type); - -tSQLExprListList *tSQLListListAppend(tSQLExprListList *pList, tSQLExprList *pExprList); - -void destroyAllSelectClause(SSubclauseInfo *pSql); -void doDestroyQuerySql(SQuerySQL *pSql); - -SSqlInfo * setSQLInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SSQLToken *pMeterName, int32_t type); -SSubclauseInfo *setSubclause(SSubclauseInfo *pClause, void *pSqlExprInfo); - -SSubclauseInfo *appendSelectClause(SSubclauseInfo *pInfo, void *pSubclause); - -void setCreatedMeterName(SSqlInfo *pInfo, SSQLToken *pMeterName, SSQLToken *pIfNotExists); - -void SQLInfoDestroy(SSqlInfo *pInfo); - -void setDCLSQLElems(SSqlInfo *pInfo, int32_t type, int32_t nParams, ...); -void setDropDBTableInfo(SSqlInfo *pInfo, int32_t type, SSQLToken* pToken, SSQLToken* existsCheck); -void setShowOptions(SSqlInfo *pInfo, int32_t type, SSQLToken* prefix, SSQLToken* pPatterns); - -tDCLSQL *tTokenListAppend(tDCLSQL *pTokenList, SSQLToken *pToken); - -void setCreateDBSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *pToken, SCreateDBInfo *pDB, SSQLToken *pIgExists); - -void setCreateAcctSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *pName, SSQLToken *pPwd, SCreateAcctSQL *pAcctInfo); -void setCreateUserSQL(SSqlInfo *pInfo, SSQLToken *pName, SSQLToken *pPasswd); -void setKillSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *ip); -void setAlterUserSQL(SSqlInfo *pInfo, int16_t type, SSQLToken *pName, SSQLToken* pPwd, SSQLToken *pPrivilege); - -void setDefaultCreateDbOption(SCreateDBInfo *pDBInfo); - -// prefix show db.tables; -void setDBName(SSQLToken *pCpxName, SSQLToken *pDB); - -tSQLExpr *tSQLExprIdValueCreate(SSQLToken *pToken, int32_t optType); - -tSQLExpr *tSQLExprCreateFunction(tSQLExprList *pList, SSQLToken *pFuncToken, SSQLToken *endToken, int32_t optType); - -void tSQLSetColumnInfo(TAOS_FIELD *pField, SSQLToken *pName, TAOS_FIELD *pType); - -void tSQLSetColumnType(TAOS_FIELD *pField, SSQLToken *pToken); - int32_t tSQLParse(SSqlInfo *pSQLInfo, const char *pSql); #ifdef __cplusplus diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 6ae6ff6d746314f77b696c4e9a38783a8f3bbd47..caec0fdbb8c444e865610ac1e08b992decfc31b3 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -31,6 +31,7 @@ extern "C" { #include "tsqlfunction.h" #include "tutil.h" #include "trpc.h" +#include "qsqltype.h" #define TSC_GET_RESPTR_BASE(res, _queryinfo, col) (res->data + ((_queryinfo)->fieldsInfo.pSqlExpr[col]->offset) * res->numOfRows) @@ -428,6 +429,8 @@ void tscFreeSqlObj(SSqlObj *pObj); void tscCloseTscObj(STscObj *pObj); +void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const char* sqlstr, int32_t sqlLen); + void tscProcessMultiVnodesInsert(SSqlObj *pSql); void tscProcessMultiVnodesInsertFromFile(SSqlObj *pSql); void tscKillMetricQuery(SSqlObj *pSql); @@ -447,7 +450,7 @@ void tscQueueAsyncFreeResult(SSqlObj *pSql); extern void * pVnodeConn; extern void * pTscMgmtConn; extern void * tscCacheHandle; -extern uint8_t globalCode; +extern int32_t globalCode; extern int slaveIndex; extern void * tscTmr; extern void * tscConnCache; diff --git a/src/util/src/tcache.c b/src/client/src/tcache.c similarity index 100% rename from src/util/src/tcache.c rename to src/client/src/tcache.c diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 67ea3c5120a15ecf15e2cbdceccdd2e093bc49ef..f1630ef294cd33fb80d096892120fe9f162203bc 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -40,47 +40,22 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows); static void tscAsyncFetchSingleRowProxy(void *param, TAOS_RES *tres, int numOfRows); -// TODO return the correct error code to client in tscQueueAsyncError -void taos_query_a(TAOS *taos, const char *sqlstr, void (*fp)(void *, TAOS_RES *, int), void *param) { - STscObj *pObj = (STscObj *)taos; - if (pObj == NULL || pObj->signature != pObj) { - tscError("bug!!! pObj:%p", pObj); - globalCode = TSDB_CODE_DISCONNECTED; - tscQueueAsyncError(fp, param); - return; - } - - int32_t sqlLen = strlen(sqlstr); - if (sqlLen > tsMaxSQLStringLen) { - tscError("sql string too long"); - tscQueueAsyncError(fp, param); - return; - } - - taosNotePrintTsc(sqlstr); - - SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); - if (pSql == NULL) { - tscError("failed to malloc sqlObj"); - tscQueueAsyncError(fp, param); - return; - } - +void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const char* sqlstr, int32_t sqlLen) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; - + pSql->signature = pSql; pSql->pTscObj = pObj; pSql->fp = fp; pSql->param = param; - + if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) { tscError("failed to malloc payload"); tfree(pSql); tscQueueAsyncError(fp, param); return; } - + pSql->sqlstr = malloc(sqlLen + 1); if (pSql->sqlstr == NULL) { tscError("%p failed to malloc sql string buffer", pSql); @@ -89,25 +64,54 @@ void taos_query_a(TAOS *taos, const char *sqlstr, void (*fp)(void *, TAOS_RES *, free(pSql); return; } - + pRes->qhandle = 0; pRes->numOfRows = 1; - + strtolower(pSql->sqlstr, sqlstr); tscDump("%p pObj:%p, Async SQL: %s", pSql, pObj, pSql->sqlstr); - + int32_t code = tsParseSql(pSql, true); if (code == TSDB_CODE_ACTION_IN_PROGRESS) return; - + if (code != TSDB_CODE_SUCCESS) { pSql->res.code = (uint8_t)code; tscQueueAsyncRes(pSql); return; } - + tscDoQuery(pSql); } +// TODO return the correct error code to client in tscQueueAsyncError +void taos_query_a(TAOS *taos, const char *sqlstr, void (*fp)(void *, TAOS_RES *, int), void *param) { + STscObj *pObj = (STscObj *)taos; + if (pObj == NULL || pObj->signature != pObj) { + tscError("bug!!! pObj:%p", pObj); + globalCode = TSDB_CODE_DISCONNECTED; + tscQueueAsyncError(fp, param); + return; + } + + int32_t sqlLen = strlen(sqlstr); + if (sqlLen > tsMaxSQLStringLen) { + tscError("sql string too long"); + tscQueueAsyncError(fp, param); + return; + } + + taosNotePrintTsc(sqlstr); + + SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); + if (pSql == NULL) { + tscError("failed to malloc sqlObj"); + tscQueueAsyncError(fp, param); + return; + } + + doAsyncQuery(pObj, pSql, fp, param, sqlstr, sqlLen); +} + static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) { if (tres == NULL) { return; diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 59dc708e99fe930f887b20fe784c984fa1954a90..b54600f6412f84c67b892fd228d10d0380e5f948 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -18,13 +18,13 @@ #define _XOPEN_SOURCE -#include "os.h" #include "hash.h" +#include "os.h" #include "tscSecondaryMerge.h" #include "tscUtil.h" #include "tschemautil.h" #include "tsclient.h" -#include "tsqldef.h" +#include "ttokendef.h" #include "ttypes.h" #include "tlog.h" diff --git a/src/client/src/tscSchemaUtil.c b/src/client/src/tscSchemaUtil.c index 605b77a796421cba4902232b8fa584909ac8ff76..250e296e5345845152534c692f5a28020e22748f 100644 --- a/src/client/src/tscSchemaUtil.c +++ b/src/client/src/tscSchemaUtil.c @@ -16,7 +16,7 @@ #include "os.h" #include "taosmsg.h" #include "tschemautil.h" -#include "tsqldef.h" +#include "ttokendef.h" #include "ttypes.h" #include "tutil.h" diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index 893b42d9caf7ad159372bc5f323f9ae93e57cc1a..397ad3aa11cbfee3eb99f42c05c0de9303fcb35f 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -182,6 +182,8 @@ int tscSendMsgToServer(SSqlObj *pSql) { } pSql->ipList->ip[0] = inet_addr("192.168.0.1"); + SSqlCmd* pCmd = &pSql->cmd; + if (pSql->cmd.command < TSDB_SQL_MGMT) { pSql->ipList->port = tsVnodeShellPort; tscPrint("%p msg:%s is sent to server %d", pSql, taosMsg[pSql->cmd.msgType], pSql->ipList->port); diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index 2f3312b0b6dca5d8ec5db584b4ca732b91fcdcdf..465263a439773f59fc07bbfe8452c3dd521d6d1f 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -238,39 +238,36 @@ int taos_query_imp(STscObj *pObj, SSqlObj *pSql) { return pRes->code; } +static void syncQueryCallback(void *param, TAOS_RES *tres, int code) { + STscObj *pObj = (STscObj *)param; + assert(pObj != NULL && pObj->pSql != NULL); + + sem_post(&pObj->pSql->rspSem); +} + int taos_query(TAOS *taos, const char *sqlstr) { STscObj *pObj = (STscObj *)taos; if (pObj == NULL || pObj->signature != pObj) { globalCode = TSDB_CODE_DISCONNECTED; return TSDB_CODE_DISCONNECTED; } - - SSqlObj *pSql = pObj->pSql; - SSqlRes *pRes = &pSql->res; - - size_t sqlLen = strlen(sqlstr); - if (sqlLen > tsMaxSQLStringLen) { - pRes->code = - tscInvalidSQLErrMsg(pSql->cmd.payload, "sql too long", NULL); // set the additional error msg for invalid sql - tscError("%p SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj); - - return pRes->code; - } - - taosNotePrintTsc(sqlstr); - - void *sql = realloc(pSql->sqlstr, sqlLen + 1); - if (sql == NULL) { - pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY; - tscError("%p failed to malloc sql string buffer, reason:%s", pSql, strerror(errno)); - - tscError("%p SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(taos), pObj); - return pRes->code; + + SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); + if (pSql == NULL) { + tscError("failed to malloc sqlObj"); + return TSDB_CODE_CLI_OUT_OF_MEMORY; } + + pObj->pSql = pSql; + tsem_init(&pSql->rspSem, 0, 0); + + int32_t sqlLen = strlen(sqlstr); + doAsyncQuery(pObj, pObj->pSql, syncQueryCallback, taos, sqlstr, sqlLen); - pSql->sqlstr = sql; - strtolower(pSql->sqlstr, sqlstr); - return taos_query_imp(pObj, pSql); + // wait for the callback function to post the semaphore + sem_wait(&pSql->rspSem); + + return pSql->res.code; } TAOS_RES *taos_use_result(TAOS *taos) { @@ -683,33 +680,37 @@ TAOS_ROW taos_fetch_row_impl(TAOS_RES *res) { return doSetResultRowData(pSql); } +static void asyncFetchCallback(void *param, TAOS_RES *tres, int numOfRows) { + SSqlObj* pSql = (SSqlObj*) tres; + if (numOfRows < 0) { + // set the error code + pSql->res.code = -numOfRows; + } + + sem_post(&pSql->rspSem); +} + TAOS_ROW taos_fetch_row(TAOS_RES *res) { SSqlObj *pSql = (SSqlObj *)res; - SSqlCmd *pCmd = &pSql->cmd; - if (pSql == NULL || pSql->signature != pSql) { globalCode = TSDB_CODE_DISCONNECTED; return NULL; } - - /* - * projection query on super table, access each virtual node sequentially retrieve data from vnode list, - * instead of two-stage merge - */ - TAOS_ROW rows = taos_fetch_row_impl(res); - if (rows != NULL) { - return rows; + + SSqlCmd *pCmd = &pSql->cmd; + SSqlRes *pRes = &pSql->res; + + if (pRes->qhandle == 0 || pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT || pCmd->command == TSDB_SQL_INSERT) { + return NULL; } - - // current subclause is completed, try the next subclause - while (rows == NULL && pCmd->clauseIndex < pCmd->numOfClause - 1) { - tscTryQueryNextClause(pSql, NULL); - - // if the rows is not NULL, return immediately - rows = taos_fetch_row_impl(res); + + // current data are exhausted, fetch more data + if (pRes->data == NULL || (pRes->data != NULL && pRes->row >= pRes->numOfRows && pCmd->command == TSDB_SQL_RETRIEVE)) { + taos_fetch_rows_a(res, asyncFetchCallback, pSql->pTscObj); + sem_wait(&pSql->rspSem); } - - return rows; + + return doSetResultRowData(pSql); } int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) { @@ -782,7 +783,13 @@ void taos_free_result_imp(TAOS_RES *res, int keepCmd) { /* Query rsp is not received from vnode, so the qhandle is NULL */ tscTrace("%p qhandle is null, abort free, fp:%p", pSql, pSql->fp); if (pSql->fp != NULL) { - tscFreeSqlObj(pSql); + STscObj* pObj = pSql->pTscObj; + + if (pSql == pObj->pSql) { + pObj->pSql = NULL; + tscFreeSqlObj(pSql); + } + tscTrace("%p Async SqlObj is freed by app", pSql); } else if (keepCmd) { tscFreeSqlResult(pSql); @@ -849,6 +856,11 @@ void taos_free_result_imp(TAOS_RES *res, int keepCmd) { tscFreeSqlObjPartial(pSql); tscTrace("%p sql result is freed by app", pSql); } + } else { // for async release, remove its link + STscObj* pObj = pSql->pTscObj; + if (pObj->pSql == pSql) { + pObj->pSql = NULL; + } } } else { // if no free resource msg is sent to vnode, we free this object immediately. diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c index ced0d76ca4360a1ae712b6d9ce01a5d6811481d3..d7fe6f4ac8d6fe0462b065a2b2434d332b4ecfb7 100644 --- a/src/client/src/tscSystem.c +++ b/src/client/src/tscSystem.c @@ -33,7 +33,7 @@ void * pVMeterConn; void * pTscMgmtConn; void * pSlaveConn; void * tscCacheHandle; -uint8_t globalCode = 0; +int32_t globalCode = 0; int initialized = 0; int slaveIndex; void * tscTmr; diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 2a5af0473c8bc5c8e40807c43ee1968a9ead24f0..397ef2f0d03ed9fe4cc3c67b85dfdefcbdb0439a 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -13,10 +13,11 @@ * along with this program. If not, see . */ -#include "os.h" #include "tscUtil.h" #include "hash.h" +#include "os.h" #include "taosmsg.h" +#include "tast.h" #include "tcache.h" #include "tkey.h" #include "tmd5.h" @@ -25,9 +26,8 @@ #include "tscSecondaryMerge.h" #include "tschemautil.h" #include "tsclient.h" -#include "tsqldef.h" #include "ttimer.h" -#include "tast.h" +#include "ttokendef.h" /* * the detailed information regarding metric meta key is: @@ -460,11 +460,16 @@ void tscFreeSqlObjPartial(SSqlObj* pSql) { pthread_mutex_lock(&pObj->mutex); tfree(pSql->sqlstr); pthread_mutex_unlock(&pObj->mutex); - + tscFreeSqlResult(pSql); tfree(pSql->pSubs); pSql->numOfSubs = 0; - + + pSql->freed = 0; + tscFreeSqlCmdData(pCmd); + + tscTrace("%p free sqlObj partial completed", pSql); + tscFreeSqlCmdData(pCmd); } diff --git a/src/dnode/CMakeLists.txt b/src/dnode/CMakeLists.txt index bcde03664d093d18a457102ad4878575796f8aca..73160c074f95167d0f0f39633a190e7bdb361ef0 100644 --- a/src/dnode/CMakeLists.txt +++ b/src/dnode/CMakeLists.txt @@ -5,6 +5,7 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc) + INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) INCLUDE_DIRECTORIES(${TD_ENTERPRISE_DIR}/src/inc) INCLUDE_DIRECTORIES(inc) AUX_SOURCE_DIRECTORY(src SRC) diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index d3c8edee44458b203e83fb999f0838d58a0f2539..7a8cd28428fa0e4ad7a8aa4207c0f728803a09ab 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -196,20 +196,6 @@ extern "C" { #define TSDB_MAX_NCHAR_LEN (TSDB_MAX_BYTES_PER_ROW-TSDB_KEYSIZE) #define PRIMARYKEY_TIMESTAMP_COL_INDEX 0 -#define TSDB_DATA_BOOL_NULL 0x02 -#define TSDB_DATA_TINYINT_NULL 0x80 -#define TSDB_DATA_SMALLINT_NULL 0x8000 -#define TSDB_DATA_INT_NULL 0x80000000 -#define TSDB_DATA_BIGINT_NULL 0x8000000000000000L - -#define TSDB_DATA_FLOAT_NULL 0x7FF00000 // it is an NAN -#define TSDB_DATA_DOUBLE_NULL 0x7FFFFF0000000000L // an NAN -#define TSDB_DATA_NCHAR_NULL 0xFFFFFFFF -#define TSDB_DATA_BINARY_NULL 0xFF - -#define TSDB_DATA_NULL_STR "NULL" -#define TSDB_DATA_NULL_STR_L "null" - #define TSDB_MAX_RPC_THREADS 5 #define TSDB_QUERY_TYPE_NON_TYPE 0x00U // none type diff --git a/src/util/inc/tsqldef.h b/src/inc/ttokendef.h similarity index 100% rename from src/util/inc/tsqldef.h rename to src/inc/ttokendef.h diff --git a/src/kit/shell/CMakeLists.txt b/src/kit/shell/CMakeLists.txt index 20a740dee9aead2c91826903de3fa7b5d872c118..73bee20c73258841d12951fe0f16d2c3f44d9001 100644 --- a/src/kit/shell/CMakeLists.txt +++ b/src/kit/shell/CMakeLists.txt @@ -4,6 +4,7 @@ PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) +INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc) INCLUDE_DIRECTORIES(inc) diff --git a/src/kit/shell/src/shellEngine.c b/src/kit/shell/src/shellEngine.c index 22af4ca5c3d7a9514b0d604757b92e2b72cc952b..a4a589d55ccd77d61e389efddcb4a6f7e80b7302 100644 --- a/src/kit/shell/src/shellEngine.c +++ b/src/kit/shell/src/shellEngine.c @@ -21,6 +21,7 @@ #include "shellCommand.h" #include "ttime.h" #include "tutil.h" +#include "ttypes.h" #include "taoserror.h" #include diff --git a/src/kit/taosdump/CMakeLists.txt b/src/kit/taosdump/CMakeLists.txt index 0ff54200ce340293f011ca150d8d91a91e907ad7..a15b0ff5524d7b4211cdd99ae77857e50e660282 100644 --- a/src/kit/taosdump/CMakeLists.txt +++ b/src/kit/taosdump/CMakeLists.txt @@ -4,6 +4,7 @@ PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc) +INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc) INCLUDE_DIRECTORIES(inc) diff --git a/src/mnode/CMakeLists.txt b/src/mnode/CMakeLists.txt index acf8b15f2263a35de39ebc9077c0e9372d985948..16dbbcb740834e34fb2d8545a7926a054c1a122a 100644 --- a/src/mnode/CMakeLists.txt +++ b/src/mnode/CMakeLists.txt @@ -5,6 +5,7 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc) + INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/dnode/inc) INCLUDE_DIRECTORIES(inc) diff --git a/src/mnode/src/mgmtChildTable.c b/src/mnode/src/mgmtChildTable.c index 02771b19c9018f3c98fbd2361c922918ba12ab0e..1bc4305438e5ea46d60ba2b8fc0a335e2ec36da7 100644 --- a/src/mnode/src/mgmtChildTable.c +++ b/src/mnode/src/mgmtChildTable.c @@ -16,12 +16,9 @@ #define _DEFAULT_SOURCE #include "os.h" #include "taosmsg.h" -#include "tast.h" -#include "textbuffer.h" #include "tschemautil.h" #include "tscompression.h" #include "tskiplist.h" -#include "tsqlfunction.h" #include "ttime.h" #include "tstatus.h" #include "tutil.h" diff --git a/src/mnode/src/mgmtNormalTable.c b/src/mnode/src/mgmtNormalTable.c index aaabe0bcacf7e5353af0763b14585d5d35c7487f..fddb47cb7ea30597b01b678f71c4406e80ef635c 100644 --- a/src/mnode/src/mgmtNormalTable.c +++ b/src/mnode/src/mgmtNormalTable.c @@ -16,12 +16,8 @@ #define _DEFAULT_SOURCE #include "os.h" #include "taosmsg.h" -#include "tast.h" -#include "textbuffer.h" -#include "tschemautil.h" #include "tscompression.h" #include "tskiplist.h" -#include "tsqlfunction.h" #include "ttime.h" #include "tstatus.h" #include "tutil.h" diff --git a/src/mnode/src/mgmtSuperTable.c b/src/mnode/src/mgmtSuperTable.c index 6a74f7616d224749bf9e574c00542d50e34d24d7..2fb4129e755050cee9845dbe3a351ac0005d3d74 100644 --- a/src/mnode/src/mgmtSuperTable.c +++ b/src/mnode/src/mgmtSuperTable.c @@ -16,8 +16,6 @@ #define _DEFAULT_SOURCE #include "os.h" #include "taosmsg.h" -#include "tast.h" -#include "textbuffer.h" #include "tschemautil.h" #include "tscompression.h" #include "tskiplist.h" diff --git a/src/plugins/http/CMakeLists.txt b/src/plugins/http/CMakeLists.txt index 7044f5d09d0f1fe2930e4d998af0d970d76f4655..57ca4ca9f0b0d5e0210178f62e3ca82ba5e48e61 100644 --- a/src/plugins/http/CMakeLists.txt +++ b/src/plugins/http/CMakeLists.txt @@ -5,6 +5,7 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc) + INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/zlib-1.2.11/inc) INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc) INCLUDE_DIRECTORIES(inc) diff --git a/src/plugins/monitor/CMakeLists.txt b/src/plugins/monitor/CMakeLists.txt index 6bc41d2b3e9fb385274d582ecc4623186b61c9b2..c409f28b2042da2551d677b96bf376fea86f3d30 100644 --- a/src/plugins/monitor/CMakeLists.txt +++ b/src/plugins/monitor/CMakeLists.txt @@ -5,6 +5,7 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc) + INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc) INCLUDE_DIRECTORIES(inc) AUX_SOURCE_DIRECTORY(./src SRC) diff --git a/src/plugins/monitor/src/monitorSystem.c b/src/plugins/monitor/src/monitorSystem.c index 5a42d66493b56e6d3a252b2ededbc786b9445089..4fb3ba2f5b55ee72452fd7e39793053394f9c51a 100644 --- a/src/plugins/monitor/src/monitorSystem.c +++ b/src/plugins/monitor/src/monitorSystem.c @@ -13,11 +13,9 @@ * along with this program. If not, see . */ +#include "os.h" + #include "monitor.h" -#include -#include -#include -#include #include "dnode.h" #include "monitorSystem.h" #include "tsclient.h" diff --git a/src/query/CMakeLists.txt b/src/query/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..c0ded1dafb70cf36ea05886cbe17904b18addc24 --- /dev/null +++ b/src/query/CMakeLists.txt @@ -0,0 +1,13 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +PROJECT(TDengine) + +INCLUDE_DIRECTORIES(${TD_OS_DIR}/inc) +INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc) +INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/util/inc) +INCLUDE_DIRECTORIES(inc) + +IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) + AUX_SOURCE_DIRECTORY(src SRC) + ADD_LIBRARY(query ${SRC}) + TARGET_LINK_LIBRARIES(query util m rt) +ENDIF () \ No newline at end of file diff --git a/src/query/inc/qsqlparser.h b/src/query/inc/qsqlparser.h new file mode 100644 index 0000000000000000000000000000000000000000..7a1322be10fb24581b9f0d38db173a7d7f86612e --- /dev/null +++ b/src/query/inc/qsqlparser.h @@ -0,0 +1,336 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef TDENGINE_QASTDEF_H +#define TDENGINE_QASTDEF_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "taos.h" +#include "taosmsg.h" +#include "tstoken.h" +#include "tvariant.h" + +#define ParseTOKENTYPE SSQLToken +extern char tTokenTypeSwitcher[13]; + +#define toTSDBType(x) \ + do { \ + if ((x) >= tListLen(tTokenTypeSwitcher)) { \ + (x) = TSDB_DATA_TYPE_BINARY; \ + } else { \ + (x) = tTokenTypeSwitcher[(x)]; \ + } \ + } while (0) + +typedef struct tFieldList { + int32_t nField; + int32_t nAlloc; + TAOS_FIELD *p; +} tFieldList; + +typedef struct SLimitVal { + int64_t limit; + int64_t offset; +} SLimitVal; + +typedef struct SOrderVal { + uint32_t order; + int32_t orderColId; +} SOrderVal; + +typedef struct tVariantListItem { + tVariant pVar; + uint8_t sortOrder; +} tVariantListItem; + +typedef struct tVariantList { + int32_t nExpr; /* Number of expressions on the list */ + int32_t nAlloc; /* Number of entries allocated below */ + tVariantListItem *a; /* One entry for each expression */ +} tVariantList; + +typedef struct SQuerySQL { + struct tSQLExprList *pSelection; // select clause + tVariantList * from; // from clause + struct tSQLExpr * pWhere; // where clause [optional] + tVariantList * pGroupby; // groupby clause, only for tags[optional] + tVariantList * pSortOrder; // orderby [optional] + SSQLToken interval; // interval [optional] + SSQLToken sliding; // sliding window [optional] + SLimitVal limit; // limit offset [optional] + SLimitVal slimit; // group limit offset [optional] + tVariantList * fillType; // fill type[optional] + SSQLToken selectToken; // sql string +} SQuerySQL; + +typedef struct SCreateTableSQL { + struct SSQLToken name; // meter name, create table [meterName] xxx + bool existCheck; + + int8_t type; // create normal table/from super table/ stream + struct { + tFieldList *pTagColumns; // for normal table, pTagColumns = NULL; + tFieldList *pColumns; + } colInfo; + + struct { + SSQLToken stableName; // super table name, for using clause + tVariantList *pTagVals; // create by using metric, tag value + STagData tagdata; + } usingInfo; + + SQuerySQL *pSelect; +} SCreateTableSQL; + +typedef struct SAlterTableSQL { + SSQLToken name; + int16_t type; + STagData tagData; + + tFieldList * pAddColumns; + tVariantList *varList; // set t=val or: change src dst +} SAlterTableSQL; + +typedef struct SCreateDBInfo { + SSQLToken dbname; + int32_t replica; + int32_t cacheBlockSize; + int32_t tablesPerVnode; + int32_t daysPerFile; + int32_t rowPerFileBlock; + + float numOfAvgCacheBlocks; + int32_t numOfBlocksPerTable; + + int64_t commitTime; + int32_t commitLog; + int32_t compressionLevel; + SSQLToken precision; + + tVariantList *keep; +} SCreateDBInfo; + +typedef struct SCreateAcctSQL { + int32_t maxUsers; + int32_t maxDbs; + int32_t maxTimeSeries; + int32_t maxStreams; + int32_t maxPointsPerSecond; + int64_t maxStorage; + int64_t maxQueryTime; + int32_t maxConnections; + SSQLToken stat; +} SCreateAcctSQL; + +typedef struct SShowInfo { + uint8_t showType; + SSQLToken prefix; + SSQLToken pattern; +} SShowInfo; + +typedef struct SUserInfo { + SSQLToken user; + SSQLToken passwd; + SSQLToken privilege; + int16_t type; +} SUserInfo; + +typedef struct tDCLSQL { + int32_t nTokens; /* Number of expressions on the list */ + int32_t nAlloc; /* Number of entries allocated below */ + SSQLToken *a; /* one entry for element */ + bool existsCheck; + + union { + SCreateDBInfo dbOpt; + SCreateAcctSQL acctOpt; + SShowInfo showOpt; + SSQLToken ip; + }; + + SUserInfo user; + +} tDCLSQL; + +typedef struct SSubclauseInfo { // "UNION" multiple select sub-clause + SQuerySQL **pClause; + int32_t numOfClause; +} SSubclauseInfo; + +typedef struct SSqlInfo { + int32_t type; + bool valid; + + union { + SCreateTableSQL *pCreateTableInfo; + SAlterTableSQL * pAlterInfo; + tDCLSQL * pDCLInfo; + }; + + SSubclauseInfo subclauseInfo; + char pzErrMsg[256]; +} SSqlInfo; + +typedef struct tSQLExpr { + /* + * for single operand: + * TK_ALL + * TK_ID + * TK_SUM + * TK_AVG + * TK_MIN + * TK_MAX + * TK_FIRST + * TK_LAST + * TK_BOTTOM + * TK_TOP + * TK_STDDEV + * TK_PERCENTILE + * + * for binary operand: + * TK_LESS + * TK_LARGE + * TK_EQUAL etc... + */ + uint32_t nSQLOptr; // TK_FUNCTION: sql function, TK_LE: less than(binary expr) + + // the full sql string of function(col, param), which is actually the raw + // field name, since the function name is kept in nSQLOptr already + SSQLToken operand; + struct tSQLExprList *pParam; // function parameters + + SSQLToken colInfo; // field id + tVariant val; // value only for string, float, int + + struct tSQLExpr *pLeft; // left child + struct tSQLExpr *pRight; // right child +} tSQLExpr; + +// used in select clause. select from xxx +typedef struct tSQLExprItem { + tSQLExpr *pNode; // The list of expressions + char * aliasName; // alias name, null-terminated string +} tSQLExprItem; + +typedef struct tSQLExprList { + int32_t nExpr; /* Number of expressions on the list */ + int32_t nAlloc; /* Number of entries allocated below */ + tSQLExprItem *a; /* One entry for each expression */ +} tSQLExprList; + +typedef struct tSQLExprListList { + int32_t nList; /* Number of expressions on the list */ + int32_t nAlloc; /* Number of entries allocated below */ + tSQLExprList **a; /* one entry for each row */ +} tSQLExprListList; + + +/** + * + * @param yyp The parser + * @param yymajor The major token code number + * @param yyminor The value for the token + */ +void Parse(void *yyp, int yymajor, ParseTOKENTYPE yyminor, SSqlInfo *); + +/** + * + * @param p The parser to be deleted + * @param freeProc Function used to reclaim memory + */ +void ParseFree(void *p, void (*freeProc)(void *)); + +tVariantList *tVariantListAppend(tVariantList *pList, tVariant *pVar, uint8_t sortOrder); + +tVariantList *tVariantListInsert(tVariantList *pList, tVariant *pVar, uint8_t sortOrder, int32_t index); + +tVariantList *tVariantListAppendToken(tVariantList *pList, SSQLToken *pAliasToken, uint8_t sortOrder); +void tVariantListDestroy(tVariantList *pList); + +tFieldList *tFieldListAppend(tFieldList *pList, TAOS_FIELD *pField); + +void tFieldListDestroy(tFieldList *pList); + +tSQLExpr *tSQLExprCreate(tSQLExpr *pLeft, tSQLExpr *pRight, int32_t optType); + +void tSQLExprDestroy(tSQLExpr *); + +tSQLExprList *tSQLExprListAppend(tSQLExprList *pList, tSQLExpr *pNode, SSQLToken *pToken); + +void tSQLExprListDestroy(tSQLExprList *pList); + +SQuerySQL *tSetQuerySQLElems(SSQLToken *pSelectToken, tSQLExprList *pSelection, tVariantList *pFrom, tSQLExpr *pWhere, + tVariantList *pGroupby, tVariantList *pSortOrder, SSQLToken *pInterval, + SSQLToken *pSliding, tVariantList *pFill, SLimitVal *pLimit, SLimitVal *pGLimit); + +SCreateTableSQL *tSetCreateSQLElems(tFieldList *pCols, tFieldList *pTags, SSQLToken *pMetricName, + tVariantList *pTagVals, SQuerySQL *pSelect, int32_t type); + +void tSQLExprNodeDestroy(tSQLExpr *pExpr); +tSQLExpr *tSQLExprNodeClone(tSQLExpr *pExpr); + +SAlterTableSQL *tAlterTableSQLElems(SSQLToken *pMeterName, tFieldList *pCols, tVariantList *pVals, int32_t type); + +tSQLExprListList *tSQLListListAppend(tSQLExprListList *pList, tSQLExprList *pExprList); + +void destroyAllSelectClause(SSubclauseInfo *pSql); +void doDestroyQuerySql(SQuerySQL *pSql); + +SSqlInfo * setSQLInfo(SSqlInfo *pInfo, void *pSqlExprInfo, SSQLToken *pMeterName, int32_t type); +SSubclauseInfo *setSubclause(SSubclauseInfo *pClause, void *pSqlExprInfo); + +SSubclauseInfo *appendSelectClause(SSubclauseInfo *pInfo, void *pSubclause); + +void setCreatedMeterName(SSqlInfo *pInfo, SSQLToken *pMeterName, SSQLToken *pIfNotExists); + +void SQLInfoDestroy(SSqlInfo *pInfo); + +void setDCLSQLElems(SSqlInfo *pInfo, int32_t type, int32_t nParams, ...); +void setDropDBTableInfo(SSqlInfo *pInfo, int32_t type, SSQLToken* pToken, SSQLToken* existsCheck); +void setShowOptions(SSqlInfo *pInfo, int32_t type, SSQLToken* prefix, SSQLToken* pPatterns); + +tDCLSQL *tTokenListAppend(tDCLSQL *pTokenList, SSQLToken *pToken); + +void setCreateDBSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *pToken, SCreateDBInfo *pDB, SSQLToken *pIgExists); + +void setCreateAcctSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *pName, SSQLToken *pPwd, SCreateAcctSQL *pAcctInfo); +void setCreateUserSQL(SSqlInfo *pInfo, SSQLToken *pName, SSQLToken *pPasswd); +void setKillSQL(SSqlInfo *pInfo, int32_t type, SSQLToken *ip); +void setAlterUserSQL(SSqlInfo *pInfo, int16_t type, SSQLToken *pName, SSQLToken* pPwd, SSQLToken *pPrivilege); + +void setDefaultCreateDbOption(SCreateDBInfo *pDBInfo); + +// prefix show db.tables; +void setDBName(SSQLToken *pCpxName, SSQLToken *pDB); + +tSQLExpr *tSQLExprIdValueCreate(SSQLToken *pToken, int32_t optType); + +tSQLExpr *tSQLExprCreateFunction(tSQLExprList *pList, SSQLToken *pFuncToken, SSQLToken *endToken, int32_t optType); + +void tSQLSetColumnInfo(TAOS_FIELD *pField, SSQLToken *pName, TAOS_FIELD *pType); + +void tSQLSetColumnType(TAOS_FIELD *pField, SSQLToken *pToken); + + +void *ParseAlloc(void *(*mallocProc)(size_t)); + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_QASTDEF_H diff --git a/src/query/inc/qsqltype.h b/src/query/inc/qsqltype.h new file mode 100644 index 0000000000000000000000000000000000000000..5d85ab4b80ebad4534ea6fa09b23d3ed97df04c0 --- /dev/null +++ b/src/query/inc/qsqltype.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef TDENGINE_QSQLCMD_H +#define TDENGINE_QSQLCMD_H + +#ifdef __cplusplus +extern "C" { +#endif + +enum _sql_type { + TSDB_SQL_SELECT = 1, + TSDB_SQL_FETCH, + TSDB_SQL_INSERT, + + TSDB_SQL_MGMT, // the SQL below is for mgmt node + TSDB_SQL_CREATE_DB, + TSDB_SQL_CREATE_TABLE, + TSDB_SQL_DROP_DB, + TSDB_SQL_DROP_TABLE, + TSDB_SQL_CREATE_ACCT, + TSDB_SQL_CREATE_USER, // 10 + TSDB_SQL_DROP_ACCT, + TSDB_SQL_DROP_USER, + TSDB_SQL_ALTER_USER, + TSDB_SQL_ALTER_ACCT, + TSDB_SQL_ALTER_TABLE, + TSDB_SQL_ALTER_DB, + TSDB_SQL_CREATE_MNODE, + TSDB_SQL_DROP_MNODE, + TSDB_SQL_CREATE_DNODE, + TSDB_SQL_DROP_DNODE, // 20 + TSDB_SQL_CFG_DNODE, + TSDB_SQL_CFG_MNODE, + TSDB_SQL_SHOW, + TSDB_SQL_RETRIEVE, + TSDB_SQL_KILL_QUERY, + TSDB_SQL_KILL_STREAM, + TSDB_SQL_KILL_CONNECTION, + + TSDB_SQL_READ, // SQL below is for read operation + TSDB_SQL_CONNECT, + TSDB_SQL_USE_DB, // 30 + TSDB_SQL_META, + TSDB_SQL_METRIC, + TSDB_SQL_MULTI_META, + TSDB_SQL_HB, + + TSDB_SQL_LOCAL, // SQL below for client local + TSDB_SQL_DESCRIBE_TABLE, + TSDB_SQL_RETRIEVE_METRIC, + TSDB_SQL_METRIC_JOIN_RETRIEVE, + TSDB_SQL_RETRIEVE_TAGS, + + /* + * build empty result instead of accessing dnode to fetch result + * reset the client cache + */ + TSDB_SQL_RETRIEVE_EMPTY_RESULT, // 40 + + TSDB_SQL_RESET_CACHE, + TSDB_SQL_SERV_STATUS, + TSDB_SQL_CURRENT_DB, + TSDB_SQL_SERV_VERSION, + TSDB_SQL_CLI_VERSION, + TSDB_SQL_CURRENT_USER, + TSDB_SQL_CFG_LOCAL, + + TSDB_SQL_MAX // 48 +}; + + +// create table operation type +enum TSQL_TYPE { + TSQL_CREATE_TABLE = 0x1, + TSQL_CREATE_STABLE = 0x2, + TSQL_CREATE_TABLE_FROM_STABLE = 0x3, + TSQL_CREATE_STREAM = 0x4, +}; + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_QSQLCMD_H diff --git a/src/inc/sql.y b/src/query/inc/sql.y similarity index 100% rename from src/inc/sql.y rename to src/query/inc/sql.y diff --git a/src/util/inc/tast.h b/src/query/inc/tast.h similarity index 98% rename from src/util/inc/tast.h rename to src/query/inc/tast.h index aa5cfa2d705f3eee1e5afff0f3ffd6d888b1747e..3cb483a91b134fe3301533d0360174d250fba578 100644 --- a/src/util/inc/tast.h +++ b/src/query/inc/tast.h @@ -20,13 +20,11 @@ extern "C" { #endif -#include -#include -#include +#include "os.h" #include "taosmsg.h" #include "ttypes.h" -#include "os.h" +#include "tvariant.h" struct tSQLBinaryExpr; struct SSchema; diff --git a/src/util/inc/tcache.h b/src/query/inc/tcache.h similarity index 100% rename from src/util/inc/tcache.h rename to src/query/inc/tcache.h diff --git a/src/util/inc/textbuffer.h b/src/query/inc/textbuffer.h similarity index 100% rename from src/util/inc/textbuffer.h rename to src/query/inc/textbuffer.h diff --git a/src/util/inc/thistogram.h b/src/query/inc/thistogram.h similarity index 100% rename from src/util/inc/thistogram.h rename to src/query/inc/thistogram.h diff --git a/src/util/inc/tinterpolation.h b/src/query/inc/tinterpolation.h similarity index 100% rename from src/util/inc/tinterpolation.h rename to src/query/inc/tinterpolation.h diff --git a/src/util/inc/tlosertree.h b/src/query/inc/tlosertree.h similarity index 100% rename from src/util/inc/tlosertree.h rename to src/query/inc/tlosertree.h diff --git a/src/inc/tresultBuf.h b/src/query/inc/tresultBuf.h similarity index 78% rename from src/inc/tresultBuf.h rename to src/query/inc/tresultBuf.h index b99c44e73fcbd834152640b80f8a59728c7cfd8f..8f30ff7c61555e993838989aecb32a81d1c414bf 100644 --- a/src/inc/tresultBuf.h +++ b/src/query/inc/tresultBuf.h @@ -1,3 +1,18 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + #ifndef TDENGINE_VNODEQUERYUTIL_H #define TDENGINE_VNODEQUERYUTIL_H diff --git a/src/client/inc/tscSyntaxtreefunction.h b/src/query/inc/tscSyntaxtreefunction.h similarity index 100% rename from src/client/inc/tscSyntaxtreefunction.h rename to src/query/inc/tscSyntaxtreefunction.h diff --git a/src/util/inc/tsqlfunction.h b/src/query/inc/tsqlfunction.h similarity index 99% rename from src/util/inc/tsqlfunction.h rename to src/query/inc/tsqlfunction.h index b42358967213ae182574cd6a4c806fc090431af4..dc5f284efab09c0b54e2366e7b11ed055fa14cc4 100644 --- a/src/util/inc/tsqlfunction.h +++ b/src/query/inc/tsqlfunction.h @@ -25,6 +25,7 @@ extern "C" { #include "trpc.h" #include "ttypes.h" +#include "tvariant.h" #define TSDB_FUNC_INVALID_ID -1 #define TSDB_FUNC_COUNT 0 diff --git a/src/query/inc/tvariant.h b/src/query/inc/tvariant.h new file mode 100644 index 0000000000000000000000000000000000000000..f54a3a434827aea2e4b0685bb0b4df345d263dae --- /dev/null +++ b/src/query/inc/tvariant.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#ifndef TDENGINE_TVARIANT_H +#define TDENGINE_TVARIANT_H + +#ifdef __cplusplus +extern "C" { +#endif + +// variant, each number/string/field_id has a corresponding struct during parsing sql +typedef struct tVariant { + uint32_t nType; + int32_t nLen; // only used for string, for number, it is useless + union { + int64_t i64Key; + double dKey; + char * pz; + wchar_t *wpz; + }; +} tVariant; + +void tVariantCreate(tVariant *pVar, SSQLToken *token); + +void tVariantCreateFromString(tVariant *pVar, char *pz, uint32_t len, uint32_t type); + +void tVariantCreateFromBinary(tVariant *pVar, char *pz, uint32_t len, uint32_t type); + +void tVariantDestroy(tVariant *pV); + +void tVariantAssign(tVariant *pDst, const tVariant *pSrc); + +int32_t tVariantToString(tVariant *pVar, char *dst); + +int32_t tVariantDump(tVariant *pVariant, char *payload, char type); + +int32_t tVariantTypeSetType(tVariant *pVariant, char type); + +#ifdef __cplusplus +} +#endif + +#endif // TDENGINE_TVARIANT_H diff --git a/src/client/src/sql.c b/src/query/src/sql.c similarity index 99% rename from src/client/src/sql.c rename to src/query/src/sql.c index 54df3e36696359b429aa97ad5f06c6d93b8e67bf..f1dce997fef02772ad6b0effa8084e8c26e9ef4e 100644 --- a/src/client/src/sql.c +++ b/src/query/src/sql.c @@ -25,13 +25,18 @@ #include /************ Begin %include sections from the grammar ************************/ +#include +#include #include #include #include -#include -#include -#include "tscSQLParser.h" +#include "qsqlparser.h" +#include "tstoken.h" #include "tutil.h" +#include "tvariant.h" +#include "ttokendef.h" +#include "qsqltype.h" + /**************** End of %include directives **********************************/ /* These constants specify the various numeric values for terminal symbols ** in a format understandable to "makeheaders". This section is blank unless diff --git a/src/util/src/textbuffer.c b/src/query/src/textbuffer.c similarity index 100% rename from src/util/src/textbuffer.c rename to src/query/src/textbuffer.c diff --git a/src/util/src/thistogram.c b/src/query/src/thistogram.c similarity index 100% rename from src/util/src/thistogram.c rename to src/query/src/thistogram.c diff --git a/src/util/src/tinterpolation.c b/src/query/src/tinterpolation.c similarity index 100% rename from src/util/src/tinterpolation.c rename to src/query/src/tinterpolation.c diff --git a/src/util/src/tlosertree.c b/src/query/src/tlosertree.c similarity index 100% rename from src/util/src/tlosertree.c rename to src/query/src/tlosertree.c diff --git a/src/util/src/tpercentile.c b/src/query/src/tpercentile.c similarity index 100% rename from src/util/src/tpercentile.c rename to src/query/src/tpercentile.c diff --git a/src/util/src/tresultBuf.c b/src/query/src/tresultBuf.c similarity index 100% rename from src/util/src/tresultBuf.c rename to src/query/src/tresultBuf.c diff --git a/src/client/src/tscAst.c b/src/query/src/tscAst.c similarity index 68% rename from src/client/src/tscAst.c rename to src/query/src/tscAst.c index 17e7667445da7eb67dbd1153faf335012411aa56..70fda9bd9360a1d9715fac5b904a72078610762e 100644 --- a/src/client/src/tscAst.c +++ b/src/query/src/tscAst.c @@ -14,19 +14,19 @@ */ #include "os.h" +#include "sskiplist.h" +#include "taosdef.h" #include "taosmsg.h" #include "tast.h" #include "tlog.h" -#include "tscSQLParser.h" #include "tscSyntaxtreefunction.h" #include "tschemautil.h" -#include "taosdef.h" -#include "sskiplist.h" -#include "tsqldef.h" #include "tsqlfunction.h" #include "tstoken.h" +#include "ttokendef.h" #include "ttypes.h" #include "tutil.h" +#include "qsqlparser.h" /* * @@ -468,182 +468,182 @@ void tSQLBinaryExprDestroy(tSQLBinaryExpr **pExpr, void (*fp)(void *)) { *pExpr = NULL; } -static void setInitialValueForRangeQueryCondition(tSKipListQueryCond *q, int8_t type) { - q->lowerBndRelOptr = TSDB_RELATION_LARGE; - q->upperBndRelOptr = TSDB_RELATION_LESS; - - switch (type) { - case TSDB_DATA_TYPE_BOOL: - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_BIGINT: { - q->upperBnd.nType = TSDB_DATA_TYPE_BIGINT; - q->lowerBnd.nType = TSDB_DATA_TYPE_BIGINT; - - q->upperBnd.i64Key = INT64_MAX; - q->lowerBnd.i64Key = INT64_MIN; - break; - }; - case TSDB_DATA_TYPE_FLOAT: - case TSDB_DATA_TYPE_DOUBLE: { - q->upperBnd.nType = TSDB_DATA_TYPE_DOUBLE; - q->lowerBnd.nType = TSDB_DATA_TYPE_DOUBLE; - q->upperBnd.dKey = DBL_MAX; - q->lowerBnd.dKey = -DBL_MIN; - break; - }; - case TSDB_DATA_TYPE_NCHAR: - case TSDB_DATA_TYPE_BINARY: { - q->upperBnd.nType = type; - q->upperBnd.pz = NULL; - q->upperBnd.nLen = -1; - - q->lowerBnd.nType = type; - q->lowerBnd.pz = NULL; - q->lowerBnd.nLen = -1; - } - } -} - -static void tSQLDoFilterInitialResult(tSkipList *pSkipList, bool (*fp)(), tQueryInfo *queryColInfo, - tQueryResultset *result) { - // primary key filter, search according to skiplist - if (queryColInfo->colIdx == 0 && queryColInfo->optr != TSDB_RELATION_LIKE) { - tSKipListQueryCond q; - setInitialValueForRangeQueryCondition(&q, queryColInfo->q.nType); - - switch (queryColInfo->optr) { - case TSDB_RELATION_EQUAL: { - result->num = - tSkipListPointQuery(pSkipList, &queryColInfo->q, 1, INCLUDE_POINT_QUERY, (tSkipListNode ***)&result->pRes); - break; - } - case TSDB_RELATION_NOT_EQUAL: { - result->num = - tSkipListPointQuery(pSkipList, &queryColInfo->q, 1, EXCLUDE_POINT_QUERY, (tSkipListNode ***)&result->pRes); - break; - } - case TSDB_RELATION_LESS_EQUAL: { - tVariantAssign(&q.upperBnd, &queryColInfo->q); - q.upperBndRelOptr = queryColInfo->optr; - result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes); - break; - } - case TSDB_RELATION_LESS: { - tVariantAssign(&q.upperBnd, &queryColInfo->q); - result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes); - break; - } - case TSDB_RELATION_LARGE: { - tVariantAssign(&q.lowerBnd, &queryColInfo->q); - result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes); - break; - } - case TSDB_RELATION_LARGE_EQUAL: { - tVariantAssign(&q.lowerBnd, &queryColInfo->q); - q.lowerBndRelOptr = queryColInfo->optr; - result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes); - break; - } - default: - pTrace("skiplist:%p, unsupport query operator:%d", pSkipList, queryColInfo->optr); - } - - tSkipListDestroyKey(&q.upperBnd); - tSkipListDestroyKey(&q.lowerBnd); - } else { - /* - * Brutal force scan the whole skiplit to find the appropriate result, - * since the filter is not applied to indexed column. - */ - result->num = tSkipListIterateList(pSkipList, (tSkipListNode ***)&result->pRes, fp, queryColInfo); - } -} +//static void setInitialValueForRangeQueryCondition(tSKipListQueryCond *q, int8_t type) { +// q->lowerBndRelOptr = TSDB_RELATION_LARGE; +// q->upperBndRelOptr = TSDB_RELATION_LESS; +// +// switch (type) { +// case TSDB_DATA_TYPE_BOOL: +// case TSDB_DATA_TYPE_TINYINT: +// case TSDB_DATA_TYPE_SMALLINT: +// case TSDB_DATA_TYPE_INT: +// case TSDB_DATA_TYPE_BIGINT: { +// q->upperBnd.nType = TSDB_DATA_TYPE_BIGINT; +// q->lowerBnd.nType = TSDB_DATA_TYPE_BIGINT; +// +// q->upperBnd.i64Key = INT64_MAX; +// q->lowerBnd.i64Key = INT64_MIN; +// break; +// }; +// case TSDB_DATA_TYPE_FLOAT: +// case TSDB_DATA_TYPE_DOUBLE: { +// q->upperBnd.nType = TSDB_DATA_TYPE_DOUBLE; +// q->lowerBnd.nType = TSDB_DATA_TYPE_DOUBLE; +// q->upperBnd.dKey = DBL_MAX; +// q->lowerBnd.dKey = -DBL_MIN; +// break; +// }; +// case TSDB_DATA_TYPE_NCHAR: +// case TSDB_DATA_TYPE_BINARY: { +// q->upperBnd.nType = type; +// q->upperBnd.pz = NULL; +// q->upperBnd.nLen = -1; +// +// q->lowerBnd.nType = type; +// q->lowerBnd.pz = NULL; +// q->lowerBnd.nLen = -1; +// } +// } +//} + +//static void tSQLDoFilterInitialResult(tSkipList *pSkipList, bool (*fp)(), tQueryInfo *queryColInfo, +// tQueryResultset *result) { +// // primary key filter, search according to skiplist +// if (queryColInfo->colIdx == 0 && queryColInfo->optr != TSDB_RELATION_LIKE) { +// tSKipListQueryCond q; +// setInitialValueForRangeQueryCondition(&q, queryColInfo->q.nType); +// +// switch (queryColInfo->optr) { +// case TSDB_RELATION_EQUAL: { +// result->num = +// tSkipListPointQuery(pSkipList, &queryColInfo->q, 1, INCLUDE_POINT_QUERY, (tSkipListNode ***)&result->pRes); +// break; +// } +// case TSDB_RELATION_NOT_EQUAL: { +// result->num = +// tSkipListPointQuery(pSkipList, &queryColInfo->q, 1, EXCLUDE_POINT_QUERY, (tSkipListNode ***)&result->pRes); +// break; +// } +// case TSDB_RELATION_LESS_EQUAL: { +// tVariantAssign(&q.upperBnd, &queryColInfo->q); +// q.upperBndRelOptr = queryColInfo->optr; +// result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes); +// break; +// } +// case TSDB_RELATION_LESS: { +// tVariantAssign(&q.upperBnd, &queryColInfo->q); +// result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes); +// break; +// } +// case TSDB_RELATION_LARGE: { +// tVariantAssign(&q.lowerBnd, &queryColInfo->q); +// result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes); +// break; +// } +// case TSDB_RELATION_LARGE_EQUAL: { +// tVariantAssign(&q.lowerBnd, &queryColInfo->q); +// q.lowerBndRelOptr = queryColInfo->optr; +// result->num = tSkipListQuery(pSkipList, &q, (tSkipListNode ***)&result->pRes); +// break; +// } +// default: +// pTrace("skiplist:%p, unsupport query operator:%d", pSkipList, queryColInfo->optr); +// } +// +// tSkipListDestroyKey(&q.upperBnd); +// tSkipListDestroyKey(&q.lowerBnd); +// } else { +// /* +// * Brutal force scan the whole skiplit to find the appropriate result, +// * since the filter is not applied to indexed column. +// */ +// result->num = tSkipListIterateList(pSkipList, (tSkipListNode ***)&result->pRes, fp, queryColInfo); +// } +//} /* * qsort comparator * sort the result to ensure meters with the same gid is grouped together */ -static int32_t compareByAddr(const void *pLeft, const void *pRight) { - int64_t p1 = (int64_t) * ((tSkipListNode **)pLeft); - int64_t p2 = (int64_t) * ((tSkipListNode **)pRight); - - DEFAULT_COMP(p1, p2); -} +//static int32_t compareByAddr(const void *pLeft, const void *pRight) { +// int64_t p1 = (int64_t) * ((tSkipListNode **)pLeft); +// int64_t p2 = (int64_t) * ((tSkipListNode **)pRight); +// +// DEFAULT_COMP(p1, p2); +//} int32_t merge(tQueryResultset *pLeft, tQueryResultset *pRight, tQueryResultset *pFinalRes) { - assert(pFinalRes->pRes == 0); - - pFinalRes->pRes = calloc((size_t)(pLeft->num + pRight->num), POINTER_BYTES); - pFinalRes->num = 0; - - // sort according to address - tSkipListNode **pLeftNodes = (tSkipListNode **)pLeft->pRes; - qsort(pLeftNodes, pLeft->num, sizeof(pLeft->pRes[0]), compareByAddr); - - tSkipListNode **pRightNodes = (tSkipListNode **)pRight->pRes; - qsort(pRightNodes, pRight->num, sizeof(pRight->pRes[0]), compareByAddr); - - int32_t i = 0, j = 0; - - // merge two sorted arrays in O(n) time - while (i < pLeft->num && j < pRight->num) { - int64_t ret = (int64_t)pLeftNodes[i] - (int64_t)pRightNodes[j]; - - if (ret < 0) { - pFinalRes->pRes[pFinalRes->num++] = pLeftNodes[i++]; - } else if (ret > 0) { - pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++]; - } else { // pNode->key > pkey[i] - pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++]; - i++; - } - } - - while (i < pLeft->num) { - pFinalRes->pRes[pFinalRes->num++] = pLeftNodes[i++]; - } - - while (j < pRight->num) { - pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++]; - } - - return pFinalRes->num; +// assert(pFinalRes->pRes == 0); +// +// pFinalRes->pRes = calloc((size_t)(pLeft->num + pRight->num), POINTER_BYTES); +// pFinalRes->num = 0; +// +// // sort according to address +// tSkipListNode **pLeftNodes = (tSkipListNode **)pLeft->pRes; +// qsort(pLeftNodes, pLeft->num, sizeof(pLeft->pRes[0]), compareByAddr); +// +// tSkipListNode **pRightNodes = (tSkipListNode **)pRight->pRes; +// qsort(pRightNodes, pRight->num, sizeof(pRight->pRes[0]), compareByAddr); +// +// int32_t i = 0, j = 0; +// +// // merge two sorted arrays in O(n) time +// while (i < pLeft->num && j < pRight->num) { +// int64_t ret = (int64_t)pLeftNodes[i] - (int64_t)pRightNodes[j]; +// +// if (ret < 0) { +// pFinalRes->pRes[pFinalRes->num++] = pLeftNodes[i++]; +// } else if (ret > 0) { +// pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++]; +// } else { // pNode->key > pkey[i] +// pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++]; +// i++; +// } +// } +// +// while (i < pLeft->num) { +// pFinalRes->pRes[pFinalRes->num++] = pLeftNodes[i++]; +// } +// +// while (j < pRight->num) { +// pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j++]; +// } +// +// return pFinalRes->num; } int32_t intersect(tQueryResultset *pLeft, tQueryResultset *pRight, tQueryResultset *pFinalRes) { - int64_t num = MIN(pLeft->num, pRight->num); - - assert(pFinalRes->pRes == 0); - - pFinalRes->pRes = calloc(num, POINTER_BYTES); - pFinalRes->num = 0; - - // sort according to address - tSkipListNode **pLeftNodes = (tSkipListNode **)pLeft->pRes; - qsort(pLeftNodes, pLeft->num, sizeof(pLeft->pRes[0]), compareByAddr); - - tSkipListNode **pRightNodes = (tSkipListNode **)pRight->pRes; - qsort(pRightNodes, pRight->num, sizeof(pRight->pRes[0]), compareByAddr); - - int32_t i = 0, j = 0; - // merge two sorted arrays in O(n) time - while (i < pLeft->num && j < pRight->num) { - int64_t ret = (int64_t)pLeftNodes[i] - (int64_t)pRightNodes[j]; - - if (ret < 0) { - i++; - } else if (ret > 0) { - j++; - } else { // pNode->key > pkey[i] - pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j]; - i++; - j++; - } - } - - return pFinalRes->num; +// int64_t num = MIN(pLeft->num, pRight->num); +// +// assert(pFinalRes->pRes == 0); +// +// pFinalRes->pRes = calloc(num, POINTER_BYTES); +// pFinalRes->num = 0; +// +// // sort according to address +// tSkipListNode **pLeftNodes = (tSkipListNode **)pLeft->pRes; +// qsort(pLeftNodes, pLeft->num, sizeof(pLeft->pRes[0]), compareByAddr); +// +// tSkipListNode **pRightNodes = (tSkipListNode **)pRight->pRes; +// qsort(pRightNodes, pRight->num, sizeof(pRight->pRes[0]), compareByAddr); +// +// int32_t i = 0, j = 0; +// // merge two sorted arrays in O(n) time +// while (i < pLeft->num && j < pRight->num) { +// int64_t ret = (int64_t)pLeftNodes[i] - (int64_t)pRightNodes[j]; +// +// if (ret < 0) { +// i++; +// } else if (ret > 0) { +// j++; +// } else { // pNode->key > pkey[i] +// pFinalRes->pRes[pFinalRes->num++] = pRightNodes[j]; +// i++; +// j++; +// } +// } +// +// return pFinalRes->num; } /* @@ -719,113 +719,113 @@ static void tSQLBinaryTraverseOnResult(tSQLBinaryExpr *pExpr, tQueryResultset *p pResult->num = n; } -static void tSQLBinaryTraverseOnSkipList(tSQLBinaryExpr *pExpr, tQueryResultset *pResult, tSkipList *pSkipList, - SBinaryFilterSupp *param) { - int32_t n = 0; - SSkipListIterator iter = {0}; - - int32_t ret = tSkipListIteratorReset(pSkipList, &iter); - assert(ret == 0); - - pResult->pRes = calloc(pSkipList->nSize, POINTER_BYTES); - - while (tSkipListIteratorNext(&iter)) { - tSkipListNode *pNode = tSkipListIteratorGet(&iter); - if (filterItem(pExpr, pNode, param)) { - pResult->pRes[n++] = pNode; - } - } - - pResult->num = n; -} +//static void tSQLBinaryTraverseOnSkipList(tSQLBinaryExpr *pExpr, tQueryResultset *pResult, tSkipList *pSkipList, +// SBinaryFilterSupp *param) { +// int32_t n = 0; +// SSkipListIterator iter = {0}; +// +// int32_t ret = tSkipListIteratorReset(pSkipList, &iter); +// assert(ret == 0); +// +// pResult->pRes = calloc(pSkipList->nSize, POINTER_BYTES); +// +// while (tSkipListIteratorNext(&iter)) { +// tSkipListNode *pNode = tSkipListIteratorGet(&iter); +// if (filterItem(pExpr, pNode, param)) { +// pResult->pRes[n++] = pNode; +// } +// } +// +// pResult->num = n; +//} // post-root order traverse syntax tree -void tSQLBinaryExprTraverse(tSQLBinaryExpr *pExpr, tSkipList *pSkipList, tQueryResultset *result, - SBinaryFilterSupp *param) { - if (pExpr == NULL) { - return; - } - - tSQLSyntaxNode *pLeft = pExpr->pLeft; - tSQLSyntaxNode *pRight = pExpr->pRight; - - // recursive traverse left child branch - if (pLeft->nodeType == TSQL_NODE_EXPR || pRight->nodeType == TSQL_NODE_EXPR) { - uint8_t weight = pLeft->pExpr->filterOnPrimaryKey + pRight->pExpr->filterOnPrimaryKey; - - if (weight == 0 && result->num > 0 && pSkipList == NULL) { - /** - * Perform the filter operation based on the initial filter result, which is obtained from filtering from index. - * Since no index presented, the filter operation is done by scan all elements in the result set. - * - * if the query is a high selectivity filter, only small portion of meters are retrieved. - */ - tSQLBinaryTraverseOnResult(pExpr, result, param); - } else if (weight == 0) { - /** - * apply the hierarchical expression to every node in skiplist for find the qualified nodes - */ - assert(result->num == 0); - tSQLBinaryTraverseOnSkipList(pExpr, result, pSkipList, param); - } else if (weight == 2 || (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_OR)) { - tQueryResultset rLeft = {0}; - tQueryResultset rRight = {0}; - - tSQLBinaryExprTraverse(pLeft->pExpr, pSkipList, &rLeft, param); - tSQLBinaryExprTraverse(pRight->pExpr, pSkipList, &rRight, param); - - if (pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) { // CROSS - intersect(&rLeft, &rRight, result); - } else if (pExpr->nSQLBinaryOptr == TSDB_RELATION_OR) { // or - merge(&rLeft, &rRight, result); - } else { - assert(false); - } - - free(rLeft.pRes); - free(rRight.pRes); - } else { - /* - * (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) is handled here - * - * first, we filter results based on the skiplist index, which is the initial filter stage, - * then, we conduct the secondary filter operation based on the result from the initial filter stage. - */ - assert(pExpr->nSQLBinaryOptr == TSDB_RELATION_AND); - - tSQLBinaryExpr *pFirst = NULL; - tSQLBinaryExpr *pSecond = NULL; - if (pLeft->pExpr->filterOnPrimaryKey == 1) { - pFirst = pLeft->pExpr; - pSecond = pRight->pExpr; - } else { - pFirst = pRight->pExpr; - pSecond = pLeft->pExpr; - } - - assert(pFirst != pSecond && pFirst != NULL && pSecond != NULL); - - // we filter the result based on the skiplist index in the first place - tSQLBinaryExprTraverse(pFirst, pSkipList, result, param); - - /* - * recursively perform the filter operation based on the initial results, - * So, we do not set the skiplist index as a parameter - */ - tSQLBinaryExprTraverse(pSecond, NULL, result, param); - } - } else { // column project - assert(pLeft->nodeType == TSQL_NODE_COL && pRight->nodeType == TSQL_NODE_VALUE); - - param->setupInfoFn(pExpr, param->pExtInfo); - if (pSkipList == NULL) { - tSQLListTraverseOnResult(pExpr, param->fp, result); - } else { - assert(result->num == 0); - tSQLDoFilterInitialResult(pSkipList, param->fp, pExpr->info, result); - } - } -} +//void tSQLBinaryExprTraverse(tSQLBinaryExpr *pExpr, tSkipList *pSkipList, tQueryResultset *result, +// SBinaryFilterSupp *param) { +// if (pExpr == NULL) { +// return; +// } +// +// tSQLSyntaxNode *pLeft = pExpr->pLeft; +// tSQLSyntaxNode *pRight = pExpr->pRight; +// +// // recursive traverse left child branch +// if (pLeft->nodeType == TSQL_NODE_EXPR || pRight->nodeType == TSQL_NODE_EXPR) { +// uint8_t weight = pLeft->pExpr->filterOnPrimaryKey + pRight->pExpr->filterOnPrimaryKey; +// +// if (weight == 0 && result->num > 0 && pSkipList == NULL) { +// /** +// * Perform the filter operation based on the initial filter result, which is obtained from filtering from index. +// * Since no index presented, the filter operation is done by scan all elements in the result set. +// * +// * if the query is a high selectivity filter, only small portion of meters are retrieved. +// */ +// tSQLBinaryTraverseOnResult(pExpr, result, param); +// } else if (weight == 0) { +// /** +// * apply the hierarchical expression to every node in skiplist for find the qualified nodes +// */ +// assert(result->num == 0); +// tSQLBinaryTraverseOnSkipList(pExpr, result, pSkipList, param); +// } else if (weight == 2 || (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_OR)) { +// tQueryResultset rLeft = {0}; +// tQueryResultset rRight = {0}; +// +// tSQLBinaryExprTraverse(pLeft->pExpr, pSkipList, &rLeft, param); +// tSQLBinaryExprTraverse(pRight->pExpr, pSkipList, &rRight, param); +// +// if (pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) { // CROSS +// intersect(&rLeft, &rRight, result); +// } else if (pExpr->nSQLBinaryOptr == TSDB_RELATION_OR) { // or +// merge(&rLeft, &rRight, result); +// } else { +// assert(false); +// } +// +// free(rLeft.pRes); +// free(rRight.pRes); +// } else { +// /* +// * (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) is handled here +// * +// * first, we filter results based on the skiplist index, which is the initial filter stage, +// * then, we conduct the secondary filter operation based on the result from the initial filter stage. +// */ +// assert(pExpr->nSQLBinaryOptr == TSDB_RELATION_AND); +// +// tSQLBinaryExpr *pFirst = NULL; +// tSQLBinaryExpr *pSecond = NULL; +// if (pLeft->pExpr->filterOnPrimaryKey == 1) { +// pFirst = pLeft->pExpr; +// pSecond = pRight->pExpr; +// } else { +// pFirst = pRight->pExpr; +// pSecond = pLeft->pExpr; +// } +// +// assert(pFirst != pSecond && pFirst != NULL && pSecond != NULL); +// +// // we filter the result based on the skiplist index in the first place +// tSQLBinaryExprTraverse(pFirst, pSkipList, result, param); +// +// /* +// * recursively perform the filter operation based on the initial results, +// * So, we do not set the skiplist index as a parameter +// */ +// tSQLBinaryExprTraverse(pSecond, NULL, result, param); +// } +// } else { // column project +// assert(pLeft->nodeType == TSQL_NODE_COL && pRight->nodeType == TSQL_NODE_VALUE); +// +// param->setupInfoFn(pExpr, param->pExtInfo); +// if (pSkipList == NULL) { +// tSQLListTraverseOnResult(pExpr, param->fp, result); +// } else { +// assert(result->num == 0); +//// tSQLDoFilterInitialResult(pSkipList, param->fp, pExpr->info, result); +// } +// } +//} void tSQLBinaryExprCalcTraverse(tSQLBinaryExpr *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, char *(*getSourceDataBlock)(void *, char *, int32_t)) { diff --git a/src/client/src/tscSQLParserImpl.c b/src/query/src/tscSQLParserImpl.c similarity index 99% rename from src/client/src/tscSQLParserImpl.c rename to src/query/src/tscSQLParserImpl.c index 17e1c6f45790acc36c35111aec75e00be227044f..0a76b867f29780a7af3f381237c28ced03d9354d 100644 --- a/src/client/src/tscSQLParserImpl.c +++ b/src/query/src/tscSQLParserImpl.c @@ -13,13 +13,16 @@ * along with this program. If not, see . */ +#include #include "os.h" +#include "qsqlparser.h" #include "taosmsg.h" #include "tglobalcfg.h" #include "tlog.h" -#include "tscSQLParser.h" #include "tstoken.h" #include "ttime.h" +#include "ttokendef.h" +#include "ttypes.h" #include "tutil.h" int32_t tSQLParse(SSqlInfo *pSQLInfo, const char *pStr) { diff --git a/src/client/src/tscSyntaxtreefunction.c b/src/query/src/tscSyntaxtreefunction.c similarity index 99% rename from src/client/src/tscSyntaxtreefunction.c rename to src/query/src/tscSyntaxtreefunction.c index 1d82b0f239572676c204025fe535704c192e4da6..3fe43d9c1ef35e9f073c67b72047ef932d256c11 100644 --- a/src/client/src/tscSyntaxtreefunction.c +++ b/src/query/src/tscSyntaxtreefunction.c @@ -16,7 +16,6 @@ #include "os.h" #include "tscSyntaxtreefunction.h" -#include "tscSQLParser.h" #include "ttypes.h" #include "tutil.h" diff --git a/src/util/src/ttokenizer.c b/src/query/src/ttokenizer.c similarity index 99% rename from src/util/src/ttokenizer.c rename to src/query/src/ttokenizer.c index 7cbb4552b410536176f5e69d9ee9336af197d94f..c53debcb455d05cf8852769e4cac5f0e7be30ebb 100644 --- a/src/util/src/ttokenizer.c +++ b/src/query/src/ttokenizer.c @@ -13,14 +13,14 @@ * along with this program. If not, see . */ -#include "os.h" +#include "hash.h" #include "hashutil.h" +#include "os.h" #include "shash.h" -#include "tutil.h" -#include "tsqldef.h" #include "tstoken.h" +#include "ttokendef.h" #include "ttypes.h" -#include "hash.h" +#include "tutil.h" // All the keywords of the SQL language are stored in a hash table typedef struct SKeyword { diff --git a/src/query/src/tvariant.c b/src/query/src/tvariant.c new file mode 100644 index 0000000000000000000000000000000000000000..8c8887ca2ec7da2c956a2ec883a147d61bf4db71 --- /dev/null +++ b/src/query/src/tvariant.c @@ -0,0 +1,851 @@ +/* + * Copyright (c) 2019 TAOS Data, Inc. + * + * This program is free software: you can use, redistribute, and/or modify + * it under the terms of the GNU Affero General Public License, version 3 + * or later ("AGPL"), as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#include "hash.h" +#include "hashutil.h" +#include "os.h" +#include "shash.h" +#include "tstoken.h" +#include "ttokendef.h" +#include "ttypes.h" +#include "tutil.h" +#include "tvariant.h" +#include "ttypes.h" +#include "taos.h" + +// todo support scientific expression number and oct number +void tVariantCreate(tVariant *pVar, SSQLToken *token) { tVariantCreateFromString(pVar, token->z, token->n, token->type); } + +void tVariantCreateFromString(tVariant *pVar, char *pz, uint32_t len, uint32_t type) { + memset(pVar, 0, sizeof(tVariant)); + + switch (type) { + case TSDB_DATA_TYPE_BOOL: { + int32_t k = strncasecmp(pz, "true", 4); + if (k == 0) { + pVar->i64Key = TSDB_TRUE; + } else { + assert(strncasecmp(pz, "false", 5) == 0); + pVar->i64Key = TSDB_FALSE; + } + break; + } + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_INT: + pVar->i64Key = strtoll(pz, NULL, 10); + break; + case TSDB_DATA_TYPE_DOUBLE: + case TSDB_DATA_TYPE_FLOAT: + pVar->dKey = strtod(pz, NULL); + break; + case TSDB_DATA_TYPE_BINARY: { + pVar->pz = strndup(pz, len); + pVar->nLen = strdequote(pVar->pz); + break; + } + + default: { // nType == 0 means the null value + type = TSDB_DATA_TYPE_NULL; + } + } + + pVar->nType = type; +} + +/** + * create tVariant from binary string, not ascii data + * @param pVar + * @param pz + * @param len + * @param type + */ +void tVariantCreateFromBinary(tVariant *pVar, char *pz, uint32_t len, uint32_t type) { + switch (type) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: { + pVar->i64Key = GET_INT8_VAL(pz); + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + pVar->i64Key = GET_INT16_VAL(pz); + break; + } + case TSDB_DATA_TYPE_INT: { + pVar->i64Key = GET_INT32_VAL(pz); + break; + } + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_TIMESTAMP: { + pVar->i64Key = GET_INT64_VAL(pz); + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + pVar->dKey = GET_DOUBLE_VAL(pz); + break; + } + case TSDB_DATA_TYPE_FLOAT: { + pVar->dKey = GET_FLOAT_VAL(pz); + break; + } + case TSDB_DATA_TYPE_NCHAR: { // here we get the nchar length from raw binary bits length + pVar->nLen = len / TSDB_NCHAR_SIZE; + pVar->wpz = calloc(1, (pVar->nLen + 1) * TSDB_NCHAR_SIZE); + + wcsncpy(pVar->wpz, (wchar_t *)pz, pVar->nLen); + pVar->wpz[pVar->nLen] = 0; + + break; + } + case TSDB_DATA_TYPE_BINARY: { + pVar->pz = strndup(pz, len); + pVar->nLen = strdequote(pVar->pz); + + break; + } + + default: + pVar->i64Key = GET_INT32_VAL(pVar); + } + + pVar->nType = type; +} + +void tVariantDestroy(tVariant *pVar) { + if (pVar == NULL) return; + + if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR) { + tfree(pVar->pz); + pVar->nLen = 0; + } +} + +void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { + if (pSrc == NULL || pDst == NULL) return; + + *pDst = *pSrc; + + if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR) { + int32_t len = pSrc->nLen + 1; + if (pSrc->nType == TSDB_DATA_TYPE_NCHAR) { + len = len * TSDB_NCHAR_SIZE; + } + + pDst->pz = calloc(1, len); + memcpy(pDst->pz, pSrc->pz, len); + } +} + +int32_t tVariantToString(tVariant *pVar, char *dst) { + if (pVar == NULL || dst == NULL) return 0; + + switch (pVar->nType) { + case TSDB_DATA_TYPE_BINARY: { + int32_t len = sprintf(dst, "\'%s\'", pVar->pz); + assert(len <= pVar->nLen + sizeof("\'") * 2); // two more chars + return len; + } + + case TSDB_DATA_TYPE_NCHAR: { + dst[0] = '\''; + taosUcs4ToMbs(pVar->wpz, (wcslen(pVar->wpz) + 1) * TSDB_NCHAR_SIZE, dst + 1); + int32_t len = strlen(dst); + dst[len] = '\''; + dst[len + 1] = 0; + return len + 1; + } + + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_SMALLINT: + case TSDB_DATA_TYPE_INT: + return sprintf(dst, "%d", (int32_t)pVar->i64Key); + + case TSDB_DATA_TYPE_BIGINT: + return sprintf(dst, "%" PRId64, pVar->i64Key); + + case TSDB_DATA_TYPE_FLOAT: + case TSDB_DATA_TYPE_DOUBLE: + return sprintf(dst, "%.9lf", pVar->dKey); + + default: + return 0; + } +} + +#if 0 +static int32_t doConvertToInteger(tVariant *pVariant, char *pDest, int32_t type, bool releaseVariantPtr) { + if (pVariant->nType == TSDB_DATA_TYPE_NULL) { + setNull(pDest, type, tDataTypeDesc[type].nSize); + return 0; + } + + if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { + *((int64_t *)pDest) = pVariant->i64Key; + } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { + if ((pVariant->dKey < INT64_MIN) || (pVariant->dKey > INT64_MAX)) { + return -1; + } + + *((int64_t *)pDest) = (int64_t)pVariant->dKey; + } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { + errno = 0; + char *endPtr = NULL; + + SSQLToken token = {0}; + token.n = tSQLGetToken(pVariant->pz, &token.type); + + if (token.type == TK_MINUS || token.type == TK_PLUS) { + token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); + } + + if (token.type == TK_FLOAT) { + double v = strtod(pVariant->pz, &endPtr); + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + + if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { + return -1; + } + + if ((v < INT64_MIN) || (v > INT64_MAX)) { + return -1; + } + + *((int64_t *)pDest) = (int64_t)v; + } else if (token.type == TK_INTEGER) { + int64_t val = strtoll(pVariant->pz, &endPtr, 10); + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + + if (errno == ERANGE) { + return -1; // data overflow + } + + *((int64_t *)pDest) = val; + } else if (token.type == TK_NULL) { + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + setNull(pDest, type, tDataTypeDesc[type].nSize); + } else { + return -1; + } + + } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { + errno = 0; + wchar_t *endPtr = NULL; + + SSQLToken token = {0}; + token.n = tSQLGetToken(pVariant->pz, &token.type); + + if (token.type == TK_MINUS || token.type == TK_PLUS) { + token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); + } + + if (token.type == TK_FLOAT) { + double v = wcstod(pVariant->wpz, &endPtr); + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + + if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { + return -1; + } + + if ((v < INT64_MIN) || (v > INT64_MAX)) { + return -1; + } + + *((int64_t *)pDest) = (int64_t)v; + } else if (token.type == TK_NULL) { + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + setNull(pDest, type, tDataTypeDesc[type].nSize); + } else { + int64_t val = wcstoll(pVariant->wpz, &endPtr, 10); + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + + if (errno == ERANGE) { + return -1; // data overflow + } + + *((int64_t *)pDest) = val; + } + } + + return 0; +} +#endif +static FORCE_INLINE int32_t convertToBoolImpl(char *pStr, int32_t len) { + if ((strncasecmp(pStr, "true", len) == 0) && (len == 4)) { + return TSDB_TRUE; + } else if ((strncasecmp(pStr, "false", len) == 0) && (len == 5)) { + return TSDB_FALSE; + } else if (strcasecmp(pStr, TSDB_DATA_NULL_STR_L) == 0) { + return TSDB_DATA_BOOL_NULL; + } else { + return -1; + } +} + +static FORCE_INLINE int32_t wcsconvertToBoolImpl(wchar_t *pstr, int32_t len) { + if ((wcsncasecmp(pstr, L"true", len) == 0) && (len == 4)) { + return TSDB_TRUE; + } else if (wcsncasecmp(pstr, L"false", len) == 0 && (len == 5)) { + return TSDB_FALSE; + } else { + return -1; + } +} + +static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) { + const int32_t INITIAL_ALLOC_SIZE = 20; + char * pBuf = NULL; + + if (*pDest == pVariant->pz) { + pBuf = calloc(1, INITIAL_ALLOC_SIZE); + } + + if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { + size_t newSize = pVariant->nLen * TSDB_NCHAR_SIZE; + if (pBuf != NULL) { + if (newSize > INITIAL_ALLOC_SIZE) { + pBuf = realloc(pBuf, newSize + 1); + } + + taosUcs4ToMbs(pVariant->wpz, newSize, pBuf); + free(pVariant->wpz); + + /* terminated string */ + pBuf[newSize] = 0; + } else { + taosUcs4ToMbs(pVariant->wpz, newSize, *pDest); + } + + } else { + if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { + sprintf(pBuf == NULL ? *pDest : pBuf, "%" PRId64, pVariant->i64Key); + } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { + sprintf(pBuf == NULL ? *pDest : pBuf, "%lf", pVariant->dKey); + } else if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { + sprintf(pBuf == NULL ? *pDest : pBuf, "%s", (pVariant->i64Key == TSDB_TRUE) ? "TRUE" : "FALSE"); + } else if (pVariant->nType == 0) { // null data + setNull(pBuf == NULL ? *pDest : pBuf, TSDB_DATA_TYPE_BINARY, 0); + } + } + + if (pBuf != NULL) { + *pDest = pBuf; + } + + *pDestSize = strlen(*pDest); + return 0; +} + +static int32_t toNchar(tVariant *pVariant, char **pDest, int32_t *pDestSize) { + char tmpBuf[40] = {0}; + + char * pDst = tmpBuf; + int32_t nLen = 0; + + if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { + nLen = sprintf(pDst, "%" PRId64, pVariant->i64Key); + } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { + nLen = sprintf(pDst, "%lf", pVariant->dKey); + } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { + pDst = pVariant->pz; + nLen = pVariant->nLen; + } else if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { + nLen = sprintf(pDst, "%s", (pVariant->i64Key == TSDB_TRUE) ? "TRUE" : "FALSE"); + } + + if (*pDest == pVariant->pz) { + wchar_t *pWStr = calloc(1, (nLen + 1) * TSDB_NCHAR_SIZE); + taosMbsToUcs4(pDst, nLen, (char *)pWStr, (nLen + 1) * TSDB_NCHAR_SIZE); + + // free the binary buffer in the first place + if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { + free(pVariant->wpz); + } + + pVariant->wpz = pWStr; + *pDestSize = wcslen(pVariant->wpz); + + // shrink the allocate memory, no need to check here. + char* tmp = realloc(pVariant->wpz, (*pDestSize + 1)*TSDB_NCHAR_SIZE); + assert(tmp != NULL); + + pVariant->wpz = (wchar_t *)tmp; + } else { + taosMbsToUcs4(pDst, nLen, *pDest, (nLen + 1) * TSDB_NCHAR_SIZE); + } + + return 0; +} + +static FORCE_INLINE int32_t convertToDouble(char *pStr, int32_t len, double *value) { + SSQLToken stoken = {.z = pStr, .n = len}; + + if (TK_ILLEGAL == isValidNumber(&stoken)) { + return -1; + } + + *value = strtod(pStr, NULL); + + return 0; +} + +static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result, int32_t type, int64_t lowBnd, + int64_t upperBnd, bool releaseVariantPtr) { + if (pVariant->nType == TSDB_DATA_TYPE_NULL) { + setNull((char *)result, type, tDataTypeDesc[type].nSize); + return 0; + } + + if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { + *result = pVariant->i64Key; + } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { + *result = (int64_t)pVariant->dKey; + } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { + errno = 0; + char *endPtr = NULL; + + SSQLToken token = {0}; + token.n = tSQLGetToken(pVariant->pz, &token.type); + + if (token.type == TK_MINUS || token.type == TK_PLUS) { + token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); + } + + if (token.type == TK_NULL) { + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + setNull((char *)result, type, tDataTypeDesc[type].nSize); + return 0; + } + + SSQLToken sToken = {.z = pVariant->pz, .n = pVariant->nLen}; + if (TK_ILLEGAL == isValidNumber(&sToken)) { + return -1; + } + + if (token.type == TK_FLOAT) { + double v = strtod(pVariant->pz, &endPtr); + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + + if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { + return -1; + } + + *result = (int64_t)v; + } else if (token.type == TK_INTEGER) { + int64_t val = strtoll(pVariant->pz, &endPtr, 10); + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + + if (errno == ERANGE) { + return -1; // data overflow + } + + *result = val; + } else { + return -1; + } + } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { + errno = 0; + wchar_t *endPtr = NULL; + + SSQLToken token = {0}; + token.n = tSQLGetToken(pVariant->pz, &token.type); + + if (token.type == TK_MINUS || token.type == TK_PLUS) { + token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); + } + + if (token.type == TK_FLOAT) { + double v = wcstod(pVariant->wpz, &endPtr); + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + + if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { + return -1; + } + + *result = (int64_t)v; + } else if (token.type == TK_NULL) { + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + setNull((char *)result, type, tDataTypeDesc[type].nSize); + return 0; + } else { + int64_t val = wcstoll(pVariant->wpz, &endPtr, 10); + if (releaseVariantPtr) { + free(pVariant->pz); + pVariant->nLen = 0; + } + + if (errno == ERANGE) { + return -1; // data overflow + } + + *result = val; + } + } + + if ((*result <= lowBnd) || (*result > upperBnd)) { + return -1; + } + + return 0; +} + +static int32_t convertToBool(tVariant *pVariant, int64_t *pDest) { + if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { + *pDest = pVariant->i64Key; // in order to be compatible to null of bool + } else if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { + *pDest = ((pVariant->i64Key != 0) ? TSDB_TRUE : TSDB_FALSE); + } else if (pVariant->nType == TSDB_DATA_TYPE_FLOAT || pVariant->nType == TSDB_DATA_TYPE_DOUBLE) { + *pDest = ((pVariant->dKey != 0) ? TSDB_TRUE : TSDB_FALSE); + } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { + int32_t ret = 0; + if ((ret = convertToBoolImpl(pVariant->pz, pVariant->nLen)) < 0) { + return ret; + } + + *pDest = ret; + } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { + int32_t ret = 0; + if ((ret = wcsconvertToBoolImpl(pVariant->wpz, pVariant->nLen)) < 0) { + return ret; + } + *pDest = ret; + } else if (pVariant->nType == TSDB_DATA_TYPE_NULL) { + *pDest = TSDB_DATA_BOOL_NULL; + } + + assert(*pDest == TSDB_TRUE || *pDest == TSDB_FALSE || *pDest == TSDB_DATA_BOOL_NULL); + return 0; +} + +/* + * transfer data from variant serve as the implicit data conversion: from input sql string pVariant->nType + * to column type defined in schema + * + * todo handle the return value + */ +int32_t tVariantDump(tVariant *pVariant, char *payload, char type) { + if (pVariant == NULL || (pVariant->nType != 0 && !isValidDataType(pVariant->nType, pVariant->nLen))) { + return -1; + } + + errno = 0; // reset global error code + + switch (type) { + case TSDB_DATA_TYPE_BOOL: { + int64_t dst = 0; + if (convertToBool(pVariant, &dst) < 0) { + return -1; + } + *(int8_t *)payload = (int8_t)dst; + break; + } + + case TSDB_DATA_TYPE_TINYINT: { + int64_t result = 0; + if (convertToInteger(pVariant, &result, type, INT8_MIN, INT8_MAX, false) < 0) { + return -1; + } + + *((int8_t *)payload) = (int8_t)result; + break; + } + + case TSDB_DATA_TYPE_SMALLINT: { + int64_t result = 0; + if (convertToInteger(pVariant, &result, type, INT16_MIN, INT16_MAX, false) < 0) { + return -1; + } + + *((int16_t *)payload) = (int16_t)result; + break; + } + + case TSDB_DATA_TYPE_INT: { + int64_t result = 0; + if (convertToInteger(pVariant, &result, type, INT32_MIN, INT32_MAX, false) < 0) { + return -1; + } + + *((int32_t *)payload) = (int32_t)result; + break; + } + + case TSDB_DATA_TYPE_BIGINT: { + int64_t result = 0; + if (convertToInteger(pVariant, &result, type, INT64_MIN, INT64_MAX, false) < 0) { + return -1; + } + + *((int64_t *)payload) = (int64_t)result; + break; + } + + case TSDB_DATA_TYPE_FLOAT: { + if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { + if (strncasecmp(TSDB_DATA_NULL_STR_L, pVariant->pz, pVariant->nLen) == 0 && + strlen(TSDB_DATA_NULL_STR_L) == pVariant->nLen) { + *((int32_t *)payload) = TSDB_DATA_FLOAT_NULL; + return 0; + } else { + double value; + int32_t ret; + ret = convertToDouble(pVariant->pz, pVariant->nLen, &value); + if ((errno == ERANGE && (float)value == -1) || (ret != 0)) { + return -1; + } + +#ifdef _TD_ARM_32_ + //memcpy(&payload, &value, sizeof(float)); + float fv = (float)value; + SET_FLOAT_VAL_ALIGN(payload, &fv); +#else + *((float *)payload) = (float)value; +#endif + } + } else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { +#ifdef _TD_ARM_32_ + //memcpy(&payload, &pVariant->i64Key, sizeof(float)); + float fv = (float)pVariant->i64Key; + SET_FLOAT_VAL_ALIGN(payload, &fv); +#else + *((float *)payload) = pVariant->i64Key; +#endif + } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { +#ifdef _TD_ARM_32_ + //memcpy(&payload, &pVariant->dKey, sizeof(float)); + float fv = (float)pVariant->dKey; + SET_FLOAT_VAL_ALIGN(payload, &fv); +#else + *((float *)payload) = (float)pVariant->dKey; +#endif + } else if (pVariant->nType == TSDB_DATA_TYPE_NULL) { + *((int32_t *)payload) = TSDB_DATA_FLOAT_NULL; + return 0; + } + +#ifdef _TD_ARM_32_ + float fv = GET_FLOAT_VAL(payload); + if (isinf(fv) || isnan(fv) || fv > FLT_MAX || fv < -FLT_MAX) { + return -1; + } +#else + if (isinf(*((float *)payload)) || isnan(*((float *)payload)) || *((float *)payload) > FLT_MAX || + *((float *)payload) < -FLT_MAX) { + return -1; + } +#endif + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { + if (strncasecmp(TSDB_DATA_NULL_STR_L, pVariant->pz, pVariant->nLen) == 0 && + strlen(TSDB_DATA_NULL_STR_L) == pVariant->nLen) { + *((int64_t *)payload) = TSDB_DATA_DOUBLE_NULL; + return 0; + } else { + double value = 0; + int32_t ret; + ret = convertToDouble(pVariant->pz, pVariant->nLen, &value); + if ((errno == ERANGE && value == -1) || (ret != 0)) { + return -1; + } + +#ifdef _TD_ARM_32_ + SET_DOUBLE_VAL_ALIGN(payload, &value); +#else + *((double *)payload) = value; +#endif + } + } else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { +#ifdef _TD_ARM_32_ + double dv = (double)(pVariant->i64Key); + SET_DOUBLE_VAL_ALIGN(payload, &dv); +#else + *((double *)payload) = pVariant->i64Key; +#endif + } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { +#ifdef _TD_ARM_32_ + double dv = (double)(pVariant->dKey); + SET_DOUBLE_VAL_ALIGN(payload, &dv); +#else + *((double *)payload) = pVariant->dKey; +#endif + } else if (pVariant->nType == TSDB_DATA_TYPE_NULL) { + *((int64_t *)payload) = TSDB_DATA_DOUBLE_NULL; + return 0; + } + +#ifdef _TD_ARM_32_ + double dv = GET_DOUBLE_VAL(payload); + if (isinf(dv) || isnan(dv) || dv > DBL_MAX || dv < -DBL_MAX) { + return -1; + } +#else + if (isinf(*((double *)payload)) || isnan(*((double *)payload)) || *((double *)payload) > DBL_MAX || + *((double *)payload) < -DBL_MAX) { + return -1; + } +#endif + break; + } + + case TSDB_DATA_TYPE_BINARY: { + if (pVariant->nType == TSDB_DATA_TYPE_NULL) { + *payload = TSDB_DATA_BINARY_NULL; + } else { + if (pVariant->nType != TSDB_DATA_TYPE_BINARY) { + toBinary(pVariant, &payload, &pVariant->nLen); + } else { + strncpy(payload, pVariant->pz, pVariant->nLen); + } + } + break; + } + case TSDB_DATA_TYPE_TIMESTAMP: { + if (pVariant->nType == TSDB_DATA_TYPE_NULL) { + *((int64_t *)payload) = TSDB_DATA_BIGINT_NULL; + } else { + *((int64_t *)payload) = pVariant->i64Key; + } + break; + } + case TSDB_DATA_TYPE_NCHAR: { + if (pVariant->nType == TSDB_DATA_TYPE_NULL) { + *(uint32_t *)payload = TSDB_DATA_NCHAR_NULL; + } else { + if (pVariant->nType != TSDB_DATA_TYPE_NCHAR) { + toNchar(pVariant, &payload, &pVariant->nLen); + } else { + wcsncpy((wchar_t *)payload, pVariant->wpz, pVariant->nLen); + } + } + break; + } + } + + return 0; +} + +/* + * In variant, bool/smallint/tinyint/int/bigint share the same attribution of + * structure, also ignore the convert the type required + * + * It is actually the bigint/binary/bool/nchar type transfer + */ +int32_t tVariantTypeSetType(tVariant *pVariant, char type) { + if (pVariant == NULL || pVariant->nType == 0) { // value is not set + return 0; + } + + switch (type) { + case TSDB_DATA_TYPE_BOOL: { // bool + if (convertToBool(pVariant, &pVariant->i64Key) < 0) { + return -1; + } + + pVariant->nType = type; + break; + } + case TSDB_DATA_TYPE_INT: + case TSDB_DATA_TYPE_BIGINT: + case TSDB_DATA_TYPE_TINYINT: + case TSDB_DATA_TYPE_SMALLINT: { + convertToInteger(pVariant, &(pVariant->i64Key), type, INT64_MIN, INT64_MAX, true); + pVariant->nType = TSDB_DATA_TYPE_BIGINT; + break; + } + case TSDB_DATA_TYPE_FLOAT: + case TSDB_DATA_TYPE_DOUBLE: { + if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { + errno = 0; + double v = strtod(pVariant->pz, NULL); + if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { + free(pVariant->pz); + return -1; + } + + free(pVariant->pz); + pVariant->dKey = v; + } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { + errno = 0; + double v = wcstod(pVariant->wpz, NULL); + if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { + free(pVariant->pz); + return -1; + } + + free(pVariant->pz); + pVariant->dKey = v; + } else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { + pVariant->dKey = pVariant->i64Key; + } + + pVariant->nType = TSDB_DATA_TYPE_DOUBLE; + break; + } + case TSDB_DATA_TYPE_BINARY: { + if (pVariant->nType != TSDB_DATA_TYPE_BINARY) { + toBinary(pVariant, &pVariant->pz, &pVariant->nLen); + } + pVariant->nType = type; + break; + } + case TSDB_DATA_TYPE_NCHAR: { + if (pVariant->nType != TSDB_DATA_TYPE_NCHAR) { + toNchar(pVariant, &pVariant->pz, &pVariant->nLen); + } + pVariant->nType = type; + break; + } + } + + return 0; +} + + diff --git a/src/util/inc/sskiplist.h b/src/util/inc/sskiplist.h index 28300a69b4cc1688b205e1c3056a85ef21849d63..2f300fa4ea0765ae81e06d560172dbec2c672a16 100644 --- a/src/util/inc/sskiplist.h +++ b/src/util/inc/sskiplist.h @@ -12,6 +12,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +#if 0 #ifndef TBASE_TSKIPLIST_H #define TBASE_TSKIPLIST_H @@ -203,3 +204,4 @@ tSkipListNode *tSkipListIteratorGet(SSkipListIterator *iter); #endif #endif // TBASE_TSKIPLIST_H +#endif \ No newline at end of file diff --git a/src/util/inc/tstoken.h b/src/util/inc/tstoken.h index 3ecf28aa2af6717e751c2c7cf11956468c642df5..13190e800d91213b630d19832a8fcf8316a7786d 100644 --- a/src/util/inc/tstoken.h +++ b/src/util/inc/tstoken.h @@ -20,7 +20,7 @@ extern "C" { #endif -#include +#include "os.h" #define TK_SPACE 200 #define TK_COMMENT 201 diff --git a/src/util/inc/ttypes.h b/src/util/inc/ttypes.h index db6490f8404f2b9c0be4f83ce0391ec4dad39a81..a099f3fa7cf14e7321b3dcfef4dec2a1c4efe74a 100644 --- a/src/util/inc/ttypes.h +++ b/src/util/inc/ttypes.h @@ -35,14 +35,28 @@ extern "C" { #define POINTER_BYTES sizeof(void *) // 8 by default assert(sizeof(ptrdiff_t) == sizseof(void*) -typedef struct tDataDescriptor { +#define TSDB_DATA_BOOL_NULL 0x02 +#define TSDB_DATA_TINYINT_NULL 0x80 +#define TSDB_DATA_SMALLINT_NULL 0x8000 +#define TSDB_DATA_INT_NULL 0x80000000 +#define TSDB_DATA_BIGINT_NULL 0x8000000000000000L + +#define TSDB_DATA_FLOAT_NULL 0x7FF00000 // it is an NAN +#define TSDB_DATA_DOUBLE_NULL 0x7FFFFF0000000000L // an NAN +#define TSDB_DATA_NCHAR_NULL 0xFFFFFFFF +#define TSDB_DATA_BINARY_NULL 0xFF + +#define TSDB_DATA_NULL_STR "NULL" +#define TSDB_DATA_NULL_STR_L "null" + +typedef struct tDataTypeDescriptor { int16_t nType; int16_t nameLen; int32_t nSize; char * aName; -} tDataDescriptor; +} tDataTypeDescriptor; -extern tDataDescriptor tDataTypeDesc[11]; +extern tDataTypeDescriptor tDataTypeDesc[11]; bool isValidDataType(int32_t type, int32_t length); bool isNull(const char *val, int32_t type); @@ -53,34 +67,6 @@ void setNullN(char *val, int32_t type, int32_t bytes, int32_t numOfElems); void assignVal(char *val, const char *src, int32_t len, int32_t type); void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size); -// variant, each number/string/field_id has a corresponding struct during parsing sql -typedef struct tVariant { - uint32_t nType; - int32_t nLen; // only used for string, for number, it is useless - union { - int64_t i64Key; - double dKey; - char * pz; - wchar_t *wpz; - }; -} tVariant; - -void tVariantCreate(tVariant *pVar, SSQLToken *token); - -void tVariantCreateFromString(tVariant *pVar, char *pz, uint32_t len, uint32_t type); - -void tVariantCreateFromBinary(tVariant *pVar, char *pz, uint32_t len, uint32_t type); - -void tVariantDestroy(tVariant *pV); - -void tVariantAssign(tVariant *pDst, const tVariant *pSrc); - -int32_t tVariantToString(tVariant *pVar, char *dst); - -int32_t tVariantDump(tVariant *pVariant, char *payload, char type); - -int32_t tVariantTypeSetType(tVariant *pVariant, char type); - #ifdef __cplusplus } #endif diff --git a/src/util/src/sskiplist.c b/src/util/src/sskiplist.c index 47948e1660fb29aeffe5189ea8baa54f903dabff..cba38e9bed5242c28a47fb13e00907299d46c184 100644 --- a/src/util/src/sskiplist.c +++ b/src/util/src/sskiplist.c @@ -12,6 +12,8 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ + +#if 0 #include "os.h" #include "tlog.h" @@ -842,3 +844,5 @@ int32_t tSkipListPointQuery(tSkipList *pSkipList, tSkipListKey *pKey, int32_t nu return retLen; } } + +#endif \ No newline at end of file diff --git a/src/util/src/ttypes.c b/src/util/src/ttypes.c index 86fa7cd5f8c7fb0b66062c6d358fcabdb5fe7c9f..5fd679dccfc7673133880b6c86b3b630b18e436d 100644 --- a/src/util/src/ttypes.c +++ b/src/util/src/ttypes.c @@ -12,14 +12,14 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +#include "ttypes.h" #include "os.h" #include "taos.h" #include "taosdef.h" -#include "tsqldef.h" -#include "ttypes.h" +#include "ttokendef.h" #include "tutil.h" -tDataDescriptor tDataTypeDesc[11] = { +tDataTypeDescriptor tDataTypeDesc[11] = { {TSDB_DATA_TYPE_NULL, 6, 1, "NOTYPE"}, {TSDB_DATA_TYPE_BOOL, 4, CHAR_BYTES, "BOOL"}, {TSDB_DATA_TYPE_TINYINT, 7, CHAR_BYTES, "TINYINT"}, @@ -61,829 +61,6 @@ bool isValidDataType(int32_t type, int32_t length) { return true; } -// todo support scientific expression number and oct number -void tVariantCreate(tVariant *pVar, SSQLToken *token) { tVariantCreateFromString(pVar, token->z, token->n, token->type); } - -void tVariantCreateFromString(tVariant *pVar, char *pz, uint32_t len, uint32_t type) { - memset(pVar, 0, sizeof(tVariant)); - - switch (type) { - case TSDB_DATA_TYPE_BOOL: { - int32_t k = strncasecmp(pz, "true", 4); - if (k == 0) { - pVar->i64Key = TSDB_TRUE; - } else { - assert(strncasecmp(pz, "false", 5) == 0); - pVar->i64Key = TSDB_FALSE; - } - break; - } - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_BIGINT: - case TSDB_DATA_TYPE_INT: - pVar->i64Key = strtoll(pz, NULL, 10); - break; - case TSDB_DATA_TYPE_DOUBLE: - case TSDB_DATA_TYPE_FLOAT: - pVar->dKey = strtod(pz, NULL); - break; - case TSDB_DATA_TYPE_BINARY: { - pVar->pz = strndup(pz, len); - pVar->nLen = strdequote(pVar->pz); - break; - } - - default: { // nType == 0 means the null value - type = TSDB_DATA_TYPE_NULL; - } - } - - pVar->nType = type; -} - -/** - * create tVariant from binary string, not ascii data - * @param pVar - * @param pz - * @param len - * @param type - */ -void tVariantCreateFromBinary(tVariant *pVar, char *pz, uint32_t len, uint32_t type) { - switch (type) { - case TSDB_DATA_TYPE_BOOL: - case TSDB_DATA_TYPE_TINYINT: { - pVar->i64Key = GET_INT8_VAL(pz); - break; - } - case TSDB_DATA_TYPE_SMALLINT: { - pVar->i64Key = GET_INT16_VAL(pz); - break; - } - case TSDB_DATA_TYPE_INT: { - pVar->i64Key = GET_INT32_VAL(pz); - break; - } - case TSDB_DATA_TYPE_BIGINT: - case TSDB_DATA_TYPE_TIMESTAMP: { - pVar->i64Key = GET_INT64_VAL(pz); - break; - } - case TSDB_DATA_TYPE_DOUBLE: { - pVar->dKey = GET_DOUBLE_VAL(pz); - break; - } - case TSDB_DATA_TYPE_FLOAT: { - pVar->dKey = GET_FLOAT_VAL(pz); - break; - } - case TSDB_DATA_TYPE_NCHAR: { // here we get the nchar length from raw binary bits length - pVar->nLen = len / TSDB_NCHAR_SIZE; - pVar->wpz = calloc(1, (pVar->nLen + 1) * TSDB_NCHAR_SIZE); - - wcsncpy(pVar->wpz, (wchar_t *)pz, pVar->nLen); - pVar->wpz[pVar->nLen] = 0; - - break; - } - case TSDB_DATA_TYPE_BINARY: { - pVar->pz = strndup(pz, len); - pVar->nLen = strdequote(pVar->pz); - - break; - } - - default: - pVar->i64Key = GET_INT32_VAL(pVar); - } - - pVar->nType = type; -} - -void tVariantDestroy(tVariant *pVar) { - if (pVar == NULL) return; - - if (pVar->nType == TSDB_DATA_TYPE_BINARY || pVar->nType == TSDB_DATA_TYPE_NCHAR) { - tfree(pVar->pz); - pVar->nLen = 0; - } -} - -void tVariantAssign(tVariant *pDst, const tVariant *pSrc) { - if (pSrc == NULL || pDst == NULL) return; - - *pDst = *pSrc; - - if (pSrc->nType == TSDB_DATA_TYPE_BINARY || pSrc->nType == TSDB_DATA_TYPE_NCHAR) { - int32_t len = pSrc->nLen + 1; - if (pSrc->nType == TSDB_DATA_TYPE_NCHAR) { - len = len * TSDB_NCHAR_SIZE; - } - - pDst->pz = calloc(1, len); - memcpy(pDst->pz, pSrc->pz, len); - } -} - -int32_t tVariantToString(tVariant *pVar, char *dst) { - if (pVar == NULL || dst == NULL) return 0; - - switch (pVar->nType) { - case TSDB_DATA_TYPE_BINARY: { - int32_t len = sprintf(dst, "\'%s\'", pVar->pz); - assert(len <= pVar->nLen + sizeof("\'") * 2); // two more chars - return len; - } - - case TSDB_DATA_TYPE_NCHAR: { - dst[0] = '\''; - taosUcs4ToMbs(pVar->wpz, (wcslen(pVar->wpz) + 1) * TSDB_NCHAR_SIZE, dst + 1); - int32_t len = strlen(dst); - dst[len] = '\''; - dst[len + 1] = 0; - return len + 1; - } - - case TSDB_DATA_TYPE_BOOL: - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_INT: - return sprintf(dst, "%d", (int32_t)pVar->i64Key); - - case TSDB_DATA_TYPE_BIGINT: - return sprintf(dst, "%" PRId64, pVar->i64Key); - - case TSDB_DATA_TYPE_FLOAT: - case TSDB_DATA_TYPE_DOUBLE: - return sprintf(dst, "%.9lf", pVar->dKey); - - default: - return 0; - } -} - -#if 0 -static int32_t doConvertToInteger(tVariant *pVariant, char *pDest, int32_t type, bool releaseVariantPtr) { - if (pVariant->nType == TSDB_DATA_TYPE_NULL) { - setNull(pDest, type, tDataTypeDesc[type].nSize); - return 0; - } - - if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { - *((int64_t *)pDest) = pVariant->i64Key; - } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { - if ((pVariant->dKey < INT64_MIN) || (pVariant->dKey > INT64_MAX)) { - return -1; - } - - *((int64_t *)pDest) = (int64_t)pVariant->dKey; - } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { - errno = 0; - char *endPtr = NULL; - - SSQLToken token = {0}; - token.n = tSQLGetToken(pVariant->pz, &token.type); - - if (token.type == TK_MINUS || token.type == TK_PLUS) { - token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); - } - - if (token.type == TK_FLOAT) { - double v = strtod(pVariant->pz, &endPtr); - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - - if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { - return -1; - } - - if ((v < INT64_MIN) || (v > INT64_MAX)) { - return -1; - } - - *((int64_t *)pDest) = (int64_t)v; - } else if (token.type == TK_INTEGER) { - int64_t val = strtoll(pVariant->pz, &endPtr, 10); - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - - if (errno == ERANGE) { - return -1; // data overflow - } - - *((int64_t *)pDest) = val; - } else if (token.type == TK_NULL) { - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - setNull(pDest, type, tDataTypeDesc[type].nSize); - } else { - return -1; - } - - } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { - errno = 0; - wchar_t *endPtr = NULL; - - SSQLToken token = {0}; - token.n = tSQLGetToken(pVariant->pz, &token.type); - - if (token.type == TK_MINUS || token.type == TK_PLUS) { - token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); - } - - if (token.type == TK_FLOAT) { - double v = wcstod(pVariant->wpz, &endPtr); - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - - if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { - return -1; - } - - if ((v < INT64_MIN) || (v > INT64_MAX)) { - return -1; - } - - *((int64_t *)pDest) = (int64_t)v; - } else if (token.type == TK_NULL) { - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - setNull(pDest, type, tDataTypeDesc[type].nSize); - } else { - int64_t val = wcstoll(pVariant->wpz, &endPtr, 10); - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - - if (errno == ERANGE) { - return -1; // data overflow - } - - *((int64_t *)pDest) = val; - } - } - - return 0; -} -#endif -static FORCE_INLINE int32_t convertToBoolImpl(char *pStr, int32_t len) { - if ((strncasecmp(pStr, "true", len) == 0) && (len == 4)) { - return TSDB_TRUE; - } else if ((strncasecmp(pStr, "false", len) == 0) && (len == 5)) { - return TSDB_FALSE; - } else if (strcasecmp(pStr, TSDB_DATA_NULL_STR_L) == 0) { - return TSDB_DATA_BOOL_NULL; - } else { - return -1; - } -} - -static FORCE_INLINE int32_t wcsconvertToBoolImpl(wchar_t *pstr, int32_t len) { - if ((wcsncasecmp(pstr, L"true", len) == 0) && (len == 4)) { - return TSDB_TRUE; - } else if (wcsncasecmp(pstr, L"false", len) == 0 && (len == 5)) { - return TSDB_FALSE; - } else { - return -1; - } -} - -static int32_t toBinary(tVariant *pVariant, char **pDest, int32_t *pDestSize) { - const int32_t INITIAL_ALLOC_SIZE = 20; - char * pBuf = NULL; - - if (*pDest == pVariant->pz) { - pBuf = calloc(1, INITIAL_ALLOC_SIZE); - } - - if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { - size_t newSize = pVariant->nLen * TSDB_NCHAR_SIZE; - if (pBuf != NULL) { - if (newSize > INITIAL_ALLOC_SIZE) { - pBuf = realloc(pBuf, newSize + 1); - } - - taosUcs4ToMbs(pVariant->wpz, newSize, pBuf); - free(pVariant->wpz); - - /* terminated string */ - pBuf[newSize] = 0; - } else { - taosUcs4ToMbs(pVariant->wpz, newSize, *pDest); - } - - } else { - if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { - sprintf(pBuf == NULL ? *pDest : pBuf, "%" PRId64, pVariant->i64Key); - } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { - sprintf(pBuf == NULL ? *pDest : pBuf, "%lf", pVariant->dKey); - } else if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { - sprintf(pBuf == NULL ? *pDest : pBuf, "%s", (pVariant->i64Key == TSDB_TRUE) ? "TRUE" : "FALSE"); - } else if (pVariant->nType == 0) { // null data - setNull(pBuf == NULL ? *pDest : pBuf, TSDB_DATA_TYPE_BINARY, 0); - } - } - - if (pBuf != NULL) { - *pDest = pBuf; - } - - *pDestSize = strlen(*pDest); - return 0; -} - -static int32_t toNchar(tVariant *pVariant, char **pDest, int32_t *pDestSize) { - char tmpBuf[40] = {0}; - - char * pDst = tmpBuf; - int32_t nLen = 0; - - if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { - nLen = sprintf(pDst, "%" PRId64, pVariant->i64Key); - } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { - nLen = sprintf(pDst, "%lf", pVariant->dKey); - } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { - pDst = pVariant->pz; - nLen = pVariant->nLen; - } else if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { - nLen = sprintf(pDst, "%s", (pVariant->i64Key == TSDB_TRUE) ? "TRUE" : "FALSE"); - } - - if (*pDest == pVariant->pz) { - wchar_t *pWStr = calloc(1, (nLen + 1) * TSDB_NCHAR_SIZE); - taosMbsToUcs4(pDst, nLen, (char *)pWStr, (nLen + 1) * TSDB_NCHAR_SIZE); - - // free the binary buffer in the first place - if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { - free(pVariant->wpz); - } - - pVariant->wpz = pWStr; - *pDestSize = wcslen(pVariant->wpz); - - // shrink the allocate memory, no need to check here. - char* tmp = realloc(pVariant->wpz, (*pDestSize + 1)*TSDB_NCHAR_SIZE); - assert(tmp != NULL); - - pVariant->wpz = (wchar_t *)tmp; - } else { - taosMbsToUcs4(pDst, nLen, *pDest, (nLen + 1) * TSDB_NCHAR_SIZE); - } - - return 0; -} - -static FORCE_INLINE int32_t convertToDouble(char *pStr, int32_t len, double *value) { - SSQLToken stoken = {.z = pStr, .n = len}; - - if (TK_ILLEGAL == isValidNumber(&stoken)) { - return -1; - } - - *value = strtod(pStr, NULL); - - return 0; -} - -static FORCE_INLINE int32_t convertToInteger(tVariant *pVariant, int64_t *result, int32_t type, int64_t lowBnd, - int64_t upperBnd, bool releaseVariantPtr) { - if (pVariant->nType == TSDB_DATA_TYPE_NULL) { - setNull((char *)result, type, tDataTypeDesc[type].nSize); - return 0; - } - - if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { - *result = pVariant->i64Key; - } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { - *result = (int64_t)pVariant->dKey; - } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { - errno = 0; - char *endPtr = NULL; - - SSQLToken token = {0}; - token.n = tSQLGetToken(pVariant->pz, &token.type); - - if (token.type == TK_MINUS || token.type == TK_PLUS) { - token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); - } - - if (token.type == TK_NULL) { - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - setNull((char *)result, type, tDataTypeDesc[type].nSize); - return 0; - } - - SSQLToken sToken = {.z = pVariant->pz, .n = pVariant->nLen}; - if (TK_ILLEGAL == isValidNumber(&sToken)) { - return -1; - } - - if (token.type == TK_FLOAT) { - double v = strtod(pVariant->pz, &endPtr); - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - - if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { - return -1; - } - - *result = (int64_t)v; - } else if (token.type == TK_INTEGER) { - int64_t val = strtoll(pVariant->pz, &endPtr, 10); - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - - if (errno == ERANGE) { - return -1; // data overflow - } - - *result = val; - } else { - return -1; - } - } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { - errno = 0; - wchar_t *endPtr = NULL; - - SSQLToken token = {0}; - token.n = tSQLGetToken(pVariant->pz, &token.type); - - if (token.type == TK_MINUS || token.type == TK_PLUS) { - token.n = tSQLGetToken(pVariant->pz + token.n, &token.type); - } - - if (token.type == TK_FLOAT) { - double v = wcstod(pVariant->wpz, &endPtr); - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - - if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { - return -1; - } - - *result = (int64_t)v; - } else if (token.type == TK_NULL) { - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - setNull((char *)result, type, tDataTypeDesc[type].nSize); - return 0; - } else { - int64_t val = wcstoll(pVariant->wpz, &endPtr, 10); - if (releaseVariantPtr) { - free(pVariant->pz); - pVariant->nLen = 0; - } - - if (errno == ERANGE) { - return -1; // data overflow - } - - *result = val; - } - } - - if ((*result <= lowBnd) || (*result > upperBnd)) { - return -1; - } - - return 0; -} - -static int32_t convertToBool(tVariant *pVariant, int64_t *pDest) { - if (pVariant->nType == TSDB_DATA_TYPE_BOOL) { - *pDest = pVariant->i64Key; // in order to be compatible to null of bool - } else if (pVariant->nType >= TSDB_DATA_TYPE_TINYINT && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { - *pDest = ((pVariant->i64Key != 0) ? TSDB_TRUE : TSDB_FALSE); - } else if (pVariant->nType == TSDB_DATA_TYPE_FLOAT || pVariant->nType == TSDB_DATA_TYPE_DOUBLE) { - *pDest = ((pVariant->dKey != 0) ? TSDB_TRUE : TSDB_FALSE); - } else if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { - int32_t ret = 0; - if ((ret = convertToBoolImpl(pVariant->pz, pVariant->nLen)) < 0) { - return ret; - } - - *pDest = ret; - } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { - int32_t ret = 0; - if ((ret = wcsconvertToBoolImpl(pVariant->wpz, pVariant->nLen)) < 0) { - return ret; - } - *pDest = ret; - } else if (pVariant->nType == TSDB_DATA_TYPE_NULL) { - *pDest = TSDB_DATA_BOOL_NULL; - } - - assert(*pDest == TSDB_TRUE || *pDest == TSDB_FALSE || *pDest == TSDB_DATA_BOOL_NULL); - return 0; -} - -/* - * transfer data from variant serve as the implicit data conversion: from input sql string pVariant->nType - * to column type defined in schema - * - * todo handle the return value - */ -int32_t tVariantDump(tVariant *pVariant, char *payload, char type) { - if (pVariant == NULL || (pVariant->nType != 0 && !isValidDataType(pVariant->nType, pVariant->nLen))) { - return -1; - } - - errno = 0; // reset global error code - - switch (type) { - case TSDB_DATA_TYPE_BOOL: { - int64_t dst = 0; - if (convertToBool(pVariant, &dst) < 0) { - return -1; - } - *(int8_t *)payload = (int8_t)dst; - break; - } - - case TSDB_DATA_TYPE_TINYINT: { - int64_t result = 0; - if (convertToInteger(pVariant, &result, type, INT8_MIN, INT8_MAX, false) < 0) { - return -1; - } - - *((int8_t *)payload) = (int8_t)result; - break; - } - - case TSDB_DATA_TYPE_SMALLINT: { - int64_t result = 0; - if (convertToInteger(pVariant, &result, type, INT16_MIN, INT16_MAX, false) < 0) { - return -1; - } - - *((int16_t *)payload) = (int16_t)result; - break; - } - - case TSDB_DATA_TYPE_INT: { - int64_t result = 0; - if (convertToInteger(pVariant, &result, type, INT32_MIN, INT32_MAX, false) < 0) { - return -1; - } - - *((int32_t *)payload) = (int32_t)result; - break; - } - - case TSDB_DATA_TYPE_BIGINT: { - int64_t result = 0; - if (convertToInteger(pVariant, &result, type, INT64_MIN, INT64_MAX, false) < 0) { - return -1; - } - - *((int64_t *)payload) = (int64_t)result; - break; - } - - case TSDB_DATA_TYPE_FLOAT: { - if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { - if (strncasecmp(TSDB_DATA_NULL_STR_L, pVariant->pz, pVariant->nLen) == 0 && - strlen(TSDB_DATA_NULL_STR_L) == pVariant->nLen) { - *((int32_t *)payload) = TSDB_DATA_FLOAT_NULL; - return 0; - } else { - double value; - int32_t ret; - ret = convertToDouble(pVariant->pz, pVariant->nLen, &value); - if ((errno == ERANGE && (float)value == -1) || (ret != 0)) { - return -1; - } - -#ifdef _TD_ARM_32_ - //memcpy(&payload, &value, sizeof(float)); - float fv = (float)value; - SET_FLOAT_VAL_ALIGN(payload, &fv); -#else - *((float *)payload) = (float)value; -#endif - } - } else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { -#ifdef _TD_ARM_32_ - //memcpy(&payload, &pVariant->i64Key, sizeof(float)); - float fv = (float)pVariant->i64Key; - SET_FLOAT_VAL_ALIGN(payload, &fv); -#else - *((float *)payload) = pVariant->i64Key; -#endif - } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { -#ifdef _TD_ARM_32_ - //memcpy(&payload, &pVariant->dKey, sizeof(float)); - float fv = (float)pVariant->dKey; - SET_FLOAT_VAL_ALIGN(payload, &fv); -#else - *((float *)payload) = (float)pVariant->dKey; -#endif - } else if (pVariant->nType == TSDB_DATA_TYPE_NULL) { - *((int32_t *)payload) = TSDB_DATA_FLOAT_NULL; - return 0; - } - -#ifdef _TD_ARM_32_ - float fv = GET_FLOAT_VAL(payload); - if (isinf(fv) || isnan(fv) || fv > FLT_MAX || fv < -FLT_MAX) { - return -1; - } -#else - if (isinf(*((float *)payload)) || isnan(*((float *)payload)) || *((float *)payload) > FLT_MAX || - *((float *)payload) < -FLT_MAX) { - return -1; - } -#endif - break; - } - case TSDB_DATA_TYPE_DOUBLE: { - if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { - if (strncasecmp(TSDB_DATA_NULL_STR_L, pVariant->pz, pVariant->nLen) == 0 && - strlen(TSDB_DATA_NULL_STR_L) == pVariant->nLen) { - *((int64_t *)payload) = TSDB_DATA_DOUBLE_NULL; - return 0; - } else { - double value = 0; - int32_t ret; - ret = convertToDouble(pVariant->pz, pVariant->nLen, &value); - if ((errno == ERANGE && value == -1) || (ret != 0)) { - return -1; - } - -#ifdef _TD_ARM_32_ - SET_DOUBLE_VAL_ALIGN(payload, &value); -#else - *((double *)payload) = value; -#endif - } - } else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { -#ifdef _TD_ARM_32_ - double dv = (double)(pVariant->i64Key); - SET_DOUBLE_VAL_ALIGN(payload, &dv); -#else - *((double *)payload) = pVariant->i64Key; -#endif - } else if (pVariant->nType == TSDB_DATA_TYPE_DOUBLE || pVariant->nType == TSDB_DATA_TYPE_FLOAT) { -#ifdef _TD_ARM_32_ - double dv = (double)(pVariant->dKey); - SET_DOUBLE_VAL_ALIGN(payload, &dv); -#else - *((double *)payload) = pVariant->dKey; -#endif - } else if (pVariant->nType == TSDB_DATA_TYPE_NULL) { - *((int64_t *)payload) = TSDB_DATA_DOUBLE_NULL; - return 0; - } - -#ifdef _TD_ARM_32_ - double dv = GET_DOUBLE_VAL(payload); - if (isinf(dv) || isnan(dv) || dv > DBL_MAX || dv < -DBL_MAX) { - return -1; - } -#else - if (isinf(*((double *)payload)) || isnan(*((double *)payload)) || *((double *)payload) > DBL_MAX || - *((double *)payload) < -DBL_MAX) { - return -1; - } -#endif - break; - } - - case TSDB_DATA_TYPE_BINARY: { - if (pVariant->nType == TSDB_DATA_TYPE_NULL) { - *payload = TSDB_DATA_BINARY_NULL; - } else { - if (pVariant->nType != TSDB_DATA_TYPE_BINARY) { - toBinary(pVariant, &payload, &pVariant->nLen); - } else { - strncpy(payload, pVariant->pz, pVariant->nLen); - } - } - break; - } - case TSDB_DATA_TYPE_TIMESTAMP: { - if (pVariant->nType == TSDB_DATA_TYPE_NULL) { - *((int64_t *)payload) = TSDB_DATA_BIGINT_NULL; - } else { - *((int64_t *)payload) = pVariant->i64Key; - } - break; - } - case TSDB_DATA_TYPE_NCHAR: { - if (pVariant->nType == TSDB_DATA_TYPE_NULL) { - *(uint32_t *)payload = TSDB_DATA_NCHAR_NULL; - } else { - if (pVariant->nType != TSDB_DATA_TYPE_NCHAR) { - toNchar(pVariant, &payload, &pVariant->nLen); - } else { - wcsncpy((wchar_t *)payload, pVariant->wpz, pVariant->nLen); - } - } - break; - } - } - - return 0; -} - -/* - * In variant, bool/smallint/tinyint/int/bigint share the same attribution of - * structure, also ignore the convert the type required - * - * It is actually the bigint/binary/bool/nchar type transfer - */ -int32_t tVariantTypeSetType(tVariant *pVariant, char type) { - if (pVariant == NULL || pVariant->nType == 0) { // value is not set - return 0; - } - - switch (type) { - case TSDB_DATA_TYPE_BOOL: { // bool - if (convertToBool(pVariant, &pVariant->i64Key) < 0) { - return -1; - } - - pVariant->nType = type; - break; - } - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_BIGINT: - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_SMALLINT: { - convertToInteger(pVariant, &(pVariant->i64Key), type, INT64_MIN, INT64_MAX, true); - pVariant->nType = TSDB_DATA_TYPE_BIGINT; - break; - } - case TSDB_DATA_TYPE_FLOAT: - case TSDB_DATA_TYPE_DOUBLE: { - if (pVariant->nType == TSDB_DATA_TYPE_BINARY) { - errno = 0; - double v = strtod(pVariant->pz, NULL); - if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { - free(pVariant->pz); - return -1; - } - - free(pVariant->pz); - pVariant->dKey = v; - } else if (pVariant->nType == TSDB_DATA_TYPE_NCHAR) { - errno = 0; - double v = wcstod(pVariant->wpz, NULL); - if ((errno == ERANGE && v == -1) || (isinf(v) || isnan(v))) { - free(pVariant->pz); - return -1; - } - - free(pVariant->pz); - pVariant->dKey = v; - } else if (pVariant->nType >= TSDB_DATA_TYPE_BOOL && pVariant->nType <= TSDB_DATA_TYPE_BIGINT) { - pVariant->dKey = pVariant->i64Key; - } - - pVariant->nType = TSDB_DATA_TYPE_DOUBLE; - break; - } - case TSDB_DATA_TYPE_BINARY: { - if (pVariant->nType != TSDB_DATA_TYPE_BINARY) { - toBinary(pVariant, &pVariant->pz, &pVariant->nLen); - } - pVariant->nType = type; - break; - } - case TSDB_DATA_TYPE_NCHAR: { - if (pVariant->nType != TSDB_DATA_TYPE_NCHAR) { - toNchar(pVariant, &pVariant->pz, &pVariant->nLen); - } - pVariant->nType = type; - break; - } - } - - return 0; -} - bool isNull(const char *val, int32_t type) { switch (type) { case TSDB_DATA_TYPE_BOOL: @@ -976,21 +153,21 @@ void assignVal(char *val, const char *src, int32_t len, int32_t type) { break; } case TSDB_DATA_TYPE_FLOAT: { - #ifdef _TD_ARM_32_ +#ifdef _TD_ARM_32_ float fv = GET_FLOAT_VAL(src); SET_FLOAT_VAL_ALIGN(val, &fv); - #else +#else *((float *)val) = GET_FLOAT_VAL(src); - #endif +#endif break; }; case TSDB_DATA_TYPE_DOUBLE: { - #ifdef _TD_ARM_32_ +#ifdef _TD_ARM_32_ double dv = GET_DOUBLE_VAL(src); SET_DOUBLE_VAL_ALIGN(val, &dv); - #else +#else *((double *)val) = GET_DOUBLE_VAL(src); - #endif +#endif break; }; case TSDB_DATA_TYPE_TIMESTAMP: @@ -1024,13 +201,13 @@ void assignVal(char *val, const char *src, int32_t len, int32_t type) { void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size) { char tmpBuf[4096] = {0}; - + switch (type) { case TSDB_DATA_TYPE_INT: { SWAP(*(int32_t *)(pLeft), *(int32_t *)(pRight), int32_t); break; } - + case TSDB_DATA_TYPE_BIGINT: case TSDB_DATA_TYPE_TIMESTAMP: { SWAP(*(int64_t *)(pLeft), *(int64_t *)(pRight), int64_t); @@ -1044,18 +221,18 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size) { SWAP(*(int16_t *)(pLeft), *(int16_t *)(pRight), int16_t); break; } - + case TSDB_DATA_TYPE_FLOAT: { SWAP(*(float *)(pLeft), *(float *)(pRight), float); break; } - + case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT: { SWAP(*(int8_t *)(pLeft), *(int8_t *)(pRight), int8_t); break; } - + default: { assert(size <= 4096); memcpy(tmpBuf, pLeft, size); @@ -1064,4 +241,4 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size) { break; } } -} +} \ No newline at end of file diff --git a/src/vnode/detail/src/vnodeSupertableQuery.c b/src/vnode/detail/src/vnodeSupertableQuery.c index 74f96aa1a8dfe7c2cd26cae4231b29bb86fa2eff..038577bd8d02bc490d283b286b1f4f3d6fb2749b 100644 --- a/src/vnode/detail/src/vnodeSupertableQuery.c +++ b/src/vnode/detail/src/vnodeSupertableQuery.c @@ -726,7 +726,7 @@ static int32_t mgmtFilterMeterByIndex(STabObj* pMetric, tQueryResultset* pRes, c .setupInfoFn = (__do_filter_suppl_fn_t)filterPrepare, .pExtInfo = &s}; - tSQLBinaryExprTraverse(pExpr, pMetric->pSkipList, pRes, &supp); +// tSQLBinaryExprTraverse(pExpr, pMetric->pSkipList, pRes, &supp); tSQLBinaryExprDestroy(&pExpr, tSQLListTraverseDestroyInfo); }