Author: shawkins
Date: 2011-04-06 14:05:32 -0400 (Wed, 06 Apr 2011)
New Revision: 3068
Added:
trunk/api/src/main/java/org/teiid/metadata/MetadataProvider.java
Modified:
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
trunk/engine/src/main/java/org/teiid/query/mapping/relational/QueryNode.java
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java
trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java
Log:
TEIID-1326 adding the ability to inject new view definitions at runtime.
Added: trunk/api/src/main/java/org/teiid/metadata/MetadataProvider.java
===================================================================
--- trunk/api/src/main/java/org/teiid/metadata/MetadataProvider.java
(rev 0)
+++ trunk/api/src/main/java/org/teiid/metadata/MetadataProvider.java 2011-04-06 18:05:32
UTC (rev 3068)
@@ -0,0 +1,70 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership. Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.metadata;
+
+import org.teiid.CommandContext;
+
+/**
+ * A hook for providing {@link ViewDefinition}s
+ */
+public interface MetadataProvider {
+
+ public enum Scope {
+ /**
+ * The {@link ViewDefinition} applies only to the calling user
+ */
+ USER,
+ /**
+ * The {@link ViewDefinition} applies to all users
+ */
+ VDB
+ }
+
+ public static class ViewDefinition {
+ private String sql;
+ private Scope scope = Scope.VDB;
+
+ public ViewDefinition(String sql, Scope scope) {
+ this.sql = sql;
+ this.scope = scope;
+ }
+
+ public String getSql() {
+ return sql;
+ }
+
+ public Scope getScope() {
+ return scope;
+ }
+ }
+
+ /**
+ * Returns an updated {@link ViewDefinition} or null if the default view definition
+ * should be used.
+ * @param viewName
+ * @param context
+ * @return
+ */
+ ViewDefinition getViewDefinition(String schema, String viewName, CommandContext
context);
+
+}
Property changes on: trunk/api/src/main/java/org/teiid/metadata/MetadataProvider.java
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-04-06
18:00:20 UTC (rev 3067)
+++
trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPConfiguration.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -25,6 +25,7 @@
import org.teiid.cache.CacheConfiguration;
import org.teiid.client.RequestMessage;
import org.teiid.core.util.ApplicationInfo;
+import org.teiid.metadata.MetadataProvider;
public class DQPConfiguration{
@@ -56,6 +57,7 @@
private int userRequestSourceConcurrency = DEFAULT_USER_REQUEST_SOURCE_CONCURRENCY;
private AuthorizationValidator authorizationValidator;
+ private MetadataProvider metadataProvider;
@ManagementProperty(description="Max active plans (default 20). Increase this
value, and max threads, on highly concurrent systems - but ensure that the underlying
pools can handle the increased load without timeouts.")
public int getMaxActivePlans() {
@@ -220,4 +222,12 @@
AuthorizationValidator authorizationValidator) {
this.authorizationValidator = authorizationValidator;
}
+
+ public MetadataProvider getMetadataProvider() {
+ return metadataProvider;
+ }
+
+ public void setMetadataProvider(MetadataProvider metadataProvider) {
+ this.metadataProvider = metadataProvider;
+ }
}
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-04-06
18:00:20 UTC (rev 3067)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -325,6 +325,7 @@
request.setResultSetCacheEnabled(this.rsCache != null);
request.setAuthorizationValidator(this.authorizationValidator);
request.setUserRequestConcurrency(this.getUserRequestSourceConcurrency());
+ request.setMetadataProvider(this.config.getMetadataProvider());
ResultsFuture<ResultsMessage> resultsFuture = new
ResultsFuture<ResultsMessage>();
RequestWorkItem workItem = new RequestWorkItem(this, requestMsg, request,
resultsFuture.getResultsReceiver(), requestID, workContext);
logMMCommand(workItem, Event.NEW, null);
Modified: trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java 2011-04-06
18:00:20 UTC (rev 3067)
+++ trunk/engine/src/main/java/org/teiid/dqp/internal/process/Request.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -24,8 +24,11 @@
import java.sql.Connection;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -57,10 +60,14 @@
import org.teiid.logging.LogConstants;
import org.teiid.logging.LogManager;
import org.teiid.logging.MessageLevel;
+import org.teiid.metadata.MetadataProvider;
import org.teiid.metadata.FunctionMethod.Determinism;
+import org.teiid.metadata.MetadataProvider.ViewDefinition;
import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
import org.teiid.query.eval.SecurityFunctionEvaluator;
+import org.teiid.query.mapping.relational.QueryNode;
+import org.teiid.query.metadata.BasicQueryMetadataWrapper;
import org.teiid.query.metadata.QueryMetadataInterface;
import org.teiid.query.metadata.TempCapabilitiesFinder;
import org.teiid.query.metadata.TempMetadataAdapter;
@@ -98,8 +105,53 @@
/**
* Server side representation of the RequestMessage. Knows how to process itself.
*/
-public class Request {
+public class Request implements SecurityFunctionEvaluator {
+ private final class ViewDefinitionMetadataWrapper extends
+ BasicQueryMetadataWrapper {
+
+ private Map<List<String>, QueryNode> qnodes = new
HashMap<List<String>, QueryNode>();
+
+ private ViewDefinitionMetadataWrapper(
+ QueryMetadataInterface actualMetadata) {
+ super(actualMetadata);
+ }
+
+ @Override
+ public QueryNode getVirtualPlan(Object groupID)
+ throws TeiidComponentException, QueryMetadataException {
+ QueryNode result = super.getVirtualPlan(groupID);
+ //if there's no exception, then this must be a visible view
+
+ String schema = getName(getModelID(groupID));
+ String viewName = getName(groupID);
+ List<String> key = Arrays.asList(schema, viewName);
+
+ QueryNode cached = qnodes.get(key);
+ if (cached != null) {
+ return cached;
+ }
+ if (context == null) {
+ //TODO: could just consider moving up when the context is created
+ throw new AssertionError("Should not attempt to resolve a view before the
context has been set."); //$NON-NLS-1$
+ }
+ ViewDefinition vd = metadataProvider.getViewDefinition(getName(getModelID(groupID)),
getName(groupID), context);
+ if (vd != null) {
+ result = new QueryNode(DataTypeManager.getCanonicalString(vd.getSql()));
+ if (vd.getScope() == MetadataProvider.Scope.USER) {
+ result.setUser(context.getUserName());
+ }
+ }
+ qnodes.put(key, result);
+ return result;
+ }
+
+ @Override
+ public QueryMetadataInterface getDesignTimeMetadata() {
+ return new
ViewDefinitionMetadataWrapper(this.actualMetadata.getDesignTimeMetadata());
+ }
+ }
+
// init state
protected RequestMessage requestMsg;
private String vdbName;
@@ -135,6 +187,7 @@
private boolean resultSetCacheEnabled = true;
private int userRequestConcurrency;
private AuthorizationValidator authorizationValidator;
+ private MetadataProvider metadataProvider;
void initialize(RequestMessage requestMsg,
BufferManager bufferManager,
@@ -173,6 +226,10 @@
this.authorizationValidator = authorizationValidator;
}
+ public void setMetadataProvider(MetadataProvider metadataProvider) {
+ this.metadataProvider = metadataProvider;
+ }
+
/**
* if the metadata has not been supplied via setMetadata, this method will create the
appropriate state
*
@@ -201,6 +258,10 @@
this.metadata = new MultiSourceMetadataWrapper(this.metadata,
this.multiSourceModels);
}
+ if (this.metadataProvider != null) {
+ this.metadata = new ViewDefinitionMetadataWrapper(this.metadata);
+ }
+
TempMetadataAdapter tma = new TempMetadataAdapter(metadata, new
TempMetadataStore());
tma.setSession(true);
this.metadata = tma;
@@ -244,15 +305,7 @@
context.setPlanToProcessConverter(modifier);
}
- context.setSecurityFunctionEvaluator(new SecurityFunctionEvaluator() {
- @Override
- public boolean hasRole(String roleType, String roleName) throws
TeiidComponentException {
- if (!DATA_ROLE.equalsIgnoreCase(roleType)) {
- return false;
- }
- return authorizationValidator.hasRole(roleName, workContext);
- }
- });
+ context.setSecurityFunctionEvaluator(this);
context.setTempTableStore(tempTableStore);
context.setQueryProcessorFactory(new
QueryProcessorFactoryImpl(this.bufferManager, this.processorDataManager,
this.capabilitiesFinder, idGenerator, metadata));
context.setMetadata(this.metadata);
@@ -262,6 +315,15 @@
context.setUserRequestSourceConcurrency(this.userRequestConcurrency);
}
+ @Override
+ public boolean hasRole(String roleType, String roleName)
+ throws TeiidComponentException {
+ if (!DATA_ROLE.equalsIgnoreCase(roleType)) {
+ return false;
+ }
+ return authorizationValidator.hasRole(roleName, workContext);
+ }
+
public void setUserRequestConcurrency(int userRequestConcurrency) {
this.userRequestConcurrency = userRequestConcurrency;
}
Modified: trunk/engine/src/main/java/org/teiid/query/mapping/relational/QueryNode.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/mapping/relational/QueryNode.java 2011-04-06
18:00:20 UTC (rev 3067)
+++
trunk/engine/src/main/java/org/teiid/query/mapping/relational/QueryNode.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -26,6 +26,7 @@
import java.util.List;
import org.teiid.query.sql.lang.Command;
+import org.teiid.query.validator.UpdateValidator.UpdateInfo;
/**
@@ -43,9 +44,10 @@
// Initial state
private String query;
private List<String> bindings; // optional - construct if needed
-
+ private String user;
// After parsing and resolution
private Command command;
+ private UpdateInfo updateInfo;
/**
* Construct a query node with the required parameters.
@@ -123,5 +125,21 @@
public String toString() {
return query;
}
-
+
+ public String getUser() {
+ return user;
+ }
+
+ public void setUser(String user) {
+ this.user = user;
+ }
+
+ public UpdateInfo getUpdateInfo() {
+ return updateInfo;
+ }
+
+ public void setUpdateInfo(UpdateInfo updateInfo) {
+ this.updateInfo = updateInfo;
+ }
+
}
Modified:
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2011-04-06
18:00:20 UTC (rev 3067)
+++
trunk/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -1114,7 +1114,7 @@
qnode = metadata.getVirtualPlan(metadataID);
}
- Command result = QueryResolver.resolveView(virtualGroup, qnode, cacheString,
metadata);
+ Command result = (Command)QueryResolver.resolveView(virtualGroup, qnode,
cacheString, metadata).getCommand().clone();
return QueryRewriter.rewrite(result, metadata, context);
}
@@ -1155,7 +1155,7 @@
for (Object index : indexes) {
id.addIndex(resolveIndex(metadata, id, index));
}
- Command c = QueryResolver.resolveView(table,
metadata.getVirtualPlan(table.getMetadataID()), SQLConstants.Reserved.SELECT, metadata);
+ Command c = (Command)QueryResolver.resolveView(table,
metadata.getVirtualPlan(table.getMetadataID()), SQLConstants.Reserved.SELECT,
metadata).getCommand().clone();
CacheHint hint = c.getCacheHint();
if (hint != null) {
recordAnnotation(analysisRecord, Annotation.MATERIALIZED_VIEW, Priority.LOW,
"SimpleQueryResolver.cache_hint_used", table, matTableName, id.getCacheHint());
//$NON-NLS-1$
Modified:
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java 2011-04-06
18:00:20 UTC (rev 3067)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/ProcedureContainerResolver.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -29,10 +29,10 @@
import org.teiid.api.exception.query.QueryMetadataException;
import org.teiid.api.exception.query.QueryParserException;
import org.teiid.api.exception.query.QueryResolverException;
+import org.teiid.api.exception.query.QueryValidatorException;
import org.teiid.client.metadata.ParameterInfo;
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
-import org.teiid.core.util.StringUtil;
import org.teiid.language.SQLConstants;
import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
@@ -43,7 +43,6 @@
import org.teiid.query.metadata.TempMetadataStore;
import org.teiid.query.metadata.TempMetadataID.Type;
import org.teiid.query.parser.QueryParser;
-import org.teiid.query.resolver.command.UpdateProcedureResolver;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.sql.ProcedureReservedWords;
import org.teiid.query.sql.lang.Command;
@@ -55,9 +54,7 @@
import org.teiid.query.sql.symbol.ElementSymbol;
import org.teiid.query.sql.symbol.GroupSymbol;
import org.teiid.query.sql.symbol.SingleElementSymbol;
-import org.teiid.query.validator.UpdateValidator;
import org.teiid.query.validator.UpdateValidator.UpdateInfo;
-import org.teiid.query.validator.UpdateValidator.UpdateType;
public abstract class ProcedureContainerResolver implements CommandResolver {
@@ -184,37 +181,16 @@
public static UpdateInfo getUpdateInfo(GroupSymbol group,
QueryMetadataInterface metadata) throws TeiidComponentException,
QueryMetadataException, QueryResolverException {
- //if this is not a view, just return null
- if(group.isTempGroupSymbol() || !metadata.isVirtualGroup(group.getMetadataID()) ||
!metadata.isVirtualModel(metadata.getModelID(group.getMetadataID()))) {
+ if (!QueryResolver.isView(group, metadata)) {
return null;
}
- String updatePlan = metadata.getUpdatePlan(group.getMetadataID());
- String deletePlan = metadata.getDeletePlan(group.getMetadataID());
- String insertPlan = metadata.getInsertPlan(group.getMetadataID());
-
- UpdateInfo info = (UpdateInfo)metadata.getFromMetadataCache(group.getMetadataID(),
"UpdateInfo"); //$NON-NLS-1$
- if (info == null) {
- List<ElementSymbol> elements =
ResolverUtil.resolveElementsInGroup(group, metadata);
- UpdateValidator validator = new UpdateValidator(metadata,
determineType(insertPlan), determineType(updatePlan), determineType(deletePlan));
- info = validator.getUpdateInfo();
- validator.validate(UpdateProcedureResolver.getQueryTransformCmd(group, metadata),
elements);
- metadata.addToMetadataCache(group.getMetadataID(), "UpdateInfo", info);
//$NON-NLS-1$
- }
- return info;
- }
-
- private static UpdateType determineType(String plan) {
- UpdateType type = UpdateType.INHERENT;
- if (plan != null) {
- if (StringUtil.startsWithIgnoreCase(plan, SQLConstants.Reserved.CREATE)) {
- type = UpdateType.UPDATE_PROCEDURE;
- } else {
- type = UpdateType.INSTEAD_OF;
- }
+ try {
+ return QueryResolver.resolveView(group,
metadata.getVirtualPlan(group.getMetadataID()), SQLConstants.Reserved.SELECT,
metadata).getUpdateInfo();
+ } catch (QueryValidatorException e) {
+ throw new QueryResolverException(e, e.getMessage());
}
- return type;
}
-
+
/**
* @param metadata
* @param procCommand
Modified: trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java
===================================================================
--- trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java 2011-04-06
18:00:20 UTC (rev 3067)
+++ trunk/engine/src/main/java/org/teiid/query/resolver/QueryResolver.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -37,7 +37,9 @@
import org.teiid.core.TeiidComponentException;
import org.teiid.core.types.DataTypeManager;
import org.teiid.core.util.Assertion;
+import org.teiid.core.util.StringUtil;
import org.teiid.dqp.internal.process.Request;
+import org.teiid.language.SQLConstants;
import org.teiid.logging.LogManager;
import org.teiid.query.QueryPlugin;
import org.teiid.query.analysis.AnalysisRecord;
@@ -80,7 +82,10 @@
import org.teiid.query.sql.symbol.SingleElementSymbol;
import org.teiid.query.sql.visitor.ExpressionMappingVisitor;
import org.teiid.query.sql.visitor.ValueIteratorProviderCollectorVisitor;
+import org.teiid.query.validator.UpdateValidator;
import org.teiid.query.validator.ValidationVisitor;
+import org.teiid.query.validator.UpdateValidator.UpdateInfo;
+import org.teiid.query.validator.UpdateValidator.UpdateType;
/**
@@ -423,16 +428,20 @@
}
}
- public static Command resolveView(GroupSymbol virtualGroup, QueryNode qnode,
+ public static QueryNode resolveView(GroupSymbol virtualGroup, QueryNode qnode,
String cacheString, QueryMetadataInterface qmi) throws TeiidComponentException,
QueryMetadataException, QueryResolverException,
QueryValidatorException {
qmi = qmi.getDesignTimeMetadata();
- Command result = (Command)qmi.getFromMetadataCache(virtualGroup.getMetadataID(),
"transformation/" + cacheString); //$NON-NLS-1$
- if (result != null) {
- result = (Command)result.clone();
- } else {
- result = qnode.getCommand();
+ cacheString = "transformation/" + cacheString; //$NON-NLS-1$
+ if (qnode.getUser() != null) {
+ cacheString += "/" + qnode.getUser(); //$NON-NLS-1$
+ }
+ QueryNode cachedNode =
(QueryNode)qmi.getFromMetadataCache(virtualGroup.getMetadataID(), cacheString);
+ if (cachedNode == null
+ || (qnode.getQuery() != null &&
!cachedNode.getQuery().equals(qnode.getQuery()))
+ || (qnode.getCommand() != null &&
!cachedNode.getCommand().equals(qnode.getCommand()))) {
+ Command result = qnode.getCommand();
List bindings = null;
if (result == null) {
try {
@@ -463,9 +472,42 @@
}
ResolverUtil.setSymbolType(projectedSymbol, symbols.get(i).getType());
}
- qmi.addToMetadataCache(virtualGroup.getMetadataID(), "transformation/"
+ cacheString, result.clone()); //$NON-NLS-1$
+ cachedNode = new QueryNode(qnode.getQuery());
+ cachedNode.setCommand((Command)result.clone());
+ cachedNode.setUser(qnode.getUser());
+
+ if(isView(virtualGroup, qmi)) {
+ String updatePlan = qmi.getUpdatePlan(virtualGroup.getMetadataID());
+ String deletePlan = qmi.getDeletePlan(virtualGroup.getMetadataID());
+ String insertPlan = qmi.getInsertPlan(virtualGroup.getMetadataID());
+
+ List<ElementSymbol> elements =
ResolverUtil.resolveElementsInGroup(virtualGroup, qmi);
+ UpdateValidator validator = new UpdateValidator(qmi, determineType(insertPlan),
determineType(updatePlan), determineType(deletePlan));
+ validator.validate(result, elements);
+ UpdateInfo info = validator.getUpdateInfo();
+ cachedNode.setUpdateInfo(info);
+ }
+ qmi.addToMetadataCache(virtualGroup.getMetadataID(), cacheString, cachedNode);
}
- return result;
+ return cachedNode;
}
+
+ public static boolean isView(GroupSymbol virtualGroup,
+ QueryMetadataInterface qmi) throws TeiidComponentException,
+ QueryMetadataException {
+ return !virtualGroup.isTempGroupSymbol() &&
qmi.isVirtualGroup(virtualGroup.getMetadataID()) &&
qmi.isVirtualModel(qmi.getModelID(virtualGroup.getMetadataID()));
+ }
+ private static UpdateType determineType(String plan) {
+ UpdateType type = UpdateType.INHERENT;
+ if (plan != null) {
+ if (StringUtil.startsWithIgnoreCase(plan, SQLConstants.Reserved.CREATE)) {
+ type = UpdateType.UPDATE_PROCEDURE;
+ } else {
+ type = UpdateType.INSTEAD_OF;
+ }
+ }
+ return type;
+ }
+
}
Modified:
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java
===================================================================
---
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java 2011-04-06
18:00:20 UTC (rev 3067)
+++
trunk/engine/src/main/java/org/teiid/query/resolver/command/UpdateProcedureResolver.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -50,6 +50,7 @@
import org.teiid.query.resolver.util.ResolveVirtualGroupCriteriaVisitor;
import org.teiid.query.resolver.util.ResolverUtil;
import org.teiid.query.resolver.util.ResolverVisitor;
+import org.teiid.query.sql.LanguageObject;
import org.teiid.query.sql.ProcedureReservedWords;
import org.teiid.query.sql.lang.Command;
import org.teiid.query.sql.lang.Criteria;
@@ -97,21 +98,14 @@
// get a symbol map between virtual elements and the elements that define
// then in the query transformation, this info is used in evaluating/validating
// has criteria/translate criteria clauses
- Command transformCmd = getQueryTransformCmd(virtualGroup, metadata);
- Map symbolMap = SymbolMap.createSymbolMap(virtualGroup,
transformCmd.getProjectedSymbols(), metadata).asMap();
- procCommand.setSymbolMap(symbolMap);
- }
-
- /**
- * Get the command for the transformation query that defines this virtual group.
- */
- public static Command getQueryTransformCmd(GroupSymbol virtualGroup,
QueryMetadataInterface metadata)
- throws QueryMetadataException, QueryResolverException, TeiidComponentException {
- try {
- return QueryResolver.resolveView(virtualGroup,
metadata.getVirtualPlan(virtualGroup.getMetadataID()), SQLConstants.Reserved.SELECT,
metadata);
+ Command transformCmd;
+ try {
+ transformCmd = QueryResolver.resolveView(virtualGroup,
metadata.getVirtualPlan(virtualGroup.getMetadataID()), SQLConstants.Reserved.SELECT,
metadata).getCommand();
} catch (QueryValidatorException e) {
throw new QueryResolverException(e, e.getMessage());
}
+ Map<ElementSymbol, Expression> symbolMap =
SymbolMap.createSymbolMap(virtualGroup,
LanguageObject.Util.deepClone(transformCmd.getProjectedSymbols(),
SingleElementSymbol.class), metadata).asMap();
+ procCommand.setSymbolMap(symbolMap);
}
/**
Modified: trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java
===================================================================
--- trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java 2011-04-06
18:00:20 UTC (rev 3067)
+++ trunk/engine/src/test/java/org/teiid/dqp/internal/process/TestDQPCore.java 2011-04-06
18:05:32 UTC (rev 3068)
@@ -34,6 +34,7 @@
import org.junit.Ignore;
import org.junit.Test;
import org.mockito.Mockito;
+import org.teiid.CommandContext;
import org.teiid.api.exception.query.QueryResolverException;
import org.teiid.cache.DefaultCacheFactory;
import org.teiid.client.RequestMessage;
@@ -44,20 +45,23 @@
import org.teiid.dqp.internal.process.AbstractWorkItem.ThreadState;
import org.teiid.dqp.service.AutoGenDataService;
import org.teiid.dqp.service.FakeBufferService;
+import org.teiid.metadata.MetadataProvider;
import org.teiid.query.optimizer.TestOptimizer;
import org.teiid.query.optimizer.capabilities.BasicSourceCapabilities;
import org.teiid.query.optimizer.capabilities.SourceCapabilities.Capability;
import org.teiid.query.unittest.FakeMetadataFactory;
+import org.teiid.query.unittest.RealMetadataFactory;
@SuppressWarnings("nls")
public class TestDQPCore {
private DQPCore core;
+ private DQPConfiguration config;
private AutoGenDataService agds;
@Before public void setUp() throws Exception {
agds = new AutoGenDataService();
- DQPWorkContext context =
FakeMetadataFactory.buildWorkContext(FakeMetadataFactory.exampleBQT());
+ DQPWorkContext context =
FakeMetadataFactory.buildWorkContext(RealMetadataFactory.exampleBQTCached());
context.getVDB().getModel("BQT3").setVisible(false); //$NON-NLS-1$
context.getVDB().getModel("VQT").setVisible(false); //$NON-NLS-1$
@@ -70,7 +74,7 @@
core.setCacheFactory(new DefaultCacheFactory());
core.setTransactionService(new FakeTransactionService());
- DQPConfiguration config = new DQPConfiguration();
+ config = new DQPConfiguration();
config.setMaxActivePlans(1);
config.setUserRequestSourceConcurrency(2);
core.start(config);
@@ -309,6 +313,33 @@
assertEquals(1, agds.getExecuteCount().get());
}
+ @Test public void testMetadataProvider() throws Exception {
+ this.config.setMetadataProvider(new MetadataProvider() {
+ int callCount;
+ @Override
+ public ViewDefinition getViewDefinition(String schema,
+ String viewName, CommandContext context) {
+ if (callCount++ > 0) {
+ ViewDefinition vd = new ViewDefinition("SELECT 'something
else'", Scope.USER);
+ return vd;
+ }
+ ViewDefinition vd = new ViewDefinition("SELECT 'hello world'",
Scope.USER);
+ return vd;
+ }
+ });
+ //the sql should normally return 10 rows
+ String sql = "SELECT * FROM vqt.SmallB UNION SELECT * FROM vqt.SmallB";
//$NON-NLS-1$
+ String userName = "1"; //$NON-NLS-1$
+
+ ResultsMessage rm = helpExecute(sql, userName);
+ assertEquals(1, rm.getResults().length); //$NON-NLS-1$
+ assertEquals("hello world", rm.getResults()[0].get(0)); //$NON-NLS-1$
+
+ rm = helpExecute(sql, userName);
+ assertEquals(1, rm.getResults().length); //$NON-NLS-1$
+ assertEquals("something else", rm.getResults()[0].get(0));
//$NON-NLS-1$
+ }
+
public void helpTestVisibilityFails(String sql) throws Exception {
RequestMessage reqMsg = exampleRequestMessage(sql);
reqMsg.setTxnAutoWrapMode(RequestMessage.TXN_WRAP_OFF);