private IPhysicalOperator createHashConnector(IOptimizationContext ctx, IPhysicalPropertiesVector deliveredByChild, INodeDomain domain, IPhysicalPropertiesVector requiredAtChild, IPartitioningProperty rqdPartitioning, int childIndex, ILogicalOperator parentOp) { IPhysicalOperator hashConnector; List<LogicalVariable> vars = new ArrayList<>(((UnorderedPartitionedProperty) rqdPartitioning).getColumnSet()); String hashMergeHint = (String) ctx.getMetadataProvider().getConfig().get(HASH_MERGE); if (hashMergeHint == null || !hashMergeHint.equalsIgnoreCase(TRUE_CONSTANT)) { hashConnector = new HashPartitionExchangePOperator(vars, domain); return hashConnector; } List<ILocalStructuralProperty> cldLocals = deliveredByChild.getLocalProperties(); List<ILocalStructuralProperty> reqdLocals = requiredAtChild.getLocalProperties(); boolean propWasSet = false; hashConnector = null; if (reqdLocals != null && cldLocals != null && allAreOrderProps(cldLocals)) { AbstractLogicalOperator c = (AbstractLogicalOperator) parentOp.getInputs().get(childIndex).getValue(); Map<LogicalVariable, EquivalenceClass> ecs = ctx.getEquivalenceClassMap(c); List<FunctionalDependency> fds = ctx.getFDList(c); if (PropertiesUtil.matchLocalProperties(reqdLocals, cldLocals, ecs, fds)) { List<OrderColumn> orderColumns = getOrderColumnsFromGroupingProperties(reqdLocals, cldLocals); hashConnector = new HashPartitionMergeExchangePOperator(orderColumns, vars, domain); propWasSet = true; } } if (!propWasSet) { hashConnector = new HashPartitionExchangePOperator(vars, domain); } return hashConnector; }