PageRenderTime 47ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/EffiProz-h18/EffiProzDBTest/TestSubselect.cs

#
C# | 411 lines | 259 code | 73 blank | 79 comment | 6 complexity | 41765dc3a7af4c177ccf7a7a7eb19359 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. //
  2. // (C) Copyright 2009 Irantha Suwandarathna (irantha@gmail.com)
  3. // All rights reserved.
  4. //
  5. using System;
  6. using System.Text;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using Microsoft.VisualStudio.TestTools.UnitTesting;
  10. using EffiProzDB;
  11. using EffiProzDB.Lib;
  12. using EffiProzDB.DataTypes;
  13. using EffiProzDB.Persist;
  14. namespace EffiProzDBTest
  15. {
  16. /// <summary>
  17. /// Summary description for TestSubselect
  18. /// </summary>
  19. [TestClass]
  20. public class TestSubselect : BaseTest
  21. {
  22. public TestSubselect()
  23. {
  24. }
  25. private TestContext testContextInstance;
  26. /// <summary>
  27. ///Gets or sets the test context which provides
  28. ///information about and functionality for the current test run.
  29. ///</summary>
  30. public TestContext TestContext
  31. {
  32. get
  33. {
  34. return testContextInstance;
  35. }
  36. set
  37. {
  38. testContextInstance = value;
  39. }
  40. }
  41. void createDataset()
  42. {
  43. CleanUp("TestSubselect");
  44. sessionProxy = DatabaseManager.newSession(DatabaseURL.S_FILE, dataPath + "TestSubselect",
  45. user, password, props);
  46. TestHelper.ExecuteUpdateSQL_Success(sessionProxy, "drop table colors if exists; "
  47. + "drop table sizes if exists; "
  48. + "drop table fruits if exists; "
  49. + "drop table trees if exists; ");
  50. TestHelper.ExecuteUpdateSQL_Success(sessionProxy,
  51. "create table colors(id int, val char); "
  52. + "insert into colors values(1,'red'); "
  53. + "insert into colors values(2,'green'); "
  54. + "insert into colors values(3,'orange'); "
  55. + "insert into colors values(4,'indigo'); "
  56. + "create table sizes(id int, val char); "
  57. + "insert into sizes values(1,'small'); "
  58. + "insert into sizes values(2,'medium'); "
  59. + "insert into sizes values(3,'large'); "
  60. + "insert into sizes values(4,'odd'); "
  61. + "create table fruits(id int, name char, color_id int); "
  62. + "insert into fruits values(1, 'golden delicious',2); "
  63. + "insert into fruits values(2, 'macintosh',1); "
  64. + "insert into fruits values(3, 'red delicious',1); "
  65. + "insert into fruits values(4, 'granny smith',2); "
  66. + "insert into fruits values(5, 'tangerine',4); "
  67. + "create table trees(id int, name char, fruit_id int, size_id int); "
  68. + "insert into trees values(1, 'small golden delicious tree',1,1); "
  69. + "insert into trees values(2, 'large macintosh tree',2,3); "
  70. + "insert into trees values(3, 'large red delicious tree',3,3); "
  71. + "insert into trees values(4, 'small red delicious tree',3,1); "
  72. + "insert into trees values(5, 'medium granny smith tree',4,2); ");
  73. }
  74. /**
  75. * This test is basically a sanity check of the data set.
  76. */
  77. public void testSimpleJoin()
  78. {
  79. String sql =
  80. "select trees.id, trees.name, sizes.val, fruits.name, colors.val"
  81. + " from trees, sizes, fruits, colors"
  82. + " where trees.size_id = sizes.id"
  83. + " and trees.fruit_id = fruits.id"
  84. + " and fruits.color_id = colors.id" + " order by 1";
  85. int expectedRows = 5;
  86. String[] expectedTrees = new String[] {
  87. "small golden delicious tree", "large macintosh tree",
  88. "large red delicious tree", "small red delicious tree",
  89. "medium granny smith tree"
  90. };
  91. String[] expectedSizes = new String[] {
  92. "small", "large", "large", "small", "medium"
  93. };
  94. String[] expectedFruits = new String[] {
  95. "golden delicious", "macintosh", "red delicious", "red delicious",
  96. "granny smith"
  97. };
  98. String[] expectedColors = new String[] {
  99. "green", "red", "red", "red", "green"
  100. };
  101. Result results = TestHelper.ExecuteSelectSQL(sessionProxy, sql, null);
  102. String[] trees = new String[expectedRows];
  103. String[] fruits = new String[expectedRows];
  104. String[] sizes = new String[expectedRows];
  105. String[] colors = new String[expectedRows];
  106. for (int rowCount = 0; rowCount < expectedRows; rowCount++)
  107. {
  108. TestHelper.MatchSingleResultRow(results, rowCount,rowCount+1, expectedTrees[rowCount], expectedSizes[rowCount],
  109. expectedFruits[rowCount], expectedColors[rowCount]);
  110. rowCount++;
  111. }
  112. }
  113. /**
  114. * Inner select with where clause in outer select having column with same name as where clause in inner select
  115. */
  116. public void testWhereClausesColliding() {
  117. String sql =
  118. "select name from fruits where id in (select fruit_id from trees where id < 3) order by name";
  119. String[] expected = new String[] {
  120. "golden delicious", "macintosh"
  121. };
  122. Result results = TestHelper.ExecuteSelectSQL(sessionProxy, sql, expected.Length);
  123. for (int rowCount = 0; rowCount < expected.Length; rowCount++)
  124. {
  125. TestHelper.MatchSingleResultRow(results, rowCount, expected[rowCount]);
  126. }
  127. }
  128. /**
  129. * As above, with table aliases.
  130. */
  131. public void testWhereClausesCollidingWithAliases() {
  132. String sql =
  133. "select a.name from fruits a where a.id in (select b.fruit_id from trees b where b.id < 3) order by name";
  134. String[] expected = new String[] {
  135. "golden delicious", "macintosh"
  136. };
  137. Result results = TestHelper.ExecuteSelectSQL(sessionProxy, sql, expected.Length);
  138. for (int rowCount = 0; rowCount < expected.Length; rowCount++)
  139. {
  140. TestHelper.MatchSingleResultRow(results, rowCount, expected[rowCount]);
  141. }
  142. }
  143. /**
  144. * Inner select with two tables having columns with the same name, one of which is referred to in the
  145. * subselect, the other of which is not used in the query (both FRUITS and TREES have NAME column,
  146. * but we're only selecting FRUITS.NAME and we're not referring to TREES.NAME at all).
  147. */
  148. public void testHiddenCollision() {
  149. String sql =
  150. "select name from fruits where id in (select fruit_id from trees) order by name";
  151. String[] expected = new String[] {
  152. "golden delicious", "granny smith", "macintosh", "red delicious"
  153. };
  154. Result results = TestHelper.ExecuteSelectSQL(sessionProxy, sql, expected.Length);
  155. for (int rowCount = 0; rowCount < expected.Length; rowCount++)
  156. {
  157. TestHelper.MatchSingleResultRow(results, rowCount, expected[rowCount]);
  158. }
  159. }
  160. /**
  161. * As above, with table aliases.
  162. */
  163. public void testHiddenCollisionWithAliases() {
  164. String sql =
  165. "select a.name from fruits a where a.id in (select b.fruit_id from trees b) order by a.name";
  166. String[] expected = new String[] {
  167. "golden delicious", "granny smith", "macintosh", "red delicious"
  168. };
  169. compareResults(sql, expected);
  170. }
  171. public void compareResults(string sql, string[] expected)
  172. {
  173. Result results = TestHelper.ExecuteSelectSQL(sessionProxy, sql, expected.Length);
  174. for (int rowCount = 0; rowCount < expected.Length; rowCount++)
  175. {
  176. TestHelper.MatchSingleResultRow(results, rowCount, expected[rowCount]);
  177. }
  178. }
  179. /**
  180. * Inner select with where clause in outer select having column with same name as select clause in inner select
  181. */
  182. public void testWhereSelectColliding() {
  183. // Yes, this is a nonsensical query
  184. String sql =
  185. "select val from colors where id in (select id from trees where fruit_id = 3) order by val";
  186. String[] expected = new String[] {
  187. "indigo", "orange"
  188. };
  189. compareResults(sql, expected);
  190. }
  191. /**
  192. * As above, with aliases.
  193. */
  194. public void testWhereSelectCollidingWithAliases() {
  195. // Yes, this is a nonsensical query
  196. String sql =
  197. "select a.val from colors a where a.id in (select b.id from trees b where b.fruit_id = 3) order by a.val";
  198. String[] expected = new String[] {
  199. "indigo", "orange"
  200. };
  201. compareResults(sql, expected);
  202. }
  203. /**
  204. * Inner select involving same table
  205. */
  206. public void testSameTable() {
  207. String sql =
  208. "select name from trees where id in (select id from trees where fruit_id = 3) order by name";
  209. String[] expected = new String[] {
  210. "large red delicious tree", "small red delicious tree"
  211. };
  212. compareResults(sql, expected);
  213. }
  214. /**
  215. * As above with aliases.
  216. */
  217. public void testSameTableWithAliases() {
  218. String sql =
  219. "select a.name from trees a where a.id in (select b.id from trees b where b.fruit_id = 3) order by a.name";
  220. String[] expected = new String[] {
  221. "large red delicious tree", "small red delicious tree"
  222. };
  223. compareResults(sql, expected);
  224. }
  225. /**
  226. * Inner select involving same table as one of two joined tables in outer select
  227. */
  228. public void testSameTableWithJoin() {
  229. String sql =
  230. "select sizes.val from trees, sizes where sizes.id = trees.size_id and trees.id in (select id from trees where fruit_id = 3) order by sizes.val";
  231. String[] expected = new String[] {
  232. "large", "small"
  233. };
  234. compareResults(sql, expected);
  235. }
  236. /**
  237. * Tests two subselects, anded.
  238. */
  239. public void testAndedSubselects() {
  240. String sql =
  241. "select name from trees where size_id in (select id from sizes where val = 'large') and fruit_id in (select id from fruits where color_id = 1) order by name";
  242. String[] expected = new String[] {
  243. "large macintosh tree", "large red delicious tree"
  244. };
  245. compareResults(sql, expected);
  246. }
  247. /**
  248. * Test nested subselects.
  249. */
  250. public void testNestedSubselects() {
  251. String sql =
  252. "select name from trees where fruit_id in (select id from fruits where color_id in (select id from colors where val = 'red')) order by name";
  253. String[] expected = new String[] {
  254. "large macintosh tree", "large red delicious tree",
  255. "small red delicious tree"
  256. };
  257. compareResults(sql, expected);
  258. }
  259. /**
  260. * Inner select with "not in" in outer select where clause.
  261. */
  262. public void testNotIn() {
  263. String sql =
  264. "select name from fruits where id not in (select fruit_id from trees) order by name";
  265. String[] expected = new String[]{ "tangerine" };
  266. compareResults(sql, expected);
  267. }
  268. /**
  269. * Inner select with "not in" in outer select where clause and same table in inner select where clause.
  270. */
  271. public void testNotInSameTableAndColumn() {
  272. String sql =
  273. "select name from fruits where id not in (select id from fruits where color_id > 1 ) order by name";
  274. String[] expected = new String[] {
  275. "macintosh", "red delicious"
  276. };
  277. compareResults(sql, expected);
  278. }
  279. /**
  280. * Inner select reusing alias names from outer select, but using them for different tables
  281. */
  282. public void testAliasScope() {
  283. String sql =
  284. "select a.val, b.name from sizes a, trees b where a.id = b.size_id and b.id in (select a.id from trees a, fruits b where a.fruit_id = b.id and b.name='red delicious') order by a.val";
  285. String[] expectedSizes = new String[] {
  286. "large", "small"
  287. };
  288. String[] expectedTrees = new String[] {
  289. "large red delicious tree", "small red delicious tree"
  290. };
  291. Assert.AreEqual(expectedSizes.Length, expectedTrees.Length,
  292. "Programmer error: expected arrays should be of equal length.");
  293. Result results = TestHelper.ExecuteSelectSQL(sessionProxy, sql, expectedTrees.Length);
  294. for (int rowCount = 0; rowCount < expectedTrees.Length; rowCount++)
  295. {
  296. TestHelper.MatchSingleResultRow(results, rowCount, expectedSizes[rowCount], expectedTrees[rowCount]);
  297. }
  298. }
  299. #region Additional test attributes
  300. //
  301. // You can use the following additional attributes as you write your tests:
  302. //
  303. // Use ClassInitialize to run code before running the first test in the class
  304. // [ClassInitialize()]
  305. // public static void MyClassInitialize(TestContext testContext) { }
  306. //
  307. // Use ClassCleanup to run code after all tests in a class have run
  308. // [ClassCleanup()]
  309. // public static void MyClassCleanup() { }
  310. //
  311. // Use TestInitialize to run code before running each test
  312. // [TestInitialize()]
  313. // public void MyTestInitialize() { }
  314. //
  315. // Use TestCleanup to run code after each test has run
  316. // [TestCleanup()]
  317. // public void MyTestCleanup() { }
  318. //
  319. #endregion
  320. [TestMethod]
  321. public void Subselect()
  322. {
  323. createDataset();
  324. testSimpleJoin();
  325. testWhereClausesColliding();
  326. testWhereClausesCollidingWithAliases();
  327. testWhereSelectColliding();
  328. testWhereSelectCollidingWithAliases();
  329. testSameTable();
  330. testSameTableWithAliases();
  331. testSameTableWithJoin();
  332. testAndedSubselects();
  333. testNestedSubselects();
  334. testNotIn();
  335. testNotInSameTableAndColumn();
  336. }
  337. }
  338. }