1   package uba.db.sql.parser.impl;
2   
3   import java.io.StringReader;
4   
5   import junit.framework.TestCase;
6   import uba.db.sql.language.BooleanValue;
7   import uba.db.sql.language.ColumnName;
8   import uba.db.sql.language.ColumnReference;
9   import uba.db.sql.language.DisplayColumns;
10  import uba.db.sql.language.DisplayOneColumn;
11  import uba.db.sql.language.EqualComparison;
12  import uba.db.sql.language.GreatherThanComparison;
13  import uba.db.sql.language.GreatherThanEqualsComparison;
14  import uba.db.sql.language.IntegerValue;
15  import uba.db.sql.language.Join;
16  import uba.db.sql.language.LessThanComparison;
17  import uba.db.sql.language.LessThanEqualsComparison;
18  import uba.db.sql.language.SelectionCriteria;
19  import uba.db.sql.language.SelectionSource;
20  import uba.db.sql.language.SingleSelectionCriteria;
21  import uba.db.sql.language.SingleValue;
22  import uba.db.sql.language.StringValue;
23  import uba.db.sql.language.TableName;
24  import uba.db.sql.language.TableSelectionSource;
25  import uba.db.sql.language.ValueEnumeration;
26  import uba.db.testhelpers.TestUtils;
27  
28  /***
29   * Test de cada una de las reglas del parser.
30   * 
31   * @version $Revision: 1.7 $
32   */
33  public class SQLParserTest extends TestCase {
34      private static final SingleSelectionCriteria E_EQUALS_F = new SingleSelectionCriteria(
35              new EqualComparison(new ColumnName("e"), new ColumnName("f")));
36      private static final SingleSelectionCriteria C_EQUALS_D = new SingleSelectionCriteria(
37              new EqualComparison(new ColumnName("c"), new ColumnName("d")));
38      private static final SingleSelectionCriteria A_EQUALS_B = new SingleSelectionCriteria(
39              new EqualComparison(new ColumnName("a"), new ColumnName("b")));
40  
41      /***
42       * Test de la regla comparison, con numeros
43       */
44      public void testComparisonWithNumberLiterals() throws Exception {
45          BooleanValue result = parserFor("1=2").comparison();
46          EqualComparison expected = new EqualComparison(new IntegerValue(1),
47                  new IntegerValue(2));
48  
49          assertEquals(expected, result);
50      }
51  
52      /***
53       * Test: parsear una expresion de comparacion con una referencia a una
54       * columna.
55       */
56      public void testComparisonWithColumnReferences() throws Exception {
57          BooleanValue result = parserFor("col1=2").comparison();
58          EqualComparison expected = new EqualComparison(new ColumnName("col1"),
59                  new IntegerValue(2));
60          assertEquals(expected, result);
61  
62          result = parserFor("T.col1=2").comparison();
63          expected = new EqualComparison(new TableName("T").column("col1"),
64                  new IntegerValue(2));
65          assertEquals(expected, result);
66      }
67  
68      private SQLParser parserFor(String text) {
69          SQLLexer lexer = new SQLLexer(new StringReader(text));
70          SQLParser parser = new SQLParser(lexer);
71          return parser;
72      }
73  
74      /***
75       * Test de la regla booleanExpression, con string.
76       */
77      public void testComparisonWithStringLiterals() throws Exception {
78          BooleanValue result = parserFor("'abc' = 'a'").comparison();
79          EqualComparison expected = new EqualComparison(new StringValue("abc"),
80                  new StringValue("a"));
81  
82          assertEquals(expected, result);
83      }
84  
85      /***
86       * Test: parsear un string entre comillas simples con caracteres de escape.
87       */
88      public void testQuotedStringLiteral() throws Exception {
89          SingleValue result = parserFor("'//'hola//' mundo'").literal();
90          StringValue expected = new StringValue("'hola' mundo");
91  
92          assertEquals(expected, result);
93      }
94  
95      /***
96       * Test: parsear una expresion del tipo a < b
97       */
98      public void testLessThan() throws Exception {
99          BooleanValue result = parserFor("1 < 2").comparison();
100         LessThanComparison expected = new LessThanComparison(new IntegerValue(1),
101                 new IntegerValue(2));
102 
103         assertEquals(expected, result);
104     }
105 
106     /***
107      * Test: parsear una expresion del tipo a > b
108      */
109     public void testGreatherThan() throws Exception {
110         BooleanValue result = parserFor("1 > 2").comparison();
111         GreatherThanComparison expected = new GreatherThanComparison(new IntegerValue(1),
112                 new IntegerValue(2));
113 
114         assertEquals(expected, result);
115     }
116 
117     /***
118      * Test: parsear una expresion del tipo a <= b
119      */
120     public void testLessThanEquals() throws Exception {
121         BooleanValue result = parserFor("1 <= 2").comparison();
122         LessThanEqualsComparison expected = new LessThanEqualsComparison(
123                 new IntegerValue(1), new IntegerValue(2));
124 
125         assertEquals(expected, result);
126     }
127 
128     /***
129      * Test: parsear una expresion del tipo a >= b
130      */
131     public void testGreatherThanEquals() throws Exception {
132         BooleanValue result = parserFor("1 >= 2").comparison();
133         GreatherThanEqualsComparison expected = new GreatherThanEqualsComparison(
134                 new IntegerValue(1), new IntegerValue(2));
135 
136         assertEquals(expected, result);
137     }
138 
139     /***
140      * Test: parsear un nombre de columna.
141      */
142     public void testColumnName() throws Exception {
143         ColumnReference result = parserFor("columnName").columnReference();
144         ColumnName expected = new ColumnName("columnName");
145 
146         assertEquals(expected, result);
147     }
148 
149     /***
150      * Test: parsear un nombre de columna entre comillas
151      */
152     public void testColumnNameWithQuotes() throws Exception {
153         ColumnReference result = parserFor("\"columnName con espacios\"")
154                 .columnReference();
155         ColumnName expected = new ColumnName("columnName con espacios");
156 
157         assertEquals(expected, result);
158     }
159 
160     /***
161      * Test: parsear un nombre de columna entre comillas (como si fuese un
162      * valor).
163      */
164     public void testSingleValue() throws Exception {
165         SingleValue result = parserFor("\"columnName con espacios\"").singleValue();
166         SingleValue expected = new ColumnName("columnName con espacios");
167 
168         assertEquals(expected, result);
169     }
170 
171     /***
172      * Test: parsear una enumeracion de valores literales.
173      */
174     public void testValueEnumeration() throws Exception {
175         ValueEnumeration result = parserFor("(1,2,3)").valueEnumeration();
176         ValueEnumeration expected = new ValueEnumeration(TestUtils.list(new IntegerValue(
177                 1), new IntegerValue(2), new IntegerValue(3)));
178 
179         assertEquals(expected, result);
180     }
181 
182     /***
183      * Test: parsear "display columns" de literales.
184      */
185     public void testDisplayColumnsWithLiterals() throws Exception {
186         DisplayColumns result = parserFor("col,'hola'").displayColumns();
187         DisplayColumns expected = new DisplayOneColumn(new ColumnName("col"))
188                 .append(new DisplayOneColumn(new StringValue("hola")));
189 
190         assertEquals(expected, result);
191     }
192 
193     /***
194      * Test: parsear las tablas en un FROM.
195      */
196     public void testSelectionSource() throws Exception {
197         SelectionSource result = parserFor("t1,t2").selectionSource();
198         SelectionSource expected = new Join(new TableSelectionSource("t1"),
199                 new TableSelectionSource("t2"));
200 
201         assertEquals(expected, result);
202     }
203 
204     /***
205      * Test: parsear un WHERE de una sola condicion.
206      */
207     public void testSingleConditionSelectionCriteria() throws Exception {
208         SelectionCriteria result = parserFor("a = b").selectionCriteria();
209         SelectionCriteria expected = A_EQUALS_B;
210 
211         assertEquals(expected, result);
212     }
213 
214     /***
215      * Test: parsear un WHERE con un AND.
216      */
217     public void testAndConditionSelectionCriteria() throws Exception {
218         SelectionCriteria result = parserFor("a = b AND c = d").selectionCriteria();
219         SelectionCriteria expected = A_EQUALS_B.and(C_EQUALS_D);
220 
221         assertEquals(expected, result);
222     }
223 
224     /***
225      * Test: parsear un WHERE con un OR.
226      */
227     public void testOrConditionSelectionCriteria() throws Exception {
228         SelectionCriteria result = parserFor("a = b OR c = d").selectionCriteria();
229         SelectionCriteria expected = A_EQUALS_B.or(C_EQUALS_D);
230 
231         assertEquals(expected, result);
232     }
233 
234     /***
235      * Test: parsear un WHERE con un OR y AND.
236      */
237     public void testAndOrConditionSelectionCriteria() throws Exception {
238         SelectionCriteria result = parserFor("a = b OR c = d AND e = f")
239                 .selectionCriteria();
240         SelectionCriteria expected = A_EQUALS_B.or(C_EQUALS_D).and(E_EQUALS_F);
241 
242         assertEquals(expected, result);
243     }
244 
245     /***
246      * Test: parsear un WHERE con un OR y AND (estableciendo la precedencia con
247      * parentesis).
248      */
249     public void testAndOrSelectionCriteriaWithParens() throws Exception {
250         SelectionCriteria result = parserFor("a = b OR (c = d AND e = f)")
251                 .selectionCriteria();
252         SelectionCriteria expected = A_EQUALS_B.or(C_EQUALS_D.and(E_EQUALS_F));
253 
254         assertEquals(expected, result);
255     }
256 
257     /***
258      * Test: parsear un WHERE con la condicion negada.
259      */
260     public void testNegatedSelectionCriteria() throws Exception {
261         SelectionCriteria result = parserFor("NOT a = b").selectionCriteria();
262         SelectionCriteria expected = A_EQUALS_B.not();
263 
264         assertEquals(expected, result);
265     }
266 
267     /***
268      * Test: precedencia del NOT con el AND
269      */
270     public void testNegationPrecedence() throws Exception {
271         SelectionCriteria result = parserFor("NOT a = b AND c = d").selectionCriteria();
272         SelectionCriteria expected = A_EQUALS_B.not().and(C_EQUALS_D);
273 
274         assertEquals(expected, result);
275 
276         result = parserFor("NOT (NOT a = b AND c = d)").selectionCriteria();
277         expected = (A_EQUALS_B.not().and(C_EQUALS_D)).not();
278 
279         assertEquals(expected, result);
280 
281     }
282 
283     /***
284      * Test: cambiar la precedencia del NOT usando parentesis.
285      */
286     public void testNegationPrecedenceWithParens() throws Exception {
287         SelectionCriteria result = parserFor("NOT (a = b AND c = d)").selectionCriteria();
288         SelectionCriteria expected = (A_EQUALS_B.and(C_EQUALS_D)).not();
289 
290         assertEquals(expected, result);
291     }
292 }