morrySnow commented on code in PR #41913: URL: https://github.com/apache/doris/pull/41913#discussion_r1816092697
########## fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java: ########## @@ -3829,4 +3855,113 @@ public LogicalPlan visitShowConfig(ShowConfigContext ctx) { } return command; } + + @Override + public SetOptionsCommand visitSetOptions(SetOptionsContext ctx) { + List<SetVarOp> setVarOpList = new ArrayList<>(1); + for (Object child : ctx.children) { + if (child instanceof RuleNode) { + setVarOpList.add(typedVisit((RuleNode) child)); + } + } + return new SetOptionsCommand(setVarOpList); + } + + @Override + public SetVarOp visitSetSystemVariable(SetSystemVariableContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; Review Comment: use NullLiteral to present default? i don't think this is a good idea, because we may need to assign NullLiteral to some variable in future ########## fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java: ########## @@ -3829,4 +3855,113 @@ public LogicalPlan visitShowConfig(ShowConfigContext ctx) { } return command; } + + @Override + public SetOptionsCommand visitSetOptions(SetOptionsContext ctx) { + List<SetVarOp> setVarOpList = new ArrayList<>(1); + for (Object child : ctx.children) { + if (child instanceof RuleNode) { + setVarOpList.add(typedVisit((RuleNode) child)); + } + } + return new SetOptionsCommand(setVarOpList); + } + + @Override + public SetVarOp visitSetSystemVariable(SetSystemVariableContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; + return new SetSessionVarOp(type, name, expression); + } + + @Override + public SetVarOp visitSetVariableWithType(SetVariableWithTypeContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; Review Comment: ditto ########## fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java: ########## @@ -3829,4 +3855,113 @@ public LogicalPlan visitShowConfig(ShowConfigContext ctx) { } return command; } + + @Override + public SetOptionsCommand visitSetOptions(SetOptionsContext ctx) { + List<SetVarOp> setVarOpList = new ArrayList<>(1); + for (Object child : ctx.children) { + if (child instanceof RuleNode) { + setVarOpList.add(typedVisit((RuleNode) child)); + } + } + return new SetOptionsCommand(setVarOpList); + } + + @Override + public SetVarOp visitSetSystemVariable(SetSystemVariableContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; + return new SetSessionVarOp(type, name, expression); + } + + @Override + public SetVarOp visitSetVariableWithType(SetVariableWithTypeContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; + return new SetSessionVarOp(type, name, expression); + } + + @Override + public SetVarOp visitSetPassword(SetPasswordContext ctx) { + String user; + String host; + boolean isDomain; + String passwordText; + boolean isPlain; + UserIdentity userIdentity = null; + if (ctx.userIdentify() != null) { + user = stripQuotes(ctx.userIdentify().user.getText()); + host = ctx.userIdentify().host != null ? stripQuotes(ctx.userIdentify().host.getText()) : "%"; + isDomain = ctx.userIdentify().LEFT_PAREN() != null; + userIdentity = new UserIdentity(user, host, isDomain); + } + passwordText = stripQuotes(ctx.STRING_LITERAL().getText()); + isPlain = ctx.LEFT_PAREN() != null; + return new SetPassVarOp(userIdentity, new PassVar(passwordText, isPlain)); + } + + @Override + public SetVarOp visitSetNames(SetNamesContext ctx) { + return new SetNamesVarOp(); + } + + @Override + public SetVarOp visitSetCharset(SetCharsetContext ctx) { + String charset = ctx.charsetName != null ? stripQuotes(ctx.charsetName.getText()) : null; + return new SetCharsetAndCollateVarOp(charset); + } + + @Override + public SetVarOp visitSetCollate(SetCollateContext ctx) { + String charset = ctx.charsetName != null ? stripQuotes(ctx.charsetName.getText()) : null; + String collate = ctx.collateName != null ? stripQuotes(ctx.collateName.getText()) : null; + return new SetCharsetAndCollateVarOp(charset, collate); + } + + @Override + public SetVarOp visitSetLdapAdminPassword(SetLdapAdminPasswordContext ctx) { + String passwordText = stripQuotes(ctx.STRING_LITERAL().getText()); + boolean isPlain = ctx.LEFT_PAREN() != null; Review Comment: ```suggestion boolean isPlain = ctx.PASSWORD() != null; ``` ########## fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java: ########## @@ -3829,4 +3855,113 @@ public LogicalPlan visitShowConfig(ShowConfigContext ctx) { } return command; } + + @Override + public SetOptionsCommand visitSetOptions(SetOptionsContext ctx) { + List<SetVarOp> setVarOpList = new ArrayList<>(1); + for (Object child : ctx.children) { + if (child instanceof RuleNode) { + setVarOpList.add(typedVisit((RuleNode) child)); + } + } + return new SetOptionsCommand(setVarOpList); + } + + @Override + public SetVarOp visitSetSystemVariable(SetSystemVariableContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; + return new SetSessionVarOp(type, name, expression); + } + + @Override + public SetVarOp visitSetVariableWithType(SetVariableWithTypeContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; + return new SetSessionVarOp(type, name, expression); + } + + @Override + public SetVarOp visitSetPassword(SetPasswordContext ctx) { + String user; + String host; + boolean isDomain; + String passwordText; + boolean isPlain; + UserIdentity userIdentity = null; + if (ctx.userIdentify() != null) { + user = stripQuotes(ctx.userIdentify().user.getText()); + host = ctx.userIdentify().host != null ? stripQuotes(ctx.userIdentify().host.getText()) : "%"; + isDomain = ctx.userIdentify().LEFT_PAREN() != null; Review Comment: should use `ATSIGN` ? ########## fe/fe-core/src/main/java/org/apache/doris/nereids/parser/LogicalPlanBuilder.java: ########## @@ -3829,4 +3855,113 @@ public LogicalPlan visitShowConfig(ShowConfigContext ctx) { } return command; } + + @Override + public SetOptionsCommand visitSetOptions(SetOptionsContext ctx) { + List<SetVarOp> setVarOpList = new ArrayList<>(1); + for (Object child : ctx.children) { + if (child instanceof RuleNode) { + setVarOpList.add(typedVisit((RuleNode) child)); + } + } + return new SetOptionsCommand(setVarOpList); + } + + @Override + public SetVarOp visitSetSystemVariable(SetSystemVariableContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; + return new SetSessionVarOp(type, name, expression); + } + + @Override + public SetVarOp visitSetVariableWithType(SetVariableWithTypeContext ctx) { + SetType type = SetType.DEFAULT; + if (ctx.GLOBAL() != null) { + type = SetType.GLOBAL; + } else if (ctx.LOCAL() != null || ctx.SESSION() != null) { + type = SetType.SESSION; + } + String name = stripQuotes(ctx.identifier().getText()); + Expression expression = ctx.expression() != null ? typedVisit(ctx.expression()) : NullLiteral.INSTANCE; + return new SetSessionVarOp(type, name, expression); + } + + @Override + public SetVarOp visitSetPassword(SetPasswordContext ctx) { + String user; + String host; + boolean isDomain; + String passwordText; + boolean isPlain; + UserIdentity userIdentity = null; + if (ctx.userIdentify() != null) { + user = stripQuotes(ctx.userIdentify().user.getText()); + host = ctx.userIdentify().host != null ? stripQuotes(ctx.userIdentify().host.getText()) : "%"; + isDomain = ctx.userIdentify().LEFT_PAREN() != null; + userIdentity = new UserIdentity(user, host, isDomain); + } + passwordText = stripQuotes(ctx.STRING_LITERAL().getText()); + isPlain = ctx.LEFT_PAREN() != null; Review Comment: we assign a name on second PASSWORD in antlr file, and use it to judgement `isPlain` ########## fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/Command.java: ########## @@ -116,4 +116,14 @@ public String treeString() { public Plan withGroupExpression(Optional<GroupExpression> groupExpression) { throw new RuntimeException("Command do not implement withGroupExpression"); } + + public String toSql() { + return ""; + } + + public boolean needAuditEncryption() { + return false; + } + + public void afterForwardToMaster(ConnectContext ctx) throws Exception {} Review Comment: maybe this interface should in `Forward` trait ########## fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/Command.java: ########## @@ -116,4 +116,14 @@ public String treeString() { public Plan withGroupExpression(Optional<GroupExpression> groupExpression) { throw new RuntimeException("Command do not implement withGroupExpression"); } + + public String toSql() { + return ""; + } + + public boolean needAuditEncryption() { + return false; + } Review Comment: command should not have these interface ########## fe/fe-core/src/main/java/org/apache/doris/nereids/trees/plans/commands/info/SetPassVarOp.java: ########## @@ -0,0 +1,103 @@ +// 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.nereids.trees.plans.commands.info; + +import org.apache.doris.analysis.PassVar; +import org.apache.doris.analysis.SetType; +import org.apache.doris.analysis.UserIdentity; +import org.apache.doris.catalog.Env; +import org.apache.doris.cluster.ClusterNamespace; +import org.apache.doris.common.AnalysisException; +import org.apache.doris.common.ErrorCode; +import org.apache.doris.common.ErrorReport; +import org.apache.doris.common.UserException; +import org.apache.doris.mysql.privilege.Auth; +import org.apache.doris.mysql.privilege.PrivPredicate; +import org.apache.doris.qe.ConnectContext; + +/** + * SetPassVarOp + */ +public class SetPassVarOp extends SetVarOp { + private UserIdentity userIdent; + private PassVar passVar; + + // The password in parameter is a hashed password. + public SetPassVarOp(UserIdentity userIdent, PassVar passVar) { + super(SetType.DEFAULT); + this.userIdent = userIdent; + this.passVar = passVar; + } + + @Override + public void validate(ConnectContext ctx) throws UserException { + boolean isSelf = false; + if (userIdent == null) { + // set userIdent as what current_user() returns + userIdent = ctx.getCurrentUserIdentity(); + isSelf = true; + } else { + userIdent.analyze(); + if (userIdent.equals(ctx.getCurrentUserIdentity())) { + isSelf = true; + } + } + + // Check password + if (passVar != null) { + passVar.analyze(); + } + + // check privs. + // 1. this is user itself + if (isSelf) { + return; + } + + // 2. No user can set password for root expect for root user itself + if (userIdent.getQualifiedUser().equals(Auth.ROOT_USER) + && !ClusterNamespace.getNameFromFullName(ctx.getQualifiedUser()).equals(Auth.ROOT_USER)) { + throw new AnalysisException("Can not set password for root user, except root itself"); Review Comment: use isSelf to check it better? -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscr...@doris.apache.org For additional commands, e-mail: commits-h...@doris.apache.org