public function realJoin(
        /*# string */ $joinType,
        $table,
        $firstTableCol = '',
        /*# string */ $operator = ClauseInterface::NO_OPERATOR,
        /*# string */ $secondTableCol = ClauseInterface::NO_VALUE,
        /*# bool */ $rawMode = false
    ) {
        $join = strtoupper($joinType) . ' JOIN';

        // raw mode
        if ($rawMode || '' === $firstTableCol) {
            $rawMode = true;
            $on = null;

        // groupd on/orOn
        } elseif (is_object($firstTableCol) &&
                $firstTableCol instanceof ExpressionInterface
        ) {
            // object ExpressionInterface
            $on = $firstTableCol;

        } elseif ($this->isRaw($firstTableCol)) {
            $rawMode = true;

            // raw string
            $on = $firstTableCol;

        // col provided
        } else {
            // only ONE colName provided
            if (ClauseInterface::NO_OPERATOR === $operator) {
                $on = [$firstTableCol, '=', $firstTableCol];

            // 2 colNames provides
            } elseif (ClauseInterface::NO_VALUE === $secondTableCol) {
                $on = [$firstTableCol, '=', $operator];

            // 2 colNames and operator provided
            } else {
                $on = [$firstTableCol, $operator, $secondTableCol];
            }
        }

        // check table alias
        if (is_object($table) && $table instanceof SelectStatementInterface) {
            // subquery MUST have alias
            $alias = $table->getAlias();
        } else {
            // find alias in the $table
            $splitted = $this->splitAlias($table);
            if (!$rawMode && isset($splitted[1])) {
                $table = $splitted[0];
                $alias = $splitted[1];
            } else {
                $alias = null;
            }
        }

        $this->clause_join[] = [$rawMode, $join, $table, $on, $alias];

        return $this;
    }
public function realJoin(
        /*# string */ $joinType,
        $table,
        $firstTableCol = '',
        /*# string */ $operator = ClauseInterface::NO_OPERATOR,
        /*# string */ $secondTableCol = ClauseInterface::NO_VALUE,
        /*# bool */ $rawMode = false
    ) {
        $join = strtoupper($joinType) . ' JOIN';

        // raw mode
        if ($rawMode || '' === $firstTableCol) {
            $rawMode = true;
            $on = null;

        // groupd on/orOn
        } elseif (is_object($firstTableCol) &&
                $firstTableCol instanceof ExpressionInterface
        ) {
            // object ExpressionInterface
            $on = $firstTableCol;

        } elseif ($this->isRaw($firstTableCol)) {
            $rawMode = true;

            // raw string
            $on = $firstTableCol;

        // col provided
        } else {
            // only ONE colName provided
            if (ClauseInterface::NO_OPERATOR === $operator) {
                $on = [$firstTableCol, '=', $firstTableCol];

            // 2 colNames provides
            } elseif (ClauseInterface::NO_VALUE === $secondTableCol) {
                $on = [$firstTableCol, '=', $operator];

            // 2 colNames and operator provided
            } else {
                $on = [$firstTableCol, $operator, $secondTableCol];
            }
        }

        // check table alias
        if (is_object($table) && $table instanceof SelectStatementInterface) {
            // subquery MUST have alias
            $alias = $table->getAlias();
        } else {
            // find alias in the $table
            $splitted = $this->splitAlias($table);
            if (!$rawMode && isset($splitted[1])) {
                $table = $splitted[0];
                $alias = $splitted[1];
            } else {
                $alias = null;
            }
        }

        $this->clause_join[] = [$rawMode, $join, $table, $on, $alias];

        return $this;
    }
{@inheritDoc}