diff --git a/cmake/define.inc b/cmake/define.inc index e825dce024..da80baabbb 100755 --- a/cmake/define.inc +++ b/cmake/define.inc @@ -117,10 +117,14 @@ IF (TD_LINUX) ADD_DEFINITIONS(-D_TD_NINGSI_60) MESSAGE(STATUS "set ningsi macro to true") ENDIF () - - SET(DEBUG_FLAGS "-O0 -g3 -DDEBUG") + + IF (TD_MEMORY_SANITIZER) + SET(DEBUG_FLAGS "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment -static-libasan -O0 -g3 -DDEBUG") + ELSE () + SET(DEBUG_FLAGS "-O0 -g3 -DDEBUG") + ENDIF () SET(RELEASE_FLAGS "-O3 -Wno-error") - + IF (${COVER} MATCHES "true") MESSAGE(STATUS "Test coverage mode, add extra flags") SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage") @@ -139,7 +143,11 @@ IF (TD_DARWIN_64) ADD_DEFINITIONS(-DUSE_LIBICONV) MESSAGE(STATUS "darwin64 is defined") SET(COMMON_FLAGS "-std=gnu99 -Wall -Werror -Wno-missing-braces -fPIC -msse4.2 -D_FILE_OFFSET_BITS=64 -D_LARGE_FILE") - SET(DEBUG_FLAGS "-O0 -g3 -DDEBUG") + IF (TD_MEMORY_SANITIZER) + SET(DEBUG_FLAGS "-fsanitize=address -fsanitize=undefined -fno-sanitize-recover=all -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow -fno-sanitize=null -fno-sanitize=alignment -O0 -g3 -DDEBUG") + ELSE () + SET(DEBUG_FLAGS "-O0 -g3 -DDEBUG") + ENDIF () SET(RELEASE_FLAGS "-Og") INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lz4/inc) @@ -157,7 +165,11 @@ IF (TD_WINDOWS) IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900)) SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18") ENDIF () - SET(DEBUG_FLAGS "/Zi /W3 /GL") + IF (TD_MEMORY_SANITIZER) + SET(DEBUG_FLAGS "/fsanitize=address /Zi /W3 /GL") + ELSE () + SET(DEBUG_FLAGS "/Zi /W3 /GL") + ENDIF () SET(RELEASE_FLAGS "/W0 /O3 /GL") ENDIF () @@ -166,7 +178,7 @@ IF (TD_WINDOWS) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/regex) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/wepoll/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/MsvcLibX/include) -ENDIF () +ENDIF () IF (TD_WINDOWS_64) ADD_DEFINITIONS(-D_M_X64) diff --git a/cmake/input.inc b/cmake/input.inc index 5841a46567..ca1a27ec44 100755 --- a/cmake/input.inc +++ b/cmake/input.inc @@ -78,3 +78,8 @@ SET(TD_BUILD_JDBC TRUE) IF (${BUILD_JDBC} MATCHES "false") SET(TD_BUILD_JDBC FALSE) ENDIF () + +SET(TD_MEMORY_SANITIZER FALSE) +IF (${MEMORY_SANITIZER} MATCHES "true") + SET(TD_MEMORY_SANITIZER TRUE) +ENDIF () diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 0e63fa3551..6e273df38f 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -405,6 +405,7 @@ typedef struct SSqlObj { typedef struct SSqlStream { SSqlObj *pSql; + void * cqhandle; // stream belong to SCQContext handle const char* dstTable; uint32_t streamId; char listed; diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index f1dd8975dc..bba9db86c5 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -466,6 +466,10 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1 int32_t cnt = 0; int32_t j = 0; + if (sToken.n >= TSDB_MAX_BYTES_PER_ROW) { + return tscSQLSyntaxErrMsg(pCmd->payload, "too long string", sToken.z); + } + for (uint32_t k = 1; k < sToken.n - 1; ++k) { if (sToken.z[k] == '\\' || (sToken.z[k] == delim && sToken.z[k + 1] == delim)) { tmpTokenBuf[j] = sToken.z[k + 1]; @@ -705,7 +709,7 @@ static int32_t doParseInsertStatement(SSqlCmd* pCmd, char **str, STableDataBlock } code = TSDB_CODE_TSC_INVALID_SQL; - char tmpTokenBuf[16*1024] = {0}; // used for deleting Escape character: \\, \', \" + char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // used for deleting Escape character: \\, \', \" int32_t numOfRows = 0; code = tsParseValues(str, dataBuf, maxNumOfRows, pCmd, &numOfRows, tmpTokenBuf); diff --git a/src/client/src/tscProfile.c b/src/client/src/tscProfile.c index ea2a3d8228..5b2198be62 100644 --- a/src/client/src/tscProfile.c +++ b/src/client/src/tscProfile.c @@ -19,6 +19,7 @@ #include "ttimer.h" #include "tutil.h" #include "taosmsg.h" +#include "tcq.h" #include "taos.h" @@ -294,24 +295,34 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) { return msgLen; } +// cqContext->dbconn is killed then call this callback +void cqConnKilledNotify(void* handle, void* conn) { + if (handle == NULL || conn == NULL){ + return ; + } + + SCqContext* pContext = (SCqContext*) handle; + if (pContext->dbConn == conn){ + atomic_store_ptr(&(pContext->dbConn), NULL); + } +} + void tscKillConnection(STscObj *pObj) { + // get stream header by locked pthread_mutex_lock(&pObj->mutex); - - SSqlObj *pSql = pObj->sqlList; - while (pSql) { - pSql = pSql->next; - } - - SSqlStream *pStream = pObj->streamList; + pthread_mutex_unlock(&pObj->mutex); + while (pStream) { SSqlStream *tmp = pStream->next; + // set associate variant to NULL + cqConnKilledNotify(pStream->cqhandle, pObj); + // taos_close_stream function call pObj->mutet lock , careful death-lock taos_close_stream(pStream); pStream = tmp; } - pthread_mutex_unlock(&pObj->mutex); - tscDebug("connection:%p is killed", pObj); taos_close(pObj); } + diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 50ae545a8e..37f51a856e 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -314,7 +314,9 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { } } else if (pInfo->type == TSDB_SQL_DROP_DNODE) { - pzName->n = strdequote(pzName->z); + if (pzName->type == TK_STRING) { + pzName->n = strdequote(pzName->z); + } strncpy(pCmd->payload, pzName->z, pzName->n); } else { // drop user/account if (pzName->n >= TSDB_USER_LEN) { @@ -392,7 +394,9 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { } SStrToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0); - id->n = strdequote(id->z); + if (id->type == TK_STRING) { + id->n = strdequote(id->z); + } break; } @@ -1987,6 +1991,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col const char* msg7 = "normal table can not apply this function"; const char* msg8 = "multi-columns selection does not support alias column name"; const char* msg9 = "diff can no be applied to unsigned numeric type"; + const char* msg10 = "parameter is out of range [1, 100]"; switch (functionId) { case TSDB_FUNC_COUNT: { @@ -2374,7 +2379,7 @@ int32_t addExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, int32_t col int64_t nTop = GET_INT32_VAL(val); if (nTop <= 0 || nTop > 100) { // todo use macro - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10); } // todo REFACTOR @@ -6674,7 +6679,8 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { const char* msg5 = "sql too long"; // todo ADD support const char* msg6 = "from missing in subclause"; const char* msg7 = "time interval is required"; - + const char* msg8 = "the first column should be primary timestamp column"; + SSqlCmd* pCmd = &pSql->cmd; SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); assert(pQueryInfo->numOfTables == 1); @@ -6731,8 +6737,26 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } - if (!tscIsProjectionQuery(pQueryInfo) && pQueryInfo->interval.interval == 0) { - return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + // project query primary column must be timestamp type + if (tscIsProjectionQuery(pQueryInfo)) { + size_t size = tscSqlExprNumOfExprs(pQueryInfo); + // check zero + if(size == 0) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); + } + + // check primary column is timestamp + SSqlExpr* pSqlExpr = tscSqlExprGet(pQueryInfo, 0); + if(pSqlExpr == NULL) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); + } + if( pSqlExpr->colInfo.colId != PRIMARYKEY_TIMESTAMP_COL_INDEX) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg8); + } + } else { + if (pQueryInfo->interval.interval == 0) { + return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); + } } // set the created table[stream] name diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index b60824b2fa..de2f0087ce 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -141,6 +141,10 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) { pStream->numOfRes = 0; // reset the numOfRes. SSqlObj *pSql = pStream->pSql; + // pSql == NULL maybe killStream already called + if(pSql == NULL) { + return ; + } SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); tscDebug("0x%"PRIx64" add into timer", pSql->self); @@ -336,8 +340,12 @@ static void tscSetRetryTimer(SSqlStream *pStream, SSqlObj *pSql, int64_t timer) if (pStream->isProject) { int64_t now = taosGetTimestamp(pStream->precision); int64_t etime = now > pStream->etime ? pStream->etime : now; - - if (pStream->etime < now && now - pStream->etime > tsMaxRetentWindow) { + int64_t maxRetent = tsMaxRetentWindow * 1000; + if(pStream->precision == TSDB_TIME_PRECISION_MICRO) { + maxRetent *= 1000; + } + + if (pStream->etime < now && now - pStream->etime > maxRetent) { /* * current time window will be closed, since it too early to exceed the maxRetentWindow value */ @@ -662,7 +670,7 @@ void cbParseSql(void* param, TAOS_RES* res, int code) { } TAOS_STREAM *taos_open_stream_withname(TAOS *taos, const char* dstTable, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), - int64_t stime, void *param, void (*callback)(void *)) { + int64_t stime, void *param, void (*callback)(void *), void* cqhandle) { STscObj *pObj = (STscObj *)taos; if (pObj == NULL || pObj->signature != pObj) return NULL; @@ -695,6 +703,7 @@ TAOS_STREAM *taos_open_stream_withname(TAOS *taos, const char* dstTable, const c pStream->callback = callback; pStream->param = param; pStream->pSql = pSql; + pStream->cqhandle = cqhandle; pSql->pStream = pStream; pSql->param = pStream; pSql->maxRetry = TSDB_MAX_REPLICA; @@ -735,7 +744,7 @@ TAOS_STREAM *taos_open_stream_withname(TAOS *taos, const char* dstTable, const c TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), int64_t stime, void *param, void (*callback)(void *)) { - return taos_open_stream_withname(taos, "", sqlstr, fp, stime, param, callback); + return taos_open_stream_withname(taos, "", sqlstr, fp, stime, param, callback, NULL); } void taos_close_stream(TAOS_STREAM *handle) { diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index ed91695569..381d2804c1 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -817,6 +817,16 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); + cfg.option = "precision"; + cfg.ptr = &tsTimePrecision; + cfg.valType = TAOS_CFG_VTYPE_INT8; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; + cfg.minValue = TSDB_MIN_PRECISION; + cfg.maxValue = TSDB_MAX_PRECISION; + cfg.ptrLength = 0; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + cfg.option = "comp"; cfg.ptr = &tsCompression; cfg.valType = TAOS_CFG_VTYPE_INT8; @@ -887,6 +897,16 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); + cfg.option = "cachelast"; + cfg.ptr = &tsCacheLastRow; + cfg.valType = TAOS_CFG_VTYPE_INT8; + cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; + cfg.minValue = TSDB_MIN_DB_CACHE_LAST_ROW; + cfg.maxValue = TSDB_MAX_DB_CACHE_LAST_ROW; + cfg.ptrLength = 0; + cfg.unitType = TAOS_CFG_UTYPE_NONE; + taosInitConfigOption(cfg); + cfg.option = "mqttHostName"; cfg.ptr = tsMqttHostName; cfg.valType = TAOS_CFG_VTYPE_STRING; diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c index 9988450c30..33dab51633 100644 --- a/src/common/src/tvariant.c +++ b/src/common/src/tvariant.c @@ -74,7 +74,7 @@ void tVariantCreate(tVariant *pVar, SStrToken *token) { case TSDB_DATA_TYPE_BINARY: { pVar->pz = strndup(token->z, token->n); - pVar->nLen = strdequote(pVar->pz); + pVar->nLen = strRmquote(pVar->pz, token->n); break; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java index 5dcaa77ebd..48811d30a6 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java @@ -12,6 +12,9 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da private final static int DRIVER_MAJAR_VERSION = 2; private final static int DRIVER_MINOR_VERSION = 0; + private String precision = "ms"; + private String database; + public boolean allProceduresAreCallable() throws SQLException { return false; } @@ -493,102 +496,105 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException; + private List buildGetTablesColumnMetaDataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT + columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM + columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME + columnMetaDataList.add(buildTableTypeMeta(4)); // 4. TABLE_TYPE + columnMetaDataList.add(buildRemarksMeta(5)); // 5. remarks + columnMetaDataList.add(buildTypeCatMeta(6)); // 6. TYPE_CAT + columnMetaDataList.add(buildTypeSchemaMeta(7)); // 7. TYPE_SCHEM + columnMetaDataList.add(buildTypeNameMeta(8)); // 8. TYPE_NAME + columnMetaDataList.add(buildSelfReferencingColName(9)); // 9. SELF_REFERENCING_COL_NAME + columnMetaDataList.add(buildRefGenerationMeta(10)); // 10. REF_GENERATION + return columnMetaDataList; + } + + private ColumnMetaData buildTypeCatMeta(int colIndex) { + ColumnMetaData col6 = new ColumnMetaData(); + col6.setColIndex(colIndex); + col6.setColName("TYPE_CAT"); + col6.setColType(Types.NCHAR); + return col6; + } + + private ColumnMetaData buildTypeSchemaMeta(int colIndex) { + ColumnMetaData col7 = new ColumnMetaData(); + col7.setColIndex(colIndex); + col7.setColName("TYPE_SCHEM"); + col7.setColType(Types.NCHAR); + return col7; + } + + private ColumnMetaData buildTypeNameMeta(int colIndex) { + ColumnMetaData col8 = new ColumnMetaData(); + col8.setColIndex(colIndex); + col8.setColName("TYPE_NAME"); + col8.setColType(Types.NCHAR); + return col8; + } + + private ColumnMetaData buildSelfReferencingColName(int colIndex) { + ColumnMetaData col9 = new ColumnMetaData(); + col9.setColIndex(colIndex); + col9.setColName("SELF_REFERENCING_COL_NAME"); + col9.setColType(Types.NCHAR); + return col9; + } + + private ColumnMetaData buildRefGenerationMeta(int colIndex) { + ColumnMetaData col10 = new ColumnMetaData(); + col10.setColIndex(colIndex); + col10.setColName("REF_GENERATION"); + col10.setColType(Types.NCHAR); + return col10; + } + protected ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types, Connection connection) throws SQLException { + if (catalog == null || catalog.isEmpty()) + return null; + if (!isAvailableCatalog(connection, catalog)) + return new EmptyResultSet(); + + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + // set column metadata list + resultSet.setColumnMetaDataList(buildGetTablesColumnMetaDataList()); + // set row data + List rowDataList = new ArrayList<>(); try (Statement stmt = connection.createStatement()) { - if (catalog == null || catalog.isEmpty()) - return null; - - ResultSet databases = stmt.executeQuery("show databases"); - String dbname = null; - while (databases.next()) { - dbname = databases.getString("name"); - if (dbname.equalsIgnoreCase(catalog)) - break; - } - databases.close(); - if (dbname == null) - return null; - - stmt.execute("use " + dbname); - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); - List columnMetaDataList = new ArrayList<>(); - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(1); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - ColumnMetaData col2 = new ColumnMetaData(); - col2.setColIndex(2); - col2.setColName("TABLE_SCHEM"); - col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col2); - ColumnMetaData col3 = new ColumnMetaData(); - col3.setColIndex(3); - col3.setColName("TABLE_NAME"); - col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col3); - ColumnMetaData col4 = new ColumnMetaData(); - col4.setColIndex(4); - col4.setColName("TABLE_TYPE"); - col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col4); - ColumnMetaData col5 = new ColumnMetaData(); - col5.setColIndex(5); - col5.setColName("REMARKS"); - col5.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col5); - ColumnMetaData col6 = new ColumnMetaData(); - col6.setColIndex(6); - col6.setColName("TYPE_CAT"); - col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col6); - ColumnMetaData col7 = new ColumnMetaData(); - col7.setColIndex(7); - col7.setColName("TYPE_SCHEM"); - col7.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col7); - ColumnMetaData col8 = new ColumnMetaData(); - col8.setColIndex(8); - col8.setColName("TYPE_NAME"); - col8.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col8); - ColumnMetaData col9 = new ColumnMetaData(); - col9.setColIndex(9); - col9.setColName("SELF_REFERENCING_COL_NAME"); - col9.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col9); - ColumnMetaData col10 = new ColumnMetaData(); - col10.setColIndex(10); - col10.setColName("REF_GENERATION"); - col10.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col10); - resultSet.setColumnMetaDataList(columnMetaDataList); - - List rowDataList = new ArrayList<>(); + stmt.execute("use " + catalog); ResultSet tables = stmt.executeQuery("show tables"); while (tables.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(10); - rowData.setString(0, dbname); //table_cat - rowData.setString(1, null); //TABLE_SCHEM - rowData.setString(2, tables.getString("table_name")); //TABLE_NAME - rowData.setString(3, "TABLE"); //TABLE_TYPE - rowData.setString(4, ""); //REMARKS + rowData.setStringValue(1, catalog); //TABLE_CAT + rowData.setStringValue(2, null); //TABLE_SCHEM + rowData.setStringValue(3, tables.getString("table_name")); //TABLE_NAME + rowData.setStringValue(4, "TABLE"); //TABLE_TYPE + rowData.setStringValue(5, ""); //REMARKS rowDataList.add(rowData); } - ResultSet stables = stmt.executeQuery("show stables"); while (stables.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(10); - rowData.setString(0, dbname); //TABLE_CAT - rowData.setString(1, null); //TABLE_SCHEM - rowData.setString(2, stables.getString("name")); //TABLE_NAME - rowData.setString(3, "TABLE"); //TABLE_TYPE - rowData.setString(4, "STABLE"); //REMARKS + rowData.setStringValue(1, catalog); //TABLE_CAT + rowData.setStringValue(2, null); //TABLE_SCHEM + rowData.setStringValue(3, stables.getString("name")); //TABLE_NAME + rowData.setStringValue(4, "TABLE"); //TABLE_TYPE + rowData.setStringValue(5, "STABLE"); //REMARKS rowDataList.add(rowData); } resultSet.setRowDataList(rowDataList); - return resultSet; } + return resultSet; + } + + private ColumnMetaData buildTableTypeMeta(int colIndex) { + ColumnMetaData col4 = new ColumnMetaData(); + col4.setColIndex(colIndex); + col4.setColName("TABLE_TYPE"); + col4.setColType(Types.NCHAR); + return col4; } public ResultSet getSchemas() throws SQLException { @@ -597,25 +603,24 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da public abstract ResultSet getCatalogs() throws SQLException; + private List buildTableTypesColumnMetadataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableTypeMeta(1)); + return columnMetaDataList; + } + public ResultSet getTableTypes() throws SQLException { DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); // set up ColumnMetaDataList - List columnMetaDataList = new ArrayList<>(); - ColumnMetaData colMetaData = new ColumnMetaData(); - colMetaData.setColIndex(0); - colMetaData.setColName("TABLE_TYPE"); - colMetaData.setColSize(10); - colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(colMetaData); - resultSet.setColumnMetaDataList(columnMetaDataList); + resultSet.setColumnMetaDataList(buildTableTypesColumnMetadataList()); // set up rowDataList List rowDataList = new ArrayList<>(); TSDBResultSetRowData rowData = new TSDBResultSetRowData(1); - rowData.setString(0, "TABLE"); + rowData.setStringValue(1, "TABLE"); rowDataList.add(rowData); rowData = new TSDBResultSetRowData(1); - rowData.setString(0, "STABLE"); + rowData.setStringValue(1, "STABLE"); rowDataList.add(rowData); resultSet.setRowDataList(rowDataList); @@ -625,278 +630,330 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da public abstract ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException; protected ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern, Connection conn) { + if (catalog == null || catalog.isEmpty()) + return null; + if (!isAvailableCatalog(conn, catalog)) + return new EmptyResultSet(); + + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + // set up ColumnMetaDataList + resultSet.setColumnMetaDataList(buildGetColumnsColumnMetaDataList()); + // set up rowDataList + List rowDataList = new ArrayList<>(); try (Statement stmt = conn.createStatement()) { - if (catalog == null || catalog.isEmpty()) - return null; - - ResultSet databases = stmt.executeQuery("show databases"); - String dbname = null; - while (databases.next()) { - dbname = databases.getString("name"); - if (dbname.equalsIgnoreCase(catalog)) - break; - } - databases.close(); - if (dbname == null) - return null; - - stmt.execute("use " + dbname); - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); - // set up ColumnMetaDataList - - List columnMetaDataList = new ArrayList<>(); - // TABLE_CAT - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(1); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - // TABLE_SCHEM - ColumnMetaData col2 = new ColumnMetaData(); - col2.setColIndex(2); - col2.setColName("TABLE_SCHEM"); - col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col2); - // TABLE_NAME - ColumnMetaData col3 = new ColumnMetaData(); - col3.setColIndex(3); - col3.setColName("TABLE_NAME"); - col3.setColSize(193); - col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col3); - // COLUMN_NAME - ColumnMetaData col4 = new ColumnMetaData(); - col4.setColIndex(4); - col4.setColName("COLUMN_NAME"); - col4.setColSize(65); - col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col4); - // DATA_TYPE - ColumnMetaData col5 = new ColumnMetaData(); - col5.setColIndex(5); - col5.setColName("DATA_TYPE"); - col5.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col5); - // TYPE_NAME - ColumnMetaData col6 = new ColumnMetaData(); - col6.setColIndex(6); - col6.setColName("TYPE_NAME"); - col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col6); - // COLUMN_SIZE - ColumnMetaData col7 = new ColumnMetaData(); - col7.setColIndex(7); - col7.setColName("COLUMN_SIZE"); - col7.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col7); - // BUFFER_LENGTH, not used - ColumnMetaData col8 = new ColumnMetaData(); - col8.setColIndex(8); - col8.setColName("BUFFER_LENGTH"); - columnMetaDataList.add(col8); - // DECIMAL_DIGITS - ColumnMetaData col9 = new ColumnMetaData(); - col9.setColIndex(9); - col9.setColName("DECIMAL_DIGITS"); - col9.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col9); - // add NUM_PREC_RADIX - ColumnMetaData col10 = new ColumnMetaData(); - col10.setColIndex(10); - col10.setColName("NUM_PREC_RADIX"); - col10.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col10); - // NULLABLE - ColumnMetaData col11 = new ColumnMetaData(); - col11.setColIndex(11); - col11.setColName("NULLABLE"); - col11.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col11); - // REMARKS - ColumnMetaData col12 = new ColumnMetaData(); - col12.setColIndex(12); - col12.setColName("REMARKS"); - col12.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col12); - // COLUMN_DEF - ColumnMetaData col13 = new ColumnMetaData(); - col13.setColIndex(13); - col13.setColName("COLUMN_DEF"); - col13.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col13); - //SQL_DATA_TYPE - ColumnMetaData col14 = new ColumnMetaData(); - col14.setColIndex(14); - col14.setColName("SQL_DATA_TYPE"); - col14.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col14); - //SQL_DATETIME_SUB - ColumnMetaData col15 = new ColumnMetaData(); - col15.setColIndex(15); - col15.setColName("SQL_DATETIME_SUB"); - col15.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col15); - //CHAR_OCTET_LENGTH - ColumnMetaData col16 = new ColumnMetaData(); - col16.setColIndex(16); - col16.setColName("CHAR_OCTET_LENGTH"); - col16.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col16); - //ORDINAL_POSITION - ColumnMetaData col17 = new ColumnMetaData(); - col17.setColIndex(17); - col17.setColName("ORDINAL_POSITION"); - col17.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col17); - // IS_NULLABLE - ColumnMetaData col18 = new ColumnMetaData(); - col18.setColIndex(18); - col18.setColName("IS_NULLABLE"); - col18.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col18); - //SCOPE_CATALOG - ColumnMetaData col19 = new ColumnMetaData(); - col19.setColIndex(19); - col19.setColName("SCOPE_CATALOG"); - col19.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col19); - //SCOPE_SCHEMA - ColumnMetaData col20 = new ColumnMetaData(); - col20.setColIndex(20); - col20.setColName("SCOPE_SCHEMA"); - col20.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col20); - //SCOPE_TABLE - ColumnMetaData col21 = new ColumnMetaData(); - col21.setColIndex(21); - col21.setColName("SCOPE_TABLE"); - col21.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col21); - //SOURCE_DATA_TYPE - ColumnMetaData col22 = new ColumnMetaData(); - col22.setColIndex(22); - col22.setColName("SOURCE_DATA_TYPE"); - col22.setColType(TSDBConstants.TSDB_DATA_TYPE_SMALLINT); - columnMetaDataList.add(col22); - //IS_AUTOINCREMENT - ColumnMetaData col23 = new ColumnMetaData(); - col23.setColIndex(23); - col23.setColName("IS_AUTOINCREMENT"); - col23.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col23); - //IS_GENERATEDCOLUMN - ColumnMetaData col24 = new ColumnMetaData(); - col24.setColIndex(24); - col24.setColName("IS_GENERATEDCOLUMN"); - col24.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col24); - - resultSet.setColumnMetaDataList(columnMetaDataList); - // set up rowDataList - ResultSet rs = stmt.executeQuery("describe " + dbname + "." + tableNamePattern); - List rowDataList = new ArrayList<>(); - int index = 0; + ResultSet rs = stmt.executeQuery("describe " + catalog + "." + tableNamePattern); + int rowIndex = 0; while (rs.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(24); // set TABLE_CAT - rowData.setString(0, dbname); + rowData.setStringValue(1, catalog); + // set TABLE_SCHEM + rowData.setStringValue(2, null); // set TABLE_NAME - rowData.setString(2, tableNamePattern); + rowData.setStringValue(3, tableNamePattern); // set COLUMN_NAME - rowData.setString(3, rs.getString("Field")); + rowData.setStringValue(4, rs.getString("Field")); // set DATA_TYPE String typeName = rs.getString("Type"); - rowData.setInt(4, getDataType(typeName)); + rowData.setIntValue(5, TSDBConstants.typeName2JdbcType(typeName)); // set TYPE_NAME - rowData.setString(5, typeName); + rowData.setStringValue(6, typeName); // set COLUMN_SIZE int length = rs.getInt("Length"); - rowData.setInt(6, getColumnSize(typeName, length)); + rowData.setIntValue(7, calculateColumnSize(typeName, precision, length)); + // set BUFFER LENGTH + rowData.setStringValue(8, null); // set DECIMAL_DIGITS - rowData.setInt(8, getDecimalDigits(typeName)); + Integer decimalDigits = calculateDecimalDigits(typeName); + if (decimalDigits != null) { + rowData.setIntValue(9, decimalDigits); + } else { + rowData.setStringValue(9, null); + } // set NUM_PREC_RADIX - rowData.setInt(9, 10); + rowData.setIntValue(10, 10); // set NULLABLE - rowData.setInt(10, getNullable(index, typeName)); + rowData.setIntValue(11, isNullable(rowIndex, typeName)); // set REMARKS - rowData.setString(11, rs.getString("Note")); + String note = rs.getString("Note"); + rowData.setStringValue(12, note.trim().isEmpty() ? null : note); rowDataList.add(rowData); - index++; + rowIndex++; } resultSet.setRowDataList(rowDataList); - return resultSet; - } catch (SQLException e) { e.printStackTrace(); } - return null; + return resultSet; } - protected int getNullable(int index, String typeName) { + private int isNullable(int index, String typeName) { if (index == 0 && "TIMESTAMP".equals(typeName)) return DatabaseMetaData.columnNoNulls; return DatabaseMetaData.columnNullable; } - protected int getColumnSize(String typeName, int length) { + private Integer calculateColumnSize(String typeName, String precisionType, int length) { switch (typeName) { case "TIMESTAMP": - return 23; - default: - return 0; - } - } - - protected int getDecimalDigits(String typeName) { - switch (typeName) { - case "FLOAT": - return 5; - case "DOUBLE": - return 9; - default: - return 0; - } - } - - protected int getDataType(String typeName) { - switch (typeName) { - case "TIMESTAMP": - return Types.TIMESTAMP; - case "INT": - return Types.INTEGER; - case "BIGINT": - return Types.BIGINT; - case "FLOAT": - return Types.FLOAT; - case "DOUBLE": - return Types.DOUBLE; - case "BINARY": - return Types.BINARY; - case "SMALLINT": - return Types.SMALLINT; - case "TINYINT": - return Types.TINYINT; + return precisionType.equals("ms") ? TSDBConstants.TIMESTAMP_MS_PRECISION : TSDBConstants.TIMESTAMP_US_PRECISION; case "BOOL": - return Types.BOOLEAN; + return TSDBConstants.BOOLEAN_PRECISION; + case "TINYINT": + return TSDBConstants.TINYINT_PRECISION; + case "SMALLINT": + return TSDBConstants.SMALLINT_PRECISION; + case "INT": + return TSDBConstants.INT_PRECISION; + case "BIGINT": + return TSDBConstants.BIGINT_PRECISION; + case "FLOAT": + return TSDBConstants.FLOAT_PRECISION; + case "DOUBLE": + return TSDBConstants.DOUBLE_PRECISION; case "NCHAR": - return Types.NCHAR; + case "BINARY": + return length; default: - return Types.NULL; + return null; } } - public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) - throws SQLException { + private Integer calculateDecimalDigits(String typeName) { + switch (typeName) { + case "TINYINT": + case "SMALLINT": + case "INT": + case "BIGINT": + return 0; + default: + return null; + } + } + + private ColumnMetaData buildTableCatalogMeta(int colIndex) { + ColumnMetaData col1 = new ColumnMetaData(); + col1.setColIndex(colIndex); + col1.setColName("TABLE_CAT"); + col1.setColType(Types.NCHAR); + return col1; + } + + private ColumnMetaData buildTableSchemaMeta(int colIndex) { + ColumnMetaData col2 = new ColumnMetaData(); + col2.setColIndex(colIndex); + col2.setColName("TABLE_SCHEM"); + col2.setColType(Types.NCHAR); + return col2; + } + + private ColumnMetaData buildTableNameMeta(int colIndex) { + ColumnMetaData col3 = new ColumnMetaData(); + col3.setColIndex(colIndex); + col3.setColName("TABLE_NAME"); + col3.setColSize(193); + col3.setColType(Types.NCHAR); + return col3; + } + + private ColumnMetaData buildColumnNameMeta(int colIndex) { + ColumnMetaData col4 = new ColumnMetaData(); + col4.setColIndex(colIndex); + col4.setColName("COLUMN_NAME"); + col4.setColSize(65); + col4.setColType(Types.NCHAR); + return col4; + } + + private ColumnMetaData buildDataTypeMeta(int colIndex) { + ColumnMetaData col5 = new ColumnMetaData(); + col5.setColIndex(colIndex); + col5.setColName("DATA_TYPE"); + col5.setColType(Types.INTEGER); + return col5; + } + + private ColumnMetaData buildColumnSizeMeta() { + ColumnMetaData col7 = new ColumnMetaData(); + col7.setColIndex(7); + col7.setColName("COLUMN_SIZE"); + col7.setColType(Types.INTEGER); + return col7; + } + + private ColumnMetaData buildBufferLengthMeta() { + ColumnMetaData col8 = new ColumnMetaData(); + col8.setColIndex(8); + col8.setColName("BUFFER_LENGTH"); + return col8; + } + + private ColumnMetaData buildDecimalDigitsMeta() { + ColumnMetaData col9 = new ColumnMetaData(); + col9.setColIndex(9); + col9.setColName("DECIMAL_DIGITS"); + col9.setColType(Types.INTEGER); + return col9; + } + + private ColumnMetaData buildNumPrecRadixMeta() { + ColumnMetaData col10 = new ColumnMetaData(); + col10.setColIndex(10); + col10.setColName("NUM_PREC_RADIX"); + col10.setColType(Types.INTEGER); + return col10; + } + + private ColumnMetaData buildNullableMeta() { + ColumnMetaData col11 = new ColumnMetaData(); + col11.setColIndex(11); + col11.setColName("NULLABLE"); + col11.setColType(Types.INTEGER); + return col11; + } + + private ColumnMetaData buildRemarksMeta(int colIndex) { + ColumnMetaData col12 = new ColumnMetaData(); + col12.setColIndex(colIndex); + col12.setColName("REMARKS"); + col12.setColType(Types.NCHAR); + return col12; + } + + private ColumnMetaData buildColumnDefMeta() { + ColumnMetaData col13 = new ColumnMetaData(); + col13.setColIndex(13); + col13.setColName("COLUMN_DEF"); + col13.setColType(Types.NCHAR); + return col13; + } + + private ColumnMetaData buildSqlDataTypeMeta() { + ColumnMetaData col14 = new ColumnMetaData(); + col14.setColIndex(14); + col14.setColName("SQL_DATA_TYPE"); + col14.setColType(Types.INTEGER); + return col14; + } + + private ColumnMetaData buildSqlDatetimeSubMeta() { + ColumnMetaData col15 = new ColumnMetaData(); + col15.setColIndex(15); + col15.setColName("SQL_DATETIME_SUB"); + col15.setColType(Types.INTEGER); + return col15; + } + + private ColumnMetaData buildCharOctetLengthMeta() { + ColumnMetaData col16 = new ColumnMetaData(); + col16.setColIndex(16); + col16.setColName("CHAR_OCTET_LENGTH"); + col16.setColType(Types.INTEGER); + return col16; + } + + private ColumnMetaData buildOrdinalPositionMeta() { + ColumnMetaData col17 = new ColumnMetaData(); + col17.setColIndex(17); + col17.setColName("ORDINAL_POSITION"); + col17.setColType(Types.INTEGER); + return col17; + } + + private ColumnMetaData buildIsNullableMeta() { + ColumnMetaData col18 = new ColumnMetaData(); + col18.setColIndex(18); + col18.setColName("IS_NULLABLE"); + col18.setColType(Types.NCHAR); + return col18; + } + + private ColumnMetaData buildScopeCatalogMeta() { + ColumnMetaData col19 = new ColumnMetaData(); + col19.setColIndex(19); + col19.setColName("SCOPE_CATALOG"); + col19.setColType(Types.NCHAR); + return col19; + } + + private ColumnMetaData buildScopeSchemaMeta() { + ColumnMetaData col20 = new ColumnMetaData(); + col20.setColIndex(20); + col20.setColName("SCOPE_SCHEMA"); + col20.setColType(Types.NCHAR); + return col20; + } + + private ColumnMetaData buildScopeTableMeta() { + ColumnMetaData col21 = new ColumnMetaData(); + col21.setColIndex(21); + col21.setColName("SCOPE_TABLE"); + col21.setColType(Types.NCHAR); + return col21; + } + + private ColumnMetaData buildSourceDataTypeMeta() { + ColumnMetaData col22 = new ColumnMetaData(); + col22.setColIndex(22); + col22.setColName("SOURCE_DATA_TYPE"); + col22.setColType(TSDBConstants.TSDB_DATA_TYPE_SMALLINT); + return col22; + } + + private ColumnMetaData buildIsAutoIncrementMeta() { + ColumnMetaData col23 = new ColumnMetaData(); + col23.setColIndex(23); + col23.setColName("IS_AUTOINCREMENT"); + col23.setColType(Types.NCHAR); + return col23; + } + + private ColumnMetaData buildIsGeneratedColumnMeta() { + ColumnMetaData col24 = new ColumnMetaData(); + col24.setColIndex(24); + col24.setColName("IS_GENERATEDCOLUMN"); + col24.setColType(Types.NCHAR); + return col24; + } + + private List buildGetColumnsColumnMetaDataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); //1. TABLE_CAT + columnMetaDataList.add(buildTableSchemaMeta(2)); //2. TABLE_SCHEMA + columnMetaDataList.add(buildTableNameMeta(3)); //3. TABLE_NAME + columnMetaDataList.add(buildColumnNameMeta(4)); //4. COLUMN_NAME + columnMetaDataList.add(buildDataTypeMeta(5)); //5. DATA_TYPE + columnMetaDataList.add(buildTypeNameMeta(6)); //6. TYPE_NAME + columnMetaDataList.add(buildColumnSizeMeta()); //7. COLUMN_SIZE + columnMetaDataList.add(buildBufferLengthMeta()); //8. BUFFER_LENGTH, not used + columnMetaDataList.add(buildDecimalDigitsMeta()); //9. DECIMAL_DIGITS + columnMetaDataList.add(buildNumPrecRadixMeta()); //10. NUM_PREC_RADIX + columnMetaDataList.add(buildNullableMeta()); //11. NULLABLE + columnMetaDataList.add(buildRemarksMeta(12)); //12. REMARKS + columnMetaDataList.add(buildColumnDefMeta()); //13. COLUMN_DEF + columnMetaDataList.add(buildSqlDataTypeMeta()); //14. SQL_DATA_TYPE + columnMetaDataList.add(buildSqlDatetimeSubMeta()); //15. SQL_DATETIME_SUB + columnMetaDataList.add(buildCharOctetLengthMeta()); //16. CHAR_OCTET_LENGTH + columnMetaDataList.add(buildOrdinalPositionMeta()); //17. ORDINAL_POSITION + columnMetaDataList.add(buildIsNullableMeta()); //18. IS_NULLABLE + columnMetaDataList.add(buildScopeCatalogMeta()); //19. SCOPE_CATALOG + columnMetaDataList.add(buildScopeSchemaMeta()); //20. SCOPE_SCHEMA + columnMetaDataList.add(buildScopeTableMeta()); //21. SCOPE_TABLE + columnMetaDataList.add(buildSourceDataTypeMeta()); //22. SOURCE_DATA_TYPE + columnMetaDataList.add(buildIsAutoIncrementMeta()); //23. IS_AUTOINCREMENT + columnMetaDataList.add(buildIsGeneratedColumnMeta()); //24. IS_GENERATEDCOLUMN + return columnMetaDataList; + } + + public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { return getEmptyResultSet(); } - public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) - throws SQLException { + public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { return getEmptyResultSet(); } - public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) - throws SQLException { + public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { return getEmptyResultSet(); } @@ -914,8 +971,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da return getEmptyResultSet(); } - public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, - String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { + public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { return getEmptyResultSet(); } @@ -923,8 +979,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da return getEmptyResultSet(); } - public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) - throws SQLException { + public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { return getEmptyResultSet(); } @@ -976,8 +1031,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da return false; } - public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) - throws SQLException { + public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { return getEmptyResultSet(); } @@ -1005,8 +1059,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da public abstract ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException; - public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, - String attributeNamePattern) throws SQLException { + public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException { return getEmptyResultSet(); } @@ -1069,18 +1122,15 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da return getEmptyResultSet(); } - public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) - throws SQLException { + public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { return getEmptyResultSet(); } - public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, - String columnNamePattern) throws SQLException { + public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException { return getEmptyResultSet(); } - public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, - String columnNamePattern) throws SQLException { + public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { return getEmptyResultSet(); } @@ -1093,164 +1143,142 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da } protected ResultSet getCatalogs(Connection conn) throws SQLException { + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + // set up ColumnMetaDataList + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT + resultSet.setColumnMetaDataList(columnMetaDataList); + try (Statement stmt = conn.createStatement()) { - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); - // set up ColumnMetaDataList - List columnMetaDataList = new ArrayList<>(); - // TABLE_CAT - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(1); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - - resultSet.setColumnMetaDataList(columnMetaDataList); - List rowDataList = new ArrayList<>(); ResultSet rs = stmt.executeQuery("show databases"); while (rs.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(1); - rowData.setString(0, rs.getString("name")); + rowData.setStringValue(1, rs.getString("name")); rowDataList.add(rowData); } resultSet.setRowDataList(rowDataList); - return resultSet; } + return resultSet; } protected ResultSet getPrimaryKeys(String catalog, String schema, String table, Connection conn) throws SQLException { + if (catalog == null || catalog.isEmpty()) + return null; + if (!isAvailableCatalog(conn, catalog)) + return new EmptyResultSet(); + + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); try (Statement stmt = conn.createStatement()) { - if (catalog == null || catalog.isEmpty()) - return null; - - ResultSet databases = stmt.executeQuery("show databases"); - String dbname = null; - while (databases.next()) { - dbname = databases.getString("name"); - if (dbname.equalsIgnoreCase(catalog)) - break; - } - databases.close(); - if (dbname == null) - return null; - - stmt.execute("use " + dbname); - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); // set up ColumnMetaDataList - List columnMetaDataList = new ArrayList<>(); - // TABLE_CAT - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(0); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - // TABLE_SCHEM - ColumnMetaData col2 = new ColumnMetaData(); - col2.setColIndex(1); - col2.setColName("TABLE_SCHEM"); - col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col2); - // TABLE_NAME - ColumnMetaData col3 = new ColumnMetaData(); - col3.setColIndex(2); - col3.setColName("TABLE_NAME"); - col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col3); - // COLUMN_NAME - ColumnMetaData col4 = new ColumnMetaData(); - col4.setColIndex(3); - col4.setColName("COLUMN_NAME"); - col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col4); - // KEY_SEQ - ColumnMetaData col5 = new ColumnMetaData(); - col5.setColIndex(4); - col5.setColName("KEY_SEQ"); - col5.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col5); - // PK_NAME - ColumnMetaData col6 = new ColumnMetaData(); - col6.setColIndex(5); - col6.setColName("PK_NAME"); - col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col6); - resultSet.setColumnMetaDataList(columnMetaDataList); - + resultSet.setColumnMetaDataList(buildGetPrimaryKeysMetadataList()); // set rowData List rowDataList = new ArrayList<>(); - ResultSet rs = stmt.executeQuery("describe " + dbname + "." + table); + ResultSet rs = stmt.executeQuery("describe " + catalog + "." + table); rs.next(); TSDBResultSetRowData rowData = new TSDBResultSetRowData(6); - rowData.setString(0, null); - rowData.setString(1, null); - rowData.setString(2, table); - String pkName = rs.getString(1); - rowData.setString(3, pkName); - rowData.setInt(4, 1); - rowData.setString(5, pkName); + rowData.setStringValue(1, catalog); + rowData.setStringValue(2, null); + rowData.setStringValue(3, table); + String primaryKey = rs.getString("Field"); + rowData.setStringValue(4, primaryKey); + rowData.setShortValue(5, (short) 1); + rowData.setStringValue(6, primaryKey); rowDataList.add(rowData); resultSet.setRowDataList(rowDataList); - return resultSet; } + return resultSet; + } + + private List buildGetPrimaryKeysMetadataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT + columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM + columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME + columnMetaDataList.add(buildColumnNameMeta(4)); // 4. COLUMN_NAME + columnMetaDataList.add(buildKeySeqMeta(5)); // 5. KEY_SEQ + columnMetaDataList.add(buildPrimaryKeyNameMeta(6)); // 6. PK_NAME + return columnMetaDataList; + } + + private ColumnMetaData buildKeySeqMeta(int colIndex) { + ColumnMetaData col5 = new ColumnMetaData(); + col5.setColIndex(colIndex); + col5.setColName("KEY_SEQ"); + col5.setColType(Types.SMALLINT); + return col5; + } + + private ColumnMetaData buildPrimaryKeyNameMeta(int colIndex) { + ColumnMetaData col6 = new ColumnMetaData(); + col6.setColIndex(colIndex); + col6.setColName("PK_NAME"); + col6.setColType(Types.NCHAR); + return col6; + } + + private boolean isAvailableCatalog(Connection connection, String catalog) { + try (Statement stmt = connection.createStatement()) { + ResultSet databases = stmt.executeQuery("show databases"); + while (databases.next()) { + String dbname = databases.getString("name"); + this.database = dbname; + this.precision = databases.getString("precision"); + if (dbname.equalsIgnoreCase(catalog)) + return true; + } + databases.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + return false; } protected ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern, Connection conn) throws SQLException { + if (catalog == null || catalog.isEmpty()) + return null; + + if (!isAvailableCatalog(conn, catalog)) { + return new EmptyResultSet(); + } + + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); try (Statement stmt = conn.createStatement()) { - if (catalog == null || catalog.isEmpty()) - return null; - - ResultSet databases = stmt.executeQuery("show databases"); - String dbname = null; - while (databases.next()) { - dbname = databases.getString("name"); - if (dbname.equalsIgnoreCase(catalog)) - break; - } - databases.close(); - if (dbname == null) - return null; - - stmt.execute("use " + dbname); - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); // set up ColumnMetaDataList - List columnMetaDataList = new ArrayList<>(); - // TABLE_CAT - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(0); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - // TABLE_SCHEM - ColumnMetaData col2 = new ColumnMetaData(); - col2.setColIndex(1); - col2.setColName("TABLE_SCHEM"); - col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col2); - // TABLE_NAME - ColumnMetaData col3 = new ColumnMetaData(); - col3.setColIndex(2); - col3.setColName("TABLE_NAME"); - col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col3); - // SUPERTABLE_NAME - ColumnMetaData col4 = new ColumnMetaData(); - col4.setColIndex(3); - col4.setColName("SUPERTABLE_NAME"); - col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col4); - resultSet.setColumnMetaDataList(columnMetaDataList); - + resultSet.setColumnMetaDataList(buildGetSuperTablesColumnMetaDataList()); + // set result set row data + stmt.execute("use " + catalog); ResultSet rs = stmt.executeQuery("show tables like '" + tableNamePattern + "'"); List rowDataList = new ArrayList<>(); while (rs.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(4); - rowData.setString(2, rs.getString(1)); - rowData.setString(3, rs.getString(4)); + rowData.setStringValue(1, catalog); + rowData.setStringValue(2, null); + rowData.setStringValue(3, rs.getString("table_name")); + rowData.setStringValue(4, rs.getString("stable_name")); rowDataList.add(rowData); } resultSet.setRowDataList(rowDataList); - return resultSet; } + return resultSet; } + + private List buildGetSuperTablesColumnMetaDataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT + columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM + columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME + columnMetaDataList.add(buildSuperTableNameMeta(4)); // 4. SUPERTABLE_NAME + return columnMetaDataList; + } + + private ColumnMetaData buildSuperTableNameMeta(int colIndex) { + ColumnMetaData col4 = new ColumnMetaData(); + col4.setColIndex(colIndex); + col4.setColName("SUPERTABLE_NAME"); + col4.setColType(Types.NCHAR); + return col4; + } + } \ No newline at end of file diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java index 7df7252ae2..cb6c7d40ad 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java @@ -1,5 +1,7 @@ package com.taosdata.jdbc; +import com.sun.org.apache.xpath.internal.operations.Bool; + import java.sql.ParameterMetaData; import java.sql.SQLException; import java.sql.Timestamp; @@ -49,6 +51,22 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P if (param < 1 && param >= parameters.length) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); + if (parameters[param - 1] instanceof Boolean) + return TSDBConstants.BOOLEAN_PRECISION; + if (parameters[param - 1] instanceof Byte) + return TSDBConstants.TINYINT_PRECISION; + if (parameters[param - 1] instanceof Short) + return TSDBConstants.SMALLINT_PRECISION; + if (parameters[param - 1] instanceof Integer) + return TSDBConstants.INT_PRECISION; + if (parameters[param - 1] instanceof Long) + return TSDBConstants.BIGINT_PRECISION; + if (parameters[param - 1] instanceof Timestamp) + return TSDBConstants.TIMESTAMP_MS_PRECISION; + if (parameters[param - 1] instanceof Float) + return TSDBConstants.FLOAT_PRECISION; + if (parameters[param - 1] instanceof Double) + return TSDBConstants.DOUBLE_PRECISION; if (parameters[param - 1] instanceof String) return ((String) parameters[param - 1]).length(); if (parameters[param - 1] instanceof byte[]) @@ -60,6 +78,11 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P public int getScale(int param) throws SQLException { if (param < 1 && param >= parameters.length) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); + + if (parameters[param - 1] instanceof Float) + return TSDBConstants.FLOAT_SCALE; + if (parameters[param - 1] instanceof Double) + return TSDBConstants.DOUBLE_SCALE; return 0; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java index 4b5b88d93b..e17548055c 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java @@ -66,10 +66,16 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet public abstract byte[] getBytes(int columnIndex) throws SQLException; @Override - public abstract Date getDate(int columnIndex) throws SQLException; + public Date getDate(int columnIndex) throws SQLException { + Timestamp timestamp = getTimestamp(columnIndex); + return timestamp == null ? null : new Date(timestamp.getTime()); + } @Override - public abstract Time getTime(int columnIndex) throws SQLException; + public Time getTime(int columnIndex) throws SQLException { + Timestamp timestamp = getTimestamp(columnIndex); + return timestamp == null ? null : new Time(timestamp.getTime()); + } @Override public abstract Timestamp getTimestamp(int columnIndex) throws SQLException; @@ -84,10 +90,12 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet } @Override + @Deprecated public InputStream getUnicodeStream(int columnIndex) throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); - + } + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } @@ -171,6 +179,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet } @Override + @Deprecated public InputStream getUnicodeStream(String columnLabel) throws SQLException { return getUnicodeStream(findColumn(columnLabel)); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java index f6a0fcca31..cd266529f3 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java @@ -14,76 +14,42 @@ *****************************************************************************/ package com.taosdata.jdbc; -import java.io.InputStream; -import java.io.Reader; import java.math.BigDecimal; -import java.net.URL; -import java.sql.Date; import java.sql.*; -import java.util.*; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Iterator; +import java.util.List; /* - * TDengine only supports a subset of the standard SQL, thus this implemetation of the + * TDengine only supports a subset of the standard SQL, thus this implementation of the * standard JDBC API contains more or less some adjustments customized for certain * compatibility needs. */ -public class DatabaseMetaDataResultSet implements ResultSet { +public class DatabaseMetaDataResultSet extends AbstractResultSet { - private List columnMetaDataList; - private List rowDataList; + private List columnMetaDataList = new ArrayList<>(); + private List rowDataList = new ArrayList<>(); private TSDBResultSetRowData rowCursor; // position of cursor, starts from 0 as beforeFirst, increases as next() is called private int cursorRowNumber = 0; - public DatabaseMetaDataResultSet() { - rowDataList = new ArrayList(); - columnMetaDataList = new ArrayList(); - } - - public List getRowDataList() { - return rowDataList; - } - public void setRowDataList(List rowDataList) { this.rowDataList = rowDataList; } - public List getColumnMetaDataList() { - return columnMetaDataList; - } - public void setColumnMetaDataList(List columnMetaDataList) { this.columnMetaDataList = columnMetaDataList; } - public TSDBResultSetRowData getRowCursor() { - return rowCursor; - } - - public void setRowCursor(TSDBResultSetRowData rowCursor) { - this.rowCursor = rowCursor; - } - @Override public boolean next() throws SQLException { -// boolean ret = false; -// if (rowDataList.size() > 0) { -// ret = rowDataList.iterator().hasNext(); -// if (ret) { -// rowCursor = rowDataList.iterator().next(); -// cursorRowNumber++; -// } -// } -// return ret; - - /**** add by zyyang 2020-09-29 ****************/ boolean ret = false; if (!rowDataList.isEmpty() && cursorRowNumber < rowDataList.size()) { rowCursor = rowDataList.get(cursorRowNumber++); ret = true; } - return ret; } @@ -99,189 +65,72 @@ public class DatabaseMetaDataResultSet implements ResultSet { @Override public String getString(int columnIndex) throws SQLException { - columnIndex--; - int colType = columnMetaDataList.get(columnIndex).getColType(); - return rowCursor.getString(columnIndex, colType); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getString(columnIndex, nativeType); } @Override public boolean getBoolean(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getBoolean(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getBoolean(columnIndex, nativeType); } @Override public byte getByte(int columnIndex) throws SQLException { - columnIndex--; - return (byte) rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return (byte) rowCursor.getInt(columnIndex, nativeType); } @Override public short getShort(int columnIndex) throws SQLException { - columnIndex--; - return (short) rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return (short) rowCursor.getInt(columnIndex, nativeType); } @Override public int getInt(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getInt(columnIndex, nativeType); } @Override public long getLong(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getLong(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getLong(columnIndex, nativeType); } @Override public float getFloat(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getFloat(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getFloat(columnIndex, nativeType); } @Override public double getDouble(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType()); - } - - @Override - public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { - columnIndex--; - return new BigDecimal(rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType())); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getDouble(columnIndex, nativeType); } @Override public byte[] getBytes(int columnIndex) throws SQLException { - columnIndex--; - return (rowCursor.getString(columnIndex, columnMetaDataList.get(columnIndex).getColType())).getBytes(); - } - - @Override - public Date getDate(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Time getTime(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return (rowCursor.getString(columnIndex, nativeType)).getBytes(); } @Override public Timestamp getTimestamp(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getTimestamp(columnIndex); - } - - @Override - public InputStream getAsciiStream(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public InputStream getUnicodeStream(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public InputStream getBinaryStream(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public String getString(String columnLabel) throws SQLException { - return getString(findColumn(columnLabel)); - } - - @Override - public boolean getBoolean(String columnLabel) throws SQLException { - return getBoolean(findColumn(columnLabel)); - } - - @Override - public byte getByte(String columnLabel) throws SQLException { - return getByte(findColumn(columnLabel)); - } - - @Override - public short getShort(String columnLabel) throws SQLException { - return getShort(findColumn(columnLabel)); - } - - @Override - public int getInt(String columnLabel) throws SQLException { - return getInt(findColumn(columnLabel)); - } - - @Override - public long getLong(String columnLabel) throws SQLException { - return getLong(findColumn(columnLabel)); - } - - @Override - public float getFloat(String columnLabel) throws SQLException { - return getFloat(findColumn(columnLabel)); - } - - @Override - public double getDouble(String columnLabel) throws SQLException { - return getDouble(findColumn(columnLabel)); - } - - @Override - public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { - return getBigDecimal(findColumn(columnLabel)); - } - - @Override - public byte[] getBytes(String columnLabel) throws SQLException { - return getBytes(findColumn(columnLabel)); - } - - @Override - public Date getDate(String columnLabel) throws SQLException { - return getDate(findColumn(columnLabel)); - } - - @Override - public Time getTime(String columnLabel) throws SQLException { - return getTime(findColumn(columnLabel)); - } - - @Override - public Timestamp getTimestamp(String columnLabel) throws SQLException { - return getTimestamp(findColumn(columnLabel)); - } - - @Override - public InputStream getAsciiStream(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public InputStream getUnicodeStream(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public InputStream getBinaryStream(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public SQLWarning getWarnings() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void clearWarnings() throws SQLException { - - } - - @Override - public String getCursorName() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getTimestamp(columnIndex,nativeType); } @Override @@ -291,12 +140,7 @@ public class DatabaseMetaDataResultSet implements ResultSet { @Override public Object getObject(int columnIndex) throws SQLException { - return rowCursor.get(columnIndex); - } - - @Override - public Object getObject(String columnLabel) throws SQLException { - return rowCursor.get(findColumn(columnLabel)); + return rowCursor.getObject(columnIndex); } @Override @@ -304,31 +148,19 @@ public class DatabaseMetaDataResultSet implements ResultSet { Iterator colMetaDataIt = this.columnMetaDataList.iterator(); while (colMetaDataIt.hasNext()) { ColumnMetaData colMetaData = colMetaDataIt.next(); - if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) { - return colMetaData.getColIndex() + 1; + if (colMetaData.getColName() != null && colMetaData.getColName().equals(columnLabel)) { + return colMetaData.getColIndex(); } } throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); } - @Override - public Reader getCharacterStream(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Reader getCharacterStream(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - @Override public BigDecimal getBigDecimal(int columnIndex) throws SQLException { - return new BigDecimal(rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType())); - } - - @Override - public BigDecimal getBigDecimal(String columnLabel) throws SQLException { - return getBigDecimal(findColumn(columnLabel)); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + double value = rowCursor.getDouble(columnIndex, nativeType); + return new BigDecimal(value); } @Override @@ -378,7 +210,6 @@ public class DatabaseMetaDataResultSet implements ResultSet { } else { return 0; } - } @Override @@ -396,434 +227,14 @@ public class DatabaseMetaDataResultSet implements ResultSet { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } - @Override - public void setFetchDirection(int direction) throws SQLException { - - } - - @Override - public int getFetchDirection() throws SQLException { - return ResultSet.FETCH_FORWARD; - } - - @Override - public void setFetchSize(int rows) throws SQLException { - - } - - @Override - public int getFetchSize() throws SQLException { - return 0; - } - - @Override - public int getType() throws SQLException { - return ResultSet.TYPE_FORWARD_ONLY; - } - - @Override - public int getConcurrency() throws SQLException { - return ResultSet.CONCUR_READ_ONLY; - } - - @Override - public boolean rowUpdated() throws SQLException { - return false; - } - - @Override - public boolean rowInserted() throws SQLException { - return false; - } - - @Override - public boolean rowDeleted() throws SQLException { - return false; - } - - @Override - public void updateNull(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBoolean(int columnIndex, boolean x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateByte(int columnIndex, byte x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateShort(int columnIndex, short x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateInt(int columnIndex, int x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateLong(int columnIndex, long x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateFloat(int columnIndex, float x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateDouble(int columnIndex, double x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateString(int columnIndex, String x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBytes(int columnIndex, byte[] x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateDate(int columnIndex, Date x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateTime(int columnIndex, Time x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateObject(int columnIndex, Object x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateNull(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBoolean(String columnLabel, boolean x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateByte(String columnLabel, byte x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateShort(String columnLabel, short x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateInt(String columnLabel, int x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateLong(String columnLabel, long x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateFloat(String columnLabel, float x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateDouble(String columnLabel, double x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateString(String columnLabel, String x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBytes(String columnLabel, byte[] x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateDate(String columnLabel, Date x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateTime(String columnLabel, Time x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateObject(String columnLabel, Object x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void insertRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void deleteRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void refreshRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void cancelRowUpdates() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void moveToInsertRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void moveToCurrentRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - @Override public Statement getStatement() throws SQLException { return null; } - @Override - public Object getObject(int columnIndex, Map> map) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Ref getRef(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Blob getBlob(int columnIndex) throws SQLException { - return null; - } - - @Override - public Clob getClob(int columnIndex) throws SQLException { - return null; - } - - @Override - public Array getArray(int columnIndex) throws SQLException { - return null; - } - - @Override - public Object getObject(String columnLabel, Map> map) throws SQLException { - return null; - } - - @Override - public Ref getRef(String columnLabel) throws SQLException { - return null; - } - - @Override - public Blob getBlob(String columnLabel) throws SQLException { - return null; - } - - @Override - public Clob getClob(String columnLabel) throws SQLException { - return null; - } - - @Override - public Array getArray(String columnLabel) throws SQLException { - return null; - } - - @Override - public Date getDate(int columnIndex, Calendar cal) throws SQLException { - return null; - } - - @Override - public Date getDate(String columnLabel, Calendar cal) throws SQLException { - return null; - } - - @Override - public Time getTime(int columnIndex, Calendar cal) throws SQLException { - return null; - } - - @Override - public Time getTime(String columnLabel, Calendar cal) throws SQLException { - return null; - } - - @Override public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { - return null; - } - - @Override - public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { - return null; - } - - @Override - public URL getURL(int columnIndex) throws SQLException { - return null; - } - - @Override - public URL getURL(String columnLabel) throws SQLException { - return null; - } - - @Override - public void updateRef(int columnIndex, Ref x) throws SQLException { - - } - - @Override - public void updateRef(String columnLabel, Ref x) throws SQLException { - - } - - @Override - public void updateBlob(int columnIndex, Blob x) throws SQLException { - - } - - @Override - public void updateBlob(String columnLabel, Blob x) throws SQLException { - - } - - @Override - public void updateClob(int columnIndex, Clob x) throws SQLException { - - } - - @Override - public void updateClob(String columnLabel, Clob x) throws SQLException { - - } - - @Override - public void updateArray(int columnIndex, Array x) throws SQLException { - - } - - @Override - public void updateArray(String columnLabel, Array x) throws SQLException { - - } - - @Override - public RowId getRowId(int columnIndex) throws SQLException { - return null; - } - - @Override - public RowId getRowId(String columnLabel) throws SQLException { - return null; - } - - @Override - public void updateRowId(int columnIndex, RowId x) throws SQLException { - - } - - @Override - public void updateRowId(String columnLabel, RowId x) throws SQLException { - - } - - @Override - public int getHoldability() throws SQLException { - return 0; + //TODO: calendar is not used + return getTimestamp(columnIndex); } @Override @@ -831,246 +242,9 @@ public class DatabaseMetaDataResultSet implements ResultSet { return false; } - @Override - public void updateNString(int columnIndex, String nString) throws SQLException { - - } - - @Override - public void updateNString(String columnLabel, String nString) throws SQLException { - - } - - @Override - public void updateNClob(int columnIndex, NClob nClob) throws SQLException { - - } - - @Override - public void updateNClob(String columnLabel, NClob nClob) throws SQLException { - - } - - @Override - public NClob getNClob(int columnIndex) throws SQLException { - return null; - } - - @Override - public NClob getNClob(String columnLabel) throws SQLException { - return null; - } - - @Override - public SQLXML getSQLXML(int columnIndex) throws SQLException { - return null; - } - - @Override - public SQLXML getSQLXML(String columnLabel) throws SQLException { - return null; - } - - @Override - public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { - - } - - @Override - public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { - - } - @Override public String getNString(int columnIndex) throws SQLException { - return null; + return getString(columnIndex); } - @Override - public String getNString(String columnLabel) throws SQLException { - return null; - } - - @Override - public Reader getNCharacterStream(int columnIndex) throws SQLException { - return null; - } - - @Override - public Reader getNCharacterStream(String columnLabel) throws SQLException { - return null; - } - - @Override - public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { - - } - - @Override - public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { - - } - - @Override - public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { - - } - - @Override - public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { - - } - - @Override - public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { - - } - - @Override - public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { - - } - - @Override - public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { - - } - - @Override - public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { - - } - - @Override - public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { - - } - - @Override - public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { - - } - - @Override - public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { - - } - - @Override - public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { - - } - - @Override - public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { - - } - - @Override - public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { - - } - - @Override - public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { - - } - - @Override - public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { - - } - - @Override - public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { - - } - - @Override - public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { - - } - - @Override - public void updateClob(int columnIndex, Reader reader) throws SQLException { - - } - - @Override - public void updateClob(String columnLabel, Reader reader) throws SQLException { - - } - - @Override - public void updateNClob(int columnIndex, Reader reader) throws SQLException { - - } - - @Override - public void updateNClob(String columnLabel, Reader reader) throws SQLException { - - } - - @Override - public T getObject(int columnIndex, Class type) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public T getObject(String columnLabel, Class type) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public T unwrap(Class iface) throws SQLException { - return null; - } - - @Override - public boolean isWrapperFor(Class iface) throws SQLException { - return false; - } - - private int getTrueColumnIndex(int columnIndex) throws SQLException { - if (columnIndex < 1) { - throw new SQLException("Column Index out of range, " + columnIndex + " < " + 1); - } - - int numOfCols = this.columnMetaDataList.size(); - if (columnIndex > numOfCols) { - throw new SQLException("Column Index out of range, " + columnIndex + " > " + numOfCols); - } - - return columnIndex - 1; - } } 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 c8ab9fb15a..02fee74eb5 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 @@ -49,7 +49,7 @@ public class TSDBConnection extends AbstractConnection { this.databaseMetaData.setConnection(this); } - public TSDBJNIConnector getConnection() { + public TSDBJNIConnector getConnector() { return this.connector; } @@ -58,7 +58,7 @@ public class TSDBConnection extends AbstractConnection { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); } - return new TSDBStatement(this, this.connector); + return new TSDBStatement(this); } public TSDBSubscribe subscribe(String topic, String sql, boolean restart) throws SQLException { @@ -74,14 +74,18 @@ public class TSDBConnection extends AbstractConnection { } public PreparedStatement prepareStatement(String sql) throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); - return new TSDBPreparedStatement(this, this.connector, sql); + } + + return new TSDBPreparedStatement(this, sql); } public void close() throws SQLException { - if (isClosed) + if (isClosed) { return; + } + this.connector.closeConnection(); this.isClosed = true; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java index f38555ce8a..e6406d2c6d 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java @@ -41,15 +41,15 @@ public abstract class TSDBConstants { public static final int TSDB_DATA_TYPE_BINARY = 8; public static final int TSDB_DATA_TYPE_TIMESTAMP = 9; public static final int TSDB_DATA_TYPE_NCHAR = 10; - /* - 系统增加新的无符号数据类型,分别是: - unsigned tinyint, 数值范围:0-254, NULL 为255 - unsigned smallint,数值范围: 0-65534, NULL 为65535 - unsigned int,数值范围:0-4294967294,NULL 为4294967295u - unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。 - example: - create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned); - */ + /** + * 系统增加新的无符号数据类型,分别是: + * unsigned tinyint, 数值范围:0-254, NULL 为255 + * unsigned smallint,数值范围: 0-65534, NULL 为65535 + * unsigned int,数值范围:0-4294967294,NULL 为4294967295u + * unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。 + * example: + * create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned); + */ public static final int TSDB_DATA_TYPE_UTINYINT = 11; //unsigned tinyint public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int @@ -57,6 +57,47 @@ public abstract class TSDBConstants { // nchar column max length public static final int maxFieldSize = 16 * 1024; + // precision for data types + public static final int BOOLEAN_PRECISION = 1; + public static final int TINYINT_PRECISION = 4; + public static final int SMALLINT_PRECISION = 6; + public static final int INT_PRECISION = 11; + public static final int BIGINT_PRECISION = 20; + public static final int FLOAT_PRECISION = 12; + public static final int DOUBLE_PRECISION = 22; + public static final int TIMESTAMP_MS_PRECISION = 23; + public static final int TIMESTAMP_US_PRECISION = 26; + // scale for data types + public static final int FLOAT_SCALE = 31; + public static final int DOUBLE_SCALE = 31; + + public static int typeName2JdbcType(String type) { + switch (type.toUpperCase()) { + case "TIMESTAMP": + return Types.TIMESTAMP; + case "INT": + return Types.INTEGER; + case "BIGINT": + return Types.BIGINT; + case "FLOAT": + return Types.FLOAT; + case "DOUBLE": + return Types.DOUBLE; + case "BINARY": + return Types.BINARY; + case "SMALLINT": + return Types.SMALLINT; + case "TINYINT": + return Types.TINYINT; + case "BOOL": + return Types.BOOLEAN; + case "NCHAR": + return Types.NCHAR; + default: + return Types.NULL; + } + } + public static int taosType2JdbcType(int taosType) throws SQLException { switch (taosType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: @@ -88,7 +129,7 @@ public abstract class TSDBConstants { } public static String taosType2JdbcTypeName(int taosType) throws SQLException { - switch (taosType){ + switch (taosType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return "BOOL"; case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: @@ -119,7 +160,7 @@ public abstract class TSDBConstants { } public static int jdbcType2TaosType(int jdbcType) throws SQLException { - switch (jdbcType){ + switch (jdbcType) { case Types.BOOLEAN: return TSDBConstants.TSDB_DATA_TYPE_BOOL; case Types.TINYINT: @@ -145,7 +186,7 @@ public abstract class TSDBConstants { } public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException { - switch (jdbcType){ + switch (jdbcType) { case Types.BOOLEAN: return "BOOL"; case Types.TINYINT: 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 7f0cf7de8d..92792d9751 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 @@ -18,6 +18,7 @@ package com.taosdata.jdbc; import com.taosdata.jdbc.utils.TaosInfo; +import java.nio.ByteBuffer; import java.sql.SQLException; import java.sql.SQLWarning; import java.util.List; @@ -29,10 +30,13 @@ public class TSDBJNIConnector { private static volatile Boolean isInitialized = false; private TaosInfo taosInfo = TaosInfo.getInstance(); + // Connection pointer used in C private long taos = TSDBConstants.JNI_NULL_POINTER; + // result set status in current connection private boolean isResultsetClosed; + private int affectedRows = -1; static { @@ -75,7 +79,6 @@ public class TSDBJNIConnector { public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException { if (this.taos != TSDBConstants.JNI_NULL_POINTER) { -// this.closeConnectionImp(this.taos); closeConnection(); this.taos = TSDBConstants.JNI_NULL_POINTER; } @@ -97,12 +100,6 @@ public class TSDBJNIConnector { * @throws SQLException */ public long executeQuery(String sql) throws SQLException { - // close previous result set if the user forgets to invoke the - // free method to close previous result set. -// if (!this.isResultsetClosed) { -// freeResultSet(taosResultSetPointer); -// } - Long pSql = 0l; try { pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos); @@ -170,7 +167,7 @@ public class TSDBJNIConnector { private native long isUpdateQueryImp(long connection, long pSql); /** - * Free resultset operation from C to release resultset pointer by JNI + * Free result set operation from C to release result set pointer by JNI */ public int freeResultSet(long pSql) { int res = this.freeResultSetImp(this.taos, pSql); @@ -178,19 +175,6 @@ public class TSDBJNIConnector { return res; } - /** - * Close the open result set which is associated to the current connection. If the result set is already - * closed, return 0 for success. - */ -// public int freeResultSet() { -// int resCode = TSDBConstants.JNI_SUCCESS; -// if (!isResultsetClosed) { -// resCode = this.freeResultSetImp(this.taos, this.taosResultSetPointer); -// taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER; -// isResultsetClosed = true; -// } -// return resCode; -// } private native int freeResultSetImp(long connection, long result); /** @@ -210,7 +194,9 @@ public class TSDBJNIConnector { * Get schema metadata */ public int getSchemaMetaData(long resultSet, List columnMetaData) { - return this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData); + int ret = this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData); + columnMetaData.stream().forEach(column -> column.setColIndex(column.getColIndex() + 1)); + return ret; } private native int getSchemaMetaDataImp(long connection, long resultSet, List columnMetaData); @@ -237,6 +223,7 @@ public class TSDBJNIConnector { */ public void closeConnection() throws SQLException { int code = this.closeConnectionImp(this.taos); + if (code < 0) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); } else if (code == 0) { @@ -244,6 +231,7 @@ public class TSDBJNIConnector { } else { throw new SQLException("Undefined error code returned by TDengine when closing a connection"); } + // invoke closeConnectionImpl only here taosInfo.connect_close_increment(); } @@ -280,7 +268,7 @@ public class TSDBJNIConnector { private native void unsubscribeImp(long subscription, boolean isKeep); /** - * Validate if a create table sql statement is correct without actually creating that table + * Validate if a create table SQL statement is correct without actually creating that table */ public boolean validateCreateTableSql(String sql) { int res = validateCreateTableSqlImp(taos, sql.getBytes()); @@ -288,4 +276,76 @@ public class TSDBJNIConnector { } private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes); + + public long prepareStmt(String sql) throws SQLException { + Long stmt; + try { + stmt = prepareStmtImp(sql.getBytes(), this.taos); + } catch (Exception e) { + e.printStackTrace(); + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING); + } + + if (stmt == TSDBConstants.JNI_CONNECTION_NULL) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); + } + + if (stmt == TSDBConstants.JNI_SQL_NULL) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL); + } + + if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY); + } + + return stmt; + } + + private native long prepareStmtImp(byte[] sql, long con); + + public void setBindTableName(long stmt, String tableName) throws SQLException { + int code = setBindTableNameImp(stmt, tableName, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to set table name"); + } + } + + private native int setBindTableNameImp(long stmt, String name, long conn); + + public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException { + int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(), + nullList.array(), this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags"); + } + } + + private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn); + + public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows, int columnIndex) throws SQLException { + int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data"); + } + } + + private native int bindColDataImp(long stmt, byte[] colDataList, byte[] lengthList, byte[] isNullList, int type, int bytes, int numOfRows, int columnIndex, long conn); + + public void executeBatch(long stmt) throws SQLException { + int code = executeBatchImp(stmt, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to execute batch bind"); + } + } + + private native int executeBatchImp(long stmt, long con); + + public void closeBatch(long stmt) throws SQLException { + int code = closeStmt(stmt, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to close batch bind"); + } + } + + private native int closeStmt(long stmt, long con); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java index 56f971a35e..c3d5abf35c 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java @@ -18,33 +18,43 @@ import com.taosdata.jdbc.utils.Utils; import java.io.InputStream; import java.io.Reader; +import java.io.UnsupportedEncodingException; import java.math.BigDecimal; import java.net.URL; +import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.sql.*; import java.util.ArrayList; import java.util.Calendar; +import java.util.Collections; import java.util.regex.Matcher; import java.util.regex.Pattern; /* - * TDengine only supports a subset of the standard SQL, thus this implemetation of the + * TDengine only supports a subset of the standard SQL, thus this implementation of the * standard JDBC API contains more or less some adjustments customized for certain * compatibility needs. */ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement { - private String rawSql; private Object[] parameters; private boolean isPrepared; + private ArrayList colData; + private ArrayList tableTags; + private int tagValueLength; + + private String tableName; + private long nativeStmtHandle = 0; + private volatile TSDBParameterMetaData parameterMetaData; - TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) { - super(connection, connecter); + TSDBPreparedStatement(TSDBConnection connection, String sql) { + super(connection); init(sql); + int parameterCnt = 0; if (sql.contains("?")) { - int parameterCnt = 0; for (int i = 0; i < sql.length(); i++) { if ('?' == sql.charAt(i)) { parameterCnt++; @@ -53,6 +63,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat parameters = new Object[parameterCnt]; this.isPrepared = true; } + + if (parameterCnt > 1) { + // the table name is also a parameter, so ignore it. + this.colData = new ArrayList(); + this.tableTags = new ArrayList(); + } } private void init(String sql) { @@ -189,9 +205,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + setObject(parameterIndex, x.doubleValue()); } @Override @@ -206,16 +220,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setDate(int parameterIndex, Date x) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + setObject(parameterIndex, new Timestamp(x.getTime())); } @Override public void setTime(int parameterIndex, Time x) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + setObject(parameterIndex, new Timestamp(x.getTime())); } @Override @@ -260,10 +270,13 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setObject(int parameterIndex, Object x) throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - if (parameterIndex < 1 && parameterIndex >= parameters.length) + } + + if (parameterIndex < 1 && parameterIndex >= parameters.length) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); + } parameters[parameterIndex - 1] = x; } @@ -300,8 +313,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setRef(int parameterIndex, Ref x) throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); + } throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } @@ -329,9 +343,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public ResultSetMetaData getMetaData() throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + if (this.getResultSet() == null) + return null; + return getResultSet().getMetaData(); } @Override @@ -375,10 +389,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat if (isClosed()) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - if (parameterMetaData == null) { - this.parameterMetaData = new TSDBParameterMetaData(parameters); - } - return this.parameterMetaData; + return new TSDBParameterMetaData(parameters); } @Override @@ -390,9 +401,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setNString(int parameterIndex, String value) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + setString(parameterIndex, value); } @Override @@ -515,4 +524,495 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } + + /////////////////////////////////////////////////////////////////////// + // NOTE: the following APIs are not JDBC compatible + // set the bind table name + private static class ColumnInfo { + @SuppressWarnings("rawtypes") + private ArrayList data; + private int type; + private int bytes; + private boolean typeIsSet; + + public ColumnInfo() { + this.typeIsSet = false; + } + + public void setType(int type) throws SQLException { + if (this.isTypeSet()) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type has been set"); + } + + this.typeIsSet = true; + this.type = type; + } + + public boolean isTypeSet() { + return this.typeIsSet; + } + } + + ; + + private static class TableTagInfo { + private boolean isNull; + private Object value; + private int type; + + public TableTagInfo(Object value, int type) { + this.value = value; + this.type = type; + } + + public static TableTagInfo createNullTag(int type) { + TableTagInfo info = new TableTagInfo(null, type); + info.isNull = true; + return info; + } + } + + ; + + public void setTableName(String name) { + this.tableName = name; + } + + private void ensureTagCapacity(int index) { + if (this.tableTags.size() < index + 1) { + int delta = index + 1 - this.tableTags.size(); + this.tableTags.addAll(Collections.nCopies(delta, null)); + } + } + + public void setTagNull(int index, int type) { + ensureTagCapacity(index); + this.tableTags.set(index, TableTagInfo.createNullTag(type)); + } + + public void setTagBoolean(int index, boolean value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL)); + this.tagValueLength += Byte.BYTES; + } + + public void setTagInt(int index, int value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT)); + this.tagValueLength += Integer.BYTES; + } + + public void setTagByte(int index, byte value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT)); + this.tagValueLength += Byte.BYTES; + } + + public void setTagShort(int index, short value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT)); + this.tagValueLength += Short.BYTES; + } + + public void setTagLong(int index, long value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT)); + this.tagValueLength += Long.BYTES; + } + + public void setTagTimestamp(int index, long value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP)); + this.tagValueLength += Long.BYTES; + } + + public void setTagFloat(int index, float value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT)); + this.tagValueLength += Float.BYTES; + } + + public void setTagDouble(int index, double value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE)); + this.tagValueLength += Double.BYTES; + } + + public void setTagString(int index, String value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY)); + this.tagValueLength += value.getBytes().length; + } + + public void setTagNString(int index, String value) { + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR)); + + String charset = TaosGlobalConfig.getCharset(); + try { + this.tagValueLength += value.getBytes(charset).length; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + + public void setValueImpl(int columnIndex, ArrayList list, int type, int bytes) throws SQLException { + if (this.colData.size() == 0) { + this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null)); + } + + ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex); + if (col == null) { + ColumnInfo p = new ColumnInfo(); + p.setType(type); + p.bytes = bytes; + p.data = (ArrayList) list.clone(); + this.colData.set(columnIndex, p); + } else { + if (col.type != type) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch"); + } + col.data.addAll(list); + } + } + + public void setInt(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES); + } + + public void setFloat(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES); + } + + public void setTimestamp(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES); + } + + public void setLong(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES); + } + + public void setDouble(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES); + } + + public void setBoolean(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES); + } + + public void setByte(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES); + } + + public void setShort(int columnIndex, ArrayList list) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES); + } + + public void setString(int columnIndex, ArrayList list, int size) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size); + } + + // note: expand the required space for each NChar character + public void setNString(int columnIndex, ArrayList list, int size) throws SQLException { + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES); + } + + public void columnDataAddBatch() throws SQLException { + // pass the data block to native code + if (rawSql == null) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql statement not set yet"); + } + + // table name is not set yet, abort + if (this.tableName == null) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "table name not set yet"); + } + + int numOfCols = this.colData.size(); + if (numOfCols == 0) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); + } + + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + this.nativeStmtHandle = connector.prepareStmt(rawSql); + + if (this.tableTags == null) { + connector.setBindTableName(this.nativeStmtHandle, this.tableName); + } else { + int num = this.tableTags.size(); + ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength); + tagDataList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer typeList = ByteBuffer.allocate(num); + typeList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES); + lengthList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES); + isNullList.order(ByteOrder.LITTLE_ENDIAN); + + for (int i = 0; i < num; ++i) { + TableTagInfo tag = this.tableTags.get(i); + if (tag.isNull) { + typeList.put((byte) tag.type); + isNullList.putInt(1); + lengthList.putLong(0); + continue; + } + + switch (tag.type) { + case TSDBConstants.TSDB_DATA_TYPE_INT: { + Integer val = (Integer) tag.value; + tagDataList.putInt(val); + lengthList.putLong(Integer.BYTES); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { + Byte val = (Byte) tag.value; + tagDataList.put(val); + lengthList.putLong(Byte.BYTES); + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_BOOL: { + Boolean val = (Boolean) tag.value; + tagDataList.put((byte) (val ? 1 : 0)); + lengthList.putLong(Byte.BYTES); + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { + Short val = (Short) tag.value; + tagDataList.putShort(val); + lengthList.putLong(Short.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { + Long val = (Long) tag.value; + tagDataList.putLong(val == null ? 0 : val); + lengthList.putLong(Long.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { + Float val = (Float) tag.value; + tagDataList.putFloat(val == null ? 0 : val); + lengthList.putLong(Float.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + Double val = (Double) tag.value; + tagDataList.putDouble(val == null ? 0 : val); + lengthList.putLong(Double.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + String charset = TaosGlobalConfig.getCharset(); + String val = (String) tag.value; + + byte[] b = null; + try { + if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) { + b = val.getBytes(); + } else { + b = val.getBytes(charset); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + tagDataList.put(b); + lengthList.putLong(b.length); + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: + case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: + case TSDBConstants.TSDB_DATA_TYPE_UINT: + case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types"); + } + } + + typeList.put((byte) tag.type); + isNullList.putInt(tag.isNull ? 1 : 0); + } + + connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList, + typeList, lengthList, isNullList); + } + + ColumnInfo colInfo = (ColumnInfo) this.colData.get(0); + if (colInfo == null) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); + } + + int rows = colInfo.data.size(); + for (int i = 0; i < numOfCols; ++i) { + ColumnInfo col1 = this.colData.get(i); + if (col1 == null || !col1.isTypeSet()) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); + } + + if (rows != col1.data.size()) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical"); + } + + ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes); + colDataList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer lengthList = ByteBuffer.allocate(rows * Integer.BYTES); + lengthList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer isNullList = ByteBuffer.allocate(rows * Byte.BYTES); + isNullList.order(ByteOrder.LITTLE_ENDIAN); + + switch (col1.type) { + case TSDBConstants.TSDB_DATA_TYPE_INT: { + for (int j = 0; j < rows; ++j) { + Integer val = (Integer) col1.data.get(j); + colDataList.putInt(val == null ? Integer.MIN_VALUE : val); + isNullList.put((byte) (val == null ? 1 : 0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { + for (int j = 0; j < rows; ++j) { + Byte val = (Byte) col1.data.get(j); + colDataList.put(val == null ? 0 : val); + isNullList.put((byte) (val == null ? 1 : 0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_BOOL: { + for (int j = 0; j < rows; ++j) { + Boolean val = (Boolean) col1.data.get(j); + if (val == null) { + colDataList.put((byte) 0); + } else { + colDataList.put((byte) (val ? 1 : 0)); + } + + isNullList.put((byte) (val == null ? 1 : 0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { + for (int j = 0; j < rows; ++j) { + Short val = (Short) col1.data.get(j); + colDataList.putShort(val == null ? 0 : val); + isNullList.put((byte) (val == null ? 1 : 0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { + for (int j = 0; j < rows; ++j) { + Long val = (Long) col1.data.get(j); + colDataList.putLong(val == null ? 0 : val); + isNullList.put((byte) (val == null ? 1 : 0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { + for (int j = 0; j < rows; ++j) { + Float val = (Float) col1.data.get(j); + colDataList.putFloat(val == null ? 0 : val); + isNullList.put((byte) (val == null ? 1 : 0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + for (int j = 0; j < rows; ++j) { + Double val = (Double) col1.data.get(j); + colDataList.putDouble(val == null ? 0 : val); + isNullList.put((byte) (val == null ? 1 : 0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + String charset = TaosGlobalConfig.getCharset(); + for (int j = 0; j < rows; ++j) { + String val = (String) col1.data.get(j); + + colDataList.position(j * col1.bytes); // seek to the correct position + if (val != null) { + byte[] b = null; + try { + if (col1.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) { + b = val.getBytes(); + } else { + b = val.getBytes(charset); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + if (val.length() > col1.bytes) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long"); + } + + colDataList.put(b); + lengthList.putInt(b.length); + isNullList.put((byte) 0); + } else { + lengthList.putInt(0); + isNullList.put((byte) 1); + } + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: + case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: + case TSDBConstants.TSDB_DATA_TYPE_UINT: + case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types"); + } + } + ; + + connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i); + } + } + + public void columnDataExecuteBatch() throws SQLException { + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + connector.executeBatch(this.nativeStmtHandle); + this.columnDataClearBatch(); + } + + public void columnDataClearBatch() { + int size = this.colData.size(); + this.colData.clear(); + + this.colData.addAll(Collections.nCopies(size, null)); + this.tableName = null; // clear the table name + } + + public void columnDataCloseBatch() throws SQLException { + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + connector.closeBatch(this.nativeStmtHandle); + + this.nativeStmtHandle = 0L; + this.tableName = null; + } } 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 aba29d602b..59a64ad520 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 @@ -133,9 +133,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getString(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getString(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getString(columnIndex, nativeType); } return res; } @@ -147,9 +148,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getBoolean(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getBoolean(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getBoolean(columnIndex, nativeType); } return res; } @@ -161,9 +163,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return (byte) this.blockData.getInt(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = (byte) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = (byte) this.rowData.getInt(columnIndex, nativeType); } return res; } @@ -175,9 +178,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return (short) this.blockData.getInt(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = (short) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = (short) this.rowData.getInt(columnIndex, nativeType); } return res; } @@ -189,9 +193,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getInt(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getInt(columnIndex, nativeType); } return res; } @@ -203,13 +209,15 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getLong(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - Object value = this.rowData.get(columnIndex - 1); - if (value instanceof Timestamp) + Object value = this.rowData.getObject(columnIndex); + if (value instanceof Timestamp) { res = ((Timestamp) value).getTime(); - else - res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + } else { + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getLong(columnIndex, nativeType); + } } return res; } @@ -221,9 +229,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return (float) this.blockData.getDouble(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); - if (!lastWasNull) - res = this.rowData.getFloat(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + this.lastWasNull = this.rowData.wasNull(columnIndex); + if (!lastWasNull) { + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getFloat(columnIndex, nativeType); + } return res; } @@ -235,9 +245,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getDouble(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getDouble(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getDouble(columnIndex, nativeType); } return res; } @@ -245,34 +256,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { public byte[] getBytes(int columnIndex) throws SQLException { checkAvailability(columnIndex, this.columnMetaDataList.size()); - Object value = this.rowData.get(columnIndex - 1); + Object value = this.rowData.getObject(columnIndex); if (value == null) return null; - int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); - switch (colType) { + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BIGINT: - return Longs.toByteArray((Long) value); + return Longs.toByteArray((long) value); case TSDBConstants.TSDB_DATA_TYPE_INT: return Ints.toByteArray((int) value); case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: - return Shorts.toByteArray((Short) value); + return Shorts.toByteArray((short) value); case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return new byte[]{(byte) value}; + case TSDBConstants.TSDB_DATA_TYPE_BINARY: + return (byte[]) value; + case TSDBConstants.TSDB_DATA_TYPE_BOOL: + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + default: + return value.toString().getBytes(); } - return value.toString().getBytes(); - } - - @Override - public Date getDate(int columnIndex) throws SQLException { - Timestamp timestamp = getTimestamp(columnIndex); - return timestamp == null ? null : new Date(timestamp.getTime()); - } - - @Override - public Time getTime(int columnIndex) throws SQLException { - Timestamp timestamp = getTimestamp(columnIndex); - return timestamp == null ? null : new Time(timestamp.getTime()); } public Timestamp getTimestamp(int columnIndex) throws SQLException { @@ -282,9 +286,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getTimestamp(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getTimestamp(columnIndex - 1); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getTimestamp(columnIndex, nativeType); } return res; } @@ -304,13 +309,9 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.get(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); - if (colType == TSDBConstants.TSDB_DATA_TYPE_BINARY) - res = ((String) this.rowData.get(columnIndex - 1)).getBytes(); - else - res = this.rowData.get(columnIndex - 1); + res = this.rowData.getObject(columnIndex); } return res; } @@ -318,7 +319,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { public int findColumn(String columnLabel) throws SQLException { for (ColumnMetaData colMetaData : this.columnMetaDataList) { if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) { - return colMetaData.getColIndex() + 1; + return colMetaData.getColIndex(); } } throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); @@ -329,25 +330,25 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return new BigDecimal(this.blockData.getLong(columnIndex - 1)); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); BigDecimal res = null; if (!lastWasNull) { - int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); - switch (colType) { + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: - res = new BigDecimal(Long.valueOf(this.rowData.get(columnIndex - 1).toString())); + res = new BigDecimal(Long.valueOf(this.rowData.getObject(columnIndex).toString())); break; case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: - res = new BigDecimal(Double.valueOf(this.rowData.get(columnIndex - 1).toString())); + res = new BigDecimal(Double.valueOf(this.rowData.getObject(columnIndex).toString())); break; case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: - return new BigDecimal(((Timestamp) this.rowData.get(columnIndex - 1)).getTime()); + return new BigDecimal(((Timestamp) this.rowData.getObject(columnIndex)).getTime()); default: - res = new BigDecimal(this.rowData.get(columnIndex - 1).toString()); + res = new BigDecimal(this.rowData.getObject(columnIndex).toString()); } } return res; 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 index ce5290de66..7b3be5d263 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java @@ -29,6 +29,8 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import com.taosdata.jdbc.utils.NullType; + public class TSDBResultSetBlockData { private int numOfRows = 0; private int rowIndex = 0; @@ -164,59 +166,7 @@ public class TSDBResultSetBlockData { } } - 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 @@ -488,8 +438,8 @@ public class TSDBResultSetBlockData { } try { - String ss = TaosGlobalConfig.getCharset(); - return new String(dest, ss); + String charset = TaosGlobalConfig.getCharset(); + return new String(dest, charset); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java index e4ac5303d0..48d4247392 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java @@ -113,6 +113,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1); switch (columnMetaData.getColType()) { + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return 5; case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: 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 34470fbc4e..01104440ab 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 @@ -14,6 +14,8 @@ *****************************************************************************/ package com.taosdata.jdbc; +import com.taosdata.jdbc.utils.NullType; + import java.math.BigDecimal; import java.sql.SQLException; import java.sql.Timestamp; @@ -22,11 +24,13 @@ import java.util.ArrayList; import java.util.Collections; public class TSDBResultSetRowData { + private ArrayList data; - private int colSize = 0; + private int colSize; public TSDBResultSetRowData(int colSize) { - this.setColSize(colSize); + this.colSize = colSize; + this.clear(); } public void clear() { @@ -41,67 +45,104 @@ public class TSDBResultSetRowData { } public boolean wasNull(int col) { - return data.get(col) == null; + return data.get(col - 1) == null; } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setBooleanValue(int col, boolean value) { + setBoolean(col - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setBoolean(int col, boolean value) { data.set(col, value); } - public boolean getBoolean(int col, int srcType) throws SQLException { - Object obj = data.get(col); + public boolean getBoolean(int col, int nativeType) throws SQLException { + Object obj = data.get(col - 1); - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return (Boolean) obj; - case TSDBConstants.TSDB_DATA_TYPE_FLOAT: - return ((Float) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE; - case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: - return ((Double) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE; case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; case TSDBConstants.TSDB_DATA_TYPE_INT: return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; - case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE; + case TSDBConstants.TSDB_DATA_TYPE_BINARY: + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: { + return obj.toString().contains("1"); + } default: return false; } } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setByteValue(int colIndex, byte value) { + setByte(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setByte(int col, byte value) { data.set(col, value); } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setShortValue(int colIndex, short value) { + setShort(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setShort(int col, short value) { data.set(col, value); } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setIntValue(int colIndex, int value) { + setInt(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setInt(int col, int value) { data.set(col, value); } - public int getInt(int col, int srcType) throws SQLException { - Object obj = data.get(col); + public int getInt(int col, int nativeType) throws SQLException { + Object obj = data.get(col - 1); + if (obj == null) + return NullType.getIntNull(); - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj) ? 1 : 0; - case TSDBConstants.TSDB_DATA_TYPE_FLOAT: - return ((Float) obj).intValue(); - case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: - return ((Double) obj).intValue(); case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj; case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: return (Short) obj; case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj; - case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: return ((Long) obj).intValue(); case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_BINARY: @@ -128,35 +169,48 @@ public class TSDBResultSetRowData { long value = (long) obj; if (value < 0) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); - return new Long(value).intValue(); + return Long.valueOf(value).intValue(); } + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: + return ((Float) obj).intValue(); + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: + return ((Double) obj).intValue(); + default: + return 0; } - - return 0; } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setLongValue(int colIndex, long value) { + setLong(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setLong(int col, long value) { data.set(col, value); } - public long getLong(int col, int srcType) throws SQLException { - Object obj = data.get(col); + public long getLong(int col, int nativeType) throws SQLException { + Object obj = data.get(col - 1); + if (obj == null) { + return NullType.getBigIntNull(); + } - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj) ? 1 : 0; - case TSDBConstants.TSDB_DATA_TYPE_FLOAT: - return ((Float) obj).longValue(); - case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: - return ((Double) obj).longValue(); case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj; case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: return (Short) obj; case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj; - case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: return (Long) obj; case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_BINARY: @@ -185,19 +239,35 @@ public class TSDBResultSetRowData { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); return value; } + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: + return ((Float) obj).longValue(); + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: + return ((Double) obj).longValue(); + default: + return 0; } - - return 0; } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setFloatValue(int colIndex, float value) { + setFloat(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setFloat(int col, float value) { data.set(col, value); } - public float getFloat(int col, int srcType) { - Object obj = data.get(col); + public float getFloat(int col, int nativeType) { + Object obj = data.get(col - 1); + if (obj == null) + return NullType.getFloatNull(); - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj) ? 1 : 0; case TSDBConstants.TSDB_DATA_TYPE_FLOAT: @@ -213,19 +283,31 @@ public class TSDBResultSetRowData { case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj; + default: + return NullType.getFloatNull(); } - - return 0; } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setDoubleValue(int colIndex, double value) { + setDouble(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setDouble(int col, double value) { data.set(col, value); } - public double getDouble(int col, int srcType) { - Object obj = data.get(col); + public double getDouble(int col, int nativeType) { + Object obj = data.get(col - 1); + if (obj == null) + return NullType.getDoubleNull(); - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj) ? 1 : 0; case TSDBConstants.TSDB_DATA_TYPE_FLOAT: @@ -241,16 +323,46 @@ public class TSDBResultSetRowData { case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj; + default: + return NullType.getDoubleNull(); } - - return 0; } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setStringValue(int colIndex, String value) { + data.set(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setString(int col, String value) { - data.set(col, value); + // TODO: + // !!!NOTE!!! + // this is very confusing problem which related to JNI-method implementation, + // the JNI method return a String(encoded in UTF) for BINARY value, which means the JNI method will invoke + // this setString(int, String) to handle BINARY value, we need to build a byte[] with default charsetEncoding + data.set(col, value == null ? null : value.getBytes()); } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setByteArrayValue(int colIndex, byte[] value) { + setByteArray(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setByteArray(int col, byte[] value) { + // TODO: + // !!!NOTE!!! + // this is very confusing problem which related to JNI-method implementation, + // the JNI method return a byte[] for NCHAR value, which means the JNI method will invoke + // this setByteArr(int, byte[]) to handle NCHAR value, we need to build a String with charsetEncoding by TaosGlobalConfig try { data.set(col, new String(value, TaosGlobalConfig.getCharset())); } catch (Exception e) { @@ -258,47 +370,56 @@ public class TSDBResultSetRowData { } } - /** - * The original type may not be a string type, but will be converted to by calling this method - * - * @param col column index - * @return - */ - public String getString(int col, int srcType) { - switch (srcType) { - case TSDBConstants.TSDB_DATA_TYPE_BINARY: - case TSDBConstants.TSDB_DATA_TYPE_NCHAR: - return (String) data.get(col); + public String getString(int col, int nativeType) { + Object obj = data.get(col - 1); + if (obj == null) + return null; + + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { - Byte value = new Byte(String.valueOf(data.get(col))); + Byte value = new Byte(String.valueOf(obj)); if (value >= 0) return value.toString(); return Integer.toString(value & 0xff); } case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: { - Short value = new Short(String.valueOf(data.get(col))); + Short value = new Short(String.valueOf(obj)); if (value >= 0) return value.toString(); return Integer.toString(value & 0xffff); } case TSDBConstants.TSDB_DATA_TYPE_UINT: { - Integer value = new Integer(String.valueOf(data.get(col))); + Integer value = new Integer(String.valueOf(obj)); if (value >= 0) return value.toString(); return Long.toString(value & 0xffffffffl); } case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { - Long value = new Long(String.valueOf(data.get(col))); + Long value = new Long(String.valueOf(obj)); if (value >= 0) return value.toString(); long lowValue = value & 0x7fffffffffffffffL; return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)).toString(); } + case TSDBConstants.TSDB_DATA_TYPE_BINARY: + return new String((byte[]) obj); + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + return (String) obj; default: - return String.valueOf(data.get(col)); + return String.valueOf(obj); } } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setTimestampValue(int colIndex, long value) { + setTimestamp(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setTimestamp(int col, long ts) { //TODO: this implementation contains logical error // when precision is us the (long ts) is 16 digital number @@ -315,28 +436,20 @@ public class TSDBResultSetRowData { } } - public Timestamp getTimestamp(int col) { - return (Timestamp) data.get(col); + public Timestamp getTimestamp(int col, int nativeType) { + Object obj = data.get(col - 1); + if (obj == null) + return null; + switch (nativeType) { + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + return new Timestamp((Long) obj); + default: + return (Timestamp) obj; + } } - public Object get(int col) { - return data.get(col); + public Object getObject(int col) { + return data.get(col - 1); } - public int getColSize() { - return colSize; - } - - private void setColSize(int colSize) { - this.colSize = colSize; - this.clear(); - } - - public ArrayList getData() { - return data; - } - - 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 fb20a621b0..e1ebc4ab3c 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,8 +19,6 @@ import java.sql.ResultSet; import java.sql.SQLException; public class TSDBStatement extends AbstractStatement { - - private TSDBJNIConnector connector; /** * Status of current statement */ @@ -29,29 +27,27 @@ public class TSDBStatement extends AbstractStatement { private TSDBConnection connection; private TSDBResultSet resultSet; - public void setConnection(TSDBConnection connection) { + TSDBStatement(TSDBConnection connection) { this.connection = connection; } - TSDBStatement(TSDBConnection connection, TSDBJNIConnector connector) { - this.connection = connection; - this.connector = connector; - } - public ResultSet executeQuery(String sql) throws SQLException { - // check if closed - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - //TODO: 如果在executeQuery方法中执行insert语句,那么先执行了SQL,再通过pSql来检查是否为一个insert语句,但这个insert SQL已经执行成功了 - - // execute query - long pSql = this.connector.executeQuery(sql); + } + //TODO: + // this is an unreasonable implementation, if the paratemer is a insert statement, + // the JNI connector will execute the sql at first and return a pointer: pSql, + // we use this pSql and invoke the isUpdateQuery(long pSql) method to decide . + // but the insert sql is already executed in database. + //execute query + long pSql = this.connection.getConnector().executeQuery(sql); // if pSql is create/insert/update/delete/alter SQL - if (this.connector.isUpdateQuery(pSql)) { - this.connector.freeResultSet(pSql); + if (this.connection.getConnector().isUpdateQuery(pSql)) { + this.connection.getConnector().freeResultSet(pSql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); } - TSDBResultSet res = new TSDBResultSet(this, this.connector, pSql); + TSDBResultSet res = new TSDBResultSet(this, this.connection.getConnector(), pSql); res.setBatchFetch(this.connection.getBatchFetch()); return res; } @@ -60,14 +56,14 @@ public class TSDBStatement extends AbstractStatement { if (isClosed()) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - long pSql = this.connector.executeQuery(sql); + long pSql = this.connection.getConnector().executeQuery(sql); // if pSql is create/insert/update/delete/alter SQL - if (!this.connector.isUpdateQuery(pSql)) { - this.connector.freeResultSet(pSql); + if (!this.connection.getConnector().isUpdateQuery(pSql)) { + this.connection.getConnector().freeResultSet(pSql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE); } - int affectedRows = this.connector.getAffectedRows(pSql); - this.connector.freeResultSet(pSql); + int affectedRows = this.connection.getConnector().getAffectedRows(pSql); + this.connection.getConnector().freeResultSet(pSql); return affectedRows; } @@ -81,30 +77,29 @@ public class TSDBStatement extends AbstractStatement { public boolean execute(String sql) throws SQLException { // check if closed - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); + } + // execute query - long pSql = this.connector.executeQuery(sql); + long pSql = this.connection.getConnector().executeQuery(sql); // if pSql is create/insert/update/delete/alter SQL - if (this.connector.isUpdateQuery(pSql)) { - this.affectedRows = this.connector.getAffectedRows(pSql); - this.connector.freeResultSet(pSql); + if (this.connection.getConnector().isUpdateQuery(pSql)) { + this.affectedRows = this.connection.getConnector().getAffectedRows(pSql); + this.connection.getConnector().freeResultSet(pSql); return false; } - this.resultSet = new TSDBResultSet(this, this.connector, pSql); + this.resultSet = new TSDBResultSet(this, this.connection.getConnector(), pSql); this.resultSet.setBatchFetch(this.connection.getBatchFetch()); return true; } public ResultSet getResultSet() throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); -// long resultSetPointer = connector.getResultSet(); -// TSDBResultSet resSet = null; -// if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) { -// resSet = new TSDBResultSet(connector, resultSetPointer); -// } + } + return this.resultSet; } @@ -115,12 +110,20 @@ public class TSDBStatement extends AbstractStatement { } public Connection getConnection() throws SQLException { - if (isClosed()) + if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - if (this.connector == null) + } + + if (this.connection.getConnector() == null) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); + } + return this.connection; } + + public void setConnection(TSDBConnection connection) { + this.connection = connection; + } public boolean isClosed() throws SQLException { return isClosed; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java new file mode 100755 index 0000000000..0e05aeeee7 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java @@ -0,0 +1,91 @@ +package com.taosdata.jdbc.utils; + +public 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; + } + + public static boolean isTinyIntNull(byte val) { + return val == Byte.MIN_VALUE; + } + + public static boolean isSmallIntNull(short val) { + return val == Short.MIN_VALUE; + } + + public static boolean isIntNull(int val) { + return val == Integer.MIN_VALUE; + } + + public static boolean isBigIntNull(long val) { + return val == Long.MIN_VALUE; + } + + public static boolean isFloatNull(float val) { + return Float.isNaN(val); + } + + public static boolean isDoubleNull(double val) { + return Double.isNaN(val); + } + + public static boolean isBinaryNull(byte[] val, int length) { + if (length != Byte.BYTES) { + return false; + } + + return val[0] == 0xFF; + } + + public static boolean isNcharNull(byte[] val, int length) { + if (length != Integer.BYTES) { + return false; + } + + return (val[0] & val[1] & val[2] & val[3]) == 0xFF; + } + + public static byte getBooleanNull() { + return NullType.NULL_BOOL_VAL; + } + + public static byte getTinyintNull() { + return Byte.MIN_VALUE; + } + + public static int getIntNull() { + return Integer.MIN_VALUE; + } + + public static short getSmallIntNull() { + return Short.MIN_VALUE; + } + + public static long getBigIntNull() { + return Long.MIN_VALUE; + } + + public static int getFloatNull() { + return 0x7FF00000; + } + + public static long getDoubleNull() { + return 0x7FFFFF0000000000L; + } + + public static byte getBinaryNull() { + return (byte) 0xFF; + } + + public static byte[] getNcharNull() { + return new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF}; + } + +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java index 082cec1e24..8ab610fec6 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java @@ -95,16 +95,7 @@ public class Utils { public static String getNativeSql(String rawSql, Object[] parameters) { // toLowerCase String preparedSql = rawSql.trim().toLowerCase(); - - String[] clause = new String[0]; - if (SqlSyntaxValidator.isInsertSql(preparedSql)) { - // insert or import - clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)"}; - } - if (SqlSyntaxValidator.isSelectSql(preparedSql)) { - // select - clause = new String[]{"where\\s*.*"}; - } + String[] clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)", "where\\s*.*"}; Map placeholderPositions = new HashMap<>(); RangeSet clauseRangeSet = TreeRangeSet.create(); findPlaceholderPosition(preparedSql, placeholderPositions); @@ -146,6 +137,7 @@ public class Utils { */ private static String transformSql(String rawSql, Object[] paramArr, Map placeholderPosition, RangeSet clauseRangeSet) { String[] sqlArr = rawSql.split("\\?"); + return IntStream.range(0, sqlArr.length).mapToObj(index -> { if (index == paramArr.length) return sqlArr[index]; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java index ca7251bb0e..dc6d0d322a 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java @@ -32,20 +32,34 @@ public class TSDBConnectionTest { } @Test - public void subscribe() { + public void runSubscribe() { try { + // given TSDBConnection unwrap = conn.unwrap(TSDBConnection.class); TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false); + // when TSDBResultSet rs = subscribe.consume(); ResultSetMetaData metaData = rs.getMetaData(); - for (int count = 0; count < 10 && rs.next(); count++) { - for (int i = 1; i <= metaData.getColumnCount(); i++) { - String value = rs.getString(i); - System.out.print(metaData.getColumnLabel(i) + ":" + value + "\t"); - } - System.out.println(); - } + + // then Assert.assertNotNull(rs); + Assert.assertEquals(4, metaData.getColumnCount()); + Assert.assertEquals("ts", metaData.getColumnLabel(1)); + Assert.assertEquals("level", metaData.getColumnLabel(2)); + Assert.assertEquals("content", metaData.getColumnLabel(3)); + Assert.assertEquals("ipaddr", metaData.getColumnLabel(4)); + rs.next(); + // row 1 + { + Assert.assertNotNull(rs.getTimestamp(1)); + Assert.assertNotNull(rs.getTimestamp("ts")); + Assert.assertNotNull(rs.getByte(2)); + Assert.assertNotNull(rs.getByte("level")); + Assert.assertNotNull(rs.getString(3)); + Assert.assertNotNull(rs.getString("content")); + Assert.assertNotNull(rs.getString(4)); + Assert.assertNotNull(rs.getString("ipaddr")); + } subscribe.close(false); } catch (SQLException e) { e.printStackTrace(); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java index a7657fa3e5..cb6133015c 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java @@ -7,9 +7,11 @@ import java.util.Properties; public class TSDBDatabaseMetaDataTest { private static final String host = "127.0.0.1"; + private static final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; private static Connection connection; private static TSDBDatabaseMetaData metaData; + @Test public void unwrap() throws SQLException { TSDBDatabaseMetaData unwrap = metaData.unwrap(TSDBDatabaseMetaData.class); @@ -33,7 +35,7 @@ public class TSDBDatabaseMetaDataTest { @Test public void getURL() throws SQLException { - Assert.assertEquals("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", metaData.getURL()); + Assert.assertEquals(url, metaData.getURL()); } @Test @@ -627,17 +629,32 @@ public class TSDBDatabaseMetaDataTest { @Test public void getTables() throws SQLException { - System.out.println("****************************************************"); - ResultSet tables = metaData.getTables("log", "", null, null); - ResultSetMetaData metaData = tables.getMetaData(); - while (tables.next()) { - System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t"); - System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t"); - System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t"); - System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n"); + ResultSet rs = metaData.getTables("log", "", null, null); + ResultSetMetaData meta = rs.getMetaData(); + Assert.assertNotNull(rs); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_SCHEM + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertNotNull(rs.getString(3)); + Assert.assertNotNull(rs.getString("TABLE_NAME")); + // TABLE_TYPE + Assert.assertEquals("TABLE_TYPE", meta.getColumnLabel(4)); + Assert.assertEquals("TABLE", rs.getString(4)); + Assert.assertEquals("TABLE", rs.getString("TABLE_TYPE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(5)); + Assert.assertEquals("", rs.getString(5)); + Assert.assertEquals("", rs.getString("REMARKS")); } - System.out.println(); - Assert.assertNotNull(tables); } @Test @@ -647,46 +664,130 @@ public class TSDBDatabaseMetaDataTest { @Test public void getCatalogs() throws SQLException { - System.out.println("****************************************************"); - - ResultSet catalogs = metaData.getCatalogs(); - ResultSetMetaData meta = catalogs.getMetaData(); - while (catalogs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i)); - } - System.out.println(); + ResultSet rs = metaData.getCatalogs(); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertNotNull(rs.getString(1)); + Assert.assertNotNull(rs.getString("TABLE_CAT")); } } @Test public void getTableTypes() throws SQLException { - System.out.println("****************************************************"); - ResultSet tableTypes = metaData.getTableTypes(); - while (tableTypes.next()) { - System.out.println(tableTypes.getString("TABLE_TYPE")); + tableTypes.next(); + // tableTypes: table + { + Assert.assertEquals("TABLE", tableTypes.getString(1)); + Assert.assertEquals("TABLE", tableTypes.getString("TABLE_TYPE")); + } + tableTypes.next(); + // tableTypes: stable + { + Assert.assertEquals("STABLE", tableTypes.getString(1)); + Assert.assertEquals("STABLE", tableTypes.getString("TABLE_TYPE")); } - Assert.assertNotNull(metaData.getTableTypes()); } @Test public void getColumns() throws SQLException { - System.out.println("****************************************************"); - + // when ResultSet columns = metaData.getColumns("log", "", "dn", ""); + // then ResultSetMetaData meta = columns.getMetaData(); - while (columns.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t"); - System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t"); - System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t"); - System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t"); - System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t"); - System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n"); - System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n"); + columns.next(); + // column: 1 + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", columns.getString(1)); + Assert.assertEquals("log", columns.getString("TABLE_CAT")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn", columns.getString(3)); + Assert.assertEquals("dn", columns.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("ts", columns.getString(4)); + Assert.assertEquals("ts", columns.getString("COLUMN_NAME")); + // DATA_TYPE + Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5)); + Assert.assertEquals(Types.TIMESTAMP, columns.getInt(5)); + Assert.assertEquals(Types.TIMESTAMP, columns.getInt("DATA_TYPE")); + // TYPE_NAME + Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("TIMESTAMP", columns.getString(6)); + Assert.assertEquals("TIMESTAMP", columns.getString("TYPE_NAME")); + // COLUMN_SIZE + Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7)); + Assert.assertEquals(26, columns.getInt(7)); + Assert.assertEquals(26, columns.getInt("COLUMN_SIZE")); + // DECIMAL_DIGITS + Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS")); + Assert.assertEquals(null, columns.getString(9)); + Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS")); + // NUM_PREC_RADIX + Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10)); + Assert.assertEquals(10, columns.getInt(10)); + Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX")); + // NULLABLE + Assert.assertEquals("NULLABLE", meta.getColumnLabel(11)); + Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt(11)); + Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt("NULLABLE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(12)); + Assert.assertEquals(null, columns.getString(12)); + Assert.assertEquals(null, columns.getString("REMARKS")); + } + columns.next(); + // column: 2 + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", columns.getString(1)); + Assert.assertEquals("log", columns.getString("TABLE_CAT")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn", columns.getString(3)); + Assert.assertEquals("dn", columns.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("cpu_taosd", columns.getString(4)); + Assert.assertEquals("cpu_taosd", columns.getString("COLUMN_NAME")); + // DATA_TYPE + Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5)); + Assert.assertEquals(Types.FLOAT, columns.getInt(5)); + Assert.assertEquals(Types.FLOAT, columns.getInt("DATA_TYPE")); + // TYPE_NAME + Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("FLOAT", columns.getString(6)); + Assert.assertEquals("FLOAT", columns.getString("TYPE_NAME")); + // COLUMN_SIZE + Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7)); + Assert.assertEquals(12, columns.getInt(7)); + Assert.assertEquals(12, columns.getInt("COLUMN_SIZE")); + // DECIMAL_DIGITS + Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS")); + Assert.assertEquals(null, columns.getString(9)); + Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS")); + // NUM_PREC_RADIX + Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10)); + Assert.assertEquals(10, columns.getInt(10)); + Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX")); + // NULLABLE + Assert.assertEquals("NULLABLE", meta.getColumnLabel(11)); + Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt(11)); + Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt("NULLABLE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(12)); + Assert.assertEquals(null, columns.getString(12)); } } @@ -712,17 +813,35 @@ public class TSDBDatabaseMetaDataTest { @Test public void getPrimaryKeys() throws SQLException { - System.out.println("****************************************************"); - ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1"); - while (rs.next()) { - System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); - System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME")); - System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ")); - System.out.println("PK_NAME: " + rs.getString("PK_NAME")); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_SCHEM + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn1", rs.getString(3)); + Assert.assertEquals("dn1", rs.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("ts", rs.getString(4)); + Assert.assertEquals("ts", rs.getString("COLUMN_NAME")); + // KEY_SEQ + Assert.assertEquals("KEY_SEQ", meta.getColumnLabel(5)); + Assert.assertEquals(1, rs.getShort(5)); + Assert.assertEquals(1, rs.getShort("KEY_SEQ")); + // DATA_TYPE + Assert.assertEquals("PK_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("ts", rs.getString(6)); + Assert.assertEquals("ts", rs.getString("PK_NAME")); } - - Assert.assertNotNull(rs); } @Test @@ -847,14 +966,27 @@ public class TSDBDatabaseMetaDataTest { @Test public void getSuperTables() throws SQLException { - System.out.println("****************************************************"); - ResultSet rs = metaData.getSuperTables("log", "", "dn1"); - while (rs.next()) { - System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); - System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME")); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_CAT + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_CAT + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn1", rs.getString(3)); + Assert.assertEquals("dn1", rs.getString("TABLE_NAME")); + // TABLE_CAT + Assert.assertEquals("SUPERTABLE_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("dn", rs.getString(4)); + Assert.assertEquals("dn", rs.getString("SUPERTABLE_NAME")); } - Assert.assertNotNull(rs); } @Test @@ -951,15 +1083,12 @@ public class TSDBDatabaseMetaDataTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); - connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties); + connection = DriverManager.getConnection(url, properties); metaData = connection.getMetaData().unwrap(TSDBDatabaseMetaData.class); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java index 161539962d..66078ef503 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java @@ -45,9 +45,9 @@ public class TSDBJNIConnectorTest { rowData = new TSDBResultSetRowData(columnSize); // iterate resultSet for (int i = 0; next(connector, pSql); i++) { - System.out.println("col[" + i + "] size: " + rowData.getColSize()); - rowData.getData().stream().forEach(col -> System.out.print(col + "\t")); - System.out.println(); +// System.out.println("col[" + i + "] size: " + rowData.getColSize()); +// rowData.getData().stream().forEach(col -> System.out.print(col + "\t")); +// System.out.println(); } // close resultSet code = connector.freeResultSet(pSql); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java index 12bcc43917..83caf1bebb 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java @@ -54,16 +54,17 @@ public class TSDBParameterMetaDataTest { @Test public void getPrecision() throws SQLException { - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); - Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); - Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); + //create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) + Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1)); + Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2)); + Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3)); + Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4)); + Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5)); + Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6)); + Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7)); + Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8)); + Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9)); + Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10)); } @Test @@ -71,8 +72,8 @@ public class TSDBParameterMetaDataTest { Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); - Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); - Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); + Assert.assertEquals(31, parameterMetaData_insert.getScale(4)); + Assert.assertEquals(31, parameterMetaData_insert.getScale(5)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); @@ -124,10 +125,16 @@ public class TSDBParameterMetaDataTest { @Test public void getParameterMode() throws SQLException { - for (int i = 1; i <= parameterMetaData_insert.getParameterCount(); i++) { - int parameterMode = parameterMetaData_insert.getParameterMode(i); - Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMode); - } + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(1)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(2)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(3)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(4)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(5)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(6)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(7)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(8)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(9)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(10)); } @Test @@ -144,7 +151,6 @@ public class TSDBParameterMetaDataTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); try (Statement stmt = conn.createStatement()) { stmt.execute("drop database if exists test_pstmt"); @@ -164,7 +170,7 @@ public class TSDBParameterMetaDataTest { pstmt_insert.setObject(7, Byte.MAX_VALUE); pstmt_insert.setObject(8, true); pstmt_insert.setObject(9, "hello".getBytes()); - pstmt_insert.setObject(10, "Hello"); + pstmt_insert.setObject(10, "涛思数据"); parameterMetaData_insert = pstmt_insert.getParameterMetaData(); pstmt_select = conn.prepareStatement(sql_select); @@ -173,7 +179,7 @@ public class TSDBParameterMetaDataTest { pstmt_select.setInt(3, 0); parameterMetaData_select = pstmt_select.getParameterMetaData(); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java index dc6fd4c501..0daf6c00bc 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java @@ -1,231 +1,645 @@ package com.taosdata.jdbc; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.*; import java.io.IOException; -import java.io.Serializable; +import java.math.BigDecimal; import java.sql.*; +import java.util.ArrayList; +import java.util.Random; public class TSDBPreparedStatementTest { + private static final String host = "127.0.0.1"; private static Connection conn; private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - private static PreparedStatement pstmt_insert; - private static final String sql_select = "select * from t1 where ts > ? and ts <= ? and f1 >= ?"; - private static PreparedStatement pstmt_select; + private static final String sql_select = "select * from t1 where ts >= ? and ts < ? and f1 >= ?"; + + private PreparedStatement pstmt_insert; + private PreparedStatement pstmt_select; + //create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64)) @Test public void executeQuery() throws SQLException { - long end = System.currentTimeMillis(); - long start = end - 1000 * 60 * 60; + // given + long ts = System.currentTimeMillis(); + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setInt(2, 2); + pstmt_insert.setLong(3, 3l); + pstmt_insert.setFloat(4, 3.14f); + pstmt_insert.setDouble(5, 3.1415); + pstmt_insert.setShort(6, (short) 6); + pstmt_insert.setByte(7, (byte) 7); + pstmt_insert.setBoolean(8, true); + pstmt_insert.setBytes(9, "abc".getBytes()); + pstmt_insert.setString(10, "涛思数据"); + pstmt_insert.executeUpdate(); + long start = ts - 1000 * 60 * 60; + long end = ts + 1000 * 60 * 60; pstmt_select.setTimestamp(1, new Timestamp(start)); pstmt_select.setTimestamp(2, new Timestamp(end)); pstmt_select.setInt(3, 0); + // when ResultSet rs = pstmt_select.executeQuery(); - Assert.assertNotNull(rs); ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); + rs.next(); + + // then + assertMetaData(meta); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(2, rs.getInt(2)); + Assert.assertEquals(2, rs.getInt("f1")); + Assert.assertEquals(3l, rs.getLong(3)); + Assert.assertEquals(3l, rs.getLong("f2")); + Assert.assertEquals(3.14f, rs.getFloat(4), 0.0); + Assert.assertEquals(3.14f, rs.getFloat("f3"), 0.0); + Assert.assertEquals(3.1415, rs.getDouble(5), 0.0); + Assert.assertEquals(3.1415, rs.getDouble("f4"), 0.0); + Assert.assertEquals((short) 6, rs.getShort(6)); + Assert.assertEquals((short) 6, rs.getShort("f5")); + Assert.assertEquals((byte) 7, rs.getByte(7)); + Assert.assertEquals((byte) 7, rs.getByte("f6")); + Assert.assertTrue(rs.getBoolean(8)); + Assert.assertTrue(rs.getBoolean("f7")); + Assert.assertArrayEquals("abc".getBytes(), rs.getBytes(9)); + Assert.assertArrayEquals("abc".getBytes(), rs.getBytes("f8")); + Assert.assertEquals("涛思数据", rs.getString(10)); + Assert.assertEquals("涛思数据", rs.getString("f9")); + } + } + + private void assertMetaData(ResultSetMetaData meta) throws SQLException { + Assert.assertEquals(10, meta.getColumnCount()); + Assert.assertEquals("ts", meta.getColumnLabel(1)); + Assert.assertEquals("f1", meta.getColumnLabel(2)); + Assert.assertEquals("f2", meta.getColumnLabel(3)); + Assert.assertEquals("f3", meta.getColumnLabel(4)); + Assert.assertEquals("f4", meta.getColumnLabel(5)); + Assert.assertEquals("f5", meta.getColumnLabel(6)); + Assert.assertEquals("f6", meta.getColumnLabel(7)); + Assert.assertEquals("f7", meta.getColumnLabel(8)); + Assert.assertEquals("f8", meta.getColumnLabel(9)); + Assert.assertEquals("f9", meta.getColumnLabel(10)); + } + + @Test + public void setNullForTimestamp() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setNull(2, Types.INTEGER); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } + + private void assertAllNullExceptTimestamp(ResultSet rs, long ts) throws SQLException { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(0, rs.getInt(2)); + Assert.assertEquals(0, rs.getInt("f1")); + Assert.assertEquals(0, rs.getLong(3)); + Assert.assertEquals(0, rs.getLong("f2")); + Assert.assertEquals(0, rs.getFloat(4), 0.0); + Assert.assertEquals(0, rs.getFloat("f3"), 0.0); + Assert.assertEquals(0, rs.getDouble(5), 0.0); + Assert.assertEquals(0, rs.getDouble("f4"), 0.0); + Assert.assertEquals(0, rs.getShort(6)); + Assert.assertEquals(0, rs.getShort("f5")); + Assert.assertEquals(0, rs.getByte(7)); + Assert.assertEquals(0, rs.getByte("f6")); + Assert.assertFalse(rs.getBoolean(8)); + Assert.assertFalse(rs.getBoolean("f7")); + Assert.assertNull(rs.getBytes(9)); + Assert.assertNull(rs.getBytes("f8")); + Assert.assertNull(rs.getString(10)); + Assert.assertNull(rs.getString("f9")); + } + + @Test + public void setNullForInteger() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setNull(3, Types.BIGINT); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); } } @Test - public void executeUpdate() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setFloat(4, 3.14f); + public void setNullForFloat() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setNull(4, Types.FLOAT); int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } } @Test - public void setNull() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(2, Types.INTEGER); - int result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); + public void setNullForDouble() throws SQLException { + // given + long ts = System.currentTimeMillis(); - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(3, Types.BIGINT); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(4, Types.FLOAT); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(5, Types.DOUBLE); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); + int result = pstmt_insert.executeUpdate(); - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(6, Types.SMALLINT); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(7, Types.TINYINT); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(8, Types.BOOLEAN); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(9, Types.BINARY); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(10, Types.NCHAR); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(10, Types.OTHER); - result = pstmt_insert.executeUpdate(); + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } } + @Test + public void setNullForSmallInt() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setNull(6, Types.SMALLINT); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } + + @Test + public void setNullForTinyInt() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setNull(7, Types.TINYINT); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } + + @Test + public void setNullForBoolean() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setNull(8, Types.BOOLEAN); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } + + @Test + public void setNullForBinary() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setNull(9, Types.BINARY); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } + + @Test + public void setNullForNchar() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setNull(10, Types.NCHAR); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } + @Test public void setBoolean() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setBoolean(8, true); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertTrue(rs.getBoolean(8)); + Assert.assertTrue(rs.getBoolean("f7")); + } + } } @Test public void setByte() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setByte(7, (byte) 0x001); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals((byte) 0x001, rs.getByte(7)); + Assert.assertEquals((byte) 0x001, rs.getByte("f6")); + } + } } @Test public void setShort() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setShort(6, (short) 2); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals((short) 2, rs.getByte(6)); + Assert.assertEquals((short) 2, rs.getByte("f5")); + } + } } @Test public void setInt() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setInt(2, 10086); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(10086, rs.getInt(2)); + Assert.assertEquals(10086, rs.getInt("f1")); + } + } } @Test public void setLong() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setLong(3, Long.MAX_VALUE); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(Long.MAX_VALUE, rs.getLong(3)); + Assert.assertEquals(Long.MAX_VALUE, rs.getLong("f2")); + } + } } @Test public void setFloat() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setFloat(4, 3.14f); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(3.14f, rs.getFloat(4), 0.0f); + Assert.assertEquals(3.14f, rs.getFloat("f3"), 0.0f); + } + } } @Test public void setDouble() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setDouble(5, 3.14444); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(3.14444, rs.getDouble(5), 0.0); + Assert.assertEquals(3.14444, rs.getDouble("f4"), 0.0); + } + } } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void setBigDecimal() throws SQLException { - pstmt_insert.setBigDecimal(1, null); + // given + long ts = System.currentTimeMillis(); + BigDecimal bigDecimal = new BigDecimal(3.14444); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setBigDecimal(5, bigDecimal); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(3.14444, rs.getDouble(5), 0.0); + Assert.assertEquals(3.14444, rs.getDouble("f4"), 0.0); + } + } } @Test public void setString() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setString(10, "aaaa"); - boolean execute = pstmt_insert.execute(); - Assert.assertFalse(execute); + // given + long ts = System.currentTimeMillis(); + String f9 = "{\"name\": \"john\", \"age\": 10, \"address\": \"192.168.1.100\"}"; - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setString(10, new Person("john", 33, true).toString()); - Assert.assertFalse(pstmt_insert.execute()); + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setString(10, f9); + int result = pstmt_insert.executeUpdate(); - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setString(10, new Person("john", 33, true).toString().replaceAll("'", "\"")); - Assert.assertFalse(pstmt_insert.execute()); - } - - class Person { - String name; - int age; - boolean sex; - - public Person(String name, int age, boolean sex) { - this.name = name; - this.age = age; - this.sex = sex; - } - - @Override - public String toString() { - return "Person{" + - "name='" + name + '\'' + - ", age=" + age + - ", sex=" + sex + - '}'; + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(f9, rs.getString(10)); + Assert.assertEquals(f9, rs.getString("f9")); + } } } @Test public void setBytes() throws SQLException, IOException { + // given + long ts = System.currentTimeMillis(); + byte[] f8 = "{\"name\": \"john\", \"age\": 10, \"address\": \"192.168.1.100\"}".getBytes(); + + // when pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + pstmt_insert.setBytes(9, f8); + int result = pstmt_insert.executeUpdate(); -// ByteArrayOutputStream baos = new ByteArrayOutputStream(); -// ObjectOutputStream oos = new ObjectOutputStream(baos); -// oos.writeObject(new Person("john", 33, true)); -// oos.flush(); -// byte[] bytes = baos.toByteArray(); -// pstmt_insert.setBytes(9, bytes); - - pstmt_insert.setBytes(9, new Person("john", 33, true).toString().getBytes()); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertArrayEquals(f8, rs.getBytes(9)); + Assert.assertArrayEquals(f8, rs.getBytes("f8")); + } + } } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void setDate() throws SQLException { - pstmt_insert.setDate(1, new Date(System.currentTimeMillis())); + // given + long ts = new java.util.Date().getTime(); + + // when + pstmt_insert.setDate(1, new Date(ts)); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + } + } } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void setTime() throws SQLException { - pstmt_insert.setTime(1, new Time(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTime(1, new Time(ts)); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + } + } } @Test public void setTimestamp() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + } + } } @Test(expected = SQLFeatureNotSupportedException.class) @@ -238,72 +652,6 @@ public class TSDBPreparedStatementTest { pstmt_insert.setBinaryStream(1, null); } - @Test - public void clearParameters() throws SQLException { - pstmt_insert.clearParameters(); - } - - @Test - public void setObject() throws SQLException { - pstmt_insert.setObject(1, new Timestamp(System.currentTimeMillis())); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(2, 111); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(3, Long.MAX_VALUE); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(4, 3.14159265354f); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(5, Double.MAX_VALUE); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(6, Short.MAX_VALUE); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(7, Byte.MAX_VALUE); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(8, true); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(9, "hello".getBytes()); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(10, "Hello"); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - } - - @Test - public void execute() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - executeQuery(); - } - @Test(expected = SQLFeatureNotSupportedException.class) public void setCharacterStream() throws SQLException { pstmt_insert.setCharacterStream(1, null); @@ -329,9 +677,17 @@ public class TSDBPreparedStatementTest { pstmt_insert.setArray(1, null); } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void getMetaData() throws SQLException { - pstmt_insert.getMetaData(); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + ResultSetMetaData metaData = pstmt_insert.getMetaData(); + + // then + Assert.assertNull(metaData); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -341,9 +697,46 @@ public class TSDBPreparedStatementTest { @Test public void getParameterMetaData() throws SQLException { + // given + long ts = System.currentTimeMillis(); + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setInt(2, 2); + pstmt_insert.setLong(3, 3l); + pstmt_insert.setFloat(4, 3.14f); + pstmt_insert.setDouble(5, 3.1415); + pstmt_insert.setShort(6, (short) 6); + pstmt_insert.setByte(7, (byte) 7); + pstmt_insert.setBoolean(8, true); + pstmt_insert.setBytes(9, "abc".getBytes()); + pstmt_insert.setString(10, "涛思数据"); + + // when ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData(); + + // then Assert.assertNotNull(parameterMetaData); - //TODO: modify the test case + Assert.assertEquals(10, parameterMetaData.getParameterCount()); + Assert.assertEquals(Types.TIMESTAMP, parameterMetaData.getParameterType(1)); + Assert.assertEquals(Types.INTEGER, parameterMetaData.getParameterType(2)); + Assert.assertEquals(Types.BIGINT, parameterMetaData.getParameterType(3)); + Assert.assertEquals(Types.FLOAT, parameterMetaData.getParameterType(4)); + Assert.assertEquals(Types.DOUBLE, parameterMetaData.getParameterType(5)); + Assert.assertEquals(Types.SMALLINT, parameterMetaData.getParameterType(6)); + Assert.assertEquals(Types.TINYINT, parameterMetaData.getParameterType(7)); + Assert.assertEquals(Types.BOOLEAN, parameterMetaData.getParameterType(8)); + Assert.assertEquals(Types.BINARY, parameterMetaData.getParameterType(9)); + Assert.assertEquals(Types.NCHAR, parameterMetaData.getParameterType(10)); + + Assert.assertEquals("TIMESTAMP", parameterMetaData.getParameterTypeName(1)); + Assert.assertEquals("INT", parameterMetaData.getParameterTypeName(2)); + Assert.assertEquals("BIGINT", parameterMetaData.getParameterTypeName(3)); + Assert.assertEquals("FLOAT", parameterMetaData.getParameterTypeName(4)); + Assert.assertEquals("DOUBLE", parameterMetaData.getParameterTypeName(5)); + Assert.assertEquals("SMALLINT", parameterMetaData.getParameterTypeName(6)); + Assert.assertEquals("TINYINT", parameterMetaData.getParameterTypeName(7)); + Assert.assertEquals("BOOL", parameterMetaData.getParameterTypeName(8)); + Assert.assertEquals("BINARY", parameterMetaData.getParameterTypeName(9)); + Assert.assertEquals("NCHAR", parameterMetaData.getParameterTypeName(10)); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -351,9 +744,9 @@ public class TSDBPreparedStatementTest { pstmt_insert.setRowId(1, null); } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void setNString() throws SQLException { - pstmt_insert.setNString(1, null); + setString(); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -371,22 +764,45 @@ public class TSDBPreparedStatementTest { pstmt_insert.setSQLXML(1, null); } + @Before + public void before() { + try { + Statement stmt = conn.createStatement(); + stmt.execute("drop table if exists weather"); + stmt.execute("create table if not exists weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))"); + stmt.execute("create table if not exists t1 using weather tags('beijing')"); + stmt.close(); + + pstmt_insert = conn.prepareStatement(sql_insert); + pstmt_select = conn.prepareStatement(sql_select); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @After + public void after() { + try { + if (pstmt_insert != null) + pstmt_insert.close(); + if (pstmt_select != null) + pstmt_select.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + + } @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); try (Statement stmt = conn.createStatement()) { stmt.execute("drop database if exists test_pstmt_jni"); stmt.execute("create database if not exists test_pstmt_jni"); stmt.execute("use test_pstmt_jni"); - stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))"); - stmt.execute("create table t1 using weather tags('beijing')"); } - pstmt_insert = conn.prepareStatement(sql_insert); - pstmt_select = conn.prepareStatement(sql_select); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } @@ -394,10 +810,6 @@ public class TSDBPreparedStatementTest { @AfterClass public static void afterClass() { try { - if (pstmt_insert != null) - pstmt_insert.close(); - if (pstmt_select != null) - pstmt_select.close(); if (conn != null) conn.close(); } catch (SQLException e) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java index c5c6f7bca5..ec54a44b7c 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java @@ -3,7 +3,6 @@ package com.taosdata.jdbc; import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; -import com.taosdata.jdbc.rs.RestfulResultSet; import org.junit.AfterClass; import org.junit.Assert; import org.junit.BeforeClass; @@ -15,6 +14,7 @@ import java.math.BigDecimal; import java.sql.*; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Arrays; public class TSDBResultSetTest { @@ -134,7 +134,7 @@ public class TSDBResultSetTest { Assert.assertEquals(3.1415926, Double.valueOf(new String(f5)), 0.000000f); byte[] f6 = rs.getBytes("f6"); - Assert.assertEquals("abc", new String(f6)); + Assert.assertTrue(Arrays.equals("abc".getBytes(), f6)); byte[] f7 = rs.getBytes("f7"); Assert.assertEquals((short) 10, Shorts.fromByteArray(f7)); @@ -177,7 +177,8 @@ public class TSDBResultSetTest { rs.getAsciiStream("f1"); } - @Test(expected = SQLFeatureNotSupportedException.class) + @SuppressWarnings("deprecation") + @Test(expected = SQLFeatureNotSupportedException.class) public void getUnicodeStream() throws SQLException { rs.getUnicodeStream("f1"); } @@ -326,7 +327,7 @@ public class TSDBResultSetTest { @Test(expected = SQLFeatureNotSupportedException.class) public void getRow() throws SQLException { - int row = rs.getRow(); + rs.getRow(); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -405,12 +406,12 @@ public class TSDBResultSetTest { @Test(expected = SQLFeatureNotSupportedException.class) public void updateByte() throws SQLException { - rs.updateByte(1, new Byte("0")); + rs.updateByte(1, (byte) 0); } @Test(expected = SQLFeatureNotSupportedException.class) public void updateShort() throws SQLException { - rs.updateShort(1, new Short("0")); + rs.updateShort(1, (short) 0); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -646,7 +647,6 @@ public class TSDBResultSetTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); stmt = conn.createStatement(); stmt.execute("create database if not exists restful_test"); @@ -656,10 +656,9 @@ public class TSDBResultSetTest { stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')"); rs = stmt.executeQuery("select * from restful_test.weather"); rs.next(); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } - } @AfterClass diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java index 671551c426..51535bc886 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java @@ -387,15 +387,12 @@ public class TSDBStatementTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties); stmt = conn.createStatement(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java index a3c46dc232..4b4e83719f 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java @@ -345,6 +345,7 @@ public class InsertSpecialCharacterJniTest { } } + @Test public void testCase12() throws SQLException { final long now = System.currentTimeMillis(); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java index a052fbbdcb..85007db0e5 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java @@ -10,6 +10,7 @@ import java.sql.*; import java.util.Properties; public class RestfulDatabaseMetaDataTest { + private static final String host = "127.0.0.1"; private static final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; private static Connection connection; @@ -632,17 +633,32 @@ public class RestfulDatabaseMetaDataTest { @Test public void getTables() throws SQLException { - System.out.println("****************************************************"); - ResultSet tables = metaData.getTables("log", "", null, null); - ResultSetMetaData metaData = tables.getMetaData(); - while (tables.next()) { - System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t"); - System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t"); - System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t"); - System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n"); + ResultSet rs = metaData.getTables("log", "", null, null); + ResultSetMetaData meta = rs.getMetaData(); + Assert.assertNotNull(rs); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_SCHEM + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertNotNull(rs.getString(3)); + Assert.assertNotNull(rs.getString("TABLE_NAME")); + // TABLE_TYPE + Assert.assertEquals("TABLE_TYPE", meta.getColumnLabel(4)); + Assert.assertEquals("TABLE", rs.getString(4)); + Assert.assertEquals("TABLE", rs.getString("TABLE_TYPE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(5)); + Assert.assertEquals("", rs.getString(5)); + Assert.assertEquals("", rs.getString("REMARKS")); } - System.out.println(); - Assert.assertNotNull(tables); } @Test @@ -652,46 +668,130 @@ public class RestfulDatabaseMetaDataTest { @Test public void getCatalogs() throws SQLException { - System.out.println("****************************************************"); - - ResultSet catalogs = metaData.getCatalogs(); - ResultSetMetaData meta = catalogs.getMetaData(); - while (catalogs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i)); - } - System.out.println(); + ResultSet rs = metaData.getCatalogs(); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertNotNull(rs.getString(1)); + Assert.assertNotNull(rs.getString("TABLE_CAT")); } } @Test public void getTableTypes() throws SQLException { - System.out.println("****************************************************"); - ResultSet tableTypes = metaData.getTableTypes(); - while (tableTypes.next()) { - System.out.println(tableTypes.getString("TABLE_TYPE")); + tableTypes.next(); + // tableTypes: table + { + Assert.assertEquals("TABLE", tableTypes.getString(1)); + Assert.assertEquals("TABLE", tableTypes.getString("TABLE_TYPE")); + } + tableTypes.next(); + // tableTypes: stable + { + Assert.assertEquals("STABLE", tableTypes.getString(1)); + Assert.assertEquals("STABLE", tableTypes.getString("TABLE_TYPE")); } - Assert.assertNotNull(metaData.getTableTypes()); } @Test public void getColumns() throws SQLException { - System.out.println("****************************************************"); - + // when ResultSet columns = metaData.getColumns("log", "", "dn", ""); + // then ResultSetMetaData meta = columns.getMetaData(); - while (columns.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t"); - System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t"); - System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t"); - System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t"); - System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t"); - System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n"); - System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n"); + columns.next(); + // column: 1 + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", columns.getString(1)); + Assert.assertEquals("log", columns.getString("TABLE_CAT")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn", columns.getString(3)); + Assert.assertEquals("dn", columns.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("ts", columns.getString(4)); + Assert.assertEquals("ts", columns.getString("COLUMN_NAME")); + // DATA_TYPE + Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5)); + Assert.assertEquals(Types.TIMESTAMP, columns.getInt(5)); + Assert.assertEquals(Types.TIMESTAMP, columns.getInt("DATA_TYPE")); + // TYPE_NAME + Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("TIMESTAMP", columns.getString(6)); + Assert.assertEquals("TIMESTAMP", columns.getString("TYPE_NAME")); + // COLUMN_SIZE + Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7)); + Assert.assertEquals(26, columns.getInt(7)); + Assert.assertEquals(26, columns.getInt("COLUMN_SIZE")); + // DECIMAL_DIGITS + Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS")); + Assert.assertEquals(null, columns.getString(9)); + Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS")); + // NUM_PREC_RADIX + Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10)); + Assert.assertEquals(10, columns.getInt(10)); + Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX")); + // NULLABLE + Assert.assertEquals("NULLABLE", meta.getColumnLabel(11)); + Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt(11)); + Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt("NULLABLE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(12)); + Assert.assertEquals(null, columns.getString(12)); + Assert.assertEquals(null, columns.getString("REMARKS")); + } + columns.next(); + // column: 2 + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", columns.getString(1)); + Assert.assertEquals("log", columns.getString("TABLE_CAT")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn", columns.getString(3)); + Assert.assertEquals("dn", columns.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("cpu_taosd", columns.getString(4)); + Assert.assertEquals("cpu_taosd", columns.getString("COLUMN_NAME")); + // DATA_TYPE + Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5)); + Assert.assertEquals(Types.FLOAT, columns.getInt(5)); + Assert.assertEquals(Types.FLOAT, columns.getInt("DATA_TYPE")); + // TYPE_NAME + Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("FLOAT", columns.getString(6)); + Assert.assertEquals("FLOAT", columns.getString("TYPE_NAME")); + // COLUMN_SIZE + Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7)); + Assert.assertEquals(12, columns.getInt(7)); + Assert.assertEquals(12, columns.getInt("COLUMN_SIZE")); + // DECIMAL_DIGITS + Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS")); + Assert.assertEquals(null, columns.getString(9)); + Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS")); + // NUM_PREC_RADIX + Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10)); + Assert.assertEquals(10, columns.getInt(10)); + Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX")); + // NULLABLE + Assert.assertEquals("NULLABLE", meta.getColumnLabel(11)); + Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt(11)); + Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt("NULLABLE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(12)); + Assert.assertEquals(null, columns.getString(12)); } } @@ -717,17 +817,35 @@ public class RestfulDatabaseMetaDataTest { @Test public void getPrimaryKeys() throws SQLException { - System.out.println("****************************************************"); - ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1"); - while (rs.next()) { - System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); - System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME")); - System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ")); - System.out.println("PK_NAME: " + rs.getString("PK_NAME")); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_SCHEM + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn1", rs.getString(3)); + Assert.assertEquals("dn1", rs.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("ts", rs.getString(4)); + Assert.assertEquals("ts", rs.getString("COLUMN_NAME")); + // KEY_SEQ + Assert.assertEquals("KEY_SEQ", meta.getColumnLabel(5)); + Assert.assertEquals(1, rs.getShort(5)); + Assert.assertEquals(1, rs.getShort("KEY_SEQ")); + // DATA_TYPE + Assert.assertEquals("PK_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("ts", rs.getString(6)); + Assert.assertEquals("ts", rs.getString("PK_NAME")); } - - Assert.assertNotNull(rs); } @Test @@ -852,14 +970,27 @@ public class RestfulDatabaseMetaDataTest { @Test public void getSuperTables() throws SQLException { - System.out.println("****************************************************"); - ResultSet rs = metaData.getSuperTables("log", "", "dn1"); - while (rs.next()) { - System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); - System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME")); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_CAT + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_CAT + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn1", rs.getString(3)); + Assert.assertEquals("dn1", rs.getString("TABLE_NAME")); + // TABLE_CAT + Assert.assertEquals("SUPERTABLE_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("dn", rs.getString(4)); + Assert.assertEquals("dn", rs.getString("SUPERTABLE_NAME")); } - Assert.assertNotNull(rs); } @Test diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java index 8bb2532ce8..81d7f5b56c 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java @@ -54,16 +54,17 @@ public class RestfulParameterMetaDataTest { @Test public void getPrecision() throws SQLException { - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); - Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); - Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); + //create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) + Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1)); + Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2)); + Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3)); + Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4)); + Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5)); + Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6)); + Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7)); + Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8)); + Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9)); + Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10)); } @Test @@ -71,8 +72,8 @@ public class RestfulParameterMetaDataTest { Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); - Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); - Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); + Assert.assertEquals(31, parameterMetaData_insert.getScale(4)); + Assert.assertEquals(31, parameterMetaData_insert.getScale(5)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); @@ -164,7 +165,7 @@ public class RestfulParameterMetaDataTest { pstmt_insert.setObject(7, Byte.MAX_VALUE); pstmt_insert.setObject(8, true); pstmt_insert.setObject(9, "hello".getBytes()); - pstmt_insert.setObject(10, "Hello"); + pstmt_insert.setObject(10, "涛思数据"); parameterMetaData_insert = pstmt_insert.getParameterMetaData(); pstmt_select = conn.prepareStatement(sql_select); diff --git a/src/connector/python/taos/cinterface.py b/src/connector/python/taos/cinterface.py index b8824327b0..0f690aeb27 100644 --- a/src/connector/python/taos/cinterface.py +++ b/src/connector/python/taos/cinterface.py @@ -242,7 +242,7 @@ def _load_taos_linux(): def _load_taos_darwin(): - return ctypes.cDLL('libtaos.dylib') + return ctypes.CDLL('libtaos.dylib') def _load_taos_windows(): diff --git a/src/cq/src/cqMain.c b/src/cq/src/cqMain.c index ee4be02b90..f539e77253 100644 --- a/src/cq/src/cqMain.c +++ b/src/cq/src/cqMain.c @@ -38,21 +38,6 @@ #define cDebug(...) { if (cqDebugFlag & DEBUG_DEBUG) { taosPrintLog("CQ ", cqDebugFlag, __VA_ARGS__); }} #define cTrace(...) { if (cqDebugFlag & DEBUG_TRACE) { taosPrintLog("CQ ", cqDebugFlag, __VA_ARGS__); }} -typedef struct { - int32_t vgId; - int32_t master; - int32_t num; // number of continuous streams - char user[TSDB_USER_LEN]; - char pass[TSDB_KEY_LEN]; - char db[TSDB_DB_NAME_LEN]; - FCqWrite cqWrite; - struct SCqObj *pHead; - void *dbConn; - void *tmrCtrl; - pthread_mutex_t mutex; - int32_t delete; - int32_t cqObjNum; -} SCqContext; typedef struct SCqObj { tmr_h tmrId; @@ -439,7 +424,7 @@ static void cqProcessCreateTimer(void *param, void *tmrId) { // inner implement in tscStream.c TAOS_STREAM *taos_open_stream_withname(TAOS *taos, const char* desName, const char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), - int64_t stime, void *param, void (*callback)(void *)); + int64_t stime, void *param, void (*callback)(void *), void* cqhandle); static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) { pObj->pContext = pContext; @@ -453,7 +438,8 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) { pObj->tmrId = 0; if (pObj->pStream == NULL) { - pObj->pStream = taos_open_stream_withname(pContext->dbConn, pObj->dstTable, pObj->sqlStr, cqProcessStreamRes, INT64_MIN, (void *)pObj->rid, NULL); + pObj->pStream = taos_open_stream_withname(pContext->dbConn, pObj->dstTable, pObj->sqlStr, cqProcessStreamRes, \ + INT64_MIN, (void *)pObj->rid, NULL, pContext); // TODO the pObj->pStream may be released if error happens if (pObj->pStream) { diff --git a/src/inc/tcq.h b/src/inc/tcq.h index 552a40665a..7549c3d498 100644 --- a/src/inc/tcq.h +++ b/src/inc/tcq.h @@ -31,6 +31,23 @@ typedef struct { FCqWrite cqWrite; } SCqCfg; +// SCqContext +typedef struct { + int32_t vgId; + int32_t master; + int32_t num; // number of continuous streams + char user[TSDB_USER_LEN]; + char pass[TSDB_KEY_LEN]; + char db[TSDB_DB_NAME_LEN]; + FCqWrite cqWrite; + struct SCqObj *pHead; + void *dbConn; + void *tmrCtrl; + pthread_mutex_t mutex; + int32_t delete; + int32_t cqObjNum; +} SCqContext; + // the following API shall be called by vnode void *cqOpen(void *ahandle, const SCqCfg *pCfg); void cqClose(void *handle); diff --git a/src/kit/taosdemo/taosdemo.c b/src/kit/taosdemo/taosdemo.c index dcfed8bc2a..4202a833ea 100644 --- a/src/kit/taosdemo/taosdemo.c +++ b/src/kit/taosdemo/taosdemo.c @@ -625,6 +625,10 @@ static int64_t g_totalChildTables = 0; static SQueryMetaInfo g_queryInfo; static FILE * g_fpOfInsertResult = NULL; +#if _MSC_VER <= 1900 +#define __func__ __FUNCTION__ +#endif + #define debugPrint(fmt, ...) \ do { if (g_args.debug_print || g_args.verbose_print) \ fprintf(stderr, "DEBG: "fmt, __VA_ARGS__); } while(0) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index 67e0c2642e..2956dd29ad 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -43,7 +43,7 @@ */ int64_t user_mktime64(const unsigned int year0, const unsigned int mon0, const unsigned int day, const unsigned int hour, - const unsigned int min, const unsigned int sec, int64_t timezone) + const unsigned int min, const unsigned int sec, int64_t time_zone) { unsigned int mon = mon0, year = year0; @@ -61,7 +61,7 @@ int64_t user_mktime64(const unsigned int year0, const unsigned int mon0, res = res*24; res = ((res + hour) * 60 + min) * 60 + sec; - return (res + timezone); + return (res + time_zone); } // ==== mktime() kernel code =================// diff --git a/src/util/inc/tutil.h b/src/util/inc/tutil.h index fe5c038c51..7c8fd2ed83 100644 --- a/src/util/inc/tutil.h +++ b/src/util/inc/tutil.h @@ -26,6 +26,7 @@ extern "C" { #include "taosdef.h" int32_t strdequote(char *src); +int32_t strRmquote(char *z, int32_t len); size_t strtrim(char *src); char * strnchr(char *haystack, char needle, int32_t len, bool skipquote); char ** strsplit(char *src, const char *delim, int32_t *num); diff --git a/src/util/src/tutil.c b/src/util/src/tutil.c index 451976f563..bda52936f9 100644 --- a/src/util/src/tutil.c +++ b/src/util/src/tutil.c @@ -52,6 +52,36 @@ int32_t strdequote(char *z) { return j + 1; // only one quote, do nothing } + +int32_t strRmquote(char *z, int32_t len){ + // delete escape character: \\, \', \" + char delim = z[0]; + if (delim != '\'' && delim != '\"') { + return len; + } + + int32_t cnt = 0; + int32_t j = 0; + for (uint32_t k = 1; k < len - 1; ++k) { + if (z[k] == '\\' || (z[k] == delim && z[k + 1] == delim)) { + z[j] = z[k + 1]; + + cnt++; + j++; + k++; + continue; + } + + z[j] = z[k]; + j++; + } + + z[j] = 0; + + return len - 2 - cnt; +} + + size_t strtrim(char *z) { int32_t i = 0; int32_t j = 0; diff --git a/tests/mas/Jenkinsfile b/tests/mas/Jenkinsfile index 0e6e94a037..ae2286298f 100644 --- a/tests/mas/Jenkinsfile +++ b/tests/mas/Jenkinsfile @@ -21,7 +21,7 @@ def pre_test(){ cmake .. > /dev/null make > /dev/null make install > /dev/null - pip3 install ${WKC}/src/connector/python/linux/python3/ + pip3 install ${WKC}/src/connector/python/ || echo 0 ''' return 1 } diff --git a/tests/pytest/cluster/clusterSetup.py b/tests/pytest/cluster/clusterSetup.py index 8a26427021..87414303f8 100644 --- a/tests/pytest/cluster/clusterSetup.py +++ b/tests/pytest/cluster/clusterSetup.py @@ -23,7 +23,8 @@ class Node: self.hostIP = hostIP self.hostName = hostName self.homeDir = homeDir - self.conn = Connection("{}@{}".format(username, hostName), connect_kwargs={"password": "{}".format(password)}) + self.corePath = '/coredump' + self.conn = Connection("{}@{}".format(username, hostName), connect_kwargs={"password": "{}".format(password)}) def buildTaosd(self): try: @@ -126,21 +127,37 @@ class Node: except Exception as e: print("remove taosd error for node %d " % self.index) logging.exception(e) + + + def detectCoredumpFile(self): + try: + result = self.conn.run("find /coredump -name 'core_*' ", hide=True) + output = result.stdout + print("output: %s" % output) + return output + except Exception as e: + print("find coredump file error on node %d " % self.index) + logging.exception(e) + class Nodes: def __init__(self): self.tdnodes = [] - self.tdnodes.append(Node(0, 'root', '52.143.103.7', 'node1', 'a', '/root/')) - self.tdnodes.append(Node(1, 'root', '52.250.48.222', 'node2', 'a', '/root/')) - self.tdnodes.append(Node(2, 'root', '51.141.167.23', 'node3', 'a', '/root/')) - self.tdnodes.append(Node(3, 'root', '52.247.207.173', 'node4', 'a', '/root/')) - self.tdnodes.append(Node(4, 'root', '51.141.166.100', 'node5', 'a', '/root/')) + self.tdnodes.append(Node(0, 'root', '192.168.17.194', 'taosdata', 'r', '/root/')) + # self.tdnodes.append(Node(1, 'root', '52.250.48.222', 'node2', 'a', '/root/')) + # self.tdnodes.append(Node(2, 'root', '51.141.167.23', 'node3', 'a', '/root/')) + # self.tdnodes.append(Node(3, 'root', '52.247.207.173', 'node4', 'a', '/root/')) + # self.tdnodes.append(Node(4, 'root', '51.141.166.100', 'node5', 'a', '/root/')) def stopOneNode(self, index): + self.tdnodes[index].stopTaosd() self.tdnodes[index].forceStopOneTaosd() def startOneNode(self, index): self.tdnodes[index].startOneTaosd() + + def detectCoredumpFile(self, index): + return self.tdnodes[index].detectCoredumpFile() def stopAllTaosd(self): for i in range(len(self.tdnodes)): @@ -166,14 +183,32 @@ class Nodes: for i in range(len(self.tdnodes)): self.tdnodes[i].removeData() -# kill taosd randomly every 10 mins -nodes = Nodes() -loop = 0 -while True: - loop = loop + 1 - index = random.randint(0, 4) - print("loop: %d, kill taosd on node%d" %(loop, index)) - nodes.stopOneNode(index) - time.sleep(60) - nodes.startOneNode(index) - time.sleep(600) \ No newline at end of file +class Test: + def __init__(self): + self.nodes = Nodes() + + # kill taosd randomly every 10 mins + def randomlyKillDnode(self): + loop = 0 + while True: + index = random.randint(0, 4) + print("loop: %d, kill taosd on node%d" %(loop, index)) + self.nodes.stopOneNode(index) + time.sleep(60) + self.nodes.startOneNode(index) + time.sleep(600) + loop = loop + 1 + + def detectCoredump(self): + loop = 0 + while True: + for i in range(len(self.nodes.tdnodes)): + result = self.nodes.detectCoredumpFile(i) + print("core file path is %s" % result) + if result and not result.isspace(): + self.nodes.stopAllTaosd() + print("sleep for 10 mins") + time.sleep(600) + +test = Test() +test.detectCoredump() \ No newline at end of file diff --git a/tests/pytest/functions/showOfflineThresholdIs864000.py b/tests/pytest/functions/showOfflineThresholdIs864000.py index 6cce869bf2..a7a1c2bf3f 100644 --- a/tests/pytest/functions/showOfflineThresholdIs864000.py +++ b/tests/pytest/functions/showOfflineThresholdIs864000.py @@ -25,7 +25,7 @@ class TDTestCase: def run(self): tdSql.query("show variables") - tdSql.checkData(51, 1, 864000) + tdSql.checkData(53, 1, 864000) def stop(self): tdSql.close() @@ -33,4 +33,4 @@ class TDTestCase: tdCases.addWindows(__file__, TDTestCase()) -tdCases.addLinux(__file__, TDTestCase()) \ No newline at end of file +tdCases.addLinux(__file__, TDTestCase())