[Bug] Fix bug of select @@sql_mode (#4484)

Fix bug that `select @@sql_mode` throw error: Invalid number format.
This commit is contained in:
Mingyu Chen
2020-09-01 11:31:35 +08:00
committed by GitHub
parent a864db03fe
commit d49566130b
4 changed files with 61 additions and 3 deletions

View File

@ -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:

View File

@ -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());
}

View File

@ -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

View File

@ -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;
}
}
}