Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 20 additions & 27 deletions jdbc/src/main/java/tech/ydb/jdbc/query/YdbQuery.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,17 @@ public class YdbQuery {
private final String originQuery;
private final String preparedYQL;
private final List<QueryStatement> statements;
private final YqlBatcher batch;
private final YqlBatcher batcher;

private final QueryType type;
private final boolean isPlainYQL;

YdbQuery(String originQuery, String preparedYQL, List<QueryStatement> stats, QueryType type) {
this(originQuery, preparedYQL, stats, null, type);
}

YdbQuery(String originQuery, String preparedYQL, List<QueryStatement> stats, YqlBatcher batch, QueryType type) {
YdbQuery(String originQuery, String preparedYQL, List<QueryStatement> stats, YqlBatcher batcher, QueryType type) {
this.originQuery = originQuery;
this.preparedYQL = preparedYQL;
this.statements = stats;
this.type = type;
this.batch = batch;
this.batcher = batcher;

boolean hasJdbcParamters = false;
for (QueryStatement st: statements) {
Expand All @@ -43,7 +39,7 @@ public QueryType getType() {
}

public YqlBatcher getYqlBatcher() {
return batch;
return batcher.isValidBatch() ? batcher : null;
}

public boolean isPlainYQL() {
Expand All @@ -66,32 +62,29 @@ public static YdbQuery parseQuery(String query, YdbQueryProperties opts) throws
YdbQueryParser parser = new YdbQueryParser(opts.isDetectQueryType(), opts.isDetectJdbcParameters());
String preparedYQL = parser.parseSQL(query);

QueryType type = opts.getForcedQueryType();
if (type == null) {
type = parser.detectQueryType();
YqlBatcher batcher = parser.getYqlBatcher();

if (opts.isForcedScanAndBulks()) {
if (batcher.isValidBatch()) {
if (batcher.getCommand() == YqlBatcher.Cmd.UPSERT) {
type = QueryType.BULK_QUERY;
}
if (batcher.getCommand() == YqlBatcher.Cmd.INSERT) {
parser.getYqlBatcher().setForcedUpsert();
type = QueryType.BULK_QUERY;
}
}
QueryType type = null;
YqlBatcher batcher = parser.getYqlBatcher();
List<QueryStatement> statements = parser.getStatements();

if (parser.getStatements().size() == 1 && parser.getStatements().get(0).getCmd() == QueryCmd.SELECT) {
if (batcher.isValidBatch()) {
if (batcher.getCommand() == YqlBatcher.Cmd.INSERT && opts.isReplaceInsertToUpsert()) {
batcher.setForcedUpsert();
}
if (batcher.getCommand() == YqlBatcher.Cmd.UPSERT && opts.isForceBulkUpsert()) {
type = QueryType.BULK_QUERY;
}
} else {
if (opts.isForceScanSelect() && statements.size() == 1 && statements.get(0).getCmd() == QueryCmd.SELECT) {
if (parser.detectQueryType() == QueryType.DATA_QUERY) { // Only data queries may be converter to SCAN
type = QueryType.SCAN_QUERY;
}
}
}

if (parser.getYqlBatcher().isValidBatch()) {
return new YdbQuery(query, preparedYQL, parser.getStatements(), parser.getYqlBatcher(), type);
if (type == null) {
type = parser.detectQueryType();
}

return new YdbQuery(query, preparedYQL, parser.getStatements(), type);
return new YdbQuery(query, preparedYQL, statements, batcher, type);
}
}
6 changes: 4 additions & 2 deletions jdbc/src/main/java/tech/ydb/jdbc/settings/YdbConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,10 @@ public DriverPropertyInfo[] toPropertyInfo() throws SQLException {
YdbQueryProperties.DISABLE_DETECT_SQL_OPERATIONS.toInfo(properties),
YdbQueryProperties.DISABLE_JDBC_PARAMETERS.toInfo(properties),
YdbQueryProperties.DISABLE_JDBC_PARAMETERS_DECLARE.toInfo(properties),
YdbQueryProperties.FORCE_QUERY_MODE.toInfo(properties),
YdbQueryProperties.FORCE_SCAN_BULKS.toInfo(properties),

YdbQueryProperties.REPLACE_INSERT_TO_UPSERT.toInfo(properties),
YdbQueryProperties.FORCE_BULK_UPSERT.toInfo(properties),
YdbQueryProperties.FORCE_SCAN_SELECT.toInfo(properties),
};
}

Expand Down
56 changes: 45 additions & 11 deletions jdbc/src/main/java/tech/ydb/jdbc/settings/YdbQueryProperties.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

import java.sql.SQLException;
import java.util.Properties;
import java.util.logging.Logger;

import tech.ydb.jdbc.YdbDriver;
import tech.ydb.jdbc.query.QueryType;


Expand All @@ -12,6 +14,8 @@
* @author Aleksandr Gorshenin
*/
public class YdbQueryProperties {
private static final Logger LOGGER = Logger.getLogger(YdbDriver.class.getName());

static final YdbProperty<Boolean> DISABLE_DETECT_SQL_OPERATIONS = YdbProperty.bool("disableDetectSqlOperations",
"Disable detecting SQL operation based on SQL keywords", false);

Expand All @@ -27,23 +31,33 @@ public class YdbQueryProperties {
static final YdbProperty<Boolean> DISABLE_JDBC_PARAMETERS_DECLARE = YdbProperty.bool("disableJdbcParameterDeclare",
"Disable enforce DECLARE section for JDBC parameters '?'", false);

static final YdbProperty<QueryType> FORCE_QUERY_MODE = YdbProperty.enums("forceQueryMode", QueryType.class,
"Force usage one of query modes (DATA_QUERY, SCAN_QUERY, SCHEME_QUERY or EXPLAIN_QUERYn) for all statements"
@Deprecated
private static final YdbProperty<QueryType> FORCE_QUERY_MODE = YdbProperty.enums("forceQueryMode", QueryType.class,
"Force usage one of query modes (DATA_QUERY, SCAN_QUERY, SCHEME_QUERY or EXPLAIN_QUERY) for all statements"
);
static final YdbProperty<Boolean> FORCE_SCAN_BULKS = YdbProperty.bool("forceScanAndBulk",
@Deprecated
private static final YdbProperty<Boolean> FORCE_SCAN_BULKS = YdbProperty.bool("forceScanAndBulk",
"Force usage of bulk upserts instead of upserts/inserts and scan query for selects",
false
);

static final YdbProperty<Boolean> REPLACE_INSERT_TO_UPSERT = YdbProperty.bool("replaceInsertByUpsert",
"Convert all INSERT statements to UPSERT statements", false);
static final YdbProperty<Boolean> FORCE_BULK_UPSERT = YdbProperty.bool("forceBulkUpsert",
"Execute all UPSERT statements as BulkUpserts", false);
static final YdbProperty<Boolean> FORCE_SCAN_SELECT = YdbProperty.bool("forceScanSelect",
"Execute all SELECT statements as ScanQuery", false);

private final boolean isDetectQueryType;
private final boolean isDetectJdbcParameters;
private final boolean isDeclareJdbcParameters;

private final boolean isPrepareDataQueries;
private final boolean isDetectBatchQueries;

private final QueryType forcedType;
private final boolean isForcedScanAndBulks;
private final boolean isReplaceInsertToUpsert;
private final boolean isForceBulkUpsert;
private final boolean isForceScanSelect;

public YdbQueryProperties(YdbConfig config) throws SQLException {
Properties props = config.getProperties();
Expand All @@ -63,8 +77,24 @@ public YdbQueryProperties(YdbConfig config) throws SQLException {
this.isDeclareJdbcParameters = !disableSqlOperationsDetect && !disableJdbcParametersParse
&& !disableJdbcParametersDeclare;

this.forcedType = FORCE_QUERY_MODE.readValue(props).getValue();
this.isForcedScanAndBulks = FORCE_SCAN_BULKS.readValue(props).getValue();

YdbValue<QueryType> forcedType = FORCE_QUERY_MODE.readValue(props);
if (forcedType.hasValue()) {
LOGGER.warning("Option 'forceQueryMode' is deprecated and will be removed in next versions. "
+ "Use options 'forceScanSelect' and 'forceBulkUpsert' instead");
}
YdbValue<Boolean> forceScanAndBulk = FORCE_SCAN_BULKS.readValue(props);
if (forceScanAndBulk.hasValue()) {
LOGGER.warning("Option 'forceScanAndBulk' is deprecated and will be removed in next versions. "
+ "Use options 'replaceInsertByUpsert', 'forceScanSelect' and 'forceBulkUpsert' instead");
}

this.isReplaceInsertToUpsert = REPLACE_INSERT_TO_UPSERT.readValue(props)
.getValueOrOther(forceScanAndBulk.getValue());
this.isForceBulkUpsert = FORCE_BULK_UPSERT.readValue(props)
.getValueOrOther(forceScanAndBulk.getValue() || forcedType.getValue() == QueryType.BULK_QUERY);
this.isForceScanSelect = FORCE_SCAN_SELECT.readValue(props)
.getValueOrOther(forceScanAndBulk.getValue() || forcedType.getValue() == QueryType.SCAN_QUERY);
}

public boolean isDetectQueryType() {
Expand All @@ -87,11 +117,15 @@ public boolean isDetectBatchQueries() {
return isDetectBatchQueries;
}

public QueryType getForcedQueryType() {
return forcedType;
public boolean isReplaceInsertToUpsert() {
return isReplaceInsertToUpsert;
}

public boolean isForceBulkUpsert() {
return isForceBulkUpsert;
}

public boolean isForcedScanAndBulks() {
return isForcedScanAndBulks;
public boolean isForceScanSelect() {
return isForceScanSelect;
}
}
4 changes: 4 additions & 0 deletions jdbc/src/main/java/tech/ydb/jdbc/settings/YdbValue.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ public T getValue() {
return value;
}

public T getValueOrOther(T other) {
return isPresent ? value : other;
}

public boolean hasValue() {
return isPresent;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,12 @@ public void customQueriesTest() throws SQLException {

@Test
public void forceScanAndBulkTest() throws SQLException {
try (Connection conn = DriverManager.getConnection(jdbcURL.withArg("forceScanAndBulk", "true").build())) {
try (Connection conn = DriverManager.getConnection(jdbcURL
.withArg("replaceInsertByUpsert", "true")
.withArg("forceBulkUpsert", "true")
.withArg("forceScanSelect", "true")
.build()
)) {
try {
conn.createStatement().execute(DROP_TABLE);
} catch (SQLException e) {
Expand Down
10 changes: 6 additions & 4 deletions jdbc/src/test/java/tech/ydb/jdbc/YdbDriverTablesTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ public class YdbDriverTablesTest {

private static final JdbcUrlHelper jdbcURL = new JdbcUrlHelper(ydb);

private final static String ERROR_SCAN_QUERY =
"Scan query should have a single result set. (S_ERROR)";

private final static String ERROR_BULK_UNSUPPORTED =
"BULK mode is available only for prepared statement with one UPSERT";

Expand Down Expand Up @@ -206,7 +203,12 @@ public void customQueriesTest() throws SQLException {

@Test
public void forceScanAndBulkTest() throws SQLException {
try (Connection conn = DriverManager.getConnection(jdbcURL.withArg("forceScanAndBulk", "true").build())) {
try (Connection conn = DriverManager.getConnection(jdbcURL
.withArg("replaceInsertByUpsert", "true")
.withArg("forceBulkUpsert", "true")
.withArg("forceScanSelect", "true")
.build()
)) {
try {
conn.createStatement().execute(DROP_TABLE);
} catch (SQLException e) {
Expand Down
Loading