Merge branch 'develop' into test/TD-4652

This commit is contained in:
bryanchang0603 2021-06-19 13:06:06 +08:00
commit 55757e1623
62 changed files with 2819 additions and 602 deletions

245
packaging/check_package.sh Executable file
View File

@ -0,0 +1,245 @@
#!/bin/bash
#
# This file is used to install database on linux systems. The operating system
# is required to use systemd to manage services at boot
set -e
#set -x
verMode=edge
pagMode=full
iplist=""
serverFqdn=""
# -----------------------Variables definition---------------------
script_dir="../release"
# Dynamic directory
data_dir="/var/lib/taos"
log_dir="/var/log/taos"
data_link_dir="/usr/local/taos/data"
log_link_dir="/usr/local/taos/log"
cfg_install_dir="/etc/taos"
bin_link_dir="/usr/bin"
lib_link_dir="/usr/lib"
lib64_link_dir="/usr/lib64"
inc_link_dir="/usr/include"
#install main path
install_main_dir="/usr/local/taos"
# old bin dir
sbin_dir="/usr/local/taos/bin"
temp_version=""
fin_result=""
service_config_dir="/etc/systemd/system"
nginx_port=6060
nginx_dir="/usr/local/nginxd"
# Color setting
RED='\033[0;31m'
GREEN='\033[1;32m'
GREEN_DARK='\033[0;32m'
GREEN_UNDERLINE='\033[4;32m'
NC='\033[0m'
csudo=""
if command -v sudo > /dev/null; then
csudo="sudo"
fi
# ============================= get input parameters =================================================
# install.sh -v [server | client] -e [yes | no] -i [systemd | service | ...]
# set parameters by default value
interactiveFqdn=yes # [yes | no]
verType=server # [server | client]
initType=systemd # [systemd | service | ...]
while getopts "hv:d:" arg
do
case $arg in
d)
#echo "interactiveFqdn=$OPTARG"
script_dir=$( echo $OPTARG )
;;
h)
echo "Usage: `basename $0` -d scripy_path"
exit 0
;;
?) #unknow option
echo "unkonw argument"
exit 1
;;
esac
done
#echo "verType=${verType} interactiveFqdn=${interactiveFqdn}"
function kill_process() {
pid=$(ps -ef | grep "$1" | grep -v "grep" | awk '{print $2}')
if [ -n "$pid" ]; then
${csudo} kill -9 $pid || :
fi
}
function check_file() {
#check file whether exists
if [ ! -e $1/$2 ];then
echo -e "$1/$2 \033[31mnot exists\033[0m!quit"
fin_result=$fin_result"\033[31m$temp_version\033[0m test failed!\n"
echo -e $fin_result
exit 8
fi
}
function get_package_name() {
var=$1
if [[ $1 =~ 'aarch' ]];then
echo ${var::-21}
else
echo ${var::-17}
fi
}
function check_link() {
#check Link whether exists or broken
if [ -L $1 ] ; then
if [ ! -e $1 ] ; then
echo -e "$1 \033[31Broken link\033[0m"
fin_result=$fin_result"\033[31m$temp_version\033[0m test failed!\n"
echo -e $fin_result
exit 8
fi
else
echo -e "$1 \033[31mnot exists\033[0m!quit"
fin_result=$fin_result"\033[31m$temp_version\033[0m test failed!\n"
echo -e $fin_result
exit 8
fi
}
function check_main_path() {
#check install main dir and all sub dir
main_dir=("" "cfg" "bin" "connector" "driver" "examples" "include" "init.d")
for i in ${main_dir[@]};do
check_file ${install_main_dir} $i
done
if [ "$verMode" == "cluster" ]; then
nginx_main_dir=("admin" "conf" "html" "sbin" "logs")
for i in ${nginx_main_dir[@]};do
check_file ${nginx_dir} $i
done
fi
echo -e "Check main path:\033[32mOK\033[0m!"
}
function check_bin_path() {
# check install bin dir and all sub dir
bin_dir=("taos" "taosd" "taosdemo" "taosdump" "remove.sh" "tarbitrator" "set_core.sh")
for i in ${bin_dir[@]};do
check_file ${sbin_dir} $i
done
lbin_dir=("taos" "taosd" "taosdemo" "taosdump" "rmtaos" "tarbitrator" "set_core")
for i in ${lbin_dir[@]};do
check_link ${bin_link_dir}/$i
done
if [ "$verMode" == "cluster" ]; then
check_file ${nginx_dir}/sbin nginx
fi
echo -e "Check bin path:\033[32mOK\033[0m!"
}
function check_lib_path() {
# check all links
check_link ${lib_link_dir}/libtaos.so
check_link ${lib_link_dir}/libtaos.so.1
if [[ -d ${lib64_link_dir} ]]; then
check_link ${lib64_link_dir}/libtaos.so
check_link ${lib64_link_dir}/libtaos.so.1
fi
echo -e "Check lib path:\033[32mOK\033[0m!"
}
function check_header_path() {
# check all header
header_dir=("taos.h" "taoserror.h")
for i in ${header_dir[@]};do
check_link ${inc_link_dir}/$i
done
echo -e "Check bin path:\033[32mOK\033[0m!"
}
function check_config_dir() {
# check all config
check_file ${cfg_install_dir} taos.cfg
check_file ${install_main_dir}/cfg taos.cfg.org
echo -e "Check conf path:\033[32mOK\033[0m!"
}
function check_log_path() {
# check log path
check_file ${log_dir}
echo -e "Check log path:\033[32mOK\033[0m!"
}
function check_data_path() {
# check data path
check_file ${data_dir}
echo -e "Check data path:\033[32mOK\033[0m!"
}
function install_TDengine() {
cd ${script_dir}
tar zxf $1
temp_version=$(get_package_name $1)
cd $(get_package_name $1)
echo -e "\033[32muninstall TDengine && install TDengine...\033[0m"
rmtaos >/dev/null 2>&1 || echo 'taosd not installed' && echo -e '\n\n' |./install.sh >/dev/null 2>&1
echo -e "\033[32mTDengine has been installed!\033[0m"
echo -e "\033[32mTDengine is starting...\033[0m"
kill_process taos && systemctl start taosd && sleep 10
}
function test_TDengine() {
check_main_path
check_bin_path
check_lib_path
check_header_path
check_config_dir
check_log_path
check_data_path
result=`taos -s 'create database test ;create table test.tt(ts timestamp ,i int);insert into test.tt values(now,11);select * from test.tt' 2>&1 ||:`
if [[ $result =~ "Unable to establish" ]];then
echo -e "\033[31mTDengine connect failed\033[0m"
fin_result=$fin_result"\033[31m$temp_version\033[0m test failed!\n"
echo -e $fin_result
exit 8
fi
echo -e "Check TDengine connect:\033[32mOK\033[0m!"
fin_result=$fin_result"\033[32m$temp_version\033[0m test OK!\n"
}
# ## ==============================Main program starts from here============================
TD_package_name=`ls ${script_dir}/*server*gz |awk -F '/' '{print $NF}' `
temp=`pwd`
for i in $TD_package_name;do
if [[ $i =~ 'enterprise' ]];then
verMode="cluster"
else
verMode=""
fi
cd $temp
install_TDengine $i
test_TDengine
done
echo "============================================================"
echo -e $fin_result

View File

@ -367,6 +367,7 @@ static bool bnMonitorBalance() {
for (int32_t dest = 0; dest < src; dest++) { for (int32_t dest = 0; dest < src; dest++) {
SDnodeObj *pDestDnode = tsBnDnodes.list[dest]; SDnodeObj *pDestDnode = tsBnDnodes.list[dest];
if (bnCheckDnodeInVgroup(pDestDnode, pVgroup)) continue; if (bnCheckDnodeInVgroup(pDestDnode, pVgroup)) continue;
if (taosGetTimestampMs() - pDestDnode->createdTime < 2000) continue;
float destScore = bnTryCalcDnodeScore(pDestDnode, 1); float destScore = bnTryCalcDnodeScore(pDestDnode, 1);
if (srcScore + 0.0001 < destScore) continue; if (srcScore + 0.0001 < destScore) continue;

View File

@ -123,6 +123,8 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
*/ */
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo); bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
bool tscIsTWAQuery(SQueryInfo* pQueryInfo); bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
bool tscIsIrateQuery(SQueryInfo* pQueryInfo);
bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo); bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo);
bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo); bool tscIsSecondStageQuery(SQueryInfo* pQueryInfo);
bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo); bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo);

View File

@ -51,10 +51,10 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset
/* /*
* Class: com_taosdata_jdbc_TSDBJNIConnector * Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getResultTimePrecision * Method: getResultTimePrecisionImp
* Signature: (J)J * Signature: (JJ)I
*/ */
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecision JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecisionImp
(JNIEnv *, jobject, jlong, jlong); (JNIEnv *, jobject, jlong, jlong);
/* /*

View File

@ -113,7 +113,7 @@ static void jniGetGlobalMethod(JNIEnv *env) {
g_rowdataSetFloatFp = (*env)->GetMethodID(env, g_rowdataClass, "setFloat", "(IF)V"); g_rowdataSetFloatFp = (*env)->GetMethodID(env, g_rowdataClass, "setFloat", "(IF)V");
g_rowdataSetDoubleFp = (*env)->GetMethodID(env, g_rowdataClass, "setDouble", "(ID)V"); g_rowdataSetDoubleFp = (*env)->GetMethodID(env, g_rowdataClass, "setDouble", "(ID)V");
g_rowdataSetStringFp = (*env)->GetMethodID(env, g_rowdataClass, "setString", "(ILjava/lang/String;)V"); g_rowdataSetStringFp = (*env)->GetMethodID(env, g_rowdataClass, "setString", "(ILjava/lang/String;)V");
g_rowdataSetTimestampFp = (*env)->GetMethodID(env, g_rowdataClass, "setTimestamp", "(IJ)V"); g_rowdataSetTimestampFp = (*env)->GetMethodID(env, g_rowdataClass, "setTimestamp", "(IJI)V");
g_rowdataSetByteArrayFp = (*env)->GetMethodID(env, g_rowdataClass, "setByteArray", "(I[B)V"); g_rowdataSetByteArrayFp = (*env)->GetMethodID(env, g_rowdataClass, "setByteArray", "(I[B)V");
(*env)->DeleteLocalRef(env, rowdataClass); (*env)->DeleteLocalRef(env, rowdataClass);
@ -519,9 +519,11 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
jniFromNCharToByteArray(env, (char *)row[i], length[i])); jniFromNCharToByteArray(env, (char *)row[i], length[i]));
break; break;
} }
case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_TIMESTAMP: {
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetTimestampFp, i, (jlong) * ((int64_t *)row[i])); int precision = taos_result_precision(result);
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetTimestampFp, i, (jlong) * ((int64_t *)row[i]), precision);
break; break;
}
default: default:
break; break;
} }
@ -672,7 +674,15 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset(J
return (*env)->NewStringUTF(env, (const char *)tsCharset); return (*env)->NewStringUTF(env, (const char *)tsCharset);
} }
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecision(JNIEnv *env, jobject jobj, jlong con, /**
* Get Result Time Precision
* @param env vm
* @param jobj the TSDBJNIConnector java object
* @param con the c connection pointer
* @param res the TAOS_RES object, i.e. the SSqlObject
* @return precision 0:ms 1:us 2:ns
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultTimePrecisionImp(JNIEnv *env, jobject jobj, jlong con,
jlong res) { jlong res) {
TAOS *tscon = (TAOS *)con; TAOS *tscon = (TAOS *)con;
if (tscon == NULL) { if (tscon == NULL) {

View File

@ -423,18 +423,6 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
if(code != TSDB_CODE_SUCCESS) { if(code != TSDB_CODE_SUCCESS) {
return code; return code;
} }
if (pInfo->pMiscInfo->tableType == TSDB_SUPER_TABLE) {
//// code = tscGetTableMeta(pSql, pTableMetaInfo);
//// if (code != TSDB_CODE_SUCCESS) {
//// return code;
//// }
//
// if (!UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) {
// return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
// }
}
} else if (pInfo->type == TSDB_SQL_DROP_DNODE) { } else if (pInfo->type == TSDB_SQL_DROP_DNODE) {
if (pzName->type == TK_STRING) { if (pzName->type == TK_STRING) {
pzName->n = strdequote(pzName->z); pzName->n = strdequote(pzName->z);
@ -772,6 +760,11 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
pCmd->active = pCmd->pQueryInfo; pCmd->active = pCmd->pQueryInfo;
pCmd->command = pCmd->pQueryInfo->command; pCmd->command = pCmd->pQueryInfo->command;
STableMetaInfo* pTableMetaInfo1 = tscGetMetaInfo(pCmd->active, 0);
if (pTableMetaInfo1->pTableMeta != NULL) {
pSql->res.precision = tscGetTableInfo(pTableMetaInfo1->pTableMeta).precision;
}
return TSDB_CODE_SUCCESS; // do not build query message here return TSDB_CODE_SUCCESS; // do not build query message here
} }
@ -956,8 +949,10 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS
static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, bool isStable) { static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, bool isStable) {
const char* msg1 = "invalid column name"; const char* msg1 = "invalid column name";
const char* msg2 = "invalid column type";
const char* msg3 = "not support state_window with group by "; const char* msg3 = "not support state_window with group by ";
const char* msg4 = "function not support for super table query"; const char* msg4 = "function not support for super table query";
const char* msg5 = "not support state_window on tag column";
SStrToken *col = &(pSqlNode->windowstateVal.col) ; SStrToken *col = &(pSqlNode->windowstateVal.col) ;
if (col->z == NULL || col->n <= 0) { if (col->z == NULL || col->n <= 0) {
@ -985,8 +980,10 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
STableMeta* pTableMeta = pTableMetaInfo->pTableMeta; STableMeta* pTableMeta = pTableMetaInfo->pTableMeta;
int32_t numOfCols = tscGetNumOfColumns(pTableMeta); int32_t numOfCols = tscGetNumOfColumns(pTableMeta);
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX || index.columnIndex >= numOfCols) { if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3); return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
} else if (index.columnIndex >= numOfCols) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
} }
SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr; SGroupbyExpr* pGroupExpr = &pQueryInfo->groupbyExpr;
@ -995,8 +992,10 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
} }
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex); SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, index.columnIndex);
if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT || pSchema->type == TSDB_DATA_TYPE_DOUBLE) { if (pSchema->type == TSDB_DATA_TYPE_TIMESTAMP || pSchema->type == TSDB_DATA_TYPE_FLOAT
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); || pSchema->type == TSDB_DATA_TYPE_DOUBLE || pSchema->type == TSDB_DATA_TYPE_NCHAR
|| pSchema->type == TSDB_DATA_TYPE_BINARY) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
} }
tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema); tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema);
@ -2022,8 +2021,10 @@ int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, t
if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) { if (index.columnIndex == TSDB_TBNAME_COLUMN_INDEX) {
SSchema colSchema = *tGetTbnameColumnSchema(); SSchema colSchema = *tGetTbnameColumnSchema();
getColumnName(pItem, colSchema.name, colSchema.name, sizeof(colSchema.name) - 1); char name[TSDB_COL_NAME_LEN] = {0};
getColumnName(pItem, name, colSchema.name, sizeof(colSchema.name) - 1);
tstrncpy(colSchema.name, name, TSDB_COL_NAME_LEN);
/*SExprInfo* pExpr = */tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG, getNewResColId(pCmd)); /*SExprInfo* pExpr = */tscAddFuncInSelectClause(pQueryInfo, startPos, TSDB_FUNC_TAGPRJ, &index, &colSchema, TSDB_COL_TAG, getNewResColId(pCmd));
} else { } else {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex); STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, index.tableIndex);
@ -3062,8 +3063,8 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) {
} }
bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) { bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
const char* msg1 = "TWA/Diff not allowed to apply to super table directly"; const char* msg1 = "TWA/Diff/Derivative/Irate not allowed to apply to super table directly";
const char* msg2 = "TWA/Diff only support group by tbname for super table query"; const char* msg2 = "TWA/Diff/Derivative/Irate only support group by tbname for super table query";
const char* msg3 = "function not support for super table query"; const char* msg3 = "function not support for super table query";
// filter sql function not supported by metric query yet. // filter sql function not supported by metric query yet.
@ -3076,7 +3077,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
} }
} }
if (tscIsTWAQuery(pQueryInfo) || tscIsDiffDerivQuery(pQueryInfo)) { if (tscIsTWAQuery(pQueryInfo) || tscIsDiffDerivQuery(pQueryInfo) || tscIsIrateQuery(pQueryInfo)) {
if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) { if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1); invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
return true; return true;
@ -7787,7 +7788,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
} }
} }
// todo derivate funtion requires ts column exists in subquery // todo derivative function requires ts column exists in subquery
STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta; STableMeta* pTableMeta = tscGetMetaInfo(pQueryInfo, 0)->pTableMeta;
SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, 0); SSchema* pSchema = tscGetTableColumnSchema(pTableMeta, 0);

View File

