Merge branch 'master' of github.com:taosdata/TDengine into test/chr

This commit is contained in:
tomchon 2021-06-09 13:29:43 +08:00
commit 6f6a02f8c2
44 changed files with 2925 additions and 2086 deletions

View File

@ -117,10 +117,14 @@ IF (TD_LINUX)
ADD_DEFINITIONS(-D_TD_NINGSI_60) ADD_DEFINITIONS(-D_TD_NINGSI_60)
MESSAGE(STATUS "set ningsi macro to true") MESSAGE(STATUS "set ningsi macro to true")
ENDIF () 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") SET(RELEASE_FLAGS "-O3 -Wno-error")
IF (${COVER} MATCHES "true") IF (${COVER} MATCHES "true")
MESSAGE(STATUS "Test coverage mode, add extra flags") MESSAGE(STATUS "Test coverage mode, add extra flags")
SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage") SET(GCC_COVERAGE_COMPILE_FLAGS "-fprofile-arcs -ftest-coverage")
@ -139,7 +143,11 @@ IF (TD_DARWIN_64)
ADD_DEFINITIONS(-DUSE_LIBICONV) ADD_DEFINITIONS(-DUSE_LIBICONV)
MESSAGE(STATUS "darwin64 is defined") 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(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") SET(RELEASE_FLAGS "-Og")
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/cJson/inc)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lz4/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/lz4/inc)
@ -157,7 +165,11 @@ IF (TD_WINDOWS)
IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900)) IF (MSVC AND (MSVC_VERSION GREATER_EQUAL 1900))
SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18") SET(COMMON_FLAGS "${COMMON_FLAGS} /Wv:18")
ENDIF () 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") SET(RELEASE_FLAGS "/W0 /O3 /GL")
ENDIF () ENDIF ()
@ -166,7 +178,7 @@ IF (TD_WINDOWS)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/regex) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/regex)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/wepoll/inc) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/wepoll/inc)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/MsvcLibX/include) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/MsvcLibX/include)
ENDIF () ENDIF ()
IF (TD_WINDOWS_64) IF (TD_WINDOWS_64)
ADD_DEFINITIONS(-D_M_X64) ADD_DEFINITIONS(-D_M_X64)

View File

@ -78,3 +78,8 @@ SET(TD_BUILD_JDBC TRUE)
IF (${BUILD_JDBC} MATCHES "false") IF (${BUILD_JDBC} MATCHES "false")
SET(TD_BUILD_JDBC FALSE) SET(TD_BUILD_JDBC FALSE)
ENDIF () ENDIF ()
SET(TD_MEMORY_SANITIZER FALSE)
IF (${MEMORY_SANITIZER} MATCHES "true")
SET(TD_MEMORY_SANITIZER TRUE)
ENDIF ()

View File

@ -405,6 +405,7 @@ typedef struct SSqlObj {
typedef struct SSqlStream { typedef struct SSqlStream {
SSqlObj *pSql; SSqlObj *pSql;
void * cqhandle; // stream belong to SCQContext handle
const char* dstTable; const char* dstTable;
uint32_t streamId; uint32_t streamId;
char listed; char listed;

View File

@ -466,6 +466,10 @@ int tsParseOneRow(char **str, STableDataBlocks *pDataBlocks, SSqlCmd *pCmd, int1
int32_t cnt = 0; int32_t cnt = 0;
int32_t j = 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) { for (uint32_t k = 1; k < sToken.n - 1; ++k) {
if (sToken.z[k] == '\\' || (sToken.z[k] == delim && sToken.z[k + 1] == delim)) { if (sToken.z[k] == '\\' || (sToken.z[k] == delim && sToken.z[k + 1] == delim)) {
tmpTokenBuf[j] = sToken.z[k + 1]; 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; 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; int32_t numOfRows = 0;
code = tsParseValues(str, dataBuf, maxNumOfRows, pCmd, &numOfRows, tmpTokenBuf); code = tsParseValues(str, dataBuf, maxNumOfRows, pCmd, &numOfRows, tmpTokenBuf);

View File

@ -19,6 +19,7 @@
#include "ttimer.h" #include "ttimer.h"
#include "tutil.h" #include "tutil.h"
#include "taosmsg.h" #include "taosmsg.h"
#include "tcq.h"
#include "taos.h" #include "taos.h"
@ -294,24 +295,34 @@ int tscBuildQueryStreamDesc(void *pMsg, STscObj *pObj) {
return msgLen; 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) { void tscKillConnection(STscObj *pObj) {
// get stream header by locked
pthread_mutex_lock(&pObj->mutex); pthread_mutex_lock(&pObj->mutex);
SSqlObj *pSql = pObj->sqlList;
while (pSql) {
pSql = pSql->next;
}
SSqlStream *pStream = pObj->streamList; SSqlStream *pStream = pObj->streamList;
pthread_mutex_unlock(&pObj->mutex);
while (pStream) { while (pStream) {
SSqlStream *tmp = pStream->next; 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); taos_close_stream(pStream);
pStream = tmp; pStream = tmp;
} }
pthread_mutex_unlock(&pObj->mutex);
tscDebug("connection:%p is killed", pObj); tscDebug("connection:%p is killed", pObj);
taos_close(pObj); taos_close(pObj);
} }

View File

@ -314,7 +314,9 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) {
} }
} else if (pInfo->type == TSDB_SQL_DROP_DNODE) { } 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); strncpy(pCmd->payload, pzName->z, pzName->n);
} else { // drop user/account } else { // drop user/account
if (pzName->n >= TSDB_USER_LEN) { 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); SStrToken* id = taosArrayGet(pInfo->pMiscInfo->a, 0);
id->n = strdequote(id->z); if (id->type == TK_STRING) {
id->n = strdequote(id->z);
}
break; 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* msg7 = "normal table can not apply this function";
const char* msg8 = "multi-columns selection does not support alias column name"; 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* msg9 = "diff can no be applied to unsigned numeric type";
const char* msg10 = "parameter is out of range [1, 100]";
switch (functionId) { switch (functionId) {
case TSDB_FUNC_COUNT: { 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); int64_t nTop = GET_INT32_VAL(val);
if (nTop <= 0 || nTop > 100) { // todo use macro if (nTop <= 0 || nTop > 100) { // todo use macro
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg5); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg10);
} }
// todo REFACTOR // todo REFACTOR
@ -6674,7 +6679,8 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
const char* msg5 = "sql too long"; // todo ADD support const char* msg5 = "sql too long"; // todo ADD support
const char* msg6 = "from missing in subclause"; const char* msg6 = "from missing in subclause";
const char* msg7 = "time interval is required"; const char* msg7 = "time interval is required";
const char* msg8 = "the first column should be primary timestamp column";
SSqlCmd* pCmd = &pSql->cmd; SSqlCmd* pCmd = &pSql->cmd;
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0); SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, 0);
assert(pQueryInfo->numOfTables == 1); assert(pQueryInfo->numOfTables == 1);
@ -6731,8 +6737,26 @@ int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo) {
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
} }
if (!tscIsProjectionQuery(pQueryInfo) && pQueryInfo->interval.interval == 0) { // project query primary column must be timestamp type
return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg7); 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 // set the created table[stream] name

View File

