Parses JOIN entries for a given table
Concatenates $this->join entries for input table

@param string $table table to build JOIN statement for
@return string
197967
private function parseJoin($table)
    {
        $result = '';

        if (isset($this->parts['join'][$table])) {
            foreach ($this->parts['join'][$table] as $join) {
                if (!is_array($join[0])) {
                    $join[0] = [$join[0]];
                }

                $joinTable = isset($join[0][0]) ? $join[0][0] : false;
                $joinAlias = isset($join[0][1]) ? $join[0][1] : false;
                $joinOn = isset($join[1]) ? $join[1] : false;


                $joinType = isset($join[2]) ? $join[2] : '';

                $result .= ($joinType ? ' '.strtoupper($joinType) : '').' JOIN ';
                if ($joinTable instanceof AbstractQuery) {
                    $result .= '('.$joinTable.')';
                    if (empty($joinAlias)) {
                        $joinAlias = 'join1';
                    }
                    $joinTable = $joinAlias;
                } elseif (strpos($joinTable, '(') !== false) {
                    $result .= $joinTable;
                } else {
                    $result .= $this->protect($joinTable);
                }
                $result .= (!empty($joinAlias) ? ' AS '.$this->protect($joinAlias) : '');

                if ($joinOn) {
                    $result .= ' ON ';
                    if (is_array($joinOn)) {
                        $result .= $this->protect($table.'.'.$joinOn[0])
                            .' = '
                            .$this->protect($joinTable.'.'.$joinOn[1]);
                    } else {
                        $result .= '('.$joinOn.')';
                    }
                }
            }
        }

        return $result;
    }
543138
function Join(Table $table, JoinType $join, Condition $condition, $prepend = false)
    {
        $result = $this->Duplicate();
        if ($prepend)
        {
            array_unshift($result->tables, $table);
            array_unshift($result->joins, $join);
            array_unshift($result->conditions, $condition);
        }
        else
        {    
            $result->tables[] = $table;
            $result->joins[] = $join;
            $result->conditions[] = $condition;
        }
        return $result;
    }
678882
public function addPrefix($table) {
        if (strpos($table, '`') !== false) {
            return $table;
        }
        preg_match('/([\w_\.]+)( (as )?[\w_]+)?/i', $table, $match);
        $table = count($match) == 2 ? $table : $match[1];
        $alias = '';
        if (count($match) > 2) {
            $alias = $match[2];
        }
        if (strpos($table, '.') !== false) {
            list($schema, $table) = explode('.', $table);
            return sprintf('`%s`.`%s`%s', $schema, $table, $alias);
        }
        if (strpos($table, '!') === 0) {
            return sprintf('`%s`%s', substr($table, 1), $alias);
        }
        $prefix = $this->getEngine()->getConfig('prefix');
        if (empty($prefix)) {
            return sprintf('`%s`%s', $table, $alias);
        }
        return sprintf('`%s`%s', $prefix.
            Str::firstReplace($table, $prefix), $alias);
    }
664837
protected function parseJoin($join)
    {
        $result = implode(' ', $join);
        foreach($join as $item)
        {
            $this->params = array_merge($this->params, $item->getBinds());
        }
        return $result;
    }
1251675
private function build_join( $join ) {
		$sql = '';
		if ( ! empty( $join ) ) {
			$items = [];
			foreach ( $join as $data ) {
				if ( ! is_array( $data ) || count( $data ) < 3 ) {
					continue;
				}
				$table = $data[0];
				$rule  = $data[1];
				$rule  = strtoupper( $rule );
				if ( ! in_array( $rule, [
					'JOIN',
					'INNER JOIN',
					'LEFT JOIN',
					'RIGHT JOIN',
				] ) ) {
					continue;
				}

				$conditions = $data[2];
				if ( empty( $conditions ) ) {
					continue;
				}
				$check = reset( $conditions );
				if ( ! is_array( $check ) ) {
					$conditions = [ $conditions ];
				}
				$values = [];
				foreach ( $conditions as $condition ) {
					if ( ! is_array( $condition ) || count( $condition ) < 3 ) {
						continue;
					}
					$left     = $condition[0];
					$op       = $condition[1];
					$right    = $condition[2];
					$values[] = $this->get_field_name( $left, null ) . " $op " . $this->get_field_name( $right, null );
				}
				if ( ! empty( $values ) ) {
					$as = null;
					if ( is_array( $table ) && count( $table ) > 1 ) {
						$as    = $table[1];
						$table = $table[0];
					}
					$items[] = $rule . ' ' . $this->get_table( $table ) . ( isset( $as ) ? " AS $as" : '' ) . ' ON ' . implode( ' AND ', $values );
				}
			}
			if ( ! empty( $items ) ) {
				$sql .= ' ' . implode( ' ', $items );
			}
		}

		return $sql;
	}
