From e9bba3cdd74c79f73f5d844311f460aba04b0a08 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 20 Aug 2020 10:43:43 +0800 Subject: [PATCH] fix jdbc memleaks #3098 --- src/client/src/TSDBJNIConnector.c | 7 +++-- .../com/taosdata/jdbc/TSDBJNIConnector.java | 26 ++++++++++--------- .../java/com/taosdata/jdbc/TSDBStatement.java | 17 ++++++------ 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/src/client/src/TSDBJNIConnector.c b/src/client/src/TSDBJNIConnector.c index 34204f96bf..0dd5e13181 100644 --- a/src/client/src/TSDBJNIConnector.c +++ b/src/client/src/TSDBJNIConnector.c @@ -327,13 +327,12 @@ JNIEXPORT jlong JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_getResultSetImp( STscObj *pObj = pSql->pTscObj; if (tscIsUpdateQuery(pSql)) { - // taos_free_result(pSql); // free result here - jniDebug("jobj:%p, conn:%p, no resultset, %p", jobj, pObj, (void *)tres); - return 0; + jniDebug("jobj:%p, conn:%p, update query, no resultset, %p", jobj, pObj, (void *)tres); } else { jniDebug("jobj:%p, conn:%p, get resultset, %p", jobj, pObj, (void *)tres); - return tres; } + + return tres; } JNIEXPORT jint JNICALL Java_com_taosdata_jdbc_TSDBJNIConnector_freeResultSetImp(JNIEnv *env, jobject jobj, jlong con, diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java index bab3c79089..25f7f8576d 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java @@ -111,6 +111,8 @@ public class TSDBJNIConnector { * @throws SQLException */ public long executeQuery(String sql) throws SQLException { + // close previous result set if the user forgets to invoke the + // free method to close previous result set. if (!this.isResultsetClosed) { freeResultSet(taosResultSetPointer); } @@ -123,21 +125,20 @@ public class TSDBJNIConnector { this.freeResultSet(pSql); throw new SQLException(TSDBConstants.WrapErrMsg("Unsupported encoding")); } + int code = this.getErrCode(pSql); if (code != 0) { affectedRows = -1; - String err_msg = this.getErrMsg(pSql); + String msg = this.getErrMsg(pSql); + this.freeResultSet(pSql); - throw new SQLException(TSDBConstants.WrapErrMsg(err_msg), "", code); + throw new SQLException(TSDBConstants.WrapErrMsg(msg), "", code); } - // Try retrieving result set for the executed SQL using the current connection pointer. If the executed - // SQL is a DML/DDL which doesn't return a result set, then taosResultSetPointer should be 0L. Otherwise, - // taosResultSetPointer should be a non-zero value. + // Try retrieving result set for the executed SQL using the current connection pointer. taosResultSetPointer = this.getResultSetImp(this.taos, pSql); - if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) { - isResultsetClosed = false; - } + isResultsetClosed = (taosResultSetPointer == TSDBConstants.JNI_NULL_POINTER); + return pSql; } @@ -178,13 +179,14 @@ public class TSDBJNIConnector { int res = TSDBConstants.JNI_SUCCESS; if (result != taosResultSetPointer && taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) { throw new RuntimeException("Invalid result set pointer"); - } else if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) { + } + + if (taosResultSetPointer != TSDBConstants.JNI_NULL_POINTER) { res = this.freeResultSetImp(this.taos, result); - isResultsetClosed = true; // reset resultSetPointer to 0 after freeResultSetImp() return taosResultSetPointer = TSDBConstants.JNI_NULL_POINTER; - } else { - isResultsetClosed = true; } + + isResultsetClosed = true; return res; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java index e828864313..54598212ed 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java @@ -51,6 +51,8 @@ public class TSDBStatement implements Statement { if (isClosed) { throw new SQLException("Invalid method call on a closed statement."); } + + // TODO make sure it is not a update query pSql = this.connecter.executeQuery(sql); long resultSetPointer = this.connecter.getResultSet(); @@ -71,20 +73,19 @@ public class TSDBStatement implements Statement { if (isClosed) { throw new SQLException("Invalid method call on a closed statement."); } + + // TODO check if current query is update query pSql = this.connecter.executeQuery(sql); long resultSetPointer = this.connecter.getResultSet(); if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) { this.connecter.freeResultSet(pSql); throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL)); - } else if (resultSetPointer != TSDBConstants.JNI_NULL_POINTER) { - this.connecter.freeResultSet(); - throw new SQLException("The executed SQL is not a DML or a DDL"); - } else { - int num = this.connecter.getAffectedRows(pSql); - this.connecter.freeResultSet(pSql); - return num; - } + } + + int num = this.connecter.getAffectedRows(pSql); + this.connecter.freeResultSet(pSql); + return num; } public String getErrorMsg(long pSql) { -- GitLab