NABoolean MultiJoin::duplicateMatch(const RelExpr & other) const { // We need to compare the arity before RelExpr::duplicateMatch(...) // otherwise we may get out of array boundary exception when compaing // this multijoin to a RelExpr with different arity. This is different // than other RelExprs because the check for operator type does not // secure the same arity in this case. if (getArity() != other.getArity()) return FALSE; ((RelExpr*)this)->selectionPred().clear(); if (!RelExpr::duplicateMatch(other)) return FALSE; MultiJoin &o = (MultiJoin &) other; if (jbbSubset_ != o.jbbSubset_) return FALSE; // At this point we will consider MJs with different LSRs to be different // This can change in the future, but would require updating the duplicate // MJ in the cascades memo to add the scheduledLSRs from the inserted one. if (scheduledLSRs_ != o.scheduledLSRs_) return FALSE; return TRUE; }
short Join::generateShape(CollHeap * c, char * buf, NAString * shapeStr) { Space * space = (Space *)c; char mybuf[100]; switch (getOperatorType()) { case REL_NESTED_JOIN: case REL_LEFT_NESTED_JOIN: case REL_NESTED_SEMIJOIN: case REL_NESTED_ANTI_SEMIJOIN: case REL_NESTED_JOIN_FLOW: sprintf(mybuf, "nested_join("); break; case REL_MERGE_JOIN: case REL_LEFT_MERGE_JOIN: case REL_MERGE_SEMIJOIN: case REL_MERGE_ANTI_SEMIJOIN: sprintf(mybuf, "merge_join("); break; case REL_HASH_SEMIJOIN: case REL_HASH_ANTI_SEMIJOIN: sprintf(mybuf, "hash_join("); break; case REL_LEFT_HYBRID_HASH_JOIN: case REL_HYBRID_HASH_SEMIJOIN: case REL_HYBRID_HASH_ANTI_SEMIJOIN: case REL_FULL_HYBRID_HASH_JOIN: sprintf(mybuf, "hybrid_hash_join("); break; case REL_LEFT_ORDERED_HASH_JOIN: case REL_ORDERED_HASH_JOIN: case REL_ORDERED_HASH_SEMIJOIN: case REL_ORDERED_HASH_ANTI_SEMIJOIN: sprintf(mybuf, "ordered_hash_join("); break; case REL_HYBRID_HASH_JOIN: if (((HashJoin *)this)->isOrderedCrossProduct()) sprintf(mybuf, "ordered_cross_product("); else sprintf(mybuf, "hybrid_hash_join("); break; default: sprintf(mybuf, "add_to_Join::generateShape("); } outputBuffer(space, buf, mybuf, shapeStr); child(0)->generateShape(space, buf, shapeStr); sprintf(mybuf, ","); outputBuffer(space, buf, mybuf, shapeStr); child(1)->generateShape(space, buf, shapeStr); // is it IndexJoin? if both children are scans and number of base tables is // 1, it is index join if (getGroupAttr()->getNumBaseTables() == 1) { NABoolean child0isScan = FALSE; NABoolean child1isScan = FALSE; RelExpr *lChild = child(0)->castToRelExpr(); while (lChild->getArity() == 1) { lChild=lChild->child(0)->castToRelExpr(); } switch( lChild->castToRelExpr()->getOperatorType()) { case REL_SCAN: case REL_FILE_SCAN: case REL_HBASE_ACCESS: case REL_HDFS_SCAN: child0isScan = TRUE; } RelExpr *rChild = child(1)->castToRelExpr(); while (rChild->getArity() == 1) { rChild = rChild->child(0)->castToRelExpr(); } switch (rChild->castToRelExpr()->getOperatorType()) { case REL_SCAN: case REL_FILE_SCAN: case REL_HBASE_ACCESS: case REL_HDFS_SCAN: child1isScan = TRUE; } if (child0isScan && child1isScan) { sprintf(mybuf, ",INDEXJOIN)"); } else { sprintf(mybuf, ")"); } } else { sprintf(mybuf, ")"); } outputBuffer(space, buf, mybuf, shapeStr); return 0; }