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[MS-SQL data types].

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

["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 MSSQL_DATATYPE_PREFIX = "SQL_";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not so much MSSQL as ODBC spec.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, replaced all MSSQL with ODBC.


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

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));

mssqlToEs = new HashMap<>(36);

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

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

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

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

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

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

public static DataType fromMSSQLType(String mssqlType) {
return mssqlToEs.get(mssqlType);
}
/**
* 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