Skip to content

Commit 01ae14f

Browse files
authored
Fixed bug that gen:model cannot work when using pgsql. (#7400)
1 parent ca3df7a commit 01ae14f

File tree

3 files changed

+109
-3
lines changed

3 files changed

+109
-3
lines changed

src/Schema/Grammars/PostgresGrammar.php

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class PostgresGrammar extends Grammar
4747
*
4848
* @var string[]
4949
*/
50-
protected array $fluentCommands = ['Comment'];
50+
protected array $fluentCommands = ['Comment', 'TableComment'];
5151

5252
/**
5353
* Compile a create database command.
@@ -109,7 +109,46 @@ public function compileTableExists(): string
109109
*/
110110
public function compileColumnListing(): string
111111
{
112-
return 'select column_name as column_name, data_type as data_type from information_schema.columns where table_catalog = ? and table_schema = ? and table_name = ?';
112+
return <<<'SQL'
113+
SELECT
114+
a.attname AS column_name,
115+
CASE
116+
WHEN format_type(a.atttypid, a.atttypmod) LIKE 'numeric%' THEN
117+
regexp_replace(format_type(a.atttypid, a.atttypmod), '^numeric', 'decimal')
118+
WHEN format_type(a.atttypid, a.atttypmod) LIKE 'timestamp%' THEN 'datetime'
119+
WHEN format_type(a.atttypid, a.atttypmod) = 'integer' THEN 'int'
120+
WHEN format_type(a.atttypid, a.atttypmod) = 'real' THEN 'float'
121+
WHEN format_type(a.atttypid, a.atttypmod) = 'double precision' THEN 'double'
122+
ELSE format_type(a.atttypid, a.atttypmod)
123+
END AS data_type,
124+
col_description(a.attrelid, a.attnum) AS column_comment,
125+
CASE
126+
WHEN i.indisprimary THEN 'PRI'
127+
WHEN i.indisunique THEN 'UNI'
128+
ELSE NULL
129+
END AS column_key,
130+
CASE
131+
-- Detect SERIAL type (via default value using nextval)
132+
WHEN d.adbin IS NOT NULL AND pg_get_expr(d.adbin, d.adrelid) LIKE 'nextval(%' THEN 'auto_increment'
133+
-- Detect GENERATED AS IDENTITY (a = by default, d = always) pgsql10+
134+
WHEN a.attidentity IN ('a', 'd') THEN 'auto_increment'
135+
ELSE NULL
136+
END AS extra,
137+
CASE WHEN a.attnotnull THEN 'NO' ELSE 'YES' END AS is_nullable,
138+
pg_get_expr(d.adbin, d.adrelid) AS column_default
139+
FROM pg_attribute a
140+
JOIN pg_class c ON a.attrelid = c.oid
141+
JOIN pg_namespace n ON c.relnamespace = n.oid
142+
LEFT JOIN
143+
pg_index i ON i.indrelid = c.oid AND a.attnum = ANY(i.indkey)
144+
LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = a.attnum
145+
WHERE
146+
CAST(? AS text) IS NOT NULL AND -- ignore table_catalog
147+
n.nspname = ? AND
148+
c.relname = ? AND
149+
a.attnum > 0 AND NOT a.attisdropped
150+
ORDER BY a.attnum
151+
SQL;
113152
}
114153

115154
/**
@@ -499,6 +538,20 @@ public function compileComment(Blueprint $blueprint, Fluent $command)
499538
);
500539
}
501540

541+
/**
542+
* Compile a table comment command.
543+
*
544+
* @return string
545+
*/
546+
public function compileTableComment(Blueprint $blueprint, Fluent $command)
547+
{
548+
return sprintf(
549+
'comment on table %s is %s',
550+
$this->wrapTable($blueprint),
551+
"'" . str_replace("'", "''", $command->value) . "'"
552+
);
553+
}
554+
502555
/**
503556
* Create the column definition for a spatial MultiLineString type.
504557
*

src/Schema/Grammars/PostgresSqlSwooleExtGrammar.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,46 @@ public function compileTableExists(): string
2727
*/
2828
public function compileColumnListing(): string
2929
{
30-
return 'select column_name as column_name, data_type as data_type from information_schema.columns where table_catalog = $1 and table_schema = $2 and table_name = $3';
30+
return <<<'SQL'
31+
SELECT
32+
a.attname AS column_name,
33+
CASE
34+
WHEN format_type(a.atttypid, a.atttypmod) LIKE 'numeric%' THEN
35+
regexp_replace(format_type(a.atttypid, a.atttypmod), '^numeric', 'decimal')
36+
WHEN format_type(a.atttypid, a.atttypmod) LIKE 'timestamp%' THEN 'datetime'
37+
WHEN format_type(a.atttypid, a.atttypmod) = 'integer' THEN 'int'
38+
WHEN format_type(a.atttypid, a.atttypmod) = 'real' THEN 'float'
39+
WHEN format_type(a.atttypid, a.atttypmod) = 'double precision' THEN 'double'
40+
ELSE format_type(a.atttypid, a.atttypmod)
41+
END AS data_type,
42+
col_description(a.attrelid, a.attnum) AS column_comment,
43+
CASE
44+
WHEN i.indisprimary THEN 'PRI'
45+
WHEN i.indisunique THEN 'UNI'
46+
ELSE NULL
47+
END AS column_key,
48+
CASE
49+
-- Detect SERIAL type (via default value using nextval)
50+
WHEN d.adbin IS NOT NULL AND pg_get_expr(d.adbin, d.adrelid) LIKE 'nextval(%' THEN 'auto_increment'
51+
-- Detect GENERATED AS IDENTITY (a = by default, d = always) pgsql10+
52+
WHEN a.attidentity IN ('a', 'd') THEN 'auto_increment'
53+
ELSE NULL
54+
END AS extra,
55+
CASE WHEN a.attnotnull THEN 'NO' ELSE 'YES' END AS is_nullable,
56+
pg_get_expr(d.adbin, d.adrelid) AS column_default
57+
FROM pg_attribute a
58+
JOIN pg_class c ON a.attrelid = c.oid
59+
JOIN pg_namespace n ON c.relnamespace = n.oid
60+
LEFT JOIN
61+
pg_index i ON i.indrelid = c.oid AND a.attnum = ANY(i.indkey)
62+
LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = a.attnum
63+
WHERE
64+
CAST($1 AS text) IS NOT NULL AND -- ignore table_catalog
65+
n.nspname = $2 AND
66+
c.relname = $3 AND
67+
a.attnum > 0 AND NOT a.attisdropped
68+
ORDER BY a.attnum
69+
SQL;
3170
}
3271

3372
/**

tests/Cases/DatabasePostgresSchemaGrammarTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ public function testCreateTableAndCommentColumn()
7979
$this->assertSame('comment on column "users"."email" is \'my first comment\'', $statements[1]);
8080
}
8181

82+
public function testCreateTableWithTableComment()
83+
{
84+
$blueprint = new Blueprint('users');
85+
$blueprint->create();
86+
$blueprint->comment('This is a user table');
87+
$blueprint->increments('id');
88+
$blueprint->string('email');
89+
$statements = $blueprint->toSql($this->getConnection(), $this->getGrammar());
90+
91+
$this->assertCount(2, $statements);
92+
$this->assertSame('create table "users" ("id" serial primary key not null, "email" varchar(255) not null)', $statements[0]);
93+
$this->assertSame('comment on table "users" is \'This is a user table\'', $statements[1]);
94+
}
95+
8296
public function testCreateTemporaryTable()
8397
{
8498
$blueprint = new Blueprint('users');

0 commit comments

Comments
 (0)