374012
public function prefixTable(string $table): string
	{
		// Add the prefix to the table name
		// before quoting it
		if ( ! empty($this->tablePrefix))
		{
			// Split identifier by period, will split into:
			// database.schema.table OR
			// schema.table OR
			// database.table OR
			// table
			$identifiers = explode('.', $table);
			$segments = count($identifiers);

			// Quote the last item, and add the database prefix
			$identifiers[$segments - 1] = $this->_prefix(end($identifiers));

			// Rejoin
			$table = implode('.', $identifiers);
		}

		return $table;
	}
893645
private function parseJoin() {
        $joinStr = '';
        foreach ($this->joins as $join) {
            $joinStr .= ' ' . $join[ 'type' ] . ' join ' . $join[ 'join' ] . ' on ' . $join[ 'condition' ];
        }
        return $joinStr;
    }
1365949
public function join($table, $constraint, $table_alias = null)
        {
            return $this->_addJoinSource("", $table, $constraint, $table_alias);
        }
234358
private function parseChangedTable( SimpleXMLElement $table )
    {
        $addedFields = array();
        foreach ( $table->{'added-fields'}->field as $field )
        {
            $fieldName = (string) $field->name;
            $addedFields[$fieldName] = $this->parseField( $field ); 
        }

        $changedFields = array();
        foreach ( $table->{'changed-fields'}->field as $field )
        {
            $fieldName = (string) $field->name;
            $changedFields[$fieldName] = $this->parseField( $field ); 
        }

        $removedFields = array();
        foreach ( $table->{'removed-fields'}->field as $field )
        {
            $fieldName = (string) $field->name;
            if ( (string) $field->removed == 'true' )
            {
                $removedFields[$fieldName] = true;
            }
        }

        $addedIndexes = array();
        foreach ( $table->{'added-indexes'}->index as $index )
        {
            $indexName = (string) $index->name;
            $addedIndexes[$indexName] = $this->parseIndex( $index ); 
        }

        $changedIndexes = array();
        foreach ( $table->{'changed-indexes'}->index as $index )
        {
            $indexName = (string) $index->name;
            $changedIndexes[$indexName] = $this->parseIndex( $index ); 
        }

        $removedIndexes = array();
        foreach ( $table->{'removed-indexes'}->index as $index )
        {
            $indexName = (string) $index->name;
            if ( (string) $index->removed == 'true' )
            {
                $removedIndexes[$indexName] = true;
            }
        }

        return new ezcDbSchemaTableDiff(
            $addedFields, $changedFields, $removedFields, $addedIndexes,
            $changedIndexes, $removedIndexes
        );
    }
40704
public function table($table): string
	{
		if($table instanceof Raw)
		{
			return $this->raw($table);
		}
		elseif($table instanceof Subquery)
		{
			return $this->subquery($table);
		}
		elseif(stripos($table, ' AS ') !== false)
		{
			[$table, , $alias] = explode(' ', $table, 3);

			return sprintf('%s AS %s', $this->escapeTable($table), $this->escapeTable($alias));
		}

		return $this->escapeTable($table);
	}
312167
public function tableDefintion($table)
    {
        $columnStringArray = [];
        $columns = $this->getTableColumns($table, true);

        foreach ($columns as $key => $column) {
            if ($key === 'id') {
                $column['type'] = 'increments';
            }

            $columnStringArray[] = $key.':'.$this->columnNameCheck($column['type']);
        }

        $columnString = implode(',', $columnStringArray);

        return $columnString;
    }
480806
public function join(array $join = [], $table = '')
    {
        $string = '';

        foreach ($join as $type => $value) {
            $string .= sprintf("%s %s ON %s.%s = %s.%s", $type, $value[0], $value[0], $value[1], $table, $value[2]);
        }

        return $string;
    }
1249989
public function wrapTable($table)
    {
        if (! $this->isExpression($table)) {
            return $this->wrapTableValuedFunction(parent::wrapTable($table));
        }

        return $this->getValue($table);
    }
671193
public function getTableColumns(string $table): array {
		$query = <<<QUERY
			SELECT COLUMN_NAME
			FROM INFORMATION_SCHEMA.COLUMNS
			WHERE TABLE_SCHEMA = :database
			AND TABLE_NAME = :table
QUERY;
		
		$params = [
			"database" => $this->database,
			"table"    => $table,
		];
		
		try {
			$results = $this->getCol($query, $params);
			return is_array($results) ? $results : [];
		} catch (\PDOException $databaseException) {
			throw $this->prepareDatabaseException($databaseException, $query, $params);
		}
	}