@ -141,6 +141,10 @@ static void tscProcessStreamTimer(void *handle, void *tmrId) {
pStream->numOfRes = 0; // reset the numOfRes. pStream->numOfRes = 0; // reset the numOfRes.
SSqlObj *pSql = pStream->pSql; SSqlObj *pSql = pStream->pSql;
// pSql == NULL maybe killStream already called
if(pSql == NULL) {
return ;
}
SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0);
tscDebug("0x%"PRIx64" add into timer", pSql->self); 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) { if (pStream->isProject) {
int64_t now = taosGetTimestamp(pStream->precision); int64_t now = taosGetTimestamp(pStream->precision);
int64_t etime = now > pStream->etime ? pStream->etime : now; int64_t etime = now > pStream->etime ? pStream->etime : now;
int64_t maxRetent = tsMaxRetentWindow * 1000;
if (pStream->etime < now && now - pStream->etime > tsMaxRetentWindow) { 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 * 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), 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; STscObj *pObj = (STscObj *)taos;
if (pObj == NULL || pObj->signature != pObj) return NULL; 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->callback = callback;
pStream->param = param; pStream->param = param;
pStream->pSql = pSql; pStream->pSql = pSql;
pStream->cqhandle = cqhandle;
pSql->pStream = pStream; pSql->pStream = pStream;
pSql->param = pStream; pSql->param = pStream;
pSql->maxRetry = TSDB_MAX_REPLICA; 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), 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 *)) { 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) { void taos_close_stream(TAOS_STREAM *handle) {

View File

@ -817,6 +817,16 @@ static void doInitGlobalConfig(void) {
cfg.unitType = TAOS_CFG_UTYPE_NONE; cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg); 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.option = "comp";
cfg.ptr = &tsCompression; cfg.ptr = &tsCompression;
cfg.valType = TAOS_CFG_VTYPE_INT8; cfg.valType = TAOS_CFG_VTYPE_INT8;
@ -887,6 +897,16 @@ static void doInitGlobalConfig(void) {
cfg.unitType = TAOS_CFG_UTYPE_NONE; cfg.unitType = TAOS_CFG_UTYPE_NONE;
taosInitConfigOption(cfg); 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.option = "mqttHostName";
cfg.ptr = tsMqttHostName; cfg.ptr = tsMqttHostName;
cfg.valType = TAOS_CFG_VTYPE_STRING; cfg.valType = TAOS_CFG_VTYPE_STRING;

View File

@ -74,7 +74,7 @@ void tVariantCreate(tVariant *pVar, SStrToken *token) {
case TSDB_DATA_TYPE_BINARY: { case TSDB_DATA_TYPE_BINARY: {
pVar->pz = strndup(token->z, token->n); pVar->pz = strndup(token->z, token->n);
pVar->nLen = strdequote(pVar->pz); pVar->nLen = strRmquote(pVar->pz, token->n);
break; break;
} }

View File

@ -1,5 +1,7 @@
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.sun.org.apache.xpath.internal.operations.Bool;
import java.sql.ParameterMetaData; import java.sql.ParameterMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
@ -49,6 +51,22 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P
if (param < 1 && param >= parameters.length) if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); 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) if (parameters[param - 1] instanceof String)
return ((String) parameters[param - 1]).length(); return ((String) parameters[param - 1]).length();
if (parameters[param - 1] instanceof byte[]) 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 { public int getScale(int param) throws SQLException {
if (param < 1 && param >= parameters.length) if (param < 1 && param >= parameters.length)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); 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; return 0;
} }

View File

@ -66,10 +66,16 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
public abstract byte[] getBytes(int columnIndex) throws SQLException; public abstract byte[] getBytes(int columnIndex) throws SQLException;
@Override @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 @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 @Override
public abstract Timestamp getTimestamp(int columnIndex) throws SQLException; public abstract Timestamp getTimestamp(int columnIndex) throws SQLException;
@ -84,10 +90,12 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
} }
@Override @Override
@Deprecated
public InputStream getUnicodeStream(int columnIndex) throws SQLException { public InputStream getUnicodeStream(int columnIndex) throws SQLException {
if (isClosed()) if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@ -171,6 +179,7 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet
} }
@Override @Override
@Deprecated
public InputStream getUnicodeStream(String columnLabel) throws SQLException { public InputStream getUnicodeStream(String columnLabel) throws SQLException {
return getUnicodeStream(findColumn(columnLabel)); return getUnicodeStream(findColumn(columnLabel));
} }

View File

@ -49,7 +49,7 @@ public class TSDBConnection extends AbstractConnection {
this.databaseMetaData.setConnection(this); this.databaseMetaData.setConnection(this);
} }
public TSDBJNIConnector getConnection() { public TSDBJNIConnector getConnector() {
return this.connector; return this.connector;
} }
@ -58,7 +58,7 @@ public class TSDBConnection extends AbstractConnection {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); 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 { 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 { public PreparedStatement prepareStatement(String sql) throws SQLException {
if (isClosed()) if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
return new TSDBPreparedStatement(this, this.connector, sql); }
return new TSDBPreparedStatement(this, sql);
} }
public void close() throws SQLException { public void close() throws SQLException {
if (isClosed) if (isClosed) {
return; return;
}
this.connector.closeConnection(); this.connector.closeConnection();
this.isClosed = true; this.isClosed = true;
} }

View File

