[Bug] Fix bug of select @@sql_mode (#4484)
Fix bug that `select @@sql_mode` throw error: Invalid number format.
This commit is contained in:
@ -20,18 +20,20 @@ package org.apache.doris.analysis;
|
||||
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 @@ import java.util.Objects;
|
||||
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')'`
|
||||
* <p>
|
||||
* 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 @@ public class StringLiteral extends LiteralExpr {
|
||||
value = other.value;
|
||||
}
|
||||
|
||||
public void setIsSqlMode(boolean val) {
|
||||
this.isSqlMode = val;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Expr clone() {
|
||||
return new StringLiteral(this);
|
||||
@ -178,8 +196,24 @@ public class StringLiteral extends LiteralExpr {
|
||||
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:
|
||||
|
||||
@ -122,8 +122,12 @@ public class SysVariableDesc extends Expr {
|
||||
// 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());
|
||||
}
|
||||
|
||||
@ -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 class SetVariableTest {
|
||||
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
|
||||
|
||||
@ -220,5 +220,16 @@ public class UtFrameUtils {
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user