function joinOnce($table_or_column, $on_clause_or_column = null, $join_type = self::JOIN) {
		if ($table_or_column instanceof QueryJoin) {
			$join = clone $table_or_column;
		} else {
			if (null === $on_clause_or_column) {
				if ($join_type == self::JOIN || $join_type == self::INNER_JOIN) {
					foreach ($this->extraTables as &$table) {
						if ($table == $table_or_column) {
							return $this;
						}
					}
					$this->addTable($table_or_column);
					return $this;
				}
				$on_clause_or_column = '1 = 1';
			}
			$join = new QueryJoin($table_or_column, $on_clause_or_column, $join_type);
		}
		foreach ($this->joins as &$existing_join) {
			if ($join->getTable() == $existing_join->getTable()) {
				if ($join->getAlias() != $existing_join->getAlias()) {
					// tables match, but aliases don't match
					continue;
				}
				// tables match, and aliases match or there are no aliases
				return $this;
			}
		}
		$this->joins[] = $join;
		return $this;
	}