diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/StringLiteral.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/StringLiteral.java index e6dcdead4d2d74..5e55ae1a23f2d1 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/StringLiteral.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/StringLiteral.java @@ -20,18 +20,20 @@ import org.apache.doris.catalog.PrimitiveType; import org.apache.doris.catalog.Type; import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.DdlException; import org.apache.doris.common.ErrorCode; import org.apache.doris.common.ErrorReport; import org.apache.doris.common.io.Text; +import org.apache.doris.qe.SqlModeHelper; import org.apache.doris.thrift.TExprNode; import org.apache.doris.thrift.TExprNodeType; import org.apache.doris.thrift.TStringLiteral; -import com.google.common.base.Preconditions; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import com.google.common.base.Preconditions; + import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; @@ -41,6 +43,18 @@ public class StringLiteral extends LiteralExpr { private static final Logger LOG = LogManager.getLogger(StringLiteral.class); private String value; + /** + * the session variable `sql_mode` is a special kind of variable. + * it's real type is int, so when querying `select @@sql_mode`, the return column + * type is "int". but user usually set this variable by string, such as: + * `set @@sql_mode = 'STRICT_TRANS_TABLES'` + * or + * `set @@sql_mode = concat(@@sql_mode, 'STRICT_TRANS_TABLES')'` + *
+ * So when it need to be cast to int, it means "cast 'STRICT_TRANS_TABLES' to Integer". + * To support this, we set `isSqlMode` to true, so that it can cast sql mode name to integer. + */ + private boolean isSqlMode = false; public StringLiteral() { super(); @@ -59,6 +73,10 @@ protected StringLiteral(StringLiteral other) { value = other.value; } + public void setIsSqlMode(boolean val) { + this.isSqlMode = val; + } + @Override public Expr clone() { return new StringLiteral(this); @@ -178,8 +196,24 @@ protected Expr uncheckedCastTo(Type targetType) throws AnalysisException { case SMALLINT: case INT: case BIGINT: + if (isSqlMode) { + try { + long sqlMode = SqlModeHelper.encode(value); + return new IntLiteral(sqlMode, targetType); + } catch (DdlException e) { + throw new AnalysisException(e.getMessage()); + } + } return new IntLiteral(value, targetType); case LARGEINT: + if (isSqlMode) { + try { + long sqlMode = SqlModeHelper.encode(value); + return new LargeIntLiteral(String.valueOf(sqlMode)); + } catch (DdlException e) { + throw new AnalysisException(e.getMessage()); + } + } return new LargeIntLiteral(value); case FLOAT: case DOUBLE: diff --git a/fe/fe-core/src/main/java/org/apache/doris/analysis/SysVariableDesc.java b/fe/fe-core/src/main/java/org/apache/doris/analysis/SysVariableDesc.java index f8906c393e8275..5675f52d5b9972 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/analysis/SysVariableDesc.java +++ b/fe/fe-core/src/main/java/org/apache/doris/analysis/SysVariableDesc.java @@ -122,8 +122,12 @@ public Expr getResultValue() throws AnalysisException { // Such as `set sql_mode = concat(@@sql_mode, "STRICT_TRANS_TABLES");` // So we return the string type here so that it can correctly match the subsequent function signature. // We will convert the string to int in VariableMgr. + // And we also set `isSqlMode` to true in StringLiteral, so that it can be cast back + // to Integer when returning value. try { - return new StringLiteral(SqlModeHelper.decode(intValue)); + StringLiteral s = new StringLiteral(SqlModeHelper.decode(intValue)); + s.setIsSqlMode(true); + return s; } catch (DdlException e) { throw new AnalysisException(e.getMessage()); } diff --git a/fe/fe-core/src/test/java/org/apache/doris/analysis/SetVariableTest.java b/fe/fe-core/src/test/java/org/apache/doris/analysis/SetVariableTest.java index 7cf115531338bb..465234850e53cf 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/analysis/SetVariableTest.java +++ b/fe/fe-core/src/test/java/org/apache/doris/analysis/SetVariableTest.java @@ -17,6 +17,7 @@ package org.apache.doris.analysis; +import org.apache.doris.catalog.Type; import org.apache.doris.qe.ConnectContext; import org.apache.doris.qe.SqlModeHelper; import org.apache.doris.qe.StmtExecutor; @@ -50,6 +51,14 @@ public void testSqlMode() throws Exception { stmtExecutor.execute(); Assert.assertEquals("STRICT_TRANS_TABLES", SqlModeHelper.decode(connectContext.getSessionVariable().getSqlMode())); + + String selectStr = "explain select @@sql_mode;"; + connectContext.getState().reset(); + stmtExecutor = new StmtExecutor(connectContext, selectStr); + stmtExecutor.execute(); + Expr expr = stmtExecutor.getParsedStmt().getResultExprs().get(0); + Assert.assertTrue(expr instanceof SlotRef); + Assert.assertTrue(expr.getType() == Type.BIGINT); } @Test diff --git a/fe/fe-core/src/test/java/org/apache/doris/utframe/UtFrameUtils.java b/fe/fe-core/src/test/java/org/apache/doris/utframe/UtFrameUtils.java index acee9405001941..8f5ed06326ea94 100644 --- a/fe/fe-core/src/test/java/org/apache/doris/utframe/UtFrameUtils.java +++ b/fe/fe-core/src/test/java/org/apache/doris/utframe/UtFrameUtils.java @@ -220,5 +220,16 @@ public static String getSQLPlanOrErrorMsg(ConnectContext ctx, String queryStr) t return ctx.getState().getErrorMessage(); } } + + public static Planner getSQLPlanner(ConnectContext ctx, String queryStr) throws Exception { + ctx.getState().reset(); + StmtExecutor stmtExecutor = new StmtExecutor(ctx, queryStr); + stmtExecutor.execute(); + if (ctx.getState().getStateType() != QueryState.MysqlStateType.ERR) { + return stmtExecutor.planner(); + } else { + return null; + } + } }