Skip to content
Open
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 @@ -59,6 +59,7 @@
- Chg #460: Throw exception on "unsigned" column usage (@vjik)
- New #307: Add range and multirange columns support (@vjik, @Gerych1984)
- Enh #464: Load column's check expressions for table schema (@Tigrov)
- Chg #466: Refactor `ColumnDefinitionParser` (@vjik)
- Bug #467: Fix column definition parsing in cases with parentheses (@vjik)

## 1.3.0 March 21, 2024
Expand Down
64 changes: 41 additions & 23 deletions src/Column/ColumnDefinitionParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

namespace Yiisoft\Db\Pgsql\Column;

use Yiisoft\Db\Syntax\AbstractColumnDefinitionParser;

use function preg_match;
use function preg_replace;
use function strlen;
use function strtolower;
use function substr;
use function substr_count;

/**
* Parses column definition string. For example, `string(255)` or `int unsigned`.
*/
final class ColumnDefinitionParser extends \Yiisoft\Db\Syntax\ColumnDefinitionParser
final class ColumnDefinitionParser extends AbstractColumnDefinitionParser
{
private const TYPE_PATTERN = '/^(?:('
. 'time(?:stamp)?\s*(?:\((\d+)\))? with(?:out)? time zone'
Expand All @@ -24,32 +24,50 @@ final class ColumnDefinitionParser extends \Yiisoft\Db\Syntax\ColumnDefinitionPa
. '|\w*'
. ")(?:\(((?:'[^']*'|[^)])+)\))?)(\[[\d\[\]]*\])?\s*/i";

public function parse(string $definition): array
protected function parseDefinition(string $definition): array
{
preg_match(self::TYPE_PATTERN, $definition, $matches);

/** @var string $type */
$type = $matches[3] ?? preg_replace('/\s*\(\d+\)/', '', $matches[1]);
$type = strtolower($type);
$info = ['type' => $type];

$typeDetails = $matches[4] ?? $matches[2] ?? '';

if ($typeDetails !== '') {
if ($type === 'enum') {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'enum' here and in other drivers should be an abstract type and must be parsable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enum couldn't use in column definition directly.

$info += $this->enumInfo($typeDetails);
} else {
$info += $this->sizeInfo($typeDetails);
}
}

if (isset($matches[5])) {
/** @psalm-var positive-int */
$info['dimension'] = substr_count($matches[5], '[');
}

$extra = substr($definition, strlen($matches[0]));
return [
$type,
$matches[4] ?? $matches[2] ?? null,
$matches[5] ?? null,
substr($definition, strlen($matches[0])),
];
}

return $info + $this->extraInfo($extra);
protected function parseTypeParams(string $type, string $params): array
{
return match ($type) {
'bit varying',
'bit',
'bpchar',
'char',
'character varying',
'character',
'decimal',
'double precision',
'float4',
'float8',
'int',
'interval',
'numeric',
'real',
'string',
'time with time zone',
'time without time zone',
'time',
'timestamp with time zone',
'timestamp without time zone',
'timestamp',
'timestamptz',
'timetz',
'varbit',
'varchar' => $this->parseSizeInfo($params),
default => [],
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Abstract, pseudo, or user-defined types must also be parsable.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why need to parse abstract and pseudo type? What case when this is needed?

Isn't custom types are support parameters?

}
}
2 changes: 0 additions & 2 deletions tests/ArrayParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@

/**
* @group pgsql
*
* @psalm-suppress PropertyNotSetInConstructor
*/
final class ArrayParserTest extends TestCase
{
Expand Down
Loading