diff --git a/src/connector/jdbc/CMakeLists.txt b/src/connector/jdbc/CMakeLists.txt index 61e976cb184d3240bdc8917a5b2e5f3182d55fcc..9642b0490f5ba7168f62c75cd4c06b63168eed9f 100644 --- a/src/connector/jdbc/CMakeLists.txt +++ b/src/connector/jdbc/CMakeLists.txt @@ -8,10 +8,8 @@ IF (TD_MVN_INSTALLED) ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME} POST_BUILD COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml - COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.29.jar ${LIBRARY_OUTPUT_PATH} + COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.32-dist.jar ${LIBRARY_OUTPUT_PATH} COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml COMMENT "build jdbc driver") ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME}) -ENDIF () - - +ENDIF () \ No newline at end of file diff --git a/src/connector/jdbc/deploy-pom.xml b/src/connector/jdbc/deploy-pom.xml index 968a9bf470ddde1996467467fa24cfd2fbf355e0..06122372f027c003c1991729efc56dc8cf5929ae 100755 --- a/src/connector/jdbc/deploy-pom.xml +++ b/src/connector/jdbc/deploy-pom.xml @@ -5,7 +5,7 @@ com.taosdata.jdbc taos-jdbcdriver - 2.0.29 + 2.0.32 jar JDBCDriver diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml old mode 100755 new mode 100644 index ef353d1d19d37da3c1a3e9bdc4a2a378cf4edc0c..61d7fb85ef58961627db3f150f23c2fa2e584dfe --- a/src/connector/jdbc/pom.xml +++ b/src/connector/jdbc/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.taosdata.jdbc taos-jdbcdriver - 2.0.29 + 2.0.32 jar JDBCDriver https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc @@ -47,7 +47,7 @@ org.apache.httpcomponents httpclient - 4.5.8 + 4.5.13 com.alibaba @@ -113,16 +113,16 @@ **/*Test.java - **/TSDBJNIConnectorTest.java - **/UnsignedNumberJniTest.java - **/DatetimeBefore1970Test.java **/AppMemoryLeakTest.java **/AuthenticationTest.java - **/TaosInfoMonitorTest.java + **/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java + **/DatetimeBefore1970Test.java **/FailOverTest.java **/InvalidResultSetPointerTest.java **/RestfulConnectionTest.java - **/TD4144Test.java + **/TSDBJNIConnectorTest.java + **/TaosInfoMonitorTest.java + **/UnsignedNumberJniTest.java true diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java index 2970f6c2d37d73476ee0d8831a68128569766fb4..b3887d436bcacd9748d169d0a7666a7bfa85589a 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java @@ -1,5 +1,7 @@ package com.taosdata.jdbc; +import com.taosdata.jdbc.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); } @@ -304,9 +306,6 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti @Override public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); - switch (resultSetHoldability) { case ResultSet.HOLD_CURSORS_OVER_COMMIT: break; @@ -320,11 +319,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti } @Override - public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) - throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); - + public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException { switch (resultSetHoldability) { case ResultSet.HOLD_CURSORS_OVER_COMMIT: break; @@ -423,7 +418,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti status = resultSet.getInt("server_status()"); resultSet.close(); } - return status == 1 ? true : false; + return status == 1; }); boolean status = false; @@ -432,9 +427,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti status = future.get(); else status = future.get(timeout, TimeUnit.SECONDS); - } catch (InterruptedException e) { - e.printStackTrace(); - } catch (ExecutionException e) { + } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } catch (TimeoutException e) { future.cancel(true); @@ -450,8 +443,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti if (isClosed) throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED); - if (clientInfoProps != null) - clientInfoProps.setProperty(name, value); + clientInfoProps.setProperty(name, value); } @Override @@ -459,8 +451,8 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti if (isClosed) throw (SQLClientInfoException) TSDBError.createSQLException(TSDBErrorNumbers.ERROR_SQLCLIENT_EXCEPTION_ON_CONNECTION_CLOSED); - for (Enumeration enumer = properties.keys(); enumer.hasMoreElements(); ) { - String name = (String) enumer.nextElement(); + for (Enumeration enumeration = properties.keys(); enumeration.hasMoreElements(); ) { + String name = (String) enumeration.nextElement(); clientInfoProps.put(name, properties.getProperty(name)); } } @@ -516,7 +508,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 } @@ -527,14 +518,13 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti if (milliseconds < 0) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + // do nothing } @Override public int getNetworkTimeout() throws SQLException { if (isClosed()) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED); - - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + return 0; } } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java index 5dcaa77ebd4a15087785a6a9b642b85f160f5287..3c9c784f594d6cb022267c2ff1cd848c26f53ac3 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java @@ -12,6 +12,8 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da private final static int DRIVER_MAJAR_VERSION = 2; private final static int DRIVER_MINOR_VERSION = 0; + private String precision = TSDBConstants.DEFAULT_PRECISION; + public boolean allProceduresAreCallable() throws SQLException { return false; } @@ -493,102 +495,105 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException; - protected ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types, Connection connection) throws SQLException { - try (Statement stmt = connection.createStatement()) { - if (catalog == null || catalog.isEmpty()) - return null; - - ResultSet databases = stmt.executeQuery("show databases"); - String dbname = null; - while (databases.next()) { - dbname = databases.getString("name"); - if (dbname.equalsIgnoreCase(catalog)) - break; - } - databases.close(); - if (dbname == null) - return null; + private List buildGetTablesColumnMetaDataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT + columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM + columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME + columnMetaDataList.add(buildTableTypeMeta(4)); // 4. TABLE_TYPE + columnMetaDataList.add(buildRemarksMeta(5)); // 5. remarks + columnMetaDataList.add(buildTypeCatMeta(6)); // 6. TYPE_CAT + columnMetaDataList.add(buildTypeSchemaMeta(7)); // 7. TYPE_SCHEM + columnMetaDataList.add(buildTypeNameMeta(8)); // 8. TYPE_NAME + columnMetaDataList.add(buildSelfReferencingColName(9)); // 9. SELF_REFERENCING_COL_NAME + columnMetaDataList.add(buildRefGenerationMeta(10)); // 10. REF_GENERATION + return columnMetaDataList; + } + + private ColumnMetaData buildTypeCatMeta(int colIndex) { + ColumnMetaData col6 = new ColumnMetaData(); + col6.setColIndex(colIndex); + col6.setColName("TYPE_CAT"); + col6.setColType(Types.NCHAR); + return col6; + } + + private ColumnMetaData buildTypeSchemaMeta(int colIndex) { + ColumnMetaData col7 = new ColumnMetaData(); + col7.setColIndex(colIndex); + col7.setColName("TYPE_SCHEM"); + col7.setColType(Types.NCHAR); + return col7; + } + + private ColumnMetaData buildTypeNameMeta(int colIndex) { + ColumnMetaData col8 = new ColumnMetaData(); + col8.setColIndex(colIndex); + col8.setColName("TYPE_NAME"); + col8.setColType(Types.NCHAR); + return col8; + } + + private ColumnMetaData buildSelfReferencingColName(int colIndex) { + ColumnMetaData col9 = new ColumnMetaData(); + col9.setColIndex(colIndex); + col9.setColName("SELF_REFERENCING_COL_NAME"); + col9.setColType(Types.NCHAR); + return col9; + } + + private ColumnMetaData buildRefGenerationMeta(int colIndex) { + ColumnMetaData col10 = new ColumnMetaData(); + col10.setColIndex(colIndex); + col10.setColName("REF_GENERATION"); + col10.setColType(Types.NCHAR); + return col10; + } - stmt.execute("use " + dbname); - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); - List columnMetaDataList = new ArrayList<>(); - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(1); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - ColumnMetaData col2 = new ColumnMetaData(); - col2.setColIndex(2); - col2.setColName("TABLE_SCHEM"); - col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col2); - ColumnMetaData col3 = new ColumnMetaData(); - col3.setColIndex(3); - col3.setColName("TABLE_NAME"); - col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col3); - ColumnMetaData col4 = new ColumnMetaData(); - col4.setColIndex(4); - col4.setColName("TABLE_TYPE"); - col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col4); - ColumnMetaData col5 = new ColumnMetaData(); - col5.setColIndex(5); - col5.setColName("REMARKS"); - col5.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col5); - ColumnMetaData col6 = new ColumnMetaData(); - col6.setColIndex(6); - col6.setColName("TYPE_CAT"); - col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col6); - ColumnMetaData col7 = new ColumnMetaData(); - col7.setColIndex(7); - col7.setColName("TYPE_SCHEM"); - col7.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col7); - ColumnMetaData col8 = new ColumnMetaData(); - col8.setColIndex(8); - col8.setColName("TYPE_NAME"); - col8.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col8); - ColumnMetaData col9 = new ColumnMetaData(); - col9.setColIndex(9); - col9.setColName("SELF_REFERENCING_COL_NAME"); - col9.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col9); - ColumnMetaData col10 = new ColumnMetaData(); - col10.setColIndex(10); - col10.setColName("REF_GENERATION"); - col10.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col10); - resultSet.setColumnMetaDataList(columnMetaDataList); + protected ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types, Connection connection) throws SQLException { + if (catalog == null || catalog.isEmpty()) + return null; + if (!isAvailableCatalog(connection, catalog)) + return new EmptyResultSet(); - List rowDataList = new ArrayList<>(); + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + // set column metadata list + resultSet.setColumnMetaDataList(buildGetTablesColumnMetaDataList()); + // set row data + List rowDataList = new ArrayList<>(); + try (Statement stmt = connection.createStatement()) { + stmt.execute("use " + catalog); ResultSet tables = stmt.executeQuery("show tables"); while (tables.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(10); - rowData.setString(0, dbname); //table_cat - rowData.setString(1, null); //TABLE_SCHEM - rowData.setString(2, tables.getString("table_name")); //TABLE_NAME - rowData.setString(3, "TABLE"); //TABLE_TYPE - rowData.setString(4, ""); //REMARKS + rowData.setStringValue(1, catalog); //TABLE_CAT + rowData.setStringValue(2, null); //TABLE_SCHEM + rowData.setStringValue(3, tables.getString("table_name")); //TABLE_NAME + rowData.setStringValue(4, "TABLE"); //TABLE_TYPE + rowData.setStringValue(5, ""); //REMARKS rowDataList.add(rowData); } - ResultSet stables = stmt.executeQuery("show stables"); while (stables.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(10); - rowData.setString(0, dbname); //TABLE_CAT - rowData.setString(1, null); //TABLE_SCHEM - rowData.setString(2, stables.getString("name")); //TABLE_NAME - rowData.setString(3, "TABLE"); //TABLE_TYPE - rowData.setString(4, "STABLE"); //REMARKS + rowData.setStringValue(1, catalog); //TABLE_CAT + rowData.setStringValue(2, null); //TABLE_SCHEM + rowData.setStringValue(3, stables.getString("name")); //TABLE_NAME + rowData.setStringValue(4, "TABLE"); //TABLE_TYPE + rowData.setStringValue(5, "STABLE"); //REMARKS rowDataList.add(rowData); } resultSet.setRowDataList(rowDataList); - return resultSet; } + return resultSet; + } + + private ColumnMetaData buildTableTypeMeta(int colIndex) { + ColumnMetaData col4 = new ColumnMetaData(); + col4.setColIndex(colIndex); + col4.setColName("TABLE_TYPE"); + col4.setColType(Types.NCHAR); + return col4; } public ResultSet getSchemas() throws SQLException { @@ -597,25 +602,24 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da public abstract ResultSet getCatalogs() throws SQLException; + private List buildTableTypesColumnMetadataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableTypeMeta(1)); + return columnMetaDataList; + } + public ResultSet getTableTypes() throws SQLException { DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); // set up ColumnMetaDataList - List columnMetaDataList = new ArrayList<>(); - ColumnMetaData colMetaData = new ColumnMetaData(); - colMetaData.setColIndex(0); - colMetaData.setColName("TABLE_TYPE"); - colMetaData.setColSize(10); - colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(colMetaData); - resultSet.setColumnMetaDataList(columnMetaDataList); + resultSet.setColumnMetaDataList(buildTableTypesColumnMetadataList()); // set up rowDataList List rowDataList = new ArrayList<>(); TSDBResultSetRowData rowData = new TSDBResultSetRowData(1); - rowData.setString(0, "TABLE"); + rowData.setStringValue(1, "TABLE"); rowDataList.add(rowData); rowData = new TSDBResultSetRowData(1); - rowData.setString(0, "STABLE"); + rowData.setStringValue(1, "STABLE"); rowDataList.add(rowData); resultSet.setRowDataList(rowDataList); @@ -625,278 +629,330 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da public abstract ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException; protected ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern, Connection conn) { - try (Statement stmt = conn.createStatement()) { - if (catalog == null || catalog.isEmpty()) - return null; - - ResultSet databases = stmt.executeQuery("show databases"); - String dbname = null; - while (databases.next()) { - dbname = databases.getString("name"); - if (dbname.equalsIgnoreCase(catalog)) - break; - } - databases.close(); - if (dbname == null) - return null; + if (catalog == null || catalog.isEmpty()) + return null; + if (!isAvailableCatalog(conn, catalog)) + return new EmptyResultSet(); - stmt.execute("use " + dbname); - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); - // set up ColumnMetaDataList - - List columnMetaDataList = new ArrayList<>(); - // TABLE_CAT - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(1); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - // TABLE_SCHEM - ColumnMetaData col2 = new ColumnMetaData(); - col2.setColIndex(2); - col2.setColName("TABLE_SCHEM"); - col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col2); - // TABLE_NAME - ColumnMetaData col3 = new ColumnMetaData(); - col3.setColIndex(3); - col3.setColName("TABLE_NAME"); - col3.setColSize(193); - col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col3); - // COLUMN_NAME - ColumnMetaData col4 = new ColumnMetaData(); - col4.setColIndex(4); - col4.setColName("COLUMN_NAME"); - col4.setColSize(65); - col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col4); - // DATA_TYPE - ColumnMetaData col5 = new ColumnMetaData(); - col5.setColIndex(5); - col5.setColName("DATA_TYPE"); - col5.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col5); - // TYPE_NAME - ColumnMetaData col6 = new ColumnMetaData(); - col6.setColIndex(6); - col6.setColName("TYPE_NAME"); - col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col6); - // COLUMN_SIZE - ColumnMetaData col7 = new ColumnMetaData(); - col7.setColIndex(7); - col7.setColName("COLUMN_SIZE"); - col7.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col7); - // BUFFER_LENGTH, not used - ColumnMetaData col8 = new ColumnMetaData(); - col8.setColIndex(8); - col8.setColName("BUFFER_LENGTH"); - columnMetaDataList.add(col8); - // DECIMAL_DIGITS - ColumnMetaData col9 = new ColumnMetaData(); - col9.setColIndex(9); - col9.setColName("DECIMAL_DIGITS"); - col9.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col9); - // add NUM_PREC_RADIX - ColumnMetaData col10 = new ColumnMetaData(); - col10.setColIndex(10); - col10.setColName("NUM_PREC_RADIX"); - col10.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col10); - // NULLABLE - ColumnMetaData col11 = new ColumnMetaData(); - col11.setColIndex(11); - col11.setColName("NULLABLE"); - col11.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col11); - // REMARKS - ColumnMetaData col12 = new ColumnMetaData(); - col12.setColIndex(12); - col12.setColName("REMARKS"); - col12.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col12); - // COLUMN_DEF - ColumnMetaData col13 = new ColumnMetaData(); - col13.setColIndex(13); - col13.setColName("COLUMN_DEF"); - col13.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col13); - //SQL_DATA_TYPE - ColumnMetaData col14 = new ColumnMetaData(); - col14.setColIndex(14); - col14.setColName("SQL_DATA_TYPE"); - col14.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col14); - //SQL_DATETIME_SUB - ColumnMetaData col15 = new ColumnMetaData(); - col15.setColIndex(15); - col15.setColName("SQL_DATETIME_SUB"); - col15.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col15); - //CHAR_OCTET_LENGTH - ColumnMetaData col16 = new ColumnMetaData(); - col16.setColIndex(16); - col16.setColName("CHAR_OCTET_LENGTH"); - col16.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col16); - //ORDINAL_POSITION - ColumnMetaData col17 = new ColumnMetaData(); - col17.setColIndex(17); - col17.setColName("ORDINAL_POSITION"); - col17.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col17); - // IS_NULLABLE - ColumnMetaData col18 = new ColumnMetaData(); - col18.setColIndex(18); - col18.setColName("IS_NULLABLE"); - col18.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col18); - //SCOPE_CATALOG - ColumnMetaData col19 = new ColumnMetaData(); - col19.setColIndex(19); - col19.setColName("SCOPE_CATALOG"); - col19.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col19); - //SCOPE_SCHEMA - ColumnMetaData col20 = new ColumnMetaData(); - col20.setColIndex(20); - col20.setColName("SCOPE_SCHEMA"); - col20.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col20); - //SCOPE_TABLE - ColumnMetaData col21 = new ColumnMetaData(); - col21.setColIndex(21); - col21.setColName("SCOPE_TABLE"); - col21.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col21); - //SOURCE_DATA_TYPE - ColumnMetaData col22 = new ColumnMetaData(); - col22.setColIndex(22); - col22.setColName("SOURCE_DATA_TYPE"); - col22.setColType(TSDBConstants.TSDB_DATA_TYPE_SMALLINT); - columnMetaDataList.add(col22); - //IS_AUTOINCREMENT - ColumnMetaData col23 = new ColumnMetaData(); - col23.setColIndex(23); - col23.setColName("IS_AUTOINCREMENT"); - col23.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col23); - //IS_GENERATEDCOLUMN - ColumnMetaData col24 = new ColumnMetaData(); - col24.setColIndex(24); - col24.setColName("IS_GENERATEDCOLUMN"); - col24.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col24); - - resultSet.setColumnMetaDataList(columnMetaDataList); - // set up rowDataList - ResultSet rs = stmt.executeQuery("describe " + dbname + "." + tableNamePattern); - List rowDataList = new ArrayList<>(); - int index = 0; + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + // set up ColumnMetaDataList + resultSet.setColumnMetaDataList(buildGetColumnsColumnMetaDataList()); + // set up rowDataList + List rowDataList = new ArrayList<>(); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("describe " + catalog + "." + tableNamePattern); + int rowIndex = 0; while (rs.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(24); // set TABLE_CAT - rowData.setString(0, dbname); + rowData.setStringValue(1, catalog); + // set TABLE_SCHEM + rowData.setStringValue(2, null); // set TABLE_NAME - rowData.setString(2, tableNamePattern); + rowData.setStringValue(3, tableNamePattern); // set COLUMN_NAME - rowData.setString(3, rs.getString("Field")); + rowData.setStringValue(4, rs.getString("Field")); // set DATA_TYPE String typeName = rs.getString("Type"); - rowData.setInt(4, getDataType(typeName)); + rowData.setIntValue(5, TSDBConstants.typeName2JdbcType(typeName)); // set TYPE_NAME - rowData.setString(5, typeName); + rowData.setStringValue(6, typeName); // set COLUMN_SIZE int length = rs.getInt("Length"); - rowData.setInt(6, getColumnSize(typeName, length)); + rowData.setIntValue(7, calculateColumnSize(typeName, precision, length)); + // set BUFFER LENGTH + rowData.setStringValue(8, null); // set DECIMAL_DIGITS - rowData.setInt(8, getDecimalDigits(typeName)); + Integer decimalDigits = calculateDecimalDigits(typeName); + if (decimalDigits != null) { + rowData.setIntValue(9, decimalDigits); + } else { + rowData.setStringValue(9, null); + } // set NUM_PREC_RADIX - rowData.setInt(9, 10); + rowData.setIntValue(10, 10); // set NULLABLE - rowData.setInt(10, getNullable(index, typeName)); + rowData.setIntValue(11, isNullable(rowIndex, typeName)); // set REMARKS - rowData.setString(11, rs.getString("Note")); + String note = rs.getString("Note"); + rowData.setStringValue(12, note.trim().isEmpty() ? null : note); rowDataList.add(rowData); - index++; + rowIndex++; } resultSet.setRowDataList(rowDataList); - return resultSet; - } catch (SQLException e) { e.printStackTrace(); } - return null; + return resultSet; } - protected int getNullable(int index, String typeName) { + private int isNullable(int index, String typeName) { if (index == 0 && "TIMESTAMP".equals(typeName)) return DatabaseMetaData.columnNoNulls; return DatabaseMetaData.columnNullable; } - protected int getColumnSize(String typeName, int length) { + private Integer calculateColumnSize(String typeName, String precisionType, int length) { switch (typeName) { case "TIMESTAMP": - return 23; - default: - return 0; - } - } - - protected int getDecimalDigits(String typeName) { - switch (typeName) { + return precisionType.equals("ms") ? TSDBConstants.TIMESTAMP_MS_PRECISION : TSDBConstants.TIMESTAMP_US_PRECISION; + case "BOOL": + return TSDBConstants.BOOLEAN_PRECISION; + case "TINYINT": + return TSDBConstants.TINYINT_PRECISION; + case "SMALLINT": + return TSDBConstants.SMALLINT_PRECISION; + case "INT": + return TSDBConstants.INT_PRECISION; + case "BIGINT": + return TSDBConstants.BIGINT_PRECISION; case "FLOAT": - return 5; + return TSDBConstants.FLOAT_PRECISION; case "DOUBLE": - return 9; + return TSDBConstants.DOUBLE_PRECISION; + case "NCHAR": + case "BINARY": + return length; default: - return 0; + return null; } } - protected int getDataType(String typeName) { + private Integer calculateDecimalDigits(String typeName) { switch (typeName) { - case "TIMESTAMP": - return Types.TIMESTAMP; + case "TINYINT": + case "SMALLINT": case "INT": - return Types.INTEGER; case "BIGINT": - return Types.BIGINT; - case "FLOAT": - return Types.FLOAT; - case "DOUBLE": - return Types.DOUBLE; - case "BINARY": - return Types.BINARY; - case "SMALLINT": - return Types.SMALLINT; - case "TINYINT": - return Types.TINYINT; - case "BOOL": - return Types.BOOLEAN; - case "NCHAR": - return Types.NCHAR; + return 0; default: - return Types.NULL; + return null; } } - public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) - throws SQLException { + private ColumnMetaData buildTableCatalogMeta(int colIndex) { + ColumnMetaData col1 = new ColumnMetaData(); + col1.setColIndex(colIndex); + col1.setColName("TABLE_CAT"); + col1.setColType(Types.NCHAR); + return col1; + } + + private ColumnMetaData buildTableSchemaMeta(int colIndex) { + ColumnMetaData col2 = new ColumnMetaData(); + col2.setColIndex(colIndex); + col2.setColName("TABLE_SCHEM"); + col2.setColType(Types.NCHAR); + return col2; + } + + private ColumnMetaData buildTableNameMeta(int colIndex) { + ColumnMetaData col3 = new ColumnMetaData(); + col3.setColIndex(colIndex); + col3.setColName("TABLE_NAME"); + col3.setColSize(193); + col3.setColType(Types.NCHAR); + return col3; + } + + private ColumnMetaData buildColumnNameMeta(int colIndex) { + ColumnMetaData col4 = new ColumnMetaData(); + col4.setColIndex(colIndex); + col4.setColName("COLUMN_NAME"); + col4.setColSize(65); + col4.setColType(Types.NCHAR); + return col4; + } + + private ColumnMetaData buildDataTypeMeta(int colIndex) { + ColumnMetaData col5 = new ColumnMetaData(); + col5.setColIndex(colIndex); + col5.setColName("DATA_TYPE"); + col5.setColType(Types.INTEGER); + return col5; + } + + private ColumnMetaData buildColumnSizeMeta() { + ColumnMetaData col7 = new ColumnMetaData(); + col7.setColIndex(7); + col7.setColName("COLUMN_SIZE"); + col7.setColType(Types.INTEGER); + return col7; + } + + private ColumnMetaData buildBufferLengthMeta() { + ColumnMetaData col8 = new ColumnMetaData(); + col8.setColIndex(8); + col8.setColName("BUFFER_LENGTH"); + return col8; + } + + private ColumnMetaData buildDecimalDigitsMeta() { + ColumnMetaData col9 = new ColumnMetaData(); + col9.setColIndex(9); + col9.setColName("DECIMAL_DIGITS"); + col9.setColType(Types.INTEGER); + return col9; + } + + private ColumnMetaData buildNumPrecRadixMeta() { + ColumnMetaData col10 = new ColumnMetaData(); + col10.setColIndex(10); + col10.setColName("NUM_PREC_RADIX"); + col10.setColType(Types.INTEGER); + return col10; + } + + private ColumnMetaData buildNullableMeta() { + ColumnMetaData col11 = new ColumnMetaData(); + col11.setColIndex(11); + col11.setColName("NULLABLE"); + col11.setColType(Types.INTEGER); + return col11; + } + + private ColumnMetaData buildRemarksMeta(int colIndex) { + ColumnMetaData col12 = new ColumnMetaData(); + col12.setColIndex(colIndex); + col12.setColName("REMARKS"); + col12.setColType(Types.NCHAR); + return col12; + } + + private ColumnMetaData buildColumnDefMeta() { + ColumnMetaData col13 = new ColumnMetaData(); + col13.setColIndex(13); + col13.setColName("COLUMN_DEF"); + col13.setColType(Types.NCHAR); + return col13; + } + + private ColumnMetaData buildSqlDataTypeMeta() { + ColumnMetaData col14 = new ColumnMetaData(); + col14.setColIndex(14); + col14.setColName("SQL_DATA_TYPE"); + col14.setColType(Types.INTEGER); + return col14; + } + + private ColumnMetaData buildSqlDatetimeSubMeta() { + ColumnMetaData col15 = new ColumnMetaData(); + col15.setColIndex(15); + col15.setColName("SQL_DATETIME_SUB"); + col15.setColType(Types.INTEGER); + return col15; + } + + private ColumnMetaData buildCharOctetLengthMeta() { + ColumnMetaData col16 = new ColumnMetaData(); + col16.setColIndex(16); + col16.setColName("CHAR_OCTET_LENGTH"); + col16.setColType(Types.INTEGER); + return col16; + } + + private ColumnMetaData buildOrdinalPositionMeta() { + ColumnMetaData col17 = new ColumnMetaData(); + col17.setColIndex(17); + col17.setColName("ORDINAL_POSITION"); + col17.setColType(Types.INTEGER); + return col17; + } + + private ColumnMetaData buildIsNullableMeta() { + ColumnMetaData col18 = new ColumnMetaData(); + col18.setColIndex(18); + col18.setColName("IS_NULLABLE"); + col18.setColType(Types.NCHAR); + return col18; + } + + private ColumnMetaData buildScopeCatalogMeta() { + ColumnMetaData col19 = new ColumnMetaData(); + col19.setColIndex(19); + col19.setColName("SCOPE_CATALOG"); + col19.setColType(Types.NCHAR); + return col19; + } + + private ColumnMetaData buildScopeSchemaMeta() { + ColumnMetaData col20 = new ColumnMetaData(); + col20.setColIndex(20); + col20.setColName("SCOPE_SCHEMA"); + col20.setColType(Types.NCHAR); + return col20; + } + + private ColumnMetaData buildScopeTableMeta() { + ColumnMetaData col21 = new ColumnMetaData(); + col21.setColIndex(21); + col21.setColName("SCOPE_TABLE"); + col21.setColType(Types.NCHAR); + return col21; + } + + private ColumnMetaData buildSourceDataTypeMeta() { + ColumnMetaData col22 = new ColumnMetaData(); + col22.setColIndex(22); + col22.setColName("SOURCE_DATA_TYPE"); + col22.setColType(TSDBConstants.TSDB_DATA_TYPE_SMALLINT); + return col22; + } + + private ColumnMetaData buildIsAutoIncrementMeta() { + ColumnMetaData col23 = new ColumnMetaData(); + col23.setColIndex(23); + col23.setColName("IS_AUTOINCREMENT"); + col23.setColType(Types.NCHAR); + return col23; + } + + private ColumnMetaData buildIsGeneratedColumnMeta() { + ColumnMetaData col24 = new ColumnMetaData(); + col24.setColIndex(24); + col24.setColName("IS_GENERATEDCOLUMN"); + col24.setColType(Types.NCHAR); + return col24; + } + + private List buildGetColumnsColumnMetaDataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); //1. TABLE_CAT + columnMetaDataList.add(buildTableSchemaMeta(2)); //2. TABLE_SCHEMA + columnMetaDataList.add(buildTableNameMeta(3)); //3. TABLE_NAME + columnMetaDataList.add(buildColumnNameMeta(4)); //4. COLUMN_NAME + columnMetaDataList.add(buildDataTypeMeta(5)); //5. DATA_TYPE + columnMetaDataList.add(buildTypeNameMeta(6)); //6. TYPE_NAME + columnMetaDataList.add(buildColumnSizeMeta()); //7. COLUMN_SIZE + columnMetaDataList.add(buildBufferLengthMeta()); //8. BUFFER_LENGTH, not used + columnMetaDataList.add(buildDecimalDigitsMeta()); //9. DECIMAL_DIGITS + columnMetaDataList.add(buildNumPrecRadixMeta()); //10. NUM_PREC_RADIX + columnMetaDataList.add(buildNullableMeta()); //11. NULLABLE + columnMetaDataList.add(buildRemarksMeta(12)); //12. REMARKS + columnMetaDataList.add(buildColumnDefMeta()); //13. COLUMN_DEF + columnMetaDataList.add(buildSqlDataTypeMeta()); //14. SQL_DATA_TYPE + columnMetaDataList.add(buildSqlDatetimeSubMeta()); //15. SQL_DATETIME_SUB + columnMetaDataList.add(buildCharOctetLengthMeta()); //16. CHAR_OCTET_LENGTH + columnMetaDataList.add(buildOrdinalPositionMeta()); //17. ORDINAL_POSITION + columnMetaDataList.add(buildIsNullableMeta()); //18. IS_NULLABLE + columnMetaDataList.add(buildScopeCatalogMeta()); //19. SCOPE_CATALOG + columnMetaDataList.add(buildScopeSchemaMeta()); //20. SCOPE_SCHEMA + columnMetaDataList.add(buildScopeTableMeta()); //21. SCOPE_TABLE + columnMetaDataList.add(buildSourceDataTypeMeta()); //22. SOURCE_DATA_TYPE + columnMetaDataList.add(buildIsAutoIncrementMeta()); //23. IS_AUTOINCREMENT + columnMetaDataList.add(buildIsGeneratedColumnMeta()); //24. IS_GENERATEDCOLUMN + return columnMetaDataList; + } + + public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern) throws SQLException { return getEmptyResultSet(); } - public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) - throws SQLException { + public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) throws SQLException { return getEmptyResultSet(); } - public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) - throws SQLException { + public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable) throws SQLException { return getEmptyResultSet(); } @@ -914,8 +970,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da return getEmptyResultSet(); } - public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, - String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { + public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable, String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException { return getEmptyResultSet(); } @@ -923,8 +978,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da return getEmptyResultSet(); } - public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) - throws SQLException { + public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate) throws SQLException { return getEmptyResultSet(); } @@ -976,8 +1030,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da return false; } - public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) - throws SQLException { + public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types) throws SQLException { return getEmptyResultSet(); } @@ -1005,8 +1058,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da public abstract ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException; - public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, - String attributeNamePattern) throws SQLException { + public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern, String attributeNamePattern) throws SQLException { return getEmptyResultSet(); } @@ -1069,18 +1121,15 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da return getEmptyResultSet(); } - public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) - throws SQLException { + public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) throws SQLException { return getEmptyResultSet(); } - public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, - String columnNamePattern) throws SQLException { + public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern, String columnNamePattern) throws SQLException { return getEmptyResultSet(); } - public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, - String columnNamePattern) throws SQLException { + public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException { return getEmptyResultSet(); } @@ -1093,164 +1142,141 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da } protected ResultSet getCatalogs(Connection conn) throws SQLException { - try (Statement stmt = conn.createStatement()) { - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); - // set up ColumnMetaDataList - List columnMetaDataList = new ArrayList<>(); - // TABLE_CAT - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(1); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - - resultSet.setColumnMetaDataList(columnMetaDataList); + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + // set up ColumnMetaDataList + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT + resultSet.setColumnMetaDataList(columnMetaDataList); + try (Statement stmt = conn.createStatement()) { List rowDataList = new ArrayList<>(); ResultSet rs = stmt.executeQuery("show databases"); while (rs.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(1); - rowData.setString(0, rs.getString("name")); + rowData.setStringValue(1, rs.getString("name")); rowDataList.add(rowData); } resultSet.setRowDataList(rowDataList); - return resultSet; } + return resultSet; } protected ResultSet getPrimaryKeys(String catalog, String schema, String table, Connection conn) throws SQLException { - try (Statement stmt = conn.createStatement()) { - if (catalog == null || catalog.isEmpty()) - return null; + if (catalog == null || catalog.isEmpty()) + return null; + if (!isAvailableCatalog(conn, catalog)) + return new EmptyResultSet(); - ResultSet databases = stmt.executeQuery("show databases"); - String dbname = null; - while (databases.next()) { - dbname = databases.getString("name"); - if (dbname.equalsIgnoreCase(catalog)) - break; - } - databases.close(); - if (dbname == null) - return null; - - stmt.execute("use " + dbname); - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + try (Statement stmt = conn.createStatement()) { // set up ColumnMetaDataList - List columnMetaDataList = new ArrayList<>(); - // TABLE_CAT - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(0); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - // TABLE_SCHEM - ColumnMetaData col2 = new ColumnMetaData(); - col2.setColIndex(1); - col2.setColName("TABLE_SCHEM"); - col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col2); - // TABLE_NAME - ColumnMetaData col3 = new ColumnMetaData(); - col3.setColIndex(2); - col3.setColName("TABLE_NAME"); - col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col3); - // COLUMN_NAME - ColumnMetaData col4 = new ColumnMetaData(); - col4.setColIndex(3); - col4.setColName("COLUMN_NAME"); - col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col4); - // KEY_SEQ - ColumnMetaData col5 = new ColumnMetaData(); - col5.setColIndex(4); - col5.setColName("KEY_SEQ"); - col5.setColType(TSDBConstants.TSDB_DATA_TYPE_INT); - columnMetaDataList.add(col5); - // PK_NAME - ColumnMetaData col6 = new ColumnMetaData(); - col6.setColIndex(5); - col6.setColName("PK_NAME"); - col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col6); - resultSet.setColumnMetaDataList(columnMetaDataList); - + resultSet.setColumnMetaDataList(buildGetPrimaryKeysMetadataList()); // set rowData List rowDataList = new ArrayList<>(); - ResultSet rs = stmt.executeQuery("describe " + dbname + "." + table); + ResultSet rs = stmt.executeQuery("describe " + catalog + "." + table); rs.next(); TSDBResultSetRowData rowData = new TSDBResultSetRowData(6); - rowData.setString(0, null); - rowData.setString(1, null); - rowData.setString(2, table); - String pkName = rs.getString(1); - rowData.setString(3, pkName); - rowData.setInt(4, 1); - rowData.setString(5, pkName); + rowData.setStringValue(1, catalog); + rowData.setStringValue(2, null); + rowData.setStringValue(3, table); + String primaryKey = rs.getString("Field"); + rowData.setStringValue(4, primaryKey); + rowData.setShortValue(5, (short) 1); + rowData.setStringValue(6, primaryKey); rowDataList.add(rowData); resultSet.setRowDataList(rowDataList); - return resultSet; } + return resultSet; } - protected ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern, Connection conn) throws SQLException { - try (Statement stmt = conn.createStatement()) { - if (catalog == null || catalog.isEmpty()) - return null; + private List buildGetPrimaryKeysMetadataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT + columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM + columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME + columnMetaDataList.add(buildColumnNameMeta(4)); // 4. COLUMN_NAME + columnMetaDataList.add(buildKeySeqMeta(5)); // 5. KEY_SEQ + columnMetaDataList.add(buildPrimaryKeyNameMeta(6)); // 6. PK_NAME + return columnMetaDataList; + } + + private ColumnMetaData buildKeySeqMeta(int colIndex) { + ColumnMetaData col5 = new ColumnMetaData(); + col5.setColIndex(colIndex); + col5.setColName("KEY_SEQ"); + col5.setColType(Types.SMALLINT); + return col5; + } + + private ColumnMetaData buildPrimaryKeyNameMeta(int colIndex) { + ColumnMetaData col6 = new ColumnMetaData(); + col6.setColIndex(colIndex); + col6.setColName("PK_NAME"); + col6.setColType(Types.NCHAR); + return col6; + } + private boolean isAvailableCatalog(Connection connection, String catalog) { + try (Statement stmt = connection.createStatement()) { ResultSet databases = stmt.executeQuery("show databases"); - String dbname = null; while (databases.next()) { - dbname = databases.getString("name"); + String dbname = databases.getString("name"); + this.precision = databases.getString("precision"); if (dbname.equalsIgnoreCase(catalog)) - break; + return true; } databases.close(); - if (dbname == null) - return null; + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } - stmt.execute("use " + dbname); - DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); - // set up ColumnMetaDataList - List columnMetaDataList = new ArrayList<>(); - // TABLE_CAT - ColumnMetaData col1 = new ColumnMetaData(); - col1.setColIndex(0); - col1.setColName("TABLE_CAT"); - col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col1); - // TABLE_SCHEM - ColumnMetaData col2 = new ColumnMetaData(); - col2.setColIndex(1); - col2.setColName("TABLE_SCHEM"); - col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col2); - // TABLE_NAME - ColumnMetaData col3 = new ColumnMetaData(); - col3.setColIndex(2); - col3.setColName("TABLE_NAME"); - col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col3); - // SUPERTABLE_NAME - ColumnMetaData col4 = new ColumnMetaData(); - col4.setColIndex(3); - col4.setColName("SUPERTABLE_NAME"); - col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR); - columnMetaDataList.add(col4); - resultSet.setColumnMetaDataList(columnMetaDataList); + protected ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern, Connection conn) throws SQLException { + if (catalog == null || catalog.isEmpty()) + return null; + + if (!isAvailableCatalog(conn, catalog)) { + return new EmptyResultSet(); + } + DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet(); + try (Statement stmt = conn.createStatement()) { + // set up ColumnMetaDataList + resultSet.setColumnMetaDataList(buildGetSuperTablesColumnMetaDataList()); + // set result set row data + stmt.execute("use " + catalog); ResultSet rs = stmt.executeQuery("show tables like '" + tableNamePattern + "'"); List rowDataList = new ArrayList<>(); while (rs.next()) { TSDBResultSetRowData rowData = new TSDBResultSetRowData(4); - rowData.setString(2, rs.getString(1)); - rowData.setString(3, rs.getString(4)); + rowData.setStringValue(1, catalog); + rowData.setStringValue(2, null); + rowData.setStringValue(3, rs.getString("table_name")); + rowData.setStringValue(4, rs.getString("stable_name")); rowDataList.add(rowData); } resultSet.setRowDataList(rowDataList); - return resultSet; } + return resultSet; + } + + private List buildGetSuperTablesColumnMetaDataList() { + List columnMetaDataList = new ArrayList<>(); + columnMetaDataList.add(buildTableCatalogMeta(1)); // 1. TABLE_CAT + columnMetaDataList.add(buildTableSchemaMeta(2)); // 2. TABLE_SCHEM + columnMetaDataList.add(buildTableNameMeta(3)); // 3. TABLE_NAME + columnMetaDataList.add(buildSuperTableNameMeta(4)); // 4. SUPERTABLE_NAME + return columnMetaDataList; } + + private ColumnMetaData buildSuperTableNameMeta(int colIndex) { + ColumnMetaData col4 = new ColumnMetaData(); + col4.setColIndex(colIndex); + col4.setColName("SUPERTABLE_NAME"); + col4.setColType(Types.NCHAR); + return col4; + } + } \ No newline at end of file diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java index 5eaac1cd3ba7283b019a1d294c1a33334a3d9fa7..7d4a2683918d917c795fc4d23af3369560e3ef52 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java @@ -58,7 +58,7 @@ public abstract class AbstractDriver implements Driver { value = parameterValuePair.substring(indexOfEqual + 1); } } - if ((value != null && value.length() > 0) && (parameter != null && parameter.length() > 0)) { + if (value != null && value.length() > 0 && parameter.length() > 0) { urlProps.setProperty(parameter, value); } } @@ -87,7 +87,7 @@ public abstract class AbstractDriver implements Driver { url = url.substring(0, indexOfColon); } // parse host - if (url != null && url.length() > 0 && url.trim().length() > 0) { + if (url.length() > 0 && url.trim().length() > 0) { urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url); } return urlProps; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java index 7df7252ae2010b5aa5e8f74de2cca55844e25b83..7d9d8ee5154bf3e63c024d0ded1defd2d2bdb4b0 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java @@ -49,6 +49,22 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P if (param < 1 && param >= parameters.length) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); + if (parameters[param - 1] instanceof Boolean) + return TSDBConstants.BOOLEAN_PRECISION; + if (parameters[param - 1] instanceof Byte) + return TSDBConstants.TINYINT_PRECISION; + if (parameters[param - 1] instanceof Short) + return TSDBConstants.SMALLINT_PRECISION; + if (parameters[param - 1] instanceof Integer) + return TSDBConstants.INT_PRECISION; + if (parameters[param - 1] instanceof Long) + return TSDBConstants.BIGINT_PRECISION; + if (parameters[param - 1] instanceof Timestamp) + return TSDBConstants.TIMESTAMP_MS_PRECISION; + if (parameters[param - 1] instanceof Float) + return TSDBConstants.FLOAT_PRECISION; + if (parameters[param - 1] instanceof Double) + return TSDBConstants.DOUBLE_PRECISION; if (parameters[param - 1] instanceof String) return ((String) parameters[param - 1]).length(); if (parameters[param - 1] instanceof byte[]) @@ -60,6 +76,11 @@ public abstract class AbstractParameterMetaData extends WrapperImpl implements P public int getScale(int param) throws SQLException { if (param < 1 && param >= parameters.length) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); + + if (parameters[param - 1] instanceof Float) + return TSDBConstants.FLOAT_SCALE; + if (parameters[param - 1] instanceof Double) + return TSDBConstants.DOUBLE_SCALE; return 0; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java index f8ea9af4230e9584197f1141dc5a4f7c1621b3ff..e17548055c792e900a1e2fb5b510de8bf65de7a7 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java @@ -66,10 +66,16 @@ public abstract class AbstractResultSet extends WrapperImpl implements ResultSet public abstract byte[] getBytes(int columnIndex) throws SQLException; @Override - public abstract Date getDate(int columnIndex) throws SQLException; + public Date getDate(int columnIndex) throws SQLException { + Timestamp timestamp = getTimestamp(columnIndex); + return timestamp == null ? null : new Date(timestamp.getTime()); + } @Override - public abstract Time getTime(int columnIndex) throws SQLException; + public Time getTime(int columnIndex) throws SQLException { + Timestamp timestamp = getTimestamp(columnIndex); + return timestamp == null ? null : new Time(timestamp.getTime()); + } @Override public abstract Timestamp getTimestamp(int columnIndex) throws SQLException; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java index 9dc559339a4ef88b8423ffcd621c7498437dac5c..8b6c074d1b859f179aac04a83cafb24cfae7c190 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java @@ -9,8 +9,6 @@ public abstract class AbstractStatement extends WrapperImpl implements Statement protected List batchedArgs; private int fetchSize; - - @Override public abstract ResultSet executeQuery(String sql) throws SQLException; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java index f6a0fcca316cb07d28c71a4e1d51d9405de083ba..bda3d522123d09ece81384c6eba814c7e548e1ec 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java @@ -14,76 +14,44 @@ *****************************************************************************/ package com.taosdata.jdbc; -import java.io.InputStream; -import java.io.Reader; import java.math.BigDecimal; -import java.net.URL; -import java.sql.Date; -import java.sql.*; -import java.util.*; +import java.sql.ResultSetMetaData; +import java.sql.SQLException; +import java.sql.Statement; +import java.sql.Timestamp; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; /* - * TDengine only supports a subset of the standard SQL, thus this implemetation of the + * TDengine only supports a subset of the standard SQL, thus this implementation of the * standard JDBC API contains more or less some adjustments customized for certain * compatibility needs. */ -public class DatabaseMetaDataResultSet implements ResultSet { +public class DatabaseMetaDataResultSet extends AbstractResultSet { - private List columnMetaDataList; - private List rowDataList; + private List columnMetaDataList = new ArrayList<>(); + private List rowDataList = new ArrayList<>(); private TSDBResultSetRowData rowCursor; // position of cursor, starts from 0 as beforeFirst, increases as next() is called private int cursorRowNumber = 0; - public DatabaseMetaDataResultSet() { - rowDataList = new ArrayList(); - columnMetaDataList = new ArrayList(); - } - - public List getRowDataList() { - return rowDataList; - } - public void setRowDataList(List rowDataList) { this.rowDataList = rowDataList; } - public List getColumnMetaDataList() { - return columnMetaDataList; - } - public void setColumnMetaDataList(List columnMetaDataList) { this.columnMetaDataList = columnMetaDataList; } - public TSDBResultSetRowData getRowCursor() { - return rowCursor; - } - - public void setRowCursor(TSDBResultSetRowData rowCursor) { - this.rowCursor = rowCursor; - } - @Override public boolean next() throws SQLException { -// boolean ret = false; -// if (rowDataList.size() > 0) { -// ret = rowDataList.iterator().hasNext(); -// if (ret) { -// rowCursor = rowDataList.iterator().next(); -// cursorRowNumber++; -// } -// } -// return ret; - - /**** add by zyyang 2020-09-29 ****************/ boolean ret = false; if (!rowDataList.isEmpty() && cursorRowNumber < rowDataList.size()) { rowCursor = rowDataList.get(cursorRowNumber++); ret = true; } - return ret; } @@ -99,189 +67,72 @@ public class DatabaseMetaDataResultSet implements ResultSet { @Override public String getString(int columnIndex) throws SQLException { - columnIndex--; - int colType = columnMetaDataList.get(columnIndex).getColType(); - return rowCursor.getString(columnIndex, colType); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getString(columnIndex, nativeType); } @Override public boolean getBoolean(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getBoolean(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getBoolean(columnIndex, nativeType); } @Override public byte getByte(int columnIndex) throws SQLException { - columnIndex--; - return (byte) rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return (byte) rowCursor.getInt(columnIndex, nativeType); } @Override public short getShort(int columnIndex) throws SQLException { - columnIndex--; - return (short) rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return (short) rowCursor.getInt(columnIndex, nativeType); } @Override public int getInt(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getInt(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getInt(columnIndex, nativeType); } @Override public long getLong(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getLong(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getLong(columnIndex, nativeType); } @Override public float getFloat(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getFloat(columnIndex, columnMetaDataList.get(columnIndex).getColType()); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getFloat(columnIndex, nativeType); } @Override public double getDouble(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType()); - } - - @Override - public BigDecimal getBigDecimal(int columnIndex, int scale) throws SQLException { - columnIndex--; - return new BigDecimal(rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType())); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getDouble(columnIndex, nativeType); } @Override public byte[] getBytes(int columnIndex) throws SQLException { - columnIndex--; - return (rowCursor.getString(columnIndex, columnMetaDataList.get(columnIndex).getColType())).getBytes(); - } - - @Override - public Date getDate(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Time getTime(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return (rowCursor.getString(columnIndex, nativeType)).getBytes(); } @Override public Timestamp getTimestamp(int columnIndex) throws SQLException { - columnIndex--; - return rowCursor.getTimestamp(columnIndex); - } - - @Override - public InputStream getAsciiStream(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public InputStream getUnicodeStream(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public InputStream getBinaryStream(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public String getString(String columnLabel) throws SQLException { - return getString(findColumn(columnLabel)); - } - - @Override - public boolean getBoolean(String columnLabel) throws SQLException { - return getBoolean(findColumn(columnLabel)); - } - - @Override - public byte getByte(String columnLabel) throws SQLException { - return getByte(findColumn(columnLabel)); - } - - @Override - public short getShort(String columnLabel) throws SQLException { - return getShort(findColumn(columnLabel)); - } - - @Override - public int getInt(String columnLabel) throws SQLException { - return getInt(findColumn(columnLabel)); - } - - @Override - public long getLong(String columnLabel) throws SQLException { - return getLong(findColumn(columnLabel)); - } - - @Override - public float getFloat(String columnLabel) throws SQLException { - return getFloat(findColumn(columnLabel)); - } - - @Override - public double getDouble(String columnLabel) throws SQLException { - return getDouble(findColumn(columnLabel)); - } - - @Override - public BigDecimal getBigDecimal(String columnLabel, int scale) throws SQLException { - return getBigDecimal(findColumn(columnLabel)); - } - - @Override - public byte[] getBytes(String columnLabel) throws SQLException { - return getBytes(findColumn(columnLabel)); - } - - @Override - public Date getDate(String columnLabel) throws SQLException { - return getDate(findColumn(columnLabel)); - } - - @Override - public Time getTime(String columnLabel) throws SQLException { - return getTime(findColumn(columnLabel)); - } - - @Override - public Timestamp getTimestamp(String columnLabel) throws SQLException { - return getTimestamp(findColumn(columnLabel)); - } - - @Override - public InputStream getAsciiStream(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public InputStream getUnicodeStream(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public InputStream getBinaryStream(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public SQLWarning getWarnings() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void clearWarnings() throws SQLException { - - } - - @Override - public String getCursorName() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + return rowCursor.getTimestamp(columnIndex, nativeType); } @Override @@ -291,44 +142,25 @@ public class DatabaseMetaDataResultSet implements ResultSet { @Override public Object getObject(int columnIndex) throws SQLException { - return rowCursor.get(columnIndex); - } - - @Override - public Object getObject(String columnLabel) throws SQLException { - return rowCursor.get(findColumn(columnLabel)); + return rowCursor.getObject(columnIndex); } @Override public int findColumn(String columnLabel) throws SQLException { - Iterator colMetaDataIt = this.columnMetaDataList.iterator(); - while (colMetaDataIt.hasNext()) { - ColumnMetaData colMetaData = colMetaDataIt.next(); - if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) { - return colMetaData.getColIndex() + 1; + for (ColumnMetaData colMetaData : this.columnMetaDataList) { + if (colMetaData.getColName() != null && colMetaData.getColName().equals(columnLabel)) { + return colMetaData.getColIndex(); } } throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); } - @Override - public Reader getCharacterStream(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Reader getCharacterStream(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - @Override public BigDecimal getBigDecimal(int columnIndex) throws SQLException { - return new BigDecimal(rowCursor.getDouble(columnIndex, columnMetaDataList.get(columnIndex).getColType())); - } - - @Override - public BigDecimal getBigDecimal(String columnLabel) throws SQLException { - return getBigDecimal(findColumn(columnLabel)); + int colType = columnMetaDataList.get(columnIndex - 1).getColType(); + int nativeType = TSDBConstants.jdbcType2TaosType(colType); + double value = rowCursor.getDouble(columnIndex, nativeType); + return new BigDecimal(value); } @Override @@ -378,7 +210,6 @@ public class DatabaseMetaDataResultSet implements ResultSet { } else { return 0; } - } @Override @@ -397,680 +228,23 @@ public class DatabaseMetaDataResultSet implements ResultSet { } @Override - public void setFetchDirection(int direction) throws SQLException { - - } - - @Override - public int getFetchDirection() throws SQLException { - return ResultSet.FETCH_FORWARD; - } - - @Override - public void setFetchSize(int rows) throws SQLException { - - } - - @Override - public int getFetchSize() throws SQLException { - return 0; - } - - @Override - public int getType() throws SQLException { - return ResultSet.TYPE_FORWARD_ONLY; - } - - @Override - public int getConcurrency() throws SQLException { - return ResultSet.CONCUR_READ_ONLY; - } - - @Override - public boolean rowUpdated() throws SQLException { - return false; + public Statement getStatement() throws SQLException { + return null; } - @Override - public boolean rowInserted() throws SQLException { - return false; + public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { + //TODO: calendar is not used + return getTimestamp(columnIndex); } @Override - public boolean rowDeleted() throws SQLException { + public boolean isClosed() throws SQLException { return false; } @Override - public void updateNull(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBoolean(int columnIndex, boolean x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateByte(int columnIndex, byte x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateShort(int columnIndex, short x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateInt(int columnIndex, int x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateLong(int columnIndex, long x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateFloat(int columnIndex, float x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateDouble(int columnIndex, double x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBigDecimal(int columnIndex, BigDecimal x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateString(int columnIndex, String x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBytes(int columnIndex, byte[] x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateDate(int columnIndex, Date x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateTime(int columnIndex, Time x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateTimestamp(int columnIndex, Timestamp x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateAsciiStream(int columnIndex, InputStream x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBinaryStream(int columnIndex, InputStream x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateCharacterStream(int columnIndex, Reader x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateObject(int columnIndex, Object x, int scaleOrLength) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateObject(int columnIndex, Object x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateNull(String columnLabel) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBoolean(String columnLabel, boolean x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateByte(String columnLabel, byte x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateShort(String columnLabel, short x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateInt(String columnLabel, int x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateLong(String columnLabel, long x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateFloat(String columnLabel, float x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateDouble(String columnLabel, double x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBigDecimal(String columnLabel, BigDecimal x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateString(String columnLabel, String x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + public String getNString(int columnIndex) throws SQLException { + return getString(columnIndex); } - @Override - public void updateBytes(String columnLabel, byte[] x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateDate(String columnLabel, Date x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateTime(String columnLabel, Time x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateTimestamp(String columnLabel, Timestamp x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateAsciiStream(String columnLabel, InputStream x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateBinaryStream(String columnLabel, InputStream x, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateCharacterStream(String columnLabel, Reader reader, int length) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateObject(String columnLabel, Object x, int scaleOrLength) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateObject(String columnLabel, Object x) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void insertRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void updateRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void deleteRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void refreshRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void cancelRowUpdates() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void moveToInsertRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public void moveToCurrentRow() throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Statement getStatement() throws SQLException { - return null; - } - - @Override - public Object getObject(int columnIndex, Map> map) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Ref getRef(int columnIndex) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public Blob getBlob(int columnIndex) throws SQLException { - return null; - } - - @Override - public Clob getClob(int columnIndex) throws SQLException { - return null; - } - - @Override - public Array getArray(int columnIndex) throws SQLException { - return null; - } - - @Override - public Object getObject(String columnLabel, Map> map) throws SQLException { - return null; - } - - @Override - public Ref getRef(String columnLabel) throws SQLException { - return null; - } - - @Override - public Blob getBlob(String columnLabel) throws SQLException { - return null; - } - - @Override - public Clob getClob(String columnLabel) throws SQLException { - return null; - } - - @Override - public Array getArray(String columnLabel) throws SQLException { - return null; - } - - @Override - public Date getDate(int columnIndex, Calendar cal) throws SQLException { - return null; - } - - @Override - public Date getDate(String columnLabel, Calendar cal) throws SQLException { - return null; - } - - @Override - public Time getTime(int columnIndex, Calendar cal) throws SQLException { - return null; - } - - @Override - public Time getTime(String columnLabel, Calendar cal) throws SQLException { - return null; - } - - @Override - public Timestamp getTimestamp(int columnIndex, Calendar cal) throws SQLException { - return null; - } - - @Override - public Timestamp getTimestamp(String columnLabel, Calendar cal) throws SQLException { - return null; - } - - @Override - public URL getURL(int columnIndex) throws SQLException { - return null; - } - - @Override - public URL getURL(String columnLabel) throws SQLException { - return null; - } - - @Override - public void updateRef(int columnIndex, Ref x) throws SQLException { - - } - - @Override - public void updateRef(String columnLabel, Ref x) throws SQLException { - - } - - @Override - public void updateBlob(int columnIndex, Blob x) throws SQLException { - - } - - @Override - public void updateBlob(String columnLabel, Blob x) throws SQLException { - - } - - @Override - public void updateClob(int columnIndex, Clob x) throws SQLException { - - } - - @Override - public void updateClob(String columnLabel, Clob x) throws SQLException { - - } - - @Override - public void updateArray(int columnIndex, Array x) throws SQLException { - - } - - @Override - public void updateArray(String columnLabel, Array x) throws SQLException { - - } - - @Override - public RowId getRowId(int columnIndex) throws SQLException { - return null; - } - - @Override - public RowId getRowId(String columnLabel) throws SQLException { - return null; - } - - @Override - public void updateRowId(int columnIndex, RowId x) throws SQLException { - - } - - @Override - public void updateRowId(String columnLabel, RowId x) throws SQLException { - - } - - @Override - public int getHoldability() throws SQLException { - return 0; - } - - @Override - public boolean isClosed() throws SQLException { - return false; - } - - @Override - public void updateNString(int columnIndex, String nString) throws SQLException { - - } - - @Override - public void updateNString(String columnLabel, String nString) throws SQLException { - - } - - @Override - public void updateNClob(int columnIndex, NClob nClob) throws SQLException { - - } - - @Override - public void updateNClob(String columnLabel, NClob nClob) throws SQLException { - - } - - @Override - public NClob getNClob(int columnIndex) throws SQLException { - return null; - } - - @Override - public NClob getNClob(String columnLabel) throws SQLException { - return null; - } - - @Override - public SQLXML getSQLXML(int columnIndex) throws SQLException { - return null; - } - - @Override - public SQLXML getSQLXML(String columnLabel) throws SQLException { - return null; - } - - @Override - public void updateSQLXML(int columnIndex, SQLXML xmlObject) throws SQLException { - - } - - @Override - public void updateSQLXML(String columnLabel, SQLXML xmlObject) throws SQLException { - - } - - @Override - public String getNString(int columnIndex) throws SQLException { - return null; - } - - @Override - public String getNString(String columnLabel) throws SQLException { - return null; - } - - @Override - public Reader getNCharacterStream(int columnIndex) throws SQLException { - return null; - } - - @Override - public Reader getNCharacterStream(String columnLabel) throws SQLException { - return null; - } - - @Override - public void updateNCharacterStream(int columnIndex, Reader x, long length) throws SQLException { - - } - - @Override - public void updateNCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateAsciiStream(int columnIndex, InputStream x, long length) throws SQLException { - - } - - @Override - public void updateBinaryStream(int columnIndex, InputStream x, long length) throws SQLException { - - } - - @Override - public void updateCharacterStream(int columnIndex, Reader x, long length) throws SQLException { - - } - - @Override - public void updateAsciiStream(String columnLabel, InputStream x, long length) throws SQLException { - - } - - @Override - public void updateBinaryStream(String columnLabel, InputStream x, long length) throws SQLException { - - } - - @Override - public void updateCharacterStream(String columnLabel, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateBlob(int columnIndex, InputStream inputStream, long length) throws SQLException { - - } - - @Override - public void updateBlob(String columnLabel, InputStream inputStream, long length) throws SQLException { - - } - - @Override - public void updateClob(int columnIndex, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateClob(String columnLabel, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateNClob(int columnIndex, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateNClob(String columnLabel, Reader reader, long length) throws SQLException { - - } - - @Override - public void updateNCharacterStream(int columnIndex, Reader x) throws SQLException { - - } - - @Override - public void updateNCharacterStream(String columnLabel, Reader reader) throws SQLException { - - } - - @Override - public void updateAsciiStream(int columnIndex, InputStream x) throws SQLException { - - } - - @Override - public void updateBinaryStream(int columnIndex, InputStream x) throws SQLException { - - } - - @Override - public void updateCharacterStream(int columnIndex, Reader x) throws SQLException { - - } - - @Override - public void updateAsciiStream(String columnLabel, InputStream x) throws SQLException { - - } - - @Override - public void updateBinaryStream(String columnLabel, InputStream x) throws SQLException { - - } - - @Override - public void updateCharacterStream(String columnLabel, Reader reader) throws SQLException { - - } - - @Override - public void updateBlob(int columnIndex, InputStream inputStream) throws SQLException { - - } - - @Override - public void updateBlob(String columnLabel, InputStream inputStream) throws SQLException { - - } - - @Override - public void updateClob(int columnIndex, Reader reader) throws SQLException { - - } - - @Override - public void updateClob(String columnLabel, Reader reader) throws SQLException { - - } - - @Override - public void updateNClob(int columnIndex, Reader reader) throws SQLException { - - } - - @Override - public void updateNClob(String columnLabel, Reader reader) throws SQLException { - - } - - @Override - public T getObject(int columnIndex, Class type) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public T getObject(String columnLabel, Class type) throws SQLException { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); - } - - @Override - public T unwrap(Class iface) throws SQLException { - return null; - } - - @Override - public boolean isWrapperFor(Class iface) throws SQLException { - return false; - } - - private int getTrueColumnIndex(int columnIndex) throws SQLException { - if (columnIndex < 1) { - throw new SQLException("Column Index out of range, " + columnIndex + " < " + 1); - } - - int numOfCols = this.columnMetaDataList.size(); - if (columnIndex > numOfCols) { - throw new SQLException("Column Index out of range, " + columnIndex + " > " + numOfCols); - } - - return columnIndex - 1; - } } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/EmptyResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/EmptyResultSet.java index b6587b942de3c46139fa0640c07098cbc2b025d4..64b4276e93497f9aab8117df83de90ba28e74b78 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/EmptyResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/EmptyResultSet.java @@ -23,7 +23,7 @@ import java.util.Calendar; import java.util.Map; /* - * TDengine only supports a subset of the standard SQL, thus this implemetation of the + * TDengine only supports a subset of the standard SQL, thus this implementation of the * standard JDBC API contains more or less some adjustments customized for certain * compatibility needs. */ diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java index 02fee74eb5544f282559f88dab723ccfd8ca096f..8cd8da6de4f7d5324afbc6d5a5d54d6b8dcc7a8d 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java @@ -20,7 +20,7 @@ import java.util.Properties; public class TSDBConnection extends AbstractConnection { private TSDBJNIConnector connector; - private TSDBDatabaseMetaData databaseMetaData; + private final TSDBDatabaseMetaData databaseMetaData; private boolean batchFetch; public Boolean getBatchFetch() { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java index f38555ce8a6c7ee946b3bdbda2204c702b49198a..5b5128e7204f9e75c5901a0d2a5daee9b4c082b2 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java @@ -41,22 +41,66 @@ public abstract class TSDBConstants { public static final int TSDB_DATA_TYPE_BINARY = 8; public static final int TSDB_DATA_TYPE_TIMESTAMP = 9; public static final int TSDB_DATA_TYPE_NCHAR = 10; - /* - 系统增加新的无符号数据类型,分别是: - unsigned tinyint, 数值范围:0-254, NULL 为255 - unsigned smallint,数值范围: 0-65534, NULL 为65535 - unsigned int,数值范围:0-4294967294,NULL 为4294967295u - unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。 - example: - create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned); - */ + /** + * 系统增加新的无符号数据类型,分别是: + * unsigned tinyint, 数值范围:0-254, NULL 为255 + * unsigned smallint,数值范围: 0-65534, NULL 为65535 + * unsigned int,数值范围:0-4294967294,NULL 为4294967295u + * unsigned bigint,数值范围:0-18446744073709551614u,NULL 为18446744073709551615u。 + * example: + * create table tb(ts timestamp, a tinyint unsigned, b smallint unsigned, c int unsigned, d bigint unsigned); + */ public static final int TSDB_DATA_TYPE_UTINYINT = 11; //unsigned tinyint public static final int TSDB_DATA_TYPE_USMALLINT = 12; //unsigned smallint public static final int TSDB_DATA_TYPE_UINT = 13; //unsigned int public static final int TSDB_DATA_TYPE_UBIGINT = 14; //unsigned bigint + // nchar column max length public static final int maxFieldSize = 16 * 1024; + // precision for data types, this is used for metadata + public static final int BOOLEAN_PRECISION = 1; + public static final int TINYINT_PRECISION = 4; + public static final int SMALLINT_PRECISION = 6; + public static final int INT_PRECISION = 11; + public static final int BIGINT_PRECISION = 20; + public static final int FLOAT_PRECISION = 12; + public static final int DOUBLE_PRECISION = 22; + public static final int TIMESTAMP_MS_PRECISION = 23; + public static final int TIMESTAMP_US_PRECISION = 26; + // scale for data types, this is used for metadata + public static final int FLOAT_SCALE = 31; + public static final int DOUBLE_SCALE = 31; + + public static final String DEFAULT_PRECISION = "ms"; + + public static int typeName2JdbcType(String type) { + switch (type.toUpperCase()) { + case "TIMESTAMP": + return Types.TIMESTAMP; + case "INT": + return Types.INTEGER; + case "BIGINT": + return Types.BIGINT; + case "FLOAT": + return Types.FLOAT; + case "DOUBLE": + return Types.DOUBLE; + case "BINARY": + return Types.BINARY; + case "SMALLINT": + return Types.SMALLINT; + case "TINYINT": + return Types.TINYINT; + case "BOOL": + return Types.BOOLEAN; + case "NCHAR": + return Types.NCHAR; + default: + return Types.NULL; + } + } + public static int taosType2JdbcType(int taosType) throws SQLException { switch (taosType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: @@ -88,7 +132,7 @@ public abstract class TSDBConstants { } public static String taosType2JdbcTypeName(int taosType) throws SQLException { - switch (taosType){ + switch (taosType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return "BOOL"; case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: @@ -119,7 +163,7 @@ public abstract class TSDBConstants { } public static int jdbcType2TaosType(int jdbcType) throws SQLException { - switch (jdbcType){ + switch (jdbcType) { case Types.BOOLEAN: return TSDBConstants.TSDB_DATA_TYPE_BOOL; case Types.TINYINT: @@ -145,7 +189,7 @@ public abstract class TSDBConstants { } public static String jdbcType2TaosTypeName(int jdbcType) throws SQLException { - switch (jdbcType){ + switch (jdbcType) { case Types.BOOLEAN: return "BOOL"; case Types.TINYINT: diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java index 8b7ede148e89cce0d8db22e62627bd1e1c49f9bb..9a5eda4cd8bf59e75540a4ce0a1d7fb4255fa1f1 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java @@ -20,8 +20,8 @@ import java.sql.SQLException; public class TSDBDatabaseMetaData extends AbstractDatabaseMetaData { - private String url; - private String userName; + private final String url; + private final String userName; private Connection conn; public TSDBDatabaseMetaData(String url, String userName) { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java index 55533bd28cc4027c2e4a258cf2a36fd5b72d12f2..98a7d1929b824445362a7653f05a2725a41cc926 100755 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java @@ -176,7 +176,7 @@ public class TSDBDriver extends AbstractDriver { int beginningOfSlashes = url.indexOf("//"); int index = url.indexOf("?"); if (index != -1) { - String paramString = url.substring(index + 1, url.length()); + String paramString = url.substring(index + 1); url = url.substring(0, index); StringTokenizer queryParams = new StringTokenizer(paramString, "&"); while (queryParams.hasMoreElements()) { @@ -213,7 +213,7 @@ public class TSDBDriver extends AbstractDriver { url = url.substring(0, indexOfColon); } - if (url != null && url.length() > 0 && url.trim().length() > 0) { + if (url.length() > 0 && url.trim().length() > 0) { urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url); } @@ -233,7 +233,7 @@ public class TSDBDriver extends AbstractDriver { return false; } - public Logger getParentLogger() throws SQLFeatureNotSupportedException { + public Logger getParentLogger() { return null; } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java index 90967b3620fdaccf69f253c8f8927c067b6221fd..da89081428bb076c69be5e5aac189aa467d09307 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java @@ -8,7 +8,7 @@ import java.util.HashMap; import java.util.Map; public class TSDBError { - private static Map TSDBErrorMap = new HashMap<>(); + private static final Map TSDBErrorMap = new HashMap<>(); static { TSDBErrorMap.put(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED, "connection already closed"); @@ -32,10 +32,10 @@ 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"); - /**************************************************/ + TSDBErrorMap.put(TSDBErrorNumbers.ERROR_SUBSCRIBE_FAILED, "failed to create subscription"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING, "Unsupported encoding"); TSDBErrorMap.put(TSDBErrorNumbers.ERROR_JNI_TDENGINE_ERROR, "internal error of database"); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java index c978bb3a2e4a1b9dbd264268f057f2b6c735250a..714162b563d7358a1ed0b20476b0775d9cb343cb 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java @@ -1,6 +1,7 @@ package com.taosdata.jdbc; import java.util.HashSet; +import java.util.Set; public class TSDBErrorNumbers { @@ -25,6 +26,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 @@ -38,10 +40,9 @@ public class TSDBErrorNumbers { public static final int ERROR_JNI_FETCH_END = 0x2358; // fetch to the end of resultSet public static final int ERROR_JNI_OUT_OF_MEMORY = 0x2359; // JNI alloc memory failed - private static final HashSet errorNumbers; + private static final Set errorNumbers = new HashSet(); static { - errorNumbers = new HashSet(); errorNumbers.add(ERROR_CONNECTION_CLOSED); errorNumbers.add(ERROR_UNSUPPORTED_METHOD); errorNumbers.add(ERROR_INVALID_VARIABLE); @@ -62,8 +63,8 @@ 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); errorNumbers.add(ERROR_UNSUPPORTED_ENCODING); errorNumbers.add(ERROR_JNI_TDENGINE_ERROR); 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 256e735285bd493f37c9e369a49b369e9e6b4b38..7f400fc1eeae2efc3d0ab800083969404c50a469 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 @@ -16,27 +16,22 @@ */ package com.taosdata.jdbc; +import com.taosdata.jdbc.utils.TaosInfo; + import java.nio.ByteBuffer; import java.sql.SQLException; import java.sql.SQLWarning; import java.util.List; -import com.taosdata.jdbc.utils.TaosInfo; - /** * JNI connector */ public class TSDBJNIConnector { private static volatile Boolean isInitialized = false; - private TaosInfo taosInfo = TaosInfo.getInstance(); - - // Connection pointer used in C - private long taos = TSDBConstants.JNI_NULL_POINTER; - - // result set status in current connection - private boolean isResultsetClosed; - + private final TaosInfo taosInfo = TaosInfo.getInstance(); + private long taos = TSDBConstants.JNI_NULL_POINTER; // Connection pointer used in C + private boolean isResultsetClosed; // result set status in current connection private int affectedRows = -1; static { @@ -96,11 +91,9 @@ public class TSDBJNIConnector { /** * Execute DML/DDL operation - * - * @throws SQLException */ public long executeQuery(String sql) throws SQLException { - Long pSql = 0l; + long pSql = 0L; try { pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos); taosInfo.stmt_count_increment(); @@ -161,7 +154,7 @@ public class TSDBJNIConnector { private native long getResultSetImp(long connection, long pSql); public boolean isUpdateQuery(long pSql) { - return isUpdateQueryImp(this.taos, pSql) == 1 ? true : false; + return isUpdateQueryImp(this.taos, pSql) == 1; } private native long isUpdateQueryImp(long connection, long pSql); @@ -194,7 +187,9 @@ public class TSDBJNIConnector { * Get schema metadata */ public int getSchemaMetaData(long resultSet, List columnMetaData) { - return this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData); + int ret = this.getSchemaMetaDataImp(this.taos, resultSet, columnMetaData); + columnMetaData.forEach(column -> column.setColIndex(column.getColIndex() + 1)); + return ret; } private native int getSchemaMetaDataImp(long connection, long resultSet, List columnMetaData); @@ -215,13 +210,22 @@ public class TSDBJNIConnector { private native int fetchBlockImp(long connection, long resultSet, TSDBResultSetBlockData blockData); /** - * Execute close operation from C to release connection pointer by JNI + * Get Result Time Precision. * - * @throws SQLException + * @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 */ public void closeConnection() throws SQLException { int code = this.closeConnectionImp(this.taos); - + if (code < 0) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); } else if (code == 0) { @@ -229,7 +233,7 @@ public class TSDBJNIConnector { } else { throw new SQLException("Undefined error code returned by TDengine when closing a connection"); } - + // invoke closeConnectionImpl only here taosInfo.connect_close_increment(); } @@ -256,8 +260,6 @@ public class TSDBJNIConnector { /** * Unsubscribe, close a subscription - * - * @param subscription */ void unsubscribe(long subscription, boolean isKeep) { unsubscribeImp(subscription, isKeep); @@ -270,71 +272,80 @@ public class TSDBJNIConnector { */ public boolean validateCreateTableSql(String sql) { int res = validateCreateTableSqlImp(taos, sql.getBytes()); - return res != 0 ? false : true; + return res == 0; } private native int validateCreateTableSqlImp(long connection, byte[] sqlBytes); - - public long prepareStmt(String sql) throws SQLException { - Long stmt = prepareStmtImp(sql.getBytes(), this.taos); - if (stmt == TSDBConstants.JNI_TDENGINE_ERROR) { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_SQL); - } else if (stmt == TSDBConstants.JNI_CONNECTION_NULL) { + + public long prepareStmt(String sql) throws SQLException { + long stmt; + try { + stmt = prepareStmtImp(sql.getBytes(), this.taos); + } catch (Exception e) { + e.printStackTrace(); + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING); + } + + if (stmt == TSDBConstants.JNI_CONNECTION_NULL) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL); - } else if (stmt == TSDBConstants.JNI_SQL_NULL) { + } + + if (stmt == TSDBConstants.JNI_SQL_NULL) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_SQL_NULL); - } else if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) { + } + + if (stmt == TSDBConstants.JNI_OUT_OF_MEMORY) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_OUT_OF_MEMORY); } - - return stmt; + + return stmt; } - + private native long prepareStmtImp(byte[] sql, long con); - + public void setBindTableName(long stmt, String tableName) throws SQLException { - int code = setBindTableNameImp(stmt, tableName, this.taos); - if (code != TSDBConstants.JNI_SUCCESS) { + int code = setBindTableNameImp(stmt, tableName, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to set table name"); - } - } - + } + } + private native int setBindTableNameImp(long stmt, String name, long conn); - + public void setBindTableNameAndTags(long stmt, String tableName, int numOfTags, ByteBuffer tags, ByteBuffer typeList, ByteBuffer lengthList, ByteBuffer nullList) throws SQLException { - int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(), - nullList.array(), this.taos); - if (code != TSDBConstants.JNI_SUCCESS) { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags"); - } + int code = setTableNameTagsImp(stmt, tableName, numOfTags, tags.array(), typeList.array(), lengthList.array(), + nullList.array(), this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind table name and corresponding tags"); + } } - + private native int setTableNameTagsImp(long stmt, String name, int numOfTags, byte[] tags, byte[] typeList, byte[] lengthList, byte[] nullList, long conn); - - public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows,int columnIndex) throws SQLException { - int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos); - if (code != TSDBConstants.JNI_SUCCESS) { + + public void bindColumnDataArray(long stmt, ByteBuffer colDataList, ByteBuffer lengthList, ByteBuffer isNullList, int type, int bytes, int numOfRows, int columnIndex) throws SQLException { + int code = bindColDataImp(stmt, colDataList.array(), lengthList.array(), isNullList.array(), type, bytes, numOfRows, columnIndex, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to bind column data"); - } - } - + } + } + private native int bindColDataImp(long stmt, byte[] colDataList, byte[] lengthList, byte[] isNullList, int type, int bytes, int numOfRows, int columnIndex, long conn); - + public void executeBatch(long stmt) throws SQLException { - int code = executeBatchImp(stmt, this.taos); - if (code != TSDBConstants.JNI_SUCCESS) { + int code = executeBatchImp(stmt, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to execute batch bind"); - } + } } - + private native int executeBatchImp(long stmt, long con); - + public void closeBatch(long stmt) throws SQLException { - int code = closeStmt(stmt, this.taos); - if (code != TSDBConstants.JNI_SUCCESS) { + int code = closeStmt(stmt, this.taos); + if (code != TSDBConstants.JNI_SUCCESS) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "failed to close batch bind"); - } + } } - + private native int closeStmt(long stmt, long con); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java index f6810237c097a62a4c8f0f63d6e435bfb0354125..d9042fb729d9d746e16bded46e780a83913f778b 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java @@ -38,19 +38,16 @@ import java.util.regex.Pattern; public class TSDBPreparedStatement extends TSDBStatement implements PreparedStatement { private String rawSql; private Object[] parameters; - private boolean isPrepared; - + private ArrayList colData; private ArrayList tableTags; private int tagValueLength; - + private String tableName; private long nativeStmtHandle = 0; - - private volatile TSDBParameterMetaData parameterMetaData; TSDBPreparedStatement(TSDBConnection connection, String sql) { - super(connection); + super(connection); init(sql); int parameterCnt = 0; @@ -61,14 +58,13 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat } } parameters = new Object[parameterCnt]; - this.isPrepared = true; } - if (parameterCnt > 1) { - // the table name is also a parameter, so ignore it. - this.colData = new ArrayList(); - this.tableTags = new ArrayList(); - } + if (parameterCnt > 1) { + // the table name is also a parameter, so ignore it. + this.colData = new ArrayList<>(); + this.tableTags = new ArrayList<>(); + } } private void init(String sql) { @@ -76,18 +72,17 @@ 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 * order to process those supported SQLs. */ private void preprocessSql() { - /***** For processing some of Spark SQLs*****/ + /***For processing some of Spark SQLs*/ // should replace it first this.rawSql = this.rawSql.replaceAll("or (.*) is null", ""); this.rawSql = this.rawSql.replaceAll(" where ", " WHERE "); @@ -134,32 +129,17 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat } rawSql = rawSql.replace(matcher.group(1), tableFullName); } - /***** 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); } @@ -205,9 +185,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + setObject(parameterIndex, x.doubleValue()); } @Override @@ -222,16 +200,12 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setDate(int parameterIndex, Date x) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + setObject(parameterIndex, new Timestamp(x.getTime())); } @Override public void setTime(int parameterIndex, Time x) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + setObject(parameterIndex, new Timestamp(x.getTime())); } @Override @@ -279,35 +253,23 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); } - + if (parameterIndex < 1 && parameterIndex >= parameters.length) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_PARAMETER_INDEX_OUT_RANGE); } - parameters[parameterIndex - 1] = x; } @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 @@ -323,7 +285,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); } - + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } @@ -350,9 +312,9 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public ResultSetMetaData getMetaData() throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + if (this.getResultSet() == null) + return null; + return getResultSet().getMetaData(); } @Override @@ -396,10 +358,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat if (isClosed()) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - if (parameterMetaData == null) { - this.parameterMetaData = new TSDBParameterMetaData(parameters); - } - return this.parameterMetaData; + return new TSDBParameterMetaData(parameters); } @Override @@ -411,9 +370,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat @Override public void setNString(int parameterIndex, String value) throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); + setString(parameterIndex, value); } @Override @@ -536,489 +493,489 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } - + /////////////////////////////////////////////////////////////////////// // NOTE: the following APIs are not JDBC compatible // set the bind table name private static class ColumnInfo { - @SuppressWarnings("rawtypes") - private ArrayList data; - private int type; - private int bytes; - private boolean typeIsSet; - - public ColumnInfo() { - this.typeIsSet = false; - } - - public void setType(int type) throws SQLException { - if (this.isTypeSet()) { + @SuppressWarnings("rawtypes") + private ArrayList data; + private int type; + private int bytes; + private boolean typeIsSet; + + public ColumnInfo() { + this.typeIsSet = false; + } + + public void setType(int type) throws SQLException { + if (this.isTypeSet()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type has been set"); - } - - this.typeIsSet = true; - this.type = type; - } - - public boolean isTypeSet() { - return this.typeIsSet; - } - }; - + } + + this.typeIsSet = true; + this.type = type; + } + + public boolean isTypeSet() { + return this.typeIsSet; + } + } + private static class TableTagInfo { - private boolean isNull; - private Object value; - private int type; - public TableTagInfo(Object value, int type) { - this.value = value; - this.type = type; - } - - public static TableTagInfo createNullTag(int type) { - TableTagInfo info = new TableTagInfo(null, type); - info.isNull = true; - return info; - } - }; - + private boolean isNull; + private final Object value; + private final int type; + + public TableTagInfo(Object value, int type) { + this.value = value; + this.type = type; + } + + public static TableTagInfo createNullTag(int type) { + TableTagInfo info = new TableTagInfo(null, type); + info.isNull = true; + return info; + } + } + public void setTableName(String name) { - this.tableName = name; + this.tableName = name; } - + private void ensureTagCapacity(int index) { - if (this.tableTags.size() < index + 1) { - int delta = index + 1 - this.tableTags.size(); - this.tableTags.addAll(Collections.nCopies(delta, null)); - } + if (this.tableTags.size() < index + 1) { + int delta = index + 1 - this.tableTags.size(); + this.tableTags.addAll(Collections.nCopies(delta, null)); + } } - + public void setTagNull(int index, int type) { - ensureTagCapacity(index); - this.tableTags.set(index, TableTagInfo.createNullTag(type)); + ensureTagCapacity(index); + this.tableTags.set(index, TableTagInfo.createNullTag(type)); } - + public void setTagBoolean(int index, boolean value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL)); - this.tagValueLength += Byte.BYTES; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BOOL)); + this.tagValueLength += Byte.BYTES; } - + public void setTagInt(int index, int value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT)); - this.tagValueLength += Integer.BYTES; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_INT)); + this.tagValueLength += Integer.BYTES; } - + public void setTagByte(int index, byte value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT)); - this.tagValueLength += Byte.BYTES; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TINYINT)); + this.tagValueLength += Byte.BYTES; } - + public void setTagShort(int index, short value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT)); - this.tagValueLength += Short.BYTES; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_SMALLINT)); + this.tagValueLength += Short.BYTES; } - + public void setTagLong(int index, long value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT)); - this.tagValueLength += Long.BYTES; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BIGINT)); + this.tagValueLength += Long.BYTES; } - + public void setTagTimestamp(int index, long value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP)); - this.tagValueLength += Long.BYTES; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP)); + this.tagValueLength += Long.BYTES; } - + public void setTagFloat(int index, float value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT)); - this.tagValueLength += Float.BYTES; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_FLOAT)); + this.tagValueLength += Float.BYTES; } - + public void setTagDouble(int index, double value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE)); - this.tagValueLength += Double.BYTES; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_DOUBLE)); + this.tagValueLength += Double.BYTES; } - + public void setTagString(int index, String value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY)); - this.tagValueLength += value.getBytes().length; + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_BINARY)); + this.tagValueLength += value.getBytes().length; } - + public void setTagNString(int index, String value) { - ensureTagCapacity(index); - this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR)); - - String charset = TaosGlobalConfig.getCharset(); - try { - this.tagValueLength += value.getBytes(charset).length; - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - } - + ensureTagCapacity(index); + this.tableTags.set(index, new TableTagInfo(value, TSDBConstants.TSDB_DATA_TYPE_NCHAR)); + + String charset = TaosGlobalConfig.getCharset(); + try { + this.tagValueLength += value.getBytes(charset).length; + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + } + public void setValueImpl(int columnIndex, ArrayList list, int type, int bytes) throws SQLException { - if (this.colData.size() == 0) { - this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null)); - - } - ColumnInfo col = (ColumnInfo) this.colData.get(columnIndex); - if (col == null) { - ColumnInfo p = new ColumnInfo(); - p.setType(type); - p.bytes = bytes; - p.data = (ArrayList) list.clone(); - this.colData.set(columnIndex, p); - } else { - if (col.type != type) { + if (this.colData.size() == 0) { + this.colData.addAll(Collections.nCopies(this.parameters.length - 1 - this.tableTags.size(), null)); + } + + ColumnInfo col = this.colData.get(columnIndex); + if (col == null) { + ColumnInfo p = new ColumnInfo(); + p.setType(type); + p.bytes = bytes; + p.data = (ArrayList) list.clone(); + this.colData.set(columnIndex, p); + } else { + if (col.type != type) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data type mismatch"); - } - col.data.addAll(list); - } + } + col.data.addAll(list); + } } - + public void setInt(int columnIndex, ArrayList list) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_INT, Integer.BYTES); } - + public void setFloat(int columnIndex, ArrayList list) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_FLOAT, Float.BYTES); } - + public void setTimestamp(int columnIndex, ArrayList list) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP, Long.BYTES); } - + public void setLong(int columnIndex, ArrayList list) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BIGINT, Long.BYTES); } - + public void setDouble(int columnIndex, ArrayList list) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_DOUBLE, Double.BYTES); } - + public void setBoolean(int columnIndex, ArrayList list) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BOOL, Byte.BYTES); } - + public void setByte(int columnIndex, ArrayList list) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_TINYINT, Byte.BYTES); } - + public void setShort(int columnIndex, ArrayList list) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_SMALLINT, Short.BYTES); } - + public void setString(int columnIndex, ArrayList list, int size) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_BINARY, size); } - + // note: expand the required space for each NChar character public void setNString(int columnIndex, ArrayList list, int size) throws SQLException { - setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES); + setValueImpl(columnIndex, list, TSDBConstants.TSDB_DATA_TYPE_NCHAR, size * Integer.BYTES); } - + public void columnDataAddBatch() throws SQLException { - // pass the data block to native code - if (rawSql == null) { + // pass the data block to native code + if (rawSql == null) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "sql statement not set yet"); - } - - // table name is not set yet, abort - if (this.tableName == null) { + } + + // table name is not set yet, abort + if (this.tableName == null) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "table name not set yet"); - } - - int numOfCols = this.colData.size(); - if (numOfCols == 0) { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); - } - - TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); - this.nativeStmtHandle = connector.prepareStmt(rawSql); - - if (this.tableTags == null) { - connector.setBindTableName(this.nativeStmtHandle, this.tableName); - } else { - int num = this.tableTags.size(); - ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength); - tagDataList.order(ByteOrder.LITTLE_ENDIAN); - - ByteBuffer typeList = ByteBuffer.allocate(num); - typeList.order(ByteOrder.LITTLE_ENDIAN); - - ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES); - lengthList.order(ByteOrder.LITTLE_ENDIAN); - - ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES); - isNullList.order(ByteOrder.LITTLE_ENDIAN); - - for (int i = 0; i < num; ++i) { - TableTagInfo tag = this.tableTags.get(i); - if (tag.isNull) { - typeList.put((byte) tag.type); - isNullList.putInt(1); - lengthList.putLong(0); - continue; - } - - switch (tag.type) { - case TSDBConstants.TSDB_DATA_TYPE_INT: { - Integer val = (Integer) tag.value; - tagDataList.putInt(val); - lengthList.putLong(Integer.BYTES); - break; - } - case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { - Byte val = (Byte) tag.value; - tagDataList.put(val); - lengthList.putLong(Byte.BYTES); - break; - } - - case TSDBConstants.TSDB_DATA_TYPE_BOOL: { - Boolean val = (Boolean) tag.value; - tagDataList.put((byte) (val ? 1 : 0)); - lengthList.putLong(Byte.BYTES); - break; - } - - case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { - Short val = (Short) tag.value; - tagDataList.putShort(val); - lengthList.putLong(Short.BYTES); - - break; - } - - case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: - case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { - Long val = (Long) tag.value; - tagDataList.putLong(val == null ? 0 : val); - lengthList.putLong(Long.BYTES); - - break; - } - - case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { - Float val = (Float) tag.value; - tagDataList.putFloat(val == null ? 0 : val); - lengthList.putLong(Float.BYTES); - - break; - } - - case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { - Double val = (Double) tag.value; - tagDataList.putDouble(val == null ? 0 : val); - lengthList.putLong(Double.BYTES); - - break; - } - - case TSDBConstants.TSDB_DATA_TYPE_NCHAR: - case TSDBConstants.TSDB_DATA_TYPE_BINARY: { - String charset = TaosGlobalConfig.getCharset(); - String val = (String) tag.value; - - byte[] b = null; - try { - if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) { - b = val.getBytes(); - } else { - b = val.getBytes(charset); - } - } catch (UnsupportedEncodingException e) { - e.printStackTrace(); - } - - tagDataList.put(b); - lengthList.putLong(b.length); - 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"); - } - } - - typeList.put((byte) tag.type); - isNullList.putInt(tag.isNull? 1 : 0); - } - - connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList, - typeList, lengthList, isNullList); - } - - ColumnInfo colInfo = (ColumnInfo) this.colData.get(0); - if (colInfo == null) { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); - } - - int rows = colInfo.data.size(); - for (int i = 0; i < numOfCols; ++i) { - ColumnInfo col1 = this.colData.get(i); - if (col1 == null || !col1.isTypeSet()) { + } + + int numOfCols = this.colData.size(); + if (numOfCols == 0) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); + } + + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + this.nativeStmtHandle = connector.prepareStmt(rawSql); + + if (this.tableTags == null) { + connector.setBindTableName(this.nativeStmtHandle, this.tableName); + } else { + int num = this.tableTags.size(); + ByteBuffer tagDataList = ByteBuffer.allocate(this.tagValueLength); + tagDataList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer typeList = ByteBuffer.allocate(num); + typeList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer lengthList = ByteBuffer.allocate(num * Long.BYTES); + lengthList.order(ByteOrder.LITTLE_ENDIAN); + + ByteBuffer isNullList = ByteBuffer.allocate(num * Integer.BYTES); + isNullList.order(ByteOrder.LITTLE_ENDIAN); + + for (TableTagInfo tag : this.tableTags) { + if (tag.isNull) { + typeList.put((byte) tag.type); + isNullList.putInt(1); + lengthList.putLong(0); + continue; + } + + switch (tag.type) { + case TSDBConstants.TSDB_DATA_TYPE_INT: { + Integer val = (Integer) tag.value; + tagDataList.putInt(val); + lengthList.putLong(Integer.BYTES); + break; + } + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { + Byte val = (Byte) tag.value; + tagDataList.put(val); + lengthList.putLong(Byte.BYTES); + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_BOOL: { + Boolean val = (Boolean) tag.value; + tagDataList.put((byte) (val ? 1 : 0)); + lengthList.putLong(Byte.BYTES); + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: { + Short val = (Short) tag.value; + tagDataList.putShort(val); + lengthList.putLong(Short.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: + case TSDBConstants.TSDB_DATA_TYPE_BIGINT: { + Long val = (Long) tag.value; + tagDataList.putLong(val == null ? 0 : val); + lengthList.putLong(Long.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { + Float val = (Float) tag.value; + tagDataList.putFloat(val == null ? 0 : val); + lengthList.putLong(Float.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: { + Double val = (Double) tag.value; + tagDataList.putDouble(val == null ? 0 : val); + lengthList.putLong(Double.BYTES); + + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + case TSDBConstants.TSDB_DATA_TYPE_BINARY: { + String charset = TaosGlobalConfig.getCharset(); + String val = (String) tag.value; + + byte[] b = null; + try { + if (tag.type == TSDBConstants.TSDB_DATA_TYPE_BINARY) { + b = val.getBytes(); + } else { + b = val.getBytes(charset); + } + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + tagDataList.put(b); + lengthList.putLong(b.length); + 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"); + } + } + + typeList.put((byte) tag.type); + isNullList.putInt(tag.isNull ? 1 : 0); + } + + connector.setBindTableNameAndTags(this.nativeStmtHandle, this.tableName, this.tableTags.size(), tagDataList, + typeList, lengthList, isNullList); + } + + ColumnInfo colInfo = this.colData.get(0); + if (colInfo == null) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); + } + + int rows = colInfo.data.size(); + for (int i = 0; i < numOfCols; ++i) { + ColumnInfo col1 = this.colData.get(i); + if (col1 == null || !col1.isTypeSet()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "column data not bind"); - } - - if (rows != col1.data.size()) { + } + + if (rows != col1.data.size()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "the rows in column data not identical"); - } - - ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes); - colDataList.order(ByteOrder.LITTLE_ENDIAN); - + } + + ByteBuffer colDataList = ByteBuffer.allocate(rows * col1.bytes); + colDataList.order(ByteOrder.LITTLE_ENDIAN); + ByteBuffer lengthList = ByteBuffer.allocate(rows * Integer.BYTES); lengthList.order(ByteOrder.LITTLE_ENDIAN); - + ByteBuffer isNullList = ByteBuffer.allocate(rows * Byte.BYTES); isNullList.order(ByteOrder.LITTLE_ENDIAN); - - switch (col1.type) { - case TSDBConstants.TSDB_DATA_TYPE_INT: { - for (int j = 0; j < rows; ++j) { - Integer val = (Integer) col1.data.get(j); - colDataList.putInt(val == null? Integer.MIN_VALUE:val); - isNullList.put((byte) (val == null? 1:0)); - } - break; - } - - case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { - 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_BOOL: { - for (int j = 0; j < rows; ++j) { - Boolean val = (Boolean) col1.data.get(j); - if (val == null) { - colDataList.put((byte) 0); - } else { - colDataList.put((byte) (val? 1:0)); - } - - 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) { - Long val = (Long) col1.data.get(j); - colDataList.putLong(val == null? 0:val); - 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); - - 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(); - } - - if (val.length() > col1.bytes) { - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long"); - } - - colDataList.put(b); - lengthList.putInt(b.length); - isNullList.put((byte) 0); - } else { - lengthList.putInt(0); - isNullList.put((byte) 1); - } - } - 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, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i); - } - } - - public void columnDataExecuteBatch() throws SQLException { - TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); - connector.executeBatch(this.nativeStmtHandle); - this.columnDataClearBatch(); - } - + + switch (col1.type) { + case TSDBConstants.TSDB_DATA_TYPE_INT: { + for (int j = 0; j < rows; ++j) { + Integer val = (Integer) col1.data.get(j); + colDataList.putInt(val == null ? Integer.MIN_VALUE : val); + isNullList.put((byte) (val == null ? 1 : 0)); + } + break; + } + + case TSDBConstants.TSDB_DATA_TYPE_TINYINT: { + 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_BOOL: { + for (int j = 0; j < rows; ++j) { + Boolean val = (Boolean) col1.data.get(j); + if (val == null) { + colDataList.put((byte) 0); + } else { + colDataList.put((byte) (val ? 1 : 0)); + } + + 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) { + Long val = (Long) col1.data.get(j); + colDataList.putLong(val == null ? 0 : val); + 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); + + 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(); + } + + if (val.length() > col1.bytes) { + throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNKNOWN, "string data too long"); + } + + colDataList.put(b); + lengthList.putInt(b.length); + isNullList.put((byte) 0); + } else { + lengthList.putInt(0); + isNullList.put((byte) 1); + } + } + 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, colDataList, lengthList, isNullList, col1.type, col1.bytes, rows, i); + } + } + + public void columnDataExecuteBatch() throws SQLException { + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + connector.executeBatch(this.nativeStmtHandle); + this.columnDataClearBatch(); + } + public void columnDataClearBatch() { - int size = this.colData.size(); - this.colData.clear(); - + int size = this.colData.size(); + this.colData.clear(); + this.colData.addAll(Collections.nCopies(size, null)); this.tableName = null; // clear the table name } - + public void columnDataCloseBatch() throws SQLException { - TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); - connector.closeBatch(this.nativeStmtHandle); - - this.nativeStmtHandle = 0L; - this.tableName = null; + TSDBJNIConnector connector = ((TSDBConnection) this.getConnection()).getConnector(); + connector.closeBatch(this.nativeStmtHandle); + + this.nativeStmtHandle = 0L; + this.tableName = null; } } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java index aba29d602b8900d3bedee49ee94e7d226b3bd1f0..00a62206fc7861a87177d14cc4b274c464dc4184 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java @@ -133,9 +133,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getString(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getString(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getString(columnIndex, nativeType); } return res; } @@ -147,9 +148,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getBoolean(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getBoolean(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getBoolean(columnIndex, nativeType); } return res; } @@ -161,9 +163,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return (byte) this.blockData.getInt(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = (byte) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = (byte) this.rowData.getInt(columnIndex, nativeType); } return res; } @@ -175,9 +178,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return (short) this.blockData.getInt(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = (short) this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = (short) this.rowData.getInt(columnIndex, nativeType); } return res; } @@ -189,9 +193,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getInt(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getInt(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getInt(columnIndex, nativeType); } return res; } @@ -203,13 +209,15 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getLong(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - Object value = this.rowData.get(columnIndex - 1); - if (value instanceof Timestamp) + Object value = this.rowData.getObject(columnIndex); + if (value instanceof Timestamp) { res = ((Timestamp) value).getTime(); - else - res = this.rowData.getLong(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + } else { + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getLong(columnIndex, nativeType); + } } return res; } @@ -221,9 +229,11 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return (float) this.blockData.getDouble(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); - if (!lastWasNull) - res = this.rowData.getFloat(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + this.lastWasNull = this.rowData.wasNull(columnIndex); + if (!lastWasNull) { + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getFloat(columnIndex, nativeType); + } return res; } @@ -235,9 +245,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getDouble(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getDouble(columnIndex - 1, this.columnMetaDataList.get(columnIndex - 1).getColType()); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getDouble(columnIndex, nativeType); } return res; } @@ -245,34 +256,27 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { public byte[] getBytes(int columnIndex) throws SQLException { checkAvailability(columnIndex, this.columnMetaDataList.size()); - Object value = this.rowData.get(columnIndex - 1); + Object value = this.rowData.getObject(columnIndex); if (value == null) return null; - int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); - switch (colType) { + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BIGINT: - return Longs.toByteArray((Long) value); + return Longs.toByteArray((long) value); case TSDBConstants.TSDB_DATA_TYPE_INT: return Ints.toByteArray((int) value); case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: - return Shorts.toByteArray((Short) value); + return Shorts.toByteArray((short) value); case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return new byte[]{(byte) value}; + case TSDBConstants.TSDB_DATA_TYPE_BINARY: + return (byte[]) value; + case TSDBConstants.TSDB_DATA_TYPE_BOOL: + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + default: + return value.toString().getBytes(); } - return value.toString().getBytes(); - } - - @Override - public Date getDate(int columnIndex) throws SQLException { - Timestamp timestamp = getTimestamp(columnIndex); - return timestamp == null ? null : new Date(timestamp.getTime()); - } - - @Override - public Time getTime(int columnIndex) throws SQLException { - Timestamp timestamp = getTimestamp(columnIndex); - return timestamp == null ? null : new Time(timestamp.getTime()); } public Timestamp getTimestamp(int columnIndex) throws SQLException { @@ -282,9 +286,10 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.getTimestamp(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - res = this.rowData.getTimestamp(columnIndex - 1); + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + res = this.rowData.getTimestamp(columnIndex, nativeType); } return res; } @@ -304,13 +309,9 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return this.blockData.get(columnIndex - 1); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); if (!lastWasNull) { - int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); - if (colType == TSDBConstants.TSDB_DATA_TYPE_BINARY) - res = ((String) this.rowData.get(columnIndex - 1)).getBytes(); - else - res = this.rowData.get(columnIndex - 1); + res = this.rowData.getObject(columnIndex); } return res; } @@ -318,7 +319,7 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { public int findColumn(String columnLabel) throws SQLException { for (ColumnMetaData colMetaData : this.columnMetaDataList) { if (colMetaData.getColName() != null && colMetaData.getColName().equalsIgnoreCase(columnLabel)) { - return colMetaData.getColIndex() + 1; + return colMetaData.getColIndex(); } } throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE); @@ -329,25 +330,25 @@ public class TSDBResultSet extends AbstractResultSet implements ResultSet { if (this.getBatchFetch()) return new BigDecimal(this.blockData.getLong(columnIndex - 1)); - this.lastWasNull = this.rowData.wasNull(columnIndex - 1); + this.lastWasNull = this.rowData.wasNull(columnIndex); BigDecimal res = null; if (!lastWasNull) { - int colType = this.columnMetaDataList.get(columnIndex - 1).getColType(); - switch (colType) { + int nativeType = this.columnMetaDataList.get(columnIndex - 1).getColType(); + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_TINYINT: case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: case TSDBConstants.TSDB_DATA_TYPE_INT: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: - res = new BigDecimal(Long.valueOf(this.rowData.get(columnIndex - 1).toString())); + res = new BigDecimal(Long.parseLong(this.rowData.getObject(columnIndex).toString())); break; case TSDBConstants.TSDB_DATA_TYPE_FLOAT: case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: - res = new BigDecimal(Double.valueOf(this.rowData.get(columnIndex - 1).toString())); + res = BigDecimal.valueOf(Double.parseDouble(this.rowData.getObject(columnIndex).toString())); break; case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: - return new BigDecimal(((Timestamp) this.rowData.get(columnIndex - 1)).getTime()); + return new BigDecimal(((Timestamp) this.rowData.getObject(columnIndex)).getTime()); default: - res = new BigDecimal(this.rowData.get(columnIndex - 1).toString()); + res = new BigDecimal(this.rowData.getObject(columnIndex).toString()); } } return res; diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java index 7b3be5d26397eae704d98f1e1802af14abaad4fc..6211f61dc505d2ccba5f11f3aacc980771b1a110 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java @@ -36,23 +36,20 @@ public class TSDBResultSetBlockData { private int rowIndex = 0; private List columnMetaDataList; - private ArrayList colData = null; + private ArrayList colData; public TSDBResultSetBlockData(List colMeta, int numOfCols) { this.columnMetaDataList = colMeta; - this.colData = new ArrayList(numOfCols); + this.colData = new ArrayList<>(numOfCols); } public TSDBResultSetBlockData() { - this.colData = new ArrayList(); + this.colData = new ArrayList<>(); } public void clear() { int size = this.colData.size(); - if (this.colData != null) { - this.colData.clear(); - } - + this.colData.clear(); setNumOfCols(size); } @@ -69,7 +66,7 @@ public class TSDBResultSetBlockData { } public void setNumOfCols(int numOfCols) { - this.colData = new ArrayList(numOfCols); + this.colData = new ArrayList<>(numOfCols); this.colData.addAll(Collections.nCopies(numOfCols, null)); } @@ -166,15 +163,10 @@ public class TSDBResultSetBlockData { } } - /** * The original type may not be a string type, but will be converted to by * calling this method - * - * @param col column index - * @return - * @throws SQLException */ public String getString(int col) throws SQLException { Object obj = get(col); @@ -387,7 +379,7 @@ public class TSDBResultSetBlockData { return null; } - return (long) val; + return val; } case TSDBConstants.TSDB_DATA_TYPE_FLOAT: { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java index e4ac5303d09f132279e29039bf6b5b812b6c5404..6292673352529171cdc42ba73e0f47f8f05a21a4 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java @@ -41,10 +41,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD } public boolean isSearchable(int column) throws SQLException { - if (column == 1) { - return true; - } - return false; + return column == 1; } public boolean isCurrency(int column) throws SQLException { @@ -113,6 +110,7 @@ public class TSDBResultSetMetaData extends WrapperImpl implements ResultSetMetaD ColumnMetaData columnMetaData = this.colMetaDataList.get(column - 1); switch (columnMetaData.getColType()) { + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: return 5; case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java index 618e896a6ddfe43d63f631b663a356f485575b06..b91fe88dfacd7c6e414aa842184b2c349b3e33b9 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java @@ -14,19 +14,22 @@ *****************************************************************************/ package com.taosdata.jdbc; +import com.taosdata.jdbc.utils.NullType; + import java.math.BigDecimal; import java.sql.SQLException; import java.sql.Timestamp; -import java.time.Instant; import java.util.ArrayList; import java.util.Collections; public class TSDBResultSetRowData { + private ArrayList data; - private int colSize = 0; + private final int colSize; public TSDBResultSetRowData(int colSize) { - this.setColSize(colSize); + this.colSize = colSize; + this.clear(); } public void clear() { @@ -41,129 +44,191 @@ public class TSDBResultSetRowData { } public boolean wasNull(int col) { - return data.get(col) == null; + return data.get(col - 1) == null; } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setBooleanValue(int col, boolean value) { + setBoolean(col - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setBoolean(int col, boolean value) { data.set(col, value); } - public boolean getBoolean(int col, int srcType) throws SQLException { - Object obj = data.get(col); + public boolean getBoolean(int col, int nativeType) throws SQLException { + Object obj = data.get(col - 1); - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return (Boolean) obj; - case TSDBConstants.TSDB_DATA_TYPE_FLOAT: - return ((Float) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE; - case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: - return ((Double) obj) == 1.0 ? Boolean.TRUE : Boolean.FALSE; case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return ((Byte) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: return ((Short) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; case TSDBConstants.TSDB_DATA_TYPE_INT: return ((Integer) obj) == 1 ? Boolean.TRUE : Boolean.FALSE; - case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return ((Long) obj) == 1L ? Boolean.TRUE : Boolean.FALSE; + case TSDBConstants.TSDB_DATA_TYPE_BINARY: + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: { + return obj.toString().contains("1"); + } default: return false; } } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setByteValue(int colIndex, byte value) { + setByte(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setByte(int col, byte value) { data.set(col, value); } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setShortValue(int colIndex, short value) { + setShort(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setShort(int col, short value) { data.set(col, value); } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setIntValue(int colIndex, int value) { + setInt(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setInt(int col, int value) { data.set(col, value); } - @SuppressWarnings("deprecation") - public int getInt(int col, int srcType) throws SQLException { - Object obj = data.get(col); + public int getInt(int col, int nativeType) throws SQLException { + Object obj = data.get(col - 1); + if (obj == null) + return NullType.getIntNull(); - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj) ? 1 : 0; - case TSDBConstants.TSDB_DATA_TYPE_FLOAT: - return ((Float) obj).intValue(); - case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: - return ((Double) obj).intValue(); case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj; case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: return (Short) obj; case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj; - case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: return ((Long) obj).intValue(); 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: + return ((Double) obj).intValue(); + default: + return 0; } + } + + 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; + } - return 0; + 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 + */ + public void setLongValue(int colIndex, long value) { + setLong(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setLong(int col, long value) { data.set(col, value); } - public long getLong(int col, int srcType) throws SQLException { - Object obj = data.get(col); + public long getLong(int col, int nativeType) throws SQLException { + Object obj = data.get(col - 1); + if (obj == null) { + return NullType.getBigIntNull(); + } - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj) ? 1 : 0; - case TSDBConstants.TSDB_DATA_TYPE_FLOAT: - return ((Float) obj).longValue(); - case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: - return ((Double) obj).longValue(); case TSDBConstants.TSDB_DATA_TYPE_TINYINT: return (Byte) obj; case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: return (Short) obj; case TSDBConstants.TSDB_DATA_TYPE_INT: return (Integer) obj; - case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: + case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: return (Long) obj; case TSDBConstants.TSDB_DATA_TYPE_NCHAR: 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; @@ -186,19 +251,35 @@ public class TSDBResultSetRowData { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_NUMERIC_VALUE_OUT_OF_RANGE); return value; } + case TSDBConstants.TSDB_DATA_TYPE_FLOAT: + return ((Float) obj).longValue(); + case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: + return ((Double) obj).longValue(); + default: + return 0; } + } - return 0; + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setFloatValue(int colIndex, float value) { + setFloat(colIndex - 1, value); } + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setFloat(int col, float value) { data.set(col, value); } - public float getFloat(int col, int srcType) { - Object obj = data.get(col); + public float getFloat(int col, int nativeType) { + Object obj = data.get(col - 1); + if (obj == null) + return NullType.getFloatNull(); - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj) ? 1 : 0; case TSDBConstants.TSDB_DATA_TYPE_FLOAT: @@ -214,19 +295,31 @@ public class TSDBResultSetRowData { case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj; + default: + return NullType.getFloatNull(); } + } - return 0; + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setDoubleValue(int colIndex, double value) { + setDouble(colIndex - 1, value); } + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setDouble(int col, double value) { data.set(col, value); } - public double getDouble(int col, int srcType) { - Object obj = data.get(col); + public double getDouble(int col, int nativeType) { + Object obj = data.get(col - 1); + if (obj == null) + return NullType.getDoubleNull(); - switch (srcType) { + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_BOOL: return Boolean.TRUE.equals(obj) ? 1 : 0; case TSDBConstants.TSDB_DATA_TYPE_FLOAT: @@ -242,16 +335,46 @@ public class TSDBResultSetRowData { case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: case TSDBConstants.TSDB_DATA_TYPE_BIGINT: return (Long) obj; + default: + return NullType.getDoubleNull(); } + } - return 0; + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setStringValue(int colIndex, String value) { + data.set(colIndex - 1, value); } + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setString(int col, String value) { - data.set(col, value); + // TODO: + // !!!NOTE!!! + // this is very confusing problem which related to JNI-method implementation, + // the JNI method return a String(encoded in UTF) for BINARY value, which means the JNI method will invoke + // this setString(int, String) to handle BINARY value, we need to build a byte[] with default charsetEncoding + data.set(col, value == null ? null : value.getBytes()); } + /** + * $$$ this method is invoked by databaseMetaDataResultSet and so on which use a index start from 1 in JDBC api + */ + public void setByteArrayValue(int colIndex, byte[] value) { + setByteArray(colIndex - 1, value); + } + + /** + * !!! this method is invoked by JNI method and the index start from 0 in C implementations + */ public void setByteArray(int col, byte[] value) { + // TODO: + // !!!NOTE!!! + // this is very confusing problem which related to JNI-method implementation, + // the JNI method return a byte[] for NCHAR value, which means the JNI method will invoke + // this setByteArr(int, byte[]) to handle NCHAR value, we need to build a String with charsetEncoding by TaosGlobalConfig try { data.set(col, new String(value, TaosGlobalConfig.getCharset())); } catch (Exception e) { @@ -259,85 +382,99 @@ public class TSDBResultSetRowData { } } - /** - * The original type may not be a string type, but will be converted to by calling this method - * - * @param col column index - * @return - */ - public String getString(int col, int srcType) { - switch (srcType) { - case TSDBConstants.TSDB_DATA_TYPE_BINARY: - case TSDBConstants.TSDB_DATA_TYPE_NCHAR: - return (String) data.get(col); + public String getString(int col, int nativeType) { + Object obj = data.get(col - 1); + if (obj == null) + return null; + + switch (nativeType) { case TSDBConstants.TSDB_DATA_TYPE_UTINYINT: { - Byte value = new Byte(String.valueOf(data.get(col))); + byte value = new Byte(String.valueOf(obj)); if (value >= 0) - return value.toString(); + return Byte.toString(value); return Integer.toString(value & 0xff); } case TSDBConstants.TSDB_DATA_TYPE_USMALLINT: { - Short value = new Short(String.valueOf(data.get(col))); + short value = new Short(String.valueOf(obj)); if (value >= 0) - return value.toString(); + return Short.toString(value); return Integer.toString(value & 0xffff); } case TSDBConstants.TSDB_DATA_TYPE_UINT: { - Integer value = new Integer(String.valueOf(data.get(col))); + int value = new Integer(String.valueOf(obj)); if (value >= 0) - return value.toString(); - return Long.toString(value & 0xffffffffl); + return Integer.toString(value); + return Long.toString(value & 0xffffffffL); } case TSDBConstants.TSDB_DATA_TYPE_UBIGINT: { - Long value = new Long(String.valueOf(data.get(col))); + long value = new Long(String.valueOf(obj)); if (value >= 0) - return value.toString(); + return Long.toString(value); long lowValue = value & 0x7fffffffffffffffL; return BigDecimal.valueOf(lowValue).add(BigDecimal.valueOf(Long.MAX_VALUE)).add(BigDecimal.valueOf(1)).toString(); } + case TSDBConstants.TSDB_DATA_TYPE_BINARY: + return new String((byte[]) obj); + case TSDBConstants.TSDB_DATA_TYPE_NCHAR: + return (String) obj; default: - return String.valueOf(data.get(col)); + return String.valueOf(obj); } } - 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 Timestamp getTimestamp(int col) { - return (Timestamp) data.get(col); + /** + * $$$ 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, 0); } - public Object get(int col) { - return data.get(col); - } + /** + * !!! 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, int precision) { + long milliseconds; + int fracNanoseconds; + 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); + } + } - public int getColSize() { - return colSize; + Timestamp tsObj = new Timestamp(milliseconds); + tsObj.setNanos(fracNanoseconds); + data.set(col, tsObj); } - private void setColSize(int colSize) { - this.colSize = colSize; - this.clear(); + public Timestamp getTimestamp(int col, int nativeType) { + Object obj = data.get(col - 1); + if (obj == null) + return null; + if (nativeType == TSDBConstants.TSDB_DATA_TYPE_BIGINT) { + return new Timestamp((Long) obj); + } + return (Timestamp) obj; } - public ArrayList getData() { - return data; + public Object getObject(int col) { + return data.get(col - 1); } - public void setData(ArrayList data) { - this.data = (ArrayList) data.clone(); - } } 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 d8ba67576d069a6aec0a5bb17e9549e41b8cf31e..e1ebc4ab3cf498168181dbea08a3ac28194a5c7d 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 @@ -32,14 +32,15 @@ public class TSDBStatement extends AbstractStatement { } public ResultSet executeQuery(String sql) throws SQLException { - // check if closed if (isClosed()) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); } - - //TODO: 如果在executeQuery方法中执行insert语句,那么先执行了SQL,再通过pSql来检查是否为一个insert语句,但这个insert SQL已经执行成功了 - - // execute query + //TODO: + // this is an unreasonable implementation, if the paratemer is a insert statement, + // the JNI connector will execute the sql at first and return a pointer: pSql, + // we use this pSql and invoke the isUpdateQuery(long pSql) method to decide . + // but the insert sql is already executed in database. + //execute query long pSql = this.connection.getConnector().executeQuery(sql); // if pSql is create/insert/update/delete/alter SQL if (this.connection.getConnector().isUpdateQuery(pSql)) { diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java index c5fd497ca3dfed8bc8555110660ff70a9fd23447..d74f7755b24f1eb59059fb5ad5ead48d420ec7f6 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java @@ -47,9 +47,6 @@ public class TSDBSubscribe { /** * close subscription - * - * @param keepProgress - * @throws SQLException */ public void close(boolean keepProgress) throws SQLException { if (this.connecter.isClosed()) diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampFormat.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampFormat.java new file mode 100644 index 0000000000000000000000000000000000000000..5ff0774639fb20c575d46c41d977b4ce3a16de10 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampFormat.java @@ -0,0 +1,7 @@ +package com.taosdata.jdbc.enums; + +public enum TimestampFormat { + STRING, + TIMESTAMP, + UTC +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java new file mode 100644 index 0000000000000000000000000000000000000000..79350076c7f4b31743ab9fb61226e506186f0f17 --- /dev/null +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java @@ -0,0 +1,8 @@ +package com.taosdata.jdbc.enums; + +public enum TimestampPrecision { + MS, + US, + NS, + UNKNOWN +} diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java index b810f9aeb59247ef618451b542a678d6c951ad3f..12a0ab57e2c35c7f1f550dd213db19a0effd4ebc 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java @@ -16,17 +16,19 @@ public class RestfulConnection extends AbstractConnection { private final String host; private final int port; private final String url; - private volatile String database; + private final String database; + private final String token; /******************************************************/ private boolean isClosed; private final DatabaseMetaData metadata; - public RestfulConnection(String host, String port, Properties props, String database, String url) { + public RestfulConnection(String host, String port, Properties props, String database, String url, String token) { super(props); this.host = host; this.port = Integer.parseInt(port); this.database = database; this.url = url; + this.token = token; this.metadata = new RestfulDatabaseMetaData(url, props.getProperty(TSDBDriver.PROPERTY_KEY_USER), this); } @@ -66,6 +68,7 @@ public class RestfulConnection extends AbstractConnection { return this.metadata; } + // getters public String getHost() { return host; } @@ -81,4 +84,8 @@ public class RestfulConnection extends AbstractConnection { public String getUrl() { return url; } + + public String getToken() { + return token; + } } \ No newline at end of file diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java index a94cfa6e07c62ee9b163823aaad03bcc402bbffc..9ab67c5502e33d8f2337e3acc8d8eab425992e3a 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java @@ -38,15 +38,11 @@ public class RestfulDriver extends AbstractDriver { String port = props.getProperty(TSDBDriver.PROPERTY_KEY_PORT, "6041"); String database = props.containsKey(TSDBDriver.PROPERTY_KEY_DBNAME) ? props.getProperty(TSDBDriver.PROPERTY_KEY_DBNAME) : null; - String loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" - + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" - + props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + "/" - + props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD) + ""; + String loginUrl = "http://" + host + ":" + port + "/rest/login/" + props.getProperty(TSDBDriver.PROPERTY_KEY_USER) + "/" + props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD) + ""; try { String user = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_USER), "UTF-8"); String password = URLEncoder.encode(props.getProperty(TSDBDriver.PROPERTY_KEY_PASSWORD), "UTF-8"); - loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" - + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" + user + "/" + password + ""; + loginUrl = "http://" + props.getProperty(TSDBDriver.PROPERTY_KEY_HOST) + ":" + props.getProperty(TSDBDriver.PROPERTY_KEY_PORT) + "/rest/login/" + user + "/" + password + ""; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } @@ -55,12 +51,12 @@ public class RestfulDriver extends AbstractDriver { JSONObject jsonResult = JSON.parseObject(result); String status = jsonResult.getString("status"); String token = jsonResult.getString("desc"); - HttpClientPoolUtil.token = token; + if (!status.equals("succ")) { throw new SQLException(jsonResult.getString("desc")); } - RestfulConnection conn = new RestfulConnection(host, port, props, database, url); + RestfulConnection conn = new RestfulConnection(host, port, props, database, url, token); if (database != null && !database.trim().replaceAll("\\s", "").isEmpty()) { Statement stmt = conn.createStatement(); stmt.execute("use " + database); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java index f58e3f8cd2406e6372900c2f7b2547a450fb7fe9..1eaddce1d636f5c74c1226f0df0e66e322600345 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java @@ -13,7 +13,7 @@ import java.util.Calendar; public class RestfulPreparedStatement extends RestfulStatement implements PreparedStatement { - private ParameterMetaData parameterMetaData; + private final ParameterMetaData parameterMetaData; private final String rawSql; private Object[] parameters; private boolean isPrepared; @@ -44,7 +44,7 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar if (!isPrepared) return executeQuery(this.rawSql); - final String sql = getNativeSql(this.rawSql); + final String sql = Utils.getNativeSql(this.rawSql, this.parameters); return executeQuery(sql); } @@ -55,20 +55,10 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar if (!isPrepared) return executeUpdate(this.rawSql); - final String sql = getNativeSql(this.rawSql); + final String sql = Utils.getNativeSql(rawSql, this.parameters); return executeUpdate(sql); } - /**** - * 将rawSql转换成一条可执行的sql语句,使用属性parameters中的变脸进行替换 - * 对于insert into ?.? (?,?,?) using ?.? (?,?,?) tags(?, ?, ?) values(?, ?, ?) - * @param rawSql,可能是insert、select或其他,使用?做占位符 - * @return - */ - private String getNativeSql(String rawSql) { - return Utils.getNativeSql(rawSql, this.parameters); - } - @Override public void setNull(int parameterIndex, int sqlType) throws SQLException { if (isClosed()) @@ -224,16 +214,13 @@ public class RestfulPreparedStatement extends RestfulStatement implements Prepar throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); if (!isPrepared) return execute(this.rawSql); - final String sql = getNativeSql(rawSql); + final String sql = Utils.getNativeSql(rawSql, this.parameters); return execute(sql); } @Override public void addBatch() throws SQLException { - if (isClosed()) - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_STATEMENT_CLOSED); - - final String sql = getNativeSql(this.rawSql); + final String sql = Utils.getNativeSql(rawSql, this.parameters); addBatch(sql); } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java index 530b433d42bf4b387db0e9973ddcf48e3844f2f3..d435062ef6d231e4c4f3545e75b8299e9876739a 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java @@ -6,6 +6,8 @@ import com.google.common.primitives.Ints; import com.google.common.primitives.Longs; import com.google.common.primitives.Shorts; import com.taosdata.jdbc.*; +import com.taosdata.jdbc.enums.TimestampPrecision; +import com.taosdata.jdbc.enums.TimestampFormat; import com.taosdata.jdbc.utils.Utils; import java.math.BigDecimal; @@ -15,19 +17,20 @@ import java.time.ZoneOffset; import java.time.format.DateTimeParseException; import java.util.ArrayList; import java.util.Calendar; +import java.util.List; public class RestfulResultSet extends AbstractResultSet implements ResultSet { - private volatile boolean isClosed; - private int pos = -1; - private final String database; private final Statement statement; // data - private final ArrayList> resultSet = new ArrayList<>(); + private final List> resultSet = new ArrayList<>(); // meta - private ArrayList columnNames = new ArrayList<>(); - private ArrayList columns = new ArrayList<>(); - private RestfulResultSetMetaData metaData; + private final List columnNames = new ArrayList<>(); + private final List columns = new ArrayList<>(); + private final RestfulResultSetMetaData metaData; + + private volatile boolean isClosed; + private int pos = -1; /** * 由一个result的Json构造结果集,对应执行show databases, show tables等这些语句,返回结果集,但无法获取结果集对应的meta,统一当成String处理 @@ -35,34 +38,30 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { * @param resultJson: 包含data信息的结果集,有sql返回的结果集 ***/ public RestfulResultSet(String database, Statement statement, JSONObject resultJson) throws SQLException { - this.database = database; this.statement = statement; + // get head + JSONArray head = resultJson.getJSONArray("head"); // get column metadata JSONArray columnMeta = resultJson.getJSONArray("column_meta"); // get row data JSONArray data = resultJson.getJSONArray("data"); - if (data == null || data.isEmpty()) { - columnNames.clear(); - columns.clear(); - this.resultSet.clear(); - return; - } - // get head - JSONArray head = resultJson.getJSONArray("head"); // get rows Integer rows = resultJson.getInteger("rows"); + // parse column_meta if (columnMeta != null) { parseColumnMeta_new(columnMeta); } else { parseColumnMeta_old(head, data, rows); } - this.metaData = new RestfulResultSetMetaData(this.database, columns, this); + this.metaData = new RestfulResultSetMetaData(database, columns, this); + + if (data == null || data.isEmpty()) + return; // parse row data - resultSet.clear(); for (int rowIndex = 0; rowIndex < data.size(); rowIndex++) { - ArrayList row = new ArrayList(); + List row = new ArrayList(); JSONArray jsonRow = data.getJSONArray(rowIndex); for (int colIndex = 0; colIndex < this.metaData.getColumnCount(); colIndex++) { row.add(parseColumnData(jsonRow, colIndex, columns.get(colIndex).taos_type)); @@ -131,7 +130,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 +148,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 +159,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 +232,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { this.note = note; this.taos_type = taos_type; } + } @Override @@ -218,10 +240,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { if (isClosed()) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); pos++; - if (pos <= resultSet.size() - 1) { - return true; - } - return false; + return pos <= resultSet.size() - 1; } @Override @@ -231,13 +250,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { } } -// @Override -// public boolean wasNull() throws SQLException { -// if (isClosed()) -// throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); -// return resultSet.isEmpty(); -// } - @Override public String getString(int columnIndex) throws SQLException { checkAvailability(columnIndex, resultSet.get(pos).size()); @@ -262,7 +274,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { wasNull = false; if (value instanceof Boolean) return (boolean) value; - return Boolean.valueOf(value.toString()); + return Boolean.parseBoolean(value.toString()); } @Override @@ -334,6 +346,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { wasNull = true; return 0; } + wasNull = false; if (value instanceof Timestamp) { return ((Timestamp) value).getTime(); @@ -416,9 +429,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return null; if (value instanceof Timestamp) return new Date(((Timestamp) value).getTime()); - Date date = null; - date = Utils.parseDate(value.toString()); - return date; + return Utils.parseDate(value.toString()); } @Override @@ -433,8 +444,7 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { Time time = null; try { time = Utils.parseTime(value.toString()); - } catch (DateTimeParseException e) { - time = null; + } catch (DateTimeParseException ignored) { } return time; } @@ -498,9 +508,9 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return null; if (value instanceof Long || value instanceof Integer || value instanceof Short || value instanceof Byte) - return new BigDecimal(Long.valueOf(value.toString())); + return new BigDecimal(Long.parseLong(value.toString())); if (value instanceof Double || value instanceof Float) - return new BigDecimal(Double.valueOf(value.toString())); + return BigDecimal.valueOf(Double.parseDouble(value.toString())); if (value instanceof Timestamp) return new BigDecimal(((Timestamp) value).getTime()); BigDecimal ret; @@ -610,36 +620,6 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { if (isClosed()) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_RESULTSET_CLOSED); -// if (this.resultSet.size() == 0) -// return false; -// -// if (row == 0) { -// beforeFirst(); -// return false; -// } else if (row == 1) { -// return first(); -// } else if (row == -1) { -// return last(); -// } else if (row > this.resultSet.size()) { -// afterLast(); -// return false; -// } else { -// if (row < 0) { -// // adjust to reflect after end of result set -// int newRowPosition = this.resultSet.size() + row + 1; -// if (newRowPosition <= 0) { -// beforeFirst(); -// return false; -// } else { -// return absolute(newRowPosition); -// } -// } else { -// row--; // adjust for index difference -// this.pos = row; -// return true; -// } -// } - throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD); } @@ -683,5 +663,4 @@ public class RestfulResultSet extends AbstractResultSet implements ResultSet { return isClosed; } - -} +} \ No newline at end of file diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java index 7ead8bd1bbaeeb8fe1f24c951656888f6bba6b6f..148f77974fcec9a997ade815f56b12564e537f58 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java @@ -7,21 +7,20 @@ import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Timestamp; import java.sql.Types; -import java.util.ArrayList; +import java.util.Collections; +import java.util.List; public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMetaData { private final String database; - private ArrayList fields; - private final RestfulResultSet resultSet; + private final List fields; - public RestfulResultSetMetaData(String database, ArrayList fields, RestfulResultSet resultSet) { + public RestfulResultSetMetaData(String database, List fields, RestfulResultSet resultSet) { this.database = database; - this.fields = fields; - this.resultSet = resultSet; + this.fields = fields == null ? Collections.emptyList() : fields; } - public ArrayList getFields() { + public List getFields() { return fields; } @@ -139,8 +138,8 @@ public class RestfulResultSetMetaData extends WrapperImpl implements ResultSetMe @Override public String getColumnTypeName(int column) throws SQLException { - int taos_type = fields.get(column - 1).taos_type; - return TSDBConstants.taosType2JdbcTypeName(taos_type); + int taosType = fields.get(column - 1).taos_type; + return TSDBConstants.taosType2JdbcTypeName(taosType); } @Override diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java index fbc3a50a27a18db069a25ea86fe37027dca42f1f..f8acd8f06180476a09519c0809dd493d062c911c 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java @@ -35,10 +35,6 @@ public class RestfulStatement extends AbstractStatement { if (!SqlSyntaxValidator.isValidForExecuteQuery(sql)) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_QUERY, "not a valid sql for executeQuery: " + sql); - if (SqlSyntaxValidator.isDatabaseUnspecifiedQuery(sql)) { - return executeOneQuery(sql); - } - return executeOneQuery(sql); } @@ -50,9 +46,6 @@ public class RestfulStatement extends AbstractStatement { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql); final String url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sql"; - if (SqlSyntaxValidator.isDatabaseUnspecifiedUpdate(sql)) { - return executeOneUpdate(url, sql); - } return executeOneUpdate(url, sql); } @@ -83,7 +76,7 @@ public class RestfulStatement extends AbstractStatement { } if (SqlSyntaxValidator.isUseSql(sql)) { - HttpClientPoolUtil.execute(url, sql); + HttpClientPoolUtil.execute(url, sql, this.conn.getToken()); this.database = sql.trim().replace("use", "").trim(); this.conn.setCatalog(this.database); result = false; @@ -116,7 +109,7 @@ public class RestfulStatement extends AbstractStatement { if ("UTC".equalsIgnoreCase(timestampFormat)) url = "http://" + conn.getHost() + ":" + conn.getPort() + "/rest/sqlutc"; - String result = HttpClientPoolUtil.execute(url, sql); + String result = HttpClientPoolUtil.execute(url, sql, this.conn.getToken()); JSONObject resultJson = JSON.parseObject(result); if (resultJson.getString("status").equals("error")) { throw TSDBError.createSQLException(resultJson.getInteger("code"), resultJson.getString("desc")); @@ -130,7 +123,7 @@ public class RestfulStatement extends AbstractStatement { if (!SqlSyntaxValidator.isValidForExecuteUpdate(sql)) throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_FOR_EXECUTE_UPDATE, "not a valid sql for executeUpdate: " + sql); - String result = HttpClientPoolUtil.execute(url, sql); + String result = HttpClientPoolUtil.execute(url, sql, this.conn.getToken()); JSONObject jsonObject = JSON.parseObject(result); if (jsonObject.getString("status").equals("error")) { throw TSDBError.createSQLException(jsonObject.getInteger("code"), jsonObject.getString("desc")); diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java index 5e2440fd1d0e551690c5f17fe60b30c1d4a377dc..715b051b74840cd01968957ab35493db2f53c5f6 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java @@ -16,43 +16,31 @@ 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 { - public static PoolingHttpClientConnectionManager cm = null; - public static CloseableHttpClient httpClient = null; - public static String token = "cm9vdDp0YW9zZGF0YQ=="; - /** - * 默认content 类型 - */ + private static final String DEFAULT_CONTENT_TYPE = "application/json"; - /** - * 默认请求超时时间30s - */ private static final int DEFAULT_TIME_OUT = 15000; - private static final int count = 32; - private static final int totalCount = 1000; - private static final int Http_Default_Keep_Time = 15000; + private static final int DEFAULT_MAX_PER_ROUTE = 32; + private static final int DEFAULT_MAX_TOTAL = 1000; + private static final int DEFAULT_HTTP_KEEP_TIME = 15000; + + private static CloseableHttpClient httpClient; - /** - * 初始化连接池 - */ private static synchronized void initPools() { if (httpClient == null) { - cm = new PoolingHttpClientConnectionManager(); - cm.setDefaultMaxPerRoute(count); - cm.setMaxTotal(totalCount); - httpClient = HttpClients.custom().setKeepAliveStrategy(defaultStrategy).setConnectionManager(cm).build(); + PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(); + connectionManager.setDefaultMaxPerRoute(DEFAULT_MAX_PER_ROUTE); + connectionManager.setMaxTotal(DEFAULT_MAX_TOTAL); + httpClient = HttpClients.custom().setKeepAliveStrategy(DEFAULT_KEEP_ALIVE_STRATEGY).setConnectionManager(connectionManager).build(); } } - /** - * Http connection keepAlive 设置 - */ - private static ConnectionKeepAliveStrategy defaultStrategy = (response, context) -> { + private static final ConnectionKeepAliveStrategy DEFAULT_KEEP_ALIVE_STRATEGY = (response, context) -> { HeaderElementIterator it = new BasicHeaderElementIterator(response.headerIterator(HTTP.CONN_KEEP_ALIVE)); - int keepTime = Http_Default_Keep_Time * 1000; + int keepTime = DEFAULT_HTTP_KEEP_TIME * 1000; while (it.hasNext()) { HeaderElement headerElement = it.nextElement(); String param = headerElement.getName(); @@ -76,7 +64,7 @@ public class HttpClientPoolUtil { * @param data 请求数据 * @return responseBody */ - public static String execute(String uri, String data) { + public static String execute(String uri, String data, String token) { long startTime = System.currentTimeMillis(); HttpEntity httpEntity = null; HttpEntityEnclosingRequestBase method = null; @@ -90,7 +78,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(); @@ -175,28 +163,18 @@ public class HttpClientPoolUtil { httpEntity = httpResponse.getEntity(); if (httpEntity != null) { responseBody = EntityUtils.toString(httpEntity, "UTF-8"); -// logger.info("请求URL: " + uri + "+ 返回状态码:" + httpResponse.getStatusLine().getStatusCode()); } } catch (Exception e) { if (method != null) { method.abort(); } e.printStackTrace(); -// logger.error("execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" -// + (System.currentTimeMillis() - startTime)); - System.out.println("log:调用 HttpClientPoolUtil execute get request exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" - + (System.currentTimeMillis() - startTime)); } finally { if (httpEntity != null) { try { EntityUtils.consumeQuietly(httpEntity); } catch (Exception e) { -// e.printStackTrace(); -// logger.error("close response exception, url:" + uri + ", exception:" + e.toString() -// + ",cost time(ms):" + (System.currentTimeMillis() - startTime)); - new Exception("close response exception, url:" + uri + ", exception:" + e.toString() - + ",cost time(ms):" + (System.currentTimeMillis() - startTime)) - .printStackTrace(); + new Exception("close response exception, url:" + uri + ", exception:" + e.toString() + ",cost time(ms):" + (System.currentTimeMillis() - startTime)).printStackTrace(); } } } diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/SqlSyntaxValidator.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/SqlSyntaxValidator.java index 251ca2af013e2b1c9cb314b776621455c91d9384..15faa41a27c8aef9359ef938975648b5c10f4a9f 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/SqlSyntaxValidator.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/SqlSyntaxValidator.java @@ -14,10 +14,6 @@ *****************************************************************************/ package com.taosdata.jdbc.utils; -import com.taosdata.jdbc.TSDBConnection; - -import java.sql.Connection; - public class SqlSyntaxValidator { private static final String[] SQL = {"select", "insert", "import", "create", "use", "alter", "drop", "set", "show", "describe"}; @@ -26,12 +22,6 @@ public class SqlSyntaxValidator { private static final String[] databaseUnspecifiedShow = {"databases", "dnodes", "mnodes", "variables"}; - private TSDBConnection tsdbConnection; - - public SqlSyntaxValidator(Connection connection) { - this.tsdbConnection = (TSDBConnection) connection; - } - public static boolean isValidForExecuteUpdate(String sql) { for (String prefix : updateSQL) { if (sql.trim().toLowerCase().startsWith(prefix)) diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java index eeb936a1d0843c56e0de63a6c4b113fb644b778f..e3179bd317b24844e62a7071e1bc595d0e24d12b 100644 --- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java +++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java @@ -3,14 +3,14 @@ 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.nio.charset.StandardCharsets; 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 +25,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,18 +106,11 @@ 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[0]; - if (SqlSyntaxValidator.isInsertSql(preparedSql)) { - // insert or import - clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)"}; - } - if (SqlSyntaxValidator.isSelectSql(preparedSql)) { - // select - clause = new String[]{"where\\s*.*"}; - } + String[] clause = new String[]{"values\\s*\\(.*?\\)", "tags\\s*\\(.*?\\)", "where\\s*.*"}; Map placeholderPositions = new HashMap<>(); RangeSet clauseRangeSet = TreeRangeSet.create(); findPlaceholderPosition(preparedSql, placeholderPositions); @@ -155,7 +161,7 @@ public class Utils { String paraStr; if (para != null) { if (para instanceof byte[]) { - paraStr = new String((byte[]) para, Charset.forName("UTF-8")); + paraStr = new String((byte[]) para, StandardCharsets.UTF_8); } else { paraStr = para.toString(); } @@ -176,13 +182,47 @@ public class Utils { }).collect(Collectors.joining()); } - public static String formatTimestamp(Timestamp timestamp) { int nanos = timestamp.getNanos(); if (nanos % 1000000l != 0) - return timestamp.toLocalDateTime().format(formatter2); - return timestamp.toLocalDateTime().format(formatter); + return timestamp.toLocalDateTime().format(microSecFormatter); + return timestamp.toLocalDateTime().format(milliSecFormatter); } + public static TimestampPrecision guessTimestampPrecision(String value) { + if (isMilliSecFormat(value)) + return TimestampPrecision.MS; + if (isMicroSecFormat(value)) + return TimestampPrecision.US; + if (isNanoSecFormat(value)) + return TimestampPrecision.NS; + return TimestampPrecision.UNKNOWN; + } + private static boolean isMilliSecFormat(String timestampStr) { + try { + milliSecFormatter.parse(timestampStr); + } catch (DateTimeParseException e) { + return false; + } + return true; + } + + private static boolean isMicroSecFormat(String timestampStr) { + try { + microSecFormatter.parse(timestampStr); + } catch (DateTimeParseException e) { + return false; + } + return true; + } + + private static boolean isNanoSecFormat(String timestampStr) { + try { + nanoSecFormatter.parse(timestampStr); + } catch (DateTimeParseException e) { + return false; + } + return true; + } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StatementTest.java deleted file mode 100644 index 73ceafa7299b256d7e83064b53bd638835a4b075..0000000000000000000000000000000000000000 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/StatementTest.java +++ /dev/null @@ -1,108 +0,0 @@ -package com.taosdata.jdbc; - -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.sql.*; -import java.util.Properties; - -public class StatementTest { - static Connection connection = null; - static Statement statement = null; - static String dbName = "test"; - static String tName = "t0"; - static String host = "localhost"; - - @BeforeClass - public static void createConnection() throws SQLException { - try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); - 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"); - connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/?user=root&password=taosdata", properties); - statement = connection.createStatement(); - statement.executeUpdate("drop database if exists " + dbName); - - } catch (ClassNotFoundException e) { - return; - } - } - - @Test - public void testCase() { - try { - ResultSet rs = statement.executeQuery("show databases"); - ResultSetMetaData metaData = rs.getMetaData(); - while (rs.next()) { - for (int i = 1; i <= metaData.getColumnCount(); i++) { - System.out.print(metaData.getColumnLabel(i) + ":" + rs.getString(i) + "\t"); - } - System.out.println(); - } - } catch (SQLException e) { - e.printStackTrace(); - } - } - - @Test - public void createTableAndQuery() throws SQLException { - long ts = System.currentTimeMillis(); - - statement.executeUpdate("create database if not exists " + dbName); - statement.executeUpdate("create table if not exists " + dbName + "." + tName + "(ts timestamp, k1 int)"); - statement.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", 1)"); - statement.execute("select * from " + dbName + "." + tName); - ResultSet resultSet = statement.getResultSet(); - Assert.assertNotNull(resultSet); - - boolean isClosed = statement.isClosed(); - Assert.assertEquals(false, isClosed); - } - - @Test(expected = SQLException.class) - public void testUnsupport() throws SQLException { - Assert.assertNotNull(statement.unwrap(TSDBStatement.class)); - Assert.assertTrue(statement.isWrapperFor(TSDBStatement.class)); - - statement.getMaxFieldSize(); - statement.setMaxFieldSize(0); - statement.setEscapeProcessing(true); - statement.cancel(); - statement.getWarnings(); - statement.clearWarnings(); - statement.setCursorName(null); - statement.getMoreResults(); - statement.setFetchDirection(0); - statement.getFetchDirection(); - statement.getResultSetConcurrency(); - statement.getResultSetType(); - statement.getConnection(); - statement.getMoreResults(); - statement.getGeneratedKeys(); - statement.executeUpdate(null, 0); - statement.executeUpdate(null, new int[]{0}); - statement.executeUpdate(null, new String[]{"str1", "str2"}); - statement.getResultSetHoldability(); - statement.setPoolable(true); - statement.isPoolable(); - statement.closeOnCompletion(); - statement.isCloseOnCompletion(); - } - - @AfterClass - public static void close() { - try { - statement.execute("drop database if exists " + dbName); - if (statement != null) - statement.close(); - if (connection != null) - connection.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } -} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java index ca7251bb0eac306d6a21872699918e18b2447e6e..30c6d99a4093f4781c20dcd0a960b4456ef50dbe 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java @@ -32,20 +32,34 @@ public class TSDBConnectionTest { } @Test - public void subscribe() { + public void runSubscribe() { try { + // given TSDBConnection unwrap = conn.unwrap(TSDBConnection.class); TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false); + // when TSDBResultSet rs = subscribe.consume(); ResultSetMetaData metaData = rs.getMetaData(); - for (int count = 0; count < 10 && rs.next(); count++) { - for (int i = 1; i <= metaData.getColumnCount(); i++) { - String value = rs.getString(i); - System.out.print(metaData.getColumnLabel(i) + ":" + value + "\t"); - } - System.out.println(); - } + + // then Assert.assertNotNull(rs); + Assert.assertEquals(4, metaData.getColumnCount()); + Assert.assertEquals("ts", metaData.getColumnLabel(1)); + Assert.assertEquals("level", metaData.getColumnLabel(2)); + Assert.assertEquals("content", metaData.getColumnLabel(3)); + Assert.assertEquals("ipaddr", metaData.getColumnLabel(4)); + rs.next(); + // row 1 + { + Assert.assertNotNull(rs.getTimestamp(1)); + Assert.assertNotNull(rs.getTimestamp("ts")); + Assert.assertNotNull(rs.getByte(2)); + Assert.assertNotNull(rs.getByte("level")); + Assert.assertNotNull(rs.getString(3)); + Assert.assertNotNull(rs.getString("content")); + Assert.assertNotNull(rs.getString(4)); + Assert.assertNotNull(rs.getString("ipaddr")); + } subscribe.close(false); } catch (SQLException e) { e.printStackTrace(); @@ -366,14 +380,15 @@ public class TSDBConnectionTest { conn.abort(null); } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void setNetworkTimeout() throws SQLException { conn.setNetworkTimeout(null, 1000); } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void getNetworkTimeout() throws SQLException { - conn.getNetworkTimeout(); + int networkTimeout = conn.getNetworkTimeout(); + Assert.assertEquals(0, networkTimeout); } @Test diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java index a7657fa3e581c96cf85555b16fca5f8b4c7f8ebb..cb6133015c0256de99ea4db02bedeb982ce7491d 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java @@ -7,9 +7,11 @@ import java.util.Properties; public class TSDBDatabaseMetaDataTest { private static final String host = "127.0.0.1"; + private static final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; private static Connection connection; private static TSDBDatabaseMetaData metaData; + @Test public void unwrap() throws SQLException { TSDBDatabaseMetaData unwrap = metaData.unwrap(TSDBDatabaseMetaData.class); @@ -33,7 +35,7 @@ public class TSDBDatabaseMetaDataTest { @Test public void getURL() throws SQLException { - Assert.assertEquals("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", metaData.getURL()); + Assert.assertEquals(url, metaData.getURL()); } @Test @@ -627,17 +629,32 @@ public class TSDBDatabaseMetaDataTest { @Test public void getTables() throws SQLException { - System.out.println("****************************************************"); - ResultSet tables = metaData.getTables("log", "", null, null); - ResultSetMetaData metaData = tables.getMetaData(); - while (tables.next()) { - System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t"); - System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t"); - System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t"); - System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n"); + ResultSet rs = metaData.getTables("log", "", null, null); + ResultSetMetaData meta = rs.getMetaData(); + Assert.assertNotNull(rs); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_SCHEM + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertNotNull(rs.getString(3)); + Assert.assertNotNull(rs.getString("TABLE_NAME")); + // TABLE_TYPE + Assert.assertEquals("TABLE_TYPE", meta.getColumnLabel(4)); + Assert.assertEquals("TABLE", rs.getString(4)); + Assert.assertEquals("TABLE", rs.getString("TABLE_TYPE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(5)); + Assert.assertEquals("", rs.getString(5)); + Assert.assertEquals("", rs.getString("REMARKS")); } - System.out.println(); - Assert.assertNotNull(tables); } @Test @@ -647,46 +664,130 @@ public class TSDBDatabaseMetaDataTest { @Test public void getCatalogs() throws SQLException { - System.out.println("****************************************************"); - - ResultSet catalogs = metaData.getCatalogs(); - ResultSetMetaData meta = catalogs.getMetaData(); - while (catalogs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i)); - } - System.out.println(); + ResultSet rs = metaData.getCatalogs(); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertNotNull(rs.getString(1)); + Assert.assertNotNull(rs.getString("TABLE_CAT")); } } @Test public void getTableTypes() throws SQLException { - System.out.println("****************************************************"); - ResultSet tableTypes = metaData.getTableTypes(); - while (tableTypes.next()) { - System.out.println(tableTypes.getString("TABLE_TYPE")); + tableTypes.next(); + // tableTypes: table + { + Assert.assertEquals("TABLE", tableTypes.getString(1)); + Assert.assertEquals("TABLE", tableTypes.getString("TABLE_TYPE")); + } + tableTypes.next(); + // tableTypes: stable + { + Assert.assertEquals("STABLE", tableTypes.getString(1)); + Assert.assertEquals("STABLE", tableTypes.getString("TABLE_TYPE")); } - Assert.assertNotNull(metaData.getTableTypes()); } @Test public void getColumns() throws SQLException { - System.out.println("****************************************************"); - + // when ResultSet columns = metaData.getColumns("log", "", "dn", ""); + // then ResultSetMetaData meta = columns.getMetaData(); - while (columns.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t"); - System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t"); - System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t"); - System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t"); - System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t"); - System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n"); - System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n"); + columns.next(); + // column: 1 + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", columns.getString(1)); + Assert.assertEquals("log", columns.getString("TABLE_CAT")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn", columns.getString(3)); + Assert.assertEquals("dn", columns.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("ts", columns.getString(4)); + Assert.assertEquals("ts", columns.getString("COLUMN_NAME")); + // DATA_TYPE + Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5)); + Assert.assertEquals(Types.TIMESTAMP, columns.getInt(5)); + Assert.assertEquals(Types.TIMESTAMP, columns.getInt("DATA_TYPE")); + // TYPE_NAME + Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("TIMESTAMP", columns.getString(6)); + Assert.assertEquals("TIMESTAMP", columns.getString("TYPE_NAME")); + // COLUMN_SIZE + Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7)); + Assert.assertEquals(26, columns.getInt(7)); + Assert.assertEquals(26, columns.getInt("COLUMN_SIZE")); + // DECIMAL_DIGITS + Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS")); + Assert.assertEquals(null, columns.getString(9)); + Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS")); + // NUM_PREC_RADIX + Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10)); + Assert.assertEquals(10, columns.getInt(10)); + Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX")); + // NULLABLE + Assert.assertEquals("NULLABLE", meta.getColumnLabel(11)); + Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt(11)); + Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt("NULLABLE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(12)); + Assert.assertEquals(null, columns.getString(12)); + Assert.assertEquals(null, columns.getString("REMARKS")); + } + columns.next(); + // column: 2 + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", columns.getString(1)); + Assert.assertEquals("log", columns.getString("TABLE_CAT")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn", columns.getString(3)); + Assert.assertEquals("dn", columns.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("cpu_taosd", columns.getString(4)); + Assert.assertEquals("cpu_taosd", columns.getString("COLUMN_NAME")); + // DATA_TYPE + Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5)); + Assert.assertEquals(Types.FLOAT, columns.getInt(5)); + Assert.assertEquals(Types.FLOAT, columns.getInt("DATA_TYPE")); + // TYPE_NAME + Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("FLOAT", columns.getString(6)); + Assert.assertEquals("FLOAT", columns.getString("TYPE_NAME")); + // COLUMN_SIZE + Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7)); + Assert.assertEquals(12, columns.getInt(7)); + Assert.assertEquals(12, columns.getInt("COLUMN_SIZE")); + // DECIMAL_DIGITS + Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS")); + Assert.assertEquals(null, columns.getString(9)); + Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS")); + // NUM_PREC_RADIX + Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10)); + Assert.assertEquals(10, columns.getInt(10)); + Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX")); + // NULLABLE + Assert.assertEquals("NULLABLE", meta.getColumnLabel(11)); + Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt(11)); + Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt("NULLABLE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(12)); + Assert.assertEquals(null, columns.getString(12)); } } @@ -712,17 +813,35 @@ public class TSDBDatabaseMetaDataTest { @Test public void getPrimaryKeys() throws SQLException { - System.out.println("****************************************************"); - ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1"); - while (rs.next()) { - System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); - System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME")); - System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ")); - System.out.println("PK_NAME: " + rs.getString("PK_NAME")); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_SCHEM + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn1", rs.getString(3)); + Assert.assertEquals("dn1", rs.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("ts", rs.getString(4)); + Assert.assertEquals("ts", rs.getString("COLUMN_NAME")); + // KEY_SEQ + Assert.assertEquals("KEY_SEQ", meta.getColumnLabel(5)); + Assert.assertEquals(1, rs.getShort(5)); + Assert.assertEquals(1, rs.getShort("KEY_SEQ")); + // DATA_TYPE + Assert.assertEquals("PK_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("ts", rs.getString(6)); + Assert.assertEquals("ts", rs.getString("PK_NAME")); } - - Assert.assertNotNull(rs); } @Test @@ -847,14 +966,27 @@ public class TSDBDatabaseMetaDataTest { @Test public void getSuperTables() throws SQLException { - System.out.println("****************************************************"); - ResultSet rs = metaData.getSuperTables("log", "", "dn1"); - while (rs.next()) { - System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); - System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME")); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_CAT + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_CAT + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn1", rs.getString(3)); + Assert.assertEquals("dn1", rs.getString("TABLE_NAME")); + // TABLE_CAT + Assert.assertEquals("SUPERTABLE_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("dn", rs.getString(4)); + Assert.assertEquals("dn", rs.getString("SUPERTABLE_NAME")); } - Assert.assertNotNull(rs); } @Test @@ -951,15 +1083,12 @@ public class TSDBDatabaseMetaDataTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); 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"); - connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties); + connection = DriverManager.getConnection(url, properties); metaData = connection.getMetaData().unwrap(TSDBDatabaseMetaData.class); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java index 161539962da5e26e928a669083954cc0817483a2..b5f8114bffe9a4490f3189a54cf724354e9394a5 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java @@ -1,12 +1,17 @@ package com.taosdata.jdbc; import org.junit.Test; +import static org.junit.Assert.*; import java.sql.SQLException; import java.sql.SQLWarning; import java.util.ArrayList; import java.util.List; +import java.lang.management.ManagementFactory; +import java.lang.management.RuntimeMXBean; +import java.lang.management.ThreadMXBean; + public class TSDBJNIConnectorTest { private static TSDBResultSetRowData rowData; @@ -14,17 +19,68 @@ public class TSDBJNIConnectorTest { @Test public void test() { try { + + try { + //change sleepSeconds when debugging with attach to process to find PID + int sleepSeconds = -1; + if (sleepSeconds>0) { + RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean(); + String jvmName = runtimeBean.getName(); + long pid = Long.valueOf(jvmName.split("@")[0]); + System.out.println("JVM PID = " + pid); + + Thread.sleep(sleepSeconds*1000); + } + } + catch (Exception e) { + e.printStackTrace(); + } + // init - TSDBJNIConnector.init("/etc/taos/taos.cfg", null, null, null); + TSDBJNIConnector.init("/etc/taos", null, null, null); + // connect TSDBJNIConnector connector = new TSDBJNIConnector(); - connector.connect("127.0.0.1", 6030, "unsign_jni", "root", "taosdata"); + connector.connect("127.0.0.1", 6030, null, "root", "taosdata"); + + // setup + String setupSqlStrs[] = {"create database if not exists d precision \"us\"", + "create table if not exists d.t(ts timestamp, f int)", + "create database if not exists d2", + "create table if not exists d2.t2(ts timestamp, f int)", + "insert into d.t values(now+100s, 100)", + "insert into d2.t2 values(now+200s, 200)" + }; + for (String setupSqlStr : setupSqlStrs) { + long setupSql = connector.executeQuery(setupSqlStr); + + assertEquals(0, connector.getResultTimePrecision(setupSql)); + if (connector.isUpdateQuery(setupSql)) { + connector.freeResultSet(setupSql); + } + } + + { + long sqlObj1 = connector.executeQuery("select * from d2.t2"); + assertEquals(0, connector.getResultTimePrecision(sqlObj1)); + List columnMetaDataList = new ArrayList<>(); + int code = connector.getSchemaMetaData(sqlObj1, columnMetaDataList); + rowData = new TSDBResultSetRowData(columnMetaDataList.size()); + assertTrue(next(connector, sqlObj1)); + assertEquals(0, connector.getResultTimePrecision(sqlObj1)); + connector.freeResultSet(sqlObj1); + } + // executeQuery - long pSql = connector.executeQuery("select * from unsign_jni.us_table"); + long pSql = connector.executeQuery("select * from d.t"); + if (connector.isUpdateQuery(pSql)) { connector.freeResultSet(pSql); throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY); } + + assertEquals(1, connector.getResultTimePrecision(pSql)); + // get schema List columnMetaDataList = new ArrayList<>(); int code = connector.getSchemaMetaData(pSql, columnMetaDataList); @@ -37,6 +93,8 @@ public class TSDBJNIConnectorTest { if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) { throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_JNI_NUM_OF_FIELDS_0); } + + assertEquals(1, connector.getResultTimePrecision(pSql)); int columnSize = columnMetaDataList.size(); // print metadata for (int i = 0; i < columnSize; i++) { @@ -45,8 +103,7 @@ 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")); + assertEquals(1, connector.getResultTimePrecision(pSql)); System.out.println(); } // close resultSet @@ -86,4 +143,4 @@ public class TSDBJNIConnectorTest { } } -} \ No newline at end of file +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java index 12bcc4391767e129289fae0a945d048570a18bc5..83caf1bebb72ec813683b083388e51b9dab2afc9 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java @@ -54,16 +54,17 @@ public class TSDBParameterMetaDataTest { @Test public void getPrecision() throws SQLException { - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); - Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); - Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); + //create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) + Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1)); + Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2)); + Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3)); + Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4)); + Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5)); + Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6)); + Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7)); + Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8)); + Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9)); + Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10)); } @Test @@ -71,8 +72,8 @@ public class TSDBParameterMetaDataTest { Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); - Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); - Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); + Assert.assertEquals(31, parameterMetaData_insert.getScale(4)); + Assert.assertEquals(31, parameterMetaData_insert.getScale(5)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); @@ -124,10 +125,16 @@ public class TSDBParameterMetaDataTest { @Test public void getParameterMode() throws SQLException { - for (int i = 1; i <= parameterMetaData_insert.getParameterCount(); i++) { - int parameterMode = parameterMetaData_insert.getParameterMode(i); - Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMode); - } + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(1)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(2)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(3)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(4)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(5)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(6)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(7)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(8)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(9)); + Assert.assertEquals(ParameterMetaData.parameterModeUnknown, parameterMetaData_insert.getParameterMode(10)); } @Test @@ -144,7 +151,6 @@ public class TSDBParameterMetaDataTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); try (Statement stmt = conn.createStatement()) { stmt.execute("drop database if exists test_pstmt"); @@ -164,7 +170,7 @@ public class TSDBParameterMetaDataTest { pstmt_insert.setObject(7, Byte.MAX_VALUE); pstmt_insert.setObject(8, true); pstmt_insert.setObject(9, "hello".getBytes()); - pstmt_insert.setObject(10, "Hello"); + pstmt_insert.setObject(10, "涛思数据"); parameterMetaData_insert = pstmt_insert.getParameterMetaData(); pstmt_select = conn.prepareStatement(sql_select); @@ -173,7 +179,7 @@ public class TSDBParameterMetaDataTest { pstmt_select.setInt(3, 0); parameterMetaData_select = pstmt_select.getParameterMetaData(); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java index 52858e7f88c9375ea6ff0282fbe0519b9953a121..40ff5c23ef9866d0a7d8fd5c594f2b933ed80b2a 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java @@ -1,152 +1,351 @@ package com.taosdata.jdbc; -import org.junit.AfterClass; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.*; import java.io.IOException; -import java.io.Serializable; +import java.math.BigDecimal; import java.sql.*; import java.util.ArrayList; import java.util.Random; public class TSDBPreparedStatementTest { + private static final String host = "127.0.0.1"; private static Connection conn; private static final String sql_insert = "insert into t1 values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)"; - private static PreparedStatement pstmt_insert; - private static final String sql_select = "select * from t1 where ts > ? and ts <= ? and f1 >= ?"; - private static PreparedStatement pstmt_select; + 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; + //create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64)) @Test public void executeQuery() throws SQLException { - long end = System.currentTimeMillis(); - long start = end - 1000 * 60 * 60; + // given + long ts = System.currentTimeMillis(); + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setInt(2, 2); + pstmt_insert.setLong(3, 3l); + pstmt_insert.setFloat(4, 3.14f); + pstmt_insert.setDouble(5, 3.1415); + pstmt_insert.setShort(6, (short) 6); + pstmt_insert.setByte(7, (byte) 7); + pstmt_insert.setBoolean(8, true); + pstmt_insert.setBytes(9, "abc".getBytes()); + pstmt_insert.setString(10, "涛思数据"); + pstmt_insert.executeUpdate(); + long start = ts - 1000 * 60 * 60; + long end = ts + 1000 * 60 * 60; pstmt_select.setTimestamp(1, new Timestamp(start)); pstmt_select.setTimestamp(2, new Timestamp(end)); pstmt_select.setInt(3, 0); + // when ResultSet rs = pstmt_select.executeQuery(); - Assert.assertNotNull(rs); ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); + rs.next(); + + // then + assertMetaData(meta); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(2, rs.getInt(2)); + Assert.assertEquals(2, rs.getInt("f1")); + Assert.assertEquals(3l, rs.getLong(3)); + Assert.assertEquals(3l, rs.getLong("f2")); + Assert.assertEquals(3.14f, rs.getFloat(4), 0.0); + Assert.assertEquals(3.14f, rs.getFloat("f3"), 0.0); + Assert.assertEquals(3.1415, rs.getDouble(5), 0.0); + Assert.assertEquals(3.1415, rs.getDouble("f4"), 0.0); + Assert.assertEquals((short) 6, rs.getShort(6)); + Assert.assertEquals((short) 6, rs.getShort("f5")); + Assert.assertEquals((byte) 7, rs.getByte(7)); + Assert.assertEquals((byte) 7, rs.getByte("f6")); + Assert.assertTrue(rs.getBoolean(8)); + Assert.assertTrue(rs.getBoolean("f7")); + Assert.assertArrayEquals("abc".getBytes(), rs.getBytes(9)); + Assert.assertArrayEquals("abc".getBytes(), rs.getBytes("f8")); + Assert.assertEquals("涛思数据", rs.getString(10)); + Assert.assertEquals("涛思数据", rs.getString("f9")); } } - @Test - public void executeUpdate() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setFloat(4, 3.14f); - int result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); + private void assertMetaData(ResultSetMetaData meta) throws SQLException { + Assert.assertEquals(10, meta.getColumnCount()); + Assert.assertEquals("ts", meta.getColumnLabel(1)); + Assert.assertEquals("f1", meta.getColumnLabel(2)); + Assert.assertEquals("f2", meta.getColumnLabel(3)); + Assert.assertEquals("f3", meta.getColumnLabel(4)); + Assert.assertEquals("f4", meta.getColumnLabel(5)); + Assert.assertEquals("f5", meta.getColumnLabel(6)); + Assert.assertEquals("f6", meta.getColumnLabel(7)); + Assert.assertEquals("f7", meta.getColumnLabel(8)); + Assert.assertEquals("f8", meta.getColumnLabel(9)); + Assert.assertEquals("f9", meta.getColumnLabel(10)); } @Test - public void setNull() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + public void setNullForTimestamp() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(2, Types.INTEGER); int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + private void assertAllNullExceptTimestamp(ResultSet rs, long ts) throws SQLException { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(0, rs.getInt(2)); + Assert.assertEquals(0, rs.getInt("f1")); + Assert.assertEquals(0, rs.getLong(3)); + Assert.assertEquals(0, rs.getLong("f2")); + Assert.assertEquals(0, rs.getFloat(4), 0.0); + Assert.assertEquals(0, rs.getFloat("f3"), 0.0); + Assert.assertEquals(0, rs.getDouble(5), 0.0); + Assert.assertEquals(0, rs.getDouble("f4"), 0.0); + Assert.assertEquals(0, rs.getShort(6)); + Assert.assertEquals(0, rs.getShort("f5")); + Assert.assertEquals(0, rs.getByte(7)); + Assert.assertEquals(0, rs.getByte("f6")); + Assert.assertFalse(rs.getBoolean(8)); + Assert.assertFalse(rs.getBoolean("f7")); + Assert.assertNull(rs.getBytes(9)); + Assert.assertNull(rs.getBytes("f8")); + Assert.assertNull(rs.getString(10)); + Assert.assertNull(rs.getString("f9")); + } + + @Test + public void setNullForInteger() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(3, Types.BIGINT); - result = pstmt_insert.executeUpdate(); + int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + @Test + public void setNullForFloat() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(4, Types.FLOAT); - result = pstmt_insert.executeUpdate(); + int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + @Test + public void setNullForDouble() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(5, Types.DOUBLE); - result = pstmt_insert.executeUpdate(); + int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + @Test + public void setNullForSmallInt() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(6, Types.SMALLINT); - result = pstmt_insert.executeUpdate(); + int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + @Test + public void setNullForTinyInt() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(7, Types.TINYINT); - result = pstmt_insert.executeUpdate(); + int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + @Test + public void setNullForBoolean() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(8, Types.BOOLEAN); - result = pstmt_insert.executeUpdate(); + int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + @Test + public void setNullForBinary() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(9, Types.BINARY); - result = pstmt_insert.executeUpdate(); + int result = pstmt_insert.executeUpdate(); + + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } + } - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + @Test + public void setNullForNchar() throws SQLException { + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setNull(10, Types.NCHAR); - result = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, result); + int result = pstmt_insert.executeUpdate(); - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setNull(10, Types.OTHER); - result = pstmt_insert.executeUpdate(); + // then Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + assertAllNullExceptTimestamp(rs, ts); + } } @Test - public void executeTest() throws SQLException { - Statement stmt = conn.createStatement(); + public void executeTest() throws SQLException { + Statement stmt = conn.createStatement(); - int numOfRows = 1000; + int numOfRows = 1000; - for (int loop = 0; loop < 10; loop++){ + for (int loop = 0; loop < 10; loop++) { stmt.execute("drop table if exists weather_test"); - stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); + stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? values(?, ?, ?, ?, ?, ?, ?, ?)"); Random r = new Random(); s.setTableName("weather_test"); - + ArrayList ts = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { + for (int i = 0; i < numOfRows; i++) { ts.add(System.currentTimeMillis() + i); - } + } s.setTimestamp(0, ts); int random = 10 + r.nextInt(5); - ArrayList s2 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + ArrayList s2 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s2.add(null); - }else{ + } else { s2.add("分支" + i % 4); } - } - s.setNString(1, s2, 4); + } + s.setNString(1, s2, 4); random = 10 + r.nextInt(5); - ArrayList s3 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + ArrayList s3 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s3.add(null); - }else{ + } else { s3.add(r.nextFloat()); } - } + } s.setFloat(2, s3); random = 10 + r.nextInt(5); ArrayList s4 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s4.add(null); - }else{ + } else { s4.add(r.nextDouble()); } } @@ -154,47 +353,47 @@ public class TSDBPreparedStatementTest { random = 10 + r.nextInt(5); ArrayList ts2 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { ts2.add(null); - }else{ + } else { ts2.add(System.currentTimeMillis() + i); } } s.setTimestamp(4, ts2); random = 10 + r.nextInt(5); - ArrayList vals = new ArrayList<>(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + ArrayList vals = new ArrayList<>(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { vals.add(null); - }else{ + } else { vals.add(r.nextInt()); - } + } } s.setInt(5, vals); random = 10 + r.nextInt(5); ArrayList sb = new ArrayList<>(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { sb.add(null); - }else{ + } else { sb.add(i % 2 == 0 ? true : false); } } - s.setBoolean(6, sb); + s.setBoolean(6, sb); random = 10 + r.nextInt(5); ArrayList s5 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s5.add(null); - }else{ + } else { s5.add("test" + i % 10); } } - s.setString(7, s5, 10); + s.setString(7, s5, 10); s.columnDataAddBatch(); s.columnDataExecuteBatch(); @@ -204,54 +403,132 @@ public class TSDBPreparedStatementTest { PreparedStatement statement = conn.prepareStatement(sql); ResultSet rs = statement.executeQuery(); int rows = 0; - while(rs.next()) { + while (rs.next()) { rows++; } - Assert.assertEquals(numOfRows, rows); + Assert.assertEquals(numOfRows, rows); } } @Test - public void bindDataSelectColumnTest() throws SQLException { - Statement stmt = conn.createStatement(); + public void bindDataSelectColumnTest() throws SQLException { + Statement stmt = conn.createStatement(); - int numOfRows = 1000; + int numOfRows = 1000; - for (int loop = 0; loop < 10; loop++){ + for (int loop = 0; loop < 10; loop++) { stmt.execute("drop table if exists weather_test"); - stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); + stmt.execute("create table weather_test(ts timestamp, f1 nchar(4), f2 float, f3 double, f4 timestamp, f5 int, f6 bool, f7 binary(10))"); TSDBPreparedStatement s = (TSDBPreparedStatement) conn.prepareStatement("insert into ? (ts, f1, f7) values(?, ?, ?)"); Random r = new Random(); s.setTableName("weather_test"); - + ArrayList ts = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { + for (int i = 0; i < numOfRows; i++) { ts.add(System.currentTimeMillis() + i); - } + } s.setTimestamp(0, ts); int random = 10 + r.nextInt(5); - ArrayList s2 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { + ArrayList s2 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { s2.add(null); - }else{ + } else { s2.add("分支" + i % 4); } - } - s.setNString(1, s2, 4); + } + s.setNString(1, s2, 4); random = 10 + r.nextInt(5); - ArrayList s5 = new ArrayList(); - for(int i = 0; i < numOfRows; i++) { - if(i % random == 0) { - s5.add(null); - }else{ - s5.add("test" + i % 10); + ArrayList s3 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + if (i % random == 0) { + s3.add(null); + } else { + s3.add("test" + i % 10); } } - s.setString(2, s5, 10); + 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()) { + rows++; + } + Assert.assertEquals(numOfRows, rows); + } + } + + @Test + public void bindDataWithSingleTagTest() throws SQLException { + Statement stmt = conn.createStatement(); + + 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) { + case "tinyint": + case "smallint": + case "int": + case "bigint": + s.setTagInt(0, 1); + break; + case "float": + s.setTagFloat(0, 1.23f); + break; + case "double": + s.setTagDouble(0, 3.14159265); + break; + case "bool": + s.setTagBoolean(0, true); + break; + case "binary(10)": + s.setTagString(0, "test"); + break; + case "nchar(10)": + s.setTagNString(0, "test"); + break; + default: + break; + } + + + ArrayList ts = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + ts.add(System.currentTimeMillis() + i); + } + s.setTimestamp(0, ts); + + int random = 10 + r.nextInt(5); + ArrayList s2 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + s2.add("分支" + i % 4); + } + s.setNString(1, s2, 10); + + random = 10 + r.nextInt(5); + ArrayList s3 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + s3.add("test" + i % 4); + } + s.setString(2, s3, 10); s.columnDataAddBatch(); s.columnDataExecuteBatch(); @@ -261,144 +538,406 @@ 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 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"); + s.setTagInt(0, 1); + s.setTagString(1, "test"); + + + ArrayList ts = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + ts.add(System.currentTimeMillis() + i); + } + s.setTimestamp(0, ts); + + ArrayList s2 = new ArrayList(); + for (int i = 0; i < numOfRows; i++) { + s2.add("test" + i % 4); + } + s.setString(1, s2, 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()) { + rows++; + } + Assert.assertEquals(numOfRows, rows); + } + + @Test(expected = SQLException.class) + public void createTwoSameDbTest() throws SQLException { + // when + Statement stmt = conn.createStatement(); + stmt.execute("create database dbtest"); + stmt.execute("create database dbtest"); + } @Test public void setBoolean() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setBoolean(8, true); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertTrue(rs.getBoolean(8)); + Assert.assertTrue(rs.getBoolean("f7")); + } + } } @Test public void setByte() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setByte(7, (byte) 0x001); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals((byte) 0x001, rs.getByte(7)); + Assert.assertEquals((byte) 0x001, rs.getByte("f6")); + } + } } @Test public void setShort() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setShort(6, (short) 2); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals((short) 2, rs.getByte(6)); + Assert.assertEquals((short) 2, rs.getByte("f5")); + } + } } @Test public void setInt() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setInt(2, 10086); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(10086, rs.getInt(2)); + Assert.assertEquals(10086, rs.getInt("f1")); + } + } } @Test public void setLong() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setLong(3, Long.MAX_VALUE); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(Long.MAX_VALUE, rs.getLong(3)); + Assert.assertEquals(Long.MAX_VALUE, rs.getLong("f2")); + } + } } @Test public void setFloat() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setFloat(4, 3.14f); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(3.14f, rs.getFloat(4), 0.0f); + Assert.assertEquals(3.14f, rs.getFloat("f3"), 0.0f); + } + } } @Test public void setDouble() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); pstmt_insert.setDouble(5, 3.14444); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - } + int result = pstmt_insert.executeUpdate(); - @Test(expected = SQLFeatureNotSupportedException.class) - public void setBigDecimal() throws SQLException { - pstmt_insert.setBigDecimal(1, null); + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(3.14444, rs.getDouble(5), 0.0); + Assert.assertEquals(3.14444, rs.getDouble("f4"), 0.0); + } + } } @Test - public void setString() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setString(10, "aaaa"); - boolean execute = pstmt_insert.execute(); - Assert.assertFalse(execute); + public void setBigDecimal() throws SQLException { + // given + long ts = System.currentTimeMillis(); + BigDecimal bigDecimal = new BigDecimal(3.14444); - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setString(10, new Person("john", 33, true).toString()); - Assert.assertFalse(pstmt_insert.execute()); + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setBigDecimal(5, bigDecimal); + int result = pstmt_insert.executeUpdate(); - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setString(10, new Person("john", 33, true).toString().replaceAll("'", "\"")); - Assert.assertFalse(pstmt_insert.execute()); + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(3.14444, rs.getDouble(5), 0.0); + Assert.assertEquals(3.14444, rs.getDouble("f4"), 0.0); + } + } } - class Person { - String name; - int age; - boolean sex; + @Test + public void setString() throws SQLException { + // given + long ts = System.currentTimeMillis(); + String f9 = "{\"name\": \"john\", \"age\": 10, \"address\": \"192.168.1.100\"}"; - public Person(String name, int age, boolean sex) { - this.name = name; - this.age = age; - this.sex = sex; - } + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setString(10, f9); + int result = pstmt_insert.executeUpdate(); - @Override - public String toString() { - return "Person{" + - "name='" + name + '\'' + - ", age=" + age + - ", sex=" + sex + - '}'; + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertEquals(f9, rs.getString(10)); + Assert.assertEquals(f9, rs.getString("f9")); + } } } @Test public void setBytes() throws SQLException, IOException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + byte[] f8 = "{\"name\": \"john\", \"age\": 10, \"address\": \"192.168.1.100\"}".getBytes(); -// ByteArrayOutputStream baos = new ByteArrayOutputStream(); -// ObjectOutputStream oos = new ObjectOutputStream(baos); -// oos.writeObject(new Person("john", 33, true)); -// oos.flush(); -// byte[] bytes = baos.toByteArray(); -// pstmt_insert.setBytes(9, bytes); + // when + pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); + pstmt_insert.setBytes(9, f8); + int result = pstmt_insert.executeUpdate(); - pstmt_insert.setBytes(9, new Person("john", 33, true).toString().getBytes()); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + Assert.assertArrayEquals(f8, rs.getBytes(9)); + Assert.assertArrayEquals(f8, rs.getBytes("f8")); + } + } } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void setDate() throws SQLException { - pstmt_insert.setDate(1, new Date(System.currentTimeMillis())); + // given + long ts = new java.util.Date().getTime(); + + // when + pstmt_insert.setDate(1, new Date(ts)); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + } + } } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void setTime() throws SQLException { - pstmt_insert.setTime(1, new Time(System.currentTimeMillis())); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTime(1, new Time(ts)); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + } + } } @Test public void setTimestamp() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + int result = pstmt_insert.executeUpdate(); + + // then + Assert.assertEquals(1, result); + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from t1"); + ResultSetMetaData meta = rs.getMetaData(); + assertMetaData(meta); + rs.next(); + { + Assert.assertNotNull(rs); + Assert.assertEquals(ts, rs.getTimestamp(1).getTime()); + Assert.assertEquals(ts, rs.getTimestamp("ts").getTime()); + } + } } @Test(expected = SQLFeatureNotSupportedException.class) @@ -411,72 +950,6 @@ public class TSDBPreparedStatementTest { pstmt_insert.setBinaryStream(1, null); } - @Test - public void clearParameters() throws SQLException { - pstmt_insert.clearParameters(); - } - - @Test - public void setObject() throws SQLException { - pstmt_insert.setObject(1, new Timestamp(System.currentTimeMillis())); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(2, 111); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(3, Long.MAX_VALUE); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(4, 3.14159265354f); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(5, Double.MAX_VALUE); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(6, Short.MAX_VALUE); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(7, Byte.MAX_VALUE); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(8, true); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(9, "hello".getBytes()); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - pstmt_insert.setObject(10, "Hello"); - ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - } - - @Test - public void execute() throws SQLException { - pstmt_insert.setTimestamp(1, new Timestamp(System.currentTimeMillis())); - int ret = pstmt_insert.executeUpdate(); - Assert.assertEquals(1, ret); - - executeQuery(); - } - @Test(expected = SQLFeatureNotSupportedException.class) public void setCharacterStream() throws SQLException { pstmt_insert.setCharacterStream(1, null); @@ -502,9 +975,17 @@ public class TSDBPreparedStatementTest { pstmt_insert.setArray(1, null); } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void getMetaData() throws SQLException { - pstmt_insert.getMetaData(); + // given + long ts = System.currentTimeMillis(); + + // when + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + ResultSetMetaData metaData = pstmt_insert.getMetaData(); + + // then + Assert.assertNull(metaData); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -514,9 +995,46 @@ public class TSDBPreparedStatementTest { @Test public void getParameterMetaData() throws SQLException { + // given + long ts = System.currentTimeMillis(); + pstmt_insert.setTimestamp(1, new Timestamp(ts)); + pstmt_insert.setInt(2, 2); + pstmt_insert.setLong(3, 3l); + pstmt_insert.setFloat(4, 3.14f); + pstmt_insert.setDouble(5, 3.1415); + pstmt_insert.setShort(6, (short) 6); + pstmt_insert.setByte(7, (byte) 7); + pstmt_insert.setBoolean(8, true); + pstmt_insert.setBytes(9, "abc".getBytes()); + pstmt_insert.setString(10, "涛思数据"); + + // when ParameterMetaData parameterMetaData = pstmt_insert.getParameterMetaData(); + + // then Assert.assertNotNull(parameterMetaData); - //TODO: modify the test case + Assert.assertEquals(10, parameterMetaData.getParameterCount()); + Assert.assertEquals(Types.TIMESTAMP, parameterMetaData.getParameterType(1)); + Assert.assertEquals(Types.INTEGER, parameterMetaData.getParameterType(2)); + Assert.assertEquals(Types.BIGINT, parameterMetaData.getParameterType(3)); + Assert.assertEquals(Types.FLOAT, parameterMetaData.getParameterType(4)); + Assert.assertEquals(Types.DOUBLE, parameterMetaData.getParameterType(5)); + Assert.assertEquals(Types.SMALLINT, parameterMetaData.getParameterType(6)); + Assert.assertEquals(Types.TINYINT, parameterMetaData.getParameterType(7)); + Assert.assertEquals(Types.BOOLEAN, parameterMetaData.getParameterType(8)); + Assert.assertEquals(Types.BINARY, parameterMetaData.getParameterType(9)); + Assert.assertEquals(Types.NCHAR, parameterMetaData.getParameterType(10)); + + Assert.assertEquals("TIMESTAMP", parameterMetaData.getParameterTypeName(1)); + Assert.assertEquals("INT", parameterMetaData.getParameterTypeName(2)); + Assert.assertEquals("BIGINT", parameterMetaData.getParameterTypeName(3)); + Assert.assertEquals("FLOAT", parameterMetaData.getParameterTypeName(4)); + Assert.assertEquals("DOUBLE", parameterMetaData.getParameterTypeName(5)); + Assert.assertEquals("SMALLINT", parameterMetaData.getParameterTypeName(6)); + Assert.assertEquals("TINYINT", parameterMetaData.getParameterTypeName(7)); + Assert.assertEquals("BOOL", parameterMetaData.getParameterTypeName(8)); + Assert.assertEquals("BINARY", parameterMetaData.getParameterTypeName(9)); + Assert.assertEquals("NCHAR", parameterMetaData.getParameterTypeName(10)); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -524,9 +1042,9 @@ public class TSDBPreparedStatementTest { pstmt_insert.setRowId(1, null); } - @Test(expected = SQLFeatureNotSupportedException.class) + @Test public void setNString() throws SQLException { - pstmt_insert.setNString(1, null); + setString(); } @Test(expected = SQLFeatureNotSupportedException.class) @@ -544,22 +1062,45 @@ public class TSDBPreparedStatementTest { pstmt_insert.setSQLXML(1, null); } + @Before + public void before() { + try { + Statement stmt = conn.createStatement(); + stmt.execute("drop table if exists weather"); + stmt.execute("create table if not exists weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))"); + stmt.execute("create table if not exists t1 using weather tags('beijing')"); + stmt.close(); + + pstmt_insert = conn.prepareStatement(sql_insert); + pstmt_select = conn.prepareStatement(sql_select); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @After + public void after() { + try { + if (pstmt_insert != null) + pstmt_insert.close(); + if (pstmt_select != null) + pstmt_select.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + + } @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); 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("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))"); - stmt.execute("create table t1 using weather tags('beijing')"); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname); + stmt.execute("use " + dbname); } - pstmt_insert = conn.prepareStatement(sql_insert); - pstmt_select = conn.prepareStatement(sql_select); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } @@ -567,10 +1108,9 @@ public class TSDBPreparedStatementTest { @AfterClass public static void afterClass() { try { - if (pstmt_insert != null) - pstmt_insert.close(); - if (pstmt_select != null) - pstmt_select.close(); + Statement statement = conn.createStatement(); + statement.execute("drop database if exists " + dbname); + statement.close(); if (conn != null) conn.close(); } catch (SQLException e) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java index f304fd687406ccf919ea1b1e457cd218239e765f..ec54a44b7c889236676b65fea9fdf689b7207df9 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java @@ -14,6 +14,7 @@ import java.math.BigDecimal; import java.sql.*; import java.text.ParseException; import java.text.SimpleDateFormat; +import java.util.Arrays; public class TSDBResultSetTest { @@ -133,7 +134,7 @@ public class TSDBResultSetTest { Assert.assertEquals(3.1415926, Double.valueOf(new String(f5)), 0.000000f); byte[] f6 = rs.getBytes("f6"); - Assert.assertEquals("abc", new String(f6)); + Assert.assertTrue(Arrays.equals("abc".getBytes(), f6)); byte[] f7 = rs.getBytes("f7"); Assert.assertEquals((short) 10, Shorts.fromByteArray(f7)); @@ -646,7 +647,6 @@ public class TSDBResultSetTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); stmt = conn.createStatement(); stmt.execute("create database if not exists restful_test"); @@ -656,10 +656,9 @@ public class TSDBResultSetTest { stmt.execute("insert into restful_test.weather values('2021-01-01 00:00:00.000', 1, 100, 3.1415, 3.1415926, 'abc', 10, 10, true, '涛思数据')"); rs = stmt.executeQuery("select * from restful_test.weather"); rs.next(); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } - } @AfterClass diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java index 671551c42639620b09ace1ae315da6f25ea278d4..c1dfa42511cdd45ade577415fe17c872e44f5fd8 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java @@ -14,24 +14,6 @@ public class TSDBStatementTest { private static Connection conn; private static Statement stmt; - @Test - public void executeQuery() { - try { - ResultSet rs = stmt.executeQuery("show databases"); - Assert.assertNotNull(rs); - ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); - } - rs.close(); - } catch (SQLException e) { - e.printStackTrace(); - } - } - @Test public void executeUpdate() { final String dbName = ("test_" + UUID.randomUUID()).replace("-", "_").substring(0, 32); @@ -173,10 +155,6 @@ public class TSDBStatementTest { Assert.assertEquals(3, meta.getColumnCount()); int count = 0; while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); count++; } Assert.assertEquals(1, count); @@ -387,15 +365,12 @@ public class TSDBStatementTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); 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("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties); stmt = conn.createStatement(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java index 19bc5f713f9b406a943fc640fd03bb0503ed2967..4f37183e719e8eb21dcbd8dd625bd8d4d19214ce 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java @@ -1,5 +1,6 @@ package com.taosdata.jdbc.cases; +import org.junit.Assert; import org.junit.Test; import java.sql.Connection; @@ -12,21 +13,19 @@ public class AppMemoryLeakTest { @Test(expected = SQLException.class) public void testCreateTooManyConnection() throws ClassNotFoundException, SQLException { Class.forName("com.taosdata.jdbc.TSDBDriver"); - int conCnt = 0; while (true) { Connection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata"); - System.out.println(conCnt++ + " : " + conn); + Assert.assertNotNull(conn); } } @Test(expected = Exception.class) public void testCreateTooManyStatement() throws ClassNotFoundException, SQLException { Class.forName("com.taosdata.jdbc.TSDBDriver"); - int stmtCnt = 0; Connection conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata"); while (true) { Statement stmt = conn.createStatement(); - System.out.println(++stmtCnt + " : " + stmt); + Assert.assertNotNull(stmt); } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/AuthenticationTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AuthenticationTest.java similarity index 98% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/AuthenticationTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AuthenticationTest.java index a6fb6cfda044b4e88c5bd5509c51d114507d84f7..6702de9bdbf566eb1ecaea322d0338a64ffcd40c 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/AuthenticationTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AuthenticationTest.java @@ -1,4 +1,4 @@ -package com.taosdata.jdbc.rs; +package com.taosdata.jdbc.cases; import org.junit.Before; import org.junit.Test; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BadLocaleSettingTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BadLocaleSettingTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b351ee94bbcea3a4b6f79715bc03a405ff8d0c00 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BadLocaleSettingTest.java @@ -0,0 +1,58 @@ +package com.taosdata.jdbc.cases; + + +import com.taosdata.jdbc.TSDBDriver; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; +import java.io.IOException; + +import java.sql.*; +import java.util.Properties; + +public class BadLocaleSettingTest { + + private static final String host = "127.0.0.1"; + private static final String dbName = "bad_locale_test"; + private static Connection conn; + + @Test + public void canSetLocale() { + try { + 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"); + + String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + 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("drop table if exists weather"); + stmt.execute("create table weather(ts timestamp, temperature float, humidity int)"); + stmt.executeUpdate("insert into weather values(1624071506435, 12.3, 4)"); + stmt.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @BeforeClass + public static void beforeClass() { + System.setProperty("sun.jnu.encoding", "ANSI_X3.4-1968"); + System.setProperty("file.encoding", "ANSI_X3.4-1968"); + } + + @AfterClass + public static void afterClass() { + try { + if (conn != null) + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchInsertTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchInsertTest.java index 472da34980d98cbe694783b120bc5533a908fa5b..e175d6d1141e125d58f2a1e4a4f64c3d1b22bfbb 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchInsertTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchInsertTest.java @@ -28,9 +28,7 @@ public class BatchInsertTest { @Before public void before() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); - properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host); 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"); @@ -44,7 +42,7 @@ public class BatchInsertTest { String createTableSql = "create table " + stbName + "(ts timestamp, f1 int, f2 int, f3 int) tags(areaid int, loc binary(20))"; statement.executeUpdate(createTableSql); // create tables - for(int i = 0; i < numOfTables; i++) { + for (int i = 0; i < numOfTables; i++) { String loc = i % 2 == 0 ? "beijing" : "shanghai"; String createSubTalbesSql = "create table " + tablePrefix + i + " using " + stbName + " tags(" + i + ", '" + loc + "')"; statement.executeUpdate(createSubTalbesSql); @@ -62,7 +60,6 @@ public class BatchInsertTest { final int index = i; executorService.execute(() -> { try { - long startTime = System.currentTimeMillis(); Statement statement = connection.createStatement(); // get statement StringBuilder sb = new StringBuilder(); sb.append("INSERT INTO " + tablePrefix + index + " VALUES"); @@ -75,8 +72,6 @@ public class BatchInsertTest { } statement.addBatch(sb.toString()); statement.executeBatch(); - long endTime = System.currentTimeMillis(); - System.out.println("Thread " + index + " takes " + (endTime - startTime) + " microseconds"); connection.commit(); statement.close(); } catch (Exception e) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java new file mode 100644 index 0000000000000000000000000000000000000000..31893527aff2b3fd5f5512c729d60e0b8a137aa0 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java @@ -0,0 +1,56 @@ +package com.taosdata.jdbc.cases; + +import com.taosdata.jdbc.TSDBDriver; +import org.junit.Before; +import org.junit.Test; + +import java.sql.*; +import java.util.Properties; + +public class ConnectMultiTaosdByRestfulWithDifferentTokenTest { + + private static String host1 = "192.168.17.156"; + private static String user1 = "root"; + private static String password1 = "tqueue"; + private Connection conn1; + private static String host2 = "192.168.17.82"; + private static String user2 = "root"; + private static String password2 = "taosdata"; + private Connection conn2; + + @Test + public void test() { + //when + executeSelectStatus(conn1); + executeSelectStatus(conn2); + executeSelectStatus(conn1); + } + + private void executeSelectStatus(Connection connection) { + try (Statement stmt = connection.createStatement()) { + ResultSet rs = stmt.executeQuery("select server_status()"); + ResultSetMetaData meta = rs.getMetaData(); + while (rs.next()) { + } + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Before + public void before() { + 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"); + + String url1 = "jdbc:TAOS-RS://" + host1 + ":6041/?user=" + user1 + "&password=" + password1; + String url2 = "jdbc:TAOS-RS://" + host2 + ":6041/?user=" + user2 + "&password=" + password2; + try { + conn1 = DriverManager.getConnection(url1, properties); + conn2 = DriverManager.getConnection(url2, properties); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java index f97e555ad1b1acc7b6dd0024d893fcc1ccd4cc53..14c76985484857a92e174955c943caa21bdd2e72 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java @@ -1,64 +1,76 @@ package com.taosdata.jdbc.cases; import com.taosdata.jdbc.utils.TimestampUtil; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.*; import java.sql.*; public class DatetimeBefore1970Test { - private static Connection conn; + private static final String host = "127.0.0.1"; + private Connection conn; @Test public void test() { try (Statement stmt = conn.createStatement()) { + // given stmt.executeUpdate("insert into weather(ts) values('1969-12-31 23:59:59.999')"); stmt.executeUpdate("insert into weather(ts) values('1970-01-01 00:00:00.000')"); stmt.executeUpdate("insert into weather(ts) values('1970-01-01 08:00:00.000')"); stmt.executeUpdate("insert into weather(ts) values('1970-01-01 07:59:59.999')"); + ResultSet rs = stmt.executeQuery("select * from weather order by ts asc"); + ResultSetMetaData metaData = rs.getMetaData(); + Assert.assertEquals(2, metaData.getColumnCount()); + + // when + rs.next(); + // then + Timestamp ts = rs.getTimestamp("ts"); + Assert.assertEquals("1969-12-31 23:59:59.999", TimestampUtil.longToDatetime(ts.getTime())); + + // when + rs.next(); + // then + ts = rs.getTimestamp("ts"); + Assert.assertEquals("1970-01-01 00:00:00.000", TimestampUtil.longToDatetime(ts.getTime())); + + // when + rs.next(); + // then + ts = rs.getTimestamp("ts"); + Assert.assertEquals("1970-01-01 08:00:00.000", TimestampUtil.longToDatetime(ts.getTime())); + + // when + rs.next(); + // then + ts = rs.getTimestamp("ts"); + Assert.assertEquals("1970-01-01 07:59:59.999", TimestampUtil.longToDatetime(ts.getTime())); - ResultSet rs = stmt.executeQuery("select * from weather"); - while (rs.next()) { - Timestamp ts = rs.getTimestamp("ts"); - System.out.println("long: " + ts.getTime() + ", string: " + TimestampUtil.longToDatetime(ts.getTime())); - } } catch (SQLException e) { e.printStackTrace(); } } - public static void main(String[] args) { - System.out.println("timestamp: " + Long.MAX_VALUE + ", string: " + TimestampUtil.longToDatetime(Long.MAX_VALUE)); - System.out.println("timestamp: " + Long.MIN_VALUE + ", string: " + TimestampUtil.longToDatetime(Long.MIN_VALUE)); - System.out.println("timestamp: " + 0 + ", string: " + TimestampUtil.longToDatetime(0)); - System.out.println("timestamp: " + -1 + ", string: " + TimestampUtil.longToDatetime(-1)); - String datetime = "1970-01-01 00:00:00.000"; - System.out.println("timestamp: " + TimestampUtil.datetimeToLong(datetime) + ", string: " + datetime); - datetime = "1969-12-31 23:59:59.999"; - System.out.println("timestamp: " + TimestampUtil.datetimeToLong(datetime) + ", string: " + datetime); - } - - @BeforeClass - public static void beforeClass() { + @Before + public void before() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); - conn = DriverManager.getConnection("jdbc:TAOS://127.0.0.1:6030/?user=root&password=taosdata"); + conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); Statement stmt = conn.createStatement(); stmt.execute("drop database if exists test_timestamp"); stmt.execute("create database if not exists test_timestamp keep 36500"); stmt.execute("use test_timestamp"); stmt.execute("create table weather(ts timestamp,f1 float)"); stmt.close(); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } - @AfterClass - public static void afterClass() { + @After + public void after() { try { + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists test_timestamp"); if (conn != null) conn.close(); } catch (SQLException e) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DoubleQuoteInSqlTest.java similarity index 55% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DoubleQuoteInSqlTest.java index 2704d4cfa558ebdb6885c320d7ba775b36b99f09..212a751ec302ae02552d084248d34b35a7b21c59 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4174Test.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DoubleQuoteInSqlTest.java @@ -7,56 +7,64 @@ import org.junit.*; import java.sql.*; import java.util.Properties; -public class TD4174Test { - private Connection conn; +public class DoubleQuoteInSqlTest { private static final String host = "127.0.0.1"; + private static final String dbname = "td4174"; + + private Connection conn; @Test public void test() { + // given long ts = System.currentTimeMillis(); + JSONObject value = new JSONObject(); + value.put("name", "John Smith"); + value.put("age", 20); + + // when + int ret = 0; try (PreparedStatement pstmt = conn.prepareStatement("insert into weather values(" + ts + ", ?)")) { - JSONObject value = new JSONObject(); - value.put("name", "John Smith"); - value.put("age", 20); - Assert.assertEquals("{\"name\":\"John Smith\",\"age\":20}",value.toJSONString()); pstmt.setString(1, value.toJSONString()); - - int ret = pstmt.executeUpdate(); - Assert.assertEquals(1, ret); + ret = pstmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } - } - public static void main(String[] args) { - JSONObject value = new JSONObject(); - value.put("name", "John Smith"); - value.put("age", 20); - System.out.println(value.toJSONString()); + // then + Assert.assertEquals("{\"name\":\"John Smith\",\"age\":20}", value.toJSONString()); + Assert.assertEquals(1, ret); } @Before - public void before() throws SQLException { + public void before() { String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); - conn = DriverManager.getConnection(url, properties); - try (Statement stmt = conn.createStatement()) { - stmt.execute("drop database if exists td4174"); - stmt.execute("create database if not exists td4174"); - stmt.execute("use td4174"); + try { + conn = DriverManager.getConnection(url, properties); + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname); + stmt.execute("use " + dbname); stmt.execute("create table weather(ts timestamp, text binary(64))"); + } catch (SQLException e) { + e.printStackTrace(); } } @After - public void after() throws SQLException { - if (conn != null) + public void after() { + try { + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.close(); conn.close(); - + } catch (SQLException e) { + e.printStackTrace(); + } } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java index d7603312a090bedb17ed125edf6da535924964d0..bc11c7f34eeb719574a35beaf186cf637df2826f 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java @@ -20,7 +20,6 @@ public class ImportTest { @BeforeClass public static void before() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); @@ -33,8 +32,6 @@ public class ImportTest { stmt.close(); ts = System.currentTimeMillis(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } @@ -47,7 +44,6 @@ public class ImportTest { for (int i = 0; i < 50; i++) { ts++; int row = stmt.executeUpdate("import into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")"); - System.out.println("import into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")\t" + row); assertEquals(1, row); } } @@ -84,7 +80,6 @@ public class ImportTest { long t = (++ts) + a; sqlBuilder.append("(").append(t).append(",").append((100 + i)).append(",").append(i).append(") "); } - System.out.println(sqlBuilder.toString()); int rows = stmt.executeUpdate(sqlBuilder.toString()); assertEquals(50, rows); } catch (SQLException e) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionJNITest.java similarity index 97% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInJniTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionJNITest.java index f9b111bb12f189a7a42c7944237aa01ebb008d25..eb8f134227713e4c41224dc6a561916427290864 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInJniTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionJNITest.java @@ -10,7 +10,7 @@ import org.junit.Test; import java.sql.*; import java.util.Properties; -public class TwoTypeTimestampPercisionInJniTest { +public class MicroSecondPrecisionJNITest { private static final String host = "127.0.0.1"; private static final String ms_timestamp_db = "ms_precision_test"; @@ -41,7 +41,6 @@ public class TwoTypeTimestampPercisionInJniTest { rs.next(); Timestamp timestamp = rs.getTimestamp(1); - System.out.println(timestamp); long ts = timestamp.getTime(); Assert.assertEquals(timestamp1, ts); int nanos = timestamp.getNanos(); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java similarity index 99% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java index 5c83b5a9da527a55387a8ad399e78462b6fab63c..7e9f04cd6360431a3fe6c29a2f0eb61fbdc9e7c4 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TwoTypeTimestampPercisionInRestfulTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java @@ -10,10 +10,9 @@ import org.junit.Test; import java.sql.*; import java.util.Properties; -public class TwoTypeTimestampPercisionInRestfulTest { +public class MicroSecondPrecisionRestfulTest { private static final String host = "127.0.0.1"; - private static final String ms_timestamp_db = "ms_precision_test"; private static final String us_timestamp_db = "us_precision_test"; private static final long timestamp1 = System.currentTimeMillis(); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatmentTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatementTest.java similarity index 84% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatmentTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatementTest.java index 5cb76cc0cb71e1cb879b696d05cc6682f93d0bdc..da6853d2fa06fb8436e79b95e9b7f1c2fa0785e2 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatmentTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatementTest.java @@ -7,7 +7,7 @@ import org.junit.Test; import java.sql.*; import java.util.concurrent.TimeUnit; -public class MultiThreadsWithSameStatmentTest { +public class MultiThreadsWithSameStatementTest { private class Service { @@ -16,12 +16,11 @@ public class MultiThreadsWithSameStatmentTest { public Service() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata"); stmt = conn.createStatement(); stmt.execute("create database if not exists jdbctest"); stmt.executeUpdate("create table if not exists jdbctest.weather (ts timestamp, f1 int)"); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } @@ -48,10 +47,6 @@ public class MultiThreadsWithSameStatmentTest { ResultSet resultSet = service.stmt.executeQuery("select * from jdbctest.weather"); while (resultSet.next()) { ResultSetMetaData metaData = resultSet.getMetaData(); - for (int i = 1; i <= metaData.getColumnCount(); i++) { - System.out.print(metaData.getColumnLabel(i) + ": " + resultSet.getString(i)); - } - System.out.println(); } resultSet.close(); service.release(); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java new file mode 100644 index 0000000000000000000000000000000000000000..4f2c87966ad6bb8390bab47b795e7d952725baf5 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java @@ -0,0 +1,182 @@ +package com.taosdata.jdbc.cases; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.sql.*; +import java.time.Instant; +import java.util.Random; + +public class NanoSecondTimestampJNITest { + + private static final String host = "127.0.0.1"; + private static final String dbname = "nano_sec_test"; + private static final Random random = new Random(System.currentTimeMillis()); + private static Connection conn; + + @Test + public void insertUsingLongValue() { + // given + long ms = System.currentTimeMillis(); + long ns = ms * 1000_000 + random.nextInt(1000_000); + + // when + int ret = 0; + try (Statement stmt = conn.createStatement()) { + ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)"); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Assert.assertEquals(1, ret); + } + + @Test + public void insertUsingStringValue() { + // given + + // when + int ret = 0; + try (Statement stmt = conn.createStatement()) { + ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('2021-01-01 12:00:00.123456789', 12.3, 4)"); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Assert.assertEquals(1, ret); + } + + @Test + public void insertUsingTimestampValue() { + // given + long epochSec = System.currentTimeMillis() / 1000; + long nanoAdjustment = random.nextInt(1000_000_000); + Timestamp ts = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); + + // when + int ret = 0; + String sql = "insert into weather(ts, temperature, humidity) values( ?, ?, ?)"; + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setTimestamp(1, ts); + pstmt.setFloat(2, 12.34f); + pstmt.setInt(3, 55); + ret = pstmt.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Assert.assertEquals(1, ret); + } + + @Test + public void selectUsingLongValue() throws SQLException { + // given + long ms = System.currentTimeMillis(); + long ns = ms * 1000_000L + random.nextInt(1000_000); + + // when + ResultSet rs = null; + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)"); + rs = stmt.executeQuery("select * from weather"); + rs.next(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + long actual = rs.getLong(1); + Assert.assertEquals(ms, actual); + actual = rs.getLong("ts"); + Assert.assertEquals(ms, actual); + } + + @Test + public void selectUsingStringValue() throws SQLException { + // given + String timestampStr = "2021-01-01 12:00:00.123456789"; + + // when + ResultSet rs = null; + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('" + timestampStr + "', 12.3, 4)"); + rs = stmt.executeQuery("select * from weather"); + rs.next(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + String actual = rs.getString(1); + Assert.assertEquals(timestampStr, actual); + actual = rs.getString("ts"); + Assert.assertEquals(timestampStr, actual); + } + + @Test + public void selectUsingTimestampValue() throws SQLException { + // given + long timeMillis = System.currentTimeMillis(); + long epochSec = timeMillis / 1000; + long nanoAdjustment = (timeMillis % 1000) * 1000_000L + random.nextInt(1000_000); + Timestamp ts = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); + + // insert one row + String sql = "insert into weather(ts, temperature, humidity) values( ?, ?, ?)"; + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setTimestamp(1, ts); + pstmt.setFloat(2, 12.34f); + pstmt.setInt(3, 55); + pstmt.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // when + ResultSet rs = null; + try (Statement stmt = conn.createStatement()) { + rs = stmt.executeQuery("select * from weather"); + rs.next(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Timestamp actual = rs.getTimestamp(1); + Assert.assertEquals(ts, actual); + actual = rs.getTimestamp("ts"); + Assert.assertEquals(ts, actual); + Assert.assertEquals(timeMillis, actual.getTime()); + Assert.assertEquals(nanoAdjustment, actual.getNanos()); + } + + @Before + public void before() { + try (Statement stmt = conn.createStatement()) { + stmt.execute("drop table if exists weather"); + stmt.execute("create table weather(ts timestamp, temperature float, humidity int)"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @BeforeClass + public static void beforeClass() { + final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + try { + conn = DriverManager.getConnection(url); + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname + " precision 'ns'"); + stmt.execute("use " + dbname); + } catch (SQLException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4271f918b9b096000cc59b730d7b70f032a0ab29 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java @@ -0,0 +1,182 @@ +package com.taosdata.jdbc.cases; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.sql.*; +import java.time.Instant; +import java.util.Random; + +public class NanoSecondTimestampRestfulTest { + + private static final String host = "127.0.0.1"; + private static final String dbname = "nano_sec_test"; + private static final Random random = new Random(System.currentTimeMillis()); + private static Connection conn; + + @Test + public void insertUsingLongValue() { + // given + long ms = System.currentTimeMillis(); + long ns = ms * 1000_000 + random.nextInt(1000_000); + + // when + int ret = 0; + try (Statement stmt = conn.createStatement()) { + ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)"); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Assert.assertEquals(1, ret); + } + + @Test + public void insertUsingStringValue() { + // given + + // when + int ret = 0; + try (Statement stmt = conn.createStatement()) { + ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('2021-01-01 12:00:00.123456789', 12.3, 4)"); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Assert.assertEquals(1, ret); + } + + @Test + public void insertUsingTimestampValue() { + // given + long epochSec = System.currentTimeMillis() / 1000; + long nanoAdjustment = random.nextInt(1000_000_000); + Timestamp ts = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); + + // when + int ret = 0; + String sql = "insert into weather(ts, temperature, humidity) values( ?, ?, ?)"; + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setTimestamp(1, ts); + pstmt.setFloat(2, 12.34f); + pstmt.setInt(3, 55); + ret = pstmt.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Assert.assertEquals(1, ret); + } + + @Test + public void selectUsingLongValue() throws SQLException { + // given + long ms = System.currentTimeMillis(); + long ns = ms * 1000_000L + random.nextInt(1000_000); + + // when + ResultSet rs = null; + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)"); + rs = stmt.executeQuery("select * from weather"); + rs.next(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + long actual = rs.getLong(1); + Assert.assertEquals(ms, actual); + actual = rs.getLong("ts"); + Assert.assertEquals(ms, actual); + } + + @Test + public void selectUsingStringValue() throws SQLException { + // given + String timestampStr = "2021-01-01 12:00:00.123456789"; + + // when + ResultSet rs = null; + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('" + timestampStr + "', 12.3, 4)"); + rs = stmt.executeQuery("select * from weather"); + rs.next(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + String actual = rs.getString(1); + Assert.assertEquals(timestampStr, actual); + actual = rs.getString("ts"); + Assert.assertEquals(timestampStr, actual); + } + + @Test + public void selectUsingTimestampValue() throws SQLException { + // given + long timeMillis = System.currentTimeMillis(); + long epochSec = timeMillis / 1000; + long nanoAdjustment = (timeMillis % 1000) * 1000_000L + random.nextInt(1000_000); + Timestamp ts = Timestamp.from(Instant.ofEpochSecond(epochSec, nanoAdjustment)); + + // insert one row + String sql = "insert into weather(ts, temperature, humidity) values( ?, ?, ?)"; + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + pstmt.setTimestamp(1, ts); + pstmt.setFloat(2, 12.34f); + pstmt.setInt(3, 55); + pstmt.executeUpdate(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // when + ResultSet rs = null; + try (Statement stmt = conn.createStatement()) { + rs = stmt.executeQuery("select * from weather"); + rs.next(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Timestamp actual = rs.getTimestamp(1); + Assert.assertEquals(ts, actual); + actual = rs.getTimestamp("ts"); + Assert.assertEquals(ts, actual); + Assert.assertEquals(timeMillis, actual.getTime()); + Assert.assertEquals(nanoAdjustment, actual.getNanos()); + } + + @Before + public void before() { + try (Statement stmt = conn.createStatement()) { + stmt.execute("drop table if exists weather"); + stmt.execute("create table weather(ts timestamp, temperature float, humidity int)"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @BeforeClass + public static void beforeClass() { + final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; + try { + conn = DriverManager.getConnection(url); + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname + " precision 'ns'"); + stmt.execute("use " + dbname); + } catch (SQLException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java similarity index 87% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcJniTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java index 782125144c4fbe8dcc4bdfd4769e95e5119ea32f..ae0241bf31eea85083bf102c4123f7e30c2bd693 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcJniTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java @@ -6,7 +6,7 @@ import org.junit.Test; import java.sql.*; -public class NullValueInResultSetForJdbcJniTest { +public class NullValueInResultSetJNITest { private static final String host = "127.0.0.1"; Connection conn; @@ -17,11 +17,6 @@ public class NullValueInResultSetForJdbcJniTest { ResultSet rs = stmt.executeQuery("select * from weather"); ResultSetMetaData meta = rs.getMetaData(); while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - Object value = rs.getObject(i); - System.out.print(meta.getColumnLabel(i) + ": " + value + "\t"); - } - System.out.println(); } } catch (SQLException e) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java similarity index 92% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java index f2ac94adc1b6e7d94e52650dcfbb5664c8f39760..7fbb30a5244a53129807cd76472674ff1cfd6ae4 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetForJdbcRestfulTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java @@ -6,7 +6,7 @@ import org.junit.Test; import java.sql.*; -public class NullValueInResultSetForJdbcRestfulTest { +public class NullValueInResultSetRestfulTest { private static final String host = "127.0.0.1"; Connection conn; @@ -19,9 +19,7 @@ public class NullValueInResultSetForJdbcRestfulTest { while (rs.next()) { for (int i = 1; i <= meta.getColumnCount(); i++) { Object value = rs.getObject(i); - System.out.print(meta.getColumnLabel(i) + ": " + value + "\t"); } - System.out.println(); } } catch (SQLException e) { diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetTest.java similarity index 99% rename from src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java rename to src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetTest.java index c6fba81eb24b9b8c08fd553ca57b1e1d68bb81e0..61d767b5cf2bcd2e478de74e5f4bb8d66ad21678 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD3841Test.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetTest.java @@ -7,7 +7,7 @@ import org.junit.*; import java.sql.*; import java.util.Properties; -public class TD3841Test { +public class NullValueInResultSetTest { private static final String host = "127.0.0.1"; private static Properties properties; private static Connection conn_restful; diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertJNITest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertJNITest.java new file mode 100644 index 0000000000000000000000000000000000000000..ed78c2561ec437e3b7c6a0ab8d3e91699c2572af --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertJNITest.java @@ -0,0 +1,98 @@ +package com.taosdata.jdbc.cases; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.sql.*; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class PreparedStatementBatchInsertJNITest { + + private static final String host = "127.0.0.1"; + private static final String dbname = "td4668"; + + private final Random random = new Random(System.currentTimeMillis()); + private Connection conn; + + @Test + public void test() { + // given + long ts = System.currentTimeMillis(); + List rows = IntStream.range(0, 10).mapToObj(i -> { + Object[] row = new Object[6]; + final String groupId = String.format("%02d", random.nextInt(100)); + // table name (d + groupId)组合 + row[0] = "d" + groupId; + // tag + row[1] = groupId; + // ts + row[2] = ts + i; + // current 电流 + row[3] = random.nextFloat(); + // voltage 电压 + row[4] = Math.random() > 0.5 ? 220 : 380; + // phase 相位 + row[5] = random.nextInt(10); + return row; + }).collect(Collectors.toList()); + final String sql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)"; + + // when + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + for (Object[] row : rows) { + for (int i = 0; i < row.length; i++) { + pstmt.setObject(i + 1, row[i]); + } + pstmt.addBatch(); + } + pstmt.executeBatch(); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail(); + } + + // then + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from meters"); + int count = 0; + while (rs.next()) { + count++; + } + Assert.assertEquals(10, count); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Before + public void before() { + try { + conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"); + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname); + stmt.execute("use " + dbname); + stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(groupId int)"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @After + public void after() { + try { + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.close(); + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java new file mode 100644 index 0000000000000000000000000000000000000000..90b285381a2ab57b170da327a95dde4c8991ce21 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java @@ -0,0 +1,98 @@ +package com.taosdata.jdbc.cases; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.sql.*; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class PreparedStatementBatchInsertRestfulTest { + + private static final String host = "127.0.0.1"; + private static final String dbname = "td4668"; + + private final Random random = new Random(System.currentTimeMillis()); + private Connection conn; + + @Test + public void test() { + // given + long ts = System.currentTimeMillis(); + List rows = IntStream.range(0, 10).mapToObj(i -> { + Object[] row = new Object[6]; + final String groupId = String.format("%02d", random.nextInt(100)); + // table name (d + groupId)组合 + row[0] = "d" + groupId; + // tag + row[1] = groupId; + // ts + row[2] = ts + i; + // current 电流 + row[3] = random.nextFloat(); + // voltage 电压 + row[4] = Math.random() > 0.5 ? 220 : 380; + // phase 相位 + row[5] = random.nextInt(10); + return row; + }).collect(Collectors.toList()); + final String sql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)"; + + // when + try (PreparedStatement pstmt = conn.prepareStatement(sql)) { + for (Object[] row : rows) { + for (int i = 0; i < row.length; i++) { + pstmt.setObject(i + 1, row[i]); + } + pstmt.addBatch(); + } + pstmt.executeBatch(); + } catch (SQLException e) { + e.printStackTrace(); + Assert.fail(); + } + + // then + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select * from meters"); + int count = 0; + while (rs.next()) { + count++; + } + Assert.assertEquals(10, count); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Before + public void before() { + try { + conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"); + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname); + stmt.execute("use " + dbname); + stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(groupId int)"); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @After + public void after() { + try { + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.close(); + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/QueryDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/QueryDataTest.java index d0ba113b7a4a8f99e22eb8143905d0b086583e1d..535e56f7d7735a7cbd209fbb2a2fddd492021e15 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/QueryDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/QueryDataTest.java @@ -21,7 +21,6 @@ public class QueryDataTest { @Before public void createDatabase() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); @@ -36,7 +35,7 @@ public class QueryDataTest { String createTableSql = "create table " + stbName + "(ts timestamp, name binary(64))"; statement.executeUpdate(createTableSql); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { return; } } @@ -44,7 +43,6 @@ public class QueryDataTest { @Test public void testQueryBinaryData() throws SQLException { String insertSql = "insert into " + stbName + " values(now, 'taosdata')"; - System.out.println(insertSql); statement.executeUpdate(insertSql); String querySql = "select * from " + stbName; @@ -52,7 +50,6 @@ public class QueryDataTest { while (rs.next()) { String name = rs.getString(2); - System.out.println("name = " + name); assertEquals("taosdata", name); } rs.close(); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ResultSetMetaShouldNotBeNullRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ResultSetMetaShouldNotBeNullRestfulTest.java new file mode 100644 index 0000000000000000000000000000000000000000..be27b1350781245e3056185db4bbaa8b5105d2f0 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ResultSetMetaShouldNotBeNullRestfulTest.java @@ -0,0 +1,86 @@ +package com.taosdata.jdbc.cases; + +import org.junit.After; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.sql.*; + +public class ResultSetMetaShouldNotBeNullRestfulTest { + + private static final String host = "127.0.0.1"; + private static final String dbname = "td4745"; + + private Connection connection; + + @Test + public void testExecuteQuery() { + // given + ResultSetMetaData metaData = null; + int columnCount = -1; + + // when + try { + Statement statement = connection.createStatement(); + metaData = statement.executeQuery("select * from weather").getMetaData(); + columnCount = metaData.getColumnCount(); + } catch (SQLException e) { + e.printStackTrace(); + } + + // then + Assert.assertNotNull(metaData); + Assert.assertEquals(2, 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(2, columnCount); + } + + @Before + public void before() { + try { + connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"); + Statement stmt = connection.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.execute("create database if not exists " + dbname); + stmt.execute("use " + dbname); + stmt.execute("create table weather (ts timestamp, temperature float)"); + stmt.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @After + public void after() { + try { + Statement stmt = connection.createStatement(); + stmt.execute("drop database if exists " + dbname); + stmt.close(); + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/SelectTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/SelectTest.java index 38c8cbb98c48342f131f4f5f0fee885bb446e83c..0022ceaf2123ac03192f761ef068ecf5ad333e6d 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/SelectTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/SelectTest.java @@ -19,7 +19,6 @@ public class SelectTest { @Before public void createDatabaseAndTable() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); @@ -31,8 +30,6 @@ public class SelectTest { stmt.execute("create database if not exists " + dbName); stmt.execute("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)"); stmt.close(); - } catch (ClassNotFoundException e) { - return; } catch (SQLException e) { e.printStackTrace(); } @@ -47,7 +44,6 @@ public class SelectTest { for (int i = 0; i < 50; i++) { ts++; int row = stmt.executeUpdate("insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")"); - System.out.println("insert into " + dbName + "." + tName + " values (" + ts + ", " + (100 + i) + ", " + i + ")\t" + row); assertEquals(1, row); } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/StableTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/StableTest.java index 4575cb73a05fbbc19d6eaf2ba5be0ed27b61804c..332c171c380e061b747c74328ebeef37225e9b2d 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/StableTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/StableTest.java @@ -23,7 +23,6 @@ public class StableTest { @BeforeClass public static void createDatabase() { try { - Class.forName("com.taosdata.jdbc.TSDBDriver"); Properties properties = new Properties(); properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); @@ -34,8 +33,6 @@ public class StableTest { statement.execute("create database if not exists " + dbName); statement.execute("use " + dbName); statement.close(); - } catch (ClassNotFoundException e) { - return; } catch (SQLException e) { e.printStackTrace(); } @@ -68,9 +65,6 @@ public class StableTest { String sql = "describe " + stbName; ResultSet rs = stmt.executeQuery(sql); while (rs.next()) { - for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { - System.out.println(i + ":" + rs.getString(i)); - } num++; } rs.close(); @@ -86,9 +80,6 @@ public class StableTest { try (Statement stmt = connection.createStatement()) { ResultSet rs = stmt.executeQuery("describe t1"); while (rs.next()) { - for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) { - System.out.printf("%d: %s\n", i, rs.getString(i)); - } num++; } rs.close(); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java deleted file mode 100644 index 6f29f64111c51600303ad73d517faaa7c59cfe7c..0000000000000000000000000000000000000000 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TD4144Test.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.taosdata.jdbc.cases; - -import com.taosdata.jdbc.TSDBConnection; -import com.taosdata.jdbc.TSDBDriver; -import com.taosdata.jdbc.TSDBResultSet; -import com.taosdata.jdbc.TSDBSubscribe; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - -import java.sql.DriverManager; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -public class TD4144Test { - - private static TSDBConnection connection; - private static final String host = "127.0.0.1"; - - private static final String topic = "topic-meter-current-bg-10"; - private static final String sql = "select * from meters where current > 10"; - private static final String sql2 = "select * from meters where ts >= '2020-08-15 12:20:00.000'"; - - - @Test - public void test() throws SQLException { - TSDBSubscribe subscribe = null; - TSDBResultSet res = null; - boolean hasNext = false; - - try { - subscribe = connection.subscribe(topic, sql, false); - int count = 0; - while (true) { - // 等待1秒,避免频繁调用 consume,给服务端造成压力 - TimeUnit.SECONDS.sleep(1); - if (res == null) { - // 消费数据 - res = subscribe.consume(); - hasNext = res.next(); - } - - if (res == null) { - continue; - } - ResultSetMetaData metaData = res.getMetaData(); - int number = 0; - while (hasNext) { - int columnCount = metaData.getColumnCount(); - for (int i = 1; i <= columnCount; i++) { - System.out.print(metaData.getColumnLabel(i) + ": " + res.getString(i) + "\t"); - } - System.out.println(); - count++; - number++; - hasNext = res.next(); - if (!hasNext) { - res.close(); - res = null; - System.out.println("rows: " + count); - } - if (hasNext == true && number >= 10) { - System.out.println("batch" + number); - break; - } - } - - } - - } catch (SQLException | InterruptedException throwables) { - throwables.printStackTrace(); - } finally { - if (subscribe != null) - subscribe.close(true); - } - } - - @BeforeClass - public static void beforeClass() throws SQLException { - Properties properties = new Properties(); - properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); - properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); - String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; - connection = (DriverManager.getConnection(url, properties)).unwrap(TSDBConnection.class); - try (Statement stmt = connection.createStatement()) { - stmt.execute("drop database if exists power"); - stmt.execute("create database if not exists power"); - stmt.execute("use power"); - stmt.execute("create table meters(ts timestamp, current float, voltage int, phase int) tags(location binary(64), groupId int)"); - stmt.execute("create table d1001 using meters tags(\"Beijing.Chaoyang\", 2)"); - stmt.execute("create table d1002 using meters tags(\"Beijing.Haidian\", 2)"); - stmt.execute("insert into d1001 values(\"2020-08-15 12:00:00.000\", 12, 220, 1),(\"2020-08-15 12:10:00.000\", 12.3, 220, 2),(\"2020-08-15 12:20:00.000\", 12.2, 220, 1)"); - stmt.execute("insert into d1002 values(\"2020-08-15 12:00:00.000\", 9.9, 220, 1),(\"2020-08-15 12:10:00.000\", 10.3, 220, 1),(\"2020-08-15 12:20:00.000\", 11.2, 220, 1)"); - } - } - - @AfterClass - public static void afterClass() throws SQLException { - if (connection != null) - connection.close(); - } -} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TimestampPrecisionInNanoInJniTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TimestampPrecisionInNanoInJniTest.java new file mode 100644 index 0000000000000000000000000000000000000000..042d76d576b0c17fa9ec49e9ac88be851b3b47f7 --- /dev/null +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TimestampPrecisionInNanoInJniTest.java @@ -0,0 +1,570 @@ +package com.taosdata.jdbc.cases; + + +import com.taosdata.jdbc.TSDBDriver; +import org.junit.AfterClass; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.After; +import org.junit.Test; + +import java.sql.*; +import java.util.Properties; +import java.text.Format; +import java.text.SimpleDateFormat; + +public class TimestampPrecisionInNanoInJniTest { + + private static final String host = "127.0.0.1"; + private static final String ns_timestamp_db = "ns_precision_test"; + private static final long timestamp1 = System.currentTimeMillis(); + private static final long timestamp2 = timestamp1 * 1000_000 + 123455; + private static final long timestamp3 = (timestamp1 + 10) * 1000_000 + 123456; + private static final Format format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS"); + private static final String date1 = format.format(new Date(timestamp1)); + private static final String date4 = format.format(new Date(timestamp1 + 10l)); + private static final String date2 = date1 + "123455"; + private static final String date3 = date4 + "123456"; + + + private static Connection conn; + + @BeforeClass + public static void beforeClass() throws SQLException { + 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"); + + String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata"; + conn = DriverManager.getConnection(url, properties); + + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + ns_timestamp_db); + stmt.execute("create database if not exists " + ns_timestamp_db + " precision 'ns'"); + stmt.execute("create table " + ns_timestamp_db + ".weather(ts timestamp, ts2 timestamp, f1 int)"); + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(\"" + date3 + "\", \"" + date3 + "\", 128)"); + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(" + timestamp2 + "," + timestamp2 + ", 127)"); + stmt.close(); + } + + @After + public void afterEach() throws SQLException { + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists " + ns_timestamp_db); + stmt.execute("create database if not exists " + ns_timestamp_db + " precision 'ns'"); + stmt.execute("create table " + ns_timestamp_db + ".weather(ts timestamp, ts2 timestamp, f1 int)"); + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(\"" + date3 + "\", \"" + date3 + "\", 128)"); + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(" + timestamp2 + "," + timestamp2 + ", 127)"); + stmt.close(); + } + + @AfterClass + public static void afterClass() { + try { + if (conn != null) + conn.close(); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + private void checkCount(long count, ResultSet rs) throws SQLException { + if (count == 0) { + Assert.fail(); + } + rs.next(); + long test_count = rs.getLong(1); + Assert.assertEquals(count, test_count); + } + + private void checkTime(long ts, ResultSet rs) throws SQLException { + rs.next(); + int nanos = rs.getTimestamp(1).getNanos(); + Assert.assertEquals(ts % 1000_000_000l, nanos); + long test_ts = rs.getLong(1); + Assert.assertEquals(ts / 1000_000l, test_ts); + } + + @Test + public void canInsertTimestampAndQueryByEqualToInDateTypeInBothFirstAndSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts = '" + date3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts = '" + date3 + "'"); + checkTime(timestamp3, rs); + rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 = '" + date3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 = '" + date3 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canImportTimestampAndQueryByEqualToInDateTypeInBothFirstAndSecondCol() { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("import into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(\"" + date1 + "123123\", \"" + date1 + "123123\", 127)"); + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts = '" + date1 + "123123'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts = '" + date1 + "123123'"); + checkTime(timestamp1 * 1000_000l + 123123l, rs); + rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 = '" + date1 + "123123'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 = '" + date1 + "123123'"); + checkTime(timestamp1 * 1000_000l + 123123l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canInsertTimestampAndQueryByEqualToInNumberTypeInBothFirstAndSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts = '" + timestamp2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts = '" + timestamp2 + "'"); + checkTime(timestamp2, rs); + rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 = '" + timestamp2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 = '" + timestamp2 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canImportTimestampAndQueryByEqualToInNumberTypeInBothFirstAndSecondCol() { + try (Statement stmt = conn.createStatement()) { + long timestamp4 = timestamp1 * 1000_000 + 123123; + stmt.executeUpdate("import into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(" + timestamp4 + ", " + timestamp4 + ", 127)"); + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts = '" + timestamp4 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts = '" + timestamp4 + "'"); + checkTime(timestamp4, rs); + rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 = '" + timestamp4 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 = '" + timestamp4 + "'"); + checkTime(timestamp4, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canSelectLastRowFromWeatherForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select last(ts) from " + ns_timestamp_db + ".weather"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canSelectLastRowFromWeatherForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select last(ts2) from " + ns_timestamp_db + ".weather"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canSelectFirstRowFromWeatherForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select first(ts) from " + ns_timestamp_db + ".weather"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canSelectFirstRowFromWeatherForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select first(ts2) from " + ns_timestamp_db + ".weather"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLargerThanInDateTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts > '" + date2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts > '" + date2 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLargerThanInDateTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 > '" + date2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 > '" + date2 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLargerThanInNumberTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts > '" + timestamp2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts > '" + timestamp2 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLargerThanInNumberTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 > '" + timestamp2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 > '" + timestamp2 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLargerThanOrEqualToInDateTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts >= '" + date2 + "'"); + checkCount(2l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLargerThanOrEqualToInDateTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 >= '" + date2 + "'"); + checkCount(2l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLargerThanOrEqualToInNumberTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts >= '" + timestamp2 + "'"); + checkCount(2l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLargerThanOrEqualToInNumberTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 >= '" + timestamp2 + "'"); + checkCount(2l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLessThanInDateTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts < '" + date3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts < '" + date3 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLessThanInDateTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 < '" + date3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 < '" + date3 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLessThanInNumberTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts < '" + timestamp3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts < '" + timestamp3 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLessThanInNumberTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 < '" + timestamp3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 < '" + timestamp3 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLessThanOrEqualToInDateTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts <= '" + date3 + "'"); + checkCount(2l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLessThanOrEqualToInDateTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 <= '" + date3 + "'"); + checkCount(2l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLessThanOrEqualToInNumberTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts <= '" + timestamp3 + "'"); + checkCount(2l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryLessThanOrEqualToInNumberTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 <= '" + timestamp3 + "'"); + checkCount(2l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryBetweenAndInDateTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts <= '" + date3 + "' AND ts > '" + date2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts <= '" + date3 + "' AND ts > '" + date2 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryBetweenAndInDateTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 <= '" + date3 + "' AND ts2 > '" + date2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 <= '" + date3 + "' AND ts2 > '" + date2 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryBetweenAndInNumberTypeForFirstCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts <= '" + timestamp3 + "' AND ts > '" + timestamp2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts from " + ns_timestamp_db + ".weather where ts <= '" + timestamp3 + "' AND ts > '" + timestamp2 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryBetweenAndInNumberTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 <= '" + timestamp3 + "' AND ts2 > '" + timestamp2 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 <= '" + timestamp3 + "' AND ts2 > '" + timestamp2 + "'"); + checkTime(timestamp3, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryNotEqualToInDateTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 <> '" + date3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 <> '" + date3 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryNotEqualToInNumberTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 <> '" + timestamp3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 <> '" + timestamp3 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryNotEqualInDateTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 != '" + date3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 != '" + date3 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canQueryNotEqualInNumberTypeForSecondCol() { + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 != '" + timestamp3 + "'"); + checkCount(1l, rs); + rs = stmt.executeQuery("select ts2 from " + ns_timestamp_db + ".weather where ts2 != '" + timestamp3 + "'"); + checkTime(timestamp2, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canInsertTimestampWithNowAndNsOffsetInBothFirstAndSecondCol(){ + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(now + 1000b, now - 1000b, 128)"); + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather"); + checkCount(3l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canIntervalAndSlidingAcceptNsUnitForFirstCol(){ + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select sum(f1) from " + ns_timestamp_db + ".weather where ts >= '" + date2 + "' and ts <= '" + date3 + "' interval(10000000b) sliding(10000000b)"); + rs.next(); + long sum = rs.getLong(2); + Assert.assertEquals(127l, sum); + rs.next(); + sum = rs.getLong(2); + Assert.assertEquals(128l, sum); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void canIntervalAndSlidingAcceptNsUnitForSecondCol(){ + try (Statement stmt = conn.createStatement()) { + ResultSet rs = stmt.executeQuery("select sum(f1) from " + ns_timestamp_db + ".weather where ts2 >= '" + date2 + "' and ts <= '" + date3 + "' interval(10000000b) sliding(10000000b)"); + rs.next(); + long sum = rs.getLong(2); + Assert.assertEquals(127l, sum); + rs.next(); + sum = rs.getLong(2); + Assert.assertEquals(128l, sum); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void testDataOutOfRangeExceptionForFirstCol() { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(123456789012345678, 1234567890123456789, 127)"); + } catch (SQLException e) { + Assert.assertEquals("TDengine ERROR (8000060b): Timestamp data out of range", e.getMessage()); + } + } + + @Test + public void testDataOutOfRangeExceptionForSecondCol() { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values(1234567890123456789, 123456789012345678, 127)"); + } catch (SQLException e) { + Assert.assertEquals("TDengine ERROR (8000060b): Timestamp data out of range", e.getMessage()); + } + } + + @Test + public void willAutomaticallyFillToNsUnitWithZerosForFirstCol() { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values('" + date1 + "', '" + date1 + "', 127)"); + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts = '" + date1 + "000000'"); + checkCount(1l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void willAutomaticallyFillToNsUnitWithZerosForSecondCol() { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values('" + date1 + "', '" + date1 + "', 127)"); + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 = '" + date1 + "000000'"); + checkCount(1l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void willAutomaticallyDropDigitExceedNsDigitNumberForFirstCol() { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values('" + date1 + "999999999', '" + date1 + "999999999', 127)"); + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts = '" + date1 + "999999'"); + checkCount(1l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } + + @Test + public void willAutomaticallyDropDigitExceedNsDigitNumberForSecondCol() { + try (Statement stmt = conn.createStatement()) { + stmt.executeUpdate("insert into " + ns_timestamp_db + ".weather(ts, ts2, f1) values('" + date1 + "999999999', '" + date1 + "999999999', 127)"); + ResultSet rs = stmt.executeQuery("select count(*) from " + ns_timestamp_db + ".weather where ts2 = '" + date1 + "999999'"); + checkCount(1l, rs); + } catch (SQLException e) { + e.printStackTrace(); + } + } +} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java index a052fbbdcbc241a18cb7dd73b8b4ade053533541..85007db0e555634b25dee4f10446b1041bf19b21 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java @@ -10,6 +10,7 @@ import java.sql.*; import java.util.Properties; public class RestfulDatabaseMetaDataTest { + private static final String host = "127.0.0.1"; private static final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"; private static Connection connection; @@ -632,17 +633,32 @@ public class RestfulDatabaseMetaDataTest { @Test public void getTables() throws SQLException { - System.out.println("****************************************************"); - ResultSet tables = metaData.getTables("log", "", null, null); - ResultSetMetaData metaData = tables.getMetaData(); - while (tables.next()) { - System.out.print(metaData.getColumnLabel(1) + ":" + tables.getString(1) + "\t"); - System.out.print(metaData.getColumnLabel(3) + ":" + tables.getString(3) + "\t"); - System.out.print(metaData.getColumnLabel(4) + ":" + tables.getString(4) + "\t"); - System.out.print(metaData.getColumnLabel(5) + ":" + tables.getString(5) + "\n"); + ResultSet rs = metaData.getTables("log", "", null, null); + ResultSetMetaData meta = rs.getMetaData(); + Assert.assertNotNull(rs); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_SCHEM + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertNotNull(rs.getString(3)); + Assert.assertNotNull(rs.getString("TABLE_NAME")); + // TABLE_TYPE + Assert.assertEquals("TABLE_TYPE", meta.getColumnLabel(4)); + Assert.assertEquals("TABLE", rs.getString(4)); + Assert.assertEquals("TABLE", rs.getString("TABLE_TYPE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(5)); + Assert.assertEquals("", rs.getString(5)); + Assert.assertEquals("", rs.getString("REMARKS")); } - System.out.println(); - Assert.assertNotNull(tables); } @Test @@ -652,46 +668,130 @@ public class RestfulDatabaseMetaDataTest { @Test public void getCatalogs() throws SQLException { - System.out.println("****************************************************"); - - ResultSet catalogs = metaData.getCatalogs(); - ResultSetMetaData meta = catalogs.getMetaData(); - while (catalogs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + catalogs.getString(i)); - } - System.out.println(); + ResultSet rs = metaData.getCatalogs(); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertNotNull(rs.getString(1)); + Assert.assertNotNull(rs.getString("TABLE_CAT")); } } @Test public void getTableTypes() throws SQLException { - System.out.println("****************************************************"); - ResultSet tableTypes = metaData.getTableTypes(); - while (tableTypes.next()) { - System.out.println(tableTypes.getString("TABLE_TYPE")); + tableTypes.next(); + // tableTypes: table + { + Assert.assertEquals("TABLE", tableTypes.getString(1)); + Assert.assertEquals("TABLE", tableTypes.getString("TABLE_TYPE")); + } + tableTypes.next(); + // tableTypes: stable + { + Assert.assertEquals("STABLE", tableTypes.getString(1)); + Assert.assertEquals("STABLE", tableTypes.getString("TABLE_TYPE")); } - Assert.assertNotNull(metaData.getTableTypes()); } @Test public void getColumns() throws SQLException { - System.out.println("****************************************************"); - + // when ResultSet columns = metaData.getColumns("log", "", "dn", ""); + // then ResultSetMetaData meta = columns.getMetaData(); - while (columns.next()) { - System.out.print(meta.getColumnLabel(1) + ": " + columns.getString(1) + "\t"); - System.out.print(meta.getColumnLabel(3) + ": " + columns.getString(3) + "\t"); - System.out.print(meta.getColumnLabel(4) + ": " + columns.getString(4) + "\t"); - System.out.print(meta.getColumnLabel(5) + ": " + columns.getString(5) + "\t"); - System.out.print(meta.getColumnLabel(6) + ": " + columns.getString(6) + "\t"); - System.out.print(meta.getColumnLabel(7) + ": " + columns.getString(7) + "\t"); - System.out.print(meta.getColumnLabel(9) + ": " + columns.getString(9) + "\t"); - System.out.print(meta.getColumnLabel(10) + ": " + columns.getString(10) + "\t"); - System.out.print(meta.getColumnLabel(11) + ": " + columns.getString(11) + "\n"); - System.out.print(meta.getColumnLabel(12) + ": " + columns.getString(12) + "\n"); + columns.next(); + // column: 1 + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", columns.getString(1)); + Assert.assertEquals("log", columns.getString("TABLE_CAT")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn", columns.getString(3)); + Assert.assertEquals("dn", columns.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("ts", columns.getString(4)); + Assert.assertEquals("ts", columns.getString("COLUMN_NAME")); + // DATA_TYPE + Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5)); + Assert.assertEquals(Types.TIMESTAMP, columns.getInt(5)); + Assert.assertEquals(Types.TIMESTAMP, columns.getInt("DATA_TYPE")); + // TYPE_NAME + Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("TIMESTAMP", columns.getString(6)); + Assert.assertEquals("TIMESTAMP", columns.getString("TYPE_NAME")); + // COLUMN_SIZE + Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7)); + Assert.assertEquals(26, columns.getInt(7)); + Assert.assertEquals(26, columns.getInt("COLUMN_SIZE")); + // DECIMAL_DIGITS + Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS")); + Assert.assertEquals(null, columns.getString(9)); + Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS")); + // NUM_PREC_RADIX + Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10)); + Assert.assertEquals(10, columns.getInt(10)); + Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX")); + // NULLABLE + Assert.assertEquals("NULLABLE", meta.getColumnLabel(11)); + Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt(11)); + Assert.assertEquals(DatabaseMetaData.columnNoNulls, columns.getInt("NULLABLE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(12)); + Assert.assertEquals(null, columns.getString(12)); + Assert.assertEquals(null, columns.getString("REMARKS")); + } + columns.next(); + // column: 2 + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", columns.getString(1)); + Assert.assertEquals("log", columns.getString("TABLE_CAT")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn", columns.getString(3)); + Assert.assertEquals("dn", columns.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("cpu_taosd", columns.getString(4)); + Assert.assertEquals("cpu_taosd", columns.getString("COLUMN_NAME")); + // DATA_TYPE + Assert.assertEquals("DATA_TYPE", meta.getColumnLabel(5)); + Assert.assertEquals(Types.FLOAT, columns.getInt(5)); + Assert.assertEquals(Types.FLOAT, columns.getInt("DATA_TYPE")); + // TYPE_NAME + Assert.assertEquals("TYPE_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("FLOAT", columns.getString(6)); + Assert.assertEquals("FLOAT", columns.getString("TYPE_NAME")); + // COLUMN_SIZE + Assert.assertEquals("COLUMN_SIZE", meta.getColumnLabel(7)); + Assert.assertEquals(12, columns.getInt(7)); + Assert.assertEquals(12, columns.getInt("COLUMN_SIZE")); + // DECIMAL_DIGITS + Assert.assertEquals("DECIMAL_DIGITS", meta.getColumnLabel(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt(9)); + Assert.assertEquals(Integer.MIN_VALUE, columns.getInt("DECIMAL_DIGITS")); + Assert.assertEquals(null, columns.getString(9)); + Assert.assertEquals(null, columns.getString("DECIMAL_DIGITS")); + // NUM_PREC_RADIX + Assert.assertEquals("NUM_PREC_RADIX", meta.getColumnLabel(10)); + Assert.assertEquals(10, columns.getInt(10)); + Assert.assertEquals(10, columns.getInt("NUM_PREC_RADIX")); + // NULLABLE + Assert.assertEquals("NULLABLE", meta.getColumnLabel(11)); + Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt(11)); + Assert.assertEquals(DatabaseMetaData.columnNullable, columns.getInt("NULLABLE")); + // REMARKS + Assert.assertEquals("REMARKS", meta.getColumnLabel(12)); + Assert.assertEquals(null, columns.getString(12)); } } @@ -717,17 +817,35 @@ public class RestfulDatabaseMetaDataTest { @Test public void getPrimaryKeys() throws SQLException { - System.out.println("****************************************************"); - ResultSet rs = metaData.getPrimaryKeys("log", "", "dn1"); - while (rs.next()) { - System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); - System.out.println("COLUMN_NAME: " + rs.getString("COLUMN_NAME")); - System.out.println("KEY_SEQ: " + rs.getString("KEY_SEQ")); - System.out.println("PK_NAME: " + rs.getString("PK_NAME")); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_SCHEM + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_NAME + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn1", rs.getString(3)); + Assert.assertEquals("dn1", rs.getString("TABLE_NAME")); + // COLUMN_NAME + Assert.assertEquals("COLUMN_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("ts", rs.getString(4)); + Assert.assertEquals("ts", rs.getString("COLUMN_NAME")); + // KEY_SEQ + Assert.assertEquals("KEY_SEQ", meta.getColumnLabel(5)); + Assert.assertEquals(1, rs.getShort(5)); + Assert.assertEquals(1, rs.getShort("KEY_SEQ")); + // DATA_TYPE + Assert.assertEquals("PK_NAME", meta.getColumnLabel(6)); + Assert.assertEquals("ts", rs.getString(6)); + Assert.assertEquals("ts", rs.getString("PK_NAME")); } - - Assert.assertNotNull(rs); } @Test @@ -852,14 +970,27 @@ public class RestfulDatabaseMetaDataTest { @Test public void getSuperTables() throws SQLException { - System.out.println("****************************************************"); - ResultSet rs = metaData.getSuperTables("log", "", "dn1"); - while (rs.next()) { - System.out.println("TABLE_NAME: " + rs.getString("TABLE_NAME")); - System.out.println("SUPERTABLE_NAME: " + rs.getString("SUPERTABLE_NAME")); + ResultSetMetaData meta = rs.getMetaData(); + rs.next(); + { + // TABLE_CAT + Assert.assertEquals("TABLE_CAT", meta.getColumnLabel(1)); + Assert.assertEquals("log", rs.getString(1)); + Assert.assertEquals("log", rs.getString("TABLE_CAT")); + // TABLE_CAT + Assert.assertEquals("TABLE_SCHEM", meta.getColumnLabel(2)); + Assert.assertEquals(null, rs.getString(2)); + Assert.assertEquals(null, rs.getString("TABLE_SCHEM")); + // TABLE_CAT + Assert.assertEquals("TABLE_NAME", meta.getColumnLabel(3)); + Assert.assertEquals("dn1", rs.getString(3)); + Assert.assertEquals("dn1", rs.getString("TABLE_NAME")); + // TABLE_CAT + Assert.assertEquals("SUPERTABLE_NAME", meta.getColumnLabel(4)); + Assert.assertEquals("dn", rs.getString(4)); + Assert.assertEquals("dn", rs.getString("SUPERTABLE_NAME")); } - Assert.assertNotNull(rs); } @Test diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java index e239aa068bae0ee70d204aec4412bf29e5b36bf1..c2f732c86903dc80328f975260a4b2352e55efd9 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java @@ -8,11 +8,6 @@ import java.sql.*; public class RestfulDriverTest { private static final String host = "127.0.0.1"; - @Test - public void connect() { - - } - @Test public void acceptsURL() throws SQLException { Driver driver = new RestfulDriver(); @@ -27,9 +22,7 @@ public class RestfulDriverTest { Driver driver = new RestfulDriver(); final String url = ""; DriverPropertyInfo[] propertyInfo = driver.getPropertyInfo(url, null); - for (DriverPropertyInfo prop : propertyInfo) { - System.out.println(prop); - } + Assert.assertNotNull(propertyInfo); } @Test diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java index c8bb69d82749e606f18d3298697ea0995029d064..b07dae8003d6e2fea073c0d240f59fb6db0c593f 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java @@ -10,132 +10,151 @@ import java.util.Random; public class RestfulJDBCTest { private static final String host = "127.0.0.1"; - private static Connection connection; - private Random random = new Random(System.currentTimeMillis()); + private final Random random = new Random(System.currentTimeMillis()); + private Connection connection; - /** - * select * from log.log - **/ @Test public void testCase001() { - try { - Statement statement = connection.createStatement(); - ResultSet resultSet = statement.executeQuery("select * from log.log"); - ResultSetMetaData metaData = resultSet.getMetaData(); - while (resultSet.next()) { - for (int i = 1; i <= metaData.getColumnCount(); i++) { - String column = metaData.getColumnLabel(i); - String value = resultSet.getString(i); - System.out.print(column + ":" + value + "\t"); - } - System.out.println(); - } - statement.close(); - } catch (SQLException e) { - e.printStackTrace(); - } + // given + String sql = "drop database if exists restful_test"; + // when + boolean execute = execute(connection, sql); + // then + Assert.assertFalse(execute); + + // given + sql = "create database if not exists restful_test"; + // when + execute = execute(connection, sql); + // then + Assert.assertFalse(execute); + + // given + sql = "use restful_test"; + // when + execute = execute(connection, sql); + // then + Assert.assertFalse(execute); } - /** - * create database - */ @Test public void testCase002() { - try (Statement stmt = connection.createStatement()) { - stmt.execute("drop database if exists restful_test"); - stmt.execute("create database if not exists restful_test"); - stmt.execute("use restful_test"); - } catch (SQLException e) { - e.printStackTrace(); - } + // given + String sql = "create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)"; + // when + boolean execute = execute(connection, sql); + // then + Assert.assertFalse(execute); } - /** - * create super table - ***/ @Test - public void testCase003() { - try (Statement stmt = connection.createStatement()) { - stmt.execute("create table weather(ts timestamp, temperature float, humidity int) tags(location nchar(64), groupId int)"); - } catch (SQLException e) { - e.printStackTrace(); + public void testCase004() { + for (int i = 1; i <= 100; i++) { + // given + String sql = "create table t" + i + " using weather tags('beijing', '" + i + "')"; + // when + boolean execute = execute(connection, sql); + // then + Assert.assertFalse(execute); } } @Test - public void testCase004() { - try (Statement stmt = connection.createStatement()) { - for (int i = 1; i <= 100; i++) { - stmt.execute("create table t" + i + " using weather tags('beijing', '" + i + "')"); + public void testCase005() { + int rows = 0; + for (int i = 0; i < 10; i++) { + for (int j = 1; j <= 100; j++) { + + // given + long currentTimeMillis = System.currentTimeMillis(); + String sql = "insert into t" + j + " values(" + currentTimeMillis + "," + (random.nextFloat() * 50) + "," + random.nextInt(100) + ")"; + // when + int affectRows = executeUpdate(connection, sql); + // then + Assert.assertEquals(1, affectRows); + + rows += affectRows; } - } catch (SQLException e) { - e.printStackTrace(); } + Assert.assertEquals(1000, rows); } + @Test + public void testCase006() throws SQLException { + // given + String sql = "select * from weather"; + // when + ResultSet rs = executeQuery(connection, sql); + ResultSetMetaData meta = rs.getMetaData(); + + // then + Assert.assertEquals(5, meta.getColumnCount()); + + while (rs.next()) { + Assert.assertNotNull(rs.getTimestamp("ts")); + Assert.assertNotNull(rs.getFloat("temperature")); + Assert.assertNotNull(rs.getInt("humidity")); + Assert.assertNotNull(rs.getString("location")); + } + } @Test - public void testCase005() { + public void testCase007() { + // given + String sql = "drop database restful_test"; + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); + } + + private int executeUpdate(Connection connection, String sql) { try (Statement stmt = connection.createStatement()) { - int rows = 0; - for (int i = 0; i < 10; i++) { - for (int j = 1; j <= 100; j++) { - long currentTimeMillis = System.currentTimeMillis(); - int affectRows = stmt.executeUpdate("insert into t" + j + " values(" + currentTimeMillis + "," + (random.nextFloat() * 50) + "," + random.nextInt(100) + ")"); - Assert.assertEquals(1, affectRows); - rows += affectRows; - } - } - Assert.assertEquals(1000, rows); + return stmt.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } + return 0; } - @Test - public void testCase006() { + private boolean execute(Connection connection, String sql) { try (Statement stmt = connection.createStatement()) { - ResultSet rs = stmt.executeQuery("select * from weather"); - while (rs.next()) { - System.out.print("ts: " + rs.getTimestamp("ts")); - System.out.print(", temperature: " + rs.getString("temperature")); - System.out.print(", humidity: " + rs.getString("humidity")); - System.out.println(", location: " + rs.getString("location")); - } + return stmt.execute(sql); } catch (SQLException e) { e.printStackTrace(); } + return false; } - @Test - public void testCase007() { - try (Statement stmt = connection.createStatement()) { - ResultSet rs = stmt.executeQuery("select * from weather"); - ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - int columnCount = meta.getColumnCount(); - for (int i = 1; i <= columnCount; i++) { - String columnLabel = meta.getColumnLabel(i); - String value = rs.getString(i); - System.out.print(columnLabel + ": " + value + "\t"); - } - System.out.println(); - } + + private ResultSet executeQuery(Connection connection, String sql) { + try (Statement statement = connection.createStatement()) { + return statement.executeQuery(sql); } catch (SQLException e) { e.printStackTrace(); } + return null; } - @BeforeClass - public static void before() throws ClassNotFoundException, SQLException { - Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); - connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata"); + @Before + public void before() { + try { + connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata"); + } catch (SQLException e) { + e.printStackTrace(); + } } - @AfterClass - public static void after() throws SQLException { - if (connection != null) - connection.close(); + @After + public void after() { + try { + if (connection != null) + connection.close(); + } catch (SQLException e) { + e.printStackTrace(); + } } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java index 8bb2532ce82e24e4015746e04b5b2dea18f530e4..81d7f5b56c4b4e67b9573522ee031006a7e11a2b 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java @@ -54,16 +54,17 @@ public class RestfulParameterMetaDataTest { @Test public void getPrecision() throws SQLException { - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(1)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(2)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(3)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(4)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(5)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(6)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(7)); - Assert.assertEquals(0, parameterMetaData_insert.getPrecision(8)); - Assert.assertEquals(5, parameterMetaData_insert.getPrecision(9)); - Assert.assertEquals(5, parameterMetaData_insert.getPrecision(10)); + //create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) + Assert.assertEquals(TSDBConstants.TIMESTAMP_MS_PRECISION, parameterMetaData_insert.getPrecision(1)); + Assert.assertEquals(TSDBConstants.INT_PRECISION, parameterMetaData_insert.getPrecision(2)); + Assert.assertEquals(TSDBConstants.BIGINT_PRECISION, parameterMetaData_insert.getPrecision(3)); + Assert.assertEquals(TSDBConstants.FLOAT_PRECISION, parameterMetaData_insert.getPrecision(4)); + Assert.assertEquals(TSDBConstants.DOUBLE_PRECISION, parameterMetaData_insert.getPrecision(5)); + Assert.assertEquals(TSDBConstants.SMALLINT_PRECISION, parameterMetaData_insert.getPrecision(6)); + Assert.assertEquals(TSDBConstants.TINYINT_PRECISION, parameterMetaData_insert.getPrecision(7)); + Assert.assertEquals(TSDBConstants.BOOLEAN_PRECISION, parameterMetaData_insert.getPrecision(8)); + Assert.assertEquals("hello".getBytes().length, parameterMetaData_insert.getPrecision(9)); + Assert.assertEquals("涛思数据".length(), parameterMetaData_insert.getPrecision(10)); } @Test @@ -71,8 +72,8 @@ public class RestfulParameterMetaDataTest { Assert.assertEquals(0, parameterMetaData_insert.getScale(1)); Assert.assertEquals(0, parameterMetaData_insert.getScale(2)); Assert.assertEquals(0, parameterMetaData_insert.getScale(3)); - Assert.assertEquals(0, parameterMetaData_insert.getScale(4)); - Assert.assertEquals(0, parameterMetaData_insert.getScale(5)); + Assert.assertEquals(31, parameterMetaData_insert.getScale(4)); + Assert.assertEquals(31, parameterMetaData_insert.getScale(5)); Assert.assertEquals(0, parameterMetaData_insert.getScale(6)); Assert.assertEquals(0, parameterMetaData_insert.getScale(7)); Assert.assertEquals(0, parameterMetaData_insert.getScale(8)); @@ -164,7 +165,7 @@ public class RestfulParameterMetaDataTest { pstmt_insert.setObject(7, Byte.MAX_VALUE); pstmt_insert.setObject(8, true); pstmt_insert.setObject(9, "hello".getBytes()); - pstmt_insert.setObject(10, "Hello"); + pstmt_insert.setObject(10, "涛思数据"); parameterMetaData_insert = pstmt_insert.getParameterMetaData(); pstmt_select = conn.prepareStatement(sql_select); diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java index ee457ff4127ccf3fe88cf277d581a3dcb3475df9..244e8afd117868432638c771b21048fae3b1367c 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java @@ -27,12 +27,9 @@ public class RestfulPreparedStatementTest { ResultSet rs = pstmt_select.executeQuery(); Assert.assertNotNull(rs); ResultSetMetaData meta = rs.getMetaData(); - while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); - } + int columnCount = meta.getColumnCount(); + Assert.assertEquals(10, columnCount); + Assert.assertNotNull(rs); } @Test @@ -373,18 +370,19 @@ public class RestfulPreparedStatementTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata"); - try (Statement stmt = conn.createStatement()) { - stmt.execute("drop database if exists test_pstmt"); - stmt.execute("create database if not exists test_pstmt"); - stmt.execute("use test_pstmt"); - stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))"); - stmt.execute("create table t1 using weather tags('beijing')"); - } + + Statement stmt = conn.createStatement(); + stmt.execute("drop database if exists test_pstmt"); + stmt.execute("create database if not exists test_pstmt"); + stmt.execute("use test_pstmt"); + stmt.execute("create table weather(ts timestamp, f1 int, f2 bigint, f3 float, f4 double, f5 smallint, f6 tinyint, f7 bool, f8 binary(64), f9 nchar(64)) tags(loc nchar(64))"); + stmt.execute("create table t1 using weather tags('beijing')"); + stmt.close(); + pstmt_insert = conn.prepareStatement(sql_insert); pstmt_select = conn.prepareStatement(sql_select); - } catch (ClassNotFoundException | SQLException e) { + } catch (SQLException e) { e.printStackTrace(); } } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulStatementTest.java index 1be32b502d3f8f7c1b94cd1a8940073520e11b12..a7b3ceb9d3bb243a2a053d5289afe39d3c870d79 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulStatementTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulStatementTest.java @@ -12,6 +12,7 @@ import java.util.UUID; public class RestfulStatementTest { private static final String host = "127.0.0.1"; + private static Connection conn; private static Statement stmt; @@ -21,11 +22,11 @@ public class RestfulStatementTest { ResultSet rs = stmt.executeQuery("show databases"); Assert.assertNotNull(rs); ResultSetMetaData meta = rs.getMetaData(); + int columnCount = meta.getColumnCount(); + Assert.assertTrue(columnCount > 1); while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); + Assert.assertEquals("name", meta.getColumnLabel(1)); + Assert.assertNotNull(rs.getString("name")); } rs.close(); } catch (SQLException e) { @@ -174,10 +175,10 @@ public class RestfulStatementTest { Assert.assertEquals(3, meta.getColumnCount()); int count = 0; while (rs.next()) { - for (int i = 1; i <= meta.getColumnCount(); i++) { - System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t"); - } - System.out.println(); + Assert.assertEquals("ts", meta.getColumnLabel(1)); + Assert.assertNotNull(rs.getTimestamp(1)); + Assert.assertEquals("temperature", meta.getColumnLabel(2)); + Assert.assertEquals(22.33, rs.getFloat(2), 0.001f); count++; } Assert.assertEquals(1, count); @@ -388,15 +389,12 @@ public class RestfulStatementTest { @BeforeClass public static void beforeClass() { try { - Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); 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("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata", properties); stmt = conn.createStatement(); - } catch (ClassNotFoundException e) { - e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/SQLTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/SQLTest.java index 4ad9826384a93e221b1181b72fa576bf72ebaff4..6b88de258dd4addda06cfb6e971b9d4dd267b7b4 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/SQLTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/SQLTest.java @@ -1,342 +1,586 @@ package com.taosdata.jdbc.rs; -import com.taosdata.jdbc.utils.SQLExecutor; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.FixMethodOrder; -import org.junit.Test; +import org.junit.*; import org.junit.runners.MethodSorters; import java.sql.*; @FixMethodOrder(MethodSorters.NAME_ASCENDING) public class SQLTest { + private static final String host = "127.0.0.1"; private static Connection connection; @Test public void testCase001() { + // given String sql = "create database if not exists restful_test"; - SQLExecutor.execute(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase002() { + // given String sql = "use restful_test"; - SQLExecutor.execute(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase003() { + // given String sql = "show databases"; - SQLExecutor.executeWithResult(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertTrue(execute); } @Test public void testCase004() { + // given String sql = "show tables"; - SQLExecutor.executeWithResult(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertTrue(execute); } @Test public void testCase005() { + // given String sql = "show stables"; - SQLExecutor.executeWithResult(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertTrue(execute); } @Test public void testCase006() { + // given String sql = "show dnodes"; - SQLExecutor.executeWithResult(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertTrue(execute); } @Test public void testCase007() { + // given String sql = "show vgroups"; - SQLExecutor.executeWithResult(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertTrue(execute); } @Test public void testCase008() { + // given String sql = "drop table if exists restful_test.weather"; - SQLExecutor.execute(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase009() { + // given String sql = "create table if not exists restful_test.weather(ts timestamp, temperature float) tags(location nchar(64))"; - SQLExecutor.execute(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase010() { + // given String sql = "create table t1 using restful_test.weather tags('北京')"; - SQLExecutor.execute(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase011() { + // given String sql = "insert into restful_test.t1 values(now, 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase012() { + // given String sql = "insert into restful_test.t1 values('2020-01-01 00:00:00.000', 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase013() { + // given String sql = "insert into restful_test.t1 values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase014() { + // given String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:03:00.000', 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase015() { + // given String sql = "insert into restful_test.t2 using weather tags('上海') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase016() { + // given String sql = "insert into t1 values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t2 values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)"; - SQLExecutor.executeUpdate(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase017() { + // given String sql = "Insert into t3 using weather tags('广东') values('2020-01-01 01:0:00.000', 22.22),('2020-01-01 02:00:00.000', 22.22) t4 using weather tags('天津') values('2020-01-01 01:0:00.000', 33.33),('2020-01-01 02:00:00.000', 33.33)"; - SQLExecutor.executeUpdate(connection, sql); + + // when + boolean execute = execute(connection, sql); + + // then + Assert.assertFalse(execute); } @Test public void testCase018() { + // given String sql = "select * from restful_test.t1"; - SQLExecutor.executeQuery(connection, sql); + // when + boolean execute = execute(connection, sql); + // then + Assert.assertTrue(execute); } @Test public void testCase019() { + // given String sql = "select * from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + boolean execute = execute(connection, sql); + // then + Assert.assertTrue(execute); } @Test public void testCase020() { + // given String sql = "select ts, temperature from restful_test.t1"; - SQLExecutor.executeQuery(connection, sql); + // when + boolean execute = execute(connection, sql); + // then + Assert.assertTrue(execute); } @Test public void testCase021() { + // given String sql = "select ts, temperature from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + boolean execute = execute(connection, sql); + // then + Assert.assertTrue(execute); } @Test public void testCase022() { + // given String sql = "select temperature, ts from restful_test.t1"; - SQLExecutor.executeQuery(connection, sql); + // when + boolean execute = execute(connection, sql); + // then + Assert.assertTrue(execute); } @Test public void testCase023() { + // given String sql = "select temperature, ts from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + boolean execute = execute(connection, sql); + // then + Assert.assertTrue(execute); } @Test public void testCase024() { + // given String sql = "import into restful_test.t5 using weather tags('石家庄') values('2020-01-01 00:01:00.000', 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + // when + int affectedRows = executeUpdate(connection, sql); + // then + Assert.assertEquals(1, affectedRows); } @Test public void testCase025() { + // given String sql = "import into restful_test.t6 using weather tags('沈阳') values('2020-01-01 00:01:00.000', 22.22),('2020-01-01 00:02:00.000', 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + // when + int affectedRows = executeUpdate(connection, sql); + // then + Assert.assertEquals(2, affectedRows); } @Test public void testCase026() { + // given String sql = "import into restful_test.t7 using weather tags('长沙') values('2020-01-01 00:01:00.000', 22.22) restful_test.t8 using weather tags('吉林') values('2020-01-01 00:01:00.000', 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + + // when + int affectedRows = executeUpdate(connection, sql); + // then + Assert.assertEquals(2, affectedRows); } @Test public void testCase027() { + // given String sql = "import into restful_test.t9 using weather tags('武汉') values('2020-01-01 00:01:00.000', 22.22) ,('2020-01-02 00:01:00.000', 22.22) restful_test.t10 using weather tags('哈尔滨') values('2020-01-01 00:01:00.000', 22.22),('2020-01-02 00:01:00.000', 22.22)"; - SQLExecutor.executeUpdate(connection, sql); + // when + int affectedRows = executeUpdate(connection, sql); + // then + Assert.assertEquals(4, affectedRows); } @Test public void testCase028() { + // given String sql = "select location, temperature, ts from restful_test.weather where temperature > 1"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase029() { String sql = "select location, temperature, ts from restful_test.weather where temperature < 1"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase030() { String sql = "select location, temperature, ts from restful_test.weather where ts > now"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase031() { String sql = "select location, temperature, ts from restful_test.weather where ts < now"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase032() { String sql = "select count(*) from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase033() { String sql = "select first(*) from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase034() { String sql = "select last(*) from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase035() { String sql = "select last_row(*) from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase036() { String sql = "select ts, ts as primary_key from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase037() { String sql = "select database()"; - SQLExecutor.execute(connection, "use restful_test"); - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase038() { String sql = "select client_version()"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase039() { String sql = "select server_status()"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase040() { String sql = "select server_status() as status"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase041() { String sql = "select tbname, location from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase042() { String sql = "select count(tbname) from restful_test.weather"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase043() { String sql = "select * from restful_test.weather where ts < now - 1h"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase044() { String sql = "select * from restful_test.weather where ts < now - 1h and location like '%'"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase045() { String sql = "select * from restful_test.weather where ts < now - 1h order by ts"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase046() { String sql = "select last(*) from restful_test.weather where ts < now - 1h group by tbname order by tbname"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase047() { String sql = "select * from restful_test.weather limit 2"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase048() { String sql = "select * from restful_test.weather limit 2 offset 5"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase049() { String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts "; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase050() { String sql = "select * from restful_test.t1, restful_test.t3 where t1.ts = t3.ts and t1.location = t3.location"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase051() { String sql = "select * from restful_test.t1 tt, restful_test.t3 yy where tt.ts = yy.ts"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase052() { String sql = "select server_status()"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); } @Test public void testCase053() { String sql = "select avg(cpu_taosd), avg(cpu_system), max(cpu_cores), avg(mem_taosd), avg(mem_system), max(mem_total), avg(disk_used), max(disk_total), avg(band_speed), avg(io_read), avg(io_write), sum(req_http), sum(req_select), sum(req_insert) from log.dn1 where ts> now - 60m and ts<= now interval(1m) fill(value, 0)"; - SQLExecutor.executeQuery(connection, sql); + // when + ResultSet rs = executeQuery(connection, sql); + // then + Assert.assertNotNull(rs); + } + + private boolean execute(Connection connection, String sql) { + try (Statement statement = connection.createStatement()) { + return statement.execute(sql); + } catch (SQLException e) { + e.printStackTrace(); + } + return false; + } + + private ResultSet executeQuery(Connection connection, String sql) { + try (Statement statement = connection.createStatement()) { + return statement.executeQuery(sql); + } catch (SQLException e) { + e.printStackTrace(); + } + return null; + } + + private int executeUpdate(Connection connection, String sql) { + try (Statement statement = connection.createStatement()) { + return statement.executeUpdate(sql); + } catch (SQLException e) { + e.printStackTrace(); + } + return 0; } @BeforeClass - public static void before() throws ClassNotFoundException, SQLException { - Class.forName("com.taosdata.jdbc.rs.RestfulDriver"); + public static void before() throws SQLException { connection = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=root&password=taosdata"); } diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SQLExecutor.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SQLExecutor.java deleted file mode 100644 index bf034bf458bcb8eadaaacb5cf633f0905a8c1bd6..0000000000000000000000000000000000000000 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/SQLExecutor.java +++ /dev/null @@ -1,74 +0,0 @@ -package com.taosdata.jdbc.utils; - -import java.sql.*; - -public class SQLExecutor { - - // insert, import - public static void executeUpdate(Connection connection, String sql) { - try (Statement statement = connection.createStatement()) { - long start = System.currentTimeMillis(); - int affectedRows = statement.executeUpdate(sql); - long end = System.currentTimeMillis(); - System.out.println("[ affected rows : " + affectedRows + " ] time cost: " + (end - start) + " ms, execute statement ====> " + sql); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - // show databases, show tables, show stables - public static void executeWithResult(Connection connection, String sql) { - try (Statement statement = connection.createStatement()) { - statement.execute(sql); - ResultSet resultSet = statement.getResultSet(); - printResult(resultSet); - } catch (SQLException e) { - e.printStackTrace(); - } - } - - // use database, create database, create table, drop table... - public static void execute(Connection connection, String sql) { - try (Statement statement = connection.createStatement()) { - long start = System.currentTimeMillis(); - boolean execute = statement.execute(sql); - long end = System.currentTimeMillis(); - printSql(sql, execute, (end - start)); - } catch (SQLException e) { - System.out.println("ERROR execute SQL ===> " + sql); - e.printStackTrace(); - } - } - - // select - public static void executeQuery(Connection connection, String sql) { - try (Statement statement = connection.createStatement()) { - long start = System.currentTimeMillis(); - ResultSet resultSet = statement.executeQuery(sql); - long end = System.currentTimeMillis(); - printSql(sql, true, (end - start)); - printResult(resultSet); - } catch (SQLException e) { - System.out.println("ERROR execute SQL ===> " + sql); - e.printStackTrace(); - } - } - - private static void printSql(String sql, boolean succeed, long cost) { - System.out.println("[ " + (succeed ? "OK" : "ERROR!") + " ] time cost: " + cost + " ms, execute statement ====> " + sql); - } - - private static void printResult(ResultSet resultSet) throws SQLException { - ResultSetMetaData metaData = resultSet.getMetaData(); - while (resultSet.next()) { - StringBuilder sb = new StringBuilder(); - for (int i = 1; i <= metaData.getColumnCount(); i++) { - String columnLabel = metaData.getColumnLabel(i); - String value = resultSet.getString(i); - sb.append(columnLabel + ": " + value + "\t"); - } - System.out.println(sb.toString()); - } - } - -} diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java index c861ef296607b244e4564423ad4024ea1f13df5d..ee83f6ceb2d412613129611e2a575a7ad4922db0 100644 --- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java +++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java @@ -3,22 +3,98 @@ package com.taosdata.jdbc.utils; import org.junit.Assert; import org.junit.Test; -import static org.junit.Assert.*; +import java.util.stream.Stream; public class UtilsTest { @Test public void escapeSingleQuota() { + // given String s = "'''''a\\'"; + // when String news = Utils.escapeSingleQuota(s); + // then Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news); + // given s = "\'''''a\\'"; + // when news = Utils.escapeSingleQuota(s); + // then Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news); + // given s = "\'\'\'\''a\\'"; + // when news = Utils.escapeSingleQuota(s); + // then Assert.assertEquals("\\'\\'\\'\\'\\'a\\'", news); } + + @Test + public void getNativeSqlReplaceQuestionMarks() { + // given + String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)"; + Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray(); + + // when + String actual = Utils.getNativeSql(nativeSql, parameters); + + // then + String expected = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)"; + Assert.assertEquals(expected, actual); + } + + @Test + public void getNativeSqlReplaceQuestionMarks2() { + // given + String nativeSql = "INSERT INTO ? (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (?) VALUES (?,?,?,?)"; + Object[] parameters = Stream.of("d1", 1, 123, 3.14, 220, 4).toArray(); + + // when + String actual = Utils.getNativeSql(nativeSql, parameters); + + // then + String expected = "INSERT INTO d1 (TS,CURRENT,VOLTAGE,PHASE) USING METERS TAGS (1) VALUES (123,3.14,220,4)"; + Assert.assertEquals(expected, actual); + } + + + @Test + public void getNativeSqlReplaceNothing() { + // given + String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)"; + + // when + String actual = Utils.getNativeSql(nativeSql, null); + + // then + Assert.assertEquals(nativeSql, actual); + } + + @Test + public void getNativeSqlReplaceNothing2() { + // given + String nativeSql = "insert into test.t1 (ts, temperature, humidity) using test.weather tags('beijing',1) values(now, 12.2, 4)"; + Object[] parameters = Stream.of("test", "t1", "test", "weather", "beijing", 1, 12.2, 4).toArray(); + + // when + String actual = Utils.getNativeSql(nativeSql, parameters); + + // then + Assert.assertEquals(nativeSql, actual); + } + + @Test + public void getNativeSqlReplaceNothing3() { + // given + String nativeSql = "insert into ?.? (ts, temperature, humidity) using ?.? tags(?,?) values(now, ?, ?)"; + + // when + String actual = Utils.getNativeSql(nativeSql, null); + + // then + Assert.assertEquals(nativeSql, actual); + + } } \ No newline at end of file diff --git a/src/connector/nodejs/nodetaos/cinterface.js b/src/connector/nodejs/nodetaos/cinterface.js index f3961e3787c4fb6d7da7092b68632d08a8b57e20..1c2685b8cb7ec14d66c97e04e32aa86ae94759f4 100644 --- a/src/connector/nodejs/nodetaos/cinterface.js +++ b/src/connector/nodejs/nodetaos/cinterface.js @@ -126,30 +126,20 @@ function convertDouble(data, num_of_rows, nbytes = 0, offset = 0, micro = false) } return res; } -function convertBinary(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { + +function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); let res = []; + let currOffset = 0; while (currOffset < data.length) { - let dataEntry = data.slice(currOffset, currOffset + nbytes); - if (dataEntry[0] == FieldTypes.C_BINARY_NULL) { - res.push(null); - } - else { - res.push(ref.readCString(dataEntry)); - } + let len = data.readIntLE(currOffset, 2); + let dataEntry = data.slice(currOffset + 2, currOffset + len + 2); //one entry in a row under a column; + res.push(dataEntry.toString("utf-8")); currOffset += nbytes; } return res; } -function convertNchar(data, num_of_rows, nbytes = 0, offset = 0, micro = false) { - data = ref.reinterpret(data.deref(), nbytes * num_of_rows, offset); - let res = []; - let dataEntry = data.slice(0, nbytes); //one entry in a row under a column; - //TODO: should use the correct character encoding - res.push(dataEntry.toString("utf-8")); - return res; -} // Object with all the relevant converters from pblock data to javascript readable data let convertFunctions = { @@ -160,7 +150,7 @@ let convertFunctions = { [FieldTypes.C_BIGINT]: convertBigint, [FieldTypes.C_FLOAT]: convertFloat, [FieldTypes.C_DOUBLE]: convertDouble, - [FieldTypes.C_BINARY]: convertBinary, + [FieldTypes.C_BINARY]: convertNchar, [FieldTypes.C_TIMESTAMP]: convertTimestamp, [FieldTypes.C_NCHAR]: convertNchar } diff --git a/src/connector/nodejs/package.json b/src/connector/nodejs/package.json index d21b62108b14e5a132ad5457d190bbcbc58b73a8..b57d4c635c05ba423bf1ea58f5dd64f70752f8bf 100644 --- a/src/connector/nodejs/package.json +++ b/src/connector/nodejs/package.json @@ -1,6 +1,6 @@ { "name": "td2.0-connector", - "version": "2.0.7", + "version": "2.0.8", "description": "A Node.js connector for TDengine.", "main": "tdengine.js", "directories": { diff --git a/src/connector/python/README.md b/src/connector/python/README.md index 9151e9b8f0bdbabbaecf2ac34f830f4260b14326..a5dc2b72dafbeef0bf53fc1768f6afc66e714699 100644 --- a/src/connector/python/README.md +++ b/src/connector/python/README.md @@ -5,12 +5,13 @@ ## Install ```sh -pip install git+https://github.com/taosdata/TDengine-connector-python +git clone --depth 1 https://github.com/taosdata/TDengine.git +pip install ./TDengine/src/connector/python ``` ## Source Code -[TDengine] connector for Python source code is hosted on [GitHub](https://github.com/taosdata/TDengine-connector-python). +[TDengine] connector for Python source code is hosted on [GitHub](https://github.com/taosdata/TDengine/tree/develop/src/connector/python). ## License - AGPL diff --git a/src/connector/python/setup.py b/src/connector/python/setup.py index 901e8396c0440bd1c90163f0360b687dd5684ff3..284861ca87dd77b1bc6799ad4cb32ff4c489e239 100644 --- a/src/connector/python/setup.py +++ b/src/connector/python/setup.py @@ -5,7 +5,7 @@ with open("README.md", "r") as fh: setuptools.setup( name="taos", - version="2.0.10", + version="2.0.11", author="Taosdata Inc.", author_email="support@taosdata.com", description="TDengine python client package", diff --git a/src/connector/python/taos/__init__.py b/src/connector/python/taos/__init__.py index 973263573808232e4e71dc0158585624a8e7d2ab..52c6db311ecc4c2f944372ae3334fdc58cb6e779 100644 --- a/src/connector/python/taos/__init__.py +++ b/src/connector/python/taos/__init__.py @@ -2,6 +2,10 @@ from .connection import TDengineConnection from .cursor import TDengineCursor +# For some reason, the following is needed for VS Code (through PyLance) to +# recognize that "error" is a valid module of the "taos" package. +from .error import ProgrammingError + # Globals threadsafety = 0 paramstyle = 'pyformat' diff --git a/src/connector/python/taos/cinterface.py b/src/connector/python/taos/cinterface.py index b8824327b017fc0bb7f9639942e20e72891ac808..cc7c279458c779b924564cdb17c88989014e3193 100644 --- a/src/connector/python/taos/cinterface.py +++ b/src/connector/python/taos/cinterface.py @@ -14,12 +14,22 @@ def _convert_microsecond_to_datetime(micro): return datetime.datetime.fromtimestamp(micro / 1000000.0) -def _crow_timestamp_to_python(data, num_of_rows, nbytes=None, micro=False): +def _convert_nanosecond_to_datetime(nanosec): + return nanosec + + +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) @@ -242,7 +252,7 @@ def _load_taos_linux(): def _load_taos_darwin(): - return ctypes.cDLL('libtaos.dylib') + return ctypes.CDLL('libtaos.dylib') def _load_taos_windows(): @@ -448,8 +458,7 @@ class CTaosInterface(object): result, ctypes.byref(pblock)) if num_of_rows == 0: return None, 0 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) + precision = CTaosInterface.libtaos.taos_result_precision(result) blocks = [None] * len(fields) fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) fieldLen = [ @@ -462,7 +471,7 @@ class CTaosInterface(object): if fields[i]['type'] not in _CONVERT_FUNC_BLOCK: raise DatabaseError("Invalid data type returned from database") blocks[i] = _CONVERT_FUNC_BLOCK[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) + data, num_of_rows, fieldLen[i], precision) return blocks, abs(num_of_rows) @@ -472,8 +481,7 @@ class CTaosInterface(object): pblock = CTaosInterface.libtaos.taos_fetch_row(result) if pblock: num_of_rows = 1 - isMicro = (CTaosInterface.libtaos.taos_result_precision( - result) == FieldType.C_TIMESTAMP_MICRO) + precision = CTaosInterface.libtaos.taos_result_precision(result) blocks = [None] * len(fields) fieldL = CTaosInterface.libtaos.taos_fetch_lengths(result) fieldLen = [ @@ -490,7 +498,7 @@ class CTaosInterface(object): blocks[i] = [None] else: blocks[i] = _CONVERT_FUNC[fields[i]['type']]( - data, num_of_rows, fieldLen[i], isMicro) + data, num_of_rows, fieldLen[i], precision) else: return None, 0 return blocks, abs(num_of_rows) diff --git a/src/connector/python/taos/constants.py b/src/connector/python/taos/constants.py index 93466f5184a6bf37c2e1c915a00aa5c5e91d1801..85689b02db76b0032558b983d8ae8d9297229c42 100644 --- a/src/connector/python/taos/constants.py +++ b/src/connector/python/taos/constants.py @@ -40,3 +40,5 @@ class FieldType(object): # Timestamp precision definition C_TIMESTAMP_MILLI = 0 C_TIMESTAMP_MICRO = 1 + C_TIMESTAMP_NANO = 2 + C_TIMESTAMP_UNKNOWN = 3 diff --git a/tests/script/api/batchprepare.c b/tests/script/api/batchprepare.c index 55eb62d9bb4272fe7ab85a96561ebd9c87343ed0..72bb9471db8e2c3043306c332c608f1b4f1df836 100644 --- a/tests/script/api/batchprepare.c +++ b/tests/script/api/batchprepare.c @@ -1458,8 +1458,783 @@ int stmt_funcb_autoctb3(TAOS_STMT *stmt) { + +//1 tables 10 records +int stmt_funcb_autoctb4(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*5); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 5; i+=5) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_INT; + params[i+2].buffer_length = sizeof(int32_t); + params[i+2].buffer = v.v4; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+3].buffer_length = sizeof(int64_t); + params[i+3].buffer = v.v8; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+4].buffer_length = sizeof(double); + params[i+4].buffer = v.f8; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+0].buffer = v.b; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+1].buffer = v.v2; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+2].buffer = v.f4; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+3].buffer = v.bin; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 tags(1,?,2,?,4,?,6.0,?,'b') (ts,b,v4,v8,f8) values(?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + exit(1); + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, tags); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 5); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + free(tags); + + return 0; +} + + + + + +//1 tables 10 records +int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 10; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 10; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 10; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 10; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+0].buffer = v.b; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+1].buffer = v.v2; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+2].buffer = v.f4; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+3].buffer = v.bin; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 (id1,id2,id3,id4,id5,id6,id7,id8,id9) tags(1,?,2,?,4,?,6.0,?,'b') values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. error:%s\n", taos_stmt_errstr(stmt)); + return -1; + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, tags); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + free(tags); + + return 0; +} + + + + + +//1 tables 10 records +int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 10; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 10; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 10; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 10; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_INT; + tags[i+0].buffer = v.v4; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+1].buffer = v.b; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + tags[i+2].buffer = v.v1; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+3].buffer = v.v2; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = NULL; + + tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT; + tags[i+4].buffer = v.v8; + tags[i+4].is_null = &one_not_null; + tags[i+4].length = NULL; + + tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+5].buffer = v.f4; + tags[i+5].is_null = &one_not_null; + tags[i+5].length = NULL; + + tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE; + tags[i+6].buffer = v.f8; + tags[i+6].is_null = &one_not_null; + tags[i+6].length = NULL; + + tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+7].buffer = v.bin; + tags[i+7].is_null = &one_not_null; + tags[i+7].length = (uintptr_t *)lb; + + tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR; + tags[i+8].buffer = v.bin; + tags[i+8].is_null = &one_not_null; + tags[i+8].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); + exit(1); + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, NULL); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:%s\n", taos_stmt_errstr(stmt)); + return -1; + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + free(tags); + + return 0; +} + + + + + + + +//1 tables 10 records +int stmt_funcb_autoctb_e3(TAOS_STMT *stmt) { + struct { + int64_t *ts; + int8_t b[10]; + int8_t v1[10]; + int16_t v2[10]; + int32_t v4[10]; + int64_t v8[10]; + float f4[10]; + double f8[10]; + char bin[10][40]; + } v = {0}; + + v.ts = malloc(sizeof(int64_t) * 1 * 10); + + int *lb = malloc(10 * sizeof(int)); + + TAOS_BIND *tags = calloc(1, sizeof(TAOS_BIND) * 9 * 1); + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * 1*10); + +// int one_null = 1; + int one_not_null = 0; + + char* is_null = malloc(sizeof(char) * 10); + char* no_null = malloc(sizeof(char) * 10); + + for (int i = 0; i < 10; ++i) { + lb[i] = 40; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v.b[i] = (int8_t)(i % 2); + v.v1[i] = (int8_t)((i+1) % 2); + v.v2[i] = (int16_t)i; + v.v4[i] = (int32_t)(i+1); + v.v8[i] = (int64_t)(i+2); + v.f4[i] = (float)(i+3); + v.f8[i] = (double)(i+4); + memset(v.bin[i], '0'+i%10, 40); + } + + for (int i = 0; i < 10; i+=10) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v.ts[10*i/10]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = 10; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v.b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = 10; + + params[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + params[i+2].buffer_length = sizeof(int8_t); + params[i+2].buffer = v.v1; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = 10; + + params[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + params[i+3].buffer_length = sizeof(int16_t); + params[i+3].buffer = v.v2; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = 10; + + params[i+4].buffer_type = TSDB_DATA_TYPE_INT; + params[i+4].buffer_length = sizeof(int32_t); + params[i+4].buffer = v.v4; + params[i+4].length = NULL; + params[i+4].is_null = is_null; + params[i+4].num = 10; + + params[i+5].buffer_type = TSDB_DATA_TYPE_BIGINT; + params[i+5].buffer_length = sizeof(int64_t); + params[i+5].buffer = v.v8; + params[i+5].length = NULL; + params[i+5].is_null = is_null; + params[i+5].num = 10; + + params[i+6].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+6].buffer_length = sizeof(float); + params[i+6].buffer = v.f4; + params[i+6].length = NULL; + params[i+6].is_null = is_null; + params[i+6].num = 10; + + params[i+7].buffer_type = TSDB_DATA_TYPE_DOUBLE; + params[i+7].buffer_length = sizeof(double); + params[i+7].buffer = v.f8; + params[i+7].length = NULL; + params[i+7].is_null = is_null; + params[i+7].num = 10; + + params[i+8].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+8].buffer_length = 40; + params[i+8].buffer = v.bin; + params[i+8].length = lb; + params[i+8].is_null = is_null; + params[i+8].num = 10; + + params[i+9].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+9].buffer_length = 40; + params[i+9].buffer = v.bin; + params[i+9].length = lb; + params[i+9].is_null = is_null; + params[i+9].num = 10; + + } + + int64_t tts = 1591060628000; + for (int i = 0; i < 10; ++i) { + v.ts[i] = tts + i; + } + + + for (int i = 0; i < 1; ++i) { + tags[i+0].buffer_type = TSDB_DATA_TYPE_INT; + tags[i+0].buffer = v.v4; + tags[i+0].is_null = &one_not_null; + tags[i+0].length = NULL; + + tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+1].buffer = v.b; + tags[i+1].is_null = &one_not_null; + tags[i+1].length = NULL; + + tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + tags[i+2].buffer = v.v1; + tags[i+2].is_null = &one_not_null; + tags[i+2].length = NULL; + + tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+3].buffer = v.v2; + tags[i+3].is_null = &one_not_null; + tags[i+3].length = NULL; + + tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT; + tags[i+4].buffer = v.v8; + tags[i+4].is_null = &one_not_null; + tags[i+4].length = NULL; + + tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+5].buffer = v.f4; + tags[i+5].is_null = &one_not_null; + tags[i+5].length = NULL; + + tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE; + tags[i+6].buffer = v.f8; + tags[i+6].is_null = &one_not_null; + tags[i+6].length = NULL; + + tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+7].buffer = v.bin; + tags[i+7].is_null = &one_not_null; + tags[i+7].length = (uintptr_t *)lb; + + tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR; + tags[i+8].buffer = v.bin; + tags[i+8].is_null = &one_not_null; + tags[i+8].length = (uintptr_t *)lb; + } + + + unsigned long long starttime = getCurrentTime(); + + char *sql = "insert into ? using stb1 (id1,id2,id3,id4,id5,id6,id7,id8,id9) tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(stmt)); + return -1; + //exit(1); + } + + int id = 0; + for (int zz = 0; zz < 1; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + code = taos_stmt_set_tbname_tags(stmt, buf, NULL); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + return -1; + } + + taos_stmt_bind_param_batch(stmt, params + id * 10); + taos_stmt_add_batch(stmt); + } + + if (taos_stmt_execute(stmt) != 0) { + printf("failed to execute insert statement.\n"); + exit(1); + } + + ++id; + + unsigned long long endtime = getCurrentTime(); + printf("insert total %d records, used %u seconds, avg:%u useconds\n", 10, (endtime-starttime)/1000000UL, (endtime-starttime)/(10)); + + free(v.ts); + free(lb); + free(params); + free(is_null); + free(no_null); + free(tags); + + return 0; +} + + + + //1 tables 10 records -int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { +int stmt_funcb_autoctb_e4(TAOS_STMT *stmt) { struct { int64_t *ts; int8_t b[10]; @@ -1579,35 +2354,60 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { for (int i = 0; i < 1; ++i) { - tags[i+0].buffer_type = TSDB_DATA_TYPE_BOOL; - tags[i+0].buffer = v.b; + tags[i+0].buffer_type = TSDB_DATA_TYPE_INT; + tags[i+0].buffer = v.v4; tags[i+0].is_null = &one_not_null; tags[i+0].length = NULL; - tags[i+1].buffer_type = TSDB_DATA_TYPE_SMALLINT; - tags[i+1].buffer = v.v2; + tags[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + tags[i+1].buffer = v.b; tags[i+1].is_null = &one_not_null; tags[i+1].length = NULL; - tags[i+2].buffer_type = TSDB_DATA_TYPE_FLOAT; - tags[i+2].buffer = v.f4; + tags[i+2].buffer_type = TSDB_DATA_TYPE_TINYINT; + tags[i+2].buffer = v.v1; tags[i+2].is_null = &one_not_null; tags[i+2].length = NULL; - tags[i+3].buffer_type = TSDB_DATA_TYPE_BINARY; - tags[i+3].buffer = v.bin; + tags[i+3].buffer_type = TSDB_DATA_TYPE_SMALLINT; + tags[i+3].buffer = v.v2; tags[i+3].is_null = &one_not_null; - tags[i+3].length = (uintptr_t *)lb; + tags[i+3].length = NULL; + + tags[i+4].buffer_type = TSDB_DATA_TYPE_BIGINT; + tags[i+4].buffer = v.v8; + tags[i+4].is_null = &one_not_null; + tags[i+4].length = NULL; + + tags[i+5].buffer_type = TSDB_DATA_TYPE_FLOAT; + tags[i+5].buffer = v.f4; + tags[i+5].is_null = &one_not_null; + tags[i+5].length = NULL; + + tags[i+6].buffer_type = TSDB_DATA_TYPE_DOUBLE; + tags[i+6].buffer = v.f8; + tags[i+6].is_null = &one_not_null; + tags[i+6].length = NULL; + + tags[i+7].buffer_type = TSDB_DATA_TYPE_BINARY; + tags[i+7].buffer = v.bin; + tags[i+7].is_null = &one_not_null; + tags[i+7].length = (uintptr_t *)lb; + + tags[i+8].buffer_type = TSDB_DATA_TYPE_NCHAR; + tags[i+8].buffer = v.bin; + tags[i+8].is_null = &one_not_null; + tags[i+8].length = (uintptr_t *)lb; } unsigned long long starttime = getCurrentTime(); - char *sql = "insert into ? using stb1 (id1,id2,id3,id4,id5,id6,id7,id8,id9) tags(1,?,2,?,4,?,6.0,?,'b') values(?,?,?,?,?,?,?,?,?,?)"; + char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; int code = taos_stmt_prepare(stmt, sql, 0); if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); - return -1; + printf("failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(stmt)); + exit(1); } int id = 0; @@ -1616,10 +2416,22 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { sprintf(buf, "m%d", zz); code = taos_stmt_set_tbname_tags(stmt, buf, tags); if (code != 0){ - printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); + printf("failed to execute taos_stmt_set_tbname_tags. error:%s\n", taos_stmt_errstr(stmt)); + exit(1); } - taos_stmt_bind_param_batch(stmt, params + id * 10); + code = taos_stmt_bind_param_batch(stmt, params + id * 10); + if (code != 0) { + printf("failed to execute taos_stmt_bind_param_batch. error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + code = taos_stmt_bind_param_batch(stmt, params + id * 10); + if (code != 0) { + printf("failed to execute taos_stmt_bind_param_batch. error:%s\n", taos_stmt_errstr(stmt)); + return -1; + } + taos_stmt_add_batch(stmt); } @@ -1647,8 +2459,9 @@ int stmt_funcb_autoctb_e1(TAOS_STMT *stmt) { + //1 tables 10 records -int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) { +int stmt_funcb_autoctb_e5(TAOS_STMT *stmt) { struct { int64_t *ts; int8_t b[10]; @@ -1818,23 +2631,34 @@ int stmt_funcb_autoctb_e2(TAOS_STMT *stmt) { unsigned long long starttime = getCurrentTime(); char *sql = "insert into ? using stb1 tags(?,?,?,?,?,?,?,?,?) values(?,?,?,?,?,?,?,?,?,?)"; - int code = taos_stmt_prepare(stmt, sql, 0); + int code = taos_stmt_prepare(NULL, sql, 0); if (code != 0){ - printf("failed to execute taos_stmt_prepare. code:0x%x\n", code); - exit(1); + printf("failed to execute taos_stmt_prepare. code:%s\n", taos_stmt_errstr(NULL)); + return -1; } int id = 0; for (int zz = 0; zz < 1; zz++) { char buf[32]; sprintf(buf, "m%d", zz); - code = taos_stmt_set_tbname_tags(stmt, buf, NULL); + code = taos_stmt_set_tbname_tags(stmt, buf, tags); if (code != 0){ - printf("failed to execute taos_stmt_set_tbname_tags. code:0x%x\n", code); - return -1; + printf("failed to execute taos_stmt_set_tbname_tags. error:%s\n", taos_stmt_errstr(stmt)); + exit(1); } - taos_stmt_bind_param_batch(stmt, params + id * 10); + code = taos_stmt_bind_param_batch(stmt, params + id * 10); + if (code != 0) { + printf("failed to execute taos_stmt_bind_param_batch. error:%s\n", taos_stmt_errstr(stmt)); + exit(1); + } + + code = taos_stmt_bind_param_batch(stmt, params + id * 10); + if (code != 0) { + printf("failed to execute taos_stmt_bind_param_batch. error:%s\n", taos_stmt_errstr(stmt)); + return -1; + } + taos_stmt_add_batch(stmt); } @@ -3375,6 +4199,9 @@ void check_result(TAOS *taos, char *tname, int printr, int expected) { char sql[255] = "SELECT * FROM "; TAOS_RES *result; + //FORCE NO PRINT + printr = 0; + strcat(sql, tname); result = taos_query(taos, sql); @@ -3835,7 +4662,7 @@ void* runcase(void *par) { #endif -#if 1 +#if 1 prepare(taos, 1, 1); stmt = taos_stmt_init(taos); @@ -3859,9 +4686,9 @@ void* runcase(void *par) { stmt = taos_stmt_init(taos); - printf("1t+10r+bm+autoctb start\n"); + printf("1t+10r+bm+autoctb1 start\n"); stmt_funcb_autoctb1(stmt); - printf("1t+10r+bm+autoctb end\n"); + printf("1t+10r+bm+autoctb1 end\n"); printf("check result start\n"); check_result(taos, "m0", 1, 10); printf("check result end\n"); @@ -3874,9 +4701,9 @@ void* runcase(void *par) { stmt = taos_stmt_init(taos); - printf("1t+10r+bm+autoctb start\n"); + printf("1t+10r+bm+autoctb2 start\n"); stmt_funcb_autoctb2(stmt); - printf("1t+10r+bm+autoctb end\n"); + printf("1t+10r+bm+autoctb2 end\n"); printf("check result start\n"); check_result(taos, "m0", 1, 10); printf("check result end\n"); @@ -3890,9 +4717,9 @@ void* runcase(void *par) { stmt = taos_stmt_init(taos); - printf("1t+10r+bm+autoctb start\n"); + printf("1t+10r+bm+autoctb3 start\n"); stmt_funcb_autoctb3(stmt); - printf("1t+10r+bm+autoctb end\n"); + printf("1t+10r+bm+autoctb3 end\n"); printf("check result start\n"); check_result(taos, "m0", 1, 10); printf("check result end\n"); @@ -3900,11 +4727,27 @@ void* runcase(void *par) { #endif + #if 1 prepare(taos, 1, 0); stmt = taos_stmt_init(taos); + printf("1t+10r+bm+autoctb4 start\n"); + stmt_funcb_autoctb4(stmt); + printf("1t+10r+bm+autoctb4 end\n"); + printf("check result start\n"); + check_result(taos, "m0", 1, 10); + printf("check result end\n"); + taos_stmt_close(stmt); +#endif + + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + printf("1t+10r+bm+autoctb+e1 start\n"); stmt_funcb_autoctb_e1(stmt); printf("1t+10r+bm+autoctb+e1 end\n"); @@ -3930,6 +4773,52 @@ void* runcase(void *par) { #endif +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("1t+10r+bm+autoctb+e3 start\n"); + stmt_funcb_autoctb_e3(stmt); + printf("1t+10r+bm+autoctb+e3 end\n"); + printf("check result start\n"); + //check_result(taos, "m0", 1, 0); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("1t+10r+bm+autoctb+e4 start\n"); + stmt_funcb_autoctb_e4(stmt); + printf("1t+10r+bm+autoctb+e4 end\n"); + printf("check result start\n"); + //check_result(taos, "m0", 1, 0); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + +#if 1 + prepare(taos, 1, 0); + + stmt = taos_stmt_init(taos); + + printf("1t+10r+bm+autoctb+e5 start\n"); + stmt_funcb_autoctb_e5(stmt); + printf("1t+10r+bm+autoctb+e5 end\n"); + printf("check result start\n"); + //check_result(taos, "m0", 1, 0); + printf("check result end\n"); + taos_stmt_close(stmt); + +#endif + #if 1 prepare(taos, 1, 1); @@ -4138,6 +5027,8 @@ void* runcase(void *par) { #endif + printf("test end\n"); + return NULL; } diff --git a/tests/script/api/stmtBatchTest.c b/tests/script/api/stmtBatchTest.c index 24291adfa0a64349d62b59455ce0db52e36bcf4f..c488f2fa89714da3b20d9eafa4b7ff2c89580e0c 100644 --- a/tests/script/api/stmtBatchTest.c +++ b/tests/script/api/stmtBatchTest.c @@ -4406,6 +4406,654 @@ static void SpecifyColumnBatchCase_autoCreateTbl(TAOS *taos) { } +/*=======================*/ +/* +char * taos_stmt_errstr(TAOS_STMT *stmt) 用于在其他stmt API 返回错误(返回错误码或空指针)时获取错误信息,返回的错误信息可能是以下3种的一个: +1. 当stmt或sqlobj为空时的terrno对于的错误消息; +2. (可有的)详细错误消息; +3. 返回的错误码对于的错误消息; +*/ +static int stmt_specifyCol_bind_error_case_001(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d-0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_INT; + params[i+2].buffer_length = sizeof(int32_t); + params[i+2].buffer = v->v4; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+3].buffer_length = sizeof(float); + params[i+3].buffer = v->f4; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+4].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+4].buffer = v->br; + params[i+4].length = lb; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + +// create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp) + char *sql = "insert into m0 (ts,b,v4,f4,br) values(?,?,?,?,?)"; + + int code; + //TAOS_STMT *stmtNull = NULL; + //int code = taos_stmt_prepare(stmtNull, sql, 0); + //if (code != 0){ + // printf("failed to execute taos_stmt_prepare. code:0x%x[%s][%s]\n", code, tstrerror(code), taos_stmt_errstr(stmtNull)); + // return -1; + //} + + //char* sqlNull = NULL; + //code = taos_stmt_prepare(stmt, sqlNull, 0); + //if (code != 0){ + // printf("failed to execute taos_stmt_prepare. code:0x%x[%s][%s]\n", code, tstrerror(code), taos_stmt_errstr(stmt)); + //} + + code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s][%s]\n", code, tstrerror(code), taos_stmt_errstr(stmt)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + //char buf[32]; + //sprintf(buf, "m%d", zz); + //code = taos_stmt_set_tbname(stmt, buf); + //if (code != 0){ + // printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s]\n", code, tstrerror(code)); + // return -1; + //} + + //for (int col=0; col < columnNum + 1000; ++col) { + for (int col=0; col < columnNum; ++col) { + if (col >= columnNum) col = 0; + //code = taos_stmt_bind_single_param_batch(NULL, params + id, col); + //code = taos_stmt_bind_single_param_batch(stmt, NULL, col); + //code = taos_stmt_bind_single_param_batch(stmt, params + id, columnNum); + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s][%s]\n", code, tstrerror(code), taos_stmt_errstr(stmt)); + return -1; + } + id++; + } + + //code = taos_stmt_add_batch(NULL); + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s][%s]\n", code, tstrerror(code), taos_stmt_errstr(stmt)); + return -1; + } + + //code = taos_stmt_add_batch(stmt); + //if (code != 0) { + // printf("failed to execute taos_stmt_add_batch second. code:0x%x[%s][%s]\n", code, tstrerror(code), taos_stmt_errstr(stmt)); + // return -1; + //} + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +static int stmt_specifyCol_bind_error_case_002(TAOS_STMT *stmt, int tableNum, int rowsOfPerColum, int bingNum, int lenOfBinaryDef, int lenOfBinaryAct, int columnNum) { + sampleValue* v = (sampleValue *)calloc(1, sizeof(sampleValue)); + + int totalRowsPerTbl = rowsOfPerColum * bingNum; + + v->ts = (int64_t *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * tableNum)); + v->br = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + v->nr = (char *)malloc(sizeof(int64_t) * (size_t)(totalRowsPerTbl * lenOfBinaryDef)); + + int *lb = (int *)malloc(MAX_ROWS_OF_PER_COLUMN * sizeof(int)); + + TAOS_MULTI_BIND *params = calloc(1, sizeof(TAOS_MULTI_BIND) * (size_t)(bingNum * columnNum * (tableNum+1) * rowsOfPerColum)); + char* is_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + char* no_null = malloc(sizeof(char) * MAX_ROWS_OF_PER_COLUMN); + + int64_t tts = 1591060628000; + + for (int i = 0; i < rowsOfPerColum; ++i) { + lb[i] = lenOfBinaryAct; + no_null[i] = 0; + is_null[i] = (i % 10 == 2) ? 1 : 0; + v->b[i] = (int8_t)(i % 2); + v->v1[i] = (int8_t)((i+1) % 2); + v->v2[i] = (int16_t)i; + v->v4[i] = (int32_t)(i+1); + v->v8[i] = (int64_t)(i+2); + v->f4[i] = (float)(i+3); + v->f8[i] = (double)(i+4); + char tbuf[MAX_BINARY_DEF_LEN]; + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "binary-%d", i%10); + memcpy(v->br + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + memset(tbuf, 0, MAX_BINARY_DEF_LEN); + sprintf(tbuf, "nchar-%d", i%10); + memcpy(v->nr + i*lenOfBinaryDef, tbuf, (size_t)lenOfBinaryAct); + v->ts2[i] = tts + i; + } + + int i = 0; + for (int j = 0; j < bingNum * tableNum; j++) { + params[i+0].buffer_type = TSDB_DATA_TYPE_TIMESTAMP; + params[i+0].buffer_length = sizeof(int64_t); + params[i+0].buffer = &v->ts[j*rowsOfPerColum]; + params[i+0].length = NULL; + params[i+0].is_null = no_null; + params[i+0].num = rowsOfPerColum; + + params[i+1].buffer_type = TSDB_DATA_TYPE_BOOL; + params[i+1].buffer_length = sizeof(int8_t); + params[i+1].buffer = v->b; + params[i+1].length = NULL; + params[i+1].is_null = is_null; + params[i+1].num = rowsOfPerColum; + + params[i+2].buffer_type = TSDB_DATA_TYPE_INT; + params[i+2].buffer_length = sizeof(int32_t); + params[i+2].buffer = v->v4; + params[i+2].length = NULL; + params[i+2].is_null = is_null; + params[i+2].num = rowsOfPerColum; + + params[i+3].buffer_type = TSDB_DATA_TYPE_FLOAT; + params[i+3].buffer_length = sizeof(float); + params[i+3].buffer = v->f4; + params[i+3].length = NULL; + params[i+3].is_null = is_null; + params[i+3].num = rowsOfPerColum; + + params[i+4].buffer_type = TSDB_DATA_TYPE_BINARY; + params[i+4].buffer_length = (uintptr_t)lenOfBinaryDef; + params[i+4].buffer = v->br; + params[i+4].length = lb; + params[i+4].is_null = is_null; + params[i+4].num = rowsOfPerColum; + + i+=columnNum; + } + + //int64_t tts = 1591060628000; + for (int i = 0; i < totalRowsPerTbl * tableNum; ++i) { + v->ts[i] = tts + i; + } + + unsigned long long starttime = getCurrentTime(); + +// create table m%d (ts timestamp, b bool, v1 tinyint, v2 smallint, v4 int, v8 bigint, f4 float, f8 double, br binary(%d), nr nchar(%d), ts2 timestamp) + char *sql = "insert into ? (ts,b,v4,f4,br) values(?,?,?,?,?)"; + int code = taos_stmt_prepare(stmt, sql, 0); + if (code != 0){ + printf("failed to execute taos_stmt_prepare. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + + int id = 0; + for (int l = 0; l < bingNum; l++) { + for (int zz = 0; zz < tableNum; zz++) { + char buf[32]; + sprintf(buf, "m%d", zz); + + //stmt=NULL; + code = taos_stmt_set_tbname(stmt, buf); + if (code != 0){ + printf("failed to execute taos_stmt_set_tbname. code:0x%x[%s][%s]\n", code, tstrerror(code), taos_stmt_errstr(stmt)); + return -1; + } + + for (int col=0; col < columnNum; ++col) { + code = taos_stmt_bind_single_param_batch(stmt, params + id, col); + if (code != 0){ + printf("failed to execute taos_stmt_bind_single_param_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + id++; + } + + code = taos_stmt_add_batch(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_add_batch. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + code = taos_stmt_execute(stmt); + if (code != 0) { + printf("failed to execute taos_stmt_execute. code:0x%x[%s]\n", code, tstrerror(code)); + return -1; + } + } + + unsigned long long endtime = getCurrentTime(); + unsigned long long totalRows = (uint32_t)(totalRowsPerTbl * tableNum); + printf("insert total %d records, used %u seconds, avg:%u useconds per record\n", totalRows, (endtime-starttime)/1000000UL, (endtime-starttime)/totalRows); + + free(v->ts); + free(v->br); + free(v->nr); + free(v); + free(lb); + free(params); + free(is_null); + free(no_null); + + return 0; +} + +static void SpecifyColumnBatchErrorCase(TAOS *taos) { + TAOS_STMT *stmt = NULL; + + int tableNum; + int lenOfBinaryDef; + int rowsOfPerColum; + int bingNum; + int lenOfBinaryAct; + int columnNum; + + int totalRowsPerTbl; + +//=======================================================================// +//=============================== single table ==========================// +//========== case 1: ======================// +#if 0 +{ + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 1; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db1"); + stmt_specifyCol_bind_error_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 1 check result end\n\n"); +} +#endif + + //========== case 2: ======================// +#if 1 +{ + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 15; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db2"); + stmt_specifyCol_bind_error_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 2 check result end\n\n"); +} +#endif + + //========== case 2-1: ======================// +#if 0 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 32767; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 15; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db2_1"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 2-1 check result end\n\n"); + } +#endif + //========== case 2-2: ======================// +#if 0 + { + printf("====case 2-2 error test start\n"); + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 32768; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 15; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db2_2"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("====case 2-2 check result end\n\n"); + } +#endif + + + //========== case 3: ======================// +#if 0 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 1; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 20; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db3"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 3 check result end\n\n"); + } +#endif + + //========== case 4: ======================// +#if 0 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 5; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db4"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + //checkResult(taos, "m1", 0, totalRowsPerTbl); + //checkResult(taos, "m2", 0, totalRowsPerTbl); + //checkResult(taos, "m3", 0, totalRowsPerTbl); + //checkResult(taos, "m4", 0, totalRowsPerTbl); + //checkResult(taos, "m5", 0, totalRowsPerTbl); + //checkResult(taos, "m6", 0, totalRowsPerTbl); + //checkResult(taos, "m7", 0, totalRowsPerTbl); + //checkResult(taos, "m8", 0, totalRowsPerTbl); + //checkResult(taos, "m9", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 4 check result end\n\n"); + } +#endif + +//=======================================================================// +//=============================== multi tables ==========================// + //========== case 5: ======================// +#if 0 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 1; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 16; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db5"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 5 check result end\n\n"); + } +#endif + + //========== case 6: ======================// +#if 0 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 5; + bingNum = 1; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 20; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db6"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 6 check result end\n\n"); + } +#endif + + //========== case 7: ======================// +#if 0 + { + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 1; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 33; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db7"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 7 check result end\n\n"); + } +#endif + + //========== case 8: ======================// +#if 0 +{ + stmt = taos_stmt_init(taos); + + tableNum = 5; + rowsOfPerColum = 5; + bingNum = 5; + lenOfBinaryDef = 1000; + lenOfBinaryAct = 40; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db8"); + stmt_specifyCol_bind_case_002(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + checkResult(taos, "m1", 0, totalRowsPerTbl); + checkResult(taos, "m2", 0, totalRowsPerTbl); + checkResult(taos, "m3", 0, totalRowsPerTbl); + checkResult(taos, "m4", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 8 check result end\n\n"); +} +#endif + + //=======================================================================// + //=============================== multi-rows to single table ==========================// + //========== case 9: ======================// +#if 0 + { + stmt = taos_stmt_init(taos); + + tableNum = 1; + rowsOfPerColum = 23740; + bingNum = 1; + lenOfBinaryDef = 40; + lenOfBinaryAct = 8; + columnNum = 5; + + prepareVcolumn(taos, 1, tableNum, lenOfBinaryDef, "db9"); + stmt_specifyCol_bind_case_001(stmt, tableNum, rowsOfPerColum, bingNum, lenOfBinaryDef, lenOfBinaryAct, columnNum); + + totalRowsPerTbl = rowsOfPerColum * bingNum; + checkResult(taos, "m0", 0, totalRowsPerTbl); + taos_stmt_close(stmt); + printf("case 9 check result end\n\n"); + } +#endif + + return ; + +} + int main(int argc, char *argv[]) { TAOS *taos; @@ -4472,6 +5120,7 @@ int main(int argc, char *argv[]) //runCase_long(taos); //SpecifyColumnBatchCase(taos); SpecifyColumnBatchCase_autoCreateTbl(taos); + //SpecifyColumnBatchErrorCase(taos); return 0; } diff --git a/tests/script/fullGeneralSuite.sim b/tests/script/fullGeneralSuite.sim index 2cd22362005de07eb2a02b1d0fadec9fc8bdca08..c820dd3bf56fb5268092dbdec2d37d7cfa0ca0c5 100644 --- a/tests/script/fullGeneralSuite.sim +++ b/tests/script/fullGeneralSuite.sim @@ -131,10 +131,12 @@ run general/parser/join.sim run general/parser/join_multivnode.sim run general/parser/select_with_tags.sim run general/parser/groupby.sim +run general/parser/top_groupby.sim run general/parser/tags_dynamically_specifiy.sim run general/parser/set_tag_vals.sim #unsupport run general/parser/repeatAlter.sim #unsupport run general/parser/slimit_alter_tags.sim +run general/parser/precision_ns.sim run general/stable/disk.sim run general/stable/dnode3.sim run general/stable/metrics.sim diff --git a/tests/script/general/db/alter_option.sim b/tests/script/general/db/alter_option.sim index 170ba21c28b7ff4a79a8f2375dc1d36ba91e6120..c20a96fd1bd18ba911cce02859d7265d0294b76b 100644 --- a/tests/script/general/db/alter_option.sim +++ b/tests/script/general/db/alter_option.sim @@ -112,25 +112,25 @@ endi sql alter database db keep 30 sql show databases print keep $data7_db -if $data7_db != 20,20,30 then +if $data7_db != 30,30,30 then return -1 endi sql alter database db keep 40 sql show databases print keep $data7_db -if $data7_db != 20,20,40 then +if $data7_db != 40,40,40 then return -1 endi -sql alter database db keep 40 -sql alter database db keep 30 +sql alter database db keep 40,50 +sql alter database db keep 30,31 sql alter database db keep 20 -sql_error alter database db keep 10 +sql_error alter database db keep 10.0 sql_error alter database db keep 9 sql_error alter database db keep 1 -sql alter database db keep 0 -sql alter database db keep -1 +sql_error alter database db keep 0 +sql_error alter database db keep -1 sql_error alter database db keep 365001 print ============== step cache @@ -177,7 +177,7 @@ sql alter database db blocks 20 sql alter database db blocks 10 sql_error alter database db blocks 2 sql_error alter database db blocks 1 -sql alter database db blocks 0 +sql_error alter database db blocks 0 sql_error alter database db blocks -1 sql_error alter database db blocks 10001 diff --git a/tests/script/general/db/topic1.sim b/tests/script/general/db/topic1.sim index 42613405afda7580003f58ae82f950880d60de62..4939e5a0e2274e8ab26465fe04ca99a79f9f9ce0 100644 --- a/tests/script/general/db/topic1.sim +++ b/tests/script/general/db/topic1.sim @@ -367,7 +367,7 @@ sql_error topic db keep 30 sql alter database db keep 30 sql show databases print keep $data7_db -if $data7_db != 20,20,30 then +if $data7_db != 30,30,30 then return -1 endi @@ -375,18 +375,18 @@ sql_error alter topic db keep 40 sql alter database db keep 40 sql show databases print keep $data7_db -if $data7_db != 20,20,40 then +if $data7_db != 40,40,40 then return -1 endi sql alter database db keep 40 sql alter database db keep 30 sql alter database db keep 20 -sql_error alter database db keep 10 +sql_error alter database db keep 10.0 sql_error alter database db keep 9 sql_error alter database db keep 1 -sql alter database db keep 0 -sql alter database db keep -1 +sql_error alter database db keep 0 +sql_error alter database db keep -1 sql_error alter database db keep 365001 sql_error alter topic db keep 40 @@ -455,7 +455,7 @@ sql alter database db blocks 20 sql alter database db blocks 10 sql_error alter database db blocks 2 sql_error alter database db blocks 1 -sql alter database db blocks 0 +sql_error alter database db blocks 0 sql_error alter database db blocks -1 sql_error alter database db blocks 10001 diff --git a/tests/script/general/field/bigint.sim b/tests/script/general/field/bigint.sim index 3bb120c6410a2ea2e9c671bb4aca56fc8014124f..538f966c49cc3eefb8516c4bac4a49b9efd78d37 100644 --- a/tests/script/general/field/bigint.sim +++ b/tests/script/general/field/bigint.sim @@ -159,4 +159,4 @@ if $rows != 0 then return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/field/unsigined_bigint.sim b/tests/script/general/field/unsigined_bigint.sim new file mode 100644 index 0000000000000000000000000000000000000000..1cfe8ad15b31f38d2fc72d429a0c9af2cb5732fb --- /dev/null +++ b/tests/script/general/field/unsigined_bigint.sim @@ -0,0 +1,166 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c walLevel -v 1 +system sh/exec.sh -n dnode1 -s start + +sleep 2000 +sql connect +print ======================== dnode1 start + +$dbPrefix = db +$tbPrefix = tb +$mtPrefix = st +$tbNum = 10 +$rowNum = 20 +$totalNum = 200 + +print =============== step1 +$i = 0 +$db = $dbPrefix . $i +$mt = $mtPrefix . $i + +sql create database $db +sql use $db +sql create table $mt (ts timestamp, tbcol bigint unsigned) TAGS(tgcol bigint unsigned) + +$i = 0 +while $i < 5 + $tb = $tbPrefix . $i + sql create table $tb using $mt tags( 0 ) + sql create table $tb using $mt tags( -111 ) + $x = 0 + while $x < $rowNum + $ms = $x . m + sql insert into $tb values (now + $ms , 0 ) + $x = $x + 1 + sql_error insert into $tb values (now + $ms , -10) + sql_error insert into $tb values (now + $ms , -1000) + sql_error insert into $tb values (now + $ms , -10000000) + endw + $i = $i + 1 +endw +while $i < 10 + $tb = $tbPrefix . $i + sql create table $tb using $mt tags( 1 ) + $x = 0 + while $x < $rowNum + $ms = $x . m + sql insert into $tb values (now + $ms , 1 ) + $x = $x + 1 + endw + $i = $i + 1 +endw + +print =============== step2 +sql select * from $mt where tbcol = 0 +if $rows != 100 then + return -1 +endi +sql select * from $mt where tbcol <> 0 +if $rows != 100 then + return -1 +endi +sql select * from $mt where tbcol = 1 +if $rows != 100 then + return -1 +endi +sql select * from $mt where tbcol <> 1 +if $rows != 100 then + return -1 +endi +sql select * from $mt where tbcol = 1 +if $rows != 100 then + return -1 +endi +sql select * from $mt where tbcol <> 1 +if $rows != 100 then + return -1 +endi +sql select * from $mt where tbcol = 0 +if $rows != 100 then + return -1 +endi +sql select * from $mt where tbcol <> 0 +if $rows != 100 then + return -1 +endi + +print =============== step3 +sql select * from $mt where ts > now + 4m and tbcol = 1 +if $rows != 75 then + return -1 +endi +sql select * from $mt where ts > now + 4m and tbcol <> 1 +if $rows != 75 then + return -1 +endi +sql select * from $mt where ts < now + 4m and tbcol = 0 +if $rows != 25 then + return -1 +endi +sql select * from $mt where ts < now + 4m and tbcol <> 0 +if $rows != 25 then + return -1 +endi +sql select * from $mt where ts <= now + 4m and tbcol = 0 +if $rows != 25 then + return -1 +endi +sql select * from $mt where ts <= now + 4m and tbcol <> 0 +if $rows != 25 then + return -1 +endi +sql select * from $mt where ts > now + 4m and ts < now + 5m and tbcol <> 0 +if $rows != 5 then + return -1 +endi +sql select * from $mt where ts > now + 4m and tbcol <> 0 and ts < now + 5m +if $rows != 5 then + return -1 +endi + +print =============== step4 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt +print $data00 $data01 $data02 $data03 $data04 $data05 $data06 +if $data00 != 200 then + return -1 +endi + +print =============== step5 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 +print $data00 $data01 $data02 $data03 $data04 $data05 $data06 +if $data00 != 100 then + return -1 +endi + +print =============== step6 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol +print $data00 $data01 $data02 $data03 $data04 $data05 $data06 +print $data10 $data11 $data12 $data13 $data14 $data15 $data16 +if $data00 != 100 then + print expect 100, actual $data00 + return -1 +endi + +print =============== step7 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where ts < now + 4m and tbcol = 1 group by tgcol +print $data00 $data01 $data02 $data03 $data04 $data05 $data06 +if $data00 != 25 then + return -1 +endi + +print =============== step8 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 interval(1d) group by tgcol order by tgcol desc +print $data00 $data01 $data02 $data03 $data04 $data05 $data06 +if $data01 != 100 then + return -1 +endi + +print =============== clear +sql drop database $db +sql show databases +if $rows != 0 then + return -1 +endi + +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/http/grafana_bug.sim b/tests/script/general/http/grafana_bug.sim index e66cd29deacc5a02d24568c236ffed79e114eb25..0816e88f3fdfaf5a6292f746c66ecb562bee177e 100644 --- a/tests/script/general/http/grafana_bug.sim +++ b/tests/script/general/http/grafana_bug.sim @@ -20,17 +20,22 @@ sql use db sql create table tb (ts timestamp, val int, val1 int, val2 int) sql create table tb2 (ts timestamp, val int, val1 int, val2 int) sql create table t2 (ts timestamp, val int) +sql create table tb3 (ts timestamp, val int, val1 int, val2 int) sql insert into tb values('2020-01-01 00:00:00.000', 1, 11, 21) sql insert into tb values('2020-01-02 00:00:00.000', 1, 12, 22) sql insert into tb values('2020-01-03 00:00:00.000', 2, 13, 23) sql insert into tb values('2020-01-04 00:00:00.000', 2, 14, 24) + sql insert into tb2 values('2020-01-01 00:00:00.000', 21, 211, 221) sql insert into tb2 values('2020-01-02 00:00:00.000', 21, 212, 222) sql insert into tb2 values('2020-01-03 00:00:00.000', 22, 213, 223) sql insert into tb2 values('2020-01-04 00:00:00.000', 22, 214, 224) + +sql insert into tb3 values('2020-01-01 00:00:00.000', NULL, NULL, NULL) +sql insert into tb3 values('2020-01-02 00:00:00.000', NULL, NULL, NULL) print =============== step1 - one query, 1 column, with timestamp system_content curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d '[ {"refId":"A","alias":"","sql":"select ts from db.tb where ts >= 1577980800000 "} ]' 127.0.0.1:7111/grafana/query @@ -235,4 +240,11 @@ if $system_content != @[{"refId":"B","target":"BB{val2:223,}","datapoints":[[213 return -1 endi +print =============== step26 - 2 column, no timestamp, NULL +system_content curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d '[ {"refId":"A","alias":"","sql":"select * from db.tb3 "} ]' 127.0.0.1:7111/grafana/query +print step1-> $system_content +if $system_content != @[{"refId":"A","target":"{val1:nil, val2:nil}","datapoints":[[null,1577808000000],[null,1577894400000]]}]@ then + return -1 +endi + system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/general/http/restful_full.sim b/tests/script/general/http/restful_full.sim index 8094a943f507a702bb56a7d026da672134188b83..a5d3ac2b862f3b2b72b0453a2c1bb2b578672246 100644 --- a/tests/script/general/http/restful_full.sim +++ b/tests/script/general/http/restful_full.sim @@ -88,7 +88,7 @@ print =============== step2 - no db #11 system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'show databases' 127.0.0.1:7111/rest/sql print 11-> $system_content -if $system_content != @{"status":"succ","head":["name","created_time","ntables","vgroups","replica","quorum","days","keep0,keep1,keep(D)","cache(MB)","blocks","minrows","maxrows","wallevel","fsync","comp","cachelast","precision","update","status"],"column_meta":[["name",8,32],["created_time",9,8],["ntables",4,4],["vgroups",4,4],["replica",3,2],["quorum",3,2],["days",3,2],["keep0,keep1,keep(D)",8,24],["cache(MB)",4,4],["blocks",4,4],["minrows",4,4],["maxrows",4,4],["wallevel",2,1],["fsync",4,4],["comp",2,1],["cachelast",2,1],["precision",8,3],["update",2,1],["status",8,10]],"data":[],"rows":0}@ then +if $system_content != @{"status":"succ","head":["name","created_time","ntables","vgroups","replica","quorum","days","keep0,keep1,keep2","cache(MB)","blocks","minrows","maxrows","wallevel","fsync","comp","cachelast","precision","update","status"],"column_meta":[["name",8,32],["created_time",9,8],["ntables",4,4],["vgroups",4,4],["replica",3,2],["quorum",3,2],["days",3,2],["keep0,keep1,keep2",8,24],["cache(MB)",4,4],["blocks",4,4],["minrows",4,4],["maxrows",4,4],["wallevel",2,1],["fsync",4,4],["comp",2,1],["cachelast",2,1],["precision",8,3],["update",2,1],["status",8,10]],"data":[],"rows":0}@ then return -1 endi diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index ce770aee56c9ddb7b3a6b866e4317d09c463c8d6..daac2caf5da086d538d0ec4845737a819f6fa1cd 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -424,6 +424,10 @@ cd ../../../debug; make ./test.sh -f general/parser/stableOp.sim ./test.sh -f general/parser/timestamp.sim ./test.sh -f general/parser/sliding.sim +./test.sh -f general/parser/having.sim +./test.sh -f general/parser/having_child.sim +./test.sh -f general/parser/between_and.sim +./test.sh -f general/parser/last_cache.sim ./test.sh -f unique/big/balance.sim #======================b7-end=============== diff --git a/tests/script/regressionSuite.sim b/tests/script/regressionSuite.sim index d5742cd98ff4184d50c256309c807e0b19bbe1c2..bada2f655202ddc34ce6e67e718336a2afc41d50 100644 --- a/tests/script/regressionSuite.sim +++ b/tests/script/regressionSuite.sim @@ -134,6 +134,7 @@ run general/parser/bug.sim run general/parser/tags_dynamically_specifiy.sim run general/parser/set_tag_vals.sim run general/parser/repeatAlter.sim +run general/parser/precision_ns.sim ##unsupport run general/parser/slimit_alter_tags.sim run general/stable/disk.sim run general/stable/dnode3.sim diff --git a/tests/script/unique/http/admin.sim b/tests/script/unique/http/admin.sim index 1d67a7f86b2aef94a90b74d3d0e6a07dc0cf3ef2..ae206744c4e93ab7cebd5f4db7d8d4b84ad5ebbb 100644 --- a/tests/script/unique/http/admin.sim +++ b/tests/script/unique/http/admin.sim @@ -34,6 +34,7 @@ print =============== step1 - login system_content curl 127.0.0.1:7111/admin/ print 1-> $system_content if $system_content != @{"status":"error","code":4357,"desc":"no auth info input"}@ then + print actual: $system_content return -1 endi @@ -149,6 +150,8 @@ endi system_content curl -H 'Authorization: Taosd /KfeAzX/f9na8qdtNZmtONryp201ma04bEl8LcvLUd7a8qdtNZmtONryp201ma04' -d 'select * from d1.table_admin' 127.0.0.1:7111/admin/all print curl 127.0.0.1:7111/admin/all -----> $system_content if $system_content != @{"status":"succ","head":["ts","i"],"data":[["2017-12-25 21:28:41.022",1],["2017-12-25 21:28:42.022",2],["2017-12-25 21:28:43.022",3],["2017-12-25 21:28:44.022",4],["2017-12-25 21:28:45.022",5],["2017-12-25 21:28:46.022",6],["2017-12-25 21:28:47.022",7],["2017-12-25 21:28:48.022",8],["2017-12-25 21:28:49.022",9],["2017-12-25 21:28:50.022",10],["2017-12-25 21:28:51.022",11]],"rows":11}@ then + print actual: $system_content + print expect =======> {"status":"succ","head":["ts","i"],"data":[["2017-12-25 21:28:41.022",1],["2017-12-25 21:28:42.022",2],["2017-12-25 21:28:43.022",3],["2017-12-25 21:28:44.022",4],["2017-12-25 21:28:45.022",5],["2017-12-25 21:28:46.022",6],["2017-12-25 21:28:47.022",7],["2017-12-25 21:28:48.022",8],["2017-12-25 21:28:49.022",9],["2017-12-25 21:28:50.022",10],["2017-12-25 21:28:51.022",11]],"rows":11} return -1 endi