Skip to content
Merged
8 changes: 8 additions & 0 deletions src/Illuminate/Database/Query/Processors/MySqlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ public function processColumns($results)
'default' => $result->default,
'auto_increment' => $result->extra === 'auto_increment',
'comment' => $result->comment ?: null,
'generation' => $result->expression ? [
'type' => match ($result->extra) {
'STORED GENERATED' => 'stored',
'VIRTUAL GENERATED' => 'virtual',
default => null,
},
'expression' => $result->expression,
] : null,
];
}, $results);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,16 @@ public function processColumns($results)
'type' => $result->type,
'collation' => $result->collation,
'nullable' => (bool) $result->nullable,
'default' => $autoincrement ? null : $result->default,
'default' => $result->generated ? null : $result->default,
'auto_increment' => $autoincrement,
'comment' => $result->comment,
'generation' => $result->generated ? [
'type' => match ($result->generated) {
's' => 'stored',
default => null,
},
'expression' => $result->default,
] : null,
];
}, $results);
}
Expand Down
16 changes: 16 additions & 0 deletions src/Illuminate/Database/Query/Processors/SQLiteProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,14 @@ public function processColumns($results, $sql = '')
$matches
) === 1 ? strtolower($matches[1]) : null;

$isGenerated = in_array($result->extra, [2, 3]);

$expression = $isGenerated && preg_match(
'/\b'.preg_quote($result->name).'\b[^,]+\s+as\s+\(((?:[^()]+|\((?:[^()]+|\([^()]*\))*\))*)\)/i',
$sql,
$matches
) === 1 ? $matches[1] : null;

return [
'name' => $result->name,
'type_name' => strtok($type, '(') ?: '',
Expand All @@ -35,6 +43,14 @@ public function processColumns($results, $sql = '')
'default' => $result->default,
'auto_increment' => $hasPrimaryKey && $result->primary && $type === 'integer',
'comment' => null,
'generation' => $isGenerated ? [
'type' => match ((int) $result->extra) {
3 => 'stored',
2 => 'virtual',
default => null,
},
'expression' => $expression,
] : null,
];
}, $results);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ public function processColumns($results)
'default' => $result->default,
'auto_increment' => (bool) $result->autoincrement,
'comment' => $result->comment,
'generation' => $result->expression ? [
'type' => $result->persisted ? 'stored' : 'virtual',
'expression' => $result->expression,
] : null,
];
}, $results);
}
Expand Down
7 changes: 6 additions & 1 deletion src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,8 @@ public function compileColumns($database, $table)
return sprintf(
'select column_name as `name`, data_type as `type_name`, column_type as `type`, '
.'collation_name as `collation`, is_nullable as `nullable`, '
.'column_default as `default`, column_comment as `comment`, extra as `extra` '
.'column_default as `default`, column_comment as `comment`, '
.'generation_expression as `expression`, extra as `extra` '
.'from information_schema.columns where table_schema = %s and table_name = %s '
.'order by ordinal_position asc',
$this->quoteString($database),
Expand Down Expand Up @@ -343,6 +344,10 @@ public function compileRenameColumn(Blueprint $blueprint, Fluent $command, Conne
'autoIncrement' => $column['auto_increment'],
'collation' => $column['collation'],
'comment' => $column['comment'],
'virtualAs' => ! is_null($column['generation']) && $column['generation']['type'] === 'virtual'
? $column['generation']['expression'] : null,
'storedAs' => ! is_null($column['generation']) && $column['generation']['type'] === 'stored'
? $column['generation']['expression'] : null,
]));

