From ed49ac6062d3291b0d690ee9b490deb0ab4eab64 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Mon, 4 Aug 2025 23:58:58 +0000 Subject: [PATCH] Increase the precision of sum return type (#3974) Signed-off-by: Heng Qian (cherry picked from commit db2a8bfaaabb0594d5d7e6565a2e95b4a0d29e26) Signed-off-by: github-actions[bot] --- .../sql/executor/OpenSearchTypeSystem.java | 22 ++++++- .../sql/calcite/tpch/CalcitePPLTpchIT.java | 4 +- .../rest-api-spec/test/issues/3958.yml | 57 +++++++++++++++++++ 3 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 integ-test/src/yamlRestTest/resources/rest-api-spec/test/issues/3958.yml diff --git a/core/src/main/java/org/opensearch/sql/executor/OpenSearchTypeSystem.java b/core/src/main/java/org/opensearch/sql/executor/OpenSearchTypeSystem.java index c257fbe700d..4771ce3497a 100644 --- a/core/src/main/java/org/opensearch/sql/executor/OpenSearchTypeSystem.java +++ b/core/src/main/java/org/opensearch/sql/executor/OpenSearchTypeSystem.java @@ -5,10 +5,14 @@ package org.opensearch.sql.executor; +import static org.apache.calcite.sql.type.SqlTypeName.APPROX_TYPES; +import static org.apache.calcite.sql.type.SqlTypeName.INT_TYPES; + import org.apache.calcite.rel.type.RelDataType; import org.apache.calcite.rel.type.RelDataTypeFactory; import org.apache.calcite.rel.type.RelDataTypeSystem; import org.apache.calcite.rel.type.RelDataTypeSystemImpl; +import org.apache.calcite.sql.type.BasicSqlType; import org.apache.calcite.sql.type.SqlTypeName; public class OpenSearchTypeSystem extends RelDataTypeSystemImpl { @@ -20,7 +24,7 @@ private OpenSearchTypeSystem() {} public RelDataType deriveAvgAggType(RelDataTypeFactory typeFactory, RelDataType argumentType) { if (SqlTypeName.DECIMAL == argumentType.getSqlTypeName()) { return typeFactory.createTypeWithNullability(highPrecision(typeFactory, argumentType), false); - } else if (SqlTypeName.INT_TYPES.contains(argumentType.getSqlTypeName())) { + } else if (INT_TYPES.contains(argumentType.getSqlTypeName())) { return typeFactory.createTypeWithNullability( typeFactory.createSqlType(SqlTypeName.DOUBLE), false); } else { @@ -28,6 +32,22 @@ public RelDataType deriveAvgAggType(RelDataTypeFactory typeFactory, RelDataType } } + @Override + public RelDataType deriveSumType(RelDataTypeFactory typeFactory, RelDataType argumentType) { + argumentType = super.deriveSumType(typeFactory, argumentType); + if (argumentType instanceof BasicSqlType) { + SqlTypeName typeName = argumentType.getSqlTypeName(); + if (INT_TYPES.contains(typeName)) { + return typeFactory.createTypeWithNullability( + typeFactory.createSqlType(SqlTypeName.BIGINT), argumentType.isNullable()); + } else if (APPROX_TYPES.contains(typeName)) { + return typeFactory.createTypeWithNullability( + typeFactory.createSqlType(SqlTypeName.DOUBLE), argumentType.isNullable()); + } + } + return argumentType; + } + /** * Compute a higher precision version of a type. * diff --git a/integ-test/src/test/java/org/opensearch/sql/calcite/tpch/CalcitePPLTpchIT.java b/integ-test/src/test/java/org/opensearch/sql/calcite/tpch/CalcitePPLTpchIT.java index 46107a60b04..9141fc30925 100644 --- a/integ-test/src/test/java/org/opensearch/sql/calcite/tpch/CalcitePPLTpchIT.java +++ b/integ-test/src/test/java/org/opensearch/sql/calcite/tpch/CalcitePPLTpchIT.java @@ -249,8 +249,8 @@ public void testQ12() throws IOException { verifySchemaInOrder( actual, schema("l_shipmode", "string"), - schema("high_line_count", "int"), - schema("low_line_count", "int")); + schema("high_line_count", "bigint"), + schema("low_line_count", "bigint")); verifyDataRows(actual, rows("MAIL", 5, 5), rows("SHIP", 5, 10)); } diff --git a/integ-test/src/yamlRestTest/resources/rest-api-spec/test/issues/3958.yml b/integ-test/src/yamlRestTest/resources/rest-api-spec/test/issues/3958.yml new file mode 100644 index 00000000000..cad70397ab4 --- /dev/null +++ b/integ-test/src/yamlRestTest/resources/rest-api-spec/test/issues/3958.yml @@ -0,0 +1,57 @@ +setup: + - do: + query.settings: + body: + transient: + plugins.calcite.enabled : true + plugins.calcite.fallback.allowed : false + + - do: + indices.create: + index: tmp + body: + settings: + number_of_shards: 1 + number_of_replicas: 0 + mappings: + properties: + demo: + type: short + + +--- +teardown: + - do: + query.settings: + body: + transient: + plugins.calcite.enabled : false + plugins.calcite.fallback.allowed : true + +--- +"Handle sum results exceeds the max value of short": + - skip: + features: + - headers + - allowed_warnings + - do: + bulk: + index: tmp + refresh: true + body: + - '{"index": {}}' + - '{"demo": 20000}' + - '{"index": {}}' + - '{"demo": 20000}' + + - do: + allowed_warnings: + - 'Loading the fielddata on the _id field is deprecated and will be removed in future versions. If you require sorting or aggregating on this field you should also include the id in the body of your documents, and map this field as a keyword field that has [doc_values] enabled' + headers: + Content-Type: 'application/json' + ppl: + body: + query: 'source=tmp | stats sum(demo)' + - match: {"total": 1} + - match: {"schema": [{"name": "sum(demo)", "type": "bigint"}]} + - match: {"datarows": [[40000]]}