From c71228ac8316f198f2ded5bf7ece76c0f20eefc7 Mon Sep 17 00:00:00 2001 From: Hafez Divandari Date: Mon, 27 Nov 2023 23:25:21 +0330 Subject: [PATCH 1/3] fix inconsistent database parsing on PostgreSQL --- .../Schema/Grammars/PostgresGrammar.php | 5 +- .../Database/Schema/PostgresBuilder.php | 32 +++---- .../Database/DatabasePostgresBuilderTest.php | 90 ++++++++++--------- .../DatabasePostgresSchemaBuilderTest.php | 15 ++-- .../DatabasePostgresSchemaGrammarTest.php | 2 +- 5 files changed, 75 insertions(+), 69 deletions(-) diff --git a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php index 061984bdbaed..dc0d2ce5ea21 100755 --- a/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php +++ b/src/Illuminate/Database/Schema/Grammars/PostgresGrammar.php @@ -71,6 +71,8 @@ public function compileDropDatabaseIfExists($name) /** * Compile the query to determine if a table exists. * + * @deprecated Will be removed in a future Laravel version. + * * @return string */ public function compileTableExists() @@ -142,12 +144,11 @@ public function compileColumnListing() /** * Compile the query to determine the columns. * - * @param string $database * @param string $schema * @param string $table * @return string */ - public function compileColumns($database, $schema, $table) + public function compileColumns($schema, $table) { return sprintf( 'select quote_ident(a.attname) as name, t.typname as type_name, format_type(a.atttypid, a.atttypmod) as type, ' diff --git a/src/Illuminate/Database/Schema/PostgresBuilder.php b/src/Illuminate/Database/Schema/PostgresBuilder.php index 2074e3b17cbb..f4bffecf86fa 100755 --- a/src/Illuminate/Database/Schema/PostgresBuilder.php +++ b/src/Illuminate/Database/Schema/PostgresBuilder.php @@ -3,6 +3,7 @@ namespace Illuminate\Database\Schema; use Illuminate\Database\Concerns\ParsesSearchPath; +use InvalidArgumentException; class PostgresBuilder extends Builder { @@ -44,13 +45,18 @@ public function dropDatabaseIfExists($name) */ public function hasTable($table) { - [$database, $schema, $table] = $this->parseSchemaAndTable($table); + [$schema, $table] = $this->parseSchemaAndTable($table); $table = $this->connection->getTablePrefix().$table; - return count($this->connection->selectFromWriteConnection( - $this->grammar->compileTableExists(), [$database, $schema, $table] - )) > 0; + foreach ($this->getTables() as $value) { + if (strtolower($table) === strtolower($value['name']) + && strtolower($schema) === strtolower($value['schema'])) { + return true; + } + } + + return false; } /** @@ -192,12 +198,12 @@ public function dropAllTypes() */ public function getColumns($table) { - [$database, $schema, $table] = $this->parseSchemaAndTable($table); + [$schema, $table] = $this->parseSchemaAndTable($table); $table = $this->connection->getTablePrefix().$table; $results = $this->connection->selectFromWriteConnection( - $this->grammar->compileColumns($database, $schema, $table) + $this->grammar->compileColumns($schema, $table) ); return $this->connection->getPostProcessor()->processColumns($results); @@ -216,7 +222,7 @@ protected function getSchemas() } /** - * Parse the database object reference and extract the database, schema, and table. + * Parse the database object reference and extract the schema and table. * * @param string $reference * @return array @@ -225,14 +231,10 @@ protected function parseSchemaAndTable($reference) { $parts = explode('.', $reference); - $database = $this->connection->getConfig('database'); - - // If the reference contains a database name, we will use that instead of the - // default database name for the connection. This allows the database name - // to be specified in the query instead of at the full connection level. - if (count($parts) === 3) { + if (count($parts) > 2) { $database = $parts[0]; - array_shift($parts); + + throw new InvalidArgumentException("Using 3-parts reference is not supported, you may use `Schema::connection('$database')` instead."); } // We will use the default schema unless the schema has been specified in the @@ -245,7 +247,7 @@ protected function parseSchemaAndTable($reference) array_shift($parts); } - return [$database, $schema, $parts[0]]; + return [$schema, $parts[0]]; } /** diff --git a/tests/Database/DatabasePostgresBuilderTest.php b/tests/Database/DatabasePostgresBuilderTest.php index 4de2c649ebdd..d3a280239d3a 100644 --- a/tests/Database/DatabasePostgresBuilderTest.php +++ b/tests/Database/DatabasePostgresBuilderTest.php @@ -52,14 +52,17 @@ public function testHasTableWhenSchemaUnqualifiedAndSearchPathMissing() $connection->shouldReceive('getConfig')->with('search_path')->andReturn(null); $connection->shouldReceive('getConfig')->with('schema')->andReturn(null); $grammar = m::mock(PostgresGrammar::class); + $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileTableExists')->andReturn("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"); - $connection->shouldReceive('selectFromWriteConnection')->with("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'", ['laravel', 'public', 'foo'])->andReturn(['countable_result']); + $connection->shouldReceive('getPostProcessor')->andReturn($processor); + $grammar->shouldReceive('compileTables')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['schema' => 'public', 'name' => 'foo']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $builder = $this->getBuilder($connection); + $processor->shouldReceive('processTables')->andReturn([['schema' => 'public', 'name' => 'foo']]); - $builder->hasTable('foo'); + $this->assertTrue($builder->hasTable('foo')); + $this->assertTrue($builder->hasTable('public.foo')); } public function testHasTableWhenSchemaUnqualifiedAndSearchPathFilled() @@ -67,14 +70,17 @@ public function testHasTableWhenSchemaUnqualifiedAndSearchPathFilled() $connection = $this->getConnection(); $connection->shouldReceive('getConfig')->with('search_path')->andReturn('myapp,public'); $grammar = m::mock(PostgresGrammar::class); + $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileTableExists')->andReturn("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"); - $connection->shouldReceive('selectFromWriteConnection')->with("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'", ['laravel', 'myapp', 'foo'])->andReturn(['countable_result']); + $connection->shouldReceive('getPostProcessor')->andReturn($processor); + $grammar->shouldReceive('compileTables')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['schema' => 'myapp', 'name' => 'foo']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $builder = $this->getBuilder($connection); + $processor->shouldReceive('processTables')->andReturn([['schema' => 'myapp', 'name' => 'foo']]); - $builder->hasTable('foo'); + $this->assertTrue($builder->hasTable('foo')); + $this->assertTrue($builder->hasTable('myapp.foo')); } public function testHasTableWhenSchemaUnqualifiedAndSearchPathFallbackFilled() @@ -83,14 +89,17 @@ public function testHasTableWhenSchemaUnqualifiedAndSearchPathFallbackFilled() $connection->shouldReceive('getConfig')->with('search_path')->andReturn(null); $connection->shouldReceive('getConfig')->with('schema')->andReturn(['myapp', 'public']); $grammar = m::mock(PostgresGrammar::class); + $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileTableExists')->andReturn("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"); - $connection->shouldReceive('selectFromWriteConnection')->with("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'", ['laravel', 'myapp', 'foo'])->andReturn(['countable_result']); + $connection->shouldReceive('getPostProcessor')->andReturn($processor); + $grammar->shouldReceive('compileTables')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['schema' => 'myapp', 'name' => 'foo']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $builder = $this->getBuilder($connection); + $processor->shouldReceive('processTables')->andReturn([['schema' => 'myapp', 'name' => 'foo']]); - $builder->hasTable('foo'); + $this->assertTrue($builder->hasTable('foo')); + $this->assertTrue($builder->hasTable('myapp.foo')); } public function testHasTableWhenSchemaUnqualifiedAndSearchPathIsUserVariable() @@ -99,14 +108,17 @@ public function testHasTableWhenSchemaUnqualifiedAndSearchPathIsUserVariable() $connection->shouldReceive('getConfig')->with('username')->andReturn('foouser'); $connection->shouldReceive('getConfig')->with('search_path')->andReturn('$user'); $grammar = m::mock(PostgresGrammar::class); + $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileTableExists')->andReturn("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"); - $connection->shouldReceive('selectFromWriteConnection')->with("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'", ['laravel', 'foouser', 'foo'])->andReturn(['countable_result']); + $connection->shouldReceive('getPostProcessor')->andReturn($processor); + $grammar->shouldReceive('compileTables')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['schema' => 'foouser', 'name' => 'foo']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $builder = $this->getBuilder($connection); + $processor->shouldReceive('processTables')->andReturn([['schema' => 'foouser', 'name' => 'foo']]); - $builder->hasTable('foo'); + $this->assertTrue($builder->hasTable('foo')); + $this->assertTrue($builder->hasTable('foouser.foo')); } public function testHasTableWhenSchemaQualifiedAndSearchPathMismatches() @@ -114,26 +126,25 @@ public function testHasTableWhenSchemaQualifiedAndSearchPathMismatches() $connection = $this->getConnection(); $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public'); $grammar = m::mock(PostgresGrammar::class); + $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileTableExists')->andReturn("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"); - $connection->shouldReceive('selectFromWriteConnection')->with("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'", ['laravel', 'myapp', 'foo'])->andReturn(['countable_result']); + $connection->shouldReceive('getPostProcessor')->andReturn($processor); + $grammar->shouldReceive('compileTables')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['schema' => 'myapp', 'name' => 'foo']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $builder = $this->getBuilder($connection); + $processor->shouldReceive('processTables')->andReturn([['schema' => 'myapp', 'name' => 'foo']]); - $builder->hasTable('myapp.foo'); + $this->assertTrue($builder->hasTable('myapp.foo')); } public function testHasTableWhenDatabaseAndSchemaQualifiedAndSearchPathMismatches() { + $this->expectException(\InvalidArgumentException::class); + $connection = $this->getConnection(); - $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public'); $grammar = m::mock(PostgresGrammar::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileTableExists')->andReturn("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'"); - $connection->shouldReceive('selectFromWriteConnection')->with("select * from information_schema.tables where table_catalog = ? and table_schema = ? and table_name = ? and table_type = 'BASE TABLE'", ['mydatabase', 'myapp', 'foo'])->andReturn(['countable_result']); - $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $builder = $this->getBuilder($connection); $builder->hasTable('mydatabase.myapp.foo'); @@ -146,10 +157,9 @@ public function testGetColumnListingWhenSchemaUnqualifiedAndSearchPathMissing() $connection->shouldReceive('getConfig')->with('schema')->andReturn(null); $grammar = m::mock(PostgresGrammar::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileColumns')->with('laravel', 'public', 'foo')->andReturn('sql'); - $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn(['countable_result']); + $grammar->shouldReceive('compileColumns')->with('public', 'foo')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'some_column']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getPostProcessor')->andReturn($processor); $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]); @@ -164,10 +174,9 @@ public function testGetColumnListingWhenSchemaUnqualifiedAndSearchPathFilled() $connection->shouldReceive('getConfig')->with('search_path')->andReturn('myapp,public'); $grammar = m::mock(PostgresGrammar::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileColumns')->with('laravel', 'myapp', 'foo')->andReturn('sql'); - $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn(['countable_result']); + $grammar->shouldReceive('compileColumns')->with('myapp', 'foo')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'some_column']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getPostProcessor')->andReturn($processor); $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]); @@ -183,10 +192,9 @@ public function testGetColumnListingWhenSchemaUnqualifiedAndSearchPathIsUserVari $connection->shouldReceive('getConfig')->with('search_path')->andReturn('$user'); $grammar = m::mock(PostgresGrammar::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileColumns')->with('laravel', 'foouser', 'foo')->andReturn('sql'); - $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn(['countable_result']); + $grammar->shouldReceive('compileColumns')->with('foouser', 'foo')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'some_column']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getPostProcessor')->andReturn($processor); $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]); @@ -201,10 +209,9 @@ public function testGetColumnListingWhenSchemaQualifiedAndSearchPathMismatches() $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public'); $grammar = m::mock(PostgresGrammar::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileColumns')->with('laravel', 'myapp', 'foo')->andReturn('sql'); - $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn(['countable_result']); + $grammar->shouldReceive('compileColumns')->with('myapp', 'foo')->andReturn('sql'); + $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn([['name' => 'some_column']]); $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getPostProcessor')->andReturn($processor); $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]); @@ -215,17 +222,12 @@ public function testGetColumnListingWhenSchemaQualifiedAndSearchPathMismatches() public function testGetColumnWhenDatabaseAndSchemaQualifiedAndSearchPathMismatches() { + $this->expectException(\InvalidArgumentException::class); + $connection = $this->getConnection(); $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public'); $grammar = m::mock(PostgresGrammar::class); $connection->shouldReceive('getSchemaGrammar')->once()->andReturn($grammar); - $grammar->shouldReceive('compileColumns')->with('mydatabase', 'myapp', 'foo')->andReturn('sql'); - $connection->shouldReceive('selectFromWriteConnection')->with('sql')->andReturn(['countable_result']); - $connection->shouldReceive('getTablePrefix'); - $connection->shouldReceive('getConfig')->with('database')->andReturn('laravel'); - $processor = m::mock(PostgresProcessor::class); - $connection->shouldReceive('getPostProcessor')->andReturn($processor); - $processor->shouldReceive('processColumns')->andReturn([['name' => 'some_column']]); $builder = $this->getBuilder($connection); $builder->getColumnListing('mydatabase.myapp.foo'); diff --git a/tests/Database/DatabasePostgresSchemaBuilderTest.php b/tests/Database/DatabasePostgresSchemaBuilderTest.php index 448b41138a84..5794ce44aeea 100755 --- a/tests/Database/DatabasePostgresSchemaBuilderTest.php +++ b/tests/Database/DatabasePostgresSchemaBuilderTest.php @@ -20,17 +20,19 @@ public function testHasTable() { $connection = m::mock(Connection::class); $grammar = m::mock(PostgresGrammar::class); - $connection->shouldReceive('getDatabaseName')->andReturn('db'); + $processor = m::mock(PostgresProcessor::class); $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar); - $connection->shouldReceive('getConfig')->with('database')->andReturn('db'); + $connection->shouldReceive('getPostProcessor')->andReturn($processor); $connection->shouldReceive('getConfig')->with('schema')->andReturn('schema'); $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public'); $builder = new PostgresBuilder($connection); - $grammar->shouldReceive('compileTableExists')->once()->andReturn('sql'); - $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_'); - $connection->shouldReceive('selectFromWriteConnection')->once()->with('sql', ['db', 'public', 'prefix_table'])->andReturn(['prefix_table']); + $grammar->shouldReceive('compileTables')->twice()->andReturn('sql'); + $processor->shouldReceive('processTables')->twice()->andReturn([['schema' => 'public', 'name' => 'prefix_table']]); + $connection->shouldReceive('getTablePrefix')->twice()->andReturn('prefix_'); + $connection->shouldReceive('selectFromWriteConnection')->twice()->with('sql')->andReturn([['schema' => 'public', 'name' => 'prefix_table']]); $this->assertTrue($builder->hasTable('table')); + $this->assertTrue($builder->hasTable('public.table')); } public function testGetColumnListing() @@ -38,13 +40,12 @@ public function testGetColumnListing() $connection = m::mock(Connection::class); $grammar = m::mock(PostgresGrammar::class); $processor = m::mock(PostgresProcessor::class); - $connection->shouldReceive('getDatabaseName')->andReturn('db'); $connection->shouldReceive('getSchemaGrammar')->andReturn($grammar); $connection->shouldReceive('getPostProcessor')->andReturn($processor); $connection->shouldReceive('getConfig')->with('database')->andReturn('db'); $connection->shouldReceive('getConfig')->with('schema')->andReturn('schema'); $connection->shouldReceive('getConfig')->with('search_path')->andReturn('public'); - $grammar->shouldReceive('compileColumns')->with('db', 'public', 'prefix_table')->once()->andReturn('sql'); + $grammar->shouldReceive('compileColumns')->with('public', 'prefix_table')->once()->andReturn('sql'); $processor->shouldReceive('processColumns')->once()->andReturn([['name' => 'column']]); $builder = new PostgresBuilder($connection); $connection->shouldReceive('getTablePrefix')->once()->andReturn('prefix_'); diff --git a/tests/Database/DatabasePostgresSchemaGrammarTest.php b/tests/Database/DatabasePostgresSchemaGrammarTest.php index 9229c6effc8f..d90c2fb5c6f7 100755 --- a/tests/Database/DatabasePostgresSchemaGrammarTest.php +++ b/tests/Database/DatabasePostgresSchemaGrammarTest.php @@ -1203,7 +1203,7 @@ public function testCompileTableExists() public function testCompileColumns() { - $statement = $this->getGrammar()->compileColumns('db', 'public', 'table'); + $statement = $this->getGrammar()->compileColumns('public', 'table'); $this->assertStringContainsString("where c.relname = 'table' and n.nspname = 'public'", $statement); } From 58946d9735ff2910e7c04f7f500d58416fb5c8bb Mon Sep 17 00:00:00 2001 From: Hafez Divandari Date: Mon, 11 Dec 2023 15:56:48 +0330 Subject: [PATCH 2/3] fix on getIndexes --- src/Illuminate/Database/Schema/PostgresBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Schema/PostgresBuilder.php b/src/Illuminate/Database/Schema/PostgresBuilder.php index 0e6679ef9dd1..9314be37f88a 100755 --- a/src/Illuminate/Database/Schema/PostgresBuilder.php +++ b/src/Illuminate/Database/Schema/PostgresBuilder.php @@ -217,7 +217,7 @@ public function getColumns($table) */ public function getIndexes($table) { - [, $schema, $table] = $this->parseSchemaAndTable($table); + [$schema, $table] = $this->parseSchemaAndTable($table); $table = $this->connection->getTablePrefix().$table; From bb9406ed53a415c5878d050f2d396dfcc1e89f83 Mon Sep 17 00:00:00 2001 From: Hafez Divandari Date: Wed, 13 Dec 2023 16:51:50 +0330 Subject: [PATCH 3/3] fix on getForeignKeys --- src/Illuminate/Database/Schema/PostgresBuilder.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Illuminate/Database/Schema/PostgresBuilder.php b/src/Illuminate/Database/Schema/PostgresBuilder.php index 4393f3ad85aa..9cf829721ad2 100755 --- a/src/Illuminate/Database/Schema/PostgresBuilder.php +++ b/src/Illuminate/Database/Schema/PostgresBuilder.php @@ -255,7 +255,7 @@ public function getIndexes($table) */ public function getForeignKeys($table) { - [, $schema, $table] = $this->parseSchemaAndTable($table); + [$schema, $table] = $this->parseSchemaAndTable($table); $table = $this->connection->getTablePrefix().$table;