Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SQL: Implement CONVERT, an alternative to CAST #34660

Merged
merged 9 commits into from
Oct 23, 2018
33 changes: 31 additions & 2 deletions docs/reference/sql/functions/type-conversion.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ CAST ( expression<1> AS data_type<2> )

.Description

Casts the result of the given expression to the target type.
Casts the result of the given expression to the target <<sql-data-types, data type>>.
If the cast is not possible (for example because of target type is too narrow or because
the value itself cannot be converted), the query fails.

Expand All @@ -36,4 +36,33 @@ include-tagged::{sql-specs}/docs.csv-spec[conversionIntToStringCast]
["source","sql",subs="attributes,callouts,macros"]
----
include-tagged::{sql-specs}/docs.csv-spec[conversionStringToDateCast]
----
----


[[sql-functions-type-conversion-convert]]
==== `CONVERT`

.Synopsis
[source, sql]
----
CONVERT ( expression<1>, data_type<2> )
----

<1> Expression to convert
<2> Target data type to convert to

.Description

Works exactly like <<sql-functions-type-conversion-cast>> with slightly different syntax.
Moreover, apart from the standard <<sql-data-types, data types>> it supports the corresponding
https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/explicit-data-type-conversion-function?view=sql-server-2017[ODBC data types].

["source","sql",subs="attributes,callouts,macros"]
----
include-tagged::{sql-specs}/docs.csv-spec[conversionStringToIntConvertODBCDataType]
----

["source","sql",subs="attributes,callouts,macros"]
----
include-tagged::{sql-specs}/docs.csv-spec[conversionStringToIntConvertESDataType]
----
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.sql.SQLType;
import java.sql.Timestamp;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;
Expand Down Expand Up @@ -44,12 +45,63 @@ public enum DataType {
DATE( JDBCType.TIMESTAMP, Timestamp.class, Long.BYTES, 24, 24);
// @formatter:on

public static final String ODBC_DATATYPE_PREFIX = "SQL_";

private static final Map<SQLType, DataType> jdbcToEs;
private static final Map<String, DataType> odbcToEs;

static {
jdbcToEs = Arrays.stream(DataType.values())
.filter(dataType -> dataType != TEXT && dataType != NESTED && dataType != SCALED_FLOAT) // Remove duplicates
.collect(Collectors.toMap(dataType -> dataType.jdbcType, dataType -> dataType));

odbcToEs = new HashMap<>(36);

// Numeric
odbcToEs.put("SQL_BIT", BOOLEAN);
odbcToEs.put("SQL_TINYINT", BYTE);
odbcToEs.put("SQL_SMALLINT", SHORT);
odbcToEs.put("SQL_INTEGER", INTEGER);
odbcToEs.put("SQL_BIGINT", LONG);
odbcToEs.put("SQL_FLOAT", FLOAT);
odbcToEs.put("SQL_REAL", FLOAT);
odbcToEs.put("SQL_DOUBLE", DOUBLE);
odbcToEs.put("SQL_DECIMAL", DOUBLE);
odbcToEs.put("SQL_NUMERIC", DOUBLE);

// String
odbcToEs.put("SQL_GUID", KEYWORD);
odbcToEs.put("SQL_CHAR", KEYWORD);
odbcToEs.put("SQL_WCHAR", KEYWORD);
odbcToEs.put("SQL_VARCHAR", TEXT);
odbcToEs.put("SQL_WVARCHAR", TEXT);
odbcToEs.put("SQL_LONGVARCHAR", TEXT);
odbcToEs.put("SQL_WLONGVARCHAR", TEXT);

// Binary
odbcToEs.put("SQL_BINARY", BINARY);
odbcToEs.put("SQL_VARBINARY", BINARY);
odbcToEs.put("SQL_LONGVARBINARY", BINARY);

// Date
odbcToEs.put("SQL_DATE", DATE);
odbcToEs.put("SQL_TIME", DATE);
odbcToEs.put("SQL_TIMESTAMP", DATE);

// Intervals - Currently Not Supported
odbcToEs.put("SQL_INTERVAL_HOUR_TO_MINUTE", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_HOUR_TO_SECOND", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_MINUTE_TO_SECOND", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_MONTH", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_YEAR", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_YEAR_TO_MONTH", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_DAY", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_HOUR", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_MINUTE", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_SECOND", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_DAY_TO_HOUR", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_DAY_TO_MINUTE", UNSUPPORTED);
odbcToEs.put("SQL_INTERVAL_DAY_TO_SECOND", UNSUPPORTED);
}

/**
Expand Down Expand Up @@ -162,6 +214,9 @@ public static Class<?> fromJdbcTypeToJava(SQLType jdbcType) {
return jdbcToEs.get(jdbcType).javaClass();
}

public static DataType fromODBCType(String odbcType) {
return odbcToEs.get(odbcType);
}
/**
* Creates returns DataType enum coresponding to the specified es type
* <p>
Expand All @@ -170,4 +225,4 @@ public static Class<?> fromJdbcTypeToJava(SQLType jdbcType) {
public static DataType fromEsType(String esType) {
return DataType.valueOf(esType.toUpperCase(Locale.ROOT));
}
}
}
13 changes: 10 additions & 3 deletions x-pack/plugin/sql/src/main/antlr/SqlBase.g4
Original file line number Diff line number Diff line change
Expand Up @@ -226,14 +226,20 @@ primaryExpression
;

castExpression
: castTemplate
| FUNCTION_ESC castTemplate ESC_END
: castTemplate
| FUNCTION_ESC castTemplate ESC_END
| convertTemplate
| FUNCTION_ESC convertTemplate ESC_END
;

castTemplate
: CAST '(' expression AS dataType ')'
;


convertTemplate
: CONVERT '(' expression ',' dataType ')'
;

extractExpression
: extractTemplate
| FUNCTION_ESC extractTemplate ESC_END
Expand Down Expand Up @@ -347,6 +353,7 @@ CAST: 'CAST';
CATALOG: 'CATALOG';
CATALOGS: 'CATALOGS';
COLUMNS: 'COLUMNS';
CONVERT: 'CONVERT';
DEBUG: 'DEBUG';
DESC: 'DESC';
DESCRIBE: 'DESCRIBE';
Expand Down
Loading