All jdbc client escaping is done on the server

Original commit: elastic/x-pack-elasticsearch@2b8b7c8c2e
This commit is contained in:
Costin Leau 2017-09-29 20:09:58 +03:00
parent 748f9f3cd0
commit cc66bbaa00
5 changed files with 81 additions and 36 deletions

View File

@ -113,7 +113,7 @@ public class JdbcAssert {
}
else if (type == Types.DOUBLE) {
// NOCOMMIT 1d/1f seems like a huge difference.
// the 1d/1f difference is used due to rounding/flooring
assertEquals(msg, (double) expectedObject, (double) actualObject, 1d);
} else if (type == Types.FLOAT) {
assertEquals(msg, (float) expectedObject, (float) actualObject, 1f);

View File

@ -57,8 +57,8 @@ public class MetaColumnRequest extends Request {
return false;
}
MetaColumnRequest other = (MetaColumnRequest) obj;
return tablePattern.equals(other.tablePattern)
&& columnPattern.equals(other.columnPattern);
return Objects.equals(tablePattern, other.tablePattern)
&& Objects.equals(columnPattern, other.columnPattern);
}
@Override

View File

@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.List;
import static org.elasticsearch.xpack.sql.net.client.util.StringUtils.EMPTY;
import static org.elasticsearch.xpack.sql.net.client.util.StringUtils.hasText;
/**
* Implementation of {@link DatabaseMetaData} for Elasticsearch. Draws inspiration
@ -684,26 +683,32 @@ class JdbcDatabaseMetaData implements DatabaseMetaData, JdbcWrapper {
}
private boolean isDefaultCatalog(String catalog) throws SQLException {
// null means catalog info is irrelevant
// % means return all catalogs
// "" means return those without a catalog
return catalog == null || catalog.equals(EMPTY) || catalog.equals("%") || catalog.equals(defaultCatalog());
}
private boolean isDefaultSchema(String schema) {
// null means schema info is irrelevant
// % means return all schemas
// "" means return those without a schema
return schema == null || schema.equals(EMPTY) || schema.equals("%");
}
@Override
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
List<ColumnInfo> info = columnInfo("TABLES",
"TABLE_CAT",
"TABLE_SCHEM",
"TABLE_NAME",
"TABLE_TYPE",
"REMARKS",
"TYPE_CAT",
"TYPE_SCHEM",
"TYPE_NAME",
"SELF_REFERENCING_COL_NAME",
"REF_GENERATION");
"TABLE_CAT", //0
"TABLE_SCHEM", //1
"TABLE_NAME", //2
"TABLE_TYPE", //3
"REMARKS", //4
"TYPE_CAT", //5
"TYPE_SCHEM", //6
"TYPE_NAME", //7
"SELF_REFERENCING_COL_NAME", //8
"REF_GENERATION"); //9
// schema and catalogs are not being used, if these are specified return an empty result set
if (!isDefaultCatalog(catalog) || !isDefaultSchema(schemaPattern)) {
@ -711,7 +716,7 @@ class JdbcDatabaseMetaData implements DatabaseMetaData, JdbcWrapper {
}
String cat = defaultCatalog();
List<String> tables = con.client.metaInfoTables(sqlWildcardToSimplePattern(tableNamePattern));
List<String> tables = con.client.metaInfoTables(tableNamePattern);
Object[][] data = new Object[tables.size()][];
for (int i = 0; i < data.length; i++) {
data[i] = new Object[10];
@ -731,23 +736,6 @@ class JdbcDatabaseMetaData implements DatabaseMetaData, JdbcWrapper {
return memorySet(con.cfg, info, data);
}
/**
* Convert sql wildcards ({@code %} and @{code _}) into {@code Regex#simpleMatch}-style patterns.
*/
private static String sqlWildcardToSimplePattern(String pattern) {
// NOCOMMIT ? isn't supported by simple pattern
// NOCOMMIT escape *?
return hasText(pattern) ? pattern.replaceAll("%", "*").replace('_', '?') : pattern;
}
/**
* Convert sql wildcards ({@code %} and @{code _}) into regex style patterns.
*/
private static String sqlWildcardToRegexPattern(String pattern) {
// NOCOMMIT escape regex bits?
return hasText(pattern) ? pattern.replaceAll("%", ".*").replace('_', '.') : pattern;
}
@Override
public ResultSet getSchemas() throws SQLException {
Object[][] data = { { EMPTY, defaultCatalog() } };
@ -818,8 +806,8 @@ class JdbcDatabaseMetaData implements DatabaseMetaData, JdbcWrapper {
}
String cat = defaultCatalog();
List<MetaColumnInfo> columns = con.client.metaInfoColumns(
sqlWildcardToSimplePattern(tableNamePattern), sqlWildcardToRegexPattern(columnNamePattern));
// escaping is done on the server
List<MetaColumnInfo> columns = con.client.metaInfoColumns(tableNamePattern, columnNamePattern);
Object[][] data = new Object[columns.size()][];
for (int i = 0; i < data.length; i++) {
data[i] = new Object[24];

View File

@ -115,6 +115,7 @@ public abstract class StringUtils {
char curr = sqlPattern.charAt(i);
if (shouldEscape && !escaped && (curr == escapeChar)) {
escaped = true;
regex.append(curr);
}
else {
switch (curr) {
@ -143,7 +144,9 @@ public abstract class StringUtils {
case ']':
case '{':
case '}':
regex.append('\\');
if (!escaped) {
regex.append('\\');
}
}
regex.append(curr);
@ -166,7 +169,7 @@ public abstract class StringUtils {
}
public static Pattern likeRegex(String likePattern) {
return Pattern.compile(sqlToJavaPattern(likePattern, '\\', true));
return Pattern.compile(sqlToJavaPattern(likePattern));
}
public static String toString(SearchSourceBuilder source) {

View File

@ -0,0 +1,54 @@
/*
* 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.util;
import org.junit.Test;
import static org.elasticsearch.xpack.sql.util.StringUtils.sqlToJavaPattern;
import static org.junit.Assert.assertEquals;
public class StringUtilsTest {
@Test
public void testNoRegex() {
assertEquals("^fooBar$", sqlToJavaPattern("fooBar"));
}
@Test
public void testEscapedJavaRegex() {
assertEquals("^\\.\\d$", sqlToJavaPattern("\\.\\d"));
}
@Test
public void testSimpleSqlRegex1() {
assertEquals("^foo.bar$", sqlToJavaPattern("foo_bar"));
}
@Test
public void testSimpleSqlRegex2() {
assertEquals("^foo.*bar$", sqlToJavaPattern("foo%bar"));
}
@Test
public void testMultipleSqlRegexes() {
assertEquals("^foo.*bar.$", sqlToJavaPattern("foo%bar_"));
}
@Test
public void testJavaRegexNoSqlRegex() {
assertEquals("^foo\\.\\*bar$", sqlToJavaPattern("foo.*bar"));
}
@Test
public void testMultipleRegexAndSqlRegex() {
assertEquals("^foo\\.\\*bar\\..*$", sqlToJavaPattern("foo.*bar.%"));
}
@Test
public void testComplicatedJavaRegex() {
assertEquals("^\\^\\[\\d\\]\\.\\*\\$$", sqlToJavaPattern("^[\\d].*$"));
}
}