Skip to content

Commit

Permalink
TEIID-2482 allowing the planner more flexibility
Browse files Browse the repository at this point in the history
  • Loading branch information
shawkins committed May 8, 2013
1 parent 055e002 commit 498ae0f
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 25 deletions.
Expand Up @@ -100,22 +100,6 @@ public PlanNode execute(PlanNode plan,
if (!JoinStrategyType.MERGE.equals(stype)) {
continue;
}

/**
* Don't push sorts for unbalanced inner joins, we prefer to use a processing time cost based decision
*/
boolean pushLeft = true;
boolean pushRight = true;
if (joinNode.getProperty(NodeConstants.Info.JOIN_TYPE) == JoinType.JOIN_INNER && context != null) {
float leftCost = NewCalculateCostUtil.computeCostForTree(joinNode.getFirstChild(), metadata);
float rightCost = NewCalculateCostUtil.computeCostForTree(joinNode.getLastChild(), metadata);
if (leftCost != NewCalculateCostUtil.UNKNOWN_VALUE && rightCost != NewCalculateCostUtil.UNKNOWN_VALUE
&& (leftCost > context.getProcessorBatchSize() || rightCost > context.getProcessorBatchSize())) {
//we use a larger constant here to ensure that we don't unwisely prevent pushdown
pushLeft = leftCost < context.getProcessorBatchSize() || leftCost / rightCost < 8;
pushRight = rightCost < context.getProcessorBatchSize() || rightCost / leftCost < 8 || joinNode.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE) != null;
}
}

List<Expression> leftExpressions = (List<Expression>) joinNode.getProperty(NodeConstants.Info.LEFT_EXPRESSIONS);
List<Expression> rightExpressions = (List<Expression>) joinNode.getProperty(NodeConstants.Info.RIGHT_EXPRESSIONS);
Expand All @@ -133,6 +117,23 @@ public PlanNode execute(PlanNode plan,
key = NewCalculateCostUtil.getKeyUsed(leftExpressions, null, metadata, null);
right = false;
}
JoinType joinType = (JoinType) joinNode.getProperty(NodeConstants.Info.JOIN_TYPE);
/**
* Don't push sorts for unbalanced inner joins, we prefer to use a processing time cost based decision
*/
boolean pushLeft = true;
boolean pushRight = true;
if ((joinType == JoinType.JOIN_INNER || joinType == JoinType.JOIN_LEFT_OUTER) && context != null) {
float leftCost = NewCalculateCostUtil.computeCostForTree(joinNode.getFirstChild(), metadata);
float rightCost = NewCalculateCostUtil.computeCostForTree(joinNode.getLastChild(), metadata);
if (leftCost != NewCalculateCostUtil.UNKNOWN_VALUE && rightCost != NewCalculateCostUtil.UNKNOWN_VALUE
&& (leftCost > context.getProcessorBatchSize() || rightCost > context.getProcessorBatchSize())) {
//we use a larger constant here to ensure that we don't unwisely prevent pushdown
pushLeft = leftCost < context.getProcessorBatchSize() || leftCost / rightCost < 8 || (key != null && !right);
pushRight = rightCost < context.getProcessorBatchSize() || rightCost / leftCost < 8 || joinType == JoinType.JOIN_LEFT_OUTER || (key != null && right);
}
}

