Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
- Enh #420: Provide `yiisoft/db-implementation` virtual package (@vjik)
- Enh #424, #425, #428: Adapt to conditions refactoring in `yiisoft/db` package (@vjik)
- Enh #431: Remove `TableSchema` class and refactor `Schema` class (@Tigrov)
- Enh #433: Support column's collation (@Tigrov)

## 1.3.0 March 21, 2024

Expand Down
12 changes: 12 additions & 0 deletions src/Column/ColumnDefinitionBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Yiisoft\Db\Constant\ColumnType;
use Yiisoft\Db\QueryBuilder\AbstractColumnDefinitionBuilder;
use Yiisoft\Db\Schema\Column\AbstractArrayColumn;
use Yiisoft\Db\Schema\Column\CollatableColumnInterface;
use Yiisoft\Db\Schema\Column\ColumnInterface;

use function str_repeat;
Expand Down Expand Up @@ -45,6 +46,7 @@ public function build(ColumnInterface $column): string
. $this->buildUnique($column)
. $this->buildDefault($column)
. $this->buildCheck($column)
. $this->buildCollate($column)
. $this->buildReferences($column)
. $this->buildExtra($column);
}
Expand Down Expand Up @@ -74,6 +76,16 @@ public function buildType(ColumnInterface $column): string
return parent::buildType($column);
}

protected function buildCollate(ColumnInterface $column): string
{
if (!$column instanceof CollatableColumnInterface || empty($column->getCollation())) {
return '';
}

/** @psalm-suppress PossiblyNullArgument */
return ' COLLATE ' . $this->queryBuilder->getQuoter()->quoteColumnName($column->getCollation());
}

protected function getDbType(ColumnInterface $column): string
{
$dbType = $column->getDbType();
Expand Down
1 change: 1 addition & 0 deletions src/Column/ColumnFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
* @psalm-type ColumnInfo = array{
* auto_increment?: bool|string,
* check?: string|null,
* collation?: string|null,
* column?: ColumnInterface,
* columns?: array<string, ColumnInterface>,
* comment?: string|null,
Expand Down
12 changes: 11 additions & 1 deletion src/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
* scale: int|string|null,
* contype: string|null,
* dimension: int|string,
* collation: string|null,
* collation_schema: string,
* schema: string,
* table: string
* }
Expand Down Expand Up @@ -308,7 +310,9 @@ protected function findColumns(TableSchemaInterface $table): bool
a.atttypmod
) AS scale,
ct.contype,
COALESCE(NULLIF(a.attndims, 0), NULLIF(t.typndims, 0), (t.typcategory='A')::int) AS dimension
COALESCE(NULLIF(a.attndims, 0), NULLIF(t.typndims, 0), (t.typcategory='A')::int) AS dimension,
co.collname AS collation,
nco.nspname AS collation_schema
FROM
pg_class c
LEFT JOIN pg_attribute a ON a.attrelid = c.oid
Expand All @@ -328,6 +332,8 @@ protected function findColumns(TableSchemaInterface $table): bool
|| ct.conrelid || ' :resorigcol (?:'
|| replace(substr(ct.conkey::text, 2, length(ct.conkey::text) - 2), ',', '|') || ') .*')
)
LEFT JOIN (pg_collation co JOIN pg_namespace nco ON co.collnamespace = nco.oid)
ON a.attcollation = co.oid AND (nco.nspname != 'pg_catalog' OR co.collname != 'default')
WHERE
a.attnum > 0 AND t.typname != '' AND NOT a.attisdropped
AND c.relname = :tableName
Expand Down Expand Up @@ -497,9 +503,13 @@ private function loadColumn(array $info): ColumnInterface
{
$columnFactory = $this->db->getColumnFactory();
$dbType = $this->resolveFullName($info['data_type'], $info['type_scheme']);
$collation = !empty($info['collation'])
? $this->resolveFullName($info['collation'], $info['collation_schema'])
: null;

$columnInfo = [
'autoIncrement' => (bool) $info['is_autoinc'],
'collation' => $collation,
'comment' => $info['column_comment'],
'dbType' => $dbType,
'enumValues' => $info['enum_values'] !== null
Expand Down
4 changes: 4 additions & 0 deletions tests/Provider/QueryBuilderProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ public static function buildColumnDefinition(): array
$values['unsigned()'][0] = 'integer';
$values['scale(2)'][0] = 'numeric(10,2)';
$values['integer(8)->scale(2)'][0] = 'integer';
$values["collation('collation_name')"] = [
'varchar(255) COLLATE "C"',
ColumnBuilder::string()->collation('C'),
];

$db = self::getDb();
$serverVersion = self::getDb()->getServerInfo()->getVersion();
Expand Down
1 change: 1 addition & 0 deletions tests/Provider/SchemaProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public static function columns(): array
dbType: 'varchar',
size: 100,
defaultValue: 'some\'thing',
collation: 'C',
),
'char_col3' => new StringColumn(
ColumnType::TEXT,
Expand Down
2 changes: 1 addition & 1 deletion tests/Support/Fixture/pgsql.sql
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ CREATE TABLE "type" (
tinyint_col smallint DEFAULT '1',
smallint_col smallint DEFAULT '1',
char_col char(100) NOT NULL,
char_col2 varchar(100) DEFAULT 'some''thing',
char_col2 varchar(100) DEFAULT 'some''thing' COLLATE "C",
char_col3 text,
char_col4 character varying DEFAULT E'first line\nsecond line',
float_col double precision NOT NULL,
Expand Down
Loading