@ -41,15 +41,15 @@ public abstract class TSDBConstants {
public static final int TSDB_DATA_TYPE_BINARY = 8; 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_TIMESTAMP = 9;
public static final int TSDB_DATA_TYPE_NCHAR = 10; public static final int TSDB_DATA_TYPE_NCHAR = 10;
/* /**
系统增加新的无符号数据类型分别是 * 系统增加新的无符号数据类型分别是
unsigned tinyint 数值范围0-254, NULL 为255 * unsigned tinyint 数值范围0-254, NULL 为255
unsigned smallint数值范围 0-65534 NULL 为65535 * unsigned smallint数值范围 0-65534 NULL 为65535
unsigned int数值范围0-4294967294NULL 为4294967295u * unsigned int数值范围0-4294967294NULL 为4294967295u
unsigned bigint数值范围0-18446744073709551614uNULL 为18446744073709551615u * unsigned bigint数值范围0-18446744073709551614uNULL 为18446744073709551615u
example: * example:
create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned); * 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_UTINYINT = 11; //unsigned tinyint
public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint
public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int
@ -57,6 +57,47 @@ public abstract class TSDBConstants {
// nchar column max length // nchar column max length
public static final int maxFieldSize = 16 * 1024; 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 { public static int taosType2JdbcType(int taosType) throws SQLException {
switch (taosType) { switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
@ -88,7 +129,7 @@ public abstract class TSDBConstants {
} }
public static String taosType2JdbcTypeName(int taosType) throws SQLException { public static String taosType2JdbcTypeName(int taosType) throws SQLException {
switch (taosType){ switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return "BOOL"; return "BOOL";
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
@ -119,7 +160,7 @@ public abstract class TSDBConstants {
} }
public static int jdbcType2TaosType(int jdbcType) throws SQLException { public static int jdbcType2TaosType(int jdbcType) throws SQLException {
switch (jdbcType){ switch (jdbcType) {
case Types.BOOLEAN: case Types.BOOLEAN:
return TSDBConstants.TSDB_DATA_TYPE_BOOL; return TSDBConstants.TSDB_DATA_TYPE_BOOL;
case Types.TINYINT: case Types.TINYINT:
@ -145,7 +186,7 @@ public abstract class TSDBConstants {
} }
public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException { public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException {
switch (jdbcType){ switch (jdbcType) {
case Types.BOOLEAN: case Types.BOOLEAN:
return "BOOL"; return "BOOL";
case Types.TINYINT: case Types.TINYINT:

View File

@ -18,6 +18,7 @@ package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.TaosInfo; import com.taosdata.jdbc.utils.TaosInfo;
import java.nio.ByteBuffer;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLWarning; import java.sql.SQLWarning;
import java.util.List; import java.util.List;
@ -29,10 +30,13 @@ public class TSDBJNIConnector {
private static volatile Boolean isInitialized = false; private static volatile Boolean isInitialized = false;
private TaosInfo taosInfo = TaosInfo.getInstance(); private TaosInfo taosInfo = TaosInfo.getInstance();
// Connection pointer used in C // Connection pointer used in C
private long taos = TSDBConstants.JNI_NULL_POINTER; private long taos = TSDBConstants.JNI_NULL_POINTER;
// result set status in current connection // result set status in current connection
private boolean isResultsetClosed; private boolean isResultsetClosed;
private int affectedRows = -1; private int affectedRows = -1;
static { static {
@ -75,7 +79,6 @@ public class TSDBJNIConnector {
public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException { public boolean connect(String host, int port, String dbName, String user, String password) throws SQLException {
if (this.taos != TSDBConstants.JNI_NULL_POINTER) { if (this.taos != TSDBConstants.JNI_NULL_POINTER) {
// this.closeConnectionImp(this.taos);
closeConnection(); closeConnection();
this.taos = TSDBConstants.JNI_NULL_POINTER; this.taos = TSDBConstants.JNI_NULL_POINTER;
} }
@ -97,12 +100,6 @@ public class TSDBJNIConnector {
* @throws SQLException * @throws SQLException
*/ */
public long executeQuery(String sql) 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; Long pSql = 0l;
try { try {
pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos); pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos);
@ -170,7 +167,7 @@ public class TSDBJNIConnector {
private native long isUpdateQueryImp(long connection, long pSql); 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) { public int freeResultSet(long pSql) {
int res = this.freeResultSetImp(this.taos, pSql); int res = this.freeResultSetImp(this.taos, pSql);
@ -178,19 +175,6 @@ public class TSDBJNIConnector {
return res; 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); private native int freeResultSetImp(long connection, long result);
/** /**
@ -210,7 +194,9 @@ public class TSDBJNIConnector {
* Get schema metadata * Get schema metadata
*/ */
public int getSchemaMetaData(long resultSet, List<ColumnMetaData> columnMetaData) { public int getSchemaMetaData(long resultSet, List<ColumnMetaData> 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> columnMetaData); private native int getSchemaMetaDataImp(long connection, long resultSet, List<ColumnMetaData> columnMetaData);
@ -237,6 +223,7 @@ public class TSDBJNIConnector {
*/ */
public void closeConnection() throws SQLException { public void closeConnection() throws SQLException {
int code = this.closeConnectionImp(this.taos); int code = this.closeConnectionImp(this.taos);
if (code < 0) { if (code < 0) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
} else if (code == 0) { } else if (code == 0) {
@ -244,6 +231,7 @@ public class TSDBJNIConnector {
} else { } else {
throw new SQLException("Undefined error code returned by TDengine when closing a connection"); throw new SQLException("Undefined error code returned by TDengine when closing a connection");
} }
// invoke closeConnectionImpl only here // invoke closeConnectionImpl only here
taosInfo.connect_close_increment(); taosInfo.connect_close_increment();
} }
@ -280,7 +268,7 @@ public class TSDBJNIConnector {
private native void unsubscribeImp(long subscription, boolean isKeep); private native void unsubscribeImp(long subscription, boolean isKeep);
/** /**
* Validate if a <I>create table</I> sql statement is correct without actually creating that table * Validate if a <I>create table</I> SQL statement is correct without actually creating that table
*/ */
public boolean validateCreateTableSql(String sql) { public boolean validateCreateTableSql(String sql) {
int res = validateCreateTableSqlImp(taos, sql.getBytes()); int res = validateCreateTableSqlImp(taos, sql.getBytes());
@ -288,4 +276,76 @@ public class TSDBJNIConnector {
} }
private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes); 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);
} }

View File

@ -18,33 +18,43 @@ import com.taosdata.jdbc.utils.Utils;
import java.io.InputStream; import java.io.InputStream;
import java.io.Reader; import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.net.URL; import java.net.URL;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.sql.*; import java.sql.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.Collections;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; 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 * standard JDBC API contains more or less some adjustments customized for certain
* compatibility needs. * compatibility needs.
*/ */
public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement { public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement {
private String rawSql; private String rawSql;
private Object[] parameters; private Object[] parameters;
private boolean isPrepared; private boolean isPrepared;
private ArrayList<ColumnInfo> colData;
private ArrayList<TableTagInfo> tableTags;
private int tagValueLength;
private String tableName;
private long nativeStmtHandle = 0;
private volatile TSDBParameterMetaData parameterMetaData; private volatile TSDBParameterMetaData parameterMetaData;
TSDBPreparedStatement(TSDBConnection connection, TSDBJNIConnector connecter, String sql) { TSDBPreparedStatement(TSDBConnection connection, String sql) {
super(connection, connecter); super(connection);
init(sql); init(sql);
int parameterCnt = 0;
if (sql.contains("?")) { if (sql.contains("?")) {
int parameterCnt = 0;
for (int i = 0; i < sql.length(); i++) { for (int i = 0; i < sql.length(); i++) {
if ('?' == sql.charAt(i)) { if ('?' == sql.charAt(i)) {
parameterCnt++; parameterCnt++;
@ -53,6 +63,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
parameters = new Object[parameterCnt]; parameters = new Object[parameterCnt];
this.isPrepared = true; this.isPrepared = true;
} }
if (parameterCnt > 1) {
// the table name is also a parameter, so ignore it.
this.colData = new ArrayList<ColumnInfo>();
this.tableTags = new ArrayList<TableTagInfo>();
}
} }
private void init(String sql) { private void init(String sql) {
@ -189,9 +205,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
if (isClosed()) setObject(parameterIndex, x.doubleValue());
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
@ -206,16 +220,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setDate(int parameterIndex, Date x) throws SQLException { public void setDate(int parameterIndex, Date x) throws SQLException {
if (isClosed()) setObject(parameterIndex, new Timestamp(x.getTime()));
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
public void setTime(int parameterIndex, Time x) throws SQLException { public void setTime(int parameterIndex, Time x) throws SQLException {
if (isClosed()) setObject(parameterIndex, new Timestamp(x.getTime()));
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
@ -260,10 +270,13 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setObject(int parameterIndex, Object x) throws SQLException { public void setObject(int parameterIndex, Object x) throws SQLException {
if (isClosed()) if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); 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); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE);
}
parameters[parameterIndex - 1] = x; parameters[parameterIndex - 1] = x;
} }
@ -300,8 +313,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setRef(int parameterIndex, Ref x) throws SQLException { 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_STATEMENT_CLOSED);
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@ -329,9 +343,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public ResultSetMetaData getMetaData() throws SQLException { public ResultSetMetaData getMetaData() throws SQLException {
if (isClosed()) if (this.getResultSet() == null)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); return null;
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); return getResultSet().getMetaData();
} }
@Override @Override
@ -375,10 +389,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (parameterMetaData == null) { return new TSDBParameterMetaData(parameters);
this.parameterMetaData = new TSDBParameterMetaData(parameters);
}
return this.parameterMetaData;
} }
@Override @Override
@ -390,9 +401,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public void setNString(int parameterIndex, String value) throws SQLException { public void setNString(int parameterIndex, String value) throws SQLException {
if (isClosed()) setString(parameterIndex, value);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
} }
@Override @Override
@ -515,4 +524,495 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); 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 <T> void setValueImpl(int columnIndex, ArrayList<T> 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<Integer> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES);
}
public void setFloat(int columnIndex, ArrayList<Float> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES);
}
public void setTimestamp(int columnIndex, ArrayList<Long> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES);
}
public void setLong(int columnIndex, ArrayList<Long> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES);
}
public void setDouble(int columnIndex, ArrayList<Double> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES);
}
public void setBoolean(int columnIndex, ArrayList<Boolean> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES);
}
public void setByte(int columnIndex, ArrayList<Byte> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES);
}
public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES);
}
public void setString(int columnIndex, ArrayList<String> 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<String> 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;
}
} }

View File

@ -133,9 +133,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getString(columnIndex - 1); return this.blockData.getString(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { 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; return res;
} }
@ -147,9 +148,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getBoolean(columnIndex - 1); return this.blockData.getBoolean(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { 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; return res;
} }
@ -161,9 +163,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (byte) this.blockData.getInt(columnIndex - 1); return (byte) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { 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; return res;
} }
@ -175,9 +178,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (short) this.blockData.getInt(columnIndex - 1); return (short) this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { 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; return res;
} }
@ -189,9 +193,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getInt(columnIndex - 1); return this.blockData.getInt(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { 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; return res;
} }
@ -203,13 +209,15 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getLong(columnIndex - 1); return this.blockData.getLong(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
Object value = this.rowData.get(columnIndex - 1); Object value = this.rowData.getObject(columnIndex);
if (value instanceof Timestamp) if (value instanceof Timestamp) {
res = ((Timestamp) value).getTime(); res = ((Timestamp) value).getTime();
else } else {
res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getLong(columnIndex, nativeType);
}
} }
return res; return res;
} }
@ -221,9 +229,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return (float) this.blockData.getDouble(columnIndex - 1); return (float) this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) if (!lastWasNull) {
res = this.rowData.getFloat(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getFloat(columnIndex, nativeType);
}
return res; return res;
} }
@ -235,9 +245,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getDouble(columnIndex - 1); return this.blockData.getDouble(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { 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; return res;
} }
@ -245,34 +256,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public byte[] getBytes(int columnIndex) throws SQLException { public byte[] getBytes(int columnIndex) throws SQLException {
checkAvailability(columnIndex, this.columnMetaDataList.size()); checkAvailability(columnIndex, this.columnMetaDataList.size());
Object value = this.rowData.get(columnIndex - 1); Object value = this.rowData.getObject(columnIndex);
if (value == null) if (value == null)
return null; return null;
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return Longs.toByteArray((Long) value); return Longs.toByteArray((long) value);
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return Ints.toByteArray((int) value); return Ints.toByteArray((int) value);
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return Shorts.toByteArray((Short) value); return Shorts.toByteArray((short) value);
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return new byte[]{(byte) value}; 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 { public Timestamp getTimestamp(int columnIndex) throws SQLException {
@ -282,9 +286,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.getTimestamp(columnIndex - 1); return this.blockData.getTimestamp(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
res = this.rowData.getTimestamp(columnIndex - 1); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
res = this.rowData.getTimestamp(columnIndex, nativeType);
} }
return res; return res;
} }
@ -304,13 +309,9 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return this.blockData.get(columnIndex - 1); return this.blockData.get(columnIndex - 1);
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
if (!lastWasNull) { if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); res = this.rowData.getObject(columnIndex);
if (colType == TSDBConstants.TSDB_DATA_TYPE_BINARY)
res = ((String) this.rowData.get(columnIndex - 1)).getBytes();
else
res = this.rowData.get(columnIndex - 1);
} }
return res; return res;
} }
@ -318,7 +319,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
public int findColumn(String columnLabel) throws SQLException { public int findColumn(String columnLabel) throws SQLException {
for (ColumnMetaData colMetaData : this.columnMetaDataList) { for (ColumnMetaData colMetaData : this.columnMetaDataList) {
if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) { if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) {
return colMetaData.getColIndex() + 1; return colMetaData.getColIndex();
} }
} }
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
@ -329,25 +330,25 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet {
if (this.getBatchFetch()) if (this.getBatchFetch())
return new BigDecimal(this.blockData.getLong(columnIndex - 1)); return new BigDecimal(this.blockData.getLong(columnIndex - 1));
this.lastWasNull = this.rowData.wasNull(columnIndex - 1); this.lastWasNull = this.rowData.wasNull(columnIndex);
BigDecimal res = null; BigDecimal res = null;
if (!lastWasNull) { if (!lastWasNull) {
int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType();
switch (colType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: 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; break;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: 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; break;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: 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: default:
res = new BigDecimal(this.rowData.get(columnIndex - 1).toString()); res = new BigDecimal(this.rowData.getObject(columnIndex).toString());
} }
} }
return res; return res;

