提交 24f47281 编写于 作者: D dapan1121

Merge branch 'feature/TD-4038' of https://github.com/taosdata/TDengine into feature/TD-4038

...@@ -154,13 +154,12 @@ typedef struct STagCond { ...@@ -154,13 +154,12 @@ typedef struct STagCond {
typedef struct SParamInfo { typedef struct SParamInfo {
int32_t idx; int32_t idx;
char type; uint8_t type;
uint8_t timePrec; uint8_t timePrec;
int16_t bytes; int16_t bytes;
uint32_t offset; uint32_t offset;
} SParamInfo; } SParamInfo;
typedef struct SBoundColumn { typedef struct SBoundColumn {
bool hasVal; // denote if current column has bound or not bool hasVal; // denote if current column has bound or not
int32_t offset; // all column offset value int32_t offset; // all column offset value
......
...@@ -204,10 +204,10 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI ...@@ -204,10 +204,10 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
/* /*
* Class: com_taosdata_jdbc_TSDBJNIConnector * Class: com_taosdata_jdbc_TSDBJNIConnector
* Method: bindColDataImp * Method: bindColDataImp
* Signature: (J[B[BIIIIJ)J * Signature: (J[B[B[BIIIIJ)J
*/ */
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp
(JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jint, jint, jint, jint, jlong); (JNIEnv *, jobject, jlong, jbyteArray, jbyteArray, jbyteArray, jint, jint, jint, jint, jlong);
/* /*
* Class: com_taosdata_jdbc_TSDBJNIConnector * Class: com_taosdata_jdbc_TSDBJNIConnector
......
...@@ -753,7 +753,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI ...@@ -753,7 +753,7 @@ JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_setBindTableNameI
} }
JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(JNIEnv *env, jobject jobj, jlong stmt, JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(JNIEnv *env, jobject jobj, jlong stmt,
jbyteArray data, jbyteArray length, jint dataType, jint dataBytes, jint numOfRows, jint colIndex, jlong con) { jbyteArray colDataList, jbyteArray lengthList, jbyteArray nullList, jint dataType, jint dataBytes, jint numOfRows, jint colIndex, jlong con) {
TAOS *tscon = (TAOS *)con; TAOS *tscon = (TAOS *)con;
if (tscon == NULL) { if (tscon == NULL) {
jniError("jobj:%p, connection already closed", jobj); jniError("jobj:%p, connection already closed", jobj);
...@@ -767,16 +767,22 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J ...@@ -767,16 +767,22 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
} }
// todo refactor // todo refactor
jsize len = (*env)->GetArrayLength(env, data); jsize len = (*env)->GetArrayLength(env, colDataList);
char *colBuf = (char *)calloc(1, sizeof(char) * len); char *colBuf = (char *)calloc(1, len);
(*env)->GetByteArrayRegion(env, data, 0, len, (jbyte *)colBuf); (*env)->GetByteArrayRegion(env, colDataList, 0, len, (jbyte *)colBuf);
if ((*env)->ExceptionCheck(env)) { if ((*env)->ExceptionCheck(env)) {
// todo handle error // todo handle error
} }
len = (*env)->GetArrayLength(env, length); len = (*env)->GetArrayLength(env, lengthList);
char *lengthArray = (char*) calloc(1, sizeof(char) * len); char *lengthArray = (char*) calloc(1, len);
(*env)->GetByteArrayRegion(env, length, 0, len, (jbyte*) lengthArray); (*env)->GetByteArrayRegion(env, lengthList, 0, len, (jbyte*) lengthArray);
if ((*env)->ExceptionCheck(env)) {
}
len = (*env)->GetArrayLength(env, nullList);
char *nullArray = (char*) calloc(1, len);
(*env)->GetByteArrayRegion(env, nullList, 0, len, (jbyte*) nullArray);
if ((*env)->ExceptionCheck(env)) { if ((*env)->ExceptionCheck(env)) {
} }
...@@ -785,10 +791,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J ...@@ -785,10 +791,10 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
b->num = numOfRows; b->num = numOfRows;
b->buffer_type = dataType; // todo check data type b->buffer_type = dataType; // todo check data type
b->buffer_length = tDataTypes[dataType].bytes; b->buffer_length = IS_VAR_DATA_TYPE(dataType)? dataBytes:tDataTypes[dataType].bytes;
b->is_null = calloc(numOfRows, sizeof(int32_t)); b->is_null = nullArray;
b->buffer = colBuf; b->buffer = colBuf;
b->length = (uintptr_t*)lengthArray; b->length = (int32_t*)lengthArray;
// set the length and is_null array // set the length and is_null array
switch(dataType) { switch(dataType) {
...@@ -800,8 +806,13 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J ...@@ -800,8 +806,13 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_bindColDataImp(J
int32_t bytes = tDataTypes[dataType].bytes; int32_t bytes = tDataTypes[dataType].bytes;
for(int32_t i = 0; i < numOfRows; ++i) { for(int32_t i = 0; i < numOfRows; ++i) {
b->length[i] = bytes; b->length[i] = bytes;
b->is_null[i] = isNull(colBuf + bytes * i, dataType);
} }
break;
}
case TSDB_DATA_TYPE_NCHAR:
case TSDB_DATA_TYPE_BINARY: {
// do nothing
} }
} }
......
...@@ -158,7 +158,7 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { ...@@ -158,7 +158,7 @@ static int normalStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
break; break;
default: default:
tscDebug("0x%"PRIx64" param %d: type mismatch or invalid", stmt->pSql->self, i); tscDebug("0x%"PRIx64" bind column%d: type mismatch or invalid", stmt->pSql->self, i);
return TSDB_CODE_TSC_INVALID_VALUE; return TSDB_CODE_TSC_INVALID_VALUE;
} }
} }
...@@ -727,45 +727,14 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param, ...@@ -727,45 +727,14 @@ static int doBindParam(STableDataBlocks* pBlock, char* data, SParamInfo* param,
static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* bind, int32_t rowNum) { static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MULTI_BIND* bind, int32_t rowNum) {
if (bind->buffer_type != param->type) { if (bind->buffer_type != param->type || !isValidDataType(param->type)) {
return TSDB_CODE_TSC_INVALID_VALUE; return TSDB_CODE_TSC_INVALID_VALUE;
} }
short size = 0; if (IS_VAR_DATA_TYPE(param->type) && bind->length == NULL) {
switch(param->type) { tscError("BINARY/NCHAR no length");
case TSDB_DATA_TYPE_BOOL: return TSDB_CODE_TSC_INVALID_VALUE;
case TSDB_DATA_TYPE_TINYINT:
size = 1;
break;
case TSDB_DATA_TYPE_SMALLINT:
size = 2;
break;
case TSDB_DATA_TYPE_INT:
case TSDB_DATA_TYPE_FLOAT:
size = 4;
break;
case TSDB_DATA_TYPE_BIGINT:
case TSDB_DATA_TYPE_DOUBLE:
case TSDB_DATA_TYPE_TIMESTAMP:
size = 8;
break;
case TSDB_DATA_TYPE_BINARY:
case TSDB_DATA_TYPE_NCHAR:
if (bind->length == NULL) {
tscError("BINARY/NCHAR no length");
return TSDB_CODE_TSC_INVALID_VALUE;
}
break;
default:
assert(false);
return TSDB_CODE_TSC_INVALID_VALUE;
} }
for (int i = 0; i < bind->num; ++i) { for (int i = 0; i < bind->num; ++i) {
char* data = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * (rowNum + i); char* data = pBlock->pData + sizeof(SSubmitBlk) + pBlock->rowSize * (rowNum + i);
...@@ -775,8 +744,8 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU ...@@ -775,8 +744,8 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
continue; continue;
} }
if (size > 0) { if (!IS_VAR_DATA_TYPE(param->type)) {
memcpy(data + param->offset, bind->buffer + bind->buffer_length * i, size); memcpy(data + param->offset, bind->buffer + bind->buffer_length * i, tDataTypes[param->type].bytes);
if (param->offset == 0) { if (param->offset == 0) {
if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) { if (tsCheckTimestamp(pBlock, data + param->offset) != TSDB_CODE_SUCCESS) {
...@@ -786,17 +755,23 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU ...@@ -786,17 +755,23 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
} }
} else if (param->type == TSDB_DATA_TYPE_BINARY) { } else if (param->type == TSDB_DATA_TYPE_BINARY) {
if (bind->length[i] > (uintptr_t)param->bytes) { if (bind->length[i] > (uintptr_t)param->bytes) {
tscError("invalid binary length"); tscError("binary length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)bind->length[i]);
return TSDB_CODE_TSC_INVALID_VALUE; return TSDB_CODE_TSC_INVALID_VALUE;
} }
int16_t bsize = (short)bind->length[i]; int16_t bsize = (short)bind->length[i];
STR_WITH_SIZE_TO_VARSTR(data + param->offset, bind->buffer + bind->buffer_length * i, bsize); STR_WITH_SIZE_TO_VARSTR(data + param->offset, bind->buffer + bind->buffer_length * i, bsize);
} else if (param->type == TSDB_DATA_TYPE_NCHAR) { } else if (param->type == TSDB_DATA_TYPE_NCHAR) {
if (bind->length[i] > (uintptr_t)param->bytes) {
tscError("nchar string length too long, ignore it, max:%d, actual:%d", param->bytes, (int32_t)bind->length[i]);
return TSDB_CODE_TSC_INVALID_VALUE;
}
int32_t output = 0; int32_t output = 0;
if (!taosMbsToUcs4(bind->buffer + bind->buffer_length * i, bind->length[i], varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) { if (!taosMbsToUcs4(bind->buffer + bind->buffer_length * i, bind->length[i], varDataVal(data + param->offset), param->bytes - VARSTR_HEADER_SIZE, &output)) {
tscError("convert failed"); tscError("convert nchar string to UCS4_LE failed:%s", (char*)(bind->buffer + bind->buffer_length * i));
return TSDB_CODE_TSC_INVALID_VALUE; return TSDB_CODE_TSC_INVALID_VALUE;
} }
varDataSetLen(data + param->offset, output); varDataSetLen(data + param->offset, output);
} }
} }
...@@ -804,8 +779,6 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU ...@@ -804,8 +779,6 @@ static int doBindBatchParam(STableDataBlocks* pBlock, SParamInfo* param, TAOS_MU
return TSDB_CODE_SUCCESS; return TSDB_CODE_SUCCESS;
} }
static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
SSqlCmd* pCmd = &stmt->pSql->cmd; SSqlCmd* pCmd = &stmt->pSql->cmd;
STscStmt* pStmt = (STscStmt*)stmt; STscStmt* pStmt = (STscStmt*)stmt;
...@@ -860,7 +833,7 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) { ...@@ -860,7 +833,7 @@ static int insertStmtBindParam(STscStmt* stmt, TAOS_BIND* bind) {
int code = doBindParam(pBlock, data, param, &bind[param->idx], 1); int code = doBindParam(pBlock, data, param, &bind[param->idx], 1);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
tscDebug("0x%"PRIx64" param %d: type mismatch or invalid", pStmt->pSql->self, param->idx); tscDebug("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
return code; return code;
} }
} }
...@@ -930,7 +903,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c ...@@ -930,7 +903,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
int code = doBindBatchParam(pBlock, param, &bind[param->idx], pCmd->batchSize); int code = doBindBatchParam(pBlock, param, &bind[param->idx], pCmd->batchSize);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
tscError("0x%"PRIx64" param %d: type mismatch or invalid", pStmt->pSql->self, param->idx); tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
return code; return code;
} }
} }
...@@ -941,7 +914,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c ...@@ -941,7 +914,7 @@ static int insertStmtBindParamBatch(STscStmt* stmt, TAOS_MULTI_BIND* bind, int c
int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize); int code = doBindBatchParam(pBlock, param, bind, pCmd->batchSize);
if (code != TSDB_CODE_SUCCESS) { if (code != TSDB_CODE_SUCCESS) {
tscError("0x%"PRIx64" param %d: type mismatch or invalid", pStmt->pSql->self, param->idx); tscError("0x%"PRIx64" bind column %d: type mismatch or invalid", pStmt->pSql->self, param->idx);
return code; return code;
} }
......
...@@ -306,11 +306,11 @@ public class TSDBJNIConnector { ...@@ -306,11 +306,11 @@ public class TSDBJNIConnector {
private native int setBindTableNameImp(long stmt, String name, long conn); private native int setBindTableNameImp(long stmt, String name, long conn);
public int bindColumnDataArray(long stmt, ByteBuffer colList, ByteBuffer lengthList, int type, int bytes, int numOfRows,int columnIndex) { public int bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) {
return bindColDataImp(stmt, colList.array(), lengthList.array(), type, bytes, numOfRows, columnIndex, this.taos); return bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos);
} }
private native int bindColDataImp(long stmt, byte[] data, byte[] length, int type, int bytes, int numOfRows, int columnIndex, long conn); private native int bindColDataImp(long stmt, byte[] colDataList, byte[] lengthList, byte[] isNullList, int type, int bytes, int numOfRows, int columnIndex, long conn);
public int executeBatch(long stmt) { public int executeBatch(long stmt) {
return executeBatchImp(stmt, this.taos); return executeBatchImp(stmt, this.taos);
......
...@@ -18,6 +18,7 @@ import com.taosdata.jdbc.utils.Utils; ...@@ -18,6 +18,7 @@ import com.taosdata.jdbc.utils.Utils;
import java.io.InputStream; import java.io.InputStream;
import java.io.Reader; import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.net.URL; import java.net.URL;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
...@@ -40,8 +41,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -40,8 +41,6 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
private boolean isPrepared; private boolean isPrepared;
private ArrayList<ColumnInfo> colData; private ArrayList<ColumnInfo> colData;
private int type;
private String tableName; private String tableName;
private long nativeStmtHandle = 0; private long nativeStmtHandle = 0;
...@@ -540,6 +539,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -540,6 +539,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@SuppressWarnings("rawtypes") @SuppressWarnings("rawtypes")
private ArrayList data; private ArrayList data;
private int type; private int type;
private int bytes;
private boolean typeIsSet; private boolean typeIsSet;
public ColumnInfo() { public ColumnInfo() {
...@@ -564,60 +564,61 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -564,60 +564,61 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
this.tableName = name; this.tableName = name;
} }
public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type) throws SQLException { public <T> void setValueImpl(int columnIndex, ArrayList<T> list, int type, int bytes) throws SQLException {
ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex); ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex);
if (col == null) { if (col == null) {
ColumnInfo p = new ColumnInfo(); ColumnInfo p = new ColumnInfo();
p.setType(type); p.setType(type);
p.bytes = bytes;
p.data = (ArrayList<?>) list.clone(); p.data = (ArrayList<?>) list.clone();
this.colData.set(columnIndex, p); this.colData.set(columnIndex, p);
} else { } else {
if (col.type != type) { if (col.type != type) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch");
} }
col.data.addAll(list); col.data.addAll(list);
} }
} }
public void setInt(int columnIndex, ArrayList<Integer> list) throws SQLException { public void setInt(int columnIndex, ArrayList<Integer> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES);
} }
public void setFloat(int columnIndex, ArrayList<Float> list) throws SQLException { public void setFloat(int columnIndex, ArrayList<Float> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES);
} }
public void setTimestamp(int columnIndex, ArrayList<Long> list) throws SQLException { public void setTimestamp(int columnIndex, ArrayList<Long> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES);
} }
public void setLong(int columnIndex, ArrayList<Long> list) throws SQLException { public void setLong(int columnIndex, ArrayList<Long> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES);
} }
public void setDouble(int columnIndex, ArrayList<Double> list) throws SQLException { public void setDouble(int columnIndex, ArrayList<Double> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES);
} }
public void setBoolean(int columnIndex, ArrayList<Boolean> list) throws SQLException { public void setBoolean(int columnIndex, ArrayList<Boolean> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES);
} }
public void setByte(int columnIndex, ArrayList<Byte> list) throws SQLException { public void setByte(int columnIndex, ArrayList<Byte> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES);
} }
public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException { public void setShort(int columnIndex, ArrayList<Short> list) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES);
} }
public void setString(int columnIndex, ArrayList<String> list) throws SQLException { public void setString(int columnIndex, ArrayList<String> list, int size) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY); setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size);
} }
public void setNString(int columnIndex, ArrayList<String> list) throws SQLException { // note: expand the required space for each NChar character
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR); public void setNString(int columnIndex, ArrayList<String> list, int size) throws SQLException {
setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES);
} }
public void columnDataAddBatch() { public void columnDataAddBatch() {
...@@ -643,11 +644,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -643,11 +644,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
e.printStackTrace(); e.printStackTrace();
} }
int bytes = 0;
for (int i = 0; i < numOfCols; ++i) { for (int i = 0; i < numOfCols; ++i) {
ColumnInfo col1 = this.colData.get(i); ColumnInfo col1 = this.colData.get(i);
if (!col1.isTypeSet()) { if (col1 == null || !col1.isTypeSet()) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind");
} }
...@@ -655,51 +654,122 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat ...@@ -655,51 +654,122 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical"); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical");
} }
ByteBuffer bbuf = null; ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes);
colDataList.order(ByteOrder.LITTLE_ENDIAN);
ByteBuffer lengthBuf = ByteBuffer.allocate(rows * Integer.BYTES); ByteBuffer lengthList = ByteBuffer.allocate(rows * Integer.BYTES);
lengthBuf.order(ByteOrder.LITTLE_ENDIAN); lengthList.order(ByteOrder.LITTLE_ENDIAN);
ByteBuffer isNullList = ByteBuffer.allocate(rows * Byte.BYTES);
isNullList.order(ByteOrder.LITTLE_ENDIAN);
switch (col1.type) { switch (col1.type) {
case TSDBConstants.TSDB_DATA_TYPE_INT: { case TSDBConstants.TSDB_DATA_TYPE_INT: {
bbuf = ByteBuffer.allocate(rows * Integer.BYTES);
bbuf.order(ByteOrder.LITTLE_ENDIAN);
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Integer val = (Integer) col1.data.get(j); Integer val = (Integer) col1.data.get(j);
if (val == null) { colDataList.putInt(val == null? Integer.MIN_VALUE:val);
bbuf.putInt(j * Integer.BYTES, Integer.MIN_VALUE); isNullList.put((byte) (val == null? 1:0));
} else {
bbuf.putInt(j * Integer.BYTES, val);
}
lengthBuf.putInt(j * Integer.BYTES, Integer.BYTES);
} }
bytes = Integer.BYTES;
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: { case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
bbuf = ByteBuffer.allocate(rows * Long.BYTES); for (int j = 0; j < rows; ++j) {
bbuf.order(ByteOrder.LITTLE_ENDIAN); Byte val = (Byte) col1.data.get(j);
colDataList.put(val == null? 0:val);
isNullList.put((byte) (val == null? 1:0));
}
break;
}
case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
for (int j = 0; j < rows; ++j) {
Byte val = (Byte) col1.data.get(j);
colDataList.put(val == null? 0:val);
isNullList.put((byte) (val == null? 1:0));
}
break;
}
case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
for (int j = 0; j < rows; ++j) {
Short val = (Short) col1.data.get(j);
colDataList.putShort(val == null? 0:val);
isNullList.put((byte) (val == null? 1:0));
}
break;
}
case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP:
case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
for (int j = 0; j < rows; ++j) { for (int j = 0; j < rows; ++j) {
Long val = (Long) col1.data.get(j); Long val = (Long) col1.data.get(j);
if (val == null) { colDataList.putLong(val == null? 0:val);
bbuf.putLong(j * Long.BYTES, Long.MIN_VALUE); isNullList.put((byte) (val == null? 1:0));
}
break;
}
case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
for (int j = 0; j < rows; ++j) {
Float val = (Float) col1.data.get(j);
colDataList.putFloat(val == null? 0:val);
isNullList.put((byte) (val == null? 1:0));
}
break;
}
case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
for (int j = 0; j < rows; ++j) {
Double val = (Double) col1.data.get(j);
colDataList.putDouble(val == null? 0:val);
isNullList.put((byte) (val == null? 1:0));
}
break;
}
case TSDBConstants.TSDB_DATA_TYPE_NCHAR:
case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
String charset = TaosGlobalConfig.getCharset();
for (int j = 0; j < rows; ++j) {
String val = (String) col1.data.get(j);
if (val != null && val.length() > col1.bytes) {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long");
}
colDataList.position(j * col1.bytes); // seek to the correct position
if (val != null) {
byte[] b = null;
try {
if (col1.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) {
b = val.getBytes();
} else {
b = val.getBytes(charset);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
colDataList.put(b);
lengthList.putInt(b.length);
isNullList.put((byte) 0);
} else { } else {
bbuf.putLong(j * Long.BYTES, val); lengthList.putInt(0);
isNullList.put((byte) 1);
} }
lengthBuf.putInt(j * Integer.BYTES, Long.BYTES);
} }
bytes = Long.BYTES;
break; break;
} }
case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
case TSDBConstants.TSDB_DATA_TYPE_UINT:
case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: {
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "not support data types");
}
}; };
connector.bindColumnDataArray(this.nativeStmtHandle, bbuf, lengthBuf, col1.type, bytes, rows, i); connector.bindColumnDataArray(this.nativeStmtHandle, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i);
} }
connector.executeBatch(this.nativeStmtHandle); connector.executeBatch(this.nativeStmtHandle);
......
...@@ -438,8 +438,8 @@ public class TSDBResultSetBlockData { ...@@ -438,8 +438,8 @@ public class TSDBResultSetBlockData {
} }
try { try {
String ss = TaosGlobalConfig.getCharset(); String charset = TaosGlobalConfig.getCharset();
return new String(dest, ss); return new String(dest, charset);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
e.printStackTrace(); e.printStackTrace();
} }
......
...@@ -11,11 +11,11 @@ public class NullType { ...@@ -11,11 +11,11 @@ public class NullType {
public static boolean isBooleanNull(byte val) { public static boolean isBooleanNull(byte val) {
return val == NullType.NULL_BOOL_VAL; return val == NullType.NULL_BOOL_VAL;
} }
public static boolean isTinyIntNull(byte val) { public static boolean isTinyIntNull(byte val) {
return val == Byte.MIN_VALUE; return val == Byte.MIN_VALUE;
} }
public static boolean isSmallIntNull(short val) { public static boolean isSmallIntNull(short val) {
return val == Short.MIN_VALUE; return val == Short.MIN_VALUE;
} }
...@@ -23,19 +23,19 @@ public class NullType { ...@@ -23,19 +23,19 @@ public class NullType {
public static boolean isIntNull(int val) { public static boolean isIntNull(int val) {
return val == Integer.MIN_VALUE; return val == Integer.MIN_VALUE;
} }
public static boolean isBigIntNull(long val) { public static boolean isBigIntNull(long val) {
return val == Long.MIN_VALUE; return val == Long.MIN_VALUE;
} }
public static boolean isFloatNull(float val) { public static boolean isFloatNull(float val) {
return Float.isNaN(val); return Float.isNaN(val);
} }
public static boolean isDoubleNull(double val) { public static boolean isDoubleNull(double val) {
return Double.isNaN(val); return Double.isNaN(val);
} }
public static boolean isBinaryNull(byte[] val, int length) { public static boolean isBinaryNull(byte[] val, int length) {
if (length != Byte.BYTES) { if (length != Byte.BYTES) {
return false; return false;
...@@ -43,7 +43,7 @@ public class NullType { ...@@ -43,7 +43,7 @@ public class NullType {
return val[0] == 0xFF; return val[0] == 0xFF;
} }
public static boolean isNcharNull(byte[] val, int length) { public static boolean isNcharNull(byte[] val, int length) {
if (length != Integer.BYTES) { if (length != Integer.BYTES) {
return false; return false;
...@@ -51,5 +51,41 @@ public class NullType { ...@@ -51,5 +51,41 @@ public class NullType {
return (val[0] & val[1] & val[2] & val[3]) == 0xFF; return (val[0] & val[1] & val[2] & val[3]) == 0xFF;
} }
public static byte getBooleanNull() {
return NullType.NULL_BOOL_VAL;
}
public static byte getTinyintNull() {
return Byte.MIN_VALUE;
}
public static int getIntNull() {
return Integer.MIN_VALUE;
}
public static short getSmallIntNull() {
return Short.MIN_VALUE;
}
public static long getBigIntNull() {
return Long.MIN_VALUE;
}
public static int getFloatNull() {
return 0x7FF00000;
}
public static long getDoubleNull() {
return 0x7FFFFF0000000000L;
}
public static byte getBinaryNull() {
return (byte) 0xFF;
}
public static byte[] getNcharNull() {
return new byte[] {(byte) 0xFF, (byte) 0xFF, (byte) 0xFF, (byte) 0xFF};
}
} }
...@@ -104,8 +104,8 @@ typedef struct TAOS_MULTI_BIND { ...@@ -104,8 +104,8 @@ typedef struct TAOS_MULTI_BIND {
int buffer_type; int buffer_type;
void *buffer; void *buffer;
uintptr_t buffer_length; uintptr_t buffer_length;
uintptr_t *length; int32_t *length;
int *is_null; char *is_null;
int num; int num;
} TAOS_MULTI_BIND; } TAOS_MULTI_BIND;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册