SelectSqlGenerationTest.php 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601
  1. <?php
  2. namespace Doctrine\Tests\ORM\Query;
  3. use Doctrine\DBAL\Types\Type as DBALType;
  4. use Doctrine\ORM\Query;
  5. require_once __DIR__ . '/../../TestInit.php';
  6. class SelectSqlGenerationTest extends \Doctrine\Tests\OrmTestCase
  7. {
  8. private $_em;
  9. protected function setUp()
  10. {
  11. $this->_em = $this->_getTestEntityManager();
  12. }
  13. /**
  14. * Assert a valid SQL generation.
  15. *
  16. * @param string $dqlToBeTested
  17. * @param string $sqlToBeConfirmed
  18. * @param array $queryHints
  19. * @param array $queryParams
  20. */
  21. public function assertSqlGeneration($dqlToBeTested, $sqlToBeConfirmed, array $queryHints = array(), array $queryParams = array())
  22. {
  23. try {
  24. $query = $this->_em->createQuery($dqlToBeTested);
  25. foreach ($queryParams AS $name => $value) {
  26. $query->setParameter($name, $value);
  27. }
  28. $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
  29. ->useQueryCache(false);
  30. foreach ($queryHints AS $name => $value) {
  31. $query->setHint($name, $value);
  32. }
  33. $sqlGenerated = $query->getSQL();
  34. parent::assertEquals(
  35. $sqlToBeConfirmed,
  36. $sqlGenerated,
  37. sprintf('"%s" is not equal of "%s"', $sqlGenerated, $sqlToBeConfirmed)
  38. );
  39. $query->free();
  40. } catch (\Exception $e) {
  41. $this->fail($e->getMessage() ."\n".$e->getTraceAsString());
  42. }
  43. }
  44. /**
  45. * Asser an invalid SQL generation.
  46. *
  47. * @param string $dqlToBeTested
  48. * @param string $expectedException
  49. * @param array $queryHints
  50. * @param array $queryParams
  51. */
  52. public function assertInvalidSqlGeneration($dqlToBeTested, $expectedException, array $queryHints = array(), array $queryParams = array())
  53. {
  54. $this->setExpectedException($expectedException);
  55. $query = $this->_em->createQuery($dqlToBeTested);
  56. foreach ($queryParams AS $name => $value) {
  57. $query->setParameter($name, $value);
  58. }
  59. $query->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true)
  60. ->useQueryCache(false);
  61. foreach ($queryHints AS $name => $value) {
  62. $query->setHint($name, $value);
  63. }
  64. $sql = $query->getSql();
  65. $query->free();
  66. // If we reached here, test failed
  67. $this->fail($sql);
  68. }
  69. public function testSupportsSelectForAllFields()
  70. {
  71. $this->assertSqlGeneration(
  72. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u',
  73. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_'
  74. );
  75. }
  76. public function testSupportsSelectForOneField()
  77. {
  78. $this->assertSqlGeneration(
  79. 'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u',
  80. 'SELECT c0_.id AS id0 FROM cms_users c0_'
  81. );
  82. }
  83. public function testSupportsSelectForOneNestedField()
  84. {
  85. $this->assertSqlGeneration(
  86. 'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u',
  87. 'SELECT c0_.id AS id0 FROM cms_articles c1_ INNER JOIN cms_users c0_ ON c1_.user_id = c0_.id'
  88. );
  89. }
  90. public function testSupportsSelectForAllNestedField()
  91. {
  92. $this->assertSqlGeneration(
  93. 'SELECT a FROM Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u ORDER BY u.name ASC',
  94. 'SELECT c0_.id AS id0, c0_.topic AS topic1, c0_.text AS text2, c0_.version AS version3 FROM cms_articles c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id ORDER BY c1_.name ASC'
  95. );
  96. }
  97. public function testSupportsSelectForMultipleColumnsOfASingleComponent()
  98. {
  99. $this->assertSqlGeneration(
  100. 'SELECT u.username, u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
  101. 'SELECT c0_.username AS username0, c0_.name AS name1 FROM cms_users c0_'
  102. );
  103. }
  104. public function testSupportsSelectUsingMultipleFromComponents()
  105. {
  106. $this->assertSqlGeneration(
  107. 'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE u = p.user',
  108. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.phonenumber AS phonenumber4 FROM cms_users c0_, cms_phonenumbers c1_ WHERE c0_.id = c1_.user_id'
  109. );
  110. }
  111. public function testSupportsSelectWithCollectionAssociationJoin()
  112. {
  113. $this->assertSqlGeneration(
  114. 'SELECT u, p FROM Doctrine\Tests\Models\CMS\CmsUser u JOIN u.phonenumbers p',
  115. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.phonenumber AS phonenumber4 FROM cms_users c0_ INNER JOIN cms_phonenumbers c1_ ON c0_.id = c1_.user_id'
  116. );
  117. }
  118. public function testSupportsSelectWithSingleValuedAssociationJoin()
  119. {
  120. $this->assertSqlGeneration(
  121. 'SELECT u, a FROM Doctrine\Tests\Models\Forum\ForumUser u JOIN u.avatar a',
  122. 'SELECT f0_.id AS id0, f0_.username AS username1, f1_.id AS id2 FROM forum_users f0_ INNER JOIN forum_avatars f1_ ON f0_.avatar_id = f1_.id'
  123. );
  124. }
  125. public function testSelectCorrelatedSubqueryComplexMathematicalExpression()
  126. {
  127. $this->assertSqlGeneration(
  128. 'SELECT (SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = u.id) AS c FROM Doctrine\Tests\Models\CMS\CmsUser u',
  129. 'SELECT (SELECT (count(c0_.phonenumber) + 5) * 10 AS sclr1 FROM cms_phonenumbers c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id WHERE c1_.id = c2_.id) AS sclr0 FROM cms_users c2_'
  130. );
  131. }
  132. public function testSelectComplexMathematicalExpression()
  133. {
  134. $this->assertSqlGeneration(
  135. 'SELECT (count(p.phonenumber)+5)*10 FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p JOIN p.user ui WHERE ui.id = ?1',
  136. 'SELECT (count(c0_.phonenumber) + 5) * 10 AS sclr0 FROM cms_phonenumbers c0_ INNER JOIN cms_users c1_ ON c0_.user_id = c1_.id WHERE c1_.id = ?'
  137. );
  138. }
  139. /* NOT (YET?) SUPPORTED.
  140. Can be supported if SimpleSelectExpresion supports SingleValuedPathExpression instead of StateFieldPathExpression.
  141. public function testSingleAssociationPathExpressionInSubselect()
  142. {
  143. $this->assertSqlGeneration(
  144. 'SELECT (SELECT p.user FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = u) user_id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1',
  145. 'SELECT (SELECT c0_.user_id FROM cms_phonenumbers c0_ WHERE c0_.user_id = c1_.id) AS sclr0 FROM cms_users c1_ WHERE c1_.id = ?'
  146. );
  147. }*/
  148. /**
  149. * @group DDC-1077
  150. */
  151. public function testConstantValueInSelect()
  152. {
  153. $this->assertSqlGeneration(
  154. "SELECT u.name, 'foo' AS bar FROM Doctrine\Tests\Models\CMS\CmsUser u",
  155. "SELECT c0_.name AS name0, 'foo' AS sclr1 FROM cms_users c0_"
  156. );
  157. }
  158. public function testSupportsOrderByWithAscAsDefault()
  159. {
  160. $this->assertSqlGeneration(
  161. 'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id',
  162. 'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ ORDER BY f0_.id ASC'
  163. );
  164. }
  165. public function testSupportsOrderByAsc()
  166. {
  167. $this->assertSqlGeneration(
  168. 'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id asc',
  169. 'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ ORDER BY f0_.id ASC'
  170. );
  171. }
  172. public function testSupportsOrderByDesc()
  173. {
  174. $this->assertSqlGeneration(
  175. 'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u ORDER BY u.id desc',
  176. 'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ ORDER BY f0_.id DESC'
  177. );
  178. }
  179. public function testSupportsSelectDistinct()
  180. {
  181. $this->assertSqlGeneration(
  182. 'SELECT DISTINCT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u',
  183. 'SELECT DISTINCT c0_.name AS name0 FROM cms_users c0_'
  184. );
  185. }
  186. public function testSupportsAggregateFunctionInSelectedFields()
  187. {
  188. $this->assertSqlGeneration(
  189. 'SELECT COUNT(u.id) FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u.id',
  190. 'SELECT COUNT(c0_.id) AS sclr0 FROM cms_users c0_ GROUP BY c0_.id'
  191. );
  192. }
  193. public function testSupportsAggregateFunctionWithSimpleArithmetic()
  194. {
  195. $this->assertSqlGeneration(
  196. 'SELECT MAX(u.id + 4) * 2 FROM Doctrine\Tests\Models\CMS\CmsUser u',
  197. 'SELECT MAX(c0_.id + 4) * 2 AS sclr0 FROM cms_users c0_'
  198. );
  199. }
  200. public function testSupportsWhereClauseWithPositionalParameter()
  201. {
  202. $this->assertSqlGeneration(
  203. 'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.id = ?1',
  204. 'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE f0_.id = ?'
  205. );
  206. }
  207. public function testSupportsWhereClauseWithNamedParameter()
  208. {
  209. $this->assertSqlGeneration(
  210. 'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name',
  211. 'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE f0_.username = ?'
  212. );
  213. }
  214. public function testSupportsWhereAndClauseWithNamedParameters()
  215. {
  216. $this->assertSqlGeneration(
  217. 'select u from Doctrine\Tests\Models\Forum\ForumUser u where u.username = :name and u.username = :name2',
  218. 'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE f0_.username = ? AND f0_.username = ?'
  219. );
  220. }
  221. public function testSupportsCombinedWhereClauseWithNamedParameter()
  222. {
  223. $this->assertSqlGeneration(
  224. 'select u from Doctrine\Tests\Models\Forum\ForumUser u where (u.username = :name OR u.username = :name2) AND u.id = :id',
  225. 'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE (f0_.username = ? OR f0_.username = ?) AND f0_.id = ?'
  226. );
  227. }
  228. public function testSupportsAggregateFunctionInASelectDistinct()
  229. {
  230. $this->assertSqlGeneration(
  231. 'SELECT COUNT(DISTINCT u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u',
  232. 'SELECT COUNT(DISTINCT c0_.name) AS sclr0 FROM cms_users c0_'
  233. );
  234. }
  235. // Ticket #668
  236. public function testSupportsASqlKeywordInAStringLiteralParam()
  237. {
  238. $this->assertSqlGeneration(
  239. "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name LIKE '%foo OR bar%'",
  240. "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE c0_.name LIKE '%foo OR bar%'"
  241. );
  242. }
  243. public function testSupportsArithmeticExpressionsInWherePart()
  244. {
  245. $this->assertSqlGeneration(
  246. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE ((u.id + 5000) * u.id + 3) < 10000000',
  247. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id + 5000) * c0_.id + 3 < 10000000'
  248. );
  249. }
  250. public function testSupportsMultipleEntitiesInFromClause()
  251. {
  252. $this->assertSqlGeneration(
  253. 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a JOIN a.user u2 WHERE u.id = u2.id',
  254. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.id AS id4, c1_.topic AS topic5, c1_.text AS text6, c1_.version AS version7 FROM cms_users c0_, cms_articles c1_ INNER JOIN cms_users c2_ ON c1_.user_id = c2_.id WHERE c0_.id = c2_.id'
  255. );
  256. }
  257. public function testSupportsMultipleEntitiesInFromClauseUsingPathExpression()
  258. {
  259. $this->assertSqlGeneration(
  260. 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u, Doctrine\Tests\Models\CMS\CmsArticle a WHERE u.id = a.user',
  261. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c1_.id AS id4, c1_.topic AS topic5, c1_.text AS text6, c1_.version AS version7 FROM cms_users c0_, cms_articles c1_ WHERE c0_.id = c1_.user_id'
  262. );
  263. }
  264. public function testSupportsPlainJoinWithoutClause()
  265. {
  266. $this->assertSqlGeneration(
  267. 'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a',
  268. 'SELECT c0_.id AS id0, c1_.id AS id1 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id'
  269. );
  270. $this->assertSqlGeneration(
  271. 'SELECT u.id, a.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a',
  272. 'SELECT c0_.id AS id0, c1_.id AS id1 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id'
  273. );
  274. }
  275. /**
  276. * @group DDC-135
  277. */
  278. public function testSupportsJoinAndWithClauseRestriction()
  279. {
  280. $this->assertSqlGeneration(
  281. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a WITH a.topic LIKE '%foo%'",
  282. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LEFT JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic LIKE '%foo%')"
  283. );
  284. $this->assertSqlGeneration(
  285. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a WITH a.topic LIKE '%foo%'",
  286. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id AND (c1_.topic LIKE '%foo%')"
  287. );
  288. }
  289. /**
  290. * @group DDC-135
  291. * @group DDC-177
  292. */
  293. public function testJoinOnClause_NotYetSupported_ThrowsException()
  294. {
  295. $this->setExpectedException('Doctrine\ORM\Query\QueryException');
  296. $sql = $this->_em->createQuery(
  297. "SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.articles a ON a.topic LIKE '%foo%'"
  298. )->getSql();
  299. }
  300. public function testSupportsMultipleJoins()
  301. {
  302. $this->assertSqlGeneration(
  303. 'SELECT u.id, a.id, p.phonenumber, c.id from Doctrine\Tests\Models\CMS\CmsUser u JOIN u.articles a JOIN u.phonenumbers p JOIN a.comments c',
  304. 'SELECT c0_.id AS id0, c1_.id AS id1, c2_.phonenumber AS phonenumber2, c3_.id AS id3 FROM cms_users c0_ INNER JOIN cms_articles c1_ ON c0_.id = c1_.user_id INNER JOIN cms_phonenumbers c2_ ON c0_.id = c2_.user_id INNER JOIN cms_comments c3_ ON c1_.id = c3_.article_id'
  305. );
  306. }
  307. public function testSupportsTrimFunction()
  308. {
  309. $this->assertSqlGeneration(
  310. "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(TRAILING ' ' FROM u.name) = 'someone'",
  311. "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE TRIM(TRAILING ' ' FROM c0_.name) = 'someone'"
  312. );
  313. }
  314. // Ticket 894
  315. public function testSupportsBetweenClauseWithPositionalParameters()
  316. {
  317. $this->assertSqlGeneration(
  318. "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id BETWEEN ?1 AND ?2",
  319. "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE c0_.id BETWEEN ? AND ?"
  320. );
  321. }
  322. public function testSupportsFunctionalExpressionsInWherePart()
  323. {
  324. $this->assertSqlGeneration(
  325. "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE TRIM(u.name) = 'someone'",
  326. // String quoting in the SQL usually depends on the database platform.
  327. // This test works with a mock connection which uses ' for string quoting.
  328. "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE TRIM(c0_.name) = 'someone'"
  329. );
  330. }
  331. public function testSupportsInstanceOfExpressionsInWherePart()
  332. {
  333. $this->assertSqlGeneration(
  334. "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyEmployee",
  335. "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')"
  336. );
  337. }
  338. public function testSupportsInstanceOfExpressionInWherePartWithMultipleValues()
  339. {
  340. $this->assertSqlGeneration(
  341. "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF (Doctrine\Tests\Models\Company\CompanyEmployee, \Doctrine\Tests\Models\Company\CompanyManager)",
  342. "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN ('employee', 'manager')"
  343. );
  344. }
  345. /**
  346. * @group DDC-1194
  347. */
  348. public function testSupportsInstanceOfExpressionsInWherePartPrefixedSlash()
  349. {
  350. $this->assertSqlGeneration(
  351. "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\Company\CompanyEmployee",
  352. "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')"
  353. );
  354. }
  355. /**
  356. * @group DDC-1194
  357. */
  358. public function testSupportsInstanceOfExpressionsInWherePartWithUnrelatedClass()
  359. {
  360. $this->assertInvalidSqlGeneration(
  361. "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF \Doctrine\Tests\Models\CMS\CmsUser",
  362. "Doctrine\ORM\Query\QueryException"
  363. );
  364. }
  365. public function testSupportsInstanceOfExpressionsInWherePartInDeeperLevel()
  366. {
  367. $this->assertSqlGeneration(
  368. "SELECT u FROM Doctrine\Tests\Models\Company\CompanyEmployee u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager",
  369. "SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c0_.discr AS discr5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id WHERE c0_.discr IN ('manager')"
  370. );
  371. }
  372. public function testSupportsInstanceOfExpressionsInWherePartInDeepestLevel()
  373. {
  374. $this->assertSqlGeneration(
  375. "SELECT u FROM Doctrine\Tests\Models\Company\CompanyManager u WHERE u INSTANCE OF Doctrine\Tests\Models\Company\CompanyManager",
  376. "SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id WHERE c0_.discr IN ('manager')"
  377. );
  378. }
  379. public function testSupportsInstanceOfExpressionsUsingInputParameterInWherePart()
  380. {
  381. $this->assertSqlGeneration(
  382. "SELECT u FROM Doctrine\Tests\Models\Company\CompanyPerson u WHERE u INSTANCE OF ?1",
  383. "SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_ WHERE c0_.discr IN ('employee')",
  384. array(), array(1 => $this->_em->getClassMetadata('Doctrine\Tests\Models\Company\CompanyEmployee'))
  385. );
  386. }
  387. // Ticket #973
  388. public function testSupportsSingleValuedInExpressionWithoutSpacesInWherePart()
  389. {
  390. $this->assertSqlGeneration(
  391. "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE IDENTITY(u.email) IN(46)",
  392. "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE c0_.email_id IN (46)"
  393. );
  394. }
  395. public function testSupportsMultipleValuedInExpressionInWherePart()
  396. {
  397. $this->assertSqlGeneration(
  398. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id IN (1, 2)',
  399. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id IN (1, 2)'
  400. );
  401. }
  402. public function testSupportsNotInExpressionInWherePart()
  403. {
  404. $this->assertSqlGeneration(
  405. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :id NOT IN (1)',
  406. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE ? NOT IN (1)'
  407. );
  408. }
  409. public function testInExpressionWithSingleValuedAssociationPathExpressionInWherePart()
  410. {
  411. $this->assertSqlGeneration(
  412. 'SELECT u FROM Doctrine\Tests\Models\Forum\ForumUser u WHERE u.avatar IN (?1, ?2)',
  413. 'SELECT f0_.id AS id0, f0_.username AS username1 FROM forum_users f0_ WHERE f0_.avatar_id IN (?, ?)'
  414. );
  415. }
  416. public function testInvalidInExpressionWithSingleValuedAssociationPathExpressionOnInverseSide()
  417. {
  418. // We do not support SingleValuedAssociationPathExpression on inverse side
  419. $this->assertInvalidSqlGeneration(
  420. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IN (?1, ?2)",
  421. "Doctrine\ORM\Query\QueryException"
  422. );
  423. }
  424. public function testSupportsConcatFunctionForMysqlAndPostgresql()
  425. {
  426. $connMock = $this->_em->getConnection();
  427. $orgPlatform = $connMock->getDatabasePlatform();
  428. $connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform);
  429. $this->assertSqlGeneration(
  430. "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, 's') = ?1",
  431. "SELECT c0_.id AS id0 FROM cms_users c0_ WHERE CONCAT(c0_.name, 's') = ?"
  432. );
  433. $this->assertSqlGeneration(
  434. "SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
  435. "SELECT CONCAT(c0_.id, c0_.name) AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?"
  436. );
  437. $connMock->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
  438. $this->assertSqlGeneration(
  439. "SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(u.name, 's') = ?1",
  440. "SELECT c0_.id AS id0 FROM cms_users c0_ WHERE c0_.name || 's' = ?"
  441. );
  442. $this->assertSqlGeneration(
  443. "SELECT CONCAT(u.id, u.name) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1",
  444. "SELECT c0_.id || c0_.name AS sclr0 FROM cms_users c0_ WHERE c0_.id = ?"
  445. );
  446. $connMock->setDatabasePlatform($orgPlatform);
  447. }
  448. public function testSupportsExistsExpressionInWherePartWithCorrelatedSubquery()
  449. {
  450. $this->assertSqlGeneration(
  451. 'SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE EXISTS (SELECT p.phonenumber FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = u.id)',
  452. 'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT c1_.phonenumber FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = c0_.id)'
  453. );
  454. }
  455. /**
  456. * @group DDC-593
  457. */
  458. public function testSubqueriesInComparisonExpression()
  459. {
  460. $this->assertSqlGeneration(
  461. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE (u.id >= (SELECT u2.id FROM Doctrine\Tests\Models\CMS\CmsUser u2 WHERE u2.name = :name)) AND (u.id <= (SELECT u3.id FROM Doctrine\Tests\Models\CMS\CmsUser u3 WHERE u3.name = :name))',
  462. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id >= (SELECT c1_.id FROM cms_users c1_ WHERE c1_.name = ?)) AND (c0_.id <= (SELECT c2_.id FROM cms_users c2_ WHERE c2_.name = ?))'
  463. );
  464. }
  465. public function testSupportsMemberOfExpressionOneToMany()
  466. {
  467. // "Get all users who have $phone as a phonenumber." (*cough* doesnt really make sense...)
  468. $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.phonenumbers');
  469. $q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
  470. $phone = new \Doctrine\Tests\Models\CMS\CmsPhonenumber;
  471. $phone->phonenumber = 101;
  472. $q->setParameter('param', $phone);
  473. $this->assertEquals(
  474. 'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_phonenumbers c1_ WHERE c0_.id = c1_.user_id AND c1_.phonenumber = ?)',
  475. $q->getSql()
  476. );
  477. }
  478. public function testSupportsMemberOfExpressionManyToMany()
  479. {
  480. // "Get all users who are members of $group."
  481. $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE :param MEMBER OF u.groups');
  482. $q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
  483. $group = new \Doctrine\Tests\Models\CMS\CmsGroup;
  484. $group->id = 101;
  485. $q->setParameter('param', $group);
  486. $this->assertEquals(
  487. 'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id = ?)',
  488. $q->getSql()
  489. );
  490. }
  491. public function testSupportsMemberOfExpressionSelfReferencing()
  492. {
  493. // "Get all persons who have $person as a friend."
  494. // Tough one: Many-many self-referencing ("friends") with class table inheritance
  495. $q = $this->_em->createQuery('SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p WHERE :param MEMBER OF p.friends');
  496. $person = new \Doctrine\Tests\Models\Company\CompanyPerson;
  497. $this->_em->getClassMetadata(get_class($person))->setIdentifierValues($person, array('id' => 101));
  498. $q->setParameter('param', $person);
  499. $this->assertEquals(
  500. 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c1_.car_id AS car_id8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id WHERE EXISTS (SELECT 1 FROM company_persons_friends c3_ INNER JOIN company_persons c4_ ON c3_.friend_id = c4_.id WHERE c3_.person_id = c0_.id AND c4_.id = ?)',
  501. $q->getSql()
  502. );
  503. }
  504. public function testSupportsMemberOfWithSingleValuedAssociation()
  505. {
  506. // Impossible example, but it illustrates the purpose
  507. $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.email MEMBER OF u.groups');
  508. $this->assertEquals(
  509. 'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id = c0_.email_id)',
  510. $q->getSql()
  511. );
  512. }
  513. public function testSupportsMemberOfWithIdentificationVariable()
  514. {
  515. // Impossible example, but it illustrates the purpose
  516. $q = $this->_em->createQuery('SELECT u.id FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u MEMBER OF u.groups');
  517. $this->assertEquals(
  518. 'SELECT c0_.id AS id0 FROM cms_users c0_ WHERE EXISTS (SELECT 1 FROM cms_users_groups c1_ INNER JOIN cms_groups c2_ ON c1_.group_id = c2_.id WHERE c1_.user_id = c0_.id AND c2_.id = c0_.id)',
  519. $q->getSql()
  520. );
  521. }
  522. public function testSupportsCurrentDateFunction()
  523. {
  524. $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_date()');
  525. $q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
  526. $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.col_datetime > CURRENT_DATE', $q->getSql());
  527. }
  528. public function testSupportsCurrentTimeFunction()
  529. {
  530. $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.time > current_time()');
  531. $q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
  532. $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.col_time > CURRENT_TIME', $q->getSql());
  533. }
  534. public function testSupportsCurrentTimestampFunction()
  535. {
  536. $q = $this->_em->createQuery('SELECT d.id FROM Doctrine\Tests\Models\Generic\DateTimeModel d WHERE d.datetime > current_timestamp()');
  537. $q->setHint(Query::HINT_FORCE_PARTIAL_LOAD, true);
  538. $this->assertEquals('SELECT d0_.id AS id0 FROM date_time_model d0_ WHERE d0_.col_datetime > CURRENT_TIMESTAMP', $q->getSql());
  539. }
  540. public function testExistsExpressionInWhereCorrelatedSubqueryAssocCondition()
  541. {
  542. $this->assertSqlGeneration(
  543. // DQL
  544. // The result of this query consists of all employees whose spouses are also employees.
  545. 'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
  546. WHERE EXISTS (
  547. SELECT spouseEmp
  548. FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
  549. WHERE spouseEmp = emp.spouse)',
  550. // SQL
  551. 'SELECT DISTINCT c0_.id AS id0, c0_.name AS name1 FROM cms_employees c0_'
  552. . ' WHERE EXISTS ('
  553. . 'SELECT c1_.id FROM cms_employees c1_ WHERE c1_.id = c0_.spouse_id'
  554. . ')'
  555. );
  556. }
  557. public function testExistsExpressionWithSimpleSelectReturningScalar()
  558. {
  559. $this->assertSqlGeneration(
  560. // DQL
  561. // The result of this query consists of all employees whose spouses are also employees.
  562. 'SELECT DISTINCT emp FROM Doctrine\Tests\Models\CMS\CmsEmployee emp
  563. WHERE EXISTS (
  564. SELECT 1
  565. FROM Doctrine\Tests\Models\CMS\CmsEmployee spouseEmp
  566. WHERE spouseEmp = emp.spouse)',
  567. // SQL
  568. 'SELECT DISTINCT c0_.id AS id0, c0_.name AS name1 FROM cms_employees c0_'
  569. . ' WHERE EXISTS ('
  570. . 'SELECT 1 AS sclr2 FROM cms_employees c1_ WHERE c1_.id = c0_.spouse_id'
  571. . ')'
  572. );
  573. }
  574. public function testLimitFromQueryClass()
  575. {
  576. $q = $this->_em
  577. ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
  578. ->setMaxResults(10);
  579. $this->assertEquals('SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c0_.email_id AS email_id4 FROM cms_users c0_ LIMIT 10', $q->getSql());
  580. }
  581. public function testLimitAndOffsetFromQueryClass()
  582. {
  583. $q = $this->_em
  584. ->createQuery('SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u')
  585. ->setMaxResults(10)
  586. ->setFirstResult(0);
  587. $this->assertEquals('SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c0_.email_id AS email_id4 FROM cms_users c0_ LIMIT 10 OFFSET 0', $q->getSql());
  588. }
  589. public function testSizeFunction()
  590. {
  591. $this->assertSqlGeneration(
  592. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.phonenumbers) > 1",
  593. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) > 1"
  594. );
  595. }
  596. public function testSizeFunctionSupportsManyToMany()
  597. {
  598. $this->assertSqlGeneration(
  599. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE SIZE(u.groups) > 1",
  600. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_users_groups c1_ WHERE c1_.user_id = c0_.id) > 1"
  601. );
  602. }
  603. public function testEmptyCollectionComparisonExpression()
  604. {
  605. $this->assertSqlGeneration(
  606. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS EMPTY",
  607. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) = 0"
  608. );
  609. $this->assertSqlGeneration(
  610. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.phonenumbers IS NOT EMPTY",
  611. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (SELECT COUNT(*) FROM cms_phonenumbers c1_ WHERE c1_.user_id = c0_.id) > 0"
  612. );
  613. }
  614. public function testNestedExpressions()
  615. {
  616. $this->assertSqlGeneration(
  617. "select u from Doctrine\Tests\Models\CMS\CmsUser u where u.id > 10 and u.id < 42 and ((u.id * 2) > 5)",
  618. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id > 10 AND c0_.id < 42 AND (c0_.id * 2 > 5)"
  619. );
  620. }
  621. public function testNestedExpressions2()
  622. {
  623. $this->assertSqlGeneration(
  624. "select u from Doctrine\Tests\Models\CMS\CmsUser u where (u.id > 10) and (u.id < 42 and ((u.id * 2) > 5)) or u.id <> 42",
  625. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id > 10) AND (c0_.id < 42 AND (c0_.id * 2 > 5)) OR c0_.id <> 42"
  626. );
  627. }
  628. public function testNestedExpressions3()
  629. {
  630. $this->assertSqlGeneration(
  631. "select u from Doctrine\Tests\Models\CMS\CmsUser u where (u.id > 10) and (u.id between 1 and 10 or u.id in (1, 2, 3, 4, 5))",
  632. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id > 10) AND (c0_.id BETWEEN 1 AND 10 OR c0_.id IN (1, 2, 3, 4, 5))"
  633. );
  634. }
  635. public function testOrderByCollectionAssociationSize()
  636. {
  637. $this->assertSqlGeneration(
  638. "select u, size(u.articles) as numArticles from Doctrine\Tests\Models\CMS\CmsUser u order by numArticles",
  639. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, (SELECT COUNT(*) FROM cms_articles c1_ WHERE c1_.user_id = c0_.id) AS sclr4 FROM cms_users c0_ ORDER BY sclr4 ASC"
  640. );
  641. }
  642. public function testOrderBySupportsSingleValuedPathExpressionOwningSide()
  643. {
  644. $this->assertSqlGeneration(
  645. "select a from Doctrine\Tests\Models\CMS\CmsArticle a order by a.user",
  646. "SELECT c0_.id AS id0, c0_.topic AS topic1, c0_.text AS text2, c0_.version AS version3 FROM cms_articles c0_ ORDER BY c0_.user_id ASC"
  647. );
  648. }
  649. /**
  650. * @expectedException Doctrine\ORM\Query\QueryException
  651. */
  652. public function testOrderBySupportsSingleValuedPathExpressionInverseSide()
  653. {
  654. $q = $this->_em->createQuery("select u from Doctrine\Tests\Models\CMS\CmsUser u order by u.address");
  655. $q->getSQL();
  656. }
  657. public function testBooleanLiteralInWhereOnSqlite()
  658. {
  659. $oldPlat = $this->_em->getConnection()->getDatabasePlatform();
  660. $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\SqlitePlatform);
  661. $this->assertSqlGeneration(
  662. "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true",
  663. "SELECT b0_.id AS id0, b0_.booleanField AS booleanField1 FROM boolean_model b0_ WHERE b0_.booleanField = 1"
  664. );
  665. $this->assertSqlGeneration(
  666. "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false",
  667. "SELECT b0_.id AS id0, b0_.booleanField AS booleanField1 FROM boolean_model b0_ WHERE b0_.booleanField = 0"
  668. );
  669. $this->_em->getConnection()->setDatabasePlatform($oldPlat);
  670. }
  671. public function testBooleanLiteralInWhereOnPostgres()
  672. {
  673. $oldPlat = $this->_em->getConnection()->getDatabasePlatform();
  674. $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
  675. $this->assertSqlGeneration(
  676. "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = true",
  677. "SELECT b0_.id AS id0, b0_.booleanField AS booleanfield1 FROM boolean_model b0_ WHERE b0_.booleanField = true"
  678. );
  679. $this->assertSqlGeneration(
  680. "SELECT b FROM Doctrine\Tests\Models\Generic\BooleanModel b WHERE b.booleanField = false",
  681. "SELECT b0_.id AS id0, b0_.booleanField AS booleanfield1 FROM boolean_model b0_ WHERE b0_.booleanField = false"
  682. );
  683. $this->_em->getConnection()->setDatabasePlatform($oldPlat);
  684. }
  685. public function testSingleValuedAssociationFieldInWhere()
  686. {
  687. $this->assertSqlGeneration(
  688. "SELECT p FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.user = ?1",
  689. "SELECT c0_.phonenumber AS phonenumber0 FROM cms_phonenumbers c0_ WHERE c0_.user_id = ?"
  690. );
  691. }
  692. public function testSingleValuedAssociationNullCheckOnOwningSide()
  693. {
  694. $this->assertSqlGeneration(
  695. "SELECT a FROM Doctrine\Tests\Models\CMS\CmsAddress a WHERE a.user IS NULL",
  696. "SELECT c0_.id AS id0, c0_.country AS country1, c0_.zip AS zip2, c0_.city AS city3 FROM cms_addresses c0_ WHERE c0_.user_id IS NULL"
  697. );
  698. }
  699. // Null check on inverse side has to happen through explicit JOIN.
  700. // "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.address IS NULL"
  701. // where the CmsUser is the inverse side is not supported.
  702. public function testSingleValuedAssociationNullCheckOnInverseSide()
  703. {
  704. $this->assertSqlGeneration(
  705. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u LEFT JOIN u.address a WHERE a.id IS NULL",
  706. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ LEFT JOIN cms_addresses c1_ ON c0_.id = c1_.user_id WHERE c1_.id IS NULL"
  707. );
  708. }
  709. /**
  710. * @group DDC-339
  711. */
  712. public function testStringFunctionLikeExpression()
  713. {
  714. $this->assertSqlGeneration(
  715. "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE '%foo OR bar%'",
  716. "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE LOWER(c0_.name) LIKE '%foo OR bar%'"
  717. );
  718. $this->assertSqlGeneration(
  719. "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE LOWER(u.name) LIKE :str",
  720. "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE LOWER(c0_.name) LIKE ?"
  721. );
  722. $this->assertSqlGeneration(
  723. "SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE CONCAT(UPPER(u.name), '_moo') LIKE :str",
  724. "SELECT c0_.name AS name0 FROM cms_users c0_ WHERE UPPER(c0_.name) || '_moo' LIKE ?"
  725. );
  726. }
  727. /**
  728. * @group DDC-338
  729. */
  730. public function testOrderedCollectionFetchJoined()
  731. {
  732. $this->assertSqlGeneration(
  733. "SELECT r, l FROM Doctrine\Tests\Models\Routing\RoutingRoute r JOIN r.legs l",
  734. "SELECT r0_.id AS id0, r1_.id AS id1, r1_.departureDate AS departureDate2, r1_.arrivalDate AS arrivalDate3 FROM RoutingRoute r0_ INNER JOIN RoutingRouteLegs r2_ ON r0_.id = r2_.route_id INNER JOIN RoutingLeg r1_ ON r1_.id = r2_.leg_id ".
  735. "ORDER BY r1_.departureDate ASC"
  736. );
  737. }
  738. public function testSubselectInSelect()
  739. {
  740. $this->assertSqlGeneration(
  741. "SELECT u.name, (SELECT COUNT(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p WHERE p.phonenumber = 1234) pcount FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name = 'jon'",
  742. "SELECT c0_.name AS name0, (SELECT COUNT(c1_.phonenumber) AS dctrn__1 FROM cms_phonenumbers c1_ WHERE c1_.phonenumber = 1234) AS sclr1 FROM cms_users c0_ WHERE c0_.name = 'jon'"
  743. );
  744. }
  745. /**
  746. * @group locking
  747. * @group DDC-178
  748. */
  749. public function testPessimisticWriteLockQueryHint()
  750. {
  751. if ($this->_em->getConnection()->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) {
  752. $this->markTestSkipped('SqLite does not support Row locking at all.');
  753. }
  754. $this->assertSqlGeneration(
  755. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
  756. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 ".
  757. "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR UPDATE",
  758. array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::PESSIMISTIC_WRITE)
  759. );
  760. }
  761. /**
  762. * @group locking
  763. * @group DDC-178
  764. */
  765. public function testPessimisticReadLockQueryHintPostgreSql()
  766. {
  767. $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\PostgreSqlPlatform);
  768. $this->assertSqlGeneration(
  769. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
  770. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 ".
  771. "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR SHARE",
  772. array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::PESSIMISTIC_READ)
  773. );
  774. }
  775. /**
  776. * @group DDC-1693
  777. * @group locking
  778. */
  779. public function testLockModeNoneQueryHint()
  780. {
  781. $this->assertSqlGeneration(
  782. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
  783. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 ".
  784. "FROM cms_users c0_ WHERE c0_.username = 'gblanco'",
  785. array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::NONE)
  786. );
  787. }
  788. /**
  789. * @group DDC-430
  790. */
  791. public function testSupportSelectWithMoreThan10InputParameters()
  792. {
  793. $this->assertSqlGeneration(
  794. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.id = ?1 OR u.id = ?2 OR u.id = ?3 OR u.id = ?4 OR u.id = ?5 OR u.id = ?6 OR u.id = ?7 OR u.id = ?8 OR u.id = ?9 OR u.id = ?10 OR u.id = ?11",
  795. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ? OR c0_.id = ?"
  796. );
  797. }
  798. /**
  799. * @group locking
  800. * @group DDC-178
  801. */
  802. public function testPessimisticReadLockQueryHintMySql()
  803. {
  804. $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\MySqlPlatform);
  805. $this->assertSqlGeneration(
  806. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
  807. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 ".
  808. "FROM cms_users c0_ WHERE c0_.username = 'gblanco' LOCK IN SHARE MODE",
  809. array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::PESSIMISTIC_READ)
  810. );
  811. }
  812. /**
  813. * @group locking
  814. * @group DDC-178
  815. */
  816. public function testPessimisticReadLockQueryHintOracle()
  817. {
  818. $this->_em->getConnection()->setDatabasePlatform(new \Doctrine\DBAL\Platforms\OraclePlatform);
  819. $this->assertSqlGeneration(
  820. "SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.username = 'gblanco'",
  821. "SELECT c0_.id AS ID0, c0_.status AS STATUS1, c0_.username AS USERNAME2, c0_.name AS NAME3 ".
  822. "FROM cms_users c0_ WHERE c0_.username = 'gblanco' FOR UPDATE",
  823. array(Query::HINT_LOCK_MODE => \Doctrine\DBAL\LockMode::PESSIMISTIC_READ)
  824. );
  825. }
  826. /**
  827. * @group DDC-431
  828. */
  829. public function testSupportToCustomDQLFunctions()
  830. {
  831. $config = $this->_em->getConfiguration();
  832. $config->addCustomNumericFunction('MYABS', 'Doctrine\Tests\ORM\Query\MyAbsFunction');
  833. $this->assertSqlGeneration(
  834. 'SELECT MYABS(p.phonenumber) FROM Doctrine\Tests\Models\CMS\CmsPhonenumber p',
  835. 'SELECT ABS(c0_.phonenumber) AS sclr0 FROM cms_phonenumbers c0_'
  836. );
  837. $config->setCustomNumericFunctions(array());
  838. }
  839. /**
  840. * @group DDC-826
  841. */
  842. public function testMappedSuperclassAssociationJoin()
  843. {
  844. $this->assertSqlGeneration(
  845. 'SELECT f FROM Doctrine\Tests\Models\DirectoryTree\File f JOIN f.parentDirectory d WHERE f.id = ?1',
  846. 'SELECT f0_.id AS id0, f0_.extension AS extension1, f0_.name AS name2 FROM "file" f0_ INNER JOIN Directory d1_ ON f0_.parentDirectory_id = d1_.id WHERE f0_.id = ?'
  847. );
  848. }
  849. /**
  850. * @group DDC-1053
  851. */
  852. public function testGroupBy()
  853. {
  854. $this->assertSqlGeneration(
  855. 'SELECT g.id, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g.id',
  856. 'SELECT c0_.id AS id0, count(c1_.id) AS sclr1 FROM cms_groups c0_ INNER JOIN cms_users_groups c2_ ON c0_.id = c2_.group_id INNER JOIN cms_users c1_ ON c1_.id = c2_.user_id GROUP BY c0_.id'
  857. );
  858. }
  859. /**
  860. * @group DDC-1053
  861. */
  862. public function testGroupByIdentificationVariable()
  863. {
  864. $this->assertSqlGeneration(
  865. 'SELECT g, count(u.id) FROM Doctrine\Tests\Models\CMS\CmsGroup g JOIN g.users u GROUP BY g',
  866. 'SELECT c0_.id AS id0, c0_.name AS name1, count(c1_.id) AS sclr2 FROM cms_groups c0_ INNER JOIN cms_users_groups c2_ ON c0_.id = c2_.group_id INNER JOIN cms_users c1_ ON c1_.id = c2_.user_id GROUP BY c0_.id, c0_.name'
  867. );
  868. }
  869. public function testCaseContainingNullIf()
  870. {
  871. $this->assertSqlGeneration(
  872. "SELECT NULLIF(g.id, g.name) AS NullIfEqual FROM Doctrine\Tests\Models\CMS\CmsGroup g",
  873. 'SELECT NULLIF(c0_.id, c0_.name) AS sclr0 FROM cms_groups c0_'
  874. );
  875. }
  876. public function testCaseContainingCoalesce()
  877. {
  878. $this->assertSqlGeneration(
  879. "SELECT COALESCE(NULLIF(u.name, ''), u.username) as Display FROM Doctrine\Tests\Models\CMS\CmsUser u",
  880. "SELECT COALESCE(NULLIF(c0_.name, ''), c0_.username) AS sclr0 FROM cms_users c0_"
  881. );
  882. }
  883. /**
  884. * Test that the right discriminator data is inserted in a subquery.
  885. */
  886. public function testSubSelectDiscriminator()
  887. {
  888. $this->assertSqlGeneration(
  889. "SELECT u.name, (SELECT COUNT(cfc.id) total FROM Doctrine\Tests\Models\Company\CompanyFixContract cfc) as cfc_count FROM Doctrine\Tests\Models\CMS\CmsUser u",
  890. "SELECT c0_.name AS name0, (SELECT COUNT(c1_.id) AS dctrn__total FROM company_contracts c1_ WHERE c1_.discr IN ('fix')) AS sclr1 FROM cms_users c0_"
  891. );
  892. }
  893. public function testIdVariableResultVariableReuse()
  894. {
  895. $exceptionThrown = false;
  896. try {
  897. $query = $this->_em->createQuery("SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE u.name IN (SELECT u.name FROM Doctrine\Tests\Models\CMS\CmsUser u)");
  898. $query->getSql();
  899. $query->free();
  900. } catch (\Exception $e) {
  901. $exceptionThrown = true;
  902. }
  903. $this->assertTrue($exceptionThrown);
  904. }
  905. public function testSubSelectAliasesFromOuterQuery()
  906. {
  907. $this->assertSqlGeneration(
  908. "SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo",
  909. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, (SELECT c1_.name FROM cms_users c1_ WHERE c1_.id = c0_.id) AS sclr4 FROM cms_users c0_"
  910. );
  911. }
  912. public function testSubSelectAliasesFromOuterQueryWithSubquery()
  913. {
  914. $this->assertSqlGeneration(
  915. "SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id AND ui.name IN (SELECT uii.name FROM Doctrine\Tests\Models\CMS\CmsUser uii)) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo",
  916. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, (SELECT c1_.name FROM cms_users c1_ WHERE c1_.id = c0_.id AND c1_.name IN (SELECT c2_.name FROM cms_users c2_)) AS sclr4 FROM cms_users c0_"
  917. );
  918. }
  919. public function testSubSelectAliasesFromOuterQueryReuseInWhereClause()
  920. {
  921. $this->assertSqlGeneration(
  922. "SELECT uo, (SELECT ui.name FROM Doctrine\Tests\Models\CMS\CmsUser ui WHERE ui.id = uo.id) AS bar FROM Doctrine\Tests\Models\CMS\CmsUser uo WHERE bar = ?0",
  923. "SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, (SELECT c1_.name FROM cms_users c1_ WHERE c1_.id = c0_.id) AS sclr4 FROM cms_users c0_ WHERE sclr4 = ?"
  924. );
  925. }
  926. /**
  927. * @group DDC-1298
  928. */
  929. public function testSelectForeignKeyPKWithoutFields()
  930. {
  931. $this->assertSqlGeneration(
  932. "SELECT t, s, l FROM Doctrine\Tests\Models\DDC117\DDC117Link l INNER JOIN l.target t INNER JOIN l.source s",
  933. "SELECT d0_.article_id AS article_id0, d0_.title AS title1, d1_.article_id AS article_id2, d1_.title AS title3, d2_.source_id AS source_id4, d2_.target_id AS target_id5 FROM DDC117Link d2_ INNER JOIN DDC117Article d0_ ON d2_.target_id = d0_.article_id INNER JOIN DDC117Article d1_ ON d2_.source_id = d1_.article_id"
  934. );
  935. }
  936. public function testGeneralCaseWithSingleWhenClause()
  937. {
  938. $this->assertSqlGeneration(
  939. "SELECT g.id, CASE WHEN ((g.id / 2) > 18) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g",
  940. "SELECT c0_.id AS id0, CASE WHEN (c0_.id / 2 > 18) THEN 1 ELSE 0 END AS sclr1 FROM cms_groups c0_"
  941. );
  942. }
  943. public function testGeneralCaseWithMultipleWhenClause()
  944. {
  945. $this->assertSqlGeneration(
  946. "SELECT g.id, CASE WHEN (g.id / 2 < 10) THEN 2 WHEN ((g.id / 2) > 20) THEN 1 ELSE 0 END AS test FROM Doctrine\Tests\Models\CMS\CmsGroup g",
  947. "SELECT c0_.id AS id0, CASE WHEN (c0_.id / 2 < 10) THEN 2 WHEN (c0_.id / 2 > 20) THEN 1 ELSE 0 END AS sclr1 FROM cms_groups c0_"
  948. );
  949. }
  950. public function testSimpleCaseWithSingleWhenClause()
  951. {
  952. $this->assertSqlGeneration(
  953. "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = CASE g.name WHEN 'admin' THEN 1 ELSE 2 END",
  954. "SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_groups c0_ WHERE c0_.id = CASE c0_.name WHEN admin THEN 1 ELSE 2 END"
  955. );
  956. }
  957. public function testSimpleCaseWithMultipleWhenClause()
  958. {
  959. $this->assertSqlGeneration(
  960. "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id = (CASE g.name WHEN 'admin' THEN 1 WHEN 'moderator' THEN 2 ELSE 3 END)",
  961. "SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_groups c0_ WHERE c0_.id = CASE c0_.name WHEN admin THEN 1 WHEN moderator THEN 2 ELSE 3 END"
  962. );
  963. }
  964. public function testGeneralCaseWithSingleWhenClauseInSubselect()
  965. {
  966. $this->assertSqlGeneration(
  967. "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE WHEN ((g2.id / 2) > 18) THEN 2 ELSE 1 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)",
  968. "SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_groups c0_ WHERE c0_.id IN (SELECT CASE WHEN (c1_.id / 2 > 18) THEN 2 ELSE 1 END AS sclr2 FROM cms_groups c1_)"
  969. );
  970. }
  971. public function testGeneralCaseWithMultipleWhenClauseInSubselect()
  972. {
  973. $this->assertSqlGeneration(
  974. "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE WHEN (g.id / 2 < 10) THEN 3 WHEN ((g.id / 2) > 20) THEN 2 ELSE 1 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)",
  975. "SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_groups c0_ WHERE c0_.id IN (SELECT CASE WHEN (c0_.id / 2 < 10) THEN 3 WHEN (c0_.id / 2 > 20) THEN 2 ELSE 1 END AS sclr2 FROM cms_groups c1_)"
  976. );
  977. }
  978. public function testSimpleCaseWithSingleWhenClauseInSubselect()
  979. {
  980. $this->assertSqlGeneration(
  981. "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE g2.name WHEN 'admin' THEN 1 ELSE 2 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)",
  982. "SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_groups c0_ WHERE c0_.id IN (SELECT CASE c1_.name WHEN admin THEN 1 ELSE 2 END AS sclr2 FROM cms_groups c1_)"
  983. );
  984. }
  985. public function testSimpleCaseWithMultipleWhenClauseInSubselect()
  986. {
  987. $this->assertSqlGeneration(
  988. "SELECT g FROM Doctrine\Tests\Models\CMS\CmsGroup g WHERE g.id IN (SELECT CASE g2.name WHEN 'admin' THEN 1 WHEN 'moderator' THEN 2 ELSE 3 END FROM Doctrine\Tests\Models\CMS\CmsGroup g2)",
  989. "SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_groups c0_ WHERE c0_.id IN (SELECT CASE c1_.name WHEN admin THEN 1 WHEN moderator THEN 2 ELSE 3 END AS sclr2 FROM cms_groups c1_)"
  990. );
  991. }
  992. /**
  993. * @group DDC-1339
  994. */
  995. public function testIdentityFunctionInSelectClause()
  996. {
  997. $this->assertSqlGeneration(
  998. "SELECT IDENTITY(u.email) as email_id FROM Doctrine\Tests\Models\CMS\CmsUser u",
  999. "SELECT c0_.email_id AS sclr0 FROM cms_users c0_"
  1000. );
  1001. }
  1002. /**
  1003. * @group DDC-1339
  1004. */
  1005. public function testIdentityFunctionDoesNotAcceptStateField()
  1006. {
  1007. $this->assertInvalidSqlGeneration(
  1008. "SELECT IDENTITY(u.name) as name FROM Doctrine\Tests\Models\CMS\CmsUser u",
  1009. "Doctrine\ORM\Query\QueryException"
  1010. );
  1011. }
  1012. /**
  1013. * @group DDC-1389
  1014. */
  1015. public function testInheritanceTypeJoinInRootClassWithDisabledForcePartialLoad()
  1016. {
  1017. $this->assertSqlGeneration(
  1018. 'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
  1019. 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c1_.car_id AS car_id8 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id',
  1020. array(Query::HINT_FORCE_PARTIAL_LOAD => false)
  1021. );
  1022. }
  1023. /**
  1024. * @group DDC-1389
  1025. */
  1026. public function testInheritanceTypeJoinInRootClassWithEnabledForcePartialLoad()
  1027. {
  1028. $this->assertSqlGeneration(
  1029. 'SELECT p FROM Doctrine\Tests\Models\Company\CompanyPerson p',
  1030. 'SELECT c0_.id AS id0, c0_.name AS name1, c0_.discr AS discr2 FROM company_persons c0_',
  1031. array(Query::HINT_FORCE_PARTIAL_LOAD => true)
  1032. );
  1033. }
  1034. /**
  1035. * @group DDC-1389
  1036. */
  1037. public function testInheritanceTypeJoinInChildClassWithDisabledForcePartialLoad()
  1038. {
  1039. $this->assertSqlGeneration(
  1040. 'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
  1041. 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c2_.car_id AS car_id8 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id LEFT JOIN company_managers c2_ ON c1_.id = c2_.id',
  1042. array(Query::HINT_FORCE_PARTIAL_LOAD => false)
  1043. );
  1044. }
  1045. /**
  1046. * @group DDC-1389
  1047. */
  1048. public function testInheritanceTypeJoinInChildClassWithEnabledForcePartialLoad()
  1049. {
  1050. $this->assertSqlGeneration(
  1051. 'SELECT e FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
  1052. 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c0_.discr AS discr5 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id',
  1053. array(Query::HINT_FORCE_PARTIAL_LOAD => true)
  1054. );
  1055. }
  1056. /**
  1057. * @group DDC-1389
  1058. */
  1059. public function testInheritanceTypeJoinInLeafClassWithDisabledForcePartialLoad()
  1060. {
  1061. $this->assertSqlGeneration(
  1062. 'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
  1063. 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6, c0_.spouse_id AS spouse_id7, c2_.car_id AS car_id8 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id',
  1064. array(Query::HINT_FORCE_PARTIAL_LOAD => false)
  1065. );
  1066. }
  1067. /**
  1068. * @group DDC-1389
  1069. */
  1070. public function testInheritanceTypeJoinInLeafClassWithEnabledForcePartialLoad()
  1071. {
  1072. $this->assertSqlGeneration(
  1073. 'SELECT m FROM Doctrine\Tests\Models\Company\CompanyManager m',
  1074. 'SELECT c0_.id AS id0, c0_.name AS name1, c1_.salary AS salary2, c1_.department AS department3, c1_.startDate AS startDate4, c2_.title AS title5, c0_.discr AS discr6 FROM company_managers c2_ INNER JOIN company_employees c1_ ON c2_.id = c1_.id INNER JOIN company_persons c0_ ON c2_.id = c0_.id',
  1075. array(Query::HINT_FORCE_PARTIAL_LOAD => true)
  1076. );
  1077. }
  1078. /**
  1079. * @group DDC-1389
  1080. */
  1081. public function testInheritanceTypeSingleTableInRootClassWithDisabledForcePartialLoad()
  1082. {
  1083. $this->assertSqlGeneration(
  1084. 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
  1085. "SELECT c0_.id AS id0, c0_.completed AS completed1, c0_.fixPrice AS fixPrice2, c0_.hoursWorked AS hoursWorked3, c0_.pricePerHour AS pricePerHour4, c0_.maxPrice AS maxPrice5, c0_.discr AS discr6, c0_.salesPerson_id AS salesPerson_id7 FROM company_contracts c0_ WHERE c0_.discr IN ('fix', 'flexible', 'flexultra')",
  1086. array(Query::HINT_FORCE_PARTIAL_LOAD => false)
  1087. );
  1088. }
  1089. /**
  1090. * @group DDC-1389
  1091. */
  1092. public function testInheritanceTypeSingleTableInRootClassWithEnabledForcePartialLoad()
  1093. {
  1094. $this->assertSqlGeneration(
  1095. 'SELECT c FROM Doctrine\Tests\Models\Company\CompanyContract c',
  1096. "SELECT c0_.id AS id0, c0_.completed AS completed1, c0_.fixPrice AS fixPrice2, c0_.hoursWorked AS hoursWorked3, c0_.pricePerHour AS pricePerHour4, c0_.maxPrice AS maxPrice5, c0_.discr AS discr6 FROM company_contracts c0_ WHERE c0_.discr IN ('fix', 'flexible', 'flexultra')",
  1097. array(Query::HINT_FORCE_PARTIAL_LOAD => true)
  1098. );
  1099. }
  1100. /**
  1101. * @group DDC-1389
  1102. */
  1103. public function testInheritanceTypeSingleTableInChildClassWithDisabledForcePartialLoad()
  1104. {
  1105. $this->assertSqlGeneration(
  1106. 'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
  1107. "SELECT c0_.id AS id0, c0_.completed AS completed1, c0_.hoursWorked AS hoursWorked2, c0_.pricePerHour AS pricePerHour3, c0_.maxPrice AS maxPrice4, c0_.discr AS discr5, c0_.salesPerson_id AS salesPerson_id6 FROM company_contracts c0_ WHERE c0_.discr IN ('flexible', 'flexultra')",
  1108. array(Query::HINT_FORCE_PARTIAL_LOAD => false)
  1109. );
  1110. }
  1111. /**
  1112. * @group DDC-1389
  1113. */
  1114. public function testInheritanceTypeSingleTableInChildClassWithEnabledForcePartialLoad()
  1115. {
  1116. $this->assertSqlGeneration(
  1117. 'SELECT fc FROM Doctrine\Tests\Models\Company\CompanyFlexContract fc',
  1118. "SELECT c0_.id AS id0, c0_.completed AS completed1, c0_.hoursWorked AS hoursWorked2, c0_.pricePerHour AS pricePerHour3, c0_.maxPrice AS maxPrice4, c0_.discr AS discr5 FROM company_contracts c0_ WHERE c0_.discr IN ('flexible', 'flexultra')",
  1119. array(Query::HINT_FORCE_PARTIAL_LOAD => true)
  1120. );
  1121. }
  1122. /**
  1123. * @group DDC-1389
  1124. */
  1125. public function testInheritanceTypeSingleTableInLeafClassWithDisabledForcePartialLoad()
  1126. {
  1127. $this->assertSqlGeneration(
  1128. 'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
  1129. "SELECT c0_.id AS id0, c0_.completed AS completed1, c0_.hoursWorked AS hoursWorked2, c0_.pricePerHour AS pricePerHour3, c0_.maxPrice AS maxPrice4, c0_.discr AS discr5, c0_.salesPerson_id AS salesPerson_id6 FROM company_contracts c0_ WHERE c0_.discr IN ('flexultra')",
  1130. array(Query::HINT_FORCE_PARTIAL_LOAD => false)
  1131. );
  1132. }
  1133. /**
  1134. * @group DDC-1389
  1135. */
  1136. public function testInheritanceTypeSingleTableInLeafClassWithEnabledForcePartialLoad()
  1137. {
  1138. $this->assertSqlGeneration(
  1139. 'SELECT fuc FROM Doctrine\Tests\Models\Company\CompanyFlexUltraContract fuc',
  1140. "SELECT c0_.id AS id0, c0_.completed AS completed1, c0_.hoursWorked AS hoursWorked2, c0_.pricePerHour AS pricePerHour3, c0_.maxPrice AS maxPrice4, c0_.discr AS discr5 FROM company_contracts c0_ WHERE c0_.discr IN ('flexultra')",
  1141. array(Query::HINT_FORCE_PARTIAL_LOAD => true)
  1142. );
  1143. }
  1144. /**
  1145. * @group DDC-1161
  1146. */
  1147. public function testSelfReferenceWithOneToOneDoesNotDuplicateAlias()
  1148. {
  1149. $this->assertSqlGeneration(
  1150. 'SELECT p, pp FROM Doctrine\Tests\Models\Company\CompanyPerson p JOIN p.spouse pp',
  1151. "SELECT c0_.id AS id0, c0_.name AS name1, c1_.title AS title2, c2_.salary AS salary3, c2_.department AS department4, c2_.startDate AS startDate5, c3_.id AS id6, c3_.name AS name7, c4_.title AS title8, c5_.salary AS salary9, c5_.department AS department10, c5_.startDate AS startDate11, c0_.discr AS discr12, c0_.spouse_id AS spouse_id13, c1_.car_id AS car_id14, c3_.discr AS discr15, c3_.spouse_id AS spouse_id16, c4_.car_id AS car_id17 FROM company_persons c0_ LEFT JOIN company_managers c1_ ON c0_.id = c1_.id LEFT JOIN company_employees c2_ ON c0_.id = c2_.id INNER JOIN company_persons c3_ ON c0_.spouse_id = c3_.id LEFT JOIN company_managers c4_ ON c3_.id = c4_.id LEFT JOIN company_employees c5_ ON c3_.id = c5_.id",
  1152. array(Query::HINT_FORCE_PARTIAL_LOAD => false)
  1153. );
  1154. }
  1155. /**
  1156. * @group DDC-1384
  1157. */
  1158. public function testAliasDoesNotExceedPlatformDefinedLength()
  1159. {
  1160. $this->assertSqlGeneration(
  1161. 'SELECT m FROM ' . __NAMESPACE__ . '\\DDC1384Model m',
  1162. "SELECT d0_.aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo AS fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0 FROM DDC1384Model d0_"
  1163. );
  1164. }
  1165. /**
  1166. * @group DDC-331
  1167. * @group DDC-1384
  1168. */
  1169. public function testIssue331()
  1170. {
  1171. $this->assertSqlGeneration(
  1172. 'SELECT e.name FROM Doctrine\Tests\Models\Company\CompanyEmployee e',
  1173. 'SELECT c0_.name AS name0 FROM company_employees c1_ INNER JOIN company_persons c0_ ON c1_.id = c0_.id'
  1174. );
  1175. }
  1176. /**
  1177. * @group DDC-1435
  1178. */
  1179. public function testForeignKeyAsPrimaryKeySubselect()
  1180. {
  1181. $this->assertSqlGeneration(
  1182. "SELECT s FROM Doctrine\Tests\Models\DDC117\DDC117Article s WHERE EXISTS (SELECT r FROM Doctrine\Tests\Models\DDC117\DDC117Reference r WHERE r.source = s)",
  1183. "SELECT d0_.article_id AS article_id0, d0_.title AS title1 FROM DDC117Article d0_ WHERE EXISTS (SELECT d1_.source_id, d1_.target_id FROM DDC117Reference d1_ WHERE d1_.source_id = d0_.article_id)"
  1184. );
  1185. }
  1186. /**
  1187. * @group DDC-1474
  1188. */
  1189. public function testSelectWithArithmeticExpressionBeforeField()
  1190. {
  1191. $this->assertSqlGeneration(
  1192. 'SELECT - e.value AS value, e.id FROM ' . __NAMESPACE__ . '\DDC1474Entity e',
  1193. 'SELECT -d0_.value AS sclr0, d0_.id AS id1 FROM DDC1474Entity d0_'
  1194. );
  1195. $this->assertSqlGeneration(
  1196. 'SELECT e.id, + e.value AS value FROM ' . __NAMESPACE__ . '\DDC1474Entity e',
  1197. 'SELECT d0_.id AS id0, +d0_.value AS sclr1 FROM DDC1474Entity d0_'
  1198. );
  1199. }
  1200. /**
  1201. * @group DDC-1430
  1202. */
  1203. public function testGroupByAllFieldsWhenObjectHasForeignKeys()
  1204. {
  1205. $this->assertSqlGeneration(
  1206. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY u',
  1207. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ GROUP BY c0_.id, c0_.status, c0_.username, c0_.name, c0_.email_id'
  1208. );
  1209. $this->assertSqlGeneration(
  1210. 'SELECT e FROM Doctrine\Tests\Models\CMS\CmsEmployee e GROUP BY e',
  1211. 'SELECT c0_.id AS id0, c0_.name AS name1 FROM cms_employees c0_ GROUP BY c0_.id, c0_.name, c0_.spouse_id'
  1212. );
  1213. }
  1214. /**
  1215. * @group DDC-1236
  1216. */
  1217. public function testGroupBySupportsResultVariable()
  1218. {
  1219. $this->assertSqlGeneration(
  1220. 'SELECT u, u.status AS st FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY st',
  1221. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3, c0_.status AS status4 FROM cms_users c0_ GROUP BY status4'
  1222. );
  1223. }
  1224. /**
  1225. * @group DDC-1236
  1226. */
  1227. public function testGroupBySupportsIdentificationVariable()
  1228. {
  1229. $this->assertSqlGeneration(
  1230. 'SELECT u AS user FROM Doctrine\Tests\Models\CMS\CmsUser u GROUP BY user',
  1231. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ GROUP BY id0, status1, username2, name3'
  1232. );
  1233. }
  1234. /**
  1235. * @group DDC-1213
  1236. */
  1237. public function testSupportsBitComparison()
  1238. {
  1239. $this->assertSqlGeneration(
  1240. 'SELECT BIT_OR(4,2), BIT_AND(4,2), u FROM Doctrine\Tests\Models\CMS\CmsUser u',
  1241. 'SELECT (4 | 2) AS sclr0, (4 & 2) AS sclr1, c0_.id AS id2, c0_.status AS status3, c0_.username AS username4, c0_.name AS name5 FROM cms_users c0_'
  1242. );
  1243. $this->assertSqlGeneration(
  1244. 'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_OR(u.id,2) > 0',
  1245. 'SELECT (c0_.id | 2) AS sclr0, (c0_.id & 2) AS sclr1 FROM cms_users c0_ WHERE (c0_.id | 2) > 0'
  1246. );
  1247. $this->assertSqlGeneration(
  1248. 'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_AND(u.id , 4) > 0',
  1249. 'SELECT (c0_.id | 2) AS sclr0, (c0_.id & 2) AS sclr1 FROM cms_users c0_ WHERE (c0_.id & 4) > 0'
  1250. );
  1251. $this->assertSqlGeneration(
  1252. 'SELECT BIT_OR(u.id,2), BIT_AND(u.id,2) FROM Doctrine\Tests\Models\CMS\CmsUser u WHERE BIT_OR(u.id , 2) > 0 OR BIT_AND(u.id , 4) > 0',
  1253. 'SELECT (c0_.id | 2) AS sclr0, (c0_.id & 2) AS sclr1 FROM cms_users c0_ WHERE (c0_.id | 2) > 0 OR (c0_.id & 4) > 0'
  1254. );
  1255. }
  1256. /**
  1257. * @group DDC-1539
  1258. */
  1259. public function testParenthesesOnTheLeftHandOfComparison()
  1260. {
  1261. $this->assertSqlGeneration(
  1262. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where ( (u.id + u.id) * u.id ) > 100',
  1263. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id + c0_.id) * c0_.id > 100'
  1264. );
  1265. $this->assertSqlGeneration(
  1266. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where (u.id + u.id) * u.id > 100',
  1267. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE (c0_.id + c0_.id) * c0_.id > 100'
  1268. );
  1269. $this->assertSqlGeneration(
  1270. 'SELECT u FROM Doctrine\Tests\Models\CMS\CmsUser u where 100 < (u.id + u.id) * u.id ',
  1271. 'SELECT c0_.id AS id0, c0_.status AS status1, c0_.username AS username2, c0_.name AS name3 FROM cms_users c0_ WHERE 100 < (c0_.id + c0_.id) * c0_.id'
  1272. );
  1273. }
  1274. public function testCustomTypeValueSql()
  1275. {
  1276. if (DBALType::hasType('negative_to_positive')) {
  1277. DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
  1278. } else {
  1279. DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
  1280. }
  1281. $this->assertSqlGeneration(
  1282. 'SELECT p.customInteger FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
  1283. 'SELECT -(c0_.customInteger) AS customInteger0 FROM customtype_parents c0_ WHERE c0_.id = 1'
  1284. );
  1285. }
  1286. public function testCustomTypeValueSqlIgnoresIdentifierColumn()
  1287. {
  1288. if (DBALType::hasType('negative_to_positive')) {
  1289. DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
  1290. } else {
  1291. DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
  1292. }
  1293. $this->assertSqlGeneration(
  1294. 'SELECT p.id FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p WHERE p.id = 1',
  1295. 'SELECT c0_.id AS id0 FROM customtype_parents c0_ WHERE c0_.id = 1'
  1296. );
  1297. }
  1298. public function testCustomTypeValueSqlForAllFields()
  1299. {
  1300. if (DBALType::hasType('negative_to_positive')) {
  1301. DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
  1302. } else {
  1303. DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
  1304. }
  1305. $this->assertSqlGeneration(
  1306. 'SELECT p FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
  1307. 'SELECT c0_.id AS id0, -(c0_.customInteger) AS customInteger1 FROM customtype_parents c0_'
  1308. );
  1309. }
  1310. public function testCustomTypeValueSqlForPartialObject()
  1311. {
  1312. if (DBALType::hasType('negative_to_positive')) {
  1313. DBALType::overrideType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
  1314. } else {
  1315. DBALType::addType('negative_to_positive', 'Doctrine\Tests\DbalTypes\NegativeToPositiveType');
  1316. }
  1317. $this->assertSqlGeneration(
  1318. 'SELECT partial p.{id, customInteger} FROM Doctrine\Tests\Models\CustomType\CustomTypeParent p',
  1319. 'SELECT c0_.id AS id0, -(c0_.customInteger) AS customInteger1 FROM customtype_parents c0_'
  1320. );
  1321. }
  1322. }
  1323. class MyAbsFunction extends \Doctrine\ORM\Query\AST\Functions\FunctionNode
  1324. {
  1325. public $simpleArithmeticExpression;
  1326. /**
  1327. * @override
  1328. */
  1329. public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
  1330. {
  1331. return 'ABS(' . $sqlWalker->walkSimpleArithmeticExpression($this->simpleArithmeticExpression) . ')';
  1332. }
  1333. /**
  1334. * @override
  1335. */
  1336. public function parse(\Doctrine\ORM\Query\Parser $parser)
  1337. {
  1338. $lexer = $parser->getLexer();
  1339. $parser->match(\Doctrine\ORM\Query\Lexer::T_IDENTIFIER);
  1340. $parser->match(\Doctrine\ORM\Query\Lexer::T_OPEN_PARENTHESIS);
  1341. $this->simpleArithmeticExpression = $parser->SimpleArithmeticExpression();
  1342. $parser->match(\Doctrine\ORM\Query\Lexer::T_CLOSE_PARENTHESIS);
  1343. }
  1344. }
  1345. /**
  1346. * @Entity
  1347. */
  1348. class DDC1384Model
  1349. {
  1350. /**
  1351. * @Id
  1352. * @Column(type="integer")
  1353. * @GeneratedValue
  1354. */
  1355. protected $aVeryLongIdentifierThatShouldBeShortenedByTheSQLWalker_fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo;
  1356. }
  1357. /**
  1358. * @Entity
  1359. */
  1360. class DDC1474Entity
  1361. {
  1362. /**
  1363. * @Id
  1364. * @Column(type="integer")
  1365. * @GeneratedValue()
  1366. */
  1367. protected $id;
  1368. /**
  1369. * @column(type="float")
  1370. */
  1371. private $value;
  1372. /**
  1373. * @param string $float
  1374. */
  1375. public function __construct($float)
  1376. {
  1377. $this->value = $float;
  1378. }
  1379. /**
  1380. * @return integer
  1381. */
  1382. public function getId()
  1383. {
  1384. return $this->id;
  1385. }
  1386. /**
  1387. * @return float
  1388. */
  1389. public function getValue()
  1390. {
  1391. return $this->value;
  1392. }
  1393. /**
  1394. * @param float $value
  1395. */
  1396. public function setValue($value)
  1397. {
  1398. $this->value = $value;
  1399. }
  1400. }