Repository: tajo Updated Branches: refs/heads/master bebc78011 -> 4bcd46427
TAJO-1238: Add SET SESSION and RESET statement. Closes #294 Project: http://git-wip-us.apache.org/repos/asf/tajo/repo Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/4bcd4642 Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/4bcd4642 Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/4bcd4642 Branch: refs/heads/master Commit: 4bcd46427131c09bed9898a552efe416bbdbf442 Parents: bebc780 Author: Hyunsik Choi <[email protected]> Authored: Wed Dec 10 18:01:55 2014 +0900 Committer: Hyunsik Choi <[email protected]> Committed: Wed Dec 10 18:01:55 2014 +0900 ---------------------------------------------------------------------- CHANGES | 2 + .../java/org/apache/tajo/algebra/OpType.java | 3 + .../org/apache/tajo/algebra/SetSession.java | 68 ++++++++++++++++ .../org/apache/tajo/catalog/CatalogUtil.java | 1 + .../org/apache/tajo/client/QueryClient.java | 4 +- .../org/apache/tajo/client/QueryClientImpl.java | 10 ++- .../apache/tajo/client/SessionConnection.java | 75 +++++++++++++----- tajo-client/src/main/proto/ClientProtos.proto | 15 ++-- .../main/proto/TajoMasterClientProtocol.proto | 2 +- .../java/org/apache/tajo/util/KeyValueSet.java | 5 ++ .../java/org/apache/tajo/util/ProtoUtil.java | 13 ++++ .../org/apache/tajo/engine/parser/SQLLexer.g4 | 7 +- .../org/apache/tajo/engine/parser/SQLParser.g4 | 15 +++- .../apache/tajo/engine/parser/SQLAnalyzer.java | 39 ++++++++++ .../org/apache/tajo/master/GlobalEngine.java | 37 ++++++++- .../tajo/master/TajoMasterClientService.java | 31 ++++++-- .../tajo/engine/parser/TestSQLAnalyzer.java | 60 +++++++++++++++ .../tajo/engine/query/TestSetSessionQuery.java | 81 ++++++++++++++++++++ .../queries/TestSQLAnalyzer/setcatalog1.sql | 1 + .../queries/TestSQLAnalyzer/setcatalog2.sql | 1 + .../queries/TestSQLAnalyzer/setsession1.sql | 1 + .../queries/TestSQLAnalyzer/setsession2.sql | 1 + .../queries/TestSQLAnalyzer/setsession3.sql | 1 + .../queries/TestSQLAnalyzer/setsession4.sql | 1 + .../queries/TestSQLAnalyzer/setsession5.sql | 1 + .../queries/TestSQLAnalyzer/setsession6.sql | 1 + .../queries/TestSQLAnalyzer/setsession7.sql | 1 + .../queries/TestSQLAnalyzer/settimezone1.sql | 1 + .../queries/TestSQLAnalyzer/settimezone2.sql | 1 + .../queries/TestSQLAnalyzer/settimezone3.sql | 1 + .../results/TestSQLAnalyzer/setcatalog1.result | 5 ++ .../results/TestSQLAnalyzer/setcatalog2.result | 5 ++ .../results/TestSQLAnalyzer/setsession1.result | 5 ++ .../results/TestSQLAnalyzer/setsession2.result | 5 ++ .../results/TestSQLAnalyzer/setsession3.result | 5 ++ .../results/TestSQLAnalyzer/setsession4.result | 5 ++ .../results/TestSQLAnalyzer/setsession5.result | 5 ++ .../results/TestSQLAnalyzer/setsession6.result | 5 ++ .../results/TestSQLAnalyzer/setsession7.result | 5 ++ .../results/TestSQLAnalyzer/settimezone1.result | 5 ++ .../results/TestSQLAnalyzer/settimezone2.result | 5 ++ .../results/TestSQLAnalyzer/settimezone3.result | 4 + .../tajo/plan/LogicalPlanPreprocessor.java | 7 ++ .../org/apache/tajo/plan/LogicalPlanner.java | 11 +++ .../tajo/plan/algebra/AlgebraVisitor.java | 3 + .../tajo/plan/algebra/BaseAlgebraVisitor.java | 8 ++ .../org/apache/tajo/plan/logical/NodeType.java | 2 + .../tajo/plan/logical/SetSessionNode.java | 68 ++++++++++++++++ .../org/apache/tajo/plan/util/PlannerUtil.java | 10 +++ .../plan/verifier/PreLogicalPlanVerifier.java | 20 +++++ .../plan/visitor/BasicLogicalPlanVisitor.java | 9 +++ .../tajo/plan/visitor/LogicalPlanVisitor.java | 4 + 52 files changed, 640 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 710f463..8add99f 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,8 @@ Release 0.9.1 - unreleased NEW FEATURES + TAJO-1238: Add SET SESSION and RESET statement. (hyunsik) + TAJO-1222: DelimitedTextFile should be tolerant against parsing errors. (hyunsik) http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java ---------------------------------------------------------------------- diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java index 19c4ab5..3e7d277 100644 --- a/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/OpType.java @@ -24,6 +24,9 @@ import java.lang.reflect.Type; public enum OpType { + // session statements + SetSession(SetSession.class), + // relational operators Projection(Projection.class), Limit(Limit.class), http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-algebra/src/main/java/org/apache/tajo/algebra/SetSession.java ---------------------------------------------------------------------- diff --git a/tajo-algebra/src/main/java/org/apache/tajo/algebra/SetSession.java b/tajo-algebra/src/main/java/org/apache/tajo/algebra/SetSession.java new file mode 100644 index 0000000..c2ea92c --- /dev/null +++ b/tajo-algebra/src/main/java/org/apache/tajo/algebra/SetSession.java @@ -0,0 +1,68 @@ +/** + * 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.tajo.algebra; + + +import com.google.common.base.Objects; +import com.google.common.base.Preconditions; +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +public class SetSession extends Expr { + @Expose @SerializedName("name") + private String name; + @Expose @SerializedName("value") + private String value; + + public SetSession(String name, String value) { + super(OpType.SetSession); + + this.name = name; + this.value = value; + } + + public boolean isDefault() { + return value == null; + } + + public String getName() { + return name; + } + + public String getValue() { + return value; + } + + public int hashCode() { + return Objects.hashCode(name, value); + } + + boolean equalsTo(Expr expr) { + SetSession another = (SetSession) expr; + return name.equals(another.name) && value.equals(another.value); + } + + @Override + public Object clone() throws CloneNotSupportedException { + SetSession setOperation = (SetSession) super.clone(); + setOperation.name = name; + setOperation.value = value; + return setOperation; + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java ---------------------------------------------------------------------- diff --git a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java index f2d9b9c..8e8314c 100644 --- a/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java +++ b/tajo-catalog/tajo-catalog-common/src/main/java/org/apache/tajo/catalog/CatalogUtil.java @@ -18,6 +18,7 @@ package org.apache.tajo.catalog; +import com.google.common.base.Preconditions; import com.google.common.collect.Maps; import org.apache.hadoop.fs.Path; import org.apache.tajo.DataTypeUtil; http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java ---------------------------------------------------------------------- diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java index 32ef97d..73a4d35 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/QueryClient.java @@ -63,9 +63,9 @@ public interface QueryClient extends Closeable { public Boolean selectDatabase(final String databaseName) throws ServiceException; - public Boolean updateSessionVariables(final Map<String, String> variables) throws ServiceException; + public Map<String, String> updateSessionVariables(final Map<String, String> variables) throws ServiceException; - public Boolean unsetSessionVariables(final List<String> variables) throws ServiceException; + public Map<String, String> unsetSessionVariables(final List<String> variables) throws ServiceException; public String getSessionVariable(final String varname) throws ServiceException; http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java ---------------------------------------------------------------------- diff --git a/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java b/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java index 1cee515..6809fda 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/QueryClientImpl.java @@ -140,12 +140,12 @@ public class QueryClientImpl implements QueryClient { } @Override - public Boolean updateSessionVariables(Map<String, String> variables) throws ServiceException { + public Map<String, String> updateSessionVariables(Map<String, String> variables) throws ServiceException { return connection.updateSessionVariables(variables); } @Override - public Boolean unsetSessionVariables(List<String> variables) throws ServiceException { + public Map<String, String> unsetSessionVariables(List<String> variables) throws ServiceException { return connection.unsetSessionVariables(variables); } @@ -214,7 +214,11 @@ public class QueryClientImpl implements QueryClient { ClientProtos.SubmitQueryResponse response = executeQuery(sql); if (response.getResultCode() == ClientProtos.ResultCode.ERROR) { - throw new ServiceException(response.getErrorTrace()); + if (response.hasErrorMessage()) { + throw new ServiceException(response.getErrorMessage()); + } else if (response.hasErrorTrace()) { + throw new ServiceException(response.getErrorTrace()); + } } QueryId queryId = new QueryId(response.getQueryId()); http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java ---------------------------------------------------------------------- diff --git a/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java b/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java index 922984f..dcec1a3 100644 --- a/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java +++ b/tajo-client/src/main/java/org/apache/tajo/client/SessionConnection.java @@ -28,6 +28,7 @@ import org.apache.tajo.TajoIdProtos; import org.apache.tajo.annotation.Nullable; import org.apache.tajo.conf.TajoConf; import org.apache.tajo.ipc.ClientProtos; +import org.apache.tajo.ipc.ClientProtos.ResultCode; import org.apache.tajo.ipc.TajoMasterClientProtocol; import org.apache.tajo.rpc.NettyClientBase; import org.apache.tajo.rpc.RpcConnectionPool; @@ -35,12 +36,14 @@ import org.apache.tajo.rpc.ServerCallable; import org.apache.tajo.util.HAServiceUtil; import org.apache.tajo.util.KeyValueSet; import org.apache.tajo.util.NetUtils; +import org.apache.tajo.util.ProtoUtil; import org.jboss.netty.channel.ConnectTimeoutException; import java.io.Closeable; import java.io.IOException; import java.net.InetSocketAddress; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -71,7 +74,7 @@ public class SessionConnection implements Closeable { private AtomicBoolean closed = new AtomicBoolean(false); /** session variable cache */ - Map<String, String> clientSideSessionVars = new ConcurrentHashMap<String, String>(); + private final Map<String, String> sessionVarsCache = new HashMap<String, String>(); public SessionConnection(TajoConf conf) throws IOException { @@ -111,7 +114,7 @@ public class SessionConnection implements Closeable { } public Map<String, String> getClientSideSessionVars() { - return Collections.unmodifiableMap(clientSideSessionVars); + return Collections.unmodifiableMap(sessionVarsCache); } public <T> T getStub(QueryId queryId, Class protocolClass, boolean asyncMode) throws NoSuchMethodException, @@ -180,10 +183,11 @@ public class SessionConnection implements Closeable { }.withRetries(); } - public Boolean updateSessionVariables(final Map<String, String> variables) throws ServiceException { - return new ServerCallable<Boolean>(connPool, getTajoMasterAddr(), TajoMasterClientProtocol.class, false, true) { + public Map<String, String> updateSessionVariables(final Map<String, String> variables) throws ServiceException { + return new ServerCallable<Map<String, String>>(connPool, getTajoMasterAddr(), + TajoMasterClientProtocol.class, false, true) { - public Boolean call(NettyClientBase client) throws ServiceException { + public Map<String, String> call(NettyClientBase client) throws ServiceException { checkSessionAndGet(client); // keep client-side session variables @@ -192,7 +196,7 @@ public class SessionConnection implements Closeable { if (SessionVars.exists(entry.getKey())) { SessionVars configKey = SessionVars.get(key); if (configKey.getMode() == SessionVars.VariableMode.CLI_SIDE_VAR) { - clientSideSessionVars.put(key, entry.getValue()); + sessionVarsCache.put(key, entry.getValue()); } } } @@ -204,21 +208,32 @@ public class SessionConnection implements Closeable { .setSessionId(sessionId) .setSetVariables(keyValueSet.getProto()).build(); - return tajoMasterService.updateSessionVariables(null, request).getValue(); + ClientProtos.SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request); + if (response.getResultCode() == ResultCode.OK) { + Map<String, String> updated = ProtoUtil.convertToMap(response.getVariables()); + + synchronized (sessionVarsCache) { + sessionVarsCache.clear(); + sessionVarsCache.putAll(updated); + } + return Collections.unmodifiableMap(sessionVarsCache); + } else { + throw new ServiceException(response.getMessage()); + } } }.withRetries(); } - public Boolean unsetSessionVariables(final List<String> variables) throws ServiceException { - return new ServerCallable<Boolean>(connPool, getTajoMasterAddr(), TajoMasterClientProtocol.class, false, true) { + public Map<String, String> unsetSessionVariables(final List<String> variables) throws ServiceException { + return new ServerCallable<Map<String, String>>(connPool, getTajoMasterAddr(), TajoMasterClientProtocol.class, false, true) { - public Boolean call(NettyClientBase client) throws ServiceException { + public Map<String, String> call(NettyClientBase client) throws ServiceException { checkSessionAndGet(client); // Remove matched session vars for (String key : variables) { - if (clientSideSessionVars.containsKey(key)) { - clientSideSessionVars.remove(key); + if (sessionVarsCache.containsKey(key)) { + sessionVarsCache.remove(key); } } @@ -226,19 +241,39 @@ public class SessionConnection implements Closeable { ClientProtos.UpdateSessionVariableRequest request = ClientProtos.UpdateSessionVariableRequest.newBuilder() .setSessionId(sessionId) .addAllUnsetVariables(variables).build(); - return tajoMasterService.updateSessionVariables(null, request).getValue(); + + ClientProtos.SessionUpdateResponse response = tajoMasterService.updateSessionVariables(null, request); + if (response.getResultCode() == ResultCode.OK) { + Map<String, String> updated = ProtoUtil.convertToMap(response.getVariables()); + + synchronized (sessionVarsCache) { + sessionVarsCache.clear(); + sessionVarsCache.putAll(updated); + } + return Collections.unmodifiableMap(sessionVarsCache); + } else { + throw new ServiceException(response.getMessage()); + } } }.withRetries(); } + public String getCachedSessionVariable(final String varname) { + if (sessionVarsCache.containsKey(varname)) { + return sessionVarsCache.get(varname); + } else { + throw new RuntimeException("No such session variable" + varname); + } + } + public String getSessionVariable(final String varname) throws ServiceException { return new ServerCallable<String>(connPool, getTajoMasterAddr(), TajoMasterClientProtocol.class, false, true) { public String call(NettyClientBase client) throws ServiceException { // If a desired variable is client side one and exists in the cache, immediately return the variable. - if (clientSideSessionVars.containsKey(varname)) { - return clientSideSessionVars.get(varname); + if (sessionVarsCache.containsKey(varname)) { + return sessionVarsCache.get(varname); } checkSessionAndGet(client); @@ -261,6 +296,10 @@ public class SessionConnection implements Closeable { }.withRetries(); } + public Map<String, String> getCachedAllSessionVariables() { + return Collections.unmodifiableMap(sessionVarsCache); + } + public Map<String, String> getAllSessionVariables() throws ServiceException { return new ServerCallable<Map<String, String>>(connPool, getTajoMasterAddr(), TajoMasterClientProtocol.class, false, true) { @@ -269,8 +308,7 @@ public class SessionConnection implements Closeable { checkSessionAndGet(client); TajoMasterClientProtocolService.BlockingInterface tajoMasterService = client.getStub(); - KeyValueSet keyValueSet = new KeyValueSet(tajoMasterService.getAllSessionVariables(null, sessionId)); - return keyValueSet.getAllKeyValus(); + return ProtoUtil.convertToMap(tajoMasterService.getAllSessionVariables(null, sessionId)); } }.withRetries(); } @@ -336,9 +374,10 @@ public class SessionConnection implements Closeable { CreateSessionResponse response = tajoMasterService.createSession(null, builder.build()); - if (response.getState() == CreateSessionResponse.ResultState.SUCCESS) { + if (response.getResultCode() == ResultCode.OK) { sessionId = response.getSessionId(); + sessionVarsCache.putAll(ProtoUtil.convertToMap(response.getVariables())); if (LOG.isDebugEnabled()) { LOG.debug(String.format("Got session %s as a user '%s'.", sessionId.getId(), userInfo.getUserName())); } http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-client/src/main/proto/ClientProtos.proto ---------------------------------------------------------------------- diff --git a/tajo-client/src/main/proto/ClientProtos.proto b/tajo-client/src/main/proto/ClientProtos.proto index 4118458..fa12ab2 100644 --- a/tajo-client/src/main/proto/ClientProtos.proto +++ b/tajo-client/src/main/proto/ClientProtos.proto @@ -37,13 +37,10 @@ message CreateSessionRequest { } message CreateSessionResponse { - enum ResultState { - SUCCESS = 0; - FAILED = 1; - } - required ResultState state = 1; + required ResultCode resultCode = 1; optional SessionIdProto sessionId = 2; - optional string message = 3; + optional KeyValueSetProto variables = 3; + optional string message = 4; } message UpdateSessionVariableRequest { @@ -52,6 +49,12 @@ message UpdateSessionVariableRequest { repeated string unsetVariables = 3; } +message SessionUpdateResponse { + required ResultCode resultCode = 1; + optional KeyValueSetProto variables = 2; + optional string message = 3; +} + message SessionedStringProto { optional SessionIdProto sessionId = 1; required string value = 2; http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-client/src/main/proto/TajoMasterClientProtocol.proto ---------------------------------------------------------------------- diff --git a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto index bc59617..10ca268 100644 --- a/tajo-client/src/main/proto/TajoMasterClientProtocol.proto +++ b/tajo-client/src/main/proto/TajoMasterClientProtocol.proto @@ -33,7 +33,7 @@ service TajoMasterClientProtocolService { // Session APIs rpc createSession(CreateSessionRequest) returns (CreateSessionResponse); rpc removeSession(SessionIdProto) returns (BoolProto); - rpc updateSessionVariables(UpdateSessionVariableRequest) returns (BoolProto); + rpc updateSessionVariables(UpdateSessionVariableRequest) returns (SessionUpdateResponse); rpc existSessionVariable(SessionedStringProto) returns (BoolProto); rpc getSessionVariable(SessionedStringProto) returns (StringProto); rpc getAllSessionVariables(SessionIdProto) returns (KeyValueSetProto); http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java b/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java index 8e3eb2a..18d4f59 100644 --- a/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java +++ b/tajo-common/src/main/java/org/apache/tajo/util/KeyValueSet.java @@ -41,6 +41,11 @@ public class KeyValueSet implements ProtoObject<KeyValueSetProto>, Cloneable, Gs public KeyValueSet() { keyVals = TUtil.newHashMap(); } + + public KeyValueSet(Map<String, String> keyVals) { + this(); + putAll(keyVals); + } public KeyValueSet(KeyValueSetProto proto) { this.keyVals = TUtil.newHashMap(); http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java b/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java index 90ffb64..dbc987d 100644 --- a/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java +++ b/tajo-common/src/main/java/org/apache/tajo/util/ProtoUtil.java @@ -19,6 +19,7 @@ package org.apache.tajo.util; import java.util.Collection; +import java.util.Map; import static org.apache.tajo.rpc.protocolrecords.PrimitiveProtos.*; @@ -39,4 +40,16 @@ public class ProtoUtil { public static Collection<String> convertStrings(StringListProto strings) { return strings.getValuesList(); } + + public static Map<String, String> convertToMap(KeyValueSetProto proto) { + Map<String, String> keyVals = TUtil.newHashMap(); + for(KeyValueProto keyval : proto.getKeyvalList()) { + keyVals.put(keyval.getKey(), keyval.getValue()); + } + return keyVals; + } + + public static KeyValueSetProto convertFromMap(Map<String, String> map) { + return new KeyValueSet(map).getProto(); + } } http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 index 4bdbc3d..3ba008f 100644 --- a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 +++ b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLLexer.g4 @@ -132,7 +132,6 @@ CURRENT_DATE: C U R R E N T UNDERLINE D A T E; CURRENT_TIME: C U R R E N T UNDERLINE T I M E; CURRENT_TIMESTAMP: C U R R E N T UNDERLINE T I M E S T A M P; - DESC : D E S C; DISTINCT : D I S T I N C T; @@ -202,6 +201,7 @@ ALTER : A L T E R; BETWEEN : B E T W E E N; BY : B Y; +CATALOG : C A T A L O G; CENTURY : C E N T U R Y; CHARACTER : C H A R A C T E R; COLLECT : C O L L E C T; @@ -213,6 +213,7 @@ CUME_DIST : C U M E UNDERLINE D I S T; CURRENT : C U R R E N T; DAY : D A Y; +DEFAULT : D E F A U L T; DATABASE : D A T A B A S E; DEC : D E C; DECADE : D E C A D E; @@ -280,14 +281,16 @@ QUARTER : Q U A R T E R; RANGE : R A N G E; RANK : R A N K; REGEXP : R E G E X P; +RENAME : R E N A M E; +RESET : R E S E T; RLIKE : R L I K E; ROLLUP : R O L L U P; ROW : R O W; ROWS : R O W S; ROW_NUMBER : R O W UNDERLINE N U M B E R; -RENAME : R E N A M E; SECOND : S E C O N D; +SESSION : S E S S I O N; SET : S E T; SIMILAR : S I M I L A R; STDDEV_POP : S T D D E V UNDERLINE P O P; http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 index beba248..76afb6b 100644 --- a/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 +++ b/tajo-core/src/main/antlr4/org/apache/tajo/engine/parser/SQLParser.g4 @@ -43,12 +43,21 @@ explain_clause ; statement - : data_statement + : session_statement + | data_statement | data_change_statement | schema_statement | index_statement ; +session_statement + : SET CATALOG dbname = identifier + | SET TIME ZONE (TO | EQUAL)? (Character_String_Literal | signed_numerical_literal | DEFAULT) + | SET (SESSION)? name=identifier (TO | EQUAL)? + (Character_String_Literal | signed_numerical_literal | boolean_literal | DEFAULT) + | RESET name=identifier + ; + data_statement : query_expression ; @@ -221,6 +230,7 @@ nonreserved_keywords | ALTER | BETWEEN | BY + | CATALOG | CENTURY | CHARACTER | COALESCE @@ -233,6 +243,7 @@ nonreserved_keywords | DAY | DEC | DECADE + | DEFAULT | DENSE_RANK | DOW | DOY @@ -284,6 +295,7 @@ nonreserved_keywords | RANK | REGEXP | RENAME + | RESET | RLIKE | ROLLUP | ROW @@ -291,6 +303,7 @@ nonreserved_keywords | ROW_NUMBER | SECOND | SET + | SESSION | SIMILAR | STDDEV_POP | STDDEV_SAMP http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java index 03b10c9..ca04301 100644 --- a/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java +++ b/tajo-core/src/main/java/org/apache/tajo/engine/parser/SQLAnalyzer.java @@ -24,6 +24,7 @@ import org.antlr.v4.runtime.ANTLRInputStream; import org.antlr.v4.runtime.CommonTokenStream; import org.antlr.v4.runtime.misc.NotNull; import org.antlr.v4.runtime.tree.TerminalNode; +import org.apache.tajo.SessionVars; import org.apache.tajo.algebra.*; import org.apache.tajo.algebra.Aggregation.GroupType; import org.apache.tajo.algebra.LiteralValue.LiteralType; @@ -81,6 +82,44 @@ public class SQLAnalyzer extends SQLParserBaseVisitor<Expr> { } } + public Expr visitSession_statement(@NotNull SQLParser.Session_statementContext ctx) { + + if (checkIfExist(ctx.CATALOG())) { + + return new SetSession(SessionVars.CURRENT_DATABASE.name(), ctx.dbname.getText()); + + + } else if (checkIfExist(ctx.name)) { + String value; + if (checkIfExist(ctx.boolean_literal())) { + value = ctx.boolean_literal().getText(); + } else if (checkIfExist(ctx.Character_String_Literal())) { + value = stripQuote(ctx.Character_String_Literal().getText()); + } else if (checkIfExist(ctx.signed_numerical_literal())) { + value = ctx.signed_numerical_literal().getText(); + } else { + value = null; + } + return new SetSession(ctx.name.getText(), value); + + + } else if (checkIfExist(ctx.TIME()) && checkIfExist(ctx.ZONE())) { + + String value; + if (checkIfExist(ctx.Character_String_Literal())) { + value = stripQuote(ctx.Character_String_Literal().getText()); + } else if (checkIfExist(ctx.signed_numerical_literal())) { + value = ctx.signed_numerical_literal().getText(); + } else { + value = null; + } + return new SetSession(SessionVars.TZ.name(), value); + + } else { + throw new SQLSyntaxError("Unsupported session statement"); + } + } + @Override public Expr visitNon_join_query_expression(SQLParser.Non_join_query_expressionContext ctx) { http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java index 821d440..f23a8d3 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/GlobalEngine.java @@ -71,6 +71,7 @@ import java.io.IOException; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; +import java.util.TimeZone; import static org.apache.tajo.TajoConstants.DEFAULT_TABLESPACE_NAME; import static org.apache.tajo.catalog.proto.CatalogProtos.AlterTablespaceProto; @@ -212,7 +213,39 @@ public class GlobalEngine extends AbstractService { responseBuilder.setIsForwarded(false); responseBuilder.setUserName(queryContext.get(SessionVars.USERNAME)); - if (PlannerUtil.checkIfDDLPlan(rootNode)) { + if (PlannerUtil.checkIfSetSession(rootNode)) { + + SetSessionNode setSessionNode = rootNode.getChild(); + + final String varName = setSessionNode.getName(); + + // SET CATALOG 'XXX' + if (varName.equals(SessionVars.CURRENT_DATABASE.name())) { + String databaseName = setSessionNode.getValue(); + + if (catalog.existDatabase(databaseName)) { + session.selectDatabase(setSessionNode.getValue()); + } else { + responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); + responseBuilder.setResultCode(ClientProtos.ResultCode.ERROR); + responseBuilder.setErrorMessage("database \"" + databaseName + "\" does not exists."); + return responseBuilder.build(); + } + + // others + } else { + if (setSessionNode.isDefaultValue()) { + session.removeVariable(varName); + } else { + session.setVariable(varName, setSessionNode.getValue()); + } + } + + context.getSystemMetrics().counter("Query", "numDDLQuery").inc(); + responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); + responseBuilder.setResultCode(ClientProtos.ResultCode.OK); + + } else if (PlannerUtil.checkIfDDLPlan(rootNode)) { context.getSystemMetrics().counter("Query", "numDDLQuery").inc(); updateQuery(queryContext, rootNode.getChild()); responseBuilder.setQueryId(QueryIdFactory.NULL_QUERY_ID.getProto()); @@ -461,6 +494,8 @@ public class GlobalEngine extends AbstractService { private boolean updateQuery(QueryContext queryContext, LogicalNode root) throws IOException { switch (root.getType()) { + case SET_SESSION: + case CREATE_DATABASE: CreateDatabaseNode createDatabase = (CreateDatabaseNode) root; createDatabase(queryContext, createDatabase.getDatabaseName(), null, createDatabase.isIfNotExists()); http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java index 540bd71..a4f0259 100644 --- a/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java +++ b/tajo-core/src/main/java/org/apache/tajo/master/TajoMasterClientService.java @@ -143,17 +143,18 @@ public class TajoMasterClientService extends AbstractService { String sessionId = context.getSessionManager().createSession(request.getUsername(), databaseName); CreateSessionResponse.Builder builder = CreateSessionResponse.newBuilder(); - builder.setState(CreateSessionResponse.ResultState.SUCCESS); + builder.setResultCode(ResultCode.OK); builder.setSessionId(TajoIdProtos.SessionIdProto.newBuilder().setId(sessionId).build()); + builder.setVariables(ProtoUtil.convertFromMap(context.getSessionManager().getAllVariables(sessionId))); return builder.build(); } catch (NoSuchDatabaseException nsde) { CreateSessionResponse.Builder builder = CreateSessionResponse.newBuilder(); - builder.setState(CreateSessionResponse.ResultState.FAILED); + builder.setResultCode(ResultCode.ERROR); builder.setMessage(nsde.getMessage()); return builder.build(); } catch (InvalidSessionException e) { CreateSessionResponse.Builder builder = CreateSessionResponse.newBuilder(); - builder.setState(CreateSessionResponse.ResultState.FAILED); + builder.setResultCode(ResultCode.ERROR); builder.setMessage(e.getMessage()); return builder.build(); } @@ -162,14 +163,30 @@ public class TajoMasterClientService extends AbstractService { @Override public BoolProto removeSession(RpcController controller, TajoIdProtos.SessionIdProto request) throws ServiceException { + if (request != null) { context.getSessionManager().removeSession(request.getId()); } - return ProtoUtil.TRUE; + + return BOOL_TRUE; + } + + public SessionUpdateResponse buildSessionUpdateOnSuccess(Map<String, String> variables) { + SessionUpdateResponse.Builder builder = SessionUpdateResponse.newBuilder(); + builder.setResultCode(ResultCode.OK); + builder.setVariables(new KeyValueSet(variables).getProto()); + return builder.build(); + } + + public SessionUpdateResponse buildSessionUpdateOnError(String message) { + SessionUpdateResponse.Builder builder = SessionUpdateResponse.newBuilder(); + builder.setResultCode(ResultCode.ERROR); + builder.setMessage(message); + return builder.build(); } @Override - public BoolProto updateSessionVariables(RpcController controller, UpdateSessionVariableRequest request) + public SessionUpdateResponse updateSessionVariables(RpcController controller, UpdateSessionVariableRequest request) throws ServiceException { try { String sessionId = request.getSessionId().getId(); @@ -179,9 +196,9 @@ public class TajoMasterClientService extends AbstractService { for (String unsetVariable : request.getUnsetVariablesList()) { context.getSessionManager().removeVariable(sessionId, unsetVariable); } - return ProtoUtil.TRUE; + return buildSessionUpdateOnSuccess(context.getSessionManager().getAllVariables(sessionId)); } catch (Throwable t) { - throw new ServiceException(t); + return buildSessionUpdateOnError("Invalid Session Id" + request.getSessionId()); } } http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java b/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java index 23314dd..272f718 100644 --- a/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java +++ b/tajo-core/src/test/java/org/apache/tajo/engine/parser/TestSQLAnalyzer.java @@ -532,4 +532,64 @@ public class TestSQLAnalyzer { public void windowFunction9() throws IOException { assertParseResult("window9.sql", "window9.result"); } + + @Test + public void testSetCatalog1() throws IOException { + assertParseResult("setcatalog1.sql", "setcatalog1.result"); + } + + @Test + public void testSetCatalog2() throws IOException { + assertParseResult("setcatalog2.sql", "setcatalog2.result"); + } + + @Test + public void testTimezone1() throws IOException { + assertParseResult("settimezone1.sql", "settimezone1.result"); + } + + @Test + public void testTimezone2() throws IOException { + assertParseResult("settimezone2.sql", "settimezone2.result"); + } + + @Test + public void testTimezone3() throws IOException { + assertParseResult("settimezone3.sql", "settimezone3.result"); + } + + @Test + public void testSetSession1() throws IOException { + assertParseResult("setsession1.sql", "setsession1.result"); + } + + @Test + public void testSetSession2() throws IOException { + assertParseResult("setsession2.sql", "setsession2.result"); + } + + @Test + public void testSetSession3() throws IOException { + assertParseResult("setsession3.sql", "setsession3.result"); + } + + @Test + public void testSetSession4() throws IOException { + assertParseResult("setsession4.sql", "setsession4.result"); + } + + @Test + public void testSetSession5() throws IOException { + assertParseResult("setsession5.sql", "setsession5.result"); + } + + @Test + public void testSetSession6() throws IOException { + assertParseResult("setsession6.sql", "setsession6.result"); + } + + @Test + public void testSetSession7() throws IOException { + assertParseResult("setsession7.sql", "setsession7.result"); + } } http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSetSessionQuery.java ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSetSessionQuery.java b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSetSessionQuery.java new file mode 100644 index 0000000..5d463c4 --- /dev/null +++ b/tajo-core/src/test/java/org/apache/tajo/engine/query/TestSetSessionQuery.java @@ -0,0 +1,81 @@ +/* + * 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.tajo.engine.query; + +import org.apache.tajo.IntegrationTest; +import org.apache.tajo.QueryTestCaseBase; +import org.apache.tajo.TajoConstants; +import org.apache.tajo.catalog.CatalogUtil; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +@Category(IntegrationTest.class) +public class TestSetSessionQuery extends QueryTestCaseBase { + + public TestSetSessionQuery() { + super(TajoConstants.DEFAULT_DATABASE_NAME); + } + + @Test + public final void testSetCatalog1() throws Exception { + executeString("CREATE DATABASE testsetcatalog;").close(); + assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, getClient().getCurrentDatabase()); + executeString("SET CATALOG testsetcatalog").close(); + assertEquals("testsetcatalog", getClient().getCurrentDatabase()); + executeString("SET CATALOG \"default\"").close(); + executeString("DROP DATABASE testsetcatalog;").close(); + } + + @Test + public final void testSetCatalog2() throws Exception { + executeString("CREATE DATABASE \"testSetCatalog\";").close(); + assertEquals(TajoConstants.DEFAULT_DATABASE_NAME, getClient().getCurrentDatabase()); + executeString("SET CATALOG \"testSetCatalog\"").close(); + assertEquals("testSetCatalog", getClient().getCurrentDatabase()); + executeString("SET CATALOG \"default\"").close(); + executeString("DROP DATABASE \"testSetCatalog\";").close(); + } + + @Test + public final void testSetTimezone() throws Exception { + assertFalse(getClient().existSessionVariable("TZ")); + executeString("SET TIME ZONE 'GMT+9'").close(); + assertTrue(getClient().existSessionVariable("TZ")); + executeString("SET TIME ZONE to DEFAULT").close(); + } + + @Test + public final void testSetSession1() throws Exception { + assertFalse(getClient().existSessionVariable("key1")); + executeString("SET SESSION key1 to true").close(); + assertTrue(getClient().existSessionVariable("key1")); + + executeString("SET SESSION key1 to true").close(); + executeString("SET SESSION key2 to 'val1'").close(); + assertTrue(getClient().existSessionVariable("key1")); + assertTrue(getClient().existSessionVariable("key2")); + executeString("RESET key1").close(); + executeString("SET SESSION key2 to DEFAULT").close(); + assertFalse(getClient().existSessionVariable("key2")); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setcatalog1.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setcatalog1.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setcatalog1.sql new file mode 100644 index 0000000..345531c --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setcatalog1.sql @@ -0,0 +1 @@ +SET CATALOG tajo; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setcatalog2.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setcatalog2.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setcatalog2.sql new file mode 100644 index 0000000..d2ef283 --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setcatalog2.sql @@ -0,0 +1 @@ +SET CATALOG "Mixed Letter"; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession1.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession1.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession1.sql new file mode 100644 index 0000000..8efe696 --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession1.sql @@ -0,0 +1 @@ +SET SESSION ENABLE_SEQSCAN TO true; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession2.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession2.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession2.sql new file mode 100644 index 0000000..458f1e5 --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession2.sql @@ -0,0 +1 @@ +SET SESSION ENABLE_SEQSCAN TO false; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession3.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession3.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession3.sql new file mode 100644 index 0000000..432d123 --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession3.sql @@ -0,0 +1 @@ +SET SESSION EXTSORT_BUFFER_SIZE TO 100; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession4.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession4.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession4.sql new file mode 100644 index 0000000..a363702 --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession4.sql @@ -0,0 +1 @@ +SET SESSION EXTSORT_BUFFER_SIZE TO 50.7; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession5.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession5.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession5.sql new file mode 100644 index 0000000..c9fcfc5 --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession5.sql @@ -0,0 +1 @@ +SET SESSION EXTSORT_BUFFER_SIZE TO 'ABCD'; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession6.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession6.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession6.sql new file mode 100644 index 0000000..957232b --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession6.sql @@ -0,0 +1 @@ +SET SESSION EXTSORT_BUFFER_SIZE 'ABCD'; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession7.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession7.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession7.sql new file mode 100644 index 0000000..179428e --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/setsession7.sql @@ -0,0 +1 @@ +SET SESSION EXTSORT_BUFFER_SIZE = 'ABCD'; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone1.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone1.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone1.sql new file mode 100644 index 0000000..a86d255 --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone1.sql @@ -0,0 +1 @@ +SET TIME ZONE 'PDT'; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone2.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone2.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone2.sql new file mode 100644 index 0000000..85dae0f --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone2.sql @@ -0,0 +1 @@ +SET TIME ZONE -7; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone3.sql ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone3.sql b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone3.sql new file mode 100644 index 0000000..ef56b12 --- /dev/null +++ b/tajo-core/src/test/resources/queries/TestSQLAnalyzer/settimezone3.sql @@ -0,0 +1 @@ +SET TIME ZONE DEFAULT; \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setcatalog1.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setcatalog1.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setcatalog1.result new file mode 100644 index 0000000..cb24cdb --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setcatalog1.result @@ -0,0 +1,5 @@ +{ + "name": "CURRENT_DATABASE", + "value": "tajo", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setcatalog2.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setcatalog2.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setcatalog2.result new file mode 100644 index 0000000..a4f0df2 --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setcatalog2.result @@ -0,0 +1,5 @@ +{ + "name": "CURRENT_DATABASE", + "value": "Mixed Letter", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession1.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession1.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession1.result new file mode 100644 index 0000000..ffd27dd --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession1.result @@ -0,0 +1,5 @@ +{ + "name": "enable_seqscan", + "value": "true", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession2.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession2.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession2.result new file mode 100644 index 0000000..7809a2e --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession2.result @@ -0,0 +1,5 @@ +{ + "name": "enable_seqscan", + "value": "false", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession3.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession3.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession3.result new file mode 100644 index 0000000..9a36755 --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession3.result @@ -0,0 +1,5 @@ +{ + "name": "extsort_buffer_size", + "value": "100", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession4.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession4.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession4.result new file mode 100644 index 0000000..007a563 --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession4.result @@ -0,0 +1,5 @@ +{ + "name": "extsort_buffer_size", + "value": "50.7", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession5.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession5.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession5.result new file mode 100644 index 0000000..8e61229 --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession5.result @@ -0,0 +1,5 @@ +{ + "name": "extsort_buffer_size", + "value": "ABCD", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession6.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession6.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession6.result new file mode 100644 index 0000000..8e61229 --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession6.result @@ -0,0 +1,5 @@ +{ + "name": "extsort_buffer_size", + "value": "ABCD", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession7.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession7.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession7.result new file mode 100644 index 0000000..8e61229 --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/setsession7.result @@ -0,0 +1,5 @@ +{ + "name": "extsort_buffer_size", + "value": "ABCD", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone1.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone1.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone1.result new file mode 100644 index 0000000..366e447 --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone1.result @@ -0,0 +1,5 @@ +{ + "name": "TZ", + "value": "PDT", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone2.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone2.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone2.result new file mode 100644 index 0000000..7653373 --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone2.result @@ -0,0 +1,5 @@ +{ + "name": "TZ", + "value": "-7", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone3.result ---------------------------------------------------------------------- diff --git a/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone3.result b/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone3.result new file mode 100644 index 0000000..8bb188e --- /dev/null +++ b/tajo-core/src/test/resources/results/TestSQLAnalyzer/settimezone3.result @@ -0,0 +1,4 @@ +{ + "name": "TZ", + "OpType": "SetSession" +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java index 68f2186..7c29099 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanPreprocessor.java @@ -177,6 +177,13 @@ public class LogicalPlanPreprocessor extends BaseAlgebraVisitor<LogicalPlanner.P } @Override + public LogicalNode visitSetSession(LogicalPlanner.PlanContext ctx, Stack<Expr> stack, SetSession expr) + throws PlanningException { + SetSessionNode setSession = ctx.plan.createNode(SetSessionNode.class); + return setSession; + } + + @Override public LogicalNode visitProjection(LogicalPlanner.PlanContext ctx, Stack<Expr> stack, Projection expr) throws PlanningException { // If Non-from statement, it immediately returns. http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java index f21bbb5..d153971 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/LogicalPlanner.java @@ -22,6 +22,7 @@ import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Joiner; import com.google.common.collect.Lists; import com.google.common.collect.Sets; +import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.conf.Configuration; @@ -187,6 +188,16 @@ public class LogicalPlanner extends BaseAlgebraVisitor<LogicalPlanner.PlanContex return current; } + @Override + public LogicalNode visitSetSession(PlanContext context, Stack<Expr> stack, SetSession expr) throws PlanningException { + QueryBlock block = context.queryBlock; + + SetSessionNode setSessionNode = block.getNodeFromExpr(expr); + setSessionNode.init(expr.getName(), expr.getValue()); + + return setSessionNode; + } + public LogicalNode visitExplain(PlanContext ctx, Stack<Expr> stack, Explain expr) throws PlanningException { ctx.plan.setExplain(); return visit(ctx, stack, expr.getChild()); http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java index df1e341..1ac12c2 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/AlgebraVisitor.java @@ -25,6 +25,9 @@ import java.util.Stack; public interface AlgebraVisitor<CONTEXT, RESULT> { // Relational Operators + RESULT visitSetSession(CONTEXT ctx, Stack<Expr> stack, SetSession expr) throws PlanningException; + + // Relational Operators RESULT visitProjection(CONTEXT ctx, Stack<Expr> stack, Projection expr) throws PlanningException; RESULT visitLimit(CONTEXT ctx, Stack<Expr> stack, Limit expr) throws PlanningException; RESULT visitSort(CONTEXT ctx, Stack<Expr> stack, Sort expr) throws PlanningException; http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java index 57ddfbd..bd10514 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/algebra/BaseAlgebraVisitor.java @@ -51,6 +51,9 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE RESULT current; switch (expr.getType()) { + case SetSession: + current = visitSetSession(ctx, stack, (SetSession) expr); + break; case Projection: current = visitProjection(ctx, stack, (Projection) expr); @@ -295,6 +298,11 @@ public class BaseAlgebraVisitor<CONTEXT, RESULT> implements AlgebraVisitor<CONTE } @Override + public RESULT visitSetSession(CONTEXT ctx, Stack<Expr> stack, SetSession expr) throws PlanningException { + return null; + } + + @Override public RESULT visitProjection(CONTEXT ctx, Stack<Expr> stack, Projection expr) throws PlanningException { stack.push(expr); try { http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java index 5d1874f..9f01de9 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/NodeType.java @@ -26,6 +26,8 @@ package org.apache.tajo.plan.logical; * This indicates a logical node type. */ public enum NodeType { + SET_SESSION(SetSessionNode.class), + ROOT(LogicalRootNode.class), EXPRS(EvalExprNode.class), PROJECTION(ProjectionNode.class), http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/logical/SetSessionNode.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/logical/SetSessionNode.java b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/SetSessionNode.java new file mode 100644 index 0000000..ba5f83e --- /dev/null +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/logical/SetSessionNode.java @@ -0,0 +1,68 @@ +/* + * 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.tajo.plan.logical; + +import com.google.gson.annotations.Expose; +import org.apache.tajo.plan.PlanString; + +public class SetSessionNode extends LogicalNode { + @Expose private String name; + @Expose private String value; + + public SetSessionNode(int pid) { + super(pid, NodeType.SET_SESSION); + } + + public void init(String name, String value) { + this.name = name; + this.value = value; + } + + public String getName() { + return name; + } + + public boolean isDefaultValue() { + return value == null; + } + + public String getValue() { + return value; + } + + @Override + public void preOrder(LogicalNodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public void postOrder(LogicalNodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public PlanString getPlanString() { + PlanString planString = new PlanString("SET SESSION "); + planString.appendTitle(name).appendTitle("="); + if (value != null) { + planString.appendTitle(String.valueOf(value)); + } + return planString; + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java index 8a9e1ca..e6fa8de 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/util/PlannerUtil.java @@ -48,6 +48,16 @@ import static org.apache.tajo.catalog.proto.CatalogProtos.StoreType.TEXTFILE; public class PlannerUtil { + public static boolean checkIfSetSession(LogicalNode node) { + LogicalNode baseNode = node; + if (node instanceof LogicalRootNode) { + baseNode = ((LogicalRootNode) node).getChild(); + } + + return baseNode.getType() == NodeType.SET_SESSION; + + } + public static boolean checkIfDDLPlan(LogicalNode node) { LogicalNode baseNode = node; if (node instanceof LogicalRootNode) { http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java index f6d04ba..e6ff0d8 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/verifier/PreLogicalPlanVerifier.java @@ -30,7 +30,9 @@ import org.apache.tajo.plan.util.ExprFinder; import org.apache.tajo.plan.PlanningException; import org.apache.tajo.plan.algebra.BaseAlgebraVisitor; import org.apache.tajo.util.TUtil; +import org.apache.tajo.validation.ConstraintViolation; +import java.util.Collection; import java.util.Set; import java.util.Stack; @@ -58,6 +60,24 @@ public class PreLogicalPlanVerifier extends BaseAlgebraVisitor<PreLogicalPlanVer return context.state; } + @Override + public Expr visitSetSession(Context ctx, Stack<Expr> stack, SetSession expr) throws PlanningException { + + // we should allow undefined session variables which can be used in query statements in the future. + if (SessionVars.exists(expr.getName())) { + SessionVars var = SessionVars.get(expr.getName()); + if (var.validator() != null) { + Collection<ConstraintViolation> violations = var.validator().validate(expr.getValue()); + + for (ConstraintViolation violation : violations) { + ctx.state.addVerification(violation.getMessage()); + } + } + } + + return expr; + } + public Expr visitProjection(Context context, Stack<Expr> stack, Projection expr) throws PlanningException { super.visitProjection(context, stack, expr); http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java index 89eb4a8..d09710e 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/BasicLogicalPlanVisitor.java @@ -59,6 +59,9 @@ public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisi case ROOT: current = visitRoot(context, plan, block, (LogicalRootNode) node, stack); break; + case SET_SESSION: + current = visitSetSession(context, plan, block, (SetSessionNode) node, stack); + break; case EXPRS: return null; case PROJECTION: @@ -150,6 +153,12 @@ public class BasicLogicalPlanVisitor<CONTEXT, RESULT> implements LogicalPlanVisi } @Override + public RESULT visitSetSession(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, SetSessionNode node, + Stack<LogicalNode> stack) throws PlanningException { + return null; + } + + @Override public RESULT visitProjection(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, ProjectionNode node, Stack<LogicalNode> stack) throws PlanningException { http://git-wip-us.apache.org/repos/asf/tajo/blob/4bcd4642/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java ---------------------------------------------------------------------- diff --git a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java index 29807f1..6a0c338 100644 --- a/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java +++ b/tajo-plan/src/main/java/org/apache/tajo/plan/visitor/LogicalPlanVisitor.java @@ -25,9 +25,13 @@ import org.apache.tajo.plan.logical.*; import java.util.Stack; public interface LogicalPlanVisitor<CONTEXT, RESULT> { + RESULT visitRoot(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, LogicalRootNode node, Stack<LogicalNode> stack) throws PlanningException; + RESULT visitSetSession(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, SetSessionNode node, + Stack<LogicalNode> stack) throws PlanningException; + RESULT visitProjection(CONTEXT context, LogicalPlan plan, LogicalPlan.QueryBlock block, ProjectionNode node, Stack<LogicalNode> stack) throws PlanningException;
