private static boolean updateHashEquiJoinCardinality(HashEquiJoin j,
            Map<String, Integer> tableAliasToId,
            Map<String, TableStats> tableStats) {

        DbIterator[] children = j.getChildren();
        DbIterator child1 = children[0];
        DbIterator child2 = children[1];
        int child1Card = 1;
        int child2Card = 1;

        String[] tmp1 = j.getJoinField1Name().split("[.]");
        String tableAlias1 = tmp1[0];
        String pureFieldName1 = tmp1[1];
        String[] tmp2 = j.getJoinField2Name().split("[.]");
        String tableAlias2 = tmp2[0];
        String pureFieldName2 = tmp2[1];

        boolean child1HasJoinPK = Database.getCatalog()
                .getPrimaryKey(tableAliasToId.get(tableAlias1))
                .equals(pureFieldName1);
        ;
        boolean child2HasJoinPK = Database.getCatalog()
                .getPrimaryKey(tableAliasToId.get(tableAlias2))
                .equals(pureFieldName2);
        ;

        if (child1 instanceof Operator) {
            Operator child1O = (Operator) child1;
            boolean pk = updateOperatorCardinality(child1O, tableAliasToId,
                    tableStats);
            child1HasJoinPK = pk || child1HasJoinPK;
            child1Card = child1O.getEstimatedCardinality();
            child1Card = child1Card > 0 ? child1Card : 1;
        } else if (child1 instanceof SeqScan) {
            child1Card = (int) (tableStats.get(((SeqScan) child1)
                    .getTableName()).estimateTableCardinality(1.0));
        }

        if (child2 instanceof Operator) {
            Operator child2O = (Operator) child2;
            boolean pk = updateOperatorCardinality(child2O, tableAliasToId,
                    tableStats);
            child2HasJoinPK = pk || child2HasJoinPK;
            child2Card = child2O.getEstimatedCardinality();
            child2Card = child2Card > 0 ? child2Card : 1;
        } else if (child2 instanceof SeqScan) {
            child2Card = (int) (tableStats.get(((SeqScan) child2)
                    .getTableName()).estimateTableCardinality(1.0));
        }

        j.setEstimatedCardinality(JoinOptimizer.estimateTableJoinCardinality(j
                .getJoinPredicate().getOperator(), tableAlias1, tableAlias2,
                pureFieldName1, pureFieldName2, child1Card, child2Card,
                child1HasJoinPK, child2HasJoinPK, tableStats, tableAliasToId));
        return child1HasJoinPK || child2HasJoinPK;
    }