Skip to content

Commit

Permalink
Implemented incl. tests and changes file (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
ckunki authored Mar 15, 2023
1 parent d55721e commit b65836f
Show file tree
Hide file tree
Showing 14 changed files with 167 additions and 58 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Virtual Schema Common Module for JDBC-based Data Access

[![Build Status](https://github.com/exasol/virtual-schema-common-jdbc/actions/workflows/ci-build.yml/badge.svg)](https://github.com/exasol/virtual-schema-common-jdbc/actions/workflows/ci-build.yml)
[![Maven Central Virtual Schema Common JDBC](https://img.shields.io/maven-central/v/com.exasol/virtual-schema-common-jdbc)](https://search.maven.org/artifact/com.exasol/virtual-schema-common-jdbc)
[![Maven Central – Virtual Schema Common JDBC](https://img.shields.io/maven-central/v/com.exasol/virtual-schema-common-jdbc)](https://search.maven.org/artifact/com.exasol/virtual-schema-common-jdbc)

[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=com.exasol%3Avirtual-schema-common-jdbc&metric=alert_status)](https://sonarcloud.io/dashboard?id=com.exasol%3Avirtual-schema-common-jdbc)

Expand Down
4 changes: 2 additions & 2 deletions dependencies.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions doc/changes/changelog.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions doc/changes/changes_10.5.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Virtual Schema Common JDBC 10.5.0, released 2023-03-15

Code name: Escape SQL Wild Cards Optionally

## Summary

Release 10.3.0 introduced escaping wild cards in the names of database schemas and tables when retrieving column metadata from JDBC.

The current release fixes two problems in this area

| Problem | Fix |
|------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|
| VSCJDBC also escaped wild cards in the name of the database catalog, conflicting with the parameter's documentation as literal string. | Do not escape potential wild cards in the name of the database catalog. |
| VSCJDBC always used the backslash as escape string, while there are SQL dialects with different escape string, e.g. VSORA using a forward slash `/`. | Use `java.sql.DatabaseMetaData.getSearchStringEscape()` to inquire the escape string for the specific SQL dialect. |

Additionally the current release makes wild card escaping optional. In case of problems SQL dialects then can simply override `BaseColumnMetadataReader.getColumnMetadata`:
```java
@Override
protected ResultSet getColumnMetadata(String catalogName, String schemaName, String tableName) throws SQLException {
return getColumnMetadataAllowingPatterns(catalogName, schemaName, tableName);
}
```

## Bugfixes

* #142: Fixed escaping wildcards in column lookup and made escaping optional

## Dependency Updates

### Test Dependency Updates

* Updated `org.mockito:mockito-junit-jupiter:5.1.1` to `5.2.0`

### Plugin Dependency Updates

* Updated `com.exasol:project-keeper-maven-plugin:2.9.3` to `2.9.4`
* Updated `org.apache.maven.plugins:maven-deploy-plugin:3.0.0` to `3.1.0`
* Updated `org.apache.maven.plugins:maven-enforcer-plugin:3.1.0` to `3.2.1`
6 changes: 3 additions & 3 deletions pk_generated_parent.pom

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>virtual-schema-common-jdbc</artifactId>
<version>10.4.0</version>
<version>10.5.0</version>
<name>Virtual Schema Common JDBC</name>
<description>Common module for JDBC-based data access from Virtual Schemas.</description>
<url>https://github.com/exasol/virtual-schema-common-jdbc/</url>
Expand Down Expand Up @@ -50,7 +50,7 @@
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>5.1.1</version>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down Expand Up @@ -84,7 +84,7 @@
<plugin>
<groupId>com.exasol</groupId>
<artifactId>project-keeper-maven-plugin</artifactId>
<version>2.9.3</version>
<version>2.9.4</version>
<executions>
<execution>
<goals>
Expand Down Expand Up @@ -122,7 +122,7 @@
<parent>
<artifactId>virtual-schema-common-jdbc-generated-parent</artifactId>
<groupId>com.exasol</groupId>
<version>10.4.0</version>
<version>10.5.0</version>
<relativePath>pk_generated_parent.pom</relativePath>
</parent>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,40 @@ protected List<ColumnMetadata> mapColumns(final String catalogName, final String
}
}

private ResultSet getColumnMetadata(final String catalogName, final String schemaName, final String tableName)
/**
* Read column metadata from JDBC driver escaping potential SQL wild cards in the names of schema and table.
*
* @param catalogName catalog name
* @param schemaName schema name, potential SQL wildcards will be escaped
* @param tableName table name, potential SQL wildcards will be escaped
* @return list with metadata for all columns of the respective catalog, schema, and table
* @throws SQLException in case of failures
*/
protected ResultSet getColumnMetadata(final String catalogName, final String schemaName, final String tableName)
throws SQLException {
return this.connection.getMetaData().getColumns( //
catalogName == null ? null : Wildcards.escape(catalogName), //
schemaName == null ? null : Wildcards.escape(schemaName), //
Wildcards.escape(tableName), //
final DatabaseMetaData metadata = this.connection.getMetaData();
final WildcardEscaper wildcards = WildcardEscaper.instance(metadata.getSearchStringEscape());
return metadata.getColumns(catalogName, //
schemaName == null ? null : wildcards.escape(schemaName), //
tableName == null ? null : wildcards.escape(tableName), //
ANY_COLUMN);
}

/**
* Read column metadata from JDBC driver without escaping potential SQL wild cards in the names of schema and table.
*
* @param catalogName catalog name
* @param schemaNamePattern schema name pattern, may contain SQL wildcards
* @param tableNamePattern table name pattern, may contain SQL wildcards
* @return list with metadata for all columns of the respective catalog, matching schema name pattern, and table
* name pattern
* @throws SQLException in case of failures
*/
protected ResultSet getColumnMetadataAllowingPatterns(final String catalogName, final String schemaNamePattern,
final String tableNamePattern) throws SQLException {
return this.connection.getMetaData().getColumns(catalogName, schemaNamePattern, tableNamePattern, ANY_COLUMN);
}

/**
* Read the columns result set.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ private Optional<TableMetadata> getTableMetadata(final ResultSet remoteTables, f
throws SQLException {
final TableMetadata tableMetadata = mapTable(remoteTables, tableName);
if (tableHasColumns(tableMetadata)) {
LOGGER.finer(() -> "Read table metadata: " + tableMetadata.describe());
return Optional.of(tableMetadata);
} else {
logSkippingTableWithEmptyColumns(tableName);
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/exasol/adapter/jdbc/JDBCAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public CreateVirtualSchemaResponse createVirtualSchema(final ExaMetadata exasolM
* @param request create request
*/
protected void logCreateVirtualSchemaRequestReceived(final CreateVirtualSchemaRequest request) {
LOGGER.fine(() -> "Received request to create Virutal Schema \"" + request.getVirtualSchemaName() + "\".");
LOGGER.fine(() -> "Received request to create Virtual Schema \"" + request.getVirtualSchemaName() + "\".");
}

private AdapterProperties getPropertiesFromRequest(final AdapterRequest request) {
Expand Down
45 changes: 45 additions & 0 deletions src/main/java/com/exasol/adapter/jdbc/WildcardEscaper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.exasol.adapter.jdbc;

import java.sql.DatabaseMetaData;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Escape SQL wild cards in string to enable to request column metadata from JDBC driver with exact match for names of
* catalog, schema, and table.
*/
public class WildcardEscaper {

private static final Pattern REGEX_WILDCARDS = Pattern.compile("[\\\\$]");
private static final Pattern SQL_WINDCARDS = Pattern.compile("[_%]");

/**
* Create a new instance of the {@link WildcardEscaper}.
* <p>
* Use {@link DatabaseMetaData#getSearchStringEscape()} to get the escape string for wild card characters.
*
* @param searchStringEscape string that should be used to escape SQL wild cards
* @return new instance of the {@link WildcardEscaper}
*/
public static WildcardEscaper instance(final String searchStringEscape) {
final String escaped = new WildcardEscaper(REGEX_WILDCARDS, "\\\\").escape(searchStringEscape);
return new WildcardEscaper(SQL_WINDCARDS, escaped);
}

private final Pattern pattern;
private final String replacement;

WildcardEscaper(final Pattern pattern, final String replacement) {
this.pattern = pattern;
this.replacement = replacement + "$0";
}

/**
* @param input Name of catalog, schema, or table
* @return name with potential wild cards escaped.
*/
public String escape(final String input) {
final Matcher matcher = this.pattern.matcher(input);
return matcher.find() ? matcher.replaceAll(this.replacement) : input;
}
}
25 changes: 0 additions & 25 deletions src/main/java/com/exasol/adapter/jdbc/Wildcards.java

This file was deleted.

Loading

0 comments on commit b65836f

Please sign in to comment.