1   package org.apache.torque.util;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.util.Calendar;
23  import java.util.Date;
24  import java.util.List;
25  import java.util.Map;
26  
27  import org.apache.commons.configuration.BaseConfiguration;
28  import org.apache.commons.configuration.Configuration;
29  import org.apache.commons.lang.SerializationUtils;
30  import org.apache.torque.BaseTestCase;
31  import org.apache.torque.Torque;
32  import org.apache.torque.TorqueException;
33  import org.apache.torque.adapter.DBFactory;
34  import org.apache.torque.map.ColumnMap;
35  import org.apache.torque.map.DatabaseMap;
36  import org.apache.torque.map.TableMap;
37  import org.apache.torque.util.Criteria.Criterion;
38  import org.apache.torque.util.Criteria.Join;
39  
40  /***
41   * Test class for Criteria.
42   *
43   * @author <a href="mailto:celkins@scardini.com">Christopher Elkins</a>
44   * @author <a href="mailto:sam@neurogrid.com">Sam Joseph</a>
45   * @author <a href="mailto:seade@backstagetech.com.au">Scott Eade</a>
46   * @version $Id: CriteriaTest.java 535591 2007-05-06 10:05:04Z tfischer $
47   */
48  public class CriteriaTest extends BaseTestCase
49  {
50  
51      /*** The criteria to use in the test. */
52      private Criteria c;
53  
54      /***
55       * Creates a new instance.
56       *
57       * @param name the name of the test to run
58       */
59      public CriteriaTest(String name)
60      {
61          super(name);
62      }
63  
64      /***
65       * Initializes the criteria.
66       */
67      public void setUp()
68      {
69          super.setUp();
70          c = new Criteria();
71      }
72  
73      /***
74       * Test basic adding of strings.
75       */
76      public void testAddString()
77      {
78          final String table = "myTable";
79          final String column = "myColumn";
80          final String value = "myValue";
81  
82          // Add the string
83          c.add(table, column, (Object) value);
84  
85          // Verify that the key exists
86          assertTrue(c.containsKey(table, column));
87  
88          // Verify that what we get out is what we put in
89          assertTrue(c.getString(table, column).equals(value));
90      }
91  
92      /***
93       * test various properties of Criterion and nested criterion
94       */
95      public void testNestedCriterion()
96      {
97          final String table2 = "myTable2";
98          final String column2 = "myColumn2";
99          final String value2 = "myValue2";
100 
101         final String table3 = "myTable3";
102         final String column3 = "myColumn3";
103         final String value3 = "myValue3";
104 
105         final String table4 = "myTable4";
106         final String column4 = "myColumn4";
107         final String value4 = "myValue4";
108 
109         final String table5 = "myTable5";
110         final String column5 = "myColumn5";
111         final String value5 = "myValue5";
112 
113         Criteria.Criterion crit2 =
114             c.getNewCriterion(table2, column2, (Object) value2, Criteria.EQUAL);
115         Criteria.Criterion crit3 =
116             c.getNewCriterion(table3, column3, (Object) value3, Criteria.EQUAL);
117         Criteria.Criterion crit4 =
118             c.getNewCriterion(table4, column4, (Object) value4, Criteria.EQUAL);
119         Criteria.Criterion crit5 =
120             c.getNewCriterion(table5, column5, (Object) value5, Criteria.EQUAL);
121 
122         crit2.and(crit3).or(crit4.and(crit5));
123         String expect =
124             "((myTable2.myColumn2='myValue2' "
125                 + "AND myTable3.myColumn3='myValue3') "
126             + "OR (myTable4.myColumn4='myValue4' "
127                 + "AND myTable5.myColumn5='myValue5'))";
128         String result = crit2.toString();
129         assertEquals(expect, result);
130 
131         Criteria.Criterion crit6 =
132             c.getNewCriterion(table2, column2, (Object) value2, Criteria.EQUAL);
133         Criteria.Criterion crit7 =
134             c.getNewCriterion(table3, column3, (Object) value3, Criteria.EQUAL);
135         Criteria.Criterion crit8 =
136             c.getNewCriterion(table4, column4, (Object) value4, Criteria.EQUAL);
137         Criteria.Criterion crit9 =
138             c.getNewCriterion(table5, column5, (Object) value5, Criteria.EQUAL);
139 
140         crit6.and(crit7).or(crit8).and(crit9);
141         expect =
142             "(((myTable2.myColumn2='myValue2' "
143                     + "AND myTable3.myColumn3='myValue3') "
144                 + "OR myTable4.myColumn4='myValue4') "
145                     + "AND myTable5.myColumn5='myValue5')";
146         result = crit6.toString();
147         assertEquals(expect, result);
148 
149         // should make sure we have tests for all possibilities
150 
151         Criteria.Criterion[] crita = crit2.getAttachedCriterion();
152 
153         assertEquals(crit2, crita[0]);
154         assertEquals(crit3, crita[1]);
155         assertEquals(crit4, crita[2]);
156         assertEquals(crit5, crita[3]);
157 
158         List tables = crit2.getAllTables();
159 
160         assertEquals(crit2.getTable(), tables.get(0));
161         assertEquals(crit3.getTable(), tables.get(1));
162         assertEquals(crit4.getTable(), tables.get(2));
163         assertEquals(crit5.getTable(), tables.get(3));
164 
165         // simple confirmations that equality operations work
166         assertTrue(crit2.hashCode() == crit2.hashCode());
167         assertEquals(crit2.toString(), crit2.toString());
168     }
169 
170     /***
171      * Tests &lt;= and =&gt;.
172      */
173     public void testBetweenCriterion()
174     {
175         Criteria.Criterion cn1 =
176             c.getNewCriterion(
177                 "INVOICE.COST",
178                 new Integer(1000),
179                 Criteria.GREATER_EQUAL);
180         Criteria.Criterion cn2 =
181             c.getNewCriterion(
182                 "INVOICE.COST",
183                 new Integer(5000),
184                 Criteria.LESS_EQUAL);
185         c.add(cn1.and(cn2));
186         String expect =
187             "SELECT  FROM INVOICE WHERE "
188             + "(INVOICE.COST>=1000 AND INVOICE.COST<=5000)";
189         String result = null;
190         try
191         {
192             result = BasePeer.createQueryString(c);
193         }
194         catch (TorqueException e)
195         {
196             fail("TorqueException thrown in BasePeer.createQueryString()");
197         }
198 
199         assertEquals(expect, result);
200     }
201 
202     /***
203      * Verify that AND and OR criterion are nested correctly.
204      */
205     public void testPrecedence()
206     {
207         Criteria.Criterion cn1 =
208             c.getNewCriterion("INVOICE.COST", "1000", Criteria.GREATER_EQUAL);
209         Criteria.Criterion cn2 =
210             c.getNewCriterion("INVOICE.COST", "2000", Criteria.LESS_EQUAL);
211         Criteria.Criterion cn3 =
212             c.getNewCriterion("INVOICE.COST", "8000", Criteria.GREATER_EQUAL);
213         Criteria.Criterion cn4 =
214             c.getNewCriterion("INVOICE.COST", "9000", Criteria.LESS_EQUAL);
215         c.add(cn1.and(cn2));
216         c.or(cn3.and(cn4));
217 
218         String expect =
219             "SELECT  FROM INVOICE WHERE "
220             + "((INVOICE.COST>='1000' AND INVOICE.COST<='2000') "
221             + "OR (INVOICE.COST>='8000' AND INVOICE.COST<='9000'))";
222 
223         String result = null;
224         try
225         {
226             result = BasePeer.createQueryString(c);
227         }
228         catch (TorqueException e)
229         {
230             fail("TorqueException thrown in BasePeer.createQueryString()");
231         }
232 
233         assertEquals(expect, result);
234     }
235 
236     /***
237      * Test Criterion.setIgnoreCase().
238      * As the output is db specific the test just prints the result to
239      * System.out
240      */
241     public void testCriterionIgnoreCase()
242     {
243         Criteria myCriteria = new Criteria();
244 
245         Criteria.Criterion expected = myCriteria.getNewCriterion(
246                 "TABLE.COLUMN", (Object)"FoObAr", Criteria.LIKE);
247         Criteria.Criterion result = expected.setIgnoreCase(true);
248         assertEquals("Criterion mis-match after calling setIgnoreCase(true)",
249                      expected.toString(), result.toString());
250     }
251 
252     /***
253      * Test that true is evaluated correctly.
254      */
255     public void testBoolean()
256     {
257         Criteria c = new Criteria().add("TABLE.COLUMN", true);
258 
259         String expect = "SELECT  FROM TABLE WHERE TABLE.COLUMN=1";
260 
261         String result = null;
262         try
263         {
264             result = BasePeer.createQueryString(c);
265         }
266         catch (TorqueException e)
267         {
268             fail("TorqueException thrown in BasePeer.createQueryString()");
269         }
270 
271         assertEquals(expect, result);
272 
273         // test the postgresql variation
274         c = new Criteria();
275         Criteria.Criterion cc =
276             c.getNewCriterion("TABLE.COLUMN", Boolean.TRUE, Criteria.EQUAL);
277 
278         Configuration conf = new BaseConfiguration();
279         conf.addProperty("driver", "org.postgresql.Driver");
280         try
281         {
282             cc.setDB(DBFactory.create("org.postgresql.Driver"));
283         }
284         catch (Exception e)
285         {
286             fail("Exception thrown in DBFactory");
287         }
288 
289         assertEquals("TABLE.COLUMN=TRUE", cc.toString());
290     }
291 
292     /***
293      * testcase for addDate()
294      */
295     public void testAddDate()
296     {
297         Criteria c = new Criteria();
298         c.addDate("TABLE.DATE_COLUMN", 2003, 0, 22);
299 
300         String expect = "SELECT  FROM TABLE WHERE TABLE.DATE_COLUMN='20030122000000'";
301 
302         String result = null;
303         try
304         {
305             result = BasePeer.createQueryString(c);
306         }
307         catch (TorqueException e)
308         {
309             e.printStackTrace();
310             fail("TorqueException thrown in BasePeer.createQueryString()");
311         }
312         assertEquals(expect, result);
313     }
314 
315     /***
316      * testcase for andDate()
317      * issue TORQUE-42
318      */
319     public void testAndDate()
320     {
321         Criteria c = new Criteria();
322         c.addDate("TABLE.DATE_COLUMN", 2003, 0, 22, Criteria.GREATER_THAN);
323         c.andDate("TABLE.DATE_COLUMN", 2004, 0, 22, Criteria.LESS_THAN);
324 
325         String expect = "SELECT  FROM TABLE WHERE (TABLE.DATE_COLUMN>'20030122000000' AND TABLE.DATE_COLUMN<'20040122000000')";
326 
327         String result = null;
328         try
329         {
330             result = BasePeer.createQueryString(c);
331         }
332         catch (TorqueException e)
333         {
334             e.printStackTrace();
335             fail("TorqueException thrown in BasePeer.createQueryString()");
336         }
337         assertEquals(expect, result);
338     }
339 
340     /***
341      * testcase for add(Date)
342      */
343     public void testDateAdd()
344     {
345         Calendar cal = Calendar.getInstance();
346         cal.set(2003, 0, 22, 0, 0, 0);
347         Date date = cal.getTime();
348         Criteria c = new Criteria();
349         c.add("TABLE.DATE_COLUMN", date);
350 
351         String expect = "SELECT  FROM TABLE WHERE TABLE.DATE_COLUMN='20030122000000'";
352 
353         String result = null;
354         try
355         {
356             result = BasePeer.createQueryString(c);
357         }
358         catch (TorqueException e)
359         {
360             e.printStackTrace();
361             fail("TorqueException thrown in BasePeer.createQueryString()");
362         }
363         assertEquals(expect, result);
364     }
365 
366     public void testCurrentDate()
367     {
368         Criteria c = new Criteria()
369                 .add("TABLE.DATE_COLUMN", Criteria.CURRENT_DATE)
370                 .add("TABLE.TIME_COLUMN", Criteria.CURRENT_TIME);
371 
372         String expect = "SELECT  FROM TABLE WHERE TABLE.TIME_COLUMN=CURRENT_TIME AND TABLE.DATE_COLUMN=CURRENT_DATE";
373 
374         String result = null;
375         try
376         {
377             result = BasePeer.createQueryString(c);
378         }
379         catch (TorqueException e)
380         {
381             e.printStackTrace();
382             fail("TorqueException thrown in BasePeer.createQueryString()");
383         }
384 
385         assertEquals(expect,result);
386     }
387 
388     public void testCountAster()
389     {
390         Criteria c = new Criteria()
391                 .addSelectColumn("COUNT(*)")
392                 .add("TABLE.DATE_COLUMN", Criteria.CURRENT_DATE)
393                 .add("TABLE.TIME_COLUMN", Criteria.CURRENT_TIME);
394 
395         String expect = "SELECT COUNT(*) FROM TABLE WHERE TABLE.TIME_COLUMN=CURRENT_TIME AND TABLE.DATE_COLUMN=CURRENT_DATE";
396 
397         String result = null;
398         try
399         {
400             result = BasePeer.createQueryString(c);
401         }
402         catch (TorqueException e)
403         {
404             e.printStackTrace();
405             fail("TorqueException thrown in BasePeer.createQueryString()");
406         }
407 
408         assertEquals(expect,result);
409 
410     }
411 
412     /***
413      * This test case has been written to try out the fix applied to resolve
414      * TRQS73 - i.e. ensuring that Criteria.toString() does not alter any limit
415      * or offset that may be stored in the Criteria object.  This testcase
416      * could actually pass without the fix if the database in use does not
417      * support native limits and offsets.
418      */
419     public void testCriteriaToStringOffset()
420     {
421         Criteria c = new Criteria()
422                 .add("TABLE.DATE_COLUMN", Criteria.CURRENT_DATE)
423                 .setOffset(3)
424                 .setLimit(5);
425 
426         String toStringExpect = "Criteria:: TABLE.DATE_COLUMN<=>TABLE.DATE_COLUMN=CURRENT_DATE:  "
427                 + "\nCurrent Query SQL (may not be complete or applicable): "
428                 + "SELECT  FROM TABLE WHERE TABLE.DATE_COLUMN=CURRENT_DATE LIMIT 5 OFFSET 3";
429 
430         String cString = c.toString();
431         //System.out.println(cString);
432         assertEquals(toStringExpect, cString);
433 
434         // Note that this is intentionally the same as above as the behaviour is
435         // only observed on subsequent invocations of toString().
436         cString = c.toString();
437         //System.out.println(cString);
438         assertEquals(toStringExpect, cString);
439     }
440 
441     /***
442      * TORQUE-87
443      */
444     public void testCriteriaWithOffsetNoLimit()
445     {
446         Criteria c = new Criteria()
447         .add("TABLE.DATE_COLUMN", Criteria.CURRENT_DATE)
448         .setOffset(3);
449         
450         String toStringExpect = "Criteria:: TABLE.DATE_COLUMN<=>TABLE.DATE_COLUMN=CURRENT_DATE:  "
451             + "\nCurrent Query SQL (may not be complete or applicable): "
452             + "SELECT  FROM TABLE WHERE TABLE.DATE_COLUMN=CURRENT_DATE LIMIT 18446744073709551615 OFFSET 3";
453         
454         String cString = c.toString();
455         //System.out.println(cString);
456         assertEquals(toStringExpect, cString);
457         
458         // Note that this is intentionally the same as above as the behaviour is
459         // only observed on subsequent invocations of toString().
460         cString = c.toString();
461         //System.out.println(cString);
462         assertEquals(toStringExpect, cString);
463     }
464     
465     /***
466      * This test case has been written to try out the fix applied to resolve
467      * TRQS73 - i.e. ensuring that Criteria.toString() does not alter any limit
468      * or offset that may be stored in the Criteria object.  This testcase
469      * could actually pass without the fix if the database in use does not
470      * support native limits and offsets.
471      */
472     public void testCriteriaToStringLimit()
473     {
474         Criteria c = new Criteria()
475                 .add("TABLE.DATE_COLUMN", Criteria.CURRENT_DATE)
476                 .setLimit(5);
477 
478         String toStringExpect = "Criteria:: TABLE.DATE_COLUMN<=>TABLE.DATE_COLUMN=CURRENT_DATE:  "
479                 + "\nCurrent Query SQL (may not be complete or applicable): "
480                 + "SELECT  FROM TABLE WHERE TABLE.DATE_COLUMN=CURRENT_DATE LIMIT 5";
481 
482         String cString = c.toString();
483         //System.out.println(cString);
484         assertEquals(toStringExpect, cString);
485 
486         // Note that this is intentionally the same as above as the behaviour is
487         // only observed on subsequent invocations of toString().
488         cString = c.toString();
489         //System.out.println(cString);
490         assertEquals(toStringExpect, cString);
491     }
492 
493     /***
494      * This test case verifies if the Criteria.LIKE comparison type will
495      * get replaced through Criteria.EQUAL if there are no SQL wildcards
496      * in the given value.
497      */
498     public void testLikeWithoutWildcards()
499     {
500         Criteria c = new Criteria();
501         c.add("TABLE.COLUMN", (Object) "no wildcards", Criteria.LIKE);
502 
503         String expect = "SELECT  FROM TABLE WHERE TABLE.COLUMN = 'no wildcards'";
504 
505         String result = null;
506         try
507         {
508             result = BasePeer.createQueryString(c);
509         }
510         catch (TorqueException e)
511         {
512             e.printStackTrace();
513             fail("TorqueException thrown in BasePeer.createQueryString()");
514         }
515 
516         assertEquals(expect, result);
517     }
518 
519     /***
520      * This test case verifies if the Criteria.NOT_LIKE comparison type will
521      * get replaced through Criteria.NOT_EQUAL if there are no SQL wildcards
522      * in the given value.
523      */
524     public void testNotLikeWithoutWildcards()
525     {
526         Criteria c = new Criteria();
527         c.add("TABLE.COLUMN", (Object) "no wildcards", Criteria.NOT_LIKE);
528 
529         String firstExpect = "SELECT  FROM TABLE WHERE TABLE.COLUMN != 'no wildcards'";
530         String secondExpect = "SELECT  FROM TABLE WHERE TABLE.COLUMN <> 'no wildcards'";
531 
532         String result = null;
533         try
534         {
535             result = BasePeer.createQueryString(c);
536         }
537         catch (TorqueException e)
538         {
539             e.printStackTrace();
540             fail("TorqueException thrown in BasePeer.createQueryString()");
541         }
542 
543         assertTrue(result.equals(firstExpect) || result.equals(secondExpect));
544     }
545 
546     /***
547      * Test that serialization works.
548      */
549     public void testSerialization()
550     {
551         c.setOffset(10);
552         c.setLimit(11);
553         c.setIgnoreCase(true);
554         c.setSingleRecord(true);
555         c.setCascade(true);
556         c.setDbName("myDB");
557         c.setAll();
558         c.setDistinct();
559         c.addSelectColumn("Author.NAME");
560         c.addSelectColumn("Author.AUTHOR_ID");
561         c.addDescendingOrderByColumn("Author.NAME");
562         c.addAscendingOrderByColumn("Author.AUTHOR_ID");
563         c.addAlias("Writer", "Author");
564         c.addAsColumn("AUTHOR_NAME", "Author.NAME");
565         c.addJoin("Author.AUTHOR_ID", "Book.AUTHOR_ID", Criteria.INNER_JOIN);
566         c.add("Author.NAME", (Object) "author%", Criteria.LIKE);
567 
568         // Some direct Criterion checks
569         Criterion cn = c.getCriterion("Author.NAME");
570         cn.setIgnoreCase(true);
571         assertEquals("author%", cn.getValue());
572         assertEquals(Criteria.LIKE, cn.getComparison());
573         Criterion cnDirectClone = (Criterion) SerializationUtils.clone(cn);
574         assertEquals(cn, cnDirectClone);
575 
576         // Clone the object
577         Criteria cClone = (Criteria) SerializationUtils.clone(c);
578 
579         // Check the clone
580         assertEquals(c.size(), cClone.size());
581         assertEquals(10, cClone.getOffset());
582         assertEquals(c.getOffset(), cClone.getOffset());
583         assertEquals(11, cClone.getLimit());
584         assertEquals(c.getLimit(), cClone.getLimit());
585         assertEquals(true, cClone.isIgnoreCase());
586         assertEquals(c.isIgnoreCase(), cClone.isIgnoreCase());
587         assertEquals(true, cClone.isSingleRecord());
588         assertEquals(c.isSingleRecord(), cClone.isSingleRecord());
589         assertEquals(true, cClone.isCascade());
590         assertEquals(c.isCascade(), cClone.isCascade());
591         assertEquals("myDB", cClone.getDbName());
592         assertEquals(c.getDbName(), cClone.getDbName());
593         List selectModifiersClone = cClone.getSelectModifiers();
594         assertTrue(selectModifiersClone.contains(Criteria.ALL.toString()));
595         assertTrue(selectModifiersClone.contains(Criteria.DISTINCT.toString()));
596         assertEquals(c.getSelectModifiers(), cClone.getSelectModifiers());
597         List selectColumnsClone = cClone.getSelectColumns();
598         assertTrue(selectColumnsClone.contains("Author.NAME"));
599         assertTrue(selectColumnsClone.contains("Author.AUTHOR_ID"));
600         assertEquals(c.getSelectColumns(), cClone.getSelectColumns());
601         List orderByColumnsClone = cClone.getOrderByColumns();
602         assertTrue(orderByColumnsClone.contains("Author.NAME DESC"));
603         assertTrue(orderByColumnsClone.contains("Author.AUTHOR_ID ASC"));
604         assertEquals(c.getOrderByColumns(), cClone.getOrderByColumns());
605         Map aliasesClone = cClone.getAliases();
606         assertTrue(aliasesClone.containsKey("Writer"));
607         assertEquals("Author", aliasesClone.get("Writer"));
608         assertEquals(c.getAliases(), cClone.getAliases());
609         Map asColumnsClone = cClone.getAsColumns();
610         assertTrue(asColumnsClone.containsKey("AUTHOR_NAME"));
611         assertEquals("Author.NAME", asColumnsClone.get("AUTHOR_NAME"));
612         assertEquals(c.getAsColumns(), cClone.getAsColumns());
613 
614         // Check Joins
615         List joinsClone = cClone.getJoins();
616         Join joinClone = (Join) joinsClone.get(0);
617         assertEquals("Author.AUTHOR_ID", joinClone.getLeftColumn());
618         assertEquals("Book.AUTHOR_ID", joinClone.getRightColumn());
619         assertEquals(Criteria.INNER_JOIN, joinClone.getJoinType());
620         assertEquals(c.getJoins(), cClone.getJoins());
621 
622         // Some Criterion checks
623         Criterion cnClone = cClone.getCriterion("Author.NAME");
624         assertEquals("author%", cnClone.getValue());
625         assertEquals(Criteria.LIKE, cnClone.getComparison());
626         assertEquals(cn.isIgnoreCase(), cnClone.isIgnoreCase());
627 
628         // Confirm that equals() checks all of the above.
629         assertEquals(c, cClone);
630 
631         // Check hashCode() too.
632         assertEquals(c.hashCode(), cClone.hashCode());
633     }
634 
635     /***
636      * Test that {@link Criteria#equals(Object)} works correctly for a simple
637      * Criteria object.
638      * @throws TorqueException
639      */
640     public void testEquals() throws TorqueException
641     {
642         c.addSelectColumn("Author.NAME");
643         c.addSelectColumn("Author.AUTHOR_ID");
644         c.add("Author.NAME", "foobar");
645         Criteria cClone = (Criteria) SerializationUtils.clone(c);
646         assertTrue(c.equals(cClone));
647     }
648 
649     /***
650      * Checks whether orderBy works.
651      */
652     public void testOrderBy() throws TorqueException
653     {
654         // we need a rudimentary databaseMap for this test case to work
655         DatabaseMap dbMap = Torque.getDatabaseMap(Torque.getDefaultDB());
656 
657         TableMap tableMap = new TableMap("AUTHOR", dbMap);
658         dbMap.addTable(tableMap);
659 
660         ColumnMap columnMap = new ColumnMap("NAME", tableMap);
661         columnMap.setType("");
662         tableMap.addColumn(columnMap);
663 
664         columnMap = new ColumnMap("AUTHOR_ID", tableMap);
665         columnMap.setType(new Integer(0));
666         tableMap.addColumn(columnMap);
667 
668         // check that alias'ed tables are referenced by their alias
669         // name when added to the select clause.
670         Criteria criteria = new Criteria();
671         criteria.addSelectColumn("AUTHOR.NAME");
672         criteria.addAlias("a", "AUTHOR");
673         criteria.addJoin(
674                 "AUTHOR.AUTHOR_ID",
675                 "a." + "AUTHOR_ID");
676         criteria.addAscendingOrderByColumn(
677                 "a.NAME");
678 
679         String result = BasePeer.createQueryString(criteria);
680         assertEquals("SELECT AUTHOR.NAME, a.NAME "
681                     + "FROM AUTHOR, AUTHOR a "
682                     + "WHERE AUTHOR.AUTHOR_ID=a.AUTHOR_ID "
683                     + "ORDER BY a.NAME ASC",
684                 result);
685     }
686 
687 }