@@ -116,11 +116,11 @@ public function setResult(
116116 $ qb ->setParameter ("cursor_ $ fieldName " , $ fieldValue )); // prevent overwriting existing param
117117 });
118118 [
119- 'unionOfQueriesSQL ' => $ unionOfQueriesSQL ,
119+ 'rawSQL ' => $ rawSQL ,
120120 'postsKeyByTypePluralName ' => $ postsKeyByTypePluralName ,
121121 'hasMorePages ' => $ hasMorePages ,
122122 'queryPlan ' => $ queryPlan
123- ] = $ this ->getUnionQueryResult ($ queries , $ isOrderByDesc , $ maxResults );
123+ ] = $ this ->getPostQueriesResult ($ queries , $ isOrderByDesc , $ maxResults );
124124
125125 $ this ->threads = $ postsKeyByTypePluralName ->get ('threads ' , collect ());
126126 $ this ->replies = $ postsKeyByTypePluralName ->get ('replies ' , collect ());
@@ -134,7 +134,7 @@ public function setResult(
134134 $ queryByPostIDParamsName ->map (static fn (string $ postID ) => Helper::POST_ID_TO_TYPE_PLURAL [$ postID ])
135135 ))
136136 : null ;
137- $ this ->query = ['query ' => $ unionOfQueriesSQL , 'plan ' => $ queryPlan ];
137+ $ this ->query = ['query ' => $ rawSQL , 'plan ' => $ queryPlan ];
138138
139139 $ this ->stopwatch ->stop ('setResult ' );
140140 }
@@ -151,41 +151,51 @@ public function setResult(
151151 * @param Collection<Helpecr::POST_TYPE, QueryBuilder> $queries
152152 * @param bool $isOrderByDesc
153153 * @param int $maxResults
154- * @return array{unionOfQueriesSQL : string, postsKeyByTypePluralName: PostsKeyByTypePluralName, hasMorePages: bool, queryPlan: array}
154+ * @return array{rawSQL : string, postsKeyByTypePluralName: PostsKeyByTypePluralName, hasMorePages: bool, queryPlan: array}
155155 */
156- private function getUnionQueryResult (Collection $ queries , bool $ isOrderByDesc , int $ maxResults ): array
156+ private function getPostQueriesResult (Collection $ queries , bool $ isOrderByDesc , int $ maxResults ): array
157157 {
158- /** @var DBALQueryBuilder $unionOfQueries */
159- // https://stackoverflow.com/questions/36959801/doctrine-orm-querybuilder-or-dbal-querybuilder
160- $ unionOfQueries = $ queries ->reduce (function (?DBALQueryBuilder $ dbalQueryBuilder , QueryBuilder $ ormQueryBuilder ) {
161- $ ormQuery = $ ormQueryBuilder ->getQuery ();
162- $ ormQuery ->setHint (\Doctrine \ORM \Query::HINT_CUSTOM_OUTPUT_WALKER , InterpolateParametersSQLOutputWalker::class);
163- $ sql = $ ormQuery ->getSQL ();
164- if ($ dbalQueryBuilder === null ) {
165- return $ ormQueryBuilder ->getEntityManager ()->getConnection ()
166- ->createQueryBuilder ()->union ($ sql );
167- }
168- return $ dbalQueryBuilder ->addUnion ($ sql , UnionType::ALL );
169- });
158+ $ getParametersInterpolatedRawSQL = static function (QueryBuilder $ queryBuilder ) {
159+ $ query = $ queryBuilder ->getQuery ();
160+ $ query ->setHint (\Doctrine \ORM \Query::HINT_CUSTOM_OUTPUT_WALKER , InterpolateParametersSQLOutputWalker::class);
161+ return $ query ->getSQL ();
162+ };
170163 $ firstQuery = $ queries ->first ();
164+ /** @var DBALQueryBuilder|QueryBuilder $flattedQueryBuilder */
165+ $ flattedQueryBuilder = $ queries ->count () === 1
166+ ? $ firstQuery
167+ // https://stackoverflow.com/questions/36959801/doctrine-orm-querybuilder-or-dbal-querybuilder
168+ : $ queries ->reduce (function (?DBALQueryBuilder $ dbalQueryBuilder , QueryBuilder $ ormQueryBuilder ) use ($ getParametersInterpolatedRawSQL ) {
169+ $ sql = $ getParametersInterpolatedRawSQL ($ ormQueryBuilder );
170+ if ($ dbalQueryBuilder === null ) {
171+ return $ ormQueryBuilder ->getEntityManager ()->getConnection ()
172+ ->createQueryBuilder ()->union ($ sql );
173+ }
174+ return $ dbalQueryBuilder ->addUnion ($ sql , UnionType::ALL );
175+ });
171176
172177 /** @var array{key-of<UnionPostKey>, string} $firstQueryFieldAliases */
173178 // field name and aliases in the first query in a union will override any other queries in union
174179 $ firstQueryFieldAliases = array_flip ((new Parser ($ firstQuery ->getQuery ()))
175180 ->parse ()->getResultSetMapping ()->scalarMappings );
176- $ unionOfQueries = $ unionOfQueries
177- ->addOrderBy ($ firstQueryFieldAliases ['orderByField ' ], $ isOrderByDesc === true ? 'DESC ' : 'ASC ' )
178- ->addOrderBy ($ firstQueryFieldAliases ['postId ' ])
179- ->setMaxResults ($ maxResults );
180- $ unionOfQueriesSQL = (new SqlFormatter (new NullHighlighter ()))->format ($ unionOfQueries ->getSQL ());
181+ if ($ flattedQueryBuilder instanceof DBALQueryBuilder) {
182+ $ flattedQueryBuilder = $ flattedQueryBuilder
183+ ->addOrderBy ($ firstQueryFieldAliases ['orderByField ' ], $ isOrderByDesc === true ? 'DESC ' : 'ASC ' )
184+ ->addOrderBy ($ firstQueryFieldAliases ['postId ' ])
185+ ->setMaxResults ($ maxResults );
186+ }
187+ $ rawSQL = (new SqlFormatter (new NullHighlighter ()))->format (match (true ) {
188+ $ flattedQueryBuilder instanceof DBALQueryBuilder => $ flattedQueryBuilder ->getSQL (),
189+ $ flattedQueryBuilder instanceof QueryBuilder => $ getParametersInterpolatedRawSQL ($ flattedQueryBuilder )
190+ });
181191
182192 $ rsm = new ResultSetMapping ();
183193 foreach ($ firstQueryFieldAliases as $ fieldName => $ fieldAlias ) {
184194 $ rsm ->addScalarResult ($ fieldAlias , $ fieldName );
185195 }
186196
187197 ['result ' => $ result , 'hasMorePages ' => $ hasMorePages , 'queryPlan ' => $ queryPlan ] = $ this ->getQueryResult (
188- $ firstQuery ->getEntityManager ()->createNativeQuery ($ unionOfQueriesSQL , $ rsm ),
198+ $ firstQuery ->getEntityManager ()->createNativeQuery ($ rawSQL , $ rsm ),
189199 $ this ->perPageItems
190200 );
191201 /** @var PostsKeyByTypePluralName $postsKeyByTypePluralName */
@@ -211,7 +221,7 @@ private function getUnionQueryResult(Collection $queries, bool $isOrderByDesc, i
211221 Helper::abortAPIIf (40401 , $ postsKeyByTypePluralName ->every (static fn (Collection $ i ) => $ i ->isEmpty ()));
212222
213223 return [
214- 'unionOfQueriesSQL ' => $ unionOfQueriesSQL ,
224+ 'rawSQL ' => $ rawSQL ,
215225 'postsKeyByTypePluralName ' => $ postsKeyByTypePluralName ,
216226 'hasMorePages ' => $ hasMorePages ,
217227 'queryPlan ' => $ queryPlan
0 commit comments