提交 402748d9 编写于 作者: S shenglian zhou

[TD-3776]<fix>set time precision after parsing and JNI time precision minor change

上级 4066fb7c
...@@ -51,10 +51,10 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset ...@@ -51,10 +51,10 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset
/* /*
* Class: com_taosdata_jdbc_TSDBJNIConnector * Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: getResultTimePrecision * Method: getResultTimePrecisionImp
* Signature: (J)J * Signature: (JJ)I
*/ */
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecision JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecisionImp
(JNIEnv *, jobject, jlong, jlong); (JNIEnv *, jobject, jlong, jlong);
/* /*
......
...@@ -113,7 +113,7 @@ static void jniGetGlobalMethod(JNIEnv *env) { ...@@ -113,7 +113,7 @@ static void jniGetGlobalMethod(JNIEnv *env) {
g_rowdataSetFloatFp = (*env)->GetMethodID(env, g_rowdataClass, "setFloat", "(IF)V"); g_rowdataSetFloatFp = (*env)->GetMethodID(env, g_rowdataClass, "setFloat", "(IF)V");
g_rowdataSetDoubleFp = (*env)->GetMethodID(env, g_rowdataClass, "setDouble", "(ID)V"); g_rowdataSetDoubleFp = (*env)->GetMethodID(env, g_rowdataClass, "setDouble", "(ID)V");
g_rowdataSetStringFp = (*env)->GetMethodID(env, g_rowdataClass, "setString", "(ILjava/lang/String;)V"); g_rowdataSetStringFp = (*env)->GetMethodID(env, g_rowdataClass, "setString", "(ILjava/lang/String;)V");
g_rowdataSetTimestampFp = (*env)->GetMethodID(env, g_rowdataClass, "setTimestamp", "(IJ)V"); g_rowdataSetTimestampFp = (*env)->GetMethodID(env, g_rowdataClass, "setTimestamp", "(IJI)V");
g_rowdataSetByteArrayFp = (*env)->GetMethodID(env, g_rowdataClass, "setByteArray", "(I[B)V"); g_rowdataSetByteArrayFp = (*env)->GetMethodID(env, g_rowdataClass, "setByteArray", "(I[B)V");
(*env)->DeleteLocalRef(env, rowdataClass); (*env)->DeleteLocalRef(env, rowdataClass);
...@@ -519,9 +519,11 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn ...@@ -519,9 +519,11 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_fetchRowImp(JNIEn
jniFromNCharToByteArray(env, (char *)row[i], length[i])); jniFromNCharToByteArray(env, (char *)row[i], length[i]));
break; break;
} }
case TSDB_DATA_TYPE_TIMESTAMP: case TSDB_DATA_TYPE_TIMESTAMP: {
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetTimestampFp, i, (jlong) * ((int64_t *)row[i])); int precision = taos_result_precision(result);
(*env)->CallVoidMethod(env, rowobj, g_rowdataSetTimestampFp, i, (jlong) * ((int64_t *)row[i]), precision);
break; break;
}
default: default:
break; break;
} }
...@@ -672,7 +674,15 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset(J ...@@ -672,7 +674,15 @@ JNIEXPORT jstring JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getTsCharset(J
return (*env)->NewStringUTF(env, (const char *)tsCharset); return (*env)->NewStringUTF(env, (const char *)tsCharset);
} }
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TDDBJNIConnector_getResultTimePrecision(JNIEnv *env, jobject jobj, jlong con, /**
* Get Result Time Precision
* @param env vm
* @param jobj the TSDBJNIConnector java object
* @param con the c connection pointer
* @param res the TAOS_RES object, i.e. the SSqlObject
* @return precision 0:ms 1:us 2:ns
*/
JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultTimePrecisionImp(JNIEnv *env, jobject jobj, jlong con,
jlong res) { jlong res) {
TAOS *tscon = (TAOS *)con; TAOS *tscon = (TAOS *)con;
if (tscon == NULL) { if (tscon == NULL) {
......
...@@ -772,6 +772,10 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) { ...@@ -772,6 +772,10 @@ int32_t tscValidateSqlInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
pCmd->active = pCmd->pQueryInfo; pCmd->active = pCmd->pQueryInfo;
pCmd->command = pCmd->pQueryInfo->command; pCmd->command = pCmd->pQueryInfo->command;
if (pTableMetaInfo->pTableMeta != NULL) {
pSql->res.precision = tscGetTableInfo(pTableMetaInfo->pTableMeta).precision;
}
return TSDB_CODE_SUCCESS; // do not build query message here return TSDB_CODE_SUCCESS; // do not build query message here
} }
......
...@@ -216,6 +216,16 @@ public class TSDBJNIConnector { ...@@ -216,6 +216,16 @@ public class TSDBJNIConnector {
private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData); private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData);
/**
* Get Result Time Precision.
* @return 0: ms, 1: us, 2: ns
*/
public int getResultTimePrecision(long sqlObj) {
return this.getResultTimePrecisionImp(this.taos, sqlObj);
}
private native int getResultTimePrecisionImp(long connection, long result);
/** /**
* Execute close operation from C to release connection pointer by JNI * Execute close operation from C to release connection pointer by JNI
* *
......
...@@ -414,26 +414,40 @@ public class TSDBResultSetRowData { ...@@ -414,26 +414,40 @@ public class TSDBResultSetRowData {
* $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api
*/ */
public void setTimestampValue(int colIndex, long value) { public void setTimestampValue(int colIndex, long value) {
setTimestamp(colIndex - 1, value); setTimestamp(colIndex - 1, value, 0);
} }
/** /**
* !!! this method is invoked by JNI method and the index start from 0 in C implementations * !!! this method is invoked by JNI method and the index start from 0 in C implementations
* @param precision 0 : ms, 1 : us, 2 : ns
*/ */
public void setTimestamp(int col, long ts) { public void setTimestamp(int col, long ts, int precision) {
//TODO: this implementation contains logical error long milliseconds = 0;
// when precision is us the (long ts) is 16 digital number int fracNanoseconds = 0;
// when precision is ms, the (long ts) is 13 digital number switch (precision) {
// we need a JNI function like this: case 0: {
// public void setTimestamp(int col, long epochSecond, long nanoAdjustment) milliseconds = ts;
if (ts < 1_0000_0000_0000_0L) { fracNanoseconds = (int)(ts*1_000_000%1_000_000_000);
data.set(col, new Timestamp(ts)); break;
} else { }
long epochSec = ts / 1000_000l; case 1: {
long nanoAdjustment = ts % 1000_000l * 1000l; milliseconds = ts/1_000;
Timestamp timestamp = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); fracNanoseconds = (int)(ts*1_000%1_000_000_000);
data.set(col, timestamp); break;
}
case 2: {
milliseconds = ts/1_000_000;
fracNanoseconds = (int)(ts%1_000_000_000);
break;
}
default: {
throw new IllegalArgumentException("precision is not valid. precision: " + precision);
}
} }
Timestamp tsObj = new Timestamp(milliseconds);
tsObj.setNanos(fracNanoseconds);
data.set(col, tsObj);
} }
public Timestamp getTimestamp(int col, int nativeType) { public Timestamp getTimestamp(int col, int nativeType) {
......
package com.taosdata.jdbc; package com.taosdata.jdbc;
import org.junit.Test; import org.junit.Test;
import static org.junit.Assert.*;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.SQLWarning; import java.sql.SQLWarning;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
public class TSDBJNIConnectorTest { public class TSDBJNIConnectorTest {
private static TSDBResultSetRowData rowData; private static TSDBResultSetRowData rowData;
...@@ -14,17 +19,68 @@ public class TSDBJNIConnectorTest { ...@@ -14,17 +19,68 @@ public class TSDBJNIConnectorTest {
@Test @Test
public void test() { public void test() {
try { try {
try {
//change sleepSeconds when debugging with attach to process to find PID
int sleepSeconds = -1;
if (sleepSeconds>0) {
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
String jvmName = runtimeBean.getName();
long pid = Long.valueOf(jvmName.split("@")[0]);
System.out.println("JVM PID = " + pid);
Thread.sleep(sleepSeconds*1000);
}
}
catch (Exception e) {
e.printStackTrace();
}
// init // init
TSDBJNIConnector.init("/etc/taos/taos.cfg", null, null, null); TSDBJNIConnector.init("/etc/taos", null, null, null);
// connect // connect
TSDBJNIConnector connector = new TSDBJNIConnector(); TSDBJNIConnector connector = new TSDBJNIConnector();
connector.connect("127.0.0.1", 6030, "unsign_jni", "root", "taosdata"); connector.connect("127.0.0.1", 6030, null, "root", "taosdata");
// setup
String setupSqlStrs[] = {"create database if not exists d precision \"us\"",
"create table if not exists d.t(ts timestamp, f int)",
"create database if not exists d2",
"create table if not exists d2.t2(ts timestamp, f int)",
"insert into d.t values(now+100s, 100)",
"insert into d2.t2 values(now+200s, 200)"
};
for (String setupSqlStr : setupSqlStrs) {
long setupSql = connector.executeQuery(setupSqlStr);
assertEquals(0, connector.getResultTimePrecision(setupSql));
if (connector.isUpdateQuery(setupSql)) {
connector.freeResultSet(setupSql);
}
}
{
long sqlObj1 = connector.executeQuery("select * from d2.t2");
assertEquals(0, connector.getResultTimePrecision(sqlObj1));
List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(sqlObj1, columnMetaDataList);
rowData = new TSDBResultSetRowData(columnMetaDataList.size());
assertTrue(next(connector, sqlObj1));
assertEquals(0, connector.getResultTimePrecision(sqlObj1));
connector.freeResultSet(sqlObj1);
}
// executeQuery // executeQuery
long pSql = connector.executeQuery("select * from unsign_jni.us_table"); long pSql = connector.executeQuery("select * from d.t");
if (connector.isUpdateQuery(pSql)) { if (connector.isUpdateQuery(pSql)) {
connector.freeResultSet(pSql); connector.freeResultSet(pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
} }
assertEquals(1, connector.getResultTimePrecision(pSql));
// get schema // get schema
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(); List<ColumnMetaData> columnMetaDataList = new ArrayList<>();
int code = connector.getSchemaMetaData(pSql, columnMetaDataList); int code = connector.getSchemaMetaData(pSql, columnMetaDataList);
...@@ -37,6 +93,8 @@ public class TSDBJNIConnectorTest { ...@@ -37,6 +93,8 @@ public class TSDBJNIConnectorTest {
if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0);
} }
assertEquals(1, connector.getResultTimePrecision(pSql));
int columnSize = columnMetaDataList.size(); int columnSize = columnMetaDataList.size();
// print metadata // print metadata
for (int i = 0; i < columnSize; i++) { for (int i = 0; i < columnSize; i++) {
...@@ -45,9 +103,8 @@ public class TSDBJNIConnectorTest { ...@@ -45,9 +103,8 @@ public class TSDBJNIConnectorTest {
rowData = new TSDBResultSetRowData(columnSize); rowData = new TSDBResultSetRowData(columnSize);
// iterate resultSet // iterate resultSet
for (int i = 0; next(connector, pSql); i++) { for (int i = 0; next(connector, pSql); i++) {
// System.out.println("col[" + i + "] size: " + rowData.getColSize()); assertEquals(1, connector.getResultTimePrecision(pSql));
// rowData.getData().stream().forEach(col -> System.out.print(col + "\t")); System.out.println();
// System.out.println();
} }
// close resultSet // close resultSet
code = connector.freeResultSet(pSql); code = connector.freeResultSet(pSql);
...@@ -86,4 +143,4 @@ public class TSDBJNIConnectorTest { ...@@ -86,4 +143,4 @@ public class TSDBJNIConnectorTest {
} }
} }
} }
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册