[improvement](session variable) add max execution time session variabe like mysql and add setter attributes in variables (#19759)

1. add session variable max_execution_time to an alias of query timeout, if user set max_execution_time, the query timeout will be modified too.
2. add a setter attribute to session variable, so that we could add some logic in setter method instead of field reflection.
This commit is contained in:
yiguolei
2023-05-19 12:42:47 +08:00
committed by GitHub
parent cf7083d58b
commit 9c86cad4ec
3 changed files with 94 additions and 43 deletions

View File

@ -65,6 +65,7 @@ public class SessionVariable implements Serializable, Writable {
public static final String EXEC_MEM_LIMIT = "exec_mem_limit";
public static final String SCAN_QUEUE_MEM_LIMIT = "scan_queue_mem_limit";
public static final String QUERY_TIMEOUT = "query_timeout";
public static final String MAX_EXECUTION_TIME = "max_execution_time";
public static final String INSERT_TIMEOUT = "insert_timeout";
public static final String ENABLE_PROFILE = "enable_profile";
public static final String SQL_MODE = "sql_mode";
@ -367,6 +368,14 @@ public class SessionVariable implements Serializable, Writable {
@VariableMgr.VarAttr(name = QUERY_TIMEOUT)
public int queryTimeoutS = 300;
// The global max_execution_time value provides the default for the session value for new connections.
// The session value applies to SELECT executions executed within the session that include
// no MAX_EXECUTION_TIME(N) optimizer hint or for which N is 0.
// https://dev.mysql.com/doc/refman/5.7/en/server-system-variables.html
// So that it is == query timeout in doris
@VariableMgr.VarAttr(name = MAX_EXECUTION_TIME, fuzzy = true, setter = "setMaxExecutionTimeMS")
public int maxExecutionTimeMS = -1;
@VariableMgr.VarAttr(name = INSERT_TIMEOUT)
public int insertTimeoutS = 14400;
@ -1051,6 +1060,10 @@ public class SessionVariable implements Serializable, Writable {
return queryTimeoutS;
}
public int getMaxExecutionTimeMS() {
return maxExecutionTimeMS;
}
public int getInsertTimeoutS() {
return insertTimeoutS;
}
@ -1210,6 +1223,16 @@ public class SessionVariable implements Serializable, Writable {
this.queryTimeoutS = queryTimeoutS;
}
public void setMaxExecutionTimeMS(int maxExecutionTimeMS) {
this.maxExecutionTimeMS = maxExecutionTimeMS;
this.queryTimeoutS = this.maxExecutionTimeMS / 1000;
}
public void setMaxExecutionTimeMS(String maxExecutionTimeMS) {
this.maxExecutionTimeMS = Integer.valueOf(maxExecutionTimeMS);
this.queryTimeoutS = this.maxExecutionTimeMS / 1000;
}
public String getResourceGroup() {
return resourceGroup;
}

View File

@ -159,50 +159,60 @@ public class VariableMgr {
ErrorReport.reportDdlException(ErrorCode.ERR_INVALID_VALUE, attr.name(), value, e.getMessage());
}
}
try {
switch (field.getType().getSimpleName()) {
case "boolean":
if (value.equalsIgnoreCase("ON")
|| value.equalsIgnoreCase("TRUE")
|| value.equalsIgnoreCase("1")) {
field.setBoolean(obj, true);
} else if (value.equalsIgnoreCase("OFF")
|| value.equalsIgnoreCase("FALSE")
|| value.equalsIgnoreCase("0")) {
field.setBoolean(obj, false);
} else {
throw new IllegalAccessException();
}
break;
case "byte":
field.setByte(obj, Byte.valueOf(value));
break;
case "short":
field.setShort(obj, Short.valueOf(value));
break;
case "int":
field.setInt(obj, Integer.valueOf(value));
break;
case "long":
field.setLong(obj, Long.valueOf(value));
break;
case "float":
field.setFloat(obj, Float.valueOf(value));
break;
case "double":
field.setDouble(obj, Double.valueOf(value));
break;
case "String":
field.set(obj, value);
break;
default:
// Unsupported type variable.
ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_TYPE_FOR_VAR, attr.name());
// If the session variable has specified the setter, then not use reflect
if (!attr.setter().equals("")) {
Preconditions.checkArgument(obj instanceof SessionVariable);
try {
SessionVariable.class.getDeclaredMethod(attr.setter(), String.class).invoke(obj, value);
} catch (Exception e) {
ErrorReport.reportDdlException(ErrorCode.ERR_INVALID_VALUE, attr.name(), value, e.getMessage());
}
} else {
try {
switch (field.getType().getSimpleName()) {
case "boolean":
if (value.equalsIgnoreCase("ON")
|| value.equalsIgnoreCase("TRUE")
|| value.equalsIgnoreCase("1")) {
field.setBoolean(obj, true);
} else if (value.equalsIgnoreCase("OFF")
|| value.equalsIgnoreCase("FALSE")
|| value.equalsIgnoreCase("0")) {
field.setBoolean(obj, false);
} else {
throw new IllegalAccessException();
}
break;
case "byte":
field.setByte(obj, Byte.valueOf(value));
break;
case "short":
field.setShort(obj, Short.valueOf(value));
break;
case "int":
field.setInt(obj, Integer.valueOf(value));
break;
case "long":
field.setLong(obj, Long.valueOf(value));
break;
case "float":
field.setFloat(obj, Float.valueOf(value));
break;
case "double":
field.setDouble(obj, Double.valueOf(value));
break;
case "String":
field.set(obj, value);
break;
default:
// Unsupported type variable.
ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_TYPE_FOR_VAR, attr.name());
}
} catch (NumberFormatException e) {
ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_TYPE_FOR_VAR, attr.name());
} catch (IllegalAccessException e) {
ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_VALUE_FOR_VAR, attr.name(), value);
}
} catch (NumberFormatException e) {
ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_TYPE_FOR_VAR, attr.name());
} catch (IllegalAccessException e) {
ErrorReport.reportDdlException(ErrorCode.ERR_WRONG_VALUE_FOR_VAR, attr.name(), value);
}
if (VariableVarCallbacks.hasCallback(attr.name())) {
@ -652,6 +662,9 @@ public class VariableMgr {
// the checker function should be: public void checker(String value), value is the input string.
String checker() default "";
// could specify the setter method for a variable, not depend on reflect mechanism
String setter() default "";
// Set to true if the variables need to be forwarded along with forward statement.
boolean needForward() default false;