Skip to content
243 changes: 123 additions & 120 deletions fe/src/com/baidu/palo/analysis/AlterUserStmt.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,123 +18,126 @@
// specific language governing permissions and limitations
// under the License.

package com.baidu.palo.analysis;

import java.util.List;

import org.apache.commons.lang.NotImplementedException;

import com.baidu.palo.catalog.AccessPrivilege;
import com.baidu.palo.cluster.ClusterNamespace;
import com.baidu.palo.common.AnalysisException;
import com.baidu.palo.common.DdlException;
import com.baidu.palo.common.ErrorCode;
import com.baidu.palo.common.ErrorReport;
import com.baidu.palo.common.InternalException;
import com.google.common.base.Strings;

public class AlterUserStmt extends DdlStmt {
private String userName;
private AlterUserClause clause;

public AlterUserStmt(String userName, AlterClause clause) {
this.userName = userName;
this.clause = (AlterUserClause) clause;
}

private boolean hasRightToModify(Analyzer analyzer) {
String user = analyzer.getUser();
String toUser = userName;

// own can modify own
if (user.equals(toUser)) {
return true;
}

// admin can modify all
if (analyzer.getCatalog().getUserMgr().isAdmin(user)) {
return true;
}

// superuse can modify Ordinary user
if (analyzer.getCatalog().getUserMgr().isSuperuser(user)
&& !analyzer.getCatalog().getUserMgr().isSuperuser(toUser)) {
return true;
}
return false;
}

private void checkWhiteListSize(Analyzer analyzer) throws AnalysisException {
if (clause.getAlterUserType() == AlterUserType.ADD_USER_WHITELIST) {
try {
if (analyzer.getCatalog().getUserMgr().getWhiteListSize(userName) > 20) {
throw new AnalysisException("whitelist size excced the max (20)");
}
} catch (DdlException e) {
throw new AnalysisException(e.getMessage());
}
}
}

@Override
public void analyze(Analyzer analyzer) throws AnalysisException, InternalException {
super.analyze(analyzer);
// check toUser
if (Strings.isNullOrEmpty(userName)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "empty user");
}
userName = ClusterNamespace.getFullName(getClusterName(), userName);
// check destination user if exists
try {
analyzer.getCatalog().getUserMgr().checkUserIfExist(userName);
} catch (DdlException e) {
throw new AnalysisException(e.getMessage());
}

// check destination user's whitelist if ecceed max value
checkWhiteListSize(analyzer);

// only write user can modify
analyzer.checkPrivilege(analyzer.getDefaultDb(), AccessPrivilege.READ_WRITE);

// check if has the right
if (!hasRightToModify(analyzer)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "ALTER CLUSTER");
}

// alter clause analysis
clause.analyze(analyzer);
}

public String getUser() {
return userName;
}

public List<String> getHosts() {
return clause.getHosts();
}

public List<String> getIps() {
return clause.getIps();
}

public List<String> getStarIps() {
return clause.getStarIps();
}

public AlterUserType getAlterUserType() {
return clause.getAlterUserType();
}

@Override
public String toSql() {
throw new NotImplementedException();
}

@Override
public String toString() {
throw new NotImplementedException();
}


}
package com.baidu.palo.analysis;

import java.util.List;

import org.apache.commons.lang.NotImplementedException;

import com.baidu.palo.catalog.AccessPrivilege;
import com.baidu.palo.cluster.ClusterNamespace;
import com.baidu.palo.common.AnalysisException;
import com.baidu.palo.common.Config;
import com.baidu.palo.common.DdlException;
import com.baidu.palo.common.ErrorCode;
import com.baidu.palo.common.ErrorReport;
import com.baidu.palo.common.InternalException;
import com.google.common.base.Strings;

