Skip to content

[10.x] WIP #48352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
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
17 changes: 14 additions & 3 deletions src/Illuminate/Database/Query/Processors/MySqlProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,26 @@
class MySqlProcessor extends Processor
{
/**
* Process the results of a column listing query.
* Process the results of columns query.
*
* @param array $results
* @return array
*/
public function processColumnListing($results)
public function processColumns($results)
Copy link
Member

Choose a reason for hiding this comment

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

Changing the behavior of the processColumnListing method on each of these grammars is a breaking change unfortunately. Can we move this to master for Laravel v11?

Copy link
Contributor Author

@hafezdivandari hafezdivandari Sep 11, 2023

Choose a reason for hiding this comment

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

@driesvints We can keep them without change if you think it's breaking. I'll push a commit. would you please reopen this and make it draft?

{
return array_map(function ($result) {
return ((object) $result)->column_name;
$result = (object) $result;

return [
'name' => $result->name,
'type_name' => $result->type_name,
'type' => $result->type,
'collation' => $result->collation,
'nullable' => $result->nullable === 'YES',
'default' => $result->default,
'auto_increment' => $result->extra === 'auto_increment',
'comment' => $result->comment,
];
}, $results);
}
}
19 changes: 16 additions & 3 deletions src/Illuminate/Database/Query/Processors/PostgresProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,28 @@ public function processInsertGetId(Builder $query, $sql, $values, $sequence = nu
}

