fix(agents): sanitize backtick identifier quote for GBase 8s
This commit is contained in:
2 files changed
+104
-1
No files matched your search
@@ -454,7 +454,57 @@ public abstract class AbstractJdbcAgent extends BaseDatabaseAgent {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
String quote = connection.getMetaData().getIdentifierQuoteString();
|
String quote = connection.getMetaData().getIdentifierQuoteString();
|
||||||
return quote == null || quote.trim().isEmpty() ? "" : quote.trim();
|
if (quote == null || quote.trim().isEmpty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
return sanitizeInformixFamilyBacktickQuote(params, connection, quote.trim());
|
||||||
|
} catch (Exception ignored) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// GBase 8s and other Informix-family JDBC drivers report "`" from
|
||||||
|
// getIdentifierQuoteString() even though their servers reject backtick-quoted
|
||||||
|
// identifiers with "illegal character in statement" outside MySQL compatibility
|
||||||
|
// mode (SQLMODE=mysql). An empty quote makes clients emit unquoted identifiers,
|
||||||
|
// which both SQL modes accept.
|
||||||
|
private static String sanitizeInformixFamilyBacktickQuote(ConnectParams params, Connection connection, String quote) {
|
||||||
|
if (!"`".equals(quote) || !isInformixFamilyJdbc(params, connection) || isInformixFamilyMysqlCompat(params, connection)) {
|
||||||
|
return quote;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isInformixFamilyJdbc(ConnectParams params, Connection connection) {
|
||||||
|
StringBuilder identity = new StringBuilder();
|
||||||
|
appendJdbcIdentity(identity, params.getConnection_string());
|
||||||
|
appendJdbcIdentity(identity, params.getJdbc_driver_class());
|
||||||
|
List<String> driverPaths = params.getJdbc_driver_paths();
|
||||||
|
if (driverPaths != null) {
|
||||||
|
for (String path : driverPaths) {
|
||||||
|
appendJdbcIdentity(identity, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
appendJdbcIdentity(identity, connectionUrl(connection));
|
||||||
|
String normalized = identity.toString().toLowerCase(Locale.ROOT);
|
||||||
|
return normalized.contains("jdbc:gbasedbt")
|
||||||
|
|| normalized.contains("jdbc:informix")
|
||||||
|
|| normalized.contains("com.gbasedbt")
|
||||||
|
|| normalized.contains("com.informix");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isInformixFamilyMysqlCompat(ConnectParams params, Connection connection) {
|
||||||
|
if (params.isMysql_compat_mode()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
String identity = (params.getConnection_string() + "\n" + connectionUrl(connection)).toLowerCase(Locale.ROOT);
|
||||||
|
return identity.contains("sqlmode=mysql");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String connectionUrl(Connection connection) {
|
||||||
|
try {
|
||||||
|
String url = connection.getMetaData().getURL();
|
||||||
|
return url == null ? "" : url;
|
||||||
} catch (Exception ignored) {
|
} catch (Exception ignored) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -115,6 +115,55 @@ class AbstractJdbcAgentTest {
|
|||||||
assertEquals(0, tracking.compatibilityQueryCount);
|
assertEquals(0, tracking.compatibilityQueryCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void ignoresGbase8sDriverBacktickIdentifierQuote() {
|
||||||
|
TrackingConnection tracking = new TrackingConnection();
|
||||||
|
tracking.identifierQuote = "`";
|
||||||
|
tracking.jdbcUrl = "jdbc:gbasedbt-sqli://localhost:9088/appdb:GBASEDBTSERVER=gbase8s";
|
||||||
|
TestAgent agent = new TestAgent(tracking);
|
||||||
|
|
||||||
|
agent.connect(new ConnectParams());
|
||||||
|
|
||||||
|
assertEquals("", agent.getIdentifierQuote());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void ignoresBacktickQuoteForInformixFamilyConnectionString() {
|
||||||
|
TrackingConnection tracking = new TrackingConnection();
|
||||||
|
tracking.identifierQuote = "`";
|
||||||
|
TestAgent agent = new TestAgent(tracking);
|
||||||
|
|
||||||
|
ConnectParams params = new ConnectParams();
|
||||||
|
params.setConnection_string("jdbc:informix-sqli://localhost:9088/appdb:INFORMIXSERVER=ol_informix");
|
||||||
|
agent.connect(params);
|
||||||
|
|
||||||
|
assertEquals("", agent.getIdentifierQuote());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void keepsInformixFamilyBacktickQuoteInMysqlCompatMode() {
|
||||||
|
TrackingConnection tracking = new TrackingConnection();
|
||||||
|
tracking.identifierQuote = "`";
|
||||||
|
tracking.jdbcUrl = "jdbc:gbasedbt-sqli://localhost:9088/appdb:GBASEDBTSERVER=gbase8s;SQLMODE=mysql";
|
||||||
|
TestAgent agent = new TestAgent(tracking);
|
||||||
|
|
||||||
|
agent.connect(new ConnectParams());
|
||||||
|
|
||||||
|
assertEquals("`", agent.getIdentifierQuote());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void keepsNonBacktickQuotesForInformixFamilyDrivers() {
|
||||||
|
TrackingConnection tracking = new TrackingConnection();
|
||||||
|
tracking.identifierQuote = "\"";
|
||||||
|
tracking.jdbcUrl = "jdbc:gbasedbt-sqli://localhost:9088/appdb:GBASEDBTSERVER=gbase8s";
|
||||||
|
TestAgent agent = new TestAgent(tracking);
|
||||||
|
|
||||||
|
agent.connect(new ConnectParams());
|
||||||
|
|
||||||
|
assertEquals("\"", agent.getIdentifierQuote());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testsConnectionsThroughSharedLifecycle() {
|
void testsConnectionsThroughSharedLifecycle() {
|
||||||
TrackingConnection tracking = new TrackingConnection();
|
TrackingConnection tracking = new TrackingConnection();
|
||||||
@@ -469,6 +518,7 @@ class AbstractJdbcAgentTest {
|
|||||||
private boolean autoCommit = true;
|
private boolean autoCommit = true;
|
||||||
private String compatibilityMode;
|
private String compatibilityMode;
|
||||||
private String identifierQuote = "\"";
|
private String identifierQuote = "\"";
|
||||||
|
private String jdbcUrl;
|
||||||
private boolean compatibilityQueryFails;
|
private boolean compatibilityQueryFails;
|
||||||
private int compatibilityQueryCount;
|
private int compatibilityQueryCount;
|
||||||
private boolean isValidUnsupported;
|
private boolean isValidUnsupported;
|
||||||
@@ -534,6 +584,9 @@ class AbstractJdbcAgentTest {
|
|||||||
if ("getIdentifierQuoteString".equals(method.getName())) {
|
if ("getIdentifierQuoteString".equals(method.getName())) {
|
||||||
return identifierQuote;
|
return identifierQuote;
|
||||||
}
|
}
|
||||||
|
if ("getURL".equals(method.getName())) {
|
||||||
|
return jdbcUrl;
|
||||||
|
}
|
||||||
return defaultValue(method.getReturnType());
|
return defaultValue(method.getReturnType());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in new issue
Block a user