SQL: Scripting support for casting functions CAST and CONVERT (#36640)
This commit is contained in:
parent
c0866393ee
commit
b15f27f6a6
|
@ -130,12 +130,66 @@ SELECT MAX(languages) max, MIN(languages) min, SUM(languages) sum, AVG(languages
|
||||||
FROM test_emp GROUP BY languages ORDER BY languages ASC LIMIT 5;
|
FROM test_emp GROUP BY languages ORDER BY languages ASC LIMIT 5;
|
||||||
|
|
||||||
max:bt | min:bt | sum:bt | avg:d | percent:d | percent_rank:d| kurtosis:d | skewness:d
|
max:bt | min:bt | sum:bt | avg:d | percent:d | percent_rank:d| kurtosis:d | skewness:d
|
||||||
---------------+---------------+---------------+---------------+---------------+---------------+---------------+---------------
|
---------------+---------------+---------------+--------------+---------------+---------------+---------------+---------------
|
||||||
null |null |null |null |null |null |null |null
|
null |null |null |null |null |null |null |null
|
||||||
1 |1 |15 |1 |1.0 |100.0 |NaN |NaN
|
1 |1 |15 |1 |1.0 |100.0 |NaN |NaN
|
||||||
2 |2 |38 |2 |2.0 |100.0 |NaN |NaN
|
2 |2 |38 |2 |2.0 |100.0 |NaN |NaN
|
||||||
3 |3 |51 |3 |3.0 |100.0 |NaN |NaN
|
3 |3 |51 |3 |3.0 |100.0 |NaN |NaN
|
||||||
4 |4 |72 |4 |4.0 |0.0 |NaN |NaN
|
4 |4 |72 |4 |4.0 |0.0 |NaN |NaN
|
||||||
|
;
|
||||||
|
|
||||||
|
aggByComplexCastedValue
|
||||||
|
SELECT CONVERT(CONCAT(LTRIM(CONVERT("emp_no", SQL_VARCHAR)), LTRIM(CONVERT("languages", SQL_VARCHAR))), SQL_BIGINT) AS "TEMP"
|
||||||
|
FROM "test_emp" GROUP BY "TEMP" ORDER BY "TEMP" LIMIT 20;
|
||||||
|
|
||||||
|
TEMP:l
|
||||||
|
---------------
|
||||||
|
10020
|
||||||
|
10021
|
||||||
|
10022
|
||||||
|
10023
|
||||||
|
10024
|
||||||
|
10025
|
||||||
|
10026
|
||||||
|
10027
|
||||||
|
10028
|
||||||
|
10029
|
||||||
|
100012
|
||||||
|
100025
|
||||||
|
100034
|
||||||
|
100045
|
||||||
|
100051
|
||||||
|
100063
|
||||||
|
100074
|
||||||
|
100082
|
||||||
|
100091
|
||||||
|
100104
|
||||||
|
;
|
||||||
|
|
||||||
|
aggAndOrderByCastedValue
|
||||||
|
SELECT CHAR_LENGTH(SPACE(CAST(languages AS SMALLINT))), COUNT(*) FROM test_emp GROUP BY 1 ORDER BY 1 DESC;
|
||||||
|
|
||||||
|
CHAR_LENGTH(SPACE(CAST(languages AS SMALLINT))):i| COUNT(1):l
|
||||||
|
-------------------------------------------------+---------------
|
||||||
|
5 |21
|
||||||
|
4 |18
|
||||||
|
3 |17
|
||||||
|
2 |19
|
||||||
|
1 |15
|
||||||
|
null |10
|
||||||
|
;
|
||||||
|
|
||||||
|
aggAndOrderByCastedFunctionValue
|
||||||
|
SELECT ROUND(SQRT(CAST(EXP(languages) AS SMALLINT)), 2), COUNT(*) FROM test_emp GROUP BY 1 ORDER BY 1 DESC;
|
||||||
|
|
||||||
|
ROUND(SQRT(CAST(EXP(languages) AS SMALLINT)),2):d| COUNT(1):l
|
||||||
|
-------------------------------------------------+---------------
|
||||||
|
12.17 |21
|
||||||
|
7.42 |18
|
||||||
|
4.47 |17
|
||||||
|
2.65 |19
|
||||||
|
1.73 |15
|
||||||
|
null |10
|
||||||
;
|
;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,14 +7,18 @@ package org.elasticsearch.xpack.sql.expression.function.scalar;
|
||||||
|
|
||||||
import org.elasticsearch.xpack.sql.expression.Expression;
|
import org.elasticsearch.xpack.sql.expression.Expression;
|
||||||
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
|
import org.elasticsearch.xpack.sql.expression.gen.processor.Processor;
|
||||||
|
import org.elasticsearch.xpack.sql.expression.gen.script.ScriptTemplate;
|
||||||
import org.elasticsearch.xpack.sql.tree.Location;
|
import org.elasticsearch.xpack.sql.tree.Location;
|
||||||
import org.elasticsearch.xpack.sql.tree.NodeInfo;
|
import org.elasticsearch.xpack.sql.tree.NodeInfo;
|
||||||
import org.elasticsearch.xpack.sql.type.DataType;
|
import org.elasticsearch.xpack.sql.type.DataType;
|
||||||
import org.elasticsearch.xpack.sql.type.DataTypeConversion;
|
import org.elasticsearch.xpack.sql.type.DataTypeConversion;
|
||||||
import org.elasticsearch.xpack.sql.type.DataTypes;
|
import org.elasticsearch.xpack.sql.type.DataTypes;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import static org.elasticsearch.xpack.sql.expression.gen.script.ParamsBuilder.paramsBuilder;
|
||||||
|
|
||||||
public class Cast extends UnaryScalarFunction {
|
public class Cast extends UnaryScalarFunction {
|
||||||
|
|
||||||
private final DataType dataType;
|
private final DataType dataType;
|
||||||
|
@ -74,6 +78,18 @@ public class Cast extends UnaryScalarFunction {
|
||||||
return new CastProcessor(DataTypeConversion.conversionFor(from(), to()));
|
return new CastProcessor(DataTypeConversion.conversionFor(from(), to()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ScriptTemplate asScript() {
|
||||||
|
ScriptTemplate fieldAsScript = asScript(field());
|
||||||
|
return new ScriptTemplate(
|
||||||
|
formatTemplate(String.format(Locale.ROOT, "{sql}.cast(%s,{})", fieldAsScript.template())),
|
||||||
|
paramsBuilder()
|
||||||
|
.script(fieldAsScript.params())
|
||||||
|
.variable(dataType.name())
|
||||||
|
.build(),
|
||||||
|
dataType());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(super.hashCode(), dataType);
|
return Objects.hash(super.hashCode(), dataType);
|
||||||
|
|
|
@ -35,6 +35,7 @@ import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.Bina
|
||||||
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.InProcessor;
|
import org.elasticsearch.xpack.sql.expression.predicate.operator.comparison.InProcessor;
|
||||||
import org.elasticsearch.xpack.sql.expression.predicate.regex.RegexProcessor.RegexOperation;
|
import org.elasticsearch.xpack.sql.expression.predicate.regex.RegexProcessor.RegexOperation;
|
||||||
import org.elasticsearch.xpack.sql.type.DataType;
|
import org.elasticsearch.xpack.sql.type.DataType;
|
||||||
|
import org.elasticsearch.xpack.sql.type.DataTypeConversion;
|
||||||
import org.elasticsearch.xpack.sql.util.DateUtils;
|
import org.elasticsearch.xpack.sql.util.DateUtils;
|
||||||
import org.elasticsearch.xpack.sql.util.StringUtils;
|
import org.elasticsearch.xpack.sql.util.StringUtils;
|
||||||
|
|
||||||
|
@ -458,4 +459,11 @@ public final class InternalSqlScriptUtils {
|
||||||
public static String ucase(String s) {
|
public static String ucase(String s) {
|
||||||
return (String) StringOperation.UCASE.apply(s);
|
return (String) StringOperation.UCASE.apply(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Casting
|
||||||
|
//
|
||||||
|
public static Object cast(Object value, String typeName) {
|
||||||
|
return DataTypeConversion.convert(value, DataType.fromTypeName(typeName));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -130,4 +130,9 @@ class org.elasticsearch.xpack.sql.expression.function.scalar.whitelist.InternalS
|
||||||
String space(Number)
|
String space(Number)
|
||||||
String substring(String, Number, Number)
|
String substring(String, Number, Number)
|
||||||
String ucase(String)
|
String ucase(String)
|
||||||
|
|
||||||
|
#
|
||||||
|
# Casting
|
||||||
|
#
|
||||||
|
def cast(Object, String)
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,10 +240,10 @@ public class QueryFolderTests extends ESTestCase {
|
||||||
assertEquals(EsQueryExec.class, p.getClass());
|
assertEquals(EsQueryExec.class, p.getClass());
|
||||||
EsQueryExec ee = (EsQueryExec) p;
|
EsQueryExec ee = (EsQueryExec) p;
|
||||||
assertThat(ee.queryContainer().aggs().asAggBuilder().toString().replaceAll("\\s+", ""),
|
assertThat(ee.queryContainer().aggs().asAggBuilder().toString().replaceAll("\\s+", ""),
|
||||||
endsWith("{\"script\":{" +
|
endsWith("{\"script\":{\"source\":\"InternalSqlScriptUtils.cast(" +
|
||||||
"\"source\":\"InternalSqlScriptUtils.docValue(doc,params.v0)\",\"lang\":\"painless\"," +
|
"InternalSqlScriptUtils.docValue(doc,params.v0),params.v1)\"," +
|
||||||
"\"params\":{\"v0\":\"keyword\"}},\"missing_bucket\":true," +
|
"\"lang\":\"painless\",\"params\":{\"v0\":\"keyword\",\"v1\":\"IP\"}}," +
|
||||||
"\"value_type\":\"ip\",\"order\":\"asc\"}}}]}}}"));
|
"\"missing_bucket\":true,\"value_type\":\"ip\",\"order\":\"asc\"}}}]}}}"));
|
||||||
assertEquals(2, ee.output().size());
|
assertEquals(2, ee.output().size());
|
||||||
assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->"));
|
assertThat(ee.output().get(0).toString(), startsWith("COUNT(1){a->"));
|
||||||
assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
|
assertThat(ee.output().get(1).toString(), startsWith("a{s->"));
|
||||||
|
|
Loading…
Reference in New Issue