331949
protected static function getWithPrefix($table)
    {
        $prefix = static::$prefix;

        if (is_null($prefix) || empty($prefix)) {
            // If prefix is null, then no need to prepend a redundant _
            return $table;
        }

        return sprintf('%s_%s', $prefix, $table);
    }
26457
public function metaColumns($table)
    {
        $connection = $this->getConnection();
        $databaseName = $connection->getDatabase();
        $query = "
            SELECT
              COLUMN_NAME AS `Field`,
              COLUMN_TYPE AS `Type`,
              IS_NULLABLE AS `Null`,
              COLUMN_KEY AS `Key`,
              COLUMN_DEFAULT AS `Default`,
              EXTRA AS `Extra`,
              COLUMN_COMMENT AS `Comment`,
              CHARACTER_SET_NAME AS `CharacterSet`,
              COLLATION_NAME AS `Collation`
            FROM information_schema.COLUMNS
            WHERE
              TABLE_SCHEMA = '$databaseName'
              AND
              TABLE_NAME = '$table'";

        try {
            $columns = $connection->executeQuery($query)->fetchAll();
        } catch (DBALException $exception) {
            $exception = $this->convertException($exception);
            $this->handleException($exception);
        } catch (PDOException $exception) {
            $exception = $this->convertException($exception);
            $this->handleException($exception);
        }

        /** Depending on the fetch mode we may find numeric or string key in the array $rawColumns */
        $result = [];

        foreach ($columns as $column) {
            $type = $this->getMetaColumnValueByKey($column, 'Type');
            $field = $this->getMetaColumnValueByKey($column, 'Field');
            $null = $this->getMetaColumnValueByKey($column, 'Null');
            $key = $this->getMetaColumnValueByKey($column, 'Key');
            $default = $this->getMetaColumnValueByKey($column, 'Default');
            $extra = $this->getMetaColumnValueByKey($column, 'Extra');
            $comment = $this->getMetaColumnValueByKey($column, 'Comment');
            $characterSet = $this->getMetaColumnValueByKey($column, 'CharacterSet');
            $collation = $this->getMetaColumnValueByKey($column, 'Collation');


            $typeInformation = explode('(', $type);
            $typeName = trim($typeInformation[0]);

            $item = new \stdClass();
            $item->name = $field;
            $item->type = $typeName;
            $item->not_null = ('no' === strtolower($null));
            $item->primary_key = (strtolower($key) == 'pri');
            $item->auto_increment = strtolower($extra) == 'auto_increment';
            $item->binary = (false !== strpos(strtolower($type), 'blob'));
            $item->unsigned = (false !== strpos(strtolower($type), 'unsigned'));
            $item->has_default = ('' === $default || is_null($default)) ? false : true;
            if ($item->has_default) {
                $item->default_value = $default;
            }

            /**
             * These variables were set only when there was a value in the previous implementation with ADOdb Lite.
             * We do it the same way here for compatibility.
             */
            list($max_length, $scale) = $this->getColumnMaxLengthAndScale($column, $item->type);
            if (-1 !== $max_length) {
                $item->max_length = (string) $max_length;
            } else {
                $item->max_length = $max_length;
            }
            if (-1 !== $scale) {
                $item->scale = (string) $scale;
            } else {
                $item->scale = null;
            }

            /** Unset has_default and default_value for binary types */
            if ($item->binary) {
                unset($item->has_default, $item->default_value);
            }

            /** Additional properties not found in ADODB lite */
            $item->comment = $comment;
            $item->characterSet = $characterSet;
            $item->collation = $collation;

            /**
             * ADODB lite properties not implemented
             *
             * @todo: implement the enums property for SET and ENUM fields
             */
            // $item->enums

            if (array_key_exists('Field', $column)) {
                $result[$item->name] = $item;
            } else {
                $result[] = $item;
            }
        }

        return $result;
    }
519378
public static function dumpTable($table)
    {
        $tokens = array();
        foreach ($table as $name => $value) {
            switch ($value[0]) {
                case 'D':
                    $val = $value[1]->n . 'E' . $value[1]->e;
                    break;
                case 'F':
                    $val = '(' . self::dumpTable($value[1]) . ')';
                    break;
                case 'T':
                    $val = date('Y-m-d H:i:s', $value[1]);
                    break;
                default:
                    $val = $value[1];
            }
            $tokens[] = $name . '=' . $val;
        }
        return implode(', ', $tokens);
    }