function Schema::queryTableInformation

Same name and namespace in other branches
  1. 9 core/modules/pgsql/src/Driver/Database/pgsql/Schema.php \Drupal\pgsql\Driver\Database\pgsql\Schema::queryTableInformation()
  2. 8.9.x core/lib/Drupal/Core/Database/Driver/pgsql/Schema.php \Drupal\Core\Database\Driver\pgsql\Schema::queryTableInformation()
  3. 11.x core/modules/pgsql/src/Driver/Database/pgsql/Schema.php \Drupal\pgsql\Driver\Database\pgsql\Schema::queryTableInformation()

Fetch the list of blobs and sequences used on a table.

We introspect the database to collect the information required by insert and update queries.

Parameters

string $table: The non-prefixed name of the table.

Return value

mixed|object An object with two member variables:

  • 'blob_fields' that lists all the blob fields in the table.
  • 'sequences' that lists the sequences used in that table.

Throws

\Exception Exception thrown when the query for the table information fails.

2 calls to Schema::queryTableInformation()
Schema::changeField in core/modules/pgsql/src/Driver/Database/pgsql/Schema.php
Change a field definition.
Schema::renameTable in core/modules/pgsql/src/Driver/Database/pgsql/Schema.php
Rename a table.

File

core/modules/pgsql/src/Driver/Database/pgsql/Schema.php, line 128

Class

Schema
PostgreSQL implementation of <a href="/api/drupal/core%21lib%21Drupal%21Core%21Database%21Schema.php/class/Schema/10" title="Provides a base implementation for Database Schema." class="local">\Drupal\Core\Database\Schema</a>.

Namespace

Drupal\pgsql\Driver\Database\pgsql

Code

public function queryTableInformation($table) {
    // Generate a key to reference this table's information on.
    $prefixed_table = $this->connection
        ->getPrefix() . $table;
    $key = $this->connection
        ->prefixTables('{' . $table . '}');
    // Take into account that temporary tables are stored in a different schema.
    // \Drupal\Core\Database\Connection::generateTemporaryTableName() sets the
    // 'db_temporary_' prefix to all temporary tables.
    if (str_contains($table, 'db_temporary_')) {
        $key = $quoted_key = $this->getTempNamespaceName() . '.' . $prefixed_table;
    }
    else {
        $key = $this->defaultSchema . '.' . $prefixed_table;
        $quoted_key = '"' . $this->defaultSchema . '"."' . $prefixed_table . '"';
    }
    if (!isset($this->tableInformation[$key])) {
        $table_information = (object) [
            'blob_fields' => [],
            'sequences' => [],
        ];
        $this->connection
            ->addSavepoint();
        try {
            // The bytea columns and sequences for a table can be found in
            // pg_attribute, which is significantly faster than querying the
            // information_schema. The data type of a field can be found by lookup
            // of the attribute ID, and the default value must be extracted from the
            // node tree for the attribute definition instead of the historical
            // human-readable column, adsrc.
            $sql = <<<'EOD'
SELECT pg_attribute.attname AS column_name, format_type(pg_attribute.atttypid, pg_attribute.atttypmod) AS data_type, pg_get_expr(pg_attrdef.adbin, pg_attribute.attrelid) AS column_default
FROM pg_attribute
LEFT JOIN pg_attrdef ON pg_attrdef.adrelid = pg_attribute.attrelid AND pg_attrdef.adnum = pg_attribute.attnum
WHERE pg_attribute.attnum > 0
AND NOT pg_attribute.attisdropped
AND pg_attribute.attrelid = :key::regclass
AND (format_type(pg_attribute.atttypid, pg_attribute.atttypmod) = 'bytea'
OR pg_get_expr(pg_attrdef.adbin, pg_attribute.attrelid) LIKE 'nextval%')
EOD;
            $result = $this->connection
                ->query($sql, [
                ':key' => $quoted_key,
            ]);
        } catch (\Exception $e) {
            $this->connection
                ->rollbackSavepoint();
            throw $e;
        }
        $this->connection
            ->releaseSavepoint();
        // If the table information does not yet exist in the PostgreSQL
        // metadata, then return the default table information here, so that it
        // will not be cached.
        if (empty($result)) {
            return $table_information;
        }
        foreach ($result as $column) {
            if ($column->data_type == 'bytea') {
                $table_information->blob_fields[$column->column_name] = TRUE;
            }
            elseif (preg_match("/nextval\\('([^']+)'/", $column->column_default, $matches)) {
                // We must know of any sequences in the table structure to help us
                // return the last insert id. If there is more than 1 sequences the
                // first one (index 0 of the sequences array) will be used.
                $table_information->sequences[] = $matches[1];
                $table_information->serial_fields[] = $column->column_name;
            }
        }
        $this->tableInformation[$key] = $table_information;
    }
    return $this->tableInformation[$key];
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.