diff --git a/alert/README.md b/alert/README.md index 547f3a0381a74714b1f6c8c74b861678b3805619..b8b8c92a2797bf58ca9f80b1781fc1f5d7555f6b 100644 --- a/alert/README.md +++ b/alert/README.md @@ -61,7 +61,7 @@ The use of each configuration item is: * **port**: This is the `http` service port which enables other application to manage rules by `restful API`. * **database**: rules are stored in a `sqlite` database, this is the path of the database file (if the file does not exist, the alert application creates it automatically). -* **tdengine**: connection string of `TDEngine` server, note the database name should be put in the `sql` field of a rule in most cases, thus it should NOT be included in the string. +* **tdengine**: connection string of `TDEngine` server (please refer the documentation of GO connector for the detailed format of this string), note the database name should be put in the `sql` field of a rule in most cases, thus it should NOT be included in the string. * **log > level**: log level, could be `production` or `debug`. * **log > path**: log output file path. * **receivers > alertManager**: the alert application pushes alerts to `AlertManager` at this URL. diff --git a/alert/README_cn.md b/alert/README_cn.md index 938b23a58406f5d6f279191a47dc957c446911ce..f659e997e3ea8ec8acef8cc3eb6e41a4c692a476 100644 --- a/alert/README_cn.md +++ b/alert/README_cn.md @@ -58,7 +58,7 @@ $ go build * **port**:报警监测程序支持使用 `restful API` 对规则进行管理,这个参数用于配置 `http` 服务的侦听端口。 * **database**:报警监测程序将规则保存到了一个 `sqlite` 数据库中,这个参数用于指定数据库文件的路径(不需要提前创建这个文件,如果它不存在,程序会自动创建它)。 -* **tdengine**:`TDEngine` 的连接字符串,一般来说,数据库名应该在报警规则的 `sql` 语句中指定,所以这个字符串中 **不** 应包含数据库名。 +* **tdengine**:`TDEngine` 的连接字符串(这个字符串的详细格式说明请见 GO 连接器的文档),一般来说,数据库名应该在报警规则的 `sql` 语句中指定,所以这个字符串中 **不** 应包含数据库名。 * **log > level**:日志的记录级别,可选 `production` 或 `debug`。 * **log > path**:日志文件的路径。 * **receivers > alertManager**:报警监测程序会将报警推送到 `AlertManager`,在这里指定 `AlertManager` 的接收地址。 diff --git a/alert/app/rule.go b/alert/app/rule.go index 44596ca26d7da0ddec55dfabc2930c7166dc3547..236e5bd75562d90cac8bb5e20608dc08e1298f56 100644 --- a/alert/app/rule.go +++ b/alert/app/rule.go @@ -84,6 +84,7 @@ func (alert *Alert) doRefresh(firing bool, rule *Rule) bool { case firing && (alert.State == AlertStateWaiting): alert.StartsAt = time.Now() + alert.EndsAt = time.Time{} if rule.For.Nanoseconds() > 0 { alert.State = AlertStatePending return false @@ -95,6 +96,7 @@ func (alert *Alert) doRefresh(firing bool, rule *Rule) bool { return false } alert.StartsAt = alert.StartsAt.Add(rule.For.Duration) + alert.EndsAt = time.Time{} alert.State = AlertStateFiring case firing && (alert.State == AlertStateFiring): diff --git a/cmake/install.inc b/cmake/install.inc index 9bbcc2cf40520a9ab5e7aa4d19f46b47b6b42192..746e493a17cd09db6f8bffa4e3e4ac925fac2510 100755 --- a/cmake/install.inc +++ b/cmake/install.inc @@ -9,7 +9,7 @@ ELSEIF (TD_WINDOWS) ELSE () SET(CMAKE_INSTALL_PREFIX C:/TDengine) ENDIF () - + INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/go DESTINATION connector) INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/nodejs DESTINATION connector) INSTALL(DIRECTORY ${TD_COMMUNITY_DIR}/src/connector/python DESTINATION connector) @@ -20,12 +20,12 @@ ELSEIF (TD_WINDOWS) INSTALL(FILES ${TD_COMMUNITY_DIR}/src/inc/taoserror.h DESTINATION include) INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.lib DESTINATION driver) INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.exp DESTINATION driver) - INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver) - + INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos.dll DESTINATION driver) + IF (TD_POWER) INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/power.exe DESTINATION .) - ELSE () - INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taos.exe DESTINATION .) + ELSE () + INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taos.exe DESTINATION .) INSTALL(FILES ${EXECUTABLE_OUTPUT_PATH}/taosdemo.exe DESTINATION .) ENDIF () diff --git a/cmake/version.inc b/cmake/version.inc index 741f76da43b18600122b413627d01a925ee1fb20..2f0ec81aea2dcc932845537bcb37f5ab64d9bcb8 100644 --- a/cmake/version.inc +++ b/cmake/version.inc @@ -4,7 +4,7 @@ PROJECT(TDengine) IF (DEFINED VERNUMBER) SET(TD_VER_NUMBER ${VERNUMBER}) ELSE () - SET(TD_VER_NUMBER "2.0.7.0") + SET(TD_VER_NUMBER "2.0.8.0") ENDIF () IF (DEFINED VERCOMPATIBLE) diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh index aedfb0a6834afbf3c0c8c822b056ea5705f8d2ff..ddf7114f08387c2277df47e9174948e479d432ba 100755 --- a/packaging/tools/install.sh +++ b/packaging/tools/install.sh @@ -312,7 +312,7 @@ function install_data() { } function install_connector() { - ${csudo} cp -rf ${script_dir}/connector/* ${install_main_dir}/connector + ${csudo} cp -rf ${script_dir}/connector/ ${install_main_dir}/ } function install_examples() { diff --git a/packaging/tools/install_client.sh b/packaging/tools/install_client.sh index 24586d3390fe5c4f38b6292442fed2936d5ea7a6..34a9bfaecb4d0366008ea9b78a60434297ea9f51 100755 --- a/packaging/tools/install_client.sh +++ b/packaging/tools/install_client.sh @@ -163,7 +163,7 @@ function install_log() { } function install_connector() { - ${csudo} cp -rf ${script_dir}/connector/* ${install_main_dir}/connector + ${csudo} cp -rf ${script_dir}/connector/ ${install_main_dir}/ } function install_examples() { diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml index 1738ff7ec8e412b51403efcb2874b179726b13f9..059c0650c2bbba99694253a73b59d77cd16f06bf 100644 --- a/snap/snapcraft.yaml +++ b/snap/snapcraft.yaml @@ -1,6 +1,6 @@ name: tdengine base: core18 -version: '2.0.7.0' +version: '2.0.8.0' icon: snap/gui/t-dengine.svg summary: an open-source big data platform designed and optimized for IoT. description: | @@ -72,7 +72,7 @@ parts: - usr/bin/taosd - usr/bin/taos - usr/bin/taosdemo - - usr/lib/libtaos.so.2.0.6.0 + - usr/lib/libtaos.so.2.0.8.0 - usr/lib/libtaos.so.1 - usr/lib/libtaos.so diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f619edd221c005a8d8e707afa5271072b032f74a..a2600785c35a80d040b9f91137c630d7761cef7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,6 @@ ADD_SUBDIRECTORY(tsdb) ADD_SUBDIRECTORY(wal) ADD_SUBDIRECTORY(cq) ADD_SUBDIRECTORY(dnode) -ADD_SUBDIRECTORY(connector/odbc) +#ADD_SUBDIRECTORY(connector/odbc) ADD_SUBDIRECTORY(connector/jdbc) diff --git a/src/client/inc/tscLocalMerge.h b/src/client/inc/tscLocalMerge.h index ce67344b03a015419e485aa28e54575c2cf60045..2c7c2f51d02ea1b9943004fc62f8e48f2034d0fe 100644 --- a/src/client/inc/tscLocalMerge.h +++ b/src/client/inc/tscLocalMerge.h @@ -84,9 +84,9 @@ typedef struct SRetrieveSupport { } SRetrieveSupport; int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pDesc, - SColumnModel **pFinalModel, uint32_t nBufferSize); + SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSize); -void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, +void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel* pFFModel, int32_t numOfVnodes); int32_t saveToBuffer(tExtMemBuffer *pMemoryBuf, tOrderDescriptor *pDesc, tFilePage *pPage, void *data, diff --git a/src/client/inc/tscSubquery.h b/src/client/inc/tscSubquery.h index 3226f705283fc4b5af5f1d8c6e3a736300bd2fa6..f7832c9818226d19ba1e20cb47fa17c5bfb0f611 100644 --- a/src/client/inc/tscSubquery.h +++ b/src/client/inc/tscSubquery.h @@ -39,9 +39,9 @@ int32_t tscHandleMultivnodeInsert(SSqlObj *pSql); int32_t tscHandleInsertRetry(SSqlObj* pSql); void tscBuildResFromSubqueries(SSqlObj *pSql); -TAOS_ROW doSetResultRowData(SSqlObj *pSql, bool finalResult); +TAOS_ROW doSetResultRowData(SSqlObj *pSql); -char *getArithemicInputSrc(void *param, const char *name, int32_t colId); +char *getArithmeticInputSrc(void *param, const char *name, int32_t colId); #ifdef __cplusplus } diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index 223fb5d226690f480f6d8196180ec61b3f2fbd92..bde27d2932a5bacd09864c76ee81faa6adef04a7 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -282,6 +282,7 @@ int tscSetMgmtEpSetFromCfg(const char *first, const char *second); bool tscSetSqlOwner(SSqlObj* pSql); void tscClearSqlOwner(SSqlObj* pSql); +int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize); void* malloc_throw(size_t size); void* calloc_throw(size_t nmemb, size_t size); diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 6b3d97d6f9e5ffb6168938d3bc3e0a7a26dcbf33..ff36cf0f5ac31ecf3baa4abae5697e08a1c8bc0b 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -293,32 +293,32 @@ typedef struct SResRec { } SResRec; typedef struct { - int64_t numOfRows; // num of results in current retrieved - int64_t numOfRowsGroup; // num of results of current group - int64_t numOfTotal; // num of total results - int64_t numOfClauseTotal; // num of total result in current subclause - char * pRsp; - int32_t rspType; - int32_t rspLen; - uint64_t qhandle; - int64_t uid; - int64_t useconds; - int64_t offset; // offset value from vnode during projection query of stable - int32_t row; - int16_t numOfCols; - int16_t precision; - bool completed; - int32_t code; - int32_t numOfGroups; - SResRec * pGroupRec; - char * data; - TAOS_ROW tsrow; - int32_t* length; // length for each field for current row - char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t) - SColumnIndex * pColumnIndex; + int32_t numOfRows; // num of results in current retrieval + int64_t numOfRowsGroup; // num of results of current group + int64_t numOfTotal; // num of total results + int64_t numOfClauseTotal; // num of total result in current subclause + char * pRsp; + int32_t rspType; + int32_t rspLen; + uint64_t qhandle; + int64_t useconds; + int64_t offset; // offset value from vnode during projection query of stable + int32_t row; + int16_t numOfCols; + int16_t precision; + bool completed; + int32_t code; + int32_t numOfGroups; + SResRec * pGroupRec; + char * data; + TAOS_ROW tsrow; + TAOS_ROW urow; + int32_t* length; // length for each field for current row + char ** buffer; // Buffer used to put multibytes encoded using unicode (wchar_t) + SColumnIndex* pColumnIndex; + SArithmeticSupport* pArithSup; // support the arithmetic expression calculation on agg functions - - struct SLocalReducer *pLocalReducer; + struct SLocalReducer* pLocalReducer; } SSqlRes; typedef struct STscObj { @@ -425,6 +425,7 @@ int32_t tscTansformSQLFuncForSTableQuery(SQueryInfo *pQueryInfo); void tscRestoreSQLFuncForSTableQuery(SQueryInfo *pQueryInfo); int32_t tscCreateResPointerInfo(SSqlRes *pRes, SQueryInfo *pQueryInfo); +void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo); void tscResetSqlCmdObj(SSqlCmd *pCmd, bool removeFromCache); @@ -471,8 +472,9 @@ static FORCE_INLINE void tscGetResultColumnChr(SSqlRes* pRes, SFieldInfo* pField int32_t bytes = pInfo->field.bytes; char* pData = pRes->data + (int32_t)(offset * pRes->numOfRows + bytes * pRes->row); + UNUSED(pData); - // user defined constant value output columns +// user defined constant value output columns if (pInfo->pSqlExpr != NULL && TSDB_COL_IS_UD_COL(pInfo->pSqlExpr->colInfo.flag)) { if (type == TSDB_DATA_TYPE_NCHAR || type == TSDB_DATA_TYPE_BINARY) { pData = pInfo->pSqlExpr->param[1].pz; diff --git a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h index eaea91d1bfb0197a36fe67d78a09ab190e7e3aeb..582bd6bac03ce0049c7c22fe58fa4fa6eb8c69fb 100644 --- a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h +++ b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h @@ -129,6 +129,14 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaData JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp (JNIEnv *, jobject, jlong, jlong, jobject); +/* + * Class: com_taosdata_jdbc_TSDBJNIConnector + * Method: fetchBlockImp + * Signature: (JJLcom/taosdata/jdbc/TSDBResultSetBlockData;)I + */ +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchBlockImp + (JNIEnv *, jobject, jlong, jlong, jobject); + /* * Class: com_taosdata_jdbc_TSDBJNIConnector * Method: closeConnectionImp diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c index 4e2272eb0566569754df5ef6201f3d190f2789c1..a8829499a324605036beefad62d83eccf4d1c65b 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -17,7 +17,6 @@ #include "taos.h" #include "tlog.h" #include "tscUtil.h" -#include "tsclient.h" #include "com_taosdata_jdbc_TSDBJNIConnector.h" @@ -57,6 +56,10 @@ jmethodID g_rowdataSetStringFp; jmethodID g_rowdataSetTimestampFp; jmethodID g_rowdataSetByteArrayFp; +jmethodID g_blockdataSetByteArrayFp; +jmethodID g_blockdataSetNumOfRowsFp; +jmethodID g_blockdataSetNumOfColsFp; + #define JNI_SUCCESS 0 #define JNI_TDENGINE_ERROR -1 #define JNI_CONNECTION_NULL -2 @@ -66,7 +69,7 @@ jmethodID g_rowdataSetByteArrayFp; #define JNI_FETCH_END -6 #define JNI_OUT_OF_MEMORY -7 -void jniGetGlobalMethod(JNIEnv *env) { +static void jniGetGlobalMethod(JNIEnv *env) { // make sure init function executed once switch (atomic_val_compare_exchange_32(&__init, 0, 1)) { case 0: @@ -114,10 +117,31 @@ void jniGetGlobalMethod(JNIEnv *env) { g_rowdataSetByteArrayFp = (*env)->GetMethodID(env, g_rowdataClass, "setByteArray", "(I[B)V"); (*env)->DeleteLocalRef(env, rowdataClass); + jclass blockdataClass = (*env)->FindClass(env, "com/taosdata/jdbc/TSDBResultSetBlockData"); + jclass g_blockdataClass = (*env)->NewGlobalRef(env, blockdataClass); + g_blockdataSetByteArrayFp = (*env)->GetMethodID(env, g_blockdataClass, "setByteArray", "(II[B)V"); + g_blockdataSetNumOfRowsFp = (*env)->GetMethodID(env, g_blockdataClass, "setNumOfRows", "(I)V"); + g_blockdataSetNumOfColsFp = (*env)->GetMethodID(env, g_blockdataClass, "setNumOfCols", "(I)V"); + (*env)->DeleteLocalRef(env, blockdataClass); + atomic_store_32(&__init, 2); jniDebug("native method register finished"); } +static int32_t check_for_params(jobject jobj, jlong conn, jlong res) { + if ((TAOS*) conn == NULL) { + jniError("jobj:%p, connection is closed", jobj); + return JNI_CONNECTION_NULL; + } + + if ((TAOS_RES *) res == NULL) { + jniError("jobj:%p, conn:%p, res is null", jobj, (TAOS*) conn); + return JNI_RESULT_SET_NULL; + } + + return JNI_SUCCESS; +} + JNIEXPORT void JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setAllocModeImp(JNIEnv *env, jobject jobj, jint jMode, jstring jPath, jboolean jAutoDump) { if (jPath != NULL) { @@ -192,39 +216,37 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setOptions(JNIEnv JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp(JNIEnv *env, jobject jobj, jstring jhost, jint jport, jstring jdbName, jstring juser, jstring jpass) { - jlong ret = 0; + jlong ret = 0; const char *host = NULL; - const char *dbname = NULL; const char *user = NULL; const char *pass = NULL; + const char *dbname = NULL; if (jhost != NULL) { host = (*env)->GetStringUTFChars(env, jhost, NULL); } + if (jdbName != NULL) { dbname = (*env)->GetStringUTFChars(env, jdbName, NULL); } + if (juser != NULL) { user = (*env)->GetStringUTFChars(env, juser, NULL); } + if (jpass != NULL) { pass = (*env)->GetStringUTFChars(env, jpass, NULL); } if (user == NULL) { - jniDebug("jobj:%p, user is null, use default user %s", jobj, TSDB_DEFAULT_USER); + jniDebug("jobj:%p, user not specified, use default user %s", jobj, TSDB_DEFAULT_USER); } + if (pass == NULL) { - jniDebug("jobj:%p, pass is null, use default password", jobj); + jniDebug("jobj:%p, pass not specified, use default password", jobj); } - /* - * set numOfThreadsPerCore = 0 - * means only one thread for client side scheduler - */ - tsNumOfThreadsPerCore = 0.0; - - ret = (jlong)taos_connect((char *)host, (char *)user, (char *)pass, (char *)dbname, (uint16_t)jport); + ret = (jlong) taos_connect((char *)host, (char *)user, (char *)pass, (char *)dbname, (uint16_t)jport); if (ret == 0) { jniError("jobj:%p, conn:%p, connect to database failed, host=%s, user=%s, dbname=%s, port=%d", jobj, (void *)ret, (char *)host, (char *)user, (char *)dbname, (int32_t)jport); @@ -233,10 +255,21 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_connectImp(JNIEn (char *)host, (char *)user, (char *)dbname, (int32_t)jport); } - if (host != NULL) (*env)->ReleaseStringUTFChars(env, jhost, host); - if (dbname != NULL) (*env)->ReleaseStringUTFChars(env, jdbName, dbname); - if (user != NULL) (*env)->ReleaseStringUTFChars(env, juser, user); - if (pass != NULL) (*env)->ReleaseStringUTFChars(env, jpass, pass); + if (host != NULL) { + (*env)->ReleaseStringUTFChars(env, jhost, host); + } + + if (dbname != NULL) { + (*env)->ReleaseStringUTFChars(env, jdbName, dbname); + } + + if (user != NULL) { + (*env)->ReleaseStringUTFChars(env, juser, user); + } + + if (pass != NULL) { + (*env)->ReleaseStringUTFChars(env, jpass, pass); + } return ret; } @@ -245,64 +278,53 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_executeQueryImp( jbyteArray jsql, jlong con) { TAOS *tscon = (TAOS *)con; if (tscon == NULL) { - jniError("jobj:%p, connection is already closed", jobj); + jniError("jobj:%p, connection already closed", jobj); return JNI_CONNECTION_NULL; } if (jsql == NULL) { - jniError("jobj:%p, conn:%p, sql is null", jobj, tscon); + jniError("jobj:%p, conn:%p, empty sql string", jobj, tscon); return JNI_SQL_NULL; } jsize len = (*env)->GetArrayLength(env, jsql); - char *dst = (char *)calloc(1, sizeof(char) * (len + 1)); - if (dst == NULL) { - jniError("jobj:%p, conn:%p, can not alloc memory", jobj, tscon); + char *str = (char *) calloc(1, sizeof(char) * (len + 1)); + if (str == NULL) { + jniError("jobj:%p, conn:%p, alloc memory failed", jobj, tscon); return JNI_OUT_OF_MEMORY; } - (*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)dst); + (*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)str); if ((*env)->ExceptionCheck(env)) { // todo handle error } - jniDebug("jobj:%p, conn:%p, sql:%s", jobj, tscon, dst); - - SSqlObj *pSql = taos_query(tscon, dst); + SSqlObj *pSql = taos_query(tscon, str); int32_t code = taos_errno(pSql); if (code != TSDB_CODE_SUCCESS) { jniError("jobj:%p, conn:%p, code:%s, msg:%s", jobj, tscon, tstrerror(code), taos_errstr(pSql)); } else { - int32_t affectRows = 0; if (pSql->cmd.command == TSDB_SQL_INSERT) { - affectRows = taos_affected_rows(pSql); + int32_t affectRows = taos_affected_rows(pSql); jniDebug("jobj:%p, conn:%p, code:%s, affect rows:%d", jobj, tscon, tstrerror(code), affectRows); } else { jniDebug("jobj:%p, conn:%p, code:%s", jobj, tscon, tstrerror(code)); } } - free(dst); - return (jlong)pSql; + free(str); + return (jlong) pSql; } JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrCodeImp(JNIEnv *env, jobject jobj, jlong con, jlong tres) { - TAOS *tscon = (TAOS *)con; - if (tscon == NULL) { - jniError("jobj:%p, connection is closed", jobj); - return (jint)TSDB_CODE_TSC_INVALID_CONNECTION; + int32_t code = check_for_params(jobj, con, tres); + if (code != JNI_SUCCESS) { + return code; } - if ((void *)tres == NULL) { - jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon); - return JNI_RESULT_SET_NULL; - } - - TAOS_RES *pSql = (TAOS_RES *)tres; - - return (jint)taos_errno(pSql); + return (jint)taos_errno((TAOS_RES*) tres); } JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrMsgImp(JNIEnv *env, jobject jobj, jlong tres) { @@ -313,23 +335,16 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getErrMsgImp(J JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp(JNIEnv *env, jobject jobj, jlong con, jlong tres) { TAOS *tscon = (TAOS *)con; - if (tscon == NULL) { - jniError("jobj:%p, connection is closed", jobj); - return JNI_CONNECTION_NULL; - } - - if ((void *)tres == NULL) { - jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon); - return JNI_RESULT_SET_NULL; + int32_t code = check_for_params(jobj, con, tres); + if (code != JNI_SUCCESS) { + return code; } SSqlObj *pSql = (TAOS_RES *)tres; - STscObj *pObj = pSql->pTscObj; - if (tscIsUpdateQuery(pSql)) { - jniDebug("jobj:%p, conn:%p, update query, no resultset, %p", jobj, pObj, (void *)tres); + jniDebug("jobj:%p, conn:%p, update query, no resultset, %p", jobj, tscon, (void *)tres); } else { - jniDebug("jobj:%p, conn:%p, get resultset, %p", jobj, pObj, (void *)tres); + jniDebug("jobj:%p, conn:%p, get resultset, %p", jobj, tscon, (void *)tres); } return tres; @@ -337,15 +352,9 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp( JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp(JNIEnv *env, jobject jobj, jlong con, jlong tres) { - TAOS *tscon = (TAOS *)con; - if (tscon == NULL) { - jniError("jobj:%p, connection is closed", jobj); - return JNI_CONNECTION_NULL; - } - - if ((void *)tres == NULL) { - jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon); - return JNI_RESULT_SET_NULL; + int32_t code = check_for_params(jobj, con, tres); + if (code != JNI_SUCCESS) { + return code; } SSqlObj *pSql = (TAOS_RES *)tres; @@ -355,37 +364,27 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_isUpdateQueryImp( JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp(JNIEnv *env, jobject jobj, jlong con, jlong res) { - TAOS *tscon = (TAOS *)con; - if (tscon == NULL) { - jniError("jobj:%p, connection is closed", jobj); - return JNI_CONNECTION_NULL; - } - - if ((void *)res == NULL) { - jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon); - return JNI_RESULT_SET_NULL; + int32_t code = check_for_params(jobj, con, res); + if (code != JNI_SUCCESS) { + return code; } taos_free_result((void *)res); - jniDebug("jobj:%p, conn:%p, free resultset:%p", jobj, tscon, (void *)res); + jniDebug("jobj:%p, conn:%p, free resultset:%p", jobj, (TAOS*) con, (void *)res); + return JNI_SUCCESS; } JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getAffectedRowsImp(JNIEnv *env, jobject jobj, jlong con, jlong res) { TAOS *tscon = (TAOS *)con; - if (tscon == NULL) { - jniError("jobj:%p, connection is closed", jobj); - return JNI_CONNECTION_NULL; - } - - if ((void *)res == NULL) { - jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon); - return JNI_RESULT_SET_NULL; + int32_t code = check_for_params(jobj, con, res); + if (code != JNI_SUCCESS) { + return code; } jint ret = taos_affected_rows((SSqlObj *)res); - jniDebug("jobj:%p, conn:%p, sql:%p, res: %p, affect rows:%d", jobj, tscon, (void *)con, (void *)res, (int32_t)ret); + jniDebug("jobj:%p, conn:%p, sql:%p, res: %p, affect rows:%d", jobj, tscon, (TAOS *)con, (TAOS_RES *)res, (int32_t)ret); return ret; } @@ -394,27 +393,20 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getSchemaMetaData jlong con, jlong res, jobject arrayListObj) { TAOS *tscon = (TAOS *)con; - if (tscon == NULL) { - jniError("jobj:%p, connection is closed", jobj); - return JNI_CONNECTION_NULL; - } - - TAOS_RES *result = (TAOS_RES *)res; - if (result == NULL) { - jniError("jobj:%p, conn:%p, resultset is null", jobj, tscon); - return JNI_RESULT_SET_NULL; + int32_t code = check_for_params(jobj, con, res); + if (code != JNI_SUCCESS) { + return code; } - TAOS_FIELD *fields = taos_fetch_fields(result); - int num_fields = taos_num_fields(result); - - // jobject arrayListObj = (*env)->NewObject(env, g_arrayListClass, g_arrayListConstructFp, ""); + TAOS_RES* tres = (TAOS_RES*) res; + TAOS_FIELD *fields = taos_fetch_fields(tres); + int32_t num_fields = taos_num_fields(tres); if (num_fields == 0) { - jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void *)res, num_fields); + jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, tres, num_fields); return JNI_NUM_OF_FIELDS_0; } else { - jniDebug("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void *)res, num_fields); + jniDebug("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, tres, num_fields); for (int i = 0; i < num_fields; ++i) { jobject metadataObj = (*env)->NewObject(env, g_metadataClass, g_metadataConstructFp); (*env)->SetIntField(env, metadataObj, g_metadataColtypeField, fields[i].type); @@ -457,21 +449,21 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn } TAOS_FIELD *fields = taos_fetch_fields(result); - int num_fields = taos_num_fields(result); - if (num_fields == 0) { - jniError("jobj:%p, conn:%p, resultset:%p, fields size is %d", jobj, tscon, (void*)res, num_fields); + int32_t numOfFields = taos_num_fields(result); + if (numOfFields == 0) { + jniError("jobj:%p, conn:%p, resultset:%p, fields size %d", jobj, tscon, (void*)res, numOfFields); return JNI_NUM_OF_FIELDS_0; } TAOS_ROW row = taos_fetch_row(result); if (row == NULL) { - int tserrno = taos_errno(result); - if (tserrno == 0) { - jniDebug("jobj:%p, conn:%p, resultset:%p, fields size is %d, fetch row to the end", jobj, tscon, (void*)res, num_fields); + int code = taos_errno(result); + if (code == TSDB_CODE_SUCCESS) { + jniDebug("jobj:%p, conn:%p, resultset:%p, fields size is %d, fetch row to the end", jobj, tscon, (void*)res, numOfFields); return JNI_FETCH_END; } else { - jniDebug("jobj:%p, conn:%p, interruptted query", jobj, tscon); + jniDebug("jobj:%p, conn:%p, interrupted query", jobj, tscon); return JNI_RESULT_SET_NULL; } } @@ -480,7 +472,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn char tmp[TSDB_MAX_BYTES_PER_ROW] = {0}; - for (int i = 0; i < num_fields; i++) { + for (int i = 0; i < numOfFields; i++) { if (row[i] == NULL) { continue; } @@ -534,6 +526,45 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn return JNI_SUCCESS; } +JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchBlockImp(JNIEnv *env, jobject jobj, jlong con, + jlong res, jobject rowobj) { + TAOS * tscon = (TAOS *)con; + int32_t code = check_for_params(jobj, con, res); + if (code != JNI_SUCCESS) { + return code; + } + + TAOS_RES * tres = (TAOS_RES *)res; + TAOS_FIELD *fields = taos_fetch_fields(tres); + + int32_t numOfFields = taos_num_fields(tres); + assert(numOfFields > 0); + + TAOS_ROW row = NULL; + int32_t numOfRows = taos_fetch_block(tres, &row); + if (numOfRows == 0) { + code = taos_errno(tres); + if (code == JNI_SUCCESS) { + jniDebug("jobj:%p, conn:%p, resultset:%p, numOfFields:%d, no data to retrieve", jobj, tscon, (void *)res, + numOfFields); + return JNI_FETCH_END; + } else { + jniDebug("jobj:%p, conn:%p, query interrupted", jobj, tscon); + return JNI_RESULT_SET_NULL; + } + } + + (*env)->CallVoidMethod(env, rowobj, g_blockdataSetNumOfRowsFp, (jint)numOfRows); + (*env)->CallVoidMethod(env, rowobj, g_blockdataSetNumOfColsFp, (jint)numOfFields); + + for (int i = 0; i < numOfFields; i++) { + (*env)->CallVoidMethod(env, rowobj, g_blockdataSetByteArrayFp, i, fields[i].bytes * numOfRows, + jniFromNCharToByteArray(env, (char *)row[i], fields[i].bytes * numOfRows)); + } + + return JNI_SUCCESS; +} + JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_closeConnectionImp(JNIEnv *env, jobject jobj, jlong con) { TAOS *tscon = (TAOS *)con; @@ -589,7 +620,6 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_consumeImp(JNIEn jniGetGlobalMethod(env); TAOS_SUB *tsub = (TAOS_SUB *)sub; - TAOS_RES *res = taos_consume(tsub); if (res == NULL) { @@ -621,16 +651,16 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_validateCreateTab jsize len = (*env)->GetArrayLength(env, jsql); - char *dst = (char *)calloc(1, sizeof(char) * (len + 1)); - (*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)dst); + char *str = (char *)calloc(1, sizeof(char) * (len + 1)); + (*env)->GetByteArrayRegion(env, jsql, 0, len, (jbyte *)str); if ((*env)->ExceptionCheck(env)) { // todo handle error } - int code = taos_validate_sql(tscon, dst); + int code = taos_validate_sql(tscon, str); jniDebug("jobj:%p, conn:%p, code is %d", jobj, tscon, code); - free(dst); + free(str); return code; } diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index e9e8214c4c15588b126b0768745db084e6e7dc3b..3ff8a68d8f07f776dbb03b4b55b830b7e37dfdff 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -91,8 +91,8 @@ void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *pa int32_t sqlLen = (int32_t)strlen(sqlstr); if (sqlLen > tsMaxSQLStringLen) { tscError("sql string exceeds max length:%d", tsMaxSQLStringLen); - terrno = TSDB_CODE_TSC_INVALID_SQL; - tscQueueAsyncError(fp, param, TSDB_CODE_TSC_INVALID_SQL); + terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT; + tscQueueAsyncError(fp, param, terrno); return; } diff --git a/src/client/src/tscFunctionImpl.c b/src/client/src/tscFunctionImpl.c index 35dc94f37bccf46ba95cee119faef3921a63705e..d39b833374b4891358053788a1afbf9246dfb0dd 100644 --- a/src/client/src/tscFunctionImpl.c +++ b/src/client/src/tscFunctionImpl.c @@ -130,11 +130,11 @@ typedef struct STopBotInfo { } STopBotInfo; // leastsquares do not apply to super table -typedef struct SLeastsquareInfo { +typedef struct SLeastsquaresInfo { double mat[2][3]; double startVal; int64_t num; -} SLeastsquareInfo; +} SLeastsquaresInfo; typedef struct SAPercentileInfo { SHistogramInfo *pHisto; @@ -316,7 +316,7 @@ int32_t getResultDataInfo(int32_t dataType, int32_t dataBytes, int32_t functionI *interBytes = (int16_t)sizeof(SPercentileInfo); } else if (functionId == TSDB_FUNC_LEASTSQR) { *type = TSDB_DATA_TYPE_BINARY; - *bytes = TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE; // string + *bytes = MAX(TSDB_AVG_FUNCTION_INTER_BUFFER_SIZE, sizeof(SLeastsquaresInfo)); // string *interBytes = *bytes; } else if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST) { *type = TSDB_DATA_TYPE_BINARY; @@ -681,7 +681,7 @@ static int32_t firstFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, i } // no result for first query, data block is required - if (GET_RES_INFO(pCtx)->numOfRes <= 0) { + if (GET_RES_INFO(pCtx) == NULL || GET_RES_INFO(pCtx)->numOfRes <= 0) { return BLK_DATA_ALL_NEEDED; } else { return BLK_DATA_NO_NEEDED; @@ -693,7 +693,7 @@ static int32_t lastFuncRequired(SQLFunctionCtx *pCtx, TSKEY start, TSKEY end, in return BLK_DATA_NO_NEEDED; } - if (GET_RES_INFO(pCtx)->numOfRes <= 0) { + if (GET_RES_INFO(pCtx) == NULL || GET_RES_INFO(pCtx)->numOfRes <= 0) { return BLK_DATA_ALL_NEEDED; } else { return BLK_DATA_NO_NEEDED; @@ -2756,7 +2756,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx) { } SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); - SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); + SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); // 2*3 matrix pInfo->startVal = pCtx->param[0].dKey; @@ -2783,7 +2783,7 @@ static bool leastsquares_function_setup(SQLFunctionCtx *pCtx) { static void leastsquares_function(SQLFunctionCtx *pCtx) { SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); - SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); + SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); double(*param)[3] = pInfo->mat; double x = pInfo->startVal; @@ -2853,40 +2853,40 @@ static void leastsquares_function_f(SQLFunctionCtx *pCtx, int32_t index) { return; } - SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); - SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); + SResultRowCellInfo *pResInfo = GET_RES_INFO(pCtx); + SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); double(*param)[3] = pInfo->mat; switch (pCtx->inputType) { case TSDB_DATA_TYPE_INT: { int32_t *p = pData; - LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey); + LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey); break; }; case TSDB_DATA_TYPE_TINYINT: { int8_t *p = pData; - LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey); + LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey); break; } case TSDB_DATA_TYPE_SMALLINT: { int16_t *p = pData; - LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey); + LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey); break; } case TSDB_DATA_TYPE_BIGINT: { int64_t *p = pData; - LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey); + LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey); break; } case TSDB_DATA_TYPE_FLOAT: { float *p = pData; - LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey); + LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey); break; } case TSDB_DATA_TYPE_DOUBLE: { double *p = pData; - LEASTSQR_CAL(param, pInfo->startVal, p, index, pCtx->param[1].dKey); + LEASTSQR_CAL(param, pInfo->startVal, p, 0, pCtx->param[1].dKey); break; } default: @@ -2904,15 +2904,10 @@ static void leastsquares_function_f(SQLFunctionCtx *pCtx, int32_t index) { static void leastsquares_finalizer(SQLFunctionCtx *pCtx) { // no data in query SResultRowCellInfo * pResInfo = GET_RES_INFO(pCtx); - SLeastsquareInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); + SLeastsquaresInfo *pInfo = GET_ROWCELL_INTERBUF(pResInfo); if (pInfo->num == 0) { - if (pCtx->outputType == TSDB_DATA_TYPE_BINARY || pCtx->outputType == TSDB_DATA_TYPE_NCHAR) { - setVardataNull(pCtx->aOutputBuf, pCtx->outputType); - } else { - setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes); - } - + setNull(pCtx->aOutputBuf, pCtx->outputType, pCtx->outputBytes); return; } diff --git a/src/client/src/tscLocal.c b/src/client/src/tscLocal.c index 310c4c665761212f6fc46b889a8a2c887b7213eb..538e652f3c6577098363565a4e76fa637b60709c 100644 --- a/src/client/src/tscLocal.c +++ b/src/client/src/tscLocal.c @@ -341,7 +341,7 @@ TAOS_ROW tscFetchRow(void *param) { return NULL; } - void* data = doSetResultRowData(pSql, true); + void* data = doSetResultRowData(pSql); tscClearSqlOwner(pSql); return data; diff --git a/src/client/src/tscLocalMerge.c b/src/client/src/tscLocalMerge.c index b07c7ca66dde0a9b568436f997572829b81cb9fa..3c7d46f914dd2632ac97cbcb728898ff9a657e82 100644 --- a/src/client/src/tscLocalMerge.c +++ b/src/client/src/tscLocalMerge.c @@ -30,8 +30,6 @@ typedef struct SCompareParam { int32_t groupOrderType; } SCompareParam; -static void doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize); - int32_t treeComparator(const void *pLeft, const void *pRight, void *param) { int32_t pLeftIdx = *(int32_t *)pLeft; int32_t pRightIdx = *(int32_t *)pRight; @@ -174,14 +172,14 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd SSqlRes* pRes = &pSql->res; if (pMemBuffer == NULL) { - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer); + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); tscError("%p pMemBuffer is NULL", pMemBuffer); pRes->code = TSDB_CODE_TSC_APP_ERROR; return; } if (pDesc->pColumnModel == NULL) { - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer); + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); tscError("%p no local buffer or intermediate result format model", pSql); pRes->code = TSDB_CODE_TSC_APP_ERROR; return; @@ -199,7 +197,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd } if (numOfFlush == 0 || numOfBuffer == 0) { - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer); + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); tscDebug("%p retrieved no data", pSql); return; } @@ -208,7 +206,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd tscError("%p Invalid value of buffer capacity %d and page size %d ", pSql, pDesc->pColumnModel->capacity, pMemBuffer[0]->pageSize); - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer); + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); pRes->code = TSDB_CODE_TSC_APP_ERROR; return; } @@ -219,7 +217,7 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd if (pReducer == NULL) { tscError("%p failed to create local merge structure, out of memory", pSql); - tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, numOfBuffer); + tscLocalReducerEnvDestroy(pMemBuffer, pDesc, finalmodel, pFFModel, numOfBuffer); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; return; } @@ -336,6 +334,8 @@ void tscCreateLocalReducer(tExtMemBuffer **pMemBuffer, int32_t numOfBuffer, tOrd pReducer->resColModel = finalmodel; pReducer->resColModel->capacity = pReducer->nResultBufSize; + pReducer->finalModel = pFFModel; + assert(pReducer->finalRowSize > 0); if (pReducer->finalRowSize > 0) { pReducer->resColModel->capacity /= pReducer->finalRowSize; @@ -533,7 +533,7 @@ void tscDestroyLocalReducer(SSqlObj *pSql) { tfree(pLocalReducer->pFinalRes); tfree(pLocalReducer->discardData); - tscLocalReducerEnvDestroy(pLocalReducer->pExtMemBuffer, pLocalReducer->pDesc, pLocalReducer->resColModel, + tscLocalReducerEnvDestroy(pLocalReducer->pExtMemBuffer, pLocalReducer->pDesc, pLocalReducer->resColModel, pLocalReducer->finalModel, pLocalReducer->numOfVnode); for (int32_t i = 0; i < pLocalReducer->numOfBuffer; ++i) { tfree(pLocalReducer->pLocalDataSrc[i]); @@ -657,7 +657,7 @@ bool isSameGroup(SSqlCmd *pCmd, SLocalReducer *pReducer, char *pPrev, tFilePage } int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOrderDescriptor **pOrderDesc, - SColumnModel **pFinalModel, uint32_t nBufferSizes) { + SColumnModel **pFinalModel, SColumnModel** pFFModel, uint32_t nBufferSizes) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; @@ -755,6 +755,18 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr *pFinalModel = createColumnModel(pSchema, (int32_t)size, capacity); + memset(pSchema, 0, sizeof(SSchema) * size); + size = tscNumOfFields(pQueryInfo); + + for(int32_t i = 0; i < size; ++i) { + SInternalField* pField = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i); + pSchema[i].bytes = pField->field.bytes; + pSchema[i].type = pField->field.type; + tstrncpy(pSchema[i].name, pField->field.name, tListLen(pSchema[i].name)); + } + + *pFFModel = createColumnModel(pSchema, (int32_t) size, capacity); + tfree(pSchema); return TSDB_CODE_SUCCESS; } @@ -765,9 +777,11 @@ int32_t tscLocalReducerEnvCreate(SSqlObj *pSql, tExtMemBuffer ***pMemBuffer, tOr * @param pFinalModel * @param numOfVnodes */ -void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, +void tscLocalReducerEnvDestroy(tExtMemBuffer **pMemBuffer, tOrderDescriptor *pDesc, SColumnModel *pFinalModel, SColumnModel *pFFModel, int32_t numOfVnodes) { destroyColumnModel(pFinalModel); + destroyColumnModel(pFFModel); + tOrderDescDestroy(pDesc); for (int32_t i = 0; i < numOfVnodes; ++i) { @@ -870,17 +884,17 @@ static void genFinalResWithoutFill(SSqlRes* pRes, SLocalReducer *pLocalReducer, tFilePage * pBeforeFillData = pLocalReducer->pResultBuf; pRes->data = pLocalReducer->pFinalRes; - pRes->numOfRows = pBeforeFillData->num; + pRes->numOfRows = (int32_t) pBeforeFillData->num; if (pQueryInfo->limit.offset > 0) { if (pQueryInfo->limit.offset < pRes->numOfRows) { - int32_t prevSize = (int32_t)pBeforeFillData->num; - tColModelErase(pLocalReducer->resColModel, pBeforeFillData, prevSize, 0, (int32_t)pQueryInfo->limit.offset - 1); + int32_t prevSize = (int32_t) pBeforeFillData->num; + tColModelErase(pLocalReducer->finalModel, pBeforeFillData, prevSize, 0, (int32_t)pQueryInfo->limit.offset - 1); /* remove the hole in column model */ - tColModelCompact(pLocalReducer->resColModel, pBeforeFillData, prevSize); + tColModelCompact(pLocalReducer->finalModel, pBeforeFillData, prevSize); - pRes->numOfRows -= pQueryInfo->limit.offset; + pRes->numOfRows -= (int32_t) pQueryInfo->limit.offset; pQueryInfo->limit.offset = 0; } else { pQueryInfo->limit.offset -= pRes->numOfRows; @@ -900,7 +914,7 @@ static void genFinalResWithoutFill(SSqlRes* pRes, SLocalReducer *pLocalReducer, pRes->numOfRows -= overflow; pBeforeFillData->num -= overflow; - tColModelCompact(pLocalReducer->resColModel, pBeforeFillData, prevSize); + tColModelCompact(pLocalReducer->finalModel, pBeforeFillData, prevSize); // set remain data to be discarded, and reset the interpolation information savePrevRecordAndSetupFillInfo(pLocalReducer, pQueryInfo, pLocalReducer->pFillInfo); @@ -948,7 +962,7 @@ static void doFillResult(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool doneO } pRes->data = pLocalReducer->pFinalRes; - pRes->numOfRows = newRows; + pRes->numOfRows = (int32_t) newRows; pQueryInfo->limit.offset = 0; break; @@ -1242,7 +1256,7 @@ bool genFinalResults(SSqlObj *pSql, SLocalReducer *pLocalReducer, bool noMoreCur tColModelCompact(pModel, pResBuf, pModel->capacity); if (tscIsSecondStageQuery(pQueryInfo)) { - doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalReducer->finalRowSize); + pLocalReducer->finalRowSize = doArithmeticCalculate(pQueryInfo, pResBuf, pModel->rowSize, pLocalReducer->finalRowSize); } #ifdef _DEBUG_VIEW @@ -1612,7 +1626,7 @@ void tscInitResObjForLocalQuery(SSqlObj *pObj, int32_t numOfRes, int32_t rowLen) pRes->data = pRes->pLocalReducer->pResultBuf->data; } -void doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) { +int32_t doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t rowSize, int32_t finalRowSize) { char* pbuf = calloc(1, pOutput->num * rowSize); size_t size = tscNumOfFields(pQueryInfo); @@ -1637,7 +1651,7 @@ void doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t r // calculate the result from several other columns if (pSup->pArithExprInfo != NULL) { arithSup.pArithExpr = pSup->pArithExprInfo; - tExprTreeCalcTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithemicInputSrc); + tExprTreeCalcTraverse(arithSup.pArithExpr->pExpr, (int32_t) pOutput->num, pbuf + pOutput->num*offset, &arithSup, TSDB_ORDER_ASC, getArithmeticInputSrc); } else { SSqlExpr* pExpr = pSup->pSqlExpr; memcpy(pbuf + pOutput->num * offset, pExpr->offset * pOutput->num + pOutput->data, pExpr->resBytes * pOutput->num); @@ -1647,8 +1661,10 @@ void doArithmeticCalculate(SQueryInfo* pQueryInfo, tFilePage* pOutput, int32_t r } assert(finalRowSize <= rowSize); - memcpy(pOutput->data, pbuf, pOutput->num * finalRowSize); + memcpy(pOutput->data, pbuf, pOutput->num * offset); tfree(pbuf); tfree(arithSup.data); + + return offset; } \ No newline at end of file diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index 1739e4348ca2d1e90e4cdc292a14c7dcc5dde2da..68f2ecbf0e194bc13362b0af965959367a9f86b8 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -268,7 +268,6 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) { if (1) { // allow user bind param data with different type - short size = 0; union { int8_t v1; int16_t v2; @@ -600,7 +599,7 @@ static int doBindParam(char* data, SParamInfo* param, TAOS_BIND* bind) { if ((*bind->length) > (uintptr_t)param->bytes) { return TSDB_CODE_TSC_INVALID_VALUE; } - size = (short)*bind->length; + short size = (short)*bind->length; STR_WITH_SIZE_TO_VARSTR(data + param->offset, bind->buffer, size); return TSDB_CODE_SUCCESS; } break; diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index b55326bbd37afb1255dfe71d253b084826983f72..15d2647c5117d0bffe6dd301fb503f7e9d54235f 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -1454,13 +1454,13 @@ static void addPrimaryTsColIntoResult(SQueryInfo* pQueryInfo) { } } - SColumnIndex index = {0}; // set the constant column value always attached to first table. STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); SSchema* pSchema = tscGetTableColumnSchema(pTableMetaInfo->pTableMeta, PRIMARYKEY_TIMESTAMP_COL_INDEX); // add the timestamp column into the output columns + SColumnIndex index = {0}; // primary timestamp column info int32_t numOfCols = (int32_t)tscSqlExprNumOfExprs(pQueryInfo); tscAddSpecialColumnForSelect(pQueryInfo, numOfCols, TSDB_FUNC_PRJ, &index, pSchema, TSDB_COL_NORMAL); @@ -2432,6 +2432,8 @@ int32_t getTableIndexImpl(SStrToken* pTableToken, SQueryInfo* pQueryInfo, SColum if (pTableToken->n == 0) { // only one table and no table name prefix in column name if (pQueryInfo->numOfTables == 1) { pIndex->tableIndex = 0; + } else { + pIndex->tableIndex = COLUMN_INDEX_INITIAL_VAL; } return TSDB_CODE_SUCCESS; @@ -3950,9 +3952,6 @@ static void doExtractExprForSTable(SSqlCmd* pCmd, tSQLExpr** pExpr, SQueryInfo* return; } - SStrToken t = {0}; - extractTableNameFromToken(&pLeft->colInfo, &t); - *pOut = *pExpr; (*pExpr) = NULL; @@ -4187,7 +4186,7 @@ static void cleanQueryExpr(SCondExpr* pCondExpr) { static void doAddJoinTagsColumnsIntoTagList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondExpr* pCondExpr) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { - SColumnIndex index = {0}; + SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (getColumnIndexByName(pCmd, &pCondExpr->pJoinExpr->pLeft->colInfo, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { tscError("%p: invalid column name (left)", pQueryInfo); @@ -4604,7 +4603,7 @@ int32_t parseOrderbyClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SQuerySQL* pQu } SStrToken columnName = {pVar->nLen, pVar->nType, pVar->pz}; - SColumnIndex index = {0}; + SColumnIndex index = COLUMN_INDEX_INITIALIZER; if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { // super table query if (getColumnIndexByName(pCmd, &columnName, pQueryInfo, &index) != TSDB_CODE_SUCCESS) { @@ -5509,7 +5508,9 @@ void doAddGroupColumnForSubquery(SQueryInfo* pQueryInfo, int32_t tagIndex) { tscAddSpecialColumnForSelect(pQueryInfo, (int32_t)size, TSDB_FUNC_PRJ, &colIndex, pSchema, TSDB_COL_NORMAL); - SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, (int32_t)size); + int32_t numOfFields = tscNumOfFields(pQueryInfo); + SInternalField* pInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, numOfFields - 1); + doLimitOutputNormalColOfGroupby(pInfo->pSqlExpr); pInfo->visible = false; } @@ -6412,7 +6413,7 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { return code; } - tVariantListItem* p1 = taosArrayGet(pQuerySql->from, i); + tVariantListItem* p1 = taosArrayGet(pQuerySql->from, i + 1); if (p1->pVar.nType != TSDB_DATA_TYPE_BINARY) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg11); } @@ -6620,7 +6621,7 @@ int32_t exprTreeFromSqlExpr(SSqlCmd* pCmd, tExprNode **pExpr, const tSQLExpr* pS } } } else if (pSqlExpr->nSQLOptr == TK_ID) { // column name, normal column arithmetic expression - SColumnIndex index = {0}; + SColumnIndex index = COLUMN_INDEX_INITIALIZER; int32_t ret = getColumnIndexByName(pCmd, &pSqlExpr->colInfo, pQueryInfo, &index); if (ret != TSDB_CODE_SUCCESS) { return ret; diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index e8b6cb284ee40a3b2200e8d54913dca4ca158309..cbc5604a279fdb4fd0eab8e9cdb902e3c42a4832 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -547,7 +547,7 @@ static int32_t tscEstimateQueryMsgSize(SSqlCmd *pCmd, int32_t clauseIndex) { int32_t srcColListSize = (int32_t)(taosArrayGetSize(pQueryInfo->colList) * sizeof(SColumnInfo)); size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs); + int32_t exprSize = (int32_t)(sizeof(SSqlFuncMsg) * numOfExprs * 2); int32_t tsBufSize = (pQueryInfo->tsBuf != NULL) ? pQueryInfo->tsBuf->fileSize : 0; @@ -787,8 +787,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pSqlFuncExpr = (SSqlFuncMsg *)pMsg; } - if(tscIsSecondStageQuery(pQueryInfo)) { - size_t output = tscNumOfFields(pQueryInfo); + size_t output = tscNumOfFields(pQueryInfo); + + if (tscIsSecondStageQuery(pQueryInfo)) { pQueryMsg->secondStageOutput = htonl((int32_t) output); SSqlFuncMsg *pSqlFuncExpr1 = (SSqlFuncMsg *)pMsg; @@ -1437,19 +1438,6 @@ int tscBuildRetrieveFromMgmtMsg(SSqlObj *pSql, SSqlInfo *pInfo) { return TSDB_CODE_SUCCESS; } -static int tscSetResultPointer(SQueryInfo *pQueryInfo, SSqlRes *pRes) { - if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { - return pRes->code; - } - - for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - int16_t offset = tscFieldInfoGetOffset(pQueryInfo, i); - pRes->tsrow[i] = (unsigned char*)((char*) pRes->data + offset * pRes->numOfRows); - } - - return 0; -} - /* * this function can only be called once. * by using pRes->rspType to denote its status @@ -1460,15 +1448,18 @@ static int tscLocalResultCommonBuilder(SSqlObj *pSql, int32_t numOfRes) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - pRes->code = TSDB_CODE_SUCCESS; if (pRes->rspType == 0) { pRes->numOfRows = numOfRes; pRes->row = 0; pRes->rspType = 1; - tscSetResultPointer(pQueryInfo, pRes); + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); + if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { + return pRes->code; + } + + tscSetResRawPtr(pRes, pQueryInfo); } else { tscResetForNextRetrieve(pRes); } @@ -1512,10 +1503,11 @@ int tscProcessRetrieveLocalMergeRsp(SSqlObj *pSql) { } pRes->code = tscDoLocalMerge(pSql); - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); if (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows > 0) { + SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); tscCreateResPointerInfo(pRes, pQueryInfo); + tscSetResRawPtr(pRes, pQueryInfo); } pRes->row = 0; @@ -2195,7 +2187,16 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { if (tscCreateResPointerInfo(pRes, pQueryInfo) != TSDB_CODE_SUCCESS) { return pRes->code; } - + + STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + if (pCmd->command == TSDB_SQL_RETRIEVE) { + tscSetResRawPtr(pRes, pQueryInfo); + } else if ((UTIL_TABLE_IS_CHILD_TABLE(pTableMetaInfo) || UTIL_TABLE_IS_NORMAL_TABLE(pTableMetaInfo)) && !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_SUBQUERY)) { + tscSetResRawPtr(pRes, pQueryInfo); + } else if (tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0) && !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_QUERY) && !TSDB_QUERY_HAS_TYPE(pQueryInfo->type, TSDB_QUERY_TYPE_JOIN_SEC_STAGE)) { + tscSetResRawPtr(pRes, pQueryInfo); + } + if (pSql->pSubscription != NULL) { int32_t numOfCols = pQueryInfo->fieldsInfo.numOfOutput; @@ -2217,7 +2218,7 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) { } pRes->row = 0; - tscDebug("%p numOfRows:%" PRId64 ", offset:%" PRId64 ", complete:%d", pSql, pRes->numOfRows, pRes->offset, pRes->completed); + tscDebug("%p numOfRows:%d, offset:%" PRId64 ", complete:%d", pSql, pRes->numOfRows, pRes->offset, pRes->completed); return 0; } diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index a7b859b294da689406911cb027d75b3c91149ccc..020305a0a83864ec41db4cbf06ce01ec565c2203 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -321,7 +321,7 @@ TAOS_RES* taos_query_c(TAOS *taos, const char *sqlstr, uint32_t sqlLen, TAOS_RES if (sqlLen > (uint32_t)tsMaxSQLStringLen) { tscError("sql string exceeds max length:%d", tsMaxSQLStringLen); - terrno = TSDB_CODE_TSC_INVALID_SQL; + terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT; return NULL; } @@ -394,7 +394,7 @@ int taos_affected_rows(TAOS_RES *tres) { SSqlObj* pSql = (SSqlObj*) tres; if (pSql == NULL || pSql->signature != pSql) return 0; - return (int)(pSql->res.numOfRows); + return pSql->res.numOfRows; } TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) { @@ -443,50 +443,30 @@ int taos_retrieve(TAOS_RES *res) { if (pCmd->command < TSDB_SQL_LOCAL) { pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; } - tscProcessSql(pSql); - return (int)pRes->numOfRows; + tscProcessSql(pSql); + return pRes->numOfRows; } -int taos_fetch_block_impl(TAOS_RES *res, TAOS_ROW *rows) { - SSqlObj *pSql = (SSqlObj *)res; - SSqlCmd *pCmd = &pSql->cmd; +static bool needToFetchNewBlock(SSqlObj* pSql) { SSqlRes *pRes = &pSql->res; + SSqlCmd *pCmd = &pSql->cmd; - if (pRes->qhandle == 0 || pSql->signature != pSql) { - *rows = NULL; - return 0; - } - - // Retrieve new block - tscResetForNextRetrieve(pRes); - if (pCmd->command < TSDB_SQL_LOCAL) { - pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; - } - - tscProcessSql(pSql); - if (pRes->numOfRows == 0) { - *rows = NULL; - return 0; - } - - // secondary merge has handle this situation - if (pCmd->command != TSDB_SQL_RETRIEVE_LOCALMERGE) { - pRes->numOfClauseTotal += pRes->numOfRows; - } - - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); - if (pQueryInfo == NULL) - return 0; - - assert(0); - for (int i = 0; i < pQueryInfo->fieldsInfo.numOfOutput; ++i) { - tscGetResultColumnChr(pRes, &pQueryInfo->fieldsInfo, i, 0); - } - - *rows = pRes->tsrow; - - return (int)((pQueryInfo->order.order == TSDB_ORDER_DESC) ? pRes->numOfRows : -pRes->numOfRows); + return (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) && + (pCmd->command == TSDB_SQL_RETRIEVE || + pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE || + pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE || + pCmd->command == TSDB_SQL_FETCH || + pCmd->command == TSDB_SQL_SHOW || + pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE || + pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE || + pCmd->command == TSDB_SQL_SELECT || + pCmd->command == TSDB_SQL_DESCRIBE_TABLE || + pCmd->command == TSDB_SQL_SERV_STATUS || + pCmd->command == TSDB_SQL_CURRENT_DB || + pCmd->command == TSDB_SQL_SERV_VERSION || + pCmd->command == TSDB_SQL_CLI_VERSION || + pCmd->command == TSDB_SQL_CURRENT_USER); } TAOS_ROW taos_fetch_row(TAOS_RES *res) { @@ -509,77 +489,50 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) { // set the sql object owner tscSetSqlOwner(pSql); - // current data set are exhausted, fetch more data from node - if (pRes->row >= pRes->numOfRows && (pRes->completed != true || hasMoreVnodesToTry(pSql) || hasMoreClauseToTry(pSql)) && - (pCmd->command == TSDB_SQL_RETRIEVE || - pCmd->command == TSDB_SQL_RETRIEVE_LOCALMERGE || - pCmd->command == TSDB_SQL_TABLE_JOIN_RETRIEVE || - pCmd->command == TSDB_SQL_FETCH || - pCmd->command == TSDB_SQL_SHOW || - pCmd->command == TSDB_SQL_SHOW_CREATE_TABLE || - pCmd->command == TSDB_SQL_SHOW_CREATE_DATABASE || - pCmd->command == TSDB_SQL_SELECT || - pCmd->command == TSDB_SQL_DESCRIBE_TABLE || - pCmd->command == TSDB_SQL_SERV_STATUS || - pCmd->command == TSDB_SQL_CURRENT_DB || - pCmd->command == TSDB_SQL_SERV_VERSION || - pCmd->command == TSDB_SQL_CLI_VERSION || - pCmd->command == TSDB_SQL_CURRENT_USER )) { + // current data set are exhausted, fetch more result from node + if (pRes->row >= pRes->numOfRows && needToFetchNewBlock(pSql)) { taos_fetch_rows_a(res, waitForRetrieveRsp, pSql->pTscObj); tsem_wait(&pSql->rspSem); } - void* data = doSetResultRowData(pSql, true); + void* data = doSetResultRowData(pSql); tscClearSqlOwner(pSql); return data; } int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows) { -#if 0 SSqlObj *pSql = (SSqlObj *)res; - SSqlCmd *pCmd = &pSql->cmd; - SSqlRes *pRes = &pSql->res; - - int nRows = 0; - if (pSql == NULL || pSql->signature != pSql) { terrno = TSDB_CODE_TSC_DISCONNECTED; - *rows = NULL; return 0; } - // projection query on metric, pipeline retrieve data from vnode list, - // instead of two-stage mergednodeProcessMsgFromShell free qhandle - nRows = taos_fetch_block_impl(res, rows); - - // current subclause is completed, try the next subclause - while (rows == NULL && pCmd->clauseIndex < pCmd->numOfClause - 1) { - SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); - - pSql->cmd.command = pQueryInfo->command; - pCmd->clauseIndex++; - - pRes->numOfTotal += pRes->numOfClauseTotal; - pRes->numOfClauseTotal = 0; - pRes->rspType = 0; + SSqlCmd *pCmd = &pSql->cmd; + SSqlRes *pRes = &pSql->res; - pSql->subState.numOfSub = 0; - tfree(pSql->pSubs); + if (pRes->qhandle == 0 || + pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED || + pCmd->command == TSDB_SQL_RETRIEVE_EMPTY_RESULT || + pCmd->command == TSDB_SQL_INSERT) { + return 0; + } - assert(pSql->fp == NULL); + tscResetForNextRetrieve(pRes); - tscDebug("%p try data in the next subclause:%d, total subclause:%d", pSql, pCmd->clauseIndex, pCmd->numOfClause); - tscProcessSql(pSql); + // set the sql object owner + tscSetSqlOwner(pSql); - nRows = taos_fetch_block_impl(res, rows); + // current data set are exhausted, fetch more data from node + if (needToFetchNewBlock(pSql)) { + taos_fetch_rows_a(res, waitForRetrieveRsp, pSql->pTscObj); + tsem_wait(&pSql->rspSem); } - return nRows; -#endif + *rows = pRes->urow; - (*rows) = taos_fetch_row(res); - return ((*rows) != NULL)? 1:0; + tscClearSqlOwner(pSql); + return pRes->numOfRows; } int taos_select_db(TAOS *taos, const char *db) { @@ -600,7 +553,7 @@ int taos_select_db(TAOS *taos, const char *db) { } // send free message to vnode to free qhandle and corresponding resources in vnode -static UNUSED_FUNC bool tscKillQueryInDnode(SSqlObj* pSql) { +static bool tscKillQueryInDnode(SSqlObj* pSql) { SSqlCmd* pCmd = &pSql->cmd; SSqlRes* pRes = &pSql->res; @@ -795,6 +748,25 @@ void taos_stop_query(TAOS_RES *res) { tscDebug("%p query is cancelled", res); } +bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col) { + SSqlObj *pSql = (SSqlObj *)res; + if (pSql == NULL || pSql->signature != pSql) { + return true; + } + + SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + if (pQueryInfo == NULL) { + return true; + } + + SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, col); + if (col < 0 || col >= tscNumOfFields(pQueryInfo) || row < 0 || row > pSql->res.numOfRows) { + return true; + } + + return isNull(((char*) pSql->res.urow[col]) + row * pInfo->field.bytes, pInfo->field.type); +} + int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields) { int len = 0; for (int i = 0; i < num_fields; ++i) { @@ -892,18 +864,16 @@ int taos_validate_sql(TAOS *taos, const char *sql) { int32_t sqlLen = (int32_t)strlen(sql); if (sqlLen > tsMaxSQLStringLen) { tscError("%p sql too long", pSql); - pRes->code = TSDB_CODE_TSC_INVALID_SQL; tfree(pSql); - return pRes->code; + return TSDB_CODE_TSC_EXCEED_SQL_LIMIT; } pSql->sqlstr = realloc(pSql->sqlstr, sqlLen + 1); if (pSql->sqlstr == NULL) { - pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; tscError("%p failed to malloc sql string buffer", pSql); tscDebug("%p Valid SQL result:%d, %s pObj:%p", pSql, pRes->code, taos_errstr(pSql), pObj); tfree(pSql); - return pRes->code; + return TSDB_CODE_TSC_OUT_OF_MEMORY; } strtolower(pSql->sqlstr, sql); diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index bc522d4007e24a01ed1bf61846f924c912cf3387..6ebbeeef411f8922662e7045027cf55410cbf89d 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -594,7 +594,7 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr if (taosArrayGetSize(result) > 0) { SVgroupTableInfo* prevGroup = taosArrayGet(result, taosArrayGetSize(result) - 1); - tscDebug("%p vgId:%d, tables:%"PRId64, pSql, prevGroup->vgInfo.vgId, taosArrayGetSize(prevGroup->itemList)); + tscDebug("%p vgId:%d, tables:%"PRIzu, pSql, prevGroup->vgInfo.vgId, taosArrayGetSize(prevGroup->itemList)); } taosArrayPush(result, &info); @@ -612,7 +612,7 @@ void tscBuildVgroupTableInfo(SSqlObj* pSql, STableMetaInfo* pTableMetaInfo, SArr if (taosArrayGetSize(result) > 0) { SVgroupTableInfo* g = taosArrayGet(result, taosArrayGetSize(result) - 1); - tscDebug("%p vgId:%d, tables:%"PRId64, pSql, g->vgInfo.vgId, taosArrayGetSize(g->itemList)); + tscDebug("%p vgId:%d, tables:%"PRIzu, pSql, g->vgInfo.vgId, taosArrayGetSize(g->itemList)); } } @@ -753,7 +753,7 @@ static int32_t getIntersectionOfTableTuple(SQueryInfo* pQueryInfo, SSqlObj* pPar } #endif - tscDebug("%p tags match complete, result: %"PRId64", %"PRId64, pParentSql, t1, t2); + tscDebug("%p tags match complete, result: %"PRIzu", %"PRIzu, pParentSql, t1, t2); return TSDB_CODE_SUCCESS; } @@ -948,7 +948,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow if (!pRes->completed) { taosGetTmpfilePath("ts-join", pSupporter->path); pSupporter->f = fopen(pSupporter->path, "w"); - pRes->row = (int32_t)pRes->numOfRows; + pRes->row = pRes->numOfRows; taos_fetch_rows_a(tres, tsCompRetrieveCallback, param); return; @@ -974,7 +974,7 @@ static void tsCompRetrieveCallback(void* param, TAOS_RES* tres, int32_t numOfRow // TODO check for failure pSupporter->f = fopen(pSupporter->path, "w"); - pRes->row = (int32_t)pRes->numOfRows; + pRes->row = pRes->numOfRows; // set the callback function pSql->fp = tscJoinQueryCallback; @@ -1085,7 +1085,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR SSqlRes* pRes1 = &pParentSql->pSubs[i]->res; if (pRes1->row > 0 && pRes1->numOfRows > 0) { - tscDebug("%p sub:%p index:%d numOfRows:%"PRId64" total:%"PRId64 " (not retrieve)", pParentSql, pParentSql->pSubs[i], i, + tscDebug("%p sub:%p index:%d numOfRows:%d total:%"PRId64 " (not retrieve)", pParentSql, pParentSql->pSubs[i], i, pRes1->numOfRows, pRes1->numOfTotal); assert(pRes1->row < pRes1->numOfRows); } else { @@ -1093,7 +1093,7 @@ static void joinRetrieveFinalResCallback(void* param, TAOS_RES* tres, int numOfR pRes1->numOfClauseTotal += pRes1->numOfRows; } - tscDebug("%p sub:%p index:%d numOfRows:%"PRId64" total:%"PRId64, pParentSql, pParentSql->pSubs[i], i, + tscDebug("%p sub:%p index:%d numOfRows:%d total:%"PRId64, pParentSql, pParentSql->pSubs[i], i, pRes1->numOfRows, pRes1->numOfTotal); } } @@ -1644,6 +1644,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { tExtMemBuffer ** pMemoryBuf = NULL; tOrderDescriptor *pDesc = NULL; SColumnModel *pModel = NULL; + SColumnModel *pFinalModel = NULL; pRes->qhandle = 0x1; // hack the qhandle check @@ -1662,7 +1663,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { assert(pState->numOfSub > 0); - int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, nBufferSize); + int32_t ret = tscLocalReducerEnvCreate(pSql, &pMemoryBuf, &pDesc, &pModel, &pFinalModel, nBufferSize); if (ret != 0) { pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; tscQueueAsyncRes(pSql); @@ -1677,7 +1678,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { if (pSql->pSubs == NULL) { tfree(pSql->pSubs); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pState->numOfSub); + tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel,pState->numOfSub); tscQueueAsyncRes(pSql); return ret; @@ -1707,6 +1708,7 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { trs->subqueryIndex = i; trs->pParentSql = pSql; trs->pFinalColModel = pModel; + trs->pFFColModel = pFinalModel; SSqlObj *pNew = tscCreateSTableSubquery(pSql, trs, NULL); if (pNew == NULL) { @@ -1730,13 +1732,13 @@ int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { tscError("%p failed to prepare subquery structure and launch subqueries", pSql); pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; - tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pState->numOfSub); + tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel, pState->numOfSub); doCleanupSubqueries(pSql, i); return pRes->code; // free all allocated resource } if (pRes->code == TSDB_CODE_TSC_QUERY_CANCELLED) { - tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pState->numOfSub); + tscLocalReducerEnvDestroy(pMemoryBuf, pDesc, pModel, pFinalModel, pState->numOfSub); doCleanupSubqueries(pSql, i); return pRes->code; } @@ -1876,7 +1878,7 @@ void tscHandleSubqueryError(SRetrieveSupport *trsupport, SSqlObj *pSql, int numO tstrerror(pParentSql->res.code)); // release allocated resource - tscLocalReducerEnvDestroy(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, trsupport->pFinalColModel, + tscLocalReducerEnvDestroy(trsupport->pExtMemBuffer, trsupport->pOrderDescriptor, trsupport->pFinalColModel, trsupport->pFFColModel, pState->numOfSub); tscFreeRetrieveSup(pSql); @@ -2030,7 +2032,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR assert(pRes->numOfRows == numOfRows); int64_t num = atomic_add_fetch_64(&pState->numOfRetrievedRows, numOfRows); - tscDebug("%p sub:%p retrieve numOfRows:%" PRId64 " totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d", pParentSql, pSql, + tscDebug("%p sub:%p retrieve numOfRows:%d totalNumOfRows:%" PRIu64 " from ep:%s, orderOfSub:%d", pParentSql, pSql, pRes->numOfRows, pState->numOfRetrievedRows, pSql->epSet.fqdn[pSql->epSet.inUse], idx); if (num > tsMaxNumOfOrderedResults && tscIsProjectionQueryOnSTable(pQueryInfo, 0)) { @@ -2057,7 +2059,7 @@ static void tscRetrieveFromDnodeCallBack(void *param, TAOS_RES *tres, int numOfR } int32_t ret = saveToBuffer(trsupport->pExtMemBuffer[idx], pDesc, trsupport->localBuffer, pRes->data, - (int32_t)pRes->numOfRows, pQueryInfo->groupbyExpr.orderType); + pRes->numOfRows, pQueryInfo->groupbyExpr.orderType); if (ret != 0) { // set no disk space error info, and abort retry tscAbortFurtherRetryRetrieval(trsupport, tres, TSDB_CODE_TSC_NO_DISKSPACE); } else if (pRes->completed) { @@ -2169,7 +2171,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) return; } - tscDebug("%p Async insertion completed, total inserted:%" PRId64, pParentObj, pParentObj->res.numOfRows); + tscDebug("%p Async insertion completed, total inserted:%d", pParentObj, pParentObj->res.numOfRows); // restore user defined fp pParentObj->fp = pParentObj->fetchFp; @@ -2312,10 +2314,10 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { return; } - int32_t totalSize = tscGetResRowLength(pQueryInfo->exprList); + int32_t rowSize = tscGetResRowLength(pQueryInfo->exprList); - assert(numOfRes * totalSize > 0); - char* tmp = realloc(pRes->pRsp, numOfRes * totalSize); + assert(numOfRes * rowSize > 0); + char* tmp = realloc(pRes->pRsp, numOfRes * rowSize + sizeof(tFilePage)); if (tmp == NULL) { pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; return; @@ -2323,9 +2325,12 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { pRes->pRsp = tmp; } - pRes->data = pRes->pRsp; + tFilePage* pFilePage = (tFilePage*) pRes->pRsp; + pFilePage->num = numOfRes; + pRes->data = pFilePage->data; char* data = pRes->data; + int16_t bytes = 0; size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); @@ -2352,6 +2357,17 @@ static void doBuildResFromSubqueries(SSqlObj* pSql) { pRes->numOfRows = numOfRes; pRes->numOfClauseTotal += numOfRes; + + int32_t finalRowSize = 0; + for(int32_t i = 0; i < tscNumOfFields(pQueryInfo); ++i) { + TAOS_FIELD* pField = tscFieldInfoGetField(&pQueryInfo->fieldsInfo, i); + finalRowSize += pField->bytes; + } + + doArithmeticCalculate(pQueryInfo, pFilePage, rowSize, finalRowSize); + + pRes->data = pFilePage->data; + tscSetResRawPtr(pRes, pQueryInfo); } void tscBuildResFromSubqueries(SSqlObj *pSql) { @@ -2364,13 +2380,12 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { if (pRes->tsrow == NULL) { SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, pSql->cmd.clauseIndex); + pRes->numOfCols = (int16_t) tscSqlExprNumOfExprs(pQueryInfo); - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - pRes->numOfCols = (int16_t)numOfExprs; - - pRes->tsrow = calloc(numOfExprs, POINTER_BYTES); - pRes->buffer = calloc(numOfExprs, POINTER_BYTES); - pRes->length = calloc(numOfExprs, sizeof(int32_t)); + pRes->tsrow = calloc(pRes->numOfCols, POINTER_BYTES); + pRes->urow = calloc(pRes->numOfCols, POINTER_BYTES); + pRes->buffer = calloc(pRes->numOfCols, POINTER_BYTES); + pRes->length = calloc(pRes->numOfCols, sizeof(int32_t)); if (pRes->tsrow == NULL || pRes->buffer == NULL || pRes->length == NULL) { pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; @@ -2390,7 +2405,7 @@ void tscBuildResFromSubqueries(SSqlObj *pSql) { } } -static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) { +static UNUSED_FUNC void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pField) { SSqlRes *pRes = &pSql->res; if (pRes->tsrow[columnIndex] != NULL && pField->type == TSDB_DATA_TYPE_NCHAR) { @@ -2414,7 +2429,7 @@ static void transferNcharData(SSqlObj *pSql, int32_t columnIndex, TAOS_FIELD *pF } } -char *getArithemicInputSrc(void *param, const char *name, int32_t colId) { +char *getArithmeticInputSrc(void *param, const char *name, int32_t colId) { SArithmeticSupport *pSupport = (SArithmeticSupport *) param; int32_t index = -1; @@ -2432,7 +2447,7 @@ char *getArithemicInputSrc(void *param, const char *name, int32_t colId) { return pSupport->data[index] + pSupport->offset * pExpr->resBytes; } -TAOS_ROW doSetResultRowData(SSqlObj *pSql, bool finalResult) { +TAOS_ROW doSetResultRowData(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; @@ -2445,22 +2460,20 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql, bool finalResult) { SQueryInfo *pQueryInfo = tscGetQueryInfoDetail(pCmd, pCmd->clauseIndex); size_t size = tscNumOfFields(pQueryInfo); - int32_t offset = 0; - for (int i = 0; i < size; ++i) { - tscGetResultColumnChr(pRes, &pQueryInfo->fieldsInfo, i, offset); - TAOS_FIELD *pField = TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); + SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); - offset += pField->bytes; + int32_t type = pInfo->field.type; + int32_t bytes = pInfo->field.bytes; - // primary key column cannot be null in interval query, no need to check - if (i == 0 && pQueryInfo->interval.interval > 0) { - continue; + if (type != TSDB_DATA_TYPE_BINARY && type != TSDB_DATA_TYPE_NCHAR) { + pRes->tsrow[i] = isNull(pRes->urow[i], type) ? NULL : pRes->urow[i]; + } else { + pRes->tsrow[i] = isNull(pRes->urow[i], type) ? NULL : varDataVal(pRes->urow[i]); + pRes->length[i] = varDataLen(pRes->urow[i]); } - if (pRes->tsrow[i] != NULL && pField->type == TSDB_DATA_TYPE_NCHAR) { - transferNcharData(pSql, i, pField); - } + ((char**) pRes->urow)[i] += bytes; } pRes->row++; // index increase one-step diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index 27824fc1ffe01615a55b78056817733ac4c400c8..7a82bcaaab63603d136ae79f28b1625c90944779 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -220,13 +220,11 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) { } bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo) { - size_t numOfOutput = tscNumOfFields(pQueryInfo); - size_t numOfExprs = tscSqlExprNumOfExprs(pQueryInfo); - - if (numOfOutput == numOfExprs) { + if (tscIsProjectionQuery(pQueryInfo)) { return false; } + size_t numOfOutput = tscNumOfFields(pQueryInfo); for(int32_t i = 0; i < numOfOutput; ++i) { SExprInfo* pExprInfo = tscFieldInfoGetInternalField(&pQueryInfo->fieldsInfo, i)->pArithExprInfo; if (pExprInfo != NULL) { @@ -265,16 +263,20 @@ void tscClearInterpInfo(SQueryInfo* pQueryInfo) { int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) { if (pRes->tsrow == NULL) { - int32_t numOfOutput = pQueryInfo->fieldsInfo.numOfOutput; - pRes->numOfCols = numOfOutput; + pRes->numOfCols = pQueryInfo->fieldsInfo.numOfOutput; - pRes->tsrow = calloc(numOfOutput, POINTER_BYTES); - pRes->length = calloc(numOfOutput, sizeof(int32_t)); - pRes->buffer = calloc(numOfOutput, POINTER_BYTES); + pRes->tsrow = calloc(pRes->numOfCols, POINTER_BYTES); + pRes->urow = calloc(pRes->numOfCols, POINTER_BYTES); + pRes->length = calloc(pRes->numOfCols, sizeof(int32_t)); + pRes->buffer = calloc(pRes->numOfCols, POINTER_BYTES); // not enough memory - if (pRes->tsrow == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) { + if (pRes->tsrow == NULL || pRes->urow == NULL || pRes->length == NULL || (pRes->buffer == NULL && pRes->numOfCols > 0)) { tfree(pRes->tsrow); + tfree(pRes->urow); + tfree(pRes->length); + tfree(pRes->buffer); + pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY; return pRes->code; } @@ -283,6 +285,71 @@ int32_t tscCreateResPointerInfo(SSqlRes* pRes, SQueryInfo* pQueryInfo) { return TSDB_CODE_SUCCESS; } +void tscSetResRawPtr(SSqlRes* pRes, SQueryInfo* pQueryInfo) { + assert(pRes->numOfCols > 0); + + int32_t offset = 0; + + for (int32_t i = 0; i < pRes->numOfCols; ++i) { + SInternalField* pInfo = (SInternalField*)TARRAY_GET_ELEM(pQueryInfo->fieldsInfo.internalField, i); + + pRes->urow[i] = pRes->data + offset * pRes->numOfRows; + pRes->length[i] = pInfo->field.bytes; + + offset += pInfo->field.bytes; + + // generated the user-defined column result + if (pInfo->pSqlExpr != NULL && TSDB_COL_IS_UD_COL(pInfo->pSqlExpr->colInfo.flag)) { + if (pInfo->pSqlExpr->param[1].nType == TSDB_DATA_TYPE_NULL) { + setNullN(pRes->urow[i], pInfo->field.type, pInfo->field.bytes, (int32_t) pRes->numOfRows); + } else { + if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR || pInfo->field.type == TSDB_DATA_TYPE_BINARY) { + assert(pInfo->pSqlExpr->param[1].nLen <= pInfo->field.bytes); + + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; + + memcpy(varDataVal(p), pInfo->pSqlExpr->param[1].pz, pInfo->pSqlExpr->param[1].nLen); + varDataSetLen(p, pInfo->pSqlExpr->param[1].nLen); + } + } else { + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* p = ((char**)pRes->urow)[i] + k * pInfo->field.bytes; + memcpy(p, &pInfo->pSqlExpr->param[1].i64Key, pInfo->field.bytes); + } + } + } + + } else if (pInfo->field.type == TSDB_DATA_TYPE_NCHAR) { + // convert unicode to native code in a temporary buffer extra one byte for terminated symbol + pRes->buffer[i] = realloc(pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + + // string terminated char for binary data + memset(pRes->buffer[i], 0, pInfo->field.bytes * pRes->numOfRows); + + char* p = pRes->urow[i]; + for (int32_t k = 0; k < pRes->numOfRows; ++k) { + char* dst = pRes->buffer[i] + k * pInfo->field.bytes; + + if (isNull(p, TSDB_DATA_TYPE_NCHAR)) { + memcpy(dst, p, varDataTLen(p)); + } else { + int32_t length = taosUcs4ToMbs(varDataVal(p), varDataLen(p), varDataVal(dst)); + varDataSetLen(dst, length); + + if (length == 0) { + tscError("charset:%s to %s. val:%s convert failed.", DEFAULT_UNICODE_ENCODEC, tsCharset, (char*)p); + } + } + + p += pInfo->field.bytes; + } + + memcpy(pRes->urow[i], pRes->buffer[i], pInfo->field.bytes * pRes->numOfRows); + } + } +} + static void tscDestroyResPointerInfo(SSqlRes* pRes) { if (pRes->buffer != NULL) { // free all buffers containing the multibyte string for (int i = 0; i < pRes->numOfCols; i++) { @@ -297,6 +364,7 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) { tfree(pRes->tsrow); tfree(pRes->length); tfree(pRes->buffer); + tfree(pRes->urow); tfree(pRes->pGroupRec); tfree(pRes->pColumnIndex); diff --git a/src/connector/grafanaplugin b/src/connector/grafanaplugin index d598db167eb256fe67409b7bb3d0eb7fffc3ff8c..ec77d9049a719dabfd1a7c1122a209e201861944 160000 --- a/src/connector/grafanaplugin +++ b/src/connector/grafanaplugin @@ -1 +1 @@ -Subproject commit d598db167eb256fe67409b7bb3d0eb7fffc3ff8c +Subproject commit ec77d9049a719dabfd1a7c1122a209e201861944 diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml index 3b62f66d2ec88002d2f749166fb00bff670617ee..e7124a0599fa80baabba84700eb097bde3e57287 100755 --- a/src/connector/jdbc/pom.xml +++ b/src/connector/jdbc/pom.xml @@ -56,6 +56,23 @@ test + + + org.apache.httpcomponents + httpclient + 4.5.8 + + + org.apache.commons + commons-lang3 + 3.9 + + + com.alibaba + fastjson + 1.2.58 + + diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractTaosDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractTaosDriver.java new file mode 100644 index 0000000000000000000000000000000000000000..f864788bfffc8bdfefb0b91ec645a10ae8eec843 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractTaosDriver.java @@ -0,0 +1,161 @@ +package com.taosdata.jdbc; + +import java.io.*; +import java.sql.Driver; +import java.sql.DriverPropertyInfo; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; +import java.util.StringTokenizer; + +public abstract class AbstractTaosDriver implements Driver { + + private static final String TAOS_CFG_FILENAME = "taos.cfg"; + + /** + * @param cfgDirPath + * @return return the config dir + **/ + protected File loadConfigDir(String cfgDirPath) { + if (cfgDirPath == null) + return loadDefaultConfigDir(); + File cfgDir = new File(cfgDirPath); + if (!cfgDir.exists()) + return loadDefaultConfigDir(); + return cfgDir; + } + + /** + * @return search the default config dir, if the config dir is not exist will return null + */ + protected File loadDefaultConfigDir() { + File cfgDir; + File cfgDir_linux = new File("/etc/taos"); + cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null; + File cfgDir_windows = new File("C:\\TDengine\\cfg"); + cfgDir = (cfgDir == null && cfgDir_windows.exists()) ? cfgDir_windows : cfgDir; + return cfgDir; + } + + protected List loadConfigEndpoints(File cfgFile) { + List endpoints = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) { + String line = null; + while ((line = reader.readLine()) != null) { + if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")) { + endpoints.add(line.substring(line.indexOf('p') + 1).trim()); + } + if (endpoints.size() > 1) + break; + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + return endpoints; + } + + protected void loadTaosConfig(Properties info) { + if ((info.getProperty(TSDBDriver.PROPERTY_KEY_HOST) == null || + info.getProperty(TSDBDriver.PROPERTY_KEY_HOST).isEmpty()) && ( + info.getProperty(TSDBDriver.PROPERTY_KEY_PORT) == null || + info.getProperty(TSDBDriver.PROPERTY_KEY_PORT).isEmpty())) { + File cfgDir = loadConfigDir(info.getProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR)); + File cfgFile = cfgDir.listFiles((dir, name) -> TAOS_CFG_FILENAME.equalsIgnoreCase(name))[0]; + List endpoints = loadConfigEndpoints(cfgFile); + if (!endpoints.isEmpty()) { + info.setProperty(TSDBDriver.PROPERTY_KEY_HOST, endpoints.get(0).split(":")[0]); + info.setProperty(TSDBDriver.PROPERTY_KEY_PORT, endpoints.get(0).split(":")[1]); + } + } + } + + protected DriverPropertyInfo[] getPropertyInfo(Properties info) { + DriverPropertyInfo hostProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_HOST, info.getProperty(TSDBDriver.PROPERTY_KEY_HOST)); + hostProp.required = false; + hostProp.description = "Hostname"; + + DriverPropertyInfo portProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_PORT, info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT)); + portProp.required = false; + portProp.description = "Port"; + + DriverPropertyInfo dbProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_DBNAME, info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME)); + dbProp.required = false; + dbProp.description = "Database name"; + + DriverPropertyInfo userProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_USER, info.getProperty(TSDBDriver.PROPERTY_KEY_USER)); + userProp.required = true; + userProp.description = "User"; + + DriverPropertyInfo passwordProp = new DriverPropertyInfo(TSDBDriver.PROPERTY_KEY_PASSWORD, info.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD)); + passwordProp.required = true; + passwordProp.description = "Password"; + + DriverPropertyInfo[] propertyInfo = new DriverPropertyInfo[5]; + propertyInfo[0] = hostProp; + propertyInfo[1] = portProp; + propertyInfo[2] = dbProp; + propertyInfo[3] = userProp; + propertyInfo[4] = passwordProp; + return propertyInfo; + } + + protected Properties parseURL(String url, Properties defaults) { + Properties urlProps = (defaults != null) ? defaults : new Properties(); + + // parse properties + int beginningOfSlashes = url.indexOf("//"); + int index = url.indexOf("?"); + if (index != -1) { + String paramString = url.substring(index + 1, url.length()); + url = url.substring(0, index); + StringTokenizer queryParams = new StringTokenizer(paramString, "&"); + while (queryParams.hasMoreElements()) { + String parameterValuePair = queryParams.nextToken(); + int indexOfEqual = parameterValuePair.indexOf("="); + String parameter = null; + String value = null; + if (indexOfEqual != -1) { + parameter = parameterValuePair.substring(0, indexOfEqual); + if (indexOfEqual + 1 < parameterValuePair.length()) { + value = parameterValuePair.substring(indexOfEqual + 1); + } + } + if ((value != null && value.length() > 0) && (parameter != null && parameter.length() > 0)) { + urlProps.setProperty(parameter, value); + } + } + } + + // parse Product Name + String dbProductName = url.substring(0, beginningOfSlashes); + dbProductName = dbProductName.substring(dbProductName.indexOf(":") + 1); + dbProductName = dbProductName.substring(0, dbProductName.indexOf(":")); + // parse dbname + url = url.substring(beginningOfSlashes + 2); + int indexOfSlash = url.indexOf("/"); + if (indexOfSlash != -1) { + if (indexOfSlash + 1 < url.length()) { + urlProps.setProperty(TSDBDriver.PROPERTY_KEY_DBNAME, url.substring(indexOfSlash + 1)); + } + url = url.substring(0, indexOfSlash); + } + // parse port + int indexOfColon = url.indexOf(":"); + if (indexOfColon != -1) { + if (indexOfColon + 1 < url.length()) { + urlProps.setProperty(TSDBDriver.PROPERTY_KEY_PORT, url.substring(indexOfColon + 1)); + } + url = url.substring(0, indexOfColon); + } + // parse host + if (url != null && url.length() > 0 && url.trim().length() > 0) { + urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url); + } + return urlProps; + } + + + +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java index 5c7f80c715c12d1d3831a4cfbfe5f4a326b569eb..633fdcd5ab7c9f077abbd725c2511bcc2251db44 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java @@ -16,10 +16,10 @@ package com.taosdata.jdbc; public class ColumnMetaData { - int colType = 0; - String colName = null; - int colSize = -1; - int colIndex = 0; + private int colType = 0; + private String colName = null; + private int colSize = -1; + private int colIndex = 0; public int getColSize() { return colSize; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java index f93412ffecb0673f946f187f13472a0b4d6a140e..94abe3965507170a4b31e17ebb431ddcb4fa11f8 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java @@ -14,7 +14,6 @@ *****************************************************************************/ package com.taosdata.jdbc; -import java.io.*; import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; @@ -35,11 +34,10 @@ import java.util.*; import java.util.concurrent.Executor; public class TSDBConnection implements Connection { + protected Properties props = null; private TSDBJNIConnector connector = null; - protected Properties props = null; - private String catalog = null; private TSDBDatabaseMetaData dbMetaData = null; @@ -47,15 +45,21 @@ public class TSDBConnection implements Connection { private Properties clientInfoProps = new Properties(); private int timeoutMilliseconds = 0; - - private String tsCharSet = ""; + + private boolean batchFetch = false; public TSDBConnection(Properties info, TSDBDatabaseMetaData meta) throws SQLException { this.dbMetaData = meta; connect(info.getProperty(TSDBDriver.PROPERTY_KEY_HOST), Integer.parseInt(info.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "0")), - info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME), info.getProperty(TSDBDriver.PROPERTY_KEY_USER), + info.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME), + info.getProperty(TSDBDriver.PROPERTY_KEY_USER), info.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD)); + + String batchLoad = info.getProperty(TSDBDriver.PROPERTY_KEY_BATCH_LOAD); + if (batchLoad != null) { + this.batchFetch = Boolean.parseBoolean(batchLoad); + } } private void connect(String host, int port, String dbName, String user, String password) throws SQLException { @@ -223,6 +227,14 @@ public class TSDBConnection implements Connection { return this.prepareStatement(sql); } + + public Boolean getBatchFetch() { + return this.batchFetch; + } + + public void setBatchFetch(Boolean batchFetch) { + this.batchFetch = batchFetch; + } public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java index 63c42ca399b6098a5fa8c34d6fafeb51bdc8f588..06f88cebfaa8aa90cc81506a98374ec8076ad82e 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java @@ -14,7 +14,6 @@ *****************************************************************************/ package com.taosdata.jdbc; -import java.io.*; import java.sql.*; import java.util.*; import java.util.logging.Logger; @@ -38,7 +37,7 @@ import java.util.logging.Logger; * register it with the DriverManager. This means that a user can load and * register a driver by doing Class.forName("foo.bah.Driver") */ -public class TSDBDriver implements java.sql.Driver { +public class TSDBDriver extends AbstractTaosDriver { @Deprecated private static final String URL_PREFIX1 = "jdbc:TSDB://"; @@ -87,6 +86,11 @@ public class TSDBDriver implements java.sql.Driver { */ public static final String PROPERTY_KEY_CHARSET = "charset"; + /** + * fetch data from native function in a batch model + */ + public static final String PROPERTY_KEY_BATCH_LOAD = "batchfetch"; + private TSDBDatabaseMetaData dbMetaData = null; static { @@ -97,50 +101,6 @@ public class TSDBDriver implements java.sql.Driver { } } - private List loadConfigEndpoints(File cfgFile) { - List endpoints = new ArrayList<>(); - try (BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) { - String line = null; - while ((line = reader.readLine()) != null) { - if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")) { - endpoints.add(line.substring(line.indexOf('p') + 1).trim()); - } - if (endpoints.size() > 1) - break; - } - } catch (FileNotFoundException e) { - e.printStackTrace(); - } catch (IOException e) { - e.printStackTrace(); - } - return endpoints; - } - - /** - * @param cfgDirPath - * @return return the config dir - **/ - private File loadConfigDir(String cfgDirPath) { - if (cfgDirPath == null) - return loadDefaultConfigDir(); - File cfgDir = new File(cfgDirPath); - if (!cfgDir.exists()) - return loadDefaultConfigDir(); - return cfgDir; - } - - /** - * @return search the default config dir, if the config dir is not exist will return null - */ - private File loadDefaultConfigDir() { - File cfgDir; - File cfgDir_linux = new File("/etc/taos"); - cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null; - File cfgDir_windows = new File("C:\\TDengine\\cfg"); - cfgDir = (cfgDir == null && cfgDir_windows.exists()) ? cfgDir_windows : cfgDir; - return cfgDir; - } - public Connection connect(String url, Properties info) throws SQLException { if (url == null) throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!")); @@ -152,26 +112,12 @@ public class TSDBDriver implements java.sql.Driver { if ((props = parseURL(url, info)) == null) { return null; } - //load taos.cfg start - if ((info.getProperty(TSDBDriver.PROPERTY_KEY_HOST) == null || - info.getProperty(TSDBDriver.PROPERTY_KEY_HOST).isEmpty()) && ( - info.getProperty(TSDBDriver.PROPERTY_KEY_PORT) == null || - info.getProperty(TSDBDriver.PROPERTY_KEY_PORT).isEmpty())) { - File cfgDir = loadConfigDir(info.getProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR)); - File cfgFile = cfgDir.listFiles((dir, name) -> "taos.cfg".equalsIgnoreCase(name))[0]; - List endpoints = loadConfigEndpoints(cfgFile); - if (!endpoints.isEmpty()) { - info.setProperty(TSDBDriver.PROPERTY_KEY_HOST, endpoints.get(0).split(":")[0]); - info.setProperty(TSDBDriver.PROPERTY_KEY_PORT, endpoints.get(0).split(":")[1]); - } - } + loadTaosConfig(info); try { - TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), - (String) props.get(PROPERTY_KEY_LOCALE), - (String) props.get(PROPERTY_KEY_CHARSET), - (String) props.get(PROPERTY_KEY_TIME_ZONE)); + TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE), + (String) props.get(PROPERTY_KEY_CHARSET), (String) props.get(PROPERTY_KEY_TIME_ZONE)); Connection newConn = new TSDBConnection(props, this.dbMetaData); return newConn; } catch (SQLWarning sqlWarning) { @@ -208,39 +154,13 @@ public class TSDBDriver implements java.sql.Driver { info = parseURL(url, info); } - DriverPropertyInfo hostProp = new DriverPropertyInfo(PROPERTY_KEY_HOST, info.getProperty(PROPERTY_KEY_HOST)); - hostProp.required = false; - hostProp.description = "Hostname"; - - DriverPropertyInfo portProp = new DriverPropertyInfo(PROPERTY_KEY_PORT, info.getProperty(PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT)); - portProp.required = false; - portProp.description = "Port"; - - DriverPropertyInfo dbProp = new DriverPropertyInfo(PROPERTY_KEY_DBNAME, info.getProperty(PROPERTY_KEY_DBNAME)); - dbProp.required = false; - dbProp.description = "Database name"; - - DriverPropertyInfo userProp = new DriverPropertyInfo(PROPERTY_KEY_USER, info.getProperty(PROPERTY_KEY_USER)); - userProp.required = true; - userProp.description = "User"; - - DriverPropertyInfo passwordProp = new DriverPropertyInfo(PROPERTY_KEY_PASSWORD, info.getProperty(PROPERTY_KEY_PASSWORD)); - passwordProp.required = true; - passwordProp.description = "Password"; - - DriverPropertyInfo[] propertyInfo = new DriverPropertyInfo[5]; - propertyInfo[0] = hostProp; - propertyInfo[1] = portProp; - propertyInfo[2] = dbProp; - propertyInfo[3] = userProp; - propertyInfo[4] = passwordProp; - - return propertyInfo; + return getPropertyInfo(info); } /** * example: jdbc:TAOS://127.0.0.1:0/db?user=root&password=your_password */ + @Override public Properties parseURL(String url, Properties defaults) { Properties urlProps = (defaults != null) ? defaults : new Properties(); if (url == null || url.length() <= 0 || url.trim().length() <= 0) @@ -257,26 +177,21 @@ public class TSDBDriver implements java.sql.Driver { url = url.substring(0, index); StringTokenizer queryParams = new StringTokenizer(paramString, "&"); while (queryParams.hasMoreElements()) { - String parameterValuePair = queryParams.nextToken(); - int indexOfEqual = parameterValuePair.indexOf("="); - String parameter = null; - String value = null; - if (indexOfEqual != -1) { - parameter = parameterValuePair.substring(0, indexOfEqual); - if (indexOfEqual + 1 < parameterValuePair.length()) { - value = parameterValuePair.substring(indexOfEqual + 1); - } - } - if ((value != null && value.length() > 0) && (parameter != null && parameter.length() > 0)) { - urlProps.setProperty(parameter, value); + String oneToken = queryParams.nextToken(); + String[] pair = oneToken.split("="); + + if ((pair[0] != null && pair[0].trim().length() > 0) && (pair[1] != null && pair[1].trim().length() > 0)) { + urlProps.setProperty(pair[0].trim(), pair[1].trim()); } } } + // parse Product Name String dbProductName = url.substring(0, beginningOfSlashes); dbProductName = dbProductName.substring(dbProductName.indexOf(":") + 1); dbProductName = dbProductName.substring(0, dbProductName.indexOf(":")); - // parse dbname + + // parse database name url = url.substring(beginningOfSlashes + 2); int indexOfSlash = url.indexOf("/"); if (indexOfSlash != -1) { @@ -285,6 +200,7 @@ public class TSDBDriver implements java.sql.Driver { } url = url.substring(0, indexOfSlash); } + // parse port int indexOfColon = url.indexOf(":"); if (indexOfColon != -1) { @@ -293,89 +209,15 @@ public class TSDBDriver implements java.sql.Driver { } url = url.substring(0, indexOfColon); } + if (url != null && url.length() > 0 && url.trim().length() > 0) { urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url); } - + this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, urlProps.getProperty(TSDBDriver.PROPERTY_KEY_USER)); - - /* - String urlForMeta = url; - String dbProductName = url.substring(url.indexOf(":") + 1); - dbProductName = dbProductName.substring(0, dbProductName.indexOf(":")); - int beginningOfSlashes = url.indexOf("//"); - url = url.substring(beginningOfSlashes + 2); - - String host = url.substring(0, url.indexOf(":")); - url = url.substring(url.indexOf(":") + 1); - urlProps.setProperty(PROPERTY_KEY_HOST, host); - - String port = url.substring(0, url.indexOf("/")); - urlProps.setProperty(PROPERTY_KEY_PORT, port); - url = url.substring(url.indexOf("/") + 1); - - if (url.indexOf("?") != -1) { - String dbName = url.substring(0, url.indexOf("?")); - urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName); - url = url.trim().substring(url.indexOf("?") + 1); - } else { - // without user & password so return - if (!url.trim().isEmpty()) { - String dbName = url.trim(); - urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName); - } - this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, urlProps.getProperty("user")); - return urlProps; - } - - String user = ""; - - if (url.indexOf("&") == -1) { - String[] kvPair = url.trim().split("="); - if (kvPair.length == 2) { - setPropertyValue(urlProps, kvPair); - return urlProps; - } - } - - String[] queryStrings = url.trim().split("&"); - for (String queryStr : queryStrings) { - String[] kvPair = queryStr.trim().split("="); - if (kvPair.length < 2) { - continue; - } - setPropertyValue(urlProps, kvPair); - } - - user = urlProps.getProperty(PROPERTY_KEY_USER).toString(); - this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, user); -*/ return urlProps; } - private void setPropertyValue(Properties property, String[] keyValuePair) { - switch (keyValuePair[0].toLowerCase()) { - case PROPERTY_KEY_USER: - property.setProperty(PROPERTY_KEY_USER, keyValuePair[1]); - break; - case PROPERTY_KEY_PASSWORD: - property.setProperty(PROPERTY_KEY_PASSWORD, keyValuePair[1]); - break; - case PROPERTY_KEY_TIME_ZONE: - property.setProperty(PROPERTY_KEY_TIME_ZONE, keyValuePair[1]); - break; - case PROPERTY_KEY_LOCALE: - property.setProperty(PROPERTY_KEY_LOCALE, keyValuePair[1]); - break; - case PROPERTY_KEY_CHARSET: - property.setProperty(PROPERTY_KEY_CHARSET, keyValuePair[1]); - break; - case PROPERTY_KEY_CONFIG_DIR: - property.setProperty(PROPERTY_KEY_CONFIG_DIR, keyValuePair[1]); - break; - } - } - public int getMajorVersion() { return 2; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java index edc160e323d2dc9c885b5404545a6d0689857a31..f918463439fba293171827001acf6930ab271b81 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java @@ -243,6 +243,11 @@ public class TSDBJNIConnector { private native int fetchRowImp(long connection, long resultSet, TSDBResultSetRowData rowData); + public int fetchBlock(long resultSet, TSDBResultSetBlockData blockData) { + return this.fetchBlockImp(this.taos, resultSet, blockData); + } + + private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData); /** * Execute close operation from C to release connection pointer by JNI * diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java index 961633b8aec4ec433a56522e504fb35495ccfa78..84a3f58f4692a99737af7d93c5578fc7a5a09c27 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java @@ -47,10 +47,14 @@ public class TSDBResultSet implements ResultSet { private List columnMetaDataList = new ArrayList(); private TSDBResultSetRowData rowData; + private TSDBResultSetBlockData blockData; + private boolean batchFetch = false; private boolean lastWasNull = false; private final int COLUMN_INDEX_START_VALUE = 1; + private int rowIndex = 0; + public TSDBJNIConnector getJniConnector() { return jniConnector; } @@ -67,6 +71,14 @@ public class TSDBResultSet implements ResultSet { this.resultSetPointer = resultSetPointer; } + public void setBatchFetch(boolean batchFetch) { + this.batchFetch = batchFetch; + } + + public Boolean getBatchFetch() { + return this.batchFetch; + } + public List getColumnMetaDataList() { return columnMetaDataList; } @@ -94,8 +106,8 @@ public class TSDBResultSet implements ResultSet { public TSDBResultSet() { } - public TSDBResultSet(TSDBJNIConnector connecter, long resultSetPointer) throws SQLException { - this.jniConnector = connecter; + public TSDBResultSet(TSDBJNIConnector connector, long resultSetPointer) throws SQLException { + this.jniConnector = connector; this.resultSetPointer = resultSetPointer; int code = this.jniConnector.getSchemaMetaData(this.resultSetPointer, this.columnMetaDataList); if (code == TSDBConstants.JNI_CONNECTION_NULL) { @@ -107,6 +119,7 @@ public class TSDBResultSet implements ResultSet { } this.rowData = new TSDBResultSetRowData(this.columnMetaDataList.size()); + this.blockData = new TSDBResultSetBlockData(this.columnMetaDataList, this.columnMetaDataList.size()); } public T unwrap(Class iface) throws SQLException { @@ -118,21 +131,42 @@ public class TSDBResultSet implements ResultSet { } public boolean next() throws SQLException { - if (rowData != null) { - this.rowData.clear(); - } + if (this.getBatchFetch()) { + if (this.blockData.forward()) { + return true; + } + + int code = this.jniConnector.fetchBlock(this.resultSetPointer, this.blockData); + this.blockData.reset(); + + if (code == TSDBConstants.JNI_CONNECTION_NULL) { + throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); + } else if (code == TSDBConstants.JNI_RESULT_SET_NULL) { + throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL)); + } else if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { + throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0)); + } else if (code == TSDBConstants.JNI_FETCH_END) { + return false; + } - int code = this.jniConnector.fetchRow(this.resultSetPointer, this.rowData); - if (code == TSDBConstants.JNI_CONNECTION_NULL) { - throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); - } else if (code == TSDBConstants.JNI_RESULT_SET_NULL) { - throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL)); - } else if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { - throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0)); - } else if (code == TSDBConstants.JNI_FETCH_END) { - return false; - } else { return true; + } else { + if (rowData != null) { + this.rowData.clear(); + } + + int code = this.jniConnector.fetchRow(this.resultSetPointer, this.rowData); + if (code == TSDBConstants.JNI_CONNECTION_NULL) { + throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); + } else if (code == TSDBConstants.JNI_RESULT_SET_NULL) { + throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL)); + } else if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { + throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0)); + } else if (code == TSDBConstants.JNI_FETCH_END) { + return false; + } else { + return true; + } } } @@ -155,21 +189,30 @@ public class TSDBResultSet implements ResultSet { String res = null; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + } + return res; + } else { + return this.blockData.getString(colIndex); } - return res; } public boolean getBoolean(int columnIndex) throws SQLException { boolean res = false; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = this.rowData.getBoolean(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + } + } else { + return this.blockData.getBoolean(colIndex); } + return res; } @@ -177,66 +220,91 @@ public class TSDBResultSet implements ResultSet { byte res = 0; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = (byte) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + } + return res; + } else { + return (byte) this.blockData.getInt(colIndex); } - return res; } public short getShort(int columnIndex) throws SQLException { short res = 0; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = (short) this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + } + return res; + } else { + return (short) this.blockData.getInt(colIndex); } - return res; } public int getInt(int columnIndex) throws SQLException { int res = 0; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = this.rowData.getInt(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + } + return res; + } else { + return this.blockData.getInt(colIndex); } - return res; + } public long getLong(int columnIndex) throws SQLException { long res = 0l; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + } + return res; + } else { + return this.blockData.getLong(colIndex); } - return res; } public float getFloat(int columnIndex) throws SQLException { float res = 0; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = this.rowData.getFloat(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + } + return res; + } else { + return (float) this.blockData.getDouble(colIndex); } - return res; } public double getDouble(int columnIndex) throws SQLException { double res = 0; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = this.rowData.getDouble(colIndex, this.columnMetaDataList.get(colIndex).getColType()); + } + return res; + } else { + return this.blockData.getDouble(colIndex); } - return res; } /* @@ -249,25 +317,11 @@ public class TSDBResultSet implements ResultSet { */ @Deprecated public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { - BigDecimal res = null; - int colIndex = getTrueColumnIndex(columnIndex); - - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType())); - } - return res; + return new BigDecimal(getLong(columnIndex)); } public byte[] getBytes(int columnIndex) throws SQLException { - byte[] res = null; - int colIndex = getTrueColumnIndex(columnIndex); - - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = this.rowData.getString(colIndex, this.columnMetaDataList.get(colIndex).getColType()).getBytes(); - } - return res; + return getString(columnIndex).getBytes(); } public Date getDate(int columnIndex) throws SQLException { @@ -284,11 +338,15 @@ public class TSDBResultSet implements ResultSet { Timestamp res = null; int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - if (!lastWasNull) { - res = this.rowData.getTimestamp(colIndex); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + if (!lastWasNull) { + res = this.rowData.getTimestamp(colIndex); + } + return res; + } else { + return this.blockData.getTimestamp(columnIndex); } - return res; } public InputStream getAsciiStream(int columnIndex) throws SQLException { @@ -400,8 +458,12 @@ public class TSDBResultSet implements ResultSet { public Object getObject(int columnIndex) throws SQLException { int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - return this.rowData.get(colIndex); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + return this.rowData.get(colIndex); + } else { + return this.blockData.get(colIndex); + } } public Object getObject(String columnLabel) throws SQLException { @@ -433,8 +495,12 @@ public class TSDBResultSet implements ResultSet { public BigDecimal getBigDecimal(int columnIndex) throws SQLException { int colIndex = getTrueColumnIndex(columnIndex); - this.lastWasNull = this.rowData.wasNull(colIndex); - return new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType())); + if (!this.getBatchFetch()) { + this.lastWasNull = this.rowData.wasNull(colIndex); + return new BigDecimal(this.rowData.getLong(colIndex, this.columnMetaDataList.get(colIndex).getColType())); + } else { + return new BigDecimal(this.blockData.getLong(colIndex)); + } } public BigDecimal getBigDecimal(String columnLabel) throws SQLException { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java new file mode 100644 index 0000000000000000000000000000000000000000..9352cf525350ff57525680f405d61c6b00c0cf55 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java @@ -0,0 +1,497 @@ +/*************************************************************************** + * 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 . + *****************************************************************************/ +package com.taosdata.jdbc; + +import java.io.UnsupportedEncodingException; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.DoubleBuffer; +import java.nio.FloatBuffer; +import java.nio.IntBuffer; +import java.nio.LongBuffer; +import java.nio.ShortBuffer; +import java.sql.SQLDataException; +import java.sql.SQLException; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public class TSDBResultSetBlockData { + private int numOfRows = 0; + private int rowIndex = 0; + + private List columnMetaDataList; + private ArrayList colData = null; + + public TSDBResultSetBlockData(List colMeta, int numOfCols) { + this.columnMetaDataList = colMeta; + this.colData = new ArrayList(numOfCols); + } + + public TSDBResultSetBlockData() { + this.colData = new ArrayList(); + } + + public void clear() { + int size = this.colData.size(); + if (this.colData != null) { + this.colData.clear(); + } + + setNumOfCols(size); + } + + public int getNumOfRows() { + return this.numOfRows; + } + + public void setNumOfRows(int numOfRows) { + this.numOfRows = numOfRows; + } + + public int getNumOfCols() { + return this.colData.size(); + } + + public void setNumOfCols(int numOfCols) { + this.colData = new ArrayList(numOfCols); + this.colData.addAll(Collections.nCopies(numOfCols, null)); + } + + public boolean hasMore() { + return this.rowIndex < this.numOfRows; + } + + public boolean forward() { + if (this.rowIndex > this.numOfRows) { + return false; + } + + return ((++this.rowIndex) < this.numOfRows); + } + + public void reset() { + this.rowIndex = 0; + } + + public void setBoolean(int col, boolean value) { + colData.set(col, value); + } + + public void setByteArray(int col, int length, byte[] value) { + try { + switch (this.columnMetaDataList.get(col).getColType()) { + case TSDBConstants.TSDB_DATA_TYPE_BOOL: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + buf.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer(); + this.colData.set(col, buf); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + buf.order(ByteOrder.LITTLE_ENDIAN); + this.colData.set(col, buf); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + ShortBuffer sb = buf.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer(); + this.colData.set(col, sb); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_INT: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + IntBuffer ib = buf.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer(); + this.colData.set(col, ib); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + LongBuffer lb = buf.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer(); + this.colData.set(col, lb); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + FloatBuffer fb = buf.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer(); + this.colData.set(col, fb); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + DoubleBuffer db = buf.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer(); + this.colData.set(col, db); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + buf.order(ByteOrder.LITTLE_ENDIAN); + this.colData.set(col, buf); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + LongBuffer lb = buf.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer(); + this.colData.set(col, lb); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: { + ByteBuffer buf = ByteBuffer.wrap(value, 0, length); + buf.order(ByteOrder.LITTLE_ENDIAN); + this.colData.set(col, buf); + break; + } + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static class NullType { + private static final byte NULL_BOOL_VAL = 0x2; + private static final String NULL_STR = "null"; + + public String toString() { + return NullType.NULL_STR; + } + + public static boolean isBooleanNull(byte val) { + return val == NullType.NULL_BOOL_VAL; + } + + private static boolean isTinyIntNull(byte val) { + return val == Byte.MIN_VALUE; + } + + private static boolean isSmallIntNull(short val) { + return val == Short.MIN_VALUE; + } + + private static boolean isIntNull(int val) { + return val == Integer.MIN_VALUE; + } + + private static boolean isBigIntNull(long val) { + return val == Long.MIN_VALUE; + } + + private static boolean isFloatNull(float val) { + return Float.isNaN(val); + } + + private static boolean isDoubleNull(double val) { + return Double.isNaN(val); + } + + private static boolean isBinaryNull(byte[] val, int length) { + if (length != Byte.BYTES) { + return false; + } + + return val[0] == 0xFF; + } + + private static boolean isNcharNull(byte[] val, int length) { + if (length != Integer.BYTES) { + return false; + } + + return (val[0] & val[1] & val[2] & val[3]) == 0xFF; + } + + } + + /** + * The original type may not be a string type, but will be converted to by + * calling this method + * + * @param col column index + * @return + * @throws SQLException + */ + public String getString(int col) throws SQLException { + Object obj = get(col); + if (obj == null) { + return new NullType().toString(); + } + + return obj.toString(); + } + + public int getInt(int col) { + Object obj = get(col); + if (obj == null) { + return 0; + } + + int type = this.columnMetaDataList.get(col).getColType(); + switch (type) { + case TSDBConstants.TSDB_DATA_TYPE_BOOL: + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: + case TSDBConstants.TSDB_DATA_TYPE_INT: { + return (int) obj; + } + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { + return ((Long) obj).intValue(); + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + return ((Double) obj).intValue(); + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + return Integer.parseInt((String) obj); + } + } + + return 0; + } + + public boolean getBoolean(int col) throws SQLException { + Object obj = get(col); + if (obj == null) { + return Boolean.FALSE; + } + + int type = this.columnMetaDataList.get(col).getColType(); + switch (type) { + case TSDBConstants.TSDB_DATA_TYPE_BOOL: + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: + case TSDBConstants.TSDB_DATA_TYPE_INT: { + return ((int) obj == 0L) ? Boolean.FALSE : Boolean.TRUE; + } + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { + return (((Long) obj) == 0L) ? Boolean.FALSE : Boolean.TRUE; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + return (((Double) obj) == 0) ? Boolean.FALSE : Boolean.TRUE; + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + if ("TRUE".compareToIgnoreCase((String) obj) == 0) { + return Boolean.TRUE; + } else if ("FALSE".compareToIgnoreCase((String) obj) == 0) { + return Boolean.TRUE; + } else { + throw new SQLDataException(); + } + } + } + + return Boolean.FALSE; + } + + public long getLong(int col) throws SQLException { + Object obj = get(col); + if (obj == null) { + return 0; + } + + int type = this.columnMetaDataList.get(col).getColType(); + switch (type) { + case TSDBConstants.TSDB_DATA_TYPE_BOOL: + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: + case TSDBConstants.TSDB_DATA_TYPE_INT: { + return (int) obj; + } + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { + return (long) obj; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + return ((Double) obj).longValue(); + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + return Long.parseLong((String) obj); + } + } + + return 0; + } + + public Timestamp getTimestamp(int col) { + try { + return new Timestamp(getLong(col)); + } catch (SQLException e) { + e.printStackTrace(); + } + + return null; + } + + public double getDouble(int col) { + Object obj = get(col); + if (obj == null) { + return 0; + } + + int type = this.columnMetaDataList.get(col).getColType(); + switch (type) { + case TSDBConstants.TSDB_DATA_TYPE_BOOL: + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: + case TSDBConstants.TSDB_DATA_TYPE_INT: { + return (int) obj; + } + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { + return (long) obj; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + return (double) obj; + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + return Double.parseDouble((String) obj); + } + } + + return 0; + } + + public Object get(int col) { + int fieldSize = this.columnMetaDataList.get(col).getColSize(); + + switch (this.columnMetaDataList.get(col).getColType()) { + case TSDBConstants.TSDB_DATA_TYPE_BOOL: { + ByteBuffer bb = (ByteBuffer) this.colData.get(col); + + byte val = bb.get(this.rowIndex); + if (NullType.isBooleanNull(val)) { + return null; + } + + return (val == 0x0) ? Boolean.FALSE : Boolean.TRUE; + } + + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { + ByteBuffer bb = (ByteBuffer) this.colData.get(col); + + byte val = bb.get(this.rowIndex); + if (NullType.isTinyIntNull(val)) { + return null; + } + + return val; + } + + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { + ShortBuffer sb = (ShortBuffer) this.colData.get(col); + short val = sb.get(this.rowIndex); + if (NullType.isSmallIntNull(val)) { + return null; + } + + return val; + } + + case TSDBConstants.TSDB_DATA_TYPE_INT: { + IntBuffer ib = (IntBuffer) this.colData.get(col); + int val = ib.get(this.rowIndex); + if (NullType.isIntNull(val)) { + return null; + } + + return val; + } + + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { + LongBuffer lb = (LongBuffer) this.colData.get(col); + long val = lb.get(this.rowIndex); + if (NullType.isBigIntNull(val)) { + return null; + } + + return (long) val; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { + FloatBuffer fb = (FloatBuffer) this.colData.get(col); + float val = fb.get(this.rowIndex); + if (NullType.isFloatNull(val)) { + return null; + } + + return val; + } + + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + DoubleBuffer lb = (DoubleBuffer) this.colData.get(col); + double val = lb.get(this.rowIndex); + if (NullType.isDoubleNull(val)) { + return null; + } + + return val; + } + + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + ByteBuffer bb = (ByteBuffer) this.colData.get(col); + bb.position(fieldSize * this.rowIndex); + + int length = bb.getShort(); + + byte[] dest = new byte[length]; + bb.get(dest, 0, length); + if (NullType.isBinaryNull(dest, length)) { + return null; + } + + return new String(dest); + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: { + ByteBuffer bb = (ByteBuffer) this.colData.get(col); + bb.position(fieldSize * this.rowIndex); + + int length = bb.getShort(); + + byte[] dest = new byte[length]; + bb.get(dest, 0, length); + if (NullType.isNcharNull(dest, length)) { + return null; + } + + try { + String ss = TaosGlobalConfig.getCharset(); + return new String(dest, ss); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + } + + return 0; + } +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java index 8efcac90001b63af53c2943c0137f3c89bc994c5..c57f19550dd14719baecb835d76263df1e6a669b 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java @@ -218,5 +218,4 @@ public class TSDBResultSetRowData { public void setData(ArrayList data) { this.data = (ArrayList) data.clone(); } - } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java index 5c6b0545e91a13b793478efa1ec687e616d1a9ef..cdd88b825e2a8f6ba81c131bfd1214ffbe46f32c 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java @@ -19,7 +19,7 @@ import java.util.ArrayList; import java.util.List; public class TSDBStatement implements Statement { - private TSDBJNIConnector connecter = null; + private TSDBJNIConnector connector = null; /** * To store batched commands @@ -45,9 +45,9 @@ public class TSDBStatement implements Statement { this.connection = connection; } - TSDBStatement(TSDBConnection connection, TSDBJNIConnector connecter) { + TSDBStatement(TSDBConnection connection, TSDBJNIConnector connector) { this.connection = connection; - this.connecter = connecter; + this.connector = connector; this.isClosed = false; } @@ -65,25 +65,27 @@ public class TSDBStatement implements Statement { } // TODO make sure it is not a update query - pSql = this.connecter.executeQuery(sql); + pSql = this.connector.executeQuery(sql); - long resultSetPointer = this.connecter.getResultSet(); + long resultSetPointer = this.connector.getResultSet(); if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) { - this.connecter.freeResultSet(pSql); + this.connector.freeResultSet(pSql); throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); } // create/insert/update/delete/alter if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) { - this.connecter.freeResultSet(pSql); + this.connector.freeResultSet(pSql); return null; } - if (!this.connecter.isUpdateQuery(pSql)) { - return new TSDBResultSet(this.connecter, resultSetPointer); + if (!this.connector.isUpdateQuery(pSql)) { + TSDBResultSet res = new TSDBResultSet(this.connector, resultSetPointer); + res.setBatchFetch(this.connection.getBatchFetch()); + return res; } else { - this.connecter.freeResultSet(pSql); + this.connector.freeResultSet(pSql); return null; } @@ -95,28 +97,28 @@ public class TSDBStatement implements Statement { } // TODO check if current query is update query - pSql = this.connecter.executeQuery(sql); - long resultSetPointer = this.connecter.getResultSet(); + pSql = this.connector.executeQuery(sql); + long resultSetPointer = this.connector.getResultSet(); if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) { - this.connecter.freeResultSet(pSql); + this.connector.freeResultSet(pSql); throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); } - this.affectedRows = this.connecter.getAffectedRows(pSql); - this.connecter.freeResultSet(pSql); + this.affectedRows = this.connector.getAffectedRows(pSql); + this.connector.freeResultSet(pSql); return this.affectedRows; } public String getErrorMsg(long pSql) { - return this.connecter.getErrMsg(pSql); + return this.connector.getErrMsg(pSql); } public void close() throws SQLException { if (!isClosed) { - if (!this.connecter.isResultsetClosed()) { - this.connecter.freeResultSet(); + if (!this.connector.isResultsetClosed()) { + this.connector.freeResultSet(); } isClosed = true; } @@ -136,7 +138,7 @@ public class TSDBStatement implements Statement { } public void setMaxRows(int max) throws SQLException { - // always set maxRows to zero, meaning unlimitted rows in a resultSet + // always set maxRows to zero, meaning unlimited rows in a resultSet } public void setEscapeProcessing(boolean enable) throws SQLException { @@ -172,15 +174,15 @@ public class TSDBStatement implements Statement { throw new SQLException("Invalid method call on a closed statement."); } boolean res = true; - pSql = this.connecter.executeQuery(sql); - long resultSetPointer = this.connecter.getResultSet(); + pSql = this.connector.executeQuery(sql); + long resultSetPointer = this.connector.getResultSet(); if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) { - this.connecter.freeResultSet(pSql); + this.connector.freeResultSet(pSql); throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); } else if (resultSetPointer == TSDBConstants.JNI_NULL_POINTER) { // no result set is retrieved - this.connecter.freeResultSet(pSql); + this.connector.freeResultSet(pSql); res = false; } @@ -191,10 +193,10 @@ public class TSDBStatement implements Statement { if (isClosed) { throw new SQLException("Invalid method call on a closed statement."); } - long resultSetPointer = connecter.getResultSet(); + long resultSetPointer = connector.getResultSet(); TSDBResultSet resSet = null; if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) { - resSet = new TSDBResultSet(connecter, resultSetPointer); + resSet = new TSDBResultSet(connector, resultSetPointer); } return resSet; } @@ -267,7 +269,7 @@ public class TSDBStatement implements Statement { } public Connection getConnection() throws SQLException { - if (this.connecter != null) + if (this.connector != null) return this.connection; throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java new file mode 100644 index 0000000000000000000000000000000000000000..b82efca3ef4defb166632e4dd347de528e52d2c6 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java @@ -0,0 +1,319 @@ +package com.taosdata.jdbc.rs; + +import com.taosdata.jdbc.TSDBConstants; + +import java.sql.*; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.Executor; + +public class RestfulConnection implements Connection { + + private final String host; + private final int port; + private final Properties props; + private final String database; + private final String url; + + + public RestfulConnection(String host, String port, Properties props, String database, String url) { + this.host = host; + this.port = Integer.parseInt(port); + this.props = props; + this.database = database; + this.url = url; + } + + @Override + public Statement createStatement() throws SQLException { + if (isClosed()) + throw new SQLException(TSDBConstants.WrapErrMsg("restful TDengine connection is closed.")); + return new RestfulStatement(this, this.database); + } + + @Override + public PreparedStatement prepareStatement(String sql) throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql) throws SQLException { + return null; + } + + @Override + public String nativeSQL(String sql) throws SQLException { + return null; + } + + @Override + public void setAutoCommit(boolean autoCommit) throws SQLException { + + } + + @Override + public boolean getAutoCommit() throws SQLException { + return false; + } + + @Override + public void commit() throws SQLException { + + } + + @Override + public void rollback() throws SQLException { + + } + + @Override + public void close() throws SQLException { + + } + + @Override + public boolean isClosed() throws SQLException { + return false; + } + + @Override + public DatabaseMetaData getMetaData() throws SQLException { + //TODO: RestfulDatabaseMetaData is not implemented + return new RestfulDatabaseMetaData(); + } + + @Override + public void setReadOnly(boolean readOnly) throws SQLException { + + } + + @Override + public boolean isReadOnly() throws SQLException { + return false; + } + + @Override + public void setCatalog(String catalog) throws SQLException { + + } + + @Override + public String getCatalog() throws SQLException { + return null; + } + + @Override + public void setTransactionIsolation(int level) throws SQLException { + + } + + @Override + public int getTransactionIsolation() throws SQLException { + return 0; + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return null; + } + + @Override + public void clearWarnings() throws SQLException { + + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException { + return null; + } + + @Override + public Map> getTypeMap() throws SQLException { + return null; + } + + @Override + public void setTypeMap(Map> map) throws SQLException { + + } + + @Override + public void setHoldability(int holdability) throws SQLException { + + } + + @Override + public int getHoldability() throws SQLException { + return 0; + } + + @Override + public Savepoint setSavepoint() throws SQLException { + return null; + } + + @Override + public Savepoint setSavepoint(String name) throws SQLException { + return null; + } + + @Override + public void rollback(Savepoint savepoint) throws SQLException { + + } + + @Override + public void releaseSavepoint(Savepoint savepoint) throws SQLException { + + } + + @Override + public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return null; + } + + @Override + public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException { + return null; + } + + @Override + public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException { + return null; + } + + @Override + public Clob createClob() throws SQLException { + return null; + } + + @Override + public Blob createBlob() throws SQLException { + return null; + } + + @Override + public NClob createNClob() throws SQLException { + return null; + } + + @Override + public SQLXML createSQLXML() throws SQLException { + return null; + } + + @Override + public boolean isValid(int timeout) throws SQLException { + return false; + } + + @Override + public void setClientInfo(String name, String value) throws SQLClientInfoException { + + } + + @Override + public void setClientInfo(Properties properties) throws SQLClientInfoException { + + } + + @Override + public String getClientInfo(String name) throws SQLException { + return null; + } + + @Override + public Properties getClientInfo() throws SQLException { + return null; + } + + @Override + public Array createArrayOf(String typeName, Object[] elements) throws SQLException { + return null; + } + + @Override + public Struct createStruct(String typeName, Object[] attributes) throws SQLException { + return null; + } + + @Override + public void setSchema(String schema) throws SQLException { + + } + + @Override + public String getSchema() throws SQLException { + return null; + } + + @Override + public void abort(Executor executor) throws SQLException { + + } + + @Override + public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException { + + } + + @Override + public int getNetworkTimeout() throws SQLException { + return 0; + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } + + public String getHost() { + return host; + } + + public int getPort() { + return port; + } + + public Properties getProps() { + return props; + } + + public String getDatabase() { + return database; + } + + public String getUrl() { + return url; + } +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaData.java new file mode 100644 index 0000000000000000000000000000000000000000..2b4d7899fa6dc6fbd45e01aacd14e99b3a6fb536 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaData.java @@ -0,0 +1,886 @@ +package com.taosdata.jdbc.rs; + +import java.sql.*; + +public class RestfulDatabaseMetaData implements DatabaseMetaData { + + @Override + public boolean allProceduresAreCallable() throws SQLException { + return false; + } + + @Override + public boolean allTablesAreSelectable() throws SQLException { + return false; + } + + @Override + public String getURL() throws SQLException { + return null; + } + + @Override + public String getUserName() throws SQLException { + return null; + } + + @Override + public boolean isReadOnly() throws SQLException { + return false; + } + + @Override + public boolean nullsAreSortedHigh() throws SQLException { + return false; + } + + @Override + public boolean nullsAreSortedLow() throws SQLException { + return false; + } + + @Override + public boolean nullsAreSortedAtStart() throws SQLException { + return false; + } + + @Override + public boolean nullsAreSortedAtEnd() throws SQLException { + return false; + } + + @Override + public String getDatabaseProductName() throws SQLException { + return null; + } + + @Override + public String getDatabaseProductVersion() throws SQLException { + return null; + } + + @Override + public String getDriverName() throws SQLException { + return null; + } + + @Override + public String getDriverVersion() throws SQLException { + return null; + } + + @Override + public int getDriverMajorVersion() { + return 0; + } + + @Override + public int getDriverMinorVersion() { + return 0; + } + + @Override + public boolean usesLocalFiles() throws SQLException { + return false; + } + + @Override + public boolean usesLocalFilePerTable() throws SQLException { + return false; + } + + @Override + public boolean supportsMixedCaseIdentifiers() throws SQLException { + return false; + } + + @Override + public boolean storesUpperCaseIdentifiers() throws SQLException { + return false; + } + + @Override + public boolean storesLowerCaseIdentifiers() throws SQLException { + return false; + } + + @Override + public boolean storesMixedCaseIdentifiers() throws SQLException { + return false; + } + + @Override + public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException { + return false; + } + + @Override + public boolean storesUpperCaseQuotedIdentifiers() throws SQLException { + return false; + } + + @Override + public boolean storesLowerCaseQuotedIdentifiers() throws SQLException { + return false; + } + + @Override + public boolean storesMixedCaseQuotedIdentifiers() throws SQLException { + return false; + } + + @Override + public String getIdentifierQuoteString() throws SQLException { + return null; + } + + @Override + public String getSQLKeywords() throws SQLException { + return null; + } + + @Override + public String getNumericFunctions() throws SQLException { + return null; + } + + @Override + public String getStringFunctions() throws SQLException { + return null; + } + + @Override + public String getSystemFunctions() throws SQLException { + return null; + } + + @Override + public String getTimeDateFunctions() throws SQLException { + return null; + } + + @Override + public String getSearchStringEscape() throws SQLException { + return null; + } + + @Override + public String getExtraNameCharacters() throws SQLException { + return null; + } + + @Override + public boolean supportsAlterTableWithAddColumn() throws SQLException { + return false; + } + + @Override + public boolean supportsAlterTableWithDropColumn() throws SQLException { + return false; + } + + @Override + public boolean supportsColumnAliasing() throws SQLException { + return false; + } + + @Override + public boolean nullPlusNonNullIsNull() throws SQLException { + return false; + } + + @Override + public boolean supportsConvert() throws SQLException { + return false; + } + + @Override + public boolean supportsConvert(int fromType, int toType) throws SQLException { + return false; + } + + @Override + public boolean supportsTableCorrelationNames() throws SQLException { + return false; + } + + @Override + public boolean supportsDifferentTableCorrelationNames() throws SQLException { + return false; + } + + @Override + public boolean supportsExpressionsInOrderBy() throws SQLException { + return false; + } + + @Override + public boolean supportsOrderByUnrelated() throws SQLException { + return false; + } + + @Override + public boolean supportsGroupBy() throws SQLException { + return false; + } + + @Override + public boolean supportsGroupByUnrelated() throws SQLException { + return false; + } + + @Override + public boolean supportsGroupByBeyondSelect() throws SQLException { + return false; + } + + @Override + public boolean supportsLikeEscapeClause() throws SQLException { + return false; + } + + @Override + public boolean supportsMultipleResultSets() throws SQLException { + return false; + } + + @Override + public boolean supportsMultipleTransactions() throws SQLException { + return false; + } + + @Override + public boolean supportsNonNullableColumns() throws SQLException { + return false; + } + + @Override + public boolean supportsMinimumSQLGrammar() throws SQLException { + return false; + } + + @Override + public boolean supportsCoreSQLGrammar() throws SQLException { + return false; + } + + @Override + public boolean supportsExtendedSQLGrammar() throws SQLException { + return false; + } + + @Override + public boolean supportsANSI92EntryLevelSQL() throws SQLException { + return false; + } + + @Override + public boolean supportsANSI92IntermediateSQL() throws SQLException { + return false; + } + + @Override + public boolean supportsANSI92FullSQL() throws SQLException { + return false; + } + + @Override + public boolean supportsIntegrityEnhancementFacility() throws SQLException { + return false; + } + + @Override + public boolean supportsOuterJoins() throws SQLException { + return false; + } + + @Override + public boolean supportsFullOuterJoins() throws SQLException { + return false; + } + + @Override + public boolean supportsLimitedOuterJoins() throws SQLException { + return false; + } + + @Override + public String getSchemaTerm() throws SQLException { + return null; + } + + @Override + public String getProcedureTerm() throws SQLException { + return null; + } + + @Override + public String getCatalogTerm() throws SQLException { + return null; + } + + @Override + public boolean isCatalogAtStart() throws SQLException { + return false; + } + + @Override + public String getCatalogSeparator() throws SQLException { + return null; + } + + @Override + public boolean supportsSchemasInDataManipulation() throws SQLException { + return false; + } + + @Override + public boolean supportsSchemasInProcedureCalls() throws SQLException { + return false; + } + + @Override + public boolean supportsSchemasInTableDefinitions() throws SQLException { + return false; + } + + @Override + public boolean supportsSchemasInIndexDefinitions() throws SQLException { + return false; + } + + @Override + public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException { + return false; + } + + @Override + public boolean supportsCatalogsInDataManipulation() throws SQLException { + return false; + } + + @Override + public boolean supportsCatalogsInProcedureCalls() throws SQLException { + return false; + } + + @Override + public boolean supportsCatalogsInTableDefinitions() throws SQLException { + return false; + } + + @Override + public boolean supportsCatalogsInIndexDefinitions() throws SQLException { + return false; + } + + @Override + public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException { + return false; + } + + @Override + public boolean supportsPositionedDelete() throws SQLException { + return false; + } + + @Override + public boolean supportsPositionedUpdate() throws SQLException { + return false; + } + + @Override + public boolean supportsSelectForUpdate() throws SQLException { + return false; + } + + @Override + public boolean supportsStoredProcedures() throws SQLException { + return false; + } + + @Override + public boolean supportsSubqueriesInComparisons() throws SQLException { + return false; + } + + @Override + public boolean supportsSubqueriesInExists() throws SQLException { + return false; + } + + @Override + public boolean supportsSubqueriesInIns() throws SQLException { + return false; + } + + @Override + public boolean supportsSubqueriesInQuantifieds() throws SQLException { + return false; + } + + @Override + public boolean supportsCorrelatedSubqueries() throws SQLException { + return false; + } + + @Override + public boolean supportsUnion() throws SQLException { + return false; + } + + @Override + public boolean supportsUnionAll() throws SQLException { + return false; + } + + @Override + public boolean supportsOpenCursorsAcrossCommit() throws SQLException { + return false; + } + + @Override + public boolean supportsOpenCursorsAcrossRollback() throws SQLException { + return false; + } + + @Override + public boolean supportsOpenStatementsAcrossCommit() throws SQLException { + return false; + } + + @Override + public boolean supportsOpenStatementsAcrossRollback() throws SQLException { + return false; + } + + @Override + public int getMaxBinaryLiteralLength() throws SQLException { + return 0; + } + + @Override + public int getMaxCharLiteralLength() throws SQLException { + return 0; + } + + @Override + public int getMaxColumnNameLength() throws SQLException { + return 0; + } + + @Override + public int getMaxColumnsInGroupBy() throws SQLException { + return 0; + } + + @Override + public int getMaxColumnsInIndex() throws SQLException { + return 0; + } + + @Override + public int getMaxColumnsInOrderBy() throws SQLException { + return 0; + } + + @Override + public int getMaxColumnsInSelect() throws SQLException { + return 0; + } + + @Override + public int getMaxColumnsInTable() throws SQLException { + return 0; + } + + @Override + public int getMaxConnections() throws SQLException { + return 0; + } + + @Override + public int getMaxCursorNameLength() throws SQLException { + return 0; + } + + @Override + public int getMaxIndexLength() throws SQLException { + return 0; + } + + @Override + public int getMaxSchemaNameLength() throws SQLException { + return 0; + } + + @Override + public int getMaxProcedureNameLength() throws SQLException { + return 0; + } + + @Override + public int getMaxCatalogNameLength() throws SQLException { + return 0; + } + + @Override + public int getMaxRowSize() throws SQLException { + return 0; + } + + @Override + public boolean doesMaxRowSizeIncludeBlobs() throws SQLException { + return false; + } + + @Override + public int getMaxStatementLength() throws SQLException { + return 0; + } + + @Override + public int getMaxStatements() throws SQLException { + return 0; + } + + @Override + public int getMaxTableNameLength() throws SQLException { + return 0; + } + + @Override + public int getMaxTablesInSelect() throws SQLException { + return 0; + } + + @Override + public int getMaxUserNameLength() throws SQLException { + return 0; + } + + @Override + public int getDefaultTransactionIsolation() throws SQLException { + return 0; + } + + @Override + public boolean supportsTransactions() throws SQLException { + return false; + } + + @Override + public boolean supportsTransactionIsolationLevel(int level) throws SQLException { + return false; + } + + @Override + public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException { + return false; + } + + @Override + public boolean supportsDataManipulationTransactionsOnly() throws SQLException { + return false; + } + + @Override + public boolean dataDefinitionCausesTransactionCommit() throws SQLException { + return false; + } + + @Override + public boolean dataDefinitionIgnoredInTransactions() throws SQLException { + return false; + } + + @Override + public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException { + return null; + } + + @Override + public ResultSet getSchemas() throws SQLException { + return null; + } + + @Override + public ResultSet getCatalogs() throws SQLException { + return null; + } + + @Override + public ResultSet getTableTypes() throws SQLException { + return null; + } + + @Override + public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { + return null; + } + + @Override + public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException { + return null; + } + + @Override + public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { + return null; + } + + @Override + public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException { + return null; + } + + @Override + public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException { + return null; + } + + @Override + public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { + return null; + } + + @Override + public ResultSet getTypeInfo() throws SQLException { + return null; + } + + @Override + public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { + return null; + } + + @Override + public boolean supportsResultSetType(int type) throws SQLException { + return false; + } + + @Override + public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException { + return false; + } + + @Override + public boolean ownUpdatesAreVisible(int type) throws SQLException { + return false; + } + + @Override + public boolean ownDeletesAreVisible(int type) throws SQLException { + return false; + } + + @Override + public boolean ownInsertsAreVisible(int type) throws SQLException { + return false; + } + + @Override + public boolean othersUpdatesAreVisible(int type) throws SQLException { + return false; + } + + @Override + public boolean othersDeletesAreVisible(int type) throws SQLException { + return false; + } + + @Override + public boolean othersInsertsAreVisible(int type) throws SQLException { + return false; + } + + @Override + public boolean updatesAreDetected(int type) throws SQLException { + return false; + } + + @Override + public boolean deletesAreDetected(int type) throws SQLException { + return false; + } + + @Override + public boolean insertsAreDetected(int type) throws SQLException { + return false; + } + + @Override + public boolean supportsBatchUpdates() throws SQLException { + return false; + } + + @Override + public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { + return null; + } + + @Override + public Connection getConnection() throws SQLException { + return null; + } + + @Override + public boolean supportsSavepoints() throws SQLException { + return false; + } + + @Override + public boolean supportsNamedParameters() throws SQLException { + return false; + } + + @Override + public boolean supportsMultipleOpenResults() throws SQLException { + return false; + } + + @Override + public boolean supportsGetGeneratedKeys() throws SQLException { + return false; + } + + @Override + public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException { + return null; + } + + @Override + public boolean supportsResultSetHoldability(int holdability) throws SQLException { + return false; + } + + @Override + public int getResultSetHoldability() throws SQLException { + return 0; + } + + @Override + public int getDatabaseMajorVersion() throws SQLException { + return 0; + } + + @Override + public int getDatabaseMinorVersion() throws SQLException { + return 0; + } + + @Override + public int getJDBCMajorVersion() throws SQLException { + return 0; + } + + @Override + public int getJDBCMinorVersion() throws SQLException { + return 0; + } + + @Override + public int getSQLStateType() throws SQLException { + return 0; + } + + @Override + public boolean locatorsUpdateCopy() throws SQLException { + return false; + } + + @Override + public boolean supportsStatementPooling() throws SQLException { + return false; + } + + @Override + public RowIdLifetime getRowIdLifetime() throws SQLException { + return null; + } + + @Override + public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { + return null; + } + + @Override + public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException { + return false; + } + + @Override + public boolean autoCommitFailureClosesAllResultSets() throws SQLException { + return false; + } + + @Override + public ResultSet getClientInfoProperties() throws SQLException { + return null; + } + + @Override + public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException { + return null; + } + + @Override + public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { + return null; + } + + @Override + public boolean generatedKeyAlwaysReturned() throws SQLException { + return false; + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java new file mode 100644 index 0000000000000000000000000000000000000000..c267f660debdc6b195f6f2cd64e72b37ae0677ea --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java @@ -0,0 +1,91 @@ +package com.taosdata.jdbc.rs; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.taosdata.jdbc.AbstractTaosDriver; +import com.taosdata.jdbc.TSDBConstants; +import com.taosdata.jdbc.TSDBDriver; +import com.taosdata.jdbc.rs.util.HttpClientPoolUtil; + +import java.sql.*; +import java.util.Properties; +import java.util.logging.Logger; + +public class RestfulDriver extends AbstractTaosDriver { + + private static final String URL_PREFIX = "jdbc:TAOS-RS://"; + + static { + try { + DriverManager.registerDriver(new RestfulDriver()); + } catch (SQLException e) { + throw new RuntimeException(TSDBConstants.WrapErrMsg("can not register Restful JDBC driver"), e); + } + } + + @Override + public Connection connect(String url, Properties info) throws SQLException { + // throw SQLException if url is null + if (url == null) + throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!")); + // return null if url is not be accepted + if (!acceptsURL(url)) + return null; + + Properties props = parseURL(url, info); + String host = props.getProperty(TSDBDriver.PROPERTY_KEY_HOST, "localhost"); + String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041"); + String database = props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME); + + String loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" + + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" + + props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + "/" + + props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD) + ""; + String result = HttpClientPoolUtil.execute(loginUrl); + JSONObject jsonResult = JSON.parseObject(result); + String status = jsonResult.getString("status"); + if (!status.equals("succ")) { + throw new SQLException(jsonResult.getString("desc")); + } + + return new RestfulConnection(host, port, props, database, url); + } + + @Override + public boolean acceptsURL(String url) throws SQLException { + if (url == null) + throw new SQLException(TSDBConstants.WrapErrMsg("url is null")); + return (url != null && url.length() > 0 && url.trim().length() > 0) && url.startsWith(URL_PREFIX); + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException { + if (info == null) { + info = new Properties(); + } + if (acceptsURL(url)) { + info = parseURL(url, info); + } + return getPropertyInfo(info); + } + + @Override + public int getMajorVersion() { + return 2; + } + + @Override + public int getMinorVersion() { + return 0; + } + + @Override + public boolean jdbcCompliant() { + return false; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + return null; + } +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java new file mode 100644 index 0000000000000000000000000000000000000000..c536ae4a8957519cdcb8d64f95fbdf2934624fff --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java @@ -0,0 +1,1180 @@ +package com.taosdata.jdbc.rs; + +import com.taosdata.jdbc.TSDBConstants; +import org.apache.commons.lang3.StringUtils; + +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.URL; +import java.sql.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Map; + +public class RestfulResultSet implements ResultSet { + private boolean isClosed = false; + private int pos = -1; + private ArrayList> data; + private ArrayList fields; + + public RestfulResultSet(String str, String fieldData) { + data = new ArrayList<>(); + str = str.substring(2, str.length() - 2); + ArrayList strTemp = new ArrayList<>(Arrays.asList(str.split("],\\["))); + for (String s : strTemp) { + ArrayList curr = new ArrayList<>(Arrays.asList(s.split(","))); + data.add(curr); + } + if (!StringUtils.isBlank(fieldData)) { + fields = new ArrayList<>(); + fieldData = fieldData.substring(2, fieldData.length() - 2); + ArrayList fieldTemp = new ArrayList<>(Arrays.asList(fieldData.split("],\\["))); + for (String s : fieldTemp) { + String curr = Arrays.asList(s.split(",")).get(0); + fields.add(curr.substring(1, curr.length() - 1)); // 去掉双引号 + } + } + } + + @Override + public boolean next() throws SQLException { + if (isClosed) throw new SQLException(TSDBConstants.WrapErrMsg("Result is Closed!!!")); + if (pos < data.size() - 1) { + pos++; + return true; + } + return false; + } + + @Override + public void close() throws SQLException { + this.isClosed = true; + } + + @Override + public boolean wasNull() throws SQLException { + return data.isEmpty(); + } + + @Override + public String getString(int columnIndex) throws SQLException { + if (columnIndex > data.get(pos).size()) { + throw new SQLException(TSDBConstants.WrapErrMsg("Column Index out of range, " + columnIndex + " > " + data.get(pos).size())); + } + return data.get(pos).get(columnIndex - 1); + } + + @Override + public boolean getBoolean(int columnIndex) throws SQLException { + String result = getString(columnIndex); + if (!(result.equals("true") || result.equals("false"))) { + throw new SQLException("not boolean value"); + } + return result.equals("true"); + } + + @Override + public byte getByte(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public short getShort(int columnIndex) throws SQLException { + return Short.parseShort(getString(columnIndex)); + } + + @Override + public int getInt(int columnIndex) throws SQLException { + String result = getString(columnIndex); + return Integer.parseInt(result); + } + + @Override + public long getLong(int columnIndex) throws SQLException { + String result = getString(columnIndex); + return Long.parseLong(result); + } + + @Override + public float getFloat(int columnIndex) throws SQLException { + String result = getString(columnIndex); + return Float.parseFloat(result); + } + + @Override + public double getDouble(int columnIndex) throws SQLException { + String result = getString(columnIndex); + return Double.parseDouble(result); + } + + @Override + public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public byte[] getBytes(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Date getDate(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Time getTime(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Timestamp getTimestamp(int columnIndex) throws SQLException { + String strDate = getString(columnIndex); + strDate = strDate.substring(1, strDate.length() - 1); + return Timestamp.valueOf(strDate); + } + + @Override + public InputStream getAsciiStream(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public InputStream getUnicodeStream(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public InputStream getBinaryStream(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getString(String columnLabel) throws SQLException { + return getString(findColumn(columnLabel) + 1); + } + + @Override + public boolean getBoolean(String columnLabel) throws SQLException { + return Boolean.parseBoolean(getString(columnLabel)); + } + + @Override + public byte getByte(String columnLabel) throws SQLException { + return 0; + } + + @Override + public short getShort(String columnLabel) throws SQLException { + return Short.parseShort(getString(columnLabel)); + } + + @Override + public int getInt(String columnLabel) throws SQLException { + return Integer.parseInt(getString(columnLabel)); + } + + @Override + public long getLong(String columnLabel) throws SQLException { + return Long.parseLong(getString(columnLabel)); + } + + @Override + public float getFloat(String columnLabel) throws SQLException { + String result = getString(columnLabel); + return Float.parseFloat(result); + } + + @Override + public double getDouble(String columnLabel) throws SQLException { + return Double.parseDouble(getString(columnLabel)); + } + + @Override + public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { + return null; + } + + @Override + public byte[] getBytes(String columnLabel) throws SQLException { + return new byte[0]; + } + + @Override + public Date getDate(String columnLabel) throws SQLException { + return null; + } + + @Override + public Time getTime(String columnLabel) throws SQLException { + return null; + } + + @Override + public Timestamp getTimestamp(String columnLabel) throws SQLException { + return Timestamp.valueOf(getString(columnLabel)); + } + + @Override + public InputStream getAsciiStream(String columnLabel) throws SQLException { + return null; + } + + @Override + public InputStream getUnicodeStream(String columnLabel) throws SQLException { + return null; + } + + @Override + public InputStream getBinaryStream(String columnLabel) throws SQLException { + return null; + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return null; + //TODO: SQLFeature Not Supported +// throw new SQLFeatureNotSupportedException(); + } + + @Override + public void clearWarnings() throws SQLException { + return; + //TODO: SQLFeature Not Supported +// throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getCursorName() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public ResultSetMetaData getMetaData() throws SQLException { + return new RestfulResultSetMetaData(fields); + } + + @Override + public Object getObject(int columnIndex) throws SQLException { +// return null; + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getObject(String columnLabel) throws SQLException { +// return null; + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int findColumn(String columnLabel) throws SQLException { + return fields.indexOf(columnLabel); + } + + @Override + public Reader getCharacterStream(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Reader getCharacterStream(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public BigDecimal getBigDecimal(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public BigDecimal getBigDecimal(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isBeforeFirst() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isAfterLast() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isFirst() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isLast() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void beforeFirst() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void afterLast() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean first() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean last() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getRow() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean absolute(int row) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean relative(int rows) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean previous() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getFetchDirection() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void setFetchSize(int rows) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getFetchSize() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getType() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getConcurrency() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean rowUpdated() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean rowInserted() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean rowDeleted() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNull(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBoolean(int columnIndex, boolean x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateByte(int columnIndex, byte x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateShort(int columnIndex, short x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateInt(int columnIndex, int x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateLong(int columnIndex, long x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateFloat(int columnIndex, float x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateDouble(int columnIndex, double x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateString(int columnIndex, String x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBytes(int columnIndex, byte[] x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateDate(int columnIndex, Date x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateTime(int columnIndex, Time x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateObject(int columnIndex, Object x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNull(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBoolean(String columnLabel, boolean x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateByte(String columnLabel, byte x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateShort(String columnLabel, short x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateInt(String columnLabel, int x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateLong(String columnLabel, long x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateFloat(String columnLabel, float x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateDouble(String columnLabel, double x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateString(String columnLabel, String x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBytes(String columnLabel, byte[] x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateDate(String columnLabel, Date x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateTime(String columnLabel, Time x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateObject(String columnLabel, Object x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void insertRow() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateRow() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void deleteRow() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void refreshRow() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void cancelRowUpdates() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void moveToInsertRow() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void moveToCurrentRow() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Statement getStatement() throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getObject(int columnIndex, Map> map) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Ref getRef(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Blob getBlob(int columnIndex) throws SQLException { + return null; + } + + @Override + public Clob getClob(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Array getArray(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Object getObject(String columnLabel, Map> map) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Ref getRef(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Blob getBlob(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Clob getClob(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Array getArray(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Date getDate(int columnIndex, Calendar cal) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Date getDate(String columnLabel, Calendar cal) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Time getTime(int columnIndex, Calendar cal) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Time getTime(String columnLabel, Calendar cal) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public URL getURL(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public URL getURL(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateRef(int columnIndex, Ref x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateRef(String columnLabel, Ref x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBlob(int columnIndex, Blob x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBlob(String columnLabel, Blob x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateClob(int columnIndex, Clob x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateClob(String columnLabel, Clob x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateArray(int columnIndex, Array x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateArray(String columnLabel, Array x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public RowId getRowId(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public RowId getRowId(String columnLabel) throws SQLException { + return null; + } + + @Override + public void updateRowId(int columnIndex, RowId x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateRowId(String columnLabel, RowId x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public int getHoldability() throws SQLException { +// return 0; + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isClosed() throws SQLException { + return false; + //TODO: SQLFeature Not Supported +// throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNString(int columnIndex, String nString) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNString(String columnLabel, String nString) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNClob(int columnIndex, NClob nClob) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNClob(String columnLabel, NClob nClob) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public NClob getNClob(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public NClob getNClob(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public SQLXML getSQLXML(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public SQLXML getSQLXML(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getNString(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public String getNString(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Reader getNCharacterStream(int columnIndex) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public Reader getNCharacterStream(String columnLabel) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateClob(int columnIndex, Reader reader) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateClob(String columnLabel, Reader reader) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNClob(int columnIndex, Reader reader) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public void updateNClob(String columnLabel, Reader reader) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T getObject(int columnIndex, Class type) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T getObject(String columnLabel, Class type) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public T unwrap(Class iface) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + //TODO: SQLFeature Not Supported + throw new SQLFeatureNotSupportedException(); + } +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java new file mode 100644 index 0000000000000000000000000000000000000000..5dd61391bcf0f973726c7954e330bb5054c4e91f --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java @@ -0,0 +1,129 @@ +package com.taosdata.jdbc.rs; + +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.util.List; + +public class RestfulResultSetMetaData implements ResultSetMetaData { + + private List fields; + + public RestfulResultSetMetaData(List fields) { + this.fields = fields; + } + + @Override + public int getColumnCount() throws SQLException { + return fields.size(); + } + + @Override + public boolean isAutoIncrement(int column) throws SQLException { + return false; + } + + @Override + public boolean isCaseSensitive(int column) throws SQLException { + return false; + } + + @Override + public boolean isSearchable(int column) throws SQLException { + return false; + } + + @Override + public boolean isCurrency(int column) throws SQLException { + return false; + } + + @Override + public int isNullable(int column) throws SQLException { + return 0; + } + + @Override + public boolean isSigned(int column) throws SQLException { + return false; + } + + @Override + public int getColumnDisplaySize(int column) throws SQLException { + return 0; + } + + @Override + public String getColumnLabel(int column) throws SQLException { + return fields.get(column - 1); + } + + @Override + public String getColumnName(int column) throws SQLException { + return null; + } + + @Override + public String getSchemaName(int column) throws SQLException { + return null; + } + + @Override + public int getPrecision(int column) throws SQLException { + return 0; + } + + @Override + public int getScale(int column) throws SQLException { + return 0; + } + + @Override + public String getTableName(int column) throws SQLException { + return null; + } + + @Override + public String getCatalogName(int column) throws SQLException { + return null; + } + + @Override + public int getColumnType(int column) throws SQLException { + return 0; + } + + @Override + public String getColumnTypeName(int column) throws SQLException { + return null; + } + + @Override + public boolean isReadOnly(int column) throws SQLException { + return false; + } + + @Override + public boolean isWritable(int column) throws SQLException { + return false; + } + + @Override + public boolean isDefinitelyWritable(int column) throws SQLException { + return false; + } + + @Override + public String getColumnClassName(int column) throws SQLException { + return null; + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java new file mode 100644 index 0000000000000000000000000000000000000000..20510f01352c6b8a82ed300bd629d3184eb58894 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java @@ -0,0 +1,280 @@ +package com.taosdata.jdbc.rs; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.taosdata.jdbc.TSDBConstants; +import com.taosdata.jdbc.rs.util.HttpClientPoolUtil; + +import java.sql.*; +import java.util.Arrays; +import java.util.List; + +public class RestfulStatement implements Statement { + + private final String catalog; + private final RestfulConnection conn; + + public RestfulStatement(RestfulConnection c, String catalog) { + this.conn = c; + this.catalog = catalog; + } + + @Override + public ResultSet executeQuery(String sql) throws SQLException { + + final String url = "http://" + conn.getHost() + ":"+conn.getPort()+"/rest/sql"; + + String result = HttpClientPoolUtil.execute(url, sql); + String fields = ""; + List words = Arrays.asList(sql.split(" ")); + if (words.get(0).equalsIgnoreCase("select")) { + int index = 0; + if (words.contains("from")) { + index = words.indexOf("from"); + } + if (words.contains("FROM")) { + index = words.indexOf("FROM"); + } + fields = HttpClientPoolUtil.execute(url, "DESCRIBE " + words.get(index + 1)); + } + + JSONObject jsonObject = JSON.parseObject(result); + if (jsonObject.getString("status").equals("error")) { + throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + + jsonObject.getString("desc") + "\n" + + "error code: " + jsonObject.getString("code"))); + } + String dataStr = jsonObject.getString("data"); + if ("use".equalsIgnoreCase(fields.split(" ")[0])) { + return new RestfulResultSet(dataStr, ""); + } + + JSONObject jsonField = JSON.parseObject(fields); + if (jsonField == null) { + return new RestfulResultSet(dataStr, ""); + } + if (jsonField.getString("status").equals("error")) { + throw new SQLException(TSDBConstants.WrapErrMsg("SQL execution error: " + + jsonField.getString("desc") + "\n" + + "error code: " + jsonField.getString("code"))); + } + String fieldData = jsonField.getString("data"); + + return new RestfulResultSet(dataStr, fieldData); + } + + @Override + public int executeUpdate(String sql) throws SQLException { + return 0; + } + + @Override + public void close() throws SQLException { + + } + + @Override + public int getMaxFieldSize() throws SQLException { + return 0; + } + + @Override + public void setMaxFieldSize(int max) throws SQLException { + + } + + @Override + public int getMaxRows() throws SQLException { + return 0; + } + + @Override + public void setMaxRows(int max) throws SQLException { + + } + + @Override + public void setEscapeProcessing(boolean enable) throws SQLException { + + } + + @Override + public int getQueryTimeout() throws SQLException { + return 0; + } + + @Override + public void setQueryTimeout(int seconds) throws SQLException { + + } + + @Override + public void cancel() throws SQLException { + + } + + @Override + public SQLWarning getWarnings() throws SQLException { + return null; + } + + @Override + public void clearWarnings() throws SQLException { + + } + + @Override + public void setCursorName(String name) throws SQLException { + + } + + @Override + public boolean execute(String sql) throws SQLException { + return false; + } + + @Override + public ResultSet getResultSet() throws SQLException { + return null; + } + + @Override + public int getUpdateCount() throws SQLException { + return 0; + } + + @Override + public boolean getMoreResults() throws SQLException { + return false; + } + + @Override + public void setFetchDirection(int direction) throws SQLException { + + } + + @Override + public int getFetchDirection() throws SQLException { + return 0; + } + + @Override + public void setFetchSize(int rows) throws SQLException { + + } + + @Override + public int getFetchSize() throws SQLException { + return 0; + } + + @Override + public int getResultSetConcurrency() throws SQLException { + return 0; + } + + @Override + public int getResultSetType() throws SQLException { + return 0; + } + + @Override + public void addBatch(String sql) throws SQLException { + + } + + @Override + public void clearBatch() throws SQLException { + + } + + @Override + public int[] executeBatch() throws SQLException { + return new int[0]; + } + + @Override + public Connection getConnection() throws SQLException { + return null; + } + + @Override + public boolean getMoreResults(int current) throws SQLException { + return false; + } + + @Override + public ResultSet getGeneratedKeys() throws SQLException { + return null; + } + + @Override + public int executeUpdate(String sql, int autoGeneratedKeys) throws SQLException { + return 0; + } + + @Override + public int executeUpdate(String sql, int[] columnIndexes) throws SQLException { + return 0; + } + + @Override + public int executeUpdate(String sql, String[] columnNames) throws SQLException { + return 0; + } + + @Override + public boolean execute(String sql, int autoGeneratedKeys) throws SQLException { + return false; + } + + @Override + public boolean execute(String sql, int[] columnIndexes) throws SQLException { + return false; + } + + @Override + public boolean execute(String sql, String[] columnNames) throws SQLException { + return false; + } + + @Override + public int getResultSetHoldability() throws SQLException { + return 0; + } + + @Override + public boolean isClosed() throws SQLException { + return false; + } + + @Override + public void setPoolable(boolean poolable) throws SQLException { + + } + + @Override + public boolean isPoolable() throws SQLException { + return false; + } + + @Override + public void closeOnCompletion() throws SQLException { + + } + + @Override + public boolean isCloseOnCompletion() throws SQLException { + return false; + } + + @Override + public T unwrap(Class iface) throws SQLException { + return null; + } + + @Override + public boolean isWrapperFor(Class iface) throws SQLException { + return false; + } +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/util/HttpClientPoolUtil.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/util/HttpClientPoolUtil.java new file mode 100644 index 0000000000000000000000000000000000000000..65399b122d97254b88b6bc2ef08910d7badc5061 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/util/HttpClientPoolUtil.java @@ -0,0 +1,222 @@ +package com.taosdata.jdbc.rs.util; + +import org.apache.commons.lang3.StringUtils; +import org.apache.http.HeaderElement; +import org.apache.http.HeaderElementIterator; +import org.apache.http.HttpEntity; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.*; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.conn.ConnectionKeepAliveStrategy; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; +import org.apache.http.message.BasicHeaderElementIterator; +import org.apache.http.protocol.HTTP; +import org.apache.http.protocol.HttpContext; +import org.apache.http.util.EntityUtils; + + +public class HttpClientPoolUtil { + public static PoolingHttpClientConnectionManager cm = null; + public static CloseableHttpClient httpClient = null; + /** + * 默认content 类型 + */ + private static final String DEFAULT_CONTENT_TYPE = "application/json"; + /** + * 默认请求超时时间30s + */ + private static final int DEFAULT_TIME_OUT = 15000; + private static final int count = 32; + private static final int totalCount = 1000; + private static final int Http_Default_Keep_Time = 15000; + + /** + * 初始化连接池 + */ + public static synchronized void initPools() { + if (httpClient == null) { + cm = new PoolingHttpClientConnectionManager(); + cm.setDefaultMaxPerRoute(count); + cm.setMaxTotal(totalCount); + httpClient = HttpClients.custom().setKeepAliveStrategy(defaultStrategy).setConnectionManager(cm).build(); + } + } + + /** + * Http connection keepAlive 设置 + */ + public static ConnectionKeepAliveStrategy defaultStrategy = (response, context) -> { + HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE)); + int keepTime = Http_Default_Keep_Time * 1000; + while (it.hasNext()) { + HeaderElement headerElement = it.nextElement(); + String param = headerElement.getName(); + String value = headerElement.getValue(); + if (value != null && param.equalsIgnoreCase("timeout")) { + try { + return Long.parseLong(value) * 1000; + } catch (Exception e) { + new Exception( + "format KeepAlive timeout exception, exception:" + e.toString()) + .printStackTrace(); + } + } + } + return keepTime; + }; + + public static CloseableHttpClient getHttpClient() { + return httpClient; + } + + public static PoolingHttpClientConnectionManager getHttpConnectionManager() { + return cm; + } + + /** + * 执行http post请求 + * 默认采用Content-Type:application/json,Accept:application/json + * + * @param uri 请求地址 + * @param data 请求数据 + * @return responseBody + */ + public static String execute(String uri, String data) { + long startTime = System.currentTimeMillis(); + HttpEntity httpEntity = null; + HttpEntityEnclosingRequestBase method = null; + String responseBody = ""; + try { + if (httpClient == null) { + initPools(); + } + method = (HttpEntityEnclosingRequestBase) getRequest(uri, HttpPost.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0); + method.setEntity(new StringEntity(data)); + HttpContext context = HttpClientContext.create(); + CloseableHttpResponse httpResponse = httpClient.execute(method, context); + httpEntity = httpResponse.getEntity(); + if (httpEntity != null) { + responseBody = EntityUtils.toString(httpEntity, "UTF-8"); + } + } catch (Exception e) { + if (method != null) { + method.abort(); + } +// e.printStackTrace(); +// logger.error("execute post request exception, url:" + uri + ", exception:" + e.toString() +// + ", cost time(ms):" + (System.currentTimeMillis() - startTime)); + new Exception("execute post request exception, url:" + + uri + ", exception:" + e.toString() + + ", cost time(ms):" + (System.currentTimeMillis() - startTime)) + .printStackTrace(); + } finally { + if (httpEntity != null) { + try { + EntityUtils.consumeQuietly(httpEntity); + } catch (Exception e) { +// e.printStackTrace(); +// logger.error("close response exception, url:" + uri + ", exception:" + e.toString() +// + ", cost time(ms):" + (System.currentTimeMillis() - startTime)); + new Exception( + "close response exception, url:" + uri + + ", exception:" + e.toString() + + ", cost time(ms):" + (System.currentTimeMillis() - startTime)) + .printStackTrace(); + } + } + } + return responseBody; + } + + /** + * * 创建请求 + * + * @param uri 请求url + * @param methodName 请求的方法类型 + * @param contentType contentType类型 + * @param timeout 超时时间 + * @return HttpRequestBase 返回类型 + * @author lisc + */ + public static HttpRequestBase getRequest(String uri, String methodName, String contentType, int timeout) { + if (httpClient == null) { + initPools(); + } + HttpRequestBase method; + if (timeout <= 0) { + timeout = DEFAULT_TIME_OUT; + } + RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(timeout * 1000) + .setConnectTimeout(timeout * 1000).setConnectionRequestTimeout(timeout * 1000) + .setExpectContinueEnabled(false).build(); + if (HttpPut.METHOD_NAME.equalsIgnoreCase(methodName)) { + method = new HttpPut(uri); + } else if (HttpPost.METHOD_NAME.equalsIgnoreCase(methodName)) { + method = new HttpPost(uri); + } else if (HttpGet.METHOD_NAME.equalsIgnoreCase(methodName)) { + method = new HttpGet(uri); + } else { + method = new HttpPost(uri); + } + + if (StringUtils.isBlank(contentType)) { + contentType = DEFAULT_CONTENT_TYPE; + } + method.addHeader("Content-Type", contentType); + method.addHeader("Accept", contentType); + method.setConfig(requestConfig); + return method; + } + + /** + * 执行GET 请求 + * + * @param uri 网址 + * @return responseBody + */ + public static String execute(String uri) { + long startTime = System.currentTimeMillis(); + HttpEntity httpEntity = null; + HttpRequestBase method = null; + String responseBody = ""; + try { + if (httpClient == null) { + initPools(); + } + method = getRequest(uri, HttpGet.METHOD_NAME, DEFAULT_CONTENT_TYPE, 0); + HttpContext context = HttpClientContext.create(); + CloseableHttpResponse httpResponse = httpClient.execute(method, context); + httpEntity = httpResponse.getEntity(); + if (httpEntity != null) { + responseBody = EntityUtils.toString(httpEntity, "UTF-8"); +// logger.info("请求URL: " + uri + "+ 返回状态码:" + httpResponse.getStatusLine().getStatusCode()); + } + } catch (Exception e) { + if (method != null) { + method.abort(); + } + e.printStackTrace(); +// logger.error("execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" +// + (System.currentTimeMillis() - startTime)); + System.out.println("log:调用 HttpClientPoolUtil execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" + + (System.currentTimeMillis() - startTime)); + } finally { + if (httpEntity != null) { + try { + EntityUtils.consumeQuietly(httpEntity); + } catch (Exception e) { +// e.printStackTrace(); +// logger.error("close response exception, url:" + uri + ", exception:" + e.toString() +// + ",cost time(ms):" + (System.currentTimeMillis() - startTime)); + new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + + ",cost time(ms):" + (System.currentTimeMillis() - startTime)) + .printStackTrace(); + } + } + } + return responseBody; + } +} \ No newline at end of file diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/BaseTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/BaseTest.java index b793a47c990a930579b749b1eec95abed6ad554e..ce3735c12894807efadd1f5673fc34eee43ae01b 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/BaseTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/BaseTest.java @@ -5,24 +5,24 @@ import com.taosdata.jdbc.utils.TDNodes; import org.junit.AfterClass; import org.junit.BeforeClass; -public class BaseTest { +public abstract class BaseTest { - private static boolean testCluster = false; + private static boolean testCluster = false; private static TDNodes nodes = new TDNodes(); - + @BeforeClass public static void setupEnv() { - try{ + try { if (nodes.getTDNode(1).getTaosdPid() != null) { System.out.println("Kill taosd before running JDBC test"); nodes.getTDNode(1).setRunning(1); nodes.stop(1); } - nodes.setTestCluster(testCluster); + nodes.setTestCluster(testCluster); nodes.deploy(1); nodes.start(1); } catch (Exception e) { - e.printStackTrace(); + e.printStackTrace(); } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java new file mode 100644 index 0000000000000000000000000000000000000000..83295df5274a669ca2fc7fdbba506a97a01cc55c --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java @@ -0,0 +1,36 @@ +package com.taosdata.jdbc.cases; + +import org.junit.Test; + +import java.sql.*; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.concurrent.TimeUnit; + +public class FailOverTest { + + private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); + + @Test + public void testFailOver() throws ClassNotFoundException { + Class.forName("com.taosdata.jdbc.TSDBDriver"); + final String url = "jdbc:TAOS://:/?user=root&password=taosdata"; + + long end = System.currentTimeMillis() + 1000 * 60 * 5; + while (System.currentTimeMillis() < end) { + try (Connection conn = DriverManager.getConnection(url)) { + Statement stmt = conn.createStatement(); + ResultSet resultSet = stmt.executeQuery("select server_status()"); + resultSet.next(); + int status = resultSet.getInt("server_status()"); + System.out.println(">>>>>>>>>" + sdf.format(new Date()) + " status : " + status); + stmt.close(); + TimeUnit.SECONDS.sleep(5); + } catch (SQLException | InterruptedException e) { + e.printStackTrace(); + } + } + + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a91d1c2d6b84f1c79cf106a44645abaf87a7a3ab --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java @@ -0,0 +1,40 @@ +package com.taosdata.jdbc.rs; + +import org.junit.Assert; +import org.junit.Test; + +import java.sql.*; + +public class RestfulDriverTest { + + @Test + public void testCase001() { + try { + Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); + Connection connection = DriverManager.getConnection("jdbc:TAOS-RS://master:6041/?user=root&password=taosdata"); + Statement statement = connection.createStatement(); + ResultSet resultSet = statement.executeQuery("select * from log.log"); + ResultSetMetaData metaData = resultSet.getMetaData(); + while (resultSet.next()) { + for (int i = 1; i <= metaData.getColumnCount(); i++) { + String column = metaData.getColumnLabel(i); + String value = resultSet.getString(i); + System.out.print(column + ":" + value + "\t"); + } + System.out.println(); + } + statement.close(); + connection.close(); + } catch (SQLException | ClassNotFoundException e) { + e.printStackTrace(); + } + } + + @Test + public void testAcceptUrl() throws SQLException { + Driver driver = new RestfulDriver(); + boolean isAccept = driver.acceptsURL("jdbc:TAOS-RS://master:6041"); + Assert.assertTrue(isAccept); + } + +} diff --git a/src/connector/odbc/CMakeLists.txt b/src/connector/odbc/CMakeLists.txt index 58e7b6acf1f8424c8b8f72578a9ece027d1a9447..0d8c07041aa741793b7a1b8db20c3a3b470cf193 100644 --- a/src/connector/odbc/CMakeLists.txt +++ b/src/connector/odbc/CMakeLists.txt @@ -3,7 +3,6 @@ PROJECT(TDengine) IF (TD_LINUX_64) find_program(HAVE_ODBCINST NAMES odbcinst) - IF (HAVE_ODBCINST) include(CheckSymbolExists) # shall we revert CMAKE_REQUIRED_LIBRARIES and how? @@ -14,20 +13,43 @@ IF (TD_LINUX_64) message(WARNING "unixodbc-dev is not installed yet, you may install it under ubuntu by typing: sudo apt install unixodbc-dev") else () message(STATUS "unixodbc/unixodbc-dev are installed, and odbc connector will be built") - AUX_SOURCE_DIRECTORY(src SRC) - - # generate dynamic library (*.so) - ADD_LIBRARY(todbc SHARED ${SRC}) - SET_TARGET_PROPERTIES(todbc PROPERTIES CLEAN_DIRECT_OUTPUT 1) - SET_TARGET_PROPERTIES(todbc PROPERTIES VERSION ${TD_VER_NUMBER} SOVERSION 1) - TARGET_LINK_LIBRARIES(todbc taos) - - install(CODE "execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/install.sh ${CMAKE_BINARY_DIR})") - - ADD_SUBDIRECTORY(tests) + find_package(FLEX) + if(NOT FLEX_FOUND) + message(FATAL_ERROR "you need to install flex first") + else () + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 5.0.0) + message(WARNING "gcc 4.8.0 will complain too much about flex-generated code, we just bypass building ODBC driver in such case") + else () + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -Wconversion") + SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wconversion") + ADD_SUBDIRECTORY(src) + ADD_SUBDIRECTORY(tools) + ADD_SUBDIRECTORY(tests) + endif () + endif() endif() ELSE () message(WARNING "unixodbc is not installed yet, you may install it under ubuntu by typing: sudo apt install unixodbc") ENDIF () ENDIF () +IF (TD_WINDOWS_64) + find_package(ODBC) + if (NOT ODBC_FOUND) + message(FATAL_ERROR "you need to install ODBC first") + else () + message(STATUS "ODBC_INCLUDE_DIRS: ${ODBC_INCLUDE_DIRS}") + message(STATUS "ODBC_LIBRARIES: ${ODBC_LIBRARIES}") + message(STATUS "ODBC_CONFIG: ${ODBC_CONFIG}") + endif () + find_package(FLEX) + if(NOT FLEX_FOUND) + message(WARNING "you need to install flex first\n" + "you may go to: https://github.com/lexxmark/winflexbison\n" + "or download from: https://github.com/lexxmark/winflexbison/releases") + else () + ADD_SUBDIRECTORY(src) + ADD_SUBDIRECTORY(tools) + ADD_SUBDIRECTORY(tests) + endif() +ENDIF () diff --git a/src/connector/odbc/README.md b/src/connector/odbc/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e026884a0766772ac315acd3d0cac6535fb77557 --- /dev/null +++ b/src/connector/odbc/README.md @@ -0,0 +1,88 @@ + +# ODBC Driver # + +- **very initial implementation of ODBC driver for TAOS + +- **currently partially supported ODBC functions are: ` +SQLAllocEnv +SQLFreeEnv +SQLAllocConnect +SQLFreeConnect +SQLConnect +SQLDisconnect +SQLAllocStmt +SQLAllocHandle +SQLFreeStmt +SQLExecDirect +SQLExecDirectW +SQLNumResultCols +SQLRowCount +SQLColAttribute +SQLGetData +SQLFetch +SQLPrepare +SQLExecute +SQLGetDiagField +SQLGetDiagRec +SQLBindParameter +SQLDriverConnect +SQLSetConnectAttr +SQLDescribeCol +SQLNumParams +SQLSetStmtAttr +ConfigDSN +` + +- **internationalized, you can specify different charset/code page for easy going. eg.: insert `utf-8.zh_cn` characters into database located in linux machine, while query them out in `gb2312/gb18030/...` code page in your chinese windows machine, or vice-versa. and much fun, insert `gb2312/gb18030/...` characters into database located in linux box from +your japanese windows box, and query them out in your local chinese windows machine. + +- **enable ODBC-aware software to communicate with TAOS. + +- **enable any language with ODBC-bindings/ODBC-plugings to communicate with TAOS + +- **still going on... + +# Building and Testing +**Note**: all `work` is done in TDengine's project directory + + +# Building under Linux, use Ubuntu as example +``` +sudo apt install unixodbc unixodbc-dev flex +rm -rf debug && cmake -B debug && cmake --build debug && cmake --install debug && echo yes +``` +# Building under Windows, use Windows 10 as example +- install windows `flex` port. We use [https://github.com/lexxmark/winflexbison](url) at the moment. Please be noted to append `` to your `PATH`. +- install Microsoft Visual Studio, take VS2015 as example here +- `"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" amd64` +- `rmdir /s /q debug` +- `cmake -G "NMake Makefiles" -B debug` +- `cmake --build debug` +- `cmake --install debug` +- open your `Command Prompt` with Administrator's priviledge +- remove previously installed TAOS ODBC driver: run `C:\TDengine\todbcinst -u -f -n TAOS` +- install TAOS ODBC driver that was just built: run `C:\TDengine\todbcinst -i -n TAOS -p C:\TDengine\driver` +- add a new user dsn: run `odbcconf CONFIGDSN TAOS "DSN=TAOS_DSN|Server=:` + +# Test +we highly suggest that you build both in linux(ubuntu) and windows(windows 10) platform, because currently TAOS only has it's server-side port on linux platform. +**Note1**: content within <> shall be modified to match your environment +**Note2**: `.stmts` source files are all encoded in `UTF-8` +## start taosd in linux, suppose charset is `UTF-8` as default +``` +taosd -c ./debug/test/cfg +``` +## create data in linux +``` +./debug/build/bin/tcodbc --dsn TAOS_DSN --uid --pwd --sts ./src/connector/odbc/tests/create_data.stmts +-- +./debug/build/bin/tcodbc --dcs 'Driver=TAOS;UID=;PWD=;Server=:;client_enc=UTF-8' ./src/connector/odbc/tests/create_data.stmts +``` +## query data in windows +``` +.\debug\build\bin\tcodbc --dsn TAOS_DSN --uid --pwd --sts .\src\connector\odbc\tests\query_data.stmts +-- +.\debug\build\bin\tcodbc --dcs "Driver=TAOS;UID=;PWD=;Server=:;client_enc=UTF-8" .\src\connector\odbc\tests\query_data.stmts +``` + + diff --git a/src/connector/odbc/src/CMakeLists.txt b/src/connector/odbc/src/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2699e1bc90e162c80d27d690e1f7163747616526 --- /dev/null +++ b/src/connector/odbc/src/CMakeLists.txt @@ -0,0 +1,54 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +PROJECT(TDengine) + +IF (TD_LINUX_64) + FLEX_TARGET(todbcFlexScanner + todbc_scanner.l + ${CMAKE_CURRENT_BINARY_DIR}/todbc_scanner.c + ) + set(todbc_flex_scanner_src + ${FLEX_todbcFlexScanner_OUTPUTS} + ) + AUX_SOURCE_DIRECTORY(. SRC) + + # generate dynamic library (*.so) + ADD_LIBRARY(todbc SHARED ${SRC} ${todbc_flex_scanner_src}) + SET_TARGET_PROPERTIES(todbc PROPERTIES CLEAN_DIRECT_OUTPUT 1) + SET_TARGET_PROPERTIES(todbc PROPERTIES VERSION ${TD_VER_NUMBER} SOVERSION 1) + TARGET_LINK_LIBRARIES(todbc taos odbcinst) + target_include_directories(todbc PUBLIC .) + + install(CODE "execute_process(COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/install.sh ${CMAKE_BINARY_DIR})") +ENDIF () + +IF (TD_WINDOWS_64) + FLEX_TARGET(todbcFlexScanner + todbc_scanner.l + ${CMAKE_CURRENT_BINARY_DIR}/todbc_scanner.c + ) + set(todbc_flex_scanner_src + ${FLEX_todbcFlexScanner_OUTPUTS} + ) + AUX_SOURCE_DIRECTORY(. SRC) + + # generate dynamic library (*.dll) + ADD_LIBRARY(todbc SHARED + ${SRC} + ${todbc_flex_scanner_src} + ${CMAKE_CURRENT_BINARY_DIR}/todbc.rc + todbc.def) + TARGET_LINK_LIBRARIES(todbc taos_static odbccp32 legacy_stdio_definitions) + target_include_directories(todbc PUBLIC .) + target_compile_definitions(todbc PRIVATE "todbc_EXPORT") + + CONFIGURE_FILE("todbc.rc.in" + "${CMAKE_CURRENT_BINARY_DIR}/todbc.rc") + SET_TARGET_PROPERTIES(todbc PROPERTIES LINK_FLAGS + /DEF:todbc.def) + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /GL") + SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL") + + INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/todbc.lib DESTINATION driver) + INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/todbc.exp DESTINATION driver) + INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/todbc.dll DESTINATION driver) +ENDIF () diff --git a/src/connector/odbc/src/install.sh b/src/connector/odbc/src/install.sh index b8c04677c7199384f7bc0b66515eb04d0fe560fc..02f31de70ed76e150fbef5d388cbd8a3e9ba73b3 100755 --- a/src/connector/odbc/src/install.sh +++ b/src/connector/odbc/src/install.sh @@ -9,16 +9,18 @@ rm -f "${BLD_DIR}/template.dsn" cat > "${BLD_DIR}/template.ini" < "${BLD_DIR}/template.dsn" < +#include #include -#include +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#define UTF8_ENC "UTF-8" +#define UTF16_ENC "UCS-2LE" +#define UNICODE_ENC "UCS-4LE" +#define GB18030_ENC "GB18030" #define GET_REF(obj) atomic_load_64(&obj->refcount) #define INC_REF(obj) atomic_add_fetch_64(&obj->refcount, 1) @@ -41,15 +58,22 @@ do { obj->err.err_no = eno; \ const char* estr = tstrerror(eno); \ if (!estr) estr = "Unknown error"; \ - int n = snprintf(NULL, 0, "%s: @[%d][TSDB:%x]" err_fmt "", estr, __LINE__, eno, ##__VA_ARGS__); \ + int n = snprintf(NULL, 0, "[TSDB:%x]%s: @%s[%d]" err_fmt "", \ + eno, estr, \ + basename((char*)__FILE__), __LINE__, \ + ##__VA_ARGS__); \ if (n<0) break; \ - char *err_str = (char*)realloc(obj->err.err_str, n+1); \ + char *err_str = (char*)realloc(obj->err.err_str, (size_t)n+1); \ if (!err_str) break; \ obj->err.err_str = err_str; \ - snprintf(obj->err.err_str, n+1, "%s: @[%d][TSDB:%x]" err_fmt "", estr, __LINE__, eno, ##__VA_ARGS__); \ + snprintf(obj->err.err_str, (size_t)n+1, "[TSDB:%x]%s: @%s[%d]" err_fmt "", \ + eno, estr, \ + basename((char*)__FILE__), __LINE__, \ + ##__VA_ARGS__); \ snprintf((char*)obj->err.sql_state, sizeof(obj->err.sql_state), "%s", sqlstate); \ } while (0) + #define CLR_ERROR(obj) \ do { \ obj->err.err_no = TSDB_CODE_SUCCESS; \ @@ -57,14 +81,13 @@ do { obj->err.sql_state[0] = '\0'; \ } while (0) -#define FILL_ERROR(obj) \ -do { \ - size_t n = sizeof(obj->err.sql_state); \ - if (Sqlstate) strncpy((char*)Sqlstate, (char*)obj->err.sql_state, n); \ - if (NativeError) *NativeError = obj->err.err_no; \ - snprintf((char*)MessageText, BufferLength, "%s", obj->err.err_str); \ - if (TextLength && obj->err.err_str) *TextLength = strlen(obj->err.err_str); \ - if (TextLength && obj->err.err_str) *TextLength = utf8_chars(obj->err.err_str); \ +#define FILL_ERROR(obj) \ +do { \ + size_t n = sizeof(obj->err.sql_state); \ + if (Sqlstate) strncpy((char*)Sqlstate, (char*)obj->err.sql_state, n); \ + if (NativeError) *NativeError = obj->err.err_no; \ + snprintf((char*)MessageText, (size_t)BufferLength, "%s", obj->err.err_str); \ + if (TextLength && obj->err.err_str) *TextLength = (SQLSMALLINT)utf8_chars(obj->err.err_str); \ } while (0) #define FREE_ERROR(obj) \ @@ -87,7 +110,7 @@ do { SET_ERROR(obj, sqlstate, TSDB_CODE_QRY_INVALID_QHANDLE, err_fmt, ##__VA_ARGS__); \ } while (0); -#define SDUP(s,n) (s ? (s[n] ? (const char*)strndup((const char*)s,n) : (const char*)s) : strdup("")) +#define SDUP(s,n) (s ? (s[(size_t)n] ? (const char*)strndup((const char*)s,(size_t)n) : (const char*)s) : strdup("")) #define SFRE(x,s,n) \ do { \ if (x==(const char*)s) break; \ @@ -124,6 +147,15 @@ do { \ r_091c = SQL_SUCCESS; \ } while (0) +#define NORM_STR_LENGTH(obj, ptr, len) \ +do { \ + if ((len) < 0 && (len)!=SQL_NTS) { \ + SET_ERROR((obj), "HY090", TSDB_CODE_ODBC_BAD_ARG, ""); \ + return SQL_ERROR; \ + } \ + if (len==SQL_NTS) len = (ptr) ? (SQLSMALLINT)strlen((const char*)(ptr)) : 0; \ +} while (0) + #define PROFILING 0 #define PROFILE(statement) \ @@ -138,22 +170,67 @@ do { \ gettimeofday(&tv1, NULL); \ double delta = difftime(tv1.tv_sec, tv0.tv_sec); \ delta *= 1000000; \ - delta += (tv1.tv_usec-tv0.tv_usec); \ + delta += (double)(tv1.tv_usec-tv0.tv_usec); \ delta /= 1000000; \ D("%s: elapsed: [%.6f]s", #statement, delta); \ } while (0) - -#define CHK_CONV(statement) \ -do { \ - const char *sqlstate = statement; \ - if (sqlstate) { \ - SET_ERROR(sql, sqlstate, TSDB_CODE_ODBC_OUT_OF_RANGE, \ - "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", \ - sql_c_type(valueType), valueType, valueType, \ - taos_data_type(type), type, type, idx+1); \ - return SQL_ERROR; \ - } \ +#define CHK_CONV(todb, statement) \ +do { \ + TSDB_CONV_CODE code_0c80 = (statement); \ + switch (code_0c80) { \ + case TSDB_CONV_OK: return SQL_SUCCESS; \ + case TSDB_CONV_OOM: \ + case TSDB_CONV_NOT_AVAIL: { \ + SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_OOR: { \ + SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_OOR, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_CHAR_NOT_NUM: \ + case TSDB_CONV_CHAR_NOT_TS: { \ + SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_CHAR_NOT_NUM, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_NOT_VALID_TS: { \ + SET_ERROR(sql, "22007", TSDB_CODE_ODBC_CONV_NOT_VALID_TS, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_TRUNC_FRACTION: { \ + SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_TRUNC_FRAC, ""); \ + return todb ? SQL_ERROR : SQL_SUCCESS_WITH_INFO; \ + } break; \ + case TSDB_CONV_TRUNC: { \ + SET_ERROR(sql, "22001", TSDB_CODE_ODBC_CONV_TRUNC, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_SRC_TOO_LARGE: { \ + SET_ERROR(sql, "22001", TSDB_CODE_ODBC_CONV_SRC_TOO_LARGE, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_SRC_BAD_SEQ: { \ + SET_ERROR(sql, "22001", TSDB_CODE_ODBC_CONV_SRC_BAD_SEQ, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_SRC_INCOMPLETE: { \ + SET_ERROR(sql, "22001", TSDB_CODE_ODBC_CONV_SRC_INCOMPLETE, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_SRC_GENERAL: { \ + SET_ERROR(sql, "22001", TSDB_CODE_ODBC_CONV_SRC_GENERAL, ""); \ + return SQL_ERROR; \ + } break; \ + case TSDB_CONV_BAD_CHAR: { \ + SET_ERROR(sql, "22001", TSDB_CODE_ODBC_CONV_TRUNC, ""); \ + return SQL_ERROR; \ + } break; \ + default: { \ + DASSERTX(0, "internal logic error: %d", code_0c80); \ + return SQL_ERROR; /* never reached here */ \ + } break; \ + } \ } while (0) typedef struct env_s env_t; @@ -185,6 +262,9 @@ struct env_s { uint64_t refcount; unsigned int destroying:1; + char env_locale[64]; + char env_charset[64]; + taos_error_t err; }; @@ -192,6 +272,16 @@ struct conn_s { uint64_t refcount; env_t *env; + char client_enc[64]; // ODBC client that communicates with this driver + char server_enc[64]; // taos dynamic library that's loaded by this driver + + tsdb_conv_t *client_to_server; + tsdb_conv_t *server_to_client; + tsdb_conv_t *utf8_to_client; + tsdb_conv_t *utf16_to_utf8; + tsdb_conv_t *utf16_to_server; + tsdb_conv_t *client_to_utf8; + TAOS *taos; taos_error_t err; @@ -229,50 +319,98 @@ struct c_target_s { static pthread_once_t init_once = PTHREAD_ONCE_INIT; static void init_routine(void); -// conversions - -const char* tsdb_int64_to_bit(int64_t src, int8_t *dst); -const char* tsdb_int64_to_tinyint(int64_t src, int8_t *dst); -const char* tsdb_int64_to_smallint(int64_t src, int16_t *dst); -const char* tsdb_int64_to_int(int64_t src, int32_t *dst); -const char* tsdb_int64_to_bigint(int64_t src, int64_t *dst); -const char* tsdb_int64_to_ts(int64_t src, int64_t *dst); -const char* tsdb_int64_to_float(int64_t src, float *dst); -const char* tsdb_int64_to_double(int64_t src, double *dst); -const char* tsdb_int64_to_char(int64_t src, char *dst, size_t dlen); - -const char* tsdb_double_to_bit(double src, int precision, int8_t *dst); -const char* tsdb_double_to_tinyint(double src, int precision, int8_t *dst); -const char* tsdb_double_to_smallint(double src, int precision, int16_t *dst); -const char* tsdb_double_to_int(double src, int precision, int32_t *dst); -const char* tsdb_double_to_bigint(double src, int precision, int64_t *dst); -const char* tsdb_double_to_ts(double src, int precision, int64_t *dst); -const char* tsdb_double_to_float(double src, int precision, float *dst); -const char* tsdb_double_to_double(double src, int precision, double *dst); -const char* tsdb_double_to_char(double src, int precision, char *dst, size_t dlen); - -const char* tsdb_chars_to_bit(const char *src, int8_t *dst); -const char* tsdb_chars_to_tinyint(const char *src, int8_t *dst); -const char* tsdb_chars_to_smallint(const char *src, int16_t *dst); -const char* tsdb_chars_to_int(const char *src, int32_t *dst); -const char* tsdb_chars_to_bigint(const char *src, int64_t *dst); -const char* tsdb_chars_to_ts(const char *src, int64_t *dst); -const char* tsdb_chars_to_float(const char *src, float *dst); -const char* tsdb_chars_to_double(const char *src, double *dst); -const char* tsdb_chars_to_char(const char *src, char *dst, size_t dlen); - - -static int do_field_display_size(TAOS_FIELD *field); +static size_t do_field_display_size(TAOS_FIELD *field); + +static tsdb_conv_t* tsdb_conn_client_to_server(conn_t *conn) { + if (!conn->client_to_server) { + conn->client_to_server = tsdb_conv_open(conn->client_enc, conn->server_enc); + } + return conn->client_to_server; +} + +static tsdb_conv_t* tsdb_conn_server_to_client(conn_t *conn) { + if (!conn->server_to_client) { + conn->server_to_client = tsdb_conv_open(conn->server_enc, conn->client_enc); + } + return conn->server_to_client; +} + +static tsdb_conv_t* tsdb_conn_utf8_to_client(conn_t *conn) { + if (!conn->utf8_to_client) { + conn->utf8_to_client = tsdb_conv_open(UTF8_ENC, conn->client_enc); + } + return conn->utf8_to_client; +} + +static tsdb_conv_t* tsdb_conn_utf16_to_utf8(conn_t *conn) { + if (!conn->utf16_to_utf8) { + conn->utf16_to_utf8 = tsdb_conv_open(UTF16_ENC, UTF8_ENC); + } + return conn->utf16_to_utf8; +} + +static tsdb_conv_t* tsdb_conn_utf16_to_server(conn_t *conn) { + if (!conn->utf16_to_server) { + conn->utf16_to_server = tsdb_conv_open(UTF16_ENC, conn->server_enc); + } + return conn->utf16_to_server; +} + +static tsdb_conv_t* tsdb_conn_client_to_utf8(conn_t *conn) { + if (!conn->client_to_utf8) { + conn->client_to_utf8 = tsdb_conv_open(conn->client_enc, UTF8_ENC); + } + return conn->client_to_utf8; +} + +static void tsdb_conn_close_convs(conn_t *conn) { + if (conn->client_to_server) { + tsdb_conv_close(conn->client_to_server); + conn->client_to_server = NULL; + } + if (conn->server_to_client) { + tsdb_conv_close(conn->server_to_client); + conn->server_to_client = NULL; + } + if (conn->utf8_to_client) { + tsdb_conv_close(conn->utf8_to_client); + conn->utf8_to_client = NULL; + } + if (conn->utf16_to_utf8) { + tsdb_conv_close(conn->utf16_to_utf8); + conn->utf16_to_utf8 = NULL; + } + if (conn->utf16_to_server) { + tsdb_conv_close(conn->utf16_to_server); + conn->utf16_to_server = NULL; + } + if (conn->client_to_utf8) { + tsdb_conv_close(conn->client_to_utf8); + conn->client_to_utf8 = NULL; + } +} + +#define SFREE(buffer, v, src) \ +do { \ + const char *v_096a = (const char*)(v); \ + const char *src_6a = (const char*)(src); \ + if (v_096a && v_096a!=src_6a && !is_owned_by_stack_buffer((buffer), v_096a)) { \ + free((char*)v_096a); \ + } \ +} while (0) static SQLRETURN doSQLAllocEnv(SQLHENV *EnvironmentHandle) { pthread_once(&init_once, init_routine); env_t *env = (env_t*)calloc(1, sizeof(*env)); - if (!env) return SQL_ERROR; + if (!env) return SQL_INVALID_HANDLE; DASSERT(INC_REF(env)>0); + snprintf(env->env_locale, sizeof(env->env_locale), "%s", tsLocale); + snprintf(env->env_charset, sizeof(env->env_charset), "%s", tsCharset); + *EnvironmentHandle = env; CLR_ERROR(env); @@ -289,7 +427,7 @@ SQLRETURN SQL_API SQLAllocEnv(SQLHENV *EnvironmentHandle) static SQLRETURN doSQLFreeEnv(SQLHENV EnvironmentHandle) { env_t *env = (env_t*)EnvironmentHandle; - if (!env) return SQL_ERROR; + if (!env) return SQL_INVALID_HANDLE; DASSERT(GET_REF(env)==1); @@ -317,7 +455,12 @@ static SQLRETURN doSQLAllocConnect(SQLHENV EnvironmentHandle, SQLHDBC *ConnectionHandle) { env_t *env = (env_t*)EnvironmentHandle; - if (!env) return SQL_ERROR; + if (!env) return SQL_INVALID_HANDLE; + + if (!ConnectionHandle) { + SET_ERROR(env, "HY009", TSDB_CODE_ODBC_BAD_ARG, "ConnectionHandle [%p] not valid", ConnectionHandle); + return SQL_ERROR; + } DASSERT(INC_REF(env)>1); @@ -330,6 +473,10 @@ static SQLRETURN doSQLAllocConnect(SQLHENV EnvironmentHandle, } conn->env = env; + + snprintf(conn->client_enc, sizeof(conn->client_enc), "%s", conn->env->env_charset); + snprintf(conn->server_enc, sizeof(conn->server_enc), "%s", conn->env->env_charset); + *ConnectionHandle = conn; DASSERT(INC_REF(conn)>0); @@ -353,7 +500,7 @@ SQLRETURN SQL_API SQLAllocConnect(SQLHENV EnvironmentHandle, static SQLRETURN doSQLFreeConnect(SQLHDBC ConnectionHandle) { conn_t *conn = (conn_t*)ConnectionHandle; - if (!conn) return SQL_ERROR; + if (!conn) return SQL_INVALID_HANDLE; DASSERT(GET_REF(conn)==1); @@ -370,6 +517,7 @@ static SQLRETURN doSQLFreeConnect(SQLHDBC ConnectionHandle) conn->env = NULL; FREE_ERROR(conn); + tsdb_conn_close_convs(conn); free(conn); } while (0); @@ -388,6 +536,8 @@ static SQLRETURN doSQLConnect(SQLHDBC ConnectionHandle, SQLCHAR *UserName, SQLSMALLINT NameLength2, SQLCHAR *Authentication, SQLSMALLINT NameLength3) { + stack_buffer_t buffer; buffer.next = 0; + conn_t *conn = (conn_t*)ConnectionHandle; if (!conn) return SQL_ERROR; @@ -396,28 +546,58 @@ static SQLRETURN doSQLConnect(SQLHDBC ConnectionHandle, return SQL_ERROR; } - const char *serverName = SDUP(ServerName, NameLength1); - const char *userName = SDUP(UserName, NameLength2); - const char *auth = SDUP(Authentication, NameLength3); + NORM_STR_LENGTH(conn, ServerName, NameLength1); + NORM_STR_LENGTH(conn, UserName, NameLength2); + NORM_STR_LENGTH(conn, Authentication, NameLength3); + + if (NameLength1>SQL_MAX_DSN_LENGTH) { + SET_ERROR(conn, "HY090", TSDB_CODE_ODBC_BAD_ARG, ""); + return SQL_ERROR; + } + + tsdb_conv_t *client_to_server = tsdb_conn_client_to_server(conn); + const char *dsn = NULL; + const char *uid = NULL; + const char *pwd = NULL; + const char *svr = NULL; + char server[4096]; server[0] = '\0'; do { - if ((ServerName && !serverName) || (UserName && !userName) || (Authentication && !auth)) { + tsdb_conv(client_to_server, &buffer, (const char*)ServerName, (size_t)NameLength1, &dsn, NULL); + tsdb_conv(client_to_server, &buffer, (const char*)UserName, (size_t)NameLength2, &uid, NULL); + tsdb_conv(client_to_server, &buffer, (const char*)Authentication, (size_t)NameLength3, &pwd, NULL); + int n = SQLGetPrivateProfileString(dsn, "Server", "", server, sizeof(server)-1, "Odbc.ini"); + if (n<=0) { + snprintf(server, sizeof(server), "localhost:6030"); // all 7-bit ascii + } + tsdb_conv(client_to_server, &buffer, (const char*)server, (size_t)strlen(server), &svr, NULL); + + if ((!dsn) || (!uid) || (!pwd) || (!svr)) { SET_ERROR(conn, "HY001", TSDB_CODE_ODBC_OOM, ""); break; } + char *ip = NULL; + int port = 0; + char *p = strchr(svr, ':'); + if (p) { + ip = strndup(svr, (size_t)(p-svr)); + port = atoi(p+1); + } + // TODO: data-race // TODO: shall receive ip/port from odbc.ini - conn->taos = taos_connect("localhost", userName, auth, NULL, 0); + conn->taos = taos_connect(ip, uid, pwd, NULL, (uint16_t)port); if (!conn->taos) { - SET_ERROR(conn, "08001", terrno, "failed to connect to data source"); + SET_ERROR(conn, "08001", terrno, "failed to connect to data source for DSN[%s] @[%s:%d]", dsn, ip, port); break; } } while (0); - SFRE(serverName, ServerName, NameLength1); - SFRE(userName, UserName, NameLength2); - SFRE(auth, Authentication, NameLength3); + tsdb_conv_free(client_to_server, dsn, &buffer, (const char*)ServerName); + tsdb_conv_free(client_to_server, uid, &buffer, (const char*)UserName); + tsdb_conv_free(client_to_server, pwd, &buffer, (const char*)Authentication); + tsdb_conv_free(client_to_server, svr, &buffer, (const char*)server); return conn->taos ? SQL_SUCCESS : SQL_ERROR; } @@ -437,7 +617,7 @@ SQLRETURN SQL_API SQLConnect(SQLHDBC ConnectionHandle, static SQLRETURN doSQLDisconnect(SQLHDBC ConnectionHandle) { conn_t *conn = (conn_t*)ConnectionHandle; - if (!conn) return SQL_ERROR; + if (!conn) return SQL_INVALID_HANDLE; if (conn->taos) { taos_close(conn->taos); @@ -455,10 +635,15 @@ SQLRETURN SQL_API SQLDisconnect(SQLHDBC ConnectionHandle) } static SQLRETURN doSQLAllocStmt(SQLHDBC ConnectionHandle, - SQLHSTMT *StatementHandle) + SQLHSTMT *StatementHandle) { conn_t *conn = (conn_t*)ConnectionHandle; - if (!conn) return SQL_ERROR; + if (!conn) return SQL_INVALID_HANDLE; + + if (!StatementHandle) { + SET_ERROR(conn, "HY009", TSDB_CODE_ODBC_BAD_ARG, "StatementHandle [%p] not valid", StatementHandle); + return SQL_ERROR; + } DASSERT(INC_REF(conn)>1); @@ -495,20 +680,17 @@ static SQLRETURN doSQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, switch (HandleType) { case SQL_HANDLE_ENV: { SQLHENV env = {0}; + if (!OutputHandle) return SQL_ERROR; SQLRETURN r = doSQLAllocEnv(&env); - if (r==SQL_SUCCESS && OutputHandle) *OutputHandle = env; + if (r==SQL_SUCCESS) *OutputHandle = env; return r; } break; case SQL_HANDLE_DBC: { - SQLHDBC dbc = {0}; - SQLRETURN r = doSQLAllocConnect(InputHandle, &dbc); - if (r==SQL_SUCCESS && OutputHandle) *OutputHandle = dbc; + SQLRETURN r = doSQLAllocConnect(InputHandle, OutputHandle); return r; } break; case SQL_HANDLE_STMT: { - SQLHSTMT stmt = {0}; - SQLRETURN r = doSQLAllocStmt(InputHandle, &stmt); - if (r==SQL_SUCCESS && OutputHandle) *OutputHandle = stmt; + SQLRETURN r = doSQLAllocStmt(InputHandle, OutputHandle); return r; } break; default: { @@ -528,12 +710,20 @@ static SQLRETURN doSQLFreeStmt(SQLHSTMT StatementHandle, SQLUSMALLINT Option) { sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; - - if (Option == SQL_CLOSE) return SQL_SUCCESS; - if (Option != SQL_DROP) { - SET_ERROR(sql, "HY000", TSDB_CODE_ODBC_NOT_SUPPORT, "free statement with Option[%x] not supported yet", Option); - return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; + + switch (Option) { + case SQL_CLOSE: return SQL_SUCCESS; + case SQL_DROP: break; + case SQL_UNBIND: + case SQL_RESET_PARAMS: { + SET_ERROR(sql, "HY000", TSDB_CODE_ODBC_NOT_SUPPORT, "free statement with Option[%x] not supported yet", Option); + return SQL_ERROR; + } break; + default: { + SET_ERROR(sql, "HY092", TSDB_CODE_ODBC_OUT_OF_RANGE, "free statement with Option[%x] not supported yet", Option); + return SQL_ERROR; + } break; } DASSERT(GET_REF(sql)==1); @@ -560,6 +750,7 @@ static SQLRETURN doSQLFreeStmt(SQLHSTMT StatementHandle, sql->conn = NULL; FREE_ERROR(sql); + free(sql); return SQL_SUCCESS; @@ -573,15 +764,32 @@ SQLRETURN SQL_API SQLFreeStmt(SQLHSTMT StatementHandle, return r; } +static SQLRETURN do_exec_direct(sql_t *sql, TSDB_CONV_CODE code, const char *statement) { + if (code) CHK_CONV(1, code); + DASSERT(code==TSDB_CONV_OK); + + SQLRETURN r = SQL_ERROR; + do { + sql->rs = taos_query(sql->conn->taos, statement); + CHK_RS(r, sql, "failed to execute"); + } while (0); + + return r; +} + static SQLRETURN doSQLExecDirect(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength) { sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); + conn_t *conn = sql->conn; + + NORM_STR_LENGTH(sql, StatementText, TextLength); + if (sql->rs) { taos_free_result(sql->rs); sql->rs = NULL; @@ -599,19 +807,15 @@ static SQLRETURN doSQLExecDirect(SQLHSTMT StatementHandle, } sql->n_params = 0; - const char *stxt = SDUP(StatementText, TextLength); - - SQLRETURN r = SQL_ERROR; + SQLRETURN r = SQL_SUCCESS; + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_server = tsdb_conn_client_to_server(conn); + const char *stxt = NULL; do { - if (!stxt) { - SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, ""); - break; - } - sql->rs = taos_query(sql->conn->taos, stxt); - CHK_RS(r, sql, "failed to execute"); + TSDB_CONV_CODE code = tsdb_conv(client_to_server, &buffer, (const char*)StatementText, (size_t)TextLength, &stxt, NULL); + r = do_exec_direct(sql, code, stxt); } while (0); - - SFRE(stxt, StatementText, TextLength); + tsdb_conv_free(client_to_server, stxt, &buffer, (const char*)StatementText); return r; } @@ -624,18 +828,50 @@ SQLRETURN SQL_API SQLExecDirect(SQLHSTMT StatementHandle, return r; } +static SQLRETURN doSQLExecDirectW(SQLHSTMT hstmt, SQLWCHAR *szSqlStr, SQLINTEGER cbSqlStr) +{ + sql_t *sql = (sql_t*)hstmt; + if (!sql) return SQL_INVALID_HANDLE; + + CHK_CONN(sql); + CHK_CONN_TAOS(sql); + + conn_t *conn = sql->conn; + + if (!szSqlStr) { + SET_ERROR(sql, "HY009", TSDB_CODE_ODBC_BAD_ARG, "szSqlStr [%p] not allowed", szSqlStr); + return SQL_ERROR; + } + if (cbSqlStr < 0) { + SET_ERROR(sql, "HY090", TSDB_CODE_ODBC_BAD_ARG, ""); + return SQL_ERROR; + } + + SQLRETURN r = SQL_SUCCESS; + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_server = tsdb_conn_utf16_to_server(conn); + const char *stxt = NULL; + do { + size_t slen = (size_t)cbSqlStr * sizeof(*szSqlStr); + TSDB_CONV_CODE code = tsdb_conv(utf16_to_server, &buffer, (const char*)szSqlStr, slen, &stxt, NULL); + r = do_exec_direct(sql, code, stxt); + } while (0); + tsdb_conv_free(utf16_to_server, stxt, &buffer, (const char*)szSqlStr); + + return r; +} + SQLRETURN SQL_API SQLExecDirectW(SQLHSTMT hstmt, SQLWCHAR *szSqlStr, SQLINTEGER cbSqlStr) { - size_t bytes = 0; - SQLCHAR *utf8 = wchars_to_chars(szSqlStr, cbSqlStr, &bytes); - return SQLExecDirect(hstmt, utf8, bytes); + SQLRETURN r = doSQLExecDirectW(hstmt, szSqlStr, cbSqlStr); + return r; } static SQLRETURN doSQLNumResultCols(SQLHSTMT StatementHandle, SQLSMALLINT *ColumnCount) { sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); @@ -654,7 +890,7 @@ static SQLRETURN doSQLNumResultCols(SQLHSTMT StatementHandle, int fields = taos_field_count(sql->rs); if (ColumnCount) { - *ColumnCount = fields; + *ColumnCount = (SQLSMALLINT)fields; } return SQL_SUCCESS; @@ -677,7 +913,22 @@ static SQLRETURN doSQLRowCount(SQLHSTMT StatementHandle, CHK_CONN(sql); CHK_CONN_TAOS(sql); - if (sql->is_insert) { + // ref: https://docs.microsoft.com/en-us/sql/odbc/reference/syntax/sqlrowcount-function?view=sql-server-ver15 + // Summary + // SQLRowCount returns the number of rows affected by an UPDATE, INSERT, or DELETE statement; + // an SQL_ADD, SQL_UPDATE_BY_BOOKMARK, or SQL_DELETE_BY_BOOKMARK operation in SQLBulkOperations; + // or an SQL_UPDATE or SQL_DELETE operation in SQLSetPos. + + // how to fetch affected rows from taos? + // taos_affected_rows? + + if (1) { + SET_ERROR(sql, "IM001", TSDB_CODE_ODBC_NOT_SUPPORT, ""); + // if (RowCount) *RowCount = 0; + return SQL_SUCCESS_WITH_INFO; + } + + if (!sql->is_insert) { if (RowCount) *RowCount = 0; return SQL_SUCCESS; } @@ -735,11 +986,12 @@ static SQLRETURN doSQLColAttribute(SQLHSTMT StatementHandle, switch (FieldIdentifier) { case SQL_COLUMN_DISPLAY_SIZE: { - *NumericAttribute = do_field_display_size(field); + *NumericAttribute = (SQLLEN)do_field_display_size(field); } break; case SQL_COLUMN_LABEL: { + // todo: check BufferLength size_t n = sizeof(field->name); - strncpy(CharacterAttribute, field->name, (n>BufferLength ? BufferLength : n)); + strncpy(CharacterAttribute, field->name, (n>BufferLength ? (size_t)BufferLength : n)); } break; case SQL_COLUMN_UNSIGNED: { *NumericAttribute = SQL_FALSE; @@ -766,75 +1018,19 @@ SQLRETURN SQL_API SQLColAttribute(SQLHSTMT StatementHandle, return r; } -static SQLRETURN conv_tsdb_bool_to_c_bit(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_bool_to_c_tinyint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_bool_to_c_short(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_bool_to_c_long(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_bool_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_bool_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_bool_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_bool_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_bool_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b); -static SQLRETURN conv_tsdb_v1_to_c_tinyint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1); -static SQLRETURN conv_tsdb_v1_to_c_short(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1); -static SQLRETURN conv_tsdb_v1_to_c_long(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1); -static SQLRETURN conv_tsdb_v1_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1); -static SQLRETURN conv_tsdb_v1_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1); -static SQLRETURN conv_tsdb_v1_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1); -static SQLRETURN conv_tsdb_v1_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1); -static SQLRETURN conv_tsdb_v1_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1); -static SQLRETURN conv_tsdb_v2_to_c_short(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2); -static SQLRETURN conv_tsdb_v2_to_c_long(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2); -static SQLRETURN conv_tsdb_v2_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2); -static SQLRETURN conv_tsdb_v2_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2); -static SQLRETURN conv_tsdb_v2_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2); -static SQLRETURN conv_tsdb_v2_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2); -static SQLRETURN conv_tsdb_v2_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2); -static SQLRETURN conv_tsdb_v4_to_c_long(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4); -static SQLRETURN conv_tsdb_v4_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4); -static SQLRETURN conv_tsdb_v4_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4); -static SQLRETURN conv_tsdb_v4_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4); -static SQLRETURN conv_tsdb_v4_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4); -static SQLRETURN conv_tsdb_v4_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4); -static SQLRETURN conv_tsdb_v8_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8); -static SQLRETURN conv_tsdb_v8_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8); -static SQLRETURN conv_tsdb_v8_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8); -static SQLRETURN conv_tsdb_v8_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8); -static SQLRETURN conv_tsdb_v8_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8); -static SQLRETURN conv_tsdb_f4_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, float f4); -static SQLRETURN conv_tsdb_f4_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, float f4); -static SQLRETURN conv_tsdb_f4_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, float f4); -static SQLRETURN conv_tsdb_f4_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, float f4); -static SQLRETURN conv_tsdb_f8_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, double f8); -static SQLRETURN conv_tsdb_f8_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, double f8); -static SQLRETURN conv_tsdb_f8_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, double f8); -static SQLRETURN conv_tsdb_ts_to_c_v8(sql_t *sql, c_target_t *target, TAOS_FIELD *field, SQL_TIMESTAMP_STRUCT *ts); -static SQLRETURN conv_tsdb_ts_to_c_str(sql_t *sql, c_target_t *target, TAOS_FIELD *field, SQL_TIMESTAMP_STRUCT *ts); -static SQLRETURN conv_tsdb_ts_to_c_bin(sql_t *sql, c_target_t *target, TAOS_FIELD *field, SQL_TIMESTAMP_STRUCT *ts); -static SQLRETURN conv_tsdb_ts_to_c_ts(sql_t *sql, c_target_t *target, TAOS_FIELD *field, SQL_TIMESTAMP_STRUCT *ts); -static SQLRETURN conv_tsdb_bin_to_c_str(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const unsigned char *bin); -static SQLRETURN conv_tsdb_bin_to_c_bin(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const unsigned char *bin); -static SQLRETURN conv_tsdb_str_to_c_bit(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); -static SQLRETURN conv_tsdb_str_to_c_v1(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); -static SQLRETURN conv_tsdb_str_to_c_v2(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); -static SQLRETURN conv_tsdb_str_to_c_v4(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); -static SQLRETURN conv_tsdb_str_to_c_v8(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); -static SQLRETURN conv_tsdb_str_to_c_f4(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); -static SQLRETURN conv_tsdb_str_to_c_f8(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); -static SQLRETURN conv_tsdb_str_to_c_str(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); -static SQLRETURN conv_tsdb_str_to_c_bin(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str); - static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, SQLUSMALLINT ColumnNumber, SQLSMALLINT TargetType, SQLPOINTER TargetValue, SQLLEN BufferLength, SQLLEN *StrLen_or_Ind) { sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); + conn_t *conn = sql->conn; + if (!sql->rs) { SET_ERROR(sql, "HY000", TSDB_CODE_ODBC_NO_RESULT, ""); return SQL_ERROR; @@ -845,8 +1041,6 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, return SQL_ERROR; } - DASSERT(TargetValue); - int nfields = taos_field_count(sql->rs); TAOS_FIELD *fields = taos_fetch_fields(sql->rs); @@ -859,14 +1053,20 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, SET_ERROR(sql, "HY009", TSDB_CODE_ODBC_BAD_ARG, "NULL TargetValue not allowed for col [%d]", ColumnNumber); return SQL_ERROR; } + if (BufferLength<0) { + SET_ERROR(sql, "HY090", TSDB_CODE_ODBC_BAD_ARG, ""); + return SQL_ERROR; + } TAOS_FIELD *field = fields + ColumnNumber-1; void *row = sql->row[ColumnNumber-1]; if (!row) { - if (StrLen_or_Ind) { - *StrLen_or_Ind = SQL_NULL_DATA; + if (!StrLen_or_Ind) { + SET_ERROR(sql, "22002", TSDB_CODE_ODBC_BAD_ARG, "NULL StrLen_or_Ind not allowed for col [%d]", ColumnNumber); + return SQL_ERROR; } + *StrLen_or_Ind = SQL_NULL_DATA; return SQL_SUCCESS; } @@ -878,89 +1078,49 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, target.soi = StrLen_or_Ind; switch (field->type) { - case TSDB_DATA_TYPE_BOOL: { - int8_t v = *(int8_t*)row; - if (v) v = 1; - switch (target.ct) { - case SQL_C_BIT: return conv_tsdb_bool_to_c_bit(sql, &target, field, v); - case SQL_C_TINYINT: return conv_tsdb_bool_to_c_tinyint(sql, &target, field, v); - case SQL_C_SHORT: return conv_tsdb_bool_to_c_short(sql, &target, field, v); - case SQL_C_LONG: return conv_tsdb_bool_to_c_long(sql, &target, field, v); - case SQL_C_SBIGINT: return conv_tsdb_bool_to_c_sbigint(sql, &target, field, v); - case SQL_C_FLOAT: return conv_tsdb_bool_to_c_float(sql, &target, field, v); - case SQL_C_DOUBLE: return conv_tsdb_bool_to_c_double(sql, &target, field, v); - case SQL_C_CHAR: return conv_tsdb_bool_to_c_char(sql, &target, field, v); - case SQL_C_BINARY: return conv_tsdb_bool_to_c_binary(sql, &target, field, v); - default: { - SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, - "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", - taos_data_type(field->type), sql_c_type(target.ct), target.ct, target.ct, ColumnNumber); - return SQL_ERROR; - } - } - } break; - case TSDB_DATA_TYPE_TINYINT: { - int8_t v = *(int8_t*)row; - switch (target.ct) { - case SQL_C_TINYINT: return conv_tsdb_v1_to_c_tinyint(sql, &target, field, v); - case SQL_C_SHORT: return conv_tsdb_v1_to_c_short(sql, &target, field, v); - case SQL_C_LONG: return conv_tsdb_v1_to_c_long(sql, &target, field, v); - case SQL_C_SBIGINT: return conv_tsdb_v1_to_c_sbigint(sql, &target, field, v); - case SQL_C_FLOAT: return conv_tsdb_v1_to_c_float(sql, &target, field, v); - case SQL_C_DOUBLE: return conv_tsdb_v1_to_c_double(sql, &target, field, v); - case SQL_C_CHAR: return conv_tsdb_v1_to_c_char(sql, &target, field, v); - case SQL_C_BINARY: return conv_tsdb_v1_to_c_binary(sql, &target, field, v); - default: { - SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, - "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", - taos_data_type(field->type), sql_c_type(target.ct), target.ct, target.ct, ColumnNumber); - return SQL_ERROR; - } - } - } break; - case TSDB_DATA_TYPE_SMALLINT: { - int16_t v = *(int16_t*)row; - switch (target.ct) { - case SQL_C_SHORT: return conv_tsdb_v2_to_c_short(sql, &target, field, v); - case SQL_C_LONG: return conv_tsdb_v2_to_c_long(sql, &target, field, v); - case SQL_C_SBIGINT: return conv_tsdb_v2_to_c_sbigint(sql, &target, field, v); - case SQL_C_FLOAT: return conv_tsdb_v2_to_c_float(sql, &target, field, v); - case SQL_C_DOUBLE: return conv_tsdb_v2_to_c_double(sql, &target, field, v); - case SQL_C_CHAR: return conv_tsdb_v2_to_c_char(sql, &target, field, v); - case SQL_C_BINARY: return conv_tsdb_v2_to_c_binary(sql, &target, field, v); - default: { - SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, - "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", - taos_data_type(field->type), sql_c_type(target.ct), target.ct, target.ct, ColumnNumber); - return SQL_ERROR; - } - } - } break; - case TSDB_DATA_TYPE_INT: { - int32_t v = *(int32_t*)row; - switch (target.ct) { - case SQL_C_LONG: return conv_tsdb_v4_to_c_long(sql, &target, field, v); - case SQL_C_SBIGINT: return conv_tsdb_v4_to_c_sbigint(sql, &target, field, v); - case SQL_C_FLOAT: return conv_tsdb_v4_to_c_float(sql, &target, field, v); - case SQL_C_DOUBLE: return conv_tsdb_v4_to_c_double(sql, &target, field, v); - case SQL_C_CHAR: return conv_tsdb_v4_to_c_char(sql, &target, field, v); - case SQL_C_BINARY: return conv_tsdb_v4_to_c_binary(sql, &target, field, v); - default: { - SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, - "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", - taos_data_type(field->type), sql_c_type(target.ct), target.ct, target.ct, ColumnNumber); - return SQL_ERROR; - } - } - } break; + 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: { - int64_t v = *(int64_t*)row; + int64_t v; + switch (field->type) { + case TSDB_DATA_TYPE_BOOL: v = *(int8_t*)row; if (v) v = 1; break; + case TSDB_DATA_TYPE_TINYINT: v = *(int8_t*)row; break; + case TSDB_DATA_TYPE_SMALLINT: v = *(int16_t*)row; break; + case TSDB_DATA_TYPE_INT: v = *(int32_t*)row; break; + case TSDB_DATA_TYPE_BIGINT: // fall through + default: v = *(int64_t*)row; break; + } switch (target.ct) { - case SQL_C_SBIGINT: return conv_tsdb_v8_to_c_sbigint(sql, &target, field, v); - case SQL_C_FLOAT: return conv_tsdb_v8_to_c_float(sql, &target, field, v); - case SQL_C_DOUBLE: return conv_tsdb_v8_to_c_double(sql, &target, field, v); - case SQL_C_CHAR: return conv_tsdb_v8_to_c_char(sql, &target, field, v); - case SQL_C_BINARY: return conv_tsdb_v8_to_c_binary(sql, &target, field, v); + case SQL_C_BIT: { + CHK_CONV(0, tsdb_int64_to_bit(v, TargetValue)); + } break; + case SQL_C_TINYINT: { + CHK_CONV(0, tsdb_int64_to_tinyint(v, TargetValue)); + } break; + case SQL_C_SHORT: { + CHK_CONV(0, tsdb_int64_to_smallint(v, TargetValue)); + } break; + case SQL_C_LONG: { + CHK_CONV(0, tsdb_int64_to_int(v, TargetValue)); + } break; + case SQL_C_SBIGINT: { + CHK_CONV(0, tsdb_int64_to_bigint(v, TargetValue)); + } break; + case SQL_C_FLOAT: { + CHK_CONV(0, tsdb_int64_to_float(v, TargetValue)); + } break; + case SQL_C_DOUBLE: { + CHK_CONV(0, tsdb_int64_to_double(v, TargetValue)); + } break; + case SQL_C_CHAR: { + tsdb_conv_t *utf8_to_client = tsdb_conn_utf8_to_client(conn); + size_t len = (size_t)BufferLength; + TSDB_CONV_CODE code = tsdb_conv_write_int64(utf8_to_client, v, (char*)TargetValue, &len); + if (StrLen_or_Ind) *StrLen_or_Ind = (SQLLEN)len; + CHK_CONV(0, code); + } break; default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", @@ -972,10 +1132,21 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, case TSDB_DATA_TYPE_FLOAT: { float v = *(float*)row; switch (target.ct) { - case SQL_C_FLOAT: return conv_tsdb_f4_to_c_float(sql, &target, field, v); - case SQL_C_DOUBLE: return conv_tsdb_f4_to_c_double(sql, &target, field, v); - case SQL_C_CHAR: return conv_tsdb_f4_to_c_char(sql, &target, field, v); - case SQL_C_BINARY: return conv_tsdb_f4_to_c_binary(sql, &target, field, v); + case SQL_C_FLOAT: { + *(float*)TargetValue = v; + return SQL_SUCCESS; + } break; + case SQL_C_DOUBLE: { + *(double*)TargetValue = v; + return SQL_SUCCESS; + } break; + case SQL_C_CHAR: { + tsdb_conv_t *utf8_to_client = tsdb_conn_utf8_to_client(conn); + size_t len = (size_t)BufferLength; + TSDB_CONV_CODE code = tsdb_conv_write_double(utf8_to_client, v, (char*)TargetValue, &len); + if (StrLen_or_Ind) *StrLen_or_Ind = (SQLLEN)len; + CHK_CONV(0, code); + } break; default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", @@ -987,9 +1158,17 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, case TSDB_DATA_TYPE_DOUBLE: { double v = *(double*)row; switch (target.ct) { - case SQL_C_DOUBLE: return conv_tsdb_f8_to_c_double(sql, &target, field, v); - case SQL_C_CHAR: return conv_tsdb_f8_to_c_char(sql, &target, field, v); - case SQL_C_BINARY: return conv_tsdb_f8_to_c_binary(sql, &target, field, v); + case SQL_C_DOUBLE: { + *(double*)TargetValue = v; + return SQL_SUCCESS; + } break; + case SQL_C_CHAR: { + tsdb_conv_t *utf8_to_client = tsdb_conn_utf8_to_client(conn); + size_t len = (size_t)BufferLength; + TSDB_CONV_CODE code = tsdb_conv_write_double(utf8_to_client, v, (char*)TargetValue, &len); + if (StrLen_or_Ind) *StrLen_or_Ind = (SQLLEN)len; + CHK_CONV(0, code); + } break; default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", @@ -1002,21 +1181,31 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, SQL_TIMESTAMP_STRUCT ts = {0}; int64_t v = *(int64_t*)row; time_t t = v/1000; - struct tm tm = {0}; - localtime_r(&t, &tm); - ts.year = tm.tm_year + 1900; - ts.month = tm.tm_mon + 1; - ts.day = tm.tm_mday; - ts.hour = tm.tm_hour; - ts.minute = tm.tm_min; - ts.second = tm.tm_sec; - ts.fraction = v%1000 * 1000000; + struct tm vtm = {0}; + localtime_r(&t, &vtm); + ts.year = (SQLSMALLINT)(vtm.tm_year + 1900); + ts.month = (SQLUSMALLINT)(vtm.tm_mon + 1); + ts.day = (SQLUSMALLINT)(vtm.tm_mday); + ts.hour = (SQLUSMALLINT)(vtm.tm_hour); + ts.minute = (SQLUSMALLINT)(vtm.tm_min); + ts.second = (SQLUSMALLINT)(vtm.tm_sec); + ts.fraction = (SQLUINTEGER)(v%1000 * 1000000); switch (target.ct) { - case SQL_C_SBIGINT: return conv_tsdb_ts_to_c_v8(sql, &target, field, &ts); - case SQL_C_CHAR: return conv_tsdb_ts_to_c_str(sql, &target, field, &ts); - case SQL_C_BINARY: return conv_tsdb_ts_to_c_bin(sql, &target, field, &ts); - case SQL_C_TYPE_TIMESTAMP: - case SQL_C_TIMESTAMP: return conv_tsdb_ts_to_c_ts(sql, &target, field, &ts); + case SQL_C_SBIGINT: { + *(int64_t*)TargetValue = v; + return SQL_SUCCESS; + } break; + case SQL_C_CHAR: { + tsdb_conv_t *utf8_to_client = tsdb_conn_utf8_to_client(conn); + size_t len = (size_t)BufferLength; + TSDB_CONV_CODE code = tsdb_conv_write_timestamp(utf8_to_client, ts, (char*)TargetValue, &len); + if (StrLen_or_Ind) *StrLen_or_Ind = (SQLLEN)len; + CHK_CONV(0, code); + } break; + case SQL_C_TYPE_TIMESTAMP: { + *(SQL_TIMESTAMP_STRUCT*)TargetValue = ts; + return SQL_SUCCESS; + } break; default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", @@ -1026,10 +1215,34 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, } } break; case TSDB_DATA_TYPE_BINARY: { - const unsigned char *bin = (const unsigned char *)row; + size_t field_bytes = (size_t)field->bytes; + field_bytes -= VARSTR_HEADER_SIZE; switch (target.ct) { - case SQL_C_CHAR: return conv_tsdb_bin_to_c_str(sql, &target, field, bin); - case SQL_C_BINARY: return conv_tsdb_bin_to_c_bin(sql, &target, field, bin); + case SQL_C_CHAR: { + // taos cares nothing about what would be stored in 'binary' as most sql implementations do + // but the client requires to fetch it as a SQL_C_CHAR + // thus, we first try to decode binary to client charset + // if failed, we then do hex-serialization + + tsdb_conv_t *server_to_client = tsdb_conn_server_to_client(conn); + size_t slen = strnlen((const char*)row, field_bytes); + size_t len = (size_t)BufferLength; + TSDB_CONV_CODE code = tsdb_conv_write(server_to_client, + (const char*)row, &slen, + (char*)TargetValue, &len); + if (code==TSDB_CONV_OK) { + if (StrLen_or_Ind) *StrLen_or_Ind = (SQLLEN)((size_t)BufferLength - len); + CHK_CONV(0, code); + // code never reached here + } + + // todo: hex-serialization + const char *bad = ""; + int n = snprintf((char*)TargetValue, (size_t)BufferLength, "%s", bad); + // what if n < 0 ? + if (StrLen_or_Ind) *StrLen_or_Ind = n; + CHK_CONV(0, n>=BufferLength ? TSDB_CONV_TRUNC : TSDB_CONV_OK); + } break; default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", @@ -1039,17 +1252,19 @@ static SQLRETURN doSQLGetData(SQLHSTMT StatementHandle, } } break; case TSDB_DATA_TYPE_NCHAR: { - const char *str = (const char *)row; + size_t field_bytes = (size_t)field->bytes; + field_bytes -= VARSTR_HEADER_SIZE; switch (target.ct) { - case SQL_C_BIT: return conv_tsdb_str_to_c_bit(sql, &target, field, str); - case SQL_C_TINYINT: return conv_tsdb_str_to_c_v1(sql, &target, field, str); - case SQL_C_SHORT: return conv_tsdb_str_to_c_v2(sql, &target, field, str); - case SQL_C_LONG: return conv_tsdb_str_to_c_v4(sql, &target, field, str); - case SQL_C_SBIGINT: return conv_tsdb_str_to_c_v8(sql, &target, field, str); - case SQL_C_FLOAT: return conv_tsdb_str_to_c_f4(sql, &target, field, str); - case SQL_C_DOUBLE: return conv_tsdb_str_to_c_f8(sql, &target, field, str); - case SQL_C_CHAR: return conv_tsdb_str_to_c_str(sql, &target, field, str); - case SQL_C_BINARY: return conv_tsdb_str_to_c_bin(sql, &target, field, str); + case SQL_C_CHAR: { + tsdb_conv_t *server_to_client = tsdb_conn_server_to_client(conn); + size_t slen = strnlen((const char*)row, field_bytes); + size_t len = (size_t)BufferLength; + TSDB_CONV_CODE code = tsdb_conv_write(server_to_client, + (const char*)row, &slen, + (char*)TargetValue, &len); + if (StrLen_or_Ind) *StrLen_or_Ind = (SQLLEN)((size_t)BufferLength - len); + CHK_CONV(0, code); + } break; default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "no convertion from [%s] to [%s[%d][0x%x]] for col [%d]", @@ -1083,7 +1298,7 @@ SQLRETURN SQL_API SQLGetData(SQLHSTMT StatementHandle, static SQLRETURN doSQLFetch(SQLHSTMT StatementHandle) { sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); @@ -1107,12 +1322,18 @@ SQLRETURN SQL_API SQLFetch(SQLHSTMT StatementHandle) static SQLRETURN doSQLPrepare(SQLHSTMT StatementHandle, SQLCHAR *StatementText, SQLINTEGER TextLength) { + stack_buffer_t buffer; buffer.next = 0; + sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); + conn_t *conn = sql->conn; + + NORM_STR_LENGTH(sql, StatementText, TextLength); + if (sql->rs) { taos_free_result(sql->rs); sql->rs = NULL; @@ -1138,9 +1359,17 @@ static SQLRETURN doSQLPrepare(SQLHSTMT StatementHandle, break; } + tsdb_conv_t *client_to_server = tsdb_conn_client_to_server(conn); + const char *stxt = NULL; int ok = 0; do { - int r = taos_stmt_prepare(sql->stmt, (const char *)StatementText, TextLength); + tsdb_conv(client_to_server, &buffer, (const char*)StatementText, (size_t)TextLength, &stxt, NULL); + if ((!stxt)) { + SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, ""); + break; + } + + int r = taos_stmt_prepare(sql->stmt, stxt, (unsigned long)strlen(stxt)); if (r) { SET_ERROR(sql, "HY000", r, "failed to prepare a TAOS statement"); break; @@ -1164,7 +1393,7 @@ static SQLRETURN doSQLPrepare(SQLHSTMT StatementHandle, DASSERT(params>=0); if (params>0) { - param_bind_t *ar = (param_bind_t*)calloc(1, params * sizeof(*ar)); + param_bind_t *ar = (param_bind_t*)calloc(1, ((size_t)params) * sizeof(*ar)); if (!ar) { SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, ""); break; @@ -1177,6 +1406,8 @@ static SQLRETURN doSQLPrepare(SQLHSTMT StatementHandle, ok = 1; } while (0); + tsdb_conv_free(client_to_server, stxt, &buffer, (const char*)StatementText); + if (!ok) { taos_stmt_close(sql->stmt); sql->stmt = NULL; @@ -1206,57 +1437,86 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HY000", TSDB_CODE_ODBC_NOT_SUPPORT, "parameter [@%d] not bound yet", idx+1); return SQL_ERROR; } + if (param->ParameterValue==NULL) { + SET_ERROR(sql, "HY009", TSDB_CODE_ODBC_BAD_ARG, "ParameterValue [@%p] not allowed", param->ParameterValue); + return SQL_ERROR; + } + if (param->StrLen_or_Ind==NULL) { + SET_ERROR(sql, "HY009", TSDB_CODE_ODBC_BAD_ARG, "StrLen_or_Ind [@%p] not allowed", param->StrLen_or_Ind); + return SQL_ERROR; + } - SQLPOINTER paramValue = param->ParameterValue; - SQLSMALLINT valueType = param->ValueType; - SQLLEN *soi = param->StrLen_or_Ind; + conn_t *conn = sql->conn; - size_t offset = idx_row * sql->rowlen + sql->ptr_offset; + unsigned char *paramValue = param->ParameterValue; + SQLSMALLINT valueType = param->ValueType; + SQLLEN *soi = param->StrLen_or_Ind; - if (paramValue) paramValue += offset; - if (soi) soi = (SQLLEN*)((char*)soi + offset); + size_t offset = ((size_t)idx_row) * sql->rowlen + sql->ptr_offset; + paramValue += offset; + soi = (SQLLEN*)((char*)soi + offset); - if (soi && *soi == SQL_NULL_DATA) { + + if (*soi == SQL_NULL_DATA) { bind->is_null = (int*)&yes; return SQL_SUCCESS; } bind->is_null = (int*)&no; - int type = 0; - int bytes = 0; + int tsdb_type = 0; // taos internal data tsdb_type to be bound to + int tsdb_bytes = 0; // we don't rely much on 'tsdb_bytes' here, we delay until taos to check it internally if (sql->is_insert) { - int r = taos_stmt_get_param(sql->stmt, idx, &type, &bytes); + int r = taos_stmt_get_param(sql->stmt, idx, &tsdb_type, &tsdb_bytes); if (r) { SET_ERROR(sql, "HY000", TSDB_CODE_ODBC_OUT_OF_RANGE, "parameter [@%d] not valid", idx+1); return SQL_ERROR; } } else { + // we don't have correspondent data type from taos api + // we have to give a good guess here switch (valueType) { + case SQL_C_BIT: { + tsdb_type = TSDB_DATA_TYPE_BOOL; + } break; + case SQL_C_STINYINT: + case SQL_C_TINYINT: { + tsdb_type = TSDB_DATA_TYPE_TINYINT; + } break; + case SQL_C_SSHORT: + case SQL_C_SHORT: { + tsdb_type = TSDB_DATA_TYPE_SMALLINT; + } break; + case SQL_C_SLONG: case SQL_C_LONG: { - type = TSDB_DATA_TYPE_INT; + tsdb_type = TSDB_DATA_TYPE_INT; + } break; + case SQL_C_SBIGINT: { + tsdb_type = TSDB_DATA_TYPE_BIGINT; + } break; + case SQL_C_FLOAT: { + tsdb_type = TSDB_DATA_TYPE_FLOAT; + } break; + case SQL_C_DOUBLE: { + tsdb_type = TSDB_DATA_TYPE_DOUBLE; + } break; + case SQL_C_TIMESTAMP: { + tsdb_type = TSDB_DATA_TYPE_TIMESTAMP; + } break; + case SQL_C_CHAR: { + tsdb_type = TSDB_DATA_TYPE_BINARY; + tsdb_bytes = SQL_NTS; } break; case SQL_C_WCHAR: { - type = TSDB_DATA_TYPE_NCHAR; - bytes = SQL_NTS; + tsdb_type = TSDB_DATA_TYPE_NCHAR; + tsdb_bytes = SQL_NTS; } break; - case SQL_C_CHAR: - case SQL_C_SHORT: - case SQL_C_SSHORT: case SQL_C_USHORT: - case SQL_C_SLONG: case SQL_C_ULONG: - case SQL_C_FLOAT: - case SQL_C_DOUBLE: - case SQL_C_BIT: - case SQL_C_TINYINT: - case SQL_C_STINYINT: case SQL_C_UTINYINT: - case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_BINARY: case SQL_C_DATE: case SQL_C_TIME: - case SQL_C_TIMESTAMP: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIMESTAMP: @@ -1273,37 +1533,59 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin } // ref: https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/converting-data-from-c-to-sql-data-types?view=sql-server-ver15 - switch (type) { + switch (tsdb_type) { case TSDB_DATA_TYPE_BOOL: { - bind->buffer_type = type; + bind->buffer_type = tsdb_type; bind->buffer_length = sizeof(bind->u.b); bind->buffer = &bind->u.b; bind->length = &bind->buffer_length; switch (valueType) { - case SQL_C_LONG: { - CHK_CONV(tsdb_int64_to_bit(*(int32_t*)paramValue, &bind->u.b)); - } break; case SQL_C_BIT: { - CHK_CONV(tsdb_int64_to_bit(*(int8_t*)paramValue, &bind->u.b)); + CHK_CONV(1, tsdb_int64_to_bit(*(int8_t*)paramValue, &bind->u.b)); } break; - case SQL_C_CHAR: - case SQL_C_WCHAR: - case SQL_C_SHORT: - case SQL_C_SSHORT: - case SQL_C_USHORT: - case SQL_C_SLONG: - case SQL_C_ULONG: - case SQL_C_FLOAT: - case SQL_C_DOUBLE: case SQL_C_TINYINT: - case SQL_C_STINYINT: - case SQL_C_UTINYINT: - case SQL_C_SBIGINT: - case SQL_C_UBIGINT: - case SQL_C_BINARY: - case SQL_C_DATE: - case SQL_C_TIME: - case SQL_C_TIMESTAMP: + case SQL_C_STINYINT: { + CHK_CONV(1, tsdb_int64_to_bit(*(int8_t*)paramValue, &bind->u.b)); + } break; + case SQL_C_SHORT: + case SQL_C_SSHORT: { + CHK_CONV(1, tsdb_int64_to_bit(*(int16_t*)paramValue, &bind->u.b)); + } break; + case SQL_C_LONG: + case SQL_C_SLONG: { + CHK_CONV(1, tsdb_int64_to_bit(*(int32_t*)paramValue, &bind->u.b)); + } break; + case SQL_C_SBIGINT: { + CHK_CONV(1, tsdb_int64_to_bit(*(int64_t*)paramValue, &bind->u.b)); + } break; + case SQL_C_FLOAT: { + CHK_CONV(1, tsdb_double_to_bit(*(float*)paramValue, &bind->u.b)); + } break; + case SQL_C_DOUBLE: { + CHK_CONV(1, tsdb_double_to_bit(*(double*)paramValue, &bind->u.b)); + } break; + case SQL_C_CHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_utf8 = tsdb_conn_client_to_utf8(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + CHK_CONV(1, tsdb_conv_chars_to_bit(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.b)); + } break; + case SQL_C_WCHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_utf8 = tsdb_conn_utf16_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_bit(utf16_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.b)); + } break; + case SQL_C_USHORT: + case SQL_C_ULONG: + case SQL_C_UTINYINT: + case SQL_C_UBIGINT: + case SQL_C_BINARY: + case SQL_C_DATE: + case SQL_C_TIME: + case SQL_C_TIMESTAMP: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: case SQL_C_TYPE_TIMESTAMP: @@ -1313,39 +1595,54 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; case TSDB_DATA_TYPE_TINYINT: { - bind->buffer_type = type; + bind->buffer_type = tsdb_type; bind->buffer_length = sizeof(bind->u.v1); bind->buffer = &bind->u.v1; bind->length = &bind->buffer_length; switch (valueType) { + case SQL_C_BIT: { + CHK_CONV(1, tsdb_int64_to_tinyint(*(int8_t*)paramValue, &bind->u.v1)); + } break; + case SQL_C_STINYINT: case SQL_C_TINYINT: { - CHK_CONV(tsdb_int64_to_tinyint(*(int8_t*)paramValue, &bind->u.v1)); + CHK_CONV(1, tsdb_int64_to_tinyint(*(int8_t*)paramValue, &bind->u.v1)); } break; + case SQL_C_SSHORT: case SQL_C_SHORT: { - CHK_CONV(tsdb_int64_to_tinyint(*(int16_t*)paramValue, &bind->u.v1)); + CHK_CONV(1, tsdb_int64_to_tinyint(*(int16_t*)paramValue, &bind->u.v1)); } break; + case SQL_C_SLONG: case SQL_C_LONG: { - CHK_CONV(tsdb_int64_to_tinyint(*(int32_t*)paramValue, &bind->u.v1)); + CHK_CONV(1, tsdb_int64_to_tinyint(*(int32_t*)paramValue, &bind->u.v1)); } break; case SQL_C_SBIGINT: { - CHK_CONV(tsdb_int64_to_tinyint(*(int64_t*)paramValue, &bind->u.v1)); + CHK_CONV(1, tsdb_int64_to_tinyint(*(int64_t*)paramValue, &bind->u.v1)); + } break; + case SQL_C_CHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_utf8 = tsdb_conn_client_to_utf8(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + CHK_CONV(1, tsdb_conv_chars_to_tinyint(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v1)); + // CHK_CONV(1, tsdb_chars_to_tinyint((const char *)paramValue, (size_t)*soi, &bind->u.v1)); + } break; + case SQL_C_WCHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_utf8 = tsdb_conn_utf16_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_tinyint(utf16_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v1)); } break; - case SQL_C_CHAR: - case SQL_C_WCHAR: - case SQL_C_SSHORT: case SQL_C_USHORT: - case SQL_C_SLONG: case SQL_C_ULONG: case SQL_C_FLOAT: case SQL_C_DOUBLE: - case SQL_C_BIT: - case SQL_C_STINYINT: case SQL_C_UTINYINT: case SQL_C_UBIGINT: case SQL_C_BINARY: @@ -1361,36 +1658,55 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; case TSDB_DATA_TYPE_SMALLINT: { - bind->buffer_type = type; + bind->buffer_type = tsdb_type; bind->buffer_length = sizeof(bind->u.v2); bind->buffer = &bind->u.v2; bind->length = &bind->buffer_length; switch (valueType) { - case SQL_C_LONG: { - CHK_CONV(tsdb_int64_to_smallint(*(int32_t*)paramValue, &bind->u.v2)); + case SQL_C_BIT: { + CHK_CONV(1, tsdb_int64_to_smallint(*(int8_t*)paramValue, &bind->u.v2)); } break; - case SQL_C_SHORT: { - CHK_CONV(tsdb_int64_to_smallint(*(int16_t*)paramValue, &bind->u.v2)); + case SQL_C_STINYINT: + case SQL_C_TINYINT: { + CHK_CONV(1, tsdb_int64_to_smallint(*(int8_t*)paramValue, &bind->u.v2)); } break; - case SQL_C_CHAR: - case SQL_C_WCHAR: case SQL_C_SSHORT: - case SQL_C_USHORT: + case SQL_C_SHORT: { + CHK_CONV(1, tsdb_int64_to_smallint(*(int16_t*)paramValue, &bind->u.v2)); + } break; case SQL_C_SLONG: + case SQL_C_LONG: { + CHK_CONV(1, tsdb_int64_to_smallint(*(int32_t*)paramValue, &bind->u.v2)); + } break; + case SQL_C_SBIGINT: { + CHK_CONV(1, tsdb_int64_to_smallint(*(int64_t*)paramValue, &bind->u.v2)); + } break; + case SQL_C_CHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_utf8 = tsdb_conn_client_to_utf8(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + CHK_CONV(1, tsdb_conv_chars_to_smallint(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v2)); + // CHK_CONV(1, tsdb_chars_to_smallint((const char*)paramValue, (size_t)*soi, &bind->u.v2)); + } break; + case SQL_C_WCHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_utf8 = tsdb_conn_utf16_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_smallint(utf16_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v2)); + } break; + case SQL_C_USHORT: case SQL_C_ULONG: case SQL_C_FLOAT: case SQL_C_DOUBLE: - case SQL_C_BIT: - case SQL_C_TINYINT: - case SQL_C_STINYINT: case SQL_C_UTINYINT: - case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_BINARY: case SQL_C_DATE: @@ -1405,34 +1721,55 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; case TSDB_DATA_TYPE_INT: { - bind->buffer_type = type; + bind->buffer_type = tsdb_type; bind->buffer_length = sizeof(bind->u.v4); bind->buffer = &bind->u.v4; bind->length = &bind->buffer_length; switch (valueType) { - case SQL_C_LONG: { - CHK_CONV(tsdb_int64_to_int(*(int32_t*)paramValue, &bind->u.v4)); + case SQL_C_BIT: { + CHK_CONV(1, tsdb_int64_to_int(*(int8_t*)paramValue, &bind->u.v4)); + } break; + case SQL_C_STINYINT: + case SQL_C_TINYINT: { + CHK_CONV(1, tsdb_int64_to_int(*(int8_t*)paramValue, &bind->u.v4)); } break; - case SQL_C_CHAR: - case SQL_C_WCHAR: - case SQL_C_SHORT: case SQL_C_SSHORT: - case SQL_C_USHORT: + case SQL_C_SHORT: { + CHK_CONV(1, tsdb_int64_to_int(*(int16_t*)paramValue, &bind->u.v4)); + } break; case SQL_C_SLONG: + case SQL_C_LONG: { + CHK_CONV(1, tsdb_int64_to_int(*(int32_t*)paramValue, &bind->u.v4)); + } break; + case SQL_C_SBIGINT: { + CHK_CONV(1, tsdb_int64_to_int(*(int64_t*)paramValue, &bind->u.v4)); + } break; + case SQL_C_CHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_utf8 = tsdb_conn_client_to_utf8(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + CHK_CONV(1, tsdb_conv_chars_to_int(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v4)); + // CHK_CONV(1, tsdb_chars_to_int((const char*)paramValue, (size_t)*soi, &bind->u.v4)); + } break; + case SQL_C_WCHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_utf8 = tsdb_conn_utf16_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_int(utf16_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v4)); + } break; + case SQL_C_USHORT: case SQL_C_ULONG: case SQL_C_FLOAT: case SQL_C_DOUBLE: - case SQL_C_BIT: - case SQL_C_TINYINT: - case SQL_C_STINYINT: case SQL_C_UTINYINT: - case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_BINARY: case SQL_C_DATE: @@ -1447,35 +1784,54 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; case TSDB_DATA_TYPE_BIGINT: { - bind->buffer_type = type; + bind->buffer_type = tsdb_type; bind->buffer_length = sizeof(bind->u.v8); bind->buffer = &bind->u.v8; bind->length = &bind->buffer_length; switch (valueType) { - case SQL_C_SBIGINT: { - bind->u.v8 = *(int64_t*)paramValue; + case SQL_C_BIT: { + CHK_CONV(1, tsdb_int64_to_bigint(*(int8_t*)paramValue, &bind->u.v8)); } break; - case SQL_C_LONG: { - bind->u.v8 = *(int32_t*)paramValue; + case SQL_C_STINYINT: + case SQL_C_TINYINT: { + CHK_CONV(1, tsdb_int64_to_bigint(*(int8_t*)paramValue, &bind->u.v8)); } break; - case SQL_C_CHAR: - case SQL_C_WCHAR: - case SQL_C_SHORT: case SQL_C_SSHORT: - case SQL_C_USHORT: + case SQL_C_SHORT: { + CHK_CONV(1, tsdb_int64_to_bigint(*(int16_t*)paramValue, &bind->u.v8)); + } break; case SQL_C_SLONG: + case SQL_C_LONG: { + CHK_CONV(1, tsdb_int64_to_bigint(*(int32_t*)paramValue, &bind->u.v8)); + } break; + case SQL_C_SBIGINT: { + CHK_CONV(1, tsdb_int64_to_bigint(*(int64_t*)paramValue, &bind->u.v8)); + } break; + case SQL_C_CHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_utf8 = tsdb_conn_client_to_utf8(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + CHK_CONV(1, tsdb_conv_chars_to_bigint(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v8)); + // CHK_CONV(1, tsdb_chars_to_bigint((const char*)paramValue, (size_t)*soi, &bind->u.v8)); + } break; + case SQL_C_WCHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_utf8 = tsdb_conn_utf16_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_bigint(utf16_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v8)); + } break; + case SQL_C_USHORT: case SQL_C_ULONG: case SQL_C_FLOAT: case SQL_C_DOUBLE: - case SQL_C_BIT: - case SQL_C_TINYINT: - case SQL_C_STINYINT: case SQL_C_UTINYINT: case SQL_C_UBIGINT: case SQL_C_BINARY: @@ -1491,36 +1847,58 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; case TSDB_DATA_TYPE_FLOAT: { - bind->buffer_type = type; + bind->buffer_type = tsdb_type; bind->buffer_length = sizeof(bind->u.f4); bind->buffer = &bind->u.f4; bind->length = &bind->buffer_length; switch (valueType) { - case SQL_C_DOUBLE: { - bind->u.f4 = *(double*)paramValue; + case SQL_C_BIT: { + CHK_CONV(1, tsdb_int64_to_float(*(int8_t*)paramValue, &bind->u.f4)); + } break; + case SQL_C_STINYINT: + case SQL_C_TINYINT: { + CHK_CONV(1, tsdb_int64_to_float(*(int8_t*)paramValue, &bind->u.f4)); + } break; + case SQL_C_SSHORT: + case SQL_C_SHORT: { + CHK_CONV(1, tsdb_int64_to_float(*(int16_t*)paramValue, &bind->u.f4)); + } break; + case SQL_C_SLONG: + case SQL_C_LONG: { + CHK_CONV(1, tsdb_int64_to_float(*(int32_t*)paramValue, &bind->u.f4)); + } break; + case SQL_C_SBIGINT: { + CHK_CONV(1, tsdb_int64_to_float(*(int64_t*)paramValue, &bind->u.f4)); } break; case SQL_C_FLOAT: { bind->u.f4 = *(float*)paramValue; } break; - case SQL_C_CHAR: - case SQL_C_WCHAR: - case SQL_C_SHORT: - case SQL_C_SSHORT: + case SQL_C_DOUBLE: { + bind->u.f4 = (float)*(double*)paramValue; + } break; + case SQL_C_CHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_utf8 = tsdb_conn_client_to_utf8(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + CHK_CONV(1, tsdb_conv_chars_to_float(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.f4)); + } break; + case SQL_C_WCHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_utf8 = tsdb_conn_utf16_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_float(utf16_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.f4)); + } break; case SQL_C_USHORT: - case SQL_C_LONG: - case SQL_C_SLONG: case SQL_C_ULONG: - case SQL_C_BIT: - case SQL_C_TINYINT: - case SQL_C_STINYINT: case SQL_C_UTINYINT: - case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_BINARY: case SQL_C_DATE: @@ -1535,34 +1913,59 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; case TSDB_DATA_TYPE_DOUBLE: { - bind->buffer_type = type; + bind->buffer_type = tsdb_type; bind->buffer_length = sizeof(bind->u.f8); bind->buffer = &bind->u.f8; bind->length = &bind->buffer_length; switch (valueType) { + case SQL_C_BIT: { + CHK_CONV(1, tsdb_int64_to_double(*(int8_t*)paramValue, &bind->u.f8)); + } break; + case SQL_C_STINYINT: + case SQL_C_TINYINT: { + CHK_CONV(1, tsdb_int64_to_double(*(int8_t*)paramValue, &bind->u.f8)); + } break; + case SQL_C_SSHORT: + case SQL_C_SHORT: { + CHK_CONV(1, tsdb_int64_to_double(*(int16_t*)paramValue, &bind->u.f8)); + } break; + case SQL_C_SLONG: + case SQL_C_LONG: { + CHK_CONV(1, tsdb_int64_to_double(*(int32_t*)paramValue, &bind->u.f8)); + } break; + case SQL_C_SBIGINT: { + CHK_CONV(1, tsdb_int64_to_double(*(int64_t*)paramValue, &bind->u.f8)); + } break; + case SQL_C_FLOAT: { + bind->u.f8 = *(float*)paramValue; + } break; case SQL_C_DOUBLE: { bind->u.f8 = *(double*)paramValue; } break; - case SQL_C_CHAR: - case SQL_C_WCHAR: - case SQL_C_SHORT: - case SQL_C_SSHORT: + case SQL_C_CHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_utf8 = tsdb_conn_client_to_utf8(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + CHK_CONV(1, tsdb_conv_chars_to_double(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.f8)); + // CHK_CONV(1, tsdb_chars_to_double((const char*)paramValue, (size_t)*soi, &bind->u.f8)); + } break; + case SQL_C_WCHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_utf8 = tsdb_conn_utf16_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_double(utf16_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.f8)); + } break; case SQL_C_USHORT: - case SQL_C_LONG: - case SQL_C_SLONG: case SQL_C_ULONG: - case SQL_C_FLOAT: - case SQL_C_BIT: - case SQL_C_TINYINT: - case SQL_C_STINYINT: case SQL_C_UTINYINT: - case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_BINARY: case SQL_C_DATE: @@ -1577,35 +1980,51 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; - case TSDB_DATA_TYPE_BINARY: { - bind->buffer_type = type; + case TSDB_DATA_TYPE_TIMESTAMP: { + bind->buffer_type = tsdb_type; + bind->buffer_length = sizeof(bind->u.v8); + bind->buffer = &bind->u.v8; bind->length = &bind->buffer_length; switch (valueType) { + case SQL_C_CHAR: { + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *client_to_utf8 = tsdb_conn_client_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_timestamp_ts(client_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v8)); + } break; case SQL_C_WCHAR: { - DASSERT(soi); - DASSERT(*soi != SQL_NTS); - size_t bytes = 0; - SQLCHAR *utf8 = wchars_to_chars(paramValue, *soi/2, &bytes); - bind->allocated = 1; - bind->u.bin = utf8; - bind->buffer_length = bytes; - bind->buffer = bind->u.bin; + stack_buffer_t buffer; buffer.next = 0; + tsdb_conv_t *utf16_to_utf8 = tsdb_conn_utf16_to_utf8(conn); + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + CHK_CONV(1, tsdb_conv_chars_to_timestamp_ts(utf16_to_utf8, &buffer, (const char *)paramValue, slen, &bind->u.v8)); + } break; + case SQL_C_SBIGINT: { + int64_t t = *(int64_t*)paramValue; + bind->u.v8 = t; } break; - case SQL_C_BINARY: { - bind->u.bin = (unsigned char*)paramValue; - if (*soi == SQL_NTS) { - bind->buffer_length = strlen((const char*)paramValue); - } else { - bind->buffer_length = *soi; + case SQL_C_TYPE_TIMESTAMP: { + SQL_TIMESTAMP_STRUCT ts = *(SQL_TIMESTAMP_STRUCT*)paramValue; + struct tm vtm = {0}; + vtm.tm_year = ts.year - 1900; + vtm.tm_mon = ts.month - 1; + vtm.tm_mday = ts.day; + vtm.tm_hour = ts.hour; + vtm.tm_min = ts.minute; + vtm.tm_sec = ts.second; + int64_t t = (int64_t) mktime(&vtm); + if (t==-1) { + CHK_CONV(1, TSDB_CONV_NOT_VALID_TS); + // code never reached here } - bind->buffer = bind->u.bin; + bind->u.ts = t * 1000 + ts.fraction / 1000000; } break; - case SQL_C_CHAR: case SQL_C_SHORT: case SQL_C_SSHORT: case SQL_C_USHORT: @@ -1618,53 +2037,107 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin case SQL_C_TINYINT: case SQL_C_STINYINT: case SQL_C_UTINYINT: - case SQL_C_SBIGINT: case SQL_C_UBIGINT: + case SQL_C_BINARY: case SQL_C_DATE: case SQL_C_TIME: case SQL_C_TIMESTAMP: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: - case SQL_C_TYPE_TIMESTAMP: case SQL_C_NUMERIC: case SQL_C_GUID: default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; - case TSDB_DATA_TYPE_TIMESTAMP: { - bind->buffer_type = type; - bind->buffer_length = sizeof(bind->u.v8); - bind->buffer = &bind->u.v8; + case TSDB_DATA_TYPE_BINARY: { + bind->buffer_type = tsdb_type; bind->length = &bind->buffer_length; switch (valueType) { case SQL_C_WCHAR: { - DASSERT(soi); - DASSERT(*soi != SQL_NTS); - size_t bytes = 0; - int r = 0; - int64_t t = 0; - SQLCHAR *utf8 = wchars_to_chars(paramValue, *soi/2, &bytes); - // why cast utf8 to 'char*' ? - r = taosParseTime((char*)utf8, &t, strlen((const char*)utf8), TSDB_TIME_PRECISION_MILLI, 0); - bind->u.v8 = t; - free(utf8); - if (r) { - SET_ERROR(sql, "22007", TSDB_CODE_ODBC_OUT_OF_RANGE, - "convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d] failed", - sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); - return SQL_ERROR; + // taos cares nothing about what would be stored in 'binary' as most sql implementations do + // thus, we just copy it as is + // it's caller's responsibility to maintain data-consistency + // if he/she is going to use 'binary' to store characters + // taos might extend it's sql syntax to let user specify + // what charset is to be used for specific 'binary' field when + // table is to be created + // in such way, 'binary' would be 'internationalized' + // but actually speaking, normally, 'char' field is a better + // one for this purpose + size_t slen = (size_t)*soi; + DASSERT(slen != SQL_NTS); + bind->u.bin = (unsigned char*)malloc(slen + 1); // add null-terminator, just for case of use + if (!bind->u.bin) { + CHK_CONV(1, TSDB_CONV_OOM); + // code never reached here } + memcpy(bind->u.bin, paramValue, slen); + bind->buffer_length = slen; + bind->buffer = bind->u.bin; + CHK_CONV(1, TSDB_CONV_OK); + + // tsdb_conv_t *utf16_to_server = tsdb_conn_utf16_to_server(conn); + // size_t slen = (size_t)*soi; + // DASSERT(slen != SQL_NTS); + // const char *buf = NULL; + // size_t blen = 0; + // TSDB_CONV_CODE code = tsdb_conv(utf16_to_server, NULL, (const char *)paramValue, slen, &buf, &blen); + // if (code==TSDB_CONV_OK) { + // if (buf!=(const char*)paramValue) { + // bind->allocated = 1; + // } + // bind->u.bin = (unsigned char*)buf; + // bind->buffer_length = blen; + // bind->buffer = bind->u.bin; + // } + // CHK_CONV(1, code); } break; - case SQL_C_SBIGINT: { - int64_t t = *(int64_t*)paramValue; - bind->u.v8 = t; + case SQL_C_CHAR: { + // taos cares nothing about what would be stored in 'binary' as most sql implementations do + // thus, we just copy it as is + // it's caller's responsibility to maintain data-consistency + // if he/she is going to use 'binary' to store characters + // taos might extend it's sql syntax to let user specify + // what charset is to be used for specific 'binary' field when + // table is to be created + // in such way, 'binary' would be 'internationalized' + // but actually speaking, normally, 'char' field is a better + // one for this purpose + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + // we can not use strndup, because ODBC client might pass in a buffer without null-terminated + bind->u.bin = (unsigned char*)malloc(slen + 1); // add null-terminator, just for case of use + if (!bind->u.bin) { + CHK_CONV(1, TSDB_CONV_OOM); + // code never reached here + } + memcpy(bind->u.bin, paramValue, slen); + bind->buffer_length = slen; + bind->buffer = bind->u.bin; + CHK_CONV(1, TSDB_CONV_OK); + // code never reached here + + // tsdb_conv_t *client_to_server = tsdb_conn_client_to_server(conn); + // size_t slen = (size_t)*soi; + // if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + // const char *buf = NULL; + // size_t blen = 0; + // TSDB_CONV_CODE code = tsdb_conv(client_to_server, NULL, (const char *)paramValue, slen, &buf, &blen); + // if (code==TSDB_CONV_OK) { + // if (buf!=(const char*)paramValue) { + // bind->allocated = 1; + // } + // bind->u.bin = (unsigned char*)buf; + // bind->buffer_length = blen; + // bind->buffer = bind->u.bin; + // } + // CHK_CONV(1, code); } break; case SQL_C_SHORT: case SQL_C_SSHORT: @@ -1678,6 +2151,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin case SQL_C_TINYINT: case SQL_C_STINYINT: case SQL_C_UTINYINT: + case SQL_C_SBIGINT: case SQL_C_UBIGINT: case SQL_C_BINARY: case SQL_C_DATE: @@ -1685,40 +2159,55 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin case SQL_C_TIMESTAMP: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: - case SQL_C_TYPE_TIMESTAMP: + case SQL_C_TYPE_TIMESTAMP: // we don't provide auto-converstion case SQL_C_NUMERIC: case SQL_C_GUID: default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } } break; case TSDB_DATA_TYPE_NCHAR: { - bind->buffer_type = type; + bind->buffer_type = tsdb_type; bind->length = &bind->buffer_length; switch (valueType) { case SQL_C_WCHAR: { - DASSERT(soi); - DASSERT(*soi != SQL_NTS); - size_t bytes = 0; - SQLCHAR *utf8 = wchars_to_chars(paramValue, *soi/2, &bytes); - bind->allocated = 1; - bind->u.nchar = (char*)utf8; - bind->buffer_length = bytes; - bind->buffer = bind->u.nchar; + tsdb_conv_t *utf16_to_server = tsdb_conn_utf16_to_server(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + const char *buf = NULL; + size_t blen = 0; + TSDB_CONV_CODE code = tsdb_conv(utf16_to_server, NULL, (const char *)paramValue, slen, &buf, &blen); + if (code==TSDB_CONV_OK) { + if (buf!=(const char*)paramValue) { + bind->allocated = 1; + } + bind->u.nchar = (char*)buf; + bind->buffer_length = blen; + bind->buffer = bind->u.nchar; + } + CHK_CONV(1, code); } break; case SQL_C_CHAR: { - bind->u.nchar = (char*)paramValue; - if (*soi == SQL_NTS) { - bind->buffer_length = strlen((const char*)paramValue); - } else { - bind->buffer_length = *soi; + tsdb_conv_t *client_to_server = tsdb_conn_client_to_server(conn); + size_t slen = (size_t)*soi; + if (slen==SQL_NTS) slen = strlen((const char*)paramValue); + const char *buf = NULL; + size_t blen = 0; + TSDB_CONV_CODE code = tsdb_conv(client_to_server, NULL, (const char *)paramValue, slen, &buf, &blen); + if (code==TSDB_CONV_OK) { + if (buf!=(const char*)paramValue) { + bind->allocated = 1; + } + bind->u.bin = (unsigned char*)buf; + bind->buffer_length = blen; + bind->buffer = bind->u.bin; } - bind->buffer = bind->u.nchar; + CHK_CONV(1, code); } break; case SQL_C_SHORT: case SQL_C_SSHORT: @@ -1740,14 +2229,14 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin case SQL_C_TIMESTAMP: case SQL_C_TYPE_DATE: case SQL_C_TYPE_TIME: - case SQL_C_TYPE_TIMESTAMP: + case SQL_C_TYPE_TIMESTAMP: // we don't provide auto-converstion case SQL_C_NUMERIC: case SQL_C_GUID: default: { SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } @@ -1756,7 +2245,7 @@ static SQLRETURN do_bind_param_value(sql_t *sql, int idx_row, int idx, param_bin SET_ERROR(sql, "HYC00", TSDB_CODE_ODBC_OUT_OF_RANGE, "no convertion from [%s[%d/0x%x]] to [%s[%d/0x%x]] for parameter [%d]", sql_c_type(valueType), valueType, valueType, - taos_data_type(type), type, type, idx+1); + taos_data_type(tsdb_type), tsdb_type, tsdb_type, idx+1); return SQL_ERROR; } break; } @@ -1797,7 +2286,7 @@ static SQLRETURN do_execute(sql_t *sql) for (int i=0; in_rows; ++i) { TAOS_BIND *binds = NULL; if (sql->n_params>0) { - binds = (TAOS_BIND*)calloc(sql->n_params, sizeof(*binds)); + binds = (TAOS_BIND*)calloc((size_t)sql->n_params, sizeof(*binds)); if (!binds) { SET_ERROR(sql, "HY001", TSDB_CODE_ODBC_OOM, ""); return SQL_ERROR; @@ -1827,7 +2316,7 @@ static SQLRETURN do_execute(sql_t *sql) } sql->is_executed = 1; - if (sql->is_insert) return SQL_SUCCESS; + // if (sql->is_insert) return SQL_SUCCESS; SQLRETURN r = SQL_SUCCESS; PROFILE(sql->rs = taos_stmt_use_result(sql->stmt)); @@ -1872,8 +2361,12 @@ static SQLRETURN doSQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, SQLPOINTER DiagInfo, SQLSMALLINT BufferLength, SQLSMALLINT *StringLength) { - // if this function is not exported, isql will never call SQLGetDiagRec - return SQL_ERROR; + switch (DiagIdentifier) { + case SQL_DIAG_CLASS_ORIGIN: { + *StringLength = 0; + } break; + } + return SQL_SUCCESS; } SQLRETURN SQL_API SQLGetDiagField(SQLSMALLINT HandleType, SQLHANDLE Handle, @@ -1949,7 +2442,7 @@ static SQLRETURN doSQLBindParameter( SQLLEN *StrLen_or_Ind) { sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); @@ -1989,6 +2482,16 @@ static SQLRETURN doSQLBindParameter( return SQL_ERROR; } + if (ParameterValue==NULL) { + SET_ERROR(sql, "HY009", TSDB_CODE_ODBC_BAD_ARG, "ParameterValue [@%p] not allowed", ParameterValue); + return SQL_ERROR; + } + + if (StrLen_or_Ind==NULL) { + SET_ERROR(sql, "HY009", TSDB_CODE_ODBC_BAD_ARG, "StrLen_or_Ind [@%p] not allowed", StrLen_or_Ind); + return SQL_ERROR; + } + param_bind_t *pb = sql->params + ParameterNumber - 1; pb->ParameterNumber = ParameterNumber; @@ -2032,26 +2535,25 @@ static SQLRETURN doSQLDriverConnect( SQLUSMALLINT fDriverCompletion) { conn_t *conn = (conn_t*)hdbc; - if (!conn) return SQL_ERROR; + if (!conn) return SQL_INVALID_HANDLE; - if (fDriverCompletion!=SQL_DRIVER_NOPROMPT) { - SET_ERROR(conn, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "option[%d] other than SQL_DRIVER_NOPROMPT not supported yet", fDriverCompletion); + if (conn->taos) { + SET_ERROR(conn, "08002", TSDB_CODE_ODBC_CONNECTION_BUSY, "connection still in use"); return SQL_ERROR; } - if (conn->taos) { - SET_ERROR(conn, "08002", TSDB_CODE_ODBC_CONNECTION_BUSY, "connection still in use"); + if (fDriverCompletion!=SQL_DRIVER_NOPROMPT) { + SET_ERROR(conn, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "option[%d] other than SQL_DRIVER_NOPROMPT not supported yet", fDriverCompletion); return SQL_ERROR; } + NORM_STR_LENGTH(conn, szConnStrIn, cbConnStrIn); + // DSN=; UID=; PWD= const char *connStr = SDUP(szConnStrIn, cbConnStrIn); - char *serverName = NULL; - char *userName = NULL; - char *auth = NULL; - int bytes = 0; + conn_val_t val = {0}; do { if (szConnStrIn && !connStr) { @@ -2059,32 +2561,52 @@ static SQLRETURN doSQLDriverConnect( break; } - int n = sscanf((const char*)connStr, "DSN=%m[^;]; UID=%m[^;]; PWD=%m[^;] %n", &serverName, &userName, &auth, &bytes); - if (n<1) { + int n = todbc_parse_conn_string((const char *)connStr, &val); + if (n) { SET_ERROR(conn, "HY000", TSDB_CODE_ODBC_BAD_CONNSTR, "unrecognized connection string: [%s]", (const char*)szConnStrIn); break; } + char *ip = NULL; + int port = 0; + if (val.server) { + char *p = strchr(val.server, ':'); + if (p) { + ip = strndup(val.server, (size_t)(p-val.server)); + port = atoi(p+1); + } + } + + if ((val.cli_enc && strcmp(val.cli_enc, conn->client_enc)) || + (val.svr_enc && strcmp(val.svr_enc, conn->server_enc)) ) + { + tsdb_conn_close_convs(conn); + if (val.cli_enc) { + snprintf(conn->client_enc, sizeof(conn->client_enc), "%s", val.cli_enc); + } + if (val.svr_enc) { + snprintf(conn->server_enc, sizeof(conn->server_enc), "%s", val.svr_enc); + } + } // TODO: data-race // TODO: shall receive ip/port from odbc.ini - conn->taos = taos_connect("localhost", userName, auth, NULL, 0); + // shall we support non-ansi uid/pwd/db etc? + conn->taos = taos_connect(ip ? ip : "localhost", val.uid, val.pwd, val.db, (uint16_t)port); + free(ip); ip = NULL; if (!conn->taos) { SET_ERROR(conn, "HY000", terrno, "failed to connect to data source"); break; } if (szConnStrOut) { - snprintf((char*)szConnStrOut, cbConnStrOutMax, "%s", connStr); + snprintf((char*)szConnStrOut, (size_t)cbConnStrOutMax, "%s", connStr); } if (pcbConnStrOut) { *pcbConnStrOut = cbConnStrIn; } - } while (0); - if (serverName) free(serverName); - if (userName) free(userName); - if (auth) free(auth); + conn_val_reset(&val); SFRE(connStr, szConnStrIn, cbConnStrIn); @@ -2111,7 +2633,7 @@ static SQLRETURN doSQLSetConnectAttr(SQLHDBC ConnectionHandle, SQLINTEGER StringLength) { conn_t *conn = (conn_t*)ConnectionHandle; - if (!conn) return SQL_ERROR; + if (!conn) return SQL_INVALID_HANDLE; if (Attribute != SQL_ATTR_AUTOCOMMIT) { SET_ERROR(conn, "HYC00", TSDB_CODE_ODBC_NOT_SUPPORT, "Attribute other than SQL_ATTR_AUTOCOMMIT not supported yet"); @@ -2141,7 +2663,7 @@ static SQLRETURN doSQLDescribeCol(SQLHSTMT StatementHandle, SQLSMALLINT *DecimalDigits, SQLSMALLINT *Nullable) { sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); @@ -2158,19 +2680,21 @@ static SQLRETURN doSQLDescribeCol(SQLHSTMT StatementHandle, SET_ERROR(sql, "07009", TSDB_CODE_ODBC_OUT_OF_RANGE, "invalid column number [%d]", ColumnNumber); return SQL_ERROR; } + if (BufferLength<0) { + SET_ERROR(sql, "HY090", TSDB_CODE_ODBC_BAD_ARG, ""); + return SQL_ERROR; + } TAOS_FIELD *field = fields + ColumnNumber - 1; if (ColumnName) { size_t n = sizeof(field->name); - if (n>BufferLength) n = BufferLength; + if (n>BufferLength) n = (size_t)BufferLength; strncpy((char*)ColumnName, field->name, n); } if (NameLength) { - *NameLength = strnlen(field->name, sizeof(field->name)); - } - if (ColumnSize) { - *ColumnSize = field->bytes; + *NameLength = (SQLSMALLINT)strnlen(field->name, sizeof(field->name)); } + if (ColumnSize) *ColumnSize = (SQLULEN)field->bytes; if (DecimalDigits) *DecimalDigits = 0; if (DataType) { @@ -2204,12 +2728,9 @@ static SQLRETURN doSQLDescribeCol(SQLHSTMT StatementHandle, } break; case TSDB_DATA_TYPE_TIMESTAMP: { - // *DataType = SQL_TIMESTAMP; - // *ColumnSize = 30; - // *DecimalDigits = 3; *DataType = SQL_TIMESTAMP; - *ColumnSize = sizeof(SQL_TIMESTAMP_STRUCT); - *DecimalDigits = 0; + if (ColumnSize) *ColumnSize = sizeof(SQL_TIMESTAMP_STRUCT); + if (DecimalDigits) *DecimalDigits = 0; } break; case TSDB_DATA_TYPE_NCHAR: { @@ -2218,7 +2739,7 @@ static SQLRETURN doSQLDescribeCol(SQLHSTMT StatementHandle, } break; case TSDB_DATA_TYPE_BINARY: { - *DataType = SQL_BINARY; + *DataType = SQL_CHAR; if (ColumnSize) *ColumnSize -= VARSTR_HEADER_SIZE; } break; @@ -2253,7 +2774,7 @@ SQLRETURN SQL_API SQLDescribeCol(SQLHSTMT StatementHandle, static SQLRETURN doSQLNumParams(SQLHSTMT hstmt, SQLSMALLINT *pcpar) { sql_t *sql = (sql_t*)hstmt; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); @@ -2281,7 +2802,7 @@ static SQLRETURN doSQLNumParams(SQLHSTMT hstmt, SQLSMALLINT *pcpar) return SQL_ERROR; } - if (pcpar) *pcpar = params; + if (pcpar) *pcpar = (SQLSMALLINT)params; return SQL_SUCCESS; } @@ -2298,7 +2819,7 @@ static SQLRETURN doSQLSetStmtAttr(SQLHSTMT StatementHandle, SQLINTEGER StringLength) { sql_t *sql = (sql_t*)StatementHandle; - if (!sql) return SQL_ERROR; + if (!sql) return SQL_INVALID_HANDLE; CHK_CONN(sql); CHK_CONN_TAOS(sql); @@ -2355,1126 +2876,296 @@ SQLRETURN SQL_API SQLSetStmtAttr(SQLHSTMT StatementHandle, return r; } +#ifdef _MSC_VER + +#define POST_INSTALLER_ERROR(hwndParent, code, fmt, ...) \ +do { \ + char buf[4096]; \ + snprintf(buf, sizeof(buf), "%s[%d]%s():" fmt "", \ + basename((char*)__FILE__), __LINE__, __func__, \ + ##__VA_ARGS__); \ + SQLPostInstallerError(code, buf); \ + if (hwndParent) { \ + MessageBox(hwndParent, buf, "Error", MB_OK|MB_ICONEXCLAMATION); \ + } \ +} while (0) +typedef struct kv_s kv_t; +struct kv_s { + char *line; + size_t val; +}; +static BOOL get_driver_dll_path(HWND hwndParent, char *buf, size_t len) +{ + HMODULE hm = NULL; -static void init_routine(void) { - if (0) { - string_conv(NULL, NULL, NULL, 0, NULL, 0, NULL, NULL); - utf8_to_ucs4le(NULL, NULL); - ucs4le_to_utf8(NULL, 0, NULL); + if (GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, + (LPCSTR) &ConfigDSN, &hm) == 0) + { + int ret = GetLastError(); + POST_INSTALLER_ERROR(hwndParent, ODBC_ERROR_REQUEST_FAILED, "GetModuleHandle failed, error = %d\n", ret); + return FALSE; } - taos_init(); + if (GetModuleFileName(hm, buf, (DWORD)len) == 0) + { + int ret = GetLastError(); + POST_INSTALLER_ERROR(hwndParent, ODBC_ERROR_REQUEST_FAILED, "GetModuleFileName failed, error = %d\n", ret); + return FALSE; + } + return TRUE; } -static int do_field_display_size(TAOS_FIELD *field) { - switch (field->type) { - case TSDB_DATA_TYPE_TINYINT: - return 5; - break; +static BOOL doDSNAdd(HWND hwndParent, LPCSTR lpszDriver, LPCSTR lpszAttributes) +{ + BOOL r = TRUE; - case TSDB_DATA_TYPE_SMALLINT: - return 7; - break; + kv_t *kvs = NULL; - case TSDB_DATA_TYPE_INT: - return 12; - break; + kv_t dsn = {0}; + char *line = NULL; - case TSDB_DATA_TYPE_BIGINT: - return 22; - break; + do { + char driver_dll[MAX_PATH + 1]; + r = get_driver_dll_path(hwndParent, driver_dll, sizeof(driver_dll)); + if (!r) break; + + dsn.line = strdup("DSN=TAOS_DEMO"); + if (!dsn.line) { r = FALSE; break; } + + const char *p = lpszAttributes; + int ikvs = 0; + while (p && *p) { + line = strdup(p); + if (!line) { r = FALSE; break; } + char *v = strchr(line, '='); + if (!v) { r = FALSE; break; } + + if (strstr(line, "DSN")==line) { + if (dsn.line) { + free(dsn.line); + dsn.line = NULL; + dsn.val = 0; + } + dsn.line = line; + line = NULL; + } else { + kv_t *t = (kv_t*)realloc(kvs, (ikvs+1)*sizeof(*t)); + if (!t) { r = FALSE; free(line); break; } + t[ikvs].line = line; + *v = '\0'; + if (v) t[ikvs].val = v - line + 1; + line = NULL; + + kvs = t; + ++ikvs; + } - case TSDB_DATA_TYPE_FLOAT: { - return 12; - } break; + p += strlen(p) + 1; + } - case TSDB_DATA_TYPE_DOUBLE: { - return 20; - } break; + if (hwndParent) { + MessageBox(hwndParent, "Please use odbcconf to add DSN for TAOS ODBC Driver", "Warning!", MB_OK|MB_ICONEXCLAMATION); + } + if (!r) break; + + char *v = NULL; + v = strchr(dsn.line, '='); + if (!v) { r = FALSE; break; } + *v = '\0'; + dsn.val = v - dsn.line + 1; + + if ((!dsn.line)) { + if (!r) POST_INSTALLER_ERROR(hwndParent, ODBC_ERROR_REQUEST_FAILED, "lack of either DSN or Driver"); + } else { + if (r) r = SQLWritePrivateProfileString("ODBC Data Sources", dsn.line+dsn.val, lpszDriver, "Odbc.ini"); + if (r) r = SQLWritePrivateProfileString(dsn.line+dsn.val, "Driver", driver_dll, "Odbc.ini"); + } - case TSDB_DATA_TYPE_BINARY: - case TSDB_DATA_TYPE_NCHAR: { - return 3*(field->bytes - VARSTR_HEADER_SIZE) + 2; - } break; - - case TSDB_DATA_TYPE_TIMESTAMP: - return 26; - break; - - case TSDB_DATA_TYPE_BOOL: - return 7; - default: - break; - } - - return 10; -} - -// convertion from TSDB_DATA_TYPE_XXX to SQL_C_XXX -static SQLRETURN conv_tsdb_bool_to_c_bit(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - int8_t v = b; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bool_to_c_tinyint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - int8_t v = b; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bool_to_c_short(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - int16_t v = b; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bool_to_c_long(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - int32_t v = b; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bool_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - int64_t v = b; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bool_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - float v = b; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bool_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - double v = b; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bool_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - DASSERT(target->len>0); - *target->soi = 1; - target->ptr[0] = '0' + b; - if (target->len>1) { - target->ptr[1] = '\0'; - } - - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bool_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t b) -{ - DASSERT(target->len>0); - *target->soi = 1; - target->ptr[0] = '0' + b; - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v1_to_c_tinyint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1) -{ - int8_t v = v1; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v1_to_c_short(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1) -{ - int16_t v = v1; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v1_to_c_long(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1) -{ - int32_t v = v1; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v1_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1) -{ - int64_t v = v1; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v1_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1) -{ - float v = v1; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v1_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1) -{ - double v = v1; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v1_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%d", v1); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>=target->len ? target->len : n+1)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_TINYINT -> SQL_C_BIT"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_v1_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int8_t v1) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%d", v1); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>target->len ? target->len : n)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_TINYINT -> SQL_C_BIT"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_v2_to_c_short(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2) -{ - int16_t v = v2; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v2_to_c_long(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2) -{ - int32_t v = v2; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v2_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2) -{ - int64_t v = v2; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v2_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2) -{ - float v = v2; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v2_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2) -{ - double v = v2; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v2_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%d", v2); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>=target->len ? target->len : n+1)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_SMALLINT -> SQL_C_CHAR"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_v2_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int16_t v2) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%d", v2); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>target->len ? target->len : n)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_SMALLINT -> SQL_C_CHAR"); - return SQL_SUCCESS_WITH_INFO; -} - - -static SQLRETURN conv_tsdb_v4_to_c_long(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4) -{ - int32_t v = v4; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v4_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4) -{ - int64_t v = v4; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v4_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4) -{ - float v = v4; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v4_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4) -{ - double v = v4; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v4_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%d", v4); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>=target->len ? target->len : n+1)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_INTEGER -> SQL_C_CHAR"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_v4_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int32_t v4) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%d", v4); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>target->len ? target->len : n)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_INTEGER -> SQL_C_BINARY"); - return SQL_SUCCESS_WITH_INFO; -} - - -static SQLRETURN conv_tsdb_v8_to_c_sbigint(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8) -{ - int64_t v = v8; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v8_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8) -{ - float v = v8; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v8_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8) -{ - double v = v8; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_v8_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%" PRId64 "", v8); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>=target->len ? target->len : n+1)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_BIGINT -> SQL_C_CHAR"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_v8_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, int64_t v8) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%" PRId64 "", v8); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>target->len ? target->len : n)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_BIGINT -> SQL_C_BINARY"); - return SQL_SUCCESS_WITH_INFO; -} - - -static SQLRETURN conv_tsdb_f4_to_c_float(sql_t *sql, c_target_t *target, TAOS_FIELD *field, float f4) -{ - float v = f4; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_f4_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, float f4) -{ - double v = f4; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_f4_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, float f4) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%g", f4); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>=target->len ? target->len : n+1)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_FLOAT -> SQL_C_CHAR"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_f4_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, float f4) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%g", f4); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>target->len ? target->len : n)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_FLOAT -> SQL_C_BINARY"); - return SQL_SUCCESS_WITH_INFO; -} - - -static SQLRETURN conv_tsdb_f8_to_c_double(sql_t *sql, c_target_t *target, TAOS_FIELD *field, double f8) -{ - double v = f8; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_f8_to_c_char(sql_t *sql, c_target_t *target, TAOS_FIELD *field, double f8) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%.6f", f8); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>=target->len ? target->len : n+1)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_DOUBLE -> SQL_C_CHAR"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_f8_to_c_binary(sql_t *sql, c_target_t *target, TAOS_FIELD *field, double f8) -{ - char buf[64]; - int n = snprintf(buf, sizeof(buf), "%g", f8); - DASSERT(nsoi = n; - strncpy(target->ptr, buf, (n>target->len ? target->len : n)); - if (n<=target->len) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_DOUBLE -> SQL_C_BINARY"); - return SQL_SUCCESS_WITH_INFO; -} - - -static SQLRETURN conv_tsdb_ts_to_c_v8(sql_t *sql, c_target_t *target, TAOS_FIELD *field, SQL_TIMESTAMP_STRUCT *ts) -{ - struct tm tm = {0}; - tm.tm_sec = ts->second; - tm.tm_min = ts->minute; - tm.tm_hour = ts->hour; - tm.tm_mday = ts->day; - tm.tm_mon = ts->month - 1; - tm.tm_year = ts->year - 1900; - time_t t = mktime(&tm); - DASSERT(sizeof(t) == sizeof(int64_t)); - int64_t v = (int64_t)t; - v *= 1000; - v += ts->fraction / 1000000; - memcpy(target->ptr, &v, sizeof(v)); - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_ts_to_c_str(sql_t *sql, c_target_t *target, TAOS_FIELD *field, SQL_TIMESTAMP_STRUCT *ts) -{ - struct tm tm = {0}; - tm.tm_sec = ts->second; - tm.tm_min = ts->minute; - tm.tm_hour = ts->hour; - tm.tm_mday = ts->day; - tm.tm_mon = ts->month - 1; - tm.tm_year = ts->year - 1900; - - char buf[64]; - int n = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); - DASSERT(n < sizeof(buf)); - - *target->soi = n; - - unsigned int fraction = ts->fraction; - fraction /= 1000000; - snprintf(target->ptr, target->len, "%s.%03d", buf, fraction); - if (target->soi) *target->soi = strlen((const char*)target->ptr); - - if (n <= target->len) { - return SQL_SUCCESS; - } - - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_TIMESTAMP -> SQL_C_CHAR"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_ts_to_c_bin(sql_t *sql, c_target_t *target, TAOS_FIELD *field, SQL_TIMESTAMP_STRUCT *ts) -{ - struct tm tm = {0}; - tm.tm_sec = ts->second; - tm.tm_min = ts->minute; - tm.tm_hour = ts->hour; - tm.tm_mday = ts->day; - tm.tm_mon = ts->month - 1; - tm.tm_year = ts->year - 1900; - - char buf[64]; - int n = strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &tm); - DASSERT(n < sizeof(buf)); - - unsigned int fraction = ts->fraction; - fraction /= 1000000; - snprintf(target->ptr, target->len, "%s.%03d", buf, fraction); - if (target->soi) *target->soi = strlen((const char*)target->ptr); - - if (n <= target->len) { - return SQL_SUCCESS; - } - - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_TIMESTAMP -> SQL_C_BINARY"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_ts_to_c_ts(sql_t *sql, c_target_t *target, TAOS_FIELD *field, SQL_TIMESTAMP_STRUCT *ts) -{ - DASSERT(target->len == sizeof(*ts)); - memcpy(target->ptr, ts, sizeof(*ts)); - *target->soi = target->len; - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_bin_to_c_str(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const unsigned char *bin) -{ - if (target->len<1) { - SET_ERROR(sql, "HY090", TSDB_CODE_ODBC_BAD_ARG, ""); - return SQL_ERROR; - } - size_t field_bytes = field->bytes - VARSTR_HEADER_SIZE; - size_t n = strnlen((const char*)bin, field_bytes); - - if (n < target->len) { - memcpy(target->ptr, bin, n); - target->ptr[n] = '\0'; - *target->soi = n; - return SQL_SUCCESS; - } - n = target->len - 1; - *target->soi = n; - if (n > 0) { - memcpy(target->ptr, bin, n-1); - target->ptr[n-1] = '\0'; - } - SET_ERROR(sql, "01004", TSDB_CODE_ODBC_CONV_TRUNC, ""); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_bin_to_c_bin(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const unsigned char *bin) -{ - if (target->len<1) { - SET_ERROR(sql, "HY090", TSDB_CODE_ODBC_BAD_ARG, ""); - return SQL_ERROR; - } - size_t field_bytes = field->bytes - VARSTR_HEADER_SIZE; - size_t n = strnlen((const char*)bin, field_bytes); - - if (n <= target->len) { - memcpy(target->ptr, bin, n); - if (nlen) target->ptr[n] = '\0'; - *target->soi = n; - return SQL_SUCCESS; - } - - n = target->len; - memcpy(target->ptr, bin, n); - *target->soi = n; - SET_ERROR(sql, "01004", TSDB_CODE_ODBC_CONV_TRUNC, ""); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_str_to_c_bit(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) -{ - int bytes = 0; - double f8 = 0; - int n = sscanf(str, "%lf%n", &f8, &bytes); - - int8_t v = f8; - memcpy(target->ptr, &v, sizeof(v)); - - *target->soi = 1; - - if (n!=1 || bytes!=strlen(str)) { - SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_BIT"); - return SQL_SUCCESS_WITH_INFO; - } - - char buf[64]; - snprintf(buf, sizeof(buf), "%d", v); - - if (strcmp(buf, str)==0) { - if (v==0 || v==1) return SQL_SUCCESS; - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_BIT"); - return SQL_SUCCESS_WITH_INFO; - } - - if (f8>0 || f8<2) { - SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_TRUNC, "TSDB_DATA_TYPE_NCHAR -> SQL_C_BIT"); - return SQL_SUCCESS_WITH_INFO; - } - - if (f8<0 || f8>2) { - SET_ERROR(sql, "22003", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_BIT"); - return SQL_SUCCESS_WITH_INFO; - } - - SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_BIT"); - return SQL_SUCCESS_WITH_INFO; -} - -static SQLRETURN conv_tsdb_str_to_c_v1(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) -{ - int bytes = 0; - double f8 = 0; - int n = sscanf(str, "%lf%n", &f8, &bytes); - - int8_t v = f8; - memcpy(target->ptr, &v, sizeof(v)); - - *target->soi = 1; - - if (n!=1 || bytes!=strlen(str)) { - SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_TINYINT"); - return SQL_SUCCESS_WITH_INFO; - } - - char buf[64]; - snprintf(buf, sizeof(buf), "%d", v); - - if (strcmp(buf, str)==0) return SQL_SUCCESS; + for (int i=0; r && iINT8_MAX || f8 SQL_C_TINYINT"); - return SQL_SUCCESS_WITH_INFO; - } + if (dsn.line) free(dsn.line); + if (line) free(line); - SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_TRUNC, "TSDB_DATA_TYPE_NCHAR -> SQL_C_TINYINT"); - return SQL_SUCCESS_WITH_INFO; + return r; } -static SQLRETURN conv_tsdb_str_to_c_v2(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) +static BOOL doDSNConfig(HWND hwndParent, LPCSTR lpszDriver, LPCSTR lpszAttributes) { - int bytes = 0; - double f8 = 0; - int n = sscanf(str, "%lf%n", &f8, &bytes); - - int16_t v = f8; - memcpy(target->ptr, &v, sizeof(v)); - - *target->soi = 2; - - if (n!=1 || bytes!=strlen(str)) { - SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_SHORT"); - return SQL_SUCCESS_WITH_INFO; - } - - char buf[64]; - snprintf(buf, sizeof(buf), "%d", v); - - if (strcmp(buf, str)==0) return SQL_SUCCESS; - - if (f8>INT16_MAX || f8 SQL_C_SHORT"); - return SQL_SUCCESS_WITH_INFO; + const char *p = lpszAttributes; + while (p && *p) { + p += strlen(p) + 1; } - - SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_TRUNC, "TSDB_DATA_TYPE_NCHAR -> SQL_C_SHORT"); - return SQL_SUCCESS_WITH_INFO; + return FALSE; } -static SQLRETURN conv_tsdb_str_to_c_v4(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) +static BOOL doDSNRemove(HWND hwndParent, LPCSTR lpszDriver, LPCSTR lpszAttributes) { - int bytes = 0; - double f8 = 0; - int n = sscanf(str, "%lf%n", &f8, &bytes); - - int32_t v = f8; - memcpy(target->ptr, &v, sizeof(v)); - - *target->soi = 4; - - if (n!=1 || bytes!=strlen(str)) { - SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_LONG"); - return SQL_SUCCESS_WITH_INFO; - } - - char buf[64]; - snprintf(buf, sizeof(buf), "%d", v); - - if (strcmp(buf, str)==0) return SQL_SUCCESS; + BOOL r = TRUE; - if (f8>INT32_MAX || f8 SQL_C_LONG"); - return SQL_SUCCESS_WITH_INFO; - } - - SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_TRUNC, "TSDB_DATA_TYPE_NCHAR -> SQL_C_LONG"); - return SQL_SUCCESS_WITH_INFO; -} + kv_t dsn = {0}; + char *line = NULL; -static SQLRETURN conv_tsdb_str_to_c_v8(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) -{ - int bytes = 0; - double f8 = 0; - int n = sscanf(str, "%lf%n", &f8, &bytes); + do { + const char *p = lpszAttributes; + int ikvs = 0; + while (p && *p) { + line = strdup(p); + if (!line) { r = FALSE; break; } + char *v = strchr(line, '='); + if (!v) { r = FALSE; break; } + *v = '\0'; + + if (strstr(line, "DSN")==line) { + if (dsn.line) { + free(dsn.line); + dsn.line = NULL; + dsn.val = 0; + } + dsn.line = line; + dsn.val = v - line + 1; + line = NULL; + break; + } else { + free(line); + line = NULL; + } - int64_t v = f8; - memcpy(target->ptr, &v, sizeof(v)); + p += strlen(p) + 1; + } - *target->soi = 8; + if (!r) break; - if (n!=1 || bytes!=strlen(str)) { - SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_SBIGINT"); - return SQL_SUCCESS_WITH_INFO; - } + if (!dsn.line) { + POST_INSTALLER_ERROR(hwndParent, ODBC_ERROR_REQUEST_FAILED, "lack of DSN"); + r = FALSE; + break; + } - char buf[64]; - snprintf(buf, sizeof(buf), "%" PRId64 "", v); + r = SQLWritePrivateProfileString("ODBC Data Sources", dsn.line+dsn.val, NULL, "Odbc.ini"); + if (!r) break; - if (strcmp(buf, str)==0) return SQL_SUCCESS; + char buf[8192]; + r = SQLGetPrivateProfileString(dsn.line+dsn.val, NULL, "null", buf, sizeof(buf), "Odbc.ini"); + if (!r) break; - if (f8>INT64_MAX || f8 SQL_C_SBIGINT"); - return SQL_SUCCESS_WITH_INFO; - } + int n = 0; + char *s = buf; + while (s && *s && n++<10) { + SQLWritePrivateProfileString(dsn.line+dsn.val, s, NULL, "Odbc.ini"); + s += strlen(s) + 1; + } + } while (0); - SET_ERROR(sql, "01S07", TSDB_CODE_ODBC_CONV_TRUNC, "TSDB_DATA_TYPE_NCHAR -> SQL_C_SBIGINT"); - return SQL_SUCCESS_WITH_INFO; + if (dsn.line) free(dsn.line); + if (line) free(line); + return r; } -static SQLRETURN conv_tsdb_str_to_c_f4(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) +static BOOL doConfigDSN(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttributes) { - int bytes = 0; - double f8 = 0; - int n = sscanf(str, "%lf%n", &f8, &bytes); - - float v = f8; - memcpy(target->ptr, &v, sizeof(v)); - - *target->soi = 4; - - if (n!=1 || bytes!=strlen(str)) { - SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_FLOAT"); - return SQL_SUCCESS_WITH_INFO; + BOOL r = FALSE; + const char *sReq = NULL; + switch(fRequest) { + case ODBC_ADD_DSN: sReq = "ODBC_ADD_DSN"; break; + case ODBC_CONFIG_DSN: sReq = "ODBC_CONFIG_DSN"; break; + case ODBC_REMOVE_DSN: sReq = "ODBC_REMOVE_DSN"; break; + default: sReq = "UNKNOWN"; break; } - - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_str_to_c_f8(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) -{ - int bytes = 0; - double f8 = 0; - int n = sscanf(str, "%lf%n", &f8, &bytes); - - float v = f8; - memcpy(target->ptr, &v, sizeof(v)); - - *target->soi = 8; - - if (n!=1 || bytes!=strlen(str)) { - SET_ERROR(sql, "22018", TSDB_CODE_ODBC_CONV_UNDEF, "TSDB_DATA_TYPE_NCHAR -> SQL_C_DOUBLE"); - return SQL_SUCCESS_WITH_INFO; - } - - return SQL_SUCCESS; -} - -static SQLRETURN conv_tsdb_str_to_c_str(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) -{ - return conv_tsdb_bin_to_c_str(sql, target, field, (const unsigned char*)str); -} - -static SQLRETURN conv_tsdb_str_to_c_bin(sql_t *sql, c_target_t *target, TAOS_FIELD *field, const char *str) -{ - return conv_tsdb_bin_to_c_bin(sql, target, field, (const unsigned char*)str); -} - - - - -const char* tsdb_int64_to_bit(int64_t src, int8_t *dst) -{ - *dst = src; - if (src==0 || src==1) return NULL; - return "22003"; -} - -const char* tsdb_int64_to_tinyint(int64_t src, int8_t *dst) -{ - *dst = src; - if (src>=SCHAR_MIN && src<=SCHAR_MAX) return NULL; - return "22003"; -} - -const char* tsdb_int64_to_smallint(int64_t src, int16_t *dst) -{ - *dst = src; - if (src>=SHRT_MIN && src<=SHRT_MAX) return NULL; - return "22003"; -} - -const char* tsdb_int64_to_int(int64_t src, int32_t *dst) -{ - *dst = src; - if (src>=LONG_MIN && src<=LONG_MAX) return NULL; - return "22003"; -} - -const char* tsdb_int64_to_bigint(int64_t src, int64_t *dst) -{ - *dst = src; - return NULL; -} - -const char* tsdb_int64_to_ts(int64_t src, int64_t *dst) -{ - *dst = src; - - char buf[4096]; - int n = snprintf(buf, sizeof(buf), "%" PRId64 "", src); - DASSERT(n>=0); - DASSERT(n=2) return "22003"; - - char buf[4096]; - int n = snprintf(buf, sizeof(buf), "%.*g", precision, src); - DASSERT(n>=0); - DASSERT(nSCHAR_MAX) return "22003"; - - char buf[4096]; - int n = snprintf(buf, sizeof(buf), "%.*g", precision, src); - DASSERT(n>=0); - DASSERT(nSHRT_MAX) return "22003"; - - char buf[4096]; - int n = snprintf(buf, sizeof(buf), "%.*g", precision, src); - DASSERT(n>=0); - DASSERT(nLONG_MAX) return "22003"; - - char buf[4096]; - int n = snprintf(buf, sizeof(buf), "%.*g", precision, src); - DASSERT(n>=0); - DASSERT(nLLONG_MAX) return "22003"; - - char buf[4096]; - int n = snprintf(buf, sizeof(buf), "%.*g", precision, src); - DASSERT(n>=0); - DASSERT(n=0); - DASSERT(n=0); - DASSERT(n2>=0); - DASSERT(n1=0); - if (n>=dlen) return "22001"; - - return NULL; + POST_INSTALLER_ERROR(hwndParent, ODBC_ERROR_GENERAL_ERR, "not implemented yet"); + return FALSE; } -const char* tsdb_chars_to_bit(const char *src, int8_t *dst) +BOOL INSTAPI ConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszArgs, + LPSTR lpszMsg, WORD cbMsgMax, WORD *pcbMsgOut) { - int bytes = 0; - int64_t v = 0; - int n = sscanf(src, "%" PRId64 "%n", &v, &bytes); - if (n!=1) return "22018"; - - if (bytes!=strlen(src)) { - if (src[bytes-1]=='.') { - if (v==0 || v==1) return "22001"; - - return "22003"; - } - return "22018"; - } - - if (v==0 || v==1) return NULL; - - return "22003"; -} - -const char* tsdb_chars_to_tinyint(const char *src, int8_t *dst) -{ - int bytes = 0; - int64_t v = 0; - int n = sscanf(src, "%" PRId64 "%n", &v, &bytes); - if (n!=1) return "22018"; - - - if (bytes!=strlen(src)) { - if (src[bytes-1]=='.') { - if (vSCHAR_MAX) return "22001"; - - return "22003"; - } - return "22018"; - } - - if (vSCHAR_MAX) return "22001"; - - return NULL; + POST_INSTALLER_ERROR(hwndParent, ODBC_ERROR_GENERAL_ERR, "not implemented yet"); + return FALSE; } -const char* tsdb_chars_to_smallint(const char *src, int16_t *dst) -{ - int bytes = 0; - int64_t v = 0; - int n = sscanf(src, "%" PRId64 "%n", &v, &bytes); - if (n!=1) return "22018"; - +#endif // _MSC_VER - if (bytes!=strlen(src)) { - if (src[bytes-1]=='.') { - if (vSHRT_MAX) return "22001"; - return "22003"; - } - return "22018"; - } - - if (vSHRT_MAX) return "22001"; - - return NULL; -} - -const char* tsdb_chars_to_int(const char *src, int32_t *dst) -{ - int bytes = 0; - int64_t v = 0; - int n = sscanf(src, "%" PRId64 "%n", &v, &bytes); - if (n!=1) return "22018"; - - - if (bytes!=strlen(src)) { - if (src[bytes-1]=='.') { - if (vLONG_MAX) return "22001"; - - return "22003"; - } - return "22018"; - } - - if (vLONG_MAX) return "22001"; - - return NULL; +static void init_routine(void) { + taos_init(); } -const char* tsdb_chars_to_bigint(const char *src, int64_t *dst) -{ - int bytes = 0; - int64_t v = 0; - int n = sscanf(src, "%" PRId64 "%n", &v, &bytes); - if (n!=1) return "22018"; - +static size_t do_field_display_size(TAOS_FIELD *field) { + switch (field->type) { + case TSDB_DATA_TYPE_TINYINT: + return 5; + break; - if (bytes!=strlen(src)) { - if (src[bytes-1]=='.') { - if (vLLONG_MAX) return "22001"; + case TSDB_DATA_TYPE_SMALLINT: + return 7; + break; - return "22003"; - } - return "22018"; - } + case TSDB_DATA_TYPE_INT: + return 12; + break; - if (vLLONG_MAX) return "22001"; + case TSDB_DATA_TYPE_BIGINT: + return 22; + break; - return NULL; -} + case TSDB_DATA_TYPE_FLOAT: { + return 12; + } break; -const char* tsdb_chars_to_ts(const char *src, int64_t *dst) -{ - int bytes = 0; - int64_t v = 0; - int n = sscanf(src, "%" PRId64 "%n", &v, &bytes); - if (n!=1) return "22018"; + case TSDB_DATA_TYPE_DOUBLE: { + return 20; + } break; + case TSDB_DATA_TYPE_BINARY: + case TSDB_DATA_TYPE_NCHAR: { + return 3*((size_t)field->bytes - VARSTR_HEADER_SIZE) + 2; + } break; - if (bytes!=strlen(src)) { - if (src[bytes-1]=='.') { - if (vLLONG_MAX) return "22001"; + case TSDB_DATA_TYPE_TIMESTAMP: + return 26; + break; - return "22003"; - } - return "22018"; + case TSDB_DATA_TYPE_BOOL: + return 7; + default: + break; } - if (vLLONG_MAX) return "22001"; - - return NULL; -} - -const char* tsdb_chars_to_float(const char *src, float *dst) -{ - int bytes = 0; - int n = sscanf(src, "%f%n", dst, &bytes); - if (n!=1) return "22018"; - - if (bytes!=strlen(src)) return "22018"; - - return NULL; -} - -const char* tsdb_chars_to_double(const char *src, double *dst) -{ - int bytes = 0; - int n = sscanf(src, "%lf%n", dst, &bytes); - if (n!=1) return "22018"; - - if (bytes!=strlen(src)) return "22018"; - - return NULL; + return 10; } -const char* tsdb_chars_to_char(const char *src, char *dst, size_t dlen) -{ - int n = snprintf(dst, dlen, "%s", src); - if (n>=dlen) return "22001"; - return NULL; -} diff --git a/src/connector/odbc/src/todbc.def b/src/connector/odbc/src/todbc.def new file mode 100644 index 0000000000000000000000000000000000000000..1e080f01983ec2b38d657004291008f6da6198dc --- /dev/null +++ b/src/connector/odbc/src/todbc.def @@ -0,0 +1,31 @@ +EXPORTS +SQLAllocEnv +SQLFreeEnv +SQLAllocConnect +SQLFreeConnect +SQLConnect +SQLDisconnect +SQLAllocStmt +SQLAllocHandle +SQLFreeStmt +SQLExecDirect +SQLExecDirectW +SQLNumResultCols +SQLRowCount +SQLColAttribute +SQLGetData +SQLFetch +SQLPrepare +SQLExecute +SQLGetDiagField +SQLGetDiagRec +SQLBindParameter +SQLDriverConnect +SQLSetConnectAttr +SQLDescribeCol +SQLNumParams +SQLSetStmtAttr +ConfigDSN +ConfigTranslator +ConfigDriver + diff --git a/src/connector/odbc/src/todbc.rc.in b/src/connector/odbc/src/todbc.rc.in new file mode 100644 index 0000000000000000000000000000000000000000..cf0b21145456eb20097ed3dda1e582cee1e343d2 --- /dev/null +++ b/src/connector/odbc/src/todbc.rc.in @@ -0,0 +1,31 @@ +1 VERSIONINFO + FILEVERSION ${TD_VER_NUMBER} + PRODUCTVERSION ${TD_VER_NUMBER} + FILEFLAGSMASK 0x17L +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x0L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "ODBC Driver for TDengine" + VALUE "FileVersion", "${TD_VER_NUMBER}" + VALUE "InternalName", "todbc.dll(${TD_VER_CPUTYPE})" + VALUE "LegalCopyright", "Copyright (C) 2020 TAOS Data" + VALUE "OriginalFilename", "" + VALUE "ProductName", "todbc.dll(${TD_VER_CPUTYPE})" + VALUE "ProductVersion", "${TD_VER_NUMBER}" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END \ No newline at end of file diff --git a/src/connector/odbc/src/todbc.rsp b/src/connector/odbc/src/todbc.rsp new file mode 100644 index 0000000000000000000000000000000000000000..f5e511565872e51a6afa838ad6cb3d1774c2c422 --- /dev/null +++ b/src/connector/odbc/src/todbc.rsp @@ -0,0 +1,5 @@ +INSTALLDRIVER "TAOS ODBC|Driver=todbc.dll|FileUsage=0|ConnectFunctions=YYN" + + + + diff --git a/src/connector/odbc/src/todbc_conv.c b/src/connector/odbc/src/todbc_conv.c new file mode 100644 index 0000000000000000000000000000000000000000..9c0f19764c2b456c63b6d0a01402e37868a0a366 --- /dev/null +++ b/src/connector/odbc/src/todbc_conv.c @@ -0,0 +1,660 @@ +/* + * 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 "todbc_conv.h" + +#include "todbc_log.h" + +#include +#include +#include +#include +#include + +const char* tsdb_conv_code_str(TSDB_CONV_CODE code) { + switch (code) { + case TSDB_CONV_OK: return "TSDB_CONV_OK"; + case TSDB_CONV_NOT_AVAIL: return "TSDB_CONV_NOT_AVAIL"; + case TSDB_CONV_OOM: return "TSDB_CONV_OOM"; + case TSDB_CONV_OOR: return "TSDB_CONV_OOR"; + case TSDB_CONV_TRUNC_FRACTION: return "TSDB_CONV_TRUNC_FRACTION"; + case TSDB_CONV_TRUNC: return "TSDB_CONV_TRUNC"; + case TSDB_CONV_CHAR_NOT_NUM: return "TSDB_CONV_CHAR_NOT_NUM"; + case TSDB_CONV_CHAR_NOT_TS: return "TSDB_CONV_CHAR_NOT_TS"; + case TSDB_CONV_NOT_VALID_TS: return "TSDB_CONV_NOT_VALID_TS"; + case TSDB_CONV_GENERAL: return "TSDB_CONV_GENERAL"; + case TSDB_CONV_SRC_TOO_LARGE: return "TSDB_CONV_SRC_TOO_LARGE"; + case TSDB_CONV_SRC_BAD_SEQ: return "TSDB_CONV_SRC_BAD_SEQ"; + case TSDB_CONV_SRC_INCOMPLETE: return "TSDB_CONV_SRC_INCOMPLETE"; + case TSDB_CONV_SRC_GENERAL: return "TSDB_CONV_SRC_GENERAL"; + case TSDB_CONV_BAD_CHAR: return "TSDB_CONV_BAD_CHAR"; + default: return "UNKNOWN"; + }; +} + +// src: int +TSDB_CONV_CODE tsdb_int64_to_bit(int64_t src, int8_t *dst) { + *dst = (int8_t)src; + if (src==0 || src==1) return TSDB_CONV_OK; + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_int64_to_tinyint(int64_t src, int8_t *dst) { + *dst = (int8_t)src; + if (src == *dst) return TSDB_CONV_OK; + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_int64_to_smallint(int64_t src, int16_t *dst) { + *dst = (int16_t)src; + if (src == *dst) return TSDB_CONV_OK; + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_int64_to_int(int64_t src, int32_t *dst) { + *dst = (int32_t)src; + if (src == *dst) return TSDB_CONV_OK; + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_int64_to_bigint(int64_t src, int64_t *dst) { + *dst = src; + return TSDB_CONV_OK; +} + +TSDB_CONV_CODE tsdb_int64_to_ts(int64_t src, int64_t *dst) { + *dst = src; + + time_t t = (time_t)(src / 1000); + struct tm tm = {0}; + if (localtime_r(&t, &tm)) return TSDB_CONV_OK; + + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_int64_to_float(int64_t src, float *dst) { + *dst = (float)src; + + int64_t v = (int64_t)*dst; + if (v==src) return TSDB_CONV_OK; + + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_int64_to_double(int64_t src, double *dst) { + *dst = (double)src; + + int64_t v = (int64_t)*dst; + if (v==src) return TSDB_CONV_OK; + + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_int64_to_char(int64_t src, char *dst, size_t dlen) { + int n = snprintf(dst, dlen, "%" PRId64 "", src); + DASSERT(n>=0); + + if (n=2) return TSDB_CONV_OOR; + if (src == *dst) return TSDB_CONV_OK; + + int64_t v = (int64_t)src; + if (v == *dst) return TSDB_CONV_TRUNC_FRACTION; + + return TSDB_CONV_TRUNC; +} + +TSDB_CONV_CODE tsdb_double_to_tinyint(double src, int8_t *dst) { + *dst = (int8_t)src; + + if (srcSCHAR_MAX) return TSDB_CONV_OOR; + if (src == *dst) return TSDB_CONV_OK; + + int64_t v = (int64_t)src; + if (v == *dst) return TSDB_CONV_TRUNC_FRACTION; + + return TSDB_CONV_TRUNC; +} + +TSDB_CONV_CODE tsdb_double_to_smallint(double src, int16_t *dst) { + *dst = (int16_t)src; + + if (srcSHRT_MAX) return TSDB_CONV_OOR; + if (src == *dst) return TSDB_CONV_OK; + + int64_t v = (int64_t)src; + if (v == *dst) return TSDB_CONV_TRUNC_FRACTION; + + return TSDB_CONV_TRUNC; +} + +TSDB_CONV_CODE tsdb_double_to_int(double src, int32_t *dst) { + *dst = (int32_t)src; + + if (srcLONG_MAX) return TSDB_CONV_OOR; + if (src == *dst) return TSDB_CONV_OK; + + int64_t v = (int64_t)src; + if (v == *dst) return TSDB_CONV_TRUNC_FRACTION; + + return TSDB_CONV_TRUNC; +} + +TSDB_CONV_CODE tsdb_double_to_bigint(double src, int64_t *dst) { + *dst = (int64_t)src; + + if (srcLLONG_MAX) return TSDB_CONV_OOR; + if (src == *dst) return TSDB_CONV_OK; + + int64_t v = (int64_t)src; + if (v == *dst) return TSDB_CONV_TRUNC_FRACTION; + + return TSDB_CONV_TRUNC; +} + +TSDB_CONV_CODE tsdb_double_to_ts(double src, int64_t *dst) { + TSDB_CONV_CODE code = tsdb_double_to_bigint(src, dst); + + if (code==TSDB_CONV_OK || code==TSDB_CONV_TRUNC_FRACTION) { + int64_t v = (int64_t)src; + time_t t = (time_t)(v / 1000); + struct tm tm = {0}; + if (localtime_r(&t, &tm)) return TSDB_CONV_OK; + + return TSDB_CONV_OOR; + } + + return code; +} + +TSDB_CONV_CODE tsdb_double_to_char(double src, char *dst, size_t dlen) { + int n = snprintf(dst, dlen, "%lg", src); + DASSERT(n>=0); + + if (n=0); + if (n=19) return TSDB_CONV_TRUNC_FRACTION; + + return TSDB_CONV_TRUNC; +} + +// src: chars +TSDB_CONV_CODE tsdb_chars_to_bit(const char *src, size_t smax, int8_t *dst) { + if (strcmp(src, "0")==0) { + *dst = 0; + return TSDB_CONV_OK; + } + + if (strcmp(src, "1")==0) { + *dst = 1; + return TSDB_CONV_OK; + } + + double v; + int bytes; + int n = sscanf(src, "%lg%n", &v, &bytes); + + if (n!=1) return TSDB_CONV_CHAR_NOT_NUM; + if (bytes!=strlen(src)) return TSDB_CONV_CHAR_NOT_NUM; + + if (v<0 || v>=2) return TSDB_CONV_OOR; + + return TSDB_CONV_TRUNC_FRACTION; +} + +TSDB_CONV_CODE tsdb_chars_to_tinyint(const char *src, size_t smax, int8_t *dst) { + int64_t v; + TSDB_CONV_CODE code = tsdb_chars_to_bigint(src, smax, &v); + if (code!=TSDB_CONV_OK) return code; + + *dst = (int8_t)v; + + if (v==*dst) return TSDB_CONV_OK; + + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_chars_to_smallint(const char *src, size_t smax, int16_t *dst) { + int64_t v; + TSDB_CONV_CODE code = tsdb_chars_to_bigint(src, smax, &v); + if (code!=TSDB_CONV_OK) return code; + + *dst = (int16_t)v; + + if (v==*dst) return TSDB_CONV_OK; + + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_chars_to_int(const char *src, size_t smax, int32_t *dst) { + int64_t v; + TSDB_CONV_CODE code = tsdb_chars_to_bigint(src, smax, &v); + if (code!=TSDB_CONV_OK) return code; + + *dst = (int32_t)v; + + if (v==*dst) return TSDB_CONV_OK; + + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_chars_to_bigint(const char *src, size_t smax, int64_t *dst) { + int bytes; + int n = sscanf(src, "%" PRId64 "%n", dst, &bytes); + + if (n!=1) return TSDB_CONV_CHAR_NOT_NUM; + if (bytes==strlen(src)) { + return TSDB_CONV_OK; + } + + double v; + n = sscanf(src, "%lg%n", &v, &bytes); + if (n!=1) return TSDB_CONV_CHAR_NOT_NUM; + if (bytes==strlen(src)) { + return TSDB_CONV_TRUNC_FRACTION; + } + + return TSDB_CONV_OK; +} + +TSDB_CONV_CODE tsdb_chars_to_ts(const char *src, size_t smax, int64_t *dst) { + int64_t v; + TSDB_CONV_CODE code = tsdb_chars_to_bigint(src, smax, &v); + if (code!=TSDB_CONV_OK) return code; + + *dst = v; + + if (v==*dst) { + time_t t = (time_t)(v / 1000); + struct tm tm = {0}; + if (localtime_r(&t, &tm)) return TSDB_CONV_OK; + } + + return TSDB_CONV_OOR; +} + +TSDB_CONV_CODE tsdb_chars_to_float(const char *src, size_t smax, float *dst) { + int bytes; + int n = sscanf(src, "%g%n", dst, &bytes); + + if (n==1 && bytes==strlen(src)) { + return TSDB_CONV_OK; + } + + return TSDB_CONV_CHAR_NOT_NUM; +} + +TSDB_CONV_CODE tsdb_chars_to_double(const char *src, size_t smax, double *dst) { + int bytes; + int n = sscanf(src, "%lg%n", dst, &bytes); + + if (n==1 && bytes==strlen(src)) { + return TSDB_CONV_OK; + } + + return TSDB_CONV_CHAR_NOT_NUM; +} + +TSDB_CONV_CODE tsdb_chars_to_timestamp(const char *src, size_t smax, SQL_TIMESTAMP_STRUCT *dst) { + int64_t v = 0; + // why cast to 'char*' ? + int r = taosParseTime((char*)src, &v, (int32_t)smax, TSDB_TIME_PRECISION_MILLI, 0); + + if (r) { + return TSDB_CONV_CHAR_NOT_TS; + } + + time_t t = v/1000; + struct tm vtm = {0}; + localtime_r(&t, &vtm); + dst->year = (SQLSMALLINT)(vtm.tm_year + 1900); + dst->month = (SQLUSMALLINT)(vtm.tm_mon + 1); + dst->day = (SQLUSMALLINT)(vtm.tm_mday); + dst->hour = (SQLUSMALLINT)(vtm.tm_hour); + dst->minute = (SQLUSMALLINT)(vtm.tm_min); + dst->second = (SQLUSMALLINT)(vtm.tm_sec); + dst->fraction = (SQLUINTEGER)(v%1000 * 1000000); + + return TSDB_CONV_OK; +} + +TSDB_CONV_CODE tsdb_chars_to_timestamp_ts(const char *src, size_t smax, int64_t *dst) { + // why cast to 'char*' ? + int r = taosParseTime((char*)src, dst, (int32_t)smax, TSDB_TIME_PRECISION_MILLI, 0); + + if (r) { + return TSDB_CONV_CHAR_NOT_TS; + } + + return TSDB_CONV_OK; +} + +TSDB_CONV_CODE tsdb_chars_to_char(const char *src, size_t smax, char *dst, size_t dmax) { + int n = snprintf(dst, dmax, "%s", src); + DASSERT(n>=0); + if (nnext + bytes; + if (next>sizeof(buffer->buf)) return NULL; + + char *p = buffer->buf + buffer->next; + buffer->next = next; + return p; +} + +int is_owned_by_stack_buffer(stack_buffer_t *buffer, const char *ptr) { + if (!buffer) return 0; + if (ptr>=buffer->buf && ptrbuf+buffer->next) return 1; + return 0; +} + + +struct tsdb_conv_s { + iconv_t cnv; + unsigned int direct:1; +}; + +static tsdb_conv_t no_conversion = {0}; +static pthread_once_t once = PTHREAD_ONCE_INIT; +static void once_init(void) { + no_conversion.cnv = (iconv_t)-1; + no_conversion.direct = 1; +} + +tsdb_conv_t* tsdb_conv_direct() { // get a non-conversion-converter + pthread_once(&once, once_init); + return &no_conversion; +} + +tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc) { + pthread_once(&once, once_init); + tsdb_conv_t *cnv = (tsdb_conv_t*)calloc(1, sizeof(*cnv)); + if (!cnv) return NULL; + if (strcmp(from_enc, to_enc)==0 && 0) { + cnv->cnv = (iconv_t)-1; + cnv->direct = 1; + return cnv; + } + cnv->cnv = iconv_open(to_enc, from_enc); + if (cnv->cnv == (iconv_t)-1) { + free(cnv); + return NULL; + } + cnv->direct = 0; + return cnv; +} + +void tsdb_conv_close(tsdb_conv_t *cnv) { + if (!cnv) return; + if (cnv == &no_conversion) return; + if (!cnv->direct) { + if (cnv->cnv != (iconv_t)-1) { + iconv_close(cnv->cnv); + } + } + cnv->cnv = (iconv_t)-1; + cnv->direct = 0; + free(cnv); +} + +TSDB_CONV_CODE tsdb_conv_write(tsdb_conv_t *cnv, const char *src, size_t *slen, char *dst, size_t *dlen) { + if (!cnv) return TSDB_CONV_NOT_AVAIL; + if (cnv->direct) { + size_t n = (*slen > *dlen) ? *dlen : *slen; + memcpy(dst, src, n); + *slen -= n; + *dlen -= n; + if (*dlen) dst[n] = '\0'; + return TSDB_CONV_OK; + } + if (!cnv->cnv) return TSDB_CONV_NOT_AVAIL; + size_t r = iconv(cnv->cnv, (char**)&src, slen, &dst, dlen); + if (r==(size_t)-1) return TSDB_CONV_BAD_CHAR; + if (*slen) return TSDB_CONV_TRUNC; + if (*dlen) *dst = '\0'; + return TSDB_CONV_OK; +} + +TSDB_CONV_CODE tsdb_conv_write_int64(tsdb_conv_t *cnv, int64_t val, char *dst, size_t *dlen) { + char utf8[64]; + int n = snprintf(utf8, sizeof(utf8), "%" PRId64 "", val); + DASSERT(n>=0); + DASSERT(n=0); + DASSERT(n=0); + DASSERT(ndirect) { + if (src[slen]=='\0') { // access violation? + *dst = src; + if (dlen) *dlen = slen; + return TSDB_CONV_OK; + } + blen = slen + 1; + } else { + blen = (slen + 1) * 4; + } + + buf = stack_buffer_alloc(buffer, blen); + if (!buf) { + buf = (char*)malloc(blen); + if (!buf) return TSDB_CONV_OOM; + } + + if (cnv->direct) { + size_t n = slen; + DASSERT(blen > n); + memcpy(buf, src, n); + buf[n] = '\0'; + *dst = buf; + if (dlen) *dlen = n; + return TSDB_CONV_OK; + } + + const char *orig_s = src; + char *orig_d = buf; + size_t orig_blen = blen; + + TSDB_CONV_CODE code; + size_t r = iconv(cnv->cnv, (char**)&src, &slen, &buf, &blen); + do { + if (r==(size_t)-1) { + switch(errno) { + case E2BIG: { + code = TSDB_CONV_SRC_TOO_LARGE; + } break; + case EILSEQ: { + code = TSDB_CONV_SRC_BAD_SEQ; + } break; + case EINVAL: { + code = TSDB_CONV_SRC_INCOMPLETE; + } break; + default: { + code = TSDB_CONV_SRC_GENERAL; + } break; + } + break; + } + if (slen) { + code = TSDB_CONV_TRUNC; + break; + } + DASSERT(blen); + *buf = '\0'; + *dst = orig_d; + if (dlen) *dlen = orig_blen - blen; + return TSDB_CONV_OK; + } while (0); + + if (orig_d!=(char*)orig_s && !is_owned_by_stack_buffer(buffer, orig_d)) free(orig_d); + return code; +} + +void tsdb_conv_free(tsdb_conv_t *cnv, const char *ptr, stack_buffer_t *buffer, const char *src) { + if (ptr!=src && !is_owned_by_stack_buffer(buffer, ptr)) free((char*)ptr); +} + diff --git a/src/connector/odbc/src/todbc_conv.h b/src/connector/odbc/src/todbc_conv.h new file mode 100644 index 0000000000000000000000000000000000000000..2941f3e4961d38ed1e72bfd3d1184d1ea8de251b --- /dev/null +++ b/src/connector/odbc/src/todbc_conv.h @@ -0,0 +1,109 @@ +/* + * 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 _todbc_conv_h_ +#define _todbc_conv_h_ + +#include "os.h" +#include +#include + + +typedef enum { + TSDB_CONV_OK = 0, + TSDB_CONV_NOT_AVAIL, + TSDB_CONV_OOM, + TSDB_CONV_OOR, + TSDB_CONV_TRUNC_FRACTION, + TSDB_CONV_TRUNC, + TSDB_CONV_CHAR_NOT_NUM, + TSDB_CONV_CHAR_NOT_TS, + TSDB_CONV_NOT_VALID_TS, + TSDB_CONV_GENERAL, + TSDB_CONV_BAD_CHAR, + TSDB_CONV_SRC_TOO_LARGE, + TSDB_CONV_SRC_BAD_SEQ, + TSDB_CONV_SRC_INCOMPLETE, + TSDB_CONV_SRC_GENERAL, +} TSDB_CONV_CODE; + +const char* tsdb_conv_code_str(TSDB_CONV_CODE code); + +typedef struct stack_buffer_s stack_buffer_t; +struct stack_buffer_s { + char buf[1024*16]; + size_t next; +}; + +char* stack_buffer_alloc(stack_buffer_t *buffer, size_t bytes); +int is_owned_by_stack_buffer(stack_buffer_t *buffer, const char *ptr); + +typedef struct tsdb_conv_s tsdb_conv_t; +tsdb_conv_t* tsdb_conv_direct(); // get a non-conversion-converter +tsdb_conv_t* tsdb_conv_open(const char *from_enc, const char *to_enc); +void tsdb_conv_close(tsdb_conv_t *cnv); + +TSDB_CONV_CODE tsdb_conv_write(tsdb_conv_t *cnv, const char *src, size_t *slen, char *dst, size_t *dlen); +TSDB_CONV_CODE tsdb_conv_write_int64(tsdb_conv_t *cnv, int64_t val, char *dst, size_t *dlen); +TSDB_CONV_CODE tsdb_conv_write_double(tsdb_conv_t *cnv, double val, char *dst, size_t *dlen); +TSDB_CONV_CODE tsdb_conv_write_timestamp(tsdb_conv_t *cnv, SQL_TIMESTAMP_STRUCT val, char *dst, size_t *dlen); + +TSDB_CONV_CODE tsdb_conv_chars_to_bit(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int8_t *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_tinyint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int8_t *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_smallint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int16_t *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_int(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int32_t *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_bigint(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_ts(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_float(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, float *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_double(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, double *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_timestamp(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, SQL_TIMESTAMP_STRUCT *dst); +TSDB_CONV_CODE tsdb_conv_chars_to_timestamp_ts(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, int64_t *dst); +TSDB_CONV_CODE tsdb_conv(tsdb_conv_t *cnv, stack_buffer_t *buffer, const char *src, size_t slen, const char **dst, size_t *dlen); +void tsdb_conv_free(tsdb_conv_t *cnv, const char *ptr, stack_buffer_t *buffer, const char *src); + + +TSDB_CONV_CODE tsdb_int64_to_bit(int64_t src, int8_t *dst); +TSDB_CONV_CODE tsdb_int64_to_tinyint(int64_t src, int8_t *dst); +TSDB_CONV_CODE tsdb_int64_to_smallint(int64_t src, int16_t *dst); +TSDB_CONV_CODE tsdb_int64_to_int(int64_t src, int32_t *dst); +TSDB_CONV_CODE tsdb_int64_to_bigint(int64_t src, int64_t *dst); +TSDB_CONV_CODE tsdb_int64_to_ts(int64_t src, int64_t *dst); +TSDB_CONV_CODE tsdb_int64_to_float(int64_t src, float *dst); +TSDB_CONV_CODE tsdb_int64_to_double(int64_t src, double *dst); +TSDB_CONV_CODE tsdb_int64_to_char(int64_t src, char *dst, size_t dlen); + +TSDB_CONV_CODE tsdb_double_to_bit(double src, int8_t *dst); +TSDB_CONV_CODE tsdb_double_to_tinyint(double src, int8_t *dst); +TSDB_CONV_CODE tsdb_double_to_smallint(double src, int16_t *dst); +TSDB_CONV_CODE tsdb_double_to_int(double src, int32_t *dst); +TSDB_CONV_CODE tsdb_double_to_bigint(double src, int64_t *dst); +TSDB_CONV_CODE tsdb_double_to_ts(double src, int64_t *dst); +TSDB_CONV_CODE tsdb_double_to_char(double src, char *dst, size_t dlen); + +TSDB_CONV_CODE tsdb_timestamp_to_char(SQL_TIMESTAMP_STRUCT src, char *dst, size_t dlen); + +TSDB_CONV_CODE tsdb_chars_to_bit(const char *src, size_t smax, int8_t *dst); +TSDB_CONV_CODE tsdb_chars_to_tinyint(const char *src, size_t smax, int8_t *dst); +TSDB_CONV_CODE tsdb_chars_to_smallint(const char *src, size_t smax, int16_t *dst); +TSDB_CONV_CODE tsdb_chars_to_int(const char *src, size_t smax, int32_t *dst); +TSDB_CONV_CODE tsdb_chars_to_bigint(const char *src, size_t smax, int64_t *dst); +TSDB_CONV_CODE tsdb_chars_to_ts(const char *src, size_t smax, int64_t *dst); +TSDB_CONV_CODE tsdb_chars_to_float(const char *src, size_t smax, float *dst); +TSDB_CONV_CODE tsdb_chars_to_double(const char *src, size_t smax, double *dst); +TSDB_CONV_CODE tsdb_chars_to_timestamp(const char *src, size_t smax, SQL_TIMESTAMP_STRUCT *dst); +TSDB_CONV_CODE tsdb_chars_to_char(const char *src, size_t smax, char *dst, size_t dmax); + +#endif // _todbc_conv_h_ + diff --git a/src/connector/odbc/src/todbc_flex.h b/src/connector/odbc/src/todbc_flex.h new file mode 100644 index 0000000000000000000000000000000000000000..a13f1f4d2ebd8bbca73d9ff224bb3ed20ed43174 --- /dev/null +++ b/src/connector/odbc/src/todbc_flex.h @@ -0,0 +1,36 @@ +/* + * 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 _TODBC_FLEX_H_ +#define _TODBC_FLEX_H_ + +typedef struct conn_val_s conn_val_t; +struct conn_val_s { + char *key; + char *dsn; + char *uid; + char *pwd; + char *db; + char *server; + char *svr_enc; + char *cli_enc; +}; + + +void conn_val_reset(conn_val_t *val); +int todbc_parse_conn_string(const char *conn, conn_val_t *val); + +#endif // _TODBC_FLEX_H_ + diff --git a/src/connector/odbc/src/todbc_log.h b/src/connector/odbc/src/todbc_log.h new file mode 100644 index 0000000000000000000000000000000000000000..391a690cccb0954736cac76af3354cc8a39754a8 --- /dev/null +++ b/src/connector/odbc/src/todbc_log.h @@ -0,0 +1,42 @@ +/* + * 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 _todbc_log_h_ +#define _todbc_log_h_ + +#include "os.h" + +#define D(fmt, ...) \ + fprintf(stderr, \ + "%s[%d]:%s() " fmt "\n", \ + basename((char*)__FILE__), __LINE__, __func__, \ + ##__VA_ARGS__) + +#define DASSERT(statement) \ +do { \ + if (statement) break; \ + D("Assertion failure: %s", #statement); \ + abort(); \ +} while (0) + +#define DASSERTX(statement, fmt, ...) \ +do { \ + if (statement) break; \ + D("Assertion failure: %s, " fmt "", #statement, ##__VA_ARGS__); \ + abort(); \ +} while (0) + +#endif // _todbc_log_h_ + diff --git a/src/connector/odbc/src/todbc_scanner.l b/src/connector/odbc/src/todbc_scanner.l new file mode 100644 index 0000000000000000000000000000000000000000..f8c6a15d92442ee7f7b9041f017b41a4ed590314 --- /dev/null +++ b/src/connector/odbc/src/todbc_scanner.l @@ -0,0 +1,165 @@ +%{ +#include "todbc_flex.h" +#include + +#ifdef _MSC_VER +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + +#define PUSH_STATE(state) yy_push_state(state, yyscanner) +#define POP_STATE() yy_pop_state(yyscanner) + +#define CHG_STATE(state) \ +do { \ + yy_pop_state(yyscanner); \ + yy_push_state(state, yyscanner); \ +} while (0) + +#define TOP_STATE(top) \ +do { \ + yy_push_state(INITIAL, yyscanner); \ + top = yy_top_state(yyscanner); \ + yy_pop_state(yyscanner); \ +} while (0) + +#define UNPUT() \ +do { \ + while (yyleng) unput(yytext[yyleng-1]); \ +} while (0) + +#define set_key() \ +do { \ + free(yyextra->key); \ + yyextra->key = strdup(yytext); \ +} while (0) + +#define set_val() \ +do { \ + if (!yyextra->key) break; \ + if (strcasecmp(yyextra->key, "DSN")==0) { \ + free(yyextra->dsn); \ + yyextra->dsn = strdup(yytext); \ + break; \ + } \ + if (strcasecmp(yyextra->key, "UID")==0) { \ + free(yyextra->uid); \ + yyextra->uid = strdup(yytext); \ + break; \ + } \ + if (strcasecmp(yyextra->key, "PWD")==0) { \ + free(yyextra->pwd); \ + yyextra->pwd = strdup(yytext); \ + break; \ + } \ + if (strcasecmp(yyextra->key, "DB")==0) { \ + free(yyextra->db); \ + yyextra->pwd = strdup(yytext); \ + break; \ + } \ + if (strcasecmp(yyextra->key, "Server")==0) { \ + free(yyextra->server); \ + yyextra->server = strdup(yytext); \ + break; \ + } \ + if (strcasecmp(yyextra->key, "SERVER_ENC")==0) { \ + free(yyextra->svr_enc); \ + yyextra->svr_enc = strdup(yytext); \ + break; \ + } \ + if (strcasecmp(yyextra->key, "CLIENT_ENC")==0) { \ + free(yyextra->cli_enc); \ + yyextra->cli_enc = strdup(yytext); \ + break; \ + } \ +} while (0) + +%} + +%option prefix="todbc_yy" +%option extra-type="conn_val_t *" +%option nounistd +%option never-interactive +%option reentrant +%option noyywrap +%option noinput nounput +%option debug verbose +%option stack +%option nodefault +%option warn +%option perf-report +%option 8bit + +%x KEY EQ BRACE1 BRACE2 VAL + +%% +<> { int state; TOP_STATE(state); + if (state == INITIAL) yyterminate(); + if (state == VAL) yyterminate(); + return -1; } +[[:space:]]+ { } +[[:alnum:]_]+ { set_key(); PUSH_STATE(KEY); } +.|\n { return -1; } + +[[:space:]]+ { } +[=] { CHG_STATE(EQ); } +.|\n { return -1; } + +[[:space:]]+ { } +[^][{}(),;?*=!@/\\\n[:space:]]+ { set_val(); CHG_STATE(VAL); } +[{] { CHG_STATE(BRACE1); } +.|\n { return -1; } + +[^{}\n]+ { set_val(); CHG_STATE(BRACE2); } +.|\n { return -1; } + +[[:space:]]+ { } +[}] { CHG_STATE(VAL); } +.|\n { return -1; } + +[;] { POP_STATE(); } +.|\n { return -1; } +%% + +int todbc_parse_conn_string(const char *conn, conn_val_t *val) { + yyscan_t arg = {0}; + yylex_init(&arg); + yyset_debug(0, arg); + yyset_extra(val, arg); + yy_scan_string(conn, arg); + int ret =yylex(arg); + yylex_destroy(arg); + if (val->key) free(val->key); val->key = NULL; + if (ret) { + conn_val_reset(val); + } + return ret ? -1 : 0; +} + +void conn_val_reset(conn_val_t *val) { + if (val->key) { + free(val->key); val->key = NULL; + } + if (val->dsn) { + free(val->dsn); val->dsn = NULL; + } + if (val->uid) { + free(val->uid); val->uid = NULL; + } + if (val->pwd) { + free(val->pwd); val->pwd = NULL; + } + if (val->db) { + free(val->db); val->db = NULL; + } + if (val->server) { + free(val->server); val->server = NULL; + } + if (val->svr_enc) { + free(val->svr_enc); val->svr_enc = NULL; + } + if (val->cli_enc) { + free(val->cli_enc); val->cli_enc = NULL; + } +} + diff --git a/src/connector/odbc/src/todbc_util.c b/src/connector/odbc/src/todbc_util.c index b6b45d8120d28da31dcc1d323893984f9b93519b..9c130b4f2f2e6d0f5d4a19e11ab323d42b800195 100644 --- a/src/connector/odbc/src/todbc_util.c +++ b/src/connector/odbc/src/todbc_util.c @@ -14,14 +14,10 @@ */ #include "todbc_util.h" - -#include "iconv.h" - -#include -#include +#include "todbc_log.h" +#include #include -#include -#include + const char* sql_sql_type(int type) { switch (type) { @@ -111,39 +107,6 @@ int is_valid_sql_sql_type(int type) { return 1; } -int string_conv(const char *fromcode, const char *tocode, - const unsigned char *src, size_t sbytes, - unsigned char *dst, size_t dbytes, - size_t *consumed, size_t *generated) -{ - if (consumed) *consumed = 0; - if (generated) *generated = 0; - - if (dbytes <= 0) return -1; - dst[0] = '\0'; - - iconv_t conv = iconv_open(tocode, fromcode); - if (!conv) return -1; - - int r = 0; - do { - char *s = (char*)src; - char *d = (char*)dst; - size_t sl = sbytes; - size_t dl = dbytes; - - r = iconv(conv, &s, &sl, &d, &dl); - *d = '\0'; - - if (consumed) *consumed = sbytes - sl; - if (generated) *generated = dbytes - dl; - - } while (0); - - iconv_close(conv); - return r; -} - int utf8_chars(const char *src) { const char *fromcode = "UTF-8"; @@ -161,78 +124,6 @@ int utf8_chars(const char *src) size_t chars = (sizeof(buf) - dlen) / 2; iconv_close(conv); - return chars; -} - -unsigned char* utf8_to_ucs4le(const char *utf8, size_t *chars) -{ - const char *tocode = "UCS-4LE"; - const char *fromcode = "UTF-8"; - - iconv_t conv = iconv_open(tocode, fromcode); - if (!conv) return NULL; - - unsigned char *ucs4le = NULL; - - do { - size_t slen = strlen(utf8); - size_t dlen = slen * 4; - - ucs4le = (unsigned char*)malloc(dlen+1); - if (!ucs4le) break; - - char *src = (char*)utf8; - char *dst = (char*)ucs4le; - size_t s = slen; - size_t d = dlen; - iconv(conv, &src, &s, &dst, &d); - dst[0] = '\0'; - - if (chars) *chars = (dlen - d) / 4; - } while (0); - - iconv_close(conv); - return ucs4le; -} - -char* ucs4le_to_utf8(const unsigned char *ucs4le, size_t slen, size_t *chars) -{ - const char *fromcode = "UCS-4LE"; - const char *tocode = "UTF-8"; - - iconv_t conv = iconv_open(tocode, fromcode); - if (!conv) return NULL; - - char *utf8 = NULL; - - do { - size_t dlen = slen; - - utf8 = (char*)malloc(dlen+1); - if (!utf8) break; - - char *dst = utf8; - char *src = (char*)ucs4le; - size_t s = slen; - size_t d = dlen; - iconv(conv, &src, &s, &dst, &d); - dst[0] = '\0'; - - if (chars) *chars = (slen - s) / 4; - } while (0); - - iconv_close(conv); - return utf8; -} - -SQLCHAR* wchars_to_chars(const SQLWCHAR *wchars, size_t chs, size_t *bytes) -{ - size_t dlen = chs * 4; - SQLCHAR *dst = (SQLCHAR*)malloc(dlen + 1); - if (!dst) return NULL; - - string_conv("UCS-2LE", "UTF-8", (const unsigned char*)wchars, chs * sizeof(*wchars), dst, dlen + 1, NULL, bytes); - - return dst; + return (int)chars; } diff --git a/src/connector/odbc/src/todbc_util.h b/src/connector/odbc/src/todbc_util.h index 43264975b4e618bd495691e59fb9df59f6664e03..ead0d7348973409c85741cc4d676e40f6f140447 100644 --- a/src/connector/odbc/src/todbc_util.h +++ b/src/connector/odbc/src/todbc_util.h @@ -16,33 +16,10 @@ #ifndef _TODBC_UTIL_H_ #define _TODBC_UTIL_H_ -#include -#include -#include -#include -#include - -#define D(fmt, ...) \ - fprintf(stderr, \ - "%s[%d]:%s() " fmt "\n", \ - basename((char*)__FILE__), __LINE__, __func__, \ - ##__VA_ARGS__) - -#define DASSERT(statement) \ -do { \ - if (statement) break; \ - D("Assertion failure: %s", #statement); \ - abort(); \ -} while (0) - -#define DASSERTX(statement, fmt, ...) \ -do { \ - if (statement) break; \ - D("Assertion failure: %s, " fmt "", #statement, ##__VA_ARGS__); \ - abort(); \ -} while (0) - +#include "os.h" +#include +#include const char* sql_sql_type(int type); const char* sql_c_type(int type); @@ -50,14 +27,7 @@ const char* sql_c_type(int type); int is_valid_sql_c_type(int type); int is_valid_sql_sql_type(int type); -int string_conv(const char *fromcode, const char *tocode, - const unsigned char *src, size_t sbytes, - unsigned char *dst, size_t dbytes, - size_t *consumed, size_t *generated); int utf8_chars(const char *src); -unsigned char* utf8_to_ucs4le(const char *utf8, size_t *chars); -char* ucs4le_to_utf8(const unsigned char *ucs4le, size_t slen, size_t *chars); -SQLCHAR* wchars_to_chars(const SQLWCHAR *wchars, size_t chs, size_t *bytes); - #endif // _TODBC_UTIL_H_ + diff --git a/src/connector/odbc/tests/CMakeLists.txt b/src/connector/odbc/tests/CMakeLists.txt index ac57a5647fce8bd036e133936284f3f4c847d8c8..1cc6acaf4bf34aa2158cc1f4fa0836d6e51f3a41 100644 --- a/src/connector/odbc/tests/CMakeLists.txt +++ b/src/connector/odbc/tests/CMakeLists.txt @@ -1,7 +1,18 @@ PROJECT(TDengine) IF (TD_LINUX) - AUX_SOURCE_DIRECTORY(. SRC) + # AUX_SOURCE_DIRECTORY(. SRC) ADD_EXECUTABLE(tcodbc main.c) TARGET_LINK_LIBRARIES(tcodbc odbc) + ADD_EXECUTABLE(tconv tconv.c) +ENDIF () + +IF (TD_WINDOWS_64) + SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} /GL") + SET(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} /GL") + # AUX_SOURCE_DIRECTORY(. SRC) + ADD_EXECUTABLE(tcodbc main.c) + TARGET_LINK_LIBRARIES(tcodbc odbc32 odbccp32 user32 legacy_stdio_definitions os) + ADD_EXECUTABLE(tconv tconv.c) + TARGET_LINK_LIBRARIES(tconv tutil) ENDIF () diff --git a/src/connector/odbc/tests/create_data.stmts b/src/connector/odbc/tests/create_data.stmts new file mode 100644 index 0000000000000000000000000000000000000000..549cb583d8322906b4bdaffafde8eb510cb91c90 --- /dev/null +++ b/src/connector/odbc/tests/create_data.stmts @@ -0,0 +1,12 @@ +P:drop database if exists m; +P:create database m; +P:use m; + +P:drop table if exists t; +P:create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(3), name nchar(1)); +P:insert into t (ts, blob, name) values('2020-10-10 00:00:00', 0, 1); +P:insert into t (ts, blob, name) values('2020-10-10 00:00:00.001', 1, 2); +P:insert into t (ts, blob, name) values('2020-10-10 00:00:00.002', '你', '好'); +P:insert into t (ts, blob, name) values('2020-10-10 00:00:00.003', 'abc', 'd'); +P:select * from t; + diff --git a/src/connector/odbc/tests/main.c b/src/connector/odbc/tests/main.c index 1ac9b71369e8a526b051008b9379fdda4b6a5e77..417de00d55f64249a9194b77fecbeb458c560cc7 100644 --- a/src/connector/odbc/tests/main.c +++ b/src/connector/odbc/tests/main.c @@ -1,14 +1,38 @@ +#include "../src/todbc_log.h" + +#ifdef _MSC_VER +#include +#include +#include "os.h" +#endif #include #include +#include #include #include -#include "os.h" +#define CHK_TEST(statement) \ +do { \ + D("testing: %s", #statement); \ + int r = (statement); \ + if (r) { \ + D("testing failed: %s", #statement); \ + return 1; \ + } \ +} while (0); + +typedef struct db_column_s db_column_t; +struct db_column_s { + SQLSMALLINT nameLength; + char name[4096]; // seems enough + SQLSMALLINT dataType; + SQLULEN columnSize; + SQLSMALLINT decimalDigits; + SQLSMALLINT nullable; +}; -// static const char *dsn = "TAOS_DSN"; -// static const char *uid = "root"; -// static const char *pwd = "taosdata"; +static db_column_t *columns = NULL; typedef struct data_s data_t; struct data_s { @@ -37,7 +61,7 @@ static const char *pro_stmts[] = { // "drop database db" }; -#define CHK_RESULT(r, ht, h) \ +#define CHK_RESULT(r, ht, h, fmt, ...) \ do { \ if (r==0) break; \ SQLCHAR ss[10]; \ @@ -48,23 +72,149 @@ do { es[0] = '\0'; \ SQLRETURN ret = SQLGetDiagRec(ht, h, 1, ss, &ne, es, sizeof(es), &n); \ if (ret) break; \ - fprintf(stderr, "%s%s\n", ss, es); \ + D("[%s]%s: " fmt "", ss, es, ##__VA_ARGS__); \ } while (0) +static int open_connect(const char *dsn, const char *uid, const char *pwd, SQLHENV *pEnv, SQLHDBC *pConn) { + SQLRETURN r; + SQLHENV env = {0}; + SQLHDBC conn = {0}; + r = SQLAllocEnv(&env); + if (r!=SQL_SUCCESS) return 1; + do { + r = SQLAllocConnect(env, &conn); + CHK_RESULT(r, SQL_HANDLE_ENV, env, ""); + if (r!=SQL_SUCCESS) break; + do { + r = SQLConnect(conn, (SQLCHAR*)dsn, (SQLSMALLINT)(dsn ? strlen(dsn) : 0), + (SQLCHAR*)uid, (SQLSMALLINT)(uid ? strlen(uid) : 0), + (SQLCHAR*)pwd, (SQLSMALLINT)(pwd ? strlen(pwd) : 0)); + CHK_RESULT(r, SQL_HANDLE_DBC, conn, ""); + if (r==SQL_SUCCESS) { + *pEnv = env; + *pConn = conn; + return 0; + } + } while (0); + SQLFreeConnect(conn); + } while (0); + SQLFreeEnv(env); + + return 1; +} + +static int open_driver_connect(const char *connstr, SQLHENV *pEnv, SQLHDBC *pConn) { + SQLRETURN r; + SQLHENV env = {0}; + SQLHDBC conn = {0}; + r = SQLAllocEnv(&env); + if (r!=SQL_SUCCESS) return 1; + do { + r = SQLAllocConnect(env, &conn); + CHK_RESULT(r, SQL_HANDLE_ENV, env, ""); + if (r!=SQL_SUCCESS) break; + do { + SQLCHAR buf[4096]; + SQLSMALLINT blen = 0; + SQLHDBC ConnectionHandle = conn; + SQLHWND WindowHandle = NULL; + SQLCHAR * InConnectionString = (SQLCHAR*)connstr; + SQLSMALLINT StringLength1 = (SQLSMALLINT)(connstr ? strlen(connstr) : 0); + SQLCHAR * OutConnectionString = buf; + SQLSMALLINT BufferLength = sizeof(buf); + SQLSMALLINT * StringLength2Ptr = &blen; + SQLUSMALLINT DriverCompletion = SQL_DRIVER_NOPROMPT; + r = SQLDriverConnect(ConnectionHandle, WindowHandle, InConnectionString, + StringLength1, OutConnectionString, BufferLength, + StringLength2Ptr, DriverCompletion); + CHK_RESULT(r, SQL_HANDLE_DBC, conn, ""); + if (r==SQL_SUCCESS) { + *pEnv = env; + *pConn = conn; + return 0; + } + } while (0); + SQLFreeConnect(conn); + } while (0); + SQLFreeEnv(env); + + return 1; +} + +static SQLRETURN traverse_cols(SQLHSTMT stmt, SQLSMALLINT cols) { + SQLRETURN r = SQL_ERROR; + for (SQLSMALLINT i=0; i0) fprintf(stdout, "\n"); + return r; + } + } + if (soi==SQL_NULL_DATA) { + fprintf(stdout, "%snull", i==0?"":","); + } else { + fprintf(stdout, "%s\"%s\"", i==0?"":",", buf); + } + } + fprintf(stdout, "\n"); + } + + // r = SQLFetch(stmt); + // if (r==SQL_NO_DATA) { + // D(".........."); + // r = SQL_SUCCESS; + // break; + // } + // CHK_RESULT(r, SQL_HANDLE_STMT, stmt, ""); + // if (r) break; + // r = SQLPrepare(stmt, (SQLCHAR*)statement, strlen(statement)); + // CHK_RESULT(r, SQL_HANDLE_STMT, stmt, ""); + // if (r) break; + // r = SQLExecute(stmt); + // CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); + // if (r) break; } while (0); - fprintf(stderr, "r: [%x][%d]\n", r, r); return r; } @@ -74,158 +224,450 @@ static int do_insert(SQLHSTMT stmt, data_t data) { SQLLEN lblob; const char *statement = "insert into t values (?, ?, ?, ?, ?, ?, ?, ?, ?,?)"; - int ignored = 0; + #define ignored 0 do { - fprintf(stderr, "prepare [%s]\n", statement); - r = SQLPrepare(stmt, (SQLCHAR*)statement, strlen(statement)); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + r = SQLPrepare(stmt, (SQLCHAR*)statement, (SQLINTEGER)strlen(statement)); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 1 [%s]\n", statement); r = SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_TIMESTAMP, ignored, ignored, &data.ts, ignored, NULL); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 2 [%s]\n", statement); r = SQLBindParameter(stmt, 2, SQL_PARAM_INPUT, SQL_C_BIT, SQL_BIT, ignored, ignored, &data.b, ignored, NULL); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 3 [%s]\n", statement); r = SQLBindParameter(stmt, 3, SQL_PARAM_INPUT, SQL_C_TINYINT, SQL_TINYINT, ignored, ignored, &data.v1, ignored, NULL); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 4 [%s]\n", statement); r = SQLBindParameter(stmt, 4, SQL_PARAM_INPUT, SQL_C_SHORT, SQL_SMALLINT, ignored, ignored, &data.v2, ignored, NULL); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 5 [%s]\n", statement); r = SQLBindParameter(stmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, ignored, ignored, &data.v4, ignored, NULL); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 6 [%s]\n", statement); r = SQLBindParameter(stmt, 6, SQL_PARAM_INPUT, SQL_C_SBIGINT, SQL_BIGINT, ignored, ignored, &data.v8, ignored, NULL); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 7 [%s]\n", statement); r = SQLBindParameter(stmt, 7, SQL_PARAM_INPUT, SQL_C_FLOAT, SQL_FLOAT, ignored, ignored, &data.f4, ignored, NULL); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 8 [%s]\n", statement); r = SQLBindParameter(stmt, 8, SQL_PARAM_INPUT, SQL_C_DOUBLE, SQL_DOUBLE, ignored, ignored, &data.f8, ignored, NULL); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 9 [%s]\n", statement); lbin = SQL_NTS; r = SQLBindParameter(stmt, 9, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, sizeof(data.bin)-1, ignored, &data.bin, ignored, &lbin); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "bind 10 [%s]\n", statement); lblob = SQL_NTS; r = SQLBindParameter(stmt, 10, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(data.blob)-1, ignored, &data.blob, ignored, &lblob); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; - fprintf(stderr, "execute [%s]\n", statement); r = SQLExecute(stmt); - CHK_RESULT(r, SQL_HANDLE_STMT, stmt); + CHK_RESULT(r, SQL_HANDLE_STMT, stmt, "statement: %s", statement); if (r) break; // ts += 1; // v = 2; - // fprintf(stderr, "execute [%s]\n", statement); // r = SQLExecute(stmt); // if (r) break; - - fprintf(stderr, "done\n"); } while (0); - fprintf(stderr, "r: [%x][%d]\n", r, r); + + #undef ignored return r; } -int main(int argc, char *argv[]) { - if (argc < 4) return 1; - const char *dsn = argv[1]; - const char *uid = argv[2]; - const char *pwd = argv[3]; - SQLRETURN r; +static int test1(const char *dsn, const char *uid, const char *pwd) { SQLHENV env = {0}; SQLHDBC conn = {0}; - r = SQLAllocEnv(&env); - if (r!=SQL_SUCCESS) return 1; + int n = open_connect(dsn, uid, pwd, &env, &conn); + if (n) return 1; + + int ok = 0; do { - r = SQLAllocConnect(env, &conn); - CHK_RESULT(r, SQL_HANDLE_ENV, env); + SQLRETURN r = SQL_SUCCESS; + SQLHSTMT stmt = {0}; + r = SQLAllocHandle(SQL_HANDLE_STMT, conn, &stmt); if (r!=SQL_SUCCESS) break; do { - r = SQLConnect(conn, (SQLCHAR*)dsn, strlen(dsn), - (SQLCHAR*)uid, strlen(uid), - (SQLCHAR*)pwd, strlen(pwd)); - CHK_RESULT(r, SQL_HANDLE_DBC, conn); - if (r!=SQL_SUCCESS) break; + if (do_statement(stmt, "drop database if exists db")) { + break; + } + for (size_t i=0; i0 && line[n-1] == '\n') line[n-1]='\0'; + if (n>0 && line[n-1] == '\r') line[n-1]='\0'; + if (n>1 && line[n-2] == '\r') line[n-2]='\0'; + p = line; + while (isspace(*p)) ++p; + + if (*p==0) break; + + int positive = 1; + if (strncmp(p, "N:", 2)==0) { + positive = 0; + p += 2; + } else if (strncmp(p, "P:", 2)==0) { + p += 2; + } + + D("statement: [%s]", p); + r = do_statement(stmt, p); + + if (positive && r==0) break; + if (!positive && r) { r = 0; break; } + if (positive) return r; + D("expecting negative result, but got positive"); + return -1; + } while (0); + + free(line); + + if (r) break; + } + + fclose(f); + return r ? 1 : 0; +} + +int test_sqls_in_conn(SQLHENV env, SQLHDBC conn, const char *sqls) { + SQLHSTMT stmt = {0}; + CHK_TEST(create_statement(env, conn, &stmt)); + int r = test_sqls_in_stmt(env, conn, stmt, sqls); + SQLFreeHandle(SQL_HANDLE_STMT, stmt); + return r ? 1 : 0; +} + +int test_sqls(const char *dsn, const char *uid, const char *pwd, const char *connstr, const char *sqls) { + int r = 0; + SQLHENV env = {0}; + SQLHDBC conn = {0}; + if (dsn) { + CHK_TEST(open_connect(dsn, uid, pwd, &env, &conn)); + } else { + CHK_TEST(open_driver_connect(connstr, &env, &conn)); + } + if (sqls) { + r = test_sqls_in_conn(env, conn, sqls); + } + SQLDisconnect(conn); + SQLFreeConnect(conn); + SQLFreeEnv(env); + return r ? 1 : 0; +} + +void usage(const char *arg0) { + fprintf(stdout, "%s usage:\n", arg0); + fprintf(stdout, "%s [--dsn ] [--uid ] [--pwd ] [--dcs ] [--sts ]\n", arg0); + fprintf(stdout, " --dsn : DSN\n"); + fprintf(stdout, " --uid : UID\n"); + fprintf(stdout, " --pwd : PWD\n"); + fprintf(stdout, " --dcs : driver connection string\n"); + fprintf(stdout, " --sts : file where statements store\n"); +} + +int main(int argc, char *argv[]) { + // if (argc==1) { + // CHK_TEST(test_env()); + // CHK_TEST(test1("TAOS_DSN", "root", "taoxsdata")); + // D("Done!"); + // return 0; + // } + + const char *dsn = NULL; + const char *uid = NULL; + const char *pwd = NULL; + const char *dcs = NULL; // driver connection string + const char *sts = NULL; // statements file + for (size_t i=1; i=argc) { + D(" expected but got nothing"); + return 1; + } + if (dcs) { + D("--dcs has already been specified"); + return 1; + } + dsn = argv[i]; + continue; + } + if (strcmp(arg, "--uid")==0) { + ++i; + if (i>=argc) { + D(" expected but got nothing"); + return 1; + } + uid = argv[i]; + continue; + } + if (strcmp(arg, "--pwd")==0) { + ++i; + if (i>=argc) { + D(" expected but got nothing"); + return 1; + } + pwd = argv[i]; + continue; + } + if (strcmp(arg, "--dcs")==0) { + ++i; + if (i>=argc) { + D(" expected but got nothing"); + return 1; + } + if (dsn || uid || pwd) { + D("either of --dsn/--uid/--pwd has already been specified"); + return 1; + } + dcs = argv[i]; + continue; + } + if (strcmp(arg, "--sts")==0) { + ++i; + if (i>=argc) { + D(" expected but got nothing"); + return 1; + } + sts = argv[i]; + continue; + } + } + CHK_TEST(test_sqls(dsn, uid, pwd, dcs, sts)); + D("Done!"); + return 0; + + if (0) { + const char *dsn = (argc>1) ? argv[1] : NULL; + const char *uid = (argc>2) ? argv[2] : NULL; + const char *pwd = (argc>3) ? argv[3] : NULL; + const char *connstr = (argc>4) ? argv[4] : NULL; + const char *sqls = (argc>5) ? argv[5] : NULL; + + dsn = NULL; + uid = NULL; + pwd = NULL; + connstr = argv[1]; + sqls = argv[2]; + if (0) { + CHK_TEST(test_env()); + + CHK_TEST(test1(dsn, uid, pwd)); + + const char *statements[] = { + "drop database if exists m", + "create database m", + "use m", + "drop database m", + NULL + }; + CHK_TEST(test_statements(dsn, uid, pwd, statements)); + + if (connstr) + CHK_TEST(test_driver_connect(connstr)); + + if (connstr) { + SQLHENV env = {0}; + SQLHDBC conn = {0}; + CHK_TEST(open_driver_connect(connstr, &env, &conn)); + int r = tests(env, conn); + SQLDisconnect(conn); + SQLFreeConnect(conn); + SQLFreeEnv(env); + if (r) return 1; + } + } + + if ((dsn || connstr) && 1) { + CHK_TEST(test_sqls(dsn, uid, pwd, connstr, sqls)); + } + + D("Done!"); + return 0; + } +} + diff --git a/src/connector/odbc/tests/odbc.py b/src/connector/odbc/tests/odbc.py index d2de8f39c631dff15a29565a9a19582c58c43b6f..c137905775e567f6163846690886850cb77a684a 100644 --- a/src/connector/odbc/tests/odbc.py +++ b/src/connector/odbc/tests/odbc.py @@ -1,16 +1,17 @@ import pyodbc -cnxn = pyodbc.connect('DSN=TAOS_DSN;UID=root;PWD=taosdata', autocommit=True) +# cnxn = pyodbc.connect('DSN={TAOS_DSN};UID={ root };PWD={ taosdata };HOST={ localhost:6030 }', autocommit=True) +cnxn = pyodbc.connect('DSN={TAOS_DSN}; UID=root;PWD=taosdata; HOST=localhost:6030', autocommit=True) cnxn.setdecoding(pyodbc.SQL_CHAR, encoding='utf-8') #cnxn.setdecoding(pyodbc.SQL_WCHAR, encoding='utf-8') #cnxn.setencoding(encoding='utf-8') -cursor = cnxn.cursor() -cursor.execute("SELECT * from db.t") -row = cursor.fetchone() -while row: - print(row) - row = cursor.fetchone() -cursor.close() +#cursor = cnxn.cursor() +#cursor.execute("SELECT * from db.t") +#row = cursor.fetchone() +#while row: +# print(row) +# row = cursor.fetchone() +#cursor.close() #cursor = cnxn.cursor() #cursor.execute(""" @@ -36,32 +37,32 @@ cursor.execute("create database db"); cursor.close() cursor = cnxn.cursor() -cursor.execute("create table db.t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))"); +cursor.execute("create table db.mt (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(40), blob nchar(10))"); cursor.close() cursor = cnxn.cursor() -cursor.execute("insert into db.t values('2020-10-13 06:44:00', 1, 127, 32767, 32768, 32769, 123.456, 789.987, 'hello', 'world')") +cursor.execute("insert into db.mt values('2020-10-13 06:44:00', 1, 127, 32767, 32768, 32769, 123.456, 789.987, 'hello', 'world')") cursor.close() cursor = cnxn.cursor() -cursor.execute("insert into db.t values(?,?,?,?,?,?,?,?,?,?)", "2020-10-13 07:06:00", 0, 127, 32767, 32768, 32769, 123.456, 789.987, "hel后lo", "wo哈rld"); +cursor.execute("insert into db.mt values(?,?,?,?,?,?,?,?,?,?)", "2020-10-13 07:06:00", 0, 127, 32767, 32768, 32769, 123.456, 789.987, "hel后lo", "wo哈rld"); cursor.close() cursor = cnxn.cursor() -cursor.execute("SELECT * from db.t") +cursor.execute("SELECT * from db.mt") row = cursor.fetchone() while row: print(row) row = cursor.fetchone() cursor.close() -cursor = cnxn.cursor() -cursor.execute("drop database if exists db"); -cursor.close() - -cursor = cnxn.cursor() -cursor.execute("create database db"); -cursor.close() +#cursor = cnxn.cursor() +#cursor.execute("drop database if exists db"); +#cursor.close() +# +#cursor = cnxn.cursor() +#cursor.execute("create database db"); +#cursor.close() cursor = cnxn.cursor() cursor.execute("create table db.t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, bin binary(4), blob nchar(4))"); @@ -118,3 +119,13 @@ while row: row = cursor.fetchone() cursor.close() +cursor = cnxn.cursor() +cursor.execute("create table db.f (ts timestamp, v1 float)") +cursor.close() + +params = [ ('2020-10-20 00:00:10', '123.3') ] +cursor = cnxn.cursor() +cursor.fast_executemany = True +cursor.executemany("insert into db.f values (?, ?)", params) +cursor.close() + diff --git a/src/connector/odbc/tests/query_data.stmts b/src/connector/odbc/tests/query_data.stmts new file mode 100644 index 0000000000000000000000000000000000000000..b0e9ea27ea81f53780ebf3bced8e8a5f63bf7e2b --- /dev/null +++ b/src/connector/odbc/tests/query_data.stmts @@ -0,0 +1 @@ +P:select * from m.t; diff --git a/src/connector/odbc/tests/select.stmts b/src/connector/odbc/tests/select.stmts new file mode 100644 index 0000000000000000000000000000000000000000..f7152ba6cf59ae2d0af75bba1845f6fb80150a0e --- /dev/null +++ b/src/connector/odbc/tests/select.stmts @@ -0,0 +1,4 @@ +P: select * from db.t; +P: select * from db.f; +P: select * from db.v; +P: select * from db.mt; \ No newline at end of file diff --git a/src/connector/odbc/tests/simples.stmts b/src/connector/odbc/tests/simples.stmts new file mode 100644 index 0000000000000000000000000000000000000000..0db58a8807491b9ea4be96dc7c4efc5b43488244 --- /dev/null +++ b/src/connector/odbc/tests/simples.stmts @@ -0,0 +1,44 @@ +P:drop database if exists m; +P:create database m; +P:use m; + +P:create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(1), name nchar(1)); +P:insert into t (ts, b) values('2020-10-10 00:00:00', 0); +P:insert into t (ts, b) values('2020-10-10 00:00:00.001', 1); +P:insert into t (ts, b) values('2020-10-10 00:00:00.002', 10); +P:select * from t; + +P:drop table t; +P:create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(1), name nchar(1)); +P:insert into t (ts, v1) values('2020-10-10 00:00:00', 0); +P:insert into t (ts, v1) values('2020-10-10 00:00:00.001', 1); +P:insert into t (ts, v1) values('2020-10-10 00:00:00.002', 10); +P:select * from t; + +P:drop table t; +P:create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(1), name nchar(1)); +P:insert into t (ts, name) values('2020-10-10 00:00:00', 0); +P:insert into t (ts, name) values('2020-10-10 00:00:00.001', 1); +P:insert into t (ts, name) values('2020-10-10 00:00:00.002', '人'); +P:insert into t (ts, name) values('2020-10-10 00:00:00.003', 'a'); +P:select * from t; + +P:drop table t; +P:create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(3), name nchar(1)); +P:insert into t (ts, blob) values('2020-10-10 00:00:00', 0); +P:insert into t (ts, blob) values('2020-10-10 00:00:00.001', 1); +P:insert into t (ts, blob) values('2020-10-10 00:00:00.002', 'a'); +P:insert into t (ts, blob) values('2020-10-10 00:00:00.003', 'b'); +P:insert into t (ts, blob) values('2020-10-10 00:00:00.004', '人'); +P:select * from t; + +P:drop table t; +P:create table t (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, blob binary(3), name nchar(1)); +N:insert into t (ts, blob) values('2020-10-10 00:00:00', '1234'); +N:insert into t (ts, blob) values('2020-10-10 00:00:00.001', '0000'); +N:insert into t (ts, blob) values('2020-10-10 00:00:00.002', '人a'); +P:insert into t (ts, blob) values('2020-10-10 00:00:00.003', 'a'); +P:insert into t (ts, blob) values('2020-10-10 00:00:00.004', 'b'); +P:insert into t (ts, blob) values('2020-10-10 00:00:00.005', '人'); +P:select * from t; + diff --git a/src/connector/odbc/tests/tconv.c b/src/connector/odbc/tests/tconv.c new file mode 100644 index 0000000000000000000000000000000000000000..acae6421bbe52d8522f37a756d5097a3b32bb5c7 --- /dev/null +++ b/src/connector/odbc/tests/tconv.c @@ -0,0 +1,156 @@ +#include "../src/todbc_log.h" + +#ifdef _MSC_VER +#include +#include +#endif + +#include + + +#include +#include + +static void usage(const char *arg0); +static int do_conv(iconv_t cnv, FILE *fin, FILE *fout); + +int main(int argc, char *argv[]) { + const char *from_enc = "UTF-8"; + const char *to_enc = "UTF-8"; + const char *dst_file = NULL; + const char *src = NULL; +#ifdef _MSC_VER + from_enc = "CP936"; + to_enc = "CP936"; +#endif + for (int i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (strcmp(arg, "-h") == 0) { + usage(argv[0]); + return 0; + } else if (strcmp(arg, "-f") == 0 ) { + i += 1; + if (i>=argc) { + fprintf(stderr, "expecing , but got nothing\n"); + return 1; + } + from_enc = argv[i]; + continue; + } else if (strcmp(arg, "-t") == 0 ) { + i += 1; + if (i>=argc) { + fprintf(stderr, "expecing , but got nothing\n"); + return 1; + } + to_enc = argv[i]; + continue; + } else if (strcmp(arg, "-o") == 0 ) { + i += 1; + if (i>=argc) { + fprintf(stderr, "expecing , but got nothing\n"); + return 1; + } + dst_file = argv[i]; + continue; + } else if (arg[0]=='-') { + fprintf(stderr, "unknown argument: [%s]\n", arg); + return 1; + } else { + if (src) { + fprintf(stderr, "does not allow multiple files\n"); + return 1; + } + src = arg; + continue; + } + } + int r = -1; + FILE *fin = src ? fopen(src, "rb") : stdin; + FILE *fout = dst_file ? fopen(dst_file, "wb") : stdout; + iconv_t cnv = iconv_open(to_enc, from_enc); + do { + if (!fin) { + fprintf(stderr, "failed to open file [%s]\n", src); + break; + } + if (!fout) { + fprintf(stderr, "failed to open file [%s]\n", dst_file); + break; + } +#ifdef _MSC_VER + if (fout == stdout) { + r = _setmode(_fileno(fout), _O_BINARY); + if (r == -1) { + fprintf(stderr, "Cannot set binary mode for output stream: %d[%s]\n", errno, strerror(errno)); + } + } +#endif + + if (cnv == (iconv_t)-1) { + fprintf(stderr, "failed to open conv from [%s] to [%s]: [%s]\n", from_enc, to_enc, strerror(errno)); + break; + } + r = do_conv(cnv, fin, fout); + iconv_close(cnv); + cnv = (iconv_t)-1; + } while (0); + if (fin && fin != stdin) fclose(fin); + if (fout && fout != stdout) fclose(fout); + return r ? 1 : 0; +} + +static void usage(const char *arg0) { + fprintf(stderr, "%s -h | [-f ] [-t ] [-o ] [file]\n", arg0); + return; +} + +#define IN_SIZE (64*1024) +#define OUT_SIZE (8*IN_SIZE) +static int do_conv(iconv_t cnv, FILE *fin, FILE *fout) { + int r = 0; + char src[IN_SIZE]; + size_t slen = sizeof(src); + char dst[OUT_SIZE]; + size_t dlen = sizeof(dst); + char *start = src; + while (!feof(fin)) { + slen = (size_t)(src + sizeof(src) - start); + size_t n = fread(start, 1, slen, fin); + if (n>0) { + char *ss = src; + size_t sl = n; + while (sl) { + char *dd = dst; + size_t dn = dlen; + size_t v = iconv(cnv, &ss, &sl, &dd, &dn); + if (v==(size_t)-1) { + int err = errno; + if (err == EILSEQ) { + fprintf(stderr, "failed to convert: [%s]\n", strerror(err)); + r = -1; + break; + } + if (err == EINVAL) { + fprintf(stderr, "[%s]\n", strerror(errno)); + size_t ava = (size_t)(src + sizeof(src) - ss); + memcpy(src, ss, ava); + start = ss; + } else { + fprintf(stderr, "internal logic error: [%s]\n", strerror(errno)); + r = -1; + break; + } + } + n = fwrite(dst, 1, (size_t)(dd-dst), fout); + if (n +#include +#include "os.h" +#endif +#include + +#include +#include +#include + +static void usage(const char *arg0); +static int do_install(int i, int argc, char *argv[]); +static int do_uninstall(int i, int argc, char *argv[]); + +int main(int argc, char *argv[]) { + for (int i = 1; i < argc; i++) { + const char *arg = argv[i]; + if (strcmp(arg, "-h") == 0) { + usage(argv[0]); + return 0; + } else if (strcmp(arg, "-i") == 0 ) { + i = do_install(i + 1, argc, argv); + if (i > 0) continue; + return i == 0 ? 0 : 1; + } else if (strcmp(arg, "-u") == 0 ) { + i = do_uninstall(i + 1, argc, argv); + if (i > 0) continue; + return i == 0 ? 0 : 1; + } else { + fprintf(stderr, "unknown argument: [%s]\n", arg); + return 1; + } + } +} + +static void usage(const char *arg0) { + fprintf(stderr, "%s -h | -i -n [TaosDriverName] -p [TaosDriverPath] | -u [-f] -n [TaosDriverName]\n", arg0); + return; +} + +static int do_install(int i, int argc, char *argv[]) { + const char* driverName = NULL; +#ifdef _MSC_VER + const char* driverFile = "todbc.dll"; +#else + const char* driverFile = "libtodbc.so"; +#endif + const char* driverPath = NULL; + for (; i < argc; ++i) { + const char *arg = argv[i]; + if (strcmp(arg, "-n") == 0) { + i += 1; + if (i >= argc) { + fprintf(stderr, "expecting TaosDriverName, but got nothing\n"); + return -1; + } + arg = argv[i]; + if (strstr(arg, "TAOS") != arg) { + fprintf(stderr, "TaosDriverName shall begin with 'TAOS': [%s]\n", arg); + return -1; + } + driverName = arg; + } else if (strcmp(arg, "-p") == 0) { + i += 1; + if (i >= argc) { + fprintf(stderr, "expecting TaosDriverPath, but got nothing\n"); + return -1; + } + driverPath = argv[i]; + } else { + fprintf(stderr, "unknown argument: [%s]\n", arg); + return -1; + } + } + if (!driverName) { + fprintf(stderr, "TaosDriverName not specified\n"); + return -1; + } + if (!driverPath) { + fprintf(stderr, "TaosDriverPath not specified\n"); + return -1; + } + char buf[8192]; + snprintf(buf, sizeof(buf), "%s%cDriver=%s%cFileUage=0%cConnectFunctions=YYN%c", + driverName, 0, driverFile, 0, 0, 0); + BOOL ok = 1; + DWORD usageCount = 1; + char installed[PATH_MAX + 1]; + WORD len = 0; + ok = SQLInstallDriverEx(buf, driverPath, installed, sizeof(installed), &len, ODBC_INSTALL_INQUIRY, &usageCount); + if (!ok) { + fprintf(stderr, "failed to query TaosDriverName: [%s]\n", driverName); + return -1; + } + int r = 0; +#ifdef _MSC_VER + r = stricmp(driverPath, installed); +#else + r = strcasecmp(driverPath, installed); +#endif + if (r) { + fprintf(stderr, "previously installed TaosDriver [%s] has different target path [%s]\n" + "it shall be uninstalled before you can install it to different path [%s]\n", + driverName, installed, driverPath); + return -1; + } + ok = SQLInstallDriverEx(buf, driverPath, installed, sizeof(installed), &len, ODBC_INSTALL_COMPLETE, &usageCount); + if (!ok) { + fprintf(stderr, "failed to install TaosDriverName: [%s][%s]\n", driverName, driverPath); + return -1; + } + + fprintf(stderr, "ODBC driver [%s] has been installed in [%s], and UsageCount is now [%d]\n", + driverName, driverPath, usageCount); + return argc; +} + +static int do_uninstall(int i, int argc, char *argv[]) { + int forceful = 0; + const char* driverName = NULL; + for (; i < argc; ++i) { + const char *arg = argv[i]; + if (strcmp(arg, "-f") == 0) { + forceful = 1; + } else if (strcmp(arg, "-n") == 0) { + i += 1; + if (i >= argc) { + fprintf(stderr, "expecting TaosDriverName, but got nothing\n"); + return -1; + } + arg = argv[i]; + if (strstr(arg, "TAOS") != arg) { + fprintf(stderr, "TaosDriverName shall begin with 'TAOS': [%s]\n", arg); + return -1; + } + driverName = arg; + } else { + fprintf(stderr, "unknown argument: [%s]\n", arg); + return -1; + } + } + if (!driverName) { + fprintf(stderr, "TaosDriverName not specified\n"); + return -1; + } + BOOL ok = 1; + DWORD usageCount = 1; + do { + ok = SQLRemoveDriver(driverName, 0, &usageCount); + if (!ok) { + fprintf(stderr, "failed to remove driver [%s]\n", driverName); + return -1; + } + if (!forceful) { + fprintf(stderr, "UsageCount for ODBC driver [%s] is now: [%d]\n", driverName, usageCount); + return argc; + } + } while (usageCount > 0); + fprintf(stderr, "ODBC driver [%s] is now fully uninstalled\n", driverName); + return argc; +} + diff --git a/src/connector/python/linux/python2/taos/cinterface.py b/src/connector/python/linux/python2/taos/cinterface.py index 32859f6b340b4393b523d475bce1ac89cef1a040..269326535cfb39373544c71685e8a2b9e9b51db1 100644 --- a/src/connector/python/linux/python2/taos/cinterface.py +++ b/src/connector/python/linux/python2/taos/cinterface.py @@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): _timestamp_converter = _convert_microsecond_to_datetime if num_of_rows > 0: - return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::-1])) + return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1])) else: return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)])) @@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bool row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ] @@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C tinyint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ] @@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C smallint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]] + return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]] else: return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ] @@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C int row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ] @@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bigint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ] @@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C float row to python row """ if num_of_rows > 0: - return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ] + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ] else: return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ] @@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C double row to python row """ if num_of_rows > 0: - return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ] + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ] else: return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ] @@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ if num_of_rows > 0: - return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]] + return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]] else: return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] @@ -311,29 +311,24 @@ class CTaosInterface(object): @staticmethod def fetchBlock(result, fields): pblock = ctypes.c_void_p(0) - num_of_rows = CTaosInterface.libtaos.taos_fetch_block( - result, ctypes.byref(pblock)) - - if num_of_rows == 0: + pblock = CTaosInterface.libtaos.taos_fetch_row(result) + if pblock : + num_of_rows = 1 + isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) + blocks = [None] * len(fields) + fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) + fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] + for i in range(len(fields)): + data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] + if fields[i]['type'] not in _CONVERT_FUNC: + raise DatabaseError("Invalid data type returned from database") + if data is None: + blocks[i] = [None] + else: + blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) + else: return None, 0 - - isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if data == None: - blocks[i] = [None] * num_of_rows - continue - - if fields[i]['type'] not in _CONVERT_FUNC: - raise DatabaseError("Invalid data type returned from database") - - blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) - return blocks, abs(num_of_rows) - @staticmethod def freeResult(result): CTaosInterface.libtaos.taos_free_result(result) diff --git a/src/connector/python/linux/python2/taos/cursor.py b/src/connector/python/linux/python2/taos/cursor.py index 37c02d330e856717b5ed0bdac76723cf64d3860b..bc6670ca776a351c4739d61fc165d71334ceaa3b 100644 --- a/src/connector/python/linux/python2/taos/cursor.py +++ b/src/connector/python/linux/python2/taos/cursor.py @@ -1,6 +1,7 @@ from .cinterface import CTaosInterface from .error import * from .constants import FieldType +import threading class TDengineCursor(object): @@ -35,6 +36,7 @@ class TDengineCursor(object): self._block_iter = 0 self._affected_rows = 0 self._logfile = "" + self._threadId = threading.get_ident() if connection is not None: self._connection = connection @@ -42,7 +44,7 @@ class TDengineCursor(object): def __iter__(self): return self - def next(self): + def __next__(self): if self._result is None or self._fields is None: raise OperationalError("Invalid use of fetch iterator") @@ -137,7 +139,7 @@ class TDengineCursor(object): else: raise ProgrammingError( CTaosInterface.errStr( - self._result ), errno) + self._result), errno) def executemany(self, operation, seq_of_parameters): """Prepare a database operation (query or command) and then execute it against all parameter sequences or mappings found in the sequence seq_of_parameters. @@ -148,6 +150,8 @@ class TDengineCursor(object): """Fetch the next row of a query result set, returning a single sequence, or None when no more data is available. """ pass + def fetchmany(self): + pass def istype(self, col, dataType): if (dataType.upper() == "BOOL"): @@ -180,9 +184,6 @@ class TDengineCursor(object): return False - def fetchmany(self): - pass - def fetchall(self): """Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation. """ @@ -201,8 +202,6 @@ class TDengineCursor(object): self._rowcount += num_of_fields for i in range(len(self._fields)): buffer[i].extend(block[i]) - - return list(map(tuple, zip(*buffer))) def nextset(self): diff --git a/src/connector/python/linux/python3/taos/cinterface.py b/src/connector/python/linux/python3/taos/cinterface.py index 609154a3a4b38cfd1cf7976fb755e4aef7be3354..be5b99d8c18272c5f53d1e49f731588b70062b29 100644 --- a/src/connector/python/linux/python3/taos/cinterface.py +++ b/src/connector/python/linux/python3/taos/cinterface.py @@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): _timestamp_converter = _convert_microsecond_to_datetime if num_of_rows > 0: - return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::-1])) + return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1])) else: return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)])) @@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bool row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ] @@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C tinyint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ] @@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C smallint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]] + return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]] else: return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ] @@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C int row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ] @@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bigint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_long))[:abs(num_of_rows)] ] @@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C float row to python row """ if num_of_rows > 0: - return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ] + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ] else: return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ] @@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C double row to python row """ if num_of_rows > 0: - return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ] + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ] else: return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ] @@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ if num_of_rows > 0: - return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]] + return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]] else: return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] @@ -111,7 +111,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): # except ValueError: # res.append(None) # return res - # # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::-1]] + # # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)][::1]] # else: # return [ele.value for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_wchar * (nbytes//4))))[:abs(num_of_rows)]] @@ -308,32 +308,48 @@ class CTaosInterface(object): return fields + # @staticmethod + # def fetchBlock(result, fields): + # pblock = ctypes.c_void_p(0) + # num_of_rows = CTaosInterface.libtaos.taos_fetch_block( + # result, ctypes.byref(pblock)) + # if num_of_rows == 0: + # return None, 0 + + # isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) + # blocks = [None] * len(fields) + # fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) + # fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] + # for i in range(len(fields)): + # data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] + + # if fields[i]['type'] not in _CONVERT_FUNC: + # raise DatabaseError("Invalid data type returned from database") + # print('====================',fieldLen[i]) + # blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) + + # return blocks, abs(num_of_rows) @staticmethod def fetchBlock(result, fields): pblock = ctypes.c_void_p(0) - num_of_rows = CTaosInterface.libtaos.taos_fetch_block( - result, ctypes.byref(pblock)) - - if num_of_rows == 0: + pblock = CTaosInterface.libtaos.taos_fetch_row(result) + if pblock : + num_of_rows = 1 + isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) + blocks = [None] * len(fields) + fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) + fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] + for i in range(len(fields)): + data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] + if fields[i]['type'] not in _CONVERT_FUNC: + raise DatabaseError("Invalid data type returned from database") + if data is None: + blocks[i] = [None] + else: + blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) + else: return None, 0 - - isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if data == None: - blocks[i] = [None] * num_of_rows - continue - - if fields[i]['type'] not in _CONVERT_FUNC: - raise DatabaseError("Invalid data type returned from database") - - blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) - return blocks, abs(num_of_rows) - @staticmethod def freeResult(result): CTaosInterface.libtaos.taos_free_result(result) diff --git a/src/connector/python/linux/python3/taos/cursor.py b/src/connector/python/linux/python3/taos/cursor.py index ec7a85ee1a3f8cb0cd49aca8c2a4242dca89021e..eb10bed4859828961a0c521e146c18a5f8e21d7c 100644 --- a/src/connector/python/linux/python3/taos/cursor.py +++ b/src/connector/python/linux/python3/taos/cursor.py @@ -216,7 +216,6 @@ class TDengineCursor(object): self._rowcount += num_of_fields for i in range(len(self._fields)): buffer[i].extend(block[i]) - return list(map(tuple, zip(*buffer))) def nextset(self): diff --git a/src/connector/python/windows/python2/taos/cinterface.py b/src/connector/python/windows/python2/taos/cinterface.py index 6a9c5bfcef0d317844b6b58796f307e5cf155a43..084d38e41cee0e8c31a11d319d47e6bc5b125bd7 100644 --- a/src/connector/python/windows/python2/taos/cinterface.py +++ b/src/connector/python/windows/python2/taos/cinterface.py @@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): _timestamp_converter = _convert_microsecond_to_datetime if num_of_rows > 0: - return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1])) + return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1])) else: return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)])) @@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bool row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ] @@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C tinyint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ] @@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C smallint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]] + return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]] else: return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ] @@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C int row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ] @@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bigint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ] @@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C float row to python row """ if num_of_rows > 0: - return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ] + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ] else: return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ] @@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C double row to python row """ if num_of_rows > 0: - return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ] + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ] else: return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ] @@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ if num_of_rows > 0: - return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]] + return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]] else: return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] @@ -310,27 +310,23 @@ class CTaosInterface(object): @staticmethod def fetchBlock(result, fields): pblock = ctypes.c_void_p(0) - num_of_rows = CTaosInterface.libtaos.taos_fetch_block( - result, ctypes.byref(pblock)) - - if num_of_rows == 0: + pblock = CTaosInterface.libtaos.taos_fetch_row(result) + if pblock : + num_of_rows = 1 + isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) + blocks = [None] * len(fields) + fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) + fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] + for i in range(len(fields)): + data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] + if fields[i]['type'] not in _CONVERT_FUNC: + raise DatabaseError("Invalid data type returned from database") + if data is None: + blocks[i] = [None] + else: + blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) + else: return None, 0 - - isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if data == None: - blocks[i] = [None] * num_of_rows - continue - - if fields[i]['type'] not in _CONVERT_FUNC: - raise DatabaseError("Invalid data type returned from database") - - blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) - return blocks, abs(num_of_rows) @staticmethod diff --git a/src/connector/python/windows/python2/taos/cursor.py b/src/connector/python/windows/python2/taos/cursor.py index 8714fe77cb739f23f79247a41d72aa127b6d6d25..35846cbe11f49386747a5a1f59e5529b84a741a0 100644 --- a/src/connector/python/windows/python2/taos/cursor.py +++ b/src/connector/python/windows/python2/taos/cursor.py @@ -1,5 +1,9 @@ from .cinterface import CTaosInterface from .error import * +from .constants import FieldType +import threading + +# querySeqNum = 0 class TDengineCursor(object): """Database cursor which is used to manage the context of a fetch operation. @@ -32,6 +36,8 @@ class TDengineCursor(object): self._block_rows = -1 self._block_iter = 0 self._affected_rows = 0 + self._logfile = "" + self._threadId = threading.get_ident() if connection is not None: self._connection = connection @@ -39,7 +45,7 @@ class TDengineCursor(object): def __iter__(self): return self - def next(self): + def __next__(self): if self._result is None or self._fields is None: raise OperationalError("Invalid use of fetch iterator") diff --git a/src/connector/python/windows/python3/taos/cinterface.py b/src/connector/python/windows/python3/taos/cinterface.py index fa7124431c92a179b2a0042b57e8ad45609ea352..68adf191c9bf696575254974ab6a544d5664faa5 100644 --- a/src/connector/python/windows/python3/taos/cinterface.py +++ b/src/connector/python/windows/python3/taos/cinterface.py @@ -18,7 +18,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): _timestamp_converter = _convert_microsecond_to_datetime if num_of_rows > 0: - return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1])) + return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1])) else: return list(map(_timestamp_converter, ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)])) @@ -26,7 +26,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bool row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_BOOL_NULL else bool(ele) for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_bool))[:abs(num_of_rows)] ] @@ -34,7 +34,7 @@ def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C tinyint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_byte))[:abs(num_of_rows)] ] @@ -42,7 +42,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C smallint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::-1]] + return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)][::1]] else: return [ None if ele == FieldType.C_SMALLINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_short))[:abs(num_of_rows)] ] @@ -50,7 +50,7 @@ def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C int row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)] ] @@ -58,7 +58,7 @@ def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C bigint row to python row """ if num_of_rows > 0: - return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::-1] ] + return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)][::1] ] else: return [ None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_longlong))[:abs(num_of_rows)] ] @@ -66,7 +66,7 @@ def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C float row to python row """ if num_of_rows > 0: - return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::-1] ] + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)][::1] ] else: return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)] ] @@ -74,7 +74,7 @@ def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C double row to python row """ if num_of_rows > 0: - return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::-1] ] + return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)][::1] ] else: return [ None if math.isnan(ele) else ele for ele in ctypes.cast(data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)] ] @@ -82,7 +82,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): """Function to convert C binary row to python row """ if num_of_rows > 0: - return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::-1]] + return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)][::1]] else: return [ None if ele.value[0:1] == FieldType.C_BINARY_NULL else ele.value.decode('utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] @@ -225,6 +225,7 @@ class CTaosInterface(object): if connection.value == None: print('connect to TDengine failed') + raise ConnectionError("connect to TDengine failed") # sys.exit(1) else: print('connect to TDengine success') @@ -310,27 +311,23 @@ class CTaosInterface(object): @staticmethod def fetchBlock(result, fields): pblock = ctypes.c_void_p(0) - num_of_rows = CTaosInterface.libtaos.taos_fetch_block( - result, ctypes.byref(pblock)) - - if num_of_rows == 0: + pblock = CTaosInterface.libtaos.taos_fetch_row(result) + if pblock : + num_of_rows = 1 + isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) + blocks = [None] * len(fields) + fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) + fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] + for i in range(len(fields)): + data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] + if fields[i]['type'] not in _CONVERT_FUNC: + raise DatabaseError("Invalid data type returned from database") + if data is None: + blocks[i] = [None] + else: + blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) + else: return None, 0 - - isMicro = (CTaosInterface.libtaos.taos_result_precision(result) == FieldType.C_TIMESTAMP_MICRO) - blocks = [None] * len(fields) - fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) - fieldLen = [ele for ele in ctypes.cast(fieldL, ctypes.POINTER(ctypes.c_int))[:len(fields)]] - for i in range(len(fields)): - data = ctypes.cast(pblock, ctypes.POINTER(ctypes.c_void_p))[i] - if data == None: - blocks[i] = [None] * num_of_rows - continue - - if fields[i]['type'] not in _CONVERT_FUNC: - raise DatabaseError("Invalid data type returned from database") - - blocks[i] = _CONVERT_FUNC[fields[i]['type']](data, num_of_rows, fieldLen[i], isMicro) - return blocks, abs(num_of_rows) @staticmethod diff --git a/src/connector/python/windows/python3/taos/cursor.py b/src/connector/python/windows/python3/taos/cursor.py index c2c442b06ee71ae90ec63662886c709e38d4d2ad..b58b494cad0e0a2b664ef4765eae2baee27aa20b 100644 --- a/src/connector/python/windows/python3/taos/cursor.py +++ b/src/connector/python/windows/python3/taos/cursor.py @@ -1,5 +1,10 @@ from .cinterface import CTaosInterface from .error import * +from .constants import FieldType +import threading + +# querySeqNum = 0 + class TDengineCursor(object): """Database cursor which is used to manage the context of a fetch operation. @@ -32,6 +37,8 @@ class TDengineCursor(object): self._block_rows = -1 self._block_iter = 0 self._affected_rows = 0 + self._logfile = "" + self._threadId = threading.get_ident() if connection is not None: self._connection = connection diff --git a/src/dnode/inc/dnodeVRead.h b/src/dnode/inc/dnodeVRead.h index b3c3df80b2e201ff9f4b40ebfcceafba57de1366..5b17693146cb68ab66943593bc2f9cd6587cc225 100644 --- a/src/dnode/inc/dnodeVRead.h +++ b/src/dnode/inc/dnodeVRead.h @@ -24,7 +24,7 @@ int32_t dnodeInitVRead(); void dnodeCleanupVRead(); void dnodeDispatchToVReadQueue(SRpcMsg *pMsg); void * dnodeAllocVReadQueue(void *pVnode); -void dnodeFreeVReadQueue(void *rqueue); +void dnodeFreeVReadQueue(void *pRqueue); #ifdef __cplusplus } diff --git a/src/dnode/src/dnodeEps.c b/src/dnode/src/dnodeEps.c index 9c90c391813f57024ecf090136dfa86f5e5f91e6..83f294e05eb0e559638fef1259ad96ac6f162460 100644 --- a/src/dnode/src/dnodeEps.c +++ b/src/dnode/src/dnodeEps.c @@ -33,7 +33,7 @@ static void dnodePrintEps(SDnodeEps *eps); int32_t dnodeInitEps() { pthread_mutex_init(&tsEpsMutex, NULL); - tsEpsHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true); + tsEpsHash = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); dnodeResetEps(NULL); int32_t ret = dnodeReadEps(); if (ret == 0) { diff --git a/src/dnode/src/dnodeMRead.c b/src/dnode/src/dnodeMRead.c index c14c7a81586d306ff1423e8dba91e0844293c407..ee9da72e4d3424ffb97b6cbc90098edd1abf3a6d 100644 --- a/src/dnode/src/dnodeMRead.c +++ b/src/dnode/src/dnodeMRead.c @@ -168,7 +168,8 @@ static void *dnodeProcessMReadQueue(void *param) { break; } - dDebug("%p, msg:%s will be processed in mread queue", pRead->rpcMsg.ahandle, taosMsg[pRead->rpcMsg.msgType]); + dDebug("msg:%p, app:%p type:%s will be processed in mread queue", pRead->rpcMsg.ahandle, pRead, + taosMsg[pRead->rpcMsg.msgType]); int32_t code = mnodeProcessRead(pRead); dnodeSendRpcMReadRsp(pRead, code); } diff --git a/src/dnode/src/dnodeMWrite.c b/src/dnode/src/dnodeMWrite.c index bde4b95bc6d0019178312cfa76a34bb381608097..65c0d5381969f291d40245bc31dc4acdf849f5ac 100644 --- a/src/dnode/src/dnodeMWrite.c +++ b/src/dnode/src/dnodeMWrite.c @@ -127,7 +127,7 @@ void dnodeDispatchToMWriteQueue(SRpcMsg *pMsg) { dnodeSendRedirectMsg(pMsg, true); } else { SMnodeMsg *pWrite = mnodeCreateMsg(pMsg); - dDebug("app:%p:%p, msg:%s is put into mwrite queue:%p", pWrite->rpcMsg.ahandle, pWrite, + dDebug("msg:%p, app:%p type:%s is put into mwrite queue:%p", pWrite, pWrite->rpcMsg.ahandle, taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue); taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite); } @@ -136,7 +136,7 @@ void dnodeDispatchToMWriteQueue(SRpcMsg *pMsg) { } static void dnodeFreeMWriteMsg(SMnodeMsg *pWrite) { - dDebug("app:%p:%p, msg:%s is freed from mwrite queue:%p", pWrite->rpcMsg.ahandle, pWrite, + dDebug("msg:%p, app:%p type:%s is freed from mwrite queue:%p", pWrite, pWrite->rpcMsg.ahandle, taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue); mnodeCleanupMsg(pWrite); @@ -174,7 +174,7 @@ static void *dnodeProcessMWriteQueue(void *param) { break; } - dDebug("app:%p:%p, msg:%s will be processed in mwrite queue", pWrite->rpcMsg.ahandle, pWrite, + dDebug("msg:%p, app:%p type:%s will be processed in mwrite queue", pWrite, pWrite->rpcMsg.ahandle, taosMsg[pWrite->rpcMsg.msgType]); int32_t code = mnodeProcessWrite(pWrite); @@ -188,13 +188,13 @@ void dnodeReprocessMWriteMsg(void *pMsg) { SMnodeMsg *pWrite = pMsg; if (!mnodeIsRunning() || tsMWriteQueue == NULL) { - dDebug("app:%p:%p, msg:%s is redirected for mnode not running, retry times:%d", pWrite->rpcMsg.ahandle, pWrite, + dDebug("msg:%p, app:%p type:%s is redirected for mnode not running, retry times:%d", pWrite, pWrite->rpcMsg.ahandle, taosMsg[pWrite->rpcMsg.msgType], pWrite->retry); dnodeSendRedirectMsg(pMsg, true); dnodeFreeMWriteMsg(pWrite); } else { - dDebug("app:%p:%p, msg:%s is reput into mwrite queue:%p, retry times:%d", pWrite->rpcMsg.ahandle, pWrite, + dDebug("msg:%p, app:%p type:%s is reput into mwrite queue:%p, retry times:%d", pWrite, pWrite->rpcMsg.ahandle, taosMsg[pWrite->rpcMsg.msgType], tsMWriteQueue, pWrite->retry); taosWriteQitem(tsMWriteQueue, TAOS_QTYPE_RPC, pWrite); diff --git a/src/dnode/src/dnodeMgmt.c b/src/dnode/src/dnodeMgmt.c index dcb48f7833abf921d1085e1cbb14b9cfbf2aa8b7..da1852e05eca11ae9909fe75ff1bb14eee6ae5fb 100644 --- a/src/dnode/src/dnodeMgmt.c +++ b/src/dnode/src/dnodeMgmt.c @@ -216,7 +216,7 @@ static void *dnodeProcessMgmtQueue(void *param) { } pMsg = &pMgmt->rpcMsg; - dDebug("%p, msg:%p:%s will be processed", pMsg->ahandle, pMgmt, taosMsg[pMsg->msgType]); + dDebug("msg:%p, ahandle:%p type:%s will be processed", pMgmt, pMsg->ahandle, taosMsg[pMsg->msgType]); if (dnodeProcessMgmtMsgFp[pMsg->msgType]) { rsp.code = (*dnodeProcessMgmtMsgFp[pMsg->msgType])(pMsg); } else { diff --git a/src/dnode/src/dnodeVRead.c b/src/dnode/src/dnodeVRead.c index 34df11adcce72a6a21718b81c1895c30c66bea1c..4cce54bf59eecbef6a7056e005819d456178279a 100644 --- a/src/dnode/src/dnodeVRead.c +++ b/src/dnode/src/dnodeVRead.c @@ -35,7 +35,7 @@ typedef struct { pthread_mutex_t mutex; } SVReadWorkerPool; -static void *dnodeProcessReadQueue(void *param); +static void *dnodeProcessReadQueue(void *pWorker); // module global variable static SVReadWorkerPool tsVReadWP; @@ -47,7 +47,7 @@ int32_t dnodeInitVRead() { tsVReadWP.min = tsNumOfCores; tsVReadWP.max = tsNumOfCores * tsNumOfThreadsPerCore; if (tsVReadWP.max <= tsVReadWP.min * 2) tsVReadWP.max = 2 * tsVReadWP.min; - tsVReadWP.worker = (SVReadWorker *)calloc(sizeof(SVReadWorker), tsVReadWP.max); + tsVReadWP.worker = calloc(sizeof(SVReadWorker), tsVReadWP.max); pthread_mutex_init(&tsVReadWP.mutex, NULL); if (tsVReadWP.worker == NULL) return -1; @@ -85,7 +85,7 @@ void dnodeCleanupVRead() { void dnodeDispatchToVReadQueue(SRpcMsg *pMsg) { int32_t queuedMsgNum = 0; int32_t leftLen = pMsg->contLen; - char * pCont = (char *)pMsg->pCont; + char * pCont = pMsg->pCont; while (leftLen > 0) { SMsgHead *pHead = (SMsgHead *)pCont; @@ -146,8 +146,8 @@ void *dnodeAllocVReadQueue(void *pVnode) { return queue; } -void dnodeFreeVReadQueue(void *rqueue) { - taosCloseQueue(rqueue); +void dnodeFreeVReadQueue(void *pRqueue) { + taosCloseQueue(pRqueue); } void dnodeSendRpcVReadRsp(void *pVnode, SVReadMsg *pRead, int32_t code) { @@ -159,14 +159,12 @@ void dnodeSendRpcVReadRsp(void *pVnode, SVReadMsg *pRead, int32_t code) { }; rpcSendResponse(&rpcRsp); - vnodeRelease(pVnode); } void dnodeDispatchNonRspMsg(void *pVnode, SVReadMsg *pRead, int32_t code) { - vnodeRelease(pVnode); } -static void *dnodeProcessReadQueue(void *param) { +static void *dnodeProcessReadQueue(void *pWorker) { SVReadMsg *pRead; int32_t qtype; void * pVnode; @@ -177,7 +175,7 @@ static void *dnodeProcessReadQueue(void *param) { break; } - dDebug("%p, msg:%p:%s will be processed in vread queue, qtype:%d", pRead->rpcAhandle, pRead, + dDebug("msg:%p, app:%p type:%s will be processed in vread queue, qtype:%d", pRead, pRead->rpcAhandle, taosMsg[pRead->msgType], qtype); int32_t code = vnodeProcessRead(pVnode, pRead); @@ -193,7 +191,7 @@ static void *dnodeProcessReadQueue(void *param) { } } - taosFreeQitem(pRead); + vnodeFreeFromRQueue(pVnode, pRead); } return NULL; diff --git a/src/dnode/src/dnodeVWrite.c b/src/dnode/src/dnodeVWrite.c index da1a902fb3f6f3d84298d15cec840a7cc352f028..959eb3c9c532c249a04a67ae2d8b34992e9bcdc6 100644 --- a/src/dnode/src/dnodeVWrite.c +++ b/src/dnode/src/dnodeVWrite.c @@ -205,8 +205,8 @@ static void *dnodeProcessVWriteQueue(void *wparam) { bool forceFsync = false; for (int32_t i = 0; i < numOfMsgs; ++i) { taosGetQitem(pWorker->qall, &qtype, (void **)&pWrite); - dTrace("%p, msg:%p:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite->rpcAhandle, pWrite, - taosMsg[pWrite->pHead->msgType], qtypeStr[qtype], pWrite->pHead->version); + dTrace("msg:%p, app:%p type:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite, + pWrite->rpcAhandle, taosMsg[pWrite->pHead->msgType], qtypeStr[qtype], pWrite->pHead->version); pWrite->code = vnodeProcessWrite(pVnode, pWrite->pHead, qtype, &pWrite->rspRet); if (pWrite->code <= 0) pWrite->processedCount = 1; diff --git a/src/inc/dnode.h b/src/inc/dnode.h index d71fdd5e0a12511d84366a661f6c9dd8a73e8c9a..eef4490800a4191c2dee55c450cf99b8381bb64d 100644 --- a/src/inc/dnode.h +++ b/src/inc/dnode.h @@ -57,7 +57,7 @@ void *dnodeAllocVWriteQueue(void *pVnode); void dnodeFreeVWriteQueue(void *pWqueue); void dnodeSendRpcVWriteRsp(void *pVnode, void *pWrite, int32_t code); void *dnodeAllocVReadQueue(void *pVnode); -void dnodeFreeVReadQueue(void *rqueue); +void dnodeFreeVReadQueue(void *pRqueue); int32_t dnodeAllocateMPeerQueue(); void dnodeFreeMPeerQueue(); diff --git a/src/inc/taos.h b/src/inc/taos.h index 2c6454ced1911de603f120c79af5237c2f064c48..cd863587a635ea0aee1e4a288f617e4601b0a09a 100644 --- a/src/inc/taos.h +++ b/src/inc/taos.h @@ -17,6 +17,7 @@ #define TDENGINE_TAOS_H #include +#include #ifdef __cplusplus extern "C" { @@ -109,13 +110,14 @@ DLL_EXPORT TAOS_RES *taos_query(TAOS *taos, const char *sql); DLL_EXPORT TAOS_ROW taos_fetch_row(TAOS_RES *res); DLL_EXPORT int taos_result_precision(TAOS_RES *res); // get the time precision of result DLL_EXPORT void taos_free_result(TAOS_RES *res); -DLL_EXPORT int taos_field_count(TAOS_RES *tres); +DLL_EXPORT int taos_field_count(TAOS_RES *res); DLL_EXPORT int taos_num_fields(TAOS_RES *res); DLL_EXPORT int taos_affected_rows(TAOS_RES *res); DLL_EXPORT TAOS_FIELD *taos_fetch_fields(TAOS_RES *res); DLL_EXPORT int taos_select_db(TAOS *taos, const char *db); DLL_EXPORT int taos_print_row(char *str, TAOS_ROW row, TAOS_FIELD *fields, int num_fields); DLL_EXPORT void taos_stop_query(TAOS_RES *res); +DLL_EXPORT bool taos_is_null(TAOS_RES *res, int32_t row, int32_t col); int taos_fetch_block(TAOS_RES *res, TAOS_ROW *rows); int taos_validate_sql(TAOS *taos, const char *sql); diff --git a/src/inc/taoserror.h b/src/inc/taoserror.h index 1aa9095b30f3bedced87d41b4c74fa30a073e2d3..ff91989e5f15b00775fd02505704a3afccaab500 100644 --- a/src/inc/taoserror.h +++ b/src/inc/taoserror.h @@ -24,9 +24,9 @@ extern "C" { #include #ifdef TAOS_ERROR_C -#define TAOS_DEFINE_ERROR(name, mod, code, msg) {.val = (0x80000000 | ((mod)<<16) | (code)), .str=(msg)}, +#define TAOS_DEFINE_ERROR(name, mod, code, msg) {.val = (int32_t)((0x80000000 | ((mod)<<16) | (code))), .str=(msg)}, #else -#define TAOS_DEFINE_ERROR(name, mod, code, msg) static const int32_t name = (0x80000000 | ((mod)<<16) | (code)); +#define TAOS_DEFINE_ERROR(name, mod, code, msg) static const int32_t name = (int32_t)((0x80000000 | ((mod)<<16) | (code))); #endif #define TAOS_SYSTEM_ERROR(code) (0x80ff0000 | (code)) @@ -107,6 +107,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_TSC_CONN_KILLED, 0, 0x0215, "Connection TAOS_DEFINE_ERROR(TSDB_CODE_TSC_SQL_SYNTAX_ERROR, 0, 0x0216, "Syntax error in SQL") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_DB_NOT_SELECTED, 0, 0x0217, "Database not specified or available") TAOS_DEFINE_ERROR(TSDB_CODE_TSC_INVALID_TABLE_NAME, 0, 0x0218, "Table does not exist") +TAOS_DEFINE_ERROR(TSDB_CODE_TSC_EXCEED_SQL_LIMIT, 0, 0x0219, "SQL statement too long, check maxSQLLength config") // mnode TAOS_DEFINE_ERROR(TSDB_CODE_MND_MSG_NOT_PROCESSED, 0, 0x0300, "Message not processed") @@ -365,20 +366,28 @@ TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_OP_VALUE_NULL, 0, 0x11A5, "value not TAOS_DEFINE_ERROR(TSDB_CODE_HTTP_OP_VALUE_TYPE, 0, 0x11A6, "value type should be boolean, number or string") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_OOM, 0, 0x2101, "out of memory") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_OOM, 0, 0x2100, "out of memory") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_CHAR_NOT_NUM, 0, 0x2101, "convertion not a valid literal input") TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_UNDEF, 0, 0x2102, "convertion undefined") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_TRUNC, 0, 0x2103, "convertion truncated") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_NOT_SUPPORT, 0, 0x2104, "convertion not supported") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_OUT_OF_RANGE, 0, 0x2105, "out of range") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_NOT_SUPPORT, 0, 0x2106, "not supported yet") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_INVALID_HANDLE, 0, 0x2107, "invalid handle") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_NO_RESULT, 0, 0x2108, "no result set") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_NO_FIELDS, 0, 0x2109, "no fields returned") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_INVALID_CURSOR, 0, 0x2110, "invalid cursor") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_STATEMENT_NOT_READY, 0, 0x2111, "statement not ready") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONNECTION_BUSY, 0, 0x2112, "connection still busy") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_BAD_CONNSTR, 0, 0x2113, "bad connection string") -TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_BAD_ARG, 0, 0x2114, "bad argument") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_TRUNC_FRAC, 0, 0x2103, "convertion fractional truncated") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_TRUNC, 0, 0x2104, "convertion truncated") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_NOT_SUPPORT, 0, 0x2105, "convertion not supported") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_OOR, 0, 0x2106, "convertion numeric value out of range") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_OUT_OF_RANGE, 0, 0x2107, "out of range") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_NOT_SUPPORT, 0, 0x2108, "not supported yet") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_INVALID_HANDLE, 0, 0x2109, "invalid handle") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_NO_RESULT, 0, 0x210a, "no result set") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_NO_FIELDS, 0, 0x210b, "no fields returned") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_INVALID_CURSOR, 0, 0x210c, "invalid cursor") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_STATEMENT_NOT_READY, 0, 0x210d, "statement not ready") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONNECTION_BUSY, 0, 0x210e, "connection still busy") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_BAD_CONNSTR, 0, 0x210f, "bad connection string") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_BAD_ARG, 0, 0x2110, "bad argument") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_NOT_VALID_TS, 0, 0x2111, "not a valid timestamp") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_TOO_LARGE, 0, 0x2112, "src too large") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_BAD_SEQ, 0, 0x2113, "src bad sequence") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_INCOMPLETE, 0, 0x2114, "src incomplete") +TAOS_DEFINE_ERROR(TSDB_CODE_ODBC_CONV_SRC_GENERAL, 0, 0x2115, "src general") #ifdef TAOS_ERROR_C diff --git a/src/inc/tsync.h b/src/inc/tsync.h index d57433eba9bacb622081032f4ed6a2a72406248d..77a3b36e73ec6a151e1f8b23e26673d3113dc012 100644 --- a/src/inc/tsync.h +++ b/src/inc/tsync.h @@ -24,18 +24,18 @@ extern "C" { #define TAOS_SYNC_MAX_INDEX 0x7FFFFFFF typedef enum _TAOS_SYNC_ROLE { - TAOS_SYNC_ROLE_OFFLINE, - TAOS_SYNC_ROLE_UNSYNCED, - TAOS_SYNC_ROLE_SYNCING, - TAOS_SYNC_ROLE_SLAVE, - TAOS_SYNC_ROLE_MASTER, + TAOS_SYNC_ROLE_OFFLINE = 0, + TAOS_SYNC_ROLE_UNSYNCED = 1, + TAOS_SYNC_ROLE_SYNCING = 2, + TAOS_SYNC_ROLE_SLAVE = 3, + TAOS_SYNC_ROLE_MASTER = 4 } ESyncRole; typedef enum _TAOS_SYNC_STATUS { - TAOS_SYNC_STATUS_INIT, - TAOS_SYNC_STATUS_START, - TAOS_SYNC_STATUS_FILE, - TAOS_SYNC_STATUS_CACHE, + TAOS_SYNC_STATUS_INIT = 0, + TAOS_SYNC_STATUS_START = 1, + TAOS_SYNC_STATUS_FILE = 2, + TAOS_SYNC_STATUS_CACHE = 3 } ESyncStatus; typedef struct { @@ -64,33 +64,32 @@ typedef struct { if name is provided(name[0] is not zero), get the named file at the specified index. If not there, return zero. If it is there, set the size to file size, and return file magic number. Index shall not be updated. */ -typedef uint32_t (*FGetFileInfo)(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion); +typedef uint32_t (*FGetFileInfo)(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion); // get the wal file from index or after // return value, -1: error, 1:more wal files, 0:last WAL. if name[0]==0, no WAL file -typedef int32_t (*FGetWalInfo)(void *ahandle, char *fileName, int64_t *fileId); +typedef int32_t (*FGetWalInfo)(int32_t vgId, char *fileName, int64_t *fileId); // when a forward pkt is received, call this to handle data -typedef int32_t (*FWriteToCache)(void *ahandle, void *pHead, int32_t qtype, void *pMsg); +typedef int32_t (*FWriteToCache)(int32_t vgId, void *pHead, int32_t qtype, void *pMsg); // when forward is confirmed by peer, master call this API to notify app -typedef void (*FConfirmForward)(void *ahandle, void *mhandle, int32_t code); +typedef void (*FConfirmForward)(int32_t vgId, void *mhandle, int32_t code); // when role is changed, call this to notify app -typedef void (*FNotifyRole)(void *ahandle, int8_t role); +typedef void (*FNotifyRole)(int32_t vgId, int8_t role); // if a number of retrieving data failed, call this to start flow control -typedef void (*FNotifyFlowCtrl)(void *ahandle, int32_t mseconds); +typedef void (*FNotifyFlowCtrl)(int32_t vgId, int32_t mseconds); // when data file is synced successfully, notity app -typedef int32_t (*FNotifyFileSynced)(void *ahandle, uint64_t fversion); +typedef int32_t (*FNotifyFileSynced)(int32_t vgId, uint64_t fversion); typedef struct { int32_t vgId; // vgroup ID uint64_t version; // initial version SSyncCfg syncCfg; // configuration from mgmt - char path[128]; // path to the file - void * ahandle; // handle provided by APP + char path[TSDB_FILENAME_LEN]; // path to the file FGetFileInfo getFileInfo; FGetWalInfo getWalInfo; FWriteToCache writeToCache; diff --git a/src/inc/vnode.h b/src/inc/vnode.h index 563d035898758a69fb57d6e1e5d8dc7e99886af4..4e8389498b5ced87f4ff07dddac817614f5af368 100644 --- a/src/inc/vnode.h +++ b/src/inc/vnode.h @@ -23,12 +23,12 @@ extern "C" { #include "twal.h" typedef enum _VN_STATUS { - TAOS_VN_STATUS_INIT, - TAOS_VN_STATUS_READY, - TAOS_VN_STATUS_CLOSING, - TAOS_VN_STATUS_UPDATING, - TAOS_VN_STATUS_RESET, -} EVnStatus; + TAOS_VN_STATUS_INIT = 0, + TAOS_VN_STATUS_READY = 1, + TAOS_VN_STATUS_CLOSING = 2, + TAOS_VN_STATUS_UPDATING = 3, + TAOS_VN_STATUS_RESET = 4, +} EVnodeStatus; typedef struct { int32_t len; @@ -81,7 +81,8 @@ void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes); int32_t vnodeInitResources(); void vnodeCleanupResources(); -int32_t vnodeWriteToRQueue(void *vparam, void *pCont, int32_t contLen, int8_t qtype, void *rparam); +int32_t vnodeWriteToRQueue(void *pVnode, void *pCont, int32_t contLen, int8_t qtype, void *rparam); +void vnodeFreeFromRQueue(void *pVnode, SVReadMsg *pRead); int32_t vnodeProcessRead(void *pVnode, SVReadMsg *pRead); #ifdef __cplusplus diff --git a/src/mnode/inc/mnodeSdb.h b/src/mnode/inc/mnodeSdb.h index f4854f69a0f315d06d402eef3a125b2a3e45ab0e..29d8cf1207c0cb82773780b5aa212bfa08791acd 100644 --- a/src/mnode/inc/mnodeSdb.h +++ b/src/mnode/inc/mnodeSdb.h @@ -20,7 +20,8 @@ extern "C" { #endif -struct SMnodeMsg; +#include "mnode.h" +#include "twal.h" typedef enum { SDB_TABLE_CLUSTER = 0, @@ -36,44 +37,46 @@ typedef enum { } ESdbTable; typedef enum { - SDB_KEY_STRING, - SDB_KEY_INT, - SDB_KEY_AUTO, - SDB_KEY_VAR_STRING, + SDB_KEY_STRING = 0, + SDB_KEY_INT = 1, + SDB_KEY_AUTO = 2, + SDB_KEY_VAR_STRING = 3, } ESdbKey; typedef enum { - SDB_OPER_GLOBAL, - SDB_OPER_LOCAL + SDB_OPER_GLOBAL = 0, + SDB_OPER_LOCAL = 1 } ESdbOper; -typedef struct SSdbOper { - ESdbOper type; - int32_t rowSize; - int32_t retCode; // for callback in sdb queue - int32_t processedCount; // for sync fwd callback - int32_t (*reqFp)(struct SMnodeMsg *pMsg); - int32_t (*writeCb)(struct SMnodeMsg *pMsg, int32_t code); - void * table; - void * pObj; - void * rowData; - struct SMnodeMsg *pMsg; -} SSdbOper; +typedef struct SSdbRow { + ESdbOper type; + int32_t processedCount; // for sync fwd callback + int32_t code; // for callback in sdb queue + int32_t rowSize; + void * rowData; + void * pObj; + void * pTable; + SMnodeMsg *pMsg; + int32_t (*fpReq)(SMnodeMsg *pMsg); + int32_t (*fpRsp)(SMnodeMsg *pMsg, int32_t code); + char reserveForSync[16]; + SWalHead pHead[]; +} SSdbRow; typedef struct { - char *tableName; - int32_t hashSessions; - int32_t maxRowSize; - int32_t refCountPos; - ESdbTable tableId; + char * name; + int32_t hashSessions; + int32_t maxRowSize; + int32_t refCountPos; + ESdbTable id; ESdbKey keyType; - int32_t (*insertFp)(SSdbOper *pOper); - int32_t (*deleteFp)(SSdbOper *pOper); - int32_t (*updateFp)(SSdbOper *pOper); - int32_t (*encodeFp)(SSdbOper *pOper); - int32_t (*decodeFp)(SSdbOper *pDesc); - int32_t (*destroyFp)(SSdbOper *pDesc); - int32_t (*restoredFp)(); + int32_t (*fpInsert)(SSdbRow *pRow); + int32_t (*fpDelete)(SSdbRow *pRow); + int32_t (*fpUpdate)(SSdbRow *pRow); + int32_t (*fpEncode)(SSdbRow *pRow); + int32_t (*fpDecode)(SSdbRow *pRow); + int32_t (*fpDestroy)(SSdbRow *pRow); + int32_t (*fpRestored)(); } SSdbTableDesc; int32_t sdbInit(); @@ -84,20 +87,20 @@ bool sdbIsMaster(); bool sdbIsServing(); void sdbUpdateMnodeRoles(); -int32_t sdbInsertRow(SSdbOper *pOper); -int32_t sdbDeleteRow(SSdbOper *pOper); -int32_t sdbUpdateRow(SSdbOper *pOper); -int32_t sdbInsertRowImp(SSdbOper *pOper); +int32_t sdbInsertRow(SSdbRow *pRow); +int32_t sdbDeleteRow(SSdbRow *pRow); +int32_t sdbUpdateRow(SSdbRow *pRow); +int32_t sdbInsertRowToQueue(SSdbRow *pRow); -void *sdbGetRow(void *handle, void *key); -void *sdbFetchRow(void *handle, void *pIter, void **ppRow); +void *sdbGetRow(void *pTable, void *key); +void *sdbFetchRow(void *pTable, void *pIter, void **ppRow); void sdbFreeIter(void *pIter); -void sdbIncRef(void *thandle, void *pRow); -void sdbDecRef(void *thandle, void *pRow); -int64_t sdbGetNumOfRows(void *handle); -int32_t sdbGetId(void *handle); +void sdbIncRef(void *pTable, void *pRow); +void sdbDecRef(void *pTable, void *pRow); +int64_t sdbGetNumOfRows(void *pTable); +int32_t sdbGetId(void *pTable); uint64_t sdbGetVersion(); -bool sdbCheckRowDeleted(void *thandle, void *pRow); +bool sdbCheckRowDeleted(void *pTable, void *pRow); #ifdef __cplusplus } diff --git a/src/mnode/src/mnodeAcct.c b/src/mnode/src/mnodeAcct.c index 365cf656de283a53899ccd866682e8d0a06caaf8..9fff2f02291d6b23163c0e58d3d2bfe545da6eb5 100644 --- a/src/mnode/src/mnodeAcct.c +++ b/src/mnode/src/mnodeAcct.c @@ -16,6 +16,7 @@ #define _DEFAULT_SOURCE #include "os.h" #include "taoserror.h" +#include "tglobal.h" #include "dnode.h" #include "mnodeDef.h" #include "mnodeInt.h" @@ -25,36 +26,34 @@ #include "mnodeUser.h" #include "mnodeVgroup.h" -#include "tglobal.h" - void * tsAcctSdb = NULL; static int32_t tsAcctUpdateSize; static int32_t mnodeCreateRootAcct(); -static int32_t mnodeAcctActionDestroy(SSdbOper *pOper) { - SAcctObj *pAcct = pOper->pObj; +static int32_t mnodeAcctActionDestroy(SSdbRow *pRow) { + SAcctObj *pAcct = pRow->pObj; pthread_mutex_destroy(&pAcct->mutex); - tfree(pOper->pObj); + tfree(pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t mnodeAcctActionInsert(SSdbOper *pOper) { - SAcctObj *pAcct = pOper->pObj; +static int32_t mnodeAcctActionInsert(SSdbRow *pRow) { + SAcctObj *pAcct = pRow->pObj; memset(&pAcct->acctInfo, 0, sizeof(SAcctInfo)); pAcct->acctInfo.accessState = TSDB_VN_ALL_ACCCESS; pthread_mutex_init(&pAcct->mutex, NULL); return TSDB_CODE_SUCCESS; } -static int32_t mnodeAcctActionDelete(SSdbOper *pOper) { - SAcctObj *pAcct = pOper->pObj; +static int32_t mnodeAcctActionDelete(SSdbRow *pRow) { + SAcctObj *pAcct = pRow->pObj; mnodeDropAllUsers(pAcct); mnodeDropAllDbs(pAcct); return TSDB_CODE_SUCCESS; } -static int32_t mnodeAcctActionUpdate(SSdbOper *pOper) { - SAcctObj *pAcct = pOper->pObj; +static int32_t mnodeAcctActionUpdate(SSdbRow *pRow) { + SAcctObj *pAcct = pRow->pObj; SAcctObj *pSaved = mnodeGetAcct(pAcct->user); if (pAcct != pSaved) { memcpy(pSaved, pAcct, tsAcctUpdateSize); @@ -64,19 +63,19 @@ static int32_t mnodeAcctActionUpdate(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeAcctActionEncode(SSdbOper *pOper) { - SAcctObj *pAcct = pOper->pObj; - memcpy(pOper->rowData, pAcct, tsAcctUpdateSize); - pOper->rowSize = tsAcctUpdateSize; +static int32_t mnodeAcctActionEncode(SSdbRow *pRow) { + SAcctObj *pAcct = pRow->pObj; + memcpy(pRow->rowData, pAcct, tsAcctUpdateSize); + pRow->rowSize = tsAcctUpdateSize; return TSDB_CODE_SUCCESS; } -static int32_t mnodeAcctActionDecode(SSdbOper *pOper) { +static int32_t mnodeAcctActionDecode(SSdbRow *pRow) { SAcctObj *pAcct = (SAcctObj *) calloc(1, sizeof(SAcctObj)); if (pAcct == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - memcpy(pAcct, pOper->rowData, tsAcctUpdateSize); - pOper->pObj = pAcct; + memcpy(pAcct, pRow->rowData, tsAcctUpdateSize); + pRow->pObj = pAcct; return TSDB_CODE_SUCCESS; } @@ -99,29 +98,29 @@ int32_t mnodeInitAccts() { SAcctObj tObj; tsAcctUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; - SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_ACCOUNT, - .tableName = "accounts", + SSdbTableDesc desc = { + .id = SDB_TABLE_ACCOUNT, + .name = "accounts", .hashSessions = TSDB_DEFAULT_ACCOUNTS_HASH_SIZE, .maxRowSize = tsAcctUpdateSize, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_STRING, - .insertFp = mnodeAcctActionInsert, - .deleteFp = mnodeAcctActionDelete, - .updateFp = mnodeAcctActionUpdate, - .encodeFp = mnodeAcctActionEncode, - .decodeFp = mnodeAcctActionDecode, - .destroyFp = mnodeAcctActionDestroy, - .restoredFp = mnodeAcctActionRestored + .fpInsert = mnodeAcctActionInsert, + .fpDelete = mnodeAcctActionDelete, + .fpUpdate = mnodeAcctActionUpdate, + .fpEncode = mnodeAcctActionEncode, + .fpDecode = mnodeAcctActionDecode, + .fpDestroy = mnodeAcctActionDestroy, + .fpRestored = mnodeAcctActionRestored }; - tsAcctSdb = sdbOpenTable(&tableDesc); + tsAcctSdb = sdbOpenTable(&desc); if (tsAcctSdb == NULL) { - mError("table:%s, failed to create hash", tableDesc.tableName); + mError("table:%s, failed to create hash", desc.name); return -1; } - mDebug("table:%s, hash is created", tableDesc.tableName); + mDebug("table:%s, hash is created", desc.name); return TSDB_CODE_SUCCESS; } @@ -226,13 +225,13 @@ static int32_t mnodeCreateRootAcct() { pAcct->acctId = sdbGetId(tsAcctSdb); pAcct->createdTime = taosGetTimestampMs(); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsAcctSdb, - .pObj = pAcct, + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsAcctSdb, + .pObj = pAcct, }; - return sdbInsertRow(&oper); + return sdbInsertRow(&row); } #ifndef _ACCT diff --git a/src/mnode/src/mnodeCluster.c b/src/mnode/src/mnodeCluster.c index 98587cf53d673b847a321ded9c369e2085195081..5be67e4ad9b1b1746598331997e428f4e78607cf 100644 --- a/src/mnode/src/mnodeCluster.c +++ b/src/mnode/src/mnodeCluster.c @@ -32,36 +32,36 @@ static int32_t mnodeCreateCluster(); static int32_t mnodeGetClusterMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); static int32_t mnodeRetrieveClusters(SShowObj *pShow, char *data, int32_t rows, void *pConn); -static int32_t mnodeClusterActionDestroy(SSdbOper *pOper) { - tfree(pOper->pObj); +static int32_t mnodeClusterActionDestroy(SSdbRow *pRow) { + tfree(pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t mnodeClusterActionInsert(SSdbOper *pOper) { +static int32_t mnodeClusterActionInsert(SSdbRow *pRow) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeClusterActionDelete(SSdbOper *pOper) { +static int32_t mnodeClusterActionDelete(SSdbRow *pRow) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeClusterActionUpdate(SSdbOper *pOper) { +static int32_t mnodeClusterActionUpdate(SSdbRow *pRow) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeClusterActionEncode(SSdbOper *pOper) { - SClusterObj *pCluster = pOper->pObj; - memcpy(pOper->rowData, pCluster, tsClusterUpdateSize); - pOper->rowSize = tsClusterUpdateSize; +static int32_t mnodeClusterActionEncode(SSdbRow *pRow) { + SClusterObj *pCluster = pRow->pObj; + memcpy(pRow->rowData, pCluster, tsClusterUpdateSize); + pRow->rowSize = tsClusterUpdateSize; return TSDB_CODE_SUCCESS; } -static int32_t mnodeClusterActionDecode(SSdbOper *pOper) { +static int32_t mnodeClusterActionDecode(SSdbRow *pRow) { SClusterObj *pCluster = (SClusterObj *) calloc(1, sizeof(SClusterObj)); if (pCluster == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - memcpy(pCluster, pOper->rowData, tsClusterUpdateSize); - pOper->pObj = pCluster; + memcpy(pCluster, pRow->rowData, tsClusterUpdateSize); + pRow->pObj = pCluster; return TSDB_CODE_SUCCESS; } @@ -84,32 +84,32 @@ int32_t mnodeInitCluster() { SClusterObj tObj; tsClusterUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; - SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_CLUSTER, - .tableName = "cluster", + SSdbTableDesc desc = { + .id = SDB_TABLE_CLUSTER, + .name = "cluster", .hashSessions = TSDB_DEFAULT_CLUSTER_HASH_SIZE, .maxRowSize = tsClusterUpdateSize, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_STRING, - .insertFp = mnodeClusterActionInsert, - .deleteFp = mnodeClusterActionDelete, - .updateFp = mnodeClusterActionUpdate, - .encodeFp = mnodeClusterActionEncode, - .decodeFp = mnodeClusterActionDecode, - .destroyFp = mnodeClusterActionDestroy, - .restoredFp = mnodeClusterActionRestored + .fpInsert = mnodeClusterActionInsert, + .fpDelete = mnodeClusterActionDelete, + .fpUpdate = mnodeClusterActionUpdate, + .fpEncode = mnodeClusterActionEncode, + .fpDecode = mnodeClusterActionDecode, + .fpDestroy = mnodeClusterActionDestroy, + .fpRestored = mnodeClusterActionRestored }; - tsClusterSdb = sdbOpenTable(&tableDesc); + tsClusterSdb = sdbOpenTable(&desc); if (tsClusterSdb == NULL) { - mError("table:%s, failed to create hash", tableDesc.tableName); + mError("table:%s, failed to create hash", desc.name); return -1; } mnodeAddShowMetaHandle(TSDB_MGMT_TABLE_CLUSTER, mnodeGetClusterMeta); mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_CLUSTER, mnodeRetrieveClusters); - mDebug("table:%s, hash is created", tableDesc.tableName); + mDebug("table:%s, hash is created", desc.name); return TSDB_CODE_SUCCESS; } @@ -145,13 +145,13 @@ static int32_t mnodeCreateCluster() { mDebug("uid is %s", pCluster->uid); } - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsClusterSdb, - .pObj = pCluster, + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsClusterSdb, + .pObj = pCluster, }; - return sdbInsertRow(&oper); + return sdbInsertRow(&row); } const char* mnodeGetClusterId() { diff --git a/src/mnode/src/mnodeDb.c b/src/mnode/src/mnodeDb.c index 3b3a21aeb18f08d9af20a17ee78dcba124bd00d7..d121208447c498280fb6f397e2181e2993ad1dbe 100644 --- a/src/mnode/src/mnodeDb.c +++ b/src/mnode/src/mnodeDb.c @@ -56,8 +56,8 @@ static void mnodeDestroyDb(SDbObj *pDb) { tfree(pDb); } -static int32_t mnodeDbActionDestroy(SSdbOper *pOper) { - mnodeDestroyDb(pOper->pObj); +static int32_t mnodeDbActionDestroy(SSdbRow *pRow) { + mnodeDestroyDb(pRow->pObj); return TSDB_CODE_SUCCESS; } @@ -65,8 +65,8 @@ int64_t mnodeGetDbNum() { return sdbGetNumOfRows(tsDbSdb); } -static int32_t mnodeDbActionInsert(SSdbOper *pOper) { - SDbObj *pDb = pOper->pObj; +static int32_t mnodeDbActionInsert(SSdbRow *pRow) { + SDbObj *pDb = pRow->pObj; SAcctObj *pAcct = mnodeGetAcct(pDb->acct); pthread_mutex_init(&pDb->mutex, NULL); @@ -91,8 +91,8 @@ static int32_t mnodeDbActionInsert(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeDbActionDelete(SSdbOper *pOper) { - SDbObj *pDb = pOper->pObj; +static int32_t mnodeDbActionDelete(SSdbRow *pRow) { + SDbObj *pDb = pRow->pObj; SAcctObj *pAcct = mnodeGetAcct(pDb->acct); mnodeDropAllChildTables(pDb); @@ -107,11 +107,11 @@ static int32_t mnodeDbActionDelete(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeDbActionUpdate(SSdbOper *pOper) { - SDbObj *pNew = pOper->pObj; +static int32_t mnodeDbActionUpdate(SSdbRow *pRow) { + SDbObj *pNew = pRow->pObj; SDbObj *pDb = mnodeGetDb(pNew->name); if (pDb != NULL && pNew != pDb) { - memcpy(pDb, pNew, pOper->rowSize); + memcpy(pDb, pNew, pRow->rowSize); free(pNew->vgList); free(pNew); } @@ -120,19 +120,19 @@ static int32_t mnodeDbActionUpdate(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeDbActionEncode(SSdbOper *pOper) { - SDbObj *pDb = pOper->pObj; - memcpy(pOper->rowData, pDb, tsDbUpdateSize); - pOper->rowSize = tsDbUpdateSize; +static int32_t mnodeDbActionEncode(SSdbRow *pRow) { + SDbObj *pDb = pRow->pObj; + memcpy(pRow->rowData, pDb, tsDbUpdateSize); + pRow->rowSize = tsDbUpdateSize; return TSDB_CODE_SUCCESS; } -static int32_t mnodeDbActionDecode(SSdbOper *pOper) { +static int32_t mnodeDbActionDecode(SSdbRow *pRow) { SDbObj *pDb = (SDbObj *) calloc(1, sizeof(SDbObj)); if (pDb == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - memcpy(pDb, pOper->rowData, tsDbUpdateSize); - pOper->pObj = pDb; + memcpy(pDb, pRow->rowData, tsDbUpdateSize); + pRow->pObj = pDb; return TSDB_CODE_SUCCESS; } @@ -144,23 +144,23 @@ int32_t mnodeInitDbs() { SDbObj tObj; tsDbUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; - SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_DB, - .tableName = "dbs", + SSdbTableDesc desc = { + .id = SDB_TABLE_DB, + .name = "dbs", .hashSessions = TSDB_DEFAULT_DBS_HASH_SIZE, .maxRowSize = tsDbUpdateSize, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_STRING, - .insertFp = mnodeDbActionInsert, - .deleteFp = mnodeDbActionDelete, - .updateFp = mnodeDbActionUpdate, - .encodeFp = mnodeDbActionEncode, - .decodeFp = mnodeDbActionDecode, - .destroyFp = mnodeDbActionDestroy, - .restoredFp = mnodeDbActionRestored + .fpInsert = mnodeDbActionInsert, + .fpDelete = mnodeDbActionDelete, + .fpUpdate = mnodeDbActionUpdate, + .fpEncode = mnodeDbActionEncode, + .fpDecode = mnodeDbActionDecode, + .fpDestroy = mnodeDbActionDestroy, + .fpRestored = mnodeDbActionRestored }; - tsDbSdb = sdbOpenTable(&tableDesc); + tsDbSdb = sdbOpenTable(&desc); if (tsDbSdb == NULL) { mError("failed to init db data"); return -1; @@ -412,16 +412,16 @@ static int32_t mnodeCreateDb(SAcctObj *pAcct, SCreateDbMsg *pCreate, SMnodeMsg * pMsg->pDb = pDb; mnodeIncDbRef(pDb); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsDbSdb, - .pObj = pDb, - .rowSize = sizeof(SDbObj), - .pMsg = pMsg, - .writeCb = mnodeCreateDbCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDbSdb, + .pObj = pDb, + .rowSize = sizeof(SDbObj), + .pMsg = pMsg, + .fpRsp = mnodeCreateDbCb }; - code = sdbInsertRow(&oper); + code = sdbInsertRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("db:%s, failed to create, reason:%s", pDb->name, tstrerror(code)); pMsg->pDb = NULL; @@ -440,8 +440,8 @@ bool mnodeCheckIsMonitorDB(char *db, char *monitordb) { } #if 0 -void mnodePrintVgroups(SDbObj *pDb, char *oper) { - mInfo("db:%s, vgroup link from head, oper:%s", pDb->name, oper); +void mnodePrintVgroups(SDbObj *pDb, char *row) { + mInfo("db:%s, vgroup link from head, row:%s", pDb->name, row); SVgObj *pVgroup = pDb->pHead; while (pVgroup != NULL) { mInfo("vgId:%d", pVgroup->vgId); @@ -807,13 +807,13 @@ static int32_t mnodeSetDbDropping(SDbObj *pDb) { if (pDb->status) return TSDB_CODE_SUCCESS; pDb->status = true; - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsDbSdb, - .pObj = pDb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDbSdb, + .pObj = pDb }; - int32_t code = sdbUpdateRow(&oper); + int32_t code = sdbUpdateRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("db:%s, failed to set dropping state, reason:%s", pDb->name, tstrerror(code)); } @@ -1019,15 +1019,15 @@ static int32_t mnodeAlterDb(SDbObj *pDb, SAlterDbMsg *pAlter, void *pMsg) { if (memcmp(&newCfg, &pDb->cfg, sizeof(SDbCfg)) != 0) { pDb->cfg = newCfg; pDb->cfgVersion++; - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsDbSdb, - .pObj = pDb, - .pMsg = pMsg, - .writeCb = mnodeAlterDbCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDbSdb, + .pObj = pDb, + .pMsg = pMsg, + .fpRsp = mnodeAlterDbCb }; - code = sdbUpdateRow(&oper); + code = sdbUpdateRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("db:%s, failed to alter, reason:%s", pDb->name, tstrerror(code)); } @@ -1071,15 +1071,15 @@ static int32_t mnodeDropDb(SMnodeMsg *pMsg) { SDbObj *pDb = pMsg->pDb; mInfo("db:%s, drop db from sdb", pDb->name); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsDbSdb, - .pObj = pDb, - .pMsg = pMsg, - .writeCb = mnodeDropDbCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDbSdb, + .pObj = pDb, + .pMsg = pMsg, + .fpRsp = mnodeDropDbCb }; - int32_t code = sdbDeleteRow(&oper); + int32_t code = sdbDeleteRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("db:%s, failed to drop, reason:%s", pDb->name, tstrerror(code)); } @@ -1134,13 +1134,13 @@ void mnodeDropAllDbs(SAcctObj *pAcct) { if (pDb->pAcct == pAcct) { mInfo("db:%s, drop db from sdb for acct:%s is dropped", pDb->name, pAcct->user); - SSdbOper oper = { - .type = SDB_OPER_LOCAL, - .table = tsDbSdb, - .pObj = pDb + SSdbRow row = { + .type = SDB_OPER_LOCAL, + .pTable = tsDbSdb, + .pObj = pDb }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); numOfDbs++; } mnodeDecDbRef(pDb); diff --git a/src/mnode/src/mnodeDnode.c b/src/mnode/src/mnodeDnode.c index 7e34e0837389e8a288ba70a2b18d4627f91219ae..f76533c76032907e627eea7c1d16bb99009e0ed3 100644 --- a/src/mnode/src/mnodeDnode.c +++ b/src/mnode/src/mnodeDnode.c @@ -87,13 +87,13 @@ static char* offlineReason[] = { "unknown", }; -static int32_t mnodeDnodeActionDestroy(SSdbOper *pOper) { - tfree(pOper->pObj); +static int32_t mnodeDnodeActionDestroy(SSdbRow *pRow) { + tfree(pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t mnodeDnodeActionInsert(SSdbOper *pOper) { - SDnodeObj *pDnode = pOper->pObj; +static int32_t mnodeDnodeActionInsert(SSdbRow *pRow) { + SDnodeObj *pDnode = pRow->pObj; if (pDnode->status != TAOS_DN_STATUS_DROPPING) { pDnode->status = TAOS_DN_STATUS_OFFLINE; pDnode->lastAccess = tsAccessSquence; @@ -107,8 +107,8 @@ static int32_t mnodeDnodeActionInsert(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeDnodeActionDelete(SSdbOper *pOper) { - SDnodeObj *pDnode = pOper->pObj; +static int32_t mnodeDnodeActionDelete(SSdbRow *pRow) { + SDnodeObj *pDnode = pRow->pObj; #ifndef _SYNC mnodeDropAllDnodeVgroups(pDnode); @@ -121,11 +121,11 @@ static int32_t mnodeDnodeActionDelete(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeDnodeActionUpdate(SSdbOper *pOper) { - SDnodeObj *pNew = pOper->pObj; +static int32_t mnodeDnodeActionUpdate(SSdbRow *pRow) { + SDnodeObj *pNew = pRow->pObj; SDnodeObj *pDnode = mnodeGetDnode(pNew->dnodeId); if (pDnode != NULL && pNew != pDnode) { - memcpy(pDnode, pNew, pOper->rowSize); + memcpy(pDnode, pNew, pRow->rowSize); free(pNew); } mnodeDecDnodeRef(pDnode); @@ -134,19 +134,19 @@ static int32_t mnodeDnodeActionUpdate(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeDnodeActionEncode(SSdbOper *pOper) { - SDnodeObj *pDnode = pOper->pObj; - memcpy(pOper->rowData, pDnode, tsDnodeUpdateSize); - pOper->rowSize = tsDnodeUpdateSize; +static int32_t mnodeDnodeActionEncode(SSdbRow *pRow) { + SDnodeObj *pDnode = pRow->pObj; + memcpy(pRow->rowData, pDnode, tsDnodeUpdateSize); + pRow->rowSize = tsDnodeUpdateSize; return TSDB_CODE_SUCCESS; } -static int32_t mnodeDnodeActionDecode(SSdbOper *pOper) { +static int32_t mnodeDnodeActionDecode(SSdbRow *pRow) { SDnodeObj *pDnode = (SDnodeObj *) calloc(1, sizeof(SDnodeObj)); if (pDnode == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - memcpy(pDnode, pOper->rowData, tsDnodeUpdateSize); - pOper->pObj = pDnode; + memcpy(pDnode, pRow->rowData, tsDnodeUpdateSize); + pRow->pObj = pDnode; return TSDB_CODE_SUCCESS; } @@ -171,23 +171,23 @@ int32_t mnodeInitDnodes() { tsDnodeUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; pthread_mutex_init(&tsDnodeEpsMutex, NULL); - SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_DNODE, - .tableName = "dnodes", + SSdbTableDesc desc = { + .id = SDB_TABLE_DNODE, + .name = "dnodes", .hashSessions = TSDB_DEFAULT_DNODES_HASH_SIZE, .maxRowSize = tsDnodeUpdateSize, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_AUTO, - .insertFp = mnodeDnodeActionInsert, - .deleteFp = mnodeDnodeActionDelete, - .updateFp = mnodeDnodeActionUpdate, - .encodeFp = mnodeDnodeActionEncode, - .decodeFp = mnodeDnodeActionDecode, - .destroyFp = mnodeDnodeActionDestroy, - .restoredFp = mnodeDnodeActionRestored + .fpInsert = mnodeDnodeActionInsert, + .fpDelete = mnodeDnodeActionDelete, + .fpUpdate = mnodeDnodeActionUpdate, + .fpEncode = mnodeDnodeActionEncode, + .fpDecode = mnodeDnodeActionDecode, + .fpDestroy = mnodeDnodeActionDestroy, + .fpRestored = mnodeDnodeActionRestored }; - tsDnodeSdb = sdbOpenTable(&tableDesc); + tsDnodeSdb = sdbOpenTable(&desc); if (tsDnodeSdb == NULL) { mError("failed to init dnodes data"); return -1; @@ -296,13 +296,13 @@ void mnodeDecDnodeRef(SDnodeObj *pDnode) { } void mnodeUpdateDnode(SDnodeObj *pDnode) { - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsDnodeSdb, - .pObj = pDnode + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDnodeSdb, + .pObj = pDnode }; - int32_t code = sdbUpdateRow(&oper); + int32_t code = sdbUpdateRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("dnodeId:%d, failed update", pDnode->dnodeId); } @@ -644,15 +644,15 @@ static int32_t mnodeCreateDnode(char *ep, SMnodeMsg *pMsg) { tstrncpy(pDnode->dnodeEp, ep, TSDB_EP_LEN); taosGetFqdnPortFromEp(ep, pDnode->dnodeFqdn, &pDnode->dnodePort); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsDnodeSdb, - .pObj = pDnode, + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDnodeSdb, + .pObj = pDnode, .rowSize = sizeof(SDnodeObj), - .pMsg = pMsg + .pMsg = pMsg }; - int32_t code = sdbInsertRow(&oper); + int32_t code = sdbInsertRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { int dnodeId = pDnode->dnodeId; tfree(pDnode); @@ -665,14 +665,14 @@ static int32_t mnodeCreateDnode(char *ep, SMnodeMsg *pMsg) { } int32_t mnodeDropDnode(SDnodeObj *pDnode, void *pMsg) { - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsDnodeSdb, - .pObj = pDnode, - .pMsg = pMsg + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsDnodeSdb, + .pObj = pDnode, + .pMsg = pMsg }; - int32_t code = sdbDeleteRow(&oper); + int32_t code = sdbDeleteRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("dnode:%d, failed to drop from cluster, result:%s", pDnode->dnodeId, tstrerror(code)); } else { @@ -1141,7 +1141,7 @@ static int32_t mnodeRetrieveVnodes(SShowObj *pShow, char *data, int32_t rows, vo cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - strcpy(pWrite, mnodeGetMnodeRoleStr(pVgid->role)); + strcpy(pWrite, syncRole[pVgid->role]); cols++; } } diff --git a/src/mnode/src/mnodeInt.c b/src/mnode/src/mnodeInt.c index 8431baf4f455a2c577321ec18ff3bfcd7fbe5d46..534deec09a821ce2aa6e5761d2d7242015713fd0 100644 --- a/src/mnode/src/mnodeInt.c +++ b/src/mnode/src/mnodeInt.c @@ -48,7 +48,7 @@ void *mnodeCreateMsg(SRpcMsg *pRpcMsg) { int32_t mnodeInitMsg(SMnodeMsg *pMsg) { if (pMsg->pUser != NULL) { - mDebug("app:%p:%p, user info already inited", pMsg->rpcMsg.ahandle, pMsg); + mTrace("msg:%p, app:%p user info already inited", pMsg, pMsg->rpcMsg.ahandle); return TSDB_CODE_SUCCESS; } diff --git a/src/mnode/src/mnodeMnode.c b/src/mnode/src/mnodeMnode.c index 092f246c139533f806ce1d311162e0516088d879..205bfda4b9571b488ccb335ab98c677f94166aae 100644 --- a/src/mnode/src/mnodeMnode.c +++ b/src/mnode/src/mnodeMnode.c @@ -58,13 +58,13 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo #define mnodeMnodeDestroyLock() pthread_mutex_destroy(&tsMnodeLock) #endif -static int32_t mnodeMnodeActionDestroy(SSdbOper *pOper) { - tfree(pOper->pObj); +static int32_t mnodeMnodeActionDestroy(SSdbRow *pRow) { + tfree(pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t mnodeMnodeActionInsert(SSdbOper *pOper) { - SMnodeObj *pMnode = pOper->pObj; +static int32_t mnodeMnodeActionInsert(SSdbRow *pRow) { + SMnodeObj *pMnode = pRow->pObj; SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId); if (pDnode == NULL) return TSDB_CODE_MND_DNODE_NOT_EXIST; @@ -76,8 +76,8 @@ static int32_t mnodeMnodeActionInsert(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeMnodeActionDelete(SSdbOper *pOper) { - SMnodeObj *pMnode = pOper->pObj; +static int32_t mnodeMnodeActionDelete(SSdbRow *pRow) { + SMnodeObj *pMnode = pRow->pObj; SDnodeObj *pDnode = mnodeGetDnode(pMnode->mnodeId); if (pDnode == NULL) return TSDB_CODE_MND_DNODE_NOT_EXIST; @@ -88,30 +88,30 @@ static int32_t mnodeMnodeActionDelete(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeMnodeActionUpdate(SSdbOper *pOper) { - SMnodeObj *pMnode = pOper->pObj; +static int32_t mnodeMnodeActionUpdate(SSdbRow *pRow) { + SMnodeObj *pMnode = pRow->pObj; SMnodeObj *pSaved = mnodeGetMnode(pMnode->mnodeId); if (pMnode != pSaved) { - memcpy(pSaved, pMnode, pOper->rowSize); + memcpy(pSaved, pMnode, pRow->rowSize); free(pMnode); } mnodeDecMnodeRef(pSaved); return TSDB_CODE_SUCCESS; } -static int32_t mnodeMnodeActionEncode(SSdbOper *pOper) { - SMnodeObj *pMnode = pOper->pObj; - memcpy(pOper->rowData, pMnode, tsMnodeUpdateSize); - pOper->rowSize = tsMnodeUpdateSize; +static int32_t mnodeMnodeActionEncode(SSdbRow *pRow) { + SMnodeObj *pMnode = pRow->pObj; + memcpy(pRow->rowData, pMnode, tsMnodeUpdateSize); + pRow->rowSize = tsMnodeUpdateSize; return TSDB_CODE_SUCCESS; } -static int32_t mnodeMnodeActionDecode(SSdbOper *pOper) { +static int32_t mnodeMnodeActionDecode(SSdbRow *pRow) { SMnodeObj *pMnode = calloc(1, sizeof(SMnodeObj)); if (pMnode == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - memcpy(pMnode, pOper->rowData, tsMnodeUpdateSize); - pOper->pObj = pMnode; + memcpy(pMnode, pRow->rowData, tsMnodeUpdateSize); + pRow->pObj = pMnode; return TSDB_CODE_SUCCESS; } @@ -137,23 +137,23 @@ int32_t mnodeInitMnodes() { SMnodeObj tObj; tsMnodeUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; - SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_MNODE, - .tableName = "mnodes", + SSdbTableDesc desc = { + .id = SDB_TABLE_MNODE, + .name = "mnodes", .hashSessions = TSDB_DEFAULT_MNODES_HASH_SIZE, .maxRowSize = tsMnodeUpdateSize, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_INT, - .insertFp = mnodeMnodeActionInsert, - .deleteFp = mnodeMnodeActionDelete, - .updateFp = mnodeMnodeActionUpdate, - .encodeFp = mnodeMnodeActionEncode, - .decodeFp = mnodeMnodeActionDecode, - .destroyFp = mnodeMnodeActionDestroy, - .restoredFp = mnodeMnodeActionRestored + .fpInsert = mnodeMnodeActionInsert, + .fpDelete = mnodeMnodeActionDelete, + .fpUpdate = mnodeMnodeActionUpdate, + .fpEncode = mnodeMnodeActionEncode, + .fpDecode = mnodeMnodeActionDecode, + .fpDestroy = mnodeMnodeActionDestroy, + .fpRestored = mnodeMnodeActionRestored }; - tsMnodeSdb = sdbOpenTable(&tableDesc); + tsMnodeSdb = sdbOpenTable(&desc); if (tsMnodeSdb == NULL) { mError("failed to init mnodes data"); return -1; @@ -192,10 +192,6 @@ void *mnodeGetNextMnode(void *pIter, SMnodeObj **pMnode) { return sdbFetchRow(tsMnodeSdb, pIter, (void **)pMnode); } -char *mnodeGetMnodeRoleStr(int32_t role) { - return syncRole[role]; -} - void mnodeUpdateMnodeEpSet() { mInfo("update mnodes epSet, numOfEps:%d ", mnodeGetMnodesNum()); @@ -329,11 +325,11 @@ void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) { pMnode->mnodeId = dnodeId; pMnode->createdTime = taosGetTimestampMs(); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsMnodeSdb, - .pObj = pMnode, - .writeCb = mnodeCreateMnodeCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsMnodeSdb, + .pObj = pMnode, + .fpRsp = mnodeCreateMnodeCb }; int32_t code = TSDB_CODE_SUCCESS; @@ -346,7 +342,7 @@ void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) { return; } - code = sdbInsertRow(&oper); + code = sdbInsertRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("dnode:%d, failed to create mnode, ep:%s reason:%s", dnodeId, dnodeEp, tstrerror(code)); tfree(pMnode); @@ -356,8 +352,8 @@ void mnodeCreateMnode(int32_t dnodeId, char *dnodeEp, bool needConfirm) { void mnodeDropMnodeLocal(int32_t dnodeId) { SMnodeObj *pMnode = mnodeGetMnode(dnodeId); if (pMnode != NULL) { - SSdbOper oper = {.type = SDB_OPER_LOCAL, .table = tsMnodeSdb, .pObj = pMnode}; - sdbDeleteRow(&oper); + SSdbRow row = {.type = SDB_OPER_LOCAL, .pTable = tsMnodeSdb, .pObj = pMnode}; + sdbDeleteRow(&row); mnodeDecMnodeRef(pMnode); } @@ -371,13 +367,13 @@ int32_t mnodeDropMnode(int32_t dnodeId) { return TSDB_CODE_MND_DNODE_NOT_EXIST; } - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsMnodeSdb, - .pObj = pMnode + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsMnodeSdb, + .pObj = pMnode }; - int32_t code = sdbDeleteRow(&oper); + int32_t code = sdbDeleteRow(&row); sdbDecRef(tsMnodeSdb, pMnode); @@ -469,7 +465,7 @@ static int32_t mnodeRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, vo cols++; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - char* roles = mnodeGetMnodeRoleStr(pMnode->role); + char* roles = syncRole[pMnode->role]; STR_WITH_MAXSIZE_TO_VARSTR(pWrite, roles, pShow->bytes[cols]); cols++; diff --git a/src/mnode/src/mnodePeer.c b/src/mnode/src/mnodePeer.c index e43f8c1b786e6126253cdb40c0184bc34dc4dab2..f13ef7539800919e5f31d43b55def590b801e86d 100644 --- a/src/mnode/src/mnodePeer.c +++ b/src/mnode/src/mnodePeer.c @@ -47,7 +47,7 @@ void mnodeAddPeerRspHandle(uint8_t msgType, void (*fp)(SRpcMsg *rpcMsg)) { int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) { if (pMsg->rpcMsg.pCont == NULL) { - mError("%p, msg:%s in mpeer queue, content is null", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); + mError("msg:%p, ahandle:%p type:%s in mpeer queue, content is null", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); return TSDB_CODE_MND_INVALID_MSG_LEN; } @@ -58,8 +58,8 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) { rpcRsp->rsp = epSet; rpcRsp->len = sizeof(SRpcEpSet); - mDebug("%p, msg:%s in mpeer queue will be redirected, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle, - taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse); + mDebug("msg:%p, ahandle:%p type:%s in mpeer queue will be redirected, numOfEps:%d inUse:%d", pMsg, + pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse); for (int32_t i = 0; i < epSet->numOfEps; ++i) { if (strcmp(epSet->fqdn[i], tsLocalFqdn) == 0 && htons(epSet->port[i]) == tsServerPort + TSDB_PORT_DNODEDNODE) { epSet->inUse = (i + 1) % epSet->numOfEps; @@ -73,7 +73,8 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) { } if (tsMnodeProcessPeerMsgFp[pMsg->rpcMsg.msgType] == NULL) { - mError("%p, msg:%s in mpeer queue, not processed", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); + mError("msg:%p, ahandle:%p type:%s in mpeer queue, not processed", pMsg, pMsg->rpcMsg.ahandle, + taosMsg[pMsg->rpcMsg.msgType]); return TSDB_CODE_MND_MSG_NOT_PROCESSED; } @@ -82,13 +83,14 @@ int32_t mnodeProcessPeerReq(SMnodeMsg *pMsg) { void mnodeProcessPeerRsp(SRpcMsg *pMsg) { if (!sdbIsMaster()) { - mError("%p, msg:%s is not processed for it is not master", pMsg->ahandle, taosMsg[pMsg->msgType]); + mError("msg:%p, ahandle:%p type:%s is not processed for it is not master", pMsg, pMsg->ahandle, + taosMsg[pMsg->msgType]); return; } if (tsMnodeProcessPeerRspFp[pMsg->msgType]) { (*tsMnodeProcessPeerRspFp[pMsg->msgType])(pMsg); } else { - mError("%p, msg:%s is not processed", pMsg->ahandle, taosMsg[pMsg->msgType]); + mError("msg:%p, ahandle:%p type:%s is not processed", pMsg, pMsg->ahandle, taosMsg[pMsg->msgType]); } } diff --git a/src/mnode/src/mnodeRead.c b/src/mnode/src/mnodeRead.c index 93b944febb42d3c7e7bac113b5447ddd1488369c..ea7ce783e8f0a018d3648257206cb6abcaf28e26 100644 --- a/src/mnode/src/mnodeRead.c +++ b/src/mnode/src/mnodeRead.c @@ -43,7 +43,7 @@ void mnodeAddReadMsgHandle(uint8_t msgType, int32_t (*fp)(SMnodeMsg *pMsg)) { int32_t mnodeProcessRead(SMnodeMsg *pMsg) { if (pMsg->rpcMsg.pCont == NULL) { - mError("%p, msg:%s in mread queue, content is null", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); + mError("msg:%p, app:%p type:%s in mread queue, content is null", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); return TSDB_CODE_MND_INVALID_MSG_LEN; } @@ -52,7 +52,7 @@ int32_t mnodeProcessRead(SMnodeMsg *pMsg) { SRpcEpSet *epSet = rpcMallocCont(sizeof(SRpcEpSet)); mnodeGetMnodeEpSetForShell(epSet); - mDebug("%p, msg:%s in mread queue will be redirected, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle, + mDebug("msg:%p, app:%p type:%s in mread queue will be redirected, numOfEps:%d inUse:%d", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse); for (int32_t i = 0; i < epSet->numOfEps; ++i) { if (strcmp(epSet->fqdn[i], tsLocalFqdn) == 0 && htons(epSet->port[i]) == tsServerPort) { @@ -70,13 +70,15 @@ int32_t mnodeProcessRead(SMnodeMsg *pMsg) { } if (tsMnodeProcessReadMsgFp[pMsg->rpcMsg.msgType] == NULL) { - mError("%p, msg:%s in mread queue, not processed", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); + mError("msg:%p, app:%p type:%s in mread queue, not processed", pMsg, pMsg->rpcMsg.ahandle, + taosMsg[pMsg->rpcMsg.msgType]); return TSDB_CODE_MND_MSG_NOT_PROCESSED; } int32_t code = mnodeInitMsg(pMsg); if (code != TSDB_CODE_SUCCESS) { - mError("%p, msg:%s in mread queue, not processed reason:%s", pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], tstrerror(code)); + mError("msg:%p, app:%p type:%s in mread queue, not processed reason:%s", pMsg, pMsg->rpcMsg.ahandle, + taosMsg[pMsg->rpcMsg.msgType], tstrerror(code)); return code; } diff --git a/src/mnode/src/mnodeSdb.c b/src/mnode/src/mnodeSdb.c index 003ecd0d24498d51d5e82d041740aa6f0a180280..36e1a1eb2b1b8316b2cb4eee1ad40fa93e9b06ac 100644 --- a/src/mnode/src/mnodeSdb.c +++ b/src/mnode/src/mnodeSdb.c @@ -34,23 +34,30 @@ #include "mnodeSdb.h" #define SDB_TABLE_LEN 12 -#define SDB_SYNC_HACK 16 +#define MAX_QUEUED_MSG_NUM 10000 typedef enum { - SDB_ACTION_INSERT, - SDB_ACTION_DELETE, - SDB_ACTION_UPDATE + SDB_ACTION_INSERT = 0, + SDB_ACTION_DELETE = 1, + SDB_ACTION_UPDATE = 2 } ESdbAction; typedef enum { - SDB_STATUS_OFFLINE, - SDB_STATUS_SERVING, - SDB_STATUS_CLOSING + SDB_STATUS_OFFLINE = 0, + SDB_STATUS_SERVING = 1, + SDB_STATUS_CLOSING = 2 } ESdbStatus; -typedef struct _SSdbTable { - char tableName[SDB_TABLE_LEN]; - ESdbTable tableId; +char *actStr[] = { + "insert", + "delete", + "update", + "invalid" +}; + +typedef struct SSdbTable { + char name[SDB_TABLE_LEN]; + ESdbTable id; ESdbKey keyType; int32_t hashSessions; int32_t maxRowSize; @@ -58,13 +65,13 @@ typedef struct _SSdbTable { int32_t autoIndex; int64_t numOfRows; void * iHandle; - int32_t (*insertFp)(SSdbOper *pDesc); - int32_t (*deleteFp)(SSdbOper *pOper); - int32_t (*updateFp)(SSdbOper *pOper); - int32_t (*decodeFp)(SSdbOper *pOper); - int32_t (*encodeFp)(SSdbOper *pOper); - int32_t (*destroyFp)(SSdbOper *pOper); - int32_t (*restoredFp)(); + int32_t (*fpInsert)(SSdbRow *pRow); + int32_t (*fpDelete)(SSdbRow *pRow); + int32_t (*fpUpdate)(SSdbRow *pRow); + int32_t (*fpDecode)(SSdbRow *pRow); + int32_t (*fpEncode)(SSdbRow *pRow); + int32_t (*fpDestroy)(SSdbRow *pRow); + int32_t (*fpRestored)(); pthread_mutex_t mutex; } SSdbTable; @@ -75,60 +82,61 @@ typedef struct { int64_t sync; void * wal; SSyncCfg cfg; + int32_t queuedMsg; int32_t numOfTables; SSdbTable *tableList[SDB_TABLE_MAX]; pthread_mutex_t mutex; -} SSdbObject; +} SSdbMgmt; typedef struct { pthread_t thread; int32_t workerId; -} SSdbWriteWorker; +} SSdbWorker; typedef struct { int32_t num; - SSdbWriteWorker *writeWorker; -} SSdbWriteWorkerPool; + SSdbWorker *worker; +} SSdbWorkerPool; extern void * tsMnodeTmr; -static void * tsUpdateSyncTmr; -static SSdbObject tsSdbObj = {0}; -static taos_qset tsSdbWriteQset; -static taos_qall tsSdbWriteQall; -static taos_queue tsSdbWriteQueue; -static SSdbWriteWorkerPool tsSdbPool; - -static int32_t sdbWrite(void *param, void *data, int32_t type, void *pMsg); -static int32_t sdbWriteToQueue(void *param, void *data, int32_t type, void *pMsg); -static void * sdbWorkerFp(void *param); -static int32_t sdbInitWriteWorker(); -static void sdbCleanupWriteWorker(); -static int32_t sdbAllocWriteQueue(); -static void sdbFreeWritequeue(); -static int32_t sdbUpdateRowImp(SSdbOper *pOper); -static int32_t sdbDeleteRowImp(SSdbOper *pOper); -static int32_t sdbInsertHash(SSdbTable *pTable, SSdbOper *pOper); -static int32_t sdbUpdateHash(SSdbTable *pTable, SSdbOper *pOper); -static int32_t sdbDeleteHash(SSdbTable *pTable, SSdbOper *pOper); - -int32_t sdbGetId(void *handle) { - return ((SSdbTable *)handle)->autoIndex; +static void * tsSdbTmr; +static SSdbMgmt tsSdbMgmt = {0}; +static taos_qset tsSdbWQset; +static taos_qall tsSdbWQall; +static taos_queue tsSdbWQueue; +static SSdbWorkerPool tsSdbPool; + +static int32_t sdbProcessWrite(void *pRow, void *pHead, int32_t qtype, void *unused); +static int32_t sdbWriteWalToQueue(int32_t vgId, void *pHead, int32_t qtype, void *rparam); +static int32_t sdbWriteRowToQueue(SSdbRow *pRow, int32_t action); +static void sdbFreeFromQueue(SSdbRow *pRow); +static void * sdbWorkerFp(void *pWorker); +static int32_t sdbInitWorker(); +static void sdbCleanupWorker(); +static int32_t sdbAllocQueue(); +static void sdbFreeQueue(); +static int32_t sdbInsertHash(SSdbTable *pTable, SSdbRow *pRow); +static int32_t sdbUpdateHash(SSdbTable *pTable, SSdbRow *pRow); +static int32_t sdbDeleteHash(SSdbTable *pTable, SSdbRow *pRow); + +int32_t sdbGetId(void *pTable) { + return ((SSdbTable *)pTable)->autoIndex; } -int64_t sdbGetNumOfRows(void *handle) { - return ((SSdbTable *)handle)->numOfRows; +int64_t sdbGetNumOfRows(void *pTable) { + return ((SSdbTable *)pTable)->numOfRows; } uint64_t sdbGetVersion() { - return tsSdbObj.version; + return tsSdbMgmt.version; } bool sdbIsMaster() { - return tsSdbObj.role == TAOS_SYNC_ROLE_MASTER; + return tsSdbMgmt.role == TAOS_SYNC_ROLE_MASTER; } bool sdbIsServing() { - return tsSdbObj.status == SDB_STATUS_SERVING; + return tsSdbMgmt.status == SDB_STATUS_SERVING; } static void *sdbGetObjKey(SSdbTable *pTable, void *key) { @@ -139,18 +147,6 @@ static void *sdbGetObjKey(SSdbTable *pTable, void *key) { return key; } -static char *sdbGetActionStr(int32_t action) { - switch (action) { - case SDB_ACTION_INSERT: - return "insert"; - case SDB_ACTION_DELETE: - return "delete"; - case SDB_ACTION_UPDATE: - return "update"; - } - return "invalid"; -} - static char *sdbGetKeyStr(SSdbTable *pTable, void *key) { static char str[16]; switch (pTable->keyType) { @@ -166,28 +162,28 @@ static char *sdbGetKeyStr(SSdbTable *pTable, void *key) { } } -static char *sdbGetKeyStrFromObj(SSdbTable *pTable, void *key) { +static char *sdbGetRowStr(SSdbTable *pTable, void *key) { return sdbGetKeyStr(pTable, sdbGetObjKey(pTable, key)); } static void *sdbGetTableFromId(int32_t tableId) { - return tsSdbObj.tableList[tableId]; + return tsSdbMgmt.tableList[tableId]; } static int32_t sdbInitWal() { SWalCfg walCfg = {.vgId = 1, .walLevel = TAOS_WAL_FSYNC, .keep = TAOS_WAL_KEEP, .fsyncPeriod = 0}; - char temp[TSDB_FILENAME_LEN]; + char temp[TSDB_FILENAME_LEN] = {0}; sprintf(temp, "%s/wal", tsMnodeDir); - tsSdbObj.wal = walOpen(temp, &walCfg); - if (tsSdbObj.wal == NULL) { - sdbError("failed to open sdb wal in %s", tsMnodeDir); + tsSdbMgmt.wal = walOpen(temp, &walCfg); + if (tsSdbMgmt.wal == NULL) { + sdbError("vgId:1, failed to open wal in %s", tsMnodeDir); return -1; } - sdbInfo("open sdb wal for restore"); - int code = walRestore(tsSdbObj.wal, NULL, sdbWrite); + sdbInfo("vgId:1, open wal for restore"); + int32_t code = walRestore(tsSdbMgmt.wal, NULL, sdbProcessWrite); if (code != TSDB_CODE_SUCCESS) { - sdbError("failed to open wal for restore, reason:%s", tstrerror(code)); + sdbError("vgId:1, failed to open wal for restore since %s", tstrerror(code)); return -1; } return 0; @@ -199,31 +195,31 @@ static void sdbRestoreTables() { for (int32_t tableId = 0; tableId < SDB_TABLE_MAX; ++tableId) { SSdbTable *pTable = sdbGetTableFromId(tableId); if (pTable == NULL) continue; - if (pTable->restoredFp) { - (*pTable->restoredFp)(); + if (pTable->fpRestored) { + (*pTable->fpRestored)(); } totalRows += pTable->numOfRows; numOfTables++; - sdbDebug("table:%s, is restored, numOfRows:%" PRId64, pTable->tableName, pTable->numOfRows); + sdbDebug("vgId:1, sdb:%s is restored, rows:%" PRId64, pTable->name, pTable->numOfRows); } - sdbInfo("sdb is restored, ver:%" PRId64 " totalRows:%d numOfTables:%d", tsSdbObj.version, totalRows, numOfTables); + sdbInfo("vgId:1, sdb is restored, mver:%" PRIu64 " rows:%d tables:%d", tsSdbMgmt.version, totalRows, numOfTables); } void sdbUpdateMnodeRoles() { - if (tsSdbObj.sync <= 0) return; + if (tsSdbMgmt.sync <= 0) return; SNodesRole roles = {0}; - syncGetNodesRole(tsSdbObj.sync, &roles); + if (syncGetNodesRole(tsSdbMgmt.sync, &roles) != 0) return; - sdbInfo("update mnodes sync roles, total:%d", tsSdbObj.cfg.replica); - for (int32_t i = 0; i < tsSdbObj.cfg.replica; ++i) { + sdbInfo("vgId:1, update mnodes role, replica:%d", tsSdbMgmt.cfg.replica); + for (int32_t i = 0; i < tsSdbMgmt.cfg.replica; ++i) { SMnodeObj *pMnode = mnodeGetMnode(roles.nodeId[i]); if (pMnode != NULL) { pMnode->role = roles.role[i]; - sdbInfo("mnode:%d, role:%s", pMnode->mnodeId, mnodeGetMnodeRoleStr(pMnode->role)); - if (pMnode->mnodeId == dnodeGetDnodeId()) tsSdbObj.role = pMnode->role; + sdbInfo("vgId:1, mnode:%d, role:%s", pMnode->mnodeId, syncRole[pMnode->role]); + if (pMnode->mnodeId == dnodeGetDnodeId()) tsSdbMgmt.role = pMnode->role; mnodeDecMnodeRef(pMnode); } } @@ -232,93 +228,80 @@ void sdbUpdateMnodeRoles() { mnodeUpdateMnodeEpSet(); } -static uint32_t sdbGetFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion) { +static uint32_t sdbGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion) { sdbUpdateMnodeRoles(); return 0; } -static int32_t sdbGetWalInfo(void *ahandle, char *fileName, int64_t *fileId) { - return walGetWalFile(tsSdbObj.wal, fileName, fileId); +static int32_t sdbGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId) { + return walGetWalFile(tsSdbMgmt.wal, fileName, fileId); } -static void sdbNotifyRole(void *ahandle, int8_t role) { - sdbInfo("mnode role changed from %s to %s", mnodeGetMnodeRoleStr(tsSdbObj.role), mnodeGetMnodeRoleStr(role)); +static void sdbNotifyRole(int32_t vgId, int8_t role) { + sdbInfo("vgId:1, mnode role changed from %s to %s", syncRole[tsSdbMgmt.role], syncRole[role]); - if (role == TAOS_SYNC_ROLE_MASTER && tsSdbObj.role != TAOS_SYNC_ROLE_MASTER) { + if (role == TAOS_SYNC_ROLE_MASTER && tsSdbMgmt.role != TAOS_SYNC_ROLE_MASTER) { balanceReset(); } - tsSdbObj.role = role; + tsSdbMgmt.role = role; sdbUpdateMnodeRoles(); } -FORCE_INLINE -static void sdbConfirmForward(void *ahandle, void *param, int32_t code) { - assert(param); - SSdbOper * pOper = param; - SMnodeMsg *pMsg = pOper->pMsg; - if (code <= 0) pOper->retCode = code; - - int32_t processedCount = atomic_add_fetch_32(&pOper->processedCount, 1); - if (processedCount <= 1) { - if (pMsg != NULL) { - sdbDebug("app:%p:%p, waiting for confirm this operation, count:%d result:%s", pMsg->rpcMsg.ahandle, pMsg, - processedCount, tstrerror(code)); - } - return; - } +// failed to forward, need revert insert +static void sdbHandleFailedConfirm(SSdbRow *pRow) { + SWalHead *pHead = pRow->pHead; + int32_t action = pHead->msgType % 10; - if (pMsg != NULL) { - sdbDebug("app:%p:%p, is confirmed and will do callback func, result:%s", pMsg->rpcMsg.ahandle, pMsg, - tstrerror(code)); - } + sdbError("vgId:1, row:%p:%s hver:%" PRIu64 " action:%s, failed to foward since %s", pRow->pObj, + sdbGetKeyStr(pRow->pTable, pHead->cont), pHead->version, actStr[action], tstrerror(pRow->code)); - // failed to forward, need revert insert - if (pOper->retCode != TSDB_CODE_SUCCESS) { - SWalHead *pHead = (void *)pOper + sizeof(SSdbOper) + SDB_SYNC_HACK; - int32_t action = pHead->msgType % 10; - sdbError("table:%s record:%p:%s ver:%" PRIu64 ", action:%d failed to foward reason:%s", - ((SSdbTable *)pOper->table)->tableName, pOper->pObj, sdbGetKeyStr(pOper->table, pHead->cont), - pHead->version, action, tstrerror(pOper->retCode)); - if (action == SDB_ACTION_INSERT) { - // It's better to create a table in two stages, create it first and then set it success - //sdbDeleteHash(pOper->table, pOper); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = pOper->table, - .pObj = pOper->pObj - }; - sdbDeleteRow(&oper); - } + // It's better to create a table in two stages, create it first and then set it success + if (action == SDB_ACTION_INSERT) { + SSdbRow row = {.type = SDB_OPER_GLOBAL, .pTable = pRow->pTable, .pObj = pRow->pObj}; + sdbDeleteRow(&row); } +} - if (pOper->writeCb != NULL) { - pOper->retCode = (*pOper->writeCb)(pMsg, pOper->retCode); +FORCE_INLINE +static void sdbConfirmForward(int32_t vgId, void *wparam, int32_t code) { + if (wparam == NULL) return; + SSdbRow *pRow = wparam; + SMnodeMsg * pMsg = pRow->pMsg; + + if (code <= 0) pRow->code = code; + int32_t count = atomic_add_fetch_32(&pRow->processedCount, 1); + if (count <= 1) { + if (pMsg != NULL) sdbTrace("vgId:1, msg:%p waiting for confirm, count:%d code:%x", pMsg, count, code); + return; + } else { + if (pMsg != NULL) sdbTrace("vgId:1, msg:%p is confirmed, code:%x", pMsg, code); } - dnodeSendRpcMWriteRsp(pMsg, pOper->retCode); - // if ahandle, means this func is called by sdb write - if (ahandle == NULL) { - sdbDecRef(pOper->table, pOper->pObj); + if (pRow->code != TSDB_CODE_SUCCESS) sdbHandleFailedConfirm(pRow); + + if (pRow->fpRsp != NULL) { + pRow->code = (*pRow->fpRsp)(pMsg, pRow->code); } - taosFreeQitem(pOper); + dnodeSendRpcMWriteRsp(pMsg, pRow->code); + sdbFreeFromQueue(pRow); } static void sdbUpdateSyncTmrFp(void *param, void *tmrId) { sdbUpdateSync(NULL); } void sdbUpdateAsync() { - taosTmrReset(sdbUpdateSyncTmrFp, 200, NULL, tsMnodeTmr, &tsUpdateSyncTmr); + taosTmrReset(sdbUpdateSyncTmrFp, 200, NULL, tsMnodeTmr, &tsSdbTmr); } void sdbUpdateSync(void *pMnodes) { SMnodeInfos *mnodes = pMnodes; if (!mnodeIsRunning()) { - mDebug("mnode not start yet, update sync config later"); + mDebug("vgId:1, mnode not start yet, update sync config later"); return; } - mDebug("update sync config in sync module, mnodes:%p", pMnodes); + mDebug("vgId:1, update sync config in sync module, mnodes:%p", pMnodes); SSyncCfg syncCfg = {0}; int32_t index = 0; @@ -344,7 +327,7 @@ void sdbUpdateSync(void *pMnodes) { } sdbFreeIter(pIter); syncCfg.replica = index; - mDebug("mnodes info not input, use infos in sdb, numOfMnodes:%d", syncCfg.replica); + mDebug("vgId:1, mnodes info not input, use infos in sdb, numOfMnodes:%d", syncCfg.replica); } else { for (index = 0; index < mnodes->mnodeNum; ++index) { SMnodeInfo *node = &mnodes->mnodeInfos[index]; @@ -353,7 +336,7 @@ void sdbUpdateSync(void *pMnodes) { syncCfg.nodeInfo[index].nodePort += TSDB_PORT_SYNC; } syncCfg.replica = index; - mDebug("mnodes info input, numOfMnodes:%d", syncCfg.replica); + mDebug("vgId:1, mnodes info input, numOfMnodes:%d", syncCfg.replica); } syncCfg.quorum = (syncCfg.replica == 1) ? 1 : 2; @@ -367,18 +350,19 @@ void sdbUpdateSync(void *pMnodes) { } if (!hasThisDnode) { - sdbDebug("update sync config, this dnode not exist"); + sdbDebug("vgId:1, update sync config, this dnode not exist"); return; } - if (memcmp(&syncCfg, &tsSdbObj.cfg, sizeof(SSyncCfg)) == 0) { - sdbDebug("update sync config, info not changed"); + if (memcmp(&syncCfg, &tsSdbMgmt.cfg, sizeof(SSyncCfg)) == 0) { + sdbDebug("vgId:1, update sync config, info not changed"); return; } - sdbInfo("work as mnode, replica:%d", syncCfg.replica); + sdbInfo("vgId:1, work as mnode, replica:%d", syncCfg.replica); for (int32_t i = 0; i < syncCfg.replica; ++i) { - sdbInfo("mnode:%d, %s:%d", syncCfg.nodeInfo[i].nodeId, syncCfg.nodeInfo[i].nodeFqdn, syncCfg.nodeInfo[i].nodePort); + sdbInfo("vgId:1, mnode:%d, %s:%d", syncCfg.nodeInfo[i].nodeId, syncCfg.nodeInfo[i].nodeFqdn, + syncCfg.nodeInfo[i].nodePort); } SSyncInfo syncInfo = {0}; @@ -386,26 +370,26 @@ void sdbUpdateSync(void *pMnodes) { syncInfo.version = sdbGetVersion(); syncInfo.syncCfg = syncCfg; sprintf(syncInfo.path, "%s", tsMnodeDir); - syncInfo.ahandle = NULL; syncInfo.getWalInfo = sdbGetWalInfo; syncInfo.getFileInfo = sdbGetFileInfo; - syncInfo.writeToCache = sdbWriteToQueue; + syncInfo.writeToCache = sdbWriteWalToQueue; syncInfo.confirmForward = sdbConfirmForward; syncInfo.notifyRole = sdbNotifyRole; - tsSdbObj.cfg = syncCfg; + tsSdbMgmt.cfg = syncCfg; - if (tsSdbObj.sync) { - syncReconfig(tsSdbObj.sync, &syncCfg); + if (tsSdbMgmt.sync) { + syncReconfig(tsSdbMgmt.sync, &syncCfg); } else { - tsSdbObj.sync = syncStart(&syncInfo); + tsSdbMgmt.sync = syncStart(&syncInfo); } + sdbUpdateMnodeRoles(); } int32_t sdbInit() { - pthread_mutex_init(&tsSdbObj.mutex, NULL); + pthread_mutex_init(&tsSdbMgmt.mutex, NULL); - if (sdbInitWriteWorker() != 0) { + if (sdbInitWorker() != 0) { return -1; } @@ -416,56 +400,56 @@ int32_t sdbInit() { sdbRestoreTables(); if (mnodeGetMnodesNum() == 1) { - tsSdbObj.role = TAOS_SYNC_ROLE_MASTER; + tsSdbMgmt.role = TAOS_SYNC_ROLE_MASTER; } - tsSdbObj.status = SDB_STATUS_SERVING; + tsSdbMgmt.status = SDB_STATUS_SERVING; return TSDB_CODE_SUCCESS; } void sdbCleanUp() { - if (tsSdbObj.status != SDB_STATUS_SERVING) return; + if (tsSdbMgmt.status != SDB_STATUS_SERVING) return; - tsSdbObj.status = SDB_STATUS_CLOSING; - - sdbCleanupWriteWorker(); - sdbDebug("sdb will be closed, ver:%" PRId64, tsSdbObj.version); + tsSdbMgmt.status = SDB_STATUS_CLOSING; + + sdbCleanupWorker(); + sdbDebug("vgId:1, sdb will be closed, mver:%" PRIu64, tsSdbMgmt.version); - if (tsSdbObj.sync) { - syncStop(tsSdbObj.sync); - tsSdbObj.sync = -1; + if (tsSdbMgmt.sync) { + syncStop(tsSdbMgmt.sync); + tsSdbMgmt.sync = -1; } - if (tsSdbObj.wal) { - walClose(tsSdbObj.wal); - tsSdbObj.wal = NULL; + if (tsSdbMgmt.wal) { + walClose(tsSdbMgmt.wal); + tsSdbMgmt.wal = NULL; } - pthread_mutex_destroy(&tsSdbObj.mutex); + pthread_mutex_destroy(&tsSdbMgmt.mutex); } -void sdbIncRef(void *handle, void *pObj) { - if (pObj == NULL || handle == NULL) return; +void sdbIncRef(void *tparam, void *pRow) { + if (pRow == NULL || tparam == NULL) return; - SSdbTable *pTable = handle; - int32_t * pRefCount = (int32_t *)(pObj + pTable->refCountPos); + SSdbTable *pTable = tparam; + int32_t * pRefCount = (int32_t *)(pRow + pTable->refCountPos); int32_t refCount = atomic_add_fetch_32(pRefCount, 1); - sdbTrace("add ref to table:%s record:%p:%s:%d", pTable->tableName, pObj, sdbGetKeyStrFromObj(pTable, pObj), refCount); + sdbTrace("vgId:1, sdb:%s, inc ref to row:%p:%s:%d", pTable->name, pRow, sdbGetRowStr(pTable, pRow), refCount); } -void sdbDecRef(void *handle, void *pObj) { - if (pObj == NULL || handle == NULL) return; +void sdbDecRef(void *tparam, void *pRow) { + if (pRow == NULL || tparam == NULL) return; - SSdbTable *pTable = handle; - int32_t * pRefCount = (int32_t *)(pObj + pTable->refCountPos); + SSdbTable *pTable = tparam; + int32_t * pRefCount = (int32_t *)(pRow + pTable->refCountPos); int32_t refCount = atomic_sub_fetch_32(pRefCount, 1); - sdbTrace("def ref of table:%s record:%p:%s:%d", pTable->tableName, pObj, sdbGetKeyStrFromObj(pTable, pObj), refCount); + sdbTrace("vgId:1, sdb:%s, dec ref to row:%p:%s:%d", pTable->name, pRow, sdbGetRowStr(pTable, pRow), refCount); - int32_t *updateEnd = pObj + pTable->refCountPos - 4; + int32_t *updateEnd = pRow + pTable->refCountPos - 4; if (refCount <= 0 && *updateEnd) { - sdbTrace("table:%s, record:%p:%s:%d is destroyed", pTable->tableName, pObj, sdbGetKeyStrFromObj(pTable, pObj), refCount); - SSdbOper oper = {.pObj = pObj}; - (*pTable->destroyFp)(&oper); + sdbTrace("vgId:1, sdb:%s, row:%p:%s:%d destroyed", pTable->name, pRow, sdbGetRowStr(pTable, pRow), refCount); + SSdbRow row = {.pObj = pRow}; + (*pTable->fpDestroy)(&row); } } @@ -487,12 +471,12 @@ static void *sdbGetRowMetaFromObj(SSdbTable *pTable, void *key) { return sdbGetRowMeta(pTable, sdbGetObjKey(pTable, key)); } -void *sdbGetRow(void *handle, void *key) { - SSdbTable *pTable = handle; +void *sdbGetRow(void *tparam, void *key) { + SSdbTable *pTable = tparam; pthread_mutex_lock(&pTable->mutex); - void *pRow = sdbGetRowMeta(handle, key); - if (pRow) sdbIncRef(handle, pRow); + void *pRow = sdbGetRowMeta(pTable, key); + if (pRow) sdbIncRef(pTable, pRow); pthread_mutex_unlock(&pTable->mutex); return pRow; @@ -502,8 +486,8 @@ static void *sdbGetRowFromObj(SSdbTable *pTable, void *key) { return sdbGetRow(pTable, sdbGetObjKey(pTable, key)); } -static int32_t sdbInsertHash(SSdbTable *pTable, SSdbOper *pOper) { - void * key = sdbGetObjKey(pTable, pOper->pObj); +static int32_t sdbInsertHash(SSdbTable *pTable, SSdbRow *pRow) { + void * key = sdbGetObjKey(pTable, pRow->pObj); int32_t keySize = sizeof(int32_t); if (pTable->keyType == SDB_KEY_STRING || pTable->keyType == SDB_KEY_VAR_STRING) { @@ -511,43 +495,43 @@ static int32_t sdbInsertHash(SSdbTable *pTable, SSdbOper *pOper) { } pthread_mutex_lock(&pTable->mutex); - taosHashPut(pTable->iHandle, key, keySize, &pOper->pObj, sizeof(int64_t)); + taosHashPut(pTable->iHandle, key, keySize, &pRow->pObj, sizeof(int64_t)); pthread_mutex_unlock(&pTable->mutex); - sdbIncRef(pTable, pOper->pObj); + sdbIncRef(pTable, pRow->pObj); atomic_add_fetch_32(&pTable->numOfRows, 1); if (pTable->keyType == SDB_KEY_AUTO) { - pTable->autoIndex = MAX(pTable->autoIndex, *((uint32_t *)pOper->pObj)); + pTable->autoIndex = MAX(pTable->autoIndex, *((uint32_t *)pRow->pObj)); } else { atomic_add_fetch_32(&pTable->autoIndex, 1); } - sdbDebug("table:%s, insert record:%s to hash, rowSize:%d numOfRows:%" PRId64 ", msg:%p", pTable->tableName, - sdbGetKeyStrFromObj(pTable, pOper->pObj), pOper->rowSize, pTable->numOfRows, pOper->pMsg); + sdbDebug("vgId:1, sdb:%s, insert key:%s to hash, rowSize:%d rows:%" PRId64 ", msg:%p", pTable->name, + sdbGetRowStr(pTable, pRow->pObj), pRow->rowSize, pTable->numOfRows, pRow->pMsg); - int32_t code = (*pTable->insertFp)(pOper); + int32_t code = (*pTable->fpInsert)(pRow); if (code != TSDB_CODE_SUCCESS) { - sdbError("table:%s, failed to insert record:%s to hash, remove it", pTable->tableName, - sdbGetKeyStrFromObj(pTable, pOper->pObj)); - sdbDeleteHash(pTable, pOper); + sdbError("vgId:1, sdb:%s, failed to insert key:%s to hash, remove it", pTable->name, + sdbGetRowStr(pTable, pRow->pObj)); + sdbDeleteHash(pTable, pRow); } return TSDB_CODE_SUCCESS; } -static int32_t sdbDeleteHash(SSdbTable *pTable, SSdbOper *pOper) { - int32_t *updateEnd = pOper->pObj + pTable->refCountPos - 4; +static int32_t sdbDeleteHash(SSdbTable *pTable, SSdbRow *pRow) { + int32_t *updateEnd = pRow->pObj + pTable->refCountPos - 4; bool set = atomic_val_compare_exchange_32(updateEnd, 0, 1) == 0; if (!set) { - sdbError("table:%s, failed to delete record:%s from hash, for it already removed", pTable->tableName, - sdbGetKeyStrFromObj(pTable, pOper->pObj)); + sdbError("vgId:1, sdb:%s, failed to delete key:%s from hash, for it already removed", pTable->name, + sdbGetRowStr(pTable, pRow->pObj)); return TSDB_CODE_MND_SDB_OBJ_NOT_THERE; } - (*pTable->deleteFp)(pOper); + (*pTable->fpDelete)(pRow); - void * key = sdbGetObjKey(pTable, pOper->pObj); + void * key = sdbGetObjKey(pTable, pRow->pObj); int32_t keySize = sizeof(int32_t); if (pTable->keyType == SDB_KEY_STRING || pTable->keyType == SDB_KEY_VAR_STRING) { keySize = strlen((char *)key); @@ -558,310 +542,221 @@ static int32_t sdbDeleteHash(SSdbTable *pTable, SSdbOper *pOper) { pthread_mutex_unlock(&pTable->mutex); atomic_sub_fetch_32(&pTable->numOfRows, 1); - - sdbDebug("table:%s, delete record:%s from hash, numOfRows:%" PRId64 ", msg:%p", pTable->tableName, - sdbGetKeyStrFromObj(pTable, pOper->pObj), pTable->numOfRows, pOper->pMsg); - sdbDecRef(pTable, pOper->pObj); + sdbDebug("vgId:1, sdb:%s, delete key:%s from hash, numOfRows:%" PRId64 ", msg:%p", pTable->name, + sdbGetRowStr(pTable, pRow->pObj), pTable->numOfRows, pRow->pMsg); + + sdbDecRef(pTable, pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t sdbUpdateHash(SSdbTable *pTable, SSdbOper *pOper) { - sdbDebug("table:%s, update record:%s in hash, numOfRows:%" PRId64 ", msg:%p", pTable->tableName, - sdbGetKeyStrFromObj(pTable, pOper->pObj), pTable->numOfRows, pOper->pMsg); +static int32_t sdbUpdateHash(SSdbTable *pTable, SSdbRow *pRow) { + sdbDebug("vgId:1, sdb:%s, update key:%s in hash, numOfRows:%" PRId64 ", msg:%p", pTable->name, + sdbGetRowStr(pTable, pRow->pObj), pTable->numOfRows, pRow->pMsg); - (*pTable->updateFp)(pOper); + (*pTable->fpUpdate)(pRow); return TSDB_CODE_SUCCESS; } -static int sdbWrite(void *param, void *data, int32_t type, void *pMsg) { - SSdbOper *pOper = param; - SWalHead *pHead = data; +static int sdbProcessWrite(void *wparam, void *hparam, int32_t qtype, void *unused) { + SSdbRow *pRow = wparam; + SWalHead *pHead = hparam; int32_t tableId = pHead->msgType / 10; int32_t action = pHead->msgType % 10; SSdbTable *pTable = sdbGetTableFromId(tableId); assert(pTable != NULL); - pthread_mutex_lock(&tsSdbObj.mutex); + pthread_mutex_lock(&tsSdbMgmt.mutex); if (pHead->version == 0) { // assign version - tsSdbObj.version++; - pHead->version = tsSdbObj.version; + tsSdbMgmt.version++; + pHead->version = tsSdbMgmt.version; } else { // for data from WAL or forward, version may be smaller - if (pHead->version <= tsSdbObj.version) { - pthread_mutex_unlock(&tsSdbObj.mutex); - sdbDebug("table:%s, failed to restore %s record:%s from source(%d), ver:%" PRId64 " too large, sdb ver:%" PRId64, - pTable->tableName, sdbGetActionStr(action), sdbGetKeyStr(pTable, pHead->cont), type, pHead->version, tsSdbObj.version); + if (pHead->version <= tsSdbMgmt.version) { + pthread_mutex_unlock(&tsSdbMgmt.mutex); + sdbDebug("vgId:1, sdb:%s, failed to restore %s key:%s from source(%d), hver:%" PRIu64 " too large, mver:%" PRIu64, + pTable->name, actStr[action], sdbGetKeyStr(pTable, pHead->cont), qtype, pHead->version, tsSdbMgmt.version); return TSDB_CODE_SUCCESS; - } else if (pHead->version != tsSdbObj.version + 1) { - pthread_mutex_unlock(&tsSdbObj.mutex); - sdbError("table:%s, failed to restore %s record:%s from source(%d), ver:%" PRId64 " too large, sdb ver:%" PRId64, - pTable->tableName, sdbGetActionStr(action), sdbGetKeyStr(pTable, pHead->cont), type, pHead->version, tsSdbObj.version); + } else if (pHead->version != tsSdbMgmt.version + 1) { + pthread_mutex_unlock(&tsSdbMgmt.mutex); + sdbError("vgId:1, sdb:%s, failed to restore %s key:%s from source(%d), hver:%" PRIu64 " too large, mver:%" PRIu64, + pTable->name, actStr[action], sdbGetKeyStr(pTable, pHead->cont), qtype, pHead->version, tsSdbMgmt.version); return TSDB_CODE_SYN_INVALID_VERSION; } else { - tsSdbObj.version = pHead->version; + tsSdbMgmt.version = pHead->version; } } - int32_t code = walWrite(tsSdbObj.wal, pHead); + int32_t code = walWrite(tsSdbMgmt.wal, pHead); if (code < 0) { - pthread_mutex_unlock(&tsSdbObj.mutex); + pthread_mutex_unlock(&tsSdbMgmt.mutex); return code; } - pthread_mutex_unlock(&tsSdbObj.mutex); + pthread_mutex_unlock(&tsSdbMgmt.mutex); - // from app, oper is created - if (pOper != NULL) { + // from app, row is created + if (pRow != NULL) { // forward to peers - pOper->processedCount = 0; - int32_t syncCode = syncForwardToPeer(tsSdbObj.sync, pHead, pOper, TAOS_QTYPE_RPC); - if (syncCode <= 0) pOper->processedCount = 1; + pRow->processedCount = 0; + int32_t syncCode = syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC); + if (syncCode <= 0) pRow->processedCount = 1; if (syncCode < 0) { - sdbError("table:%s, failed to forward request, result:%s action:%s record:%s ver:%" PRId64 ", msg:%p", pTable->tableName, - tstrerror(syncCode), sdbGetActionStr(action), sdbGetKeyStr(pTable, pHead->cont), pHead->version, pOper->pMsg); + sdbError("vgId:1, sdb:%s, failed to forward req since %s action:%s key:%s hver:%" PRIu64 ", msg:%p", pTable->name, + tstrerror(syncCode), actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version, pRow->pMsg); } else if (syncCode > 0) { - sdbDebug("table:%s, forward request is sent, action:%s record:%s ver:%" PRId64 ", msg:%p", pTable->tableName, - sdbGetActionStr(action), sdbGetKeyStr(pTable, pHead->cont), pHead->version, pOper->pMsg); + sdbDebug("vgId:1, sdb:%s, forward req is sent, action:%s key:%s hver:%" PRIu64 ", msg:%p", pTable->name, + actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version, pRow->pMsg); } else { - sdbTrace("table:%s, no need to send fwd request, action:%s record:%s ver:%" PRId64 ", msg:%p", pTable->tableName, - sdbGetActionStr(action), sdbGetKeyStr(pTable, pHead->cont), pHead->version, pOper->pMsg); + sdbTrace("vgId:1, sdb:%s, no need to send fwd req, action:%s key:%s hver:%" PRIu64 ", msg:%p", pTable->name, + actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version, pRow->pMsg); } return syncCode; } - sdbDebug("table:%s, record from wal/fwd is disposed, action:%s record:%s ver:%" PRId64, pTable->tableName, - sdbGetActionStr(action), sdbGetKeyStr(pTable, pHead->cont), pHead->version); + sdbDebug("vgId:1, sdb:%s, record from wal/fwd is disposed, action:%s key:%s hver:%" PRIu64, pTable->name, + actStr[action], sdbGetKeyStr(pTable, pHead->cont), pHead->version); // even it is WAL/FWD, it shall be called to update version in sync - syncForwardToPeer(tsSdbObj.sync, pHead, pOper, TAOS_QTYPE_RPC); + syncForwardToPeer(tsSdbMgmt.sync, pHead, pRow, TAOS_QTYPE_RPC); - // from wal or forward msg, oper not created, should add into hash + // from wal or forward msg, row not created, should add into hash if (action == SDB_ACTION_INSERT) { - SSdbOper oper = {.rowSize = pHead->len, .rowData = pHead->cont, .table = pTable}; - code = (*pTable->decodeFp)(&oper); - return sdbInsertHash(pTable, &oper); + SSdbRow row = {.rowSize = pHead->len, .rowData = pHead->cont, .pTable = pTable}; + code = (*pTable->fpDecode)(&row); + return sdbInsertHash(pTable, &row); } else if (action == SDB_ACTION_DELETE) { - void *pRow = sdbGetRowMeta(pTable, pHead->cont); - if (pRow == NULL) { - sdbDebug("table:%s, object:%s not exist in hash, ignore delete action", pTable->tableName, + void *pObj = sdbGetRowMeta(pTable, pHead->cont); + if (pObj == NULL) { + sdbDebug("vgId:1, sdb:%s, object:%s not exist in hash, ignore delete action", pTable->name, sdbGetKeyStr(pTable, pHead->cont)); return TSDB_CODE_SUCCESS; } - SSdbOper oper = {.table = pTable, .pObj = pRow}; - return sdbDeleteHash(pTable, &oper); + SSdbRow row = {.pTable = pTable, .pObj = pObj}; + return sdbDeleteHash(pTable, &row); } else if (action == SDB_ACTION_UPDATE) { - void *pRow = sdbGetRowMeta(pTable, pHead->cont); - if (pRow == NULL) { - sdbDebug("table:%s, object:%s not exist in hash, ignore update action", pTable->tableName, + void *pObj = sdbGetRowMeta(pTable, pHead->cont); + if (pObj == NULL) { + sdbDebug("vgId:1, sdb:%s, object:%s not exist in hash, ignore update action", pTable->name, sdbGetKeyStr(pTable, pHead->cont)); return TSDB_CODE_SUCCESS; } - SSdbOper oper = {.rowSize = pHead->len, .rowData = pHead->cont, .table = pTable}; - code = (*pTable->decodeFp)(&oper); - return sdbUpdateHash(pTable, &oper); + SSdbRow row = {.rowSize = pHead->len, .rowData = pHead->cont, .pTable = pTable}; + code = (*pTable->fpDecode)(&row); + return sdbUpdateHash(pTable, &row); } else { return TSDB_CODE_MND_INVALID_MSG_TYPE; } } -int32_t sdbInsertRow(SSdbOper *pOper) { - SSdbTable *pTable = (SSdbTable *)pOper->table; +int32_t sdbInsertRow(SSdbRow *pRow) { + SSdbTable *pTable = pRow->pTable; if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; - if (sdbGetRowFromObj(pTable, pOper->pObj)) { - sdbError("table:%s, failed to insert record:%s, already exist", pTable->tableName, - sdbGetKeyStrFromObj(pTable, pOper->pObj)); - sdbDecRef(pTable, pOper->pObj); + if (sdbGetRowFromObj(pTable, pRow->pObj)) { + sdbError("vgId:1, sdb:%s, failed to insert:%s since it exist", pTable->name, sdbGetRowStr(pTable, pRow->pObj)); + sdbDecRef(pTable, pRow->pObj); return TSDB_CODE_MND_SDB_OBJ_ALREADY_THERE; } if (pTable->keyType == SDB_KEY_AUTO) { - *((uint32_t *)pOper->pObj) = atomic_add_fetch_32(&pTable->autoIndex, 1); + *((uint32_t *)pRow->pObj) = atomic_add_fetch_32(&pTable->autoIndex, 1); // let vgId increase from 2 - if (pTable->autoIndex == 1 && strcmp(pTable->tableName, "vgroups") == 0) { - *((uint32_t *)pOper->pObj) = atomic_add_fetch_32(&pTable->autoIndex, 1); + if (pTable->autoIndex == 1 && pTable->id == SDB_TABLE_VGROUP) { + *((uint32_t *)pRow->pObj) = atomic_add_fetch_32(&pTable->autoIndex, 1); } } - int32_t code = sdbInsertHash(pTable, pOper); + int32_t code = sdbInsertHash(pTable, pRow); if (code != TSDB_CODE_SUCCESS) { - sdbError("table:%s, failed to insert into hash", pTable->tableName); + sdbError("vgId:1, sdb:%s, failed to insert:%s into hash", pTable->name, sdbGetRowStr(pTable, pRow->pObj)); return code; } // just insert data into memory - if (pOper->type != SDB_OPER_GLOBAL) { + if (pRow->type != SDB_OPER_GLOBAL) { return TSDB_CODE_SUCCESS; } - if (pOper->reqFp) { - return (*pOper->reqFp)(pOper->pMsg); + if (pRow->fpReq) { + return (*pRow->fpReq)(pRow->pMsg); } else { - return sdbInsertRowImp(pOper); - } -} - -int32_t sdbInsertRowImp(SSdbOper *pOper) { - SSdbTable *pTable = (SSdbTable *)pOper->table; - if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; - - int32_t size = sizeof(SSdbOper) + sizeof(SWalHead) + pTable->maxRowSize + SDB_SYNC_HACK; - SSdbOper *pNewOper = taosAllocateQitem(size); - - SWalHead *pHead = (void *)pNewOper + sizeof(SSdbOper) + SDB_SYNC_HACK; - pHead->version = 0; - pHead->len = pOper->rowSize; - pHead->msgType = pTable->tableId * 10 + SDB_ACTION_INSERT; - - pOper->rowData = pHead->cont; - (*pTable->encodeFp)(pOper); - pHead->len = pOper->rowSize; - - memcpy(pNewOper, pOper, sizeof(SSdbOper)); - - if (pNewOper->pMsg != NULL) { - sdbDebug("app:%p:%p, table:%s record:%p:%s, insert action is add to sdb queue", pNewOper->pMsg->rpcMsg.ahandle, - pNewOper->pMsg, pTable->tableName, pOper->pObj, sdbGetKeyStrFromObj(pTable, pOper->pObj)); + return sdbWriteRowToQueue(pRow, SDB_ACTION_INSERT); } - - sdbIncRef(pNewOper->table, pNewOper->pObj); - taosWriteQitem(tsSdbWriteQueue, TAOS_QTYPE_RPC, pNewOper); - - return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -bool sdbCheckRowDeleted(void *pTableInput, void *pRow) { - SSdbTable *pTable = pTableInput; +bool sdbCheckRowDeleted(void *tparam, void *pRow) { + SSdbTable *pTable = tparam; if (pTable == NULL) return false; int32_t *updateEnd = pRow + pTable->refCountPos - 4; return atomic_val_compare_exchange_32(updateEnd, 1, 1) == 1; } -int32_t sdbDeleteRow(SSdbOper *pOper) { - SSdbTable *pTable = (SSdbTable *)pOper->table; +int32_t sdbDeleteRow(SSdbRow *pRow) { + SSdbTable *pTable = pRow->pTable; if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; - void *pRow = sdbGetRowMetaFromObj(pTable, pOper->pObj); - if (pRow == NULL) { - sdbDebug("table:%s, record is not there, delete failed", pTable->tableName); + void *pObj = sdbGetRowMetaFromObj(pTable, pRow->pObj); + if (pObj == NULL) { + sdbDebug("vgId:1, sdb:%s, record is not there, delete failed", pTable->name); return TSDB_CODE_MND_SDB_OBJ_NOT_THERE; } - sdbIncRef(pTable, pOper->pObj); - - int32_t code = sdbDeleteHash(pTable, pOper); + int32_t code = sdbDeleteHash(pTable, pRow); if (code != TSDB_CODE_SUCCESS) { - sdbError("table:%s, failed to delete from hash", pTable->tableName); - sdbDecRef(pTable, pOper->pObj); + sdbError("vgId:1, sdb:%s, failed to delete from hash", pTable->name); return code; } // just delete data from memory - if (pOper->type != SDB_OPER_GLOBAL) { - sdbDecRef(pTable, pOper->pObj); + if (pRow->type != SDB_OPER_GLOBAL) { return TSDB_CODE_SUCCESS; } - if (pOper->reqFp) { - return (*pOper->reqFp)(pOper->pMsg); + if (pRow->fpReq) { + return (*pRow->fpReq)(pRow->pMsg); } else { - return sdbDeleteRowImp(pOper); - } -} - -int32_t sdbDeleteRowImp(SSdbOper *pOper) { - SSdbTable *pTable = (SSdbTable *)pOper->table; - if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; - - int32_t size = sizeof(SSdbOper) + sizeof(SWalHead) + pTable->maxRowSize + SDB_SYNC_HACK; - SSdbOper *pNewOper = taosAllocateQitem(size); - - SWalHead *pHead = (void *)pNewOper + sizeof(SSdbOper) + SDB_SYNC_HACK; - pHead->version = 0; - pHead->msgType = pTable->tableId * 10 + SDB_ACTION_DELETE; - - pOper->rowData = pHead->cont; - (*pTable->encodeFp)(pOper); - pHead->len = pOper->rowSize; - - memcpy(pNewOper, pOper, sizeof(SSdbOper)); - - if (pNewOper->pMsg != NULL) { - sdbDebug("app:%p:%p, table:%s record:%p:%s, delete action is add to sdb queue", pNewOper->pMsg->rpcMsg.ahandle, - pNewOper->pMsg, pTable->tableName, pOper->pObj, sdbGetKeyStrFromObj(pTable, pOper->pObj)); + return sdbWriteRowToQueue(pRow, SDB_ACTION_DELETE); } - - taosWriteQitem(tsSdbWriteQueue, TAOS_QTYPE_RPC, pNewOper); - - return TSDB_CODE_MND_ACTION_IN_PROGRESS; } -int32_t sdbUpdateRow(SSdbOper *pOper) { - SSdbTable *pTable = (SSdbTable *)pOper->table; +int32_t sdbUpdateRow(SSdbRow *pRow) { + SSdbTable *pTable = pRow->pTable; if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; - void *pRow = sdbGetRowMetaFromObj(pTable, pOper->pObj); - if (pRow == NULL) { - sdbDebug("table:%s, record is not there, update failed", pTable->tableName); + void *pObj = sdbGetRowMetaFromObj(pTable, pRow->pObj); + if (pObj == NULL) { + sdbDebug("vgId:1, sdb:%s, record is not there, update failed", pTable->name); return TSDB_CODE_MND_SDB_OBJ_NOT_THERE; } - int32_t code = sdbUpdateHash(pTable, pOper); + int32_t code = sdbUpdateHash(pTable, pRow); if (code != TSDB_CODE_SUCCESS) { - sdbError("table:%s, failed to update hash", pTable->tableName); + sdbError("vgId:1, sdb:%s, failed to update hash", pTable->name); return code; } // just update data in memory - if (pOper->type != SDB_OPER_GLOBAL) { + if (pRow->type != SDB_OPER_GLOBAL) { return TSDB_CODE_SUCCESS; } - if (pOper->reqFp) { - return (*pOper->reqFp)(pOper->pMsg); + if (pRow->fpReq) { + return (*pRow->fpReq)(pRow->pMsg); } else { - return sdbUpdateRowImp(pOper); + return sdbWriteRowToQueue(pRow, SDB_ACTION_UPDATE); } } -int32_t sdbUpdateRowImp(SSdbOper *pOper) { - SSdbTable *pTable = (SSdbTable *)pOper->table; - if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; - - int32_t size = sizeof(SSdbOper) + sizeof(SWalHead) + pTable->maxRowSize + SDB_SYNC_HACK; - SSdbOper *pNewOper = taosAllocateQitem(size); - - SWalHead *pHead = (void *)pNewOper + sizeof(SSdbOper) + SDB_SYNC_HACK; - pHead->version = 0; - pHead->msgType = pTable->tableId * 10 + SDB_ACTION_UPDATE; - - pOper->rowData = pHead->cont; - (*pTable->encodeFp)(pOper); - pHead->len = pOper->rowSize; - - memcpy(pNewOper, pOper, sizeof(SSdbOper)); - - if (pNewOper->pMsg != NULL) { - sdbDebug("app:%p:%p, table:%s record:%p:%s, update action is add to sdb queue", pNewOper->pMsg->rpcMsg.ahandle, - pNewOper->pMsg, pTable->tableName, pOper->pObj, sdbGetKeyStrFromObj(pTable, pOper->pObj)); - } - - sdbIncRef(pNewOper->table, pNewOper->pObj); - taosWriteQitem(tsSdbWriteQueue, TAOS_QTYPE_RPC, pNewOper); - - return TSDB_CODE_MND_ACTION_IN_PROGRESS; -} - -void *sdbFetchRow(void *handle, void *pNode, void **ppRow) { - SSdbTable *pTable = (SSdbTable *)handle; +void *sdbFetchRow(void *tparam, void *pNode, void **ppRow) { + SSdbTable *pTable = tparam; *ppRow = NULL; if (pTable == NULL) return NULL; @@ -882,7 +777,7 @@ void *sdbFetchRow(void *handle, void *pNode, void **ppRow) { } *ppRow = *ppMetaRow; - sdbIncRef(handle, *ppMetaRow); + sdbIncRef(pTable, *ppMetaRow); return pIter; } @@ -899,28 +794,28 @@ void *sdbOpenTable(SSdbTableDesc *pDesc) { if (pTable == NULL) return NULL; pthread_mutex_init(&pTable->mutex, NULL); - tstrncpy(pTable->tableName, pDesc->tableName, SDB_TABLE_LEN); + tstrncpy(pTable->name, pDesc->name, SDB_TABLE_LEN); pTable->keyType = pDesc->keyType; - pTable->tableId = pDesc->tableId; + pTable->id = pDesc->id; pTable->hashSessions = pDesc->hashSessions; pTable->maxRowSize = pDesc->maxRowSize; pTable->refCountPos = pDesc->refCountPos; - pTable->insertFp = pDesc->insertFp; - pTable->deleteFp = pDesc->deleteFp; - pTable->updateFp = pDesc->updateFp; - pTable->encodeFp = pDesc->encodeFp; - pTable->decodeFp = pDesc->decodeFp; - pTable->destroyFp = pDesc->destroyFp; - pTable->restoredFp = pDesc->restoredFp; + pTable->fpInsert = pDesc->fpInsert; + pTable->fpDelete = pDesc->fpDelete; + pTable->fpUpdate = pDesc->fpUpdate; + pTable->fpEncode = pDesc->fpEncode; + pTable->fpDecode = pDesc->fpDecode; + pTable->fpDestroy = pDesc->fpDestroy; + pTable->fpRestored = pDesc->fpRestored; _hash_fn_t hashFp = taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT); if (pTable->keyType == SDB_KEY_STRING || pTable->keyType == SDB_KEY_VAR_STRING) { hashFp = taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY); } - pTable->iHandle = taosHashInit(pTable->hashSessions, hashFp, true, true); + pTable->iHandle = taosHashInit(pTable->hashSessions, hashFp, true, HASH_ENTRY_LOCK); - tsSdbObj.numOfTables++; - tsSdbObj.tableList[pTable->tableId] = pTable; + tsSdbMgmt.numOfTables++; + tsSdbMgmt.tableList[pTable->id] = pTable; return pTable; } @@ -928,87 +823,87 @@ void sdbCloseTable(void *handle) { SSdbTable *pTable = (SSdbTable *)handle; if (pTable == NULL) return; - tsSdbObj.numOfTables--; - tsSdbObj.tableList[pTable->tableId] = NULL; + tsSdbMgmt.numOfTables--; + tsSdbMgmt.tableList[pTable->id] = NULL; SHashMutableIterator *pIter = taosHashCreateIter(pTable->iHandle); while (taosHashIterNext(pIter)) { void **ppRow = taosHashIterGet(pIter); if (ppRow == NULL) continue; - SSdbOper oper = { + SSdbRow row = { .pObj = *ppRow, - .table = pTable, + .pTable = pTable, }; - (*pTable->destroyFp)(&oper); + (*pTable->fpDestroy)(&row); } taosHashDestroyIter(pIter); taosHashCleanup(pTable->iHandle); pthread_mutex_destroy(&pTable->mutex); - sdbDebug("table:%s, is closed, numOfTables:%d", pTable->tableName, tsSdbObj.numOfTables); + sdbDebug("vgId:1, sdb:%s, is closed, numOfTables:%d", pTable->name, tsSdbMgmt.numOfTables); free(pTable); } -int32_t sdbInitWriteWorker() { +static int32_t sdbInitWorker() { tsSdbPool.num = 1; - tsSdbPool.writeWorker = (SSdbWriteWorker *)calloc(sizeof(SSdbWriteWorker), tsSdbPool.num); + tsSdbPool.worker = calloc(sizeof(SSdbWorker), tsSdbPool.num); - if (tsSdbPool.writeWorker == NULL) return -1; + if (tsSdbPool.worker == NULL) return -1; for (int32_t i = 0; i < tsSdbPool.num; ++i) { - SSdbWriteWorker *pWorker = tsSdbPool.writeWorker + i; + SSdbWorker *pWorker = tsSdbPool.worker + i; pWorker->workerId = i; } - sdbAllocWriteQueue(); + sdbAllocQueue(); - mInfo("sdb write is opened"); + mInfo("vgId:1, sdb write is opened"); return 0; } -void sdbCleanupWriteWorker() { +static void sdbCleanupWorker() { for (int32_t i = 0; i < tsSdbPool.num; ++i) { - SSdbWriteWorker *pWorker = tsSdbPool.writeWorker + i; + SSdbWorker *pWorker = tsSdbPool.worker + i; if (pWorker->thread) { - taosQsetThreadResume(tsSdbWriteQset); + taosQsetThreadResume(tsSdbWQset); } } for (int32_t i = 0; i < tsSdbPool.num; ++i) { - SSdbWriteWorker *pWorker = tsSdbPool.writeWorker + i; + SSdbWorker *pWorker = tsSdbPool.worker + i; if (pWorker->thread) { pthread_join(pWorker->thread, NULL); } } - sdbFreeWritequeue(); - tfree(tsSdbPool.writeWorker); + sdbFreeQueue(); + tfree(tsSdbPool.worker); - mInfo("sdb write is closed"); + mInfo("vgId:1, sdb write is closed"); } -int32_t sdbAllocWriteQueue() { - tsSdbWriteQueue = taosOpenQueue(); - if (tsSdbWriteQueue == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; +static int32_t sdbAllocQueue() { + tsSdbWQueue = taosOpenQueue(); + if (tsSdbWQueue == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - tsSdbWriteQset = taosOpenQset(); - if (tsSdbWriteQset == NULL) { - taosCloseQueue(tsSdbWriteQueue); + tsSdbWQset = taosOpenQset(); + if (tsSdbWQset == NULL) { + taosCloseQueue(tsSdbWQueue); return TSDB_CODE_MND_OUT_OF_MEMORY; } - taosAddIntoQset(tsSdbWriteQset, tsSdbWriteQueue, NULL); + taosAddIntoQset(tsSdbWQset, tsSdbWQueue, NULL); - tsSdbWriteQall = taosAllocateQall(); - if (tsSdbWriteQall == NULL) { - taosCloseQset(tsSdbWriteQset); - taosCloseQueue(tsSdbWriteQueue); + tsSdbWQall = taosAllocateQall(); + if (tsSdbWQall == NULL) { + taosCloseQset(tsSdbWQset); + taosCloseQueue(tsSdbWQueue); return TSDB_CODE_MND_OUT_OF_MEMORY; } for (int32_t i = 0; i < tsSdbPool.num; ++i) { - SSdbWriteWorker *pWorker = tsSdbPool.writeWorker + i; + SSdbWorker *pWorker = tsSdbPool.worker + i; pWorker->workerId = i; pthread_attr_t thAttr; @@ -1017,9 +912,9 @@ int32_t sdbAllocWriteQueue() { if (pthread_create(&pWorker->thread, &thAttr, sdbWorkerFp, pWorker) != 0) { mError("failed to create thread to process sdb write queue, reason:%s", strerror(errno)); - taosFreeQall(tsSdbWriteQall); - taosCloseQset(tsSdbWriteQset); - taosCloseQueue(tsSdbWriteQueue); + taosFreeQall(tsSdbWQall); + taosCloseQset(tsSdbWQset); + taosCloseQueue(tsSdbWQueue); return TSDB_CODE_MND_OUT_OF_MEMORY; } @@ -1027,85 +922,128 @@ int32_t sdbAllocWriteQueue() { mDebug("sdb write worker:%d is launched, total:%d", pWorker->workerId, tsSdbPool.num); } - mDebug("sdb write queue:%p is allocated", tsSdbWriteQueue); + mDebug("sdb write queue:%p is allocated", tsSdbWQueue); return TSDB_CODE_SUCCESS; } -void sdbFreeWritequeue() { - taosCloseQueue(tsSdbWriteQueue); - taosFreeQall(tsSdbWriteQall); - taosCloseQset(tsSdbWriteQset); - tsSdbWriteQall = NULL; - tsSdbWriteQset = NULL; - tsSdbWriteQueue = NULL; +static void sdbFreeQueue() { + taosCloseQueue(tsSdbWQueue); + taosFreeQall(tsSdbWQall); + taosCloseQset(tsSdbWQset); + tsSdbWQall = NULL; + tsSdbWQset = NULL; + tsSdbWQueue = NULL; } -int32_t sdbWriteToQueue(void *param, void *data, int32_t qtype, void *pMsg) { - SWalHead *pHead = data; - int32_t size = sizeof(SWalHead) + pHead->len; - SWalHead *pWal = taosAllocateQitem(size); - memcpy(pWal, pHead, size); +static int32_t sdbWriteToQueue(SSdbRow *pRow, int32_t qtype) { + SWalHead *pHead = pRow->pHead; - taosWriteQitem(tsSdbWriteQueue, qtype, pWal); - return 0; + if (pHead->len > TSDB_MAX_WAL_SIZE) { + sdbError("vgId:1, wal len:%d exceeds limit, hver:%" PRIu64, pHead->len, pHead->version); + taosFreeQitem(pRow); + return TSDB_CODE_WAL_SIZE_LIMIT; + } + + int32_t queued = atomic_add_fetch_32(&tsSdbMgmt.queuedMsg, 1); + if (queued > MAX_QUEUED_MSG_NUM) { + sdbDebug("vgId:1, too many msg:%d in sdb queue, flow control", queued); + taosMsleep(1); + } + + sdbIncRef(pRow->pTable, pRow->pObj); + + sdbTrace("vgId:1, msg:%p qtype:%s write into to sdb queue, queued:%d", pRow->pMsg, qtypeStr[qtype], queued); + taosWriteQitem(tsSdbWQueue, qtype, pRow); + + return TSDB_CODE_MND_ACTION_IN_PROGRESS; +} + +static void sdbFreeFromQueue(SSdbRow *pRow) { + int32_t queued = atomic_sub_fetch_32(&tsSdbMgmt.queuedMsg, 1); + sdbTrace("vgId:1, msg:%p free from sdb queue, queued:%d", pRow->pMsg, queued); + + sdbDecRef(pRow->pTable, pRow->pObj); + taosFreeQitem(pRow); } -static void *sdbWorkerFp(void *param) { - SWalHead *pHead; - SSdbOper *pOper; - int32_t type; - int32_t numOfMsgs; - void * item; - void * unUsed; +static int32_t sdbWriteWalToQueue(int32_t vgId, void *wparam, int32_t qtype, void *rparam) { + SWalHead *pHead = wparam; + + int32_t size = sizeof(SSdbRow) + sizeof(SWalHead) + pHead->len; + SSdbRow *pRow = taosAllocateQitem(size); + if (pRow == NULL) { + return TSDB_CODE_VND_OUT_OF_MEMORY; + } + + memcpy(pRow->pHead, pHead, sizeof(SWalHead) + pHead->len); + pRow->rowData = pRow->pHead->cont; + + return sdbWriteToQueue(pRow, qtype); +} + +static int32_t sdbWriteRowToQueue(SSdbRow *pInputRow, int32_t action) { + SSdbTable *pTable = pInputRow->pTable; + if (pTable == NULL) return TSDB_CODE_MND_SDB_INVALID_TABLE_TYPE; + + int32_t size = sizeof(SSdbRow) + sizeof(SWalHead) + pTable->maxRowSize; + SSdbRow *pRow = taosAllocateQitem(size); + if (pRow == NULL) { + return TSDB_CODE_VND_OUT_OF_MEMORY; + } + + memcpy(pRow, pInputRow, sizeof(SSdbRow)); + pRow->processedCount = 1; + + SWalHead *pHead = pRow->pHead; + pRow->rowData = pHead->cont; + (*pTable->fpEncode)(pRow); + + pHead->len = pRow->rowSize; + pHead->version = 0; + pHead->msgType = pTable->id * 10 + action; + + return sdbWriteToQueue(pRow, TAOS_QTYPE_RPC); +} + +int32_t sdbInsertRowToQueue(SSdbRow *pRow) { return sdbWriteRowToQueue(pRow, SDB_ACTION_INSERT); } + +static void *sdbWorkerFp(void *pWorker) { + SSdbRow *pRow; + int32_t qtype; + void * unUsed; while (1) { - numOfMsgs = taosReadAllQitemsFromQset(tsSdbWriteQset, tsSdbWriteQall, &unUsed); + int32_t numOfMsgs = taosReadAllQitemsFromQset(tsSdbWQset, tsSdbWQall, &unUsed); if (numOfMsgs == 0) { - sdbDebug("qset:%p, sdb got no message from qset, exiting", tsSdbWriteQset); + sdbDebug("qset:%p, sdb got no message from qset, exiting", tsSdbWQset); break; } for (int32_t i = 0; i < numOfMsgs; ++i) { - taosGetQitem(tsSdbWriteQall, &type, &item); - if (type == TAOS_QTYPE_RPC) { - pOper = (SSdbOper *)item; - pOper->processedCount = 1; - pHead = (void *)pOper + sizeof(SSdbOper) + SDB_SYNC_HACK; - if (pOper->pMsg != NULL) { - sdbDebug("app:%p:%p, table:%s record:%p:%s ver:%" PRIu64 ", will be processed in sdb queue", - pOper->pMsg->rpcMsg.ahandle, pOper->pMsg, ((SSdbTable *)pOper->table)->tableName, pOper->pObj, - sdbGetKeyStr(pOper->table, pHead->cont), pHead->version); - } - } else { - pHead = (SWalHead *)item; - pOper = NULL; - } + taosGetQitem(tsSdbWQall, &qtype, (void **)&pRow); + sdbTrace("vgId:1, msg:%p, row:%p hver:%" PRIu64 ", will be processed in sdb queue", pRow->pMsg, pRow->pObj, + pRow->pHead->version); - int32_t code = sdbWrite(pOper, pHead, type, NULL); - if (code > 0) code = 0; - if (pOper) { - pOper->retCode = code; - } else { - pHead->len = code; // hackway - } + pRow->code = sdbProcessWrite((qtype == TAOS_QTYPE_RPC) ? pRow : NULL, pRow->pHead, qtype, NULL); + if (pRow->code > 0) pRow->code = 0; + + sdbTrace("vgId:1, msg:%p is processed in sdb queue, code:%x", pRow->pMsg, pRow->code); } - walFsync(tsSdbObj.wal, true); + walFsync(tsSdbMgmt.wal, true); // browse all items, and process them one by one - taosResetQitems(tsSdbWriteQall); + taosResetQitems(tsSdbWQall); for (int32_t i = 0; i < numOfMsgs; ++i) { - taosGetQitem(tsSdbWriteQall, &type, &item); - - if (type == TAOS_QTYPE_RPC) { - pOper = (SSdbOper *)item; - sdbConfirmForward(NULL, pOper, pOper->retCode); - } else if (type == TAOS_QTYPE_FWD) { - pHead = (SWalHead *)item; - syncConfirmForward(tsSdbObj.sync, pHead->version, pHead->len); - taosFreeQitem(item); + taosGetQitem(tsSdbWQall, &qtype, (void **)&pRow); + + if (qtype == TAOS_QTYPE_RPC) { + sdbConfirmForward(1, pRow, pRow->code); } else { - taosFreeQitem(item); + if (qtype == TAOS_QTYPE_FWD) { + syncConfirmForward(tsSdbMgmt.sync, pRow->pHead->version, pRow->code); + } + sdbFreeFromQueue(pRow); } } } diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index 2b5e6455c0ec731d0697f2b8f6b638a1ce139788..d0a5402986fcc9d24d3c8dce4e07e87af9a2061a 100644 --- a/src/mnode/src/mnodeTable.c +++ b/src/mnode/src/mnodeTable.c @@ -99,13 +99,13 @@ static void mnodeDestroyChildTable(SCTableObj *pTable) { tfree(pTable); } -static int32_t mnodeChildTableActionDestroy(SSdbOper *pOper) { - mnodeDestroyChildTable(pOper->pObj); +static int32_t mnodeChildTableActionDestroy(SSdbRow *pRow) { + mnodeDestroyChildTable(pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t mnodeChildTableActionInsert(SSdbOper *pOper) { - SCTableObj *pTable = pOper->pObj; +static int32_t mnodeChildTableActionInsert(SSdbRow *pRow) { + SCTableObj *pTable = pRow->pObj; SVgObj *pVgroup = mnodeGetVgroup(pTable->vgId); if (pVgroup == NULL) { @@ -153,8 +153,8 @@ static int32_t mnodeChildTableActionInsert(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeChildTableActionDelete(SSdbOper *pOper) { - SCTableObj *pTable = pOper->pObj; +static int32_t mnodeChildTableActionDelete(SSdbRow *pRow) { + SCTableObj *pTable = pRow->pObj; if (pTable->vgId == 0) { return TSDB_CODE_MND_VGROUP_NOT_EXIST; } @@ -189,8 +189,8 @@ static int32_t mnodeChildTableActionDelete(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeChildTableActionUpdate(SSdbOper *pOper) { - SCTableObj *pNew = pOper->pObj; +static int32_t mnodeChildTableActionUpdate(SSdbRow *pRow) { + SCTableObj *pNew = pRow->pObj; SCTableObj *pTable = mnodeGetChildTable(pNew->info.tableId); if (pTable != pNew) { void *oldTableId = pTable->info.tableId; @@ -216,50 +216,50 @@ static int32_t mnodeChildTableActionUpdate(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeChildTableActionEncode(SSdbOper *pOper) { - SCTableObj *pTable = pOper->pObj; - assert(pTable != NULL && pOper->rowData != NULL); +static int32_t mnodeChildTableActionEncode(SSdbRow *pRow) { + SCTableObj *pTable = pRow->pObj; + assert(pTable != NULL && pRow->rowData != NULL); int32_t len = strlen(pTable->info.tableId); if (len >= TSDB_TABLE_FNAME_LEN) return TSDB_CODE_MND_INVALID_TABLE_ID; - memcpy(pOper->rowData, pTable->info.tableId, len); - memset(pOper->rowData + len, 0, 1); + memcpy(pRow->rowData, pTable->info.tableId, len); + memset(pRow->rowData + len, 0, 1); len++; - memcpy(pOper->rowData + len, (char*)pTable + sizeof(char *), tsChildTableUpdateSize); + memcpy(pRow->rowData + len, (char*)pTable + sizeof(char *), tsChildTableUpdateSize); len += tsChildTableUpdateSize; if (pTable->info.type != TSDB_CHILD_TABLE) { int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - memcpy(pOper->rowData + len, pTable->schema, schemaSize); + memcpy(pRow->rowData + len, pTable->schema, schemaSize); len += schemaSize; if (pTable->sqlLen != 0) { - memcpy(pOper->rowData + len, pTable->sql, pTable->sqlLen); + memcpy(pRow->rowData + len, pTable->sql, pTable->sqlLen); len += pTable->sqlLen; } } - pOper->rowSize = len; + pRow->rowSize = len; return TSDB_CODE_SUCCESS; } -static int32_t mnodeChildTableActionDecode(SSdbOper *pOper) { - assert(pOper->rowData != NULL); +static int32_t mnodeChildTableActionDecode(SSdbRow *pRow) { + assert(pRow->rowData != NULL); SCTableObj *pTable = calloc(1, sizeof(SCTableObj)); if (pTable == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - int32_t len = strlen(pOper->rowData); + int32_t len = strlen(pRow->rowData); if (len >= TSDB_TABLE_FNAME_LEN) { free(pTable); return TSDB_CODE_MND_INVALID_TABLE_ID; } - pTable->info.tableId = strdup(pOper->rowData); + pTable->info.tableId = strdup(pRow->rowData); len++; - memcpy((char*)pTable + sizeof(char *), pOper->rowData + len, tsChildTableUpdateSize); + memcpy((char*)pTable + sizeof(char *), pRow->rowData + len, tsChildTableUpdateSize); len += tsChildTableUpdateSize; if (pTable->info.type != TSDB_CHILD_TABLE) { @@ -269,7 +269,7 @@ static int32_t mnodeChildTableActionDecode(SSdbOper *pOper) { mnodeDestroyChildTable(pTable); return TSDB_CODE_MND_INVALID_TABLE_TYPE; } - memcpy(pTable->schema, pOper->rowData + len, schemaSize); + memcpy(pTable->schema, pRow->rowData + len, schemaSize); len += schemaSize; if (pTable->sqlLen != 0) { @@ -278,11 +278,11 @@ static int32_t mnodeChildTableActionDecode(SSdbOper *pOper) { mnodeDestroyChildTable(pTable); return TSDB_CODE_MND_OUT_OF_MEMORY; } - memcpy(pTable->sql, pOper->rowData + len, pTable->sqlLen); + memcpy(pTable->sql, pRow->rowData + len, pTable->sqlLen); } } - pOper->pObj = pTable; + pRow->pObj = pTable; return TSDB_CODE_SUCCESS; } @@ -297,7 +297,7 @@ static int32_t mnodeChildTableActionRestored() { SDbObj *pDb = mnodeGetDbByTableId(pTable->info.tableId); if (pDb == NULL || pDb->status != TSDB_DB_STATUS_READY) { mError("ctable:%s, failed to get db or db in dropping, discard it", pTable->info.tableId); - SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb}; + SSdbRow desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .pTable = tsChildTableSdb}; sdbDeleteRow(&desc); mnodeDecTableRef(pTable); mnodeDecDbRef(pDb); @@ -309,7 +309,7 @@ static int32_t mnodeChildTableActionRestored() { if (pVgroup == NULL) { mError("ctable:%s, failed to get vgId:%d tid:%d, discard it", pTable->info.tableId, pTable->vgId, pTable->tid); pTable->vgId = 0; - SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb}; + SSdbRow desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .pTable = tsChildTableSdb}; sdbDeleteRow(&desc); mnodeDecTableRef(pTable); continue; @@ -320,7 +320,7 @@ static int32_t mnodeChildTableActionRestored() { mError("ctable:%s, db:%s not match with vgId:%d db:%s sid:%d, discard it", pTable->info.tableId, pDb->name, pTable->vgId, pVgroup->dbName, pTable->tid); pTable->vgId = 0; - SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb}; + SSdbRow desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .pTable = tsChildTableSdb}; sdbDeleteRow(&desc); mnodeDecTableRef(pTable); continue; @@ -331,7 +331,7 @@ static int32_t mnodeChildTableActionRestored() { if (pSuperTable == NULL) { mError("ctable:%s, stable:%" PRIu64 " not exist", pTable->info.tableId, pTable->suid); pTable->vgId = 0; - SSdbOper desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .table = tsChildTableSdb}; + SSdbRow desc = {.type = SDB_OPER_LOCAL, .pObj = pTable, .pTable = tsChildTableSdb}; sdbDeleteRow(&desc); mnodeDecTableRef(pTable); continue; @@ -352,19 +352,19 @@ static int32_t mnodeInitChildTables() { tsChildTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj.info.type; SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_CTABLE, - .tableName = "ctables", + .id = SDB_TABLE_CTABLE, + .name = "ctables", .hashSessions = TSDB_DEFAULT_CTABLES_HASH_SIZE, .maxRowSize = sizeof(SCTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_FNAME_LEN + TSDB_CQ_SQL_SIZE, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_VAR_STRING, - .insertFp = mnodeChildTableActionInsert, - .deleteFp = mnodeChildTableActionDelete, - .updateFp = mnodeChildTableActionUpdate, - .encodeFp = mnodeChildTableActionEncode, - .decodeFp = mnodeChildTableActionDecode, - .destroyFp = mnodeChildTableActionDestroy, - .restoredFp = mnodeChildTableActionRestored + .fpInsert = mnodeChildTableActionInsert, + .fpDelete = mnodeChildTableActionDelete, + .fpUpdate = mnodeChildTableActionUpdate, + .fpEncode = mnodeChildTableActionEncode, + .fpDecode = mnodeChildTableActionDecode, + .fpDestroy = mnodeChildTableActionDestroy, + .fpRestored = mnodeChildTableActionRestored }; tsChildTableSdb = sdbOpenTable(&tableDesc); @@ -394,7 +394,7 @@ static void mnodeAddTableIntoStable(SSTableObj *pStable, SCTableObj *pCtable) { atomic_add_fetch_32(&pStable->numOfTables, 1); if (pStable->vgHash == NULL) { - pStable->vgHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, false); + pStable->vgHash = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_NO_LOCK); } if (pStable->vgHash != NULL) { @@ -413,7 +413,7 @@ static void mnodeRemoveTableFromStable(SSTableObj *pStable, SCTableObj *pCtable) SVgObj *pVgroup = mnodeGetVgroup(pCtable->vgId); if (pVgroup == NULL) { - taosHashRemove(pStable->vgHash, (char *)&pCtable->vgId, sizeof(pCtable->vgId)); + taosHashRemove(pStable->vgHash, &pCtable->vgId, sizeof(pCtable->vgId)); mDebug("table:%s, vgId:%d is remove from stable vgList, sizeOfVgList:%d", pStable->info.tableId, pCtable->vgId, (int32_t)taosHashGetSize(pStable->vgHash)); } @@ -430,13 +430,13 @@ static void mnodeDestroySuperTable(SSTableObj *pStable) { tfree(pStable); } -static int32_t mnodeSuperTableActionDestroy(SSdbOper *pOper) { - mnodeDestroySuperTable(pOper->pObj); +static int32_t mnodeSuperTableActionDestroy(SSdbRow *pRow) { + mnodeDestroySuperTable(pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t mnodeSuperTableActionInsert(SSdbOper *pOper) { - SSTableObj *pStable = pOper->pObj; +static int32_t mnodeSuperTableActionInsert(SSdbRow *pRow) { + SSTableObj *pStable = pRow->pObj; SDbObj *pDb = mnodeGetDbByTableId(pStable->info.tableId); if (pDb != NULL && pDb->status == TSDB_DB_STATUS_READY) { mnodeAddSuperTableIntoDb(pDb); @@ -446,8 +446,8 @@ static int32_t mnodeSuperTableActionInsert(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeSuperTableActionDelete(SSdbOper *pOper) { - SSTableObj *pStable = pOper->pObj; +static int32_t mnodeSuperTableActionDelete(SSdbRow *pRow) { + SSTableObj *pStable = pRow->pObj; SDbObj *pDb = mnodeGetDbByTableId(pStable->info.tableId); if (pDb != NULL) { mnodeRemoveSuperTableFromDb(pDb); @@ -458,8 +458,8 @@ static int32_t mnodeSuperTableActionDelete(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeSuperTableActionUpdate(SSdbOper *pOper) { - SSTableObj *pNew = pOper->pObj; +static int32_t mnodeSuperTableActionUpdate(SSdbRow *pRow) { + SSTableObj *pNew = pRow->pObj; SSTableObj *pTable = mnodeGetSuperTable(pNew->info.tableId); if (pTable != NULL && pTable != pNew) { void *oldTableId = pTable->info.tableId; @@ -483,43 +483,43 @@ static int32_t mnodeSuperTableActionUpdate(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeSuperTableActionEncode(SSdbOper *pOper) { - SSTableObj *pStable = pOper->pObj; - assert(pOper->pObj != NULL && pOper->rowData != NULL); +static int32_t mnodeSuperTableActionEncode(SSdbRow *pRow) { + SSTableObj *pStable = pRow->pObj; + assert(pRow->pObj != NULL && pRow->rowData != NULL); int32_t len = strlen(pStable->info.tableId); if (len >= TSDB_TABLE_FNAME_LEN) len = TSDB_CODE_MND_INVALID_TABLE_ID; - memcpy(pOper->rowData, pStable->info.tableId, len); - memset(pOper->rowData + len, 0, 1); + memcpy(pRow->rowData, pStable->info.tableId, len); + memset(pRow->rowData + len, 0, 1); len++; - memcpy(pOper->rowData + len, (char*)pStable + sizeof(char *), tsSuperTableUpdateSize); + memcpy(pRow->rowData + len, (char*)pStable + sizeof(char *), tsSuperTableUpdateSize); len += tsSuperTableUpdateSize; int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags); - memcpy(pOper->rowData + len, pStable->schema, schemaSize); + memcpy(pRow->rowData + len, pStable->schema, schemaSize); len += schemaSize; - pOper->rowSize = len; + pRow->rowSize = len; return TSDB_CODE_SUCCESS; } -static int32_t mnodeSuperTableActionDecode(SSdbOper *pOper) { - assert(pOper->rowData != NULL); +static int32_t mnodeSuperTableActionDecode(SSdbRow *pRow) { + assert(pRow->rowData != NULL); SSTableObj *pStable = (SSTableObj *) calloc(1, sizeof(SSTableObj)); if (pStable == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - int32_t len = strlen(pOper->rowData); + int32_t len = strlen(pRow->rowData); if (len >= TSDB_TABLE_FNAME_LEN){ free(pStable); return TSDB_CODE_MND_INVALID_TABLE_ID; } - pStable->info.tableId = strdup(pOper->rowData); + pStable->info.tableId = strdup(pRow->rowData); len++; - memcpy((char*)pStable + sizeof(char *), pOper->rowData + len, tsSuperTableUpdateSize); + memcpy((char*)pStable + sizeof(char *), pRow->rowData + len, tsSuperTableUpdateSize); len += tsSuperTableUpdateSize; int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags); @@ -529,9 +529,9 @@ static int32_t mnodeSuperTableActionDecode(SSdbOper *pOper) { return TSDB_CODE_MND_NOT_SUPER_TABLE; } - memcpy(pStable->schema, pOper->rowData + len, schemaSize); + memcpy(pStable->schema, pRow->rowData + len, schemaSize); - pOper->pObj = pStable; + pRow->pObj = pStable; return TSDB_CODE_SUCCESS; } @@ -545,19 +545,19 @@ static int32_t mnodeInitSuperTables() { tsSuperTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj.info.type; SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_STABLE, - .tableName = "stables", + .id = SDB_TABLE_STABLE, + .name = "stables", .hashSessions = TSDB_DEFAULT_STABLES_HASH_SIZE, .maxRowSize = sizeof(SSTableObj) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16) + TSDB_TABLE_FNAME_LEN, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_VAR_STRING, - .insertFp = mnodeSuperTableActionInsert, - .deleteFp = mnodeSuperTableActionDelete, - .updateFp = mnodeSuperTableActionUpdate, - .encodeFp = mnodeSuperTableActionEncode, - .decodeFp = mnodeSuperTableActionDecode, - .destroyFp = mnodeSuperTableActionDestroy, - .restoredFp = mnodeSuperTableActionRestored + .fpInsert = mnodeSuperTableActionInsert, + .fpDelete = mnodeSuperTableActionDelete, + .fpUpdate = mnodeSuperTableActionUpdate, + .fpEncode = mnodeSuperTableActionEncode, + .fpDecode = mnodeSuperTableActionDecode, + .fpDestroy = mnodeSuperTableActionDestroy, + .fpRestored = mnodeSuperTableActionRestored }; tsSuperTableSdb = sdbOpenTable(&tableDesc); @@ -703,7 +703,7 @@ static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *pMsg) { if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDb(pCreate->db); if (pMsg->pDb == NULL) { - mError("app:%p:%p, table:%s, failed to create, db not selected", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId); + mError("msg:%p, app:%p table:%s, failed to create, db not selected", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return TSDB_CODE_MND_DB_NOT_SELECTED; } @@ -715,24 +715,24 @@ static int32_t mnodeProcessCreateTableMsg(SMnodeMsg *pMsg) { if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pCreate->tableId); if (pMsg->pTable != NULL && pMsg->retry == 0) { if (pCreate->getMeta) { - mDebug("app:%p:%p, table:%s, continue to get meta", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId); + mDebug("msg:%p, app:%p table:%s, continue to get meta", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return mnodeGetChildTableMeta(pMsg); } else if (pCreate->igExists) { - mDebug("app:%p:%p, table:%s, is already exist", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId); + mDebug("msg:%p, app:%p table:%s, is already exist", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return TSDB_CODE_SUCCESS; } else { - mError("app:%p:%p, table:%s, failed to create, table already exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, failed to create, table already exist", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return TSDB_CODE_MND_TABLE_ALREADY_EXIST; } } if (pCreate->numOfTags != 0) { - mDebug("app:%p:%p, table:%s, create stable msg is received from thandle:%p", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, create stable msg is received from thandle:%p", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId, pMsg->rpcMsg.handle); return mnodeProcessCreateSuperTableMsg(pMsg); } else { - mDebug("app:%p:%p, table:%s, create ctable msg is received from thandle:%p", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, create ctable msg is received from thandle:%p", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId, pMsg->rpcMsg.handle); return mnodeProcessCreateChildTableMsg(pMsg); } @@ -742,17 +742,18 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) { SCMDropTableMsg *pDrop = pMsg->rpcMsg.pCont; if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableId(pDrop->tableId); if (pMsg->pDb == NULL) { - mError("app:%p:%p, table:%s, failed to drop table, db not selected or db in dropping", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId); + mError("msg:%p, app:%p table:%s, failed to drop table, db not selected or db in dropping", pMsg, + pMsg->rpcMsg.ahandle, pDrop->tableId); return TSDB_CODE_MND_DB_NOT_SELECTED; } - + if (pMsg->pDb->status != TSDB_DB_STATUS_READY) { mError("db:%s, status:%d, in dropping", pMsg->pDb->name, pMsg->pDb->status); return TSDB_CODE_MND_DB_IN_DROPPING; } if (mnodeCheckIsMonitorDB(pMsg->pDb->name, tsMonitorDbName)) { - mError("app:%p:%p, table:%s, failed to drop table, in monitor database", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, failed to drop table, in monitor database", pMsg, pMsg->rpcMsg.ahandle, pDrop->tableId); return TSDB_CODE_MND_MONITOR_DB_FORBIDDEN; } @@ -760,22 +761,22 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) { if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pDrop->tableId); if (pMsg->pTable == NULL) { if (pDrop->igNotExists) { - mDebug("app:%p:%p, table:%s, table is not exist, treat as success", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId); + mDebug("msg:%p, app:%p table:%s is not exist, treat as success", pMsg, pMsg->rpcMsg.ahandle, pDrop->tableId); return TSDB_CODE_SUCCESS; } else { - mError("app:%p:%p, table:%s, failed to drop table, table not exist", pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId); + mError("msg:%p, app:%p table:%s, failed to drop, table not exist", pMsg, pMsg->rpcMsg.ahandle, pDrop->tableId); return TSDB_CODE_MND_INVALID_TABLE_NAME; } } if (pMsg->pTable->type == TSDB_SUPER_TABLE) { SSTableObj *pSTable = (SSTableObj *)pMsg->pTable; - mInfo("app:%p:%p, table:%s, start to drop stable, uid:%" PRIu64 ", numOfChildTables:%d, sizeOfVgList:%d", - pMsg->rpcMsg.ahandle, pMsg, pDrop->tableId, pSTable->uid, pSTable->numOfTables, (int32_t)taosHashGetSize(pSTable->vgHash)); + mInfo("msg:%p, app:%p table:%s, start to drop stable, uid:%" PRIu64 ", numOfChildTables:%d, sizeOfVgList:%d", + pMsg, pMsg->rpcMsg.ahandle, pDrop->tableId, pSTable->uid, pSTable->numOfTables, (int32_t)taosHashGetSize(pSTable->vgHash)); return mnodeProcessDropSuperTableMsg(pMsg); } else { SCTableObj *pCTable = (SCTableObj *)pMsg->pTable; - mInfo("app:%p:%p, table:%s, start to drop ctable, vgId:%d tid:%d uid:%" PRIu64, pMsg->rpcMsg.ahandle, pMsg, + mInfo("msg:%p, app:%p table:%s, start to drop ctable, vgId:%d tid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle, pDrop->tableId, pCTable->vgId, pCTable->tid, pCTable->uid); return mnodeProcessDropChildTableMsg(pMsg); } @@ -784,12 +785,12 @@ static int32_t mnodeProcessDropTableMsg(SMnodeMsg *pMsg) { static int32_t mnodeProcessTableMetaMsg(SMnodeMsg *pMsg) { STableInfoMsg *pInfo = pMsg->rpcMsg.pCont; pInfo->createFlag = htons(pInfo->createFlag); - mDebug("app:%p:%p, table:%s, table meta msg is received from thandle:%p, createFlag:%d", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, table meta msg is received from thandle:%p, createFlag:%d", pMsg, pMsg->rpcMsg.ahandle, pInfo->tableId, pMsg->rpcMsg.handle, pInfo->createFlag); if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableId(pInfo->tableId); if (pMsg->pDb == NULL) { - mError("app:%p:%p, table:%s, failed to get table meta, db not selected", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, failed to get table meta, db not selected", pMsg, pMsg->rpcMsg.ahandle, pInfo->tableId); return TSDB_CODE_MND_DB_NOT_SELECTED; } @@ -802,11 +803,11 @@ static int32_t mnodeProcessTableMetaMsg(SMnodeMsg *pMsg) { if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pInfo->tableId); if (pMsg->pTable == NULL) { if (!pInfo->createFlag) { - mError("app:%p:%p, table:%s, failed to get table meta, table not exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, failed to get table meta, table not exist", pMsg, pMsg->rpcMsg.ahandle, pInfo->tableId); return TSDB_CODE_MND_INVALID_TABLE_NAME; } else { - mDebug("app:%p:%p, table:%s, failed to get table meta, start auto create table ", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, failed to get table meta, start auto create table ", pMsg, pMsg->rpcMsg.ahandle, pInfo->tableId); return mnodeAutoCreateChildTable(pMsg); } @@ -826,9 +827,9 @@ static int32_t mnodeCreateSuperTableCb(SMnodeMsg *pMsg, int32_t code) { if (code == TSDB_CODE_SUCCESS) { mLInfo("stable:%s, is created in sdb, uid:%" PRIu64, pTable->info.tableId, pTable->uid); } else { - mError("app:%p:%p, stable:%s, failed to create in sdb, reason:%s", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, + mError("msg:%p, app:%p stable:%s, failed to create in sdb, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, tstrerror(code)); - SSdbOper desc = {.type = SDB_OPER_GLOBAL, .pObj = pTable, .table = tsSuperTableSdb}; + SSdbRow desc = {.type = SDB_OPER_GLOBAL, .pObj = pTable, .pTable = tsSuperTableSdb}; sdbDeleteRow(&desc); } @@ -841,7 +842,7 @@ static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) { SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont; SSTableObj * pStable = calloc(1, sizeof(SSTableObj)); if (pStable == NULL) { - mError("app:%p:%p, table:%s, failed to create, no enough memory", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId); + mError("msg:%p, app:%p table:%s, failed to create, no enough memory", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return TSDB_CODE_MND_OUT_OF_MEMORY; } @@ -860,7 +861,7 @@ static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) { pStable->schema = (SSchema *)calloc(1, schemaSize); if (pStable->schema == NULL) { free(pStable); - mError("app:%p:%p, table:%s, failed to create, no schema input", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId); + mError("msg:%p, app:%p table:%s, failed to create, no schema input", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return TSDB_CODE_MND_INVALID_TABLE_NAME; } memcpy(pStable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); @@ -878,20 +879,20 @@ static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) { pMsg->pTable = (STableObj *)pStable; mnodeIncTableRef(pMsg->pTable); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pStable, .rowSize = sizeof(SSTableObj) + schemaSize, - .pMsg = pMsg, - .writeCb = mnodeCreateSuperTableCb + .pMsg = pMsg, + .fpRsp = mnodeCreateSuperTableCb }; - int32_t code = sdbInsertRow(&oper); + int32_t code = sdbInsertRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mnodeDestroySuperTable(pStable); pMsg->pTable = NULL; - mError("app:%p:%p, table:%s, failed to create, sdb error", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId); + mError("msg:%p, app:%p table:%s, failed to create, sdb error", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); } return code; @@ -900,9 +901,9 @@ static int32_t mnodeProcessCreateSuperTableMsg(SMnodeMsg *pMsg) { static int32_t mnodeDropSuperTableCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pTable = (SSTableObj *)pMsg->pTable; if (code != TSDB_CODE_SUCCESS) { - mError("app:%p:%p, stable:%s, failed to drop, sdb error", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId); + mError("msg:%p, app:%p stable:%s, failed to drop, sdb error", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); } else { - mLInfo("app:%p:%p, stable:%s, is dropped from sdb", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId); + mLInfo("msg:%p, app:%p stable:%s, is dropped from sdb", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); } return code; @@ -925,8 +926,8 @@ static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) { pDrop->uid = htobe64(pStable->uid); mnodeExtractTableName(pStable->info.tableId, pDrop->tableId); - mInfo("app:%p:%p, stable:%s, send drop stable msg to vgId:%d", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, - pVgroup->vgId); + mInfo("msg:%p, app:%p stable:%s, send drop stable msg to vgId:%d", pMsg, pMsg->rpcMsg.ahandle, + pStable->info.tableId, pVgroup->vgId); SRpcEpSet epSet = mnodeGetEpSetFromVgroup(pVgroup); SRpcMsg rpcMsg = {.pCont = pDrop, .contLen = sizeof(SDropSTableMsg), .msgType = TSDB_MSG_TYPE_MD_DROP_STABLE}; dnodeSendMsgToDnode(&epSet, &rpcMsg); @@ -937,17 +938,17 @@ static int32_t mnodeProcessDropSuperTableMsg(SMnodeMsg *pMsg) { mnodeDropAllChildTablesInStable(pStable); } - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, - .pMsg = pMsg, - .writeCb = mnodeDropSuperTableCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pStable, + .pMsg = pMsg, + .fpRsp = mnodeDropSuperTableCb }; - int32_t code = sdbDeleteRow(&oper); + int32_t code = sdbDeleteRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { - mError("app:%p:%p, table:%s, failed to drop, reason:%s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mError("msg:%p, app:%p table:%s, failed to drop, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); } @@ -967,7 +968,7 @@ static int32_t mnodeFindSuperTableTagIndex(SSTableObj *pStable, const char *tagN static int32_t mnodeAddSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; - mLInfo("app:%p:%p, stable %s, add tag result:%s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mLInfo("msg:%p, app:%p stable %s, add tag result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); return code; @@ -976,20 +977,20 @@ static int32_t mnodeAddSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) { static int32_t mnodeAddSuperTableTag(SMnodeMsg *pMsg, SSchema schema[], int32_t ntags) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; if (pStable->numOfTags + ntags > TSDB_MAX_TAGS) { - mError("app:%p:%p, stable:%s, add tag, too many tags", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId); + mError("msg:%p, app:%p stable:%s, add tag, too many tags", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId); return TSDB_CODE_MND_TOO_MANY_TAGS; } for (int32_t i = 0; i < ntags; i++) { if (mnodeFindSuperTableColumnIndex(pStable, schema[i].name) > 0) { - mError("app:%p:%p, stable:%s, add tag, column:%s already exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p stable:%s, add tag, column:%s already exist", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, schema[i].name); return TSDB_CODE_MND_TAG_ALREAY_EXIST; } if (mnodeFindSuperTableTagIndex(pStable, schema[i].name) > 0) { - mError("app:%p:%p, stable:%s, add tag, tag:%s already exist", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, - schema[i].name); + mError("msg:%p, app:%p stable:%s, add tag, tag:%s already exist", pMsg, pMsg->rpcMsg.ahandle, + pStable->info.tableId, schema[i].name); return TSDB_CODE_MND_FIELD_ALREAY_EXIST; } } @@ -1007,23 +1008,23 @@ static int32_t mnodeAddSuperTableTag(SMnodeMsg *pMsg, SSchema schema[], int32_t pStable->numOfTags += ntags; pStable->tversion++; - mInfo("app:%p:%p, stable %s, start to add tag %s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mInfo("msg:%p, app:%p stable %s, start to add tag %s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, schema[0].name); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, - .pMsg = pMsg, - .writeCb = mnodeAddSuperTableTagCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pStable, + .pMsg = pMsg, + .fpRsp = mnodeAddSuperTableTagCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } static int32_t mnodeDropSuperTableTagCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; - mLInfo("app:%p:%p, stable %s, drop tag result:%s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mLInfo("msg:%p, app:%p stable %s, drop tag result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); return code; } @@ -1032,7 +1033,7 @@ static int32_t mnodeDropSuperTableTag(SMnodeMsg *pMsg, char *tagName) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; int32_t col = mnodeFindSuperTableTagIndex(pStable, tagName); if (col < 0) { - mError("app:%p:%p, stable:%s, drop tag, tag:%s not exist", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mError("msg:%p, app:%p stable:%s, drop tag, tag:%s not exist", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tagName); return TSDB_CODE_MND_TAG_NOT_EXIST; } @@ -1042,22 +1043,22 @@ static int32_t mnodeDropSuperTableTag(SMnodeMsg *pMsg, char *tagName) { pStable->numOfTags--; pStable->tversion++; - mInfo("app:%p:%p, stable %s, start to drop tag %s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, tagName); + mInfo("msg:%p, app:%p stable %s, start to drop tag %s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tagName); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, - .pMsg = pMsg, - .writeCb = mnodeDropSuperTableTagCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pStable, + .pMsg = pMsg, + .fpRsp = mnodeDropSuperTableTagCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } static int32_t mnodeModifySuperTableTagNameCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; - mLInfo("app:%p:%p, stable %s, modify tag result:%s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mLInfo("msg:%p, app:%p stable %s, modify tag result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); return code; } @@ -1066,7 +1067,7 @@ static int32_t mnodeModifySuperTableTagName(SMnodeMsg *pMsg, char *oldTagName, c SSTableObj *pStable = (SSTableObj *)pMsg->pTable; int32_t col = mnodeFindSuperTableTagIndex(pStable, oldTagName); if (col < 0) { - mError("app:%p:%p, stable:%s, failed to modify table tag, oldName: %s, newName: %s", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p stable:%s, failed to modify table tag, oldName: %s, newName: %s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, oldTagName, newTagName); return TSDB_CODE_MND_TAG_NOT_EXIST; } @@ -1085,18 +1086,18 @@ static int32_t mnodeModifySuperTableTagName(SMnodeMsg *pMsg, char *oldTagName, c SSchema *schema = (SSchema *) (pStable->schema + pStable->numOfColumns + col); tstrncpy(schema->name, newTagName, sizeof(schema->name)); - mInfo("app:%p:%p, stable %s, start to modify tag %s to %s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mInfo("msg:%p, app:%p stable %s, start to modify tag %s to %s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, oldTagName, newTagName); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, - .pMsg = pMsg, - .writeCb = mnodeModifySuperTableTagNameCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pStable, + .pMsg = pMsg, + .fpRsp = mnodeModifySuperTableTagNameCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } static int32_t mnodeFindSuperTableColumnIndex(SSTableObj *pStable, char *colName) { @@ -1112,7 +1113,7 @@ static int32_t mnodeFindSuperTableColumnIndex(SSTableObj *pStable, char *colName static int32_t mnodeAddSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; - mLInfo("app:%p:%p, stable %s, add column result:%s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mLInfo("msg:%p, app:%p stable %s, add column result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); return code; } @@ -1121,19 +1122,19 @@ static int32_t mnodeAddSuperTableColumn(SMnodeMsg *pMsg, SSchema schema[], int32 SDbObj *pDb = pMsg->pDb; SSTableObj *pStable = (SSTableObj *)pMsg->pTable; if (ncols <= 0) { - mError("app:%p:%p, stable:%s, add column, ncols:%d <= 0", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, ncols); + mError("msg:%p, app:%p stable:%s, add column, ncols:%d <= 0", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, ncols); return TSDB_CODE_MND_APP_ERROR; } for (int32_t i = 0; i < ncols; i++) { if (mnodeFindSuperTableColumnIndex(pStable, schema[i].name) > 0) { - mError("app:%p:%p, stable:%s, add column, column:%s already exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p stable:%s, add column, column:%s already exist", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, schema[i].name); return TSDB_CODE_MND_FIELD_ALREAY_EXIST; } if (mnodeFindSuperTableTagIndex(pStable, schema[i].name) > 0) { - mError("app:%p:%p, stable:%s, add column, tag:%s already exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p stable:%s, add column, tag:%s already exist", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, schema[i].name); return TSDB_CODE_MND_TAG_ALREAY_EXIST; } @@ -1160,22 +1161,22 @@ static int32_t mnodeAddSuperTableColumn(SMnodeMsg *pMsg, SSchema schema[], int32 mnodeDecAcctRef(pAcct); } - mInfo("app:%p:%p, stable %s, start to add column", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId); + mInfo("msg:%p, app:%p stable %s, start to add column", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, - .pMsg = pMsg, - .writeCb = mnodeAddSuperTableColumnCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pStable, + .pMsg = pMsg, + .fpRsp = mnodeAddSuperTableColumnCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } static int32_t mnodeDropSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; - mLInfo("app:%p:%p, stable %s, delete column result:%s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mLInfo("msg:%p, app:%p stable %s, delete column result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); return code; } @@ -1185,7 +1186,7 @@ static int32_t mnodeDropSuperTableColumn(SMnodeMsg *pMsg, char *colName) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; int32_t col = mnodeFindSuperTableColumnIndex(pStable, colName); if (col <= 0) { - mError("app:%p:%p, stable:%s, drop column, column:%s not exist", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mError("msg:%p, app:%p stable:%s, drop column, column:%s not exist", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, colName); return TSDB_CODE_MND_FIELD_NOT_EXIST; } @@ -1205,22 +1206,22 @@ static int32_t mnodeDropSuperTableColumn(SMnodeMsg *pMsg, char *colName) { mnodeDecAcctRef(pAcct); } - mInfo("app:%p:%p, stable %s, start to delete column", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId); + mInfo("msg:%p, app:%p stable %s, start to delete column", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, - .pMsg = pMsg, - .writeCb = mnodeDropSuperTableColumnCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pStable, + .pMsg = pMsg, + .fpRsp = mnodeDropSuperTableColumnCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } static int32_t mnodeChangeSuperTableColumnCb(SMnodeMsg *pMsg, int32_t code) { SSTableObj *pStable = (SSTableObj *)pMsg->pTable; - mLInfo("app:%p:%p, stable %s, change column result:%s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mLInfo("msg:%p, app:%p stable %s, change column result:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, tstrerror(code)); return code; } @@ -1229,7 +1230,7 @@ static int32_t mnodeChangeSuperTableColumn(SMnodeMsg *pMsg, char *oldName, char SSTableObj *pStable = (SSTableObj *)pMsg->pTable; int32_t col = mnodeFindSuperTableColumnIndex(pStable, oldName); if (col < 0) { - mError("app:%p:%p, stable:%s, change column, oldName: %s, newName: %s", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p stable:%s, change column, oldName:%s, newName:%s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, oldName, newName); return TSDB_CODE_MND_FIELD_NOT_EXIST; } @@ -1248,18 +1249,18 @@ static int32_t mnodeChangeSuperTableColumn(SMnodeMsg *pMsg, char *oldName, char SSchema *schema = (SSchema *) (pStable->schema + col); tstrncpy(schema->name, newName, sizeof(schema->name)); - mInfo("app:%p:%p, stable %s, start to modify column %s to %s", pMsg->rpcMsg.ahandle, pMsg, pStable->info.tableId, + mInfo("msg:%p, app:%p stable %s, start to modify column %s to %s", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, oldName, newName); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, - .pMsg = pMsg, - .writeCb = mnodeChangeSuperTableColumnCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsSuperTableSdb, + .pObj = pStable, + .pMsg = pMsg, + .fpRsp = mnodeChangeSuperTableColumnCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } // show super tables @@ -1417,12 +1418,12 @@ void mnodeDropAllSuperTables(SDbObj *pDropDb) { if (pTable == NULL) break; if (strncmp(prefix, pTable->info.tableId, prefixLen) == 0) { - SSdbOper oper = { - .type = SDB_OPER_LOCAL, - .table = tsSuperTableSdb, - .pObj = pTable, + SSdbRow row = { + .type = SDB_OPER_LOCAL, + .pTable = tsSuperTableSdb, + .pObj = pTable, }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); numOfTables ++; } @@ -1470,7 +1471,7 @@ static int32_t mnodeGetSuperTableMeta(SMnodeMsg *pMsg) { pMsg->rpcRsp.rsp = pMeta; - mDebug("app:%p:%p, stable:%s, uid:%" PRIu64 " table meta is retrieved", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p stable:%s, uid:%" PRIu64 " table meta is retrieved", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->uid); return TSDB_CODE_SUCCESS; } @@ -1503,12 +1504,12 @@ static int32_t mnodeProcessSuperTableVgroupMsg(SMnodeMsg *pMsg) { char * stableName = (char *)pInfo + sizeof(SSTableVgroupMsg) + (TSDB_TABLE_FNAME_LEN)*i; SSTableObj *pTable = mnodeGetSuperTable(stableName); if (pTable == NULL) { - mError("app:%p:%p, stable:%s, not exist while get stable vgroup info", pMsg->rpcMsg.ahandle, pMsg, stableName); + mError("msg:%p, app:%p stable:%s, not exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, stableName); mnodeDecTableRef(pTable); continue; } if (pTable->vgHash == NULL) { - mDebug("app:%p:%p, stable:%s, no vgroup exist while get stable vgroup info", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p stable:%s, no vgroup exist while get stable vgroup info", pMsg, pMsg->rpcMsg.ahandle, stableName); mnodeDecTableRef(pTable); @@ -1650,7 +1651,7 @@ static int32_t mnodeDoCreateChildTableFp(SMnodeMsg *pMsg) { SCTableObj *pTable = (SCTableObj *)pMsg->pTable; assert(pTable); - mDebug("app:%p:%p, table:%s, created in mnode, vgId:%d sid:%d, uid:%" PRIu64, pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, created in mnode, vgId:%d sid:%d, uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid); SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont; @@ -1679,22 +1680,22 @@ static int32_t mnodeDoCreateChildTableCb(SMnodeMsg *pMsg, int32_t code) { if (code == TSDB_CODE_SUCCESS) { if (pCreate->getMeta) { - mDebug("app:%p:%p, table:%s, created in dnode and continue to get meta, thandle:%p", pMsg->rpcMsg.ahandle, pMsg, - pTable->info.tableId, pMsg->rpcMsg.handle); + mDebug("msg:%p, app:%p table:%s, created in dnode and continue to get meta, thandle:%p", pMsg, + pMsg->rpcMsg.ahandle, pTable->info.tableId, pMsg->rpcMsg.handle); pMsg->retry = 0; dnodeReprocessMWriteMsg(pMsg); } else { - mDebug("app:%p:%p, table:%s, created in dnode, thandle:%p", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, + mDebug("msg:%p, app:%p table:%s, created in dnode, thandle:%p", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pMsg->rpcMsg.handle); dnodeSendRpcMWriteRsp(pMsg, TSDB_CODE_SUCCESS); } return TSDB_CODE_MND_ACTION_IN_PROGRESS; } else { - mError("app:%p:%p, table:%s, failed to create table sid:%d, uid:%" PRIu64 ", reason:%s", pMsg->rpcMsg.ahandle, pMsg, - pTable->info.tableId, pTable->tid, pTable->uid, tstrerror(code)); - SSdbOper desc = {.type = SDB_OPER_GLOBAL, .pObj = pTable, .table = tsChildTableSdb}; + mError("msg:%p, app:%p table:%s, failed to create table sid:%d, uid:%" PRIu64 ", reason:%s", pMsg, + pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->tid, pTable->uid, tstrerror(code)); + SSdbRow desc = {.type = SDB_OPER_GLOBAL, .pObj = pTable, .pTable = tsChildTableSdb}; sdbDeleteRow(&desc); return code; } @@ -1705,7 +1706,7 @@ static int32_t mnodeDoCreateChildTable(SMnodeMsg *pMsg, int32_t tid) { SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont; SCTableObj *pTable = calloc(1, sizeof(SCTableObj)); if (pTable == NULL) { - mError("app:%p:%p, table:%s, failed to alloc memory", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId); + mError("msg:%p, app:%p table:%s, failed to alloc memory", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return TSDB_CODE_MND_OUT_OF_MEMORY; } @@ -1724,7 +1725,7 @@ static int32_t mnodeDoCreateChildTable(SMnodeMsg *pMsg, int32_t tid) { STagData *pTagData = (STagData *)pCreate->schema; // it is a tag key if (pMsg->pSTable == NULL) pMsg->pSTable = mnodeGetSuperTable(pTagData->name); if (pMsg->pSTable == NULL) { - mError("app:%p:%p, table:%s, corresponding super table:%s does not exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, corresponding super table:%s does not exist", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId, pTagData->name); mnodeDestroyChildTable(pTable); return TSDB_CODE_MND_INVALID_TABLE_NAME; @@ -1772,7 +1773,7 @@ static int32_t mnodeDoCreateChildTable(SMnodeMsg *pMsg, int32_t tid) { } memcpy(pTable->sql, (char *) (pCreate->schema) + numOfCols * sizeof(SSchema), pTable->sqlLen); pTable->sql[pTable->sqlLen - 1] = 0; - mDebug("app:%p:%p, table:%s, stream sql len:%d sql:%s", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, + mDebug("msg:%p, app:%p table:%s, stream sql len:%d sql:%s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->sqlLen, pTable->sql); } } @@ -1780,22 +1781,22 @@ static int32_t mnodeDoCreateChildTable(SMnodeMsg *pMsg, int32_t tid) { pMsg->pTable = (STableObj *)pTable; mnodeIncTableRef(pMsg->pTable); - SSdbOper desc = { - .type = SDB_OPER_GLOBAL, - .pObj = pTable, - .table = tsChildTableSdb, - .pMsg = pMsg, - .reqFp = mnodeDoCreateChildTableFp + SSdbRow desc = { + .type = SDB_OPER_GLOBAL, + .pObj = pTable, + .pTable = tsChildTableSdb, + .pMsg = pMsg, + .fpReq = mnodeDoCreateChildTableFp }; int32_t code = sdbInsertRow(&desc); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mnodeDestroyChildTable(pTable); pMsg->pTable = NULL; - mError("app:%p:%p, table:%s, failed to create, reason:%s", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId, + mError("msg:%p, app:%p table:%s, failed to create, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId, tstrerror(code)); } else { - mDebug("app:%p:%p, table:%s, allocated in vgroup, vgId:%d sid:%d uid:%" PRIu64, pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, allocated in vgroup, vgId:%d sid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pVgroup->vgId, pTable->tid, pTable->uid); } @@ -1806,7 +1807,7 @@ static int32_t mnodeProcessCreateChildTableMsg(SMnodeMsg *pMsg) { SCMCreateTableMsg *pCreate = pMsg->rpcMsg.pCont; int32_t code = grantCheck(TSDB_GRANT_TIMESERIES); if (code != TSDB_CODE_SUCCESS) { - mError("app:%p:%p, table:%s, failed to create, grant timeseries failed", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, failed to create, grant timeseries failed", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return code; } @@ -1817,7 +1818,7 @@ static int32_t mnodeProcessCreateChildTableMsg(SMnodeMsg *pMsg) { int32_t tid = 0; code = mnodeGetAvailableVgroup(pMsg, &pVgroup, &tid); if (code != TSDB_CODE_SUCCESS) { - mDebug("app:%p:%p, table:%s, failed to get available vgroup, reason:%s", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, failed to get available vgroup, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId, tstrerror(code)); return code; } @@ -1836,22 +1837,22 @@ static int32_t mnodeProcessCreateChildTableMsg(SMnodeMsg *pMsg) { } if (pMsg->pTable == NULL) { - mError("app:%p:%p, table:%s, object not found, retry:%d reason:%s", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId, pMsg->retry, + mError("msg:%p, app:%p table:%s, object not found, retry:%d reason:%s", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId, pMsg->retry, tstrerror(terrno)); return terrno; } else { - mDebug("app:%p:%p, table:%s, send create msg to vnode again", pMsg->rpcMsg.ahandle, pMsg, pCreate->tableId); + mDebug("msg:%p, app:%p table:%s, send create msg to vnode again", pMsg, pMsg->rpcMsg.ahandle, pCreate->tableId); return mnodeDoCreateChildTableFp(pMsg); } } static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) { SCTableObj *pTable = (SCTableObj *)pMsg->pTable; - mLInfo("app:%p:%p, ctable:%s, is dropped from sdb", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId); + mLInfo("msg:%p, app:%p ctable:%s, is dropped from sdb", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); SMDDropTableMsg *pDrop = rpcMallocCont(sizeof(SMDDropTableMsg)); if (pDrop == NULL) { - mError("app:%p:%p, ctable:%s, failed to drop ctable, no enough memory", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p ctable:%s, failed to drop ctable, no enough memory", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); return TSDB_CODE_MND_OUT_OF_MEMORY; } @@ -1864,7 +1865,7 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) { SRpcEpSet epSet = mnodeGetEpSetFromVgroup(pMsg->pVgroup); - mInfo("app:%p:%p, ctable:%s, send drop ctable msg, vgId:%d sid:%d uid:%" PRIu64, pMsg->rpcMsg.ahandle, pMsg, + mInfo("msg:%p, app:%p ctable:%s, send drop ctable msg, vgId:%d sid:%d uid:%" PRIu64, pMsg, pMsg->rpcMsg.ahandle, pDrop->tableId, pTable->vgId, pTable->tid, pTable->uid); SRpcMsg rpcMsg = { @@ -1885,7 +1886,7 @@ static int32_t mnodeSendDropChildTableMsg(SMnodeMsg *pMsg, bool needReturn) { static int32_t mnodeDropChildTableCb(SMnodeMsg *pMsg, int32_t code) { if (code != TSDB_CODE_SUCCESS) { SCTableObj *pTable = (SCTableObj *)pMsg->pTable; - mError("app:%p:%p, ctable:%s, failed to drop, sdb error", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId); + mError("msg:%p, app:%p ctable:%s, failed to drop, sdb error", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); return code; } @@ -1896,22 +1897,22 @@ static int32_t mnodeProcessDropChildTableMsg(SMnodeMsg *pMsg) { SCTableObj *pTable = (SCTableObj *)pMsg->pTable; if (pMsg->pVgroup == NULL) pMsg->pVgroup = mnodeGetVgroup(pTable->vgId); if (pMsg->pVgroup == NULL) { - mError("app:%p:%p, table:%s, failed to drop ctable, vgroup not exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, failed to drop ctable, vgroup not exist", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); return TSDB_CODE_MND_APP_ERROR; } - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsChildTableSdb, - .pObj = pTable, - .pMsg = pMsg, - .writeCb = mnodeDropChildTableCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsChildTableSdb, + .pObj = pTable, + .pMsg = pMsg, + .fpRsp = mnodeDropChildTableCb }; - int32_t code = sdbDeleteRow(&oper); + int32_t code = sdbDeleteRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { - mError("app:%p:%p, ctable:%s, failed to drop, reason:%s", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, + mError("msg:%p, app:%p ctable:%s, failed to drop, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, tstrerror(code)); } @@ -1932,7 +1933,7 @@ static int32_t mnodeFindNormalTableColumnIndex(SCTableObj *pTable, char *colName static int32_t mnodeAlterNormalTableColumnCb(SMnodeMsg *pMsg, int32_t code) { SCTableObj *pTable = (SCTableObj *)pMsg->pTable; if (code != TSDB_CODE_SUCCESS) { - mError("app:%p:%p, ctable %s, failed to alter column, reason:%s", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, + mError("msg:%p, app:%p ctable %s, failed to alter column, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, tstrerror(code)); return code; } @@ -1946,7 +1947,7 @@ static int32_t mnodeAlterNormalTableColumnCb(SMnodeMsg *pMsg, int32_t code) { pMsg->pVgroup = mnodeGetVgroup(pTable->vgId); if (pMsg->pVgroup == NULL) { rpcFreeCont(pMDCreate); - mError("app:%p:%p, ctable %s, vgId:%d not exist in mnode", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, + mError("msg:%p, app:%p ctable %s, vgId:%d not exist in mnode", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->vgId); return TSDB_CODE_MND_VGROUP_NOT_EXIST; } @@ -1961,7 +1962,7 @@ static int32_t mnodeAlterNormalTableColumnCb(SMnodeMsg *pMsg, int32_t code) { .msgType = TSDB_MSG_TYPE_MD_ALTER_TABLE }; - mDebug("app:%p:%p, ctable %s, send alter column msg to vgId:%d", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, + mDebug("msg:%p, app:%p ctable %s, send alter column msg to vgId:%d", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pMsg->pVgroup->vgId); dnodeSendMsgToDnode(&epSet, &rpcMsg); @@ -1972,13 +1973,13 @@ static int32_t mnodeAddNormalTableColumn(SMnodeMsg *pMsg, SSchema schema[], int3 SCTableObj *pTable = (SCTableObj *)pMsg->pTable; SDbObj *pDb = pMsg->pDb; if (ncols <= 0) { - mError("app:%p:%p, ctable:%s, add column, ncols:%d <= 0", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, ncols); + mError("msg:%p, app:%p ctable:%s, add column, ncols:%d <= 0", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, ncols); return TSDB_CODE_MND_APP_ERROR; } for (int32_t i = 0; i < ncols; i++) { if (mnodeFindNormalTableColumnIndex(pTable, schema[i].name) > 0) { - mError("app:%p:%p, ctable:%s, add column, column:%s already exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p ctable:%s, add column, column:%s already exist", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, schema[i].name); return TSDB_CODE_MND_FIELD_ALREAY_EXIST; } @@ -2003,17 +2004,17 @@ static int32_t mnodeAddNormalTableColumn(SMnodeMsg *pMsg, SSchema schema[], int3 mnodeDecAcctRef(pAcct); } - mInfo("app:%p:%p, ctable %s, start to add column", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId); + mInfo("msg:%p, app:%p ctable %s, start to add column", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsChildTableSdb, - .pObj = pTable, - .pMsg = pMsg, - .writeCb = mnodeAlterNormalTableColumnCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsChildTableSdb, + .pObj = pTable, + .pMsg = pMsg, + .fpRsp = mnodeAlterNormalTableColumnCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } static int32_t mnodeDropNormalTableColumn(SMnodeMsg *pMsg, char *colName) { @@ -2021,8 +2022,8 @@ static int32_t mnodeDropNormalTableColumn(SMnodeMsg *pMsg, char *colName) { SCTableObj *pTable = (SCTableObj *)pMsg->pTable; int32_t col = mnodeFindNormalTableColumnIndex(pTable, colName); if (col <= 0) { - mError("app:%p:%p, ctable:%s, drop column, column:%s not exist", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, - colName); + mError("msg:%p, app:%p ctable:%s, drop column, column:%s not exist", pMsg, pMsg->rpcMsg.ahandle, + pTable->info.tableId, colName); return TSDB_CODE_MND_FIELD_NOT_EXIST; } @@ -2036,24 +2037,24 @@ static int32_t mnodeDropNormalTableColumn(SMnodeMsg *pMsg, char *colName) { mnodeDecAcctRef(pAcct); } - mInfo("app:%p:%p, ctable %s, start to drop column %s", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, colName); + mInfo("msg:%p, app:%p ctable %s, start to drop column %s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, colName); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsChildTableSdb, - .pObj = pTable, - .pMsg = pMsg, - .writeCb = mnodeAlterNormalTableColumnCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsChildTableSdb, + .pObj = pTable, + .pMsg = pMsg, + .fpRsp = mnodeAlterNormalTableColumnCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } static int32_t mnodeChangeNormalTableColumn(SMnodeMsg *pMsg, char *oldName, char *newName) { SCTableObj *pTable = (SCTableObj *)pMsg->pTable; int32_t col = mnodeFindNormalTableColumnIndex(pTable, oldName); if (col < 0) { - mError("app:%p:%p, ctable:%s, change column, oldName: %s, newName: %s", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p ctable:%s, change column, oldName: %s, newName: %s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, oldName, newName); return TSDB_CODE_MND_FIELD_NOT_EXIST; } @@ -2072,18 +2073,18 @@ static int32_t mnodeChangeNormalTableColumn(SMnodeMsg *pMsg, char *oldName, char SSchema *schema = (SSchema *) (pTable->schema + col); tstrncpy(schema->name, newName, sizeof(schema->name)); - mInfo("app:%p:%p, ctable %s, start to modify column %s to %s", pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, + mInfo("msg:%p, app:%p ctable %s, start to modify column %s to %s", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, oldName, newName); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsChildTableSdb, - .pObj = pTable, - .pMsg = pMsg, - .writeCb = mnodeAlterNormalTableColumnCb + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsChildTableSdb, + .pObj = pTable, + .pMsg = pMsg, + .fpRsp = mnodeAlterNormalTableColumnCb }; - return sdbUpdateRow(&oper); + return sdbUpdateRow(&row); } static int32_t mnodeSetSchemaFromNormalTable(SSchema *pSchema, SCTableObj *pTable) { @@ -2128,7 +2129,7 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) { if (pMsg->pVgroup == NULL) pMsg->pVgroup = mnodeGetVgroup(pTable->vgId); if (pMsg->pVgroup == NULL) { - mError("app:%p:%p, table:%s, failed to get table meta, vgroup not exist", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, failed to get table meta, vgroup not exist", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); return TSDB_CODE_MND_VGROUP_NOT_EXIST; } @@ -2143,7 +2144,7 @@ static int32_t mnodeDoGetChildTableMeta(SMnodeMsg *pMsg, STableMetaMsg *pMeta) { } pMeta->vgroup.vgId = htonl(pMsg->pVgroup->vgId); - mDebug("app:%p:%p, table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d sid:%d", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, uid:%" PRIu64 " table meta is retrieved, vgId:%d sid:%d", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->uid, pTable->vgId, pTable->tid); return TSDB_CODE_SUCCESS; @@ -2154,16 +2155,16 @@ static int32_t mnodeAutoCreateChildTable(SMnodeMsg *pMsg) { STagData *pTags = (STagData *)pInfo->tags; int32_t tagLen = htonl(pTags->dataLen); if (pTags->name[0] == 0) { - mError("app:%p:%p, table:%s, failed to create table on demand for stable is empty, tagLen:%d", pMsg->rpcMsg.ahandle, - pMsg, pInfo->tableId, tagLen); - return TSDB_CODE_MND_INVALID_STABLE_NAME; + mError("msg:%p, app:%p table:%s, failed to create table on demand for stable is empty, tagLen:%d", pMsg, + pMsg->rpcMsg.ahandle, pInfo->tableId, tagLen); + return TSDB_CODE_MND_INVALID_STABLE_NAME; } int32_t contLen = sizeof(SCMCreateTableMsg) + offsetof(STagData, data) + tagLen; SCMCreateTableMsg *pCreateMsg = calloc(1, contLen); if (pCreateMsg == NULL) { - mError("app:%p:%p, table:%s, failed to create table while get meta info, no enough memory", pMsg->rpcMsg.ahandle, - pMsg, pInfo->tableId); + mError("msg:%p, app:%p table:%s, failed to create table while get meta info, no enough memory", pMsg, + pMsg->rpcMsg.ahandle, pInfo->tableId); return TSDB_CODE_MND_OUT_OF_MEMORY; } @@ -2175,8 +2176,8 @@ static int32_t mnodeAutoCreateChildTable(SMnodeMsg *pMsg) { pCreateMsg->contLen = htonl(contLen); memcpy(pCreateMsg->schema, pTags, contLen - sizeof(SCMCreateTableMsg)); - mDebug("app:%p:%p, table:%s, start to create on demand, tagLen:%d stable:%s", - pMsg->rpcMsg.ahandle, pMsg, pInfo->tableId, tagLen, pTags->name); + mDebug("msg:%p, app:%p table:%s, start to create on demand, tagLen:%d stable:%s", pMsg, pMsg->rpcMsg.ahandle, + pInfo->tableId, tagLen, pTags->name); if (pMsg->rpcMsg.pCont != pMsg->pCont) { tfree(pMsg->rpcMsg.pCont); @@ -2192,7 +2193,7 @@ static int32_t mnodeGetChildTableMeta(SMnodeMsg *pMsg) { STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * (TSDB_MAX_TAGS + TSDB_MAX_COLUMNS + 16)); if (pMeta == NULL) { - mError("app:%p:%p, table:%s, failed to get table meta, no enough memory", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p table:%s, failed to get table meta, no enough memory", pMsg, pMsg->rpcMsg.ahandle, pMsg->pTable->tableId); return TSDB_CODE_MND_OUT_OF_MEMORY; } @@ -2218,12 +2219,12 @@ void mnodeDropAllChildTablesInVgroups(SVgObj *pVgroup) { if (pTable == NULL) break; if (pTable->vgId == pVgroup->vgId) { - SSdbOper oper = { - .type = SDB_OPER_LOCAL, - .table = tsChildTableSdb, - .pObj = pTable, + SSdbRow row = { + .type = SDB_OPER_LOCAL, + .pTable = tsChildTableSdb, + .pObj = pTable, }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); numOfTables++; } mnodeDecTableRef(pTable); @@ -2251,12 +2252,12 @@ void mnodeDropAllChildTables(SDbObj *pDropDb) { if (pTable == NULL) break; if (strncmp(prefix, pTable->info.tableId, prefixLen) == 0) { - SSdbOper oper = { - .type = SDB_OPER_LOCAL, - .table = tsChildTableSdb, - .pObj = pTable, + SSdbRow row = { + .type = SDB_OPER_LOCAL, + .pTable = tsChildTableSdb, + .pObj = pTable, }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); numOfTables++; } mnodeDecTableRef(pTable); @@ -2280,12 +2281,12 @@ static void mnodeDropAllChildTablesInStable(SSTableObj *pStable) { if (pTable == NULL) break; if (pTable->superTable == pStable) { - SSdbOper oper = { - .type = SDB_OPER_LOCAL, - .table = tsChildTableSdb, - .pObj = pTable, + SSdbRow row = { + .type = SDB_OPER_LOCAL, + .pTable = tsChildTableSdb, + .pObj = pTable, }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); numOfTables++; } @@ -2317,12 +2318,12 @@ static int32_t mnodeProcessTableCfgMsg(SMnodeMsg *pMsg) { pCfg->dnodeId = htonl(pCfg->dnodeId); pCfg->vgId = htonl(pCfg->vgId); pCfg->sid = htonl(pCfg->sid); - mDebug("app:%p:%p, dnode:%d, vgId:%d sid:%d, receive table config msg", pMsg->rpcMsg.ahandle, pMsg, pCfg->dnodeId, + mDebug("msg:%p, app:%p dnode:%d, vgId:%d sid:%d, receive table config msg", pMsg, pMsg->rpcMsg.ahandle, pCfg->dnodeId, pCfg->vgId, pCfg->sid); SCTableObj *pTable = mnodeGetTableByPos(pCfg->vgId, pCfg->sid); if (pTable == NULL) { - mError("app:%p:%p, dnode:%d, vgId:%d sid:%d, table not found", pMsg->rpcMsg.ahandle, pMsg, pCfg->dnodeId, + mError("msg:%p, app:%p dnode:%d, vgId:%d sid:%d, table not found", pMsg, pMsg->rpcMsg.ahandle, pCfg->dnodeId, pCfg->vgId, pCfg->sid); return TSDB_CODE_MND_INVALID_TABLE_ID; } @@ -2343,38 +2344,37 @@ static int32_t mnodeProcessTableCfgMsg(SMnodeMsg *pMsg) { static void mnodeProcessDropChildTableRsp(SRpcMsg *rpcMsg) { if (rpcMsg->ahandle == NULL) return; - SMnodeMsg *mnodeMsg = rpcMsg->ahandle; - mnodeMsg->received++; + SMnodeMsg *pMsg = rpcMsg->ahandle; + pMsg->received++; - SCTableObj *pTable = (SCTableObj *)mnodeMsg->pTable; + SCTableObj *pTable = (SCTableObj *)pMsg->pTable; assert(pTable); - mInfo("app:%p:%p, table:%s, drop table rsp received, vgId:%d sid:%d uid:%" PRIu64 ", thandle:%p result:%s", - mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid, - mnodeMsg->rpcMsg.handle, tstrerror(rpcMsg->code)); + mInfo("msg:%p, app:%p table:%s, drop table rsp received, vgId:%d sid:%d uid:%" PRIu64 ", thandle:%p result:%s", pMsg, + pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid, pMsg->rpcMsg.handle, + tstrerror(rpcMsg->code)); if (rpcMsg->code != TSDB_CODE_SUCCESS) { - mError("app:%p:%p, table:%s, failed to drop in dnode, vgId:%d sid:%d uid:%" PRIu64 ", reason:%s", - mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid, - tstrerror(rpcMsg->code)); - dnodeSendRpcMWriteRsp(mnodeMsg, rpcMsg->code); + mError("msg:%p, app:%p table:%s, failed to drop in dnode, vgId:%d sid:%d uid:%" PRIu64 ", reason:%s", pMsg, + pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid, tstrerror(rpcMsg->code)); + dnodeSendRpcMWriteRsp(pMsg, rpcMsg->code); return; } - if (mnodeMsg->pVgroup == NULL) mnodeMsg->pVgroup = mnodeGetVgroup(pTable->vgId); - if (mnodeMsg->pVgroup == NULL) { - mError("app:%p:%p, table:%s, failed to get vgroup", mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId); - dnodeSendRpcMWriteRsp(mnodeMsg, TSDB_CODE_MND_VGROUP_NOT_EXIST); + if (pMsg->pVgroup == NULL) pMsg->pVgroup = mnodeGetVgroup(pTable->vgId); + if (pMsg->pVgroup == NULL) { + mError("msg:%p, app:%p table:%s, failed to get vgroup", pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId); + dnodeSendRpcMWriteRsp(pMsg, TSDB_CODE_MND_VGROUP_NOT_EXIST); return; } - if (mnodeMsg->pVgroup->numOfTables <= 0) { - mInfo("app:%p:%p, vgId:%d, all tables is dropped, drop vgroup", mnodeMsg->rpcMsg.ahandle, mnodeMsg, - mnodeMsg->pVgroup->vgId); - mnodeDropVgroup(mnodeMsg->pVgroup, NULL); + if (pMsg->pVgroup->numOfTables <= 0) { + mInfo("msg:%p, app:%p vgId:%d, all tables is dropped, drop vgroup", pMsg, pMsg->rpcMsg.ahandle, + pMsg->pVgroup->vgId); + mnodeDropVgroup(pMsg->pVgroup, NULL); } - dnodeSendRpcMWriteRsp(mnodeMsg, TSDB_CODE_SUCCESS); + dnodeSendRpcMWriteRsp(pMsg, TSDB_CODE_SUCCESS); } /* @@ -2384,70 +2384,70 @@ static void mnodeProcessDropChildTableRsp(SRpcMsg *rpcMsg) { static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) { if (rpcMsg->ahandle == NULL) return; - SMnodeMsg *mnodeMsg = rpcMsg->ahandle; - mnodeMsg->received++; + SMnodeMsg *pMsg = rpcMsg->ahandle; + pMsg->received++; - SCTableObj *pTable = (SCTableObj *)mnodeMsg->pTable; + SCTableObj *pTable = (SCTableObj *)pMsg->pTable; assert(pTable); // If the table is deleted by another thread during creation, stop creating and send drop msg to vnode if (sdbCheckRowDeleted(tsChildTableSdb, pTable)) { - mDebug("app:%p:%p, table:%s, create table rsp received, but a deleting opertion incoming, vgId:%d sid:%d uid:%" PRIu64, - mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid); + mDebug("msg:%p, app:%p table:%s, create table rsp received, but a deleting opertion incoming, vgId:%d sid:%d uid:%" PRIu64, + pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid); // if the vgroup is already dropped from hash, it can't be accquired by pTable->vgId // so the refCount of vgroup can not be decreased // SVgObj *pVgroup = mnodeGetVgroup(pTable->vgId); // if (pVgroup == NULL) { - // mnodeRemoveTableFromVgroup(mnodeMsg->pVgroup, pTable); + // mnodeRemoveTableFromVgroup(pMsg->pVgroup, pTable); // } // mnodeDecVgroupRef(pVgroup); - mnodeSendDropChildTableMsg(mnodeMsg, false); + mnodeSendDropChildTableMsg(pMsg, false); rpcMsg->code = TSDB_CODE_SUCCESS; - dnodeSendRpcMWriteRsp(mnodeMsg, rpcMsg->code); + dnodeSendRpcMWriteRsp(pMsg, rpcMsg->code); return; } if (rpcMsg->code == TSDB_CODE_SUCCESS || rpcMsg->code == TSDB_CODE_TDB_TABLE_ALREADY_EXIST) { - SSdbOper desc = { - .type = SDB_OPER_GLOBAL, - .pObj = pTable, - .table = tsChildTableSdb, - .pMsg = mnodeMsg, - .writeCb = mnodeDoCreateChildTableCb + SSdbRow desc = { + .type = SDB_OPER_GLOBAL, + .pObj = pTable, + .pTable = tsChildTableSdb, + .pMsg = pMsg, + .fpRsp = mnodeDoCreateChildTableCb }; - int32_t code = sdbInsertRowImp(&desc); + int32_t code = sdbInsertRowToQueue(&desc); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { - mnodeMsg->pTable = NULL; + pMsg->pTable = NULL; mnodeDestroyChildTable(pTable); - dnodeSendRpcMWriteRsp(mnodeMsg, code); + dnodeSendRpcMWriteRsp(pMsg, code); } } else { - mnodeMsg->retry++; + pMsg->retry++; int32_t sec = taosGetTimestampSec(); - if (mnodeMsg->retry < CREATE_CTABLE_RETRY_TIMES && ABS(sec - mnodeMsg->incomingTs) < CREATE_CTABLE_RETRY_SEC) { - mDebug("app:%p:%p, table:%s, create table rsp received, need retry, times:%d vgId:%d sid:%d uid:%" PRIu64 + if (pMsg->retry < CREATE_CTABLE_RETRY_TIMES && ABS(sec - pMsg->incomingTs) < CREATE_CTABLE_RETRY_SEC) { + mDebug("msg:%p, app:%p table:%s, create table rsp received, need retry, times:%d vgId:%d sid:%d uid:%" PRIu64 " result:%s thandle:%p", - mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, mnodeMsg->retry, pTable->vgId, pTable->tid, - pTable->uid, tstrerror(rpcMsg->code), mnodeMsg->rpcMsg.handle); + pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pMsg->retry, pTable->vgId, pTable->tid, pTable->uid, + tstrerror(rpcMsg->code), pMsg->rpcMsg.handle); - dnodeDelayReprocessMWriteMsg(mnodeMsg); + dnodeDelayReprocessMWriteMsg(pMsg); } else { - mError("app:%p:%p, table:%s, failed to create in dnode, vgId:%d sid:%d uid:%" PRIu64 + mError("msg:%p, app:%p table:%s, failed to create in dnode, vgId:%d sid:%d uid:%" PRIu64 ", result:%s thandle:%p incomingTs:%d curTs:%d retryTimes:%d", - mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid, - tstrerror(rpcMsg->code), mnodeMsg->rpcMsg.handle, mnodeMsg->incomingTs, sec, mnodeMsg->retry); + pMsg, pMsg->rpcMsg.ahandle, pTable->info.tableId, pTable->vgId, pTable->tid, pTable->uid, + tstrerror(rpcMsg->code), pMsg->rpcMsg.handle, pMsg->incomingTs, sec, pMsg->retry); - SSdbOper oper = {.type = SDB_OPER_GLOBAL, .table = tsChildTableSdb, .pObj = pTable}; - sdbDeleteRow(&oper); + SSdbRow row = {.type = SDB_OPER_GLOBAL, .pTable = tsChildTableSdb, .pObj = pTable}; + sdbDeleteRow(&row); if (rpcMsg->code == TSDB_CODE_APP_NOT_READY) { //Avoid retry again in client rpcMsg->code = TSDB_CODE_MND_VGROUP_NOT_READY; } - dnodeSendRpcMWriteRsp(mnodeMsg, rpcMsg->code); + dnodeSendRpcMWriteRsp(pMsg, rpcMsg->code); } } } @@ -2455,28 +2455,28 @@ static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) { static void mnodeProcessAlterTableRsp(SRpcMsg *rpcMsg) { if (rpcMsg->ahandle == NULL) return; - SMnodeMsg *mnodeMsg = rpcMsg->ahandle; - mnodeMsg->received++; + SMnodeMsg *pMsg = rpcMsg->ahandle; + pMsg->received++; - SCTableObj *pTable = (SCTableObj *)mnodeMsg->pTable; + SCTableObj *pTable = (SCTableObj *)pMsg->pTable; assert(pTable); if (rpcMsg->code == TSDB_CODE_SUCCESS || rpcMsg->code == TSDB_CODE_TDB_TABLE_ALREADY_EXIST) { - mDebug("app:%p:%p, ctable:%s, altered in dnode, thandle:%p result:%s", mnodeMsg->rpcMsg.ahandle, mnodeMsg, - pTable->info.tableId, mnodeMsg->rpcMsg.handle, tstrerror(rpcMsg->code)); + mDebug("msg:%p, app:%p ctable:%s, altered in dnode, thandle:%p result:%s", pMsg, pMsg->rpcMsg.ahandle, + pTable->info.tableId, pMsg->rpcMsg.handle, tstrerror(rpcMsg->code)); - dnodeSendRpcMWriteRsp(mnodeMsg, TSDB_CODE_SUCCESS); + dnodeSendRpcMWriteRsp(pMsg, TSDB_CODE_SUCCESS); } else { - if (mnodeMsg->retry++ < ALTER_CTABLE_RETRY_TIMES) { - mDebug("app:%p:%p, table:%s, alter table rsp received, need retry, times:%d result:%s thandle:%p", - mnodeMsg->rpcMsg.ahandle, mnodeMsg, pTable->info.tableId, mnodeMsg->retry, tstrerror(rpcMsg->code), - mnodeMsg->rpcMsg.handle); + if (pMsg->retry++ < ALTER_CTABLE_RETRY_TIMES) { + mDebug("msg:%p, app:%p table:%s, alter table rsp received, need retry, times:%d result:%s thandle:%p", + pMsg->rpcMsg.ahandle, pMsg, pTable->info.tableId, pMsg->retry, tstrerror(rpcMsg->code), + pMsg->rpcMsg.handle); - dnodeDelayReprocessMWriteMsg(mnodeMsg); + dnodeDelayReprocessMWriteMsg(pMsg); } else { - mError("app:%p:%p, table:%s, failed to alter in dnode, result:%s thandle:%p", mnodeMsg->rpcMsg.ahandle, mnodeMsg, - pTable->info.tableId, tstrerror(rpcMsg->code), mnodeMsg->rpcMsg.handle); - dnodeSendRpcMWriteRsp(mnodeMsg, rpcMsg->code); + mError("msg:%p, app:%p table:%s, failed to alter in dnode, result:%s thandle:%p", pMsg, pMsg->rpcMsg.ahandle, + pTable->info.tableId, tstrerror(rpcMsg->code), pMsg->rpcMsg.handle); + dnodeSendRpcMWriteRsp(pMsg, rpcMsg->code); } } } @@ -2719,12 +2719,12 @@ static int32_t mnodeRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) { SAlterTableMsg *pAlter = pMsg->rpcMsg.pCont; - mDebug("app:%p:%p, table:%s, alter table msg is received from thandle:%p", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p table:%s, alter table msg is received from thandle:%p", pMsg, pMsg->rpcMsg.ahandle, pAlter->tableId, pMsg->rpcMsg.handle); if (pMsg->pDb == NULL) pMsg->pDb = mnodeGetDbByTableId(pAlter->tableId); if (pMsg->pDb == NULL) { - mError("app:%p:%p, table:%s, failed to alter table, db not selected", pMsg->rpcMsg.ahandle, pMsg, pAlter->tableId); + mError("msg:%p, app:%p table:%s, failed to alter table, db not selected", pMsg, pMsg->rpcMsg.ahandle, pAlter->tableId); return TSDB_CODE_MND_DB_NOT_SELECTED; } @@ -2734,13 +2734,13 @@ static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) { } if (mnodeCheckIsMonitorDB(pMsg->pDb->name, tsMonitorDbName)) { - mError("app:%p:%p, table:%s, failed to alter table, its log db", pMsg->rpcMsg.ahandle, pMsg, pAlter->tableId); + mError("msg:%p, app:%p table:%s, failed to alter table, its log db", pMsg, pMsg->rpcMsg.ahandle, pAlter->tableId); return TSDB_CODE_MND_MONITOR_DB_FORBIDDEN; } if (pMsg->pTable == NULL) pMsg->pTable = mnodeGetTable(pAlter->tableId); if (pMsg->pTable == NULL) { - mError("app:%p:%p, table:%s, failed to alter table, table not exist", pMsg->rpcMsg.ahandle, pMsg, pAlter->tableId); + mError("msg:%p, app:%p table:%s, failed to alter table, table not exist", pMsg, pMsg->rpcMsg.ahandle, pAlter->tableId); return TSDB_CODE_MND_INVALID_TABLE_NAME; } @@ -2749,7 +2749,7 @@ static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) { pAlter->tagValLen = htonl(pAlter->tagValLen); if (pAlter->numOfCols > 2) { - mError("app:%p:%p, table:%s, error numOfCols:%d in alter table", pMsg->rpcMsg.ahandle, pMsg, pAlter->tableId, + mError("msg:%p, app:%p table:%s, error numOfCols:%d in alter table", pMsg, pMsg->rpcMsg.ahandle, pAlter->tableId, pAlter->numOfCols); return TSDB_CODE_MND_APP_ERROR; } @@ -2760,7 +2760,7 @@ static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) { int32_t code = TSDB_CODE_COM_OPS_NOT_SUPPORT; if (pMsg->pTable->type == TSDB_SUPER_TABLE) { - mDebug("app:%p:%p, table:%s, start to alter stable", pMsg->rpcMsg.ahandle, pMsg, pAlter->tableId); + mDebug("msg:%p, app:%p table:%s, start to alter stable", pMsg, pMsg->rpcMsg.ahandle, pAlter->tableId); if (pAlter->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) { code = mnodeAddSuperTableTag(pMsg, pAlter->schema, 1); } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) { @@ -2776,7 +2776,7 @@ static int32_t mnodeProcessAlterTableMsg(SMnodeMsg *pMsg) { } else { } } else { - mDebug("app:%p:%p, table:%s, start to alter ctable", pMsg->rpcMsg.ahandle, pMsg, pAlter->tableId); + mDebug("msg:%p, app:%p table:%s, start to alter ctable", pMsg, pMsg->rpcMsg.ahandle, pAlter->tableId); if (pAlter->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) { return TSDB_CODE_COM_OPS_NOT_SUPPORT; } else if (pAlter->type == TSDB_ALTER_TABLE_ADD_COLUMN) { diff --git a/src/mnode/src/mnodeUser.c b/src/mnode/src/mnodeUser.c index cd02d5a935c3ef3cf822d518a9cc3bbd795db46b..dc76d92eb8c2c01396705b33cc9ea55ccc4275df 100644 --- a/src/mnode/src/mnodeUser.c +++ b/src/mnode/src/mnodeUser.c @@ -42,13 +42,13 @@ static int32_t mnodeProcessAlterUserMsg(SMnodeMsg *pMsg); static int32_t mnodeProcessDropUserMsg(SMnodeMsg *pMsg); static int32_t mnodeProcessAuthMsg(SMnodeMsg *pMsg); -static int32_t mnodeUserActionDestroy(SSdbOper *pOper) { - tfree(pOper->pObj); +static int32_t mnodeUserActionDestroy(SSdbRow *pRow) { + tfree(pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t mnodeUserActionInsert(SSdbOper *pOper) { - SUserObj *pUser = pOper->pObj; +static int32_t mnodeUserActionInsert(SSdbRow *pRow) { + SUserObj *pUser = pRow->pObj; SAcctObj *pAcct = mnodeGetAcct(pUser->acct); if (pAcct != NULL) { @@ -62,8 +62,8 @@ static int32_t mnodeUserActionInsert(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeUserActionDelete(SSdbOper *pOper) { - SUserObj *pUser = pOper->pObj; +static int32_t mnodeUserActionDelete(SSdbRow *pRow) { + SUserObj *pUser = pRow->pObj; SAcctObj *pAcct = mnodeGetAcct(pUser->acct); if (pAcct != NULL) { @@ -74,8 +74,8 @@ static int32_t mnodeUserActionDelete(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeUserActionUpdate(SSdbOper *pOper) { - SUserObj *pUser = pOper->pObj; +static int32_t mnodeUserActionUpdate(SSdbRow *pRow) { + SUserObj *pUser = pRow->pObj; SUserObj *pSaved = mnodeGetUser(pUser->user); if (pUser != pSaved) { memcpy(pSaved, pUser, tsUserUpdateSize); @@ -85,19 +85,19 @@ static int32_t mnodeUserActionUpdate(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeUserActionEncode(SSdbOper *pOper) { - SUserObj *pUser = pOper->pObj; - memcpy(pOper->rowData, pUser, tsUserUpdateSize); - pOper->rowSize = tsUserUpdateSize; +static int32_t mnodeUserActionEncode(SSdbRow *pRow) { + SUserObj *pUser = pRow->pObj; + memcpy(pRow->rowData, pUser, tsUserUpdateSize); + pRow->rowSize = tsUserUpdateSize; return TSDB_CODE_SUCCESS; } -static int32_t mnodeUserActionDecode(SSdbOper *pOper) { +static int32_t mnodeUserActionDecode(SSdbRow *pRow) { SUserObj *pUser = (SUserObj *)calloc(1, sizeof(SUserObj)); if (pUser == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - memcpy(pUser, pOper->rowData, tsUserUpdateSize); - pOper->pObj = pUser; + memcpy(pUser, pRow->rowData, tsUserUpdateSize); + pRow->pObj = pUser; return TSDB_CODE_SUCCESS; } @@ -150,25 +150,25 @@ int32_t mnodeInitUsers() { SUserObj tObj; tsUserUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; - SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_USER, - .tableName = "users", + SSdbTableDesc desc = { + .id = SDB_TABLE_USER, + .name = "users", .hashSessions = TSDB_DEFAULT_USERS_HASH_SIZE, .maxRowSize = tsUserUpdateSize, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_STRING, - .insertFp = mnodeUserActionInsert, - .deleteFp = mnodeUserActionDelete, - .updateFp = mnodeUserActionUpdate, - .encodeFp = mnodeUserActionEncode, - .decodeFp = mnodeUserActionDecode, - .destroyFp = mnodeUserActionDestroy, - .restoredFp = mnodeUserActionRestored + .fpInsert = mnodeUserActionInsert, + .fpDelete = mnodeUserActionDelete, + .fpUpdate = mnodeUserActionUpdate, + .fpEncode = mnodeUserActionEncode, + .fpDecode = mnodeUserActionDecode, + .fpDestroy = mnodeUserActionDestroy, + .fpRestored = mnodeUserActionRestored }; - tsUserSdb = sdbOpenTable(&tableDesc); + tsUserSdb = sdbOpenTable(&desc); if (tsUserSdb == NULL) { - mError("table:%s, failed to create hash", tableDesc.tableName); + mError("table:%s, failed to create hash", desc.name); return -1; } @@ -179,7 +179,7 @@ int32_t mnodeInitUsers() { mnodeAddShowRetrieveHandle(TSDB_MGMT_TABLE_USER, mnodeRetrieveUsers); mnodeAddPeerMsgHandle(TSDB_MSG_TYPE_DM_AUTH, mnodeProcessAuthMsg); - mDebug("table:%s, hash is created", tableDesc.tableName); + mDebug("table:%s, hash is created", desc.name); return 0; } @@ -205,14 +205,14 @@ void mnodeDecUserRef(SUserObj *pUser) { } static int32_t mnodeUpdateUser(SUserObj *pUser, void *pMsg) { - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsUserSdb, - .pObj = pUser, - .pMsg = pMsg + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsUserSdb, + .pObj = pUser, + .pMsg = pMsg }; - int32_t code = sdbUpdateRow(&oper); + int32_t code = sdbUpdateRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("user:%s, failed to alter by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code)); } else { @@ -259,15 +259,15 @@ int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) { pUser->superAuth = 1; } - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsUserSdb, - .pObj = pUser, - .rowSize = sizeof(SUserObj), - .pMsg = pMsg + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsUserSdb, + .pObj = pUser, + .rowSize = sizeof(SUserObj), + .pMsg = pMsg }; - code = sdbInsertRow(&oper); + code = sdbInsertRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("user:%s, failed to create by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code)); tfree(pUser); @@ -279,14 +279,14 @@ int32_t mnodeCreateUser(SAcctObj *pAcct, char *name, char *pass, void *pMsg) { } static int32_t mnodeDropUser(SUserObj *pUser, void *pMsg) { - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsUserSdb, - .pObj = pUser, - .pMsg = pMsg + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsUserSdb, + .pObj = pUser, + .pMsg = pMsg }; - int32_t code = sdbDeleteRow(&oper); + int32_t code = sdbDeleteRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("user:%s, failed to drop by %s, reason:%s", pUser->user, mnodeGetUserFromMsg(pMsg), tstrerror(code)); } else { @@ -562,12 +562,12 @@ void mnodeDropAllUsers(SAcctObj *pAcct) { if (pUser == NULL) break; if (strncmp(pUser->acct, pAcct->user, acctNameLen) == 0) { - SSdbOper oper = { - .type = SDB_OPER_LOCAL, - .table = tsUserSdb, - .pObj = pUser, + SSdbRow row = { + .type = SDB_OPER_LOCAL, + .pTable = tsUserSdb, + .pObj = pUser, }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); numOfUsers++; } diff --git a/src/mnode/src/mnodeVgroup.c b/src/mnode/src/mnodeVgroup.c index 9e398e94f136de7324f18ee6bef32fdd4a700b33..f9a49e5ec20d611415023535f3ba2e8fce311054 100644 --- a/src/mnode/src/mnodeVgroup.c +++ b/src/mnode/src/mnodeVgroup.c @@ -72,13 +72,13 @@ static void mnodeDestroyVgroup(SVgObj *pVgroup) { tfree(pVgroup); } -static int32_t mnodeVgroupActionDestroy(SSdbOper *pOper) { - mnodeDestroyVgroup(pOper->pObj); +static int32_t mnodeVgroupActionDestroy(SSdbRow *pRow) { + mnodeDestroyVgroup(pRow->pObj); return TSDB_CODE_SUCCESS; } -static int32_t mnodeVgroupActionInsert(SSdbOper *pOper) { - SVgObj *pVgroup = pOper->pObj; +static int32_t mnodeVgroupActionInsert(SSdbRow *pRow) { + SVgObj *pVgroup = pRow->pObj; // refer to db SDbObj *pDb = mnodeGetDb(pVgroup->dbName); @@ -115,8 +115,8 @@ static int32_t mnodeVgroupActionInsert(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeVgroupActionDelete(SSdbOper *pOper) { - SVgObj *pVgroup = pOper->pObj; +static int32_t mnodeVgroupActionDelete(SSdbRow *pRow) { + SVgObj *pVgroup = pRow->pObj; if (pVgroup->pDb == NULL) { mError("vgId:%d, db:%s is not exist while insert into hash", pVgroup->vgId, pVgroup->dbName); @@ -137,8 +137,8 @@ static int32_t mnodeVgroupActionDelete(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeVgroupActionUpdate(SSdbOper *pOper) { - SVgObj *pNew = pOper->pObj; +static int32_t mnodeVgroupActionUpdate(SSdbRow *pRow) { + SVgObj *pNew = pRow->pObj; SVgObj *pVgroup = mnodeGetVgroup(pNew->vgId); if (pVgroup != pNew) { @@ -176,25 +176,25 @@ static int32_t mnodeVgroupActionUpdate(SSdbOper *pOper) { return TSDB_CODE_SUCCESS; } -static int32_t mnodeVgroupActionEncode(SSdbOper *pOper) { - SVgObj *pVgroup = pOper->pObj; - memcpy(pOper->rowData, pVgroup, tsVgUpdateSize); - SVgObj *pTmpVgroup = pOper->rowData; +static int32_t mnodeVgroupActionEncode(SSdbRow *pRow) { + SVgObj *pVgroup = pRow->pObj; + memcpy(pRow->rowData, pVgroup, tsVgUpdateSize); + SVgObj *pTmpVgroup = pRow->rowData; for (int32_t i = 0; i < TSDB_MAX_REPLICA; ++i) { pTmpVgroup->vnodeGid[i].pDnode = NULL; pTmpVgroup->vnodeGid[i].role = 0; } - pOper->rowSize = tsVgUpdateSize; + pRow->rowSize = tsVgUpdateSize; return TSDB_CODE_SUCCESS; } -static int32_t mnodeVgroupActionDecode(SSdbOper *pOper) { +static int32_t mnodeVgroupActionDecode(SSdbRow *pRow) { SVgObj *pVgroup = (SVgObj *) calloc(1, sizeof(SVgObj)); if (pVgroup == NULL) return TSDB_CODE_MND_OUT_OF_MEMORY; - memcpy(pVgroup, pOper->rowData, tsVgUpdateSize); - pOper->pObj = pVgroup; + memcpy(pVgroup, pRow->rowData, tsVgUpdateSize); + pRow->pObj = pVgroup; return TSDB_CODE_SUCCESS; } @@ -206,23 +206,23 @@ int32_t mnodeInitVgroups() { SVgObj tObj; tsVgUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; - SSdbTableDesc tableDesc = { - .tableId = SDB_TABLE_VGROUP, - .tableName = "vgroups", + SSdbTableDesc desc = { + .id = SDB_TABLE_VGROUP, + .name = "vgroups", .hashSessions = TSDB_DEFAULT_VGROUPS_HASH_SIZE, .maxRowSize = tsVgUpdateSize, .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_AUTO, - .insertFp = mnodeVgroupActionInsert, - .deleteFp = mnodeVgroupActionDelete, - .updateFp = mnodeVgroupActionUpdate, - .encodeFp = mnodeVgroupActionEncode, - .decodeFp = mnodeVgroupActionDecode, - .destroyFp = mnodeVgroupActionDestroy, - .restoredFp = mnodeVgroupActionRestored, + .fpInsert = mnodeVgroupActionInsert, + .fpDelete = mnodeVgroupActionDelete, + .fpUpdate = mnodeVgroupActionUpdate, + .fpEncode = mnodeVgroupActionEncode, + .fpDecode = mnodeVgroupActionDecode, + .fpDestroy = mnodeVgroupActionDestroy, + .fpRestored = mnodeVgroupActionRestored, }; - tsVgroupSdb = sdbOpenTable(&tableDesc); + tsVgroupSdb = sdbOpenTable(&desc); if (tsVgroupSdb == NULL) { mError("failed to init vgroups data"); return -1; @@ -253,13 +253,13 @@ SVgObj *mnodeGetVgroup(int32_t vgId) { } void mnodeUpdateVgroup(SVgObj *pVgroup) { - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsVgroupSdb, - .pObj = pVgroup + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsVgroupSdb, + .pObj = pVgroup }; - int32_t code = sdbUpdateRow(&oper); + int32_t code = sdbUpdateRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mError("vgId:%d, failed to update vgroup", pVgroup->vgId); } @@ -421,7 +421,7 @@ int32_t mnodeGetAvailableVgroup(SMnodeMsg *pMsg, SVgObj **ppVgroup, int32_t *pSi int32_t sid = taosAllocateId(pVgroup->idPool); if (sid <= 0) { - mDebug("app:%p:%p, db:%s, no enough sid in vgId:%d", pMsg->rpcMsg.ahandle, pMsg, pDb->name, pVgroup->vgId); + mDebug("msg:%p, app:%p db:%s, no enough sid in vgId:%d", pMsg, pMsg->rpcMsg.ahandle, pDb->name, pVgroup->vgId); continue; } @@ -442,8 +442,8 @@ int32_t mnodeGetAvailableVgroup(SMnodeMsg *pMsg, SVgObj **ppVgroup, int32_t *pSi int32_t code = TSDB_CODE_MND_NO_ENOUGH_DNODES; if (pDb->numOfVgroups < maxVgroupsPerDb) { - mDebug("app:%p:%p, db:%s, try to create a new vgroup, numOfVgroups:%d maxVgroupsPerDb:%d", pMsg->rpcMsg.ahandle, - pMsg, pDb->name, pDb->numOfVgroups, maxVgroupsPerDb); + mDebug("msg:%p, app:%p db:%s, try to create a new vgroup, numOfVgroups:%d maxVgroupsPerDb:%d", pMsg, + pMsg->rpcMsg.ahandle, pDb->name, pDb->numOfVgroups, maxVgroupsPerDb); pthread_mutex_unlock(&pDb->mutex); code = mnodeCreateVgroup(pMsg); if (code == TSDB_CODE_MND_ACTION_IN_PROGRESS) { @@ -455,8 +455,8 @@ int32_t mnodeGetAvailableVgroup(SMnodeMsg *pMsg, SVgObj **ppVgroup, int32_t *pSi if (pDb->numOfVgroups < 1) { pthread_mutex_unlock(&pDb->mutex); - mDebug("app:%p:%p, db:%s, failed create new vgroup since:%s, numOfVgroups:%d maxVgroupsPerDb:%d ", - pMsg->rpcMsg.ahandle, pMsg, pDb->name, tstrerror(code), pDb->numOfVgroups, maxVgroupsPerDb); + mDebug("msg:%p, app:%p db:%s, failed create new vgroup since:%s, numOfVgroups:%d maxVgroupsPerDb:%d ", pMsg, + pMsg->rpcMsg.ahandle, pDb->name, tstrerror(code), pDb->numOfVgroups, maxVgroupsPerDb); return code; } @@ -474,7 +474,7 @@ int32_t mnodeGetAvailableVgroup(SMnodeMsg *pMsg, SVgObj **ppVgroup, int32_t *pSi int32_t sid = taosAllocateId(pVgroup->idPool); if (sid <= 0) { - mError("app:%p:%p, db:%s, no enough sid in vgId:%d", pMsg->rpcMsg.ahandle, pMsg, pDb->name, pVgroup->vgId); + mError("msg:%p, app:%p db:%s, no enough sid in vgId:%d", pMsg, pMsg->rpcMsg.ahandle, pDb->name, pVgroup->vgId); pthread_mutex_unlock(&pDb->mutex); return TSDB_CODE_MND_NO_ENOUGH_DNODES; } @@ -496,10 +496,10 @@ static int32_t mnodeCreateVgroupFp(SMnodeMsg *pMsg) { SDbObj *pDb = pMsg->pDb; assert(pVgroup); - mInfo("app:%p:%p, vgId:%d, is created in mnode, db:%s replica:%d", pMsg->rpcMsg.ahandle, pMsg, pVgroup->vgId, + mInfo("msg:%p, app:%p vgId:%d, is created in mnode, db:%s replica:%d", pMsg, pMsg->rpcMsg.ahandle, pVgroup->vgId, pDb->name, pVgroup->numOfVnodes); for (int32_t i = 0; i < pVgroup->numOfVnodes; ++i) { - mInfo("app:%p:%p, vgId:%d, index:%d, dnode:%d", pMsg->rpcMsg.ahandle, pMsg, pVgroup->vgId, i, + mInfo("msg:%p, app:%p vgId:%d, index:%d, dnode:%d", pMsg, pMsg->rpcMsg.ahandle, pVgroup->vgId, i, pVgroup->vnodeGid[i].dnodeId); } @@ -517,30 +517,30 @@ static int32_t mnodeCreateVgroupCb(SMnodeMsg *pMsg, int32_t code) { assert(pVgroup); if (code != TSDB_CODE_SUCCESS) { - mError("app:%p:%p, vgId:%d, failed to create in sdb, reason:%s", pMsg->rpcMsg.ahandle, pMsg, pVgroup->vgId, + mError("msg:%p, app:%p vgId:%d, failed to create in sdb, reason:%s", pMsg, pMsg->rpcMsg.ahandle, pVgroup->vgId, tstrerror(code)); - SSdbOper desc = {.type = SDB_OPER_GLOBAL, .pObj = pVgroup, .table = tsVgroupSdb}; + SSdbRow desc = {.type = SDB_OPER_GLOBAL, .pObj = pVgroup, .pTable = tsVgroupSdb}; sdbDeleteRow(&desc); return code; } else { - mInfo("app:%p:%p, vgId:%d, is created in sdb, db:%s replica:%d", pMsg->rpcMsg.ahandle, pMsg, pVgroup->vgId, - pDb->name, pVgroup->numOfVnodes); + mInfo("msg:%p, app:%p vgId:%d, is created in sdb, db:%s replica:%d", pMsg, pMsg->rpcMsg.ahandle, pVgroup->vgId, + pDb->name, pVgroup->numOfVnodes); pVgroup->status = TAOS_VG_STATUS_READY; - SSdbOper desc = {.type = SDB_OPER_GLOBAL, .pObj = pVgroup, .table = tsVgroupSdb}; + SSdbRow desc = {.type = SDB_OPER_GLOBAL, .pObj = pVgroup, .pTable = tsVgroupSdb}; (void)sdbUpdateRow(&desc); dnodeReprocessMWriteMsg(pMsg); return TSDB_CODE_MND_ACTION_IN_PROGRESS; // if (pVgroup->status == TAOS_VG_STATUS_CREATING || pVgroup->status == TAOS_VG_STATUS_READY) { - // mInfo("app:%p:%p, vgId:%d, is created in sdb, db:%s replica:%d", pMsg->rpcMsg.ahandle, pMsg, pVgroup->vgId, + // mInfo("msg:%p, app:%p vgId:%d, is created in sdb, db:%s replica:%d", pMsg, pMsg->rpcMsg.ahandle, pVgroup->vgId, // pDb->name, pVgroup->numOfVnodes); // pVgroup->status = TAOS_VG_STATUS_READY; - // SSdbOper desc = {.type = SDB_OPER_GLOBAL, .pObj = pVgroup, .table = tsVgroupSdb}; + // SSdbRow desc = {.type = SDB_OPER_GLOBAL, .pObj = pVgroup, .pTable = tsVgroupSdb}; // (void)sdbUpdateRow(&desc); // dnodeReprocessMWriteMsg(pMsg); // return TSDB_CODE_MND_ACTION_IN_PROGRESS; // } else { - // mError("app:%p:%p, vgId:%d, is created in sdb, db:%s replica:%d, but vgroup is dropping", pMsg->rpcMsg.ahandle, + // mError("msg:%p, app:%p vgId:%d, is created in sdb, db:%s replica:%d, but vgroup is dropping", pMsg->rpcMsg.ahandle, // pMsg, pVgroup->vgId, pDb->name, pVgroup->numOfVnodes); // return TSDB_CODE_MND_VGROUP_NOT_EXIST; // } @@ -571,16 +571,16 @@ int32_t mnodeCreateVgroup(SMnodeMsg *pMsg) { pMsg->pVgroup = pVgroup; mnodeIncVgroupRef(pVgroup); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsVgroupSdb, - .pObj = pVgroup, - .rowSize = sizeof(SVgObj), - .pMsg = pMsg, - .reqFp = mnodeCreateVgroupFp + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsVgroupSdb, + .pObj = pVgroup, + .rowSize = sizeof(SVgObj), + .pMsg = pMsg, + .fpReq = mnodeCreateVgroupFp }; - code = sdbInsertRow(&oper); + code = sdbInsertRow(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { pMsg->pVgroup = NULL; mnodeDestroyVgroup(pVgroup); @@ -595,12 +595,12 @@ void mnodeDropVgroup(SVgObj *pVgroup, void *ahandle) { } else { mDebug("vgId:%d, replica:%d is deleting from sdb", pVgroup->vgId, pVgroup->numOfVnodes); mnodeSendDropVgroupMsg(pVgroup, NULL); - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsVgroupSdb, - .pObj = pVgroup + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsVgroupSdb, + .pObj = pVgroup }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); } } @@ -770,7 +770,7 @@ static int32_t mnodeRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, v SDnodeObj * pDnode = pVgroup->vnodeGid[i].pDnode; const char *role = "NULL"; if (pDnode != NULL) { - role = mnodeGetMnodeRoleStr(pVgroup->vnodeGid[i].role); + role = syncRole[pVgroup->vnodeGid[i].role]; } pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; @@ -957,28 +957,28 @@ static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg) { if (mnodeMsg->received != mnodeMsg->expected) return; if (mnodeMsg->received == mnodeMsg->successed) { - SSdbOper oper = { + SSdbRow row = { .type = SDB_OPER_GLOBAL, - .table = tsVgroupSdb, + .pTable = tsVgroupSdb, .pObj = pVgroup, .rowSize = sizeof(SVgObj), .pMsg = mnodeMsg, - .writeCb = mnodeCreateVgroupCb + .fpRsp = mnodeCreateVgroupCb }; - int32_t code = sdbInsertRowImp(&oper); + int32_t code = sdbInsertRowToQueue(&row); if (code != TSDB_CODE_SUCCESS && code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { mnodeMsg->pVgroup = NULL; mnodeDestroyVgroup(pVgroup); dnodeSendRpcMWriteRsp(mnodeMsg, code); } } else { - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsVgroupSdb, - .pObj = pVgroup + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsVgroupSdb, + .pObj = pVgroup }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); dnodeSendRpcMWriteRsp(mnodeMsg, mnodeMsg->code); } } @@ -1031,12 +1031,12 @@ static void mnodeProcessDropVnodeRsp(SRpcMsg *rpcMsg) { if (mnodeMsg->received != mnodeMsg->expected) return; - SSdbOper oper = { - .type = SDB_OPER_GLOBAL, - .table = tsVgroupSdb, - .pObj = pVgroup + SSdbRow row = { + .type = SDB_OPER_GLOBAL, + .pTable = tsVgroupSdb, + .pObj = pVgroup }; - int32_t code = sdbDeleteRow(&oper); + int32_t code = sdbDeleteRow(&row); if (code != 0) { code = TSDB_CODE_MND_SDB_ERROR; } @@ -1084,12 +1084,12 @@ void mnodeDropAllDnodeVgroups(SDnodeObj *pDropDnode) { if (pVgroup->vnodeGid[0].dnodeId == pDropDnode->dnodeId) { mnodeDropAllChildTablesInVgroups(pVgroup); - SSdbOper oper = { - .type = SDB_OPER_LOCAL, - .table = tsVgroupSdb, - .pObj = pVgroup, + SSdbRow row = { + .type = SDB_OPER_LOCAL, + .pTable = tsVgroupSdb, + .pObj = pVgroup, }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); numOfVgroups++; } mnodeDecVgroupRef(pVgroup); @@ -1135,12 +1135,12 @@ void mnodeDropAllDbVgroups(SDbObj *pDropDb) { if (pVgroup == NULL) break; if (pVgroup->pDb == pDropDb) { - SSdbOper oper = { - .type = SDB_OPER_LOCAL, - .table = tsVgroupSdb, - .pObj = pVgroup, + SSdbRow row = { + .type = SDB_OPER_LOCAL, + .pTable = tsVgroupSdb, + .pObj = pVgroup, }; - sdbDeleteRow(&oper); + sdbDeleteRow(&row); numOfVgroups++; } diff --git a/src/mnode/src/mnodeWrite.c b/src/mnode/src/mnodeWrite.c index d021745d2b754c21e422f87438d18539a15fd908..8893316ffc2e9ac3291a1411d7ea5054e198ff9b 100644 --- a/src/mnode/src/mnodeWrite.c +++ b/src/mnode/src/mnodeWrite.c @@ -43,7 +43,7 @@ void mnodeAddWriteMsgHandle(uint8_t msgType, int32_t (*fp)(SMnodeMsg *mnodeMsg)) int32_t mnodeProcessWrite(SMnodeMsg *pMsg) { if (pMsg->rpcMsg.pCont == NULL) { - mError("app:%p:%p, msg:%s content is null", pMsg->rpcMsg.ahandle, pMsg, taosMsg[pMsg->rpcMsg.msgType]); + mError("msg:%p, app:%p type:%s content is null", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); return TSDB_CODE_MND_INVALID_MSG_LEN; } @@ -54,15 +54,15 @@ int32_t mnodeProcessWrite(SMnodeMsg *pMsg) { rpcRsp->rsp = epSet; rpcRsp->len = sizeof(SRpcEpSet); - mDebug("app:%p:%p, msg:%s in write queue, will be redirected, numOfEps:%d inUse:%d", pMsg->rpcMsg.ahandle, pMsg, + mDebug("msg:%p, app:%p type:%s in write queue, will be redirected, numOfEps:%d inUse:%d", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], epSet->numOfEps, epSet->inUse); for (int32_t i = 0; i < epSet->numOfEps; ++i) { if (strcmp(epSet->fqdn[i], tsLocalFqdn) == 0 && htons(epSet->port[i]) == tsServerPort) { epSet->inUse = (i + 1) % epSet->numOfEps; - mDebug("app:%p:%p, mnode index:%d ep:%s:%d, set inUse to %d", pMsg->rpcMsg.ahandle, pMsg, i, epSet->fqdn[i], + mDebug("msg:%p, app:%p mnode index:%d ep:%s:%d, set inUse to %d", pMsg, pMsg->rpcMsg.ahandle, i, epSet->fqdn[i], htons(epSet->port[i]), epSet->inUse); } else { - mDebug("app:%p:%p, mnode index:%d ep:%s:%d", pMsg->rpcMsg.ahandle, pMsg, i, epSet->fqdn[i], + mDebug("msg:%p, app:%p mnode index:%d ep:%s:%d", pMsg, pMsg->rpcMsg.ahandle, i, epSet->fqdn[i], htons(epSet->port[i])); } } @@ -71,19 +71,19 @@ int32_t mnodeProcessWrite(SMnodeMsg *pMsg) { } if (tsMnodeProcessWriteMsgFp[pMsg->rpcMsg.msgType] == NULL) { - mError("app:%p:%p, msg:%s not processed", pMsg->rpcMsg.ahandle, pMsg, taosMsg[pMsg->rpcMsg.msgType]); + mError("msg:%p, app:%p type:%s not processed", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); return TSDB_CODE_MND_MSG_NOT_PROCESSED; } int32_t code = mnodeInitMsg(pMsg); if (code != TSDB_CODE_SUCCESS) { - mError("app:%p:%p, msg:%s not processed, reason:%s", pMsg->rpcMsg.ahandle, pMsg, taosMsg[pMsg->rpcMsg.msgType], + mError("msg:%p, app:%p type:%s not processed, reason:%s", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType], tstrerror(code)); return code; } if (!pMsg->pUser->writeAuth) { - mError("app:%p:%p, msg:%s not processed, no write auth", pMsg->rpcMsg.ahandle, pMsg, + mError("msg:%p, app:%p type:%s not processed, no write auth", pMsg, pMsg->rpcMsg.ahandle, taosMsg[pMsg->rpcMsg.msgType]); return TSDB_CODE_MND_NO_RIGHTS; } diff --git a/src/os/inc/osTime.h b/src/os/inc/osTime.h index 6b209219c6c736ed95c69659a78d14037987be00..b20ccadadb22a04733d97bd19b919660ee677d0d 100644 --- a/src/os/inc/osTime.h +++ b/src/os/inc/osTime.h @@ -38,14 +38,14 @@ int32_t taosGetTimestampSec(); static FORCE_INLINE int64_t taosGetTimestampMs() { struct timeval systemTime; gettimeofday(&systemTime, NULL); - return (int64_t)systemTime.tv_sec * 1000L + (uint64_t)systemTime.tv_usec / 1000; + return (int64_t)systemTime.tv_sec * 1000L + (int64_t)systemTime.tv_usec / 1000; } //@return timestamp in microsecond static FORCE_INLINE int64_t taosGetTimestampUs() { struct timeval systemTime; gettimeofday(&systemTime, NULL); - return (int64_t)systemTime.tv_sec * 1000000L + (uint64_t)systemTime.tv_usec; + return (int64_t)systemTime.tv_sec * 1000000L + (int64_t)systemTime.tv_usec; } /* diff --git a/src/os/inc/osWindows.h b/src/os/inc/osWindows.h index 36e30528bf9d84739fd391442145d7e65e1f7df2..5003e48c44a75011a0006a923a6e53d3d7639195 100644 --- a/src/os/inc/osWindows.h +++ b/src/os/inc/osWindows.h @@ -43,6 +43,7 @@ #include "msvcProcess.h" #include "msvcDirect.h" #include "msvcFcntl.h" +#include "msvcLibgen.h" #include "msvcStdio.h" #include "sys/msvcStat.h" #include "sys/msvcTypes.h" diff --git a/src/os/src/windows/wSysinfo.c b/src/os/src/windows/wSysinfo.c index 61adc3ee14ed4a815117d306559970f67a961ea8..1bfee25c4a6a1851bdfbc16e795185412f007df2 100644 --- a/src/os/src/windows/wSysinfo.c +++ b/src/os/src/windows/wSysinfo.c @@ -31,7 +31,10 @@ #pragma comment(lib, "Mswsock.lib ") #endif +#pragma warning(push) +#pragma warning(disable:4091) #include +#pragma warning(pop) static void taosGetSystemTimezone() { // get and set default timezone diff --git a/src/plugins/http/inc/httpInt.h b/src/plugins/http/inc/httpInt.h index affc0e838ea97f25dcb2e53947ecbb7b025dffb1..ebdfabf3101001d020e24bf63c3d699492ff21d0 100644 --- a/src/plugins/http/inc/httpInt.h +++ b/src/plugins/http/inc/httpInt.h @@ -118,7 +118,7 @@ typedef struct { typedef struct { char *module; - bool (*decodeFp)(struct HttpContext *pContext); + bool (*fpDecode)(struct HttpContext *pContext); } HttpDecodeMethod; typedef struct { diff --git a/src/plugins/http/src/httpHandle.c b/src/plugins/http/src/httpHandle.c index b50217cfc4bffe0835de8a744a78997426db6d3b..7c565075147c03cc2d65055c5d4d4773424ab927 100644 --- a/src/plugins/http/src/httpHandle.c +++ b/src/plugins/http/src/httpHandle.c @@ -21,11 +21,11 @@ #include "httpHandle.h" bool httpDecodeRequest(HttpContext* pContext) { - if (pContext->decodeMethod->decodeFp == NULL) { + if (pContext->decodeMethod->fpDecode == NULL) { return false; } - return (*pContext->decodeMethod->decodeFp)(pContext); + return (*pContext->decodeMethod->fpDecode)(pContext); } /** diff --git a/src/plugins/monitor/src/monitorMain.c b/src/plugins/monitor/src/monitorMain.c index de1e0e233c2b1441a00c226d7305f99a6db41109..24998b54cd1a0114697c411fa145465f52e1e48a 100644 --- a/src/plugins/monitor/src/monitorMain.c +++ b/src/plugins/monitor/src/monitorMain.c @@ -148,10 +148,12 @@ static void *monitorThreadFunc(void *param) { } if (tsMonitor.state == MON_STATE_NOT_INIT) { + int code = 0; + for (; tsMonitor.cmdIndex < MON_CMD_MAX; ++tsMonitor.cmdIndex) { monitorBuildMonitorSql(tsMonitor.sql, tsMonitor.cmdIndex); void *res = taos_query(tsMonitor.conn, tsMonitor.sql); - int code = taos_errno(res); + code = taos_errno(res); taos_free_result(res); if (code != 0) { @@ -162,7 +164,7 @@ static void *monitorThreadFunc(void *param) { } } - if (tsMonitor.start) { + if (tsMonitor.start && code == 0) { tsMonitor.state = MON_STATE_INITED; } } diff --git a/src/query/inc/qExecutor.h b/src/query/inc/qExecutor.h index 6b4b188c5ede2fc10baa894a55ad5d2225283d0c..895b414a56287bb6e35bcc0c50adcc338edbee1b 100644 --- a/src/query/inc/qExecutor.h +++ b/src/query/inc/qExecutor.h @@ -171,11 +171,10 @@ typedef struct SQuery { typedef struct SQueryRuntimeEnv { jmp_buf env; - SResultRow* pResultRow; // todo refactor to merge with SWindowResInfo SQuery* pQuery; SQLFunctionCtx* pCtx; int32_t numOfRowsPerPage; - uint16_t offset[TSDB_MAX_COLUMNS]; + uint16_t* offset; uint16_t scanFlag; // denotes reversed scan of data or not SFillInfo* pFillInfo; SWindowResInfo windowResInfo; diff --git a/src/query/inc/qUtil.h b/src/query/inc/qUtil.h index 93dca42fdcfd85b8e11fde205392a15caaa59416..4cd0e60ebed3bc01c40fa8bee1a255fe9d0b132f 100644 --- a/src/query/inc/qUtil.h +++ b/src/query/inc/qUtil.h @@ -34,7 +34,7 @@ int32_t initWindowResInfo(SWindowResInfo* pWindowResInfo, int32_t size, int32_t void cleanupTimeWindowInfo(SWindowResInfo* pWindowResInfo); void resetTimeWindowInfo(SQueryRuntimeEnv* pRuntimeEnv, SWindowResInfo* pWindowResInfo); -void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num); +void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num); void clearClosedTimeWindow(SQueryRuntimeEnv* pRuntimeEnv); int32_t numOfClosedTimeWindow(SWindowResInfo* pWindowResInfo); diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 869f57f117db9b349b6d28cd819c84aa36f82baf..d0874c36bc1783242c8536ebeec1fbce8559389f 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -177,7 +177,7 @@ static void getNextTimeWindow(SQuery* pQuery, STimeWindow* tw) { static int32_t mergeIntoGroupResultImpl(SQInfo *pQInfo, SArray *group); static void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult); -static void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult); +static void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult); static void resetMergeResultBuf(SQueryRuntimeEnv* pRuntimeEnv, SQLFunctionCtx *pCtx, SResultRow *pRow); static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx *pCtx, int32_t functionId); @@ -618,7 +618,7 @@ static int32_t setWindowOutputBufByKey(SQueryRuntimeEnv *pRuntimeEnv, SWindowRes // set time window for current result pResultRow->win = (*win); - setWindowResOutputBufInitCtx(pRuntimeEnv, pResultRow); + setResultRowOutputBufInitCtx(pRuntimeEnv, pResultRow); return TSDB_CODE_SUCCESS; } @@ -660,7 +660,13 @@ static FORCE_INLINE int32_t getForwardStepsInBlock(int32_t numOfRows, __block_se */ static int32_t doCheckQueryCompleted(SQueryRuntimeEnv *pRuntimeEnv, TSKEY lastKey, SWindowResInfo *pWindowResInfo) { SQuery *pQuery = pRuntimeEnv->pQuery; - if (pRuntimeEnv->scanFlag != MASTER_SCAN || (!QUERY_IS_INTERVAL_QUERY(pQuery))) { + if (pRuntimeEnv->scanFlag != MASTER_SCAN) { + return pWindowResInfo->size; + } + + // for group by normal column query, close time window and return. + if (!QUERY_IS_INTERVAL_QUERY(pQuery)) { + closeAllTimeWindow(pWindowResInfo); return pWindowResInfo->size; } @@ -847,35 +853,50 @@ static int32_t getNextQualifiedWindow(SQueryRuntimeEnv *pRuntimeEnv, STimeWindow } int32_t startPos = 0; + // tumbling time window query, a special case of sliding time window query if (pQuery->interval.sliding == pQuery->interval.interval && prevPosition != -1) { int32_t factor = GET_FORWARD_DIRECTION_FACTOR(pQuery->order.order); startPos = prevPosition + factor; } else { - startPos = searchFn((char *)primaryKeys, pDataBlockInfo->rows, startKey, pQuery->order.order); + if (startKey <= pDataBlockInfo->window.skey && QUERY_IS_ASC_QUERY(pQuery)) { + startPos = 0; + } else if (startKey >= pDataBlockInfo->window.ekey && !QUERY_IS_ASC_QUERY(pQuery)) { + startPos = pDataBlockInfo->rows - 1; + } else { + startPos = searchFn((char *)primaryKeys, pDataBlockInfo->rows, startKey, pQuery->order.order); + } } /* * This time window does not cover any data, try next time window, * this case may happen when the time window is too small */ - if (QUERY_IS_ASC_QUERY(pQuery) && primaryKeys[startPos] > pNext->ekey) { - TSKEY next = primaryKeys[startPos]; - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - pNext->skey = taosTimeTruncate(next, &pQuery->interval, pQuery->precision); - pNext->ekey = taosTimeAdd(pNext->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + if (primaryKeys == NULL) { + if (QUERY_IS_ASC_QUERY(pQuery)) { + assert(pDataBlockInfo->window.skey <= pNext->ekey); } else { - pNext->ekey += ((next - pNext->ekey + pQuery->interval.sliding - 1)/pQuery->interval.sliding) * pQuery->interval.sliding; - pNext->skey = pNext->ekey - pQuery->interval.interval + 1; + assert(pDataBlockInfo->window.ekey >= pNext->skey); } - } else if ((!QUERY_IS_ASC_QUERY(pQuery)) && primaryKeys[startPos] < pNext->skey) { - TSKEY next = primaryKeys[startPos]; - if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { - pNext->skey = taosTimeTruncate(next, &pQuery->interval, pQuery->precision); - pNext->ekey = taosTimeAdd(pNext->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; - } else { - pNext->skey -= ((pNext->skey - next + pQuery->interval.sliding - 1) / pQuery->interval.sliding) * pQuery->interval.sliding; - pNext->ekey = pNext->skey + pQuery->interval.interval - 1; + } else { + if (QUERY_IS_ASC_QUERY(pQuery) && primaryKeys[startPos] > pNext->ekey) { + TSKEY next = primaryKeys[startPos]; + if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { + pNext->skey = taosTimeTruncate(next, &pQuery->interval, pQuery->precision); + pNext->ekey = taosTimeAdd(pNext->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + } else { + pNext->ekey += ((next - pNext->ekey + pQuery->interval.sliding - 1)/pQuery->interval.sliding) * pQuery->interval.sliding; + pNext->skey = pNext->ekey - pQuery->interval.interval + 1; + } + } else if ((!QUERY_IS_ASC_QUERY(pQuery)) && primaryKeys[startPos] < pNext->skey) { + TSKEY next = primaryKeys[startPos]; + if (pQuery->interval.intervalUnit == 'n' || pQuery->interval.intervalUnit == 'y') { + pNext->skey = taosTimeTruncate(next, &pQuery->interval, pQuery->precision); + pNext->ekey = taosTimeAdd(pNext->skey, pQuery->interval.interval, pQuery->interval.intervalUnit, pQuery->precision) - 1; + } else { + pNext->skey -= ((pNext->skey - next + pQuery->interval.sliding - 1) / pQuery->interval.sliding) * pQuery->interval.sliding; + pNext->ekey = pNext->skey + pQuery->interval.interval - 1; + } } } @@ -1236,7 +1257,7 @@ static bool functionNeedToExecute(SQueryRuntimeEnv *pRuntimeEnv, SQLFunctionCtx return QUERY_IS_ASC_QUERY(pQuery); } - // todo add comments + // denote the order type if ((functionId == TSDB_FUNC_LAST_DST || functionId == TSDB_FUNC_LAST)) { return pCtx->param[0].i64Key == pQuery->order.order; } @@ -1433,7 +1454,7 @@ static int32_t tableApplyFunctionsOnBlock(SQueryRuntimeEnv *pRuntimeEnv, SDataBl // interval query with limit applied int32_t numOfRes = 0; - if (QUERY_IS_INTERVAL_QUERY(pQuery)) { + if (QUERY_IS_INTERVAL_QUERY(pQuery) || pRuntimeEnv->groupbyNormalCol) { numOfRes = doCheckQueryCompleted(pRuntimeEnv, lastKey, pWindowResInfo); } else { numOfRes = (int32_t)getNumOfResult(pRuntimeEnv); @@ -1606,10 +1627,10 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order SQuery *pQuery = pRuntimeEnv->pQuery; pRuntimeEnv->pCtx = (SQLFunctionCtx *)calloc(pQuery->numOfOutput, sizeof(SQLFunctionCtx)); + pRuntimeEnv->offset = calloc(pQuery->numOfOutput, sizeof(int16_t)); pRuntimeEnv->rowCellInfoOffset = calloc(pQuery->numOfOutput, sizeof(int32_t)); - pRuntimeEnv->pResultRow = getNewResultRow(pRuntimeEnv->pool); - if (pRuntimeEnv->pResultRow == NULL || pRuntimeEnv->pCtx == NULL || pRuntimeEnv->rowCellInfoOffset == NULL) { + if (pRuntimeEnv->offset == NULL || pRuntimeEnv->pCtx == NULL || pRuntimeEnv->rowCellInfoOffset == NULL) { goto _clean; } @@ -1649,15 +1670,15 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order assert(isValidDataType(pCtx->inputType)); pCtx->ptsOutputBuf = NULL; - pCtx->outputBytes = pQuery->pExpr1[i].bytes; - pCtx->outputType = pQuery->pExpr1[i].type; + pCtx->outputBytes = pQuery->pExpr1[i].bytes; + pCtx->outputType = pQuery->pExpr1[i].type; - pCtx->order = pQuery->order.order; - pCtx->functionId = pSqlFuncMsg->functionId; - pCtx->stableQuery = pRuntimeEnv->stableQuery; + pCtx->order = pQuery->order.order; + pCtx->functionId = pSqlFuncMsg->functionId; + pCtx->stableQuery = pRuntimeEnv->stableQuery; pCtx->interBufBytes = pQuery->pExpr1[i].interBytes; - pCtx->numOfParams = pSqlFuncMsg->numOfParams; + pCtx->numOfParams = pSqlFuncMsg->numOfParams; for (int32_t j = 0; j < pCtx->numOfParams; ++j) { int16_t type = pSqlFuncMsg->arg[j].argType; int16_t bytes = pSqlFuncMsg->arg[j].argBytes; @@ -1705,6 +1726,8 @@ static int32_t setupQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv, int16_t order _clean: tfree(pRuntimeEnv->pCtx); + tfree(pRuntimeEnv->offset); + tfree(pRuntimeEnv->rowCellInfoOffset); return TSDB_CODE_QRY_OUT_OF_MEMORY; } @@ -1754,6 +1777,8 @@ static void teardownQueryRuntimeEnv(SQueryRuntimeEnv *pRuntimeEnv) { doFreeQueryHandle(pQInfo); pRuntimeEnv->pTSBuf = tsBufDestroy(pRuntimeEnv->pTSBuf); + + tfree(pRuntimeEnv->offset); tfree(pRuntimeEnv->keyBuf); tfree(pRuntimeEnv->rowCellInfoOffset); @@ -2394,7 +2419,7 @@ static void ensureOutputBufferSimple(SQueryRuntimeEnv* pRuntimeEnv, int32_t capa assert(bytes > 0 && capacity > 0); char *tmp = realloc(pQuery->sdata[i], bytes * capacity + sizeof(tFilePage)); - if (tmp == NULL) { // todo handle the oom + if (tmp == NULL) { longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } else { pQuery->sdata[i] = (tFilePage *)tmp; @@ -2425,7 +2450,7 @@ static void ensureOutputBuffer(SQueryRuntimeEnv* pRuntimeEnv, SDataBlockInfo* pB assert(bytes > 0 && newSize > 0); char *tmp = realloc(pQuery->sdata[i], bytes * newSize + sizeof(tFilePage)); - if (tmp == NULL) { // todo handle the oom + if (tmp == NULL) { longjmp(pRuntimeEnv->env, TSDB_CODE_QRY_OUT_OF_MEMORY); } else { memset(tmp + sizeof(tFilePage) + bytes * pRec->rows, 0, (size_t)((newSize - pRec->rows) * bytes)); @@ -3316,7 +3341,10 @@ int32_t initResultRow(SResultRow *pResultRow) { void resetCtxOutputBuf(SQueryRuntimeEnv *pRuntimeEnv) { SQuery *pQuery = pRuntimeEnv->pQuery; - SResultRow* pRow = pRuntimeEnv->pResultRow; + + int32_t groupIndex = 0; + int32_t uid = 0; + SResultRow* pRow = doPrepareResultRowFromKey(pRuntimeEnv, &pRuntimeEnv->windowResInfo, (char *)&groupIndex, sizeof(groupIndex), true, uid); for (int32_t i = 0; i < pQuery->numOfOutput; ++i) { SQLFunctionCtx *pCtx = &pRuntimeEnv->pCtx[i]; @@ -3811,7 +3839,7 @@ void setResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult) { } } -void setWindowResOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult) { +void setResultRowOutputBufInitCtx(SQueryRuntimeEnv *pRuntimeEnv, SResultRow *pResult) { SQuery *pQuery = pRuntimeEnv->pQuery; // Note: pResult->pos[i]->num == 0, there is only fixed number of results for each group @@ -4598,12 +4626,6 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo tsBufSetTraverseOrder(pRuntimeEnv->pTSBuf, order); } - // create runtime environment - code = setupQueryRuntimeEnv(pRuntimeEnv, pQuery->order.order); - if (code != TSDB_CODE_SUCCESS) { - return code; - } - int32_t ps = DEFAULT_PAGE_SIZE; int32_t rowsize = 0; getIntermediateBufInfo(pRuntimeEnv, &ps, &rowsize); @@ -4635,7 +4657,7 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo return code; } } - } else if (pRuntimeEnv->groupbyNormalCol || QUERY_IS_INTERVAL_QUERY(pQuery)) { + } else if (pRuntimeEnv->groupbyNormalCol || QUERY_IS_INTERVAL_QUERY(pQuery) || (!isSTableQuery)) { int32_t numOfResultRows = getInitialPageNum(pQInfo); getIntermediateBufInfo(pRuntimeEnv, &ps, &rowsize); code = createDiskbasedResultBuffer(&pRuntimeEnv->pResultBuf, rowsize, ps, TWOMB, pQInfo); @@ -4656,6 +4678,12 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo } } + // create runtime environment + code = setupQueryRuntimeEnv(pRuntimeEnv, pQuery->order.order); + if (code != TSDB_CODE_SUCCESS) { + return code; + } + if (pQuery->fillType != TSDB_FILL_NONE && !isPointInterpoQuery(pQuery)) { SFillColInfo* pColInfo = createFillColInfo(pQuery); STimeWindow w = TSWINDOW_INITIALIZER; @@ -5336,8 +5364,11 @@ static char *getArithemicInputSrc(void *param, const char *name, int32_t colId) } static void doSecondaryArithmeticProcess(SQuery* pQuery) { - SArithmeticSupport arithSup = {0}; + if (pQuery->numOfExpr2 == 0) { + return; + } + SArithmeticSupport arithSup = {0}; tFilePage **data = calloc(pQuery->numOfExpr2, POINTER_BYTES); for (int32_t i = 0; i < pQuery->numOfExpr2; ++i) { int32_t bytes = pQuery->pExpr2[i].bytes; @@ -5494,7 +5525,7 @@ static void tableIntervalProcessImpl(SQueryRuntimeEnv *pRuntimeEnv, TSKEY start) int32_t numOfClosed = numOfClosedTimeWindow(&pRuntimeEnv->windowResInfo); int32_t c = (int32_t)(MIN(numOfClosed, pQuery->limit.offset)); - clearFirstNTimeWindow(pRuntimeEnv, c); + clearFirstNWindowRes(pRuntimeEnv, c); pQuery->limit.offset -= c; } @@ -5515,10 +5546,12 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) { TSKEY newStartKey = TSKEY_INITIAL_VAL; // skip blocks without load the actual data block from file if no filter condition present - skipTimeInterval(pRuntimeEnv, &newStartKey); - if (pQuery->limit.offset > 0 && pQuery->numOfFilterCols == 0 && pRuntimeEnv->pFillInfo == NULL) { - setQueryStatus(pQuery, QUERY_COMPLETED); - return; + if (!pRuntimeEnv->groupbyNormalCol) { + skipTimeInterval(pRuntimeEnv, &newStartKey); + if (pQuery->limit.offset > 0 && pQuery->numOfFilterCols == 0 && pRuntimeEnv->pFillInfo == NULL) { + setQueryStatus(pQuery, QUERY_COMPLETED); + return; + } } while (1) { @@ -5529,11 +5562,11 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) { pQuery->rec.rows = 0; copyFromWindowResToSData(pQInfo, &pRuntimeEnv->windowResInfo); - clearFirstNTimeWindow(pRuntimeEnv, pQInfo->groupIndex); + clearFirstNWindowRes(pRuntimeEnv, pQInfo->groupIndex); } // no result generated, abort - if (pQuery->rec.rows == 0) { + if (pQuery->rec.rows == 0 || pRuntimeEnv->groupbyNormalCol) { break; } @@ -5561,10 +5594,21 @@ static void tableIntervalProcess(SQInfo *pQInfo, STableQueryInfo* pTableInfo) { // all data scanned, the group by normal column can return if (pRuntimeEnv->groupbyNormalCol) { // todo refactor with merge interval time result - pQInfo->groupIndex = 0; - pQuery->rec.rows = 0; - copyFromWindowResToSData(pQInfo, &pRuntimeEnv->windowResInfo); - clearFirstNTimeWindow(pRuntimeEnv, pQInfo->groupIndex); + // maxOutput <= 0, means current query does not generate any results + int32_t numOfClosed = numOfClosedTimeWindow(&pRuntimeEnv->windowResInfo); + + if ((pQuery->limit.offset > 0 && pQuery->limit.offset < numOfClosed) || pQuery->limit.offset == 0) { + // skip offset result rows + clearFirstNWindowRes(pRuntimeEnv, (int32_t) pQuery->limit.offset); + + pQuery->rec.rows = 0; + pQInfo->groupIndex = 0; + copyFromWindowResToSData(pQInfo, &pRuntimeEnv->windowResInfo); + clearFirstNWindowRes(pRuntimeEnv, pQInfo->groupIndex); + + doSecondaryArithmeticProcess(pQuery); + limitResults(pRuntimeEnv); + } } } @@ -5594,7 +5638,7 @@ static void tableQueryImpl(SQInfo *pQInfo) { if (pRuntimeEnv->windowResInfo.size > 0) { copyFromWindowResToSData(pQInfo, &pRuntimeEnv->windowResInfo); - clearFirstNTimeWindow(pRuntimeEnv, pQInfo->groupIndex); + clearFirstNWindowRes(pRuntimeEnv, pQInfo->groupIndex); if (pQuery->rec.rows > 0) { qDebug("QInfo:%p %"PRId64" rows returned from group results, total:%"PRId64"", pQInfo, pQuery->rec.rows, pQuery->rec.total); diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c index 17642892196d2aa6efa64cc674746b0284424c3a..ca1203cb17da52b8ffe638e29913b06bdfcade29 100644 --- a/src/query/src/qFill.c +++ b/src/query/src/qFill.c @@ -332,7 +332,7 @@ static void doFillOneRowResult(SFillInfo* pFillInfo, tFilePage** data, char** sr point1 = (SPoint){.key = *(TSKEY*)(prev), .val = prev + pCol->col.offset}; point2 = (SPoint){.key = ts, .val = srcData[i] + pFillInfo->index * bytes}; - point = (SPoint){.key = pFillInfo->start, .val = val1}; + point = (SPoint){.key = pFillInfo->currentKey, .val = val1}; taosGetLinearInterpolationVal(type, &point1, &point2, &point); } } else { diff --git a/src/query/src/qParserImpl.c b/src/query/src/qParserImpl.c index 4481ff5e8fbbf0244ec664e4c699e4747ebd7e92..0853565fc633d9ed32eb4d562dd4f2901c059d04 100644 --- a/src/query/src/qParserImpl.c +++ b/src/query/src/qParserImpl.c @@ -225,7 +225,8 @@ tSQLExpr *tSQLExprCreate(tSQLExpr *pLeft, tSQLExpr *pRight, int32_t optrType) { tSQLExprDestroy(pLeft); tSQLExprDestroy(pRight); - } else if ((pLeft->nSQLOptr == TK_FLOAT && pRight->nSQLOptr == TK_INTEGER) || (pLeft->nSQLOptr == TK_INTEGER && pRight->nSQLOptr == TK_FLOAT)) { + } else if ((pLeft->nSQLOptr == TK_FLOAT && pRight->nSQLOptr == TK_INTEGER) || (pLeft->nSQLOptr == TK_INTEGER && pRight->nSQLOptr == TK_FLOAT) || + (pLeft->nSQLOptr == TK_FLOAT && pRight->nSQLOptr == TK_FLOAT)) { pExpr->val.nType = TSDB_DATA_TYPE_DOUBLE; pExpr->nSQLOptr = TK_FLOAT; diff --git a/src/query/src/qResultbuf.c b/src/query/src/qResultbuf.c index 2645cff678b7fe91f62dda0f3fe65f3a968f9c11..c5ba551f204d72424e11f3e0ef29029a03e1c207 100644 --- a/src/query/src/qResultbuf.c +++ b/src/query/src/qResultbuf.c @@ -165,7 +165,7 @@ static char* doFlushPageToDisk(SDiskbasedResultBuf* pResultBuf, SPageInfo* pg) { static char* flushPageToDisk(SDiskbasedResultBuf* pResultBuf, SPageInfo* pg) { int32_t ret = TSDB_CODE_SUCCESS; - assert(pResultBuf->numOfPages * pResultBuf->pageSize == pResultBuf->totalBufSize && pResultBuf->numOfPages >= pResultBuf->inMemPages); + assert(((int64_t) pResultBuf->numOfPages * pResultBuf->pageSize) == pResultBuf->totalBufSize && pResultBuf->numOfPages >= pResultBuf->inMemPages); if (pResultBuf->file == NULL) { if ((ret = createDiskFile(pResultBuf)) != TSDB_CODE_SUCCESS) { diff --git a/src/query/src/qUtil.c b/src/query/src/qUtil.c index f4f89a8709a16d0d84ff8333cc6ef3d4463b6c64..c5317226c7c9a8113395a5ae9502ff1835043acb 100644 --- a/src/query/src/qUtil.c +++ b/src/query/src/qUtil.c @@ -53,7 +53,7 @@ void cleanupTimeWindowInfo(SWindowResInfo *pWindowResInfo) { return; } if (pWindowResInfo->capacity == 0) { - assert(/*pWindowResInfo->hashList == NULL && */pWindowResInfo->pResult == NULL); + assert(pWindowResInfo->pResult == NULL); return; } @@ -64,10 +64,18 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0) { return; } - + +// assert(pWindowResInfo->size == 1); + for (int32_t i = 0; i < pWindowResInfo->size; ++i) { SResultRow *pWindowRes = pWindowResInfo->pResult[i]; clearResultRow(pRuntimeEnv, pWindowRes); + + int32_t groupIndex = 0; + int64_t uid = 0; + + SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, &groupIndex, sizeof(groupIndex), uid); + taosHashRemove(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(sizeof(groupIndex))); } pWindowResInfo->curIndex = -1; @@ -77,7 +85,7 @@ void resetTimeWindowInfo(SQueryRuntimeEnv *pRuntimeEnv, SWindowResInfo *pWindowR pWindowResInfo->prevSKey = TSKEY_INITIAL_VAL; } -void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) { +void clearFirstNWindowRes(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) { SWindowResInfo *pWindowResInfo = &pRuntimeEnv->windowResInfo; if (pWindowResInfo == NULL || pWindowResInfo->capacity == 0 || pWindowResInfo->size == 0 || num == 0) { return; @@ -88,6 +96,11 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) { int16_t type = pWindowResInfo->type; STableId* id = TSDB_TABLEID(pRuntimeEnv->pQuery->current->pTable); // uid is always set to be 0. + int64_t uid = id->uid; + if (pRuntimeEnv->groupbyNormalCol) { + uid = 0; + } + char *key = NULL; int16_t bytes = -1; @@ -97,14 +110,14 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) { // todo refactor if (type == TSDB_DATA_TYPE_BINARY || type == TSDB_DATA_TYPE_NCHAR) { - key = varDataVal(pResult->key); + key = varDataVal(pResult->key); bytes = varDataLen(pResult->key); } else { key = (char*) &pResult->win.skey; bytes = tDataTypeDesc[pWindowResInfo->type].nSize; } - SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, id->uid); + SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid); taosHashRemove(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes)); } else { break; @@ -137,14 +150,14 @@ void clearFirstNTimeWindow(SQueryRuntimeEnv *pRuntimeEnv, int32_t num) { bytes = tDataTypeDesc[pWindowResInfo->type].nSize; } - SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, id->uid); + SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid); int32_t *p = (int32_t *)taosHashGet(pRuntimeEnv->pResultRowHashTable, (const char *)pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes)); assert(p != NULL); int32_t v = (*p - num); assert(v >= 0 && v <= pWindowResInfo->size); - SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, id->uid); + SET_RES_WINDOW_KEY(pRuntimeEnv->keyBuf, key, bytes, uid); taosHashPut(pRuntimeEnv->pResultRowHashTable, pRuntimeEnv->keyBuf, GET_RES_WINDOW_KEY_LEN(bytes), (char *)&v, sizeof(int32_t)); } @@ -158,7 +171,7 @@ void clearClosedTimeWindow(SQueryRuntimeEnv *pRuntimeEnv) { } int32_t numOfClosed = numOfClosedTimeWindow(pWindowResInfo); - clearFirstNTimeWindow(pRuntimeEnv, numOfClosed); + clearFirstNWindowRes(pRuntimeEnv, numOfClosed); } int32_t numOfClosedTimeWindow(SWindowResInfo *pWindowResInfo) { diff --git a/src/sync/inc/syncInt.h b/src/sync/inc/syncInt.h index 7156a2d08a83fc4a36f82be9898b794032639de8..7dbb1985d4cd6e68b7009004a563f66ab63a6697 100644 --- a/src/sync/inc/syncInt.h +++ b/src/sync/inc/syncInt.h @@ -27,16 +27,20 @@ extern "C" { #define sDebug(...) { if (sDebugFlag & DEBUG_DEBUG) { taosPrintLog("SYN ", sDebugFlag, __VA_ARGS__); }} #define sTrace(...) { if (sDebugFlag & DEBUG_TRACE) { taosPrintLog("SYN ", sDebugFlag, __VA_ARGS__); }} -#define TAOS_SMSG_SYNC_DATA 1 -#define TAOS_SMSG_FORWARD 2 -#define TAOS_SMSG_FORWARD_RSP 3 -#define TAOS_SMSG_SYNC_REQ 4 -#define TAOS_SMSG_SYNC_RSP 5 -#define TAOS_SMSG_SYNC_MUST 6 -#define TAOS_SMSG_STATUS 7 +typedef enum { + TAOS_SMSG_SYNC_DATA = 1, + TAOS_SMSG_FORWARD = 2, + TAOS_SMSG_FORWARD_RSP = 3, + TAOS_SMSG_SYNC_REQ = 4, + TAOS_SMSG_SYNC_RSP = 5, + TAOS_SMSG_SYNC_MUST = 6, + TAOS_SMSG_STATUS = 7 +} ESyncMsgType; #define SYNC_MAX_SIZE (TSDB_MAX_WAL_SIZE + sizeof(SWalHead) + sizeof(SSyncHead) + 16) #define SYNC_RECV_BUFFER_SIZE (5*1024*1024) +#define SYNC_FWD_TIMER 300 +#define SYNC_ROLE_TIMER 10000 #define nodeRole pNode->peerInfo[pNode->selfIndex]->role #define nodeVersion pNode->peerInfo[pNode->selfIndex]->version @@ -68,6 +72,9 @@ typedef struct { typedef struct { int8_t role; int8_t ack; + int8_t type; + int8_t reserved[3]; + uint16_t tranId; uint64_t version; SPeerStatus peersStatus[]; } SPeersStatus; @@ -106,7 +113,7 @@ typedef struct { int8_t nacks; int8_t confirmed; int32_t code; - uint64_t time; + int64_t time; } SFwdInfo; typedef struct { @@ -120,12 +127,12 @@ typedef struct SsyncPeer { int32_t nodeId; uint32_t ip; uint16_t port; + int8_t role; + int8_t sstatus; // sync status char fqdn[TSDB_FQDN_LEN]; // peer ip string char id[TSDB_EP_LEN + 32]; // peer vgId + end point - int8_t role; - int8_t sstatus; // sync status uint64_t version; - uint64_t sversion; // track the peer version in retrieve process + uint64_t sversion; // track the peer version in retrieve process int32_t syncFd; int32_t peerFd; // forward FD int32_t numOfRetrieves; // number of retrieves tried @@ -135,7 +142,7 @@ typedef struct SsyncPeer { int32_t notifyFd; int32_t watchNum; int32_t *watchFd; - int8_t refCount; // reference count + int32_t refCount; // reference count struct SSyncNode *pSyncNode; } SSyncPeer; @@ -143,29 +150,29 @@ typedef struct SSyncNode { char path[TSDB_FILENAME_LEN]; int8_t replica; int8_t quorum; + int8_t selfIndex; uint32_t vgId; int64_t rid; - void *ahandle; - int8_t selfIndex; - SSyncPeer *peerInfo[TAOS_SYNC_MAX_REPLICA+1]; // extra one for arbitrator - SSyncPeer *pMaster; - int8_t refCount; + SSyncPeer * peerInfo[TAOS_SYNC_MAX_REPLICA + 1]; // extra one for arbitrator + SSyncPeer * pMaster; SRecvBuffer *pRecv; - SSyncFwds *pSyncFwds; // saved forward info if quorum >1 - void *pFwdTimer; - FGetFileInfo getFileInfo; - FGetWalInfo getWalInfo; - FWriteToCache writeToCache; - FConfirmForward confirmForward; - FNotifyRole notifyRole; - FNotifyFlowCtrl notifyFlowCtrl; + SSyncFwds * pSyncFwds; // saved forward info if quorum >1 + void * pFwdTimer; + void * pRoleTimer; + FGetFileInfo getFileInfo; + FGetWalInfo getWalInfo; + FWriteToCache writeToCache; + FConfirmForward confirmForward; + FNotifyRole notifyRole; + FNotifyFlowCtrl notifyFlowCtrl; FNotifyFileSynced notifyFileSynced; - pthread_mutex_t mutex; + pthread_mutex_t mutex; } SSyncNode; // sync module global extern int32_t tsSyncNum; extern char tsNodeFqdn[TSDB_FQDN_LEN]; +extern char * syncStatus[]; void *syncRetrieveData(void *param); void *syncRestoreData(void *param); diff --git a/src/sync/src/syncMain.c b/src/sync/src/syncMain.c index 6ff04aad64b4a987aa9e8cd1370db1e1aff5f70c..8d3997a5d695916bf229715f3f68345568e80d05 100644 --- a/src/sync/src/syncMain.c +++ b/src/sync/src/syncMain.c @@ -13,8 +13,7 @@ * along with this program. If not, see . */ -//#include -//#include +#define _DEFAULT_SOURCE #include "os.h" #include "hash.h" #include "tlog.h" @@ -50,7 +49,7 @@ static int32_t tsSyncRefId = -1; static void syncProcessSyncRequest(char *pMsg, SSyncPeer *pPeer); static void syncRecoverFromMaster(SSyncPeer *pPeer); static void syncCheckPeerConnection(void *param, void *tmrId); -static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack); +static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type, uint16_t tranId); static void syncProcessBrokenLink(void *param); static int32_t syncProcessPeerMsg(void *param, void *buffer); static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp); @@ -59,6 +58,7 @@ static void syncAddArbitrator(SSyncNode *pNode); static void syncFreeNode(void *); static void syncRemoveConfirmedFwdInfo(SSyncNode *pNode); static void syncMonitorFwdInfos(void *param, void *tmrId); +static void syncMonitorNodeRole(void *param, void *tmrId); static void syncProcessFwdAck(SSyncNode *pNode, SFwdInfo *pFwdInfo, int32_t code); static void syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle); static void syncRestartPeer(SSyncPeer *pPeer); @@ -73,8 +73,42 @@ char* syncRole[] = { "master" }; +char *syncStatus[] = { + "init", + "start", + "file", + "cache", + "invalid" +}; + +typedef enum { + SYNC_STATUS_BROADCAST, + SYNC_STATUS_BROADCAST_RSP, + SYNC_STATUS_SETUP_CONN, + SYNC_STATUS_SETUP_CONN_RSP, + SYNC_STATUS_EXCHANGE_DATA, + SYNC_STATUS_EXCHANGE_DATA_RSP, + SYNC_STATUS_CHECK_ROLE, + SYNC_STATUS_CHECK_ROLE_RSP +} ESyncStatusType; + +char *statusType[] = { + "broadcast", + "broadcast-rsp", + "setup-conn", + "setup-conn-rsp", + "exchange-data", + "exchange-data-rsp", + "check-role", + "check-role-rsp" +}; + +uint16_t syncGenTranId() { + return taosRand() & 0XFFFF; +} + int32_t syncInit() { - SPoolInfo info; + SPoolInfo info = {0}; info.numOfThreads = tsSyncTcpThreads; info.serverIp = 0; @@ -98,7 +132,7 @@ int32_t syncInit() { return -1; } - tsVgIdHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true); + tsVgIdHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); if (tsVgIdHash == NULL) { sError("failed to init tsVgIdHash"); taosTmrCleanUp(tsSyncTmrCtrl); @@ -145,7 +179,7 @@ void syncCleanUp() { int64_t syncStart(const SSyncInfo *pInfo) { const SSyncCfg *pCfg = &pInfo->syncCfg; - SSyncNode *pNode = (SSyncNode *)calloc(sizeof(SSyncNode), 1); + SSyncNode *pNode = calloc(sizeof(SSyncNode), 1); if (pNode == NULL) { sError("no memory to allocate syncNode"); terrno = TAOS_SYSTEM_ERROR(errno); @@ -155,7 +189,6 @@ int64_t syncStart(const SSyncInfo *pInfo) { tstrncpy(pNode->path, pInfo->path, sizeof(pNode->path)); pthread_mutex_init(&pNode->mutex, NULL); - pNode->ahandle = pInfo->ahandle; pNode->getFileInfo = pInfo->getFileInfo; pNode->getWalInfo = pInfo->getWalInfo; pNode->writeToCache = pInfo->writeToCache; @@ -176,18 +209,18 @@ int64_t syncStart(const SSyncInfo *pInfo) { return -1; } - for (int32_t i = 0; i < pCfg->replica; ++i) { - const SNodeInfo *pNodeInfo = pCfg->nodeInfo + i; - pNode->peerInfo[i] = syncAddPeer(pNode, pNodeInfo); - if (pNode->peerInfo[i] == NULL) { - sError("vgId:%d, node:%d fqdn:%s port:%u is not configured, stop taosd", pNode->vgId, pNodeInfo->nodeId, pNodeInfo->nodeFqdn, - pNodeInfo->nodePort); + for (int32_t index = 0; index < pCfg->replica; ++index) { + const SNodeInfo *pNodeInfo = pCfg->nodeInfo + index; + pNode->peerInfo[index] = syncAddPeer(pNode, pNodeInfo); + if (pNode->peerInfo[index] == NULL) { + sError("vgId:%d, node:%d fqdn:%s port:%u is not configured, stop taosd", pNode->vgId, pNodeInfo->nodeId, + pNodeInfo->nodeFqdn, pNodeInfo->nodePort); syncStop(pNode->rid); exit(1); } if ((strcmp(pNodeInfo->nodeFqdn, tsNodeFqdn) == 0) && (pNodeInfo->nodePort == tsSyncPort)) { - pNode->selfIndex = i; + pNode->selfIndex = index; } } @@ -211,18 +244,25 @@ int64_t syncStart(const SSyncInfo *pInfo) { return -1; } - pNode->pFwdTimer = taosTmrStart(syncMonitorFwdInfos, 300, (void *)pNode->rid, tsSyncTmrCtrl); + pNode->pFwdTimer = taosTmrStart(syncMonitorFwdInfos, SYNC_FWD_TIMER, (void *)pNode->rid, tsSyncTmrCtrl); if (pNode->pFwdTimer == NULL) { - sError("vgId:%d, failed to allocate timer", pNode->vgId); + sError("vgId:%d, failed to allocate fwd timer", pNode->vgId); + syncStop(pNode->rid); + return -1; + } + + pNode->pRoleTimer = taosTmrStart(syncMonitorNodeRole, SYNC_ROLE_TIMER, (void *)pNode->rid, tsSyncTmrCtrl); + if (pNode->pRoleTimer == NULL) { + sError("vgId:%d, failed to allocate role timer", pNode->vgId); syncStop(pNode->rid); return -1; } syncAddArbitrator(pNode); - taosHashPut(tsVgIdHash, (const char *)&pNode->vgId, sizeof(int32_t), (char *)(&pNode), sizeof(SSyncNode *)); + taosHashPut(tsVgIdHash, &pNode->vgId, sizeof(int32_t), &pNode, sizeof(SSyncNode *)); if (pNode->notifyRole) { - (*pNode->notifyRole)(pNode->ahandle, nodeRole); + (*pNode->notifyRole)(pNode->vgId, nodeRole); } return pNode->rid; @@ -236,20 +276,21 @@ void syncStop(int64_t rid) { sInfo("vgId:%d, cleanup sync", pNode->vgId); - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); - if (tsVgIdHash) taosHashRemove(tsVgIdHash, (const char *)&pNode->vgId, sizeof(int32_t)); + if (tsVgIdHash) taosHashRemove(tsVgIdHash, &pNode->vgId, sizeof(int32_t)); if (pNode->pFwdTimer) taosTmrStop(pNode->pFwdTimer); + if (pNode->pRoleTimer) taosTmrStop(pNode->pRoleTimer); - for (int32_t i = 0; i < pNode->replica; ++i) { - pPeer = pNode->peerInfo[i]; + for (int32_t index = 0; index < pNode->replica; ++index) { + pPeer = pNode->peerInfo[index]; if (pPeer) syncRemovePeer(pPeer); } pPeer = pNode->peerInfo[TAOS_SYNC_MAX_REPLICA]; if (pPeer) syncRemovePeer(pPeer); - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); taosReleaseRef(tsSyncRefId, rid); taosRemoveRef(tsSyncRefId, rid); @@ -264,7 +305,7 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) { sInfo("vgId:%d, reconfig, role:%s replica:%d old:%d", pNode->vgId, syncRole[nodeRole], pNewCfg->replica, pNode->replica); - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); for (i = 0; i < pNode->replica; ++i) { for (j = 0; j < pNewCfg->replica; ++j) { @@ -314,17 +355,15 @@ int32_t syncReconfig(int64_t rid, const SSyncCfg *pNewCfg) { if (pNewCfg->replica <= 1) { sInfo("vgId:%d, no peers are configured, work as master!", pNode->vgId); nodeRole = TAOS_SYNC_ROLE_MASTER; - (*pNode->notifyRole)(pNode->ahandle, nodeRole); + (*pNode->notifyRole)(pNode->vgId, nodeRole); } - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); - sInfo("vgId:%d, %d replicas are configured, quorum:%d role:%s", pNode->vgId, pNode->replica, pNode->quorum, - syncRole[nodeRole]); + sInfo("vgId:%d, %d replicas are configured, quorum:%d", pNode->vgId, pNode->replica, pNode->quorum); syncBroadcastStatus(pNode); taosReleaseRef(tsSyncRefId, rid); - return 0; } @@ -356,10 +395,10 @@ void syncConfirmForward(int64_t rid, uint64_t version, int32_t code) { pFwdRsp->code = code; int32_t msgLen = sizeof(SSyncHead) + sizeof(SFwdRsp); - int32_t retLen = write(pPeer->peerFd, msg, msgLen); + int32_t retLen = taosWriteMsg(pPeer->peerFd, msg, msgLen); if (retLen == msgLen) { - sDebug("%s, forward-rsp is sent, code:%x hver:%" PRIu64, pPeer->id, code, version); + sTrace("%s, forward-rsp is sent, code:%x hver:%" PRIu64, pPeer->id, code, version); } else { sDebug("%s, failed to send forward ack, restart", pPeer->id); syncRestartConnection(pPeer); @@ -369,6 +408,7 @@ void syncConfirmForward(int64_t rid, uint64_t version, int32_t code) { taosReleaseRef(tsSyncRefId, rid); } +#if 0 void syncRecover(int64_t rid) { SSyncPeer *pPeer; @@ -379,22 +419,23 @@ void syncRecover(int64_t rid) { // if take this node to unsync state, the whole system may not work nodeRole = TAOS_SYNC_ROLE_UNSYNCED; - (*pNode->notifyRole)(pNode->ahandle, nodeRole); + (*pNode->notifyRole)(pNode->vgId, nodeRole); nodeVersion = 0; - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); for (int32_t i = 0; i < pNode->replica; ++i) { - pPeer = (SSyncPeer *)pNode->peerInfo[i]; + pPeer = pNode->peerInfo[i]; if (pPeer->peerFd >= 0) { syncRestartConnection(pPeer); } } - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); taosReleaseRef(tsSyncRefId, rid); } +#endif int32_t syncGetNodesRole(int64_t rid, SNodesRole *pNodesRole) { SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid); @@ -449,10 +490,10 @@ static void syncFreeNode(void *param) { tfree(pNode); } -void syncAddPeerRef(SSyncPeer *pPeer) { atomic_add_fetch_8(&pPeer->refCount, 1); } +void syncAddPeerRef(SSyncPeer *pPeer) { atomic_add_fetch_32(&pPeer->refCount, 1); } int32_t syncDecPeerRef(SSyncPeer *pPeer) { - if (atomic_sub_fetch_8(&pPeer->refCount, 1) == 0) { + if (atomic_sub_fetch_32(&pPeer->refCount, 1) == 0) { taosReleaseRef(tsSyncRefId, pPeer->pSyncNode->rid); sDebug("%s, resource is freed", pPeer->id); @@ -465,6 +506,8 @@ int32_t syncDecPeerRef(SSyncPeer *pPeer) { } static void syncClosePeerConn(SSyncPeer *pPeer) { + sDebug("%s, pfd:%d sfd:%d will be closed", pPeer->id, pPeer->peerFd, pPeer->syncFd); + taosTmrStopA(&pPeer->timer); taosClose(pPeer->syncFd); if (pPeer->peerFd >= 0) { @@ -510,7 +553,7 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) { if (pPeer->nodeId == 0 || (ret > 0) || (ret == 0 && pPeer->port > tsSyncPort)) { int32_t checkMs = 100 + (pNode->vgId * 10) % 100; if (pNode->vgId > 1) checkMs = tsStatusInterval * 1000 + checkMs; - sDebug("%s, start to check peer connection after %d ms", pPeer->id, checkMs); + sDebug("%s, check peer connection after %d ms", pPeer->id, checkMs); taosTmrReset(syncCheckPeerConnection, checkMs, pPeer, tsSyncTmrCtrl, &pPeer->timer); } @@ -519,22 +562,20 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) { } void syncBroadcastStatus(SSyncNode *pNode) { - SSyncPeer *pPeer; - - for (int32_t i = 0; i < pNode->replica; ++i) { - if (i == pNode->selfIndex) continue; - pPeer = pNode->peerInfo[i]; - syncSendPeersStatusMsgToPeer(pPeer, 1); + for (int32_t index = 0; index < pNode->replica; ++index) { + if (index == pNode->selfIndex) continue; + SSyncPeer *pPeer = pNode->peerInfo[index]; + syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_BROADCAST, syncGenTranId()); } } static void syncResetFlowCtrl(SSyncNode *pNode) { - for (int32_t i = 0; i < pNode->replica; ++i) { - pNode->peerInfo[i]->numOfRetrieves = 0; + for (int32_t index = 0; index < pNode->replica; ++index) { + pNode->peerInfo[index]->numOfRetrieves = 0; } if (pNode->notifyFlowCtrl) { - (*pNode->notifyFlowCtrl)(pNode->ahandle, 0); + (*pNode->notifyFlowCtrl)(pNode->vgId, 0); } } @@ -544,8 +585,6 @@ static void syncChooseMaster(SSyncNode *pNode) { int32_t index = -1; int32_t replica = pNode->replica; - sDebug("vgId:%d, choose master", pNode->vgId); - for (int32_t i = 0; i < pNode->replica; ++i) { if (pNode->peerInfo[i]->role != TAOS_SYNC_ROLE_OFFLINE) { onlineNum++; @@ -599,7 +638,7 @@ static void syncChooseMaster(SSyncNode *pNode) { } #endif syncResetFlowCtrl(pNode); - (*pNode->notifyRole)(pNode->ahandle, nodeRole); + (*pNode->notifyRole)(pNode->vgId, nodeRole); } else { pPeer = pNode->peerInfo[index]; sInfo("%s, it shall work as master", pPeer->id); @@ -611,11 +650,11 @@ static void syncChooseMaster(SSyncNode *pNode) { static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { int32_t onlineNum = 0; - int32_t index = -1; + int32_t masterIndex = -1; int32_t replica = pNode->replica; - for (int32_t i = 0; i < pNode->replica; ++i) { - if (pNode->peerInfo[i]->role != TAOS_SYNC_ROLE_OFFLINE) { + for (int32_t index = 0; index < pNode->replica; ++index) { + if (pNode->peerInfo[index]->role != TAOS_SYNC_ROLE_OFFLINE) { onlineNum++; } } @@ -630,97 +669,99 @@ static SSyncPeer *syncCheckMaster(SSyncNode *pNode) { if (onlineNum <= replica * 0.5) { if (nodeRole != TAOS_SYNC_ROLE_UNSYNCED) { nodeRole = TAOS_SYNC_ROLE_UNSYNCED; - // pNode->peerInfo[pNode->selfIndex]->role = nodeRole; - (*pNode->notifyRole)(pNode->ahandle, nodeRole); - sInfo("vgId:%d, change to unsynced state, online:%d replica:%d", pNode->vgId, onlineNum, replica); + (*pNode->notifyRole)(pNode->vgId, nodeRole); + sInfo("vgId:%d, self change to unsynced state, online:%d replica:%d", pNode->vgId, onlineNum, replica); } } else { - for (int32_t i = 0; i < pNode->replica; ++i) { - SSyncPeer *pTemp = pNode->peerInfo[i]; + for (int32_t index = 0; index < pNode->replica; ++index) { + SSyncPeer *pTemp = pNode->peerInfo[index]; if (pTemp->role != TAOS_SYNC_ROLE_MASTER) continue; - if (index < 0) { - index = i; + if (masterIndex < 0) { + masterIndex = index; } else { // multiple masters, it shall not happen - if (i == pNode->selfIndex) { + if (masterIndex == pNode->selfIndex) { sError("%s, peer is master, work as slave instead", pTemp->id); nodeRole = TAOS_SYNC_ROLE_SLAVE; - (*pNode->notifyRole)(pNode->ahandle, nodeRole); + (*pNode->notifyRole)(pNode->vgId, nodeRole); } } } } - SSyncPeer *pMaster = (index >= 0) ? pNode->peerInfo[index] : NULL; + SSyncPeer *pMaster = (masterIndex >= 0) ? pNode->peerInfo[masterIndex] : NULL; return pMaster; } static int32_t syncValidateMaster(SSyncPeer *pPeer) { SSyncNode *pNode = pPeer->pSyncNode; - int32_t code = 0; + int32_t code = 0; if (nodeRole == TAOS_SYNC_ROLE_MASTER && nodeVersion < pPeer->version) { - sDebug("%s, slave has higher version, restart all connections!!!", pPeer->id); + sDebug("%s, peer has higher sver:%" PRIu64 ", restart all peer connections", pPeer->id, pPeer->version); nodeRole = TAOS_SYNC_ROLE_UNSYNCED; - (*pNode->notifyRole)(pNode->ahandle, nodeRole); + (*pNode->notifyRole)(pNode->vgId, nodeRole); code = -1; - for (int32_t i = 0; i < pNode->replica; ++i) { - if (i == pNode->selfIndex) continue; - syncRestartPeer(pNode->peerInfo[i]); + for (int32_t index = 0; index < pNode->replica; ++index) { + if (index == pNode->selfIndex) continue; + syncRestartPeer(pNode->peerInfo[index]); } } return code; } -static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus peersStatus[], int8_t newRole) { +static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus* peersStatus, int8_t newPeerRole) { SSyncNode *pNode = pPeer->pSyncNode; - int8_t peerOldRole = pPeer->role; - int8_t selfOldRole = nodeRole; - int8_t i, syncRequired = 0; - - // pNode->peerInfo[pNode->selfIndex]->version = nodeVersion; - pPeer->role = newRole; + int8_t oldPeerRole = pPeer->role; + int8_t oldSelfRole = nodeRole; + int8_t syncRequired = 0; - sDebug("%s, own role:%s, new peer role:%s", pPeer->id, syncRole[nodeRole], syncRole[pPeer->role]); + pPeer->role = newPeerRole; + sDebug("%s, peer role:%s change to %s", pPeer->id, syncRole[oldPeerRole], syncRole[newPeerRole]); SSyncPeer *pMaster = syncCheckMaster(pNode); if (pMaster) { // master is there pNode->pMaster = pMaster; - sDebug("%s, it is the master, ver:%" PRIu64, pMaster->id, pMaster->version); + sDebug("%s, it is the master, sver:%" PRIu64, pMaster->id, pMaster->version); if (syncValidateMaster(pPeer) < 0) return; if (nodeRole == TAOS_SYNC_ROLE_UNSYNCED) { if (nodeVersion < pMaster->version) { + sDebug("%s, is master, sync required, self sver:%" PRIu64, pMaster->id, nodeVersion); syncRequired = 1; } else { - sInfo("%s is master, work as slave, ver:%" PRIu64, pMaster->id, pMaster->version); + sInfo("%s, is master, work as slave, self sver:%" PRIu64, pMaster->id, nodeVersion); nodeRole = TAOS_SYNC_ROLE_SLAVE; - (*pNode->notifyRole)(pNode->ahandle, nodeRole); + (*pNode->notifyRole)(pNode->vgId, nodeRole); } } else if (nodeRole == TAOS_SYNC_ROLE_SLAVE && pMaster == pPeer) { - // nodeVersion = pMaster->version; + sDebug("%s, is master, continue work as slave, self sver:%" PRIu64, pMaster->id, nodeVersion); } } else { // master not there, if all peer's state and version are consistent, choose the master int32_t consistent = 0; - if (peersStatus) { - for (i = 0; i < pNode->replica; ++i) { - SSyncPeer *pTemp = pNode->peerInfo[i]; - if (pTemp->role != peersStatus[i].role) break; - if ((pTemp->role != TAOS_SYNC_ROLE_OFFLINE) && (pTemp->version != peersStatus[i].version)) break; + int32_t index = 0; + if (peersStatus != NULL) { + for (index = 0; index < pNode->replica; ++index) { + SSyncPeer *pTemp = pNode->peerInfo[index]; + if (pTemp->role != peersStatus[index].role) break; + if ((pTemp->role != TAOS_SYNC_ROLE_OFFLINE) && (pTemp->version != peersStatus[index].version)) break; } - if (i >= pNode->replica) consistent = 1; + if (index >= pNode->replica) consistent = 1; } else { if (pNode->replica == 2) consistent = 1; } if (consistent) { + sDebug("vgId:%d, choose master", pNode->vgId); syncChooseMaster(pNode); + } else { + sDebug("vgId:%d, cannot choose master since roles inconsistent", pNode->vgId); } } @@ -728,7 +769,8 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus peersStatus[], int8_t ne syncRecoverFromMaster(pMaster); } - if (peerOldRole != newRole || nodeRole != selfOldRole) { + if (oldPeerRole != newPeerRole || nodeRole != oldSelfRole) { + sDebug("vgId:%d, roles changed, broadcast status", pNode->vgId); syncBroadcastStatus(pNode); } @@ -738,14 +780,16 @@ static void syncCheckRole(SSyncPeer *pPeer, SPeerStatus peersStatus[], int8_t ne } static void syncRestartPeer(SSyncPeer *pPeer) { - sDebug("%s, restart connection", pPeer->id); + sDebug("%s, restart peer connection, last sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]); syncClosePeerConn(pPeer); pPeer->sstatus = TAOS_SYNC_STATUS_INIT; + sDebug("%s, peer conn is restart and set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]); int32_t ret = strcmp(pPeer->fqdn, tsNodeFqdn); if (ret > 0 || (ret == 0 && pPeer->port > tsSyncPort)) { + sDebug("%s, check peer connection in 1000 ms", pPeer->id); taosTmrReset(syncCheckPeerConnection, tsSyncTimer * 1000, pPeer, tsSyncTmrCtrl, &pPeer->timer); } } @@ -770,7 +814,7 @@ static void syncProcessSyncRequest(char *msg, SSyncPeer *pPeer) { } if (pPeer->sstatus != TAOS_SYNC_STATUS_INIT) { - sDebug("%s, sync is already started", pPeer->id); + sDebug("%s, sync is already started for sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]); return; // already started } @@ -784,11 +828,11 @@ static void syncProcessSyncRequest(char *msg, SSyncPeer *pPeer) { pthread_attr_destroy(&thattr); if (ret != 0) { - sError("%s, failed to create sync thread(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to create sync thread since %s", pPeer->id, strerror(errno)); syncDecPeerRef(pPeer); } else { pPeer->sstatus = TAOS_SYNC_STATUS_START; - sDebug("%s, thread is created to retrieve data", pPeer->id); + sDebug("%s, thread is created to retrieve data, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]); } } @@ -796,27 +840,28 @@ static void syncNotStarted(void *param, void *tmrId) { SSyncPeer *pPeer = param; SSyncNode *pNode = pPeer->pSyncNode; - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); pPeer->timer = NULL; - sInfo("%s, sync connection is still not up, restart", pPeer->id); + pPeer->sstatus = TAOS_SYNC_STATUS_INIT; + sInfo("%s, sync conn is still not up, restart and set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]); syncRestartConnection(pPeer); - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); } static void syncTryRecoverFromMaster(void *param, void *tmrId) { SSyncPeer *pPeer = param; SSyncNode *pNode = pPeer->pSyncNode; - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); syncRecoverFromMaster(pPeer); - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); } static void syncRecoverFromMaster(SSyncPeer *pPeer) { SSyncNode *pNode = pPeer->pSyncNode; if (nodeSStatus != TAOS_SYNC_STATUS_INIT) { - sDebug("%s, sync is already started, status:%d", pPeer->id, nodeSStatus); + sDebug("%s, sync is already started since sstatus:%s", pPeer->id, syncStatus[nodeSStatus]); return; } @@ -840,11 +885,11 @@ static void syncRecoverFromMaster(SSyncPeer *pPeer) { firstPkt.port = tsSyncPort; taosTmrReset(syncNotStarted, tsSyncTimer * 1000, pPeer, tsSyncTmrCtrl, &pPeer->timer); - if (write(pPeer->peerFd, &firstPkt, sizeof(firstPkt)) != sizeof(firstPkt)) { + if (taosWriteMsg(pPeer->peerFd, &firstPkt, sizeof(firstPkt)) != sizeof(firstPkt)) { sError("%s, failed to send sync-req to peer", pPeer->id); } else { nodeSStatus = TAOS_SYNC_STATUS_START; - sInfo("%s, sync-req is sent", pPeer->id); + sInfo("%s, sync-req is sent to peer, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]); } } @@ -854,7 +899,7 @@ static void syncProcessFwdResponse(char *cont, SSyncPeer *pPeer) { SSyncFwds *pSyncFwds = pNode->pSyncFwds; SFwdInfo * pFwdInfo; - sDebug("%s, forward-rsp is received, code:%x ver:%" PRIu64, pPeer->id, pFwdRsp->code, pFwdRsp->version); + sTrace("%s, forward-rsp is received, code:%x hver:%" PRIu64, pPeer->id, pFwdRsp->code, pFwdRsp->version); SFwdInfo *pFirst = pSyncFwds->fwdInfo + pSyncFwds->first; if (pFirst->version <= pFwdRsp->version && pSyncFwds->fwds > 0) { @@ -873,16 +918,17 @@ static void syncProcessForwardFromPeer(char *cont, SSyncPeer *pPeer) { SSyncNode *pNode = pPeer->pSyncNode; SWalHead * pHead = (SWalHead *)cont; - sDebug("%s, forward is received, hver:%" PRIu64 ", len:%d", pPeer->id, pHead->version, pHead->len); + sTrace("%s, forward is received, hver:%" PRIu64 ", len:%d", pPeer->id, pHead->version, pHead->len); if (nodeRole == TAOS_SYNC_ROLE_SLAVE) { // nodeVersion = pHead->version; - (*pNode->writeToCache)(pNode->ahandle, pHead, TAOS_QTYPE_FWD, NULL); + (*pNode->writeToCache)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL); } else { if (nodeSStatus != TAOS_SYNC_STATUS_INIT) { syncSaveIntoBuffer(pPeer, pHead); } else { - sError("%s, forward discarded, hver:%" PRIu64, pPeer->id, pHead->version); + sError("%s, forward discarded since sstatus:%s, hver:%" PRIu64, pPeer->id, syncStatus[nodeSStatus], + pHead->version); } } } @@ -891,14 +937,15 @@ static void syncProcessPeersStatusMsg(char *cont, SSyncPeer *pPeer) { SSyncNode * pNode = pPeer->pSyncNode; SPeersStatus *pPeersStatus = (SPeersStatus *)cont; - sDebug("%s, status msg is received, self:%s ver:%" PRIu64 " peer:%s ver:%" PRIu64 ", ack:%d", pPeer->id, - syncRole[nodeRole], nodeVersion, syncRole[pPeersStatus->role], pPeersStatus->version, pPeersStatus->ack); + sDebug("%s, status is received, self:%s:%s:%" PRIu64 ", peer:%s:%" PRIu64 ", ack:%d tranId:%u type:%s pfd:%d", + pPeer->id, syncRole[nodeRole], syncStatus[nodeSStatus], nodeVersion, syncRole[pPeersStatus->role], + pPeersStatus->version, pPeersStatus->ack, pPeersStatus->tranId, statusType[pPeersStatus->type], pPeer->peerFd); pPeer->version = pPeersStatus->version; syncCheckRole(pPeer, pPeersStatus->peersStatus, pPeersStatus->role); if (pPeersStatus->ack) { - syncSendPeersStatusMsgToPeer(pPeer, 0); + syncSendPeersStatusMsgToPeer(pPeer, 0, pPeersStatus->type + 1, pPeersStatus->tranId); } } @@ -933,7 +980,7 @@ static int32_t syncProcessPeerMsg(void *param, void *buffer) { char * cont = buffer; SSyncNode *pNode = pPeer->pSyncNode; - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); int32_t code = syncReadPeerMsg(pPeer, &head, cont); @@ -949,14 +996,14 @@ static int32_t syncProcessPeerMsg(void *param, void *buffer) { } } - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); return code; } #define statusMsgLen sizeof(SSyncHead) + sizeof(SPeersStatus) + sizeof(SPeerStatus) * TAOS_SYNC_MAX_REPLICA -static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack) { +static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack, int8_t type, uint16_t tranId) { SSyncNode *pNode = pPeer->pSyncNode; char msg[statusMsgLen] = {0}; @@ -971,22 +1018,24 @@ static void syncSendPeersStatusMsgToPeer(SSyncPeer *pPeer, char ack) { pPeersStatus->version = nodeVersion; pPeersStatus->role = nodeRole; pPeersStatus->ack = ack; + pPeersStatus->type = type; + pPeersStatus->tranId = tranId; for (int32_t i = 0; i < pNode->replica; ++i) { pPeersStatus->peersStatus[i].role = pNode->peerInfo[i]->role; pPeersStatus->peersStatus[i].version = pNode->peerInfo[i]->version; } - int32_t retLen = write(pPeer->peerFd, msg, statusMsgLen); + int32_t retLen = taosWriteMsg(pPeer->peerFd, msg, statusMsgLen); if (retLen == statusMsgLen) { - sDebug("%s, status msg is sent, self:%s ver:%" PRIu64 ", ack:%d", pPeer->id, syncRole[pPeersStatus->role], - pPeersStatus->version, pPeersStatus->ack); + sDebug("%s, status is sent, self:%s:%s:%" PRIu64 ", peer:%s:%s:%" PRIu64 ", ack:%d tranId:%u type:%s pfd:%d", + pPeer->id, syncRole[nodeRole], syncStatus[nodeSStatus], nodeVersion, syncRole[pPeer->role], + syncStatus[pPeer->sstatus], pPeer->version, pPeersStatus->ack, pPeersStatus->tranId, + statusType[pPeersStatus->type], pPeer->peerFd); } else { sDebug("%s, failed to send status msg, restart", pPeer->id); syncRestartConnection(pPeer); } - - return; } static void syncSetupPeerConnection(SSyncPeer *pPeer) { @@ -995,13 +1044,13 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) { taosTmrStopA(&pPeer->timer); if (pPeer->peerFd >= 0) { sDebug("%s, send role version to peer", pPeer->id); - syncSendPeersStatusMsgToPeer(pPeer, 1); + syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_SETUP_CONN, syncGenTranId()); return; } int32_t connFd = taosOpenTcpClientSocket(pPeer->ip, pPeer->port, 0); if (connFd < 0) { - sDebug("%s, failed to open tcp socket(%s)", pPeer->id, strerror(errno)); + sDebug("%s, failed to open tcp socket since %s", pPeer->id, strerror(errno)); taosTmrReset(syncCheckPeerConnection, tsSyncTimer * 1000, pPeer, tsSyncTmrCtrl, &pPeer->timer); return; } @@ -1014,15 +1063,15 @@ static void syncSetupPeerConnection(SSyncPeer *pPeer) { firstPkt.port = tsSyncPort; firstPkt.sourceId = pNode->vgId; // tell arbitrator its vgId - if (write(connFd, &firstPkt, sizeof(firstPkt)) == sizeof(firstPkt)) { - sDebug("%s, connection to peer server is setup", pPeer->id); + if (taosWriteMsg(connFd, &firstPkt, sizeof(firstPkt)) == sizeof(firstPkt)) { + sDebug("%s, connection to peer server is setup, pfd:%d sfd:%d", pPeer->id, connFd, pPeer->syncFd); pPeer->peerFd = connFd; pPeer->role = TAOS_SYNC_ROLE_UNSYNCED; pPeer->pConn = taosAllocateTcpConn(tsTcpPool, pPeer, connFd); syncAddPeerRef(pPeer); } else { - sDebug("try later"); - close(connFd); + sDebug("%s, failed to setup peer connection to server since %s, try later", pPeer->id, strerror(errno)); + taosClose(connFd); taosTmrReset(syncCheckPeerConnection, tsSyncTimer * 1000, pPeer, tsSyncTmrCtrl, &pPeer->timer); } } @@ -1031,12 +1080,12 @@ static void syncCheckPeerConnection(void *param, void *tmrId) { SSyncPeer *pPeer = param; SSyncNode *pNode = pPeer->pSyncNode; - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); sDebug("%s, check peer connection", pPeer->id); syncSetupPeerConnection(pPeer); - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); } static void syncCreateRestoreDataThread(SSyncPeer *pPeer) { @@ -1069,7 +1118,7 @@ static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) { SFirstPkt firstPkt; if (taosReadMsg(connFd, &firstPkt, sizeof(firstPkt)) != sizeof(firstPkt)) { - sError("failed to read peer first pkt from ip:%s(%s)", ipstr, strerror(errno)); + sError("failed to read peer first pkt from ip:%s since %s", ipstr, strerror(errno)); taosCloseSocket(connFd); return; } @@ -1083,7 +1132,7 @@ static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) { } SSyncNode *pNode = *ppNode; - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); SSyncPeer *pPeer; for (i = 0; i < pNode->replica; ++i) { @@ -1102,17 +1151,18 @@ static void syncProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) { pPeer->syncFd = connFd; syncCreateRestoreDataThread(pPeer); } else { - sDebug("%s, TCP connection is already up, close one", pPeer->id); + sDebug("%s, TCP connection is already up(pfd:%d), close one, new pfd:%d sfd:%d", pPeer->id, pPeer->peerFd, connFd, + pPeer->syncFd); syncClosePeerConn(pPeer); pPeer->peerFd = connFd; pPeer->pConn = taosAllocateTcpConn(tsTcpPool, pPeer, connFd); syncAddPeerRef(pPeer); sDebug("%s, ready to exchange data", pPeer->id); - syncSendPeersStatusMsgToPeer(pPeer, 1); + syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_EXCHANGE_DATA, syncGenTranId()); } } - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); } static void syncProcessBrokenLink(void *param) { @@ -1121,22 +1171,22 @@ static void syncProcessBrokenLink(void *param) { SSyncNode *pNode = pPeer->pSyncNode; if (taosAcquireRef(tsSyncRefId, pNode->rid) == NULL) return; - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); - sDebug("%s, TCP link is broken(%s)", pPeer->id, strerror(errno)); + sDebug("%s, TCP link is broken since %s, pfd:%d sfd:%d", pPeer->id, strerror(errno), pPeer->peerFd, pPeer->syncFd); pPeer->peerFd = -1; if (syncDecPeerRef(pPeer) != 0) { syncRestartConnection(pPeer); } - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); taosReleaseRef(tsSyncRefId, pNode->rid); } static void syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle) { SSyncFwds *pSyncFwds = pNode->pSyncFwds; - uint64_t time = taosGetTimestampMs(); + int64_t time = taosGetTimestampMs(); if (pSyncFwds->fwds >= tsMaxFwdInfo) { pSyncFwds->first = (pSyncFwds->first + 1) % tsMaxFwdInfo; @@ -1154,7 +1204,7 @@ static void syncSaveFwdInfo(SSyncNode *pNode, uint64_t version, void *mhandle) { pFwdInfo->time = time; pSyncFwds->fwds++; - sDebug("vgId:%d, fwd info is saved, ver:%" PRIu64 " fwds:%d ", pNode->vgId, version, pSyncFwds->fwds); + sTrace("vgId:%d, fwd info is saved, hver:%" PRIu64 " fwds:%d ", pNode->vgId, version, pSyncFwds->fwds); } static void syncRemoveConfirmedFwdInfo(SSyncNode *pNode) { @@ -1168,7 +1218,7 @@ static void syncRemoveConfirmedFwdInfo(SSyncNode *pNode) { pSyncFwds->first = (pSyncFwds->first + 1) % tsMaxFwdInfo; pSyncFwds->fwds--; if (pSyncFwds->fwds == 0) pSyncFwds->first = pSyncFwds->last; - // sDebug("vgId:%d, fwd info is removed, ver:%d, fwds:%d", + // sDebug("vgId:%d, fwd info is removed, hver:%d, fwds:%d", // pNode->vgId, pFwdInfo->version, pSyncFwds->fwds); memset(pFwdInfo, 0, sizeof(SFwdInfo)); } @@ -1191,35 +1241,60 @@ static void syncProcessFwdAck(SSyncNode *pNode, SFwdInfo *pFwdInfo, int32_t code } if (confirm && pFwdInfo->confirmed == 0) { - sDebug("vgId:%d, forward is confirmed, ver:%" PRIu64 " code:%x", pNode->vgId, pFwdInfo->version, pFwdInfo->code); - (*pNode->confirmForward)(pNode->ahandle, pFwdInfo->mhandle, pFwdInfo->code); + sTrace("vgId:%d, forward is confirmed, hver:%" PRIu64 " code:%x", pNode->vgId, pFwdInfo->version, pFwdInfo->code); + (*pNode->confirmForward)(pNode->vgId, pFwdInfo->mhandle, pFwdInfo->code); pFwdInfo->confirmed = 1; } } +static void syncMonitorNodeRole(void *param, void *tmrId) { + int64_t rid = (int64_t)param; + SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid); + if (pNode == NULL) return; + + for (int32_t index = 0; index < pNode->replica; index++) { + if (index == pNode->selfIndex) continue; + + SSyncPeer *pPeer = pNode->peerInfo[index]; + if (/*pPeer->role > TAOS_SYNC_ROLE_UNSYNCED && */ nodeRole > TAOS_SYNC_ROLE_UNSYNCED) continue; + if (/*pPeer->sstatus > TAOS_SYNC_STATUS_INIT || */ nodeSStatus > TAOS_SYNC_STATUS_INIT) continue; + + sDebug("%s, check roles since self:%s sstatus:%s, peer:%s sstatus:%s", pPeer->id, syncRole[pPeer->role], + syncStatus[pPeer->sstatus], syncRole[nodeRole], syncStatus[nodeSStatus]); + syncSendPeersStatusMsgToPeer(pPeer, 1, SYNC_STATUS_CHECK_ROLE, syncGenTranId()); + break; + } + + pNode->pRoleTimer = taosTmrStart(syncMonitorNodeRole, SYNC_ROLE_TIMER, (void *)pNode->rid, tsSyncTmrCtrl); + taosReleaseRef(tsSyncRefId, rid); +} + static void syncMonitorFwdInfos(void *param, void *tmrId) { - int64_t rid = (int64_t) param; + int64_t rid = (int64_t)param; SSyncNode *pNode = taosAcquireRef(tsSyncRefId, rid); if (pNode == NULL) return; SSyncFwds *pSyncFwds = pNode->pSyncFwds; - if (pSyncFwds) {; - uint64_t time = taosGetTimestampMs(); + if (pSyncFwds) { + int64_t time = taosGetTimestampMs(); if (pSyncFwds->fwds > 0) { - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); for (int32_t i = 0; i < pSyncFwds->fwds; ++i) { SFwdInfo *pFwdInfo = pSyncFwds->fwdInfo + (pSyncFwds->first + i) % tsMaxFwdInfo; - if (time - pFwdInfo->time < 2000) break; + if (ABS(time - pFwdInfo->time) < 2000) break; + + sDebug("vgId:%d, forward info expired, hver:%" PRIu64 " curtime:%" PRIu64 " savetime:%" PRIu64, pNode->vgId, + pFwdInfo->version, time, pFwdInfo->time); syncProcessFwdAck(pNode, pFwdInfo, TSDB_CODE_RPC_NETWORK_UNAVAIL); } syncRemoveConfirmedFwdInfo(pNode); - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); } - pNode->pFwdTimer = taosTmrStart(syncMonitorFwdInfos, 300, (void *)pNode->rid, tsSyncTmrCtrl); + pNode->pFwdTimer = taosTmrStart(syncMonitorFwdInfos, SYNC_FWD_TIMER, (void *)pNode->rid, tsSyncTmrCtrl); } taosReleaseRef(tsSyncRefId, rid); @@ -1232,9 +1307,8 @@ static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle int32_t fwdLen; int32_t code = 0; - if (pWalHead->version > nodeVersion + 1) { - sError("vgId:%d, hver:%" PRIu64 ", inconsistent with ver:%" PRIu64, pNode->vgId, pWalHead->version, nodeVersion); + sError("vgId:%d, hver:%" PRIu64 ", inconsistent with sver:%" PRIu64, pNode->vgId, pWalHead->version, nodeVersion); if (nodeRole == TAOS_SYNC_ROLE_SLAVE) { sInfo("vgId:%d, restart connection", pNode->vgId); for (int32_t i = 0; i < pNode->replica; ++i) { @@ -1248,14 +1322,15 @@ static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle // always update version nodeVersion = pWalHead->version; - sTrace("vgId:%d, forward to peer, replica:%d role:%s qtype:%s hver:%" PRIu64, pNode->vgId, pNode->replica, - syncRole[nodeRole], qtypeStr[qtype], pWalHead->version); if (pNode->replica == 1 || nodeRole != TAOS_SYNC_ROLE_MASTER) return 0; // only pkt from RPC or CQ can be forwarded if (qtype != TAOS_QTYPE_RPC && qtype != TAOS_QTYPE_CQ) return 0; + sTrace("vgId:%d, forward to peer, replica:%d role:%s qtype:%s hver:%" PRIu64, pNode->vgId, pNode->replica, + syncRole[nodeRole], qtypeStr[qtype], pWalHead->version); + // a hacker way to improve the performance pSyncHead = (SSyncHead *)(((char *)pWalHead) - sizeof(SSyncHead)); pSyncHead->type = TAOS_SMSG_FORWARD; @@ -1263,7 +1338,7 @@ static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle pSyncHead->len = sizeof(SWalHead) + pWalHead->len; fwdLen = pSyncHead->len + sizeof(SSyncHead); // include the WAL and SYNC head - pthread_mutex_lock(&(pNode->mutex)); + pthread_mutex_lock(&pNode->mutex); for (int32_t i = 0; i < pNode->replica; ++i) { pPeer = pNode->peerInfo[i]; @@ -1275,16 +1350,16 @@ static int32_t syncForwardToPeerImpl(SSyncNode *pNode, void *data, void *mhandle code = 1; } - int32_t retLen = write(pPeer->peerFd, pSyncHead, fwdLen); + int32_t retLen = taosWriteMsg(pPeer->peerFd, pSyncHead, fwdLen); if (retLen == fwdLen) { - sDebug("%s, forward is sent, ver:%" PRIu64 " contLen:%d", pPeer->id, pWalHead->version, pWalHead->len); + sTrace("%s, forward is sent, hver:%" PRIu64 " contLen:%d", pPeer->id, pWalHead->version, pWalHead->len); } else { - sError("%s, failed to forward, ver:%" PRIu64 " retLen:%d", pPeer->id, pWalHead->version, retLen); + sError("%s, failed to forward, hver:%" PRIu64 " retLen:%d", pPeer->id, pWalHead->version, retLen); syncRestartConnection(pPeer); } } - pthread_mutex_unlock(&(pNode->mutex)); + pthread_mutex_unlock(&pNode->mutex); return code; } diff --git a/src/sync/src/syncRestore.c b/src/sync/src/syncRestore.c index 5d7b9eac9b9386f6e3a48de0931bd4c4455f0328..2ca4b5424ee3134d3742c29e3af2b21671637b19 100644 --- a/src/sync/src/syncRestore.c +++ b/src/sync/src/syncRestore.c @@ -13,7 +13,9 @@ * along with this program. If not, see . */ +#define _DEFAULT_SOURCE #include "os.h" +#include "taoserror.h" #include "tlog.h" #include "tutil.h" #include "ttimer.h" @@ -36,7 +38,7 @@ static void syncRemoveExtraFile(SSyncPeer *pPeer, int32_t sindex, int32_t eindex while (1) { name[0] = 0; - magic = (*pNode->getFileInfo)(pNode->ahandle, name, &index, eindex, &size, &fversion); + magic = (*pNode->getFileInfo)(pNode->vgId, name, &index, eindex, &size, &fversion); if (magic == 0) break; snprintf(fname, sizeof(fname), "%s/%s", pNode->path, name); @@ -63,7 +65,10 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) { while (1) { // read file info int32_t ret = taosReadMsg(pPeer->syncFd, &(minfo), sizeof(minfo)); - if (ret < 0) break; + if (ret < 0) { + sError("%s, failed to read file info while restore file since %s", pPeer->id, strerror(errno)); + break; + } // if no more file from master, break; if (minfo.name[0] == 0 || minfo.magic == 0) { @@ -81,8 +86,8 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) { // check the file info sinfo = minfo; - sDebug("%s, get file info:%s", pPeer->id, minfo.name); - sinfo.magic = (*pNode->getFileInfo)(pNode->ahandle, sinfo.name, &sinfo.index, TAOS_SYNC_MAX_INDEX, &sinfo.size, + sDebug("%s, get file:%s info size:%" PRId64, pPeer->id, minfo.name, minfo.size); + sinfo.magic = (*pNode->getFileInfo)(pNode->vgId, sinfo.name, &sinfo.index, TAOS_SYNC_MAX_INDEX, &sinfo.size, &sinfo.fversion); // if file not there or magic is not the same, file shall be synced @@ -90,8 +95,11 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) { fileAck.sync = (sinfo.magic != minfo.magic || sinfo.name[0] == 0) ? 1 : 0; // send file ack - ret = taosWriteMsg(pPeer->syncFd, &(fileAck), sizeof(fileAck)); - if (ret < 0) break; + ret = taosWriteMsg(pPeer->syncFd, &fileAck, sizeof(fileAck)); + if (ret < 0) { + sError("%s, failed to write file:%s ack while restore file since %s", pPeer->id, minfo.name, strerror(errno)); + break; + } // if sync is not required, continue if (fileAck.sync == 0) { @@ -106,14 +114,17 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) { int32_t dfd = open(name, O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU | S_IRWXG | S_IRWXO); if (dfd < 0) { - sError("%s, failed to open file:%s", pPeer->id, name); + sError("%s, failed to open file:%s while restore file since %s", pPeer->id, minfo.name, strerror(errno)); break; } ret = taosCopyFds(pPeer->syncFd, dfd, minfo.size); fsync(dfd); close(dfd); - if (ret < 0) break; + if (ret < 0) { + sError("%s, failed to copy file:%s while restore file since %s", pPeer->id, minfo.name, strerror(errno)); + break; + } fileChanged = true; sDebug("%s, %s is received, size:%" PRId64, pPeer->id, minfo.name, minfo.size); @@ -123,10 +134,11 @@ static int32_t syncRestoreFile(SSyncPeer *pPeer, uint64_t *fversion) { // data file is changed, code shall be set to 1 *fversion = minfo.fversion; code = 1; + sDebug("%s, file changed while restore file", pPeer->id); } if (code < 0) { - sError("%s, failed to restore %s(%s)", pPeer->id, name, strerror(errno)); + sError("%s, failed to restore %s since %s", pPeer->id, name, strerror(errno)); } return code; @@ -140,25 +152,40 @@ static int32_t syncRestoreWal(SSyncPeer *pPeer) { if (buffer == NULL) return -1; SWalHead *pHead = (SWalHead *)buffer; + uint64_t lastVer = 0; while (1) { ret = taosReadMsg(pPeer->syncFd, pHead, sizeof(SWalHead)); - if (ret < 0) break; + if (ret < 0) { + sError("%s, failed to read walhead while restore wal since %s", pPeer->id, strerror(errno)); + break; + } if (pHead->len == 0) { + sDebug("%s, wal is synced over", pPeer->id); code = 0; break; } // wal sync over ret = taosReadMsg(pPeer->syncFd, pHead->cont, pHead->len); - if (ret < 0) break; + if (ret < 0) { + sError("%s, failed to read walcont, len:%d while restore wal since %s", pPeer->id, pHead->len, strerror(errno)); + break; + } - sDebug("%s, restore a record, qtype:wal hver:%" PRIu64, pPeer->id, pHead->version); - (*pNode->writeToCache)(pNode->ahandle, pHead, TAOS_QTYPE_WAL, NULL); + sTrace("%s, restore a record, qtype:wal len:%d hver:%" PRIu64, pPeer->id, pHead->len, pHead->version); + + if (lastVer == pHead->version) { + sError("%s, failed to restore record, same hver:%" PRIu64 ", wal sync failed" PRIu64, pPeer->id, lastVer); + break; + } + lastVer = pHead->version; + + (*pNode->writeToCache)(pNode->vgId, pHead, TAOS_QTYPE_WAL, NULL); } if (code < 0) { - sError("%s, failed to restore wal(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to restore wal from syncFd:%d since %s", pPeer->id, pPeer->syncFd, strerror(errno)); } free(buffer); @@ -169,7 +196,7 @@ static char *syncProcessOneBufferedFwd(SSyncPeer *pPeer, char *offset) { SSyncNode *pNode = pPeer->pSyncNode; SWalHead * pHead = (SWalHead *)offset; - (*pNode->writeToCache)(pNode->ahandle, pHead, TAOS_QTYPE_FWD, NULL); + (*pNode->writeToCache)(pNode->vgId, pHead, TAOS_QTYPE_FWD, NULL); offset += pHead->len + sizeof(SWalHead); return offset; @@ -214,7 +241,7 @@ int32_t syncSaveIntoBuffer(SSyncPeer *pPeer, SWalHead *pHead) { memcpy(pRecv->offset, pHead, len); pRecv->offset += len; pRecv->forwards++; - sDebug("%s, fwd is saved into queue, ver:%" PRIu64 " fwds:%d", pPeer->id, pHead->version, pRecv->forwards); + sTrace("%s, fwd is saved into queue, hver:%" PRIu64 " fwds:%d", pPeer->id, pHead->version, pRecv->forwards); } else { sError("%s, buffer size:%d is too small", pPeer->id, pRecv->bufferSize); pRecv->code = -1; // set error code @@ -257,7 +284,7 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) { nodeSStatus = TAOS_SYNC_STATUS_FILE; uint64_t fversion = 0; - sDebug("%s, start to restore file", pPeer->id); + sDebug("%s, start to restore file, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]); int32_t code = syncRestoreFile(pPeer, &fversion); if (code < 0) { sError("%s, failed to restore file", pPeer->id); @@ -266,7 +293,7 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) { // if code > 0, data file is changed, notify app, and pass the version if (code > 0 && pNode->notifyFileSynced) { - if ((*pNode->notifyFileSynced)(pNode->ahandle, fversion) < 0) { + if ((*pNode->notifyFileSynced)(pNode->vgId, fversion) < 0) { sError("%s, app not in ready state", pPeer->id); return -1; } @@ -281,7 +308,7 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) { } nodeSStatus = TAOS_SYNC_STATUS_CACHE; - sDebug("%s, start to insert buffered points", pPeer->id); + sDebug("%s, start to insert buffered points, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]); if (syncProcessBufferedFwd(pPeer) < 0) { sError("%s, failed to insert buffered points", pPeer->id); return -1; @@ -291,16 +318,17 @@ static int32_t syncRestoreDataStepByStep(SSyncPeer *pPeer) { } void *syncRestoreData(void *param) { - SSyncPeer *pPeer = (SSyncPeer *)param; + SSyncPeer *pPeer = param; SSyncNode *pNode = pPeer->pSyncNode; taosBlockSIGPIPE(); __sync_fetch_and_add(&tsSyncNum, 1); - (*pNode->notifyRole)(pNode->ahandle, TAOS_SYNC_ROLE_SYNCING); + (*pNode->notifyRole)(pNode->vgId, TAOS_SYNC_ROLE_SYNCING); if (syncOpenRecvBuffer(pNode) < 0) { - sError("%s, failed to allocate recv buffer", pPeer->id); + sError("%s, failed to allocate recv buffer, restart connection", pPeer->id); + syncRestartConnection(pPeer); } else { if (syncRestoreDataStepByStep(pPeer) == 0) { sInfo("%s, it is synced successfully", pPeer->id); @@ -313,9 +341,11 @@ void *syncRestoreData(void *param) { } } - (*pNode->notifyRole)(pNode->ahandle, nodeRole); + (*pNode->notifyRole)(pNode->vgId, nodeRole); nodeSStatus = TAOS_SYNC_STATUS_INIT; + sInfo("%s, sync over, set sstatus:%s", pPeer->id, syncStatus[nodeSStatus]); + taosClose(pPeer->syncFd); syncCloseRecvBuffer(pNode); __sync_fetch_and_sub(&tsSyncNum, 1); diff --git a/src/sync/src/syncRetrieve.c b/src/sync/src/syncRetrieve.c index 21151f119937519e477e73d0e5e7cb82c1155788..58d09d080ecca141cdc55ae8b0fac1e791f6725a 100644 --- a/src/sync/src/syncRetrieve.c +++ b/src/sync/src/syncRetrieve.c @@ -13,10 +13,8 @@ * along with this program. If not, see . */ -#include -#include +#define _DEFAULT_SOURCE #include -#include #include "os.h" #include "tlog.h" #include "tutil.h" @@ -34,7 +32,7 @@ static int32_t syncAddIntoWatchList(SSyncPeer *pPeer, char *name) { pPeer->watchNum = 0; pPeer->notifyFd = inotify_init1(IN_NONBLOCK); if (pPeer->notifyFd < 0) { - sError("%s, failed to init inotify(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to init inotify since %s", pPeer->id, strerror(errno)); return -1; } @@ -51,14 +49,14 @@ static int32_t syncAddIntoWatchList(SSyncPeer *pPeer, char *name) { if (*wd >= 0) { if (inotify_rm_watch(pPeer->notifyFd, *wd) < 0) { - sError("%s, failed to remove wd:%d(%s)", pPeer->id, *wd, strerror(errno)); + sError("%s, failed to remove wd:%d since %s", pPeer->id, *wd, strerror(errno)); return -1; } } *wd = inotify_add_watch(pPeer->notifyFd, name, IN_MODIFY | IN_DELETE); if (*wd == -1) { - sError("%s, failed to add %s(%s)", pPeer->id, name, strerror(errno)); + sError("%s, failed to add %s since %s", pPeer->id, name, strerror(errno)); return -1; } else { sDebug("%s, monitor %s, wd:%d watchNum:%d", pPeer->id, name, *wd, pPeer->watchNum); @@ -75,7 +73,7 @@ static int32_t syncAreFilesModified(SSyncPeer *pPeer) { char buf[2048]; int32_t len = read(pPeer->notifyFd, buf, sizeof(buf)); if (len < 0 && errno != EAGAIN) { - sError("%s, failed to read notify FD(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to read notify FD since %s", pPeer->id, strerror(errno)); return -1; } @@ -110,13 +108,16 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) { while (1) { // retrieve file info fileInfo.name[0] = 0; - fileInfo.magic = (*pNode->getFileInfo)(pNode->ahandle, fileInfo.name, &fileInfo.index, TAOS_SYNC_MAX_INDEX, + fileInfo.magic = (*pNode->getFileInfo)(pNode->vgId, fileInfo.name, &fileInfo.index, TAOS_SYNC_MAX_INDEX, &fileInfo.size, &fileInfo.fversion); // fileInfo.size = htonl(size); // send the file info int32_t ret = taosWriteMsg(pPeer->syncFd, &(fileInfo), sizeof(fileInfo)); - if (ret < 0) break; + if (ret < 0) { + sError("%s, failed to write file:%s info while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno)); + break; + } // if no file anymore, break if (fileInfo.magic == 0 || fileInfo.name[0] == 0) { @@ -126,8 +127,11 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) { } // wait for the ack from peer - ret = taosReadMsg(pPeer->syncFd, &(fileAck), sizeof(fileAck)); - if (ret < 0) break; + ret = taosReadMsg(pPeer->syncFd, &fileAck, sizeof(fileAck)); + if (ret < 0) { + sError("%s, failed to read file:%s ack while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno)); + break; + } // set the peer sync version pPeer->sversion = fileInfo.fversion; @@ -136,7 +140,10 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) { snprintf(name, sizeof(name), "%s/%s", pNode->path, fileInfo.name); // add the file into watch list - if (syncAddIntoWatchList(pPeer, name) < 0) break; + if (syncAddIntoWatchList(pPeer, name) < 0) { + sError("%s, failed to watch file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno)); + break; + } // if sync is not required, continue if (fileAck.sync == 0) { @@ -147,21 +154,30 @@ static int32_t syncRetrieveFile(SSyncPeer *pPeer) { // send the file to peer int32_t sfd = open(name, O_RDONLY); - if (sfd < 0) break; + if (sfd < 0) { + sError("%s, failed to open file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno)); + break; + } ret = taosSendFile(pPeer->syncFd, sfd, NULL, fileInfo.size); close(sfd); - if (ret < 0) break; + if (ret < 0) { + sError("%s, failed to send file:%s while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno)); + break; + } sDebug("%s, %s is sent, size:%" PRId64, pPeer->id, name, fileInfo.size); fileInfo.index++; // check if processed files are modified - if (syncAreFilesModified(pPeer) != 0) break; + if (syncAreFilesModified(pPeer) != 0) { + sInfo("%s, file:%s are modified while retrieve file since %s", pPeer->id, fileInfo.name, strerror(errno)); + break; + } } if (code < 0) { - sError("%s, failed to retrieve file(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to retrieve file", pPeer->id); } return code; @@ -201,7 +217,7 @@ static int32_t syncMonitorLastWal(SSyncPeer *pPeer, char *name) { taosClose(pPeer->notifyFd); pPeer->notifyFd = inotify_init1(IN_NONBLOCK); if (pPeer->notifyFd < 0) { - sError("%s, failed to init inotify(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to init inotify since %s", pPeer->id, strerror(errno)); return -1; } @@ -216,7 +232,7 @@ static int32_t syncMonitorLastWal(SSyncPeer *pPeer, char *name) { *wd = inotify_add_watch(pPeer->notifyFd, name, IN_MODIFY | IN_CLOSE_WRITE); if (*wd == -1) { - sError("%s, failed to watch last wal(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to watch last wal since %s", pPeer->id, strerror(errno)); return -1; } @@ -227,7 +243,7 @@ static int32_t syncCheckLastWalChanges(SSyncPeer *pPeer, uint32_t *pEvent) { char buf[2048]; int32_t len = read(pPeer->notifyFd, buf, sizeof(buf)); if (len < 0 && errno != EAGAIN) { - sError("%s, failed to read notify FD(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to read notify FD since %s", pPeer->id, strerror(errno)); return -1; } @@ -268,7 +284,7 @@ static int32_t syncRetrieveLastWal(SSyncPeer *pPeer, char *name, uint64_t fversi break; } - sDebug("%s, last wal is forwarded, ver:%" PRIu64, pPeer->id, pHead->version); + sTrace("%s, last wal is forwarded, hver:%" PRIu64, pPeer->id, pHead->version); int32_t ret = taosWriteMsg(pPeer->syncFd, pHead, wsize); if (ret != wsize) break; pPeer->sversion = pHead->version; @@ -320,6 +336,7 @@ static int32_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index) if (((event & IN_MODIFY) == 0) || once) { if (fversion == 0) { pPeer->sstatus = TAOS_SYNC_STATUS_CACHE; // start to forward pkt + sDebug("%s, fversion is 0 then set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]); fversion = nodeVersion; // must read data to fversion } } @@ -356,7 +373,7 @@ static int32_t syncProcessLastWal(SSyncPeer *pPeer, char *wname, int64_t index) index++; wname[0] = 0; - code = (*pNode->getWalInfo)(pNode->ahandle, wname, &index); + code = (*pNode->getWalInfo)(pNode->vgId, wname, &index); if (code < 0) break; if (wname[0] == 0) { code = 0; @@ -384,7 +401,7 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) { while (1) { // retrieve wal info wname[0] = 0; - code = (*pNode->getWalInfo)(pNode->ahandle, wname, &index); + code = (*pNode->getWalInfo)(pNode->vgId, wname, &index); if (code < 0) break; // error if (wname[0] == 0) { // no wal file sDebug("%s, no wal file", pPeer->id); @@ -418,13 +435,14 @@ static int32_t syncRetrieveWal(SSyncPeer *pPeer) { } if (code == 0) { - sDebug("%s, wal retrieve is finished", pPeer->id); pPeer->sstatus = TAOS_SYNC_STATUS_CACHE; + sInfo("%s, wal retrieve is finished, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]); + SWalHead walHead; memset(&walHead, 0, sizeof(walHead)); code = taosWriteMsg(pPeer->syncFd, &walHead, sizeof(walHead)); } else { - sError("%s, failed to send wal(%s)", pPeer->id, strerror(errno)); + sError("%s, failed to send wal since %s", pPeer->id, strerror(errno)); } return code; @@ -440,14 +458,14 @@ static int32_t syncRetrieveDataStepByStep(SSyncPeer *pPeer) { tstrncpy(firstPkt.fqdn, tsNodeFqdn, sizeof(firstPkt.fqdn)); firstPkt.port = tsSyncPort; - if (write(pPeer->syncFd, (char *)&firstPkt, sizeof(firstPkt)) < 0) { + if (taosWriteMsg(pPeer->syncFd, (char *)&firstPkt, sizeof(firstPkt)) < 0) { sError("%s, failed to send syncCmd", pPeer->id); return -1; } pPeer->sversion = 0; pPeer->sstatus = TAOS_SYNC_STATUS_FILE; - sDebug("%s, start to retrieve file", pPeer->id); + sInfo("%s, start to retrieve file, set sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]); if (syncRetrieveFile(pPeer) < 0) { sError("%s, failed to retrieve file", pPeer->id); return -1; @@ -456,7 +474,7 @@ static int32_t syncRetrieveDataStepByStep(SSyncPeer *pPeer) { // if no files are synced, there must be wal to sync, sversion must be larger than one if (pPeer->sversion == 0) pPeer->sversion = 1; - sDebug("%s, start to retrieve wal", pPeer->id); + sInfo("%s, start to retrieve wal", pPeer->id); if (syncRetrieveWal(pPeer) < 0) { sError("%s, failed to retrieve wal", pPeer->id); return -1; @@ -478,7 +496,7 @@ void *syncRetrieveData(void *param) { sInfo("%s, sync tcp is setup", pPeer->id); if (syncRetrieveDataStepByStep(pPeer) == 0) { - sDebug("%s, sync retrieve process is successful", pPeer->id); + sInfo("%s, sync retrieve process is successful", pPeer->id); } else { sError("%s, failed to retrieve data, restart connection", pPeer->id); syncRestartConnection(pPeer); @@ -489,10 +507,10 @@ void *syncRetrieveData(void *param) { // if file is changed 3 times continuously, start flow control pPeer->numOfRetrieves++; if (pPeer->numOfRetrieves >= 2 && pNode->notifyFlowCtrl) - (*pNode->notifyFlowCtrl)(pNode->ahandle, 4 << (pPeer->numOfRetrieves - 2)); + (*pNode->notifyFlowCtrl)(pNode->vgId, 4 << (pPeer->numOfRetrieves - 2)); } else { pPeer->numOfRetrieves = 0; - if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->ahandle, 0); + if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->vgId, 0); } pPeer->fileChanged = 0; diff --git a/src/sync/src/taosTcpPool.c b/src/sync/src/taosTcpPool.c index 875528e66b188294707bf1cc67baf3780ece6490..d1d9815f4af2e787f251dd15e41c2d8eccfbebe9 100644 --- a/src/sync/src/taosTcpPool.c +++ b/src/sync/src/taosTcpPool.c @@ -150,7 +150,7 @@ void *taosAllocateTcpConn(void *param, void *pPeer, int32_t connFd) { } void taosFreeTcpConn(void *param) { - SConnObj * pConn = (SConnObj *)param; + SConnObj * pConn = param; SThreadObj *pThread = pConn->pThread; sDebug("%p TCP connection will be closed, fd:%d", pThread, pConn->fd); diff --git a/src/sync/src/tarbitrator.c b/src/sync/src/tarbitrator.c index b7f819a3cd8f890d3580352322d8313f7cb2828e..4016042de2135f732dfeb2bbc3b0fdc65b1b63f6 100644 --- a/src/sync/src/tarbitrator.c +++ b/src/sync/src/tarbitrator.c @@ -115,14 +115,14 @@ static void arbProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) { SFirstPkt firstPkt; if (taosReadMsg(connFd, &firstPkt, sizeof(firstPkt)) != sizeof(firstPkt)) { - sError("failed to read peer first pkt from ip:%s(%s)", ipstr, strerror(errno)); + sError("failed to read peer first pkt from ip:%s since %s", ipstr, strerror(errno)); taosCloseSocket(connFd); return; } - SNodeConn *pNode = (SNodeConn *)calloc(sizeof(SNodeConn), 1); + SNodeConn *pNode = calloc(sizeof(SNodeConn), 1); if (pNode == NULL) { - sError("failed to allocate memory(%s)", strerror(errno)); + sError("failed to allocate memory since %s", strerror(errno)); taosCloseSocket(connFd); return; } @@ -146,7 +146,7 @@ static void arbProcessIncommingConnection(int32_t connFd, uint32_t sourceIp) { static void arbProcessBrokenLink(void *param) { SNodeConn *pNode = param; - sDebug("%s, TCP link is broken(%s), close connection", pNode->id, strerror(errno)); + sDebug("%s, TCP link is broken since %s, close connection", pNode->id, strerror(errno)); tfree(pNode); } diff --git a/src/sync/test/syncServer.c b/src/sync/test/syncServer.c index 9dd3feb4614105c13ba6a2d1069931345167b472..5a64a0a36a9c5e0557e78216ba41a48a23cc874b 100644 --- a/src/sync/test/syncServer.c +++ b/src/sync/test/syncServer.c @@ -70,7 +70,7 @@ int writeIntoWal(SWalHead *pHead) { return 0; } -void confirmForward(void *ahandle, void *mhandle, int32_t code) { +void confirmForward(int32_t vgId, void *mhandle, int32_t code) { SRpcMsg * pMsg = (SRpcMsg *)mhandle; SWalHead *pHead = (SWalHead *)(((char *)pMsg->pCont) - sizeof(SWalHead)); @@ -227,7 +227,7 @@ void processRequestMsg(SRpcMsg *pMsg, SRpcEpSet *pEpSet) { taosWriteQitem(qhandle, TAOS_QTYPE_RPC, pTemp); } -uint32_t getFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion) { +uint32_t getFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion) { uint32_t magic; struct stat fstat; char aname[280]; @@ -254,7 +254,7 @@ uint32_t getFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex return magic; } -int getWalInfo(void *ahandle, char *name, int64_t *index) { +int getWalInfo(int32_t vgId, char *name, int64_t *index) { struct stat fstat; char aname[280]; @@ -272,7 +272,7 @@ int getWalInfo(void *ahandle, char *name, int64_t *index) { return 1; } -int writeToCache(void *ahandle, void *data, int type) { +int writeToCache(int32_t vgId, void *data, int type) { SWalHead *pHead = data; uDebug("pkt from peer is received, ver:%" PRIu64 " len:%d type:%d", pHead->version, pHead->len, type); @@ -285,9 +285,9 @@ int writeToCache(void *ahandle, void *data, int type) { return 0; } -void confirmFwd(void *ahandle, int64_t version) { return; } +void confirmFwd(int32_t vgId, int64_t version) { return; } -void notifyRole(void *ahandle, int8_t r) { +void notifyRole(int32_t vgId, int8_t r) { role = r; printf("current role:%s\n", syncRole[role]); } @@ -296,7 +296,6 @@ void initSync() { pCfg->replica = 1; pCfg->quorum = 1; syncInfo.vgId = 1; - syncInfo.ahandle = &syncInfo; syncInfo.getFileInfo = getFileInfo; syncInfo.getWalInfo = getWalInfo; syncInfo.writeToCache = writeToCache; diff --git a/src/util/src/tsocket.c b/src/util/src/tsocket.c index 1be79b7bbd32a20c5f784ad10ca5aeff877eaac5..2543c8170896825ae2a94349c0218e7d99ce8592 100644 --- a/src/util/src/tsocket.c +++ b/src/util/src/tsocket.c @@ -107,7 +107,7 @@ int32_t taosWriteMsg(SOCKET fd, void *buf, int32_t nbytes) { while (nleft > 0) { nwritten = (int32_t)taosWriteSocket(fd, (char *)ptr, (size_t)nleft); if (nwritten <= 0) { - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) + if (errno == EINTR /* || errno == EAGAIN || errno == EWOULDBLOCK */) continue; else return -1; @@ -133,7 +133,7 @@ int32_t taosReadMsg(SOCKET fd, void *buf, int32_t nbytes) { if (nread == 0) { break; } else if (nread < 0) { - if (errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK) { + if (errno == EINTR/* || errno == EAGAIN || errno == EWOULDBLOCK*/) { continue; } else { return -1; diff --git a/src/vnode/inc/vnodeInt.h b/src/vnode/inc/vnodeInt.h index c9689ce8b266acd88b0b6212637768934e4833ed..021831a644e1da3d1de882e14852d1fa5e58bc1d 100644 --- a/src/vnode/inc/vnodeInt.h +++ b/src/vnode/inc/vnodeInt.h @@ -37,8 +37,9 @@ extern int32_t vDebugFlag; typedef struct { int32_t vgId; // global vnode group ID int32_t refCount; // reference count - int32_t queuedMsg; - int32_t delay; + int32_t queuedWMsg; + int32_t queuedRMsg; + int32_t delayMs; int8_t status; int8_t role; int8_t accessState; diff --git a/src/vnode/src/vnodeMain.c b/src/vnode/src/vnodeMain.c index 7447acc488c2e05298b1096331745420e3fc9739..b94fea52bd4f8fbdd20677bf874684123f03a9d4 100644 --- a/src/vnode/src/vnodeMain.c +++ b/src/vnode/src/vnodeMain.c @@ -30,19 +30,21 @@ static SHashObj*tsVnodesHash; static void vnodeCleanUp(SVnodeObj *pVnode); -static int vnodeProcessTsdbStatus(void *arg, int status, int eno); -static uint32_t vnodeGetFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion); -static int vnodeGetWalInfo(void *ahandle, char *fileName, int64_t *fileId); -static void vnodeNotifyRole(void *ahandle, int8_t role); -static void vnodeCtrlFlow(void *handle, int32_t mseconds); -static int vnodeNotifyFileSynced(void *ahandle, uint64_t fversion); +static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno); +static uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion); +static int32_t vnodeGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId); +static void vnodeNotifyRole(int32_t vgId, int8_t role); +static void vnodeCtrlFlow(int32_t vgId, int32_t mseconds); +static int32_t vnodeNotifyFileSynced(int32_t vgId, uint64_t fversion); +static void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code); +static int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam); #ifndef _SYNC int64_t syncStart(const SSyncInfo *info) { return NULL; } -int32_t syncForwardToPeer(int64_t rid, void *pHead, void *mhandle, int qtype) { return 0; } +int32_t syncForwardToPeer(int64_t rid, void *pHead, void *mhandle, int32_t qtype) { return 0; } void syncStop(int64_t rid) {} -int32_t syncReconfig(int64_t rid, const SSyncCfg * cfg) { return 0; } -int syncGetNodesRole(int64_t rid, SNodesRole * cfg) { return 0; } +int32_t syncReconfig(int64_t rid, const SSyncCfg *cfg) { return 0; } +int32_t syncGetNodesRole(int64_t rid, SNodesRole *cfg) { return 0; } void syncConfirmForward(int64_t rid, uint64_t version, int32_t code) {} #endif @@ -55,13 +57,13 @@ char* vnodeStatus[] = { }; int32_t vnodeInitResources() { - int code = syncInit(); + int32_t code = syncInit(); if (code != 0) return code; vnodeInitWriteFp(); vnodeInitReadFp(); - tsVnodesHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, true); + tsVnodesHash = taosHashInit(TSDB_MIN_VNODES, taosGetDefaultHashFunction(TSDB_DATA_TYPE_INT), true, HASH_ENTRY_LOCK); if (tsVnodesHash == NULL) { vError("failed to init vnode list"); return TSDB_CODE_VND_OUT_OF_MEMORY; @@ -173,8 +175,8 @@ int32_t vnodeDrop(int32_t vgId) { return TSDB_CODE_SUCCESS; } -int32_t vnodeAlter(void *param, SCreateVnodeMsg *pVnodeCfg) { - SVnodeObj *pVnode = param; +int32_t vnodeAlter(void *vparam, SCreateVnodeMsg *pVnodeCfg) { + SVnodeObj *pVnode = vparam; // vnode in non-ready state and still needs to return success instead of TSDB_CODE_VND_INVALID_STATUS // cfgVersion can be corrected by status msg @@ -325,16 +327,28 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) { walRemoveAllOldFiles(pVnode->wal); walRenew(pVnode->wal); + pVnode->qMgmt = qOpenQueryMgmt(pVnode->vgId); + if (pVnode->qMgmt == NULL) { + vnodeCleanUp(pVnode); + return terrno; + } + + pVnode->events = NULL; + + vDebug("vgId:%d, vnode is opened in %s, pVnode:%p", pVnode->vgId, rootDir, pVnode); + tsdbIncCommitRef(pVnode->vgId); + + taosHashPut(tsVnodesHash, &pVnode->vgId, sizeof(int32_t), &pVnode, sizeof(SVnodeObj *)); + SSyncInfo syncInfo; syncInfo.vgId = pVnode->vgId; syncInfo.version = pVnode->version; syncInfo.syncCfg = pVnode->syncCfg; sprintf(syncInfo.path, "%s", rootDir); - syncInfo.ahandle = pVnode; syncInfo.getWalInfo = vnodeGetWalInfo; syncInfo.getFileInfo = vnodeGetFileInfo; - syncInfo.writeToCache = vnodeWriteToWQueue; - syncInfo.confirmForward = dnodeSendRpcVWriteRsp; + syncInfo.writeToCache = vnodeWriteToCache; + syncInfo.confirmForward = vnodeConfirmForard; syncInfo.notifyRole = vnodeNotifyRole; syncInfo.notifyFlowCtrl = vnodeCtrlFlow; syncInfo.notifyFileSynced = vnodeNotifyFileSynced; @@ -346,24 +360,13 @@ int32_t vnodeOpen(int32_t vnode, char *rootDir) { if (pVnode->sync <= 0) { vError("vgId:%d, failed to open sync module, replica:%d reason:%s", pVnode->vgId, pVnode->syncCfg.replica, tstrerror(terrno)); + vnodeRelease(pVnode); vnodeCleanUp(pVnode); return terrno; } -#endif - - pVnode->qMgmt = qOpenQueryMgmt(pVnode->vgId); - if (pVnode->qMgmt == NULL) { - vnodeCleanUp(pVnode); - return terrno; - } +#endif - pVnode->events = NULL; pVnode->status = TAOS_VN_STATUS_READY; - vDebug("vgId:%d, vnode is opened in %s, pVnode:%p", pVnode->vgId, rootDir, pVnode); - - tsdbIncCommitRef(pVnode->vgId); - taosHashPut(tsVnodesHash, (const char *)&pVnode->vgId, sizeof(int32_t), (char *)(&pVnode), sizeof(SVnodeObj *)); - return TSDB_CODE_SUCCESS; } @@ -378,9 +381,9 @@ int32_t vnodeClose(int32_t vgId) { return 0; } -void vnodeRelease(void *pVnodeRaw) { - if (pVnodeRaw == NULL) return; - SVnodeObj *pVnode = pVnodeRaw; +void vnodeRelease(void *vparam) { + if (vparam == NULL) return; + SVnodeObj *pVnode = vparam; int32_t code = 0; int32_t vgId = pVnode->vgId; @@ -389,7 +392,7 @@ void vnodeRelease(void *pVnodeRaw) { assert(refCount >= 0); if (refCount > 0) { - if (pVnode->status == TAOS_VN_STATUS_RESET && refCount == 2) { + if (pVnode->status == TAOS_VN_STATUS_RESET && refCount <= 3) { tsem_post(&pVnode->sem); } return; @@ -567,11 +570,11 @@ void vnodeSetAccess(SVgroupAccess *pAccess, int32_t numOfVnodes) { static void vnodeCleanUp(SVnodeObj *pVnode) { // remove from hash, so new messages wont be consumed - taosHashRemove(tsVnodesHash, (const char *)&pVnode->vgId, sizeof(int32_t)); + taosHashRemove(tsVnodesHash, &pVnode->vgId, sizeof(int32_t)); if (pVnode->status != TAOS_VN_STATUS_INIT) { // it may be in updateing or reset state, then it shall wait - int i = 0; + int32_t i = 0; while (atomic_val_compare_exchange_8(&pVnode->status, TAOS_VN_STATUS_READY, TAOS_VN_STATUS_CLOSING) != TAOS_VN_STATUS_READY) { if (++i % 1000 == 0) { @@ -595,7 +598,7 @@ static void vnodeCleanUp(SVnodeObj *pVnode) { } // TODO: this is a simple implement -static int vnodeProcessTsdbStatus(void *arg, int status, int eno) { +static int32_t vnodeProcessTsdbStatus(void *arg, int32_t status, int32_t eno) { SVnodeObj *pVnode = arg; if (eno != TSDB_CODE_SUCCESS) { @@ -608,56 +611,88 @@ static int vnodeProcessTsdbStatus(void *arg, int status, int eno) { if (status == TSDB_STATUS_COMMIT_START) { pVnode->fversion = pVnode->version; vDebug("vgId:%d, start commit, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, pVnode->version); - if (pVnode->status == TAOS_VN_STATUS_INIT) { - return 0; - } else { + if (pVnode->status != TAOS_VN_STATUS_INIT) { return walRenew(pVnode->wal); } + return 0; } if (status == TSDB_STATUS_COMMIT_OVER) { vDebug("vgId:%d, commit over, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, pVnode->version); pVnode->isFull = 0; - walRemoveOneOldFile(pVnode->wal); + if (pVnode->status != TAOS_VN_STATUS_INIT) { + walRemoveOneOldFile(pVnode->wal); + } return vnodeSaveVersion(pVnode); } return 0; } -static uint32_t vnodeGetFileInfo(void *ahandle, char *name, uint32_t *index, uint32_t eindex, int64_t *size, +static uint32_t vnodeGetFileInfo(int32_t vgId, char *name, uint32_t *index, uint32_t eindex, int64_t *size, uint64_t *fversion) { - SVnodeObj *pVnode = ahandle; + SVnodeObj *pVnode = vnodeAcquire(vgId); + if (pVnode == NULL) { + vError("vgId:%d, vnode not found while get file info", vgId); + return 0; + } + *fversion = pVnode->fversion; - return tsdbGetFileInfo(pVnode->tsdb, name, index, eindex, size); + uint32_t ret = tsdbGetFileInfo(pVnode->tsdb, name, index, eindex, size); + + vnodeRelease(pVnode); + return ret; } -static int vnodeGetWalInfo(void *ahandle, char *fileName, int64_t *fileId) { - SVnodeObj *pVnode = ahandle; - return walGetWalFile(pVnode->wal, fileName, fileId); +static int32_t vnodeGetWalInfo(int32_t vgId, char *fileName, int64_t *fileId) { + SVnodeObj *pVnode = vnodeAcquire(vgId); + if (pVnode == NULL) { + vError("vgId:%d, vnode not found while get wal info", vgId); + return -1; + } + + int32_t code = walGetWalFile(pVnode->wal, fileName, fileId); + + vnodeRelease(pVnode); + return code; } -static void vnodeNotifyRole(void *ahandle, int8_t role) { - SVnodeObj *pVnode = ahandle; +static void vnodeNotifyRole(int32_t vgId, int8_t role) { + SVnodeObj *pVnode = vnodeAcquire(vgId); + if (pVnode == NULL) { + vError("vgId:%d, vnode not found while notify role", vgId); + return; + } + vInfo("vgId:%d, sync role changed from %s to %s", pVnode->vgId, syncRole[pVnode->role], syncRole[role]); pVnode->role = role; dnodeSendStatusMsgToMnode(); - if (pVnode->role == TAOS_SYNC_ROLE_MASTER) + if (pVnode->role == TAOS_SYNC_ROLE_MASTER) { cqStart(pVnode->cq); - else + } else { cqStop(pVnode->cq); + } + + vnodeRelease(pVnode); } -static void vnodeCtrlFlow(void *ahandle, int32_t mseconds) { - SVnodeObj *pVnode = ahandle; - if (pVnode->delay != mseconds) { - vInfo("vgId:%d, sync flow control, mseconds:%d", pVnode->vgId, mseconds); +static void vnodeCtrlFlow(int32_t vgId, int32_t mseconds) { + SVnodeObj *pVnode = vnodeAcquire(vgId); + if (pVnode == NULL) { + vError("vgId:%d, vnode not found while ctrl flow", vgId); + return; } - pVnode->delay = mseconds; + + if (pVnode->delayMs != mseconds) { + pVnode->delayMs = mseconds; + vDebug("vgId:%d, sync flow control, mseconds:%d", pVnode->vgId, mseconds); + } + + vnodeRelease(pVnode); } -static int vnodeResetTsdb(SVnodeObj *pVnode) { +static int32_t vnodeResetTsdb(SVnodeObj *pVnode) { char rootDir[128] = "\0"; sprintf(rootDir, "%s/tsdb", pVnode->rootDir); @@ -667,11 +702,11 @@ static int vnodeResetTsdb(SVnodeObj *pVnode) { void *tsdb = pVnode->tsdb; pVnode->tsdb = NULL; - + // acquire vnode int32_t refCount = atomic_add_fetch_32(&pVnode->refCount, 1); - if (refCount > 2) { + if (refCount > 3) { tsem_wait(&pVnode->sem); } @@ -691,14 +726,44 @@ static int vnodeResetTsdb(SVnodeObj *pVnode) { return 0; } -static int vnodeNotifyFileSynced(void *ahandle, uint64_t fversion) { - SVnodeObj *pVnode = ahandle; +static int32_t vnodeNotifyFileSynced(int32_t vgId, uint64_t fversion) { + SVnodeObj *pVnode = vnodeAcquire(vgId); + if (pVnode == NULL) { + vError("vgId:%d, vnode not found while notify file synced", vgId); + return 0; + } pVnode->fversion = fversion; pVnode->version = fversion; vnodeSaveVersion(pVnode); - vDebug("vgId:%d, data file is synced, fver:%" PRIu64 " vver:%" PRIu64, pVnode->vgId, pVnode->fversion, - pVnode->version); - return vnodeResetTsdb(pVnode); + vDebug("vgId:%d, data file is synced, fver:%" PRIu64 " vver:%" PRIu64, vgId, fversion, fversion); + int32_t code = vnodeResetTsdb(pVnode); + + vnodeRelease(pVnode); + return code; +} + +void vnodeConfirmForard(int32_t vgId, void *wparam, int32_t code) { + void *pVnode = vnodeAcquire(vgId); + if (pVnode == NULL) { + vError("vgId:%d, vnode not found while confirm forward", vgId); + return; + } + + dnodeSendRpcVWriteRsp(pVnode, wparam, code); + vnodeRelease(pVnode); +} + +static int32_t vnodeWriteToCache(int32_t vgId, void *wparam, int32_t qtype, void *rparam) { + SVnodeObj *pVnode = vnodeAcquire(vgId); + if (pVnode == NULL) { + vError("vgId:%d, vnode not found while write to cache", vgId); + return TSDB_CODE_VND_INVALID_VGROUP_ID; + } + + int32_t code = vnodeWriteToWQueue(pVnode, wparam, qtype, rparam); + + vnodeRelease(pVnode); + return code; } diff --git a/src/vnode/src/vnodeRead.c b/src/vnode/src/vnodeRead.c index 4cc8819bcba07847cb3fa1b09f0663b6368b148b..5ef79cfbf01fb49ebbfd4603b8a9163b3ae9bc32 100644 --- a/src/vnode/src/vnodeRead.c +++ b/src/vnode/src/vnodeRead.c @@ -41,8 +41,8 @@ void vnodeInitReadFp(void) { // still required, or there will be a deadlock, so we don’t do any check here, but put the check codes before the // request enters the queue // -int32_t vnodeProcessRead(void *param, SVReadMsg *pRead) { - SVnodeObj *pVnode = (SVnodeObj *)param; +int32_t vnodeProcessRead(void *vparam, SVReadMsg *pRead) { + SVnodeObj *pVnode = vparam; int32_t msgType = pRead->msgType; if (vnodeProcessReadMsgFp[msgType] == NULL) { @@ -53,8 +53,7 @@ int32_t vnodeProcessRead(void *param, SVReadMsg *pRead) { return (*vnodeProcessReadMsgFp[msgType])(pVnode, pRead); } -static int32_t vnodeCheckRead(void *param) { - SVnodeObj *pVnode = param; +static int32_t vnodeCheckRead(SVnodeObj *pVnode) { if (pVnode->status != TAOS_VN_STATUS_READY) { vDebug("vgId:%d, vnode status is %s, refCount:%d pVnode:%p", pVnode->vgId, vnodeStatus[pVnode->status], pVnode->refCount, pVnode); @@ -76,6 +75,16 @@ static int32_t vnodeCheckRead(void *param) { return TSDB_CODE_SUCCESS; } +void vnodeFreeFromRQueue(void *vparam, SVReadMsg *pRead) { + SVnodeObj *pVnode = vparam; + + atomic_sub_fetch_32(&pVnode->queuedRMsg, 1); + vTrace("vgId:%d, free from vrqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedRMsg); + + taosFreeQitem(pRead); + vnodeRelease(pVnode); +} + int32_t vnodeWriteToRQueue(void *vparam, void *pCont, int32_t contLen, int8_t qtype, void *rparam) { SVnodeObj *pVnode = vparam; @@ -108,7 +117,8 @@ int32_t vnodeWriteToRQueue(void *vparam, void *pCont, int32_t contLen, int8_t qt pRead->qtype = qtype; atomic_add_fetch_32(&pVnode->refCount, 1); - vTrace("vgId:%d, get vnode rqueue, refCount:%d pVnode:%p", pVnode->vgId, pVnode->refCount, pVnode); + atomic_add_fetch_32(&pVnode->queuedRMsg, 1); + vTrace("vgId:%d, write into vrqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedRMsg); taosWriteQitem(pVnode->rqueue, qtype, pRead); return TSDB_CODE_SUCCESS; diff --git a/src/vnode/src/vnodeWrite.c b/src/vnode/src/vnodeWrite.c index 2234b4f8eda7caa8622b60be8a9018d6aae40ad1..a0227d84babef8ee4259c7d86121770660097020 100644 --- a/src/vnode/src/vnodeWrite.c +++ b/src/vnode/src/vnodeWrite.c @@ -48,10 +48,10 @@ void vnodeInitWriteFp(void) { } int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rparam) { - int32_t code = 0; - SVnodeObj * pVnode = vparam; - SWalHead * pHead = wparam; - SRspRet * pRspRet = rparam; + int32_t code = 0; + SVnodeObj *pVnode = vparam; + SWalHead * pHead = wparam; + SRspRet * pRspRet = rparam; if (vnodeProcessWriteMsgFp[pHead->msgType] == NULL) { vError("vgId:%d, msg:%s not processed since no handle, qtype:%s hver:%" PRIu64, pVnode->vgId, @@ -77,7 +77,7 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara // assign version pHead->version = pVnode->version + 1; - if (pVnode->delay) usleep(pVnode->delay * 1000); + if (pVnode->delayMs) taosMsleep(pVnode->delayMs); } else { // from wal or forward // for data from WAL or forward, version may be smaller @@ -245,13 +245,13 @@ int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rpar atomic_add_fetch_32(&pVnode->refCount, 1); - int32_t queued = atomic_add_fetch_32(&pVnode->queuedMsg, 1); + int32_t queued = atomic_add_fetch_32(&pVnode->queuedWMsg, 1); if (queued > MAX_QUEUED_MSG_NUM) { vDebug("vgId:%d, too many msg:%d in vwqueue, flow control", pVnode->vgId, queued); taosMsleep(1); } - vTrace("vgId:%d, write into vwqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedMsg); + vTrace("vgId:%d, write into vwqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedWMsg); taosWriteQitem(pVnode->wqueue, qtype, pWrite); return TSDB_CODE_SUCCESS; @@ -260,8 +260,8 @@ int32_t vnodeWriteToWQueue(void *vparam, void *wparam, int32_t qtype, void *rpar void vnodeFreeFromWQueue(void *vparam, SVWriteMsg *pWrite) { SVnodeObj *pVnode = vparam; - atomic_sub_fetch_32(&pVnode->queuedMsg, 1); - vTrace("vgId:%d, free from vwqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedMsg); + atomic_sub_fetch_32(&pVnode->queuedWMsg, 1); + vTrace("vgId:%d, free from vwqueue, refCount:%d queued:%d", pVnode->vgId, pVnode->refCount, pVnode->queuedWMsg); taosFreeQitem(pWrite); vnodeRelease(pVnode); diff --git a/src/wal/src/walWrite.c b/src/wal/src/walWrite.c index 72464d4309b5fe2b6e40f5e197bee59482843526..36b3dba165cbf399360e95d090278a681b10646d 100644 --- a/src/wal/src/walWrite.c +++ b/src/wal/src/walWrite.c @@ -144,9 +144,9 @@ void walFsync(void *handle, bool forceFsync) { if (pWal == NULL || pWal->fd < 0) return; if (forceFsync || (pWal->level == TAOS_WAL_FSYNC && pWal->fsyncPeriod == 0)) { - wTrace("vgId:%d, file:%s, do fsync", pWal->vgId, pWal->name); + wTrace("vgId:%d, fileId:%" PRId64 ", do fsync", pWal->vgId, pWal->fileId); if (fsync(pWal->fd) < 0) { - wError("vgId:%d, file:%s, fsync failed since %s", pWal->vgId, pWal->name, strerror(errno)); + wError("vgId:%d, fileId:%" PRId64 ", fsync failed since %s", pWal->vgId, pWal->fileId, strerror(errno)); } } } diff --git a/tests/examples/rust b/tests/examples/rust deleted file mode 160000 index f2ffd30521b8e8afbc9d25c75f8eeeb6a48bd030..0000000000000000000000000000000000000000 --- a/tests/examples/rust +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f2ffd30521b8e8afbc9d25c75f8eeeb6a48bd030 diff --git a/tests/perftest-scripts/perftest-query.sh b/tests/perftest-scripts/perftest-query.sh index bb5d9e0a9d16ccb232feeaea00a72a0972b31cc2..51bb9b36c3c55802fa904de223c2ae4ea2ea7151 100755 --- a/tests/perftest-scripts/perftest-query.sh +++ b/tests/perftest-scripts/perftest-query.sh @@ -1,8 +1,8 @@ #!/bin/bash today=`date +"%Y%m%d"` -WORK_DIR=/home/ubuntu/pxiao/ -PERFORMANCE_TEST_REPORT=$TDENGINE_DIR/tests/performance-test-report-$today.log +WORK_DIR=/home/ubuntu/pxiao +PERFORMANCE_TEST_REPORT=$WORK_DIR/TDengine/tests/performance-test-report-$today.log # Coloured Echoes # function red_echo { echo -e "\033[31m$@\033[0m"; } # @@ -60,11 +60,12 @@ function buildTDengine { } function runQueryPerfTest { - nohup $WORK_DIR/TDengine/debug/build/bin/taosd -c /etc/taodperf/ > /dev/null 2>&1 & + [ -f $PERFORMANCE_TEST_REPORT ] && rm $PERFORMANCE_TEST_REPORT + nohup $WORK_DIR/TDengine/debug/build/bin/taosd -c /etc/taosperf/ > /dev/null 2>&1 & echoInfo "Run Performance Test" cd $WORK_DIR/TDengine/tests/pytest - python3 query/queryPerformance.py | tee -a $PERFORMANCE_TEST_REPORT + python3 query/queryPerformance.py 0 | tee -a $PERFORMANCE_TEST_REPORT } @@ -77,9 +78,9 @@ function sendReport { sed -i 's/\x1b\[[0-9;]*m//g' $PERFORMANCE_TEST_REPORT BODY_CONTENT=`cat $PERFORMANCE_TEST_REPORT` - echo -e "to: ${receiver}\nsubject: Query Performace Report ${today}, commit ID: ${LOCAL_COMMIT}\n\n${today}:\n${BODY_CONTENT}" | \ + echo -e "From: \nto: ${receiver}\nsubject: Query Performace Report ${today}, commit ID: ${LOCAL_COMMIT}\n\n${today}:\n${BODY_CONTENT}" | \ (cat - && uuencode $PERFORMANCE_TEST_REPORT performance-test-report-$today.log) | \ - ssmtp "${receiver}" && echo "Report Sent!" + /usr/sbin/ssmtp "${receiver}" && echo "Report Sent!" } diff --git a/tests/pytest/cluster/clusterSetup.py b/tests/pytest/cluster/clusterSetup.py index 36af8ac42e56e1b8a7ab2237305a6bf286103552..dbda5657b6528402cc898762cccc78d74a196cd8 100644 --- a/tests/pytest/cluster/clusterSetup.py +++ b/tests/pytest/cluster/clusterSetup.py @@ -31,6 +31,23 @@ class Node: self.homeDir = homeDir self.conn = Connection("{}@{}".format(username, hostName), connect_kwargs={"password": "{}".format(password)}) + def buildTaosd(self): + try: + self.conn.cd("/root/TDinternal/community") + self.conn.run("git checkout develop") + self.conn.run("git pull") + self.conn.cd("/root/TDinternal") + self.conn.run("git checkout develop") + self.conn.run("git pull") + self.conn.cd("/root/TDinternal/debug") + self.conn.run("cmake ..") + self.conn.run("make") + self.conn.run("make install") + except Exception as e: + print("Build Taosd error for node %d " % self.index) + logging.exception(e) + pass + def startTaosd(self): try: self.conn.run("sudo systemctl start taosd") @@ -50,7 +67,7 @@ class Node: self.conn.run("sudo systemctl restart taosd") except Exception as e: print("Stop Taosd error for node %d " % self.index) - logging.exception(e) + logging.exception(e) def removeTaosd(self): try: @@ -105,9 +122,11 @@ class Node: class Nodes: def __init__(self): - self.node1 = Node(1, 'ubuntu', '192.168.1.52', 'node1', 'tbase125!', '/home/ubuntu') - self.node2 = Node(2, 'ubuntu', '192.168.1.53', 'node2', 'tbase125!', '/home/ubuntu') - self.node3 = Node(3, 'ubuntu', '192.168.1.54', 'node3', 'tbase125!', '/home/ubuntu') + self.node1 = Node(1, 'root', '52.151.60.239', 'node1', 'r', '/root/') + self.node2 = Node(2, 'root', '52.183.32.246', 'node1', 'r', '/root/') + self.node3 = Node(3, 'root', '51.143.46.79', 'node1', 'r', '/root/') + self.node4 = Node(4, 'root', '52.183.2.76', 'node1', 'r', '/root/') + self.node5 = Node(5, 'root', '13.66.225.87', 'node1', 'r', '/root/') def stopAllTaosd(self): self.node1.stopTaosd() diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index 3a9aa00617b42d86b811da10b5a7113221c5990b..525fbad6c1c3a9c45d0e92ba467b255a3538a975 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -202,6 +202,7 @@ python3 queryCount.py python3 ./test.py -f query/queryGroupbyWithInterval.py python3 client/twoClients.py python3 test.py -f query/queryInterval.py +python3 test.py -f query/queryFillTest.py # tools python3 test.py -f tools/taosdemo.py diff --git a/tests/pytest/handle_crash_gen_val_log.sh b/tests/pytest/handle_crash_gen_val_log.sh index 2d48de65c9a16fdb6f5f906167baf772694e9a05..ce3d1c0c673e6e62fdd2e6ac83769eb3d7a8ca71 100755 --- a/tests/pytest/handle_crash_gen_val_log.sh +++ b/tests/pytest/handle_crash_gen_val_log.sh @@ -5,7 +5,7 @@ GREEN='\033[1;32m' GREEN_DARK='\033[0;32m' GREEN_UNDERLINE='\033[4;32m' NC='\033[0m' -nohup /root/TDinternal/debug/build/bin/taosd -c /root/TDinternal/community/sim/dnode1/cfg >/dev/null & +nohup /var/lib/jenkins/workspace/TDinternal/debug/build/bin/taosd -c /var/lib/jenkins/workspace/TDinternal/community/sim/dnode1/cfg >/dev/null & ./crash_gen.sh --valgrind -p -t 10 -s 100 -b 4 pidof taosd|xargs kill grep 'start to execute\|ERROR SUMMARY' valgrind.err|grep -v 'grep'|uniq|tee crash_gen_mem_err.log diff --git a/tests/pytest/query/queryFillTest.py b/tests/pytest/query/queryFillTest.py new file mode 100644 index 0000000000000000000000000000000000000000..9fd898041a525f9aaba65bda1233f94b1bb922e6 --- /dev/null +++ b/tests/pytest/query/queryFillTest.py @@ -0,0 +1,68 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import tdLog +from util.cases import tdCases +from util.sql import tdSql + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + self.ts = 1537146000000 + + def run(self): + tdSql.prepare() + + print("==============step1") + tdSql.execute( + "create table if not exists stb (ts timestamp, col1 int, col2 int, col3 int) tags(loc nchar(20), id int)") + + currTs = self.ts + + for i in range(100): + sql = "create table tb%d using stb tags('city%d', 1)" % (i, i) + tdSql.execute(sql) + + sql = "insert into tb%d values" % i + for j in range(5): + val = 1 + j + sql += "(%d, %d, %d, %d)" % (currTs, val, val, val) + currTs += 1000000 + tdSql.execute(sql) + + tdSql.query("select first(col1) - avg(col1) from stb where ts > '2018-09-17 08:00:00.000' and ts < '2018-09-23 04:36:40.000' interval(1h)") + tdSql.checkRows(139) + + tdSql.query("select first(col1) - avg(col1) from stb where ts > '2018-09-17 08:00:00.000' and ts < '2018-09-23 04:36:40.000' interval(1h) fill(null)") + tdSql.checkRows(141) + tdSql.checkData(0, 1, None) + tdSql.checkData(140, 1, None) + + tdSql.query("select max(col1) - min(col1) from stb where ts > '2018-09-17 08:00:00.000' and ts < '2018-09-23 04:36:40.000' and id = 1 group by loc, id") + rows = tdSql.queryRows + + tdSql.query("select spread(col1) from stb where ts > '2018-09-17 08:00:00.000' and ts < '2018-09-23 04:36:40.000' and id = 1 group by loc, id") + tdSql.checkRows(rows) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file diff --git a/tests/pytest/query/queryInterval.py b/tests/pytest/query/queryInterval.py index ec3255ba7f12302f6ee00aeda391c11972f1cf26..98b8c9fbef819caebe34fce96bec66da99176131 100644 --- a/tests/pytest/query/queryInterval.py +++ b/tests/pytest/query/queryInterval.py @@ -32,30 +32,44 @@ class TDTestCase: tdSql.execute("insert into t0 using st tags('beijing') values(%d, 220) (%d, 221) (%d, 225) (%d, 228) (%d, 222)" % (self.ts, self.ts + 1000000000, self.ts + 2000000000, self.ts + 3000000000, self.ts + 6000000000)) tdSql.execute("insert into t1 using st tags('shanghai') values(%d, 220) (%d, 221) (%d, 225) (%d, 228) (%d, 222)" - % (self.ts, self.ts + 2000000000, self.ts + 4000000000, self.ts + 5000000000, self.ts + 7000000000)) + % (self.ts, self.ts + 2000000000, self.ts + 4000000000, self.ts + 5000000000, self.ts + 7000000000)) + tdSql.query("select avg(voltage) from st interval(1n)") - tdSql.checkRows(4) - tdSql.checkData(0, 1, 220.0) - tdSql.checkData(1, 1, 222.33333333333334) - tdSql.checkData(2, 1, 227.0) - tdSql.checkData(3, 1, 222.0) + tdSql.checkRows(3) + tdSql.checkData(0, 0, "2020-07-01 00:00:00") + tdSql.checkData(0, 1, 221.4) + tdSql.checkData(1, 0, "2020-08-01 00:00:00") + tdSql.checkData(1, 1, 227.0) + tdSql.checkData(2, 0, "2020-09-01 00:00:00") + tdSql.checkData(2, 1, 222.0) tdSql.query("select avg(voltage) from st interval(1n, 15d)") tdSql.checkRows(4) + tdSql.checkData(0, 0, "2020-06-16 00:00:00") tdSql.checkData(0, 1, 220.333333) + tdSql.checkData(1, 0, "2020-07-16 00:00:00") tdSql.checkData(1, 1, 224.666666) + tdSql.checkData(2, 0, "2020-08-16 00:00:00") tdSql.checkData(2, 1, 225.0) + tdSql.checkData(3, 0, "2020-09-16 00:00:00") tdSql.checkData(3, 1, 222.0) tdSql.query("select avg(voltage) from st interval(1n, 15d) group by loc") tdSql.checkRows(7) + tdSql.checkData(0, 0, "2020-06-16 00:00:00") tdSql.checkData(0, 1, 220.5) + tdSql.checkData(1, 0, "2020-07-16 00:00:00") tdSql.checkData(1, 1, 226.5) + tdSql.checkData(2, 0, "2020-08-16 00:00:00") tdSql.checkData(2, 1, 222.0) + tdSql.checkData(3, 0, "2020-06-16 00:00:00") tdSql.checkData(3, 1, 220.0) + tdSql.checkData(4, 0, "2020-07-16 00:00:00") tdSql.checkData(4, 1, 221.0) + tdSql.checkData(5, 0, "2020-08-16 00:00:00") tdSql.checkData(5, 1, 226.5) + tdSql.checkData(6, 0, "2020-09-16 00:00:00") tdSql.checkData(6, 1, 222.0) def stop(self): diff --git a/tests/pytest/query/queryJoin.py b/tests/pytest/query/queryJoin.py index 5ad49a265ea52279f7934476a4a1db2fbbdf5883..57b7e8868d711878b274644a782bd4c320351049 100644 --- a/tests/pytest/query/queryJoin.py +++ b/tests/pytest/query/queryJoin.py @@ -141,6 +141,40 @@ class TDTestCase: tdSql.query("select * from meters1, meters3 where meters1.ts = meters3.ts and meters1.tag1 = meters3.tag1") tdSql.checkRows(0) + tdSql.execute("create table join_mt0(ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) tags(t1 int, t2 binary(12))") + tdSql.execute("create table join_mt1(ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) tags(t1 int, t2 binary(12), t3 int)") + + ts = 1538548685000 + for i in range(3): + tdSql.execute("create table join_tb%d using join_mt0 tags(%d, 'abc')" % (i, i)) + sql = "insert into join_tb%d values" % i + for j in range(500): + val = j % 100 + sql += "(%d, %d, %f, %d, %d, %d, %f, %d, 'binary%d', 'nchar%d')" % (ts + j, val, val * 1.0, val, val, val, val * 1.0, val % 2, val, val) + tdSql.execute(sql) + sql = "insert into join_tb%d values" % i + for j in range(500, 1000): + val = j % 100 + sql += "(%d, %d, %f, %d, %d, %d, %f, %d, 'binary%d', 'nchar%d')" % (ts + 500 + j, val, val * 1.0, val, val, val, val * 1.0, val % 2, val, val) + tdSql.execute(sql) + + for i in range(3): + tdSql.execute("create table join_1_tb%d using join_mt1 tags(%d, 'abc%d', %d)" % (i, i, i, i)) + sql = "insert into join_1_tb%d values" % i + for j in range(500): + val = j % 100 + sql += "(%d, %d, %f, %d, %d, %d, %f, %d, 'binary%d', 'nchar%d')" % (ts + j, val, val * 1.0, val, val, val, val * 1.0, val % 2, val, val) + tdSql.execute(sql) + sql = "insert into join_1_tb%d values" % i + for j in range(500, 1000): + val = j % 100 + sql += "(%d, %d, %f, %d, %d, %d, %f, %d, 'binary%d', 'nchar%d')" % (ts + 500 + j, val, val * 1.0, val, val, val, val * 1.0, val % 2, val, val) + tdSql.execute(sql) + + tdSql.error("select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1 order by join_mt0.ts desc") + tdSql.error("select count(join_mt0.c1), first(join_mt0.c1)-first(join_mt1.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts") + tdSql.error("select count(join_mt0.c1), first(join_mt0.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2 order by join_mt0.t1 desc slimit 3") + tdSql.error("select count(join_mt0.c1), first(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1, join_mt0.t2, join_mt1.t1 order by join_mt0.ts desc, join_mt1.ts asc limit 10;") def stop(self): tdSql.close() diff --git a/tests/pytest/query/queryPerformance.py b/tests/pytest/query/queryPerformance.py index e09900acc4cde66b1f2505c0fb532889d2db81e4..72af38450c862f7558df313dd53316599a23dedd 100644 --- a/tests/pytest/query/queryPerformance.py +++ b/tests/pytest/query/queryPerformance.py @@ -23,7 +23,7 @@ class taosdemoQueryPerformace: self.host = "127.0.0.1" self.user = "root" self.password = "taosdata" - self.config = "/etc/taos" + self.config = "/etc/taosperf" self.conn = taos.connect( self.host, self.user, diff --git a/tests/pytest/tools/taosdemo.py b/tests/pytest/tools/taosdemo.py index 5bf8ebaf03beb052f09d80b92c6b6b6d588e4f4f..1a976aef594576ba29b928465fc38baea6dcb63e 100644 --- a/tests/pytest/tools/taosdemo.py +++ b/tests/pytest/tools/taosdemo.py @@ -55,6 +55,12 @@ class TDTestCase: tdSql.query("select count(*) from meters") tdSql.checkData(0, 0, self.numberOfTables * self.numberOfRecords) + tdSql.query("select sum(f1) from test.meters interval(1h) sliding(30m)") + tdSql.checkRows(2) + + tdSql.query("select apercentile(f1, 1) from test.meters interval(10s)") + tdSql.checkRows(11) + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/script/general/parser/alter.sim b/tests/script/general/parser/alter.sim index 6b28b20fb87d3983fc93a055505415ffa56ac946..5c15656f246ffa09217a991ca60e127c74353700 100644 --- a/tests/script/general/parser/alter.sim +++ b/tests/script/general/parser/alter.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = m_alt_db @@ -56,6 +56,7 @@ if $rows != 2 then endi print data03 = $data03 if $data03 != taos then + print expect taos, actual: $data03 return -1 endi sql drop table tb @@ -113,7 +114,7 @@ endi sql drop table tb sql drop table mt -sleep 3000 +sleep 500 ### ALTER TABLE WHILE STREAMING [TBASE271] #sql create table tb1 (ts timestamp, c1 int, c2 nchar(5), c3 int) #sql create table strm as select count(*), avg(c1), first(c2), sum(c3) from tb1 interval(2s) @@ -133,7 +134,7 @@ sleep 3000 # return -1 #endi #sql alter table tb1 drop column c3 -#sleep 6000 +#sleep 3000 #sql insert into tb1 values (now, 2, 'taos') #sleep 30000 #sql select * from strm @@ -144,9 +145,9 @@ sleep 3000 # return -1 #endi #sql alter table tb1 add column c3 int -#sleep 6000 -#sql insert into tb1 values (now, 3, 'taos', 3); #sleep 3000 +#sql insert into tb1 values (now, 3, 'taos', 3); +#sleep 500 #sql select * from strm #if $rows != 3 then # return -1 @@ -185,7 +186,7 @@ sql create database $db sql use $db sql create table mt (ts timestamp, c1 int, c2 nchar(7), c3 int) tags (t1 int) sql create table tb using mt tags(1) -sleep 3000 +sleep 500 sql insert into tb values ('2018-11-01 16:30:00.000', 1, 'insert', 1) sql alter table mt drop column c3 diff --git a/tests/script/general/parser/alter1.sim b/tests/script/general/parser/alter1.sim index 24cf79eae148acaa822974f1d5d681983f72405a..e013242b824a42f9100557f7a9cc267833138e16 100644 --- a/tests/script/general/parser/alter1.sim +++ b/tests/script/general/parser/alter1.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect sql reset query cache @@ -87,7 +87,7 @@ if $data13 != NULL then return -1 endi -sleep 3000 +sleep 500 print ================== insert values into table sql insert into car1 values (now, 1, 1,1 ) (now +1s, 2,2,2,) car2 values (now, 1,3,3) diff --git a/tests/script/general/parser/alter_stable.sim b/tests/script/general/parser/alter_stable.sim index b64c919042296099bf0dbb17eddff67c564a745d..6b3f3a8f53548979f12707cf381d583674114616 100644 --- a/tests/script/general/parser/alter_stable.sim +++ b/tests/script/general/parser/alter_stable.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ========== alter_stable.sim diff --git a/tests/script/general/parser/auto_create_tb.sim b/tests/script/general/parser/auto_create_tb.sim index 64fec4b56d8a6623cd37884e277e0381192410ba..6deaf92a6c8e713a8fb5281ec2f8e4ca4f2d425f 100644 --- a/tests/script/general/parser/auto_create_tb.sim +++ b/tests/script/general/parser/auto_create_tb.sim @@ -4,7 +4,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ======================== dnode1 start @@ -208,11 +208,11 @@ endi print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 sql use $db #### auto create multiple tables @@ -298,7 +298,7 @@ endi sql create table tu(ts timestamp, k int); sql_error create table txu using tu tags(0) values(now, 1); -#[TBASE-675] +print =================> [TBASE-675] sql insert into tu values(1565971200000, 1) (1565971200000,2) (1565971200001, 3)(1565971200001, 4) sql select * from tu if $rows != 2 then diff --git a/tests/script/general/parser/auto_create_tb_drop_tb.sim b/tests/script/general/parser/auto_create_tb_drop_tb.sim index be334bca4ad14930d363160d8e31ff63c5514637..8a429cf91abff583abd104344ec1ba300ca684bb 100644 --- a/tests/script/general/parser/auto_create_tb_drop_tb.sim +++ b/tests/script/general/parser/auto_create_tb_drop_tb.sim @@ -4,7 +4,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 4 system sh/cfg.sh -n dnode1 -c ctime -v 30 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = db @@ -49,7 +49,7 @@ while $t < $tbNum endw print ====== tables created -sleep 60000 +sleep 500 sql drop table tb2 $x = 0 @@ -59,9 +59,7 @@ while $x < $rowNum $t1 = $t1 . ' sql insert into tb1 using $stb tags( $t1 ) values ( $ts , $x ) $x = $x + 1 -endw - -sleep 6000 +endw $ts = $ts0 + $delta $ts = $ts + 1 diff --git a/tests/script/general/parser/binary_escapeCharacter.sim b/tests/script/general/parser/binary_escapeCharacter.sim index c3c867795a30c6e2e87081e59cfbf5f558a60fb7..e9e61f35bfda688fcd735085672be95a0fcf626f 100644 --- a/tests/script/general/parser/binary_escapeCharacter.sim +++ b/tests/script/general/parser/binary_escapeCharacter.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect sql drop database if exists ecdb diff --git a/tests/script/general/parser/col_arithmetic_operation.sim b/tests/script/general/parser/col_arithmetic_operation.sim index 3208df95e446f5f06494617fa33a71a5f09ab828..d5ba57e6c7dd5befcacb777a1e22f96ba8dae79d 100644 --- a/tests/script/general/parser/col_arithmetic_operation.sim +++ b/tests/script/general/parser/col_arithmetic_operation.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = ca_db @@ -34,7 +34,7 @@ while $i < $halfTbNum $tb1 = $tbPrefix . $tbId sql create table $tb using $stb tags( $i ) sql create table $tb1 using $stb tags( $tbId ) - + $x = 0 while $x < $rowNum $xs = $x * $delta @@ -46,8 +46,7 @@ while $i < $halfTbNum $binary = $binary . ' $nchar = 'nchar . $c $nchar = $nchar . ' - sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) - sql insert into $tb1 values ( $ts , NULL , $c , NULL , $c , NULL , $c , NULL, NULL , $nchar ) + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , NULL , $c , NULL , $c , NULL , $c , NULL, NULL , $nchar ) $x = $x + 1 endw $i = $i + 1 diff --git a/tests/script/general/parser/columnValue.sim b/tests/script/general/parser/columnValue.sim index e905f612156eae7575c4884210f8fee7b91e7556..2c03a3552a26ff8c64640f908b15fcc5d194f61e 100644 --- a/tests/script/general/parser/columnValue.sim +++ b/tests/script/general/parser/columnValue.sim @@ -5,7 +5,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ========== columnValues.sim diff --git a/tests/script/general/parser/columnValue_bigint.sim b/tests/script/general/parser/columnValue_bigint.sim index e6839b2fb60eadf8d5c284cef99f47f470723378..3546ca15ee15eba485f1868d4bae5f4c545218f9 100644 --- a/tests/script/general/parser/columnValue_bigint.sim +++ b/tests/script/general/parser/columnValue_bigint.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect sql create database if not exists db sql use db diff --git a/tests/script/general/parser/columnValue_bool.sim b/tests/script/general/parser/columnValue_bool.sim index 7f3a6c3d6affaefcc2a8d47963ac065c2dc71b25..d68f37590091ab892599d4017a73b6cbb2f28450 100644 --- a/tests/script/general/parser/columnValue_bool.sim +++ b/tests/script/general/parser/columnValue_bool.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect sql create database if not exists db sql use db diff --git a/tests/script/general/parser/columnValue_double.sim b/tests/script/general/parser/columnValue_double.sim index 733fc52285a3c90dda50e5bb34a03e51daf4b9ae..fd2da37838cbabea9c6cee2e992a6904df132c3e 100644 --- a/tests/script/general/parser/columnValue_double.sim +++ b/tests/script/general/parser/columnValue_double.sim @@ -1,5 +1,5 @@ #### -sleep 3000 +sleep 500 sql connect sql create database if not exists db sql use db diff --git a/tests/script/general/parser/columnValue_float.sim b/tests/script/general/parser/columnValue_float.sim index c71b4b40ee0d799c6faa619cd10b765959074f11..019cf176d0e0f455b5f6b61fcabb501806378c96 100644 --- a/tests/script/general/parser/columnValue_float.sim +++ b/tests/script/general/parser/columnValue_float.sim @@ -1,5 +1,5 @@ #### -sleep 3000 +sleep 500 sql connect sql create database if not exists db sql use db diff --git a/tests/script/general/parser/columnValue_int.sim b/tests/script/general/parser/columnValue_int.sim index 2a909ebf3c64dd487d6d4b1bd5341c59794e8970..1f84df5ca05ef70e95c2db03efe0a670abaff8da 100644 --- a/tests/script/general/parser/columnValue_int.sim +++ b/tests/script/general/parser/columnValue_int.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect sql create database if not exists db sql use db diff --git a/tests/script/general/parser/columnValue_smallint.sim b/tests/script/general/parser/columnValue_smallint.sim index cf34a85a2a7d8efb7b1d4e4606cead89055ae3b1..af5c5818717b6c2f01e4726975ceaee4703cdbfb 100644 --- a/tests/script/general/parser/columnValue_smallint.sim +++ b/tests/script/general/parser/columnValue_smallint.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect sql create database if not exists db sql use db diff --git a/tests/script/general/parser/columnValue_tinyint.sim b/tests/script/general/parser/columnValue_tinyint.sim index 707242a23ed3eecde6c23413e53b67c5daa83a82..3efe52cc91f2ecb1f22000a3f212ec491b9a16c1 100644 --- a/tests/script/general/parser/columnValue_tinyint.sim +++ b/tests/script/general/parser/columnValue_tinyint.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect sql create database if not exists db sql use db diff --git a/tests/script/general/parser/commit.sim b/tests/script/general/parser/commit.sim index 4d85806b690fafdb71707133f97f8fc78942c2c2..c798bf9d7cc21f2c91c8c14e8debe22ad253b72b 100644 --- a/tests/script/general/parser/commit.sim +++ b/tests/script/general/parser/commit.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxTablesperVnode -v 100 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = sc_db @@ -50,8 +50,7 @@ while $i < $halfNum $binary = $binary . ' $nchar = 'nchar . $c $nchar = $nchar . ' - sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) - sql insert into $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) $x = $x + 1 endw @@ -83,12 +82,12 @@ endw print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 -system sh/exec.sh -n dnode1 -s start sleep 3000 +system sh/exec.sh -n dnode1 -s start +sleep 500 print ================== server restart completed sql connect -sleep 3000 +sleep 500 print ====== select from table and check num of rows returned sql use $db diff --git a/tests/script/general/parser/constCol.sim b/tests/script/general/parser/constCol.sim index b5a4d4abea614e6618ac91a5df4af9d387c7ad37..4a8e443281dbaa0892106a8fe91bbdd6d61c3e8a 100644 --- a/tests/script/general/parser/constCol.sim +++ b/tests/script/general/parser/constCol.sim @@ -353,8 +353,8 @@ if $rows != 3 then endi print =============================> td-2036 -if $data00 != 0.3000000 then - print expect: 0.3000000, actual:$data00 +if $data00 != 0.300000000 then + print expect: 0.300000000, actual:$data00 return -1 endi diff --git a/tests/script/general/parser/create_db.sim b/tests/script/general/parser/create_db.sim index ed6e427fe70fe5cfe65852352ac680f645a3a21f..3b7f24b6d900dc1f130f91a138da81fd708b16fe 100644 --- a/tests/script/general/parser/create_db.sim +++ b/tests/script/general/parser/create_db.sim @@ -5,7 +5,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ======================== dnode1 start diff --git a/tests/script/general/parser/create_mt.sim b/tests/script/general/parser/create_mt.sim index f21a83067186dc226bd035fe3ff7ba5cc28675c0..e11f32276187d15334193af688b3c50604df2b32 100644 --- a/tests/script/general/parser/create_mt.sim +++ b/tests/script/general/parser/create_mt.sim @@ -5,7 +5,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ======================== dnode1 start diff --git a/tests/script/general/parser/create_tb.sim b/tests/script/general/parser/create_tb.sim index 9d1672fdbef136fccb28d38df967d45132c9d40a..609aad2adbc9611d33c595d33191e5b8a26b3359 100644 --- a/tests/script/general/parser/create_tb.sim +++ b/tests/script/general/parser/create_tb.sim @@ -5,7 +5,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ======================== dnode1 start diff --git a/tests/script/general/parser/dbtbnameValidate.sim b/tests/script/general/parser/dbtbnameValidate.sim index b46a22228280c73a2cfffa145c9ed71d75dd4957..fd40ecc3f758affa3ca401813132b830a241a049 100644 --- a/tests/script/general/parser/dbtbnameValidate.sim +++ b/tests/script/general/parser/dbtbnameValidate.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 1000 +sleep 500 sql connect print ========== db name and table name check in create and drop, describe diff --git a/tests/script/general/parser/fill.sim b/tests/script/general/parser/fill.sim index 0547db77498cf1d61baf44deb286d9045a469dc3..9851a4e7fcfea026271729cbe7436c47e184df40 100644 --- a/tests/script/general/parser/fill.sim +++ b/tests/script/general/parser/fill.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = m_fl_db diff --git a/tests/script/general/parser/fill_stb.sim b/tests/script/general/parser/fill_stb.sim index f0cd058352803f322647aad338bc84be7fa84b5a..83eb98c465927beb70ce403491dcd100f2556c7d 100644 --- a/tests/script/general/parser/fill_stb.sim +++ b/tests/script/general/parser/fill_stb.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = fl1_db diff --git a/tests/script/general/parser/fill_us.sim b/tests/script/general/parser/fill_us.sim index b597d378a24f3a07d28d3bebc1a6fe403fdf3208..dc8ee8659d6c3b99e8103e3ee0a622a10e7bc7df 100644 --- a/tests/script/general/parser/fill_us.sim +++ b/tests/script/general/parser/fill_us.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = m_fl_db diff --git a/tests/script/general/parser/first_last.sim b/tests/script/general/parser/first_last.sim index 46431b0848c72aefc9b5aaa04f7e13f525dcfe1c..a934d3bcabf09ebe1584c296d6cab2f5c80654d2 100644 --- a/tests/script/general/parser/first_last.sim +++ b/tests/script/general/parser/first_last.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxTablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = first_db @@ -76,11 +76,11 @@ run general/parser/first_last_query.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 run general/parser/first_last_query.sim diff --git a/tests/script/general/parser/first_last_query.sim b/tests/script/general/parser/first_last_query.sim index d43cd528781cb900f239e4e7549da91ace2d0e5c..a982f10362a46e7c671e8df4674b06c5c9f60b75 100644 --- a/tests/script/general/parser/first_last_query.sim +++ b/tests/script/general/parser/first_last_query.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = first_db diff --git a/tests/script/general/parser/groupby.sim b/tests/script/general/parser/groupby.sim index 145c4a008f1ae26378baeabdfd5103cc807266f3..19d9ae84cbc02e179c2ab060082507529b2bb608 100644 --- a/tests/script/general/parser/groupby.sim +++ b/tests/script/general/parser/groupby.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 1000 +sleep 500 sql connect $dbPrefix = group_db @@ -33,12 +33,19 @@ sql create database if not exists $db keep 36500 sql use $db sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12)) +$half = $tbNum / 2 + $i = 0 -while $i < $tbNum +while $i < $half $tb = $tbPrefix . $i $tg2 = ' . abc $tg2 = $tg2 . ' + + $nextSuffix = $i + $half + $tb1 = $tbPrefix . $nextSuffix + sql create table $tb using $mt tags( $i , $tg2 ) + sql create table $tb1 using $mt tags( $nextSuffix , $tg2 ) $x = 0 while $x < $rowNum @@ -55,7 +62,7 @@ while $i < $tbNum $nchar = $nchar . $c $nchar = $nchar . ' - sql insert into $tb values ($tstart , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) + sql insert into $tb values ($tstart , $c , $c , $x , $x , $c , $c , $c , $binary , $nchar ) $tb1 values ($tstart , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $tstart = $tstart + 1 $x = $x + 1 endw @@ -423,8 +430,172 @@ if $data97 != @group_tb0@ then return -1 endi +sql select count(*),first(ts),last(ts),min(c3) from group_tb1 group by c4; +if $rows != 10000 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != @70-01-01 08:01:40.000@ then + return -1 +endi + +if $data02 != @70-01-01 08:01:40.000@ then + return -1 +endi + +if $data03 != 0 then + return -1 +endi + +sql select count(*),first(ts),last(ts),min(c3) from group_tb1 group by c4 limit 1; +if $rows != 1 then + return -1 +endi + +sql select count(*),first(ts),last(ts),min(c3) from group_tb1 group by c4 limit 20 offset 9990; +if $rows != 10 then + return -1 +endi + +sql select count(*),first(ts),last(ts),min(c3),max(c3),sum(c3),avg(c3),sum(c4)/count(c4) from group_tb1 group by c4; +if $rows != 10000 then + return -1 +endi + print ---------------------------------> group by binary|nchar data add cases +sql select count(*) from group_tb1 group by c8; +if $rows != 100 then + return -1 +endi + +sql select count(*),sum(c4), count(c4), sum(c4)/count(c4) from group_tb1 group by c8 +if $rows != 100 then + return -1 +endi + +if $data00 != 100 then + return -1 +endi + +if $data01 != 495000 then + return -1 +endi + +if $data02 != 100 then + return -1 +endi + +if $data03 != 4950.000000000 then + print expect 4950.000000000 , acutal $data03 + return -1 +endi + +if $data10 != 100 then + return -1 +endi + +if $data11 != 495100 then + return -1 +endi + +if $data13 != 4951.000000000 then + return -1 +endi + +print ====================> group by normal column + slimit + soffset +sql select count(*), c8 from group_mt0 group by c8 limit 1 offset 0; +if $rows != 100 then + return -1 +endi + +sql select sum(c2),c8,avg(c2), sum(c2)/count(*) from group_mt0 group by c8 slimit 2 soffset 99 +if $rows != 1 then + return -1 +endi + +if $data00 != 79200.000000000 then + return -1 +endi + +if $data01 != @binary99@ then + return -1 +endi + +if $data02 != 99.000000000 then + return -1 +endi + +if $data03 != 99.000000000 then + return -1 +endi + +print ============>td-1765 +sql select percentile(c4, 49),min(c4),max(c4),avg(c4),stddev(c4) from group_tb0 group by c8; +if $rows != 100 then + return -1 +endi + +if $data00 != 4851.000000000 then + return -1 +endi + +if $data01 != 0 then + return -1 +endi + +if $data02 != 9900 then + return -1 +endi + +if $data03 != 4950.000000000 then + return -1 +endi +if $data04 != 2886.607004772 then + return -1 +endi + +if $data10 != 4852.000000000 then + return -1 +endi + +if $data11 != 1 then + return -1 +endi + +if $data12 != 9901 then + return -1 +endi + +if $data13 != 4951.000000000 then + return -1 +endi + +if $data14 != 2886.607004772 then + return -1 +endi + +print ================>td-2090 +sql select leastsquares(c2, 1, 1) from group_tb1 group by c8; +if $rows != 100 then + return -1 +endi + +if $data00 != @{slop:0.000000, intercept:0.000000}@ then + return -1 +endi + +if $data10 != @{slop:0.000000, intercept:1.000000}@ then + return -1 +endi + +if $data90 != @{slop:0.000000, intercept:9.000000}@ then + return -1 +endi #=========================== group by multi tags ====================== sql create table st (ts timestamp, c int) tags (t1 int, t2 int, t3 int, t4 int); diff --git a/tests/script/general/parser/import.sim b/tests/script/general/parser/import.sim index 7ab0437685869594daded7fcfd9c886339842221..6da2483738a6d5c805e3a29129183845e64c4f22 100644 --- a/tests/script/general/parser/import.sim +++ b/tests/script/general/parser/import.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = impt_db @@ -64,7 +64,7 @@ sleep 2000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 sql use $db sql select * from tb diff --git a/tests/script/general/parser/import_commit1.sim b/tests/script/general/parser/import_commit1.sim index 197ae5845362f2dbfc9392fe2a57601aec442e22..9c5144a630cbd0df20e8842211c1d3d3e5d5cbb0 100644 --- a/tests/script/general/parser/import_commit1.sim +++ b/tests/script/general/parser/import_commit1.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/cfg.sh -n dnode1 -c ctime -v 30 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = ic_db @@ -40,7 +40,7 @@ while $x < $rowNum endw print ====== tables created -sleep 6000 +sleep 3000 $ts = $ts0 + $delta $ts = $ts + 1 diff --git a/tests/script/general/parser/import_commit2.sim b/tests/script/general/parser/import_commit2.sim index e400d0c3cb7e347d34b3c75d9ae2b68ffeeb656f..000394386ec169bba4b907969d73878760584eb6 100644 --- a/tests/script/general/parser/import_commit2.sim +++ b/tests/script/general/parser/import_commit2.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/cfg.sh -n dnode1 -c ctime -v 30 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = ic_db @@ -39,7 +39,7 @@ while $x < $rowNum endw print ====== tables created -sleep 6000 +sleep 3000 $ts = $ts0 + $delta $ts = $ts + 1 diff --git a/tests/script/general/parser/import_commit3.sim b/tests/script/general/parser/import_commit3.sim index 7e7451e689bbe2ac0059b13ba3fa64c530445adf..997a4a22aada1d3f02becd8e02f82c35a41a6175 100644 --- a/tests/script/general/parser/import_commit3.sim +++ b/tests/script/general/parser/import_commit3.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/cfg.sh -n dnode1 -c ctime -v 30 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = ic_db @@ -39,7 +39,7 @@ while $x < $rowNum endw print ====== tables created -sleep 6000 +sleep 3000 $ts = $ts + 1 sql insert into $tb values ( $ts , -1, -1, -1, -1, -1) @@ -47,7 +47,7 @@ $ts = $ts0 + $delta $ts = $ts + 1 sql import into $tb values ( $ts , -2, -2, -2, -2, -2) -sleep 6000 +sleep 3000 sql show databases diff --git a/tests/script/general/parser/insert_multiTbl.sim b/tests/script/general/parser/insert_multiTbl.sim index b24c1b629fa371e417826bcb1da67180f3317c29..887f97a198237ff9c181c3d313525ae4fb66aec5 100644 --- a/tests/script/general/parser/insert_multiTbl.sim +++ b/tests/script/general/parser/insert_multiTbl.sim @@ -6,7 +6,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start sleep 2000 sql connect -sleep 3000 +sleep 500 print ======================== dnode1 start sql create database mul_db diff --git a/tests/script/general/parser/insert_tb.sim b/tests/script/general/parser/insert_tb.sim index 4ba455c2446e6fd9804b8e518dc31cacb0781bfc..0a9eb9f678c12de13b33e7dd1ca438c768addf81 100644 --- a/tests/script/general/parser/insert_tb.sim +++ b/tests/script/general/parser/insert_tb.sim @@ -5,7 +5,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ======================== dnode1 start @@ -103,7 +103,7 @@ if $rows != 1 then endi sql drop database $db -sleep 1000 +sleep 500 sql create database $db sql use $db sql create table stb1 (ts timestamp, c1 int) tags(t1 int) @@ -136,7 +136,7 @@ if $data21 != 1.000000000 then endi sql drop database $db -sleep 1000 +sleep 500 sql create database $db sql use $db sql create table stb (ts timestamp, c1 int, c2 bigint, c3 float, c4 double, c5 nchar(10), c6 binary(20)) tags(t1 int, t2 bigint, t3 double, t4 float, t5 nchar(10)) diff --git a/tests/script/general/parser/interp.sim b/tests/script/general/parser/interp.sim index 1cd857162d9a764519d2edd6f790f9fd1c083b61..0d5c1804dd6cd4e929aaaa4de2e6775cc5b71153 100644 --- a/tests/script/general/parser/interp.sim +++ b/tests/script/general/parser/interp.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = intp_db @@ -47,8 +47,7 @@ while $i < $halfNum $binary = $binary . ' $nchar = 'nchar . $c $nchar = $nchar . ' - sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) - sql insert into $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) $x = $x + 1 endw @@ -60,7 +59,7 @@ run general/parser/interp_test.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed diff --git a/tests/script/general/parser/interp_test.sim b/tests/script/general/parser/interp_test.sim index 8bffae4af634e9c04c4d5f4614d51e1e1b33ffba..42738a8bd134c3b7cc72569fe490285baa694e57 100644 --- a/tests/script/general/parser/interp_test.sim +++ b/tests/script/general/parser/interp_test.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = intp_db @@ -303,6 +303,8 @@ $tb = $tbPrefix . 0 return -1 endi + print select interp(ts), interp(c1), interp(c2), interp(c3), interp(c4), interp(c5), interp(c6), interp(c7), interp(c8), interp(c9) from $tb where ts = $ts0 fill(linear) + sql select interp(ts), interp(c1), interp(c2), interp(c3), interp(c4), interp(c5), interp(c6), interp(c7), interp(c8), interp(c9) from $tb where ts = $ts0 fill(linear) if $rows != 1 then return -1 @@ -338,6 +340,8 @@ $tb = $tbPrefix . 0 return -1 endi # columns contain NULL values + + print select interp(ts), interp(c1), interp(c2), interp(c3), interp(c4), interp(c5), interp(c6), interp(c7), interp(c8), interp(c9) from intp_tb3 where ts = $ts0 fill(linear) sql select interp(ts), interp(c1), interp(c2), interp(c3), interp(c4), interp(c5), interp(c6), interp(c7), interp(c8), interp(c9) from intp_tb3 where ts = $ts0 fill(linear) if $rows != 1 then return -1 @@ -380,6 +384,7 @@ $tb = $tbPrefix . 0 endi $t = $tsu + 1000 + print select interp(ts), interp(c1), interp(c2), interp(c3), interp(c4), interp(c5), interp(c6), interp(c7), interp(c8), interp(c9) from $tb where ts = $t fill(linear) sql select interp(ts), interp(c1), interp(c2), interp(c3), interp(c4), interp(c5), interp(c6), interp(c7), interp(c8), interp(c9) from $tb where ts = $t fill(linear) if $rows != 0 then return -1 @@ -387,6 +392,7 @@ $tb = $tbPrefix . 0 ## fill(value) $t = $ts0 + 1000 + print 91 sql select interp(ts), interp(c1), interp(c2), interp(c3), interp(c4), interp(c5), interp(c6), interp(c7), interp(c8), interp(c9) from $tb where ts = $t fill(value, -1, -2) if $rows != 1 then return -1 @@ -456,6 +462,7 @@ $tb = $tbPrefix . 0 if $data09 != nchar0 then return -1 endi + # table has NULL columns sql select interp(ts), interp(c1), interp(c2), interp(c3), interp(c4), interp(c5), interp(c6), interp(c7), interp(c8), interp(c9) from intp_tb3 where ts = $ts0 fill(value, -1, -2, -3) if $rows != 1 then @@ -491,11 +498,14 @@ $tb = $tbPrefix . 0 ##### select interp from stable ## interp(*) from stb + print select interp(*) from $stb where ts = $ts0 sql select interp(*) from $stb where ts = $ts0 if $rows != 1 then return -1 endi $t = $ts0 + 1000 + print 92 + sql select interp(*) from $stb where ts = $t if $rows != 0 then return -1 diff --git a/tests/script/general/parser/join.sim b/tests/script/general/parser/join.sim index 624c2e72c40bfee35f8b0b17646c97149eda65c1..3ee90cda352002961c131b7e014f8aa6d8155c05 100644 --- a/tests/script/general/parser/join.sim +++ b/tests/script/general/parser/join.sim @@ -7,7 +7,7 @@ system sh/cfg.sh -n dnode1 -c rpcDebugFlag -v 135 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 1000 +sleep 500 sql connect $dbPrefix = join_db @@ -360,9 +360,7 @@ endi sql select join_mt1.* from join_mt1 print $rows - -$val = 2000 -if $rows != $val then +if $rows != 2000 then return -1 endi diff --git a/tests/script/general/parser/join_multivnode.sim b/tests/script/general/parser/join_multivnode.sim index a5e71260b487ddd87a6df795c2f5bdfb9d72eca3..1c901dd2e32b3950865510176d7cc4383a41fe97 100644 --- a/tests/script/general/parser/join_multivnode.sim +++ b/tests/script/general/parser/join_multivnode.sim @@ -6,7 +6,7 @@ system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start sql connect -sleep 1000 +sleep 500 $dbPrefix = join_m_db $tbPrefix = join_tb @@ -136,9 +136,8 @@ sql select join_mt0.ts, join_mt1.t1, join_mt0.t1, join_mt1.tbname, join_mt0.tbna #1970-01-01 08:01:40.790 | 10 | 945.000000000 | 90 | true | true | 0 | sql_error select count(join_mt0.c1), sum(join_mt1.c2), first(join_mt0.c5), last(join_mt1.c7), first(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1 order by join_mt0.ts desc limit 20 offset 19; - sql select count(join_mt0.c1), sum(join_mt0.c2)/count(*), avg(c2), first(join_mt0.c5), last(c7) from join_mt0 interval(10a) group by join_mt0.t1 order by join_mt0.ts desc; -if $rows != 100 then +if $rows != 300 then return -1 endi @@ -147,7 +146,7 @@ if $data00 != @70-01-01 08:01:40.990@ then return -1 endi -if $data01 != 30 then +if $data01 != 10 then return -1 endi @@ -168,7 +167,7 @@ if $data05 != 1 then return -1 endi -if $data06 != 2 then +if $data06 != 0 then return -1 endi @@ -177,7 +176,7 @@ if $data10 != @70-01-01 08:01:40.980@ then return -1 endi -if $data11 != 30 then +if $data11 != 10 then return -1 endi @@ -198,16 +197,19 @@ if $data15 != 1 then return -1 endi -if $data16 != 2 then +if $data16 != 0 then return -1 endi # this function will cause shell crash sql_error select count(join_mt0.c1), first(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10a) group by join_mt0.t1 order by join_mt0.ts desc; +sql_error select last(join_mt1.c7), first(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10m) group by join_mt0.t1 order by join_mt0.ts asc; +sql_error select count(join_mt0.c1), first(join_mt0.c1)-last(join_mt1.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL); -sql_error select last(join_mt1.c7), first(join_mt1.c7) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts interval(10m) group by join_mt0.t1 order by join_mt0.ts asc; +print ================================> TD-2152 +sql_error select join_mt1.c1,join_mt0.c1 from join_mt1,join_mt0 where join_mt1.ts = join_mt0.ts and join_mt1.t1 = join_mt0.t1 order by t; -sql_error select count(join_mt0.c1), first(join_mt0.c1)-last(join_mt1.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL); +print =================================> add result check sql select count(join_mt0.c1), first(join_mt0.c1)/count(*), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL); sql select count(join_mt0.c1), first(join_mt0.c1)-last(join_mt0.c1), first(join_mt1.c9) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL); sql select last(join_mt0.c1) from join_mt0, join_mt1 where join_mt0.t1=join_mt1.t1 and join_mt0.ts=join_mt1.ts;", NULL); diff --git a/tests/script/general/parser/lastrow.sim b/tests/script/general/parser/lastrow.sim index 6321823fe2f75854beeab091663d268876e373b9..cc71123a77e7e48c491d8c1450addb55e243bdd6 100644 --- a/tests/script/general/parser/lastrow.sim +++ b/tests/script/general/parser/lastrow.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = lr_db @@ -62,11 +62,11 @@ run general/parser/lastrow_query.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 run general/parser/lastrow_query.sim diff --git a/tests/script/general/parser/lastrow_query.sim b/tests/script/general/parser/lastrow_query.sim index f81a48d5b2d61ddf829920201dd01f5dd1ee44ba..5b9c8b60c3f62b48159d13f5cb82ccffd32d0feb 100644 --- a/tests/script/general/parser/lastrow_query.sim +++ b/tests/script/general/parser/lastrow_query.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = lr_db diff --git a/tests/script/general/parser/limit.sim b/tests/script/general/parser/limit.sim index d8c72349db9ebf40e038a921ea7534e6a1a87e23..fb5e704bf1ba3bab457dae2dc06a23628fde316c 100644 --- a/tests/script/general/parser/limit.sim +++ b/tests/script/general/parser/limit.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 1 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = lm_db @@ -62,11 +62,11 @@ run general/parser/limit_stb.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 run general/parser/limit_tb.sim run general/parser/limit_stb.sim diff --git a/tests/script/general/parser/limit1.sim b/tests/script/general/parser/limit1.sim index 8b927b2a7fe599e5e51392e8577d3dffb112ea57..7236421ec2eb1617c7c16b5d659b9b57f300559a 100644 --- a/tests/script/general/parser/limit1.sim +++ b/tests/script/general/parser/limit1.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 1 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = lm1_db @@ -48,8 +48,7 @@ while $i < $halfNum $binary = $binary . ' $nchar = 'nchar . $c $nchar = $nchar . ' - sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) - sql insert into $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) $x = $x + 1 endw @@ -62,7 +61,7 @@ run general/parser/limit1_stb.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed diff --git a/tests/script/general/parser/limit1_stb.sim b/tests/script/general/parser/limit1_stb.sim index fbcd8d09656b9c1b5f515c2224fbca8c5e8f324c..d5846adc45327e6faa7b2bd7cdd10b44ea6fc094 100644 --- a/tests/script/general/parser/limit1_stb.sim +++ b/tests/script/general/parser/limit1_stb.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = lm1_db diff --git a/tests/script/general/parser/limit1_tb.sim b/tests/script/general/parser/limit1_tb.sim index a9484d10dbaaad1c8c08b2ae54caf85ad186207e..1e473eb8580965b6e777c7fe09cbc607af8938a8 100644 --- a/tests/script/general/parser/limit1_tb.sim +++ b/tests/script/general/parser/limit1_tb.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = lm1_db diff --git a/tests/script/general/parser/limit1_tblocks100.sim b/tests/script/general/parser/limit1_tblocks100.sim index f1702924aaee3091c7ac9e4229b36ec11c141123..9a123e645ce070f5146d2507b90e16b06d258c4d 100644 --- a/tests/script/general/parser/limit1_tblocks100.sim +++ b/tests/script/general/parser/limit1_tblocks100.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 1 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = lm1_db @@ -48,8 +48,7 @@ while $i < $halfNum $binary = $binary . ' $nchar = 'nchar . $c $nchar = $nchar . ' - sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) - sql insert into $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) $x = $x + 1 endw @@ -62,7 +61,7 @@ run general/parser/limit1_stb.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed diff --git a/tests/script/general/parser/limit2.sim b/tests/script/general/parser/limit2.sim index d22c786aa3001e6f7e275466bd5426b7e275b53c..47c3eb6d08ca1f01ded0b8e4597f91d0cd2f1933 100644 --- a/tests/script/general/parser/limit2.sim +++ b/tests/script/general/parser/limit2.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c rowsInFileBlock -v 255 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = lm2_db @@ -69,7 +69,7 @@ print ====== tables created print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed diff --git a/tests/script/general/parser/limit2_query.sim b/tests/script/general/parser/limit2_query.sim index 8294247a86415bcd90c692a8765475fbb6ecdd6b..f9a1dd8e4b51107d6713d52f850f792f339b3fa4 100644 --- a/tests/script/general/parser/limit2_query.sim +++ b/tests/script/general/parser/limit2_query.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = lm2_db diff --git a/tests/script/general/parser/limit2_tblocks100.sim b/tests/script/general/parser/limit2_tblocks100.sim index 64f86edd28092bc816b663719c0ab153ff1181e0..1aaa8e885a21b4db79c28645029a015d12a24fb5 100644 --- a/tests/script/general/parser/limit2_tblocks100.sim +++ b/tests/script/general/parser/limit2_tblocks100.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c rowsInFileBlock -v 255 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = lm2_db @@ -69,7 +69,7 @@ print ====== tables created print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 +sleep 500 system sh/exec.sh -n dnode1 -s start print ================== server restart completed diff --git a/tests/script/general/parser/limit_stb.sim b/tests/script/general/parser/limit_stb.sim index c9df03ab2efe220dc9a5bf5707cb83f81178e4d2..b41b7b726bc24b83f64cecbec8ac0eb83afa57ea 100644 --- a/tests/script/general/parser/limit_stb.sim +++ b/tests/script/general/parser/limit_stb.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = lm_db diff --git a/tests/script/general/parser/limit_tb.sim b/tests/script/general/parser/limit_tb.sim index 970c7b75c5683e8ece8ce3c7b5458097a0ec3973..b917627fdf6499fe2dacf948af7badb2b5de43d7 100644 --- a/tests/script/general/parser/limit_tb.sim +++ b/tests/script/general/parser/limit_tb.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = lm_db diff --git a/tests/script/general/parser/mixed_blocks.sim b/tests/script/general/parser/mixed_blocks.sim index 41082bb1441a111602a127b3dd8e9eb6d0420e51..d3558560df95d02256e0bc6b4a04ae9fae6e5890 100644 --- a/tests/script/general/parser/mixed_blocks.sim +++ b/tests/script/general/parser/mixed_blocks.sim @@ -5,7 +5,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = mb_db diff --git a/tests/script/general/parser/nchar.sim b/tests/script/general/parser/nchar.sim index bdac5ace55a0c5feeb3413eea13a8a7b2c13f7e4..ab4ed2607a062ed32ebe52527d30705aa135aa86 100644 --- a/tests/script/general/parser/nchar.sim +++ b/tests/script/general/parser/nchar.sim @@ -5,7 +5,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ======================== dnode1 start diff --git a/tests/script/general/parser/null_char.sim b/tests/script/general/parser/null_char.sim index 2e39fc7db2e20f9528c2d62458f3a6a625181c73..7b1c81a2958c36acbe96641494a8c156dabb275d 100644 --- a/tests/script/general/parser/null_char.sim +++ b/tests/script/general/parser/null_char.sim @@ -6,7 +6,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ========== NULL_char.sim @@ -251,7 +251,7 @@ endi ################### nchar sql alter table st41 set tag tag_nchar = "��˼����" sql select tag_binary, tag_nchar, tag_int, tag_bool, tag_float, tag_double from st41 -#sleep 1000 +#sleep 500 #if $data01 != ��˼���� then # print ==== expect ��˼����, actually $data01 # return -1 diff --git a/tests/script/general/parser/projection_limit_offset.sim b/tests/script/general/parser/projection_limit_offset.sim index 7c83ca0c2ff3d44bf487f8a94750736767834cfa..bc22bd6da9194d9798f4744dea84d999beaf6a43 100644 --- a/tests/script/general/parser/projection_limit_offset.sim +++ b/tests/script/general/parser/projection_limit_offset.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = group_db @@ -28,11 +28,19 @@ sql use $db sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int, t2 binary(12)) $i = 0 -while $i < $tbNum +$half = $tbNum / 2 + +while $i < $half $tb = $tbPrefix . $i $tg2 = ' . abc $tg2 = $tg2 . ' + + $tbId = $i + $half + + $tb1 = $tbPrefix . $tbId + sql create table $tb using $mt tags( $i , $tg2 ) + sql create table $tb1 using $mt tags( $i , $tg2 ) $x = 0 while $x < $rowNum @@ -49,7 +57,7 @@ while $i < $tbNum $nchar = $nchar . $c $nchar = $nchar . ' - sql insert into $tb values ($tstart , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) + sql insert into $tb values ($tstart , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $tb1 values ($tstart , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $tstart = $tstart + 1 $x = $x + 1 endw @@ -402,7 +410,7 @@ sql_error select k, sum(k)+1 from tm0; print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed diff --git a/tests/script/general/parser/selectResNum.sim b/tests/script/general/parser/selectResNum.sim index 42cedc034b7f000eea4b75b156a847a4d1667c5b..464f363222b2d135b68d7e41d18ec33d71d843d2 100644 --- a/tests/script/general/parser/selectResNum.sim +++ b/tests/script/general/parser/selectResNum.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 200 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = sc_db @@ -50,8 +50,7 @@ while $i < $halfNum $binary = $binary . ' $nchar = 'nchar . $c $nchar = $nchar . ' - sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) - sql insert into $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) $x = $x + 1 endw @@ -119,12 +118,12 @@ endw print ====== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 6000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ====== server restart completed -sleep 3000 +sleep 500 sql connect -sleep 3000 +sleep 500 sql use $db ##### repeat test after server restart diff --git a/tests/script/general/parser/select_across_vnodes.sim b/tests/script/general/parser/select_across_vnodes.sim index ac3a8f2b2b3bd04681a20e070aaf2aba58447b26..44e5576dac11d9f8ebffb9eee8f067bab86344c1 100644 --- a/tests/script/general/parser/select_across_vnodes.sim +++ b/tests/script/general/parser/select_across_vnodes.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 5 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = sav_db diff --git a/tests/script/general/parser/select_from_cache_disk.sim b/tests/script/general/parser/select_from_cache_disk.sim index 4fdfa7b55b88372d5497f399c5c821f10743f4d5..0fa0848144c740c6ed8c7583cbca46816d3da6bc 100644 --- a/tests/script/general/parser/select_from_cache_disk.sim +++ b/tests/script/general/parser/select_from_cache_disk.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = scd_db @@ -35,11 +35,11 @@ sql insert into $tb values ('2018-09-17 09:00:00.030', 3) print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 sql use $db # generate some data in cache diff --git a/tests/script/general/parser/select_with_tags.sim b/tests/script/general/parser/select_with_tags.sim index 68d145a5f277464a224ccf0b3c92767a48e26fb6..dab76f60044c7b587e6c98bb256f895aeedb656e 100644 --- a/tests/script/general/parser/select_with_tags.sim +++ b/tests/script/general/parser/select_with_tags.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 1000 +sleep 500 sql connect $dbPrefix = select_tags_db diff --git a/tests/script/general/parser/set_tag_vals.sim b/tests/script/general/parser/set_tag_vals.sim index 38af57c73d681fb0ed40212a967c741b0431ebad..bf29fe3902f88ae557b53068d1678a0aa1288818 100644 --- a/tests/script/general/parser/set_tag_vals.sim +++ b/tests/script/general/parser/set_tag_vals.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 1 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = db diff --git a/tests/script/general/parser/single_row_in_tb.sim b/tests/script/general/parser/single_row_in_tb.sim index 4305ae1b5d0d6fa1b308885263d1ac9947af3101..fe1edb1f738a01831ad3e926e6b1a925b0c05dcc 100644 --- a/tests/script/general/parser/single_row_in_tb.sim +++ b/tests/script/general/parser/single_row_in_tb.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = sr_db @@ -32,7 +32,7 @@ run general/parser/single_row_in_tb_query.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed diff --git a/tests/script/general/parser/single_row_in_tb_query.sim b/tests/script/general/parser/single_row_in_tb_query.sim index a1ae70ec814d0babf00dbf5051da45c5cd7daf94..9e90b91220dae51bf31c9f3dde69eb1404223e88 100644 --- a/tests/script/general/parser/single_row_in_tb_query.sim +++ b/tests/script/general/parser/single_row_in_tb_query.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = sr_db diff --git a/tests/script/general/parser/sliding.sim b/tests/script/general/parser/sliding.sim index b9fd66334d469b09812daac4d0ad15b8a2ac3a9c..4283421169d146a19a7a46eed1c1bd819f77464d 100644 --- a/tests/script/general/parser/sliding.sim +++ b/tests/script/general/parser/sliding.sim @@ -6,7 +6,7 @@ system sh/cfg.sh -n dnode1 -c debugFlag -v 135 system sh/cfg.sh -n dnode1 -c rpcDebugFlag -v 135 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 1000 +sleep 500 sql connect $dbPrefix = sliding_db diff --git a/tests/script/general/parser/slimit.sim b/tests/script/general/parser/slimit.sim index edbf0c8cc0499d3cb40e0c7696d278ebcf9ba14a..f7a23019cf2e1bcdca7540dd4acd997f24d31e69 100644 --- a/tests/script/general/parser/slimit.sim +++ b/tests/script/general/parser/slimit.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = slm_db @@ -97,11 +97,11 @@ run general/parser/slimit_query.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 run general/parser/slimit_query.sim diff --git a/tests/script/general/parser/slimit1.sim b/tests/script/general/parser/slimit1.sim index 9e26a2882a5b013aa804f01c1dd8e339d17d54db..7a2511eb76b2a0d1289c509876375a2a6f06419c 100644 --- a/tests/script/general/parser/slimit1.sim +++ b/tests/script/general/parser/slimit1.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = slm_alt_tg_db @@ -56,11 +56,11 @@ run general/parser/slimit1_query.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 run general/parser/slimit1_query.sim diff --git a/tests/script/general/parser/slimit1_query.sim b/tests/script/general/parser/slimit1_query.sim index 617ccb3fd9a13b1392510c4287d11f69df5dde4e..c205d456892d79f7a9dd8fa1ec877c04afac49ef 100644 --- a/tests/script/general/parser/slimit1_query.sim +++ b/tests/script/general/parser/slimit1_query.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = slm_alt_tg_db diff --git a/tests/script/general/parser/slimit_alter_tags.sim b/tests/script/general/parser/slimit_alter_tags.sim index eccd4a6815a5516afe5ed28dc8ec067737f18d01..1072f9ccb46c69ab1156783cbcdeb8940afb9aa4 100644 --- a/tests/script/general/parser/slimit_alter_tags.sim +++ b/tests/script/general/parser/slimit_alter_tags.sim @@ -4,7 +4,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = slm_alt_tg_db @@ -171,11 +171,11 @@ endi print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 sql use $db ### repeat above queries diff --git a/tests/script/general/parser/slimit_query.sim b/tests/script/general/parser/slimit_query.sim index 655bc5f8beab0209428a4796ba83ba10d8b3afde..3020f8047217dfbd9f39b10b5b74b9280faa4737 100644 --- a/tests/script/general/parser/slimit_query.sim +++ b/tests/script/general/parser/slimit_query.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = slm_db diff --git a/tests/script/general/parser/stream_on_sys.sim b/tests/script/general/parser/stream_on_sys.sim index 845a484488137e509a79bbb057f104378843cb8f..1c8eb82c79a537ddbb322bdb164541263d92373c 100644 --- a/tests/script/general/parser/stream_on_sys.sim +++ b/tests/script/general/parser/stream_on_sys.sim @@ -6,7 +6,7 @@ system sh/cfg.sh -n dnode1 -c monitor -v 1 system sh/cfg.sh -n dnode1 -c monitorInterval -v 1 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect print ======================== stream_on_sys.sim diff --git a/tests/script/general/parser/tags_dynamically_specifiy.sim b/tests/script/general/parser/tags_dynamically_specifiy.sim index 07bf4d8dd1cae6b0b374b9b67b1dca58f218fb3f..8303a9c86d610476d6dba164e0af3e6a9199b1da 100644 --- a/tests/script/general/parser/tags_dynamically_specifiy.sim +++ b/tests/script/general/parser/tags_dynamically_specifiy.sim @@ -3,9 +3,9 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect -sleep 3000 +sleep 500 $db = dytag_db $tbNum = 10 diff --git a/tests/script/general/parser/tags_filter.sim b/tests/script/general/parser/tags_filter.sim index 9842b4fda6304314a36eb06078fb7cb64e2c9c5c..c3d0fdfc61d2d9ec8aa19100511577652076d91d 100644 --- a/tests/script/general/parser/tags_filter.sim +++ b/tests/script/general/parser/tags_filter.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $db = tf_db diff --git a/tests/script/general/parser/tbnameIn.sim b/tests/script/general/parser/tbnameIn.sim index fd5f32972ad9e0d0f89875d1f89d2734fd2cbdd8..d0f74ae53d5c696cb598b471dfae32307dfd0f73 100644 --- a/tests/script/general/parser/tbnameIn.sim +++ b/tests/script/general/parser/tbnameIn.sim @@ -3,7 +3,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = ti_db @@ -55,8 +55,7 @@ while $i < $halfNum $binary = $binary . ' $nchar = 'nchar . $c $nchar = $nchar . ' - sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) - sql insert into $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) + sql insert into $tb values ( $ts , $c , $c , $c , $c , $c , $c , true, $binary , $nchar ) $tb1 values ( $ts , $c , NULL , $c , NULL , $c , $c , true, $binary , $nchar ) $x = $x + 1 endw @@ -68,7 +67,7 @@ run general/parser/tbnameIn_query.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed diff --git a/tests/script/general/parser/tbnameIn_query.sim b/tests/script/general/parser/tbnameIn_query.sim index 37cc1aa8245a22e698c1d756cfe1eac72fcf3fdb..ad7456f5578ccec76eef3262298130aaed2462c6 100644 --- a/tests/script/general/parser/tbnameIn_query.sim +++ b/tests/script/general/parser/tbnameIn_query.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = ti_db diff --git a/tests/script/general/parser/testSuite.sim b/tests/script/general/parser/testSuite.sim index 3dd80b8e38c8144fee218ec372e59fe262ac7a15..8593400ce8c3d6ae5375993b0fcc1d7c36b86ca8 100644 --- a/tests/script/general/parser/testSuite.sim +++ b/tests/script/general/parser/testSuite.sim @@ -1,113 +1,112 @@ -sleep 2000 run general/parser/alter.sim -sleep 2000 +sleep 500 run general/parser/alter1.sim -sleep 2000 +sleep 500 run general/parser/alter_stable.sim -sleep 2000 +sleep 500 run general/parser/auto_create_tb.sim -sleep 2000 +sleep 500 run general/parser/auto_create_tb_drop_tb.sim -sleep 2000 +sleep 500 run general/parser/col_arithmetic_operation.sim -sleep 2000 +sleep 500 run general/parser/columnValue.sim -sleep 2000 +sleep 500 run general/parser/commit.sim -sleep 2000 +sleep 500 run general/parser/create_db.sim -sleep 2000 +sleep 500 run general/parser/create_mt.sim -sleep 2000 +sleep 500 run general/parser/create_tb.sim -sleep 2000 +sleep 500 run general/parser/dbtbnameValidate.sim -sleep 2000 +sleep 500 run general/parser/fill.sim -sleep 2000 +sleep 500 run general/parser/fill_stb.sim -sleep 2000 +sleep 500 #run general/parser/fill_us.sim # -sleep 2000 +sleep 500 run general/parser/first_last.sim -sleep 2000 +sleep 500 run general/parser/import_commit1.sim -sleep 2000 +sleep 500 run general/parser/import_commit2.sim -sleep 2000 +sleep 500 run general/parser/import_commit3.sim -sleep 2000 +sleep 500 #run general/parser/import_file.sim -sleep 2000 +sleep 500 run general/parser/insert_tb.sim -sleep 2000 +sleep 500 run general/parser/tags_dynamically_specifiy.sim -sleep 2000 +sleep 500 run general/parser/interp.sim -sleep 2000 +sleep 500 run general/parser/lastrow.sim -sleep 2000 +sleep 500 run general/parser/limit.sim -sleep 2000 +sleep 500 run general/parser/limit1.sim -sleep 2000 +sleep 500 run general/parser/limit1_tblocks100.sim -sleep 2000 +sleep 500 run general/parser/limit2.sim -sleep 2000 +sleep 500 run general/parser/mixed_blocks.sim -sleep 2000 +sleep 500 run general/parser/nchar.sim -sleep 2000 +sleep 500 run general/parser/null_char.sim -sleep 2000 +sleep 500 run general/parser/selectResNum.sim -sleep 2000 +sleep 500 run general/parser/select_across_vnodes.sim -sleep 2000 +sleep 500 run general/parser/select_from_cache_disk.sim -sleep 2000 +sleep 500 run general/parser/set_tag_vals.sim -sleep 2000 +sleep 500 run general/parser/single_row_in_tb.sim -sleep 2000 +sleep 500 run general/parser/slimit.sim -sleep 2000 +sleep 500 run general/parser/slimit1.sim -sleep 2000 +sleep 500 run general/parser/slimit_alter_tags.sim -sleep 2000 +sleep 500 run general/parser/tbnameIn.sim -sleep 2000 +sleep 500 run general/parser/slimit_alter_tags.sim # persistent failed -sleep 2000 +sleep 500 run general/parser/join.sim -sleep 2000 +sleep 500 run general/parser/join_multivnode.sim -sleep 2000 +sleep 500 run general/parser/projection_limit_offset.sim -sleep 2000 +sleep 500 run general/parser/select_with_tags.sim -sleep 2000 +sleep 500 run general/parser/groupby.sim -sleep 2000 +sleep 500 run general/parser/tags_filter.sim -sleep 2000 +sleep 500 run general/parser/topbot.sim -sleep 2000 +sleep 500 run general/parser/union.sim -sleep 2000 +sleep 500 run general/parser/constCol.sim -sleep 2000 +sleep 500 run general/parser/where.sim -sleep 2000 +sleep 500 run general/parser/timestamp.sim -sleep 2000 +sleep 500 run general/parser/sliding.sim -#sleep 2000 +#sleep 500 #run general/parser/repeatStream.sim -#sleep 2000 +#sleep 500 #run general/parser/stream_on_sys.sim -#sleep 2000 +#sleep 500 #run general/parser/stream.sim \ No newline at end of file diff --git a/tests/script/general/parser/timestamp.sim b/tests/script/general/parser/timestamp.sim index 67da0f08698a29582212400f8b189e26d1446ed8..72966459d0ced737e2d0f44702cd5e6956a3aced 100644 --- a/tests/script/general/parser/timestamp.sim +++ b/tests/script/general/parser/timestamp.sim @@ -5,7 +5,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = ts_db @@ -59,10 +59,10 @@ run general/parser/timestamp_query.sim print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 +sleep 500 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 3000 +sleep 500 run general/parser/timestamp_query.sim diff --git a/tests/script/general/parser/timestamp_query.sim b/tests/script/general/parser/timestamp_query.sim index 783c03602b983bf0faea25db28d1ac1ce29d80b7..056e8bba6bd6587fcba2c2685d9764f3f67c42b7 100644 --- a/tests/script/general/parser/timestamp_query.sim +++ b/tests/script/general/parser/timestamp_query.sim @@ -1,4 +1,4 @@ -sleep 3000 +sleep 500 sql connect $dbPrefix = ts_db diff --git a/tests/script/general/parser/topbot.sim b/tests/script/general/parser/topbot.sim index c2b41888d739c559b24784c42ad040d54d7ae160..08e2f6ab00cdcdc3a974266420f7e66bb2e0a65b 100644 --- a/tests/script/general/parser/topbot.sim +++ b/tests/script/general/parser/topbot.sim @@ -5,7 +5,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 200 system sh/exec.sh -n dnode1 -s start -sleep 1000 +sleep 500 sql connect $dbPrefix = tb_db @@ -128,11 +128,11 @@ sql insert into test values(29999, 1)(70000, 2)(80000, 3) print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 5000 +sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed sql connect -sleep 1000 +sleep 500 sql select count(*) from t1.test where ts>10000 and ts<90000 interval(5000a) if $rows != 3 then @@ -169,7 +169,7 @@ endw system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start sql connect -sleep 1000 +sleep 500 sql use db; $ts = 1000 @@ -221,7 +221,7 @@ sql insert into t2 values('2020-2-2 1:1:1', 1); system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start sql connect -sleep 1000 +sleep 500 sql use db sql select count(*), first(ts), last(ts) from t2 interval(1d); diff --git a/tests/script/general/parser/union.sim b/tests/script/general/parser/union.sim index 024b9c76efe6b8ddd69c723ffc0e1e0b0d82e075..cb46ac6b0d1a6d381d33974660b6584e12faff44 100644 --- a/tests/script/general/parser/union.sim +++ b/tests/script/general/parser/union.sim @@ -7,7 +7,7 @@ system sh/cfg.sh -n dnode1 -c rpcDebugFlag -v 135 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 1000 +sleep 500 sql connect $dbPrefix = union_db @@ -36,9 +36,16 @@ sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 $i = 0 $t = 1578203484000 -while $i < $tbNum +$half = $tbNum / 2 + +while $i < $half $tb = $tbPrefix . $i + + $nextSuffix = $i + $half + $tb1 = $tbPrefix . $nextSuffix + sql create table $tb using $mt tags( $i ) + sql create table $tb1 using $mt tags( $nextSuffix ) $x = 0 while $x < $rowNum @@ -54,7 +61,7 @@ while $i < $tbNum $nchar = $nchar . ' $t1 = $t + $ms - sql insert into $tb values ($t1 , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) + sql insert into $tb values ($t1 , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $tb1 values ($t1 , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $x = $x + 1 endw @@ -96,7 +103,7 @@ while $i < $tbNum endw print sleep 1sec. -sleep 1000 +sleep 500 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/general/parser/where.sim b/tests/script/general/parser/where.sim index 066fac43ad9ee617a2cb9a91a62a6ebf984be6f0..8e17220b5b38f995c6dc7e662130f7250157aa44 100644 --- a/tests/script/general/parser/where.sim +++ b/tests/script/general/parser/where.sim @@ -5,7 +5,7 @@ system sh/cfg.sh -n dnode1 -c walLevel -v 0 system sh/cfg.sh -n dnode1 -c maxtablespervnode -v 4 system sh/exec.sh -n dnode1 -s start -sleep 3000 +sleep 500 sql connect $dbPrefix = wh_db @@ -26,10 +26,17 @@ sql create database if not exists $db sql use $db sql create table $mt (ts timestamp, c1 int, c2 float, c3 bigint, c4 smallint, c5 tinyint, c6 double, c7 bool, c8 binary(10), c9 nchar(9)) TAGS(t1 int) +$half = $tbNum / 2 + $i = 0 -while $i < $tbNum +while $i < $half $tb = $tbPrefix . $i + + $nextSuffix = $i + $half + $tb1 = $tbPrefix . $nextSuffix + sql create table $tb using $mt tags( $i ) + sql create table $tb1 using $mt tags( $nextSuffix ) $x = 0 while $x < $rowNum @@ -42,7 +49,7 @@ while $i < $tbNum $binary = $binary . ' $nchar = 'nchar . $c $nchar = $nchar . ' - sql insert into $tb values ($ms , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) + sql insert into $tb values ($ms , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $tb1 values ($ms , $c , $c , $c , $c , $c , $c , $c , $binary , $nchar ) $x = $x + 1 endw diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index daf92679bd61d8317b648b0285e46a4c956a9d94..64a6c871fcf0ae610025b060105766d3b0cf3105 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -277,6 +277,8 @@ cd ../../../debug; make ./test.sh -f unique/db/replica_part.sim ./test.sh -f unique/dnode/alternativeRole.sim +./test.sh -f unique/dnode/monitor.sim +./test.sh -f unique/dnode/monitor_bug.sim ./test.sh -f unique/dnode/simple.sim ./test.sh -f unique/dnode/balance1.sim ./test.sh -f unique/dnode/balance2.sim diff --git a/tests/script/unique/dnode/monitor.sim b/tests/script/unique/dnode/monitor.sim new file mode 100644 index 0000000000000000000000000000000000000000..1e5b0f6f56c261437ffc25c8a68139c53d7303df --- /dev/null +++ b/tests/script/unique/dnode/monitor.sim @@ -0,0 +1,92 @@ +system sh/stop_dnodes.sh + +system sh/deploy.sh -n dnode1 -i 1 +system sh/deploy.sh -n dnode2 -i 2 + +system sh/cfg.sh -n dnode1 -c role -v 1 +system sh/cfg.sh -n dnode2 -c role -v 2 + +system sh/cfg.sh -n dnode1 -c wallevel -v 1 +system sh/cfg.sh -n dnode2 -c wallevel -v 1 + +system sh/cfg.sh -n dnode1 -c numOfMnodes -v 3 +system sh/cfg.sh -n dnode2 -c numOfMnodes -v 3 + +system sh/cfg.sh -n dnode1 -c minTablesPerVnode -v 10 +system sh/cfg.sh -n dnode2 -c minTablesPerVnode -v 10 +system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 10 +system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 10 + +system sh/cfg.sh -n dnode1 -c monitor -v 1 +system sh/cfg.sh -n dnode2 -c monitor -v 1 + +print ========== step1 +system sh/exec.sh -n dnode1 -s start +sql connect +sleep 5000 + +sql show dnodes +print dnode1 openVnodes $data3_1 +if $data2_1 != 0 then + return -1 +endi + +print ========== step2 +sql create dnode $hostname2 +system sh/exec.sh -n dnode2 -s start + +sleep 10000 +sql show dnodes +print dnode1 openVnodes $data2_1 +print dnode2 openVnodes $data2_2 +if $data2_1 != 0 then + return -1 +endi +if $data2_2 != 1 then + return -1 +endi + +print ========== step3 +sql show log.tables + +print $data00 +print $data10 +print $data20 +print $data30 +print $data40 +print $data50 + +if $rows != 5 then + return -1 +endi + +print ========== step4 +sql select * from log.dn1 +print $rows +$rows1 = $rows + +sleep 3000 +sql select * from log.dn1 +print $rows +$rows2 = $rows + +if $rows2 <= $rows1 then + return -1 +endi + +print ========== step5 +sql select * from log.dn2 +print $rows +$rows1 = $rows + +sleep 3000 +sql select * from log.dn2 +print $rows +$rows2 = $rows + +if $rows2 <= $rows1 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode2 -s stop -x SIGINT diff --git a/tests/script/unique/dnode/monitor_bug.sim b/tests/script/unique/dnode/monitor_bug.sim index 519aae6ca9f64b14a4488889a1e3eb6ead884467..3169c7cdba4c9f631a41365e25e6537dd823fc5a 100644 --- a/tests/script/unique/dnode/monitor_bug.sim +++ b/tests/script/unique/dnode/monitor_bug.sim @@ -18,8 +18,8 @@ sql connect sleep 5000 sql show dnodes -print dnode1 openVnodes $data3_1 -if $data3_1 != 3 then +print dnode1 openVnodes $data2_1 +if $data2_1 != 1 then return -1 endi @@ -31,22 +31,21 @@ $x = 0 show2: $x = $x + 1 sleep 2000 - if $x == 30 then + if $x == 10 then return -1 endi sql show dnodes -print dnode1 openVnodes $data3_1 -print dnode2 openVnodes $data3_2 -if $data3_1 != 4 then +print dnode1 openVnodes $data2_1 +print dnode2 openVnodes $data2_2 +if $data2_1 != 0 then goto show2 endi -if $data3_2 != 3 then +if $data2_2 != 1 then goto show2 endi print ========== step3 -sleep 3000 sql show log.tables print $data00 @@ -56,6 +55,23 @@ print $data30 print $data40 print $data50 -if $rows != 5 then +if $rows != 4 then + return -1 +endi + +print ========== step4 +sql select * from log.dn1 +print $rows +$rows1 = $rows + +sleep 3000 +sql select * from log.dn1 +print $rows +$rows2 = $rows + +if $rows2 <= $rows1 then return -1 endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode2 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/test-all.sh b/tests/test-all.sh index 214360f3b8d438198bbeadedf63296cbfbaa05a9..ff47cbfd712650503b18fcf351b95abaae3b0b03 100755 --- a/tests/test-all.sh +++ b/tests/test-all.sh @@ -16,6 +16,10 @@ function runSimCaseOneByOne { ./test.sh -f $case > /dev/null 2>&1 && \ echo -e "${GREEN}$case success${NC}" | tee -a out.log || \ echo -e "${RED}$case failed${NC}" | tee -a out.log + out_log=`tail -1 out.log ` + if [[ $out_log =~ 'failed' ]];then + exit 8 + fi end_time=`date +%s` echo execution time of $case was `expr $end_time - $start_time`s. | tee -a out.log fi @@ -37,6 +41,10 @@ function runPyCaseOneByOne { echo -e "${GREEN}$case success${NC}" | tee -a pytest-out.log || \ echo -e "${RED}$case failed${NC}" | tee -a pytest-out.log end_time=`date +%s` + out_log=`tail -1 pytest-out.log ` + if [[ $out_log =~ 'failed' ]];then + exit 8 + fi echo execution time of $case was `expr $end_time - $start_time`s. | tee -a pytest-out.log else $line > /dev/null 2>&1