use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.
the class RuleCopyCriteria method copyCriteria.
/**
* Given a criteria and a map of elements to values try to create a new single group criteria
*
* If the new criteria does not have exactly one group or already exists in the combined criteria,
* it will not be added.
*
* @param crit
* @param tgtMap
* @param joinCriteria
* @param combinedCriteria
* @return number of remaining groups if the copy was successful
*/
private Integer copyCriteria(Criteria crit, Map<Expression, Expression> tgtMap, List<Criteria> joinCriteria, Set<Criteria> combinedCriteria, boolean checkForGroupReduction, QueryMetadataInterface metadata, boolean underAccess) {
int startGroups = GroupsUsedByElementsVisitor.getGroups(crit).size();
Criteria tgtCrit = (Criteria) crit.clone();
try {
tgtCrit = FrameUtil.convertCriteria(tgtCrit, tgtMap, metadata, true);
} catch (QueryPlannerException err) {
// $NON-NLS-1$
LogManager.logDetail(LogConstants.CTX_QUERY_PLANNER, err, "Could not remap target criteria in RuleCopyCriteria");
return null;
}
if (tgtCrit instanceof IsNullCriteria && ((IsNullCriteria) tgtCrit).isNegated()) {
return null;
}
int endGroups = GroupsUsedByElementsVisitor.getGroups(tgtCrit).size();
if (checkForGroupReduction) {
if (endGroups >= startGroups) {
return null;
}
} else if (endGroups > startGroups) {
return null;
}
boolean isNew = combinedCriteria.add(tgtCrit);
if (underAccess) {
if (!isNew || checkForGroupReduction || endGroups > 1) {
return null;
}
if (!COPY_ALL) {
boolean use = false;
Collection<ElementSymbol> cols = ElementCollectorVisitor.getElements(tgtCrit, true);
// use only if it could be used to further rewrite predicates
for (Criteria existing : combinedCriteria) {
if (existing.equals(tgtCrit)) {
continue;
}
Collection<ElementSymbol> elements = ElementCollectorVisitor.getElements(existing, true);
if (GroupsUsedByElementsVisitor.getGroups(elements).size() > 1) {
continue;
}
if (elements.containsAll(cols)) {
use = true;
break;
}
}
if (!use) {
return null;
}
}
}
// if this is unique or it a duplicate but reduced a current join conjunct, return true
if (isNew) {
joinCriteria.add(tgtCrit);
if (tgtCrit instanceof CompareCriteria) {
CompareCriteria cc = (CompareCriteria) tgtCrit;
if (!EvaluatableVisitor.willBecomeConstant(cc.getRightExpression()) && !EvaluatableVisitor.willBecomeConstant(cc.getRightExpression())) {
((CompareCriteria) tgtCrit).setOptional(true);
}
}
return endGroups;
} else if (checkForGroupReduction && endGroups < 2) {
return endGroups;
}
return null;
}
use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.
the class PlanToProcessConverter method convert.
public RelationalPlan convert(PlanNode planNode) throws QueryPlannerException, TeiidComponentException {
try {
boolean debug = analysisRecord.recordDebug();
if (debug) {
// $NON-NLS-1$
analysisRecord.println("\n============================================================================");
// $NON-NLS-1$
analysisRecord.println("CONVERTING PLAN TREE TO PROCESS TREE");
}
// Convert plan tree nodes into process tree nodes
RelationalNode processNode;
try {
processNode = convertPlan(planNode);
} catch (TeiidProcessingException e) {
if (e instanceof QueryPlannerException) {
throw (QueryPlannerException) e;
}
throw new QueryPlannerException(e);
}
if (debug) {
// $NON-NLS-1$
analysisRecord.println("\nPROCESS PLAN = \n" + processNode);
// $NON-NLS-1$
analysisRecord.println("============================================================================");
}
RelationalPlan processPlan = new RelationalPlan(processNode);
return processPlan;
} finally {
sharedCommands.clear();
}
}
use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.
the class PlanToProcessConverter method aliasCommand.
private Command aliasCommand(AccessNode aNode, Command command, Object modelID) throws TeiidComponentException, QueryPlannerException {
try {
command = (Command) command.clone();
boolean aliasGroups = modelID != null && (CapabilitiesUtil.supportsGroupAliases(modelID, metadata, capFinder) || CapabilitiesUtil.supports(Capability.QUERY_FROM_INLINE_VIEWS, modelID, metadata, capFinder));
boolean aliasColumns = modelID != null && (CapabilitiesUtil.supports(Capability.QUERY_SELECT_EXPRESSION, modelID, metadata, capFinder) || CapabilitiesUtil.supports(Capability.QUERY_FROM_INLINE_VIEWS, modelID, metadata, capFinder));
AliasGenerator visitor = new AliasGenerator(aliasGroups, !aliasColumns);
SourceHint sh = command.getSourceHint();
if (sh != null && aliasGroups) {
VDBMetaData vdb = context.getDQPWorkContext().getVDB();
ModelMetaData model = vdb.getModel(aNode.getModelName());
List<String> sourceNames = model.getSourceNames();
SpecificHint sp = null;
if (sourceNames.size() == 1) {
sp = sh.getSpecificHint(sourceNames.get(0));
}
if (sh.isUseAliases() || (sp != null && sp.isUseAliases())) {
visitor.setAliasMapping(context.getAliasMapping());
}
}
List<Reference> references = ReferenceCollectorVisitor.getReferences(command);
if (!references.isEmpty()) {
Set<String> correleatedGroups = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
for (Reference ref : references) {
if (ref.isCorrelated() && ref.getExpression().getGroupSymbol() != null) {
correleatedGroups.add(ref.getExpression().getGroupSymbol().getName());
}
}
visitor.setCorrelationGroups(correleatedGroups);
}
command.acceptVisitor(visitor);
} catch (QueryMetadataException err) {
throw new TeiidComponentException(QueryPlugin.Event.TEIID30249, err);
} catch (TeiidRuntimeException e) {
if (e.getCause() instanceof QueryPlannerException) {
throw (QueryPlannerException) e.getCause();
}
throw e;
}
return command;
}
use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.
the class PlanToProcessConverter method setRoutingName.
private void setRoutingName(AccessNode accessNode, PlanNode node, Command command) throws QueryPlannerException, TeiidComponentException {
// Look up connector binding name
try {
Object modelID = node.getProperty(NodeConstants.Info.MODEL_ID);
if (modelID == null || modelID instanceof TempMetadataID) {
if (command instanceof StoredProcedure) {
modelID = ((StoredProcedure) command).getModelID();
} else if (!(command instanceof Create || command instanceof Drop)) {
Collection<GroupSymbol> groups = GroupCollectorVisitor.getGroups(command, true);
GroupSymbol group = groups.iterator().next();
modelID = metadata.getModelID(group.getMetadataID());
}
}
String cbName = metadata.getFullName(modelID);
accessNode.setModelName(cbName);
accessNode.setModelId(modelID);
accessNode.setConformedTo((Set<Object>) node.getProperty(Info.CONFORMED_SOURCES));
} catch (QueryMetadataException e) {
throw new QueryPlannerException(QueryPlugin.Event.TEIID30251, e, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30251));
}
}
use of org.teiid.api.exception.query.QueryPlannerException in project teiid by teiid.
the class RelationalPlanner method planWith.
private void planWith(PlanNode plan, Command command) throws QueryPlannerException, QueryMetadataException, TeiidComponentException, QueryResolverException {
if (this.withPlanningState.withList.isEmpty()) {
return;
}
// TODO: merge this logic inline with the main rule execution.
RuleStack stack = new RuleStack();
stack.push(new RuleAssignOutputElements(false));
if (hints.hasRowBasedSecurity) {
stack.push(new RuleApplySecurity());
}
// use a temporary planner to run just the assign output elements
RelationalPlanner planner = new RelationalPlanner();
// we don't want to trigger the with processing for just projection
planner.processWith = false;
planner.initialize(command, idGenerator, metadata, capFinder, analysisRecord, context);
planner.executeRules(stack, plan);
// discover all of the usage
List<Command> commands = CommandCollectorVisitor.getCommands(command, true);
while (!commands.isEmpty()) {
Command cmd = commands.remove(commands.size() - 1);
commands.addAll(CommandCollectorVisitor.getCommands(cmd, true));
try {
PlanNode temp = planner.generatePlan((Command) cmd.clone());
stack.push(new RuleAssignOutputElements(false));
planner.executeRules(stack, temp);
} catch (TeiidProcessingException e) {
throw new QueryPlannerException(e);
}
}
// plan and minimize projection
for (WithQueryCommand with : this.withPlanningState.withList.values()) {
QueryCommand subCommand = with.getCommand();
TempMetadataID tid = (TempMetadataID) with.getGroupSymbol().getMetadataID();
if (tid.getTableData().getModel() != TempMetadataAdapter.TEMP_MODEL) {
tid.getTableData().setModel(null);
}
List<TempMetadataID> elements = tid.getElements();
List<Integer> toRemove = new ArrayList<Integer>();
for (int i = elements.size() - 1; i >= 0; i--) {
TempMetadataID elem = elements.get(i);
if (!elem.isAccessed()) {
toRemove.add(i);
}
}
// the definition of the with clause consistent
if (!toRemove.isEmpty()) {
if (with.isRecursive()) {
SetQuery setQuery = (SetQuery) subCommand;
setQuery.setLeftQuery(removeUnusedProjection(with, setQuery.getLeftQuery(), elements, toRemove));
setQuery.setRightQuery(removeUnusedProjection(with, setQuery.getRightQuery(), elements, toRemove));
} else {
subCommand = removeUnusedProjection(with, subCommand, elements, toRemove);
with.setCommand(subCommand);
}
}
if (with.isRecursive()) {
SetQuery setQuery = (SetQuery) subCommand;
QueryCommand qc = setQuery.getLeftQuery();
final RelationalPlan subPlan = optimize(qc);
qc.setProcessorPlan(subPlan);
AccessNode aNode = CriteriaCapabilityValidatorVisitor.getAccessNode(subPlan);
Object modelID = null;
QueryCommand withCommand = null;
if (aNode != null) {
modelID = CriteriaCapabilityValidatorVisitor.validateCommandPushdown(null, metadata, capFinder, aNode, false);
if (modelID != null) {
if (with.getGroupSymbol().getModelMetadataId() != null || !CapabilitiesUtil.supports(Capability.RECURSIVE_COMMON_TABLE_EXPRESSIONS, modelID, metadata, capFinder) || with.isMaterialize()) {
modelID = null;
} else {
withCommand = CriteriaCapabilityValidatorVisitor.getQueryCommand(aNode);
if (withCommand != null) {
// provisionally set the source
((TempMetadataID) with.getGroupSymbol().getMetadataID()).getTableData().setModel(modelID);
}
}
}
}
// now that we possibly have a model id, plan the recursive part
QueryCommand qc1 = setQuery.getRightQuery();
RelationalPlan subPlan1 = optimize((Command) qc1.clone());
qc1.setProcessorPlan(subPlan1);
if (!isPushdownValid(with, setQuery, modelID, withCommand, subPlan1) && withCommand != null) {
// reset the source to null and replan
((TempMetadataID) with.getGroupSymbol().getMetadataID()).getTableData().setModel(null);
subPlan1 = optimize(qc1);
qc1.setProcessorPlan(subPlan1);
}
continue;
}
RelationalPlan subPlan = optimize(subCommand);
subCommand.setProcessorPlan(subPlan);
RelationalPlan procPlan = subPlan;
RelationalNode root = procPlan.getRootNode();
Number planCardinality = root.getEstimateNodeCardinality();
if (planCardinality != null) {
((TempMetadataID) with.getGroupSymbol().getMetadataID()).setCardinality(planCardinality.intValue());
}
AccessNode aNode = CriteriaCapabilityValidatorVisitor.getAccessNode(procPlan);
if (aNode == null) {
continue;
}
Object modelID = CriteriaCapabilityValidatorVisitor.validateCommandPushdown(null, metadata, capFinder, aNode, false);
QueryCommand withCommand = CriteriaCapabilityValidatorVisitor.getQueryCommand(aNode);
if (modelID == null || withCommand == null) {
continue;
}
if (with.getGroupSymbol().getModelMetadataId() != null || !CapabilitiesUtil.supports(Capability.COMMON_TABLE_EXPRESSIONS, modelID, metadata, capFinder) || with.isMaterialize()) {
continue;
}
WithQueryCommand wqc = new WithQueryCommand(with.getGroupSymbol(), with.getColumns(), withCommand);
wqc.setNoInline(with.isNoInline());
((TempMetadataID) with.getGroupSymbol().getMetadataID()).getTableData().setModel(modelID);
this.withPlanningState.pushdownWith.put(with.getGroupSymbol().getName(), wqc);
}
}
Aggregations