Skip to content

Commit 42b4f23

Browse files
author
Marios Trivyzas
authored
SQL: Add CAST and CONVERT to SHOW FUNCTIONS (#34940)
Fixes: #34939
1 parent 6fd7ea7 commit 42b4f23

File tree

7 files changed

+41
-12
lines changed

7 files changed

+41
-12
lines changed

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionDefinition.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ public class FunctionDefinition {
1919
public interface Builder {
2020
Function build(UnresolvedFunction uf, boolean distinct, TimeZone tz);
2121
}
22+
2223
private final String name;
2324
private final List<String> aliases;
2425
private final Class<? extends Function> clazz;

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionRegistry.java

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.elasticsearch.xpack.sql.expression.function.aggregate.Sum;
2121
import org.elasticsearch.xpack.sql.expression.function.aggregate.SumOfSquares;
2222
import org.elasticsearch.xpack.sql.expression.function.aggregate.VarPop;
23+
import org.elasticsearch.xpack.sql.expression.function.scalar.Cast;
2324
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayName;
2425
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfMonth;
2526
import org.elasticsearch.xpack.sql.expression.function.scalar.datetime.DayOfWeek;
@@ -84,6 +85,7 @@
8485
import org.elasticsearch.xpack.sql.expression.predicate.operator.arithmetic.Mod;
8586
import org.elasticsearch.xpack.sql.parser.ParsingException;
8687
import org.elasticsearch.xpack.sql.tree.Location;
88+
import org.elasticsearch.xpack.sql.type.DataType;
8789
import org.elasticsearch.xpack.sql.util.StringUtils;
8890

8991
import java.util.Arrays;
@@ -116,14 +118,14 @@ public class FunctionRegistry {
116118
public FunctionRegistry() {
117119
defineDefaultFunctions();
118120
}
119-
121+
120122
/**
121123
* Constructor specifying alternate functions for testing.
122124
*/
123125
FunctionRegistry(FunctionDefinition... functions) {
124126
addToMap(functions);
125127
}
126-
128+
127129
private void defineDefaultFunctions() {
128130
// Aggregate functions
129131
addToMap(def(Avg.class, Avg::new),
@@ -206,11 +208,13 @@ private void defineDefaultFunctions() {
206208
def(Space.class, Space::new),
207209
def(Substring.class, Substring::new),
208210
def(UCase.class, UCase::new));
211+
// DataType conversion
212+
addToMap(def(Cast.class, Cast::new, "CONVERT"));
209213
// Special
210214
addToMap(def(Score.class, Score::new));
211215
}
212-
213-
protected void addToMap(FunctionDefinition...functions) {
216+
217+
void addToMap(FunctionDefinition...functions) {
214218
// temporary map to hold [function_name/alias_name : function instance]
215219
Map<String, FunctionDefinition> batchMap = new HashMap<>();
216220
for (FunctionDefinition f : functions) {
@@ -227,7 +231,7 @@ protected void addToMap(FunctionDefinition...functions) {
227231
// sort the temporary map by key name and add it to the global map of functions
228232
defs.putAll(batchMap.entrySet().stream()
229233
.sorted(Map.Entry.comparingByKey())
230-
.collect(Collectors.<Entry<String, FunctionDefinition>, String,
234+
.collect(Collectors.<Entry<String, FunctionDefinition>, String,
231235
FunctionDefinition, LinkedHashMap<String, FunctionDefinition>> toMap(Map.Entry::getKey, Map.Entry::getValue,
232236
(oldValue, newValue) -> oldValue, LinkedHashMap::new)));
233237
}
@@ -390,7 +394,7 @@ private static FunctionDefinition def(Class<? extends Function> function, Functi
390394
private interface FunctionBuilder {
391395
Function build(Location location, List<Expression> children, boolean distinct, TimeZone tz);
392396
}
393-
397+
394398
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
395399
static <T extends Function> FunctionDefinition def(Class<T> function,
396400
ThreeParametersFunctionBuilder<T> ctorRef, String... aliases) {
@@ -408,11 +412,11 @@ static <T extends Function> FunctionDefinition def(Class<T> function,
408412
};
409413
return def(function, builder, false, aliases);
410414
}
411-
415+
412416
interface ThreeParametersFunctionBuilder<T> {
413417
T build(Location location, Expression source, Expression exp1, Expression exp2);
414418
}
415-
419+
416420
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
417421
static <T extends Function> FunctionDefinition def(Class<T> function,
418422
FourParametersFunctionBuilder<T> ctorRef, String... aliases) {
@@ -427,11 +431,29 @@ static <T extends Function> FunctionDefinition def(Class<T> function,
427431
};
428432
return def(function, builder, false, aliases);
429433
}
430-
434+
431435
interface FourParametersFunctionBuilder<T> {
432436
T build(Location location, Expression source, Expression exp1, Expression exp2, Expression exp3);
433437
}
434438

439+
/**
440+
* Special method to create function definition for {@link Cast} as its
441+
* signature is not compatible with {@link UnresolvedFunction}
442+
*
443+
* @return Cast function definition
444+
*/
445+
@SuppressWarnings("overloads") // These are ambiguous if you aren't using ctor references but we always do
446+
private static <T extends Function> FunctionDefinition def(Class<T> function,
447+
CastFunctionBuilder<T> ctorRef,
448+
String... aliases) {
449+
FunctionBuilder builder = (location, children, distinct, tz) ->
450+
ctorRef.build(location, children.get(0), children.get(0).dataType());
451+
return def(function, builder, false, aliases);
452+
}
453+
private interface CastFunctionBuilder<T> {
454+
T build(Location location, Expression expression, DataType dataType);
455+
}
456+
435457
private static String normalize(String name) {
436458
// translate CamelCase to camel_case
437459
return StringUtils.camelCaseToUnderscore(name);

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/FunctionType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
import org.elasticsearch.xpack.sql.SqlIllegalArgumentException;
99
import org.elasticsearch.xpack.sql.expression.function.aggregate.AggregateFunction;
1010
import org.elasticsearch.xpack.sql.expression.function.scalar.ScalarFunction;
11-
import org.elasticsearch.xpack.sql.expression.function.Score;
1211

1312

1413
public enum FunctionType {
14+
1515
AGGREGATE(AggregateFunction.class),
1616
SCALAR(ScalarFunction.class),
1717
SCORE(Score.class);

x-pack/plugin/sql/src/main/java/org/elasticsearch/xpack/sql/expression/function/scalar/Cast.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.Objects;
1717

1818
public class Cast extends UnaryScalarFunction {
19+
1920
private final DataType dataType;
2021

2122
public Cast(Location location, Expression field, DataType dataType) {

x-pack/qa/sql/src/main/java/org/elasticsearch/xpack/qa/sql/cli/ShowTestCase.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ public void testShowFunctions() throws IOException {
3939
while (scalarFunction.matcher(line).matches()) {
4040
line = readLine();
4141
}
42+
4243
assertThat(line, RegexMatcher.matches("\\s*SCORE\\s*\\|\\s*SCORE\\s*"));
4344
assertEquals("", readLine());
4445
}

x-pack/qa/sql/src/main/resources/command.csv-spec

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,9 @@ RTRIM |SCALAR
9999
SPACE |SCALAR
100100
SUBSTRING |SCALAR
101101
UCASE |SCALAR
102-
SCORE |SCORE
102+
CAST |SCALAR
103+
CONVERT |SCALAR
104+
SCORE |SCORE
103105
;
104106

105107
showFunctionsWithExactMatch

x-pack/qa/sql/src/main/resources/docs.csv-spec

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,9 @@ RTRIM |SCALAR
276276
SPACE |SCALAR
277277
SUBSTRING |SCALAR
278278
UCASE |SCALAR
279-
SCORE |SCORE
279+
CAST |SCALAR
280+
CONVERT |SCALAR
281+
SCORE |SCORE
280282
// end::showFunctions
281283
;
282284

0 commit comments

Comments
 (0)