public class AlterUserStmt extends DdlStmt {
private String userName;
private AlterUserClause clause;

public AlterUserStmt(String userName, AlterClause clause) {
this.userName = userName;
this.clause = (AlterUserClause) clause;
}

private boolean hasRightToModify(Analyzer analyzer) {
String user = analyzer.getUser();
String toUser = userName;

// own can modify own
if (user.equals(toUser)) {
return true;
}

// admin can modify all
if (analyzer.getCatalog().getUserMgr().isAdmin(user)) {
return true;
}

// superuse can modify Ordinary user
if (analyzer.getCatalog().getUserMgr().isSuperuser(user)
&& !analyzer.getCatalog().getUserMgr().isSuperuser(toUser)) {
return true;
}
return false;
}

private void checkWhiteListSize(Analyzer analyzer) throws AnalysisException {
if (clause.getAlterUserType() == AlterUserType.ADD_USER_WHITELIST) {
try {
if (analyzer.getCatalog().getUserMgr().getWhiteListSize(userName)
> Config.per_user_white_list_limit) {
throw new AnalysisException("whitelist size excced the max ("
+ Config.per_user_white_list_limit + ")");
}
} catch (DdlException e) {
throw new AnalysisException(e.getMessage());
}
}
}

@Override
public void analyze(Analyzer analyzer) throws AnalysisException, InternalException {
super.analyze(analyzer);
// check toUser
if (Strings.isNullOrEmpty(userName)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "empty user");
}
userName = ClusterNamespace.getFullName(getClusterName(), userName);
// check destination user if exists
try {
analyzer.getCatalog().getUserMgr().checkUserIfExist(userName);
} catch (DdlException e) {
throw new AnalysisException(e.getMessage());
}

// check destination user's whitelist if ecceed max value
checkWhiteListSize(analyzer);

// only write user can modify
analyzer.checkPrivilege(analyzer.getDefaultDb(), AccessPrivilege.READ_WRITE);

// check if has the right
if (!hasRightToModify(analyzer)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "ALTER CLUSTER");
}

// alter clause analysis
clause.analyze(analyzer);
}

public String getUser() {
return userName;
}

public List<String> getHosts() {
return clause.getHosts();
}

public List<String> getIps() {
return clause.getIps();
}

public List<String> getStarIps() {
return clause.getStarIps();
}

public AlterUserType getAlterUserType() {
return clause.getAlterUserType();
}

@Override
public String toSql() {
throw new NotImplementedException();
}

@Override
public String toString() {
throw new NotImplementedException();
}


}
2 changes: 2 additions & 0 deletions fe/src/com/baidu/palo/analysis/DateLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -55,11 +55,13 @@ public DateLiteral(Type type, boolean isMax) throws AnalysisException {
} else {
date = isMax ? TimeUtils.MAX_DATETIME : TimeUtils.MIN_DATETIME;
}
analysisDone();
}

public DateLiteral(String s, Type type) throws AnalysisException {
super();
init(s, type);
analysisDone();
}

