Skip to content

Commit

Permalink
#249: Improved CLOB handling in Oracle dialect.
Browse files Browse the repository at this point in the history
  • Loading branch information
redcatbear committed Aug 28, 2019
1 parent dceb354 commit b490d31
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 7 deletions.
8 changes: 7 additions & 1 deletion doc/dialects/oracle.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ CREATE VIRTUAL SCHEMA <virtual schema name>

The Oracle dialect does not support all capabilities. A complete list can be found in [OracleSqlDialect.getCapabilities()](../../jdbc-adapter/virtualschema-jdbc-adapter/src/main/java/com/exasol/adapter/dialects/oracle/OracleSqlDialect.java).

## Type Mappings and Limitations

Oracle data types are mapped to their equivalents in Exasol. The following exceptions apply:

- `NUMBER`, `NUMBER with precision > 36` and `LONG` are casted to `VARCHAR` to prevent a loss of precision.
Expand All @@ -147,8 +149,12 @@ Oracle data types are mapped to their equivalents in Exasol. The following excep

This will cast NUMBER with precision > 36, NUMBER without precision and LONG to DECIMAL(36,20).
Keep in mind that this will yield errors if the data in the Oracle database does not fit into the specified DECIMAL type.

- `DATE` is casted to `TIMESTAMP`. This data type is only supported for positive year values, i.e., years > 0001.
- `TIMESTAMP WITH [LOCAL] TIME ZONE` is casted to `TIMESTAMP`.
- `INTERVAL` is casted to `VARCHAR`.
- `CLOB` are `NCLOB` are treated as `VARCHAR`.
- `CLOB` and `NCLOB` values are supported up to the maximum size of an Exasol [`VARCHAR`](https://docs.exasol.com/sql_references/data_types/datatypedetails.htm#StringDataType).

By default an error will be thrown if you try to import a value that is larger. If you want to import from tables which contain bigger values, you need to truncate the values.

- `BLOB`, `RAW` and `LONG RAW` are not supported.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class OracleSqlGenerationVisitor extends SqlGenerationVisitor {
private boolean requiresSelectListAliasesForLimit = false;
private static final String TIMESTAMP_FORMAT = "'YYYY-MM-DD HH24:MI:SS.FF3'";
private static final List<String> TYPE_NAMES_REQUIRING_CAST = List.of("TIMESTAMP", "INTERVAL", "BINARY_FLOAT",
"BINARY_DOUBLE", "CLOB", "NCLOB", "ROWID", "UROWID", "BLOB");
"BINARY_DOUBLE", "ROWID", "UROWID", "BLOB");
private final Set<AggregateFunction> aggregateFunctionsCast = EnumSet.noneOf(AggregateFunction.class);
private final Set<ScalarFunction> scalarFunctionsCast = EnumSet.noneOf(ScalarFunction.class);

Expand Down Expand Up @@ -62,7 +62,7 @@ Set<ScalarFunction> getScalarFunctionsCast() {
* SELECT c1, c2, ... FROM ( SELECT LIMIT_SUBSELECT.*, ROWNUM ROWNUM_SUB FROM ( &lt;query-with-aliases&gt; )
* LIMIT_SUBSELECT WHERE ROWNUM &lt;= 30 ) WHERE ROWNUM_SUB &gt; 20
*
* The rownum filter is evaluated before ORDER BY, which is why we need subselects
* The rownum filter is evaluated before ORDER BY, which is why we need sub-selects
*/
@Override
public String visit(final SqlStatementSelect select) throws AdapterException {
Expand Down Expand Up @@ -261,11 +261,10 @@ private String getProjectionString(final SqlColumn column, final String projecti
final AbstractSqlDialect dialect = (AbstractSqlDialect) getDialect();
final String typeName = ColumnAdapterNotes
.deserialize(column.getMetadata().getAdapterNotes(), column.getMetadata().getName()).getTypeName();
if (typeName.startsWith("INTERVAL") || typeName.equals("BINARY_FLOAT") || typeName.equals("BINARY_DOUBLE")
|| typeName.equals("CLOB") || typeName.equals("NCLOB")) {
if (typeName.startsWith("INTERVAL") || typeName.equals("BINARY_FLOAT") || typeName.equals("BINARY_DOUBLE")) {
return "TO_CHAR(" + projectionString + ")";
} else if (typeName.startsWith("TIMESTAMP")
&& ((OracleSqlDialect) dialect).getImportType() == ImportType.JDBC) {
&& (((OracleSqlDialect) dialect).getImportType() == ImportType.JDBC)) {
return "TO_TIMESTAMP(TO_CHAR(" + projectionString + ", " + TIMESTAMP_FORMAT + "), " + TIMESTAMP_FORMAT
+ ")";
} else if (typeName.equals("NUMBER")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ void testVisitSqlSelectListSelectStar() throws AdapterException {
assertSqlNodeConvertedToAsterisk(selectList, this.visitor);
}

@CsvSource({ "NUMBER", "INTERVAL", "BINARY_FLOAT", "BINARY_DOUBLE", "CLOB", "NCLOB" })
@CsvSource({ "NUMBER", "INTERVAL", "BINARY_FLOAT", "BINARY_DOUBLE" })
@ParameterizedTest
void testVisitSqlSelectListSelectStarCastToChar(final String dataType) throws AdapterException {
final SqlSelectList selectList = createSqlSelectStarListWithOneColumn(
Expand Down

0 comments on commit b490d31

Please sign in to comment.