diff --git src/wp-includes/post.php src/wp-includes/post.php
index 3b3d55f..771c95e 100644
--- src/wp-includes/post.php
+++ src/wp-includes/post.php
@@ -3703,7 +3703,7 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p
 		 * Page slugs must be unique within their own trees. Pages are in a separate
 		 * namespace than posts so page slugs are allowed to overlap post slugs.
 		 */
-		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type = %s AND ID != %d AND post_parent = %d LIMIT 1";
+		$check_sql = "SELECT post_name FROM $wpdb->posts WHERE post_name = %s AND post_type IN ( %s, 'attachment' ) AND ID != %d AND post_parent = %d LIMIT 1";
 		$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $slug, $post_type, $post_ID, $post_parent ) );
 
 		/**
@@ -3720,7 +3720,7 @@ function wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_p
 			$suffix = 2;
 			do {
 				$alt_post_name = _truncate_post_slug( $slug, 200 - ( strlen( $suffix ) + 1 ) ) . "-$suffix";
-				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID, $post_parent ) );	
+				$post_name_check = $wpdb->get_var( $wpdb->prepare( $check_sql, $alt_post_name, $post_type, $post_ID, $post_parent ) );
 				$suffix++;
 			} while ( $post_name_check );
 			$slug = $alt_post_name;
diff --git tests/phpunit/tests/post.php tests/phpunit/tests/post.php
index 2375458..1200b98 100644
--- tests/phpunit/tests/post.php
+++ tests/phpunit/tests/post.php
@@ -508,6 +508,12 @@ class Tests_Post extends WP_UnitTestCase {
 		$page       = $this->factory->post->create_and_get( array( 'post_title' => 'some-page', 'post_type' => 'page' ) );
 		$other_att  = $this->factory->post->create_and_get( array( 'post_title' => 'some-other-page', 'post_type' => 'attachment' ) );
 
+		global $wpdb;
+		$wpdb->update( $wpdb->posts, array( 'post_name' => 'some-page' ), array( 'ID' => $page->ID ) );
+		clean_post_cache( $page->ID );
+
+		$page = get_post( $page->ID );
+
 		$this->assertEquals( 'some-page', $attachment->post_name );
 		$this->assertEquals( 'some-page', $page->post_name );
 
@@ -988,6 +994,44 @@ class Tests_Post extends WP_UnitTestCase {
 	}
 
 	/**
+	 * @ticket 18962
+	 */
+	function test_wp_unique_post_slug_with_hierarchy_and_attachments() {
+		register_post_type( 'post-type-1', array( 'hierarchical' => true ) );
+
+		$args = array(
+			'post_type' => 'post-type-1',
+			'post_name' => 'some-slug',
+			'post_status' => 'publish',
+		);
+		$one = $this->factory->post->create( $args );
+
+		$args = array(
+			'post_mime_type' => 'image/jpeg',
+			'post_type' => 'attachment',
+			'post_name' => 'image'
+		);
+		$attachment = $this->factory->attachment->create_object( 'image.jpg', $one, $args );
+
+		$args = array(
+			'post_type' => 'post-type-1',
+			'post_name' => 'image',
+			'post_status' => 'publish',
+			'post_parent' => $one
+		);
+		$two = $this->factory->post->create( $args );
+
+		$this->assertEquals( 'some-slug', get_post( $one )->post_name );
+		$this->assertEquals( 'image', get_post( $attachment )->post_name );
+		$this->assertEquals( 'image-2', get_post( $two )->post_name );
+
+		// 'image' can be a child of image-2
+		$this->assertEquals( 'image', wp_unique_post_slug( 'image', 0, 'publish', 'post-type-1', $two ) );
+
+		_unregister_post_type( 'post-type-1' );
+	}
+
+	/**
 	 * @ticket 21212
 	 */
 	function test_utf8mb3_post_saves_with_emoji() {
