xref: /trunk/main/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java (revision 3309286857f19787ae62bd793a98b5af4edd2ad3)
1*f7cf3d52SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f7cf3d52SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f7cf3d52SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f7cf3d52SAndrew Rist  * distributed with this work for additional information
6*f7cf3d52SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f7cf3d52SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f7cf3d52SAndrew Rist  * "License"); you may not use this file except in compliance
9*f7cf3d52SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11*f7cf3d52SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13*f7cf3d52SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f7cf3d52SAndrew Rist  * software distributed under the License is distributed on an
15*f7cf3d52SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f7cf3d52SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f7cf3d52SAndrew Rist  * specific language governing permissions and limitations
18*f7cf3d52SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20*f7cf3d52SAndrew Rist  *************************************************************/
21*f7cf3d52SAndrew Rist 
22*f7cf3d52SAndrew Rist 
23cdf0e10cSrcweir package complex.dbaccess;
24cdf0e10cSrcweir 
25cdf0e10cSrcweir import com.sun.star.beans.PropertyState;
26cdf0e10cSrcweir import com.sun.star.sdb.SQLFilterOperator;
27cdf0e10cSrcweir import com.sun.star.beans.PropertyAttribute;
28cdf0e10cSrcweir import com.sun.star.beans.XPropertySet;
29cdf0e10cSrcweir import com.sun.star.beans.XPropertyContainer;
30cdf0e10cSrcweir import com.sun.star.beans.NamedValue;
31cdf0e10cSrcweir import com.sun.star.container.XNameAccess;
32cdf0e10cSrcweir import com.sun.star.sdbcx.XTablesSupplier;
33cdf0e10cSrcweir import com.sun.star.sdb.XParametersSupplier;
34cdf0e10cSrcweir import com.sun.star.beans.PropertyValue;
35cdf0e10cSrcweir import com.sun.star.sdbcx.XColumnsSupplier;
36cdf0e10cSrcweir import com.sun.star.container.XIndexAccess;
37cdf0e10cSrcweir import com.sun.star.sdb.CommandType;
38cdf0e10cSrcweir import com.sun.star.sdb.XSingleSelectQueryComposer;
39cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
40cdf0e10cSrcweir 
41cdf0e10cSrcweir import com.sun.star.sdbc.DataType;
42cdf0e10cSrcweir import java.lang.reflect.InvocationTargetException;
43cdf0e10cSrcweir import java.lang.reflect.Method;
44cdf0e10cSrcweir 
45cdf0e10cSrcweir // ---------- junit imports -----------------
46cdf0e10cSrcweir import org.junit.Test;
47cdf0e10cSrcweir import static org.junit.Assert.*;
48cdf0e10cSrcweir // ------------------------------------------
49cdf0e10cSrcweir 
50cdf0e10cSrcweir public class SingleSelectQueryComposer extends CRMBasedTestCase
51cdf0e10cSrcweir {
52cdf0e10cSrcweir 
53cdf0e10cSrcweir     private XSingleSelectQueryComposer m_composer = null;
54cdf0e10cSrcweir     private final static String COMPLEXFILTER = "( \"ID\" = 1 AND \"Postal\" = '4' )"
55cdf0e10cSrcweir             + " OR ( \"ID\" = 2 AND \"Postal\" = '5' )"
56cdf0e10cSrcweir             + " OR ( \"ID\" = 3 AND \"Postal\" = '6' AND \"Address\" = '7' )"
57cdf0e10cSrcweir             + " OR ( \"Address\" = '8' )"
58cdf0e10cSrcweir             + " OR ( \"Postal\" = '9' )"
59cdf0e10cSrcweir             + " OR ( NOW( ) = {D '2010-01-01' } )";
60cdf0e10cSrcweir     private final static String INNERPRODUCTSQUERY = "products (inner)";
61cdf0e10cSrcweir 
62cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
createQueries()63cdf0e10cSrcweir     private void createQueries() throws Exception
64cdf0e10cSrcweir     {
65cdf0e10cSrcweir         m_database.getDatabase().getDataSource().createQuery(INNERPRODUCTSQUERY, "SELECT * FROM \"products\"");
66cdf0e10cSrcweir     }
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
69cdf0e10cSrcweir     @Override
createTestCase()70cdf0e10cSrcweir     protected void createTestCase()
71cdf0e10cSrcweir     {
72cdf0e10cSrcweir         try
73cdf0e10cSrcweir         {
74cdf0e10cSrcweir             super.createTestCase();
75cdf0e10cSrcweir 
76cdf0e10cSrcweir             createQueries();
77cdf0e10cSrcweir 
78cdf0e10cSrcweir             m_composer = createQueryComposer();
79cdf0e10cSrcweir 
80cdf0e10cSrcweir         }
81cdf0e10cSrcweir         catch (Exception e)
82cdf0e10cSrcweir         {
83cdf0e10cSrcweir             fail("caught an exception (" + e.getMessage() + ") while creating the test case");
84cdf0e10cSrcweir         }
85cdf0e10cSrcweir     }
86cdf0e10cSrcweir 
87cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
checkAttributeAccess(String _attributeName, String _attributeValue)88cdf0e10cSrcweir     private void checkAttributeAccess(String _attributeName, String _attributeValue)
89cdf0e10cSrcweir     {
90cdf0e10cSrcweir         System.out.println("setting " + _attributeName + " to " + _attributeValue);
91cdf0e10cSrcweir         String realValue = null;
92cdf0e10cSrcweir         try
93cdf0e10cSrcweir         {
94cdf0e10cSrcweir             final Class composerClass = m_composer.getClass();
95cdf0e10cSrcweir             final Method attributeGetter = composerClass.getMethod("get" + _attributeName, new Class[]
96cdf0e10cSrcweir                     {
97cdf0e10cSrcweir                     });
98cdf0e10cSrcweir             final Method attributeSetter = composerClass.getMethod("set" + _attributeName, new Class[]
99cdf0e10cSrcweir                     {
100cdf0e10cSrcweir                         String.class
101cdf0e10cSrcweir                     });
102cdf0e10cSrcweir 
103cdf0e10cSrcweir             attributeSetter.invoke(m_composer, new Object[]
104cdf0e10cSrcweir                     {
105cdf0e10cSrcweir                         _attributeValue
106cdf0e10cSrcweir                     });
107cdf0e10cSrcweir             realValue = (String) attributeGetter.invoke(m_composer, new Object[]
108cdf0e10cSrcweir                     {
109cdf0e10cSrcweir                     });
110cdf0e10cSrcweir         }
111cdf0e10cSrcweir         catch (NoSuchMethodException e)
112cdf0e10cSrcweir         {
113cdf0e10cSrcweir         }
114cdf0e10cSrcweir         catch (IllegalAccessException e)
115cdf0e10cSrcweir         {
116cdf0e10cSrcweir         }
117cdf0e10cSrcweir         catch (InvocationTargetException e)
118cdf0e10cSrcweir         {
119cdf0e10cSrcweir         }
120cdf0e10cSrcweir         assertTrue("set/get" + _attributeName + " not working as expected (set: " + _attributeValue + ", get: " + (realValue != null ? realValue : "null") + ")",
121cdf0e10cSrcweir                 realValue.equals(_attributeValue));
122cdf0e10cSrcweir         System.out.println("  (results in " + m_composer.getQuery() + ")");
123cdf0e10cSrcweir     }
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     /** tests setCommand of the composer
126cdf0e10cSrcweir      */
127cdf0e10cSrcweir     @Test
testSetCommand()128cdf0e10cSrcweir     public void testSetCommand()
129cdf0e10cSrcweir     {
130cdf0e10cSrcweir         System.out.println("testing SingleSelectQueryComposer's setCommand");
131cdf0e10cSrcweir 
132cdf0e10cSrcweir         try
133cdf0e10cSrcweir         {
134cdf0e10cSrcweir             final String table = "SELECT * FROM \"customers\"";
135cdf0e10cSrcweir             m_composer.setCommand("customers", CommandType.TABLE);
136cdf0e10cSrcweir             assertTrue("setCommand/getQuery TABLE inconsistent", m_composer.getQuery().equals(table));
137cdf0e10cSrcweir 
138cdf0e10cSrcweir             m_database.getDatabase().getDataSource().createQuery("set command test", "SELECT * FROM \"orders for customer\" \"a\", \"customers\" \"b\" WHERE \"a\".\"Product Name\" = \"b\".\"Name\"");
139cdf0e10cSrcweir             m_composer.setCommand("set command test", CommandType.QUERY);
140cdf0e10cSrcweir             assertTrue("setCommand/getQuery QUERY inconsistent", m_composer.getQuery().equals(m_database.getDatabase().getDataSource().getQueryDefinition("set command test").getCommand()));
141cdf0e10cSrcweir 
142cdf0e10cSrcweir             final String sql = "SELECT * FROM \"orders for customer\" WHERE \"Product Name\" = 'test'";
143cdf0e10cSrcweir             m_composer.setCommand(sql, CommandType.COMMAND);
144cdf0e10cSrcweir             assertTrue("setCommand/getQuery COMMAND inconsistent", m_composer.getQuery().equals(sql));
145cdf0e10cSrcweir         }
146cdf0e10cSrcweir         catch (Exception e)
147cdf0e10cSrcweir         {
148cdf0e10cSrcweir             fail("Exception caught: " + e);
149cdf0e10cSrcweir         }
150cdf0e10cSrcweir     }
151cdf0e10cSrcweir 
152cdf0e10cSrcweir     /** tests accessing attributes of the composer (order, filter, group by, having)
153cdf0e10cSrcweir      */
154cdf0e10cSrcweir     @Test
testAttributes()155cdf0e10cSrcweir     public void testAttributes()
156cdf0e10cSrcweir     {
157cdf0e10cSrcweir         System.out.println("testing SingleSelectQueryComposer's attributes (order, filter, group by, having)");
158cdf0e10cSrcweir 
159cdf0e10cSrcweir         try
160cdf0e10cSrcweir         {
161cdf0e10cSrcweir             System.out.println("check setElementaryQuery");
162cdf0e10cSrcweir 
163cdf0e10cSrcweir             final String simpleQuery2 = "SELECT * FROM \"customers\" WHERE \"Name\" = 'oranges'";
164cdf0e10cSrcweir             m_composer.setElementaryQuery(simpleQuery2);
165cdf0e10cSrcweir             assertTrue("setElementaryQuery/getQuery inconsistent", m_composer.getQuery().equals(simpleQuery2));
166cdf0e10cSrcweir 
167cdf0e10cSrcweir             System.out.println("check setQuery");
168cdf0e10cSrcweir             final String simpleQuery = "SELECT * FROM \"customers\"";
169cdf0e10cSrcweir             m_composer.setQuery(simpleQuery);
170cdf0e10cSrcweir             assertTrue("set/getQuery inconsistent", m_composer.getQuery().equals(simpleQuery));
171cdf0e10cSrcweir 
172cdf0e10cSrcweir             checkAttributeAccess("Filter", "\"Name\" = 'oranges'");
173cdf0e10cSrcweir             checkAttributeAccess("Group", "\"City\"");
174cdf0e10cSrcweir             checkAttributeAccess("Order", "\"Address\"");
175cdf0e10cSrcweir             checkAttributeAccess("HavingClause", "\"ID\" <> 4");
176cdf0e10cSrcweir 
177cdf0e10cSrcweir             final XIndexAccess orderColumns = m_composer.getOrderColumns();
178cdf0e10cSrcweir             assertTrue("Order columns doesn't exist: \"Address\"",
179cdf0e10cSrcweir             orderColumns != null && orderColumns.getCount() == 1 && orderColumns.getByIndex(0) != null);
180cdf0e10cSrcweir 
181cdf0e10cSrcweir             final XIndexAccess groupColumns = m_composer.getGroupColumns();
182cdf0e10cSrcweir             assertTrue("Group columns doesn't exist: \"City\"",
183cdf0e10cSrcweir             groupColumns != null && groupColumns.getCount() == 1 && groupColumns.getByIndex(0) != null);
184cdf0e10cSrcweir 
185cdf0e10cSrcweir             // XColumnsSupplier
186cdf0e10cSrcweir             final XColumnsSupplier xSelectColumns = UnoRuntime.queryInterface(XColumnsSupplier.class, m_composer);
187cdf0e10cSrcweir             assertTrue("no select columns, or wrong number of select columns",
188cdf0e10cSrcweir             xSelectColumns != null && xSelectColumns.getColumns() != null && xSelectColumns.getColumns().getElementNames().length == 6);
189cdf0e10cSrcweir 
190cdf0e10cSrcweir             // structured filter
191cdf0e10cSrcweir             m_composer.setQuery("SELECT \"ID\", \"Postal\", \"Address\" FROM \"customers\"");
192cdf0e10cSrcweir             m_composer.setFilter(COMPLEXFILTER);
193cdf0e10cSrcweir             final PropertyValue[][] aStructuredFilter = m_composer.getStructuredFilter();
194cdf0e10cSrcweir             m_composer.setFilter("");
195cdf0e10cSrcweir             m_composer.setStructuredFilter(aStructuredFilter);
196cdf0e10cSrcweir             if (!m_composer.getFilter().equals(COMPLEXFILTER))
197cdf0e10cSrcweir             {
198cdf0e10cSrcweir                 System.out.println(COMPLEXFILTER);
199cdf0e10cSrcweir                 System.out.println(m_composer.getFilter());
200cdf0e10cSrcweir             }
201cdf0e10cSrcweir             assertTrue("Structured Filter not identical", m_composer.getFilter().equals(COMPLEXFILTER));
202cdf0e10cSrcweir 
203cdf0e10cSrcweir             // structured having clause
204cdf0e10cSrcweir             m_composer.setHavingClause(COMPLEXFILTER);
205cdf0e10cSrcweir             final PropertyValue[][] aStructuredHaving = m_composer.getStructuredHavingClause();
206cdf0e10cSrcweir             m_composer.setHavingClause("");
207cdf0e10cSrcweir             m_composer.setStructuredHavingClause(aStructuredHaving);
208cdf0e10cSrcweir             assertTrue("Structured Having Clause not identical", m_composer.getHavingClause().equals(COMPLEXFILTER));
209cdf0e10cSrcweir         }
210cdf0e10cSrcweir         catch (Exception e)
211cdf0e10cSrcweir         {
212cdf0e10cSrcweir             fail("Exception caught: " + e);
213cdf0e10cSrcweir         }
214cdf0e10cSrcweir     }
215cdf0e10cSrcweir 
216cdf0e10cSrcweir     /** test various sub query related features ("queries in queries")
217cdf0e10cSrcweir      */
218cdf0e10cSrcweir     @Test
testSubQueries()219cdf0e10cSrcweir     public void testSubQueries() throws Exception
220cdf0e10cSrcweir     {
221cdf0e10cSrcweir         m_composer.setQuery("SELECT * from \"" + INNERPRODUCTSQUERY + "\"");
222cdf0e10cSrcweir         final XTablesSupplier suppTables = UnoRuntime.queryInterface(XTablesSupplier.class, m_composer);
223cdf0e10cSrcweir         final XNameAccess tables = suppTables.getTables();
224cdf0e10cSrcweir         assertTrue("a simple SELECT * FROM <query> could not be parsed",
225cdf0e10cSrcweir                 tables != null && tables.hasByName(INNERPRODUCTSQUERY));
226cdf0e10cSrcweir 
227cdf0e10cSrcweir         final String sInnerCommand = m_database.getDatabase().getDataSource().getQueryDefinition(INNERPRODUCTSQUERY).getCommand();
228cdf0e10cSrcweir         final String sExecutableQuery = m_composer.getQueryWithSubstitution();
229cdf0e10cSrcweir         assertTrue("simple query containing a sub query improperly parsed to SDBC level statement: \n1. " + sExecutableQuery + "\n2. " + "SELECT * FROM ( " + sInnerCommand + " ) AS \"" + INNERPRODUCTSQUERY + "\"",
230cdf0e10cSrcweir                 sExecutableQuery.equals("SELECT * FROM ( " + sInnerCommand + " ) AS \"" + INNERPRODUCTSQUERY + "\""));
231cdf0e10cSrcweir     }
232cdf0e10cSrcweir 
233cdf0e10cSrcweir     /** tests the XParametersSupplier functionality
234cdf0e10cSrcweir      */
235cdf0e10cSrcweir     @Test
testParameters()236cdf0e10cSrcweir     public void testParameters()
237cdf0e10cSrcweir     {
238cdf0e10cSrcweir         try
239cdf0e10cSrcweir         {
240cdf0e10cSrcweir             // "orders for customers" is a query with a named parameter (based on another query)
241cdf0e10cSrcweir             m_database.getDatabase().getDataSource().createQuery("orders for customer", "SELECT * FROM \"all orders\" WHERE \"Customer Name\" LIKE :cname");
242cdf0e10cSrcweir             // "orders for customer and product" is query based on "orders for customers", adding an additional,
243cdf0e10cSrcweir             // anonymous parameter
244cdf0e10cSrcweir             m_database.getDatabase().getDataSource().createQuery("orders for customer and product", "SELECT * FROM \"orders for customer\" WHERE \"Product Name\" LIKE ?");
245cdf0e10cSrcweir 
246cdf0e10cSrcweir             m_composer.setQuery(m_database.getDatabase().getDataSource().getQueryDefinition("orders for customer and product").getCommand());
247cdf0e10cSrcweir             final XParametersSupplier suppParams = UnoRuntime.queryInterface(XParametersSupplier.class, m_composer);
248cdf0e10cSrcweir             final XIndexAccess parameters = suppParams.getParameters();
249cdf0e10cSrcweir 
250cdf0e10cSrcweir             final String expectedParamNames[] =
251cdf0e10cSrcweir 
252cdf0e10cSrcweir             {
253cdf0e10cSrcweir                 "cname",
254cdf0e10cSrcweir                 "Product Name"
255cdf0e10cSrcweir             };
256cdf0e10cSrcweir 
257cdf0e10cSrcweir             final int paramCount = parameters.getCount();
258cdf0e10cSrcweir             assertTrue("composer did find wrong number of parameters in the nested queries.",
259cdf0e10cSrcweir                     paramCount == expectedParamNames.length);
260cdf0e10cSrcweir 
261cdf0e10cSrcweir             for (int i = 0; i < paramCount; ++i)
262cdf0e10cSrcweir             {
263cdf0e10cSrcweir                 final XPropertySet parameter = UnoRuntime.queryInterface(XPropertySet.class, parameters.getByIndex(i));
264cdf0e10cSrcweir                 final String paramName = (String) parameter.getPropertyValue("Name");
265cdf0e10cSrcweir                 assertTrue("wrong parameter name at position " + (i + 1) + " (expected: " + expectedParamNames[i] + ", found: " + paramName + ")",
266cdf0e10cSrcweir                         paramName.equals(expectedParamNames[i]));
267cdf0e10cSrcweir 
268cdf0e10cSrcweir             }
269cdf0e10cSrcweir         }
270cdf0e10cSrcweir         catch (Exception e)
271cdf0e10cSrcweir         {
272cdf0e10cSrcweir             fail("caught an exception: " + e);
273cdf0e10cSrcweir         }
274cdf0e10cSrcweir     }
275cdf0e10cSrcweir 
276cdf0e10cSrcweir     @Test
testConditionByColumn()277cdf0e10cSrcweir     public void testConditionByColumn()
278cdf0e10cSrcweir     {
279cdf0e10cSrcweir         try
280cdf0e10cSrcweir         {
281cdf0e10cSrcweir             m_composer.setQuery("SELECT * FROM \"customers\"");
282cdf0e10cSrcweir 
283cdf0e10cSrcweir             final Object initArgs[] =
284cdf0e10cSrcweir 
285cdf0e10cSrcweir             {
286cdf0e10cSrcweir                 new NamedValue("AutomaticAddition", Boolean.valueOf(true))
287cdf0e10cSrcweir             };
288cdf0e10cSrcweir             final String serviceName = "com.sun.star.beans.PropertyBag";
289cdf0e10cSrcweir             final XPropertyContainer filter = UnoRuntime.queryInterface(XPropertyContainer.class, getMSF().createInstanceWithArguments(serviceName, initArgs));
290cdf0e10cSrcweir             filter.addProperty("Name", PropertyAttribute.MAYBEVOID, "Comment");
291cdf0e10cSrcweir             filter.addProperty("RealName", PropertyAttribute.MAYBEVOID, "Comment");
292cdf0e10cSrcweir             filter.addProperty("TableName", PropertyAttribute.MAYBEVOID, "customers");
293cdf0e10cSrcweir             filter.addProperty("Value", PropertyAttribute.MAYBEVOID, "Good one.");
294cdf0e10cSrcweir             filter.addProperty("Type", PropertyAttribute.MAYBEVOID, Integer.valueOf(DataType.LONGVARCHAR));
295cdf0e10cSrcweir             final XPropertySet column = UnoRuntime.queryInterface(XPropertySet.class, filter);
296cdf0e10cSrcweir 
297cdf0e10cSrcweir             m_composer.appendFilterByColumn(column, true, SQLFilterOperator.LIKE);
298cdf0e10cSrcweir             assertTrue("At least one row should exist", m_database.getConnection().createStatement().executeQuery(m_composer.getQuery()).next());
299cdf0e10cSrcweir 
300cdf0e10cSrcweir         }
301cdf0e10cSrcweir         catch (Exception e)
302cdf0e10cSrcweir         {
303cdf0e10cSrcweir             // this is an error: the query is expected to be parseable
304cdf0e10cSrcweir             fail("caught an exception: " + e);
305cdf0e10cSrcweir         }
306cdf0e10cSrcweir     }
307cdf0e10cSrcweir 
impl_testDisjunctiveNormalForm(String _query, PropertyValue[][] _expectedDNF)308cdf0e10cSrcweir     private void impl_testDisjunctiveNormalForm(String _query, PropertyValue[][] _expectedDNF)
309cdf0e10cSrcweir     {
310cdf0e10cSrcweir         try
311cdf0e10cSrcweir         {
312cdf0e10cSrcweir             m_composer.setQuery(_query);
313cdf0e10cSrcweir         }
314cdf0e10cSrcweir         catch (Exception e)
315cdf0e10cSrcweir         {
316cdf0e10cSrcweir             // this is an error: the query is expected to be parseable
317cdf0e10cSrcweir             fail("caught an exception: " + e);
318cdf0e10cSrcweir         }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir         final PropertyValue[][] disjunctiveNormalForm = m_composer.getStructuredFilter();
321cdf0e10cSrcweir 
322cdf0e10cSrcweir         assertEquals("DNF: wrong number of rows", _expectedDNF.length, disjunctiveNormalForm.length);
323cdf0e10cSrcweir         for (int i = 0; i < _expectedDNF.length; ++i)
324cdf0e10cSrcweir         {
325cdf0e10cSrcweir             assertEquals("DNF: wrong number of columns in row " + i, _expectedDNF[i].length, disjunctiveNormalForm[i].length);
326cdf0e10cSrcweir             for (int j = 0; j < _expectedDNF[i].length; ++j)
327cdf0e10cSrcweir             {
328cdf0e10cSrcweir                 assertEquals("DNF: wrong content in column " + j + ", row " + i,
329cdf0e10cSrcweir                         _expectedDNF[i][j].Name, disjunctiveNormalForm[i][j].Name);
330cdf0e10cSrcweir             }
331cdf0e10cSrcweir         }
332cdf0e10cSrcweir     }
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     /** tests the disjunctive normal form functionality, aka the structured filter,
335cdf0e10cSrcweir      *  of the composer
336cdf0e10cSrcweir      */
337cdf0e10cSrcweir     @Test
testDisjunctiveNormalForm()338cdf0e10cSrcweir     public void testDisjunctiveNormalForm()
339cdf0e10cSrcweir     {
340cdf0e10cSrcweir         // a simple case: WHERE clause simply is a combination of predicates knitted with AND
341cdf0e10cSrcweir         String query =
342cdf0e10cSrcweir                 "SELECT \"customers\".\"Name\", "
343cdf0e10cSrcweir                 + "\"customers\".\"Address\", "
344cdf0e10cSrcweir                 + "\"customers\".\"City\", "
345cdf0e10cSrcweir                 + "\"customers\".\"Postal\", "
346cdf0e10cSrcweir                 + "\"products\".\"Name\" "
347cdf0e10cSrcweir                 + "FROM \"orders\", \"customers\", \"orders_details\", \"products\" "
348cdf0e10cSrcweir                 + "WHERE (   \"orders\".\"CustomerID\" = \"customers\".\"ID\" "
349cdf0e10cSrcweir                 + "AND \"orders_details\".\"OrderID\" = \"orders\".\"ID\" "
350cdf0e10cSrcweir                 + "AND \"orders_details\".\"ProductID\" = \"products\".\"ID\" "
351cdf0e10cSrcweir                 + ") ";
352cdf0e10cSrcweir 
353cdf0e10cSrcweir         impl_testDisjunctiveNormalForm(query, new PropertyValue[][]
354cdf0e10cSrcweir                 {
355cdf0e10cSrcweir                     new PropertyValue[]
356cdf0e10cSrcweir                     {
357cdf0e10cSrcweir                         new PropertyValue("CustomerID", SQLFilterOperator.EQUAL, "\"customers\".\"ID\"", PropertyState.DIRECT_VALUE),
358cdf0e10cSrcweir                         new PropertyValue("OrderID", SQLFilterOperator.EQUAL, "\"orders\".\"ID\"", PropertyState.DIRECT_VALUE),
359cdf0e10cSrcweir                         new PropertyValue("ProductID", SQLFilterOperator.EQUAL, "\"products\".\"ID\"", PropertyState.DIRECT_VALUE)
360cdf0e10cSrcweir                     }
361cdf0e10cSrcweir                 });
362cdf0e10cSrcweir 
363cdf0e10cSrcweir         // somewhat more challenging: One of the conjunction terms is a disjunction itself
364cdf0e10cSrcweir         query =
365cdf0e10cSrcweir                 "SELECT \"customers\".\"Name\", "
366cdf0e10cSrcweir                 + "\"customers\".\"Address\", "
367cdf0e10cSrcweir                 + "\"customers\".\"City\", "
368cdf0e10cSrcweir                 + "\"customers\".\"Postal\", "
369cdf0e10cSrcweir                 + "\"products\".\"Name\" "
370cdf0e10cSrcweir                 + "FROM \"orders\", \"customers\", \"orders_details\", \"products\" "
371cdf0e10cSrcweir                 + "WHERE (   \"orders\".\"CustomerID\" = \"customers\".\"ID\" "
372cdf0e10cSrcweir                 + "AND \"orders_details\".\"OrderID\" = \"orders\".\"ID\" "
373cdf0e10cSrcweir                 + "AND \"orders_details\".\"ProductID\" = \"products\".\"ID\" "
374cdf0e10cSrcweir                 + ") "
375cdf0e10cSrcweir                 + "AND "
376cdf0e10cSrcweir                 + "(  \"products\".\"Name\" = 'Apples' "
377cdf0e10cSrcweir                 + "OR \"products\".\"ID\" = 2 "
378cdf0e10cSrcweir                 + ")";
379cdf0e10cSrcweir 
380cdf0e10cSrcweir         impl_testDisjunctiveNormalForm(query, new PropertyValue[][]
381cdf0e10cSrcweir                 {
382cdf0e10cSrcweir                     new PropertyValue[]
383cdf0e10cSrcweir                     {
384cdf0e10cSrcweir                         new PropertyValue("CustomerID", SQLFilterOperator.EQUAL, "\"customers\".\"ID\"", PropertyState.DIRECT_VALUE),
385cdf0e10cSrcweir                         new PropertyValue("OrderID", SQLFilterOperator.EQUAL, "\"orders\".\"ID\"", PropertyState.DIRECT_VALUE),
386cdf0e10cSrcweir                         new PropertyValue("ProductID", SQLFilterOperator.EQUAL, "\"products\".\"ID\"", PropertyState.DIRECT_VALUE),
387cdf0e10cSrcweir                         new PropertyValue("Name", SQLFilterOperator.EQUAL, "Apples", PropertyState.DIRECT_VALUE)
388cdf0e10cSrcweir                     },
389cdf0e10cSrcweir                     new PropertyValue[]
390cdf0e10cSrcweir                     {
391cdf0e10cSrcweir                         new PropertyValue("CustomerID", SQLFilterOperator.EQUAL, "\"customers\".\"ID\"", PropertyState.DIRECT_VALUE),
392cdf0e10cSrcweir                         new PropertyValue("OrderID", SQLFilterOperator.EQUAL, "\"orders\".\"ID\"", PropertyState.DIRECT_VALUE),
393cdf0e10cSrcweir                         new PropertyValue("ProductID", SQLFilterOperator.EQUAL, "\"products\".\"ID\"", PropertyState.DIRECT_VALUE),
394cdf0e10cSrcweir                         new PropertyValue("ID", SQLFilterOperator.EQUAL, Integer.valueOf(2), PropertyState.DIRECT_VALUE)
395cdf0e10cSrcweir                     }
396cdf0e10cSrcweir                 });
397cdf0e10cSrcweir 
398cdf0e10cSrcweir     }
399cdf0e10cSrcweir }
400