From 791e17d5e7f8399ead77cb67b64523677784a257 Mon Sep 17 00:00:00 2001 From: hujianjun <2283438167@qq.com> Date: Wed, 10 Sep 2025 21:39:45 +0800 Subject: [PATCH] script variable replaces a number that exceeds a Long type value and converts it to scientific notation --- .../linkis/common/utils/VariableUtils.scala | 16 +++----- .../linkis/common/variable/VariableType.scala | 38 +++++++++++++++++++ .../common/utils/VariableUtilsTest.scala | 32 ++++++++++++++++ 3 files changed, 75 insertions(+), 11 deletions(-) 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 bd2fab49302..09c7669fe44 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.conf.Configuration 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 @@ object VariableUtils extends Logging { } 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 71c6215b7ac..75e22cb51ba 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 YearType(value: CustomYearType) extends VariableType { } +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 892731e0d5f..a293c32590c 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 @@ class VariableUtilsTest { 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) + } + }