Skip to content

Commit 9ebbdf0

Browse files
Marios Trivyzaskcm
Marios Trivyzas
authored andcommitted
SQL: Implement CONVERT, an alternative to CAST (#34660)
`CONVERT` works exactly like cast with slightly different syntax: `CONVERT(<value>, <data_type)` as opposed to `CAST(<value> AS <data_type>)` Moreover it support format of the MS-SQL data types `SQL_<type>`, e.g.: `SQL_INTEGER` Closes: #34513
1 parent 2cfef17 commit 9ebbdf0

File tree

15 files changed

+1841
-1482
lines changed

15 files changed

+1841
-1482
lines changed

docs/reference/sql/functions/type-conversion.asciidoc

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ CAST ( expression<1> AS data_type<2> )
1919

2020
.Description
2121

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

@@ -36,4 +36,33 @@ include-tagged::{sql-specs}/docs.csv-spec[conversionIntToStringCast]
3636
["source","sql",subs="attributes,callouts,macros"]
3737
----
3838
include-tagged::{sql-specs}/docs.csv-spec[conversionStringToDateCast]
39-
----
39+
----
40+
41+
42+
[[sql-functions-type-conversion-convert]]
43+
==== `CONVERT`
44+
45+
.Synopsis
46+
[source, sql]
47+
----
48+
CONVERT ( expression<1>, data_type<2> )
49+
----
50+
51+
<1> Expression to convert
52+
<2> Target data type to convert to
53+
54+
.Description
55+
56+
Works exactly like <<sql-functions-type-conversion-cast>> with slightly different syntax.
57+
Moreover, apart from the standard <<sql-data-types, data types>> it supports the corresponding
58+
https://docs.microsoft.com/en-us/sql/odbc/reference/appendixes/explicit-data-type-conversion-function?view=sql-server-2017[ODBC data types].
59+
60+
["source","sql",subs="attributes,callouts,macros"]
61+
----
62+
include-tagged::{sql-specs}/docs.csv-spec[conversionStringToIntConvertODBCDataType]
63+
----
64+
65+
["source","sql",subs="attributes,callouts,macros"]
66+
----
67+
include-tagged::{sql-specs}/docs.csv-spec[conversionStringToIntConvertESDataType]
68+
----

x-pack/plugin/sql/sql-proto/src/main/java/org/elasticsearch/xpack/sql/type/DataType.java

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.sql.SQLType;
1010
import java.sql.Timestamp;
1111
import java.util.Arrays;
12+
import java.util.HashMap;
1213
import java.util.Locale;
1314
import java.util.Map;
1415
import java.util.stream.Collectors;
@@ -44,12 +45,63 @@ public enum DataType {
4445
DATE( JDBCType.TIMESTAMP, Timestamp.class, Long.BYTES, 24, 24);
4546
// @formatter:on
4647

48+
public static final String ODBC_DATATYPE_PREFIX = "SQL_";
49+
4750
private static final Map<SQLType, DataType> jdbcToEs;
51+
private static final Map<String, DataType> odbcToEs;
4852

4953
static {
5054
jdbcToEs = Arrays.stream(DataType.values())
5155
.filter(dataType -> dataType != TEXT && dataType != NESTED && dataType != SCALED_FLOAT) // Remove duplicates
5256
.collect(Collectors.toMap(dataType -> dataType.jdbcType, dataType -> dataType));
57+
58+
odbcToEs = new HashMap<>(36);
59+
60+
// Numeric
61+
odbcToEs.put("SQL_BIT", BOOLEAN);
62+
odbcToEs.put("SQL_TINYINT", BYTE);
63+
odbcToEs.put("SQL_SMALLINT", SHORT);
64+
odbcToEs.put("SQL_INTEGER", INTEGER);
65+
odbcToEs.put("SQL_BIGINT", LONG);
66+
odbcToEs.put("SQL_FLOAT", FLOAT);
67+
odbcToEs.put("SQL_REAL", FLOAT);
68+
odbcToEs.put("SQL_DOUBLE", DOUBLE);
69+
odbcToEs.put("SQL_DECIMAL", DOUBLE);
70+
odbcToEs.put("SQL_NUMERIC", DOUBLE);
71+
72+
// String
73+
odbcToEs.put("SQL_GUID", KEYWORD);
74+
odbcToEs.put("SQL_CHAR", KEYWORD);
75+
odbcToEs.put("SQL_WCHAR", KEYWORD);
76+
odbcToEs.put("SQL_VARCHAR", TEXT);
77+
odbcToEs.put("SQL_WVARCHAR", TEXT);
78+
odbcToEs.put("SQL_LONGVARCHAR", TEXT);
79+
odbcToEs.put("SQL_WLONGVARCHAR", TEXT);
80+
81+
// Binary
82+
odbcToEs.put("SQL_BINARY", BINARY);
83+
odbcToEs.put("SQL_VARBINARY", BINARY);
84+
odbcToEs.put("SQL_LONGVARBINARY", BINARY);
85+
86+
// Date
87+
odbcToEs.put("SQL_DATE", DATE);
88+
odbcToEs.put("SQL_TIME", DATE);
89+
odbcToEs.put("SQL_TIMESTAMP", DATE);
90+
91+
// Intervals - Currently Not Supported
92+
odbcToEs.put("SQL_INTERVAL_HOUR_TO_MINUTE", UNSUPPORTED);
93+
odbcToEs.put("SQL_INTERVAL_HOUR_TO_SECOND", UNSUPPORTED);
94+
odbcToEs.put("SQL_INTERVAL_MINUTE_TO_SECOND", UNSUPPORTED);
95+
odbcToEs.put("SQL_INTERVAL_MONTH", UNSUPPORTED);
96+
odbcToEs.put("SQL_INTERVAL_YEAR", UNSUPPORTED);
97+
odbcToEs.put("SQL_INTERVAL_YEAR_TO_MONTH", UNSUPPORTED);
98+
odbcToEs.put("SQL_INTERVAL_DAY", UNSUPPORTED);
99+
odbcToEs.put("SQL_INTERVAL_HOUR", UNSUPPORTED);
100+
odbcToEs.put("SQL_INTERVAL_MINUTE", UNSUPPORTED);
101+
odbcToEs.put("SQL_INTERVAL_SECOND", UNSUPPORTED);
102+
odbcToEs.put("SQL_INTERVAL_DAY_TO_HOUR", UNSUPPORTED);
103+
odbcToEs.put("SQL_INTERVAL_DAY_TO_MINUTE", UNSUPPORTED);
104+
odbcToEs.put("SQL_INTERVAL_DAY_TO_SECOND", UNSUPPORTED);
53105
}
54106

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

217+
public static DataType fromODBCType(String odbcType) {
218+
return odbcToEs.get(odbcType);
219+
}
165220
/**
166221
* Creates returns DataType enum coresponding to the specified es type
167222
* <p>
@@ -170,4 +225,4 @@ public static Class<?> fromJdbcTypeToJava(SQLType jdbcType) {
170225
public static DataType fromEsType(String esType) {
171226
return DataType.valueOf(esType.toUpperCase(Locale.ROOT));
172227
}
173-
}
228+
}

x-pack/plugin/sql/src/main/antlr/SqlBase.g4

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -226,14 +226,20 @@ primaryExpression
226226
;
227227

228228
castExpression
229-
: castTemplate
230-
| FUNCTION_ESC castTemplate ESC_END
229+
: castTemplate
230+
| FUNCTION_ESC castTemplate ESC_END
231+
| convertTemplate
232+
| FUNCTION_ESC convertTemplate ESC_END
231233
;
232234

233235
castTemplate
234236
: CAST '(' expression AS dataType ')'
235237
;
236-
238+
239+
convertTemplate
240+
: CONVERT '(' expression ',' dataType ')'
241+
;
242+
237243
extractExpression
238244
: extractTemplate
239245
| FUNCTION_ESC extractTemplate ESC_END
@@ -347,6 +353,7 @@ CAST: 'CAST';
347353
CATALOG: 'CATALOG';
348354
CATALOGS: 'CATALOGS';
349355
COLUMNS: 'COLUMNS';
356+
CONVERT: 'CONVERT';
350357
DEBUG: 'DEBUG';
351358
DESC: 'DESC';
352359
DESCRIBE: 'DESCRIBE';

0 commit comments

Comments
 (0)