/**
* Process the results of a column listing query.
* Process the results of columns query.
*
* @param array $results
* @return array
*/
public function processColumnListing($results)
public function processColumns($results)
{
return array_map(function ($result) {
return ((object) $result)->column_name;
$result = (object) $result;

$autoincrement = $result->default !== null && str_starts_with($result->default, 'nextval(');

return [
'name' => $result->name,
'type_name' => $result->type_name,
'type' => $result->type,
'collation' => $result->collation,
'nullable' => (bool) $result->nullable,
'default' => $autoincrement ? null : $result->default,
'auto_increment' => $autoincrement,
'comment' => $result->comment,
];
}, $results);
}
}
13 changes: 13 additions & 0 deletions src/Illuminate/Database/Query/Processors/Processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,24 @@ public function processInsertGetId(Builder $query, $sql, $values, $sequence = nu
/**
* Process the results of a column listing query.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param array $results
* @return array
*/
public function processColumnListing($results)
{
return $results;
}

/**
* Process the results of columns query.
*
* @param array $results
* @return array
*/
public function processColumns($results)
{
return $results;
}
}
23 changes: 19 additions & 4 deletions src/Illuminate/Database/Query/Processors/SQLiteProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,30 @@
class SQLiteProcessor extends Processor
{
/**
* Process the results of a column listing query.
* Process the results of columns listing query.
*
* @param array $results
* @return array
*/
public function processColumnListing($results)
public function processColumns($results)
{
return array_map(function ($result) {
return ((object) $result)->name;
$hasPrimaryKey = array_sum(array_column($results, 'pk')) === 1;

return array_map(function ($result) use ($hasPrimaryKey) {
$result = (object) $result;

$type = strtolower($result->type);

return [
'name' => $result->name,
'type_name' => strtok($type, '('),
'type' => $type,
'collation' => null,
'nullable' => ! $result->notnull,
'default' => $result->dflt_value,
'auto_increment' => $hasPrimaryKey && $result->pk && $type === 'integer',
'comment' => null,
];
}, $results);
}
}
24 changes: 21 additions & 3 deletions src/Illuminate/Database/Query/Processors/SqlServerProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,33 @@ protected function processInsertGetIdForOdbc(Connection $connection)
}

/**
* Process the results of a column listing query.
* Process the results of columns query.
*
* @param array $results
* @return array
*/
public function processColumnListing($results)
public function processColumns($results)
{
return array_map(function ($result) {
return ((object) $result)->name;
$result = (object) $result;

$type = match ($typeName = $result->type_name) {
'binary', 'varbinary', 'char', 'varchar', 'nchar', 'nvarchar' => $result->length == -1 ? $typeName.'(max)' : $typeName."($result->length)",
'decimal', 'numeric' => $typeName."($result->precision,$result->places)",
'float', 'datetime2', 'datetimeoffset', 'time' => $typeName."($result->precision)",
default => $typeName,
};

return [
'name' => $result->name,
'type_name' => $result->type_name,
'type' => $type,
'collation' => $result->collation,
'nullable' => (bool) $result->nullable,
'default' => $result->default,
'auto_increment' => (bool) $result->autoincrement,
'comment' => $result->comment,
];
}, $results);
}
}
36 changes: 30 additions & 6 deletions src/Illuminate/Database/Schema/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,26 @@ public function whenTableDoesntHaveColumn(string $table, string $column, Closure
*
* @param string $table
* @param string $column
* @param bool $fullDefinition
* @return string
*/
public function getColumnType($table, $column)
public function getColumnType($table, $column, $fullDefinition = false)
{
$table = $this->connection->getTablePrefix().$table;

return $this->connection->getDoctrineColumn($table, $column)->getType()->getName();
if (! $this->connection->usingNativeSchemaOperations()) {
return $this->connection->getDoctrineColumn($table, $column)->getType()->getName();
}

$columns = $this->getColumns($table);

foreach ($columns as $value) {
if (strtolower($value['name']) === $column) {
return $fullDefinition ? $value['type'] : $value['type_name'];
}
}

throw new InvalidArgumentException("There is no column with name '$column' on table '$table'.");
}

/**
Expand All @@ -250,11 +263,22 @@ public function getColumnType($table, $column)
*/
public function getColumnListing($table)
{
$results = $this->connection->selectFromWriteConnection($this->grammar->compileColumnListing(
$this->connection->getTablePrefix().$table
));
return array_column($this->getColumns($table), 'name');
}

/**
* Get the columns for a given table.
*
* @param string $table
* @return array
*/
public function getColumns($table)
{
$table = $this->connection->getTablePrefix().$table;

$results = $this->connection->selectFromWriteConnection($this->grammar->compileColumns($table));

return $this->connection->getPostProcessor()->processColumnListing($results);
return $this->connection->getPostProcessor()->processColumns($results);
}

/**
Expand Down
22 changes: 22 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,35 @@ public function compileTableExists()
/**
* Compile the query to determine the list of columns.
*
* @deprecated Will be removed in a future Laravel version.
*
* @return string
*/
public function compileColumnListing()
{
return 'select column_name as `column_name` from information_schema.columns where table_schema = ? and table_name = ?';
}

/**
* Compile the query to determine the columns.
*
* @param string $database
* @param string $table
* @return string
*/
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` '
.'from information_schema.columns where table_schema = %s and table_name = %s '
.'order by ordinal_position asc',
$this->quoteString($database),
$this->quoteString($table)
);
}

/**
* Compile a create table command.
*
Expand Down
26 changes: 26 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,39 @@ public function compileTableExists()
/**
* Compile the query to determine the list of columns.
*
* @deprecated Will be removed in a future Laravel version.
*
* @return string
*/
public function compileColumnListing()
{
return 'select column_name from information_schema.columns where table_catalog = ? and table_schema = ? and table_name = ?';
}

/**
* Compile the query to determine the columns.
*
* @param string $database
* @param string $schema
* @param string $table
* @return string
*/
public function compileColumns($database, $schema, $table)
{
return sprintf(
'select quote_ident(a.attname) as name, t.typname as type_name, format_type(a.atttypid, a.atttypmod) as type, '
.'(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, '
.'(select pg_description.description from pg_description where pg_description.objoid = c.oid and a.attnum = pg_description.objsubid) 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 '
.'order by a.attnum',
$this->quoteString($table),
$this->quoteString($schema)
);
}

/**
* Compile a create table command.
*
Expand Down
13 changes: 13 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SQLiteGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,23 @@ public function compileTableExists()
/**
* Compile the query to determine the list of columns.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param string $table
* @return string
*/
public function compileColumnListing($table)
{
return $this->compileColumns($table);
}

/**
* Compile the query to determine the columns.
*
* @param string $table
* @return string
*/
public function compileColumns($table)
{
return 'pragma table_info('.$this->wrap(str_replace('.', '__', $table)).')';
}
Expand Down
27 changes: 27 additions & 0 deletions src/Illuminate/Database/Schema/Grammars/SqlServerGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ public function compileTableExists()
/**
* Compile the query to determine the list of columns.
*
* @deprecated Will be removed in a future Laravel version.
*
* @param string $table
* @return string
*/
Expand All @@ -87,6 +89,31 @@ public function compileColumnListing($table)
return "select name from sys.columns where object_id = object_id('$table')";
}

/**
* Compile the query to determine the columns.
*
* @param string $table
* @return string
*/
public function compileColumns($table)
{
return sprintf(
'select col.name, type.name as type_name, '
.'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, '
.'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' "
."where obj.type = 'U' and obj.name = %s and scm.name = SCHEMA_NAME()",
$this->quoteString($table),
);
}

/**
* Compile a create table command.
*
Expand Down
8 changes: 4 additions & 4 deletions src/Illuminate/Database/Schema/MySqlBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,20 @@ public function hasTable($table)
}

/**
* Get the column listing for a given table.
* Get the columns for a given table.
*
* @param string $table
* @return array
*/
public function getColumnListing($table)
public function getColumns($table)
{
$table = $this->connection->getTablePrefix().$table;

$results = $this->connection->selectFromWriteConnection(
$this->grammar->compileColumnListing(), [$this->connection->getDatabaseName(), $table]
$this->grammar->compileColumns($this->connection->getDatabaseName(), $table)
);

return $this->connection->getPostProcessor()->processColumnListing($results);
return $this->connection->getPostProcessor()->processColumns($results);
}

/**
Expand Down
Loading