| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.iotdb.jdbc; |
| |
| import org.apache.iotdb.rpc.RpcUtils; |
| import org.apache.iotdb.rpc.StatementExecutionException; |
| import org.apache.iotdb.service.rpc.thrift.IClientRPCService; |
| import org.apache.iotdb.service.rpc.thrift.TSFetchMetadataReq; |
| import org.apache.iotdb.service.rpc.thrift.TSFetchMetadataResp; |
| |
| import org.apache.commons.lang3.StringUtils; |
| import org.apache.thrift.TException; |
| import org.apache.tsfile.common.conf.TSFileConfig; |
| import org.apache.tsfile.enums.TSDataType; |
| import org.apache.tsfile.read.common.block.TsBlock; |
| import org.apache.tsfile.read.common.block.TsBlockBuilder; |
| import org.apache.tsfile.read.common.block.column.TsBlockSerde; |
| import org.apache.tsfile.utils.Binary; |
| import org.slf4j.Logger; |
| import org.slf4j.LoggerFactory; |
| |
| import java.io.IOException; |
| import java.nio.ByteBuffer; |
| import java.sql.Connection; |
| import java.sql.DatabaseMetaData; |
| import java.sql.ResultSet; |
| import java.sql.RowIdLifetime; |
| import java.sql.SQLException; |
| import java.sql.Statement; |
| import java.sql.Types; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collections; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.TreeMap; |
| |
| public class IoTDBDatabaseMetadata implements DatabaseMetaData { |
| |
| private static final org.slf4j.Logger logger = |
| org.slf4j.LoggerFactory.getLogger(IoTDBDatabaseMetadata.class); |
| private IoTDBConnection connection; |
| private IClientRPCService.Iface client; |
| private static final Logger LOGGER = LoggerFactory.getLogger(IoTDBDatabaseMetadata.class); |
| private static final String METHOD_NOT_SUPPORTED_STRING = "Method not supported"; |
| // when running the program in IDE, we can not get the version info using |
| // getImplementationVersion() |
| private static final String DATABASE_VERSION = |
| IoTDBDatabaseMetadata.class.getPackage().getImplementationVersion() != null |
| ? IoTDBDatabaseMetadata.class.getPackage().getImplementationVersion() |
| : "UNKNOWN"; |
| private long sessionId; |
| private static String sqlKeywordsThatArentSQL92; |
| private static TsBlockSerde serde = new TsBlockSerde(); |
| |
| private static final String SHOW_DATABASES_SQL = "SHOW DATABASES "; |
| |
| private static final String PRECISION = "PRECISION"; |
| |
| private static final String PRIMARY = "PRIMARY"; |
| |
| private static final String DOUBLE = "DOUBLE"; |
| private static final String BOOLEAN = "BOOLEAN"; |
| private static final String FLOAT = "FLOAT"; |
| private static final String INT32 = "INT32"; |
| |
| private static final String INT64 = "INT64"; |
| |
| private static final String TYPE_CAT = "TYPE_CAT"; |
| |
| private static final String TYPE_NAME = "TYPE_NAME"; |
| |
| private static final String REMARKS = "REMARKS"; |
| |
| private static final String IS_NULLABLE = "IS_NULLABLE"; |
| |
| private static final String COLUMN_NAME = "COLUMN_NAME"; |
| |
| private static final String TABLE_CAT = "TABLE_CAT"; |
| |
| private static final String TABLE_SCHEM = "TABLE_SCHEM"; |
| |
| private static final String TABLE_NAME = "TABLE_NAME"; |
| |
| private static final String PKTABLE_CAT = "PKTABLE_CAT"; |
| |
| private static final String PKTABLE_SCHEM = "PKTABLE_SCHEM"; |
| |
| private static final String PKTABLE_NAME = "PKTABLE_NAME"; |
| |
| private static final String PKCOLUMN_NAME = "PKCOLUMN_NAME"; |
| |
| private static final String FKTABLE_CAT = "FKTABLE_CAT"; |
| |
| private static final String FKTABLE_SCHEM = "FKTABLE SCHEM"; |
| |
| private static final String FKTABLE_NAME = "FKTABLE_NAME"; |
| |
| private static final String FKCOLUMN_NAME = "FKCOLUMN_NAME"; |
| |
| private static final String KEY_SEQ = "KEY_SEQ"; |
| |
| private static final String DELETE_RULE = "DELETE_RULE"; |
| |
| private static final String FK_NAME = "FK_NAME"; |
| |
| private static final String PK_NAME = "PK_NAME"; |
| |
| private static final String DEFERRABILITY = "DEFERRABILITY"; |
| |
| private static final String SPECIFIC_NAME = "SPECIFIC_NAME"; |
| |
| private static final String TABLE_TYPE = "TABLE_TYPE"; |
| private static final String SHOW_FUNCTIONS = "show functions"; |
| private static final String DECIMAL_DIGITS = "DECIMAL_DIGITS"; |
| private static final String SQL_DATETIME_SUB = "SQL_DATETIME_SUB"; |
| private static final String CHAR_OCTET_LENGTH = "CHAR_OCTET_LENGTH"; |
| private static final String COLUMN_SIZE = "COLUMN_SIZE"; |
| private static final String BUFFER_LENGTH = "BUFFER_LENGTH"; |
| private static final String DATA_TYPE = "DATA_TYPE"; |
| private static final String NUM_PREC_RADIX = "NUM_PREC_RADIX"; |
| private static final String SQL_DATA_TYPE = "SQL_DATA_TYPE"; |
| private static final String ORDINAL_POSITION = "ORDINAL_POSITION"; |
| private static final String NULLABLE = "NULLABLE"; |
| |
| private static final String CONVERT_ERROR_MSG = "convert tsBlock error: {}"; |
| |
| IoTDBDatabaseMetadata( |
| IoTDBConnection connection, IClientRPCService.Iface client, long sessionId) { |
| this.connection = connection; |
| this.client = client; |
| this.sessionId = sessionId; |
| } |
| |
| static { |
| String[] allIotdbSQLKeywords = { |
| "ALTER", |
| "ADD", |
| "ALIAS", |
| "ALL", |
| "AVG", |
| "ALIGN", |
| "ATTRIBUTES", |
| "AS", |
| "ASC", |
| "BY", |
| BOOLEAN, |
| "BITMAP", |
| "CREATE", |
| "CONFIGURATION", |
| "COMPRESSOR", |
| "CHILD", |
| "COUNT", |
| "COMPRESSION", |
| "CLEAR", |
| "CACHE", |
| "CONTAIN", |
| "CONCAT", |
| "DELETE", |
| "DEVICE", |
| "DESCRIBE", |
| "DATATYPE", |
| DOUBLE, |
| "DIFF", |
| "DROP", |
| "DEVICES", |
| "DISABLE", |
| "DESC", |
| "ENCODING", |
| "FROM", |
| "FILL", |
| FLOAT, |
| "FLUSH", |
| "FIRST_VALUE", |
| "FULL", |
| "FALSE", |
| "FOR", |
| "FUNCTION", |
| "FUNCTIONS", |
| "GRANT", |
| "GROUP", |
| "GORILLA", |
| "GLOBAL", |
| "GZIP", |
| "INSERT", |
| "INTO", |
| INT32, |
| INT64, |
| "INDEX", |
| "INFO", |
| "KILL", |
| "LIMIT", |
| "LINEAR", |
| "LABEL", |
| "LINK", |
| "LIST", |
| "LOAD", |
| "LEVEL", |
| "LAST_VALUE", |
| "LAST", |
| "LZO", |
| "LZ4", |
| "ZSTD", |
| "LZMA2", |
| "LATEST", |
| "LIKE", |
| "MAX_BY", |
| "MIN_BY", |
| "METADATA", |
| "MOVE", |
| "MIN_TIME", |
| "MAX_TIME", |
| "MIN_VALUE", |
| "MAX_VALUE", |
| "NOW", |
| "NODES", |
| "ORDER", |
| "OFFSET", |
| "ON", |
| "OFF", |
| "OF", |
| "PROCESSLIST", |
| "PREVIOUS", |
| "PREVIOUSUNTILLAST", |
| "PROPERTY", |
| "PLAIN", |
| "PLAIN_DICTIONARY", |
| "PRIVILEGES", |
| "PASSWORD", |
| "PATHS", |
| "PAA", |
| "PLA", |
| "PARTITION", |
| "QUERY", |
| "ROOT", |
| "RLE", |
| "REGULAR", |
| "ROLE", |
| "REVOKE", |
| "REMOVE", |
| "RENAME", |
| "SELECT", |
| "SHOW", |
| "SET", |
| "SLIMIT", |
| "SOFFSET", |
| "STDDEV", |
| "STDDEV_POP", |
| "STDDEV_SAMP", |
| "STORAGE", |
| "SUM", |
| "SNAPPY", |
| "SNAPSHOT", |
| "SCHEMA", |
| "TO", |
| "TIMESERIES", |
| "TIMESTAMP", |
| "TEXT", |
| "TS_2DIFF", |
| "TRACING", |
| "TTL", |
| "TASK", |
| "TIME", |
| "TAGS", |
| "TRUE", |
| "TEMPORARY", |
| "TOP", |
| "TOLERANCE", |
| "UPDATE", |
| "UNLINK", |
| "UPSERT", |
| "USING", |
| "USER", |
| "UNSET", |
| "UNCOMPRESSED", |
| "VALUES", |
| "VARIANCE", |
| "VAR_POP", |
| "VAR_SAMP", |
| "VERSION", |
| "WHERE", |
| "WITH", |
| "WATERMARK_EMBEDDING" |
| }; |
| String[] sql92Keywords = { |
| "ABSOLUTE", |
| "EXEC", |
| "OVERLAPS", |
| "ACTION", |
| "EXECUTE", |
| "PAD", |
| "ADA", |
| "EXISTS", |
| "PARTIAL", |
| "ADD", |
| "EXTERNAL", |
| "PASCAL", |
| "ALL", |
| "EXTRACT", |
| "POSITION", |
| "ALLOCATE", |
| "FALSE", |
| PRECISION, |
| "ALTER", |
| "FETCH", |
| "PREPARE", |
| "AND", |
| "FIRST", |
| "PRESERVE", |
| "ANY", |
| FLOAT, |
| PRIMARY, |
| "ARE", |
| "FOR", |
| "PRIOR", |
| "AS", |
| "FOREIGN", |
| "PRIVILEGES", |
| "ASC", |
| "FORTRAN", |
| "PROCEDURE", |
| "ASSERTION", |
| "FOUND", |
| "PUBLIC", |
| "AT", |
| "FROM", |
| "READ", |
| "AUTHORIZATION", |
| "FULL", |
| "REAL", |
| "AVG", |
| "GET", |
| "REFERENCES", |
| "BEGIN", |
| "GLOBAL", |
| "RELATIVE", |
| "BETWEEN", |
| "GO", |
| "RESTRICT", |
| "BIT", |
| "GOTO", |
| "REVOKE", |
| "BIT_LENGTH", |
| "GRANT", |
| "RIGHT", |
| "BOTH", |
| "GROUP", |
| "ROLLBACK", |
| "BY", |
| "HAVING", |
| "ROWS", |
| "CASCADE", |
| "HOUR", |
| "SCHEMA", |
| "CASCADED", |
| "IDENTITY", |
| "SCROLL", |
| "CASE", |
| "IMMEDIATE", |
| "SECOND", |
| "CAST", |
| "IN", |
| "SECTION", |
| "CATALOG", |
| "INCLUDE", |
| "SELECT", |
| "CHAR", |
| "INDEX", |
| "SESSION", |
| "CHAR_LENGTH", |
| "INDICATOR", |
| "SESSION_USER", |
| "CHARACTER", |
| "INITIALLY", |
| "SET", |
| "CHARACTER_LENGTH", |
| "INNER", |
| "SIZE", |
| "CHECK", |
| "INPUT", |
| "SMALLINT", |
| "CLOSE", |
| "INSENSITIVE", |
| "SOME", |
| "COALESCE", |
| "INSERT", |
| "SPACE", |
| "COLLATE", |
| "INT", |
| "SQL", |
| "COLLATION", |
| "INTEGER", |
| "SQLCA", |
| "COLUMN", |
| "INTERSECT", |
| "SQLCODE", |
| "COMMIT", |
| "INTERVAL", |
| "SQLERROR", |
| "CONNECT", |
| "INTO", |
| "SQLSTATE", |
| "CONNECTION", |
| "IS", |
| "SQLWARNING", |
| "CONSTRAINT", |
| "ISOLATION", |
| "SUBSTRING", |
| "CONSTRAINTS", |
| "JOIN", |
| "SUM", |
| "CONTINUE", |
| "KEY", |
| "SYSTEM_USER", |
| "CONVERT", |
| "LANGUAGE", |
| "TABLE", |
| "CORRESPONDING", |
| "LAST", |
| "TEMPORARY", |
| "COUNT", |
| "LEADING", |
| "THEN", |
| "CREATE", |
| "LEFT", |
| "TIME", |
| "CROSS", |
| "LEVEL", |
| "TIMESTAMP", |
| "CURRENT", |
| "LIKE", |
| "TIMEZONE_HOUR", |
| "CURRENT_DATE", |
| "LOCAL", |
| "TIMEZONE_MINUTE", |
| "CURRENT_TIME", |
| "LOWER", |
| "TO", |
| "CURRENT_TIMESTAMP", |
| "MATCH", |
| "TRAILING", |
| "CURRENT_USER", |
| "MAX", |
| "TRANSACTION", |
| "CURSOR", |
| "MIN", |
| "TRANSLATE", |
| "DATE", |
| "MINUTE", |
| "TRANSLATION", |
| "DAY", |
| "MODULE", |
| "TRIM", |
| "DEALLOCATE", |
| "MONTH", |
| "TRUE", |
| "DEC", |
| "NAMES", |
| "UNION", |
| "DECIMAL", |
| "NATIONAL", |
| "UNIQUE", |
| "DECLARE", |
| "NATURAL", |
| "UNKNOWN", |
| "DEFAULT", |
| "NCHAR", |
| "UPDATE", |
| "DEFERRABLE", |
| "NEXT", |
| "UPPER", |
| "DEFERRED", |
| "NO", |
| "USAGE", |
| "DELETE", |
| "NONE", |
| "USER", |
| "DESC", |
| "NOT", |
| "USING", |
| "DESCRIBE", |
| "NULL", |
| "VALUE", |
| "DESCRIPTOR", |
| "NULLIF", |
| "VALUES", |
| "DIAGNOSTICS", |
| "NUMERIC", |
| "VARCHAR", |
| "DISCONNECT", |
| "OCTET_LENGTH", |
| "VARYING", |
| "DISTINCT", |
| "OF", |
| "VIEW", |
| "DOMAIN", |
| "ON", |
| "WHEN", |
| DOUBLE, |
| "ONLY", |
| "WHENEVER", |
| "DROP", |
| "OPEN", |
| "WHERE", |
| "ELSE", |
| "OPTION", |
| "WITH", |
| "END", |
| "OR", |
| "WORK", |
| "END-EXEC", |
| "ORDER", |
| "WRITE", |
| "ESCAPE", |
| "OUTER", |
| "YEAR", |
| "EXCEPT", |
| "OUTPUT", |
| "ZONE", |
| "EXCEPTION" |
| }; |
| TreeMap myKeywordMap = new TreeMap(); |
| for (int i = 0; i < allIotdbSQLKeywords.length; i++) { |
| myKeywordMap.put(allIotdbSQLKeywords[i], null); |
| } |
| HashMap sql92KeywordMap = new HashMap(sql92Keywords.length); |
| for (int j = 0; j < sql92Keywords.length; j++) { |
| sql92KeywordMap.put(sql92Keywords[j], null); |
| } |
| Iterator it = sql92KeywordMap.keySet().iterator(); |
| while (it.hasNext()) { |
| myKeywordMap.remove(it.next()); |
| } |
| StringBuilder keywordBuf = new StringBuilder(); |
| it = myKeywordMap.keySet().iterator(); |
| if (it.hasNext()) { |
| keywordBuf.append(it.next().toString()); |
| } |
| while (it.hasNext()) { |
| keywordBuf.append(","); |
| keywordBuf.append(it.next().toString()); |
| } |
| sqlKeywordsThatArentSQL92 = keywordBuf.toString(); |
| } |
| |
| @Override |
| public boolean isWrapperFor(Class<?> arg0) throws SQLException { |
| throw new SQLException(METHOD_NOT_SUPPORTED_STRING); |
| } |
| |
| @Override |
| public <T> T unwrap(Class<T> iface) throws SQLException { |
| throw new SQLException(METHOD_NOT_SUPPORTED_STRING); |
| } |
| |
| @Override |
| public boolean allProceduresAreCallable() { |
| return false; |
| } |
| |
| @Override |
| public boolean allTablesAreSelectable() { |
| return true; |
| } |
| |
| @Override |
| public boolean autoCommitFailureClosesAllResultSets() { |
| return false; |
| } |
| |
| @Override |
| public boolean dataDefinitionCausesTransactionCommit() { |
| return false; |
| } |
| |
| @Override |
| public boolean dataDefinitionIgnoredInTransactions() { |
| return false; |
| } |
| |
| @Override |
| public boolean deletesAreDetected(int arg0) { |
| return true; |
| } |
| |
| @Override |
| public boolean doesMaxRowSizeIncludeBlobs() { |
| return false; // The return value is tentatively FALSE and may be adjusted later |
| } |
| |
| @Override |
| public boolean generatedKeyAlwaysReturned() { |
| return true; |
| } |
| |
| @Override |
| public long getMaxLogicalLobSize() { |
| return Long.MAX_VALUE; |
| } |
| |
| @Override |
| public boolean supportsRefCursors() { |
| return false; |
| } |
| |
| @Override |
| public ResultSet getAttributes(String arg0, String arg1, String arg2, String arg3) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[21]; |
| fields[0] = new Field("", TYPE_CAT, "TEXT"); |
| fields[1] = new Field("", "TYPE_SCHEM", "TEXT"); |
| fields[2] = new Field("", TYPE_NAME, "TEXT"); |
| fields[3] = new Field("", "ATTR_NAME", "TEXT"); |
| fields[4] = new Field("", DATA_TYPE, INT32); |
| fields[5] = new Field("", "ATTR_TYPE_NAME", "TEXT"); |
| fields[6] = new Field("", "ATTR_SIZE", INT32); |
| fields[7] = new Field("", DECIMAL_DIGITS, INT32); |
| fields[8] = new Field("", NUM_PREC_RADIX, INT32); |
| fields[9] = new Field("", "NULLABLE ", INT32); |
| fields[10] = new Field("", REMARKS, "TEXT"); |
| fields[11] = new Field("", "ATTR_DEF", "TEXT"); |
| fields[12] = new Field("", SQL_DATA_TYPE, INT32); |
| fields[13] = new Field("", SQL_DATETIME_SUB, INT32); |
| fields[14] = new Field("", CHAR_OCTET_LENGTH, INT32); |
| fields[15] = new Field("", ORDINAL_POSITION, INT32); |
| fields[16] = new Field("", IS_NULLABLE, "TEXT"); |
| fields[17] = new Field("", "SCOPE_CATALOG", "TEXT"); |
| fields[18] = new Field("", "SCOPE_SCHEMA", "TEXT"); |
| fields[19] = new Field("", "SCOPE_TABLE", "TEXT"); |
| fields[20] = new Field("", "SOURCE_DATA_TYPE", INT32); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get attributes error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public ResultSet getBestRowIdentifier( |
| String arg0, String arg1, String arg2, int arg3, boolean arg4) throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[8]; |
| fields[0] = new Field("", "SCOPE", INT32); |
| fields[1] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[2] = new Field("", DATA_TYPE, INT32); |
| fields[3] = new Field("", TYPE_NAME, "TEXT"); |
| fields[4] = new Field("", COLUMN_SIZE, INT32); |
| fields[5] = new Field("", BUFFER_LENGTH, INT32); |
| fields[6] = new Field("", DECIMAL_DIGITS, INT32); |
| fields[7] = new Field("", "PSEUDO_COLUMN", INT32); |
| |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get best row identifier error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public String getCatalogSeparator() { |
| return "."; |
| } |
| |
| @Override |
| public String getCatalogTerm() { |
| return "database"; |
| } |
| |
| @SuppressWarnings( |
| "squid:S2095") // ignore Use try-with-resources or close this "Statement" in a "finally" |
| // clause |
| @Override |
| public ResultSet getCatalogs() throws SQLException { |
| Statement stmt = this.connection.createStatement(); |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(SHOW_DATABASES_SQL); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<TSDataType> tsDataTypeList = new ArrayList<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| tsDataTypeList.add(TSDataType.TEXT); |
| |
| while (rs.next()) { |
| List<Object> values = new ArrayList<>(); |
| values.add(rs.getString(1)); |
| valuesList.add(values); |
| } |
| columnNameList.add(TYPE_CAT); |
| columnTypeList.add("TEXT"); |
| columnNameIndex.put(TYPE_CAT, 0); |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error("get cateLogs error: {}", e.getMessage()); |
| } finally { |
| close(rs, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| public static ByteBuffer convertTsBlock( |
| List<List<Object>> valuesList, List<TSDataType> tsDataTypeList) throws IOException { |
| TsBlockBuilder tsBlockBuilder = new TsBlockBuilder(tsDataTypeList); |
| for (List<Object> valuesInRow : valuesList) { |
| tsBlockBuilder.getTimeColumnBuilder().writeLong(0); |
| for (int j = 0; j < tsDataTypeList.size(); j++) { |
| TSDataType columnType = tsDataTypeList.get(j); |
| switch (columnType) { |
| case TEXT: |
| tsBlockBuilder |
| .getColumnBuilder(j) |
| .writeBinary( |
| new Binary(valuesInRow.get(j).toString(), TSFileConfig.STRING_CHARSET)); |
| break; |
| case FLOAT: |
| tsBlockBuilder.getColumnBuilder(j).writeFloat((float) valuesInRow.get(j)); |
| break; |
| case INT32: |
| tsBlockBuilder.getColumnBuilder(j).writeInt((int) valuesInRow.get(j)); |
| break; |
| case INT64: |
| tsBlockBuilder.getColumnBuilder(j).writeLong((long) valuesInRow.get(j)); |
| break; |
| case DOUBLE: |
| tsBlockBuilder.getColumnBuilder(j).writeDouble((double) valuesInRow.get(j)); |
| break; |
| case BOOLEAN: |
| tsBlockBuilder.getColumnBuilder(j).writeBoolean((boolean) valuesInRow.get(j)); |
| break; |
| default: |
| LOGGER.error("No data type was matched {}", columnType); |
| break; |
| } |
| } |
| tsBlockBuilder.declarePosition(); |
| } |
| TsBlock tsBlock = tsBlockBuilder.build(); |
| if (tsBlock == null) { |
| return null; |
| } else { |
| return serde.serialize(tsBlock); |
| } |
| } |
| |
| @SuppressWarnings( |
| "squid:S2095") // ignore Use try-with-resources or close this "Statement" in a "finally" |
| // clause |
| @Override |
| public ResultSet getClientInfoProperties() throws SQLException { |
| Statement stmt = this.connection.createStatement(); |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(SHOW_DATABASES_SQL); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| Field[] fields = new Field[4]; |
| fields[0] = new Field("", "NAME", "TEXT"); |
| fields[1] = new Field("", "MAX_LEN", INT32); |
| fields[2] = new Field("", "DEFAULT_VALUE", INT32); |
| fields[3] = new Field("", "DESCRIPTION", "TEXT"); |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList(TSDataType.TEXT, TSDataType.INT32, TSDataType.INT32, TSDataType.TEXT); |
| List<Object> values = Arrays.asList("fetch_size", 10, 10, ""); |
| |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| |
| valuesList.add(values); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error("convert tsBlock error when get client info properties: {}", e.getMessage()); |
| } finally { |
| close(rs, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @SuppressWarnings({ |
| "squid:S6541", |
| "squid:S3776", |
| "squid:S2095" |
| }) // ignore Cognitive Complexity of methods should not be too high |
| // ignore Methods should not perform too many tasks (aka Brain method) |
| // ignore Use try-with-resources or close this "Statement" in a "finally" |
| @Override |
| public ResultSet getColumnPrivileges( |
| String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) |
| throws SQLException { |
| Statement stmt = this.connection.createStatement(); |
| |
| String sql = "SHOW DATABASES"; |
| if (catalog != null && catalog.length() > 0) { |
| if (catalog.contains("%")) { |
| catalog = catalog.replace("%", "*"); |
| } |
| sql = sql + " " + catalog; |
| } else if (schemaPattern != null && schemaPattern.length() > 0) { |
| if (schemaPattern.contains("%")) { |
| schemaPattern = schemaPattern.replace("%", "*"); |
| } |
| sql = sql + " " + schemaPattern; |
| } |
| if (((catalog != null && catalog.length() > 0) |
| || schemaPattern != null && schemaPattern.length() > 0) |
| && tableNamePattern != null |
| && tableNamePattern.length() > 0) { |
| if (tableNamePattern.contains("%")) { |
| tableNamePattern = tableNamePattern.replace("%", "*"); |
| } |
| sql = sql + "." + tableNamePattern; |
| } |
| |
| if (((catalog != null && catalog.length() > 0) |
| || schemaPattern != null && schemaPattern.length() > 0) |
| && tableNamePattern != null |
| && tableNamePattern.length() > 0 |
| && columnNamePattern != null |
| && columnNamePattern.length() > 0) { |
| sql = sql + "." + columnNamePattern; |
| } |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(sql); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| Field[] fields = new Field[8]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", "GRANTOR", "TEXT"); |
| fields[5] = new Field("", "GRANTEE", "TEXT"); |
| fields[6] = new Field("", "PRIVILEGE", "TEXT"); |
| fields[7] = new Field("", "IS_GRANTABLE", "TEXT"); |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT); |
| |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| while (rs.next()) { |
| List<Object> valuesInRow = new ArrayList<>(); |
| for (int i = 0; i < fields.length; i++) { |
| if (i < 4) { |
| valuesInRow.add(rs.getString(1)); |
| } else if (i == 5) { |
| valuesInRow.add(getUserName()); |
| } else if (i == 6) { |
| valuesInRow.add(""); |
| } else if (i == 7) { |
| valuesInRow.add("NO"); |
| } else { |
| valuesInRow.add(""); |
| } |
| } |
| valuesList.add(valuesInRow); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error("convert tsBlock error when get column privileges: {}", e.getMessage()); |
| } finally { |
| close(rs, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public Connection getConnection() { |
| return connection; |
| } |
| |
| @Override |
| public ResultSet getCrossReference( |
| String arg0, String arg1, String arg2, String arg3, String arg4, String arg5) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[14]; |
| fields[0] = new Field("", PKTABLE_CAT, "TEXT"); |
| fields[1] = new Field("", PKTABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", PKTABLE_NAME, "TEXT"); |
| fields[3] = new Field("", PKCOLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", FKTABLE_CAT, "TEXT"); |
| fields[5] = new Field("", FKTABLE_SCHEM, "TEXT"); |
| fields[6] = new Field("", FKTABLE_NAME, "TEXT"); |
| fields[7] = new Field("", FKCOLUMN_NAME, "TEXT"); |
| fields[8] = new Field("", KEY_SEQ, "TEXT"); |
| fields[9] = new Field("", "UPDATE_RULE ", "TEXT"); |
| fields[10] = new Field("", DELETE_RULE, "TEXT"); |
| fields[11] = new Field("", FK_NAME, "TEXT"); |
| fields[12] = new Field("", PK_NAME, "TEXT"); |
| fields[13] = new Field("", DEFERRABILITY, "TEXT"); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get cross reference error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public int getDatabaseMajorVersion() { |
| int majorVersion = 0; |
| try { |
| String version = client.getProperties().getVersion(); |
| String[] versions = version.split("."); |
| if (versions.length >= 2) { |
| majorVersion = Integer.valueOf(versions[0]); |
| } |
| } catch (TException e) { |
| LOGGER.error("get database major version error: {}", e.getMessage()); |
| } |
| return majorVersion; |
| } |
| |
| @Override |
| public int getDatabaseMinorVersion() { |
| int minorVersion = 0; |
| try { |
| String version = client.getProperties().getVersion(); |
| String[] versions = version.split("."); |
| if (versions.length >= 2) { |
| minorVersion = Integer.valueOf(versions[1]); |
| } |
| } catch (TException e) { |
| LOGGER.error("get database minor version error: {}", e.getMessage()); |
| } |
| return minorVersion; |
| } |
| |
| @Override |
| public String getDatabaseProductName() { |
| return Constant.GLOBAL_DB_NAME; |
| } |
| |
| @Override |
| public String getDatabaseProductVersion() { |
| return getDriverVersion(); |
| } |
| |
| @Override |
| public int getDefaultTransactionIsolation() { |
| return 0; |
| } |
| |
| @Override |
| public int getDriverMajorVersion() { |
| return 4; |
| } |
| |
| @Override |
| public int getDriverMinorVersion() { |
| return 3; |
| } |
| |
| @Override |
| public String getDriverName() { |
| return org.apache.iotdb.jdbc.IoTDBDriver.class.getName(); |
| } |
| |
| @Override |
| public String getDriverVersion() { |
| return DATABASE_VERSION; |
| } |
| |
| @Override |
| public ResultSet getExportedKeys(String catalog, String schema, final String table) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[14]; |
| fields[0] = new Field("", PKTABLE_CAT, "TEXT"); |
| fields[1] = new Field("", PKTABLE_SCHEM, INT32); |
| fields[2] = new Field("", PKTABLE_NAME, "TEXT"); |
| fields[3] = new Field("", PKCOLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", FKTABLE_CAT, "TEXT"); |
| fields[5] = new Field("", FKTABLE_SCHEM, "TEXT"); |
| fields[6] = new Field("", FKTABLE_NAME, "TEXT"); |
| fields[7] = new Field("", FKCOLUMN_NAME, "TEXT"); |
| fields[8] = new Field("", KEY_SEQ, INT32); |
| fields[9] = new Field("", "UPDATE_RULE", INT32); |
| fields[10] = new Field("", DELETE_RULE, INT32); |
| fields[11] = new Field("", FK_NAME, "TEXT"); |
| fields[12] = new Field("", PK_NAME, "TEXT"); |
| fields[13] = new Field("", DEFERRABILITY, INT32); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get exported keys error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public String getExtraNameCharacters() { |
| return ""; |
| } |
| |
| @SuppressWarnings( |
| "squid:S2095") // ignore Use try-with-resources or close this "Statement" in a "finally" |
| // clause |
| @Override |
| public ResultSet getFunctionColumns( |
| String catalog, |
| String schemaPattern, |
| java.lang.String functionNamePattern, |
| java.lang.String columnNamePattern) |
| throws SQLException { |
| Statement stmt = connection.createStatement(); |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(SHOW_FUNCTIONS); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| Field[] fields = new Field[17]; |
| fields[0] = new Field("", "FUNCTION_CAT ", "TEXT"); |
| fields[1] = new Field("", "FUNCTION_SCHEM", "TEXT"); |
| fields[2] = new Field("", "FUNCTION_NAME", "TEXT"); |
| fields[3] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", "COLUMN_TYPE", INT32); |
| fields[5] = new Field("", DATA_TYPE, INT32); |
| fields[6] = new Field("", TYPE_NAME, "TEXT"); |
| fields[7] = new Field("", PRECISION, INT32); |
| fields[8] = new Field("", "LENGTH", INT32); |
| fields[9] = new Field("", "SCALE", INT32); |
| fields[10] = new Field("", "RADIX", INT32); |
| fields[11] = new Field("", NULLABLE, INT32); |
| fields[12] = new Field("", REMARKS, "TEXT"); |
| fields[13] = new Field("", CHAR_OCTET_LENGTH, INT32); |
| fields[14] = new Field("", ORDINAL_POSITION, INT32); |
| fields[15] = new Field("", IS_NULLABLE, "TEXT"); |
| fields[16] = new Field("", SPECIFIC_NAME, "TEXT"); |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.TEXT); |
| |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| while (rs.next()) { |
| List<Object> valuesInRow = new ArrayList<>(); |
| for (int i = 0; i < fields.length; i++) { |
| if (i == 2) { |
| valuesInRow.add(rs.getString(1)); |
| } else if (INT32.equals(fields[i].getSqlType())) { |
| valuesInRow.add(0); |
| } else { |
| valuesInRow.add(""); |
| } |
| } |
| valuesList.add(valuesInRow); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error("convert tsBlock error when get function columns: {}", e.getMessage()); |
| } finally { |
| close(rs, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @SuppressWarnings( |
| "squid:S2095") // ignore Use try-with-resources or close this "Statement" in a "finally" |
| // clause |
| @Override |
| public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern) |
| throws SQLException { |
| Statement stmt = connection.createStatement(); |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(SHOW_FUNCTIONS); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| Field[] fields = new Field[6]; |
| fields[0] = new Field("", "FUNCTION_CAT ", "TEXT"); |
| fields[1] = new Field("", "FUNCTION_SCHEM", "TEXT"); |
| fields[2] = new Field("", "FUNCTION_NAME", "TEXT"); |
| fields[3] = new Field("", REMARKS, "TEXT"); |
| fields[4] = new Field("", "FUNCTION_TYPE", INT32); |
| fields[5] = new Field("", SPECIFIC_NAME, "TEXT"); |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.TEXT); |
| |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| while (rs.next()) { |
| List<Object> valueInRow = new ArrayList<>(); |
| for (int i = 0; i < fields.length; i++) { |
| if (i == 2) { |
| valueInRow.add(rs.getString(1)); |
| } else if (i == 4) { |
| valueInRow.add(0); |
| } else { |
| valueInRow.add(""); |
| } |
| } |
| valuesList.add(valueInRow); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error("convert tsBlock error when get functions: {}", e.getMessage()); |
| } finally { |
| close(rs, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public String getIdentifierQuoteString() { |
| return "\' or \""; |
| } |
| |
| @Override |
| public ResultSet getImportedKeys(String arg0, String arg1, String arg2) throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[14]; |
| fields[0] = new Field("", PKTABLE_CAT, "TEXT"); |
| fields[1] = new Field("", PKTABLE_SCHEM, INT32); |
| fields[2] = new Field("", PKTABLE_NAME, "TEXT"); |
| fields[3] = new Field("", PKCOLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", FKTABLE_CAT, "TEXT"); |
| fields[5] = new Field("", FKTABLE_SCHEM, "TEXT"); |
| fields[6] = new Field("", FKTABLE_NAME, "TEXT"); |
| fields[7] = new Field("", FKCOLUMN_NAME, "TEXT"); |
| fields[8] = new Field("", KEY_SEQ, INT32); |
| fields[9] = new Field("", "UPDATE_RULE", INT32); |
| fields[10] = new Field("", DELETE_RULE, INT32); |
| fields[11] = new Field("", FK_NAME, "TEXT"); |
| fields[12] = new Field("", PK_NAME, "TEXT"); |
| fields[13] = new Field("", DEFERRABILITY, INT32); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get import keys error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public ResultSet getIndexInfo(String arg0, String arg1, String arg2, boolean arg3, boolean arg4) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[14]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", "NON_UNIQUE", "TEXT"); |
| fields[4] = new Field("", "INDEX_QUALIFIER", "TEXT"); |
| fields[5] = new Field("", "INDEX_NAME", "TEXT"); |
| fields[6] = new Field("", "TYPE", "TEXT"); |
| fields[7] = new Field("", ORDINAL_POSITION, "TEXT"); |
| fields[8] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[9] = new Field("", "ASC_OR_DESC", "TEXT"); |
| fields[10] = new Field("", "CARDINALITY", "TEXT"); |
| fields[11] = new Field("", "PAGES", "TEXT"); |
| fields[12] = new Field("", PK_NAME, "TEXT"); |
| fields[13] = new Field("", "FILTER_CONDITION", "TEXT"); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get index info error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public int getJDBCMajorVersion() { |
| return 4; |
| } |
| |
| @Override |
| public int getJDBCMinorVersion() { |
| return 3; |
| } |
| |
| @Override |
| public int getMaxBinaryLiteralLength() { |
| return Integer.MAX_VALUE; |
| } |
| /** Although there is no limit, it is not recommended */ |
| @Override |
| public int getMaxCatalogNameLength() { |
| return 1024; |
| } |
| |
| @Override |
| public int getMaxCharLiteralLength() { |
| return Integer.MAX_VALUE; |
| } |
| /** Although there is no limit, it is not recommended */ |
| @Override |
| public int getMaxColumnNameLength() { |
| return 1024; |
| } |
| |
| @Override |
| public int getMaxColumnsInGroupBy() { |
| return 1; |
| } |
| |
| @Override |
| public int getMaxColumnsInIndex() { |
| return 0; |
| } |
| |
| @Override |
| public int getMaxColumnsInOrderBy() { |
| return 1; |
| } |
| |
| @Override |
| public int getMaxColumnsInSelect() { |
| return 0; |
| } |
| |
| @Override |
| public int getMaxColumnsInTable() { |
| return Integer.MAX_VALUE; |
| } |
| |
| @Override |
| public int getMaxConnections() { |
| int maxcount = 0; |
| try { |
| maxcount = client.getProperties().getMaxConcurrentClientNum(); |
| } catch (TException e) { |
| LOGGER.error("get max concurrentClientNUm error: {}", e.getMessage()); |
| } |
| return maxcount; |
| } |
| |
| @Override |
| public int getMaxCursorNameLength() { |
| return 0; |
| } |
| |
| @Override |
| public int getMaxIndexLength() { |
| return Integer.MAX_VALUE; |
| } |
| |
| @Override |
| public int getMaxProcedureNameLength() { |
| return 0; |
| } |
| /** maxrowsize unlimited */ |
| @Override |
| public int getMaxRowSize() { |
| return 2147483639; |
| } |
| /** Although there is no limit, it is not recommended */ |
| @Override |
| public int getMaxSchemaNameLength() { |
| return 1024; |
| } |
| |
| @Override |
| public int getMaxStatementLength() { |
| try { |
| return client.getProperties().getThriftMaxFrameSize(); |
| } catch (TException e) { |
| LOGGER.error("get max statement length error: {}", e.getMessage()); |
| } |
| return 0; |
| } |
| |
| @Override |
| public int getMaxStatements() { |
| return 0; |
| } |
| /** Although there is no limit, it is not recommended */ |
| @Override |
| public int getMaxTableNameLength() { |
| return 1024; |
| } |
| /** Although there is no limit, it is not recommended */ |
| @Override |
| public int getMaxTablesInSelect() { |
| return 1024; |
| } |
| /** Although there is no limit, it is not recommended */ |
| @Override |
| public int getMaxUserNameLength() { |
| return 1024; |
| } |
| |
| @Override |
| public String getNumericFunctions() { |
| ResultSet resultSet = null; |
| Statement statement = null; |
| String result = ""; |
| try { |
| statement = connection.createStatement(); |
| StringBuilder str = new StringBuilder(""); |
| resultSet = statement.executeQuery(SHOW_FUNCTIONS); |
| List<String> listfunction = Arrays.asList("MAX_TIME", "MIN_TIME", "TIME_DIFFERENCE", "NOW"); |
| while (resultSet.next()) { |
| if (listfunction.contains(resultSet.getString(1))) { |
| continue; |
| } |
| str.append(resultSet.getString(1)).append(","); |
| } |
| result = str.toString(); |
| if (result.length() > 0) { |
| result = result.substring(0, result.length() - 1); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get numeric functions error: {}", e.getMessage()); |
| } finally { |
| close(resultSet, statement); |
| } |
| return result; |
| } |
| |
| @Override |
| public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException { |
| Statement stmt = connection.createStatement(); |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.TEXT); |
| |
| String database = ""; |
| if (catalog != null) { |
| database = catalog; |
| } else if (schema != null) { |
| database = schema; |
| } |
| |
| Field[] fields = new Field[6]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", KEY_SEQ, INT32); |
| fields[5] = new Field("", PK_NAME, "TEXT"); |
| |
| List<Object> listValSub1 = Arrays.asList(database, "", table, "time", 1, PRIMARY); |
| List<Object> listValSub2 = Arrays.asList(database, "", table, "deivce", 2, PRIMARY); |
| List<List<Object>> valuesList = Arrays.asList(listValSub1, listValSub2); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error("get primary keys error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public ResultSet getProcedureColumns(String arg0, String arg1, String arg2, String arg3) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| |
| Field[] fields = new Field[20]; |
| fields[0] = new Field("", "PROCEDURE_CAT", "TEXT"); |
| fields[1] = new Field("", "PROCEDURE_SCHEM", "TEXT"); |
| fields[2] = new Field("", "PROCEDURE_NAME", "TEXT"); |
| fields[3] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", "COLUMN_TYPE", "TEXT"); |
| fields[5] = new Field("", DATA_TYPE, INT32); |
| fields[6] = new Field("", TYPE_NAME, "TEXT"); |
| fields[7] = new Field("", PRECISION, "TEXT"); |
| fields[8] = new Field("", "LENGTH", "TEXT"); |
| fields[9] = new Field("", "SCALE", "TEXT"); |
| fields[10] = new Field("", "RADIX", "TEXT"); |
| fields[11] = new Field("", NULLABLE, "TEXT"); |
| fields[12] = new Field("", REMARKS, "TEXT"); |
| fields[13] = new Field("", "COLUMN_DEF", "TEXT"); |
| fields[14] = new Field("", SQL_DATA_TYPE, INT32); |
| fields[15] = new Field("", SQL_DATETIME_SUB, "TEXT"); |
| fields[16] = new Field("", CHAR_OCTET_LENGTH, "TEXT"); |
| fields[17] = new Field("", ORDINAL_POSITION, "TEXT"); |
| fields[18] = new Field("", IS_NULLABLE, "TEXT"); |
| fields[19] = new Field("", SPECIFIC_NAME, "TEXT"); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get procedure columns error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public String getProcedureTerm() { |
| return ""; |
| } |
| |
| @Override |
| public ResultSet getProcedures(String arg0, String arg1, String arg2) throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[6]; |
| fields[0] = new Field("", "PROCEDURE_CAT", "TEXT"); |
| fields[1] = new Field("", "PROCEDURE_SCHEM", "TEXT"); |
| fields[2] = new Field("", "PROCEDURE_NAME", "TEXT"); |
| fields[3] = new Field("", REMARKS, "TEXT"); |
| fields[4] = new Field("", "PROCEDURE_TYPE", "TEXT"); |
| fields[5] = new Field("", SPECIFIC_NAME, "TEXT"); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get procedures error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public ResultSet getPseudoColumns( |
| String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) |
| throws SQLException { |
| Statement stmt = connection.createStatement(); |
| Field[] fields = new Field[12]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", DATA_TYPE, INT32); |
| fields[5] = new Field("", COLUMN_SIZE, INT32); |
| fields[6] = new Field("", DECIMAL_DIGITS, INT32); |
| fields[7] = new Field("", NUM_PREC_RADIX, INT32); |
| fields[8] = new Field("", "COLUMN_USAGE", "TEXT"); |
| fields[9] = new Field("", REMARKS, "TEXT"); |
| fields[10] = new Field("", CHAR_OCTET_LENGTH, INT32); |
| fields[11] = new Field("", IS_NULLABLE, "TEXT"); |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.TEXT); |
| |
| List<Object> value = |
| Arrays.asList( |
| catalog, catalog, tableNamePattern, "times", Types.BIGINT, 1, 0, 2, "", "", 13, "NO"); |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(Collections.singletonList(value), tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error(CONVERT_ERROR_MSG, e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| 0, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public int getResultSetHoldability() { |
| return ResultSet.HOLD_CURSORS_OVER_COMMIT; |
| } |
| |
| @Override |
| public RowIdLifetime getRowIdLifetime() { |
| return RowIdLifetime.ROWID_UNSUPPORTED; |
| } |
| |
| @Override |
| public String getSQLKeywords() { |
| return sqlKeywordsThatArentSQL92; |
| } |
| |
| @Override |
| public int getSQLStateType() { |
| return 0; |
| } |
| |
| @Override |
| public String getSchemaTerm() { |
| return "stroge group"; |
| } |
| |
| @SuppressWarnings( |
| "squid:S2095") // ignore Use try-with-resources or close this "Statement" in a "finally" |
| // clause |
| @Override |
| public ResultSet getSchemas() throws SQLException { |
| Statement stmt = this.connection.createStatement(); |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(SHOW_DATABASES_SQL); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| Field[] fields = new Field[2]; |
| fields[0] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[1] = new Field("", "TABLE_CATALOG", "TEXT"); |
| |
| List<TSDataType> tsDataTypeList = Arrays.asList(TSDataType.TEXT, TSDataType.TEXT); |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| while (rs.next()) { |
| List<Object> valueInRow = new ArrayList<>(); |
| for (int i = 0; i < fields.length; i++) { |
| valueInRow.add(rs.getString(1)); |
| } |
| valuesList.add(valueInRow); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error(CONVERT_ERROR_MSG, e.getMessage()); |
| } finally { |
| close(rs, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException { |
| return getSchemas(); |
| } |
| |
| @Override |
| public String getSearchStringEscape() { |
| return "\\"; |
| } |
| |
| @Override |
| public String getStringFunctions() { |
| return getSystemFunctions(); |
| } |
| |
| @Override |
| public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[4]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", "SUPERTABLE_NAME", "TEXT"); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get super tables error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[6]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", "SUPERTYPE_CAT", "TEXT"); |
| fields[4] = new Field("", "SUPERTYPE_SCHEM", "TEXT"); |
| fields[5] = new Field("", "SUPERTYPE_NAME", "TEXT"); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get super types error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public String getSystemFunctions() { |
| String result = ""; |
| Statement statement = null; |
| ResultSet resultSet = null; |
| try { |
| statement = connection.createStatement(); |
| StringBuilder str = new StringBuilder(""); |
| resultSet = statement.executeQuery(SHOW_FUNCTIONS); |
| while (resultSet.next()) { |
| str.append(resultSet.getString(1)).append(","); |
| } |
| result = str.toString(); |
| if (result.length() > 0) { |
| result = result.substring(0, result.length() - 1); |
| } |
| } catch (Exception ex) { |
| LOGGER.error("get system functions error: {}", ex.getMessage()); |
| } finally { |
| close(resultSet, statement); |
| } |
| return result; |
| } |
| |
| @SuppressWarnings({ |
| "squid:S6541", |
| "squid:S3776", |
| "squid:S2095" |
| }) // ignore Cognitive Complexity of methods should not be too high |
| // ignore Methods should not perform too many tasks (aka Brain method) |
| // ignore Use try-with-resources or close this "Statement" in a "finally" clause |
| @Override |
| public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern) |
| throws SQLException { |
| Statement stmt = this.connection.createStatement(); |
| |
| String sql = "SHOW DATABASES"; |
| if (catalog != null && catalog.length() > 0) { |
| if (catalog.contains("%")) { |
| catalog = catalog.replace("%", "*"); |
| } |
| sql = sql + " " + catalog; |
| } else if (schemaPattern != null && schemaPattern.length() > 0) { |
| if (schemaPattern.contains("%")) { |
| schemaPattern = schemaPattern.replace("%", "*"); |
| } |
| sql = sql + " " + schemaPattern; |
| } |
| if (((catalog != null && catalog.length() > 0) |
| || schemaPattern != null && schemaPattern.length() > 0) |
| && tableNamePattern != null |
| && tableNamePattern.length() > 0) { |
| if (tableNamePattern.contains("%")) { |
| tableNamePattern = tableNamePattern.replace("%", "*"); |
| } |
| sql = sql + "." + tableNamePattern; |
| } |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(sql); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| Field[] fields = new Field[8]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", "GRANTOR", "TEXT"); |
| fields[5] = new Field("", "GRANTEE", "TEXT"); |
| fields[6] = new Field("", "PRIVILEGE", "TEXT"); |
| fields[7] = new Field("", "IS_GRANTABLE", "TEXT"); |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT); |
| |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| while (rs.next()) { |
| List<Object> valueInRow = new ArrayList<>(); |
| for (int i = 0; i < fields.length; i++) { |
| if (i < 4) { |
| valueInRow.add(rs.getString(1)); |
| } else if (i == 5) { |
| valueInRow.add(getUserName()); |
| } else if (i == 6) { |
| valueInRow.add(""); |
| } else if (i == 7) { |
| valueInRow.add("NO"); |
| } else { |
| valueInRow.add(""); |
| } |
| } |
| valuesList.add(valueInRow); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error(CONVERT_ERROR_MSG, e.getMessage()); |
| } finally { |
| close(rs, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public ResultSet getTableTypes() throws SQLException { |
| Statement stmt = this.connection.createStatement(); |
| |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<TSDataType> tsDataTypeList = new ArrayList<>(); |
| List<Object> value = new ArrayList<>(); |
| |
| tsDataTypeList.add(TSDataType.TEXT); |
| value.add("table"); |
| columnNameList.add(TABLE_TYPE); |
| columnTypeList.add("TEXT"); |
| columnNameIndex.put(TABLE_TYPE, 0); |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(Collections.singletonList(value), tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error(CONVERT_ERROR_MSG, e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @SuppressWarnings({ |
| "squid:S6541", |
| "squid:S3776", |
| "squid:S2095" |
| }) // ignore Cognitive Complexity of methods should not be too high |
| // ignore Methods should not perform too many tasks (aka Brain method) |
| // ignore Use try-with-resources or close this "Statement" in a "finally" clause |
| @Override |
| public ResultSet getColumns( |
| String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) |
| throws SQLException { |
| Statement stmt = this.connection.createStatement(); |
| |
| if (this.connection.getCatalog().equals(catalog)) { |
| catalog = null; |
| } |
| |
| String sql = "SHOW TIMESERIES"; |
| if (StringUtils.isNotEmpty(catalog)) { |
| if (catalog.contains("%")) { |
| catalog = catalog.replace("%", "*"); |
| } |
| sql = sql + " " + catalog; |
| } else if (StringUtils.isNotEmpty(schemaPattern)) { |
| if (schemaPattern.contains("%")) { |
| schemaPattern = schemaPattern.replace("%", "*"); |
| } |
| sql = sql + " " + schemaPattern; |
| } |
| if ((StringUtils.isNotEmpty(catalog) || StringUtils.isNotEmpty(schemaPattern)) |
| && StringUtils.isNotEmpty(tableNamePattern)) { |
| if (tableNamePattern.contains("%")) { |
| tableNamePattern = tableNamePattern.replace("%", "*"); |
| } |
| sql = sql + "." + tableNamePattern; |
| } |
| |
| if ((StringUtils.isNotEmpty(catalog) || StringUtils.isNotEmpty(schemaPattern)) |
| && StringUtils.isNotEmpty(tableNamePattern) |
| && StringUtils.isNotEmpty(columnNamePattern)) { |
| if (columnNamePattern.contains("%")) { |
| columnNamePattern = columnNamePattern.replace("%", "*"); |
| } |
| sql = sql + "." + columnNamePattern; |
| } |
| |
| if (StringUtils.isEmpty(catalog) |
| && StringUtils.isEmpty(schemaPattern) |
| && StringUtils.isNotEmpty(tableNamePattern)) { |
| sql = sql + " " + tableNamePattern + ".*"; |
| } |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(sql); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| Field[] fields = new Field[24]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[4] = new Field("", DATA_TYPE, INT32); |
| fields[5] = new Field("", TYPE_NAME, "TEXT"); |
| fields[6] = new Field("", COLUMN_SIZE, INT32); |
| fields[7] = new Field("", BUFFER_LENGTH, INT32); |
| fields[8] = new Field("", DECIMAL_DIGITS, INT32); |
| fields[9] = new Field("", NUM_PREC_RADIX, INT32); |
| fields[10] = new Field("", NULLABLE, INT32); |
| fields[11] = new Field("", REMARKS, "TEXT"); |
| fields[12] = new Field("", "COLUMN_DEF", "TEXT"); |
| fields[13] = new Field("", SQL_DATA_TYPE, INT32); |
| fields[14] = new Field("", SQL_DATETIME_SUB, INT32); |
| fields[15] = new Field("", CHAR_OCTET_LENGTH, INT32); |
| fields[16] = new Field("", ORDINAL_POSITION, INT32); |
| fields[17] = new Field("", IS_NULLABLE, "TEXT"); |
| fields[18] = new Field("", "SCOPE_CATALOG", "TEXT"); |
| fields[19] = new Field("", "SCOPE_SCHEMA", "TEXT"); |
| fields[20] = new Field("", "SCOPE_TABLE", "TEXT"); |
| fields[21] = new Field("", "SOURCE_DATA_TYPE", INT32); |
| fields[22] = new Field("", "IS_AUTOINCREMENT", "TEXT"); |
| fields[23] = new Field("", "IS_GENERATEDCOLUMN", "TEXT"); |
| |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.TEXT); |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| while (rs.next()) { |
| List<Object> valuesInRow = new ArrayList<>(); |
| String res = rs.getString(1); |
| String[] splitRes = res.split("\\."); |
| for (int i = 0; i < fields.length; i++) { |
| if (i <= 1) { |
| valuesInRow.add(" "); |
| } else if (i == 2) { |
| valuesInRow.add( |
| res.substring(0, res.length() - splitRes[splitRes.length - 1].length() - 1)); |
| } else if (i == 3) { |
| // column name |
| valuesInRow.add(splitRes[splitRes.length - 1]); |
| } else if (i == 4) { |
| valuesInRow.add(getSQLType(rs.getString(4))); |
| } else if (i == 6) { |
| valuesInRow.add(getTypePrecision(fields[i].getSqlType())); |
| } else if (i == 7) { |
| valuesInRow.add(0); |
| } else if (i == 8) { |
| valuesInRow.add(getTypeScale(fields[i].getSqlType())); |
| } else if (i == 9) { |
| valuesInRow.add(10); |
| } else if (i == 10) { |
| valuesInRow.add(0); |
| } else if (i == 11) { |
| valuesInRow.add(""); |
| } else if (i == 12) { |
| valuesInRow.add(""); |
| } else if (i == 13) { |
| valuesInRow.add(0); |
| } else if (i == 14) { |
| valuesInRow.add(0); |
| } else if (i == 15) { |
| valuesInRow.add(getTypePrecision(fields[i].getSqlType())); |
| } else if (i == 16) { |
| valuesInRow.add(1); |
| } else if (i == 17) { |
| valuesInRow.add("NO"); |
| } else if (i == 18) { |
| valuesInRow.add(""); |
| } else if (i == 19) { |
| valuesInRow.add(""); |
| } else if (i == 20) { |
| valuesInRow.add(""); |
| } else if (i == 21) { |
| valuesInRow.add(0); |
| } else if (i == 22) { |
| valuesInRow.add("NO"); |
| } else if (i == 23) { |
| valuesInRow.add("NO"); |
| } else { |
| valuesInRow.add(""); |
| } |
| } |
| valuesList.add(valuesInRow); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error(CONVERT_ERROR_MSG, e.getMessage()); |
| } finally { |
| close(rs, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| private void close(ResultSet rs, Statement stmt) { |
| |
| try { |
| if (rs != null) { |
| rs.close(); |
| } |
| } catch (Exception ex) { |
| rs = null; |
| } |
| try { |
| if (stmt != null) { |
| stmt.close(); |
| } |
| } catch (Exception ex) { |
| stmt = null; |
| } |
| } |
| |
| public int getTypeScale(String columnType) { |
| switch (columnType.toUpperCase()) { |
| case BOOLEAN: |
| case INT32: |
| case INT64: |
| case "TEXT": |
| return 0; |
| case FLOAT: |
| return 6; |
| case DOUBLE: |
| return 15; |
| default: |
| break; |
| } |
| return 0; |
| } |
| |
| private int getSQLType(String columnType) { |
| switch (columnType.toUpperCase()) { |
| case BOOLEAN: |
| return Types.BOOLEAN; |
| case INT32: |
| return Types.INTEGER; |
| case INT64: |
| return Types.BIGINT; |
| case FLOAT: |
| return Types.FLOAT; |
| case DOUBLE: |
| return Types.DOUBLE; |
| case "TEXT": |
| return Types.LONGVARCHAR; |
| default: |
| break; |
| } |
| return 0; |
| } |
| |
| private int getTypePrecision(String columnType) { |
| // BOOLEAN, INT32, INT64, FLOAT, DOUBLE, TEXT, |
| switch (columnType.toUpperCase()) { |
| case BOOLEAN: |
| return 1; |
| case INT32: |
| return 10; |
| case INT64: |
| return 19; |
| case FLOAT: |
| return 38; |
| case DOUBLE: |
| return 308; |
| case "TEXT": |
| return Integer.MAX_VALUE; |
| default: |
| break; |
| } |
| return 0; |
| } |
| |
| @SuppressWarnings({ |
| "squid:S6541", |
| "squid:S3776", |
| "squid:S2095" |
| }) // ignore Cognitive Complexity of methods should not be too high |
| // ignore Methods should not perform too many tasks (aka Brain method) |
| // ignore Use try-with-resources or close this "Statement" in a "finally" clause |
| @Override |
| public ResultSet getTables( |
| String catalog, String schemaPattern, String tableNamePattern, String[] types) |
| throws SQLException { |
| Statement stmt = this.connection.createStatement(); |
| |
| String sql = "SHOW DEVICES"; |
| String database = ""; |
| if (catalog != null && catalog.length() > 0) { |
| if (catalog.contains("%")) { |
| catalog = catalog.replace("%", "*"); |
| } |
| database = catalog; |
| sql = sql + " " + catalog; |
| } else if (schemaPattern != null && schemaPattern.length() > 0) { |
| if (schemaPattern.contains("%")) { |
| schemaPattern = schemaPattern.replace("%", "*"); |
| } |
| database = schemaPattern; |
| sql = sql + " " + schemaPattern; |
| } |
| if (((catalog != null && catalog.length() > 0) |
| || schemaPattern != null && schemaPattern.length() > 0) |
| && tableNamePattern != null |
| && tableNamePattern.length() > 0) { |
| if (tableNamePattern.contains("%")) { |
| tableNamePattern = tableNamePattern.replace("%", "**"); |
| } |
| sql = sql + "." + tableNamePattern; |
| } |
| ResultSet rs; |
| try { |
| rs = stmt.executeQuery(sql); |
| } catch (SQLException e) { |
| stmt.close(); |
| throw e; |
| } |
| Field[] fields = new Field[10]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", TABLE_TYPE, "TEXT"); |
| fields[4] = new Field("", REMARKS, "TEXT"); |
| fields[5] = new Field("", TYPE_CAT, "TEXT"); |
| fields[6] = new Field("", "TYPE_SCHEM", "TEXT"); |
| fields[7] = new Field("", TYPE_NAME, "TEXT"); |
| fields[8] = new Field("", "SELF_REFERENCING_COL_NAME", "TEXT"); |
| fields[9] = new Field("", "REF_GENERATION", "TEXT"); |
| |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT); |
| |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| List<List<Object>> valuesList = new ArrayList<>(); |
| |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| while (rs.next()) { |
| List<Object> valueInRow = new ArrayList<>(); |
| String res = rs.getString(1); |
| |
| for (int i = 0; i < fields.length; i++) { |
| if (i < 2) { |
| valueInRow.add(""); |
| } else if (i == 2) { |
| int beginIndex = database.length() + 1; |
| if (StringUtils.isEmpty(database)) { |
| beginIndex = 0; |
| } |
| valueInRow.add(res.substring(beginIndex)); |
| } else if (i == 3) { |
| valueInRow.add("TABLE"); |
| } else { |
| valueInRow.add(""); |
| } |
| } |
| valuesList.add(valueInRow); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error(CONVERT_ERROR_MSG, e.getMessage()); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public String getTimeDateFunctions() { |
| return "MAX_TIME,MIN_TIME,TIME_DIFFERENCE,NOW"; |
| } |
| |
| @Override |
| public ResultSet getTypeInfo() throws SQLException { |
| Statement stmt = connection.createStatement(); |
| Field[] fields = new Field[18]; |
| fields[0] = new Field("", TYPE_NAME, "TEXT"); |
| fields[1] = new Field("", DATA_TYPE, INT32); |
| fields[2] = new Field("", PRECISION, INT32); |
| fields[3] = new Field("", "LITERAL_PREFIX", "TEXT"); |
| fields[4] = new Field("", "LITERAL_SUFFIX", "TEXT"); |
| fields[5] = new Field("", "CREATE_PARAMS", "TEXT"); |
| fields[6] = new Field("", NULLABLE, INT32); |
| fields[7] = new Field("", "CASE_SENSITIVE", BOOLEAN); |
| fields[8] = new Field("", "SEARCHABLE", "TEXT"); |
| fields[9] = new Field("", "UNSIGNED_ATTRIBUTE", BOOLEAN); |
| fields[10] = new Field("", "FIXED_PREC_SCALE", BOOLEAN); |
| fields[11] = new Field("", "AUTO_INCREMENT", BOOLEAN); |
| fields[12] = new Field("", "LOCAL_TYPE_NAME", "TEXT"); |
| fields[13] = new Field("", "MINIMUM_SCALE", INT32); |
| fields[14] = new Field("", "MAXIMUM_SCALE", INT32); |
| fields[15] = new Field("", SQL_DATA_TYPE, INT32); |
| fields[16] = new Field("", SQL_DATETIME_SUB, INT32); |
| fields[17] = new Field("", NUM_PREC_RADIX, INT32); |
| List<TSDataType> tsDataTypeList = |
| Arrays.asList( |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.BOOLEAN, |
| TSDataType.TEXT, |
| TSDataType.BOOLEAN, |
| TSDataType.BOOLEAN, |
| TSDataType.BOOLEAN, |
| TSDataType.TEXT, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32, |
| TSDataType.INT32); |
| List<Object> listValSub1 = |
| Arrays.asList( |
| INT32, |
| Types.INTEGER, |
| 10, |
| "", |
| "", |
| "", |
| 1, |
| true, |
| "", |
| false, |
| true, |
| false, |
| "", |
| 0, |
| 10, |
| 0, |
| 0, |
| 10); |
| List<Object> listValSub2 = |
| Arrays.asList( |
| INT64, |
| Types.BIGINT, |
| 19, |
| "", |
| "", |
| "", |
| 1, |
| true, |
| "", |
| false, |
| true, |
| false, |
| "", |
| 0, |
| 10, |
| 0, |
| 0, |
| 10); |
| List<Object> listValSub3 = |
| Arrays.asList( |
| BOOLEAN, |
| Types.BOOLEAN, |
| 1, |
| "", |
| "", |
| "", |
| 1, |
| true, |
| "", |
| false, |
| true, |
| false, |
| "", |
| 0, |
| 10, |
| 0, |
| 0, |
| 10); |
| List<Object> listValSub4 = |
| Arrays.asList( |
| FLOAT, |
| Types.FLOAT, |
| 38, |
| "", |
| "", |
| "", |
| 1, |
| true, |
| "", |
| false, |
| true, |
| false, |
| "", |
| 0, |
| 10, |
| 0, |
| 0, |
| 10); |
| List<Object> listValSub5 = |
| Arrays.asList( |
| DOUBLE, |
| Types.DOUBLE, |
| 308, |
| "", |
| "", |
| "", |
| 1, |
| true, |
| "", |
| false, |
| true, |
| false, |
| "", |
| 0, |
| 10, |
| 0, |
| 0, |
| 10); |
| List<Object> listValSub6 = |
| Arrays.asList( |
| "TEXT", |
| Types.LONGVARCHAR, |
| 64, |
| "", |
| "", |
| "", |
| 1, |
| true, |
| "", |
| false, |
| true, |
| false, |
| "", |
| 0, |
| 10, |
| 0, |
| 0, |
| 10); |
| List<List<Object>> valuesList = |
| Arrays.asList(listValSub1, listValSub2, listValSub3, listValSub4, listValSub5, listValSub6); |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| |
| ByteBuffer tsBlock = null; |
| try { |
| tsBlock = convertTsBlock(valuesList, tsDataTypeList); |
| } catch (IOException e) { |
| LOGGER.error(CONVERT_ERROR_MSG, e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| true, |
| client, |
| null, |
| -1, |
| sessionId, |
| Collections.singletonList(tsBlock), |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public ResultSet getUDTs( |
| String catalog, String schemaPattern, String typeNamePattern, int[] types) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[7]; |
| fields[0] = new Field("", TABLE_CAT, "TEXT"); |
| fields[1] = new Field("", TABLE_SCHEM, "TEXT"); |
| fields[2] = new Field("", TABLE_NAME, "TEXT"); |
| fields[3] = new Field("", "CLASS_NAME", "TEXT"); |
| fields[4] = new Field("", DATA_TYPE, INT32); |
| fields[5] = new Field("", REMARKS, "TEXT"); |
| fields[6] = new Field("", "BASE_TYPE", "TEXT"); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get UDTS error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public String getURL() { |
| // TODO: Return the URL for this DBMS or null if it cannot be generated |
| return this.connection.getUrl(); |
| } |
| |
| @Override |
| public String getUserName() throws SQLException { |
| return connection.getUserName(); |
| } |
| |
| @Override |
| public ResultSet getVersionColumns(String catalog, String schema, String table) |
| throws SQLException { |
| List<String> columnNameList = new ArrayList<>(); |
| List<String> columnTypeList = new ArrayList<>(); |
| Map<String, Integer> columnNameIndex = new HashMap<>(); |
| Statement stmt = connection.createStatement(); |
| try { |
| Field[] fields = new Field[8]; |
| fields[0] = new Field("", "SCOPE", INT32); |
| fields[1] = new Field("", COLUMN_NAME, "TEXT"); |
| fields[2] = new Field("", DATA_TYPE, INT32); |
| fields[3] = new Field("", TYPE_NAME, "TEXT"); |
| fields[4] = new Field("", COLUMN_SIZE, INT32); |
| fields[5] = new Field("", BUFFER_LENGTH, INT32); |
| fields[6] = new Field("", DECIMAL_DIGITS, INT32); |
| fields[7] = new Field("", "PSEUDO_COLUMN", INT32); |
| for (int i = 0; i < fields.length; i++) { |
| columnNameList.add(fields[i].getName()); |
| columnTypeList.add(fields[i].getSqlType()); |
| columnNameIndex.put(fields[i].getName(), i); |
| } |
| } catch (Exception e) { |
| LOGGER.error("get version columns error: {}", e.getMessage()); |
| } finally { |
| close(null, stmt); |
| } |
| return new IoTDBJDBCResultSet( |
| stmt, |
| columnNameList, |
| columnTypeList, |
| columnNameIndex, |
| false, |
| client, |
| null, |
| -1, |
| sessionId, |
| null, |
| null, |
| (long) 60 * 1000, |
| false); |
| } |
| |
| @Override |
| public boolean insertsAreDetected(int type) { |
| return false; |
| } |
| |
| @Override |
| public boolean isCatalogAtStart() { |
| return false; |
| } |
| |
| @Override |
| public boolean isReadOnly() throws SQLException { |
| try { |
| return client.getProperties().isReadOnly; |
| } catch (TException e) { |
| LOGGER.error("get is readOnly error: {}", e.getMessage()); |
| } |
| throw new SQLException("Can not get the read-only mode"); |
| } |
| |
| @Override |
| public boolean locatorsUpdateCopy() { |
| return false; |
| } |
| |
| @Override |
| public boolean nullPlusNonNullIsNull() { |
| return false; |
| } |
| |
| @Override |
| public boolean nullsAreSortedAtEnd() { |
| return false; |
| } |
| |
| @Override |
| public boolean nullsAreSortedAtStart() { |
| return false; |
| } |
| |
| @Override |
| public boolean nullsAreSortedHigh() { |
| return false; |
| } |
| |
| @Override |
| public boolean nullsAreSortedLow() { |
| return false; |
| } |
| |
| @Override |
| public boolean othersDeletesAreVisible(int type) { |
| return true; |
| } |
| |
| @Override |
| public boolean othersInsertsAreVisible(int type) { |
| return true; |
| } |
| |
| @Override |
| public boolean othersUpdatesAreVisible(int type) { |
| return true; |
| } |
| |
| @Override |
| public boolean ownDeletesAreVisible(int type) { |
| return true; |
| } |
| |
| @Override |
| public boolean ownInsertsAreVisible(int type) { |
| return true; |
| } |
| |
| @Override |
| public boolean ownUpdatesAreVisible(int type) { |
| return true; |
| } |
| |
| @Override |
| public boolean storesLowerCaseIdentifiers() { |
| return false; |
| } |
| |
| @Override |
| public boolean storesLowerCaseQuotedIdentifiers() { |
| return false; |
| } |
| |
| @Override |
| public boolean storesMixedCaseIdentifiers() { |
| return true; |
| } |
| |
| @Override |
| public boolean storesMixedCaseQuotedIdentifiers() { |
| return true; |
| } |
| |
| @Override |
| public boolean storesUpperCaseIdentifiers() { |
| return false; |
| } |
| |
| @Override |
| public boolean storesUpperCaseQuotedIdentifiers() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsANSI92EntryLevelSQL() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsANSI92FullSQL() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsANSI92IntermediateSQL() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsAlterTableWithAddColumn() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsAlterTableWithDropColumn() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsBatchUpdates() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsCatalogsInDataManipulation() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsCatalogsInIndexDefinitions() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsCatalogsInPrivilegeDefinitions() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsCatalogsInProcedureCalls() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsCatalogsInTableDefinitions() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsColumnAliasing() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsConvert() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsConvert(int fromType, int toType) { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsCoreSQLGrammar() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsCorrelatedSubqueries() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsDataDefinitionAndDataManipulationTransactions() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsDataManipulationTransactionsOnly() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsDifferentTableCorrelationNames() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsExpressionsInOrderBy() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsExtendedSQLGrammar() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsFullOuterJoins() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsGetGeneratedKeys() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsGroupBy() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsGroupByBeyondSelect() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsGroupByUnrelated() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsIntegrityEnhancementFacility() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsLikeEscapeClause() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsLimitedOuterJoins() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsMinimumSQLGrammar() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsMixedCaseIdentifiers() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsMixedCaseQuotedIdentifiers() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsMultipleOpenResults() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsMultipleResultSets() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsMultipleTransactions() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsNamedParameters() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsNonNullableColumns() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsOpenCursorsAcrossCommit() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsOpenCursorsAcrossRollback() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsOpenStatementsAcrossCommit() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsOpenStatementsAcrossRollback() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsOrderByUnrelated() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsOuterJoins() { |
| return true; |
| } |
| |
| @Override |
| public boolean supportsPositionedDelete() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsPositionedUpdate() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsResultSetConcurrency(int type, int concurrency) { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsResultSetHoldability(int holdability) { |
| return ResultSet.HOLD_CURSORS_OVER_COMMIT == holdability; |
| } |
| |
| @Override |
| public boolean supportsResultSetType(int type) throws SQLException { |
| return ResultSet.FETCH_FORWARD == type || ResultSet.TYPE_FORWARD_ONLY == type; |
| } |
| |
| @Override |
| public boolean supportsSavepoints() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSchemasInDataManipulation() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSchemasInIndexDefinitions() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSchemasInPrivilegeDefinitions() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSchemasInProcedureCalls() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSchemasInTableDefinitions() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSelectForUpdate() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsStatementPooling() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsStoredFunctionsUsingCallSyntax() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsStoredProcedures() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSubqueriesInComparisons() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSubqueriesInExists() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSubqueriesInIns() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsSubqueriesInQuantifieds() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsTableCorrelationNames() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsTransactionIsolationLevel(int level) { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsTransactions() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsUnion() { |
| return false; |
| } |
| |
| @Override |
| public boolean supportsUnionAll() { |
| return false; |
| } |
| |
| @Override |
| public boolean updatesAreDetected(int type) { |
| return false; |
| } |
| |
| @Override |
| public boolean usesLocalFilePerTable() { |
| return false; |
| } |
| |
| @Override |
| public boolean usesLocalFiles() { |
| return false; |
| } |
| |
| /** @deprecated recommend using getMetadataInJson() instead of toString() */ |
| @SuppressWarnings("squid:S1133") // ignore Deprecated code should be removed |
| @Deprecated |
| @Override |
| public String toString() { |
| try { |
| return getMetadataInJsonFunc(); |
| } catch (IoTDBSQLException e) { |
| LOGGER.error("Failed to fetch metadata in json because: ", e); |
| } catch (TException e) { |
| boolean flag = connection.reconnect(); |
| this.client = connection.getClient(); |
| if (flag) { |
| try { |
| return getMetadataInJsonFunc(); |
| } catch (TException e2) { |
| LOGGER.error( |
| "Fail to get all timeseries " |
| + "info after reconnecting." |
| + " please check server status", |
| e2); |
| } catch (IoTDBSQLException e1) { |
| // ignored |
| } |
| } else { |
| LOGGER.error( |
| "Fail to reconnect to server " |
| + "when getting all timeseries info. please check server status"); |
| } |
| } |
| return ""; |
| } |
| |
| /* |
| * recommend using getMetadataInJson() instead of toString() |
| */ |
| public String getMetadataInJson() throws SQLException { |
| try { |
| return getMetadataInJsonFunc(); |
| } catch (TException e) { |
| boolean flag = connection.reconnect(); |
| this.client = connection.getClient(); |
| if (flag) { |
| try { |
| return getMetadataInJsonFunc(); |
| } catch (TException e2) { |
| throw new SQLException( |
| "Failed to fetch all metadata in json " |
| + "after reconnecting. Please check the server status."); |
| } |
| } else { |
| throw new SQLException( |
| "Failed to reconnect to the server " |
| + "when fetching all metadata in json. Please check the server status."); |
| } |
| } |
| } |
| |
| private String getMetadataInJsonFunc() throws TException, IoTDBSQLException { |
| TSFetchMetadataReq req = new TSFetchMetadataReq(sessionId, "METADATA_IN_JSON"); |
| TSFetchMetadataResp resp = client.fetchMetadata(req); |
| try { |
| RpcUtils.verifySuccess(resp.getStatus()); |
| } catch (StatementExecutionException e) { |
| throw new IoTDBSQLException(e.getMessage(), resp.getStatus()); |
| } |
| return resp.getMetadataInJson(); |
| } |
| } |