diff --git a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h index d16b672f38fe1f7d9c36990f0eab28253f2d4d1b..7181c658ddcdfde3efe7df3c0784c20f18bd4c03 100644 --- a/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h +++ b/src/client/jni/com_taosdata_jdbc_TSDBJNIConnector.h @@ -51,10 +51,10 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset /* * Class: com_taosdata_jdbc_TSDBJNIConnector - * Method: getResultTimePrecision - * Signature: (J)J + * Method: getResultTimePrecisionImp + * 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); /* diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c index 324c436dce442f78b6daea314506c5c6b465f97f..379cf86301f6d52f202cb0fc4916db33d8d5896c 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -113,7 +113,7 @@ static void jniGetGlobalMethod(JNIEnv *env) { g_rowdataSetFloatFp = (*env)->GetMethodID(env, g_rowdataClass, "setFloat", "(IF)V"); g_rowdataSetDoubleFp = (*env)->GetMethodID(env, g_rowdataClass, "setDouble", "(ID)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"); (*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])); break; } - case TSDB_DATA_TYPE_TIMESTAMP: - (*env)->CallVoidMethod(env, rowobj, g_rowdataSetTimestampFp, i, (jlong) * ((int64_t *)row[i])); + case TSDB_DATA_TYPE_TIMESTAMP: { + int precision = taos_result_precision(result); + (*env)->CallVoidMethod(env, rowobj, g_rowdataSetTimestampFp, i, (jlong) * ((int64_t *)row[i]), precision); break; + } default: break; } @@ -672,7 +674,15 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset(J 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) { TAOS *tscon = (TAOS *)con; if (tscon == NULL) { diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index d64fedab0c181b9fc0da50ba0016e22610933e9a..79d9b6e8e33fb80385f47f8a44d7676aaf94142f 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -772,6 +772,10 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { pCmd->active = pCmd->pQueryInfo; pCmd->command = pCmd->pQueryInfo->command; + if (pTableMetaInfo->pTableMeta != NULL) { + pSql->res.precision = tscGetTableInfo(pTableMetaInfo->pTableMeta).precision; + } + return TSDB_CODE_SUCCESS; // do not build query message here } diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml index 8ec65a243e21ff6d6da535690144ba06567ce3c9..a3a36d54cfe3d0c25dd69675be5b3464f4236975 100644 --- a/src/connector/jdbc/pom.xml +++ b/src/connector/jdbc/pom.xml @@ -122,7 +122,6 @@ **/FailOverTest.java **/InvalidResultSetPointerTest.java **/RestfulConnectionTest.java - **/TD4144Test.java **/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java true diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java index 2970f6c2d37d73476ee0d8831a68128569766fb4..686ef3626249d0c6c8e89ca848e054238fe65562 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java @@ -1,5 +1,7 @@ package com.taosdata.jdbc; +import com.taosdata.jdbc.rs.enums.TimestampFormat; + import java.sql.*; import java.util.Enumeration; import java.util.Map; @@ -18,7 +20,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti for (String propName : propNames) { 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); } @@ -516,7 +518,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti public void abort(Executor executor) throws SQLException { if (isClosed()) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); - // do nothing } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java index 9dc559339a4ef88b8423ffcd621c7498437dac5c..8b6c074d1b859f179aac04a83cafb24cfae7c190 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java @@ -9,8 +9,6 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement protected List batchedArgs; private int fetchSize; - - @Override public abstract ResultSet executeQuery(String sql) throws SQLException; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java index 90967b3620fdaccf69f253c8f8927c067b6221fd..411a61eb86e317f5e38e37d2506ec1bdbe01c0a1 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java @@ -32,6 +32,7 @@ public class TSDBError { 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_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"); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java index c978bb3a2e4a1b9dbd264268f057f2b6c735250a..9f0ba5afabde71bf6359cbfb66757e150899deaf 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java @@ -25,6 +25,7 @@ public class TSDBErrorNumbers { 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_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 @@ -62,6 +63,7 @@ public class TSDBErrorNumbers { errorNumbers.add(ERROR_INVALID_SQL); errorNumbers.add(ERROR_NUMERIC_VALUE_OUT_OF_RANGE); errorNumbers.add(ERROR_UNKNOWN_TAOS_TYPE_IN_TDENGINE); + errorNumbers.add(ERROR_UNKNOWN_TIMESTAMP_PERCISION); /*****************************************************/ errorNumbers.add(ERROR_SUBSCRIBE_FAILED); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java index 92792d97517c98f9a5402aaae557d01e09bbca30..bc4d58785a1cfd15ba236c3e2f6e355f209ec916 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java @@ -216,6 +216,16 @@ public class TSDBJNIConnector { 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 * diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java index c3d5abf35c7304f86f9cc4dc4449d8c88d144e3d..1a007156e9441dbea0806aa7c66e8dbfd84e4e7b 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java @@ -38,7 +38,6 @@ import java.util.regex.Pattern; public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement { private String rawSql; private Object[] parameters; - private boolean isPrepared; private ArrayList colData; private ArrayList tableTags; @@ -47,8 +46,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat private String tableName; private long nativeStmtHandle = 0; - private volatile TSDBParameterMetaData parameterMetaData; - TSDBPreparedStatement(TSDBConnection connection, String sql) { super(connection); init(sql); @@ -61,7 +58,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat } } parameters = new Object[parameterCnt]; - this.isPrepared = true; } if (parameterCnt > 1) { @@ -76,11 +72,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat 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 * 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 *****/ } - /** - * 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 public ResultSet executeQuery() throws SQLException { - if (!isPrepared) - return executeQuery(this.rawSql); - - final String sql = getNativeSql(this.rawSql); + final String sql = Utils.getNativeSql(this.rawSql, this.parameters); return executeQuery(sql); } @Override public int executeUpdate() throws SQLException { - if (!isPrepared) - return executeUpdate(this.rawSql); - String sql = getNativeSql(this.rawSql); + String sql = Utils.getNativeSql(this.rawSql, this.parameters); return executeUpdate(sql); } @@ -282,25 +259,14 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public boolean execute() throws SQLException { - if (!isPrepared) - return execute(this.rawSql); - - final String sql = getNativeSql(this.rawSql); + final String sql = Utils.getNativeSql(this.rawSql, this.parameters); return execute(sql); } @Override public void addBatch() throws SQLException { - if (this.batchedArgs == null) { - batchedArgs = new ArrayList<>(); - } - - if (!isPrepared) { - addBatch(this.rawSql); - } else { - String sql = this.getConnection().nativeSQL(this.rawSql); - addBatch(sql); - } + String sql = Utils.getNativeSql(this.rawSql, this.parameters); + addBatch(sql); } @Override diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java index 01104440ab00c974aa021f10b4168c3f1332e91a..e00ec1e758f720c6dc59fd1a0d41f258ca66d4cc 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java @@ -147,30 +147,14 @@ public class TSDBResultSetRowData { case TSDBConstants.TSDB_DATA_TYPE_NCHAR: case TSDBConstants.TSDB_DATA_TYPE_BINARY: return Integer.parseInt((String) obj); - case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { - Byte value = (byte) obj; - if (value < 0) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); - return value; - } - case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: { - short value = (short) 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_UTINYINT: + return parseUnsignedTinyIntToInt(obj); + case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: + return parseUnsignedSmallIntToInt(obj); + case TSDBConstants.TSDB_DATA_TYPE_UINT: + return parseUnsignedIntegerToInt(obj); + case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: + return parseUnsignedBigIntToInt(obj); case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return ((Float) obj).intValue(); 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 */ @@ -216,7 +229,7 @@ public class TSDBResultSetRowData { case TSDBConstants.TSDB_DATA_TYPE_BINARY: return Long.parseLong((String) obj); case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { - Byte value = (byte) obj; + byte value = (byte) obj; if (value < 0) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); 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 */ 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 + * @param precision 0 : ms, 1 : us, 2 : ns */ - public void setTimestamp(int col, long ts) { - //TODO: this implementation contains logical error - // when precision is us the (long ts) is 16 digital number - // when precision is ms, the (long ts) is 13 digital number - // we need a JNI function like this: - // public void setTimestamp(int col, long epochSecond, long nanoAdjustment) - if (ts < 1_0000_0000_0000_0L) { - data.set(col, new Timestamp(ts)); - } else { - long epochSec = ts / 1000_000l; - long nanoAdjustment = ts % 1000_000l * 1000l; - Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); - data.set(col, timestamp); + public void setTimestamp(int col, long ts, int precision) { + long milliseconds = 0; + int fracNanoseconds = 0; + switch (precision) { + case 0: { + milliseconds = ts; + fracNanoseconds = (int)(ts*1_000_000%1_000_000_000); + break; + } + 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) { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java new file mode 100644 index 0000000000000000000000000000000000000000..79350076c7f4b31743ab9fb61226e506186f0f17 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java @@ -0,0 +1,8 @@ +package com.taosdata.jdbc.enums; + +public enum TimestampPrecision { + MS, + US, + NS, + UNKNOWN +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java index f58e3f8cd2406e6372900c2f7b2547a450fb7fe9..16272f4289ea9031afc91fa76260a8d5719f9a77 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java @@ -44,7 +44,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar if (!isPrepared) return executeQuery(this.rawSql); - final String sql = getNativeSql(this.rawSql); + final String sql = Utils.getNativeSql(this.rawSql, this.parameters); return executeQuery(sql); } @@ -55,20 +55,10 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar if (!isPrepared) return executeUpdate(this.rawSql); - final String sql = getNativeSql(this.rawSql); + final String sql = Utils.getNativeSql(rawSql, this.parameters); return executeUpdate(sql); } - /**** - * 将rawSql转换成一条可执行的sql语句,使用属性parameters中的变脸进行替换 - * 对于insert into ?.? (?,?,?) using ?.? (?,?,?) tags(?, ?, ?) values(?, ?, ?) - * @param rawSql,可能是insert、select或其他,使用?做占位符 - * @return - */ - private String getNativeSql(String rawSql) { - return Utils.getNativeSql(rawSql, this.parameters); - } - @Override public void setNull(int parameterIndex, int sqlType) throws SQLException { if (isClosed()) @@ -224,16 +214,13 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); if (!isPrepared) return execute(this.rawSql); - final String sql = getNativeSql(rawSql); + final String sql = Utils.getNativeSql(rawSql, this.parameters); return execute(sql); } @Override public void addBatch() throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - - final String sql = getNativeSql(this.rawSql); + final String sql = Utils.getNativeSql(rawSql, this.parameters); addBatch(sql); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java index 530b433d42bf4b387db0e9973ddcf48e3844f2f3..13850f0b804fef1306789fe0dba0246a0bd8038a 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java @@ -6,6 +6,8 @@ import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; import com.taosdata.jdbc.*; +import com.taosdata.jdbc.enums.TimestampPrecision; +import com.taosdata.jdbc.rs.enums.TimestampFormat; import com.taosdata.jdbc.utils.Utils; import java.math.BigDecimal; @@ -46,6 +48,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { columnNames.clear(); columns.clear(); this.resultSet.clear(); + this.metaData = new RestfulResultSetMetaData(this.database, null, this); return; } // get head @@ -131,7 +134,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { } } - private Object parseColumnData(JSONArray row, int colIndex, int taosType) throws SQLException { switch (taosType) { case TSDBConstants.TSDB_DATA_TYPE_NULL: @@ -150,44 +152,8 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return row.getFloat(colIndex); case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: return row.getDouble(colIndex); - case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { - if (row.get(colIndex) == null) - 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_TIMESTAMP: + return parseTimestampColumnData(row, colIndex); case TSDBConstants.TSDB_DATA_TYPE_BINARY: return row.getString(colIndex) == null ? null : row.getString(colIndex).getBytes(); 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; int type; int length; @@ -211,6 +236,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { this.note = note; this.taos_type = taos_type; } + } @Override @@ -334,6 +360,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { wasNull = true; return 0; } + wasNull = false; if (value instanceof Timestamp) { return ((Timestamp) value).getTime(); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java index 7ead8bd1bbaeeb8fe1f24c951656888f6bba6b6f..a185abb709605cdbc9afecd26d33a1cac85ce37d 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java @@ -8,20 +8,22 @@ import java.sql.SQLException; import java.sql.Timestamp; import java.sql.Types; import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMetaData { private final String database; - private ArrayList fields; + private List fields; private final RestfulResultSet resultSet; public RestfulResultSetMetaData(String database, ArrayList fields, RestfulResultSet resultSet) { this.database = database; - this.fields = fields; + this.fields = fields == null ? Collections.emptyList() : fields; this.resultSet = resultSet; } - public ArrayList getFields() { + public List getFields() { return fields; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/enums/TimestampFormat.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/enums/TimestampFormat.java new file mode 100644 index 0000000000000000000000000000000000000000..edc429857e4b47031b60f6a49a62f21e183d80ed --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/enums/TimestampFormat.java @@ -0,0 +1,7 @@ +package com.taosdata.jdbc.rs.enums; + +public enum TimestampFormat { + STRING, + TIMESTAMP, + UTC +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java index b1c6dae6b3543337ae253c4cf94c2aaa5a31f9f5..ff27bdbdad2d5f56a4652ae822b9ba10c80c51b0 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java @@ -16,13 +16,12 @@ import org.apache.http.protocol.HTTP; import org.apache.http.protocol.HttpContext; import org.apache.http.util.EntityUtils; -import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; public class HttpClientPoolUtil { 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_MAX_PER_ROUTE = 32; private static final int DEFAULT_MAX_TOTAL = 1000; @@ -80,7 +79,7 @@ public class HttpClientPoolUtil { method.setHeader("Connection", "keep-alive"); 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(); CloseableHttpResponse httpResponse = httpClient.execute(method, context); httpEntity = httpResponse.getEntity(); @@ -165,28 +164,18 @@ public class HttpClientPoolUtil { httpEntity = httpResponse.getEntity(); if (httpEntity != null) { responseBody = EntityUtils.toString(httpEntity, "UTF-8"); -// logger.info("请求URL: " + uri + "+ 返回状态码:" + httpResponse.getStatusLine().getStatusCode()); } } catch (Exception e) { if (method != null) { method.abort(); } e.printStackTrace(); -// logger.error("execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" -// + (System.currentTimeMillis() - startTime)); - System.out.println("log:调用 HttpClientPoolUtil execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" - + (System.currentTimeMillis() - startTime)); } finally { if (httpEntity != null) { try { EntityUtils.consumeQuietly(httpEntity); } catch (Exception e) { -// e.printStackTrace(); -// logger.error("close response exception, url:" + uri + ", exception:" + e.toString() -// + ",cost time(ms):" + (System.currentTimeMillis() - startTime)); - new Exception("close response exception, url:" + uri + ", exception:" + e.toString() - + ",cost time(ms):" + (System.currentTimeMillis() - startTime)) - .printStackTrace(); + new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace(); } } } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java index 8ab610fec6541e96d8b4b997c6883dddc01f1549..4c92d27a28625e407d94e34da60aa7a57760baac 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java @@ -3,14 +3,13 @@ package com.taosdata.jdbc.utils; import com.google.common.collect.Range; import com.google.common.collect.RangeSet; import com.google.common.collect.TreeRangeSet; +import com.taosdata.jdbc.enums.TimestampPrecision; import java.nio.charset.Charset; import java.sql.Date; import java.sql.Time; import java.sql.Timestamp; -import java.time.LocalDate; import java.time.LocalDateTime; -import java.time.LocalTime; import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatterBuilder; import java.time.format.DateTimeParseException; @@ -25,39 +24,52 @@ public class Utils { private static Pattern ptn = Pattern.compile(".*?'"); - private static final DateTimeFormatter formatter = new DateTimeFormatterBuilder() - .appendPattern("yyyy-MM-dd HH:mm:ss.SSS").toFormatter(); - private static final DateTimeFormatter formatter2 = new DateTimeFormatterBuilder() - .appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSS").toFormatter(); + private static final DateTimeFormatter milliSecFormatter = new DateTimeFormatterBuilder().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 nanoSecFormatter = new DateTimeFormatterBuilder().appendPattern("yyyy-MM-dd HH:mm:ss.SSSSSSSSS").toFormatter(); public static Time parseTime(String timestampStr) throws DateTimeParseException { - LocalTime time; - try { - time = LocalTime.parse(timestampStr, formatter); - } catch (DateTimeParseException e) { - time = LocalTime.parse(timestampStr, formatter2); - } - return Time.valueOf(time); + LocalDateTime dateTime = parseLocalDateTime(timestampStr); + return dateTime != null ? Time.valueOf(dateTime.toLocalTime()) : null; } - public static Date parseDate(String timestampStr) throws DateTimeParseException { - LocalDate date; - try { - date = LocalDate.parse(timestampStr, formatter); - } catch (DateTimeParseException e) { - date = LocalDate.parse(timestampStr, formatter2); - } - return Date.valueOf(date); + public static Date parseDate(String timestampStr) { + LocalDateTime dateTime = parseLocalDateTime(timestampStr); + return dateTime != null ? Date.valueOf(String.valueOf(dateTime)) : null; } public static Timestamp parseTimestamp(String timeStampStr) { - LocalDateTime dateTime; + LocalDateTime dateTime = parseLocalDateTime(timeStampStr); + return dateTime != null ? Timestamp.valueOf(dateTime) : null; + } + + private static LocalDateTime parseLocalDateTime(String timeStampStr) { try { - dateTime = LocalDateTime.parse(timeStampStr, formatter); + return parseMilliSecTimestamp(timeStampStr); } catch (DateTimeParseException e) { - dateTime = LocalDateTime.parse(timeStampStr, formatter2); + try { + return parseMicroSecTimestamp(timeStampStr); + } catch (DateTimeParseException ee) { + try { + return parseNanoSecTimestamp(timeStampStr); + } catch (DateTimeParseException eee) { + eee.printStackTrace(); + } + } } - return Timestamp.valueOf(dateTime); + 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) { @@ -93,6 +105,8 @@ public class Utils { } public static String getNativeSql(String rawSql, Object[] parameters) { + if (parameters == null || !rawSql.contains("?")) + return rawSql; // toLowerCase String preparedSql = rawSql.trim().toLowerCase(); String[] clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)", "where\\s*.*"}; @@ -167,13 +181,47 @@ public class Utils { }).collect(Collectors.joining()); } - public static String formatTimestamp(Timestamp timestamp) { int nanos = timestamp.getNanos(); if (nanos % 1000000l != 0) - return timestamp.toLocalDateTime().format(formatter2); - return timestamp.toLocalDateTime().format(formatter); + return timestamp.toLocalDateTime().format(microSecFormatter); + 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; + } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java index 66078ef5036d7105ae9882508b635819bac99089..b5f8114bffe9a4490f3189a54cf724354e9394a5 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java @@ -1,12 +1,17 @@ package com.taosdata.jdbc; import org.junit.Test; +import static org.junit.Assert.*; import java.sql.SQLException; import java.sql.SQLWarning; import java.util.ArrayList; import java.util.List; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.lang.management.ThreadMXBean; + public class TSDBJNIConnectorTest { private static TSDBResultSetRowData rowData; @@ -14,17 +19,68 @@ public class TSDBJNIConnectorTest { @Test public void test() { 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 - TSDBJNIConnector.init("/etc/taos/taos.cfg", null, null, null); + TSDBJNIConnector.init("/etc/taos", null, null, null); + // connect 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 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 - long pSql = connector.executeQuery("select * from unsign_jni.us_table"); + long pSql = connector.executeQuery("select * from d.t"); + if (connector.isUpdateQuery(pSql)) { connector.freeResultSet(pSql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); } + + assertEquals(1, connector.getResultTimePrecision(pSql)); + // get schema List columnMetaDataList = new ArrayList<>(); int code = connector.getSchemaMetaData(pSql, columnMetaDataList); @@ -37,6 +93,8 @@ public class TSDBJNIConnectorTest { if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0); } + + assertEquals(1, connector.getResultTimePrecision(pSql)); int columnSize = columnMetaDataList.size(); // print metadata for (int i = 0; i < columnSize; i++) { @@ -45,9 +103,8 @@ public class TSDBJNIConnectorTest { rowData = new TSDBResultSetRowData(columnSize); // iterate resultSet for (int i = 0; next(connector, pSql); i++) { -// System.out.println("col[" + i + "] size: " + rowData.getColSize()); -// rowData.getData().stream().forEach(col -> System.out.print(col + "\t")); -// System.out.println(); + assertEquals(1, connector.getResultTimePrecision(pSql)); + System.out.println(); } // close resultSet code = connector.freeResultSet(pSql); @@ -86,4 +143,4 @@ public class TSDBJNIConnectorTest { } } -} \ No newline at end of file +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java index 3f8bef4a7ea00915925b2924b08ad8c453420416..40ff5c23ef9866d0a7d8fd5c594f2b933ed80b2a 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java @@ -5,7 +5,6 @@ import org.junit.*; import java.io.IOException; import java.math.BigDecimal; import java.sql.*; -import java.time.LocalTime; import java.util.ArrayList; import java.util.Random; @@ -15,6 +14,7 @@ public class TSDBPreparedStatementTest { private static Connection conn; 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 dbname = "test_pstmt_jni"; private PreparedStatement pstmt_insert; private PreparedStatement pstmt_select; @@ -299,53 +299,53 @@ public class TSDBPreparedStatementTest { } @Test - public void executeTest() throws SQLException { - Statement stmt = conn.createStatement(); + public void executeTest() throws SQLException { + Statement stmt = conn.createStatement(); - int numOfRows = 1000; + int numOfRows = 1000; - for (int loop = 0; loop < 10; loop++){ + for (int loop = 0; loop < 10; loop++) { stmt.execute("drop table if exists weather_test"); - stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); + stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? values(?, ?, ?, ?, ?, ?, ?, ?)"); Random r = new Random(); s.setTableName("weather_test"); - + ArrayList ts = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { + for (int i = 0; i < numOfRows; i++) { ts.add(System.currentTimeMillis() + i); - } + } s.setTimestamp(0, ts); int random = 10 + r.nextInt(5); - ArrayList s2 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + ArrayList s2 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s2.add(null); - }else{ + } else { s2.add("分支" + i % 4); } - } - s.setNString(1, s2, 4); + } + s.setNString(1, s2, 4); random = 10 + r.nextInt(5); - ArrayList s3 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + ArrayList s3 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s3.add(null); - }else{ + } else { s3.add(r.nextFloat()); } - } + } s.setFloat(2, s3); random = 10 + r.nextInt(5); ArrayList s4 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s4.add(null); - }else{ + } else { s4.add(r.nextDouble()); } } @@ -353,47 +353,47 @@ public class TSDBPreparedStatementTest { random = 10 + r.nextInt(5); ArrayList ts2 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { ts2.add(null); - }else{ + } else { ts2.add(System.currentTimeMillis() + i); } } s.setTimestamp(4, ts2); random = 10 + r.nextInt(5); - ArrayList vals = new ArrayList<>(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + ArrayList vals = new ArrayList<>(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { vals.add(null); - }else{ + } else { vals.add(r.nextInt()); - } + } } s.setInt(5, vals); random = 10 + r.nextInt(5); ArrayList sb = new ArrayList<>(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { sb.add(null); - }else{ + } else { sb.add(i % 2 == 0 ? true : false); } } - s.setBoolean(6, sb); + s.setBoolean(6, sb); random = 10 + r.nextInt(5); ArrayList s5 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s5.add(null); - }else{ + } else { s5.add("test" + i % 10); } } - s.setString(7, s5, 10); + s.setString(7, s5, 10); s.columnDataAddBatch(); s.columnDataExecuteBatch(); @@ -403,54 +403,54 @@ public class TSDBPreparedStatementTest { PreparedStatement statement = conn.prepareStatement(sql); ResultSet rs = statement.executeQuery(); int rows = 0; - while(rs.next()) { + while (rs.next()) { rows++; } - Assert.assertEquals(numOfRows, rows); + Assert.assertEquals(numOfRows, rows); } } @Test - public void bindDataSelectColumnTest() throws SQLException { - Statement stmt = conn.createStatement(); + public void bindDataSelectColumnTest() throws SQLException { + Statement stmt = conn.createStatement(); - int numOfRows = 1000; + int numOfRows = 1000; - for (int loop = 0; loop < 10; loop++){ + for (int loop = 0; loop < 10; loop++) { stmt.execute("drop table if exists weather_test"); - stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); + stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? (ts, f1, f7) values(?, ?, ?)"); Random r = new Random(); s.setTableName("weather_test"); - + ArrayList ts = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { + for (int i = 0; i < numOfRows; i++) { ts.add(System.currentTimeMillis() + i); - } + } s.setTimestamp(0, ts); int random = 10 + r.nextInt(5); - ArrayList s2 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + ArrayList s2 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s2.add(null); - }else{ + } else { s2.add("分支" + i % 4); } - } - s.setNString(1, s2, 4); + } + s.setNString(1, s2, 4); random = 10 + r.nextInt(5); ArrayList s3 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s3.add(null); - }else{ + } else { s3.add("test" + i % 10); } } - s.setString(2, s3, 10); + s.setString(2, s3, 10); s.columnDataAddBatch(); s.columnDataExecuteBatch(); @@ -460,30 +460,30 @@ public class TSDBPreparedStatementTest { PreparedStatement statement = conn.prepareStatement(sql); ResultSet rs = statement.executeQuery(); int rows = 0; - while(rs.next()) { + while (rs.next()) { rows++; } - Assert.assertEquals(numOfRows, rows); + Assert.assertEquals(numOfRows, rows); } } @Test - public void bindDataWithSingleTagTest() throws SQLException { - Statement stmt = conn.createStatement(); + public void bindDataWithSingleTagTest() throws SQLException { + Statement stmt = conn.createStatement(); - String types[] = new String[] {"tinyint", "smallint", "int", "bigint", "bool", "float", "double", "binary(10)", "nchar(10)"}; + String types[] = new String[]{"tinyint", "smallint", "int", "bigint", "bool", "float", "double", "binary(10)", "nchar(10)"}; for (String type : types) { stmt.execute("drop table if exists weather_test"); stmt.execute("create table weather_test(ts timestamp, f1 nchar(10), f2 binary(10)) tags (t " + type + ")"); int numOfRows = 1; - + TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? using weather_test tags(?) values(?, ?, ?)"); Random r = new Random(); s.setTableName("w1"); - - switch(type) { + + switch (type) { case "tinyint": case "smallint": case "int": @@ -508,37 +508,37 @@ public class TSDBPreparedStatementTest { default: break; } - - + + ArrayList ts = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { + for (int i = 0; i < numOfRows; i++) { ts.add(System.currentTimeMillis() + i); - } + } s.setTimestamp(0, ts); - + int random = 10 + r.nextInt(5); - ArrayList s2 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - s2.add("分支" + i % 4); - } + ArrayList s2 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + s2.add("分支" + i % 4); + } s.setNString(1, s2, 10); - + random = 10 + r.nextInt(5); - ArrayList s3 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - s3.add("test" + i % 4); - } + ArrayList s3 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + s3.add("test" + i % 4); + } s.setString(2, s3, 10); - + s.columnDataAddBatch(); s.columnDataExecuteBatch(); s.columnDataCloseBatch(); - + String sql = "select * from weather_test"; PreparedStatement statement = conn.prepareStatement(sql); ResultSet rs = statement.executeQuery(); int rows = 0; - while(rs.next()) { + while (rs.next()) { rows++; } Assert.assertEquals(numOfRows, rows); @@ -547,32 +547,32 @@ public class TSDBPreparedStatementTest { @Test - public void bindDataWithMultipleTagsTest() throws SQLException { - Statement stmt = conn.createStatement(); - + public void bindDataWithMultipleTagsTest() throws SQLException { + Statement stmt = conn.createStatement(); + stmt.execute("drop table if exists weather_test"); stmt.execute("create table weather_test(ts timestamp, f1 nchar(10), f2 binary(10)) tags (t1 int, t2 binary(10))"); int numOfRows = 1; - TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? using weather_test tags(?,?) (ts, f2) values(?, ?)"); - s.setTableName("w2"); + TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? using weather_test tags(?,?) (ts, f2) values(?, ?)"); + s.setTableName("w2"); s.setTagInt(0, 1); s.setTagString(1, "test"); - - + + ArrayList ts = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { + for (int i = 0; i < numOfRows; i++) { ts.add(System.currentTimeMillis() + i); - } + } s.setTimestamp(0, ts); - - ArrayList s2 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { + + ArrayList s2 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { s2.add("test" + i % 4); } s.setString(1, s2, 10); - + s.columnDataAddBatch(); s.columnDataExecuteBatch(); s.columnDataCloseBatch(); @@ -581,21 +581,20 @@ public class TSDBPreparedStatementTest { PreparedStatement statement = conn.prepareStatement(sql); ResultSet rs = statement.executeQuery(); int rows = 0; - while(rs.next()) { + while (rs.next()) { rows++; } Assert.assertEquals(numOfRows, rows); - } - - @Test + + @Test(expected = SQLException.class) public void createTwoSameDbTest() throws SQLException { - Statement stmt = conn.createStatement(); - + // when + Statement stmt = conn.createStatement(); + stmt.execute("create database dbtest"); stmt.execute("create database dbtest"); - Assert.assertThrows(SQLException.class, () -> stmt.execute("create database dbtest")); } - + @Test public void setBoolean() throws SQLException { // given @@ -1097,9 +1096,9 @@ public class TSDBPreparedStatementTest { try { conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); try (Statement stmt = conn.createStatement()) { - stmt.execute("drop database if exists test_pstmt_jni"); - stmt.execute("create database if not exists test_pstmt_jni"); - stmt.execute("use test_pstmt_jni"); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname); + stmt.execute("use " + dbname); } } catch (SQLException e) { e.printStackTrace(); @@ -1109,6 +1108,9 @@ public class TSDBPreparedStatementTest { @AfterClass public static void afterClass() { try { + Statement statement = conn.createStatement(); + statement.execute("drop database if exists " + dbname); + statement.close(); if (conn != null) conn.close(); } catch (SQLException e) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DoubleQuoteInSqlTest.java similarity index 55% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DoubleQuoteInSqlTest.java index 2704d4cfa558ebdb6885c320d7ba775b36b99f09..212a751ec302ae02552d084248d34b35a7b21c59 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DoubleQuoteInSqlTest.java @@ -7,56 +7,64 @@ import org.junit.*; import java.sql.*; import java.util.Properties; -public class TD4174Test { - private Connection conn; +public class DoubleQuoteInSqlTest { private static final String host = "127.0.0.1"; + private static final String dbname = "td4174"; + + private Connection conn; @Test public void test() { + // given long ts = System.currentTimeMillis(); + JSONObject value = new JSONObject(); + value.put("name", "John Smith"); + value.put("age", 20); + + // when + int ret = 0; try (PreparedStatement pstmt = conn.prepareStatement("insert into weather values(" + ts + ", ?)")) { - JSONObject value = new JSONObject(); - value.put("name", "John Smith"); - value.put("age", 20); - Assert.assertEquals("{\"name\":\"John Smith\",\"age\":20}",value.toJSONString()); pstmt.setString(1, value.toJSONString()); - - int ret = pstmt.executeUpdate(); - Assert.assertEquals(1, ret); + ret = pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } - } - public static void main(String[] args) { - JSONObject value = new JSONObject(); - value.put("name", "John Smith"); - value.put("age", 20); - System.out.println(value.toJSONString()); + // then + Assert.assertEquals("{\"name\":\"John Smith\",\"age\":20}", value.toJSONString()); + Assert.assertEquals(1, ret); } @Before - public void before() throws SQLException { + public void before() { String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); - conn = DriverManager.getConnection(url, properties); - try (Statement stmt = conn.createStatement()) { - stmt.execute("drop database if exists td4174"); - stmt.execute("create database if not exists td4174"); - stmt.execute("use td4174"); + try { + conn = DriverManager.getConnection(url, properties); + 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 weather(ts timestamp, text binary(64))"); + } catch (SQLException e) { + e.printStackTrace(); } } @After - public void after() throws SQLException { - if (conn != null) + public void after() { + try { + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.close(); conn.close(); - + } catch (SQLException e) { + e.printStackTrace(); + } } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionJNITest.java similarity index 98% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInJniTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionJNITest.java index f9b111bb12f189a7a42c7944237aa01ebb008d25..54e4273ea3e54c8db18ca11c10f960468ab91c75 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInJniTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionJNITest.java @@ -10,7 +10,7 @@ import org.junit.Test; import java.sql.*; import java.util.Properties; -public class TwoTypeTimestampPercisionInJniTest { +public class MicroSecondPrecisionJNITest { private static final String host = "127.0.0.1"; private static final String ms_timestamp_db = "ms_precision_test"; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java similarity index 99% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java index 5c83b5a9da527a55387a8ad399e78462b6fab63c..7e9f04cd6360431a3fe6c29a2f0eb61fbdc9e7c4 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java @@ -10,10 +10,9 @@ import org.junit.Test; import java.sql.*; import java.util.Properties; -public class TwoTypeTimestampPercisionInRestfulTest { +public class MicroSecondPrecisionRestfulTest { private static final String host = "127.0.0.1"; - private static final String ms_timestamp_db = "ms_precision_test"; private static final String us_timestamp_db = "us_precision_test"; private static final long timestamp1 = System.currentTimeMillis(); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java new file mode 100644 index 0000000000000000000000000000000000000000..4f2c87966ad6bb8390bab47b795e7d952725baf5 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java @@ -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(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4271f918b9b096000cc59b730d7b70f032a0ab29 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java @@ -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(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java similarity index 97% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcJniTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java index 782125144c4fbe8dcc4bdfd4769e95e5119ea32f..076125a752e5c4e81e24cbfa3299fa349939094b 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcJniTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java @@ -6,7 +6,7 @@ import org.junit.Test; import java.sql.*; -public class NullValueInResultSetForJdbcJniTest { +public class NullValueInResultSetJNITest { private static final String host = "127.0.0.1"; Connection conn; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java similarity index 97% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java index f2ac94adc1b6e7d94e52650dcfbb5664c8f39760..ea6e36ec1d005e48f36ee1283935664aca6fcc47 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import java.sql.*; -public class NullValueInResultSetForJdbcRestfulTest { +public class NullValueInResultSetRestfulTest { private static final String host = "127.0.0.1"; Connection conn; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetTest.java similarity index 99% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetTest.java index c6fba81eb24b9b8c08fd553ca57b1e1d68bb81e0..61d767b5cf2bcd2e478de74e5f4bb8d66ad21678 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetTest.java @@ -7,7 +7,7 @@ import org.junit.*; import java.sql.*; import java.util.Properties; -public class TD3841Test { +public class NullValueInResultSetTest { private static final String host = "127.0.0.1"; private static Properties properties; private static Connection conn_restful; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertJNITest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertJNITest.java new file mode 100644 index 0000000000000000000000000000000000000000..ed78c2561ec437e3b7c6a0ab8d3e91699c2572af --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertJNITest.java @@ -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 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(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java new file mode 100644 index 0000000000000000000000000000000000000000..90b285381a2ab57b170da327a95dde4c8991ce21 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java @@ -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 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(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ResultSetMetaShouldNotBeNullRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ResultSetMetaShouldNotBeNullRestfulTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f6d6bb25566a8c6060311a1cf0c918a0456b8c24 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ResultSetMetaShouldNotBeNullRestfulTest.java @@ -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(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java deleted file mode 100644 index 6f29f64111c51600303ad73d517faaa7c59cfe7c..0000000000000000000000000000000000000000 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java +++ /dev/null @@ -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(); - } -} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java index c861ef296607b244e4564423ad4024ea1f13df5d..ee83f6ceb2d412613129611e2a575a7ad4922db0 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java @@ -3,22 +3,98 @@ package com.taosdata.jdbc.utils; import org.junit.Assert; import org.junit.Test; -import static org.junit.Assert.*; +import java.util.stream.Stream; public class UtilsTest { @Test public void escapeSingleQuota() { + // given String s = "'''''a\\'"; + // when String news = Utils.escapeSingleQuota(s); + // then Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news); + // given s = "\'''''a\\'"; + // when news = Utils.escapeSingleQuota(s); + // then Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news); + // given s = "\'\'\'\''a\\'"; + // when news = Utils.escapeSingleQuota(s); + // then 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); + + } } \ No newline at end of file diff --git a/src/connector/python/setup.py b/src/connector/python/setup.py index 901e8396c0440bd1c90163f0360b687dd5684ff3..284861ca87dd77b1bc6799ad4cb32ff4c489e239 100644 --- a/src/connector/python/setup.py +++ b/src/connector/python/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.0.10", + version="2.0.11", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/taos/cinterface.py b/src/connector/python/taos/cinterface.py index 0f690aeb27ce81d867d1727c50ba948afd9493a8..61a2a0e9c70c3097a1376efb4bab6e250b4d4438 100644 --- a/src/connector/python/taos/cinterface.py +++ b/src/connector/python/taos/cinterface.py @@ -14,12 +14,22 @@ def _convert_microsecond_to_datetime(micro): return datetime.datetime.fromtimestamp(micro / 1000000.0) -def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): +def _convert_nanosecond_to_datetime(nanosec): + return datetime.datetime.fromtimestamp(nanosec / 1000000000.0) + + +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 """ _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 + elif precision == FieldType.C_TIMESTAMP_NANO: + _timestamp_converter = _convert_nanosecond_to_datetime + else: + raise DatabaseError("Unknown precision returned from database") return [ 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): :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 """ return [ @@ -38,7 +48,7 @@ def _crow_bool_to_python(data, num_of_rows, nbytes=None, micro=False): :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 """ 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, num_of_rows, nbytes=None, - micro=False): + precision=FieldType.C_TIMESTAMP_UNKNOWN): """Function to convert C tinyint row to python row """ return [ @@ -59,7 +69,7 @@ def _crow_tinyint_unsigned_to_python( :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 """ return [ @@ -70,7 +80,7 @@ def _crow_smallint_to_python(data, num_of_rows, nbytes=None, micro=False): 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 """ return [ @@ -80,14 +90,14 @@ def _crow_smallint_unsigned_to_python( :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 """ 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)]] -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 """ return [ @@ -97,7 +107,7 @@ def _crow_int_unsigned_to_python(data, num_of_rows, nbytes=None, micro=False): :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 """ 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, num_of_rows, nbytes=None, - micro=False): + precision=FieldType.C_TIMESTAMP_UNKNOWN): """Function to convert C bigint row to python row """ return [ @@ -118,21 +128,21 @@ def _crow_bigint_unsigned_to_python( :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 """ return [None if math.isnan(ele) else ele for ele in ctypes.cast( 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 """ return [None if math.isnan(ele) else ele for ele in ctypes.cast( 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 """ 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)]] -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 """ assert(nbytes is not None) @@ -159,7 +169,7 @@ def _crow_nchar_to_python(data, num_of_rows, nbytes=None, micro=False): 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 """ 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 -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 """ assert(nbytes is not None) @@ -448,8 +458,7 @@ class CTaosInterface(object): result, ctypes.byref(pblock)) if num_of_rows == 0: return None, 0 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) + precision = CTaosInterface.libtaos.taos_result_precision(result) blocks = [None] * len(fields) fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) fieldLen = [ @@ -462,7 +471,7 @@ class CTaosInterface(object): if fields[i]['type'] not in _CONVERT_FUNC_BLOCK: raise DatabaseError("Invalid data type returned from database") 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) @@ -472,8 +481,7 @@ class CTaosInterface(object): pblock = CTaosInterface.libtaos.taos_fetch_row(result) if pblock: num_of_rows = 1 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) + precision = CTaosInterface.libtaos.taos_result_precision(result) blocks = [None] * len(fields) fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) fieldLen = [ @@ -490,7 +498,7 @@ class CTaosInterface(object): blocks[i] = [None] else: blocks[i] = _CONVERT_FUNC[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) + data, num_of_rows, fieldLen[i], precision) else: return None, 0 return blocks, abs(num_of_rows) diff --git a/src/connector/python/taos/constants.py b/src/connector/python/taos/constants.py index 93466f5184a6bf37c2e1c915a00aa5c5e91d1801..85689b02db76b0032558b983d8ae8d9297229c42 100644 --- a/src/connector/python/taos/constants.py +++ b/src/connector/python/taos/constants.py @@ -40,3 +40,5 @@ class FieldType(object): # Timestamp precision definition C_TIMESTAMP_MILLI = 0 C_TIMESTAMP_MICRO = 1 + C_TIMESTAMP_NANO = 2 + C_TIMESTAMP_UNKNOWN = 3 diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index a225c0d9389fecb511229e12ae6733d0972df1b3..032c6ee94b5abe422c017d56d0bd3a44d4a1c8cf 100644 --- a/src/mnode/src/mnodeTable.c +++ b/src/mnode/src/mnodeTable.c @@ -1475,6 +1475,7 @@ static int32_t mnodeChangeSuperTableColumn(SMnodeMsg *pMsg) { SSchema *schema = (SSchema *) (pStable->schema + col); ASSERT(schema->type == TSDB_DATA_TYPE_BINARY || schema->type == TSDB_DATA_TYPE_NCHAR); schema->bytes = pAlter->schema[0].bytes; + pStable->sversion++; mInfo("msg:%p, app:%p stable %s, start to modify column %s len to %d", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, name, schema->bytes); @@ -1504,6 +1505,7 @@ static int32_t mnodeChangeSuperTableTag(SMnodeMsg *pMsg) { SSchema *schema = (SSchema *) (pStable->schema + col + pStable->numOfColumns); ASSERT(schema->type == TSDB_DATA_TYPE_BINARY || schema->type == TSDB_DATA_TYPE_NCHAR); schema->bytes = pAlter->schema[0].bytes; + pStable->tversion++; mInfo("msg:%p, app:%p stable %s, start to modify tag len %s to %d", pMsg, pMsg->rpcMsg.ahandle, pStable->info.tableId, name, schema->bytes); diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index f403e9dd9794ec2ca56db5768f43f6b22fcb37f0..7b106c178d8f7554d6316d8a5fc1e1504b763199 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -7529,7 +7529,8 @@ static void doSetTagValueToResultBuf(char* output, const char* val, int16_t type if (IS_VAR_DATA_TYPE(type)) { // Binary data overflows for sort of unknown reasons. Let trim the overflow data if (varDataTLen(val) > bytes) { - int32_t len = bytes - VARSTR_HEADER_SIZE; // remain available space + int32_t maxLen = bytes - VARSTR_HEADER_SIZE; + int32_t len = (varDataLen(val) > maxLen)? maxLen:varDataLen(val); memcpy(varDataVal(output), varDataVal(val), len); varDataSetLen(output, len); } else { diff --git a/src/tsdb/src/tsdbMain.c b/src/tsdb/src/tsdbMain.c index 0cbabb8909814bc15e949f224cab4e21e2427660..d44f8ec74874fa990992fc008671878088d872f0 100644 --- a/src/tsdb/src/tsdbMain.c +++ b/src/tsdb/src/tsdbMain.c @@ -812,6 +812,7 @@ int tsdbRestoreInfo(STsdbRepo *pRepo) { STable *pTable = pMeta->tables[i]; if (pTable == NULL) continue; pTable->restoreColumnNum = 0; + pTable->hasRestoreLastColumn = false; } } @@ -895,6 +896,7 @@ int tsdbCacheLastData(STsdbRepo *pRepo, STsdbCfg* oldCfg) { maxTableIdx = i; if (cacheLastCol) { pTable->restoreColumnNum = 0; + pTable->hasRestoreLastColumn = false; } } @@ -913,6 +915,7 @@ int tsdbCacheLastData(STsdbRepo *pRepo, STsdbCfg* oldCfg) { } if (need_free_last_col) { tsdbFreeLastColumns(pTable); + pTable->hasRestoreLastColumn = false; } } } diff --git a/src/tsdb/src/tsdbMeta.c b/src/tsdb/src/tsdbMeta.c index 817469819700d6529389fca860b76feea3f1d5a4..621be04e216683681f276ff6181a34ffc3613ba4 100644 --- a/src/tsdb/src/tsdbMeta.c +++ b/src/tsdb/src/tsdbMeta.c @@ -148,7 +148,9 @@ int tsdbCreateTable(STsdbRepo *repo, STableCfg *pCfg) { return 0; _err: - tsdbFreeTable(super); + if (newSuper) { + tsdbFreeTable(super); + } tsdbFreeTable(table); return -1; } @@ -211,7 +213,7 @@ void *tsdbGetTableTagVal(const void* pTable, int32_t colId, int16_t type, int16_ } char *val = tdGetKVRowValOfCol(((STable*)pTable)->tagVal, colId); - assert(type == pCol->type && bytes == pCol->bytes); + assert(type == pCol->type && bytes >= pCol->bytes); // if (val != NULL && IS_VAR_DATA_TYPE(type)) { // assert(varDataLen(val) < pCol->bytes); @@ -607,6 +609,7 @@ void tsdbFreeLastColumns(STable* pTable) { pTable->maxColNum = 0; pTable->lastColSVersion = -1; pTable->restoreColumnNum = 0; + pTable->hasRestoreLastColumn = false; } int16_t tsdbGetLastColumnsIndexByColId(STable* pTable, int16_t colId) { @@ -643,6 +646,7 @@ int tsdbInitColIdCacheWithSchema(STable* pTable, STSchema* pSchema) { pTable->lastColSVersion = schemaVersion(pSchema); pTable->maxColNum = numOfColumn; pTable->restoreColumnNum = 0; + pTable->hasRestoreLastColumn = false; return 0; } @@ -655,7 +659,7 @@ int tsdbUpdateLastColSchema(STable *pTable, STSchema *pNewSchema) { 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; SDataCol *lastCols = (SDataCol*)malloc(numOfCols * sizeof(SDataCol)); @@ -800,6 +804,7 @@ static STable *tsdbNewTable() { pTable->lastCols = NULL; pTable->restoreColumnNum = 0; pTable->maxColNum = 0; + pTable->hasRestoreLastColumn = false; pTable->lastColSVersion = -1; return pTable; } diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 972c3c4e10c163c4c5b66d3390200b97f207e0a0..4ac900e30ef0418e47c970c6cb9da813b6b83104 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -2520,7 +2520,7 @@ static bool loadCachedLast(STsdbQueryHandle* pQueryHandle) { int32_t numOfCols = pTable->maxColNum; 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; } diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index 146c47c51da1a3eb9e3277417e76eb97053159a9..b9b7bbcaf6bd056329ae04b0b2fb91ff56f3ce45 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -25,6 +25,8 @@ python3 ./test.py -f insert/special_character_show.py python3 bug2265.py python3 ./test.py -f insert/bug3654.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 python3 ./test.py -f table/alter_wal0.py diff --git a/tests/pytest/insert/in_function.py b/tests/pytest/insert/in_function.py new file mode 100644 index 0000000000000000000000000000000000000000..d1fbfd702a857ab6d966aff46e04a32ac933c384 --- /dev/null +++ b/tests/pytest/insert/in_function.py @@ -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()) diff --git a/tests/pytest/insert/modify_column.py b/tests/pytest/insert/modify_column.py new file mode 100644 index 0000000000000000000000000000000000000000..3632eb817a269dbf8ae03954ccabf1c5df40266d --- /dev/null +++ b/tests/pytest/insert/modify_column.py @@ -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()) diff --git a/tests/script/general/http/grafana_bug.sim b/tests/script/general/http/grafana_bug.sim index e66cd29deacc5a02d24568c236ffed79e114eb25..0816e88f3fdfaf5a6292f746c66ecb562bee177e 100644 --- a/tests/script/general/http/grafana_bug.sim +++ b/tests/script/general/http/grafana_bug.sim @@ -20,17 +20,22 @@ sql use db 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 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-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-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-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-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 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 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 \ No newline at end of file