endpoints = new ArrayList<>();
- try (BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) {
- String line = null;
- while ((line = reader.readLine()) != null) {
- if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")) {
- endpoints.add(line.substring(line.indexOf('p') + 1).trim());
- }
- if (endpoints.size() > 1)
- break;
- }
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- return endpoints;
- }
-
- /**
- * @param cfgDirPath
- * @return return the config dir
- **/
- private File loadConfigDir(String cfgDirPath) {
- if (cfgDirPath == null)
- return loadDefaultConfigDir();
- File cfgDir = new File(cfgDirPath);
- if (!cfgDir.exists())
- return loadDefaultConfigDir();
- return cfgDir;
- }
-
- /**
- * @return search the default config dir, if the config dir is not exist will return null
- */
- private File loadDefaultConfigDir() {
- File cfgDir;
- File cfgDir_linux = new File("/etc/taos");
- cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null;
- File cfgDir_windows = new File("C:\\TDengine\\cfg");
- cfgDir = (cfgDir == null && cfgDir_windows.exists()) ? cfgDir_windows : cfgDir;
- return cfgDir;
- }
-
private void connect(String host, int port, String dbName, String user, String password) throws SQLException {
this.connector = new TSDBJNIConnector();
this.connector.connect(host, port, dbName, user, password);
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 804e09c6b349ca7c957447b9f1fdf1766f18b3d1..15f66fa2029e7c1bf8a3ecf8ec68b53a8455c648 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
@@ -68,15 +68,15 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public boolean nullsAreSortedLow() throws SQLException {
- return false;
+ return !nullsAreSortedHigh();
}
public boolean nullsAreSortedAtStart() throws SQLException {
- return false;
+ return true;
}
public boolean nullsAreSortedAtEnd() throws SQLException {
- return false;
+ return !nullsAreSortedAtStart();
}
public String getDatabaseProductName() throws SQLException {
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 e25bd64c73c01709ba34fafbdde7769aae78e6c9..bc649a31e1e4c56289284885a73469695ae4eae2 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
@@ -14,24 +14,29 @@
*****************************************************************************/
package com.taosdata.jdbc;
+
+import java.io.*;
+
import java.sql.*;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;
/**
* The Java SQL framework allows for multiple database drivers. Each driver
* should supply a class that implements the Driver interface
- *
+ *
*
* The DriverManager will try to load as many drivers as it can find and then
* for any given connection request, it will ask each driver in turn to try to
* connect to the target URL.
- *
+ *
*
* It is strongly recommended that each Driver class should be small and stand
* alone so that the Driver class can be loaded and queried without bringing in
* vast quantities of supporting code.
- *
+ *
*
* When a Driver class is loaded, it should create an instance of itself and
* register it with the DriverManager. This means that a user can load and
@@ -39,38 +44,41 @@ import java.util.logging.Logger;
*/
public class TSDBDriver implements java.sql.Driver {
- @Deprecated
- private static final String URL_PREFIX1 = "jdbc:tsdb://";
- private static final String URL_PREFIX = "jdbc:taos://";
-
- /**
- * Key used to retrieve the database value from the properties instance passed
- * to the driver.
- */
- public static final String PROPERTY_KEY_DBNAME = "dbname";
-
- /**
- * Key used to retrieve the host value from the properties instance passed to
- * the driver.
- */
- public static final String PROPERTY_KEY_HOST = "host";
- /**
- * Key used to retrieve the password value from the properties instance passed
- * to the driver.
- */
- public static final String PROPERTY_KEY_PASSWORD = "password";
-
- /**
- * Key used to retrieve the port number value from the properties instance
- * passed to the driver.
- */
- public static final String PROPERTY_KEY_PORT = "port";
-
- /**
- * Key used to retrieve the user value from the properties instance passed to
- * the driver.
- */
- public static final String PROPERTY_KEY_USER = "user";
+
+ @Deprecated
+ private static final String URL_PREFIX1 = "jdbc:TSDB://";
+
+ private static final String URL_PREFIX = "jdbc:TAOS://";
+
+ /**
+ * Key used to retrieve the database value from the properties instance passed
+ * to the driver.
+ */
+ public static final String PROPERTY_KEY_DBNAME = "dbname";
+
+ /**
+ * Key used to retrieve the host value from the properties instance passed to
+ * the driver.
+ */
+ public static final String PROPERTY_KEY_HOST = "host";
+ /**
+ * Key used to retrieve the password value from the properties instance passed
+ * to the driver.
+ */
+ public static final String PROPERTY_KEY_PASSWORD = "password";
+
+ /**
+ * Key used to retrieve the port number value from the properties instance
+ * passed to the driver.
+ */
+ public static final String PROPERTY_KEY_PORT = "port";
+
+ /**
+ * Key used to retrieve the user value from the properties instance passed to
+ * the driver.
+ */
+ public static final String PROPERTY_KEY_USER = "user";
+
/**
* Key for the configuration file directory of TSDB client in properties instance
@@ -95,278 +103,320 @@ public class TSDBDriver implements java.sql.Driver {
public static final String PROPERTY_KEY_PROTOCOL = "protocol";
- /**
- * Index for port coming out of parseHostPortPair().
- */
- public final static int PORT_NUMBER_INDEX = 1;
-
- /**
- * Index for host coming out of parseHostPortPair().
- */
- public final static int HOST_NAME_INDEX = 0;
-
- private TSDBDatabaseMetaData dbMetaData = null;
-
- static {
- try {
- java.sql.DriverManager.registerDriver(new TSDBDriver());
- } catch (SQLException E) {
- throw new RuntimeException(TSDBConstants.WrapErrMsg("can't register tdengine jdbc driver!"));
- }
- }
-
- public Connection connect(String url, Properties info) throws SQLException {
- if (url == null) {
- throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!"));
- }
-
- Properties props = null;
-
- if ((props = parseURL(url, info)) == null) {
- return null;
- }
-
- try {
- TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE), (String) props.get(PROPERTY_KEY_CHARSET),
- (String) props.get(PROPERTY_KEY_TIME_ZONE));
- Connection newConn = new TSDBConnection(props, this.dbMetaData);
- return newConn;
- } catch (SQLWarning sqlWarning) {
- sqlWarning.printStackTrace();
- Connection newConn = new TSDBConnection(props, this.dbMetaData);
- return newConn;
- } catch (SQLException sqlEx) {
- throw sqlEx;
- } catch (Exception ex) {
- SQLException sqlEx = new SQLException("SQLException:" + ex.toString());
- sqlEx.initCause(ex);
- throw sqlEx;
- }
- }
-
- /**
- * Parses hostPortPair in the form of [host][:port] into an array, with the
- * element of index HOST_NAME_INDEX being the host (or null if not specified),
- * and the element of index PORT_NUMBER_INDEX being the port (or null if not
- * specified).
- *
- * @param hostPortPair
- * host and port in form of of [host][:port]
- *
- * @return array containing host and port as Strings
- *
- * @throws SQLException
- * if a parse error occurs
- */
- protected static String[] parseHostPortPair(String hostPortPair) throws SQLException {
- String[] splitValues = new String[2];
-
- int portIndex = hostPortPair.indexOf(":");
-
- String hostname = null;
-
- if (portIndex != -1) {
- if ((portIndex + 1) < hostPortPair.length()) {
- String portAsString = hostPortPair.substring(portIndex + 1);
- hostname = hostPortPair.substring(0, portIndex);
-
- splitValues[HOST_NAME_INDEX] = hostname;
-
- splitValues[PORT_NUMBER_INDEX] = portAsString;
- } else {
- throw new SQLException(TSDBConstants.WrapErrMsg("port is not proper!"));
- }
- } else {
- splitValues[HOST_NAME_INDEX] = hostPortPair;
- splitValues[PORT_NUMBER_INDEX] = null;
- }
-
- return splitValues;
- }
-
- public boolean acceptsURL(String url) throws SQLException {
- return (url != null && url.length() > 0 && url.trim().length() > 0) && url.toLowerCase().startsWith(URL_PREFIX);
- }
-
- public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
- if (info == null) {
- info = new Properties();
- }
-
- if ((url != null) && (url.startsWith(URL_PREFIX) || url.startsWith(URL_PREFIX1))) {
- info = parseURL(url, info);
- }
-
- DriverPropertyInfo hostProp = new DriverPropertyInfo(PROPERTY_KEY_HOST, info.getProperty(PROPERTY_KEY_HOST));
- hostProp.required = true;
-
- DriverPropertyInfo portProp = new DriverPropertyInfo(PROPERTY_KEY_PORT,
- info.getProperty(PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
- portProp.required = false;
-
- DriverPropertyInfo dbProp = new DriverPropertyInfo(PROPERTY_KEY_DBNAME, info.getProperty(PROPERTY_KEY_DBNAME));
- dbProp.required = false;
- dbProp.description = "Database name";
-
- DriverPropertyInfo userProp = new DriverPropertyInfo(PROPERTY_KEY_USER, info.getProperty(PROPERTY_KEY_USER));
- userProp.required = true;
-
- DriverPropertyInfo passwordProp = new DriverPropertyInfo(PROPERTY_KEY_PASSWORD,
- info.getProperty(PROPERTY_KEY_PASSWORD));
- passwordProp.required = true;
-
- DriverPropertyInfo[] propertyInfo = new DriverPropertyInfo[5];
- propertyInfo[0] = hostProp;
- propertyInfo[1] = portProp;
- propertyInfo[2] = dbProp;
- propertyInfo[3] = userProp;
- propertyInfo[4] = passwordProp;
-
- return propertyInfo;
- }
-
- /**
- * example: jdbc:TSDB://127.0.0.1:0/db?user=root&password=your_password
- */
-
- public Properties parseURL(String url, Properties defaults) throws java.sql.SQLException {
- Properties urlProps = (defaults != null) ? defaults : new Properties();
- if (url == null) {
- return null;
- }
+
+ /**
+ * Index for port coming out of parseHostPortPair().
+ */
+ public final static int PORT_NUMBER_INDEX = 1;
+
+ /**
+ * Index for host coming out of parseHostPortPair().
+ */
+ public final static int HOST_NAME_INDEX = 0;
+
+ private TSDBDatabaseMetaData dbMetaData = null;
+
+ static {
+ try {
+ java.sql.DriverManager.registerDriver(new TSDBDriver());
+ } catch (SQLException E) {
+ throw new RuntimeException(TSDBConstants.WrapErrMsg("can't register tdengine jdbc driver!"));
+ }
+ }
+
+ private List loadConfigEndpoints(File cfgFile) {
+ List endpoints = new ArrayList<>();
+ try (BufferedReader reader = new BufferedReader(new FileReader(cfgFile))) {
+ String line = null;
+ while ((line = reader.readLine()) != null) {
+ if (line.trim().startsWith("firstEp") || line.trim().startsWith("secondEp")) {
+ endpoints.add(line.substring(line.indexOf('p') + 1).trim());
+ }
+ if (endpoints.size() > 1)
+ break;
+ }
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return endpoints;
+ }
+
+ /**
+ * @param cfgDirPath
+ * @return return the config dir
+ **/
+ private File loadConfigDir(String cfgDirPath) {
+ if (cfgDirPath == null)
+ return loadDefaultConfigDir();
+ File cfgDir = new File(cfgDirPath);
+ if (!cfgDir.exists())
+ return loadDefaultConfigDir();
+ return cfgDir;
+ }
+
+ /**
+ * @return search the default config dir, if the config dir is not exist will return null
+ */
+ private File loadDefaultConfigDir() {
+ File cfgDir;
+ File cfgDir_linux = new File("/etc/taos");
+ cfgDir = cfgDir_linux.exists() ? cfgDir_linux : null;
+ File cfgDir_windows = new File("C:\\TDengine\\cfg");
+ cfgDir = (cfgDir == null && cfgDir_windows.exists()) ? cfgDir_windows : cfgDir;
+ return cfgDir;
+ }
+
+ public Connection connect(String url, Properties info) throws SQLException {
+ if (url == null) {
+ throw new SQLException(TSDBConstants.WrapErrMsg("url is not set!"));
+ }
+
+ Properties props = null;
+ if ((props = parseURL(url, info)) == null) {
+ return null;
+ }
+
+ //load taos.cfg start
+ if (info.getProperty(TSDBDriver.PROPERTY_KEY_HOST) == null && info.getProperty(TSDBDriver.PROPERTY_KEY_PORT) == null){
+ File cfgDir = loadConfigDir(info.getProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR));
+ File cfgFile = cfgDir.listFiles((dir, name) -> "taos.cfg".equalsIgnoreCase(name))[0];
+ List endpoints = loadConfigEndpoints(cfgFile);
+ if (!endpoints.isEmpty()) {
+ info.setProperty(TSDBDriver.PROPERTY_KEY_HOST, endpoints.get(0).split(":")[0]);
+ info.setProperty(TSDBDriver.PROPERTY_KEY_PORT, endpoints.get(0).split(":")[1]);
+ }
+ }
+
+ try {
+ TSDBJNIConnector.init((String) props.get(PROPERTY_KEY_CONFIG_DIR), (String) props.get(PROPERTY_KEY_LOCALE), (String) props.get(PROPERTY_KEY_CHARSET),
+ (String) props.get(PROPERTY_KEY_TIME_ZONE));
+ Connection newConn = new TSDBConnection(props, this.dbMetaData);
+ return newConn;
+ } catch (SQLWarning sqlWarning) {
+ sqlWarning.printStackTrace();
+ Connection newConn = new TSDBConnection(props, this.dbMetaData);
+ return newConn;
+ } catch (SQLException sqlEx) {
+ throw sqlEx;
+ } catch (Exception ex) {
+ SQLException sqlEx = new SQLException("SQLException:" + ex.toString());
+ sqlEx.initCause(ex);
+ throw sqlEx;
+ }
+ }
+
+ /**
+ * Parses hostPortPair in the form of [host][:port] into an array, with the
+ * element of index HOST_NAME_INDEX being the host (or null if not specified),
+ * and the element of index PORT_NUMBER_INDEX being the port (or null if not
+ * specified).
+ *
+ * @param hostPortPair host and port in form of of [host][:port]
+ * @return array containing host and port as Strings
+ * @throws SQLException if a parse error occurs
+ */
+ protected static String[] parseHostPortPair(String hostPortPair) throws SQLException {
+ String[] splitValues = new String[2];
+
+ int portIndex = hostPortPair.indexOf(":");
+
+ String hostname = null;
+
+ if (portIndex != -1) {
+ if ((portIndex + 1) < hostPortPair.length()) {
+ String portAsString = hostPortPair.substring(portIndex + 1);
+ hostname = hostPortPair.substring(0, portIndex);
+
+ splitValues[HOST_NAME_INDEX] = hostname;
+
+ splitValues[PORT_NUMBER_INDEX] = portAsString;
+ } else {
+ throw new SQLException(TSDBConstants.WrapErrMsg("port is not proper!"));
+ }
+ } else {
+ splitValues[HOST_NAME_INDEX] = hostPortPair;
+ splitValues[PORT_NUMBER_INDEX] = null;
+ }
+
+ return splitValues;
+ }
+
+ public boolean acceptsURL(String url) throws SQLException {
+ return (url != null && url.length() > 0 && url.trim().length() > 0) && url.toLowerCase().startsWith(URL_PREFIX);
+ }
+
+ public DriverPropertyInfo[] getPropertyInfo(String url, Properties info) throws SQLException {
+ if (info == null) {
+ info = new Properties();
+ }
+
+ if ((url != null) && (url.startsWith(URL_PREFIX) || url.startsWith(URL_PREFIX1))) {
+ info = parseURL(url, info);
+ }
+
+ DriverPropertyInfo hostProp = new DriverPropertyInfo(PROPERTY_KEY_HOST, info.getProperty(PROPERTY_KEY_HOST));
+ hostProp.required = true;
+
+ DriverPropertyInfo portProp = new DriverPropertyInfo(PROPERTY_KEY_PORT, info.getProperty(PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
+ portProp.required = false;
+
+ DriverPropertyInfo dbProp = new DriverPropertyInfo(PROPERTY_KEY_DBNAME, info.getProperty(PROPERTY_KEY_DBNAME));
+ dbProp.required = false;
+ dbProp.description = "Database name";
+
+ DriverPropertyInfo userProp = new DriverPropertyInfo(PROPERTY_KEY_USER, info.getProperty(PROPERTY_KEY_USER));
+ userProp.required = true;
+
+ DriverPropertyInfo passwordProp = new DriverPropertyInfo(PROPERTY_KEY_PASSWORD, info.getProperty(PROPERTY_KEY_PASSWORD));
+ passwordProp.required = true;
+
+ DriverPropertyInfo[] propertyInfo = new DriverPropertyInfo[5];
+ propertyInfo[0] = hostProp;
+ propertyInfo[1] = portProp;
+ propertyInfo[2] = dbProp;
+ propertyInfo[3] = userProp;
+ propertyInfo[4] = passwordProp;
+
+ return propertyInfo;
+ }
+
+ /**
+ * example: jdbc:TSDB://127.0.0.1:0/db?user=root&password=your_password
+ */
+ public Properties parseURL(String url, Properties defaults) throws java.sql.SQLException {
+ Properties urlProps = (defaults != null) ? defaults : new Properties();
+ if (url == null) {
+ return null;
+ }
String lowerUrl = url.toLowerCase();
if (!lowerUrl.startsWith(URL_PREFIX) && !lowerUrl.startsWith(URL_PREFIX1)) {
- return null;
- }
-
- String urlForMeta = url;
-
- String dbProductName = url.substring(url.indexOf(":") + 1);
- dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
- int beginningOfSlashes = url.indexOf("//");
- url = url.substring(beginningOfSlashes + 2);
-
- String host = url.substring(0, url.indexOf(":"));
- url = url.substring(url.indexOf(":") + 1);
- urlProps.setProperty(PROPERTY_KEY_HOST, host);
-
- String port = url.substring(0, url.indexOf("/"));
- urlProps.setProperty(PROPERTY_KEY_PORT, port);
- url = url.substring(url.indexOf("/") + 1);
-
- if (url.indexOf("?") != -1) {
- String dbName = url.substring(0, url.indexOf("?"));
- urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName);
- url = url.trim().substring(url.indexOf("?") + 1);
- } else {
- // without user & password so return
- if(!url.trim().isEmpty()) {
- String dbName = url.trim();
- urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName);
- }
- this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, urlProps.getProperty("user"));
- return urlProps;
- }
-
- String user = "";
-
- if (url.indexOf("&") == -1) {
- String[] kvPair = url.trim().split("=");
- if (kvPair.length == 2) {
- setPropertyValue(urlProps, kvPair);
- return urlProps;
- }
- }
-
- String[] queryStrings = url.trim().split("&");
- for (String queryStr : queryStrings) {
- String[] kvPair = queryStr.trim().split("=");
- if (kvPair.length < 2){
- continue;
- }
- setPropertyValue(urlProps, kvPair);
- }
-
- user = urlProps.getProperty(PROPERTY_KEY_USER).toString();
- this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, user);
-
- return urlProps;
- }
-
- public void setPropertyValue(Properties property, String[] keyValuePair) {
- switch (keyValuePair[0].toLowerCase()) {
- case PROPERTY_KEY_USER:
- property.setProperty(PROPERTY_KEY_USER, keyValuePair[1]);
- break;
- case PROPERTY_KEY_PASSWORD:
- property.setProperty(PROPERTY_KEY_PASSWORD, keyValuePair[1]);
- break;
- case PROPERTY_KEY_TIME_ZONE:
- property.setProperty(PROPERTY_KEY_TIME_ZONE, keyValuePair[1]);
- break;
- case PROPERTY_KEY_LOCALE:
- property.setProperty(PROPERTY_KEY_LOCALE, keyValuePair[1]);
- break;
- case PROPERTY_KEY_CHARSET:
- property.setProperty(PROPERTY_KEY_CHARSET, keyValuePair[1]);
- break;
- case PROPERTY_KEY_CONFIG_DIR:
- property.setProperty(PROPERTY_KEY_CONFIG_DIR, keyValuePair[1]);
- break;
- }
- }
-
-
- public int getMajorVersion() {
- return 1;
- }
-
- public int getMinorVersion() {
- return 1;
- }
-
- public boolean jdbcCompliant() {
- return false;
- }
-
- public Logger getParentLogger() throws SQLFeatureNotSupportedException {
- return null;
- }
-
- /**
- * Returns the host property
- *
- * @param props
- * the java.util.Properties instance to retrieve the hostname from.
- *
- * @return the host
- */
- public String host(Properties props) {
- return props.getProperty(PROPERTY_KEY_HOST, "localhost");
- }
-
- /**
- * Returns the port number property
- *
- * @param props
- * the properties to get the port number from
- *
- * @return the port number
- */
- public int port(Properties props) {
- return Integer.parseInt(props.getProperty(PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
- }
-
- /**
- * Returns the database property from props
- *
- * @param props
- * the Properties to look for the database property.
- *
- * @return the database name.
- */
- public String database(Properties props) {
- return props.getProperty(PROPERTY_KEY_DBNAME);
- }
+ return null;
+ }
+
+ String urlForMeta = url;
+
+ String dbProductName = url.substring(url.indexOf(":") + 1);
+ dbProductName = dbProductName.substring(0, dbProductName.indexOf(":"));
+ int beginningOfSlashes = url.indexOf("//");
+ url = url.substring(beginningOfSlashes + 2);
+
+ String host = url.substring(0, url.indexOf(":"));
+ url = url.substring(url.indexOf(":") + 1);
+ urlProps.setProperty(PROPERTY_KEY_HOST, host);
+
+ String port = url.substring(0, url.indexOf("/"));
+ urlProps.setProperty(PROPERTY_KEY_PORT, port);
+ url = url.substring(url.indexOf("/") + 1);
+
+ if (url.indexOf("?") != -1) {
+ String dbName = url.substring(0, url.indexOf("?"));
+ urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName);
+ url = url.trim().substring(url.indexOf("?") + 1);
+ } else {
+ // without user & password so return
+ if (!url.trim().isEmpty()) {
+ String dbName = url.trim();
+ urlProps.setProperty(PROPERTY_KEY_DBNAME, dbName);
+ }
+ this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, urlProps.getProperty("user"));
+ return urlProps;
+ }
+
+ String user = "";
+
+ if (url.indexOf("&") == -1) {
+ String[] kvPair = url.trim().split("=");
+ if (kvPair.length == 2) {
+ setPropertyValue(urlProps, kvPair);
+ return urlProps;
+ }
+ }
+
+ String[] queryStrings = url.trim().split("&");
+ for (String queryStr : queryStrings) {
+ String[] kvPair = queryStr.trim().split("=");
+ if (kvPair.length < 2) {
+ continue;
+ }
+ setPropertyValue(urlProps, kvPair);
+ }
+
+ user = urlProps.getProperty(PROPERTY_KEY_USER).toString();
+ this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, user);
+
+ return urlProps;
+ }
+
+ public void setPropertyValue(Properties property, String[] keyValuePair) {
+ switch (keyValuePair[0].toLowerCase()) {
+ case PROPERTY_KEY_USER:
+ property.setProperty(PROPERTY_KEY_USER, keyValuePair[1]);
+ break;
+ case PROPERTY_KEY_PASSWORD:
+ property.setProperty(PROPERTY_KEY_PASSWORD, keyValuePair[1]);
+ break;
+ case PROPERTY_KEY_TIME_ZONE:
+ property.setProperty(PROPERTY_KEY_TIME_ZONE, keyValuePair[1]);
+ break;
+ case PROPERTY_KEY_LOCALE:
+ property.setProperty(PROPERTY_KEY_LOCALE, keyValuePair[1]);
+ break;
+ case PROPERTY_KEY_CHARSET:
+ property.setProperty(PROPERTY_KEY_CHARSET, keyValuePair[1]);
+ break;
+ case PROPERTY_KEY_CONFIG_DIR:
+ property.setProperty(PROPERTY_KEY_CONFIG_DIR, keyValuePair[1]);
+ break;
+ }
+ }
+
+
+ public int getMajorVersion() {
+ return 1;
+ }
+
+ public int getMinorVersion() {
+ return 1;
+ }
+
+ public boolean jdbcCompliant() {
+ return false;
+ }
+
+ public Logger getParentLogger() throws SQLFeatureNotSupportedException {
+ return null;
+ }
+
+ /**
+ * Returns the host property
+ *
+ * @param props the java.util.Properties instance to retrieve the hostname from.
+ * @return the host
+ */
+ public String host(Properties props) {
+ return props.getProperty(PROPERTY_KEY_HOST, "localhost");
+ }
+
+ /**
+ * Returns the port number property
+ *
+ * @param props the properties to get the port number from
+ * @return the port number
+ */
+ public int port(Properties props) {
+ return Integer.parseInt(props.getProperty(PROPERTY_KEY_PORT, TSDBConstants.DEFAULT_PORT));
+ }
+
+ /**
+ * Returns the database property from props
+ *
+ * @param props the Properties to look for the database property.
+ * @return the database name.
+ */
+ public String database(Properties props) {
+ return props.getProperty(PROPERTY_KEY_DBNAME);
+ }
}
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 a8d6ceb713136dd2a25b92de286daac86e01fa09..5c6b0545e91a13b793478efa1ec687e616d1a9ef 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
@@ -242,7 +242,7 @@ public class TSDBStatement implements Statement {
public void addBatch(String sql) throws SQLException {
if (batchedArgs == null) {
- batchedArgs = new ArrayList();
+ batchedArgs = new ArrayList<>();
}
batchedArgs.add(sql);
}
diff --git a/src/cq/src/cqMain.c b/src/cq/src/cqMain.c
index 758d620e571b387bbbe91101c89da3900019b6e3..d8f68f66a5b22fa2379b55a6a7f303c4e501c058 100644
--- a/src/cq/src/cqMain.c
+++ b/src/cq/src/cqMain.c
@@ -30,10 +30,12 @@
#include "tlog.h"
#include "twal.h"
-#define cError(...) { if (cqDebugFlag & DEBUG_ERROR) { taosPrintLog("ERROR CQ ", cqDebugFlag, __VA_ARGS__); }}
-#define cWarn(...) { if (cqDebugFlag & DEBUG_WARN) { taosPrintLog("WARN CQ ", cqDebugFlag, __VA_ARGS__); }}
+#define cFatal(...) { if (cqDebugFlag & DEBUG_FATAL) { taosPrintLog("CQ FATAL ", 255, __VA_ARGS__); }}
+#define cError(...) { if (cqDebugFlag & DEBUG_ERROR) { taosPrintLog("CQ ERROR ", 255, __VA_ARGS__); }}
+#define cWarn(...) { if (cqDebugFlag & DEBUG_WARN) { taosPrintLog("CQ WARN ", 255, __VA_ARGS__); }}
+#define cInfo(...) { if (cqDebugFlag & DEBUG_INFO) { taosPrintLog("CQ ", 255, __VA_ARGS__); }}
+#define cDebug(...) { if (cqDebugFlag & DEBUG_DEBUG) { taosPrintLog("CQ ", cqDebugFlag, __VA_ARGS__); }}
#define cTrace(...) { if (cqDebugFlag & DEBUG_TRACE) { taosPrintLog("CQ ", cqDebugFlag, __VA_ARGS__); }}
-#define cPrint(...) { taosPrintLog("CQ ", 255, __VA_ARGS__); }
typedef struct {
int vgId;
@@ -94,7 +96,7 @@ void *cqOpen(void *ahandle, const SCqCfg *pCfg) {
pthread_mutex_init(&pContext->mutex, NULL);
- cTrace("vgId:%d, CQ is opened", pContext->vgId);
+ cInfo("vgId:%d, CQ is opened", pContext->vgId);
return pContext;
}
@@ -125,7 +127,7 @@ void cqClose(void *handle) {
taosTmrCleanUp(pContext->tmrCtrl);
pContext->tmrCtrl = NULL;
- cTrace("vgId:%d, CQ is closed", pContext->vgId);
+ cInfo("vgId:%d, CQ is closed", pContext->vgId);
free(pContext);
}
@@ -133,7 +135,7 @@ void cqStart(void *handle) {
SCqContext *pContext = handle;
if (pContext->dbConn || pContext->master) return;
- cTrace("vgId:%d, start all CQs", pContext->vgId);
+ cInfo("vgId:%d, start all CQs", pContext->vgId);
pthread_mutex_lock(&pContext->mutex);
pContext->master = 1;
@@ -149,7 +151,7 @@ void cqStart(void *handle) {
void cqStop(void *handle) {
SCqContext *pContext = handle;
- cTrace("vgId:%d, stop all CQs", pContext->vgId);
+ cInfo("vgId:%d, stop all CQs", pContext->vgId);
if (pContext->dbConn == NULL || pContext->master == 0) return;
pthread_mutex_lock(&pContext->mutex);
@@ -160,7 +162,7 @@ void cqStop(void *handle) {
if (pObj->pStream) {
taos_close_stream(pObj->pStream);
pObj->pStream = NULL;
- cTrace("vgId:%d, id:%d CQ:%s is closed", pContext->vgId, pObj->tid, pObj->sqlStr);
+ cInfo("vgId:%d, id:%d CQ:%s is closed", pContext->vgId, pObj->tid, pObj->sqlStr);
} else {
taosTmrStop(pObj->tmrId);
pObj->tmrId = 0;
@@ -188,7 +190,7 @@ void *cqCreate(void *handle, uint64_t uid, int tid, char *sqlStr, STSchema *pSch
pObj->pSchema = tdDupSchema(pSchema);
pObj->rowSize = schemaTLen(pSchema);
- cTrace("vgId:%d, id:%d CQ:%s is created", pContext->vgId, pObj->tid, pObj->sqlStr);
+ cInfo("vgId:%d, id:%d CQ:%s is created", pContext->vgId, pObj->tid, pObj->sqlStr);
pthread_mutex_lock(&pContext->mutex);
@@ -228,7 +230,7 @@ void cqDrop(void *handle) {
pObj->tmrId = 0;
}
- cTrace("vgId:%d, id:%d CQ:%s is dropped", pContext->vgId, pObj->tid, pObj->sqlStr);
+ cInfo("vgId:%d, id:%d CQ:%s is dropped", pContext->vgId, pObj->tid, pObj->sqlStr);
tdFreeSchema(pObj->pSchema);
free(pObj->sqlStr);
free(pObj);
@@ -262,7 +264,7 @@ static void cqCreateStream(SCqContext *pContext, SCqObj *pObj) {
pObj->pStream = taos_open_stream(pContext->dbConn, pObj->sqlStr, cqProcessStreamRes, 0, pObj, NULL);
if (pObj->pStream) {
pContext->num++;
- cTrace("vgId:%d, id:%d CQ:%s is openned", pContext->vgId, pObj->tid, pObj->sqlStr);
+ cInfo("vgId:%d, id:%d CQ:%s is openned", pContext->vgId, pObj->tid, pObj->sqlStr);
} else {
cError("vgId:%d, id:%d CQ:%s, failed to open", pContext->vgId, pObj->tid, pObj->sqlStr);
}
@@ -278,7 +280,7 @@ static void cqProcessStreamRes(void *param, TAOS_RES *tres, TAOS_ROW row) {
STSchema *pSchema = pObj->pSchema;
if (pObj->pStream == NULL) return;
- cTrace("vgId:%d, id:%d CQ:%s stream result is ready", pContext->vgId, pObj->tid, pObj->sqlStr);
+ cDebug("vgId:%d, id:%d CQ:%s stream result is ready", pContext->vgId, pObj->tid, pObj->sqlStr);
int size = sizeof(SWalHead) + sizeof(SSubmitMsg) + sizeof(SSubmitBlk) + TD_DATA_ROW_HEAD_SIZE + pObj->rowSize;
char *buffer = calloc(size, 1);
diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h
index 9a411d8f858b9f6f90651e8f4d40d6f3c46a02f5..f9d4b3d7bf974bb8e6ca5cbb7c2021e137e32fd5 100644
--- a/src/inc/taosdef.h
+++ b/src/inc/taosdef.h
@@ -245,7 +245,7 @@ void tsDataSwap(void *pLeft, void *pRight, int32_t type, int32_t size, void* buf
#define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64
#define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE
#define TSDB_MAX_SQL_SHOW_LEN 256
-#define TSDB_MAX_ALLOWED_SQL_LEN (8*1024*1024U) // sql length should be less than 8mb
+#define TSDB_MAX_ALLOWED_SQL_LEN (1*1024*1024U) // sql length should be less than 8mb
#define TSDB_MAX_BYTES_PER_ROW 16384
#define TSDB_MAX_TAGS_LEN 16384
diff --git a/src/plugins/http/src/httpContext.c b/src/plugins/http/src/httpContext.c
index 92388693753986b0241e03580c3d5e0518421469..6abd382f8e5a3ff75c1296cd5c4e2bea533ec53f 100644
--- a/src/plugins/http/src/httpContext.c
+++ b/src/plugins/http/src/httpContext.c
@@ -230,4 +230,5 @@ void httpCloseContextByServer(HttpContext *pContext) {
pContext->parsed = false;
httpRemoveContextFromEpoll(pContext);
+ httpReleaseContext(pContext, true);
}
diff --git a/src/query/inc/qFill.h b/src/query/inc/qFill.h
index c1a5a5be8eb7d5342ca23b10c6b45e76a71816cd..6d44fee09557fa8b8d73527677a2c7b238ecb42c 100644
--- a/src/query/inc/qFill.h
+++ b/src/query/inc/qFill.h
@@ -66,7 +66,8 @@ typedef struct SPoint {
} SPoint;
SFillInfo* taosInitFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
- SInterval* pInterval, int8_t precision, int32_t fillType, SFillColInfo* pFillCol);
+ int64_t slidingTime, int8_t slidingUnit, int8_t precision, int32_t fillType,
+ SFillColInfo* pFillCol);
void taosResetFillInfo(SFillInfo* pFillInfo, TSKEY startTimestamp);
diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c
index ad9b5a9a84d4383e6eafec42401b2723f7c46618..d3f44cdcc715bb236fafaa4947a54771052df307 100644
--- a/src/query/src/qExecutor.c
+++ b/src/query/src/qExecutor.c
@@ -4581,7 +4581,8 @@ int32_t doInitQInfo(SQInfo *pQInfo, STSBuf *pTsBuf, void *tsdb, int32_t vgId, bo
getAlignQueryTimeWindow(pQuery, pQuery->window.skey, sk, ek, &w);
pRuntimeEnv->pFillInfo = taosInitFillInfo(pQuery->order.order, w.skey, 0, (int32_t)pQuery->rec.capacity, pQuery->numOfOutput,
- &pQuery->interval, (int8_t)pQuery->precision, pQuery->fillType, pColInfo);
+ pQuery->interval.sliding, pQuery->interval.slidingUnit, (int8_t)pQuery->precision,
+ pQuery->fillType, pColInfo);
}
setQueryStatus(pQuery, QUERY_NOT_COMPLETED);
diff --git a/src/query/src/qFill.c b/src/query/src/qFill.c
index 24fb9caa511726c14952076bddd6f0b5b74c5932..f186726c0120f2e2e34580fec0da00c2083e5da9 100644
--- a/src/query/src/qFill.c
+++ b/src/query/src/qFill.c
@@ -23,7 +23,7 @@
#define FILL_IS_ASC_FILL(_f) ((_f)->order == TSDB_ORDER_ASC)
SFillInfo* taosInitFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_t capacity, int32_t numOfCols,
- SInterval* pInterval, int8_t precision, int32_t fillType, SFillColInfo* pFillCol) {
+ int64_t slidingTime, int8_t slidingUnit, int8_t precision, int32_t fillType, SFillColInfo* pFillCol) {
if (fillType == TSDB_FILL_NONE) {
return NULL;
}
@@ -38,7 +38,11 @@ SFillInfo* taosInitFillInfo(int32_t order, TSKEY skey, int32_t numOfTags, int32_
pFillInfo->numOfTags = numOfTags;
pFillInfo->numOfCols = numOfCols;
pFillInfo->precision = precision;
- memcpy(&pFillInfo->interval, pInterval, sizeof(SInterval));
+
+ pFillInfo->interval.interval = slidingTime;
+ pFillInfo->interval.intervalUnit = slidingUnit;
+ pFillInfo->interval.sliding = slidingTime;
+ pFillInfo->interval.slidingUnit = slidingUnit;
pFillInfo->pData = malloc(POINTER_BYTES * numOfCols);
if (numOfTags > 0) {
diff --git a/src/sync/src/syncMain.c b/src/sync/src/syncMain.c
index f96b902efde28c62af194047b64485a8f83c0e45..3f57a8b5cddc8b08de98b412ebe582a507c07d61 100644
--- a/src/sync/src/syncMain.c
+++ b/src/sync/src/syncMain.c
@@ -511,9 +511,9 @@ static SSyncPeer *syncAddPeer(SSyncNode *pNode, const SNodeInfo *pInfo) {
sInfo("%s, it is configured", pPeer->id);
int ret = strcmp(pPeer->fqdn, tsNodeFqdn);
if (pPeer->nodeId == 0 || (ret > 0) || (ret == 0 && pPeer->port > tsSyncPort)) {
- sDebug("%s, start to check peer connection", pPeer->id);
int32_t checkMs = 100 + (pNode->vgId * 10) % 100;
- if (pNode->vgId) checkMs = tsStatusInterval * 2000 + 100;
+ if (pNode->vgId > 1) checkMs = tsStatusInterval * 2000 + checkMs;
+ sDebug("%s, start to check peer connection after %d ms", pPeer->id, checkMs);
taosTmrReset(syncCheckPeerConnection, checkMs, pPeer, syncTmrCtrl, &pPeer->timer);
}
diff --git a/tests/pytest/client/twoClients.py b/tests/pytest/client/twoClients.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a1b36c55438f8ea4050bb804b739be71c570960
--- /dev/null
+++ b/tests/pytest/client/twoClients.py
@@ -0,0 +1,96 @@
+###################################################################
+# Copyright (c) 2016 by TAOS Technologies, Inc.
+# All rights reserved.
+#
+# This file is proprietary and confidential to TAOS Technologies.
+# No part of this file may be reproduced, stored, transmitted,
+# disclosed or used in any form or by any means other than as
+# expressly provided by the written permission from Jianhui Tao
+#
+###################################################################
+
+# -*- coding: utf-8 -*-
+
+import os
+import sys
+sys.path.insert(0, os.getcwd())
+from util.log import *
+from util.sql import *
+from util.dnodes import *
+import taos
+
+
+class TwoClients:
+ def initConnection(self):
+ self.host = "127.0.0.1"
+ self.user = "root"
+ self.password = "taosdata"
+ self.config = "/home/xp/git/TDengine/sim/dnode1/cfg"
+
+ def run(self):
+ tdDnodes.init("")
+ tdDnodes.setTestCluster(False)
+ tdDnodes.setValgrind(False)
+
+ tdDnodes.stopAll()
+ tdDnodes.deploy(1)
+ tdDnodes.start(1)
+
+ # first client create a stable and insert data
+ conn1 = taos.connect(self.host, self.user, self.password, self.config)
+ cursor1 = conn1.cursor()
+ cursor1.execute("drop database if exists db")
+ cursor1.execute("create database db")
+ cursor1.execute("use db")
+ cursor1.execute("create table tb (ts timestamp, id int) tags(loc nchar(30))")
+ cursor1.execute("insert into t0 using tb tags('beijing') values(now, 1)")
+
+ # second client alter the table created by cleint
+ conn2 = taos.connect(self.host, self.user, self.password, self.config)
+ cursor2 = conn2.cursor()
+ cursor2.execute("use db")
+ cursor2.execute("alter table tb add column name nchar(30)")
+
+ # first client should not be able to use the origin metadata
+ tdSql.init(cursor1, True)
+ tdSql.error("insert into t0 values(now, 2)")
+
+ # first client should be able to insert data with udpated medadata
+ tdSql.execute("insert into t0 values(now, 2, 'test')")
+ tdSql.query("select * from tb")
+ tdSql.checkRows(2)
+
+ # second client drop the table
+ cursor2.execute("drop table t0")
+ cursor2.execute("create table t0 using tb tags('beijing')")
+
+ tdSql.execute("insert into t0 values(now, 2, 'test')")
+ tdSql.query("select * from tb")
+ tdSql.checkRows(1)
+
+ # error expected for two clients drop the same cloumn
+ cursor2.execute("alter table tb drop column name")
+ tdSql.error("alter table tb drop column name")
+
+ cursor2.execute("alter table tb add column speed int")
+ tdSql.error("alter table tb add column speed int")
+
+
+ tdSql.execute("alter table tb add column size int")
+ tdSql.query("describe tb")
+ tdSql.checkRows(5)
+ tdSql.checkData(0, 0, "ts")
+ tdSql.checkData(1, 0, "id")
+ tdSql.checkData(2, 0, "speed")
+ tdSql.checkData(3, 0, "size")
+ tdSql.checkData(4, 0, "loc")
+
+
+ cursor1.close()
+ cursor2.close()
+ conn1.close()
+ conn2.close()
+
+clients = TwoClients()
+clients.initConnection()
+clients.run()
\ No newline at end of file
diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh
index bfa546f92e6850cad1c4c070d149961221e41e22..c74fb33c3b67dd49abf2bf8f915d360216aa562f 100755
--- a/tests/pytest/fulltest.sh
+++ b/tests/pytest/fulltest.sh
@@ -187,6 +187,7 @@ python3 ./test.py -f functions/function_top.py
#python3 ./test.py -f functions/function_twa.py
python3 queryCount.py
python3 ./test.py -f query/queryGroupbyWithInterval.py
+python3 client/twoClients.py
# tools
python3 test.py -f tools/taosdemo.py
diff --git a/tests/script/general/http/chunked.sim b/tests/script/general/http/chunked.sim
index 8673655d969392873b297c82e8ae4d394ac3b190..6592c761c6ccaea94f385ac72982115c775f01d7 100644
--- a/tests/script/general/http/chunked.sim
+++ b/tests/script/general/http/chunked.sim
@@ -3,7 +3,7 @@ sleep 3000
system sh/deploy.sh -n dnode1 -i 1
system sh/cfg.sh -n dnode1 -c wallevel -v 0
system sh/cfg.sh -n dnode1 -c http -v 1
-system sh/cfg.sh -n dnode1 -c maxSQLLength -v 7340032
+system sh/cfg.sh -n dnode1 -c maxSQLLength -v 340032
system sh/exec.sh -n dnode1 -s start
sleep 3000