script variable replaces a number that exceeds a Long type value and converts it to scientific notation (#5256)
diff --git a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/VariableUtils.scala b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/VariableUtils.scala
index bd2fab4..09c7669 100644
--- a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/VariableUtils.scala
+++ b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/utils/VariableUtils.scala
@@ -21,18 +21,11 @@
import org.apache.linkis.common.exception.LinkisCommonErrorException
import org.apache.linkis.common.variable
import org.apache.linkis.common.variable._
-import org.apache.linkis.common.variable.DateTypeUtils.{
- getCurHour,
- getMonthDay,
- getToday,
- getYesterday
-}
-
-import org.apache.commons.lang3.StringUtils
+import org.apache.linkis.common.variable.DateTypeUtils.{getCurHour, getMonthDay, getToday, getYesterday}
+import org.apache.commons.lang3.{StringUtils, Strings}
import java.time.ZonedDateTime
import java.util
-
import scala.collection.JavaConverters._
import scala.collection.mutable
import scala.util.control.Exception.allCatch
@@ -121,8 +114,9 @@
}
case _ =>
if (!nameAndType.contains(key) && StringUtils.isNotEmpty(value)) {
- if ((allCatch opt value.toDouble).isDefined) {
- nameAndType(key) = variable.DoubleValue(value.toDouble)
+// if ((allCatch opt value.toDouble).isDefined) {
+ if ((allCatch opt BigDecimal(value)).isDefined && !Strings.CS.startsWith(value, "0")) {
+ nameAndType(key) = variable.BigDecimalValue(BigDecimal(value))
} else {
nameAndType(key) = variable.StringType(value)
}
diff --git a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/variable/VariableType.scala b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/variable/VariableType.scala
index 71c6215..75e22cb 100644
--- a/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/variable/VariableType.scala
+++ b/linkis-commons/linkis-common/src/main/scala/org/apache/linkis/common/variable/VariableType.scala
@@ -110,6 +110,44 @@
}
+case class BigDecimalValue(value: BigDecimal) extends VariableType {
+ override def getValue: String = {
+ val result = bigDecimalOrLong(value)
+ result match {
+ case bd: BigDecimal => bd.bigDecimal.toPlainString
+ case _ => result.toString
+ }
+ }
+
+ def calculator(signal: String, bValue: String): String = {
+ signal match {
+ case "+" => val res = value + BigDecimal(bValue); formatResult(res)
+ case "-" => val res = value - BigDecimal(bValue); formatResult(res)
+ case "*" => val res = value * BigDecimal(bValue); formatResult(res)
+ case "/" => val res = value / BigDecimal(bValue); formatResult(res)
+ case _ =>
+ throw new LinkisCommonErrorException(20050, s"BigDecimal class is not supported to use:$signal")
+ }
+ }
+
+ private def formatResult(bd: BigDecimal): String = {
+ val result = bigDecimalOrLong(bd)
+ result match {
+ case bd: BigDecimal => bd.bigDecimal.toPlainString
+ case _ => result.toString
+ }
+ }
+
+ private def bigDecimalOrLong(bd: BigDecimal): BigDecimal = {
+ // 检查是否为整数且在 Long 范围内
+ if (bd.isWhole && bd.isValidLong) {
+ bd.longValue
+ } else {
+ bd
+ }
+ }
+}
+
case class LongType(value: Long) extends VariableType {
override def getValue: String = value.toString
diff --git a/linkis-commons/linkis-common/src/test/scala/org/apache/linkis/common/utils/VariableUtilsTest.scala b/linkis-commons/linkis-common/src/test/scala/org/apache/linkis/common/utils/VariableUtilsTest.scala
index 892731e..a293c32 100644
--- a/linkis-commons/linkis-common/src/test/scala/org/apache/linkis/common/utils/VariableUtilsTest.scala
+++ b/linkis-commons/linkis-common/src/test/scala/org/apache/linkis/common/utils/VariableUtilsTest.scala
@@ -90,4 +90,36 @@
assertEquals(nameAndValue.size, 2)
}
+ @Test def testReplaceBigDecimal(): Unit = {
+ val sql = """select
+ |${num} as num,
+ |${num-2} as num_sub2,
+ |${num+2} as num_add2,
+ |${long_num} as long_num,
+ |${long_num-1} as long_num_sub1,
+ |${long_num+1} as long_num_add1,
+ |${big_num} as big_num,
+ |${big_num-1} as big_num_sub1,
+ |${big_num+1} as big_num_add1,
+ |'${str_num}' as str_num""".stripMargin
+ val varMap = new util.HashMap[String, String]()
+ varMap.put("num", "301")
+ varMap.put("long_num", "9223372036854775807")
+ varMap.put("big_num", "3000102010000000000000000200001")
+ varMap.put("str_num", "03000102010000000000000000200001")
+
+ val resultSql = """select
+ |301 as num,
+ |299 as num_sub2,
+ |303 as num_add2,
+ |9223372036854775807 as long_num,
+ |9223372036854775806 as long_num_sub1,
+ |9223372036854775808 as long_num_add1,
+ |3000102010000000000000000200001 as big_num,
+ |3000102010000000000000000200000 as big_num_sub1,
+ |3000102010000000000000000200002 as big_num_add1,
+ |'03000102010000000000000000200001' as str_num""".stripMargin
+ assertEquals(VariableUtils.replace(sql, "sql", varMap), resultSql)
+ }
+
}