if (key != null && joinNode.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE) == null) {
//redo the join predicates based upon the key alone
List<Object> keyCols = metadata.getElementIDsInKey(key);
Expand Down Expand Up @@ -182,8 +183,14 @@ public PlanNode execute(PlanNode plan,

boolean pushedLeft = insertSort(joinNode.getFirstChild(), leftExpressions, joinNode, metadata, capabilitiesFinder, pushLeft);

//TODO: this check could be performed, as it implies we're using enhanced and can back out of the sort
// but this not valid in all circumstances
//if (!pushedLeft && joinNode.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE) != null && joinType == JoinType.JOIN_INNER) {
//pushRight = true; //this sort will not be used if more than one source command is generated
//}

if (origExpressionCount == 1
&& joinNode.getProperty(NodeConstants.Info.JOIN_TYPE) == JoinType.JOIN_INNER
&& joinType == JoinType.JOIN_INNER
&& joinNode.getProperty(NodeConstants.Info.DEPENDENT_VALUE_SOURCE) != null
&& !joinNode.hasCollectionProperty(Info.NON_EQUI_JOIN_CRITERIA)) {
Collection<Expression> output = (Collection<Expression>) joinNode.getProperty(NodeConstants.Info.OUTPUT_COLS);
Expand All @@ -195,7 +202,6 @@ public PlanNode execute(PlanNode plan,
}

boolean pushedRight = insertSort(joinNode.getLastChild(), rightExpressions, joinNode, metadata, capabilitiesFinder, pushRight);
JoinType joinType = (JoinType) joinNode.getProperty(NodeConstants.Info.JOIN_TYPE);
if ((!pushedRight || !pushedLeft) && (joinType == JoinType.JOIN_INNER || (joinType == JoinType.JOIN_LEFT_OUTER && !pushedLeft))) {
joinNode.setProperty(NodeConstants.Info.JOIN_STRATEGY, JoinStrategyType.ENHANCED_SORT);
}
Expand Down
Expand Up @@ -719,7 +719,7 @@ null, getAggregatesFinder(),
metadata,
null, capFinder,
new String[] {"SELECT g_0.\"MONTH\" AS c_0, g_0.\"YEAR\" AS c_1 FROM msmodel.\"TIME\" AS g_0 WHERE g_0.\"YEAR\" = '1999' ORDER BY c_0",
"SELECT g_0.\"MONTH\" AS c_0, g_0.CITY AS c_1, SUM(g_0.SALES) AS c_2 FROM db2model.SALES AS g_0 WHERE (g_0.\"MONTH\" IN (<dependent values>)) AND (g_0.CITY IN (<dependent values>)) GROUP BY g_0.\"MONTH\", g_0.CITY ORDER BY c_0",
"SELECT g_0.\"MONTH\", g_0.CITY, SUM(g_0.SALES) FROM db2model.SALES AS g_0 WHERE (g_0.\"MONTH\" IN (<dependent values>)) AND (g_0.CITY IN (<dependent values>)) GROUP BY g_0.\"MONTH\", g_0.CITY",
"SELECT g_0.CITY AS c_0, g_0.REGION AS c_1 FROM oraclemodel.GEOGRAPHY AS g_0 WHERE g_0.REGION IN ('BORDEAUX', 'POLINESIA') ORDER BY c_0"}, //$NON-NLS-1$
ComparisonMode.EXACT_COMMAND_STRING );

Expand Down Expand Up @@ -767,7 +767,7 @@ null, getAggregatesFinder(),
metadata,
null, capFinder,
new String[] {"SELECT g_0.\"MONTH\" AS c_0, g_0.\"YEAR\" AS c_1 FROM msmodel.\"TIME\" AS g_0 WHERE g_0.\"YEAR\" = '1999' ORDER BY c_0",
"SELECT g_0.\"MONTH\" AS c_0, g_0.CITY AS c_1, SUM(g_0.SALES) AS c_2 FROM db2model.SALES AS g_0 WHERE (g_0.\"MONTH\" IN (<dependent values>)) AND (g_0.CITY IN (<dependent values>)) GROUP BY g_0.\"MONTH\", g_0.CITY ORDER BY c_0",
"SELECT g_0.\"MONTH\", g_0.CITY, SUM(g_0.SALES) FROM db2model.SALES AS g_0 WHERE (g_0.\"MONTH\" IN (<dependent values>)) AND (g_0.CITY IN (<dependent values>)) GROUP BY g_0.\"MONTH\", g_0.CITY",
"SELECT g_0.CITY AS c_0, g_0.REGION AS c_1 FROM oraclemodel.GEOGRAPHY AS g_0 WHERE g_0.REGION IN ('BORDEAUX', 'POLINESIA') ORDER BY c_0"}, //$NON-NLS-1$
ComparisonMode.EXACT_COMMAND_STRING );

Expand Down Expand Up @@ -815,7 +815,7 @@ null, getAggregatesFinder(),
metadata,
null, capFinder,
new String[] {"SELECT g_0.\"MONTH\" AS c_0, g_0.\"YEAR\" AS c_1 FROM msmodel.\"TIME\" AS g_0 WHERE g_0.\"YEAR\" = '1999' ORDER BY c_0",
"SELECT g_0.\"MONTH\" AS c_0, g_1.REGION AS c_1, SUM(g_0.SALES) AS c_2 FROM db2model.SALES AS g_0, db2model.GEOGRAPHY2 AS g_1 WHERE (g_0.CITY = g_1.CITY) AND (g_1.REGION IN ('BORDEAUX', 'POLINESIA')) AND (g_0.\"MONTH\" IN (<dependent values>)) GROUP BY g_0.\"MONTH\", g_1.REGION ORDER BY c_0"}, //$NON-NLS-1$
"SELECT g_0.\"MONTH\", g_1.REGION, SUM(g_0.SALES) FROM db2model.SALES AS g_0, db2model.GEOGRAPHY2 AS g_1 WHERE (g_0.CITY = g_1.CITY) AND (g_1.REGION IN ('BORDEAUX', 'POLINESIA')) AND (g_0.\"MONTH\" IN (<dependent values>)) GROUP BY g_0.\"MONTH\", g_1.REGION"}, //$NON-NLS-1$
ComparisonMode.EXACT_COMMAND_STRING );

