SQL: Lock down JDBC driver (#35798)
Move classes under the same package to avoid internal classes being exposed to the outside. Remove public visibility outside 3 classes: EsDriver, EsDataSource and EsTypes. The driver only has one package, namely org.elasticsearch.xpack.sql.jdbc Use Es prefix for classes to ease name conflict and indicate their destination Fix #35437
This commit is contained in:
parent
2f547bac65
commit
95346926ef
|
@ -43,9 +43,9 @@ from `artifacts.elastic.co/maven` by adding it to the repositories list:
|
||||||
[float]
|
[float]
|
||||||
=== Setup
|
=== Setup
|
||||||
|
|
||||||
The driver main class is `org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcDriver`.
|
The driver main class is `org.elasticsearch.xpack.sql.jdbc.EsDriver`.
|
||||||
Note the driver implements the JDBC 4.0 +Service Provider+ mechanism meaning it is registered automatically
|
Note the driver implements the JDBC 4.0 +Service Provider+ mechanism meaning it is registered automatically
|
||||||
as long as its available in the classpath.
|
as long as it is available in the classpath.
|
||||||
|
|
||||||
Once registered, the driver understands the following syntax as an URL:
|
Once registered, the driver understands the following syntax as an URL:
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
|
@ -3,14 +3,12 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.net.client;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.JdbcColumnInfo;
|
interface Cursor {
|
||||||
|
|
||||||
public interface Cursor {
|
|
||||||
|
|
||||||
List<JdbcColumnInfo> columns();
|
List<JdbcColumnInfo> columns();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
|
|
|
@ -3,11 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.client.SuppressForbidden;
|
import org.elasticsearch.xpack.sql.client.SuppressForbidden;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.JdbcException;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConfiguration;
|
|
||||||
|
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
@ -46,7 +44,7 @@ import javax.sql.DataSource;
|
||||||
* For this reason the {@link System#out} and {@link System#err} are being referred in this class though are used only
|
* For this reason the {@link System#out} and {@link System#err} are being referred in this class though are used only
|
||||||
* when needed.
|
* when needed.
|
||||||
*/
|
*/
|
||||||
public final class Debug {
|
final class Debug {
|
||||||
|
|
||||||
// cache for streams created by ourselves
|
// cache for streams created by ourselves
|
||||||
private static final Map<String, DebugLog> OUTPUT_CACHE = new HashMap<>();
|
private static final Map<String, DebugLog> OUTPUT_CACHE = new HashMap<>();
|
||||||
|
@ -70,7 +68,7 @@ public final class Debug {
|
||||||
* own configuration first; if that does not exist it will fallback to the managed approaches (assuming they
|
* own configuration first; if that does not exist it will fallback to the managed approaches (assuming they
|
||||||
* are specified, otherwise logging is simply disabled).
|
* are specified, otherwise logging is simply disabled).
|
||||||
*/
|
*/
|
||||||
public static Connection proxy(JdbcConfiguration info, Connection connection, PrintWriter managedPrinter) {
|
static Connection proxy(JdbcConfiguration info, Connection connection, PrintWriter managedPrinter) {
|
||||||
return createProxy(Connection.class, new ConnectionProxy(logger(info, managedPrinter), connection));
|
return createProxy(Connection.class, new ConnectionProxy(logger(info, managedPrinter), connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -180,7 +178,7 @@ public final class Debug {
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void release(JdbcConfiguration info) {
|
static void release(JdbcConfiguration info) {
|
||||||
if (!info.debug()) {
|
if (!info.debug()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -206,7 +204,7 @@ public final class Debug {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static synchronized void close() {
|
static synchronized void close() {
|
||||||
// clear the ref
|
// clear the ref
|
||||||
OUTPUT_REFS.clear();
|
OUTPUT_REFS.clear();
|
||||||
|
|
||||||
|
@ -235,4 +233,4 @@ public final class Debug {
|
||||||
private static PrintStream stderr() {
|
private static PrintStream stderr() {
|
||||||
return System.err;
|
return System.err;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.client.StringUtils;
|
import org.elasticsearch.xpack.sql.client.StringUtils;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Debug marker interface for compatible proxy.
|
* Debug marker interface for compatible proxy.
|
|
@ -3,9 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.JdbcSQLException;
|
|
||||||
|
|
||||||
import java.lang.reflect.InvocationHandler;
|
import java.lang.reflect.InvocationHandler;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
|
@ -3,10 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.net.client;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.Tuple;
|
import org.elasticsearch.common.collect.Tuple;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.JdbcColumnInfo;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.List;
|
import java.util.List;
|
|
@ -3,12 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbcx;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.client.ConnectionConfiguration;
|
import org.elasticsearch.xpack.sql.client.ConnectionConfiguration;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.debug.Debug;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConfiguration;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConnection;
|
|
||||||
import org.elasticsearch.xpack.sql.client.Version;
|
import org.elasticsearch.xpack.sql.client.Version;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
|
@ -21,10 +18,13 @@ import java.util.logging.Logger;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
/**
|
||||||
public class JdbcDataSource implements DataSource, Wrapper {
|
* Factory for connections to Elasticsearch SQL.
|
||||||
|
*/
|
||||||
|
public class EsDataSource implements DataSource, Wrapper {
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
// invoke Version to perform classpath/jar sanity checks
|
||||||
Version.CURRENT.toString();
|
Version.CURRENT.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class JdbcDataSource implements DataSource, Wrapper {
|
||||||
private int loginTimeout;
|
private int loginTimeout;
|
||||||
private Properties props;
|
private Properties props;
|
||||||
|
|
||||||
public JdbcDataSource() {}
|
public EsDataSource() {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PrintWriter getLogWriter() throws SQLException {
|
public PrintWriter getLogWriter() throws SQLException {
|
|
@ -3,14 +3,13 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.client.Version;
|
import org.elasticsearch.xpack.sql.client.Version;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.JdbcSQLException;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.debug.Debug;
|
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
|
import java.sql.Driver;
|
||||||
import java.sql.DriverManager;
|
import java.sql.DriverManager;
|
||||||
import java.sql.DriverPropertyInfo;
|
import java.sql.DriverPropertyInfo;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
@ -18,9 +17,9 @@ import java.sql.SQLFeatureNotSupportedException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
public class JdbcDriver implements java.sql.Driver {
|
public class EsDriver implements Driver {
|
||||||
|
|
||||||
private static final JdbcDriver INSTANCE = new JdbcDriver();
|
private static final EsDriver INSTANCE = new EsDriver();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// invoke Version to perform classpath/jar sanity checks
|
// invoke Version to perform classpath/jar sanity checks
|
||||||
|
@ -40,7 +39,7 @@ public class JdbcDriver implements java.sql.Driver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JdbcDriver register() throws SQLException {
|
public static EsDriver register() throws SQLException {
|
||||||
// no closing callback
|
// no closing callback
|
||||||
DriverManager.registerDriver(INSTANCE, INSTANCE::close);
|
DriverManager.registerDriver(INSTANCE, INSTANCE::close);
|
||||||
return INSTANCE;
|
return INSTANCE;
|
|
@ -4,13 +4,13 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.elasticsearch.xpack.sql.jdbc.type;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
|
|
||||||
import java.sql.SQLType;
|
import java.sql.SQLType;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
|
|
||||||
public enum DataType implements SQLType {
|
public enum EsType implements SQLType {
|
||||||
|
|
||||||
NULL( Types.NULL),
|
NULL( Types.NULL),
|
||||||
UNSUPPORTED( Types.OTHER),
|
UNSUPPORTED( Types.OTHER),
|
||||||
|
@ -46,7 +46,7 @@ public enum DataType implements SQLType {
|
||||||
|
|
||||||
private final Integer type;
|
private final Integer type;
|
||||||
|
|
||||||
DataType(int type) {
|
EsType(int type) {
|
||||||
this.type = Integer.valueOf(type);
|
this.type = Integer.valueOf(type);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.elasticsearch.xpack.sql.jdbc.type;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.JDBCType;
|
import java.sql.JDBCType;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
|
@ -3,17 +3,17 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.net.protocol;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* General information about the server.
|
* General information about the server.
|
||||||
*/
|
*/
|
||||||
public class InfoResponse {
|
class InfoResponse {
|
||||||
public final String cluster;
|
final String cluster;
|
||||||
public final int majorVersion;
|
final int majorVersion;
|
||||||
public final int minorVersion;
|
final int minorVersion;
|
||||||
|
|
||||||
public InfoResponse(String clusterName, byte versionMajor, byte versionMinor) {
|
InfoResponse(String clusterName, byte versionMajor, byte versionMinor) {
|
||||||
this.cluster = clusterName;
|
this.cluster = clusterName;
|
||||||
this.majorVersion = versionMajor;
|
this.majorVersion = versionMajor;
|
||||||
this.minorVersion = versionMinor;
|
this.minorVersion = versionMinor;
|
|
@ -3,22 +3,20 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.net.protocol;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
public class JdbcColumnInfo {
|
class JdbcColumnInfo {
|
||||||
public final String catalog;
|
public final String catalog;
|
||||||
public final String schema;
|
public final String schema;
|
||||||
public final String table;
|
public final String table;
|
||||||
public final String label;
|
public final String label;
|
||||||
public final String name;
|
public final String name;
|
||||||
public final int displaySize;
|
public final int displaySize;
|
||||||
public final DataType type;
|
public final EsType type;
|
||||||
|
|
||||||
public JdbcColumnInfo(String name, DataType type, String table, String catalog, String schema, String label, int displaySize) {
|
JdbcColumnInfo(String name, EsType type, String table, String catalog, String schema, String label, int displaySize) {
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
throw new IllegalArgumentException("[name] must not be null");
|
throw new IllegalArgumentException("[name] must not be null");
|
||||||
}
|
}
|
||||||
|
@ -46,7 +44,7 @@ public class JdbcColumnInfo {
|
||||||
this.displaySize = displaySize;
|
this.displaySize = displaySize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int displaySize() {
|
int displaySize() {
|
||||||
// 0 - means unknown
|
// 0 - means unknown
|
||||||
return displaySize;
|
return displaySize;
|
||||||
}
|
}
|
|
@ -3,12 +3,11 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.client.ConnectionConfiguration;
|
import org.elasticsearch.xpack.sql.client.ConnectionConfiguration;
|
||||||
import org.elasticsearch.xpack.sql.client.StringUtils;
|
import org.elasticsearch.xpack.sql.client.StringUtils;
|
||||||
import org.elasticsearch.xpack.sql.client.Version;
|
import org.elasticsearch.xpack.sql.client.Version;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.JdbcSQLException;
|
|
||||||
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.sql.DriverPropertyInfo;
|
import java.sql.DriverPropertyInfo;
|
||||||
|
@ -35,7 +34,7 @@ import static org.elasticsearch.xpack.sql.client.UriUtils.removeQuery;
|
||||||
/ Additional properties can be specified either through the Properties object or in the URL. In case of duplicates, the URL wins.
|
/ Additional properties can be specified either through the Properties object or in the URL. In case of duplicates, the URL wins.
|
||||||
*/
|
*/
|
||||||
//TODO: beef this up for Security/SSL
|
//TODO: beef this up for Security/SSL
|
||||||
public class JdbcConfiguration extends ConnectionConfiguration {
|
class JdbcConfiguration extends ConnectionConfiguration {
|
||||||
static final String URL_PREFIX = "jdbc:es://";
|
static final String URL_PREFIX = "jdbc:es://";
|
||||||
public static URI DEFAULT_URI = URI.create("http://localhost:9200/");
|
public static URI DEFAULT_URI = URI.create("http://localhost:9200/");
|
||||||
|
|
|
@ -3,10 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.debug.Debug;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.client.JdbcHttpClient;
|
|
||||||
|
|
||||||
import java.sql.Array;
|
import java.sql.Array;
|
||||||
import java.sql.Blob;
|
import java.sql.Blob;
|
||||||
|
@ -33,7 +30,7 @@ import java.util.concurrent.TimeUnit;
|
||||||
/**
|
/**
|
||||||
* Implementation of {@link Connection} for Elasticsearch.
|
* Implementation of {@link Connection} for Elasticsearch.
|
||||||
*/
|
*/
|
||||||
public class JdbcConnection implements Connection, JdbcWrapper {
|
class JdbcConnection implements Connection, JdbcWrapper {
|
||||||
|
|
||||||
private final String url, userName;
|
private final String url, userName;
|
||||||
final JdbcConfiguration cfg;
|
final JdbcConfiguration cfg;
|
||||||
|
@ -47,7 +44,7 @@ public class JdbcConnection implements Connection, JdbcWrapper {
|
||||||
* The SQLException is the only type of Exception the JDBC API can throw (and that the user expects).
|
* The SQLException is the only type of Exception the JDBC API can throw (and that the user expects).
|
||||||
* If we remove it, we need to make sure no other types of Exceptions (runtime or otherwise) are thrown
|
* If we remove it, we need to make sure no other types of Exceptions (runtime or otherwise) are thrown
|
||||||
*/
|
*/
|
||||||
public JdbcConnection(JdbcConfiguration connectionInfo) throws SQLException {
|
JdbcConnection(JdbcConfiguration connectionInfo) throws SQLException {
|
||||||
cfg = connectionInfo;
|
cfg = connectionInfo;
|
||||||
client = new JdbcHttpClient(connectionInfo);
|
client = new JdbcHttpClient(connectionInfo);
|
||||||
|
|
|
@ -3,14 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.client.ObjectUtils;
|
import org.elasticsearch.xpack.sql.client.ObjectUtils;
|
||||||
import org.elasticsearch.xpack.sql.client.Version;
|
import org.elasticsearch.xpack.sql.client.Version;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.JdbcSQLException;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.client.Cursor;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.JdbcColumnInfo;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.DatabaseMetaData;
|
import java.sql.DatabaseMetaData;
|
||||||
|
@ -1125,11 +1121,11 @@ class JdbcDatabaseMetaData implements DatabaseMetaData, JdbcWrapper {
|
||||||
Object obj = cols[i];
|
Object obj = cols[i];
|
||||||
if (obj instanceof String) {
|
if (obj instanceof String) {
|
||||||
String name = obj.toString();
|
String name = obj.toString();
|
||||||
DataType type = DataType.KEYWORD;
|
EsType type = EsType.KEYWORD;
|
||||||
if (i + 1 < cols.length) {
|
if (i + 1 < cols.length) {
|
||||||
Object next = cols[i + 1];
|
Object next = cols[i + 1];
|
||||||
// check if the next item it's a type
|
// check if the next item it's a type
|
||||||
if (next instanceof DataType || next instanceof JDBCType) {
|
if (next instanceof EsType || next instanceof JDBCType) {
|
||||||
try {
|
try {
|
||||||
type = TypeUtils.of((JDBCType) next);
|
type = TypeUtils.of((JDBCType) next);
|
||||||
i++;
|
i++;
|
|
@ -5,13 +5,13 @@
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
public class JdbcException extends RuntimeException {
|
class JdbcException extends RuntimeException {
|
||||||
|
|
||||||
public JdbcException(String message) {
|
JdbcException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JdbcException(Throwable cause, String message) {
|
JdbcException(Throwable cause, String message) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,12 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.net.client;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.common.collect.Tuple;
|
import org.elasticsearch.common.collect.Tuple;
|
||||||
import org.elasticsearch.common.unit.TimeValue;
|
import org.elasticsearch.common.unit.TimeValue;
|
||||||
import org.elasticsearch.xpack.sql.client.HttpClient;
|
import org.elasticsearch.xpack.sql.client.HttpClient;
|
||||||
import org.elasticsearch.xpack.sql.client.Version;
|
import org.elasticsearch.xpack.sql.client.Version;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConfiguration;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.TypeUtils;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.InfoResponse;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.JdbcColumnInfo;
|
|
||||||
import org.elasticsearch.xpack.sql.proto.ColumnInfo;
|
import org.elasticsearch.xpack.sql.proto.ColumnInfo;
|
||||||
import org.elasticsearch.xpack.sql.proto.MainResponse;
|
import org.elasticsearch.xpack.sql.proto.MainResponse;
|
||||||
import org.elasticsearch.xpack.sql.proto.Mode;
|
import org.elasticsearch.xpack.sql.proto.Mode;
|
||||||
|
@ -32,7 +28,7 @@ import static org.elasticsearch.xpack.sql.client.StringUtils.EMPTY;
|
||||||
* JDBC specific HTTP client.
|
* JDBC specific HTTP client.
|
||||||
* Since JDBC is not thread-safe, neither is this class.
|
* Since JDBC is not thread-safe, neither is this class.
|
||||||
*/
|
*/
|
||||||
public class JdbcHttpClient {
|
class JdbcHttpClient {
|
||||||
private final HttpClient httpClient;
|
private final HttpClient httpClient;
|
||||||
private final JdbcConfiguration conCfg;
|
private final JdbcConfiguration conCfg;
|
||||||
private InfoResponse serverInfo;
|
private InfoResponse serverInfo;
|
||||||
|
@ -41,16 +37,16 @@ public class JdbcHttpClient {
|
||||||
* The SQLException is the only type of Exception the JDBC API can throw (and that the user expects).
|
* The SQLException is the only type of Exception the JDBC API can throw (and that the user expects).
|
||||||
* If we remove it, we need to make sure no other types of Exceptions (runtime or otherwise) are thrown
|
* If we remove it, we need to make sure no other types of Exceptions (runtime or otherwise) are thrown
|
||||||
*/
|
*/
|
||||||
public JdbcHttpClient(JdbcConfiguration conCfg) throws SQLException {
|
JdbcHttpClient(JdbcConfiguration conCfg) throws SQLException {
|
||||||
httpClient = new HttpClient(conCfg);
|
httpClient = new HttpClient(conCfg);
|
||||||
this.conCfg = conCfg;
|
this.conCfg = conCfg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean ping(long timeoutInMs) throws SQLException {
|
boolean ping(long timeoutInMs) throws SQLException {
|
||||||
return httpClient.ping(timeoutInMs);
|
return httpClient.ping(timeoutInMs);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Cursor query(String sql, List<SqlTypedParamValue> params, RequestMeta meta) throws SQLException {
|
Cursor query(String sql, List<SqlTypedParamValue> params, RequestMeta meta) throws SQLException {
|
||||||
int fetch = meta.fetchSize() > 0 ? meta.fetchSize() : conCfg.pageSize();
|
int fetch = meta.fetchSize() > 0 ? meta.fetchSize() : conCfg.pageSize();
|
||||||
SqlQueryRequest sqlRequest = new SqlQueryRequest(sql, params, null, Protocol.TIME_ZONE,
|
SqlQueryRequest sqlRequest = new SqlQueryRequest(sql, params, null, Protocol.TIME_ZONE,
|
||||||
fetch,
|
fetch,
|
||||||
|
@ -64,18 +60,18 @@ public class JdbcHttpClient {
|
||||||
* Read the next page of results and returning
|
* Read the next page of results and returning
|
||||||
* the scroll id to use to fetch the next page.
|
* the scroll id to use to fetch the next page.
|
||||||
*/
|
*/
|
||||||
public Tuple<String, List<List<Object>>> nextPage(String cursor, RequestMeta meta) throws SQLException {
|
Tuple<String, List<List<Object>>> nextPage(String cursor, RequestMeta meta) throws SQLException {
|
||||||
SqlQueryRequest sqlRequest = new SqlQueryRequest(cursor, TimeValue.timeValueMillis(meta.timeoutInMs()),
|
SqlQueryRequest sqlRequest = new SqlQueryRequest(cursor, TimeValue.timeValueMillis(meta.timeoutInMs()),
|
||||||
TimeValue.timeValueMillis(meta.queryTimeoutInMs()), new RequestInfo(Mode.JDBC));
|
TimeValue.timeValueMillis(meta.queryTimeoutInMs()), new RequestInfo(Mode.JDBC));
|
||||||
SqlQueryResponse response = httpClient.query(sqlRequest);
|
SqlQueryResponse response = httpClient.query(sqlRequest);
|
||||||
return new Tuple<>(response.cursor(), response.rows());
|
return new Tuple<>(response.cursor(), response.rows());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean queryClose(String cursor) throws SQLException {
|
boolean queryClose(String cursor) throws SQLException {
|
||||||
return httpClient.queryClose(cursor);
|
return httpClient.queryClose(cursor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InfoResponse serverInfo() throws SQLException {
|
InfoResponse serverInfo() throws SQLException {
|
||||||
if (serverInfo == null) {
|
if (serverInfo == null) {
|
||||||
serverInfo = fetchServerInfo();
|
serverInfo = fetchServerInfo();
|
||||||
}
|
}
|
|
@ -3,9 +3,9 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.PreparedQuery.ParamInfo;
|
import org.elasticsearch.xpack.sql.jdbc.PreparedQuery.ParamInfo;
|
||||||
|
|
||||||
import java.sql.ParameterMetaData;
|
import java.sql.ParameterMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
|
@ -3,9 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
@ -72,7 +70,7 @@ class JdbcPreparedStatement extends JdbcStatement implements PreparedStatement {
|
||||||
setParam(parameterIndex, value, TypeUtils.of(sqlType));
|
setParam(parameterIndex, value, TypeUtils.of(sqlType));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setParam(int parameterIndex, Object value, DataType type) throws SQLException {
|
private void setParam(int parameterIndex, Object value, EsType type) throws SQLException {
|
||||||
checkOpen();
|
checkOpen();
|
||||||
|
|
||||||
if (parameterIndex < 0 || parameterIndex > query.paramCount()) {
|
if (parameterIndex < 0 || parameterIndex > query.paramCount()) {
|
||||||
|
@ -189,7 +187,7 @@ class JdbcPreparedStatement extends JdbcStatement implements PreparedStatement {
|
||||||
@Override
|
@Override
|
||||||
public void setObject(int parameterIndex, Object x) throws SQLException {
|
public void setObject(int parameterIndex, Object x) throws SQLException {
|
||||||
if (x == null) {
|
if (x == null) {
|
||||||
setParam(parameterIndex, null, DataType.NULL);
|
setParam(parameterIndex, null, EsType.NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,7 +341,7 @@ class JdbcPreparedStatement extends JdbcStatement implements PreparedStatement {
|
||||||
setObject(parameterIndex, x, TypeUtils.of(targetSqlType), targetSqlType.getName());
|
setObject(parameterIndex, x, TypeUtils.of(targetSqlType), targetSqlType.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setObject(int parameterIndex, Object x, DataType dataType, String typeString) throws SQLException {
|
private void setObject(int parameterIndex, Object x, EsType dataType, String typeString) throws SQLException {
|
||||||
checkOpen();
|
checkOpen();
|
||||||
|
|
||||||
// set the null value on the type and exit
|
// set the null value on the type and exit
|
||||||
|
@ -354,11 +352,11 @@ class JdbcPreparedStatement extends JdbcStatement implements PreparedStatement {
|
||||||
|
|
||||||
checkKnownUnsupportedTypes(x);
|
checkKnownUnsupportedTypes(x);
|
||||||
if (x instanceof byte[]) {
|
if (x instanceof byte[]) {
|
||||||
if (dataType != DataType.BINARY) {
|
if (dataType != EsType.BINARY) {
|
||||||
throw new SQLFeatureNotSupportedException(
|
throw new SQLFeatureNotSupportedException(
|
||||||
"Conversion from type [byte[]] to [" + typeString + "] not supported");
|
"Conversion from type [byte[]] to [" + typeString + "] not supported");
|
||||||
}
|
}
|
||||||
setParam(parameterIndex, x, DataType.BINARY);
|
setParam(parameterIndex, x, EsType.BINARY);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -369,7 +367,7 @@ class JdbcPreparedStatement extends JdbcStatement implements PreparedStatement {
|
||||||
|| x instanceof Time
|
|| x instanceof Time
|
||||||
|| x instanceof java.util.Date)
|
|| x instanceof java.util.Date)
|
||||||
{
|
{
|
||||||
if (dataType == DataType.DATE) {
|
if (dataType == EsType.DATE) {
|
||||||
// converting to {@code java.util.Date} because this is the type supported by {@code XContentBuilder} for serialization
|
// converting to {@code java.util.Date} because this is the type supported by {@code XContentBuilder} for serialization
|
||||||
java.util.Date dateToSet;
|
java.util.Date dateToSet;
|
||||||
if (x instanceof Timestamp) {
|
if (x instanceof Timestamp) {
|
|
@ -3,12 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.client.Cursor;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.JdbcColumnInfo;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.Nullable;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
@ -245,12 +240,12 @@ class JdbcResultSet implements ResultSet, JdbcWrapper {
|
||||||
|
|
||||||
private Long dateTime(int columnIndex) throws SQLException {
|
private Long dateTime(int columnIndex) throws SQLException {
|
||||||
Object val = column(columnIndex);
|
Object val = column(columnIndex);
|
||||||
DataType type = cursor.columns().get(columnIndex - 1).type;
|
EsType type = cursor.columns().get(columnIndex - 1).type;
|
||||||
try {
|
try {
|
||||||
// TODO: the B6 appendix of the jdbc spec does mention CHAR, VARCHAR, LONGVARCHAR, DATE, TIMESTAMP as supported
|
// TODO: the B6 appendix of the jdbc spec does mention CHAR, VARCHAR, LONGVARCHAR, DATE, TIMESTAMP as supported
|
||||||
// jdbc types that should be handled by getDate and getTime methods. From all of those we support VARCHAR and
|
// jdbc types that should be handled by getDate and getTime methods. From all of those we support VARCHAR and
|
||||||
// TIMESTAMP. Should we consider the VARCHAR conversion as a later enhancement?
|
// TIMESTAMP. Should we consider the VARCHAR conversion as a later enhancement?
|
||||||
if (DataType.DATE == type) {
|
if (EsType.DATE == type) {
|
||||||
// the cursor can return an Integer if the date-since-epoch is small enough, XContentParser (Jackson) will
|
// the cursor can return an Integer if the date-since-epoch is small enough, XContentParser (Jackson) will
|
||||||
// return the "smallest" data type for numbers when parsing
|
// return the "smallest" data type for numbers when parsing
|
||||||
// TODO: this should probably be handled server side
|
// TODO: this should probably be handled server side
|
||||||
|
@ -333,7 +328,7 @@ class JdbcResultSet implements ResultSet, JdbcWrapper {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataType columnType = cursor.columns().get(columnIndex - 1).type;
|
EsType columnType = cursor.columns().get(columnIndex - 1).type;
|
||||||
String typeString = type != null ? type.getSimpleName() : columnType.getName();
|
String typeString = type != null ? type.getSimpleName() : columnType.getName();
|
||||||
|
|
||||||
return TypeConverter.convert(val, columnType, type, typeString);
|
return TypeConverter.convert(val, columnType, type, typeString);
|
|
@ -3,9 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.protocol.JdbcColumnInfo;
|
|
||||||
|
|
||||||
import java.sql.ResultSetMetaData;
|
import java.sql.ResultSetMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
|
@ -7,13 +7,13 @@ package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
||||||
public class JdbcSQLException extends SQLException {
|
class JdbcSQLException extends SQLException {
|
||||||
|
|
||||||
public JdbcSQLException(String message) {
|
JdbcSQLException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public JdbcSQLException(Throwable cause, String message) {
|
JdbcSQLException(Throwable cause, String message) {
|
||||||
super(message, cause);
|
super(message, cause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,8 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.client.Cursor;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.net.client.RequestMeta;
|
|
||||||
import org.elasticsearch.xpack.sql.proto.SqlTypedParamValue;
|
import org.elasticsearch.xpack.sql.proto.SqlTypedParamValue;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Wrapper;
|
import java.sql.Wrapper;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.net.protocol;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.lang.annotation.Documented;
|
import java.lang.annotation.Documented;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
|
@ -19,5 +19,5 @@ import java.lang.annotation.Target;
|
||||||
@Documented
|
@Documented
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
|
@Target({ElementType.PARAMETER, ElementType.FIELD, ElementType.METHOD})
|
||||||
public @interface Nullable {
|
@interface Nullable {
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
final class ParameterMetaDataProxy extends DebuggingInvoker {
|
final class ParameterMetaDataProxy extends DebuggingInvoker {
|
||||||
|
|
|
@ -3,10 +3,8 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.JdbcSQLException;
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
import org.elasticsearch.xpack.sql.proto.SqlTypedParamValue;
|
import org.elasticsearch.xpack.sql.proto.SqlTypedParamValue;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
@ -17,10 +15,10 @@ import java.util.stream.Collectors;
|
||||||
class PreparedQuery {
|
class PreparedQuery {
|
||||||
|
|
||||||
static class ParamInfo {
|
static class ParamInfo {
|
||||||
DataType type;
|
EsType type;
|
||||||
Object value;
|
Object value;
|
||||||
|
|
||||||
ParamInfo(Object value, DataType type) {
|
ParamInfo(Object value, EsType type) {
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +40,7 @@ class PreparedQuery {
|
||||||
return params[param - 1];
|
return params[param - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
void setParam(int param, Object value, DataType type) throws JdbcSQLException {
|
void setParam(int param, Object value, EsType type) throws JdbcSQLException {
|
||||||
if (param < 1 || param > params.length) {
|
if (param < 1 || param > params.length) {
|
||||||
throw new JdbcSQLException("Invalid parameter index [" + param + "]");
|
throw new JdbcSQLException("Invalid parameter index [" + param + "]");
|
||||||
}
|
}
|
||||||
|
@ -56,7 +54,7 @@ class PreparedQuery {
|
||||||
|
|
||||||
void clearParams() {
|
void clearParams() {
|
||||||
for (int i = 0; i < params.length; i++) {
|
for (int i = 0; i < params.length; i++) {
|
||||||
params[i] = new ParamInfo(null, DataType.KEYWORD);
|
params[i] = new ParamInfo(null, EsType.KEYWORD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,44 +3,44 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.net.client;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
public class RequestMeta {
|
class RequestMeta {
|
||||||
|
|
||||||
private int fetchSize;
|
private int fetchSize;
|
||||||
private long timeoutInMs;
|
private long timeoutInMs;
|
||||||
private long queryTimeoutInMs;
|
private long queryTimeoutInMs;
|
||||||
|
|
||||||
public RequestMeta(int fetchSize, long timeout, long queryTimeoutInMs) {
|
RequestMeta(int fetchSize, long timeout, long queryTimeoutInMs) {
|
||||||
this.fetchSize = fetchSize;
|
this.fetchSize = fetchSize;
|
||||||
this.timeoutInMs = timeout;
|
this.timeoutInMs = timeout;
|
||||||
this.queryTimeoutInMs = queryTimeoutInMs;
|
this.queryTimeoutInMs = queryTimeoutInMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestMeta queryTimeout(long timeout) {
|
RequestMeta queryTimeout(long timeout) {
|
||||||
this.queryTimeoutInMs = timeout;
|
this.queryTimeoutInMs = timeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestMeta timeout(long timeout) {
|
RequestMeta timeout(long timeout) {
|
||||||
this.timeoutInMs = timeout;
|
this.timeoutInMs = timeout;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestMeta fetchSize(int size) {
|
RequestMeta fetchSize(int size) {
|
||||||
this.fetchSize = size;
|
this.fetchSize = size;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int fetchSize() {
|
int fetchSize() {
|
||||||
return fetchSize;
|
return fetchSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long timeoutInMs() {
|
long timeoutInMs() {
|
||||||
return timeoutInMs;
|
return timeoutInMs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long queryTimeoutInMs() {
|
long queryTimeoutInMs() {
|
||||||
return queryTimeoutInMs;
|
return queryTimeoutInMs;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
final class ResultSetMetaDataProxy extends DebuggingInvoker {
|
final class ResultSetMetaDataProxy extends DebuggingInvoker {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.ResultSetMetaData;
|
import java.sql.ResultSetMetaData;
|
||||||
import java.sql.Statement;
|
import java.sql.Statement;
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.debug;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import java.sql.Connection;
|
import java.sql.Connection;
|
||||||
import java.sql.ParameterMetaData;
|
import java.sql.ParameterMetaData;
|
|
@ -3,9 +3,7 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
|
|
||||||
import java.sql.Date;
|
import java.sql.Date;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
@ -115,7 +113,7 @@ final class TypeConverter {
|
||||||
* Converts object val from columnType to type
|
* Converts object val from columnType to type
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
static <T> T convert(Object val, DataType columnType, Class<T> type, String typeString) throws SQLException {
|
static <T> T convert(Object val, EsType columnType, Class<T> type, String typeString) throws SQLException {
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
return (T) convert(val, columnType, typeString);
|
return (T) convert(val, columnType, typeString);
|
||||||
}
|
}
|
||||||
|
@ -123,7 +121,7 @@ final class TypeConverter {
|
||||||
// converting a Long to a Timestamp shouldn't be possible according to the spec,
|
// converting a Long to a Timestamp shouldn't be possible according to the spec,
|
||||||
// it feels a little brittle to check this scenario here and I don't particularly like it
|
// it feels a little brittle to check this scenario here and I don't particularly like it
|
||||||
// TODO: can we do any better or should we go over the spec and allow getLong(date) to be valid?
|
// TODO: can we do any better or should we go over the spec and allow getLong(date) to be valid?
|
||||||
if (!(type == Long.class && columnType == DataType.DATE) && type.isInstance(val)) {
|
if (!(type == Long.class && columnType == EsType.DATE) && type.isInstance(val)) {
|
||||||
try {
|
try {
|
||||||
return type.cast(val);
|
return type.cast(val);
|
||||||
} catch (ClassCastException cce) {
|
} catch (ClassCastException cce) {
|
||||||
|
@ -192,7 +190,7 @@ final class TypeConverter {
|
||||||
/**
|
/**
|
||||||
* Converts the object from JSON representation to the specified JDBCType
|
* Converts the object from JSON representation to the specified JDBCType
|
||||||
*/
|
*/
|
||||||
static Object convert(Object v, DataType columnType, String typeString) throws SQLException {
|
static Object convert(Object v, EsType columnType, String typeString) throws SQLException {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case NULL:
|
case NULL:
|
||||||
return null;
|
return null;
|
||||||
|
@ -273,18 +271,18 @@ final class TypeConverter {
|
||||||
return nativeValue == null ? null : String.valueOf(nativeValue);
|
return nativeValue == null ? null : String.valueOf(nativeValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> T failConversion(Object value, DataType columnType, String typeString, Class<T> target) throws SQLException {
|
private static <T> T failConversion(Object value, EsType columnType, String typeString, Class<T> target) throws SQLException {
|
||||||
return failConversion(value, columnType, typeString, target, null);
|
return failConversion(value, columnType, typeString, target, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static <T> T failConversion(Object value, DataType columnType, String typeString, Class<T> target, Exception e)
|
private static <T> T failConversion(Object value, EsType columnType, String typeString, Class<T> target, Exception e)
|
||||||
throws SQLException {
|
throws SQLException {
|
||||||
String message = format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to [%s]", value, columnType,
|
String message = format(Locale.ROOT, "Unable to convert value [%.128s] of type [%s] to [%s]", value, columnType,
|
||||||
typeString);
|
typeString);
|
||||||
throw e != null ? new SQLException(message, e) : new SQLException(message);
|
throw e != null ? new SQLException(message, e) : new SQLException(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Boolean asBoolean(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Boolean asBoolean(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
case BYTE:
|
case BYTE:
|
||||||
|
@ -304,7 +302,7 @@ final class TypeConverter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Byte asByte(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Byte asByte(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
return Byte.valueOf(((Boolean) val).booleanValue() ? (byte) 1 : (byte) 0);
|
return Byte.valueOf(((Boolean) val).booleanValue() ? (byte) 1 : (byte) 0);
|
||||||
|
@ -331,7 +329,7 @@ final class TypeConverter {
|
||||||
return failConversion(val, columnType, typeString, Byte.class);
|
return failConversion(val, columnType, typeString, Byte.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Short asShort(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Short asShort(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
return Short.valueOf(((Boolean) val).booleanValue() ? (short) 1 : (short) 0);
|
return Short.valueOf(((Boolean) val).booleanValue() ? (short) 1 : (short) 0);
|
||||||
|
@ -357,7 +355,7 @@ final class TypeConverter {
|
||||||
return failConversion(val, columnType, typeString, Short.class);
|
return failConversion(val, columnType, typeString, Short.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Integer asInteger(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Integer asInteger(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
return Integer.valueOf(((Boolean) val).booleanValue() ? 1 : 0);
|
return Integer.valueOf(((Boolean) val).booleanValue() ? 1 : 0);
|
||||||
|
@ -383,7 +381,7 @@ final class TypeConverter {
|
||||||
return failConversion(val, columnType, typeString, Integer.class);
|
return failConversion(val, columnType, typeString, Integer.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Long asLong(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Long asLong(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
return Long.valueOf(((Boolean) val).booleanValue() ? 1 : 0);
|
return Long.valueOf(((Boolean) val).booleanValue() ? 1 : 0);
|
||||||
|
@ -415,7 +413,7 @@ final class TypeConverter {
|
||||||
return failConversion(val, columnType, typeString, Long.class);
|
return failConversion(val, columnType, typeString, Long.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Float asFloat(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Float asFloat(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
return Float.valueOf(((Boolean) val).booleanValue() ? 1 : 0);
|
return Float.valueOf(((Boolean) val).booleanValue() ? 1 : 0);
|
||||||
|
@ -441,7 +439,7 @@ final class TypeConverter {
|
||||||
return failConversion(val, columnType, typeString, Float.class);
|
return failConversion(val, columnType, typeString, Float.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Double asDouble(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Double asDouble(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
switch (columnType) {
|
switch (columnType) {
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
return Double.valueOf(((Boolean) val).booleanValue() ? 1 : 0);
|
return Double.valueOf(((Boolean) val).booleanValue() ? 1 : 0);
|
||||||
|
@ -467,48 +465,48 @@ final class TypeConverter {
|
||||||
return failConversion(val, columnType, typeString, Double.class);
|
return failConversion(val, columnType, typeString, Double.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Date asDate(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Date asDate(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
if (columnType == DataType.DATE) {
|
if (columnType == EsType.DATE) {
|
||||||
return new Date(utcMillisRemoveTime(((Number) val).longValue()));
|
return new Date(utcMillisRemoveTime(((Number) val).longValue()));
|
||||||
}
|
}
|
||||||
return failConversion(val, columnType, typeString, Date.class);
|
return failConversion(val, columnType, typeString, Date.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Time asTime(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Time asTime(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
if (columnType == DataType.DATE) {
|
if (columnType == EsType.DATE) {
|
||||||
return new Time(utcMillisRemoveDate(((Number) val).longValue()));
|
return new Time(utcMillisRemoveDate(((Number) val).longValue()));
|
||||||
}
|
}
|
||||||
return failConversion(val, columnType, typeString, Time.class);
|
return failConversion(val, columnType, typeString, Time.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Timestamp asTimestamp(Object val, DataType columnType, String typeString) throws SQLException {
|
private static Timestamp asTimestamp(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
if (columnType == DataType.DATE) {
|
if (columnType == EsType.DATE) {
|
||||||
return new Timestamp(((Number) val).longValue());
|
return new Timestamp(((Number) val).longValue());
|
||||||
}
|
}
|
||||||
return failConversion(val, columnType, typeString, Timestamp.class);
|
return failConversion(val, columnType, typeString, Timestamp.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static byte[] asByteArray(Object val, DataType columnType, String typeString) throws SQLException {
|
private static byte[] asByteArray(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException();
|
throw new SQLFeatureNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalDate asLocalDate(Object val, DataType columnType, String typeString) throws SQLException {
|
private static LocalDate asLocalDate(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException();
|
throw new SQLFeatureNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalTime asLocalTime(Object val, DataType columnType, String typeString) throws SQLException {
|
private static LocalTime asLocalTime(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException();
|
throw new SQLFeatureNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static LocalDateTime asLocalDateTime(Object val, DataType columnType, String typeString) throws SQLException {
|
private static LocalDateTime asLocalDateTime(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException();
|
throw new SQLFeatureNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OffsetTime asOffsetTime(Object val, DataType columnType, String typeString) throws SQLException {
|
private static OffsetTime asOffsetTime(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException();
|
throw new SQLFeatureNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static OffsetDateTime asOffsetDateTime(Object val, DataType columnType, String typeString) throws SQLException {
|
private static OffsetDateTime asOffsetDateTime(Object val, EsType columnType, String typeString) throws SQLException {
|
||||||
throw new SQLFeatureNotSupportedException();
|
throw new SQLFeatureNotSupportedException();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,175 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
|
import java.sql.JDBCType;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.SQLFeatureNotSupportedException;
|
||||||
|
import java.sql.SQLType;
|
||||||
|
import java.sql.Timestamp;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.Period;
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.GregorianCalendar;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static java.util.Collections.unmodifiableMap;
|
||||||
|
|
||||||
|
final class TypeUtils {
|
||||||
|
|
||||||
|
private TypeUtils() {}
|
||||||
|
|
||||||
|
private static final Map<Class<?>, EsType> CLASS_TO_TYPE;
|
||||||
|
private static final Map<EsType, Class<?>> TYPE_TO_CLASS;
|
||||||
|
private static final Map<String, EsType> ENUM_NAME_TO_TYPE;
|
||||||
|
private static final Map<Integer, EsType> SQL_TO_TYPE;
|
||||||
|
|
||||||
|
private static final Set<EsType> SIGNED_TYPE = EnumSet.of(EsType.BYTE,
|
||||||
|
EsType.SHORT, EsType.INTEGER, EsType.LONG,
|
||||||
|
EsType.FLOAT, EsType.HALF_FLOAT, EsType.SCALED_FLOAT, EsType.DOUBLE, EsType.DATE);
|
||||||
|
|
||||||
|
|
||||||
|
static {
|
||||||
|
Map<Class<?>, EsType> aMap = new LinkedHashMap<>();
|
||||||
|
aMap.put(Boolean.class, EsType.BOOLEAN);
|
||||||
|
aMap.put(Byte.class, EsType.BYTE);
|
||||||
|
aMap.put(Short.class, EsType.SHORT);
|
||||||
|
aMap.put(Integer.class, EsType.INTEGER);
|
||||||
|
aMap.put(Long.class, EsType.LONG);
|
||||||
|
aMap.put(Float.class, EsType.FLOAT);
|
||||||
|
aMap.put(Double.class, EsType.DOUBLE);
|
||||||
|
aMap.put(String.class, EsType.KEYWORD);
|
||||||
|
aMap.put(byte[].class, EsType.BINARY);
|
||||||
|
aMap.put(String.class, EsType.KEYWORD);
|
||||||
|
aMap.put(Timestamp.class, EsType.DATE);
|
||||||
|
|
||||||
|
// apart from the mappings in {@code DataType} three more Java classes can be mapped to a {@code JDBCType.TIMESTAMP}
|
||||||
|
// according to B-4 table from the jdbc4.2 spec
|
||||||
|
aMap.put(Calendar.class, EsType.DATE);
|
||||||
|
aMap.put(GregorianCalendar.class, EsType.DATE);
|
||||||
|
aMap.put(java.util.Date.class, EsType.DATE);
|
||||||
|
aMap.put(java.sql.Date.class, EsType.DATE);
|
||||||
|
aMap.put(java.sql.Time.class, EsType.DATE);
|
||||||
|
aMap.put(LocalDateTime.class, EsType.DATE);
|
||||||
|
CLASS_TO_TYPE = Collections.unmodifiableMap(aMap);
|
||||||
|
|
||||||
|
Map<EsType, Class<?>> types = new LinkedHashMap<>();
|
||||||
|
types.put(EsType.BOOLEAN, Boolean.class);
|
||||||
|
types.put(EsType.BYTE, Byte.class);
|
||||||
|
types.put(EsType.SHORT, Short.class);
|
||||||
|
types.put(EsType.INTEGER, Integer.class);
|
||||||
|
types.put(EsType.LONG, Long.class);
|
||||||
|
types.put(EsType.DOUBLE, Double.class);
|
||||||
|
types.put(EsType.FLOAT, Float.class);
|
||||||
|
types.put(EsType.HALF_FLOAT, Double.class);
|
||||||
|
types.put(EsType.SCALED_FLOAT, Double.class);
|
||||||
|
types.put(EsType.KEYWORD, String.class);
|
||||||
|
types.put(EsType.TEXT, String.class);
|
||||||
|
types.put(EsType.BINARY, byte[].class);
|
||||||
|
types.put(EsType.DATE, Timestamp.class);
|
||||||
|
types.put(EsType.IP, String.class);
|
||||||
|
types.put(EsType.INTERVAL_YEAR, Period.class);
|
||||||
|
types.put(EsType.INTERVAL_MONTH, Period.class);
|
||||||
|
types.put(EsType.INTERVAL_YEAR_TO_MONTH, Period.class);
|
||||||
|
types.put(EsType.INTERVAL_DAY, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_HOUR, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_MINUTE, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_SECOND, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_DAY_TO_HOUR, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_DAY_TO_MINUTE, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_DAY_TO_SECOND, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_HOUR_TO_MINUTE, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_HOUR_TO_SECOND, Duration.class);
|
||||||
|
types.put(EsType.INTERVAL_MINUTE_TO_SECOND, Duration.class);
|
||||||
|
|
||||||
|
TYPE_TO_CLASS = unmodifiableMap(types);
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, EsType> strings = new LinkedHashMap<>();
|
||||||
|
Map<Integer, EsType> numbers = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
for (EsType dataType : EsType.values()) {
|
||||||
|
strings.put(dataType.getName().toLowerCase(Locale.ROOT), dataType);
|
||||||
|
numbers.putIfAbsent(dataType.getVendorTypeNumber(), dataType);
|
||||||
|
}
|
||||||
|
|
||||||
|
ENUM_NAME_TO_TYPE = unmodifiableMap(strings);
|
||||||
|
SQL_TO_TYPE = unmodifiableMap(numbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isSigned(EsType type) {
|
||||||
|
return SIGNED_TYPE.contains(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Class<?> classOf(EsType type) {
|
||||||
|
return TYPE_TO_CLASS.get(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
static SQLType asSqlType(int sqlType) throws SQLException {
|
||||||
|
for (JDBCType jdbcType : JDBCType.class.getEnumConstants()) {
|
||||||
|
if (sqlType == jdbcType.getVendorTypeNumber().intValue()) {
|
||||||
|
return jdbcType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// fallback to DataType
|
||||||
|
return of(sqlType);
|
||||||
|
}
|
||||||
|
|
||||||
|
static EsType of(SQLType sqlType) throws SQLException {
|
||||||
|
if (sqlType instanceof EsType) {
|
||||||
|
return (EsType) sqlType;
|
||||||
|
}
|
||||||
|
EsType dataType = SQL_TO_TYPE.get(Integer.valueOf(sqlType.getVendorTypeNumber()));
|
||||||
|
if (dataType == null) {
|
||||||
|
throw new SQLFeatureNotSupportedException("Unsupported SQL type [" + sqlType + "]");
|
||||||
|
}
|
||||||
|
return dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EsType of(int sqlType) throws SQLException {
|
||||||
|
EsType dataType = SQL_TO_TYPE.get(Integer.valueOf(sqlType));
|
||||||
|
if (dataType == null) {
|
||||||
|
throw new SQLFeatureNotSupportedException("Unsupported SQL type [" + sqlType + "]");
|
||||||
|
}
|
||||||
|
return dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EsType of(String name) throws SQLException {
|
||||||
|
EsType dataType = ENUM_NAME_TO_TYPE.get(name);
|
||||||
|
if (dataType == null) {
|
||||||
|
throw new SQLFeatureNotSupportedException("Unsupported Data type [" + name + "]");
|
||||||
|
}
|
||||||
|
return dataType;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isString(EsType dataType) {
|
||||||
|
return dataType == EsType.KEYWORD || dataType == EsType.TEXT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static EsType of(Class<? extends Object> clazz) throws SQLException {
|
||||||
|
EsType dataType = CLASS_TO_TYPE.get(clazz);
|
||||||
|
|
||||||
|
if (dataType == null) {
|
||||||
|
// fall-back to iteration for checking class hierarchies (in case of custom objects)
|
||||||
|
for (Entry<Class<?>, EsType> e : CLASS_TO_TYPE.entrySet()) {
|
||||||
|
if (e.getKey().isAssignableFrom(clazz)) {
|
||||||
|
return e.getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new SQLFeatureNotSupportedException("Objects of type [" + clazz.getName() + "] are not supported");
|
||||||
|
}
|
||||||
|
return dataType;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,177 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
|
|
||||||
import java.sql.JDBCType;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.sql.SQLFeatureNotSupportedException;
|
|
||||||
import java.sql.SQLType;
|
|
||||||
import java.sql.Timestamp;
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import java.time.Period;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.EnumSet;
|
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static java.util.Collections.unmodifiableMap;
|
|
||||||
|
|
||||||
public class TypeUtils {
|
|
||||||
|
|
||||||
private TypeUtils() {}
|
|
||||||
|
|
||||||
private static final Map<Class<?>, DataType> CLASS_TO_TYPE;
|
|
||||||
private static final Map<DataType, Class<?>> TYPE_TO_CLASS;
|
|
||||||
private static final Map<String, DataType> ENUM_NAME_TO_TYPE;
|
|
||||||
private static final Map<Integer, DataType> SQL_TO_TYPE;
|
|
||||||
|
|
||||||
private static final Set<DataType> SIGNED_TYPE = EnumSet.of(DataType.BYTE,
|
|
||||||
DataType.SHORT, DataType.INTEGER, DataType.LONG,
|
|
||||||
DataType.FLOAT, DataType.HALF_FLOAT, DataType.SCALED_FLOAT, DataType.DOUBLE, DataType.DATE);
|
|
||||||
|
|
||||||
|
|
||||||
static {
|
|
||||||
Map<Class<?>, DataType> aMap = new LinkedHashMap<>();
|
|
||||||
aMap.put(Boolean.class, DataType.BOOLEAN);
|
|
||||||
aMap.put(Byte.class, DataType.BYTE);
|
|
||||||
aMap.put(Short.class, DataType.SHORT);
|
|
||||||
aMap.put(Integer.class, DataType.INTEGER);
|
|
||||||
aMap.put(Long.class, DataType.LONG);
|
|
||||||
aMap.put(Float.class, DataType.FLOAT);
|
|
||||||
aMap.put(Double.class, DataType.DOUBLE);
|
|
||||||
aMap.put(String.class, DataType.KEYWORD);
|
|
||||||
aMap.put(byte[].class, DataType.BINARY);
|
|
||||||
aMap.put(String.class, DataType.KEYWORD);
|
|
||||||
aMap.put(Timestamp.class, DataType.DATE);
|
|
||||||
|
|
||||||
// apart from the mappings in {@code DataType} three more Java classes can be mapped to a {@code JDBCType.TIMESTAMP}
|
|
||||||
// according to B-4 table from the jdbc4.2 spec
|
|
||||||
aMap.put(Calendar.class, DataType.DATE);
|
|
||||||
aMap.put(GregorianCalendar.class, DataType.DATE);
|
|
||||||
aMap.put(java.util.Date.class, DataType.DATE);
|
|
||||||
aMap.put(java.sql.Date.class, DataType.DATE);
|
|
||||||
aMap.put(java.sql.Time.class, DataType.DATE);
|
|
||||||
aMap.put(LocalDateTime.class, DataType.DATE);
|
|
||||||
CLASS_TO_TYPE = Collections.unmodifiableMap(aMap);
|
|
||||||
|
|
||||||
Map<DataType, Class<?>> types = new LinkedHashMap<>();
|
|
||||||
types.put(DataType.BOOLEAN, Boolean.class);
|
|
||||||
types.put(DataType.BYTE, Byte.class);
|
|
||||||
types.put(DataType.SHORT, Short.class);
|
|
||||||
types.put(DataType.INTEGER, Integer.class);
|
|
||||||
types.put(DataType.LONG, Long.class);
|
|
||||||
types.put(DataType.DOUBLE, Double.class);
|
|
||||||
types.put(DataType.FLOAT, Float.class);
|
|
||||||
types.put(DataType.HALF_FLOAT, Double.class);
|
|
||||||
types.put(DataType.SCALED_FLOAT, Double.class);
|
|
||||||
types.put(DataType.KEYWORD, String.class);
|
|
||||||
types.put(DataType.TEXT, String.class);
|
|
||||||
types.put(DataType.BINARY, byte[].class);
|
|
||||||
types.put(DataType.DATE, Timestamp.class);
|
|
||||||
types.put(DataType.IP, String.class);
|
|
||||||
types.put(DataType.INTERVAL_YEAR, Period.class);
|
|
||||||
types.put(DataType.INTERVAL_MONTH, Period.class);
|
|
||||||
types.put(DataType.INTERVAL_YEAR_TO_MONTH, Period.class);
|
|
||||||
types.put(DataType.INTERVAL_DAY, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_HOUR, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_MINUTE, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_SECOND, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_DAY_TO_HOUR, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_DAY_TO_MINUTE, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_DAY_TO_SECOND, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_HOUR_TO_MINUTE, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_HOUR_TO_SECOND, Duration.class);
|
|
||||||
types.put(DataType.INTERVAL_MINUTE_TO_SECOND, Duration.class);
|
|
||||||
|
|
||||||
TYPE_TO_CLASS = unmodifiableMap(types);
|
|
||||||
|
|
||||||
|
|
||||||
Map<String, DataType> strings = new LinkedHashMap<>();
|
|
||||||
Map<Integer, DataType> numbers = new LinkedHashMap<>();
|
|
||||||
|
|
||||||
for (DataType dataType : DataType.values()) {
|
|
||||||
strings.put(dataType.getName().toLowerCase(Locale.ROOT), dataType);
|
|
||||||
numbers.putIfAbsent(dataType.getVendorTypeNumber(), dataType);
|
|
||||||
}
|
|
||||||
|
|
||||||
ENUM_NAME_TO_TYPE = unmodifiableMap(strings);
|
|
||||||
SQL_TO_TYPE = unmodifiableMap(numbers);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isSigned(DataType type) {
|
|
||||||
return SIGNED_TYPE.contains(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
static Class<?> classOf(DataType type) {
|
|
||||||
return TYPE_TO_CLASS.get(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
static SQLType asSqlType(int sqlType) throws SQLException {
|
|
||||||
for (JDBCType jdbcType : JDBCType.class.getEnumConstants()) {
|
|
||||||
if (sqlType == jdbcType.getVendorTypeNumber().intValue()) {
|
|
||||||
return jdbcType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// fallback to DataType
|
|
||||||
return of(sqlType);
|
|
||||||
}
|
|
||||||
|
|
||||||
static DataType of(SQLType sqlType) throws SQLException {
|
|
||||||
if (sqlType instanceof DataType) {
|
|
||||||
return (DataType) sqlType;
|
|
||||||
}
|
|
||||||
DataType dataType = SQL_TO_TYPE.get(Integer.valueOf(sqlType.getVendorTypeNumber()));
|
|
||||||
if (dataType == null) {
|
|
||||||
throw new SQLFeatureNotSupportedException("Unsupported SQL type [" + sqlType + "]");
|
|
||||||
}
|
|
||||||
return dataType;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DataType of(int sqlType) throws SQLException {
|
|
||||||
DataType dataType = SQL_TO_TYPE.get(Integer.valueOf(sqlType));
|
|
||||||
if (dataType == null) {
|
|
||||||
throw new SQLFeatureNotSupportedException("Unsupported SQL type [" + sqlType + "]");
|
|
||||||
}
|
|
||||||
return dataType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DataType of(String name) throws SQLException {
|
|
||||||
DataType dataType = ENUM_NAME_TO_TYPE.get(name);
|
|
||||||
if (dataType == null) {
|
|
||||||
throw new SQLFeatureNotSupportedException("Unsupported Data type [" + name + "]");
|
|
||||||
}
|
|
||||||
return dataType;
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean isString(DataType dataType) {
|
|
||||||
return dataType == DataType.KEYWORD || dataType == DataType.TEXT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static DataType of(Class<? extends Object> clazz) throws SQLException {
|
|
||||||
DataType dataType = CLASS_TO_TYPE.get(clazz);
|
|
||||||
|
|
||||||
if (dataType == null) {
|
|
||||||
// fall-back to iteration for checking class hierarchies (in case of custom objects)
|
|
||||||
for (Entry<Class<?>, DataType> e : CLASS_TO_TYPE.entrySet()) {
|
|
||||||
if (e.getKey().isAssignableFrom(clazz)) {
|
|
||||||
return e.getValue();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new SQLFeatureNotSupportedException("Objects of type [" + clazz.getName() + "] are not supported");
|
|
||||||
}
|
|
||||||
return dataType;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1 +1 @@
|
||||||
org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcDriver
|
org.elasticsearch.xpack.sql.jdbc.EsDriver
|
|
@ -3,31 +3,32 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.net.protocol;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
import org.elasticsearch.xpack.sql.jdbc.EsType;
|
||||||
|
import org.elasticsearch.xpack.sql.jdbc.JdbcColumnInfo;
|
||||||
|
|
||||||
import static org.elasticsearch.xpack.sql.client.StringUtils.EMPTY;
|
import static org.elasticsearch.xpack.sql.client.StringUtils.EMPTY;
|
||||||
|
|
||||||
public class ColumnInfoTests extends ESTestCase {
|
public class ColumnInfoTests extends ESTestCase {
|
||||||
static JdbcColumnInfo varcharInfo(String name) {
|
static JdbcColumnInfo varcharInfo(String name) {
|
||||||
return new JdbcColumnInfo(name, DataType.KEYWORD, EMPTY, EMPTY, EMPTY, EMPTY, 0);
|
return new JdbcColumnInfo(name, EsType.KEYWORD, EMPTY, EMPTY, EMPTY, EMPTY, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JdbcColumnInfo intInfo(String name) {
|
static JdbcColumnInfo intInfo(String name) {
|
||||||
return new JdbcColumnInfo(name, DataType.INTEGER, EMPTY, EMPTY, EMPTY, EMPTY, 11);
|
return new JdbcColumnInfo(name, EsType.INTEGER, EMPTY, EMPTY, EMPTY, EMPTY, 11);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JdbcColumnInfo doubleInfo(String name) {
|
static JdbcColumnInfo doubleInfo(String name) {
|
||||||
return new JdbcColumnInfo(name, DataType.DOUBLE, EMPTY, EMPTY, EMPTY, EMPTY, 25);
|
return new JdbcColumnInfo(name, EsType.DOUBLE, EMPTY, EMPTY, EMPTY, EMPTY, 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testToString() {
|
public void testToString() {
|
||||||
assertEquals("test.doc.a<type=[KEYWORD] catalog=[as] schema=[ads] label=[lab]>",
|
assertEquals("test.doc.a<type=[KEYWORD] catalog=[as] schema=[ads] label=[lab]>",
|
||||||
new JdbcColumnInfo("a", DataType.KEYWORD, "test.doc", "as", "ads", "lab", 0).toString());
|
new JdbcColumnInfo("a", EsType.KEYWORD, "test.doc", "as", "ads", "lab", 0).toString());
|
||||||
assertEquals("test.doc.a<type=[KEYWORD]>",
|
assertEquals("test.doc.a<type=[KEYWORD]>",
|
||||||
new JdbcColumnInfo("a", DataType.KEYWORD, "test.doc", EMPTY, EMPTY, EMPTY, 0).toString());
|
new JdbcColumnInfo("a", EsType.KEYWORD, "test.doc", EMPTY, EMPTY, EMPTY, 0).toString());
|
||||||
assertEquals("string<type=[KEYWORD]>", varcharInfo("string").toString());
|
assertEquals("string<type=[KEYWORD]>", varcharInfo("string").toString());
|
||||||
assertEquals("int<type=[INTEGER]>", intInfo("int").toString());
|
assertEquals("int<type=[INTEGER]>", intInfo("int").toString());
|
||||||
assertEquals("d<type=[DOUBLE]>", doubleInfo("d").toString());
|
assertEquals("d<type=[DOUBLE]>", doubleInfo("d").toString());
|
|
@ -7,7 +7,6 @@ package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.Version;
|
import org.elasticsearch.Version;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcDriver;
|
|
||||||
|
|
||||||
import java.security.AccessController;
|
import java.security.AccessController;
|
||||||
import java.security.PrivilegedExceptionAction;
|
import java.security.PrivilegedExceptionAction;
|
||||||
|
@ -32,7 +31,7 @@ public class DriverManagerRegistrationTests extends ESTestCase {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void driverManagerTemplate(Consumer<JdbcDriver> c) throws Exception {
|
private static void driverManagerTemplate(Consumer<EsDriver> c) throws Exception {
|
||||||
String url = "jdbc:es:localhost:9200/";
|
String url = "jdbc:es:localhost:9200/";
|
||||||
Driver driver = null;
|
Driver driver = null;
|
||||||
try {
|
try {
|
||||||
|
@ -44,7 +43,7 @@ public class DriverManagerRegistrationTests extends ESTestCase {
|
||||||
boolean set = driver != null;
|
boolean set = driver != null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
JdbcDriver d = JdbcDriver.register();
|
EsDriver d = EsDriver.register();
|
||||||
if (driver != null) {
|
if (driver != null) {
|
||||||
assertEquals(driver, d);
|
assertEquals(driver, d);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +52,7 @@ public class DriverManagerRegistrationTests extends ESTestCase {
|
||||||
|
|
||||||
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> {
|
||||||
// mimic DriverManager and unregister the driver
|
// mimic DriverManager and unregister the driver
|
||||||
JdbcDriver.deregister();
|
EsDriver.deregister();
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -61,7 +60,7 @@ public class DriverManagerRegistrationTests extends ESTestCase {
|
||||||
assertEquals("No suitable driver", ex.getMessage());
|
assertEquals("No suitable driver", ex.getMessage());
|
||||||
} finally {
|
} finally {
|
||||||
if (set) {
|
if (set) {
|
||||||
JdbcDriver.register();
|
EsDriver.register();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
package org.elasticsearch.xpack.sql.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConfiguration;
|
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
|
@ -4,9 +4,10 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
import org.elasticsearch.xpack.sql.jdbc.JdbcDatabaseMetaData;
|
||||||
|
|
||||||
public class JdbcDatabaseMetaDataTests extends ESTestCase {
|
public class JdbcDatabaseMetaDataTests extends ESTestCase {
|
||||||
|
|
|
@ -3,10 +3,12 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
import org.elasticsearch.xpack.sql.jdbc.EsType;
|
||||||
|
import org.elasticsearch.xpack.sql.jdbc.JdbcConfiguration;
|
||||||
|
import org.elasticsearch.xpack.sql.jdbc.JdbcPreparedStatement;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
@ -26,17 +28,17 @@ import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import static java.lang.String.format;
|
import static java.lang.String.format;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.BINARY;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.BINARY;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.BOOLEAN;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.BOOLEAN;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.BYTE;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.BYTE;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.DATE;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.DATE;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.DOUBLE;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.DOUBLE;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.FLOAT;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.FLOAT;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.HALF_FLOAT;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.HALF_FLOAT;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.INTEGER;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.INTEGER;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.KEYWORD;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.KEYWORD;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.LONG;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.LONG;
|
||||||
import static org.elasticsearch.xpack.sql.jdbc.type.DataType.SHORT;
|
import static org.elasticsearch.xpack.sql.jdbc.EsType.SHORT;
|
||||||
|
|
||||||
public class JdbcPreparedStatementTests extends ESTestCase {
|
public class JdbcPreparedStatementTests extends ESTestCase {
|
||||||
|
|
||||||
|
@ -560,10 +562,10 @@ public class JdbcPreparedStatementTests extends ESTestCase {
|
||||||
JdbcPreparedStatement jps = createJdbcPreparedStatement();
|
JdbcPreparedStatement jps = createJdbcPreparedStatement();
|
||||||
byte[] buffer = "foo".getBytes(StandardCharsets.UTF_8);
|
byte[] buffer = "foo".getBytes(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class, () -> jps.setObject(1, buffer, DataType.KEYWORD));
|
SQLException sqle = expectThrows(SQLFeatureNotSupportedException.class, () -> jps.setObject(1, buffer, EsType.KEYWORD));
|
||||||
assertEquals("Conversion from type [byte[]] to [KEYWORD] not supported", sqle.getMessage());
|
assertEquals("Conversion from type [byte[]] to [KEYWORD] not supported", sqle.getMessage());
|
||||||
|
|
||||||
sqle = expectThrows(SQLFeatureNotSupportedException.class, () -> jps.setObject(1, buffer, DataType.INTERVAL_DAY_TO_MINUTE));
|
sqle = expectThrows(SQLFeatureNotSupportedException.class, () -> jps.setObject(1, buffer, EsType.INTERVAL_DAY_TO_MINUTE));
|
||||||
assertEquals("Conversion from type [byte[]] to [INTERVAL_DAY_TO_MINUTE] not supported", sqle.getMessage());
|
assertEquals("Conversion from type [byte[]] to [INTERVAL_DAY_TO_MINUTE] not supported", sqle.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -571,7 +573,7 @@ public class JdbcPreparedStatementTests extends ESTestCase {
|
||||||
return new JdbcPreparedStatement(null, JdbcConfiguration.create("jdbc:es://l:1", null, 0), "?");
|
return new JdbcPreparedStatement(null, JdbcConfiguration.create("jdbc:es://l:1", null, 0), "?");
|
||||||
}
|
}
|
||||||
|
|
||||||
private DataType jdbcType(JdbcPreparedStatement jps) throws SQLException {
|
private EsType jdbcType(JdbcPreparedStatement jps) throws SQLException {
|
||||||
return jps.query.getParam(1).type;
|
return jps.query.getParam(1).type;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,10 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
|
import org.elasticsearch.xpack.sql.jdbc.SqlQueryParameterAnalyzer;
|
||||||
|
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
|
|
|
@ -3,14 +3,13 @@
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
package org.elasticsearch.xpack.sql.jdbc.jdbc;
|
package org.elasticsearch.xpack.sql.jdbc;
|
||||||
|
|
||||||
import org.elasticsearch.common.bytes.BytesReference;
|
import org.elasticsearch.common.bytes.BytesReference;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.test.ESTestCase;
|
import org.elasticsearch.test.ESTestCase;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
import org.joda.time.DateTime;
|
import org.joda.time.DateTime;
|
||||||
import org.joda.time.ReadableDateTime;
|
import org.joda.time.ReadableDateTime;
|
||||||
|
|
||||||
|
@ -23,16 +22,16 @@ public class TypeConverterTests extends ESTestCase {
|
||||||
|
|
||||||
|
|
||||||
public void testFloatAsNative() throws Exception {
|
public void testFloatAsNative() throws Exception {
|
||||||
assertThat(convertAsNative(42.0f, DataType.FLOAT), instanceOf(Float.class));
|
assertThat(convertAsNative(42.0f, EsType.FLOAT), instanceOf(Float.class));
|
||||||
assertThat(convertAsNative(42.0, DataType.FLOAT), instanceOf(Float.class));
|
assertThat(convertAsNative(42.0, EsType.FLOAT), instanceOf(Float.class));
|
||||||
assertEquals(42.0f, (float) convertAsNative(42.0, DataType.FLOAT), 0.001f);
|
assertEquals(42.0f, (float) convertAsNative(42.0, EsType.FLOAT), 0.001f);
|
||||||
assertEquals(Float.NaN, convertAsNative(Float.NaN, DataType.FLOAT));
|
assertEquals(Float.NaN, convertAsNative(Float.NaN, EsType.FLOAT));
|
||||||
assertEquals(Float.NEGATIVE_INFINITY, convertAsNative(Float.NEGATIVE_INFINITY, DataType.FLOAT));
|
assertEquals(Float.NEGATIVE_INFINITY, convertAsNative(Float.NEGATIVE_INFINITY, EsType.FLOAT));
|
||||||
assertEquals(Float.POSITIVE_INFINITY, convertAsNative(Float.POSITIVE_INFINITY, DataType.FLOAT));
|
assertEquals(Float.POSITIVE_INFINITY, convertAsNative(Float.POSITIVE_INFINITY, EsType.FLOAT));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testDoubleAsNative() throws Exception {
|
public void testDoubleAsNative() throws Exception {
|
||||||
DataType type = randomFrom(DataType.HALF_FLOAT, DataType.SCALED_FLOAT, DataType.DOUBLE);
|
EsType type = randomFrom(EsType.HALF_FLOAT, EsType.SCALED_FLOAT, EsType.DOUBLE);
|
||||||
assertThat(convertAsNative(42.0, type), instanceOf(Double.class));
|
assertThat(convertAsNative(42.0, type), instanceOf(Double.class));
|
||||||
assertEquals(42.0f, (double) convertAsNative(42.0, type), 0.001f);
|
assertEquals(42.0f, (double) convertAsNative(42.0, type), 0.001f);
|
||||||
assertEquals(Double.NaN, convertAsNative(Double.NaN, type));
|
assertEquals(Double.NaN, convertAsNative(Double.NaN, type));
|
||||||
|
@ -42,11 +41,11 @@ public class TypeConverterTests extends ESTestCase {
|
||||||
|
|
||||||
public void testTimestampAsNative() throws Exception {
|
public void testTimestampAsNative() throws Exception {
|
||||||
DateTime now = DateTime.now();
|
DateTime now = DateTime.now();
|
||||||
assertThat(convertAsNative(now, DataType.DATE), instanceOf(Timestamp.class));
|
assertThat(convertAsNative(now, EsType.DATE), instanceOf(Timestamp.class));
|
||||||
assertEquals(now.getMillis(), ((Timestamp) convertAsNative(now, DataType.DATE)).getTime());
|
assertEquals(now.getMillis(), ((Timestamp) convertAsNative(now, EsType.DATE)).getTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
private Object convertAsNative(Object value, DataType type) throws Exception {
|
private Object convertAsNative(Object value, EsType type) throws Exception {
|
||||||
// Simulate sending over XContent
|
// Simulate sending over XContent
|
||||||
XContentBuilder builder = JsonXContent.contentBuilder();
|
XContentBuilder builder = JsonXContent.contentBuilder();
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
|
@ -61,5 +60,4 @@ public class TypeConverterTests extends ESTestCase {
|
||||||
Object copy = XContentHelper.convertToMap(BytesReference.bytes(builder), false, builder.contentType()).v2().get("value");
|
Object copy = XContentHelper.convertToMap(BytesReference.bytes(builder), false, builder.contentType()).v2().get("value");
|
||||||
return TypeConverter.convert(copy, type, type.toString());
|
return TypeConverter.convert(copy, type, type.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -8,7 +8,7 @@ package org.elasticsearch.xpack.sql.qa.jdbc;
|
||||||
import com.carrotsearch.hppc.IntObjectHashMap;
|
import com.carrotsearch.hppc.IntObjectHashMap;
|
||||||
|
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
import org.elasticsearch.xpack.sql.jdbc.EsType;
|
||||||
import org.elasticsearch.xpack.sql.proto.StringUtils;
|
import org.elasticsearch.xpack.sql.proto.StringUtils;
|
||||||
import org.relique.jdbc.csv.CsvResultSet;
|
import org.relique.jdbc.csv.CsvResultSet;
|
||||||
|
|
||||||
|
@ -39,10 +39,10 @@ import static org.junit.Assert.fail;
|
||||||
*/
|
*/
|
||||||
public class JdbcAssert {
|
public class JdbcAssert {
|
||||||
|
|
||||||
private static final IntObjectHashMap<DataType> SQL_TO_TYPE = new IntObjectHashMap<>();
|
private static final IntObjectHashMap<EsType> SQL_TO_TYPE = new IntObjectHashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
for (DataType type : DataType.values()) {
|
for (EsType type : EsType.values()) {
|
||||||
SQL_TO_TYPE.putIfAbsent(type.getVendorTypeNumber().intValue(), type);
|
SQL_TO_TYPE.putIfAbsent(type.getVendorTypeNumber().intValue(), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,8 +13,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentHelper;
|
import org.elasticsearch.common.xcontent.XContentHelper;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.test.rest.ESRestTestCase;
|
import org.elasticsearch.test.rest.ESRestTestCase;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConfiguration;
|
import org.elasticsearch.xpack.sql.jdbc.EsDataSource;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbcx.JdbcDataSource;
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -61,21 +60,21 @@ public abstract class JdbcIntegrationTestCase extends ESRestTestCase {
|
||||||
Connection connection =
|
Connection connection =
|
||||||
DriverManager.getConnection(address, connectionProperties);
|
DriverManager.getConnection(address, connectionProperties);
|
||||||
// end::connect-dm
|
// end::connect-dm
|
||||||
assertNotNull("The timezone should be specified", connectionProperties.getProperty(JdbcConfiguration.TIME_ZONE));
|
assertNotNull("The timezone should be specified", connectionProperties.getProperty("timezone"));
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Connection useDataSource() throws SQLException {
|
protected Connection useDataSource() throws SQLException {
|
||||||
String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress();
|
String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress();
|
||||||
// tag::connect-ds
|
// tag::connect-ds
|
||||||
JdbcDataSource dataSource = new JdbcDataSource();
|
EsDataSource dataSource = new EsDataSource();
|
||||||
String address = "jdbc:es://" + elasticsearchAddress; // <1>
|
String address = "jdbc:es://" + elasticsearchAddress; // <1>
|
||||||
dataSource.setUrl(address);
|
dataSource.setUrl(address);
|
||||||
Properties connectionProperties = connectionProperties(); // <2>
|
Properties connectionProperties = connectionProperties(); // <2>
|
||||||
dataSource.setProperties(connectionProperties);
|
dataSource.setProperties(connectionProperties);
|
||||||
Connection connection = dataSource.getConnection();
|
Connection connection = dataSource.getConnection();
|
||||||
// end::connect-ds
|
// end::connect-ds
|
||||||
assertNotNull("The timezone should be specified", connectionProperties.getProperty(JdbcConfiguration.TIME_ZONE));
|
assertNotNull("The timezone should be specified", connectionProperties.getProperty("timezone"));
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,7 +106,7 @@ public abstract class JdbcIntegrationTestCase extends ESRestTestCase {
|
||||||
*/
|
*/
|
||||||
protected Properties connectionProperties() {
|
protected Properties connectionProperties() {
|
||||||
Properties connectionProperties = new Properties();
|
Properties connectionProperties = new Properties();
|
||||||
connectionProperties.put(JdbcConfiguration.TIME_ZONE, randomKnownTimeZone());
|
connectionProperties.put("timezone", randomKnownTimeZone());
|
||||||
return connectionProperties;
|
return connectionProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,8 @@ public abstract class JdbcTestUtils {
|
||||||
|
|
||||||
public static final String SQL_TRACE = "org.elasticsearch.xpack.sql:TRACE";
|
public static final String SQL_TRACE = "org.elasticsearch.xpack.sql:TRACE";
|
||||||
|
|
||||||
|
public static final String JDBC_TIMEZONE = "timezone";
|
||||||
|
|
||||||
public static void logResultSetMetadata(ResultSet rs, Logger logger) throws SQLException {
|
public static void logResultSetMetadata(ResultSet rs, Logger logger) throws SQLException {
|
||||||
ResultSetMetaData metaData = rs.getMetaData();
|
ResultSetMetaData metaData = rs.getMetaData();
|
||||||
// header
|
// header
|
||||||
|
|
|
@ -13,9 +13,8 @@ import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.collect.Tuple;
|
import org.elasticsearch.common.collect.Tuple;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
import org.elasticsearch.common.xcontent.json.JsonXContent;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConfiguration;
|
import org.elasticsearch.xpack.sql.jdbc.EsDataSource;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbcx.JdbcDataSource;
|
import org.elasticsearch.xpack.sql.jdbc.EsType;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.type.DataType;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -58,6 +57,7 @@ import static java.util.Calendar.MINUTE;
|
||||||
import static java.util.Calendar.MONTH;
|
import static java.util.Calendar.MONTH;
|
||||||
import static java.util.Calendar.SECOND;
|
import static java.util.Calendar.SECOND;
|
||||||
import static java.util.Calendar.YEAR;
|
import static java.util.Calendar.YEAR;
|
||||||
|
import static org.elasticsearch.xpack.sql.qa.jdbc.JdbcTestUtils.JDBC_TIMEZONE;
|
||||||
|
|
||||||
public class ResultSetTestCase extends JdbcIntegrationTestCase {
|
public class ResultSetTestCase extends JdbcIntegrationTestCase {
|
||||||
|
|
||||||
|
@ -69,14 +69,14 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase {
|
||||||
+ "test_long, test_short, test_double, test_float, test_keyword, test_date FROM test";
|
+ "test_long, test_short, test_double, test_float, test_keyword, test_date FROM test";
|
||||||
static final String SELECT_WILDCARD = "SELECT * FROM test";
|
static final String SELECT_WILDCARD = "SELECT * FROM test";
|
||||||
static {
|
static {
|
||||||
dateTimeTestingFields.put(new Tuple<String, Object>("test_boolean", true), DataType.BOOLEAN);
|
dateTimeTestingFields.put(new Tuple<String, Object>("test_boolean", true), EsType.BOOLEAN);
|
||||||
dateTimeTestingFields.put(new Tuple<String, Object>("test_byte", 1), DataType.BYTE);
|
dateTimeTestingFields.put(new Tuple<String, Object>("test_byte", 1), EsType.BYTE);
|
||||||
dateTimeTestingFields.put(new Tuple<String, Object>("test_integer", 1), DataType.INTEGER);
|
dateTimeTestingFields.put(new Tuple<String, Object>("test_integer", 1), EsType.INTEGER);
|
||||||
dateTimeTestingFields.put(new Tuple<String, Object>("test_long", 1L), DataType.LONG);
|
dateTimeTestingFields.put(new Tuple<String, Object>("test_long", 1L), EsType.LONG);
|
||||||
dateTimeTestingFields.put(new Tuple<String, Object>("test_short", 1), DataType.SHORT);
|
dateTimeTestingFields.put(new Tuple<String, Object>("test_short", 1), EsType.SHORT);
|
||||||
dateTimeTestingFields.put(new Tuple<String, Object>("test_double", 1d), DataType.DOUBLE);
|
dateTimeTestingFields.put(new Tuple<String, Object>("test_double", 1d), EsType.DOUBLE);
|
||||||
dateTimeTestingFields.put(new Tuple<String, Object>("test_float", 1f), DataType.FLOAT);
|
dateTimeTestingFields.put(new Tuple<String, Object>("test_float", 1f), EsType.FLOAT);
|
||||||
dateTimeTestingFields.put(new Tuple<String, Object>("test_keyword", "true"), DataType.KEYWORD);
|
dateTimeTestingFields.put(new Tuple<String, Object>("test_keyword", "true"), EsType.KEYWORD);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Byte values testing
|
// Byte values testing
|
||||||
|
@ -1525,24 +1525,24 @@ public class ResultSetTestCase extends JdbcIntegrationTestCase {
|
||||||
String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress();
|
String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress();
|
||||||
String address = "jdbc:es://" + elasticsearchAddress;
|
String address = "jdbc:es://" + elasticsearchAddress;
|
||||||
Properties connectionProperties = connectionProperties();
|
Properties connectionProperties = connectionProperties();
|
||||||
connectionProperties.put(JdbcConfiguration.TIME_ZONE, timeZoneId);
|
connectionProperties.put(JDBC_TIMEZONE, timeZoneId);
|
||||||
Connection connection = DriverManager.getConnection(address, connectionProperties);
|
Connection connection = DriverManager.getConnection(address, connectionProperties);
|
||||||
|
|
||||||
assertNotNull("The timezone should be specified", connectionProperties.getProperty(JdbcConfiguration.TIME_ZONE));
|
assertNotNull("The timezone should be specified", connectionProperties.getProperty(JDBC_TIMEZONE));
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Connection useDataSource(String timeZoneId) throws SQLException {
|
private Connection useDataSource(String timeZoneId) throws SQLException {
|
||||||
String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress();
|
String elasticsearchAddress = getProtocol() + "://" + elasticsearchAddress();
|
||||||
JdbcDataSource dataSource = new JdbcDataSource();
|
EsDataSource dataSource = new EsDataSource();
|
||||||
String address = "jdbc:es://" + elasticsearchAddress;
|
String address = "jdbc:es://" + elasticsearchAddress;
|
||||||
dataSource.setUrl(address);
|
dataSource.setUrl(address);
|
||||||
Properties connectionProperties = connectionProperties();
|
Properties connectionProperties = connectionProperties();
|
||||||
connectionProperties.put(JdbcConfiguration.TIME_ZONE, timeZoneId);
|
connectionProperties.put(JDBC_TIMEZONE, timeZoneId);
|
||||||
dataSource.setProperties(connectionProperties);
|
dataSource.setProperties(connectionProperties);
|
||||||
Connection connection = dataSource.getConnection();
|
Connection connection = dataSource.getConnection();
|
||||||
|
|
||||||
assertNotNull("The timezone should be specified", connectionProperties.getProperty(JdbcConfiguration.TIME_ZONE));
|
assertNotNull("The timezone should be specified", connectionProperties.getProperty(JDBC_TIMEZONE));
|
||||||
return connection;
|
return connection;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,7 +11,6 @@ import org.elasticsearch.client.ResponseException;
|
||||||
import org.elasticsearch.client.RestClient;
|
import org.elasticsearch.client.RestClient;
|
||||||
import org.elasticsearch.common.Strings;
|
import org.elasticsearch.common.Strings;
|
||||||
import org.elasticsearch.common.SuppressForbidden;
|
import org.elasticsearch.common.SuppressForbidden;
|
||||||
import org.elasticsearch.xpack.sql.jdbc.jdbc.JdbcConfiguration;
|
|
||||||
import org.junit.AfterClass;
|
import org.junit.AfterClass;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
|
|
||||||
|
@ -115,7 +114,7 @@ public abstract class SpecBaseIntegrationTestCase extends JdbcIntegrationTestCas
|
||||||
@Override
|
@Override
|
||||||
protected Properties connectionProperties() {
|
protected Properties connectionProperties() {
|
||||||
Properties connectionProperties = new Properties();
|
Properties connectionProperties = new Properties();
|
||||||
connectionProperties.setProperty(JdbcConfiguration.TIME_ZONE, "UTC");
|
connectionProperties.setProperty("timezone", "UTC");
|
||||||
return connectionProperties;
|
return connectionProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue