提交 1337f2ec 编写于 作者: H Haojun Liao

Merge branch 'develop' into feature/query

......@@ -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);
/*
......
......@@ -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) {
......
......@@ -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
}
......
......@@ -122,7 +122,6 @@
<exclude>**/FailOverTest.java</exclude>
<exclude>**/InvalidResultSetPointerTest.java</exclude>
<exclude>**/RestfulConnectionTest.java</exclude>
<exclude>**/TD4144Test.java</exclude>
<exclude>**/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java</exclude>
</excludes>
<testFailureIgnore>true</testFailureIgnore>
......
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
}
......
......@@ -9,8 +9,6 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement
protected List<String> batchedArgs;
private int fetchSize;
@Override
public abstract ResultSet executeQuery(String sql) throws SQLException;
......
......@@ -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");
......
......@@ -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);
......
......@@ -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
*
......
......@@ -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<ColumnInfo> colData;
private ArrayList<TableTagInfo> 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
......
......@@ -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) {
......
package com.taosdata.jdbc.enums;
public enum TimestampPrecision {
MS,
US,
NS,
UNKNOWN
}
......@@ -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);
}
......
......@@ -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();
......
......@@ -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<RestfulResultSet.Field> fields;
private List<RestfulResultSet.Field> fields;
private final RestfulResultSet resultSet;
public RestfulResultSetMetaData(String database, ArrayList<RestfulResultSet.Field> fields, RestfulResultSet resultSet) {
this.database = database;
this.fields = fields;
this.fields = fields == null ? Collections.emptyList() : fields;
this.resultSet = resultSet;
}
public ArrayList<RestfulResultSet.Field> getFields() {
public List<RestfulResultSet.Field> getFields() {
return fields;
}
......
package com.taosdata.jdbc.rs.enums;
public enum TimestampFormat {
STRING,
TIMESTAMP,
UTC
}
......@@ -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();
}
}
}
......
......@@ -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;
}
}
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<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(sqlObj1, columnMetaDataList);
rowData = new TSDBResultSetRowData(columnMetaDataList.size());
assertTrue(next(connector, sqlObj1));
assertEquals(0, connector.getResultTimePrecision(sqlObj1));
connector.freeResultSet(sqlObj1);
}
// executeQuery
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<ColumnMetaData> 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
}
......@@ -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<Long> ts = new ArrayList<Long>();
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<String> s2 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
ArrayList<String> s2 = new ArrayList<String>();
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<Float> s3 = new ArrayList<Float>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
ArrayList<Float> s3 = new ArrayList<Float>();
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<Double> s4 = new ArrayList<Double>();
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<Long> ts2 = new ArrayList<Long>();
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<Integer> vals = new ArrayList<>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
ArrayList<Integer> 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<Boolean> 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<String> s5 = new ArrayList<String>();
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<Long> ts = new ArrayList<Long>();
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<String> s2 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
if(i % random == 0) {
ArrayList<String> s2 = new ArrayList<String>();
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<String> s3 = new ArrayList<String>();
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<Long> ts = new ArrayList<Long>();
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<String> s2 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
s2.add("分支" + i % 4);
}
ArrayList<String> s2 = new ArrayList<String>();
for (int i = 0; i < numOfRows; i++) {
s2.add("分支" + i % 4);
}
s.setNString(1, s2, 10);
random = 10 + r.nextInt(5);
ArrayList<String> s3 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
s3.add("test" + i % 4);
}
ArrayList<String> s3 = new ArrayList<String>();
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<Long> ts = new ArrayList<Long>();
for(int i = 0; i < numOfRows; i++) {
for (int i = 0; i < numOfRows; i++) {
ts.add(System.currentTimeMillis() + i);
}
}
s.setTimestamp(0, ts);
ArrayList<String> s2 = new ArrayList<String>();
for(int i = 0; i < numOfRows; i++) {
ArrayList<String> s2 = new ArrayList<String>();
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) {
......
......@@ -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();
}
}
}
......@@ -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";
......
......@@ -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();
......
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();
}
}
}
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();
}
}
}
......@@ -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;
......
......@@ -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;
......
......@@ -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;
......
package com.taosdata.jdbc.cases;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.sql.*;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PreparedStatementBatchInsertJNITest {
private static final String host = "127.0.0.1";
private static final String dbname = "td4668";
private final Random random = new Random(System.currentTimeMillis());
private Connection conn;
@Test
public void test() {
// given
long ts = System.currentTimeMillis();
List<Object[]> rows = IntStream.range(0, 10).mapToObj(i -> {
Object[] row = new Object[6];
final String groupId = String.format("%02d", random.nextInt(100));
// table name (d + groupId)组合
row[0] = "d" + groupId;
// tag
row[1] = groupId;
// ts
row[2] = ts + i;
// current 电流
row[3] = random.nextFloat();
// voltage 电压
row[4] = Math.random() > 0.5 ? 220 : 380;
// phase 相位
row[5] = random.nextInt(10);
return row;
}).collect(Collectors.toList());
final String sql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)";
// when
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (Object[] row : rows) {
for (int i = 0; i < row.length; i++) {
pstmt.setObject(i + 1, row[i]);
}
pstmt.addBatch();
}
pstmt.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
Assert.fail();
}
// then
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from meters");
int count = 0;
while (rs.next()) {
count++;
}
Assert.assertEquals(10, count);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Before
public void before() {
try {
conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname);
stmt.execute("use " + dbname);
stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(groupId int)");
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void after() {
try {
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package com.taosdata.jdbc.cases;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.sql.*;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class PreparedStatementBatchInsertRestfulTest {
private static final String host = "127.0.0.1";
private static final String dbname = "td4668";
private final Random random = new Random(System.currentTimeMillis());
private Connection conn;
@Test
public void test() {
// given
long ts = System.currentTimeMillis();
List<Object[]> rows = IntStream.range(0, 10).mapToObj(i -> {
Object[] row = new Object[6];
final String groupId = String.format("%02d", random.nextInt(100));
// table name (d + groupId)组合
row[0] = "d" + groupId;
// tag
row[1] = groupId;
// ts
row[2] = ts + i;
// current 电流
row[3] = random.nextFloat();
// voltage 电压
row[4] = Math.random() > 0.5 ? 220 : 380;
// phase 相位
row[5] = random.nextInt(10);
return row;
}).collect(Collectors.toList());
final String sql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)";
// when
try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
for (Object[] row : rows) {
for (int i = 0; i < row.length; i++) {
pstmt.setObject(i + 1, row[i]);
}
pstmt.addBatch();
}
pstmt.executeBatch();
} catch (SQLException e) {
e.printStackTrace();
Assert.fail();
}
// then
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from meters");
int count = 0;
while (rs.next()) {
count++;
}
Assert.assertEquals(10, count);
} catch (SQLException e) {
e.printStackTrace();
}
}
@Before
public void before() {
try {
conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata");
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname);
stmt.execute("use " + dbname);
stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(groupId int)");
} catch (SQLException e) {
e.printStackTrace();
}
}
@After
public void after() {
try {
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + dbname);
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
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();
}
}
}
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();
}
}
......@@ -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
......@@ -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",
......
......@@ -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)
......
......@@ -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
......@@ -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);
......
......@@ -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 {
......
......@@ -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;
}
}
}
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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
......
此差异已折叠。
###################################################################
# 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())
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册