protected DateLiteral(DateLiteral other) {
Expand Down
2 changes: 2 additions & 0 deletions fe/src/com/baidu/palo/analysis/DecimalLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public DecimalLiteral() {

public DecimalLiteral(BigDecimal value) {
init(value);
analysisDone();
}

public DecimalLiteral(String value) throws AnalysisException {
Expand All @@ -60,6 +61,7 @@ public DecimalLiteral(String value) throws AnalysisException {
throw new AnalysisException("Invalid floating-point literal: " + value, e);
}
init(v);
analysisDone();
}

protected DecimalLiteral(DecimalLiteral other) {
Expand Down
1 change: 1 addition & 0 deletions fe/src/com/baidu/palo/analysis/FloatLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ public FloatLiteral(Double value) {
public FloatLiteral(Double value, Type type) {
this.value = value.doubleValue();
this.type = type;
analysisDone();
}

public FloatLiteral(String value) throws AnalysisException {
Expand Down
3 changes: 3 additions & 0 deletions fe/src/com/baidu/palo/analysis/IntLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ private IntLiteral() {
public IntLiteral(long value) {
super();
init(value);
analysisDone();
}

public IntLiteral(long longValue, Type type) throws AnalysisException {
Expand Down Expand Up @@ -102,6 +103,7 @@ public IntLiteral(long longValue, Type type) throws AnalysisException {

this.value = longValue;
this.type = type;
analysisDone();
}

public IntLiteral(String value, Type type) throws AnalysisException {
Expand Down Expand Up @@ -147,6 +149,7 @@ public IntLiteral(String value, Type type) throws AnalysisException {

this.value = longValue;
this.type = type;
analysisDone();
}

protected IntLiteral(IntLiteral other) {
Expand Down
1 change: 0 additions & 1 deletion fe/src/com/baidu/palo/analysis/LiteralExpr.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ public abstract class LiteralExpr extends Expr {

public LiteralExpr() {
numDistinctValues = 1;
isAnalyzed = true;
}

protected LiteralExpr(LiteralExpr other) {
Expand Down
1 change: 1 addition & 0 deletions fe/src/com/baidu/palo/analysis/StringLiteral.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public StringLiteral(String value) {
super();
this.value = value;
type = Type.VARCHAR;
analysisDone();
}

protected StringLiteral(StringLiteral other) {
Expand Down
3 changes: 3 additions & 0 deletions fe/src/com/baidu/palo/common/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -461,4 +461,7 @@ public class Config extends ConfigBase {
// for forward compatibility, will be removed later.
// check token when download image file.
@ConfField public static boolean enable_token_check = true;

// white list limit
@ConfField public static int per_user_white_list_limit = 1024;
}
28 changes: 27 additions & 1 deletion fe/src/com/baidu/palo/qe/Coordinator.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@
import com.baidu.palo.common.util.RuntimeProfile;
import com.baidu.palo.planner.DataPartition;
import com.baidu.palo.planner.DataSink;
import com.baidu.palo.planner.ExchangeNode;
import com.baidu.palo.planner.PlanFragment;
import com.baidu.palo.planner.PlanFragmentId;
import com.baidu.palo.planner.PlanNode;
import com.baidu.palo.planner.PlanNodeId;
import com.baidu.palo.planner.Planner;
import com.baidu.palo.planner.ResultSink;
import com.baidu.palo.planner.ScanNode;
import com.baidu.palo.planner.UnionNode;
import com.baidu.palo.service.FrontendOptions;
import com.baidu.palo.system.Backend;
import com.baidu.palo.task.LoadEtlTask;
Expand Down Expand Up @@ -712,6 +714,25 @@ private TNetworkAddress toRpcHost(TNetworkAddress host) throws Exception {
return dest;
}

// estimate if this fragment contains UnionNode
private boolean containsUnionNode(PlanNode node) {
if (node instanceof UnionNode) {
return true;
}

for (PlanNode child : node.getChildren()) {
if (child instanceof ExchangeNode) {
// Ignore other fragment's node
continue;
} else if (child instanceof UnionNode) {
return true;
} else {
return containsUnionNode(child);
}
}
return false;
}

// For each fragment in fragments, computes hosts on which to run the instances
// and stores result in fragmentExecParams.hosts.
private void computeFragmentHosts() throws Exception {
Expand All @@ -736,7 +757,12 @@ private void computeFragmentHosts() throws Exception {
}

PlanNode leftMostNode = findLeftmostNode(fragment.getPlanRoot());
if (!(leftMostNode instanceof ScanNode)) {
// When fragment contains UnionNode, because the fragment may has child
// and not all BE will receive the fragment, child fragment's dest must
// be BE that fragment's scannode locates, avoid less data.
// chenhao added
boolean hasUnionNode = containsUnionNode(fragment.getPlanRoot());
if (!(leftMostNode instanceof ScanNode) && !hasUnionNode) {
// there is no leftmost scan; we assign the same hosts as those of our
// leftmost input fragment (so that a partitioned aggregation
// fragment runs on the hosts that provide the input data)
Expand Down