@ -283,6 +283,7 @@ static int tscUpdateSubscription(STscObj* pObj, SSub* pSub) {
SArray* tables = getTableList(pSql); SArray* tables = getTableList(pSql);
if (tables == NULL) { if (tables == NULL) {
pSub->lastSyncTime = 0; //force to get table list next time
return 0; return 0;
} }
size_t numOfTables = taosArrayGetSize(tables); size_t numOfTables = taosArrayGetSize(tables);
@ -489,7 +490,15 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
SSub *pSub = (SSub *)tsub; SSub *pSub = (SSub *)tsub;
if (pSub == NULL) return NULL; if (pSub == NULL) return NULL;
if (pSub->pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) { if (pSub->pTimer == NULL) {
int64_t duration = taosGetTimestampMs() - pSub->lastConsumeTime;
if (duration < (int64_t)(pSub->interval)) {
tscDebug("subscription consume too frequently, blocking...");
taosMsleep(pSub->interval - (int32_t)duration);
}
}
if (pSub->pSql->cmd.command == TSDB_SQL_RETRIEVE_EMPTY_RESULT) { //may reach here when retireve stable vgroup failed
SSqlObj* pSql = recreateSqlObj(pSub); SSqlObj* pSql = recreateSqlObj(pSub);
if (pSql == NULL) { if (pSql == NULL) {
return NULL; return NULL;
@ -503,6 +512,11 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
pSub->pSql = pSql; pSub->pSql = pSql;
pSql->pSubscription = pSub; pSql->pSubscription = pSub;
// no table list now, force to update it
tscDebug("begin table synchronization");
if (!tscUpdateSubscription(pSub->taos, pSub)) return NULL;
tscDebug("table synchronization completed");
} }
tscSaveSubscriptionProgress(pSub); tscSaveSubscriptionProgress(pSub);
@ -527,14 +541,6 @@ TAOS_RES *taos_consume(TAOS_SUB *tsub) {
tscDebug("subscribe:%s set next round subscribe skey:%"PRId64, pSub->topic, pQueryInfo->window.skey); tscDebug("subscribe:%s set next round subscribe skey:%"PRId64, pSub->topic, pQueryInfo->window.skey);
} }
if (pSub->pTimer == NULL) {
int64_t duration = taosGetTimestampMs() - pSub->lastConsumeTime;
if (duration < (int64_t)(pSub->interval)) {
tscDebug("subscription consume too frequently, blocking...");
taosMsleep(pSub->interval - (int32_t)duration);
}
}
size_t size = taosArrayGetSize(pSub->progress) * sizeof(STableIdInfo); size_t size = taosArrayGetSize(pSub->progress) * sizeof(STableIdInfo);
size += sizeof(SQueryTableMsg) + 4096; size += sizeof(SQueryTableMsg) + 4096;
int code = tscAllocPayload(&pSql->cmd, (int)size); int code = tscAllocPayload(&pSql->cmd, (int)size);

View File

@ -460,6 +460,22 @@ bool tscIsTWAQuery(SQueryInfo* pQueryInfo) {
return false; return false;
} }
bool tscIsIrateQuery(SQueryInfo* pQueryInfo) {
size_t numOfExprs = tscNumOfExprs(pQueryInfo);
for (int32_t i = 0; i < numOfExprs; ++i) {
SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
if (pExpr == NULL) {
continue;
}
if (pExpr->base.functionId == TSDB_FUNC_IRATE) {
return true;
}
}
return false;
}
bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) { bool tscIsSessionWindowQuery(SQueryInfo* pQueryInfo) {
return pQueryInfo->sessionWindow.gap > 0; return pQueryInfo->sessionWindow.gap > 0;
} }
@ -3477,6 +3493,7 @@ static void tscSubqueryRetrieveCallback(void* param, TAOS_RES* tres, int code) {
if (pSql->res.code == TSDB_CODE_SUCCESS) { if (pSql->res.code == TSDB_CODE_SUCCESS) {
(*pSql->fp)(pParentSql->param, pParentSql, pParentSql->res.numOfRows); (*pSql->fp)(pParentSql->param, pParentSql, pParentSql->res.numOfRows);
} else { } else {
pParentSql->res.code = pSql->res.code;
tscAsyncResultOnError(pParentSql); tscAsyncResultOnError(pParentSql);
} }
} }

View File

@ -122,7 +122,6 @@
<exclude>**/FailOverTest.java</exclude> <exclude>**/FailOverTest.java</exclude>
<exclude>**/InvalidResultSetPointerTest.java</exclude> <exclude>**/InvalidResultSetPointerTest.java</exclude>
<exclude>**/RestfulConnectionTest.java</exclude> <exclude>**/RestfulConnectionTest.java</exclude>
<exclude>**/TD4144Test.java</exclude>
<exclude>**/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java</exclude> <exclude>**/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java</exclude>
</excludes> </excludes>
<testFailureIgnore>true</testFailureIgnore> <testFailureIgnore>true</testFailureIgnore>

View File

@ -1,5 +1,7 @@
package com.taosdata.jdbc; package com.taosdata.jdbc;
import com.taosdata.jdbc.rs.enums.TimestampFormat;
import java.sql.*; import java.sql.*;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.Map; import java.util.Map;
@ -18,7 +20,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
for (String propName : propNames) { for (String propName : propNames) {
clientInfoProps.setProperty(propName, properties.getProperty(propName)); clientInfoProps.setProperty(propName, properties.getProperty(propName));
} }
String timestampFormat = properties.getProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, "STRING"); String timestampFormat = properties.getProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, String.valueOf(TimestampFormat.STRING));
clientInfoProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, timestampFormat); clientInfoProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT, timestampFormat);
} }
@ -516,7 +518,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
public void abort(Executor executor) throws SQLException { public void abort(Executor executor) throws SQLException {
if (isClosed()) if (isClosed())
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
// do nothing // do nothing
} }

View File

@ -9,8 +9,6 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement
protected List<String> batchedArgs; protected List<String> batchedArgs;
private int fetchSize; private int fetchSize;
@Override @Override
public abstract ResultSet executeQuery(String sql) throws SQLException; public abstract ResultSet executeQuery(String sql) throws SQLException;

View File

@ -32,6 +32,7 @@ public class TSDBError {
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_SQL, "invalid sql"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_INVALID_SQL, "invalid sql");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE, "numeric value out of range");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE, "unknown taos type in tdengine"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE, "unknown taos type in tdengine");
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PERCISION, "unknown timestamp precision");
/**************************************************/ /**************************************************/
TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNKNOWN, "unknown error");

View File

@ -25,6 +25,7 @@ public class TSDBErrorNumbers {
public static final int ERROR_INVALID_SQL = 0x2313; // invalid sql public static final int ERROR_INVALID_SQL = 0x2313; // invalid sql
public static final int ERROR_NUMERIC_VALUE_OUT_OF_RANGE = 0x2314; // numeric value out of range public static final int ERROR_NUMERIC_VALUE_OUT_OF_RANGE = 0x2314; // numeric value out of range
public static final int ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE = 0x2315; //unknown taos type in tdengine public static final int ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE = 0x2315; //unknown taos type in tdengine
public static final int ERROR_UNKNOWN_TIMESTAMP_PERCISION = 0x2316; // unknown timestamp precision
public static final int ERROR_UNKNOWN = 0x2350; //unknown error public static final int ERROR_UNKNOWN = 0x2350; //unknown error
@ -62,6 +63,7 @@ public class TSDBErrorNumbers {
errorNumbers.add(ERROR_INVALID_SQL); errorNumbers.add(ERROR_INVALID_SQL);
errorNumbers.add(ERROR_NUMERIC_VALUE_OUT_OF_RANGE); errorNumbers.add(ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE); errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE);
errorNumbers.add(ERROR_UNKNOWN_TIMESTAMP_PERCISION);
/*****************************************************/ /*****************************************************/
errorNumbers.add(ERROR_SUBSCRIBE_FAILED); errorNumbers.add(ERROR_SUBSCRIBE_FAILED);

View File

@ -216,6 +216,16 @@ public class TSDBJNIConnector {
private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData); private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData);
/**
* Get Result Time Precision.
* @return 0: ms, 1: us, 2: ns
*/
public int getResultTimePrecision(long sqlObj) {
return this.getResultTimePrecisionImp(this.taos, sqlObj);
}
private native int getResultTimePrecisionImp(long connection, long result);
/** /**
* Execute close operation from C to release connection pointer by JNI * Execute close operation from C to release connection pointer by JNI
* *

View File

@ -38,7 +38,6 @@ import java.util.regex.Pattern;
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 ArrayList<ColumnInfo> colData; private ArrayList<ColumnInfo> colData;
private ArrayList<TableTagInfo> tableTags; private ArrayList<TableTagInfo> tableTags;
@ -47,8 +46,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
private String tableName; private String tableName;
private long nativeStmtHandle = 0; private long nativeStmtHandle = 0;
private volatile TSDBParameterMetaData parameterMetaData;
TSDBPreparedStatement(TSDBConnection connection, String sql) { TSDBPreparedStatement(TSDBConnection connection, String sql) {
super(connection); super(connection);
init(sql); init(sql);
@ -61,7 +58,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
} }
} }
parameters = new Object[parameterCnt]; parameters = new Object[parameterCnt];
this.isPrepared = true;
} }
if (parameterCnt > 1) { if (parameterCnt > 1) {
@ -76,11 +72,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
preprocessSql(); preprocessSql();
} }
@Override
public int[] executeBatch() throws SQLException {
return super.executeBatch();
}
/* /*
* Some of the SQLs sent by other popular frameworks or tools like Spark, contains syntax that cannot be parsed by * Some of the SQLs sent by other popular frameworks or tools like Spark, contains syntax that cannot be parsed by
* the TDengine client. Thus, some simple parsers/filters are intentionally added in this JDBC implementation in * the TDengine client. Thus, some simple parsers/filters are intentionally added in this JDBC implementation in
@ -137,29 +128,15 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
/***** for inner queries *****/ /***** for inner queries *****/
} }
/**
* Populate parameters into prepared sql statements
*
* @return a string of the native sql statement for TSDB
*/
private String getNativeSql(String rawSql) throws SQLException {
return Utils.getNativeSql(rawSql, this.parameters);
}
@Override @Override
public ResultSet executeQuery() throws SQLException { public ResultSet executeQuery() throws SQLException {
if (!isPrepared) final String sql = Utils.getNativeSql(this.rawSql, this.parameters);
return executeQuery(this.rawSql);
final String sql = getNativeSql(this.rawSql);
return executeQuery(sql); return executeQuery(sql);
} }
@Override @Override
public int executeUpdate() throws SQLException { public int executeUpdate() throws SQLException {
if (!isPrepared) String sql = Utils.getNativeSql(this.rawSql, this.parameters);
return executeUpdate(this.rawSql);
String sql = getNativeSql(this.rawSql);
return executeUpdate(sql); return executeUpdate(sql);
} }
@ -282,26 +259,15 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override @Override
public boolean execute() throws SQLException { public boolean execute() throws SQLException {
if (!isPrepared) final String sql = Utils.getNativeSql(this.rawSql, this.parameters);
return execute(this.rawSql);
final String sql = getNativeSql(this.rawSql);
return execute(sql); return execute(sql);
} }
@Override @Override
public void addBatch() throws SQLException { public void addBatch() throws SQLException {
if (this.batchedArgs == null) { String sql = Utils.getNativeSql(this.rawSql, this.parameters);
batchedArgs = new ArrayList<>();
}
if (!isPrepared) {
addBatch(this.rawSql);
} else {
String sql = this.getConnection().nativeSQL(this.rawSql);
addBatch(sql); addBatch(sql);
} }
}
@Override @Override
public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException { public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {

View File

@ -147,30 +147,14 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return Integer.parseInt((String) obj); return Integer.parseInt((String) obj);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
Byte value = (byte) obj; return parseUnsignedTinyIntToInt(obj);
if (value < 0) case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); return parseUnsignedSmallIntToInt(obj);
return value; case TSDBConstants.TSDB_DATA_TYPE_UINT:
} return parseUnsignedIntegerToInt(obj);
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: { case TSDBConstants.TSDB_DATA_TYPE_UBIGINT:
short value = (short) obj; return parseUnsignedBigIntToInt(obj);
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
}
case TSDBConstants.TSDB_DATA_TYPE_UINT: {
int value = (int) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
}
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
long value = (long) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return Long.valueOf(value).intValue();
}
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_FLOAT:
return ((Float) obj).intValue(); return ((Float) obj).intValue();
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
@ -180,6 +164,35 @@ public class TSDBResultSetRowData {
} }
} }
private byte parseUnsignedTinyIntToInt(Object obj) throws SQLException {
byte value = (byte) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
}
private short parseUnsignedSmallIntToInt(Object obj) throws SQLException {
short value = (short) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
}
private int parseUnsignedIntegerToInt(Object obj) throws SQLException {
int value = (int) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return value;
}
private int parseUnsignedBigIntToInt(Object obj) throws SQLException {
long value = (long) obj;
if (value < 0)
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE);
return Long.valueOf(value).intValue();
}
/** /**
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/ */
@ -216,7 +229,7 @@ public class TSDBResultSetRowData {
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return Long.parseLong((String) obj); return Long.parseLong((String) obj);
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: {
Byte value = (byte) obj; byte value = (byte) 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 value; return value;
@ -414,26 +427,40 @@ public class TSDBResultSetRowData {
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api * $$$ 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) { public void setTimestampValue(int colIndex, long value) {
setTimestamp(colIndex - 1, value); setTimestamp(colIndex - 1, value, 0);
} }
/** /**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations * !!! this method is invoked by JNI method and the index start from 0 in C implementations
* @param precision 0 : ms, 1 : us, 2 : ns
*/ */
public void setTimestamp(int col, long ts) { public void setTimestamp(int col, long ts, int precision) {
//TODO: this implementation contains logical error long milliseconds = 0;
// when precision is us the (long ts) is 16 digital number int fracNanoseconds = 0;
// when precision is ms, the (long ts) is 13 digital number switch (precision) {
// we need a JNI function like this: case 0: {
// public void setTimestamp(int col, long epochSecond, long nanoAdjustment) milliseconds = ts;
if (ts < 1_0000_0000_0000_0L) { fracNanoseconds = (int)(ts*1_000_000%1_000_000_000);
data.set(col, new Timestamp(ts)); break;
} else {
long epochSec = ts / 1000_000l;
long nanoAdjustment = ts % 1000_000l * 1000l;
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
data.set(col, timestamp);
} }
case 1: {
milliseconds = ts/1_000;
fracNanoseconds = (int)(ts*1_000%1_000_000_000);
break;
}
case 2: {
milliseconds = ts/1_000_000;
fracNanoseconds = (int)(ts%1_000_000_000);
break;
}
default: {
throw new IllegalArgumentException("precision is not valid. precision: " + precision);
}
}
Timestamp tsObj = new Timestamp(milliseconds);
tsObj.setNanos(fracNanoseconds);
data.set(col, tsObj);
} }
public Timestamp getTimestamp(int col, int nativeType) { public Timestamp getTimestamp(int col, int nativeType) {

View File

@ -0,0 +1,8 @@
package com.taosdata.jdbc.enums;
public enum TimestampPrecision {
MS,
US,
NS,
UNKNOWN
}

View File

@ -44,7 +44,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
if (!isPrepared) if (!isPrepared)
return executeQuery(this.rawSql); return executeQuery(this.rawSql);
final String sql = getNativeSql(this.rawSql); final String sql = Utils.getNativeSql(this.rawSql, this.parameters);
return executeQuery(sql); return executeQuery(sql);
} }
@ -55,20 +55,10 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
if (!isPrepared) if (!isPrepared)
return executeUpdate(this.rawSql); return executeUpdate(this.rawSql);
final String sql = getNativeSql(this.rawSql); final String sql = Utils.getNativeSql(rawSql, this.parameters);
return executeUpdate(sql); return executeUpdate(sql);
} }
/****
* 将rawSql转换成一条可执行的sql语句使用属性parameters中的变脸进行替换
* 对于insert into ?.? (?,?,?) using ?.? (?,?,?) tags(?, ?, ?) values(?, ?, ?)
* @param rawSql可能是insertselect或其他使用?做占位符
* @return
*/
private String getNativeSql(String rawSql) {
return Utils.getNativeSql(rawSql, this.parameters);
}
@Override @Override
public void setNull(int parameterIndex, int sqlType) throws SQLException { public void setNull(int parameterIndex, int sqlType) throws SQLException {
if (isClosed()) if (isClosed())
@ -224,16 +214,13 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
if (!isPrepared) if (!isPrepared)
return execute(this.rawSql); return execute(this.rawSql);
final String sql = getNativeSql(rawSql); final String sql = Utils.getNativeSql(rawSql, this.parameters);
return execute(sql); return execute(sql);
} }
@Override @Override
public void addBatch() throws SQLException { public void addBatch() throws SQLException {
if (isClosed()) final String sql = Utils.getNativeSql(rawSql, this.parameters);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED);
final String sql = getNativeSql(this.rawSql);
addBatch(sql); addBatch(sql);
} }

View File

