Skip to content

Commit

Permalink
1
Browse files Browse the repository at this point in the history
  • Loading branch information
liugddx committed Feb 15, 2024
1 parent 3f228da commit 4a6fdfa
Show file tree
Hide file tree
Showing 3 changed files with 93 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -531,7 +531,7 @@ public class SessionVariable implements Serializable, Writable {
public boolean enableStats = true;

// session origin value
public Map<Field, String> sessionOriginValue = new HashMap<Field, String>();
public Map<SessionVariableField, String> sessionOriginValue = new HashMap<>();
// check stmt is or not [select /*+ SET_VAR(...)*/ ...]
// if it is setStmt, we needn't collect session origin value
public boolean isSingleSetVar = false;
Expand Down Expand Up @@ -2464,11 +2464,11 @@ public void setIsSingleSetVar(boolean issinglesetvar) {
this.isSingleSetVar = issinglesetvar;
}

public Map<Field, String> getSessionOriginValue() {
public Map<SessionVariableField, String> getSessionOriginValue() {
return sessionOriginValue;
}

public void addSessionOriginValue(Field key, String value) {
public void addSessionOriginValue(SessionVariableField key, String value) {
if (sessionOriginValue.containsKey(key)) {
// If we already set the origin value, just skip the reset.
return;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.

package org.apache.doris.qe;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Field;

public class SessionVariableField implements Serializable {
private transient Field field;

public SessionVariableField(Field field) {
this.field = field;
}

public Field getField() {
return field;
}

private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeObject(field.getName());
out.writeObject(field.getType());
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
String fieldName = (String) in.readObject();
Class<?> fieldType = (Class<?>) in.readObject();
try {
field = getField(fieldName, fieldType);
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}

private Field getField(String fieldName, Class<?> fieldType) throws NoSuchFieldException {
try {
return SessionVariableField.class.getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
Class<?> superclass = SessionVariableField.class.getSuperclass();
if (superclass != null) {
return getField(fieldName, fieldType);
}
throw e;
}
}

}
41 changes: 24 additions & 17 deletions fe/fe-core/src/main/java/org/apache/doris/qe/VariableMgr.java
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,11 @@ public static SessionVariable getDefaultSessionVariable() {
}

// Set value to a variable
private static boolean setValue(Object obj, Field field, String value) throws DdlException {
private static boolean setValue(Object obj, SessionVariableField sessionVariableField, String value)
throws DdlException {

Field field = sessionVariableField.getField();
field.setAccessible(true);
VarAttr attr = field.getAnnotation(VarAttr.class);

if (VariableVarConverters.hasConverter(attr.name())) {
Expand Down Expand Up @@ -196,22 +200,22 @@ private static boolean setValue(Object obj, Field field, String value) throws Dd
}
break;
case "byte":
field.setByte(obj, Byte.valueOf(value));
field.setByte(obj, Byte.parseByte(value));
break;
case "short":
field.setShort(obj, Short.valueOf(value));
field.setShort(obj, Short.parseShort(value));
break;
case "int":
field.setInt(obj, Integer.valueOf(value));
field.setInt(obj, Integer.parseInt(value));
break;
case "long":
field.setLong(obj, Long.valueOf(value));
field.setLong(obj, Long.parseLong(value));
break;
case "float":
field.setFloat(obj, Float.valueOf(value));
field.setFloat(obj, Float.parseFloat(value));
break;
case "double":
field.setDouble(obj, Double.valueOf(value));
field.setDouble(obj, Double.parseDouble(value));
break;
case "String":
field.set(obj, value);
Expand All @@ -236,9 +240,9 @@ private static boolean setValue(Object obj, Field field, String value) throws Dd

// revert the operator[set_var] on select/*+ SET_VAR()*/ sql;
public static void revertSessionValue(SessionVariable obj) throws DdlException {
Map<Field, String> sessionOriginValue = obj.getSessionOriginValue();
Map<SessionVariableField, String> sessionOriginValue = obj.getSessionOriginValue();
if (!sessionOriginValue.isEmpty()) {
for (Field field : sessionOriginValue.keySet()) {
for (SessionVariableField field : sessionOriginValue.keySet()) {
// revert session value
setValue(obj, field, sessionOriginValue.get(field));
}
Expand Down Expand Up @@ -351,22 +355,24 @@ private static void setVarInternal(SessionVariable sessionVariable, SetVar setVa

// No matter this is a global setting or not, always set session variable.
Field field = ctx.getField();
SessionVariableField sessionVariableField = new SessionVariableField(field);
// if stmt is "Select /*+ SET_VAR(...)*/"
if (sessionVariable.getIsSingleSetVar()) {
try {
sessionVariable.addSessionOriginValue(field, field.get(sessionVariable).toString());
sessionVariable.addSessionOriginValue(sessionVariableField, field.get(sessionVariable).toString());
} catch (Exception e) {
LOG.warn("failed to collect origin session value ", e);
}
}
setValue(sessionVariable, field, value);
setValue(sessionVariable, sessionVariableField, value);
}

private static void setGlobalVarAndWriteEditLog(VarContext ctx, String name, String value) throws DdlException {
// global variable will make effect when is set immediately.
wlock.lock();
try {
setValue(ctx.getObj(), ctx.getField(), value);

setValue(ctx.getObj(), new SessionVariableField(ctx.getField()), value);
// write edit log
GlobalVarPersistInfo info = new GlobalVarPersistInfo(defaultSessionVariable, Lists.newArrayList(name));
Env.getCurrentEnv().getEditLog().logGlobalVariableV2(info);
Expand All @@ -380,7 +386,7 @@ public static void setGlobalPipelineTask(int instance) {
try {
VarContext ctx = ctxByVarName.get(SessionVariable.PARALLEL_PIPELINE_TASK_NUM);
try {
setValue(ctx.getObj(), ctx.getField(), String.valueOf(instance));
setValue(ctx.getObj(), new SessionVariableField(ctx.getField()), String.valueOf(instance));
} catch (DdlException e) {
LOG.warn("failed to set global variable: {}", SessionVariable.PARALLEL_PIPELINE_TASK_NUM, e);
return;
Expand All @@ -400,7 +406,7 @@ public static void setGlobalBroadcastScaleFactor(double factor) {
try {
VarContext ctx = ctxByVarName.get(SessionVariable.BROADCAST_RIGHT_TABLE_SCALE_FACTOR);
try {
setValue(ctx.getObj(), ctx.getField(), String.valueOf(factor));
setValue(ctx.getObj(), new SessionVariableField(ctx.getField()), String.valueOf(factor));
} catch (DdlException e) {
LOG.warn("failed to set global variable: {}", SessionVariable.BROADCAST_RIGHT_TABLE_SCALE_FACTOR, e);
return;
Expand All @@ -420,7 +426,7 @@ public static void enableNereidsPlanner() {
try {
VarContext ctx = ctxByVarName.get(SessionVariable.ENABLE_NEREIDS_PLANNER);
try {
setValue(ctx.getObj(), ctx.getField(), String.valueOf(true));
setValue(ctx.getObj(), new SessionVariableField(ctx.getField()), String.valueOf(true));
} catch (DdlException e) {
LOG.warn("failed to set global variable: {}", SessionVariable.ENABLE_NEREIDS_PLANNER, e);
return;
Expand All @@ -440,7 +446,7 @@ public static void enableNereidsDml() {
try {
VarContext ctx = ctxByVarName.get(SessionVariable.ENABLE_NEREIDS_DML);
try {
setValue(ctx.getObj(), ctx.getField(), String.valueOf(true));
setValue(ctx.getObj(), new SessionVariableField(ctx.getField()), String.valueOf(true));
} catch (DdlException e) {
LOG.warn("failed to set global variable: {}", SessionVariable.ENABLE_NEREIDS_DML, e);
return;
Expand Down Expand Up @@ -511,7 +517,8 @@ public static void replayGlobalVariableV2(GlobalVarPersistInfo info) throws DdlE
continue;
}
try {
setValue(varContext.getObj(), varContext.getField(), root.get((String) varName).toString());
setValue(varContext.getObj(), new SessionVariableField(varContext.getField()),
root.get(varName).toString());
} catch (Exception exception) {
LOG.warn("Exception during replay global variabl {} oplog, {}, THIS EXCEPTION WILL BE IGNORED.",
(String) varName, exception.getMessage());
Expand Down

0 comments on commit 4a6fdfa

Please sign in to comment.