Repository: laravel/framework (php)

Issue:
db/model:show throw when using PostgreSQL's citext type
- Laravel Version: 9.31
- PHP Version: 8.1.7
- Database Driver & Version: PostgreSQL 14.4

### Description:

The following exception is thrown while using the brand new `db:show` / `model:show` commands:

```shell
Unknown database type citext requested, Doctrine\DBAL\Platforms\PostgreSQL100Platform may not support it.
```

This is due to the `email` field in my database being of the custom `citext` type.

### Steps To Reproduce:

```shell
php artisan db:show
```

Pull request:
[9.x] Add missing citext type mapping
Closes #44236.

Patch:
diff --git a/src/Illuminate/Database/Console/DatabaseInspectionCommand.php b/src/Illuminate/Database/Console/DatabaseInspectionCommand.php
index 4fc20b1749..80a59adeac 100644
--- a/src/Illuminate/Database/Console/DatabaseInspectionCommand.php
+++ b/src/Illuminate/Database/Console/DatabaseInspectionCommand.php
@@ -24,6 +24,7 @@ abstract class DatabaseInspectionCommand extends Command
      */
     protected $typeMappings = [
         'bit' => 'string',
+        'citext' => 'string',
         'enum' => 'string',
         'geometry' => 'string',
         'geomcollection' => 'string',
diff --git a/src/Illuminate/Queue/Middleware/WithoutOverlapping.php b/src/Illuminate/Queue/Middleware/WithoutOverlapping.php
index fe25c70db8..2a37c3bd95 100644
--- a/src/Illuminate/Queue/Middleware/WithoutOverlapping.php
+++ b/src/Illuminate/Queue/Middleware/WithoutOverlapping.php
@@ -38,6 +38,13 @@ class WithoutOverlapping
      */
     public $prefix = 'laravel-queue-overlap:';
 
+    /**
+     * Share the key across different jobs.
+     *
+     * @var bool
+     */
+    public $shareKey = false;
+
     /**
      * Create a new middleware instance.
      *
@@ -128,6 +135,18 @@ public function withPrefix(string $prefix)
         return $this;
     }
 
+    /**
+     * Indicate that the lock key should be shared across job classes.
+     *
+     * @return void
+     */
+    public function shared()
+    {
+        $this->shareKey = true;
+
+        return $this;
+    }
+
     /**
      * Get the lock key for the given job.
      *
@@ -136,6 +155,8 @@ public function withPrefix(string $prefix)
      */
     public function getLockKey($job)
     {
-        return $this->prefix.get_class($job).':'.$this->key;
+        return $this->shareKey
+            ? $this->prefix.$this->key
+            : $this->prefix.get_class($job).':'.$this->key;
     }
 }


Test patch:
diff --git a/tests/Integration/Queue/WithoutOverlappingJobsTest.php b/tests/Integration/Queue/WithoutOverlappingJobsTest.php
index 1dded8c118..049792f750 100644
--- a/tests/Integration/Queue/WithoutOverlappingJobsTest.php
+++ b/tests/Integration/Queue/WithoutOverlappingJobsTest.php
@@ -112,6 +112,53 @@ public function testOverlappingJobsCanBeSkipped()
 
         $this->assertFalse(SkipOverlappingTestJob::$handled);
     }
+
+    public function testCanShareKeyAcrossJobs()
+    {
+        OverlappingTestJobWithSharedKeyOne::$handled = false;
+        $instance = new CallQueuedHandler(new Dispatcher($this->app), $this->app);
+
+        $lockKey = (new WithoutOverlapping)->shared()->getLockKey(new OverlappingTestJobWithSharedKeyTwo);
+        $this->app->get(Cache::class)->lock($lockKey, 10)->acquire();
+
+        $job = m::mock(Job::class);
+
+        $job->shouldReceive('release')->once();
+        $job->shouldReceive('hasFailed')->andReturn(false);
+        $job->shouldReceive('isReleased')->andReturn(true);
+        $job->shouldReceive('isDeletedOrReleased')->andReturn(true);
+
+        $instance->call($job, [
+            'command' => serialize(new OverlappingTestJobWithSharedKeyOne),
+        ]);
+
+        $this->assertFalse(OverlappingTestJob::$handled);
+    }
+
+    public function testGetLock()
+    {
+        $job = new OverlappingTestJob;
+
+        $this->assertSame(
+            'laravel-queue-overlap:Illuminate\\Tests\\Integration\\Queue\\OverlappingTestJob:key',
+            (new WithoutOverlapping('key'))->getLockKey($job)
+        );
+
+        $this->assertSame(
+            'laravel-queue-overlap:key',
+            (new WithoutOverlapping('key'))->shared()->getLockKey($job)
+        );
+
+        $this->assertSame(
+            'prefix:Illuminate\\Tests\\Integration\\Queue\\OverlappingTestJob:key',
+            (new WithoutOverlapping('key'))->withPrefix('prefix:')->getLockKey($job)
+        );
+
+        $this->assertSame(
+            'prefix:key',
+            (new WithoutOverlapping('key'))->withPrefix('prefix:')->shared()->getLockKey($job)
+        );
+    }
 }
 
 class OverlappingTestJob
@@ -148,3 +195,37 @@ public function handle()
         throw new Exception;
     }
 }
+
+class OverlappingTestJobWithSharedKeyOne
+{
+    use InteractsWithQueue, Queueable;
+
+    public static $handled = false;
+
+    public function handle()
+    {
+        static::$handled = true;
+    }
+
+    public function middleware()
+    {
+        return [(new WithoutOverlapping)->shared()];
+    }
+}
+
+class OverlappingTestJobWithSharedKeyTwo
+{
+    use InteractsWithQueue, Queueable;
+
+    public static $handled = false;
+
+    public function handle()
+    {
+        static::$handled = true;
+    }
+
+    public function middleware()
+    {
+        return [(new WithoutOverlapping)->shared()];
+    }
+}