@ -6,6 +6,8 @@ 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.*; import com.taosdata.jdbc.*;
import com.taosdata.jdbc.enums.TimestampPrecision;
import com.taosdata.jdbc.rs.enums.TimestampFormat;
import com.taosdata.jdbc.utils.Utils; import com.taosdata.jdbc.utils.Utils;
import java.math.BigDecimal; import java.math.BigDecimal;
@ -46,6 +48,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
columnNames.clear(); columnNames.clear();
columns.clear(); columns.clear();
this.resultSet.clear(); this.resultSet.clear();
this.metaData = new RestfulResultSetMetaData(this.database, null, this);
return; return;
} }
// get head // get head
@ -131,7 +134,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
} }
} }
private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException { private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException {
switch (taosType) { switch (taosType) {
case TSDBConstants.TSDB_DATA_TYPE_NULL: case TSDBConstants.TSDB_DATA_TYPE_NULL:
@ -150,44 +152,8 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
return row.getFloat(colIndex); return row.getFloat(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE:
return row.getDouble(colIndex); return row.getDouble(colIndex);
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
if (row.get(colIndex) == null) return parseTimestampColumnData(row, colIndex);
return null;
String timestampFormat = this.statement.getConnection().getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT);
if ("TIMESTAMP".equalsIgnoreCase(timestampFormat)) {
Long value = row.getLong(colIndex);
//TODO: this implementation has bug if the timestamp bigger than 9999_9999_9999_9
if (value < 1_0000_0000_0000_0L)
return new Timestamp(value);
long epochSec = value / 1000_000l;
long nanoAdjustment = value % 1000_000l * 1000l;
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
}
if ("UTC".equalsIgnoreCase(timestampFormat)) {
String value = row.getString(colIndex);
long epochSec = Timestamp.valueOf(value.substring(0, 19).replace("T", " ")).getTime() / 1000;
int fractionalSec = Integer.parseInt(value.substring(20, value.length() - 5));
long nanoAdjustment = 0;
if (value.length() > 28) {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00
nanoAdjustment = fractionalSec * 1000l;
} else {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00
nanoAdjustment = fractionalSec * 1000_000l;
}
ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5));
Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant();
return Timestamp.from(instant);
}
String value = row.getString(colIndex);
if (value.length() <= 23) // ms timestamp: yyyy-MM-dd HH:mm:ss.SSS
return row.getTimestamp(colIndex);
// us timestamp: yyyy-MM-dd HH:mm:ss.SSSSSS
long epochSec = Timestamp.valueOf(value.substring(0, 19)).getTime() / 1000;
long nanoAdjustment = Integer.parseInt(value.substring(20)) * 1000l;
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
return timestamp;
}
case TSDBConstants.TSDB_DATA_TYPE_BINARY: case TSDBConstants.TSDB_DATA_TYPE_BINARY:
return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes(); return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes();
case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
@ -197,7 +163,66 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
} }
} }
public class Field { private Timestamp parseTimestampColumnData(JSONArray row, int colIndex) throws SQLException {
if (row.get(colIndex) == null)
return null;
String tsFormatUpperCase = this.statement.getConnection().getClientInfo(TSDBDriver.PROPERTY_KEY_TIMESTAMP_FORMAT).toUpperCase();
TimestampFormat timestampFormat = TimestampFormat.valueOf(tsFormatUpperCase);
switch (timestampFormat) {
case TIMESTAMP: {
Long value = row.getLong(colIndex);
//TODO: this implementation has bug if the timestamp bigger than 9999_9999_9999_9
if (value < 1_0000_0000_0000_0L)
return new Timestamp(value);
long epochSec = value / 1000_000l;
long nanoAdjustment = value % 1000_000l * 1000l;
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
}
case UTC: {
String value = row.getString(colIndex);
long epochSec = Timestamp.valueOf(value.substring(0, 19).replace("T", " ")).getTime() / 1000;
int fractionalSec = Integer.parseInt(value.substring(20, value.length() - 5));
long nanoAdjustment;
if (value.length() > 31) {
// ns timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSSSSS+0x00
nanoAdjustment = fractionalSec;
} else if (value.length() > 28) {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSSSSS+0x00
nanoAdjustment = fractionalSec * 1000L;
} else {
// ms timestamp: yyyy-MM-ddTHH:mm:ss.SSS+0x00
nanoAdjustment = fractionalSec * 1000_000L;
}
ZoneOffset zoneOffset = ZoneOffset.of(value.substring(value.length() - 5));
Instant instant = Instant.ofEpochSecond(epochSec, nanoAdjustment).atOffset(zoneOffset).toInstant();
return Timestamp.from(instant);
}
case STRING:
default: {
String value = row.getString(colIndex);
TimestampPrecision precision = Utils.guessTimestampPrecision(value);
if (precision == TimestampPrecision.MS) {
// ms timestamp: yyyy-MM-dd HH:mm:ss.SSS
return row.getTimestamp(colIndex);
}
if (precision == TimestampPrecision.US) {
// us timestamp: yyyy-MM-dd HH:mm:ss.SSSSSS
long epochSec = Timestamp.valueOf(value.substring(0, 19)).getTime() / 1000;
long nanoAdjustment = Integer.parseInt(value.substring(20)) * 1000L;
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
}
if (precision == TimestampPrecision.NS) {
// ms timestamp: yyyy-MM-dd HH:mm:ss.SSSSSSSSS
long epochSec = Timestamp.valueOf(value.substring(0, 19)).getTime() / 1000;
long nanoAdjustment = Integer.parseInt(value.substring(20));
return Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
}
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN_TIMESTAMP_PERCISION);
}
}
}
public static class Field {
String name; String name;
int type; int type;
int length; int length;
@ -211,6 +236,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
this.note = note; this.note = note;
this.taos_type = taos_type; this.taos_type = taos_type;
} }
} }
@Override @Override
@ -334,6 +360,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet {
wasNull = true; wasNull = true;
return 0; return 0;
} }
wasNull = false; wasNull = false;
if (value instanceof Timestamp) { if (value instanceof Timestamp) {
return ((Timestamp) value).getTime(); return ((Timestamp) value).getTime();

View File

@ -8,20 +8,22 @@ import java.sql.SQLException;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types; import java.sql.Types;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMetaData { public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMetaData {
private final String database; private final String database;
private ArrayList<RestfulResultSet.Field> fields; private List<RestfulResultSet.Field> fields;
private final RestfulResultSet resultSet; private final RestfulResultSet resultSet;
public RestfulResultSetMetaData(String database, ArrayList<RestfulResultSet.Field> fields, RestfulResultSet resultSet) { public RestfulResultSetMetaData(String database, ArrayList<RestfulResultSet.Field> fields, RestfulResultSet resultSet) {
this.database = database; this.database = database;
this.fields = fields; this.fields = fields == null ? Collections.emptyList() : fields;
this.resultSet = resultSet; this.resultSet = resultSet;
} }
public ArrayList<RestfulResultSet.Field> getFields() { public List<RestfulResultSet.Field> getFields() {
return fields; return fields;
} }

View File

@ -0,0 +1,7 @@
package com.taosdata.jdbc.rs.enums;
public enum TimestampFormat {
STRING,
TIMESTAMP,
UTC
}

View File

@ -16,13 +16,12 @@ import org.apache.http.protocol.HTTP;
import org.apache.http.protocol.HttpContext; import org.apache.http.protocol.HttpContext;
import org.apache.http.util.EntityUtils; import org.apache.http.util.EntityUtils;
import java.nio.charset.Charset; import java.nio.charset.StandardCharsets;
public class HttpClientPoolUtil { public class HttpClientPoolUtil {
private static final String DEFAULT_CONTENT_TYPE = "application/json"; private static final String DEFAULT_CONTENT_TYPE = "application/json";
private static final String DEFAULT_TOKEN = "cm9vdDp0YW9zZGF0YQ==";
private static final int DEFAULT_TIME_OUT = 15000; private static final int DEFAULT_TIME_OUT = 15000;
private static final int DEFAULT_MAX_PER_ROUTE = 32; private static final int DEFAULT_MAX_PER_ROUTE = 32;
private static final int DEFAULT_MAX_TOTAL = 1000; private static final int DEFAULT_MAX_TOTAL = 1000;
@ -80,7 +79,7 @@ public class HttpClientPoolUtil {
method.setHeader("Connection", "keep-alive"); method.setHeader("Connection", "keep-alive");
method.setHeader("Authorization", "Taosd " + token); method.setHeader("Authorization", "Taosd " + token);
method.setEntity(new StringEntity(data, Charset.forName("UTF-8"))); method.setEntity(new StringEntity(data, StandardCharsets.UTF_8));
HttpContext context = HttpClientContext.create(); HttpContext context = HttpClientContext.create();
CloseableHttpResponse httpResponse = httpClient.execute(method, context); CloseableHttpResponse httpResponse = httpClient.execute(method, context);
httpEntity = httpResponse.getEntity(); httpEntity = httpResponse.getEntity();
@ -165,28 +164,18 @@ public class HttpClientPoolUtil {
httpEntity = httpResponse.getEntity(); httpEntity = httpResponse.getEntity();
if (httpEntity != null) { if (httpEntity != null) {
responseBody = EntityUtils.toString(httpEntity, "UTF-8"); responseBody = EntityUtils.toString(httpEntity, "UTF-8");
// logger.info("请求URL: " + uri + "+ 返回状态码:" + httpResponse.getStatusLine().getStatusCode());
} }
} catch (Exception e) { } catch (Exception e) {
if (method != null) { if (method != null) {
method.abort(); method.abort();
} }
e.printStackTrace(); e.printStackTrace();
// logger.error("execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):"
// + (System.currentTimeMillis() - startTime));
System.out.println("log:调用 HttpClientPoolUtil execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):"
+ (System.currentTimeMillis() - startTime));
} finally { } finally {
if (httpEntity != null) { if (httpEntity != null) {
try { try {
EntityUtils.consumeQuietly(httpEntity); EntityUtils.consumeQuietly(httpEntity);
} catch (Exception e) { } catch (Exception e) {
// e.printStackTrace(); new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace();
// logger.error("close response exception, url:" + uri + ", exception:" + e.toString()
// + ",cost time(ms):" + (System.currentTimeMillis() - startTime));
new Exception("close response exception, url:" + uri + ", exception:" + e.toString()
+ ",cost time(ms):" + (System.currentTimeMillis() - startTime))
.printStackTrace();
} }
} }
} }

View File

@ -3,14 +3,13 @@ package com.taosdata.jdbc.utils;
import com.google.common.collect.Range; import com.google.common.collect.Range;
import com.google.common.collect.RangeSet; import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet; import com.google.common.collect.TreeRangeSet;
import com.taosdata.jdbc.enums.TimestampPrecision;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.sql.Date; import java.sql.Date;
import java.sql.Time; import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeFormatterBuilder;
import java.time.format.DateTimeParseException; import java.time.format.DateTimeParseException;
@ -25,39 +24,52 @@ public class Utils {
private static Pattern ptn = Pattern.compile(".*?'"); private static Pattern ptn = Pattern.compile(".*?'");
private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder() private static final DateTimeFormatter milliSecFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd HH:mm:ss.SSS").toFormatter();
.appendPattern("yyyy-MM-dd HH:mm:ss.SSS").toFormatter(); private static final DateTimeFormatter microSecFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSS").toFormatter();
private static final DateTimeFormatter formatter2 = new DateTimeFormatterBuilder() private static final DateTimeFormatter nanoSecFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS").toFormatter();
.appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSS").toFormatter();
public static Time parseTime(String timestampStr) throws DateTimeParseException { public static Time parseTime(String timestampStr) throws DateTimeParseException {
LocalTime time; LocalDateTime dateTime = parseLocalDateTime(timestampStr);
try { return dateTime != null ? Time.valueOf(dateTime.toLocalTime()) : null;
time = LocalTime.parse(timestampStr, formatter);
} catch (DateTimeParseException e) {
time = LocalTime.parse(timestampStr, formatter2);
}
return Time.valueOf(time);
} }
public static Date parseDate(String timestampStr) throws DateTimeParseException { public static Date parseDate(String timestampStr) {
LocalDate date; LocalDateTime dateTime = parseLocalDateTime(timestampStr);
try { return dateTime != null ? Date.valueOf(String.valueOf(dateTime)) : null;
date = LocalDate.parse(timestampStr, formatter);
} catch (DateTimeParseException e) {
date = LocalDate.parse(timestampStr, formatter2);
}
return Date.valueOf(date);
} }
public static Timestamp parseTimestamp(String timeStampStr) { public static Timestamp parseTimestamp(String timeStampStr) {
LocalDateTime dateTime; LocalDateTime dateTime = parseLocalDateTime(timeStampStr);
try { return dateTime != null ? Timestamp.valueOf(dateTime) : null;
dateTime = LocalDateTime.parse(timeStampStr, formatter);
} catch (DateTimeParseException e) {
dateTime = LocalDateTime.parse(timeStampStr, formatter2);
} }
return Timestamp.valueOf(dateTime);
private static LocalDateTime parseLocalDateTime(String timeStampStr) {
try {
return parseMilliSecTimestamp(timeStampStr);
} catch (DateTimeParseException e) {
try {
return parseMicroSecTimestamp(timeStampStr);
} catch (DateTimeParseException ee) {
try {
return parseNanoSecTimestamp(timeStampStr);
} catch (DateTimeParseException eee) {
eee.printStackTrace();
}
}
}
return null;
}
private static LocalDateTime parseMilliSecTimestamp(String timeStampStr) throws DateTimeParseException {
return LocalDateTime.parse(timeStampStr, milliSecFormatter);
}
private static LocalDateTime parseMicroSecTimestamp(String timeStampStr) throws DateTimeParseException {
return LocalDateTime.parse(timeStampStr, microSecFormatter);
}
private static LocalDateTime parseNanoSecTimestamp(String timeStampStr) throws DateTimeParseException {
return LocalDateTime.parse(timeStampStr, nanoSecFormatter);
} }
public static String escapeSingleQuota(String origin) { public static String escapeSingleQuota(String origin) {
@ -93,6 +105,8 @@ public class Utils {
} }
public static String getNativeSql(String rawSql, Object[] parameters) { public static String getNativeSql(String rawSql, Object[] parameters) {
if (parameters == null || !rawSql.contains("?"))
return rawSql;
// 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[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)", "where\\s*.*"};
@ -167,13 +181,47 @@ public class Utils {
}).collect(Collectors.joining()); }).collect(Collectors.joining());
} }
public static String formatTimestamp(Timestamp timestamp) { public static String formatTimestamp(Timestamp timestamp) {
int nanos = timestamp.getNanos(); int nanos = timestamp.getNanos();
if (nanos % 1000000l != 0) if (nanos % 1000000l != 0)
return timestamp.toLocalDateTime().format(formatter2); return timestamp.toLocalDateTime().format(microSecFormatter);
return timestamp.toLocalDateTime().format(formatter); return timestamp.toLocalDateTime().format(milliSecFormatter);
} }
public static TimestampPrecision guessTimestampPrecision(String value) {
if (isMilliSecFormat(value))
return TimestampPrecision.MS;
if (isMicroSecFormat(value))
return TimestampPrecision.US;
if (isNanoSecFormat(value))
return TimestampPrecision.NS;
return TimestampPrecision.UNKNOWN;
}
private static boolean isMilliSecFormat(String timestampStr) {
try {
milliSecFormatter.parse(timestampStr);
} catch (DateTimeParseException e) {
return false;
}
return true;
}
private static boolean isMicroSecFormat(String timestampStr) {
try {
microSecFormatter.parse(timestampStr);
} catch (DateTimeParseException e) {
return false;
}
return true;
}
private static boolean isNanoSecFormat(String timestampStr) {
try {
nanoSecFormatter.parse(timestampStr);
} catch (DateTimeParseException e) {
return false;
}
return true;
}
} }

View File

@ -1,12 +1,17 @@
package com.taosdata.jdbc; package com.taosdata.jdbc;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLWarning; import java.sql.SQLWarning;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
public class TSDBJNIConnectorTest { public class TSDBJNIConnectorTest {
private static TSDBResultSetRowData rowData; private static TSDBResultSetRowData rowData;
@ -14,17 +19,68 @@ public class TSDBJNIConnectorTest {
@Test @Test
public void test() { public void test() {
try { try {
try {
//change sleepSeconds when debugging with attach to process to find PID
int sleepSeconds = -1;
if (sleepSeconds>0) {
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
String jvmName = runtimeBean.getName();
long pid = Long.valueOf(jvmName.split("@")[0]);
System.out.println("JVM PID = " + pid);
Thread.sleep(sleepSeconds*1000);
}
}
catch (Exception e) {
e.printStackTrace();
}
// init // init
TSDBJNIConnector.init("/etc/taos/taos.cfg", null, null, null); TSDBJNIConnector.init("/etc/taos", null, null, null);
// connect // connect
TSDBJNIConnector connector = new TSDBJNIConnector(); TSDBJNIConnector connector = new TSDBJNIConnector();
connector.connect("127.0.0.1", 6030, "unsign_jni", "root", "taosdata"); connector.connect("127.0.0.1", 6030, null, "root", "taosdata");
// setup
String setupSqlStrs[] = {"create database if not exists d precision \"us\"",
"create table if not exists d.t(ts timestamp, f int)",
"create database if not exists d2",
"create table if not exists d2.t2(ts timestamp, f int)",
"insert into d.t values(now+100s, 100)",
"insert into d2.t2 values(now+200s, 200)"
};
for (String setupSqlStr : setupSqlStrs) {
long setupSql = connector.executeQuery(setupSqlStr);
assertEquals(0, connector.getResultTimePrecision(setupSql));
if (connector.isUpdateQuery(setupSql)) {
connector.freeResultSet(setupSql);
}
}
{
long sqlObj1 = connector.executeQuery("select * from d2.t2");
assertEquals(0, connector.getResultTimePrecision(sqlObj1));
List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(sqlObj1, columnMetaDataList);
rowData = new TSDBResultSetRowData(columnMetaDataList.size());
assertTrue(next(connector, sqlObj1));
assertEquals(0, connector.getResultTimePrecision(sqlObj1));
connector.freeResultSet(sqlObj1);
}
// executeQuery // executeQuery
long pSql = connector.executeQuery("select * from unsign_jni.us_table"); long pSql = connector.executeQuery("select * from d.t");
if (connector.isUpdateQuery(pSql)) { if (connector.isUpdateQuery(pSql)) {
connector.freeResultSet(pSql); connector.freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
} }
assertEquals(1, connector.getResultTimePrecision(pSql));
// get schema // get schema
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(pSql, columnMetaDataList); int code = connector.getSchemaMetaData(pSql, columnMetaDataList);
@ -37,6 +93,8 @@ public class TSDBJNIConnectorTest {
if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
} }
assertEquals(1, connector.getResultTimePrecision(pSql));
int columnSize = columnMetaDataList.size(); int columnSize = columnMetaDataList.size();
// print metadata // print metadata
for (int i = 0; i < columnSize; i++) { for (int i = 0; i < columnSize; i++) {
@ -45,9 +103,8 @@ 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()); assertEquals(1, connector.getResultTimePrecision(pSql));
// 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

@ -5,7 +5,6 @@ import org.junit.*;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.*; import java.sql.*;
import java.time.LocalTime;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Random; import java.util.Random;
@ -15,6 +14,7 @@ public class TSDBPreparedStatementTest {
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 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 final String dbname = "test_pstmt_jni";
private PreparedStatement pstmt_insert; private PreparedStatement pstmt_insert;
private PreparedStatement pstmt_select; private PreparedStatement pstmt_select;
@ -585,15 +585,14 @@ public class TSDBPreparedStatementTest {
rows++; rows++;
} }
Assert.assertEquals(numOfRows, rows); Assert.assertEquals(numOfRows, rows);
} }
@Test @Test(expected = SQLException.class)
public void createTwoSameDbTest() throws SQLException { public void createTwoSameDbTest() throws SQLException {
// when
Statement stmt = conn.createStatement(); Statement stmt = conn.createStatement();
stmt.execute("create database dbtest"); stmt.execute("create database dbtest");
Assert.assertThrows(SQLException.class, () -> stmt.execute("create database dbtest")); stmt.execute("create database dbtest");
} }
@Test @Test
@ -1097,9 +1096,9 @@ public class TSDBPreparedStatementTest {
try { try {
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 " + dbname);
stmt.execute("create database if not exists test_pstmt_jni"); stmt.execute("create database if not exists " + dbname);
stmt.execute("use test_pstmt_jni"); stmt.execute("use " + dbname);
} }
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
@ -1109,6 +1108,9 @@ public class TSDBPreparedStatementTest {
@AfterClass @AfterClass
public static void afterClass() { public static void afterClass() {
try { try {
Statement statement = conn.createStatement();
statement.execute("drop database if exists " + dbname);
statement.close();
if (conn != null) if (conn != null)
conn.close(); conn.close();
} catch (SQLException e) { } catch (SQLException e) {

View File

@ -7,56 +7,64 @@ import org.junit.*;
import java.sql.*; import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class TD4174Test { public class DoubleQuoteInSqlTest {
private Connection conn;
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static final String dbname = "td4174";
private Connection conn;
@Test @Test
public void test() { public void test() {
// given
long ts = System.currentTimeMillis(); long ts = System.currentTimeMillis();
try (PreparedStatement pstmt = conn.prepareStatement("insert into weather values(" + ts + ", ?)")) {
JSONObject value = new JSONObject(); JSONObject value = new JSONObject();
value.put("name", "John Smith"); value.put("name", "John Smith");
value.put("age", 20); value.put("age", 20);
Assert.assertEquals("{\"name\":\"John Smith\",\"age\":20}",value.toJSONString());
pstmt.setString(1, value.toJSONString());
int ret = pstmt.executeUpdate(); // when
Assert.assertEquals(1, ret); int ret = 0;
try (PreparedStatement pstmt = conn.prepareStatement("insert into weather values(" + ts + ", ?)")) {
pstmt.setString(1, value.toJSONString());
ret = pstmt.executeUpdate();
} catch (SQLException e) { } catch (SQLException e) {
e.printStackTrace(); e.printStackTrace();
} }
}
public static void main(String[] args) { // then
JSONObject value = new JSONObject(); Assert.assertEquals("{\"name\":\"John Smith\",\"age\":20}", value.toJSONString());
value.put("name", "John Smith"); Assert.assertEquals(1, ret);
value.put("age", 20);
System.out.println(value.toJSONString());
} }
@Before @Before
public void before() throws SQLException { public void before() {
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
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");
try {
conn = DriverManager.getConnection(url, properties); conn = DriverManager.getConnection(url, properties);
try (Statement stmt = conn.createStatement()) { Statement stmt = conn.createStatement();
stmt.execute("drop database if exists td4174"); stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists td4174"); stmt.execute("create database if not exists " + dbname);
stmt.execute("use td4174"); stmt.execute("use " + dbname);
stmt.execute("create table weather(ts timestamp, text binary(64))"); stmt.execute("create table weather(ts timestamp, text binary(64))");
} catch (SQLException e) {
e.printStackTrace();
} }
} }
@After @After
public void after() throws SQLException { public void after() {
if (conn != null) try {
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.close();
conn.close(); conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
} }
} }

View File

@ -10,7 +10,7 @@ import org.junit.Test;
import java.sql.*; import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class TwoTypeTimestampPercisionInJniTest { public class MicroSecondPrecisionJNITest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static final String ms_timestamp_db = "ms_precision_test"; private static final String ms_timestamp_db = "ms_precision_test";

View File

@ -10,10 +10,9 @@ import org.junit.Test;
import java.sql.*; import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class TwoTypeTimestampPercisionInRestfulTest { public class MicroSecondPrecisionRestfulTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static final String ms_timestamp_db = "ms_precision_test"; private static final String ms_timestamp_db = "ms_precision_test";
private static final String us_timestamp_db = "us_precision_test"; private static final String us_timestamp_db = "us_precision_test";
private static final long timestamp1 = System.currentTimeMillis(); private static final long timestamp1 = System.currentTimeMillis();

View File

@ -0,0 +1,182 @@
package com.taosdata.jdbc.cases;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*;
import java.time.Instant;
import java.util.Random;
public class NanoSecondTimestampJNITest {
private static final String host = "127.0.0.1";
private static final String dbname = "nano_sec_test";
private static final Random random = new Random(System.currentTimeMillis());
private static Connection conn;
@Test
public void insertUsingLongValue() {
// given
long ms = System.currentTimeMillis();
long ns = ms * 1000_000 + random.nextInt(1000_000);
// when
int ret = 0;
try (Statement stmt = conn.createStatement()) {
ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
} catch (SQLException e) {
e.printStackTrace();
}
// then
Assert.assertEquals(1, ret);
}
@Test
public void insertUsingStringValue() {
// given
// when
int ret = 0;
try (Statement stmt = conn.createStatement()) {
ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('2021-01-01 12:00:00.123456789', 12.3, 4)");
} catch (SQLException e) {
e.printStackTrace();
}
// then
Assert.assertEquals(1, ret);
}
@Test
public void insertUsingTimestampValue() {
// given
long epochSec = System.currentTimeMillis() / 1000;
long nanoAdjustment = random.nextInt(1000_000_000);
Timestamp ts = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
// when
int ret = 0;
String sql = "insert into weather(ts, temperature, humidity) values( ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setTimestamp(1, ts);
pstmt.setFloat(2, 12.34f);
pstmt.setInt(3, 55);
ret = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
// then
Assert.assertEquals(1, ret);
}
@Test
public void selectUsingLongValue() throws SQLException {
// given
long ms = System.currentTimeMillis();
long ns = ms * 1000_000L + random.nextInt(1000_000);
// when
ResultSet rs = null;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
// then
long actual = rs.getLong(1);
Assert.assertEquals(ms, actual);
actual = rs.getLong("ts");
Assert.assertEquals(ms, actual);
}
@Test
public void selectUsingStringValue() throws SQLException {
// given
String timestampStr = "2021-01-01 12:00:00.123456789";
// when
ResultSet rs = null;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('" + timestampStr + "', 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
// then
String actual = rs.getString(1);
Assert.assertEquals(timestampStr, actual);
actual = rs.getString("ts");
Assert.assertEquals(timestampStr, actual);
}
@Test
public void selectUsingTimestampValue() throws SQLException {
// given
long timeMillis = System.currentTimeMillis();
long epochSec = timeMillis / 1000;
long nanoAdjustment = (timeMillis % 1000) * 1000_000L + random.nextInt(1000_000);
Timestamp ts = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
// insert one row
String sql = "insert into weather(ts, temperature, humidity) values( ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setTimestamp(1, ts);
pstmt.setFloat(2, 12.34f);
pstmt.setInt(3, 55);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
// when
ResultSet rs = null;
try (Statement stmt = conn.createStatement()) {
rs = stmt.executeQuery("select * from weather");
rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
// then
Timestamp actual = rs.getTimestamp(1);
Assert.assertEquals(ts, actual);
actual = rs.getTimestamp("ts");
Assert.assertEquals(ts, actual);
Assert.assertEquals(timeMillis, actual.getTime());
Assert.assertEquals(nanoAdjustment, actual.getNanos());
}
@Before
public void before() {
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop table if exists weather");
stmt.execute("create table weather(ts timestamp, temperature float, humidity int)");
} catch (SQLException e) {
e.printStackTrace();
}
}
@BeforeClass
public static void beforeClass() {
final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
try {
conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname + " precision 'ns'");
stmt.execute("use " + dbname);
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,182 @@
package com.taosdata.jdbc.cases;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*;
import java.time.Instant;
import java.util.Random;
public class NanoSecondTimestampRestfulTest {
private static final String host = "127.0.0.1";
private static final String dbname = "nano_sec_test";
private static final Random random = new Random(System.currentTimeMillis());
private static Connection conn;
@Test
public void insertUsingLongValue() {
// given
long ms = System.currentTimeMillis();
long ns = ms * 1000_000 + random.nextInt(1000_000);
// when
int ret = 0;
try (Statement stmt = conn.createStatement()) {
ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
} catch (SQLException e) {
e.printStackTrace();
}
// then
Assert.assertEquals(1, ret);
}
@Test
public void insertUsingStringValue() {
// given
// when
int ret = 0;
try (Statement stmt = conn.createStatement()) {
ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('2021-01-01 12:00:00.123456789', 12.3, 4)");
} catch (SQLException e) {
e.printStackTrace();
}
// then
Assert.assertEquals(1, ret);
}
@Test
public void insertUsingTimestampValue() {
// given
long epochSec = System.currentTimeMillis() / 1000;
long nanoAdjustment = random.nextInt(1000_000_000);
Timestamp ts = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
// when
int ret = 0;
String sql = "insert into weather(ts, temperature, humidity) values( ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setTimestamp(1, ts);
pstmt.setFloat(2, 12.34f);
pstmt.setInt(3, 55);
ret = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
// then
Assert.assertEquals(1, ret);
}
@Test
public void selectUsingLongValue() throws SQLException {
// given
long ms = System.currentTimeMillis();
long ns = ms * 1000_000L + random.nextInt(1000_000);
// when
ResultSet rs = null;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
// then
long actual = rs.getLong(1);
Assert.assertEquals(ms, actual);
actual = rs.getLong("ts");
Assert.assertEquals(ms, actual);
}
@Test
public void selectUsingStringValue() throws SQLException {
// given
String timestampStr = "2021-01-01 12:00:00.123456789";
// when
ResultSet rs = null;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('" + timestampStr + "', 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
// then
String actual = rs.getString(1);
Assert.assertEquals(timestampStr, actual);
actual = rs.getString("ts");
Assert.assertEquals(timestampStr, actual);
}
@Test
public void selectUsingTimestampValue() throws SQLException {
// given
long timeMillis = System.currentTimeMillis();
long epochSec = timeMillis / 1000;
long nanoAdjustment = (timeMillis % 1000) * 1000_000L + random.nextInt(1000_000);
Timestamp ts = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment));
// insert one row
String sql = "insert into weather(ts, temperature, humidity) values( ?, ?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setTimestamp(1, ts);
pstmt.setFloat(2, 12.34f);
pstmt.setInt(3, 55);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
// when
ResultSet rs = null;
try (Statement stmt = conn.createStatement()) {
rs = stmt.executeQuery("select * from weather");
rs.next();
} catch (SQLException e) {
e.printStackTrace();
}
// then
Timestamp actual = rs.getTimestamp(1);
Assert.assertEquals(ts, actual);
actual = rs.getTimestamp("ts");
Assert.assertEquals(ts, actual);
Assert.assertEquals(timeMillis, actual.getTime());
Assert.assertEquals(nanoAdjustment, actual.getNanos());
}
@Before
public void before() {
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop table if exists weather");
stmt.execute("create table weather(ts timestamp, temperature float, humidity int)");
} catch (SQLException e) {
e.printStackTrace();
}
}
@BeforeClass
public static void beforeClass() {
final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
try {
conn = DriverManager.getConnection(url);
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname + " precision 'ns'");
stmt.execute("use " + dbname);
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -6,7 +6,7 @@ import org.junit.Test;
import java.sql.*; import java.sql.*;
public class NullValueInResultSetForJdbcJniTest { public class NullValueInResultSetJNITest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
Connection conn; Connection conn;

View File

@ -6,7 +6,7 @@ import org.junit.Test;
import java.sql.*; import java.sql.*;
public class NullValueInResultSetForJdbcRestfulTest { public class NullValueInResultSetRestfulTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
Connection conn; Connection conn;

View File

@ -7,7 +7,7 @@ import org.junit.*;
import java.sql.*; import java.sql.*;
import java.util.Properties; import java.util.Properties;
public class TD3841Test { public class NullValueInResultSetTest {
private static final String host = "127.0.0.1"; private static final String host = "127.0.0.1";
private static Properties properties; private static Properties properties;
private static Connection conn_restful; private static Connection conn_restful;

View File

@ -0,0 +1,98 @@
package com.taosdata.jdbc.cases;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.sql.*;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PreparedStatementBatchInsertJNITest {
private static final String host = "127.0.0.1";
private static final String dbname = "td4668";
private final Random random = new Random(System.currentTimeMillis());
private Connection conn;
@Test
public void test() {
// given
long ts = System.currentTimeMillis();
List<Object[]> rows = IntStream.range(0, 10).mapToObj(i -> {
Object[] row = new Object[6];
final String groupId = String.format("%02d", random.nextInt(100));
// table name (d + groupId)组合
row[0] = "d" + groupId;
// tag
row[1] = groupId;
// ts
row[2] = ts + i;
// current 电流
row[3] = random.nextFloat();
// voltage 电压
row[4] = Math.random() > 0.5 ? 220 : 380;
// phase 相位
row[5] = random.nextInt(10);
return row;
}).collect(Collectors.toList());
final String sql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)";
// when
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (Object[] row : rows) {
for (int i = 0; i < row.length; i++) {
pstmt.setObject(i + 1, row[i]);
}
pstmt.addBatch();
}
pstmt.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
Assert.fail();
}
// then
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from meters");
int count = 0;
while (rs.next()) {
count++;
}
Assert.assertEquals(10, count);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Before
public void before() {
try {
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname);
stmt.execute("use " + dbname);
stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(groupId int)");
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void after() {
try {
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,98 @@
package com.taosdata.jdbc.cases;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.sql.*;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PreparedStatementBatchInsertRestfulTest {
private static final String host = "127.0.0.1";
private static final String dbname = "td4668";
private final Random random = new Random(System.currentTimeMillis());
private Connection conn;
@Test
public void test() {
// given
long ts = System.currentTimeMillis();
List<Object[]> rows = IntStream.range(0, 10).mapToObj(i -> {
Object[] row = new Object[6];
final String groupId = String.format("%02d", random.nextInt(100));
// table name (d + groupId)组合
row[0] = "d" + groupId;
// tag
row[1] = groupId;
// ts
row[2] = ts + i;
// current 电流
row[3] = random.nextFloat();
// voltage 电压
row[4] = Math.random() > 0.5 ? 220 : 380;
// phase 相位
row[5] = random.nextInt(10);
return row;
}).collect(Collectors.toList());
final String sql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)";
// when
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (Object[] row : rows) {
for (int i = 0; i < row.length; i++) {
pstmt.setObject(i + 1, row[i]);
}
pstmt.addBatch();
}
pstmt.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
Assert.fail();
}
// then
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from meters");
int count = 0;
while (rs.next()) {
count++;
}
Assert.assertEquals(10, count);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Before
public void before() {
try {
conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata");
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname);
stmt.execute("use " + dbname);
stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(groupId int)");
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void after() {
try {
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,86 @@
package com.taosdata.jdbc.cases;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.sql.*;
public class ResultSetMetaShouldNotBeNullRestfulTest {
private static final String host = "127.0.0.1";
private static final String dbname = "td4745";
private Connection connection;
@Test
public void testExecuteQuery() {
// given
ResultSetMetaData metaData = null;
int columnCount = -1;
// when
try {
Statement statement = connection.createStatement();
metaData = statement.executeQuery("select * from weather").getMetaData();
columnCount = metaData.getColumnCount();
} catch (SQLException e) {
e.printStackTrace();
}
// then
Assert.assertNotNull(metaData);
Assert.assertEquals(0, columnCount);
}
@Test
public void testExecute() {
// given
ResultSetMetaData metaData = null;
int columnCount = -1;
boolean execute = false;
// when
try {
Statement statement = connection.createStatement();
execute = statement.execute("select * from weather");
metaData = statement.getResultSet().getMetaData();
columnCount = metaData.getColumnCount();
} catch (SQLException e) {
e.printStackTrace();
}
// then
Assert.assertEquals(true, execute);
Assert.assertNotNull(metaData);
Assert.assertEquals(0, columnCount);
}
@Before
public void before() {
try {
connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata");
Statement stmt = connection.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname);
stmt.execute("use " + dbname);
stmt.execute("create table weather (ts timestamp, temperature float)");
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void after() {
try {
Statement stmt = connection.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.close();
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

View File

@ -1,105 +0,0 @@
package com.taosdata.jdbc.cases;
import com.taosdata.jdbc.TSDBConnection;
import com.taosdata.jdbc.TSDBDriver;
import com.taosdata.jdbc.TSDBResultSet;
import com.taosdata.jdbc.TSDBSubscribe;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.DriverManager;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
public class TD4144Test {
private static TSDBConnection connection;
private static final String host = "127.0.0.1";
private static final String topic = "topic-meter-current-bg-10";
private static final String sql = "select * from meters where current > 10";
private static final String sql2 = "select * from meters where ts >= '2020-08-15 12:20:00.000'";
@Test
public void test() throws SQLException {
TSDBSubscribe subscribe = null;
TSDBResultSet res = null;
boolean hasNext = false;
try {
subscribe = connection.subscribe(topic, sql, false);
int count = 0;
while (true) {
// 等待1秒避免频繁调用 consume给服务端造成压力
TimeUnit.SECONDS.sleep(1);
if (res == null) {
// 消费数据
res = subscribe.consume();
hasNext = res.next();
}
if (res == null) {
continue;
}
ResultSetMetaData metaData = res.getMetaData();
int number = 0;
while (hasNext) {
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
System.out.print(metaData.getColumnLabel(i) + ": " + res.getString(i) + "\t");
}
System.out.println();
count++;
number++;
hasNext = res.next();
if (!hasNext) {
res.close();
res = null;
System.out.println("rows " + count);
}
if (hasNext == true && number >= 10) {
System.out.println("batch" + number);
break;
}
}
}
} catch (SQLException | InterruptedException throwables) {
throwables.printStackTrace();
} finally {
if (subscribe != null)
subscribe.close(true);
}
}
@BeforeClass
public static void beforeClass() throws SQLException {
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
connection = (DriverManager.getConnection(url, properties)).unwrap(TSDBConnection.class);
try (Statement stmt = connection.createStatement()) {
stmt.execute("drop database if exists power");
stmt.execute("create database if not exists power");
stmt.execute("use power");
stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(location binary(64), groupId int)");
stmt.execute("create table d1001 using meters tags(\"Beijing.Chaoyang\", 2)");
stmt.execute("create table d1002 using meters tags(\"Beijing.Haidian\", 2)");
stmt.execute("insert into d1001 values(\"2020-08-15 12:00:00.000\", 12, 220, 1),(\"2020-08-15 12:10:00.000\", 12.3, 220, 2),(\"2020-08-15 12:20:00.000\", 12.2, 220, 1)");
stmt.execute("insert into d1002 values(\"2020-08-15 12:00:00.000\", 9.9, 220, 1),(\"2020-08-15 12:10:00.000\", 10.3, 220, 1),(\"2020-08-15 12:20:00.000\", 11.2, 220, 1)");
}
}
@AfterClass
public static void afterClass() throws SQLException {
if (connection != null)
connection.close();
}
}

View File

@ -3,22 +3,98 @@ package com.taosdata.jdbc.utils;
import org.junit.Assert; import org.junit.Assert;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*; import java.util.stream.Stream;
public class UtilsTest { public class UtilsTest {
@Test @Test
public void escapeSingleQuota() { public void escapeSingleQuota() {
// given
String s = "'''''a\\'"; String s = "'''''a\\'";
// when
String news = Utils.escapeSingleQuota(s); String news = Utils.escapeSingleQuota(s);
// then
Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news); Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news);
// given
s = "\'''''a\\'"; s = "\'''''a\\'";
// when
news = Utils.escapeSingleQuota(s); news = Utils.escapeSingleQuota(s);
// then
Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news); Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news);
// given
s = "\'\'\'\''a\\'"; s = "\'\'\'\''a\\'";
// when
news = Utils.escapeSingleQuota(s); news = Utils.escapeSingleQuota(s);
// then
Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news); Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news);
} }
@Test
public void getNativeSqlReplaceQuestionMarks() {
// given
String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)";
Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray();
// when
String actual = Utils.getNativeSql(nativeSql, parameters);
// then
String expected = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)";
Assert.assertEquals(expected, actual);
}
@Test
public void getNativeSqlReplaceQuestionMarks2() {
// given
String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)";
Object[] parameters = Stream.of("d1", 1, 123, 3.14, 220, 4).toArray();
// when
String actual = Utils.getNativeSql(nativeSql, parameters);
// then
String expected = "INSERT INTO d1 (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (1) VALUES (123,3.14,220,4)";
Assert.assertEquals(expected, actual);
}
@Test
public void getNativeSqlReplaceNothing() {
// given
String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)";
// when
String actual = Utils.getNativeSql(nativeSql, null);
// then
Assert.assertEquals(nativeSql, actual);
}
@Test
public void getNativeSqlReplaceNothing2() {
// given
String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)";
Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray();
// when
String actual = Utils.getNativeSql(nativeSql, parameters);
// then
Assert.assertEquals(nativeSql, actual);
}
@Test
public void getNativeSqlReplaceNothing3() {
// given
String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)";
// when
String actual = Utils.getNativeSql(nativeSql, null);
// then
Assert.assertEquals(nativeSql, actual);
}
} }

View File

@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup( setuptools.setup(
name="taos", name="taos",
version="2.0.10", version="2.0.11",
author="Taosdata Inc.", author="Taosdata Inc.",
author_email="support@taosdata.com", author_email="support@taosdata.com",
description="TDengine python client package", description="TDengine python client package",

View File

@ -14,12 +14,22 @@ def _convert_microsecond_to_datetime(micro): #checkpoint
return datetime.datetime.fromtimestamp(micro / 1000000.0) return datetime.datetime.fromtimestamp(micro / 1000000.0)
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):#checkpoint def _convert_nanosecond_to_datetime(nanosec):
return nanosec
def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C bool row to python row """Function to convert C bool row to python row
""" """
_timestamp_converter = _convert_millisecond_to_datetime _timestamp_converter = _convert_millisecond_to_datetime
if micro: if precision == FieldType.C_TIMESTAMP_MILLI:
_timestamp_converter = _convert_millisecond_to_datetime
elif precision == FieldType.C_TIMESTAMP_MICRO:
_timestamp_converter = _convert_microsecond_to_datetime _timestamp_converter = _convert_microsecond_to_datetime
elif precision == FieldType.C_TIMESTAMP_NANO:
_timestamp_converter = _convert_nanosecond_to_datetime
else:
raise DatabaseError("Unknown precision returned from database")
return [ return [
None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast( None if ele == FieldType.C_BIGINT_NULL else _timestamp_converter(ele) for ele in ctypes.cast(
@ -28,7 +38,7 @@ def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False):#chec
:abs(num_of_rows)]] :abs(num_of_rows)]]
def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_bool_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C bool row to python row """Function to convert C bool row to python row
""" """
return [ return [
@ -38,7 +48,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False):
:abs(num_of_rows)]] :abs(num_of_rows)]]
def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_tinyint_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C tinyint row to python row """Function to convert C tinyint row to python row
""" """
return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast( return [None if ele == FieldType.C_TINYINT_NULL else ele for ele in ctypes.cast(
@ -49,7 +59,7 @@ def _crow_tinyint_unsigned_to_python(
data, data,
num_of_rows, num_of_rows,
nbytes=None, nbytes=None,
micro=False): precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C tinyint row to python row """Function to convert C tinyint row to python row
""" """
return [ return [
@ -59,7 +69,7 @@ def _crow_tinyint_unsigned_to_python(
:abs(num_of_rows)]] :abs(num_of_rows)]]
def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_smallint_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C smallint row to python row """Function to convert C smallint row to python row
""" """
return [ return [
@ -70,7 +80,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False):
def _crow_smallint_unsigned_to_python( def _crow_smallint_unsigned_to_python(
data, num_of_rows, nbytes=None, micro=False): data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C smallint row to python row """Function to convert C smallint row to python row
""" """
return [ return [
@ -80,14 +90,14 @@ def _crow_smallint_unsigned_to_python(
:abs(num_of_rows)]] :abs(num_of_rows)]]
def _crow_int_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_int_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C int row to python row """Function to convert C int row to python row
""" """
return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast( return [None if ele == FieldType.C_INT_NULL else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]] data, ctypes.POINTER(ctypes.c_int))[:abs(num_of_rows)]]
def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C int row to python row """Function to convert C int row to python row
""" """
return [ return [
@ -97,7 +107,7 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False):
:abs(num_of_rows)]] :abs(num_of_rows)]]
def _crow_bigint_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_bigint_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C bigint row to python row """Function to convert C bigint row to python row
""" """
return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast( return [None if ele == FieldType.C_BIGINT_NULL else ele for ele in ctypes.cast(
@ -108,7 +118,7 @@ def _crow_bigint_unsigned_to_python(
data, data,
num_of_rows, num_of_rows,
nbytes=None, nbytes=None,
micro=False): precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C bigint row to python row """Function to convert C bigint row to python row
""" """
return [ return [
@ -118,21 +128,21 @@ def _crow_bigint_unsigned_to_python(
:abs(num_of_rows)]] :abs(num_of_rows)]]
def _crow_float_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_float_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C float row to python row """Function to convert C float row to python row
""" """
return [None if math.isnan(ele) else ele for ele in ctypes.cast( return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]] data, ctypes.POINTER(ctypes.c_float))[:abs(num_of_rows)]]
def _crow_double_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_double_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C double row to python row """Function to convert C double row to python row
""" """
return [None if math.isnan(ele) else ele for ele in ctypes.cast( return [None if math.isnan(ele) else ele for ele in ctypes.cast(
data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]] data, ctypes.POINTER(ctypes.c_double))[:abs(num_of_rows)]]
def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C binary row to python row """Function to convert C binary row to python row
""" """
assert(nbytes is not None) assert(nbytes is not None)
@ -140,7 +150,7 @@ def _crow_binary_to_python(data, num_of_rows, nbytes=None, micro=False):
'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]] 'utf-8') for ele in (ctypes.cast(data, ctypes.POINTER(ctypes.c_char * nbytes)))[:abs(num_of_rows)]]
def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): def _crow_nchar_to_python(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C nchar row to python row """Function to convert C nchar row to python row
""" """
assert(nbytes is not None) assert(nbytes is not None)
@ -159,7 +169,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False):
return res return res
def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False): def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C binary row to python row """Function to convert C binary row to python row
""" """
assert(nbytes is not None) assert(nbytes is not None)
@ -178,7 +188,7 @@ def _crow_binary_to_python_block(data, num_of_rows, nbytes=None, micro=False):
return res return res
def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, micro=False): def _crow_nchar_to_python_block(data, num_of_rows, nbytes=None, precision=FieldType.C_TIMESTAMP_UNKNOWN):
"""Function to convert C nchar row to python row """Function to convert C nchar row to python row
""" """
assert(nbytes is not None) assert(nbytes is not None)
@ -448,8 +458,7 @@ class CTaosInterface(object):
result, ctypes.byref(pblock)) result, ctypes.byref(pblock))
if num_of_rows == 0: if num_of_rows == 0:
return None, 0 return None, 0
isMicro = (CTaosInterface.libtaos.taos_result_precision( precision = CTaosInterface.libtaos.taos_result_precision(result)
result) == FieldType.C_TIMESTAMP_MICRO)
blocks = [None] * len(fields) blocks = [None] * len(fields)
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
fieldLen = [ fieldLen = [
@ -462,7 +471,7 @@ class CTaosInterface(object):
if fields[i]['type'] not in _CONVERT_FUNC_BLOCK: if fields[i]['type'] not in _CONVERT_FUNC_BLOCK:
raise DatabaseError("Invalid data type returned from database") raise DatabaseError("Invalid data type returned from database")
blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']]( blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']](
data, num_of_rows, fieldLen[i], isMicro) data, num_of_rows, fieldLen[i], precision)
return blocks, abs(num_of_rows) return blocks, abs(num_of_rows)
@ -472,8 +481,7 @@ class CTaosInterface(object):
pblock = CTaosInterface.libtaos.taos_fetch_row(result) pblock = CTaosInterface.libtaos.taos_fetch_row(result)
if pblock: if pblock:
num_of_rows = 1 num_of_rows = 1
isMicro = (CTaosInterface.libtaos.taos_result_precision( precision = CTaosInterface.libtaos.taos_result_precision(result)
result) == FieldType.C_TIMESTAMP_MICRO)
blocks = [None] * len(fields) blocks = [None] * len(fields)
fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result)
fieldLen = [ fieldLen = [
@ -490,7 +498,7 @@ class CTaosInterface(object):
blocks[i] = [None] blocks[i] = [None]
else: else:
blocks[i] = _CONVERT_FUNC[fields[i]['type']]( blocks[i] = _CONVERT_FUNC[fields[i]['type']](
data, num_of_rows, fieldLen[i], isMicro) data, num_of_rows, fieldLen[i], precision)
else: else:
return None, 0 return None, 0
return blocks, abs(num_of_rows) return blocks, abs(num_of_rows)

View File

@ -40,3 +40,5 @@ class FieldType(object):
# Timestamp precision definition # Timestamp precision definition
C_TIMESTAMP_MILLI = 0 C_TIMESTAMP_MILLI = 0
C_TIMESTAMP_MICRO = 1 C_TIMESTAMP_MICRO = 1
C_TIMESTAMP_NANO = 2
C_TIMESTAMP_UNKNOWN = 3

View File

@ -27,6 +27,7 @@ void dnodeUpdateCfg(SDnodeCfg *cfg);
int32_t dnodeGetDnodeId(); int32_t dnodeGetDnodeId();
void dnodeGetClusterId(char *clusterId); void dnodeGetClusterId(char *clusterId);
void dnodeGetCfg(int32_t *dnodeId, char *clusterId); void dnodeGetCfg(int32_t *dnodeId, char *clusterId);
void dnodeSetDropped();
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -21,6 +21,7 @@
static SDnodeCfg tsCfg = {0}; static SDnodeCfg tsCfg = {0};
static pthread_mutex_t tsCfgMutex; static pthread_mutex_t tsCfgMutex;
static int32_t tsDnodeDropped;
static int32_t dnodeReadCfg(); static int32_t dnodeReadCfg();
static int32_t dnodeWriteCfg(); static int32_t dnodeWriteCfg();
@ -34,6 +35,10 @@ int32_t dnodeInitCfg() {
if (ret == 0) { if (ret == 0) {
dInfo("dnode cfg is initialized"); dInfo("dnode cfg is initialized");
} }
if (tsDnodeDropped) {
dInfo("dnode is dropped, exiting");
return -1;
}
return ret; return ret;
} }
@ -44,6 +49,14 @@ void dnodeUpdateCfg(SDnodeCfg *cfg) {
dnodeResetCfg(cfg); dnodeResetCfg(cfg);
} }
void dnodeSetDropped() {
pthread_mutex_lock(&tsCfgMutex);
tsDnodeDropped = 1;
dnodeWriteCfg();
pthread_mutex_unlock(&tsCfgMutex);
}
int32_t dnodeGetDnodeId() { int32_t dnodeGetDnodeId() {
int32_t dnodeId = 0; int32_t dnodeId = 0;
pthread_mutex_lock(&tsCfgMutex); pthread_mutex_lock(&tsCfgMutex);
@ -119,6 +132,14 @@ static int32_t dnodeReadCfg() {
} }
cfg.dnodeId = (int32_t)dnodeId->valueint; cfg.dnodeId = (int32_t)dnodeId->valueint;
cJSON *dnodeDropped = cJSON_GetObjectItem(root, "dnodeDropped");
if (!dnodeDropped || dnodeDropped->type != cJSON_Number) {
dError("failed to read %s, dnodeDropped not found", file);
//goto PARSE_CFG_OVER;
} else {
tsDnodeDropped = (int32_t)dnodeDropped->valueint;
}
cJSON *clusterId = cJSON_GetObjectItem(root, "clusterId"); cJSON *clusterId = cJSON_GetObjectItem(root, "clusterId");
if (!clusterId || clusterId->type != cJSON_String) { if (!clusterId || clusterId->type != cJSON_String) {
dError("failed to read %s, clusterId not found", file); dError("failed to read %s, clusterId not found", file);
@ -154,6 +175,7 @@ static int32_t dnodeWriteCfg() {
len += snprintf(content + len, maxLen - len, "{\n"); len += snprintf(content + len, maxLen - len, "{\n");
len += snprintf(content + len, maxLen - len, " \"dnodeId\": %d,\n", tsCfg.dnodeId); len += snprintf(content + len, maxLen - len, " \"dnodeId\": %d,\n", tsCfg.dnodeId);
len += snprintf(content + len, maxLen - len, " \"dnodeDropped\": %d,\n", tsDnodeDropped);
len += snprintf(content + len, maxLen - len, " \"clusterId\": \"%s\"\n", tsCfg.clusterId); len += snprintf(content + len, maxLen - len, " \"clusterId\": \"%s\"\n", tsCfg.clusterId);
len += snprintf(content + len, maxLen - len, "}\n"); len += snprintf(content + len, maxLen - len, "}\n");

View File

@ -202,6 +202,7 @@ static void dnodeProcessStatusRsp(SRpcMsg *pMsg) {
char clusterId[TSDB_CLUSTER_ID_LEN]; char clusterId[TSDB_CLUSTER_ID_LEN];
dnodeGetClusterId(clusterId); dnodeGetClusterId(clusterId);
if (clusterId[0] != '\0') { if (clusterId[0] != '\0') {
dnodeSetDropped();
dError("exit zombie dropped dnode"); dError("exit zombie dropped dnode");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }

View File

@ -138,7 +138,6 @@ typedef struct SQueryInfo {
bool hasFilter; bool hasFilter;
bool onlyTagQuery; bool onlyTagQuery;
bool orderProjectQuery; bool orderProjectQuery;
// bool diffQuery;
bool stateWindow; bool stateWindow;
} SQueryInfo; } SQueryInfo;

View File

@ -3613,17 +3613,8 @@ static void deriv_function(SQLFunctionCtx *pCtx) {
qError("error input type"); qError("error input type");
} }
// initial value is not set yet, all data block are null
if (!pDerivInfo->valueSet || notNullElems <= 0) {
/*
* 1. current block and blocks before are full of null
* 2. current block may be null value
*/
assert(pCtx->hasNull);
} else {
GET_RES_INFO(pCtx)->numOfRes += notNullElems; GET_RES_INFO(pCtx)->numOfRes += notNullElems;
} }
}
#define DIFF_IMPL(ctx, d, type) \ #define DIFF_IMPL(ctx, d, type) \
do { \ do { \

View File

@ -1312,6 +1312,8 @@ static void doHashGroupbyAgg(SOperatorInfo* pOperator, SGroupbyOperatorInfo *pIn
} }
} }
// todo opt perf
for (int32_t k = 0; k < pOperator->numOfOutput; ++k) { for (int32_t k = 0; k < pOperator->numOfOutput; ++k) {
pInfo->binfo.pCtx[k].size = 1; pInfo->binfo.pCtx[k].size = 1;
int32_t functionId = pInfo->binfo.pCtx[k].functionId; int32_t functionId = pInfo->binfo.pCtx[k].functionId;

View File

@ -812,6 +812,7 @@ int tsdbRestoreInfo(STsdbRepo *pRepo) {
STable *pTable = pMeta->tables[i]; STable *pTable = pMeta->tables[i];
if (pTable == NULL) continue; if (pTable == NULL) continue;
pTable->restoreColumnNum = 0; pTable->restoreColumnNum = 0;
pTable->hasRestoreLastColumn = false;
} }
} }
@ -895,6 +896,7 @@ int tsdbCacheLastData(STsdbRepo *pRepo, STsdbCfg* oldCfg) {
maxTableIdx = i; maxTableIdx = i;
if (cacheLastCol) { if (cacheLastCol) {
pTable->restoreColumnNum = 0; pTable->restoreColumnNum = 0;
pTable->hasRestoreLastColumn = false;
} }
} }
@ -913,6 +915,7 @@ int tsdbCacheLastData(STsdbRepo *pRepo, STsdbCfg* oldCfg) {
} }
if (need_free_last_col) { if (need_free_last_col) {
tsdbFreeLastColumns(pTable); tsdbFreeLastColumns(pTable);
pTable->hasRestoreLastColumn = false;
} }
} }
} }

View File

@ -609,6 +609,7 @@ void tsdbFreeLastColumns(STable* pTable) {
pTable->maxColNum = 0; pTable->maxColNum = 0;
pTable->lastColSVersion = -1; pTable->lastColSVersion = -1;
pTable->restoreColumnNum = 0; pTable->restoreColumnNum = 0;
pTable->hasRestoreLastColumn = false;
} }
int16_t tsdbGetLastColumnsIndexByColId(STable* pTable, int16_t colId) { int16_t tsdbGetLastColumnsIndexByColId(STable* pTable, int16_t colId) {
@ -645,6 +646,7 @@ int tsdbInitColIdCacheWithSchema(STable* pTable, STSchema* pSchema) {
pTable->lastColSVersion = schemaVersion(pSchema); pTable->lastColSVersion = schemaVersion(pSchema);
pTable->maxColNum = numOfColumn; pTable->maxColNum = numOfColumn;
pTable->restoreColumnNum = 0; pTable->restoreColumnNum = 0;
pTable->hasRestoreLastColumn = false;
return 0; return 0;
} }
@ -657,7 +659,7 @@ int tsdbUpdateLastColSchema(STable *pTable, STSchema *pNewSchema) {
return 0; return 0;
} }
tsdbInfo("tsdbUpdateLastColSchema:%s,%d->%d", pTable->name->data, pTable->lastColSVersion, schemaVersion(pNewSchema)); tsdbDebug("tsdbUpdateLastColSchema:%s,%d->%d", pTable->name->data, pTable->lastColSVersion, schemaVersion(pNewSchema));
int16_t numOfCols = pNewSchema->numOfCols; int16_t numOfCols = pNewSchema->numOfCols;
SDataCol *lastCols = (SDataCol*)malloc(numOfCols * sizeof(SDataCol)); SDataCol *lastCols = (SDataCol*)malloc(numOfCols * sizeof(SDataCol));
@ -802,6 +804,7 @@ static STable *tsdbNewTable() {
pTable->lastCols = NULL; pTable->lastCols = NULL;
pTable->restoreColumnNum = 0; pTable->restoreColumnNum = 0;
pTable->maxColNum = 0; pTable->maxColNum = 0;
pTable->hasRestoreLastColumn = false;
pTable->lastColSVersion = -1; pTable->lastColSVersion = -1;
return pTable; return pTable;
} }

View File

@ -2520,7 +2520,7 @@ static bool loadCachedLast(STsdbQueryHandle* pQueryHandle) {
int32_t numOfCols = pTable->maxColNum; int32_t numOfCols = pTable->maxColNum;
if (pTable->lastCols == NULL || pTable->maxColNum <= 0) { if (pTable->lastCols == NULL || pTable->maxColNum <= 0) {
tsdbWarn("no last cached for table, uid:%" PRIu64 ",tid:%d", pTable->tableId.uid, pTable->tableId.tid); tsdbWarn("no last cached for table %s, uid:%" PRIu64 ",tid:%d", pTable->name->data, pTable->tableId.uid, pTable->tableId.tid);
continue; continue;
} }

View File

@ -29,13 +29,14 @@ class TDTestCase:
def run(self): def run(self):
tdSql.prepare() tdSql.prepare()
tdSql.execute('reset query cache') tdSql.execute('reset query cache')
tdSql.execute('drop database if exists db') tdSql.execute('drop database if exists db')
tdSql.execute('create database db precision "ns";') tdSql.execute('create database db precision "ns";')
tdSql.query('show databases;') tdSql.query('show databases;')
tdSql.checkData(0,16,'ns') tdSql.checkData(0,16,'ns')
tdSql.execute('use db') tdSql.execute('use db')
tdLog.debug('testing nanosecond support in 1st timestamp')
tdSql.execute('create table tb (ts timestamp, speed int)') tdSql.execute('create table tb (ts timestamp, speed int)')
tdSql.execute('insert into tb values(\'2021-06-10 0:00:00.100000001\', 1);') tdSql.execute('insert into tb values(\'2021-06-10 0:00:00.100000001\', 1);')
tdSql.execute('insert into tb values(1623254400150000000, 2);') tdSql.execute('insert into tb values(1623254400150000000, 2);')
@ -47,8 +48,6 @@ class TDTestCase:
tdSql.execute('insert into tb values(1623254400999999999, 7);') tdSql.execute('insert into tb values(1623254400999999999, 7);')
#TODO: after the connector is updated, run the following commented code
#TODO: due to the precision limit of double, spread currently cannot be tested since ns timestampe cannot be accurately represented
tdSql.query('select * from tb;') tdSql.query('select * from tb;')
tdSql.checkData(0,0,'2021-06-10 0:00:00.100000001') tdSql.checkData(0,0,'2021-06-10 0:00:00.100000001')
tdSql.checkData(1,0,'2021-06-10 0:00:00.150000000') tdSql.checkData(1,0,'2021-06-10 0:00:00.150000000')
@ -75,7 +74,7 @@ class TDTestCase:
# os.system('sudo timedatectl set-ntp off') # os.system('sudo timedatectl set-ntp off')
# os.system('sudo timedatectl set-time 2021-06-10') # os.system('sudo timedatectl set-time 2021-06-10')
tdSql.query('select count(*) from tb where ts > now + 400000000b;') tdSql.query('select count(*) from tb where ts > now + 400000000b;')
tdSql.checkData(0,0,0) tdSql.checkRows(0)
tdSql.query('select count(*) from tb where ts >= \'2021-06-10 0:00:00.100000001\';') tdSql.query('select count(*) from tb where ts >= \'2021-06-10 0:00:00.100000001\';')
tdSql.checkData(0,0,6) tdSql.checkData(0,0,6)
@ -84,7 +83,7 @@ class TDTestCase:
tdSql.checkData(0,0,4) tdSql.checkData(0,0,4)
tdSql.query('select count(*) from tb where ts = \'2021-06-10 0:00:00.000000000\';') tdSql.query('select count(*) from tb where ts = \'2021-06-10 0:00:00.000000000\';')
tdSql.checkData(0,0,0) tdSql.checkRows(0)
tdSql.query('select count(*) from tb where ts = 1623254400150000000;') tdSql.query('select count(*) from tb where ts = 1623254400150000000;')
tdSql.checkData(0,0,1) tdSql.checkData(0,0,1)
@ -119,6 +118,7 @@ class TDTestCase:
tdSql.query('select * from tb;') tdSql.query('select * from tb;')
tdSql.checkRows(7) tdSql.checkRows(7)
tdLog.debug('testing nanosecond support in other timestamps')
tdSql.execute('create table tb2 (ts timestamp, speed int, ts2 timestamp);') tdSql.execute('create table tb2 (ts timestamp, speed int, ts2 timestamp);')
tdSql.execute('insert into tb2 values(\'2021-06-10 0:00:00.100000001\', 1, \'2021-06-11 0:00:00.100000001\');') tdSql.execute('insert into tb2 values(\'2021-06-10 0:00:00.100000001\', 1, \'2021-06-11 0:00:00.100000001\');')
tdSql.execute('insert into tb2 values(1623254400150000000, 2, 1623340800150000000);') tdSql.execute('insert into tb2 values(1623254400150000000, 2, 1623340800150000000);')
@ -150,7 +150,7 @@ class TDTestCase:
# os.system('sudo timedatectl set-ntp off') # os.system('sudo timedatectl set-ntp off')
# os.system('sudo timedatectl set-time 2021-06-11') # os.system('sudo timedatectl set-time 2021-06-11')
tdSql.query('select count(*) from tb2 where ts2 > now + 400000000b;') tdSql.query('select count(*) from tb2 where ts2 > now + 400000000b;')
tdSql.checkData(0,0,0) tdSql.checkRows(0)
tdSql.query('select count(*) from tb2 where ts2 >= \'2021-06-11 0:00:00.100000001\';') tdSql.query('select count(*) from tb2 where ts2 >= \'2021-06-11 0:00:00.100000001\';')
@ -160,7 +160,7 @@ class TDTestCase:
tdSql.checkData(0,0,5) tdSql.checkData(0,0,5)
tdSql.query('select count(*) from tb2 where ts2 = \'2021-06-11 0:00:00.000000000\';') tdSql.query('select count(*) from tb2 where ts2 = \'2021-06-11 0:00:00.000000000\';')
tdSql.checkData(0,0,0) tdSql.checkRows(0)
tdSql.query('select count(*) from tb2 where ts2 = \'2021-06-11 0:00:00.300000001\';') tdSql.query('select count(*) from tb2 where ts2 = \'2021-06-11 0:00:00.300000001\';')
tdSql.checkData(0,0,1) tdSql.checkData(0,0,1)
@ -190,6 +190,7 @@ class TDTestCase:
tdSql.query('select * from tb2;') tdSql.query('select * from tb2;')
tdSql.checkRows(7) tdSql.checkRows(7)
tdLog.debug('testing ill nanosecond format handling')
tdSql.execute('create table tb3 (ts timestamp, speed int);') tdSql.execute('create table tb3 (ts timestamp, speed int);')
tdSql.error('insert into tb3 values(16232544001500000, 2);') tdSql.error('insert into tb3 values(16232544001500000, 2);')

View File

@ -25,6 +25,8 @@ python3 ./test.py -f insert/special_character_show.py
python3 bug2265.py python3 bug2265.py
python3 ./test.py -f insert/bug3654.py python3 ./test.py -f insert/bug3654.py
python3 ./test.py -f insert/insertDynamicColBeforeVal.py python3 ./test.py -f insert/insertDynamicColBeforeVal.py
python3 ./test.py -f insert/in_function.py
python3 ./test.py -f insert/modify_column.py
#table #table
python3 ./test.py -f table/alter_wal0.py python3 ./test.py -f table/alter_wal0.py
@ -73,6 +75,7 @@ python3 ./test.py -f tag_lite/smallint.py
python3 ./test.py -f tag_lite/tinyint.py python3 ./test.py -f tag_lite/tinyint.py
#python3 ./test.py -f dbmgmt/database-name-boundary.py #python3 ./test.py -f dbmgmt/database-name-boundary.py
python3 test.py -f dbmgmt/nanoSecondCheck.py
python3 ./test.py -f import_merge/importBlock1HO.py python3 ./test.py -f import_merge/importBlock1HO.py
python3 ./test.py -f import_merge/importBlock1HPO.py python3 ./test.py -f import_merge/importBlock1HPO.py

View File

@ -130,6 +130,13 @@ class TDTestCase:
tdSql.prepare() tdSql.prepare()
self.insertAndCheckData() self.insertAndCheckData()
tdSql.execute("create table st(ts timestamp, c1 int, c2 int) tags(id int)")
tdSql.execute("insert into dev1(ts, c1) using st tags(1) values(now, 1)")
tdSql.error("select derivative(c1, 10s, 0) from (select c1 from st)")
tdSql.query("select diff(c1) from (select derivative(c1, 1s, 0) c1 from dev1)")
tdSql.checkRows(0)
def stop(self): def stop(self):
tdSql.close() tdSql.close()
tdLog.success("%s successfully executed" % __file__) tdLog.success("%s successfully executed" % __file__)

View File

@ -0,0 +1,726 @@
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
import datetime
from util.log import *
from util.cases import *
from util.sql import *
class TDTestCase:
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
def run(self):
tdSql.prepare()
# test case for https://jira.taosdata.com:18080/browse/TD-4568
tdLog.info("=============== step1,check bool and tinyint data type")
tdLog.info("=============== step1.1,drop table && create table")
cmd1 = 'drop table if exists in_bool_tinyint_1 ;'
cmd2 = 'drop table if exists in_bool_tinyint_2 ;'
cmd3 = 'drop table if exists in_bool_tinyint_3 ;'
cmd10 = 'drop table if exists in_stable_1 ;'
cmd11 = 'create stable in_stable_1(ts timestamp,in_bool bool,in_tinyint tinyint) tags (tin_bool bool,tin_tinyint tinyint) ;'
cmd12 = 'create table in_bool_tinyint_1 using in_stable_1 tags(\'true\',\'127\') ; '
cmd13 = 'create table in_bool_tinyint_2 using in_stable_1 tags(\'false\',\'-127\') ; '
cmd14 = 'create table in_bool_tinyint_3 using in_stable_1 tags(\'false\',\'0\') ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdLog.info(cmd10)
tdSql.execute(cmd10)
tdLog.info(cmd11)
tdSql.execute(cmd11)
tdLog.info(cmd12)
tdSql.execute(cmd12)
tdLog.info(cmd13)
tdSql.execute(cmd13)
tdLog.info(cmd14)
tdSql.execute(cmd14)
tdLog.info("=============== step1.2,insert stable right data and check in function")
cmd1 = 'insert into in_bool_tinyint_1 values(now,\'true\',\'-127\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from in_stable_1 where in_bool in (true) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'-127')
tdSql.checkData(0,3,'True')
tdSql.checkData(0,4,'127')
tdSql.query('select * from in_stable_1 where in_tinyint in (-127) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'-127')
tdSql.checkData(0,3,'True')
tdSql.checkData(0,4,'127')
tdSql.query('select * from in_stable_1 where tin_bool in (true) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'-127')
tdSql.checkData(0,3,'True')
tdSql.checkData(0,4,'127')
tdSql.query('select * from in_stable_1 where tin_tinyint in (127) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'-127')
tdSql.checkData(0,3,'True')
tdSql.checkData(0,4,'127')
tdSql.query('select * from in_bool_tinyint_1 where in_bool in (true) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'-127')
tdSql.query('select * from in_bool_tinyint_1 where in_tinyint in (-127) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'-127')
cmd2 = 'insert into in_bool_tinyint_2 values(now,\'false\',\'127\') ;'
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdSql.query('select * from in_stable_1 where in_bool in (false) order by ts desc')
tdSql.checkData(0,1,'False')
tdSql.checkData(0,2,'127')
tdSql.checkData(0,3,'False')
tdSql.checkData(0,4,'-127')
tdSql.query('select * from in_stable_1 where in_tinyint in (127) order by ts desc')
tdSql.checkData(0,1,'False')
tdSql.checkData(0,2,'127')
tdSql.checkData(0,3,'False')
tdSql.checkData(0,4,'-127')
tdSql.query('select * from in_stable_1 where tin_bool in (false) order by ts desc')
tdSql.checkData(0,1,'False')
tdSql.checkData(0,2,'127')
tdSql.checkData(0,3,'False')
tdSql.checkData(0,4,'-127')
tdSql.query('select * from in_stable_1 where tin_tinyint in (-127) order by ts desc')
tdSql.checkData(0,1,'False')
tdSql.checkData(0,2,'127')
tdSql.checkData(0,3,'False')
tdSql.checkData(0,4,'-127')
tdSql.query('select * from in_bool_tinyint_2 where in_bool in (false) order by ts desc')
tdSql.checkData(0,1,'False')
tdSql.checkData(0,2,'127')
tdSql.query('select * from in_bool_tinyint_2 where in_tinyint in (127) order by ts desc')
tdSql.checkData(0,1,'False')
tdSql.checkData(0,2,'127')
cmd3 = 'insert into in_bool_tinyint_3 values(now,\'true\',\'0\') ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdSql.query('select * from in_stable_1 where in_tinyint in (0) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'False')
tdSql.checkData(0,4,'0')
tdSql.query('select * from in_stable_1 where tin_tinyint in (0) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'False')
tdSql.checkData(0,4,'0')
tdSql.query('select * from in_bool_tinyint_3 where in_bool in (true) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'0')
tdSql.query('select * from in_bool_tinyint_3 where in_tinyint in (0) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'0')
tdLog.info("=============== step1.3,drop normal table && create table")
cmd1 = 'drop table if exists normal_in_bool_tinyint_1 ;'
cmd2 = 'create table normal_in_bool_tinyint_1 (ts timestamp,in_bool bool,in_tinyint tinyint) ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info("=============== step1.4,insert normal table right data and check in function")
cmd1 = 'insert into normal_in_bool_tinyint_1 values(now,\'true\',\'-127\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from normal_in_bool_tinyint_1 where in_bool in (true) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'-127')
tdSql.query('select * from normal_in_bool_tinyint_1 where in_tinyint in (-127) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'-127')
cmd2 = 'insert into normal_in_bool_tinyint_1 values(now,\'false\',\'127\') ;'
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdSql.query('select * from normal_in_bool_tinyint_1 where in_bool in (false) order by ts desc')
tdSql.checkData(0,1,'False')
tdSql.checkData(0,2,'127')
tdSql.query('select * from normal_in_bool_tinyint_1 where in_tinyint in (127) order by ts desc')
tdSql.checkData(0,1,'False')
tdSql.checkData(0,2,'127')
cmd3 = 'insert into normal_in_bool_tinyint_1 values(now,\'true\',\'0\') ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdSql.query('select * from normal_in_bool_tinyint_1 where in_tinyint in (0) order by ts desc')
tdSql.checkData(0,1,'True')
tdSql.checkData(0,2,'0')
tdLog.info("=============== step2,check int、smallint and bigint data type")
tdLog.info("=============== step2.1,drop table && create table")
cmd1 = 'drop table if exists in_int_smallint_bigint_1 ;'
cmd2 = 'drop table if exists in_int_smallint_bigint_2 ;'
cmd3 = 'drop table if exists in_int_smallint_bigint_3 ;'
cmd10 = 'drop table if exists in_stable_2 ;'
cmd11 = 'create stable in_stable_2(ts timestamp,in_int int,in_small smallint , in_big bigint) tags (tin_int int,tin_small smallint , tin_big bigint) ;'
cmd12 = 'create table in_int_smallint_bigint_1 using in_stable_2 tags(\'2147483647\',\'-32767\',\'0\') ; '
cmd13 = 'create table in_int_smallint_bigint_2 using in_stable_2 tags(\'-2147483647\',\'0\',\'9223372036854775807\') ; '
cmd14 = 'create table in_int_smallint_bigint_3 using in_stable_2 tags(\'0\',\'32767\',\'-9223372036854775807\') ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdLog.info(cmd10)
tdSql.execute(cmd10)
tdLog.info(cmd11)
tdSql.execute(cmd11)
tdLog.info(cmd12)
tdSql.execute(cmd12)
tdLog.info(cmd13)
tdSql.execute(cmd13)
tdLog.info(cmd14)
tdSql.execute(cmd14)
tdLog.info("=============== step2.2,insert stable right data and check in function")
cmd1 = 'insert into in_int_smallint_bigint_1 values(now,\'2147483647\',\'-32767\',\'0\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from in_stable_2 where in_int in (2147483647) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'2147483647')
tdSql.checkData(0,5,'-32767')
tdSql.checkData(0,6,'0')
tdSql.query('select * from in_stable_2 where in_small in (-32767) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'2147483647')
tdSql.checkData(0,5,'-32767')
tdSql.checkData(0,6,'0')
tdSql.query('select * from in_stable_2 where in_big in (0) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'2147483647')
tdSql.checkData(0,5,'-32767')
tdSql.checkData(0,6,'0')
tdSql.query('select * from in_stable_2 where tin_int in (2147483647) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'2147483647')
tdSql.checkData(0,5,'-32767')
tdSql.checkData(0,6,'0')
tdSql.query('select * from in_stable_2 where tin_small in (-32767) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'2147483647')
tdSql.checkData(0,5,'-32767')
tdSql.checkData(0,6,'0')
tdSql.query('select * from in_stable_2 where tin_big in (0) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'2147483647')
tdSql.checkData(0,5,'-32767')
tdSql.checkData(0,6,'0')
tdSql.query('select * from in_int_smallint_bigint_1 where in_int in (2147483647) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.query('select * from in_int_smallint_bigint_1 where in_small in (-32767) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.query('select * from in_int_smallint_bigint_1 where in_big in (0) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
cmd2 = 'insert into in_int_smallint_bigint_2 values(now,\'-2147483647\',\'0\',\'9223372036854775807\') ;'
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdSql.query('select * from in_stable_2 where in_int in (-2147483647) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.checkData(0,4,'-2147483647')
tdSql.checkData(0,5,'0')
tdSql.checkData(0,6,'9223372036854775807')
tdSql.query('select * from in_stable_2 where in_small in (0) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.checkData(0,4,'-2147483647')
tdSql.checkData(0,5,'0')
tdSql.checkData(0,6,'9223372036854775807')
tdSql.query('select * from in_stable_2 where in_big in (9223372036854775807) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.checkData(0,4,'-2147483647')
tdSql.checkData(0,5,'0')
tdSql.checkData(0,6,'9223372036854775807')
tdSql.query('select * from in_stable_2 where tin_int in (-2147483647) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.checkData(0,4,'-2147483647')
tdSql.checkData(0,5,'0')
tdSql.checkData(0,6,'9223372036854775807')
tdSql.query('select * from in_stable_2 where tin_small in (0) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.checkData(0,4,'-2147483647')
tdSql.checkData(0,5,'0')
tdSql.checkData(0,6,'9223372036854775807')
tdSql.query('select * from in_stable_2 where tin_big in (9223372036854775807) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.checkData(0,4,'-2147483647')
tdSql.checkData(0,5,'0')
tdSql.checkData(0,6,'9223372036854775807')
tdSql.query('select * from in_int_smallint_bigint_2 where in_int in (-2147483647) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.query('select * from in_int_smallint_bigint_2 where in_small in (0) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.query('select * from in_int_smallint_bigint_2 where in_big in (9223372036854775807) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
cmd3 = 'insert into in_int_smallint_bigint_3 values(now,\'0\',\'32767\',\'-9223372036854775807\') ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdSql.query('select * from in_stable_2 where in_int in (0) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.checkData(0,4,'0')
tdSql.checkData(0,5,'32767')
tdSql.checkData(0,6,'-9223372036854775807')
tdSql.query('select * from in_stable_2 where in_small in (32767) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.checkData(0,4,'0')
tdSql.checkData(0,5,'32767')
tdSql.checkData(0,6,'-9223372036854775807')
tdSql.query('select * from in_stable_2 where in_big in (-9223372036854775807) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.checkData(0,4,'0')
tdSql.checkData(0,5,'32767')
tdSql.checkData(0,6,'-9223372036854775807')
tdSql.query('select * from in_stable_2 where tin_int in (0) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.checkData(0,4,'0')
tdSql.checkData(0,5,'32767')
tdSql.checkData(0,6,'-9223372036854775807')
tdSql.query('select * from in_stable_2 where tin_small in (32767) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.checkData(0,4,'0')
tdSql.checkData(0,5,'32767')
tdSql.checkData(0,6,'-9223372036854775807')
tdSql.query('select * from in_stable_2 where tin_big in (-9223372036854775807) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.checkData(0,4,'0')
tdSql.checkData(0,5,'32767')
tdSql.checkData(0,6,'-9223372036854775807')
tdSql.query('select * from in_int_smallint_bigint_3 where in_int in (0) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.query('select * from in_int_smallint_bigint_3 where in_small in (32767) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.query('select * from in_int_smallint_bigint_3 where in_big in (-9223372036854775807) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdLog.info("=============== step2.3,drop normal table && create table")
cmd1 = 'drop table if exists normal_int_smallint_bigint_1 ;'
cmd2 = 'create table normal_int_smallint_bigint_1 (ts timestamp,in_int int,in_small smallint , in_big bigint) ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info("=============== step2.4,insert normal table right data and check in function")
cmd1 = 'insert into normal_int_smallint_bigint_1 values(now,\'2147483647\',\'-32767\',\'0\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from normal_int_smallint_bigint_1 where in_int in (2147483647) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.query('select * from normal_int_smallint_bigint_1 where in_small in (-32767) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
tdSql.query('select * from normal_int_smallint_bigint_1 where in_big in (0) order by ts desc')
tdSql.checkData(0,1,'2147483647')
tdSql.checkData(0,2,'-32767')
tdSql.checkData(0,3,'0')
cmd2 = 'insert into normal_int_smallint_bigint_1 values(now,\'-2147483647\',\'0\',\'9223372036854775807\') ;'
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdSql.query('select * from normal_int_smallint_bigint_1 where in_int in (-2147483647) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.query('select * from normal_int_smallint_bigint_1 where in_small in (0) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
tdSql.query('select * from normal_int_smallint_bigint_1 where in_big in (9223372036854775807) order by ts desc')
tdSql.checkData(0,1,'-2147483647')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'9223372036854775807')
cmd3 = 'insert into normal_int_smallint_bigint_1 values(now,\'0\',\'32767\',\'-9223372036854775807\') ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdSql.query('select * from normal_int_smallint_bigint_1 where in_int in (0) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.query('select * from normal_int_smallint_bigint_1 where in_small in (32767) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdSql.query('select * from normal_int_smallint_bigint_1 where in_big in (-9223372036854775807) order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'32767')
tdSql.checkData(0,3,'-9223372036854775807')
tdLog.info("=============== step3,check binary and nchar data type")
tdLog.info("=============== step3.1,drop table && create table")
cmd1 = 'drop table if exists in_binary_nchar_1 ;'
cmd2 = 'drop table if exists in_binary_nchar_2 ;'
cmd3 = 'drop table if exists in_binary_nchar_3 ;'
cmd10 = 'drop table if exists in_stable_3 ;'
cmd11 = 'create stable in_stable_3(ts timestamp,in_binary binary(8),in_nchar nchar(12)) tags (tin_binary binary(16),tin_nchar nchar(20)) ;'
cmd12 = 'create table in_binary_nchar_1 using in_stable_3 tags(\'0\',\'0\') ; '
cmd13 = 'create table in_binary_nchar_2 using in_stable_3 tags(\'TDengine\',\'北京涛思数据科技有限公司\') ; '
cmd14 = 'create table in_binary_nchar_3 using in_stable_3 tags(\'taosdataTDengine\',\'北京涛思数据科技有限公司TDengine\') ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdLog.info(cmd10)
tdSql.execute(cmd10)
tdLog.info(cmd11)
tdSql.execute(cmd11)
tdLog.info(cmd12)
tdSql.execute(cmd12)
tdLog.info(cmd13)
tdSql.execute(cmd13)
tdLog.info(cmd14)
tdSql.execute(cmd14)
tdLog.info("=============== step3.2,insert stable right data and check in function")
cmd1 = 'insert into in_binary_nchar_1 values(now,\'0\',\'0\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from in_stable_3 where in_binary in (\'0\') order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'0')
tdSql.query('select * from in_stable_3 where in_nchar in (\'0\') order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'0')
tdSql.query('select * from in_stable_3 where tin_binary in (\'0\') order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'0')
tdSql.query('select * from in_stable_3 where tin_nchar in (\'0\') order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'0')
tdSql.checkData(0,3,'0')
tdSql.checkData(0,4,'0')
tdSql.query('select * from in_binary_nchar_1 where in_binary in (\'0\') order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'0')
tdSql.query('select * from in_binary_nchar_1 where in_nchar in (\'0\') order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'0')
cmd2 = 'insert into in_binary_nchar_2 values(now,\'TAOS\',\'涛思数据TAOSdata\') ;'
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdSql.query('select * from in_stable_3 where in_binary in (\'TAOS\') order by ts desc')
tdSql.checkData(0,1,'TAOS')
tdSql.checkData(0,2,'涛思数据TAOSdata')
tdSql.checkData(0,3,'TDengine')
tdSql.checkData(0,4,'北京涛思数据科技有限公司')
tdSql.query('select * from in_stable_3 where in_nchar in (\'涛思数据TAOSdata\') order by ts desc')
tdSql.checkData(0,1,'TAOS')
tdSql.checkData(0,2,'涛思数据TAOSdata')
tdSql.checkData(0,3,'TDengine')
tdSql.checkData(0,4,'北京涛思数据科技有限公司')
tdSql.query('select * from in_stable_3 where tin_binary in (\'TDengine\') order by ts desc')
tdSql.checkData(0,1,'TAOS')
tdSql.checkData(0,2,'涛思数据TAOSdata')
tdSql.checkData(0,3,'TDengine')
tdSql.checkData(0,4,'北京涛思数据科技有限公司')
tdSql.query('select * from in_stable_3 where tin_nchar in (\'北京涛思数据科技有限公司\') order by ts desc')
tdSql.checkData(0,1,'TAOS')
tdSql.checkData(0,2,'涛思数据TAOSdata')
tdSql.checkData(0,3,'TDengine')
tdSql.checkData(0,4,'北京涛思数据科技有限公司')
tdSql.query('select * from in_binary_nchar_2 where in_binary in (\'TAOS\') order by ts desc')
tdSql.checkData(0,1,'TAOS')
tdSql.checkData(0,2,'涛思数据TAOSdata')
tdSql.query('select * from in_binary_nchar_2 where in_nchar in (\'涛思数据TAOSdata\') order by ts desc')
tdSql.checkData(0,1,'TAOS')
tdSql.checkData(0,2,'涛思数据TAOSdata')
cmd3 = 'insert into in_binary_nchar_3 values(now,\'TDengine\',\'北京涛思数据科技有限公司\') ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdSql.query('select * from in_stable_3 where in_binary in (\'TDengine\') order by ts desc')
tdSql.checkData(0,1,'TDengine')
tdSql.checkData(0,2,'北京涛思数据科技有限公司')
tdSql.checkData(0,3,'taosdataTDengine')
tdSql.checkData(0,4,'北京涛思数据科技有限公司TDengine')
tdSql.query('select * from in_stable_3 where in_nchar in (\'北京涛思数据科技有限公司\') order by ts desc')
tdSql.checkData(0,1,'TDengine')
tdSql.checkData(0,2,'北京涛思数据科技有限公司')
tdSql.checkData(0,3,'taosdataTDengine')
tdSql.checkData(0,4,'北京涛思数据科技有限公司TDengine')
tdSql.query('select * from in_stable_3 where tin_binary in (\'taosdataTDengine\') order by ts desc')
tdSql.checkData(0,1,'TDengine')
tdSql.checkData(0,2,'北京涛思数据科技有限公司')
tdSql.checkData(0,3,'taosdataTDengine')
tdSql.checkData(0,4,'北京涛思数据科技有限公司TDengine')
tdSql.query('select * from in_stable_3 where tin_nchar in (\'北京涛思数据科技有限公司TDengine\') order by ts desc')
tdSql.checkData(0,1,'TDengine')
tdSql.checkData(0,2,'北京涛思数据科技有限公司')
tdSql.checkData(0,3,'taosdataTDengine')
tdSql.checkData(0,4,'北京涛思数据科技有限公司TDengine')
tdSql.query('select * from in_binary_nchar_3 where in_binary in (\'TDengine\') order by ts desc')
tdSql.checkData(0,1,'TDengine')
tdSql.checkData(0,2,'北京涛思数据科技有限公司')
tdSql.query('select * from in_binary_nchar_3 where in_nchar in (\'北京涛思数据科技有限公司\') order by ts desc')
tdSql.checkData(0,1,'TDengine')
tdSql.checkData(0,2,'北京涛思数据科技有限公司')
tdLog.info("=============== step3.3,drop normal table && create table")
cmd1 = 'drop table if exists normal_in_binary_nchar_1 ;'
cmd2 = 'create table normal_in_binary_nchar_1 (ts timestamp,in_binary binary(8),in_nchar nchar(12)) ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info("=============== step3.4,insert normal table right data and check in function")
cmd1 = 'insert into normal_in_binary_nchar_1 values(now,\'0\',\'0\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from normal_in_binary_nchar_1 where in_binary in (\'0\') order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'0')
tdSql.query('select * from normal_in_binary_nchar_1 where in_nchar in (\'0\') order by ts desc')
tdSql.checkData(0,1,'0')
tdSql.checkData(0,2,'0')
cmd2 = 'insert into normal_in_binary_nchar_1 values(now,\'TAOS\',\'涛思数据TAOSdata\') ;'
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdSql.query('select * from normal_in_binary_nchar_1 where in_binary in (\'TAOS\') order by ts desc')
tdSql.checkData(0,1,'TAOS')
tdSql.checkData(0,2,'涛思数据TAOSdata')
tdSql.query('select * from normal_in_binary_nchar_1 where in_nchar in (\'涛思数据TAOSdata\') order by ts desc')
tdSql.checkData(0,1,'TAOS')
tdSql.checkData(0,2,'涛思数据TAOSdata')
cmd3 = 'insert into normal_in_binary_nchar_1 values(now,\'TDengine\',\'北京涛思数据科技有限公司\') ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdSql.query('select * from normal_in_binary_nchar_1 where in_binary in (\'TDengine\') order by ts desc')
tdSql.checkData(0,1,'TDengine')
tdSql.checkData(0,2,'北京涛思数据科技有限公司')
tdSql.query('select * from normal_in_binary_nchar_1 where in_nchar in (\'北京涛思数据科技有限公司\') order by ts desc')
tdSql.checkData(0,1,'TDengine')
tdSql.checkData(0,2,'北京涛思数据科技有限公司')
tdLog.info("=============== step4,check float and double data type,not support")
tdLog.info("=============== step4.1,drop table && create table")
cmd1 = 'drop table if exists in_float_double_1 ;'
cmd10 = 'drop table if exists in_stable_4 ;'
cmd11 = 'create stable in_stable_4(ts timestamp,in_float float,in_double double) tags (tin_float float,tin_double double) ;'
cmd12 = 'create table in_float_double_1 using in_stable_4 tags(\'666\',\'88888\') ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd10)
tdSql.execute(cmd10)
tdLog.info(cmd11)
tdSql.execute(cmd11)
tdLog.info(cmd12)
tdSql.execute(cmd12)
tdLog.info("=============== step4.2,insert stable right data and check in function")
cmd1 = 'insert into in_float_double_1 values(now,\'888\',\'66666\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
cmd2 = 'select * from in_stable_4 where in_float in (\'888\');'
tdLog.info(cmd2)
tdSql.error(cmd2)
try:
tdSql.execute(cmd2)
tdLog.exit("invalid operation: not supported filter condition")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: not supported filter condition")
cmd3 = 'select * from in_stable_4 where in_double in (\'66666\');'
tdLog.info(cmd3)
tdSql.error(cmd3)
try:
tdSql.execute(cmd3)
tdLog.exit("invalid operation: not supported filter condition")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: not supported filter condition")
cmd4 = 'select * from in_stable_4 where tin_float in (\'666\');'
tdLog.info(cmd4)
tdSql.error(cmd4)
try:
tdSql.execute(cmd4)
tdLog.exit("invalid operation: not supported filter condition")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: not supported filter condition")
cmd5 = 'select * from in_stable_4 where tin_double in (\'88888\');'
tdLog.info(cmd5)
tdSql.error(cmd5)
try:
tdSql.execute(cmd5)
tdLog.exit("invalid operation: not supported filter condition")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: not supported filter condition")
cmd6 = 'select * from in_float_double_1 where in_float in (\'888\');'
tdLog.info(cmd6)
tdSql.error(cmd6)
try:
tdSql.execute(cmd6)
tdLog.exit("invalid operation: not supported filter condition")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: not supported filter condition")
cmd7 = 'select * from in_float_double_1 where in_double in (\'66666\');'
tdLog.info(cmd7)
tdSql.error(cmd7)
try:
tdSql.execute(cmd7)
tdLog.exit("invalid operation: not supported filter condition")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: not supported filter condition")
tdLog.info("=============== step4.3,drop normal table && create table")
cmd1 = 'drop table if exists normal_in_float_double_1 ;'
cmd2 = 'create table normal_in_float_double_1 (ts timestamp,in_float float,in_double double) ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info("=============== step4.4,insert normal table right data and check in function")
cmd1 = 'insert into normal_in_float_double_1 values(now,\'888\',\'666666\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
cmd2 = 'select * from normal_in_float_double_1 where in_float in (\'888\');'
tdLog.info(cmd2)
tdSql.error(cmd2)
try:
tdSql.execute(cmd2)
tdLog.exit("invalid operation: not supported filter condition")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: not supported filter condition")
cmd3 = 'select * from normal_in_float_double_1 where in_double in (\'66666\');'
tdLog.info(cmd3)
tdSql.error(cmd3)
try:
tdSql.execute(cmd3)
tdLog.exit("invalid operation: not supported filter condition")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: not supported filter condition")
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())

View File

@ -0,0 +1,382 @@
###################################################################
# Copyright (c) 2016 by TAOS Technologies, Inc.
# All rights reserved.
#
# This file is proprietary and confidential to TAOS Technologies.
# No part of this file may be reproduced, stored, transmitted,
# disclosed or used in any form or by any means other than as
# expressly provided by the written permission from Jianhui Tao
#
###################################################################
# -*- coding: utf-8 -*-
import sys
import datetime
from util.log import *
from util.cases import *
from util.sql import *
class TDTestCase:
def init(self, conn, logSql):
tdLog.debug("start to execute %s" % __file__)
tdSql.init(conn.cursor(), logSql)
def run(self):
tdSql.prepare()
# test case for https://jira.taosdata.com:18080/browse/TD-4541
tdLog.info("=============== step1,check normal table")
tdLog.info("=============== step1.1,drop table && create table")
cmd1 = 'drop table if exists length11 ;'
cmd2 = 'create table length11 (ts timestamp,lengthbia binary(10),lengthnchar nchar(20));'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info("=============== step1.2,insert table right data")
cmd1 = 'insert into length11 values(now,\'aaaaaaaaaa\',\'bbbbbbbbbbbbbbbbbbbb\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from length11 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb')
tdLog.info("=============== step1.3,insert table wrong data")
cmd1 = 'insert into length11 values(now,\'aaaaaaaaaa1\',\'bbbbbbbbbbbbbbbbbbbb1\') ;'
tdLog.info(cmd1)
tdSql.error(cmd1)
try:
tdSql.execute(cmd1)
tdLog.exit("string data overflow")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("insert wrong data error catched")
tdSql.query('select * from length11 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb')
tdLog.info("=============== step1.4,modify columu length ")
cmd1 = 'alter table length11 modify column lengthbia binary(10) ;'
tdLog.info(cmd1)
tdSql.error(cmd1)
try:
tdSql.execute(cmd1)
tdLog.exit("new column length should be bigger than old one")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("new column length should be bigger than old one")
cmd2 = 'alter table length11 modify column lengthnchar nchar(20);'
tdLog.info(cmd2)
tdSql.error(cmd2)
try:
tdSql.execute(cmd2)
tdLog.exit("new column length should be bigger than old one")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("new column length should be bigger than old one")
cmd3 = 'alter table length11 modify column lengthbia binary(11) ;'
cmd4 = 'describe length11 ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdLog.info(cmd4)
tdSql.execute(cmd4)
tdSql.query('describe length11 ;')
tdSql.checkData(1,2,11)
cmd5 = 'alter table length11 modify column lengthnchar nchar(21);'
cmd6 = 'describe length11 ;'
tdLog.info(cmd5)
tdSql.execute(cmd5)
tdLog.info(cmd6)
tdSql.execute(cmd6)
tdSql.query('describe length11 ;')
tdSql.checkData(2,2,21)
tdSql.query('select * from length11 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb')
tdLog.info("=============== step1.5,insert table right data")
cmd1 = 'insert into length11 values(now,\'aaaaaaaaaa1\',\'bbbbbbbbbbbbbbbbbbbb1\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from length11 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdLog.info("=============== step2,check stable table and tag")
tdLog.info("=============== step2.1,drop table && create table")
cmd1 = 'drop table if exists length1 ;'
cmd2 = 'drop table if exists length2 ;'
cmd3 = 'drop table if exists length2 ;'
cmd4 = 'drop table if exists lengthsta1 ;'
cmd5 = 'create stable lengthsta1(ts timestamp,lengthbia binary(10),lengthnchar nchar(20)) tags (tlengthbia binary(15),tlengthnchar nchar(25)) ;'
cmd6 = 'create table length1 using lengthsta1 tags(\'aaaaabbbbbaaaaa\',\'bbbbbaaaaabbbbbaaaaabbbbb\') ; '
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdLog.info(cmd4)
tdSql.execute(cmd4)
tdLog.info(cmd5)
tdSql.execute(cmd5)
tdLog.info(cmd6)
tdSql.execute(cmd6)
tdLog.info("=============== step2.2,insert table right data")
cmd1 = 'insert into length1 values(now,\'aaaaaaaaaa\',\'bbbbbbbbbbbbbbbbbbbb\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from length1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb')
tdLog.info("=============== step2.3,insert table wrong data")
cmd1 = 'insert into length1 values(now,\'aaaaaaaaaa1\',\'bbbbbbbbbbbbbbbbbbbb1\') ;'
tdLog.info(cmd1)
tdSql.error(cmd1)
try:
tdSql.execute(cmd1)
tdLog.exit("string data overflow")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("insert wrong data error catched")
tdSql.query('select * from length1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb')
tdLog.info("=============== step2.4,modify columu length ")
cmd0 = 'alter table length1 modify column lengthbia binary(10) ;'
tdLog.info(cmd0)
tdSql.error(cmd0)
try:
tdSql.execute(cmd1)
tdLog.exit("invalid operation: column can only be modified by super table")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: column can only be modified by super table")
cmd1 = 'alter table lengthsta1 modify column lengthbia binary(10) ;'
tdLog.info(cmd1)
tdSql.error(cmd1)
try:
tdSql.execute(cmd1)
tdLog.exit("new column length should be bigger than old one")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("new column length should be bigger than old one")
cmd2 = 'alter table lengthsta1 modify column lengthnchar nchar(20);'
tdLog.info(cmd2)
tdSql.error(cmd2)
try:
tdSql.execute(cmd2)
tdLog.exit("new column length should be bigger than old one")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("new column length should be bigger than old one")
cmd3 = 'alter table lengthsta1 modify column lengthbia binary(11) ;'
cmd4 = 'describe lengthsta1 ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdLog.info(cmd4)
tdSql.execute(cmd4)
tdSql.query('describe length1 ;')
tdSql.checkData(1,2,11)
cmd5 = 'alter table lengthsta1 modify column lengthnchar nchar(21);'
cmd6 = 'describe lengthsta1 ;'
tdLog.info(cmd5)
tdSql.execute(cmd5)
tdLog.info(cmd6)
tdSql.execute(cmd6)
tdSql.query('describe lengthsta1 ;')
tdSql.checkData(2,2,21)
tdSql.query('select * from lengthsta1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb')
tdLog.info("=============== step2.5,insert table right data")
cmd1 = 'insert into length1 values(now,\'aaaaaaaaaa1\',\'bbbbbbbbbbbbbbbbbbbb1\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('select * from length1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdLog.info("=============== step2.6,create table wrong tag")
cmd1 = 'create table length2 using lengthsta1 tags(\'aaaaabbbbbaaaaa1\',\'bbbbbaaaaabbbbbaaaaabbbbb1\') ;'
tdLog.info(cmd1)
tdSql.error(cmd1)
try:
tdSql.execute(cmd1)
tdLog.exit("invalid operation: tag value too long")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("invalid operation: tag value too long")
tdSql.query('select * from lengthsta1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdLog.info("=============== step2.7,modify tag columu length ")
cmd1 = 'alter table lengthsta1 modify tag tlengthbia binary(15) ;'
tdLog.info(cmd1)
tdSql.error(cmd1)
try:
tdSql.execute(cmd1)
tdLog.exit("new column length should be bigger than old one")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("new column length should be bigger than old one")
cmd2 = 'alter table lengthsta1 modify tag tlengthnchar nchar(25);'
tdLog.info(cmd2)
tdSql.error(cmd2)
try:
tdSql.execute(cmd2)
tdLog.exit("new column length should be bigger than old one")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("new column length should be bigger than old one")
cmd3 = 'alter table lengthsta1 modify tag tlengthbia binary(16) ;'
cmd4 = 'describe lengthsta1 ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdLog.info(cmd4)
tdSql.execute(cmd4)
tdSql.query('describe lengthsta1 ;')
tdSql.checkData(3,2,16)
cmd5 = 'alter table lengthsta1 modify tag tlengthnchar nchar(26);'
cmd6 = 'describe lengthsta1 ;'
tdLog.info(cmd5)
tdSql.execute(cmd5)
tdLog.info(cmd6)
tdSql.execute(cmd6)
tdSql.query('describe lengthsta1 ;')
tdSql.checkData(4,2,26)
tdSql.query('select * from lengthsta1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdSql.checkData(0,3,'aaaaabbbbbaaaaa')
tdSql.checkData(0,4,'bbbbbaaaaabbbbbaaaaabbbbb')
tdLog.info("=============== step2.8,creat tag right data and insert data")
cmd1 = 'create table length2 using lengthsta1 tags(\'aaaaabbbbbaaaaa1\',\'bbbbbaaaaabbbbbaaaaabbbbb1\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('describe length2 ;')
tdSql.checkData(3,2,16)
tdSql.checkData(4,2,26)
cmd2 = 'insert into length2 values(now,\'aaaaaaaaaa1\',\'bbbbbbbbbbbbbbbbbbbb1\') ;'
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdSql.query('select * from length2 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdSql.query('select * from lengthsta1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdSql.checkData(0,3,'aaaaabbbbbaaaaa1')
tdSql.checkData(0,4,'bbbbbaaaaabbbbbaaaaabbbbb1')
tdLog.info("=============== step2.9,modify tag columu length again ")
cmd1 = 'alter table lengthsta1 modify tag tlengthbia binary(16) ;'
tdLog.info(cmd1)
tdSql.error(cmd1)
try:
tdSql.execute(cmd1)
tdLog.exit("new column length should be bigger than old one")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("new column length should be bigger than old one")
cmd2 = 'alter table lengthsta1 modify tag tlengthnchar nchar(26);'
tdLog.info(cmd2)
tdSql.error(cmd2)
try:
tdSql.execute(cmd2)
tdLog.exit("new column length should be bigger than old one")
except Exception as e:
tdLog.info(repr(e))
tdLog.info("new column length should be bigger than old one")
cmd3 = 'alter table lengthsta1 modify tag tlengthbia binary(20) ;'
cmd4 = 'describe lengthsta1 ;'
tdLog.info(cmd3)
tdSql.execute(cmd3)
tdLog.info(cmd4)
tdSql.execute(cmd4)
tdSql.query('describe lengthsta1 ;')
tdSql.checkData(3,2,20)
cmd5 = 'alter table lengthsta1 modify tag tlengthnchar nchar(30);'
cmd6 = 'describe lengthsta1 ;'
tdLog.info(cmd5)
tdSql.execute(cmd5)
tdLog.info(cmd6)
tdSql.execute(cmd6)
tdSql.query('describe lengthsta1 ;')
tdSql.checkData(4,2,30)
tdSql.query('select * from lengthsta1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdSql.checkData(0,3,'aaaaabbbbbaaaaa1')
tdSql.checkData(0,4,'bbbbbaaaaabbbbbaaaaabbbbb1')
tdLog.info("=============== step2.10,creat tag right data and insert data again")
cmd1 = 'create table length3 using lengthsta1 tags(\'aaaaabbbbbaaaaabbbbb\',\'bbbbbaaaaabbbbbaaaaabbbbbaaaaa\') ;'
tdLog.info(cmd1)
tdSql.execute(cmd1)
tdSql.query('describe length3 ;')
tdSql.checkData(3,2,20)
tdSql.checkData(4,2,30)
cmd2 = 'insert into length3 values(now,\'aaaaaaaaaa1\',\'bbbbbbbbbbbbbbbbbbbb1\') ;'
tdLog.info(cmd2)
tdSql.execute(cmd2)
tdSql.query('select * from length3 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdSql.query('select * from lengthsta1 order by ts desc')
tdSql.checkData(0,1,'aaaaaaaaaa1')
tdSql.checkData(0,2,'bbbbbbbbbbbbbbbbbbbb1')
tdSql.checkData(0,3,'aaaaabbbbbaaaaabbbbb')
tdSql.checkData(0,4,'bbbbbaaaaabbbbbaaaaabbbbbaaaaa')
def stop(self):
tdSql.close()
tdLog.success("%s successfully executed" % __file__)
tdCases.addWindows(__file__, TDTestCase())
tdCases.addLinux(__file__, TDTestCase())

View File

@ -18,6 +18,7 @@ import datetime
import inspect import inspect
import psutil import psutil
import shutil import shutil
import pandas as pd
from util.log import * from util.log import *
@ -136,7 +137,14 @@ class TDSql:
def checkData(self, row, col, data): def checkData(self, row, col, data):
self.checkRowCol(row, col) self.checkRowCol(row, col)
if self.queryResult[row][col] != data: if self.queryResult[row][col] != data:
if self.cursor.istype(col, "TIMESTAMP") and self.queryResult[row][col] == datetime.datetime.fromisoformat(data): if self.cursor.istype(col, "TIMESTAMP"):
# suppose user want to check nanosecond timestamp if a longer data passed
if (len(data) >= 28):
if pd.to_datetime(self.queryResult[row][col]) == pd.to_datetime(data):
tdLog.info("sql:%s, row:%d col:%d data:%d == expect:%s" %
(self.sql, row, col, self.queryResult[row][col], data))
else:
if self.queryResult[row][col] == datetime.datetime.fromisoformat(data):
tdLog.info("sql:%s, row:%d col:%d data:%s == expect:%s" % tdLog.info("sql:%s, row:%d col:%d data:%s == expect:%s" %
(self.sql, row, col, self.queryResult[row][col], data)) (self.sql, row, col, self.queryResult[row][col], data))
return return

View File

@ -20,17 +20,22 @@ sql use db
sql create table tb (ts timestamp, val int, val1 int, val2 int) sql create table tb (ts timestamp, val int, val1 int, val2 int)
sql create table tb2 (ts timestamp, val int, val1 int, val2 int) sql create table tb2 (ts timestamp, val int, val1 int, val2 int)
sql create table t2 (ts timestamp, val int) sql create table t2 (ts timestamp, val int)
sql create table tb3 (ts timestamp, val int, val1 int, val2 int)
sql insert into tb values('2020-01-01 00:00:00.000', 1, 11, 21) sql insert into tb values('2020-01-01 00:00:00.000', 1, 11, 21)
sql insert into tb values('2020-01-02 00:00:00.000', 1, 12, 22) sql insert into tb values('2020-01-02 00:00:00.000', 1, 12, 22)
sql insert into tb values('2020-01-03 00:00:00.000', 2, 13, 23) sql insert into tb values('2020-01-03 00:00:00.000', 2, 13, 23)
sql insert into tb values('2020-01-04 00:00:00.000', 2, 14, 24) sql insert into tb values('2020-01-04 00:00:00.000', 2, 14, 24)
sql insert into tb2 values('2020-01-01 00:00:00.000', 21, 211, 221) sql insert into tb2 values('2020-01-01 00:00:00.000', 21, 211, 221)
sql insert into tb2 values('2020-01-02 00:00:00.000', 21, 212, 222) sql insert into tb2 values('2020-01-02 00:00:00.000', 21, 212, 222)
sql insert into tb2 values('2020-01-03 00:00:00.000', 22, 213, 223) sql insert into tb2 values('2020-01-03 00:00:00.000', 22, 213, 223)
sql insert into tb2 values('2020-01-04 00:00:00.000', 22, 214, 224) sql insert into tb2 values('2020-01-04 00:00:00.000', 22, 214, 224)
sql insert into tb3 values('2020-01-01 00:00:00.000', NULL, NULL, NULL)
sql insert into tb3 values('2020-01-02 00:00:00.000', NULL, NULL, NULL)
print =============== step1 - one query, 1 column, with timestamp print =============== step1 - one query, 1 column, with timestamp
system_content curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d '[ {"refId":"A","alias":"","sql":"select ts from db.tb where ts >= 1577980800000 "} ]' 127.0.0.1:7111/grafana/query system_content curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d '[ {"refId":"A","alias":"","sql":"select ts from db.tb where ts >= 1577980800000 "} ]' 127.0.0.1:7111/grafana/query
@ -235,4 +240,11 @@ if $system_content != @[{"refId":"B","target":"BB{val2:223,}","datapoints":[[213
return -1 return -1
endi endi
print =============== step26 - 2 column, no timestamp, NULL
system_content curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d '[ {"refId":"A","alias":"","sql":"select * from db.tb3 "} ]' 127.0.0.1:7111/grafana/query
print step1-> $system_content
if $system_content != @[{"refId":"A","target":"{val1:nil, val2:nil}","datapoints":[[null,1577808000000],[null,1577894400000]]}]@ then
return -1
endi
system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s stop -x SIGINT

View File

@ -817,6 +817,9 @@ print ====================> TODO stddev + normal column filter
print ====================> irate print ====================> irate
sql_error select irate(f1) from st1;
sql select irate(f1) from st1 group by tbname;
sql select irate(k) from t1 sql select irate(k) from t1
if $rows != 1 then if $rows != 1 then
return -1 return -1
@ -1073,6 +1076,12 @@ sql insert into t0 values('2020-1-1 1:3:9', 9);
sql insert into t0 values('2020-1-1 1:4:10', 10); sql insert into t0 values('2020-1-1 1:4:10', 10);
sql insert into t1 values('2020-1-1 1:1:2', 2); sql insert into t1 values('2020-1-1 1:1:2', 2);
print ===========================>td-4739
sql select diff(val) from (select derivative(k, 1s, 0) val from t1);
if $rows != 0 then
return -1
endi
sql insert into t1 values('2020-1-1 1:1:4', 20); sql insert into t1 values('2020-1-1 1:1:4', 20);
sql insert into t1 values('2020-1-1 1:1:6', 200); sql insert into t1 values('2020-1-1 1:1:6', 200);
sql insert into t1 values('2020-1-1 1:1:8', 2000); sql insert into t1 values('2020-1-1 1:1:8', 2000);