return sprintf('alter table %s change %s %s %s',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ public function compileColumns($schema, $table)
.'(select tc.collcollate from pg_catalog.pg_collation tc where tc.oid = a.attcollation) as collation, '
.'not a.attnotnull as nullable, '
.'(select pg_get_expr(adbin, adrelid) from pg_attrdef where c.oid = pg_attrdef.adrelid and pg_attrdef.adnum = a.attnum) as default, '
.'a.attgenerated as generated, '
.'col_description(c.oid, a.attnum) as comment '
.'from pg_attribute a, pg_class c, pg_type t, pg_namespace n '
.'where c.relname = %s and n.nspname = %s and a.attnum > 0 and a.attrelid = c.oid and a.atttypid = t.oid and n.oid = c.relnamespace '
Expand Down
18 changes: 15 additions & 3 deletions src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public function compileViews()
public function compileColumns($table)
{
return sprintf(
'select name, type, not "notnull" as "nullable", dflt_value as "default", pk as "primary" '
'select name, type, not "notnull" as "nullable", dflt_value as "default", pk as "primary", hidden as "extra" '
.'from pragma_table_xinfo(%s) order by cid asc',
$this->wrap(str_replace('.', '__', $table))
);
Expand Down Expand Up @@ -250,14 +250,22 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection

if ($column instanceof Fluent) {
$name = $this->wrap($column);
$columnNames[] = $name;
$autoIncrementColumn = $column->autoIncrement ? $column->name : $autoIncrementColumn;

if (is_null($column->virtualAs) && is_null($column->virtualAsJson) &&
is_null($column->storedAs) && is_null($column->storedAsJson)) {
$columnNames[] = $name;
}

return $this->addModifiers($name.' '.$this->getType($column), $blueprint, $column);
} else {
$name = $this->wrap($column['name']);
$columnNames[] = $name;
$autoIncrementColumn = $column['auto_increment'] ? $column['name'] : $autoIncrementColumn;
$isGenerated = ! is_null($column['generation']);

if (! $isGenerated) {
$columnNames[] = $name;
}

return $this->addModifiers($name.' '.$column['type'], $blueprint,
new ColumnDefinition([
Expand All @@ -268,6 +276,10 @@ public function compileChange(Blueprint $blueprint, Fluent $command, Connection
'autoIncrement' => $column['auto_increment'],
'collation' => $column['collation'],
'comment' => $column['comment'],
'virtualAs' => $isGenerated && $column['generation']['type'] === 'virtual'
? $column['generation']['expression'] : null,
'storedAs' => $isGenerated && $column['generation']['type'] === 'stored'
? $column['generation']['expression'] : null,
])
);
}
Expand Down
2 changes: 2 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,15 @@ public function compileColumns($schema, $table)
.'col.max_length as length, col.precision as precision, col.scale as places, '
.'col.is_nullable as nullable, def.definition as [default], '
.'col.is_identity as autoincrement, col.collation_name as collation, '
.'com.definition as [expression], is_persisted as [persisted], '
.'cast(prop.value as nvarchar(max)) as comment '
.'from sys.columns as col '
.'join sys.types as type on col.user_type_id = type.user_type_id '
.'join sys.objects as obj on col.object_id = obj.object_id '
.'join sys.schemas as scm on obj.schema_id = scm.schema_id '
.'left join sys.default_constraints def on col.default_object_id = def.object_id and col.object_id = def.parent_object_id '
."left join sys.extended_properties as prop on obj.object_id = prop.major_id and col.column_id = prop.minor_id and prop.name = 'MS_Description' "
.'left join sys.computed_columns as com on col.column_id = com.column_id '
."where obj.type in ('U', 'V') and obj.name = %s and scm.name = %s "
.'order by col.column_id',
$this->quoteString($table),
Expand Down
6 changes: 3 additions & 3 deletions tests/Database/DatabaseMariaDbProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ public function testProcessColumns()
['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => 'YES', 'default' => 'NULL', 'extra' => 'on update CURRENT_TIMESTAMP', 'comment' => 'NULL'],
];
$expected = [
['name' => 'id', 'type_name' => 'bigint', 'type' => 'bigint', 'collation' => 'collate', 'nullable' => true, 'default' => '', 'auto_increment' => true, 'comment' => 'bar'],
['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => false, 'default' => 'foo', 'auto_increment' => false, 'comment' => ''],
['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => true, 'default' => 'NULL', 'auto_increment' => false, 'comment' => 'NULL'],
['name' => 'id', 'type_name' => 'bigint', 'type' => 'bigint', 'collation' => 'collate', 'nullable' => true, 'default' => '', 'auto_increment' => true, 'comment' => 'bar', 'generation' => null],
['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => false, 'default' => 'foo', 'auto_increment' => false, 'comment' => '', 'generation' => null],
['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => true, 'default' => 'NULL', 'auto_increment' => false, 'comment' => 'NULL', 'generation' => null],
];
$this->assertEquals($expected, $processor->processColumns($listing));

Expand Down
6 changes: 3 additions & 3 deletions tests/Database/DatabaseMySqlProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ public function testProcessColumns()
['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => 'YES', 'default' => 'NULL', 'extra' => 'on update CURRENT_TIMESTAMP', 'comment' => 'NULL'],
];
$expected = [
['name' => 'id', 'type_name' => 'bigint', 'type' => 'bigint', 'collation' => 'collate', 'nullable' => true, 'default' => '', 'auto_increment' => true, 'comment' => 'bar'],
['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => false, 'default' => 'foo', 'auto_increment' => false, 'comment' => ''],
['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => true, 'default' => 'NULL', 'auto_increment' => false, 'comment' => 'NULL'],
['name' => 'id', 'type_name' => 'bigint', 'type' => 'bigint', 'collation' => 'collate', 'nullable' => true, 'default' => '', 'auto_increment' => true, 'comment' => 'bar', 'generation' => null],
['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => false, 'default' => 'foo', 'auto_increment' => false, 'comment' => null, 'generation' => null],
['name' => 'email', 'type_name' => 'varchar', 'type' => 'varchar(100)', 'collation' => 'collate', 'nullable' => true, 'default' => 'NULL', 'auto_increment' => false, 'comment' => 'NULL', 'generation' => null],
];
$this->assertEquals($expected, $processor->processColumns($listing));

Expand Down
8 changes: 4 additions & 4 deletions tests/Database/DatabasePostgresProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ public function testProcessColumns()
['name' => 'birth_date', 'type_name' => 'timestamp', 'type' => 'timestamp(6) without time zone', 'collation' => '', 'nullable' => false, 'default' => '', 'comment' => ''],
];
$expected = [
['name' => 'id', 'type_name' => 'int4', 'type' => 'integer', 'collation' => '', 'nullable' => true, 'default' => null, 'auto_increment' => true, 'comment' => ''],
['name' => 'name', 'type_name' => 'varchar', 'type' => 'character varying(100)', 'collation' => 'collate', 'nullable' => false, 'default' => '', 'auto_increment' => false, 'comment' => 'foo'],
['name' => 'balance', 'type_name' => 'numeric', 'type' => 'numeric(8,2)', 'collation' => '', 'nullable' => true, 'default' => '4', 'auto_increment' => false, 'comment' => 'NULL'],
['name' => 'birth_date', 'type_name' => 'timestamp', 'type' => 'timestamp(6) without time zone', 'collation' => '', 'nullable' => false, 'default' => '', 'auto_increment' => false, 'comment' => ''],
['name' => 'id', 'type_name' => 'int4', 'type' => 'integer', 'collation' => '', 'nullable' => true, 'default' => "nextval('employee_id_seq'::regclass)", 'auto_increment' => true, 'comment' => '', 'generation' => null],
['name' => 'name', 'type_name' => 'varchar', 'type' => 'character varying(100)', 'collation' => 'collate', 'nullable' => false, 'default' => '', 'auto_increment' => false, 'comment' => 'foo', 'generation' => null],
['name' => 'balance', 'type_name' => 'numeric', 'type' => 'numeric(8,2)', 'collation' => '', 'nullable' => true, 'default' => '4', 'auto_increment' => false, 'comment' => 'NULL', 'generation' => null],
['name' => 'birth_date', 'type_name' => 'timestamp', 'type' => 'timestamp(6) without time zone', 'collation' => '', 'nullable' => false, 'default' => '', 'auto_increment' => false, 'comment' => '', 'generation' => null],
];

$this->assertEquals($expected, $processor->processColumns($listing));
Expand Down
6 changes: 3 additions & 3 deletions tests/Database/DatabaseSQLiteProcessorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ public function testProcessColumns()
['name' => 'is_active', 'type' => 'tinyint(1)', 'nullable' => '0', 'default' => '1', 'primary' => '0'],
];
$expected = [
['name' => 'id', 'type_name' => 'integer', 'type' => 'integer', 'collation' => null, 'nullable' => false, 'default' => '', 'auto_increment' => true, 'comment' => null],
['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar', 'collation' => null, 'nullable' => true, 'default' => 'foo', 'auto_increment' => false, 'comment' => null],
['name' => 'is_active', 'type_name' => 'tinyint', 'type' => 'tinyint(1)', 'collation' => null, 'nullable' => false, 'default' => '1', 'auto_increment' => false, 'comment' => null],
['name' => 'id', 'type_name' => 'integer', 'type' => 'integer', 'collation' => null, 'nullable' => false, 'default' => '', 'auto_increment' => true, 'comment' => null, 'generation' => null],
['name' => 'name', 'type_name' => 'varchar', 'type' => 'varchar', 'collation' => null, 'nullable' => true, 'default' => 'foo', 'auto_increment' => false, 'comment' => null, 'generation' => null],
['name' => 'is_active', 'type_name' => 'tinyint', 'type' => 'tinyint(1)', 'collation' => null, 'nullable' => false, 'default' => '1', 'auto_increment' => false, 'comment' => null, 'generation' => null],
];

$this->assertEquals($expected, $processor->processColumns($listing));
Expand Down
6 changes: 6 additions & 0 deletions tests/Database/DatabaseSchemaBlueprintTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ public function testNativeRenameColumnOnMysql57()
$blueprint = new Blueprint('users', function ($table) {
$table->renameColumn('name', 'title');
$table->renameColumn('id', 'key');
$table->renameColumn('generated', 'new_generated');
});

$connection = m::mock(Connection::class);
Expand All @@ -197,11 +198,13 @@ public function testNativeRenameColumnOnMysql57()
$connection->shouldReceive('getSchemaBuilder->getColumns')->andReturn([
['name' => 'name', 'type' => 'varchar(255)', 'type_name' => 'varchar', 'nullable' => true, 'collation' => 'utf8mb4_unicode_ci', 'default' => 'foo', 'comment' => null, 'auto_increment' => false],
['name' => 'id', 'type' => 'bigint unsigned', 'type_name' => 'bigint', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => 'lorem ipsum', 'auto_increment' => true],
['name' => 'generated', 'type' => 'int', 'type_name' => 'int', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => null, 'auto_increment' => false, 'generation' => ['type' => 'stored', 'expression' => 'expression']],
]);

$this->assertEquals([
"alter table `users` change `name` `title` varchar(255) collate 'utf8mb4_unicode_ci' null default 'foo'",
"alter table `users` change `id` `key` bigint unsigned not null auto_increment comment 'lorem ipsum'",
'alter table `users` change `generated` `new_generated` int as (expression) stored not null',
], $blueprint->toSql($connection, new MySqlGrammar));
}

Expand All @@ -210,6 +213,7 @@ public function testNativeRenameColumnOnLegacyMariaDB()
$blueprint = new Blueprint('users', function ($table) {
$table->renameColumn('name', 'title');
$table->renameColumn('id', 'key');
$table->renameColumn('generated', 'new_generated');
});

$connection = m::mock(Connection::class);
Expand All @@ -218,11 +222,13 @@ public function testNativeRenameColumnOnLegacyMariaDB()
$connection->shouldReceive('getSchemaBuilder->getColumns')->andReturn([
['name' => 'name', 'type' => 'varchar(255)', 'type_name' => 'varchar', 'nullable' => true, 'collation' => 'utf8mb4_unicode_ci', 'default' => 'foo', 'comment' => null, 'auto_increment' => false],
['name' => 'id', 'type' => 'bigint unsigned', 'type_name' => 'bigint', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => 'lorem ipsum', 'auto_increment' => true],
['name' => 'generated', 'type' => 'int', 'type_name' => 'int', 'nullable' => false, 'collation' => null, 'default' => null, 'comment' => null, 'auto_increment' => false, 'generation' => ['type' => 'stored', 'expression' => 'expression']],
]);

$this->assertEquals([
"alter table `users` change `name` `title` varchar(255) collate 'utf8mb4_unicode_ci' null default 'foo'",
"alter table `users` change `id` `key` bigint unsigned not null auto_increment comment 'lorem ipsum'",
'alter table `users` change `generated` `new_generated` int as (expression) stored not null',
], $blueprint->toSql($connection, new MySqlGrammar));
}

Expand Down
Loading