View File

@ -29,6 +29,8 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import com.taosdata.jdbc.utils.NullType;
public class TSDBResultSetBlockData { public class TSDBResultSetBlockData {
private int numOfRows = 0; private int numOfRows = 0;
private int rowIndex = 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 * The original type may not be a string type, but will be converted to by
@ -488,8 +438,8 @@ public class TSDBResultSetBlockData {
} }
try { try {
String ss = TaosGlobalConfig.getCharset(); String charset = TaosGlobalConfig.getCharset();
return new String(dest, ss); return new String(dest, charset);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -113,6 +113,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD
ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1); ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1);
switch (columnMetaData.getColType()) { switch (columnMetaData.getColType()) {
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return 5; return 5;
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:

View File

@ -14,6 +14,8 @@
*****************************************************************************/ *****************************************************************************/
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.NullType;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
@ -22,11 +24,13 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
public class TSDBResultSetRowData { public class TSDBResultSetRowData {
private ArrayList<Object> data; private ArrayList<Object> data;
private int colSize = 0; private int colSize;
public TSDBResultSetRowData(int colSize) { public TSDBResultSetRowData(int colSize) {
this.setColSize(colSize); this.colSize = colSize;
this.clear();
} }
public void clear() { public void clear() {
@ -41,67 +45,104 @@ public class TSDBResultSetRowData {
} }
public boolean wasNull(int col) { 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) { public void setBoolean(int col, boolean value) {
data.set(col, value); data.set(col, value);
} }
public boolean getBoolean(int col, int srcType) throws SQLException { public boolean getBoolean(int col, int nativeType) throws SQLException {
Object obj = data.get(col); Object obj = data.get(col - 1);
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return (Boolean) obj; 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: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE; 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: default:
return false; 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) { public void setByte(int col, byte value) {
data.set(col, 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) { public void setShort(int col, short value) {
data.set(col, 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) { public void setInt(int col, int value) {
data.set(col, value); data.set(col, value);
} }
public int getInt(int col, int srcType) throws SQLException { public int getInt(int col, int nativeType) throws SQLException {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null)
return NullType.getIntNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; 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: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj; return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (Short) obj; return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj; return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return ((Long) obj).intValue(); return ((Long) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
@ -128,35 +169,48 @@ public class TSDBResultSetRowData {
long value = (long) obj; long value = (long) obj;
if (value < 0) if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); 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) { public void setLong(int col, long value) {
data.set(col, value); data.set(col, value);
} }
public long getLong(int col, int srcType) throws SQLException { public long getLong(int col, int nativeType) throws SQLException {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null) {
return NullType.getBigIntNull();
}
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; 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: case TSDBConstants.TSDB_DATA_TYPE_TINYINT:
return (Byte) obj; return (Byte) obj;
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT:
return (Short) obj; return (Short) obj;
case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_INT:
return (Integer) obj; return (Integer) obj;
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
return (Long) obj; return (Long) obj;
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
@ -185,19 +239,35 @@ public class TSDBResultSetRowData {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value; 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) { public void setFloat(int col, float value) {
data.set(col, value); data.set(col, value);
} }
public float getFloat(int col, int srcType) { public float getFloat(int col, int nativeType) {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null)
return NullType.getFloatNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
@ -213,19 +283,31 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj; 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) { public void setDouble(int col, double value) {
data.set(col, value); data.set(col, value);
} }
public double getDouble(int col, int srcType) { public double getDouble(int col, int nativeType) {
Object obj = data.get(col); Object obj = data.get(col - 1);
if (obj == null)
return NullType.getDoubleNull();
switch (srcType) { switch (nativeType) {
case TSDBConstants.TSDB_DATA_TYPE_BOOL: case TSDBConstants.TSDB_DATA_TYPE_BOOL:
return Boolean.TRUE.equals(obj) ? 1 : 0; return Boolean.TRUE.equals(obj) ? 1 : 0;
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
@ -241,16 +323,46 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT:
return (Long) obj; 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) { 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) { 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 { try {
data.set(col, new String(value, TaosGlobalConfig.getCharset())); data.set(col, new String(value, TaosGlobalConfig.getCharset()));
} catch (Exception e) { } catch (Exception e) {
@ -258,47 +370,56 @@ public class TSDBResultSetRowData {
} }
} }
/** public String getString(int col, int nativeType) {
* The original type may not be a string type, but will be converted to by calling this method Object obj = data.get(col - 1);
* if (obj == null)
* @param col column index return null;
* @return
*/ switch (nativeType) {
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);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { 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) if (value >= 0)
return value.toString(); return value.toString();
return Integer.toString(value & 0xff); return Integer.toString(value & 0xff);
} }
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: { 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) if (value >= 0)
return value.toString(); return value.toString();
return Integer.toString(value & 0xffff); return Integer.toString(value & 0xffff);
} }
case TSDBConstants.TSDB_DATA_TYPE_UINT: { 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) if (value >= 0)
return value.toString(); return value.toString();
return Long.toString(value & 0xffffffffl); return Long.toString(value & 0xffffffffl);
} }
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { 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) if (value >= 0)
return value.toString(); return value.toString();
long lowValue = value & 0x7fffffffffffffffL; long lowValue = value & 0x7fffffffffffffffL;
return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)).toString(); 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: 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) { public void setTimestamp(int col, long ts) {
//TODO: this implementation contains logical error //TODO: this implementation contains logical error
// when precision is us the (long ts) is 16 digital number // when precision is us the (long ts) is 16 digital number
@ -315,28 +436,20 @@ public class TSDBResultSetRowData {
} }
} }
public Timestamp getTimestamp(int col) { public Timestamp getTimestamp(int col, int nativeType) {
return (Timestamp) data.get(col); 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) { public Object getObject(int col) {
return data.get(col); return data.get(col - 1);
} }
public int getColSize() {
return colSize;
}
private void setColSize(int colSize) {
this.colSize = colSize;
this.clear();
}
public ArrayList<Object> getData() {
return data;
}
public void setData(ArrayList<Object> data) {
this.data = (ArrayList<Object>) data.clone();
}
} }

View File

@ -19,8 +19,6 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
public class TSDBStatement extends AbstractStatement { public class TSDBStatement extends AbstractStatement {
private TSDBJNIConnector connector;
/** /**
* Status of current statement * Status of current statement
*/ */
@ -29,29 +27,27 @@ public class TSDBStatement extends AbstractStatement {
private TSDBConnection connection; private TSDBConnection connection;
private TSDBResultSet resultSet; private TSDBResultSet resultSet;
public void setConnection(TSDBConnection connection) { TSDBStatement(TSDBConnection connection) {
this.connection = connection; this.connection = connection;
} }
TSDBStatement(TSDBConnection connection, TSDBJNIConnector connector) {
this.connection = connection;
this.connector = connector;
}
public ResultSet executeQuery(String sql) throws SQLException { public ResultSet executeQuery(String sql) throws SQLException {
// check if closed if (isClosed()) {
if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
//TODO: 如果在executeQuery方法中执行insert语句那么先执行了SQL再通过pSql来检查是否为一个insert语句但这个insert SQL已经执行成功了 }
//TODO:
// execute query // this is an unreasonable implementation, if the paratemer is a insert statement,
long pSql = this.connector.executeQuery(sql); // 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 pSql is create/insert/update/delete/alter SQL
if (this.connector.isUpdateQuery(pSql)) { if (this.connection.getConnector().isUpdateQuery(pSql)) {
this.connector.freeResultSet(pSql); this.connection.getConnector().freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); 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()); res.setBatchFetch(this.connection.getBatchFetch());
return res; return res;
} }
@ -60,14 +56,14 @@ public class TSDBStatement extends AbstractStatement {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); 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 pSql is create/insert/update/delete/alter SQL
if (!this.connector.isUpdateQuery(pSql)) { if (!this.connection.getConnector().isUpdateQuery(pSql)) {
this.connector.freeResultSet(pSql); this.connection.getConnector().freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEUPDATE);
} }
int affectedRows = this.connector.getAffectedRows(pSql); int affectedRows = this.connection.getConnector().getAffectedRows(pSql);
this.connector.freeResultSet(pSql); this.connection.getConnector().freeResultSet(pSql);
return affectedRows; return affectedRows;
} }
@ -81,30 +77,29 @@ public class TSDBStatement extends AbstractStatement {
public boolean execute(String sql) throws SQLException { public boolean execute(String sql) throws SQLException {
// check if closed // check if closed
if (isClosed()) if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
}
// execute query // 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 pSql is create/insert/update/delete/alter SQL
if (this.connector.isUpdateQuery(pSql)) { if (this.connection.getConnector().isUpdateQuery(pSql)) {
this.affectedRows = this.connector.getAffectedRows(pSql); this.affectedRows = this.connection.getConnector().getAffectedRows(pSql);
this.connector.freeResultSet(pSql); this.connection.getConnector().freeResultSet(pSql);
return false; 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()); this.resultSet.setBatchFetch(this.connection.getBatchFetch());
return true; return true;
} }
public ResultSet getResultSet() throws SQLException { public ResultSet getResultSet() throws SQLException {
if (isClosed()) if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); 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; return this.resultSet;
} }
@ -115,12 +110,20 @@ public class TSDBStatement extends AbstractStatement {
} }
public Connection getConnection() throws SQLException { public Connection getConnection() throws SQLException {
if (isClosed()) if (isClosed()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (this.connector == null) }
if (this.connection.getConnector() == null) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL);
}
return this.connection; return this.connection;
} }
public void setConnection(TSDBConnection connection) {
this.connection = connection;
}
public boolean isClosed() throws SQLException { public boolean isClosed() throws SQLException {
return isClosed; return isClosed;

View File

@ -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};
}
}

View File

@ -95,16 +95,7 @@ public class Utils {
public static String getNativeSql(String rawSql, Object[] parameters) { public static String getNativeSql(String rawSql, Object[] parameters) {
// toLowerCase // toLowerCase
String preparedSql = rawSql.trim().toLowerCase(); String preparedSql = rawSql.trim().toLowerCase();
String[] clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)", "where\\s*.*"};
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*.*"};
}
Map<Integer, Integer> placeholderPositions = new HashMap<>(); Map<Integer, Integer> placeholderPositions = new HashMap<>();
RangeSet<Integer> clauseRangeSet = TreeRangeSet.create(); RangeSet<Integer> clauseRangeSet = TreeRangeSet.create();
findPlaceholderPosition(preparedSql, placeholderPositions); findPlaceholderPosition(preparedSql, placeholderPositions);
@ -146,6 +137,7 @@ public class Utils {
*/ */
private static String transformSql(String rawSql, Object[] paramArr, Map<Integer, Integer> placeholderPosition, RangeSet<Integer> clauseRangeSet) { private static String transformSql(String rawSql, Object[] paramArr, Map<Integer, Integer> placeholderPosition, RangeSet<Integer> clauseRangeSet) {
String[] sqlArr = rawSql.split("\\?"); String[] sqlArr = rawSql.split("\\?");
return IntStream.range(0, sqlArr.length).mapToObj(index -> { return IntStream.range(0, sqlArr.length).mapToObj(index -> {
if (index == paramArr.length) if (index == paramArr.length)
return sqlArr[index]; return sqlArr[index];

View File

@ -32,20 +32,34 @@ public class TSDBConnectionTest {
} }
@Test @Test
public void subscribe() { public void runSubscribe() {
try { try {
// given
TSDBConnection unwrap = conn.unwrap(TSDBConnection.class); TSDBConnection unwrap = conn.unwrap(TSDBConnection.class);
TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false); TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false);
// when
TSDBResultSet rs = subscribe.consume(); TSDBResultSet rs = subscribe.consume();
ResultSetMetaData metaData = rs.getMetaData(); ResultSetMetaData metaData = rs.getMetaData();
for (int count = 0; count < 10 && rs.next(); count++) {
for (int i = 1; i <= metaData.getColumnCount(); i++) { // then
String value = rs.getString(i);
System.out.print(metaData.getColumnLabel(i) + ":" + value + "\t");
}
System.out.println();
}
Assert.assertNotNull(rs); 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); subscribe.close(false);
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -7,9 +7,11 @@ import java.util.Properties;
public class TSDBDatabaseMetaDataTest { public class TSDBDatabaseMetaDataTest {
private static final String host = "127.0.0.1"; 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 Connection connection;
private static TSDBDatabaseMetaData metaData; private static TSDBDatabaseMetaData metaData;
@Test @Test
public void unwrap() throws SQLException { public void unwrap() throws SQLException {
TSDBDatabaseMetaData unwrap = metaData.unwrap(TSDBDatabaseMetaData.class); TSDBDatabaseMetaData unwrap = metaData.unwrap(TSDBDatabaseMetaData.class);
@ -33,7 +35,7 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getURL() throws SQLException { public void getURL() throws SQLException {
Assert.assertEquals("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", metaData.getURL()); Assert.assertEquals(url, metaData.getURL());
} }
@Test @Test
@ -627,17 +629,32 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getTables() throws SQLException { public void getTables() throws SQLException {
System.out.println("****************************************************"); ResultSet rs = metaData.getTables("log", "", null, null);
ResultSet tables = metaData.getTables("log", "", null, null); ResultSetMetaData meta = rs.getMetaData();
ResultSetMetaData metaData = tables.getMetaData(); Assert.assertNotNull(rs);
while (tables.next()) { rs.next();
System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t"); {
System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t"); // TABLE_CAT
System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t"); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n"); 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 @Test
@ -647,46 +664,130 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getCatalogs() throws SQLException { public void getCatalogs() throws SQLException {
System.out.println("****************************************************"); ResultSet rs = metaData.getCatalogs();
ResultSetMetaData meta = rs.getMetaData();
ResultSet catalogs = metaData.getCatalogs(); rs.next();
ResultSetMetaData meta = catalogs.getMetaData(); {
while (catalogs.next()) { // TABLE_CAT
for (int i = 1; i <= meta.getColumnCount(); i++) { Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i)); Assert.assertNotNull(rs.getString(1));
} Assert.assertNotNull(rs.getString("TABLE_CAT"));
System.out.println();
} }
} }
@Test @Test
public void getTableTypes() throws SQLException { public void getTableTypes() throws SQLException {
System.out.println("****************************************************");
ResultSet tableTypes = metaData.getTableTypes(); ResultSet tableTypes = metaData.getTableTypes();
while (tableTypes.next()) { tableTypes.next();
System.out.println(tableTypes.getString("TABLE_TYPE")); // 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 @Test
public void getColumns() throws SQLException { public void getColumns() throws SQLException {
System.out.println("****************************************************"); // when
ResultSet columns = metaData.getColumns("log", "", "dn", ""); ResultSet columns = metaData.getColumns("log", "", "dn", "");
// then
ResultSetMetaData meta = columns.getMetaData(); ResultSetMetaData meta = columns.getMetaData();
while (columns.next()) { columns.next();
System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t"); // column: 1
System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t"); {
System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t"); // TABLE_CAT
System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t"); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t"); Assert.assertEquals("log", columns.getString(1));
System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t"); Assert.assertEquals("log", columns.getString("TABLE_CAT"));
System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t"); // TABLE_NAME
System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t"); Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n"); Assert.assertEquals("dn", columns.getString(3));
System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n"); 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 @Test
public void getPrimaryKeys() throws SQLException { public void getPrimaryKeys() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1"); ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1");
while (rs.next()) { ResultSetMetaData meta = rs.getMetaData();
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); rs.next();
System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME")); {
System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ")); // TABLE_CAT
System.out.println("PK_NAME: " + rs.getString("PK_NAME")); 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 @Test
@ -847,14 +966,27 @@ public class TSDBDatabaseMetaDataTest {
@Test @Test
public void getSuperTables() throws SQLException { public void getSuperTables() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getSuperTables("log", "", "dn1"); ResultSet rs = metaData.getSuperTables("log", "", "dn1");
while (rs.next()) { ResultSetMetaData meta = rs.getMetaData();
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); rs.next();
System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME")); {
// 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 @Test
@ -951,15 +1083,12 @@ public class TSDBDatabaseMetaDataTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-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); metaData = connection.getMetaData().unwrap(TSDBDatabaseMetaData.class);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -45,9 +45,9 @@ public class TSDBJNIConnectorTest {
rowData = new TSDBResultSetRowData(columnSize); rowData = new TSDBResultSetRowData(columnSize);
// iterate resultSet // iterate resultSet
for (int i = 0; next(connector, pSql); i++) { for (int i = 0; next(connector, pSql); i++) {
System.out.println("col[" + i + "] size: " + rowData.getColSize()); // System.out.println("col[" + i + "] size: " + rowData.getColSize());
rowData.getData().stream().forEach(col -> System.out.print(col + "\t")); // rowData.getData().stream().forEach(col -> System.out.print(col + "\t"));
System.out.println(); // System.out.println();
} }
// close resultSet // close resultSet
code = connector.freeResultSet(pSql); code = connector.freeResultSet(pSql);

View File

@ -54,16 +54,17 @@ public class TSDBParameterMetaDataTest {
@Test @Test
public void getPrecision() throws SQLException { public void getPrecision() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); //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(0, parameterMetaData_insert.getPrecision(2)); Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9));
Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10));
} }
@Test @Test
@ -71,8 +72,8 @@ public class TSDBParameterMetaDataTest {
Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(1));
Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2));
Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3));
Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); Assert.assertEquals(31, parameterMetaData_insert.getScale(4));
Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); Assert.assertEquals(31, parameterMetaData_insert.getScale(5));
Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6));
Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7));
Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8));
@ -124,10 +125,16 @@ public class TSDBParameterMetaDataTest {
@Test @Test
public void getParameterMode() throws SQLException { public void getParameterMode() throws SQLException {
for (int i = 1; i <= parameterMetaData_insert.getParameterCount(); i++) { Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(1));
int parameterMode = parameterMetaData_insert.getParameterMode(i); Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(2));
Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMode); 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 @Test
@ -144,7 +151,6 @@ public class TSDBParameterMetaDataTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt"); 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(7, Byte.MAX_VALUE);
pstmt_insert.setObject(8, true); pstmt_insert.setObject(8, true);
pstmt_insert.setObject(9, "hello".getBytes()); pstmt_insert.setObject(9, "hello".getBytes());
pstmt_insert.setObject(10, "Hello"); pstmt_insert.setObject(10, "涛思数据");
parameterMetaData_insert = pstmt_insert.getParameterMetaData(); parameterMetaData_insert = pstmt_insert.getParameterMetaData();
pstmt_select = conn.prepareStatement(sql_select); pstmt_select = conn.prepareStatement(sql_select);
@ -173,7 +179,7 @@ public class TSDBParameterMetaDataTest {
pstmt_select.setInt(3, 0); pstmt_select.setInt(3, 0);
parameterMetaData_select = pstmt_select.getParameterMetaData(); parameterMetaData_select = pstmt_select.getParameterMetaData();
} catch (ClassNotFoundException | SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -1,231 +1,645 @@
package com.taosdata.jdbc; package com.taosdata.jdbc;
import org.junit.AfterClass; import org.junit.*;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.IOException; import java.io.IOException;
import java.io.Serializable; import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
import java.util.ArrayList;
import java.util.Random;
public class TSDBPreparedStatementTest { public class TSDBPreparedStatementTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static Connection conn; private static Connection conn;
private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; 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 final String sql_select = "select * from t1 where ts > ? and ts <= ? and f1 >= ?";
private static PreparedStatement pstmt_select; 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 @Test
public void executeQuery() throws SQLException { public void executeQuery() throws SQLException {
long end = System.currentTimeMillis(); // given
long start = end - 1000 * 60 * 60; 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(1, new Timestamp(start));
pstmt_select.setTimestamp(2, new Timestamp(end)); pstmt_select.setTimestamp(2, new Timestamp(end));
pstmt_select.setInt(3, 0); pstmt_select.setInt(3, 0);
// when
ResultSet rs = pstmt_select.executeQuery(); ResultSet rs = pstmt_select.executeQuery();
Assert.assertNotNull(rs);
ResultSetMetaData meta = rs.getMetaData(); ResultSetMetaData meta = rs.getMetaData();
while (rs.next()) { rs.next();
for (int i = 1; i <= meta.getColumnCount(); i++) {
System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); // then
} assertMetaData(meta);
System.out.println(); {
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 @Test
public void executeUpdate() throws SQLException { public void setNullForFloat() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
pstmt_insert.setFloat(4, 3.14f); long ts = System.currentTimeMillis();
// when
pstmt_insert.setTimestamp(1, new Timestamp(ts));
pstmt_insert.setNull(4, Types.FLOAT);
int result = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
// then
Assert.assertEquals(1, result); 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 @Test
public void setNull() throws SQLException { public void setNullForDouble() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
pstmt_insert.setNull(2, Types.INTEGER); long ts = System.currentTimeMillis();
int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // when
pstmt_insert.setNull(3, Types.BIGINT); pstmt_insert.setTimestamp(1, new Timestamp(ts));
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()));
pstmt_insert.setNull(5, Types.DOUBLE); pstmt_insert.setNull(5, Types.DOUBLE);
result = pstmt_insert.executeUpdate(); int result = pstmt_insert.executeUpdate();
Assert.assertEquals(1, result);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // then
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();
Assert.assertEquals(1, result); 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 @Test
public void setBoolean() throws SQLException { 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); pstmt_insert.setBoolean(8, true);
int ret = pstmt_insert.executeUpdate(); int result = 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.assertTrue(rs.getBoolean(8));
Assert.assertTrue(rs.getBoolean("f7"));
}
}
} }
@Test @Test
public void setByte() throws SQLException { 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); pstmt_insert.setByte(7, (byte) 0x001);
int ret = pstmt_insert.executeUpdate(); int result = 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.assertEquals((byte) 0x001, rs.getByte(7));
Assert.assertEquals((byte) 0x001, rs.getByte("f6"));
}
}
} }
@Test @Test
public void setShort() throws SQLException { 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); pstmt_insert.setShort(6, (short) 2);
int ret = pstmt_insert.executeUpdate(); int result = 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.assertEquals((short) 2, rs.getByte(6));
Assert.assertEquals((short) 2, rs.getByte("f5"));
}
}
} }
@Test @Test
public void setInt() throws SQLException { 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); pstmt_insert.setInt(2, 10086);
int ret = pstmt_insert.executeUpdate(); int result = 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.assertEquals(10086, rs.getInt(2));
Assert.assertEquals(10086, rs.getInt("f1"));
}
}
} }
@Test @Test
public void setLong() throws SQLException { 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); pstmt_insert.setLong(3, Long.MAX_VALUE);
int ret = pstmt_insert.executeUpdate(); int result = 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.assertEquals(Long.MAX_VALUE, rs.getLong(3));
Assert.assertEquals(Long.MAX_VALUE, rs.getLong("f2"));
}
}
} }
@Test @Test
public void setFloat() throws SQLException { 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); pstmt_insert.setFloat(4, 3.14f);
int ret = pstmt_insert.executeUpdate(); int result = 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.assertEquals(3.14f, rs.getFloat(4), 0.0f);
Assert.assertEquals(3.14f, rs.getFloat("f3"), 0.0f);
}
}
} }
@Test @Test
public void setDouble() throws SQLException { 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); pstmt_insert.setDouble(5, 3.14444);
int ret = pstmt_insert.executeUpdate(); int result = 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.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 { 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 @Test
public void setString() throws SQLException { public void setString() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
pstmt_insert.setString(10, "aaaa"); long ts = System.currentTimeMillis();
boolean execute = pstmt_insert.execute(); String f9 = "{\"name\": \"john\", \"age\": 10, \"address\": \"192.168.1.100\"}";
Assert.assertFalse(execute);
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // when
pstmt_insert.setString(10, new Person("john", 33, true).toString()); pstmt_insert.setTimestamp(1, new Timestamp(ts));
Assert.assertFalse(pstmt_insert.execute()); pstmt_insert.setString(10, f9);
int result = pstmt_insert.executeUpdate();
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // then
pstmt_insert.setString(10, new Person("john", 33, true).toString().replaceAll("'", "\"")); Assert.assertEquals(1, result);
Assert.assertFalse(pstmt_insert.execute()); try (Statement stmt = conn.createStatement()) {
} ResultSet rs = stmt.executeQuery("select * from t1");
ResultSetMetaData meta = rs.getMetaData();
class Person { assertMetaData(meta);
String name; rs.next();
int age; {
boolean sex; Assert.assertNotNull(rs);
Assert.assertEquals(ts, rs.getTimestamp(1).getTime());
public Person(String name, int age, boolean sex) { Assert.assertEquals(ts, rs.getTimestamp("ts").getTime());
this.name = name; Assert.assertEquals(f9, rs.getString(10));
this.age = age; Assert.assertEquals(f9, rs.getString("f9"));
this.sex = sex; }
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
} }
} }
@Test @Test
public void setBytes() throws SQLException, IOException { 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.setTimestamp(1, new Timestamp(System.currentTimeMillis()));
pstmt_insert.setBytes(9, f8);
int result = pstmt_insert.executeUpdate();
// ByteArrayOutputStream baos = new ByteArrayOutputStream(); // then
// ObjectOutputStream oos = new ObjectOutputStream(baos); Assert.assertEquals(1, result);
// oos.writeObject(new Person("john", 33, true)); try (Statement stmt = conn.createStatement()) {
// oos.flush(); ResultSet rs = stmt.executeQuery("select * from t1");
// byte[] bytes = baos.toByteArray(); ResultSetMetaData meta = rs.getMetaData();
// pstmt_insert.setBytes(9, bytes); assertMetaData(meta);
rs.next();
pstmt_insert.setBytes(9, new Person("john", 33, true).toString().getBytes()); {
int ret = pstmt_insert.executeUpdate(); Assert.assertNotNull(rs);
Assert.assertEquals(1, ret); 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 { 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 { 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 @Test
public void setTimestamp() throws SQLException { public void setTimestamp() throws SQLException {
pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); // given
int ret = pstmt_insert.executeUpdate(); long ts = System.currentTimeMillis();
Assert.assertEquals(1, ret);
// 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) @Test(expected = SQLFeatureNotSupportedException.class)
@ -238,72 +652,6 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setBinaryStream(1, null); 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) @Test(expected = SQLFeatureNotSupportedException.class)
public void setCharacterStream() throws SQLException { public void setCharacterStream() throws SQLException {
pstmt_insert.setCharacterStream(1, null); pstmt_insert.setCharacterStream(1, null);
@ -329,9 +677,17 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setArray(1, null); pstmt_insert.setArray(1, null);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void getMetaData() throws SQLException { 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) @Test(expected = SQLFeatureNotSupportedException.class)
@ -341,9 +697,46 @@ public class TSDBPreparedStatementTest {
@Test @Test
public void getParameterMetaData() throws SQLException { 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(); ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData();
// then
Assert.assertNotNull(parameterMetaData); 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) @Test(expected = SQLFeatureNotSupportedException.class)
@ -351,9 +744,9 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setRowId(1, null); pstmt_insert.setRowId(1, null);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test
public void setNString() throws SQLException { public void setNString() throws SQLException {
pstmt_insert.setNString(1, null); setString();
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
@ -371,22 +764,45 @@ public class TSDBPreparedStatementTest {
pstmt_insert.setSQLXML(1, null); 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 @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
try (Statement stmt = conn.createStatement()) { try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists test_pstmt_jni"); stmt.execute("drop database if exists test_pstmt_jni");
stmt.execute("create database if not exists test_pstmt_jni"); stmt.execute("create database if not exists test_pstmt_jni");
stmt.execute("use 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); } catch (SQLException e) {
pstmt_select = conn.prepareStatement(sql_select);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@ -394,10 +810,6 @@ public class TSDBPreparedStatementTest {
@AfterClass @AfterClass
public static void afterClass() { public static void afterClass() {
try { try {
if (pstmt_insert != null)
pstmt_insert.close();
if (pstmt_select != null)
pstmt_select.close();
if (conn != null) if (conn != null)
conn.close(); conn.close();
} catch (SQLException e) { } catch (SQLException e) {

View File

@ -3,7 +3,6 @@ package com.taosdata.jdbc;
import com.google.common.primitives.Ints; import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs; import com.google.common.primitives.Longs;
import com.google.common.primitives.Shorts; import com.google.common.primitives.Shorts;
import com.taosdata.jdbc.rs.RestfulResultSet;
import org.junit.AfterClass; import org.junit.AfterClass;
import org.junit.Assert; import org.junit.Assert;
import org.junit.BeforeClass; import org.junit.BeforeClass;
@ -15,6 +14,7 @@ import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays;
public class TSDBResultSetTest { public class TSDBResultSetTest {
@ -134,7 +134,7 @@ public class TSDBResultSetTest {
Assert.assertEquals(3.1415926, Double.valueOf(new String(f5)), 0.000000f); Assert.assertEquals(3.1415926, Double.valueOf(new String(f5)), 0.000000f);
byte[] f6 = rs.getBytes("f6"); byte[] f6 = rs.getBytes("f6");
Assert.assertEquals("abc", new String(f6)); Assert.assertTrue(Arrays.equals("abc".getBytes(), f6));
byte[] f7 = rs.getBytes("f7"); byte[] f7 = rs.getBytes("f7");
Assert.assertEquals((short) 10, Shorts.fromByteArray(f7)); Assert.assertEquals((short) 10, Shorts.fromByteArray(f7));
@ -177,7 +177,8 @@ public class TSDBResultSetTest {
rs.getAsciiStream("f1"); rs.getAsciiStream("f1");
} }
@Test(expected = SQLFeatureNotSupportedException.class) @SuppressWarnings("deprecation")
@Test(expected = SQLFeatureNotSupportedException.class)
public void getUnicodeStream() throws SQLException { public void getUnicodeStream() throws SQLException {
rs.getUnicodeStream("f1"); rs.getUnicodeStream("f1");
} }
@ -326,7 +327,7 @@ public class TSDBResultSetTest {
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
public void getRow() throws SQLException { public void getRow() throws SQLException {
int row = rs.getRow(); rs.getRow();
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
@ -405,12 +406,12 @@ public class TSDBResultSetTest {
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
public void updateByte() throws SQLException { public void updateByte() throws SQLException {
rs.updateByte(1, new Byte("0")); rs.updateByte(1, (byte) 0);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
public void updateShort() throws SQLException { public void updateShort() throws SQLException {
rs.updateShort(1, new Short("0")); rs.updateShort(1, (short) 0);
} }
@Test(expected = SQLFeatureNotSupportedException.class) @Test(expected = SQLFeatureNotSupportedException.class)
@ -646,7 +647,6 @@ public class TSDBResultSetTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
stmt = conn.createStatement(); stmt = conn.createStatement();
stmt.execute("create database if not exists restful_test"); 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, '涛思数据')"); 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 = stmt.executeQuery("select * from restful_test.weather");
rs.next(); rs.next();
} catch (ClassNotFoundException | SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
} }
@AfterClass @AfterClass

View File

@ -387,15 +387,12 @@ public class TSDBStatementTest {
@BeforeClass @BeforeClass
public static void beforeClass() { public static void beforeClass() {
try { try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties(); Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties);
stmt = conn.createStatement(); stmt = conn.createStatement();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -345,6 +345,7 @@ public class InsertSpecialCharacterJniTest {
} }
} }
@Test @Test
public void testCase12() throws SQLException { public void testCase12() throws SQLException {
final long now = System.currentTimeMillis(); final long now = System.currentTimeMillis();

View File

@ -10,6 +10,7 @@ import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class RestfulDatabaseMetaDataTest { public class RestfulDatabaseMetaDataTest {
private static final String host = "127.0.0.1"; 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 final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
private static Connection connection; private static Connection connection;
@ -632,17 +633,32 @@ public class RestfulDatabaseMetaDataTest {
@Test @Test
public void getTables() throws SQLException { public void getTables() throws SQLException {
System.out.println("****************************************************"); ResultSet rs = metaData.getTables("log", "", null, null);
ResultSet tables = metaData.getTables("log", "", null, null); ResultSetMetaData meta = rs.getMetaData();
ResultSetMetaData metaData = tables.getMetaData(); Assert.assertNotNull(rs);
while (tables.next()) { rs.next();
System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t"); {
System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t"); // TABLE_CAT
System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t"); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n"); 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 @Test
@ -652,46 +668,130 @@ public class RestfulDatabaseMetaDataTest {
@Test @Test
public void getCatalogs() throws SQLException { public void getCatalogs() throws SQLException {
System.out.println("****************************************************"); ResultSet rs = metaData.getCatalogs();
ResultSetMetaData meta = rs.getMetaData();
ResultSet catalogs = metaData.getCatalogs(); rs.next();
ResultSetMetaData meta = catalogs.getMetaData(); {
while (catalogs.next()) { // TABLE_CAT
for (int i = 1; i <= meta.getColumnCount(); i++) { Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i)); Assert.assertNotNull(rs.getString(1));
} Assert.assertNotNull(rs.getString("TABLE_CAT"));
System.out.println();
} }
} }
@Test @Test
public void getTableTypes() throws SQLException { public void getTableTypes() throws SQLException {
System.out.println("****************************************************");
ResultSet tableTypes = metaData.getTableTypes(); ResultSet tableTypes = metaData.getTableTypes();
while (tableTypes.next()) { tableTypes.next();
System.out.println(tableTypes.getString("TABLE_TYPE")); // 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 @Test
public void getColumns() throws SQLException { public void getColumns() throws SQLException {
System.out.println("****************************************************"); // when
ResultSet columns = metaData.getColumns("log", "", "dn", ""); ResultSet columns = metaData.getColumns("log", "", "dn", "");
// then
ResultSetMetaData meta = columns.getMetaData(); ResultSetMetaData meta = columns.getMetaData();
while (columns.next()) { columns.next();
System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t"); // column: 1
System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t"); {
System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t"); // TABLE_CAT
System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t"); Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1));
System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t"); Assert.assertEquals("log", columns.getString(1));
System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t"); Assert.assertEquals("log", columns.getString("TABLE_CAT"));
System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t"); // TABLE_NAME
System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t"); Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3));
System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n"); Assert.assertEquals("dn", columns.getString(3));
System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n"); 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 @Test
public void getPrimaryKeys() throws SQLException { public void getPrimaryKeys() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1"); ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1");
while (rs.next()) { ResultSetMetaData meta = rs.getMetaData();
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); rs.next();
System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME")); {
System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ")); // TABLE_CAT
System.out.println("PK_NAME: " + rs.getString("PK_NAME")); 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 @Test
@ -852,14 +970,27 @@ public class RestfulDatabaseMetaDataTest {
@Test @Test
public void getSuperTables() throws SQLException { public void getSuperTables() throws SQLException {
System.out.println("****************************************************");
ResultSet rs = metaData.getSuperTables("log", "", "dn1"); ResultSet rs = metaData.getSuperTables("log", "", "dn1");
while (rs.next()) { ResultSetMetaData meta = rs.getMetaData();
System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); rs.next();
System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME")); {
// 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 @Test

View File

@ -54,16 +54,17 @@ public class RestfulParameterMetaDataTest {
@Test @Test
public void getPrecision() throws SQLException { public void getPrecision() throws SQLException {
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); //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(0, parameterMetaData_insert.getPrecision(2)); Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6));
Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8));
Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9));
Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10));
} }
@Test @Test
@ -71,8 +72,8 @@ public class RestfulParameterMetaDataTest {
Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(1));
Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2));
Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3));
Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); Assert.assertEquals(31, parameterMetaData_insert.getScale(4));
Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); Assert.assertEquals(31, parameterMetaData_insert.getScale(5));
Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6));
Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7));
Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8));
@ -164,7 +165,7 @@ public class RestfulParameterMetaDataTest {
pstmt_insert.setObject(7, Byte.MAX_VALUE); pstmt_insert.setObject(7, Byte.MAX_VALUE);
pstmt_insert.setObject(8, true); pstmt_insert.setObject(8, true);
pstmt_insert.setObject(9, "hello".getBytes()); pstmt_insert.setObject(9, "hello".getBytes());
pstmt_insert.setObject(10, "Hello"); pstmt_insert.setObject(10, "涛思数据");
parameterMetaData_insert = pstmt_insert.getParameterMetaData(); parameterMetaData_insert = pstmt_insert.getParameterMetaData();
pstmt_select = conn.prepareStatement(sql_select); pstmt_select = conn.prepareStatement(sql_select);

View File

@ -242,7 +242,7 @@ def _load_taos_linux():
def _load_taos_darwin(): def _load_taos_darwin():
return ctypes.cDLL('libtaos.dylib') return ctypes.CDLL('libtaos.dylib')
def _load_taos_windows(): def _load_taos_windows():

View File

@ -38,21 +38,6 @@
#define cDebug(...) { if (cqDebugFlag & DEBUG_DEBUG) { taosPrintLog("CQ ", cqDebugFlag, __VA_ARGS__); }} #define cDebug(...) { if (cqDebugFlag & DEBUG_DEBUG) { taosPrintLog("CQ ", cqDebugFlag, __VA_ARGS__); }}
#define cTrace(...) { if (cqDebugFlag & DEBUG_TRACE) { 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 { typedef struct SCqObj {
tmr_h tmrId; tmr_h tmrId;
@ -439,7 +424,7 @@ static void cqProcessCreateTimer(void *param, void *tmrId) {
// inner implement in tscStream.c // 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), 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) { static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
pObj->pContext = pContext; pObj->pContext = pContext;
@ -453,7 +438,8 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
pObj->tmrId = 0; pObj->tmrId = 0;
if (pObj->pStream == NULL) { 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 // TODO the pObj->pStream may be released if error happens
if (pObj->pStream) { if (pObj->pStream) {

View File

@ -31,6 +31,23 @@ typedef struct {
FCqWrite cqWrite; FCqWrite cqWrite;
} SCqCfg; } 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 // the following API shall be called by vnode
void *cqOpen(void *ahandle, const SCqCfg *pCfg); void *cqOpen(void *ahandle, const SCqCfg *pCfg);
void cqClose(void *handle); void cqClose(void *handle);

View File

@ -625,6 +625,10 @@ static int64_t g_totalChildTables = 0;
static SQueryMetaInfo g_queryInfo; static SQueryMetaInfo g_queryInfo;
static FILE * g_fpOfInsertResult = NULL; static FILE * g_fpOfInsertResult = NULL;
#if _MSC_VER <= 1900
#define __func__ __FUNCTION__
#endif
#define debugPrint(fmt, ...) \ #define debugPrint(fmt, ...) \
do { if (g_args.debug_print || g_args.verbose_print) \ do { if (g_args.debug_print || g_args.verbose_print) \
fprintf(stderr, "DEBG: "fmt, __VA_ARGS__); } while(0) fprintf(stderr, "DEBG: "fmt, __VA_ARGS__); } while(0)

View File

@ -43,7 +43,7 @@
*/ */
int64_t user_mktime64(const unsigned int year0, const unsigned int mon0, int64_t user_mktime64(const unsigned int year0, const unsigned int mon0,
const unsigned int day, const unsigned int hour, 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; 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*24;
res = ((res + hour) * 60 + min) * 60 + sec; res = ((res + hour) * 60 + min) * 60 + sec;
return (res + timezone); return (res + time_zone);
} }
// ==== mktime() kernel code =================// // ==== mktime() kernel code =================//

View File

@ -26,6 +26,7 @@ extern "C" {
#include "taosdef.h" #include "taosdef.h"
int32_t strdequote(char *src); int32_t strdequote(char *src);
int32_t strRmquote(char *z, int32_t len);
size_t strtrim(char *src); size_t strtrim(char *src);
char * strnchr(char *haystack, char needle, int32_t len, bool skipquote); char * strnchr(char *haystack, char needle, int32_t len, bool skipquote);
char ** strsplit(char *src, const char *delim, int32_t *num); char ** strsplit(char *src, const char *delim, int32_t *num);

View File

@ -52,6 +52,36 @@ int32_t strdequote(char *z) {
return j + 1; // only one quote, do nothing 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) { size_t strtrim(char *z) {
int32_t i = 0; int32_t i = 0;
int32_t j = 0; int32_t j = 0;

View File

@ -21,7 +21,7 @@ def pre_test(){
cmake .. > /dev/null cmake .. > /dev/null
make > /dev/null make > /dev/null
make install > /dev/null make install > /dev/null
pip3 install ${WKC}/src/connector/python/linux/python3/ pip3 install ${WKC}/src/connector/python/ || echo 0
''' '''
return 1 return 1
} }

View File

@ -23,7 +23,8 @@ class Node:
self.hostIP = hostIP self.hostIP = hostIP
self.hostName = hostName self.hostName = hostName
self.homeDir = homeDir 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): def buildTaosd(self):
try: try:
@ -126,21 +127,37 @@ class Node:
except Exception as e: except Exception as e:
print("remove taosd error for node %d " % self.index) print("remove taosd error for node %d " % self.index)
logging.exception(e) 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: class Nodes:
def __init__(self): def __init__(self):
self.tdnodes = [] self.tdnodes = []
self.tdnodes.append(Node(0, 'root', '52.143.103.7', 'node1', '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(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(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(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(4, 'root', '51.141.166.100', 'node5', 'a', '/root/'))
def stopOneNode(self, index): def stopOneNode(self, index):
self.tdnodes[index].stopTaosd()
self.tdnodes[index].forceStopOneTaosd() self.tdnodes[index].forceStopOneTaosd()
def startOneNode(self, index): def startOneNode(self, index):
self.tdnodes[index].startOneTaosd() self.tdnodes[index].startOneTaosd()
def detectCoredumpFile(self, index):
return self.tdnodes[index].detectCoredumpFile()
def stopAllTaosd(self): def stopAllTaosd(self):
for i in range(len(self.tdnodes)): for i in range(len(self.tdnodes)):
@ -166,14 +183,32 @@ class Nodes:
for i in range(len(self.tdnodes)): for i in range(len(self.tdnodes)):
self.tdnodes[i].removeData() self.tdnodes[i].removeData()
# kill taosd randomly every 10 mins class Test:
nodes = Nodes() def __init__(self):
loop = 0 self.nodes = Nodes()
while True:
loop = loop + 1 # kill taosd randomly every 10 mins
index = random.randint(0, 4) def randomlyKillDnode(self):
print("loop: %d, kill taosd on node%d" %(loop, index)) loop = 0
nodes.stopOneNode(index) while True:
time.sleep(60) index = random.randint(0, 4)
nodes.startOneNode(index) print("loop: %d, kill taosd on node%d" %(loop, index))
time.sleep(600) 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()

View File

@ -25,7 +25,7 @@ class TDTestCase:
def run(self): def run(self):
tdSql.query("show variables") tdSql.query("show variables")
tdSql.checkData(51, 1, 864000) tdSql.checkData(53, 1, 864000)
def stop(self): def stop(self):
tdSql.close() tdSql.close()
@ -33,4 +33,4 @@ class TDTestCase:
tdCases.addWindows(__file__, TDTestCase()) tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase()) tdCases.addLinux(__file__, TDTestCase())