checkNodeTypes(plan, new int[] {
Expand Down
Expand Up @@ -634,7 +634,7 @@ private void checkNotDependentGroups(ProcessorPlan plan, String[] groups) {

ProcessorPlan plan = TestOptimizer.helpPlan(sql, metadata,
null, capFinder,
new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0", "SELECT g_0.e1 AS c_0 FROM pm1.g3 AS g_0 ORDER BY c_0", "SELECT g_0.e1 AS c_0 FROM pm1.g2 AS g_0 WHERE g_0.e1 IN (<dependent values>) ORDER BY c_0" }, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0", "SELECT g_0.e1 AS c_0 FROM pm1.g3 AS g_0 ORDER BY c_0", "SELECT g_0.e1 FROM pm1.g2 AS g_0 WHERE g_0.e1 IN (<dependent values>)" }, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
TestOptimizer.checkNodeTypes(plan, new int[] {
2, // Access
1, // DependentAccess
Expand Down Expand Up @@ -673,7 +673,7 @@ private void checkNotDependentGroups(ProcessorPlan plan, String[] groups) {

ProcessorPlan plan = TestOptimizer.helpPlan(sql, metadata,
null, capFinder,
new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0", "SELECT g_0.e1 AS c_0 FROM pm1.g2 AS g_0 WHERE g_0.e1 IN (<dependent values>) ORDER BY c_0" }, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
new String[] { "SELECT g_0.e1 AS c_0 FROM pm1.g1 AS g_0 ORDER BY c_0", "SELECT g_0.e1 FROM pm1.g2 AS g_0 WHERE g_0.e1 IN (<dependent values>)" }, TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING); //$NON-NLS-1$ //$NON-NLS-2$
TestOptimizer.checkNodeTypes(plan, new int[] {
1, // Access
1, // DependentAccess
Expand Down Expand Up @@ -804,7 +804,7 @@ private void checkNotDependentGroups(ProcessorPlan plan, String[] groups) {
"SELECT max(a.stringkey) from bqt1.smalla a, bqt2.smalla a2, bqt1.smalla a1 where a.intnum = a2.intnum and a1.stringnum = a2.stringnum and a.floatnum = a1.floatnum", //$NON-NLS-1$
metadata,
null, capFinder,
new String[] {"SELECT DISTINCT g_0.StringNum AS c_0, g_0.IntNum AS c_1 FROM BQT2.SmallA AS g_0 WHERE (g_0.StringNum IN (<dependent values>)) AND (g_0.IntNum IN (<dependent values>)) ORDER BY c_0, c_1", "SELECT g_1.StringNum AS c_0, g_0.IntNum AS c_1, MAX(g_0.StringKey) AS c_2 FROM BQT1.SmallA AS g_0, BQT1.SmallA AS g_1 WHERE g_0.FloatNum = g_1.FloatNum GROUP BY g_1.StringNum, g_0.IntNum ORDER BY c_0, c_1"},
new String[] {"SELECT g_0.StringNum, g_0.IntNum FROM BQT2.SmallA AS g_0 WHERE (g_0.StringNum IN (<dependent values>)) AND (g_0.IntNum IN (<dependent values>))", "SELECT g_1.StringNum AS c_0, g_0.IntNum AS c_1, MAX(g_0.StringKey) AS c_2 FROM BQT1.SmallA AS g_0, BQT1.SmallA AS g_1 WHERE g_0.FloatNum = g_1.FloatNum GROUP BY g_1.StringNum, g_0.IntNum ORDER BY c_0, c_1"},
TestOptimizer.ComparisonMode.EXACT_COMMAND_STRING );

TestOptimizer.checkNodeTypes(plan, new int[] {
Expand Down
Expand Up @@ -3261,7 +3261,7 @@ public static TransformationMetadata example1() {

ProcessorPlan plan = helpPlan(sql, metadata,
null, capFinder,
new String[] { "SELECT pm1.g1.e1 FROM pm1.g1 ORDER BY pm1.g1.e1", "SELECT pm1.g2.e1 FROM pm1.g2 ORDER BY pm1.g2.e1"}, SHOULD_SUCCEED); //$NON-NLS-1$ //$NON-NLS-2$
new String[] { "SELECT pm1.g1.e1 FROM pm1.g1 ORDER BY pm1.g1.e1", "SELECT pm1.g2.e1 FROM pm1.g2"}, SHOULD_SUCCEED); //$NON-NLS-1$ //$NON-NLS-2$
checkNodeTypes(plan, new int[] {
2, // Access
0, // DependentAccess
Expand Down

0 comments on commit 498ae0f

Please sign in to comment.