xref: /AOO42X/main/dbaccess/qa/complex/dbaccess/Parser.java (revision b0efeae40e43e6d4ccd561d22ec612d42773857b)
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.XPropertySet;
26cdf0e10cSrcweir import com.sun.star.container.XIndexAccess;
27cdf0e10cSrcweir import com.sun.star.sdb.XParametersSupplier;
28cdf0e10cSrcweir import com.sun.star.sdb.XSingleSelectQueryComposer;
29cdf0e10cSrcweir import com.sun.star.sdbc.DataType;
30cdf0e10cSrcweir import com.sun.star.sdbc.SQLException;
31cdf0e10cSrcweir import com.sun.star.uno.Exception;
32cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime;
33cdf0e10cSrcweir 
34cdf0e10cSrcweir 
35cdf0e10cSrcweir // ---------- junit imports -----------------
36cdf0e10cSrcweir import org.junit.Test;
37cdf0e10cSrcweir import static org.junit.Assert.*;
38cdf0e10cSrcweir // ------------------------------------------
39cdf0e10cSrcweir 
40cdf0e10cSrcweir public class Parser extends CRMBasedTestCase
41cdf0e10cSrcweir {
42cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
43cdf0e10cSrcweir     @Override
createTestCase()44cdf0e10cSrcweir     protected void createTestCase()
45cdf0e10cSrcweir     {
46cdf0e10cSrcweir         try
47cdf0e10cSrcweir         {
48cdf0e10cSrcweir             super.createTestCase();
49cdf0e10cSrcweir             m_database.getDatabase().getDataSource().createQuery( "query products", "SELECT * FROM \"products\"" );
50cdf0e10cSrcweir         }
51cdf0e10cSrcweir         catch ( Exception e )
52cdf0e10cSrcweir         {
53cdf0e10cSrcweir             e.printStackTrace( System.err );
54cdf0e10cSrcweir             fail( "caught an exception (" + e.getMessage() + ") while creating the test case");
55cdf0e10cSrcweir         }
56cdf0e10cSrcweir     }
57cdf0e10cSrcweir 
58cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
59cdf0e10cSrcweir     @Test
checkWhere()60cdf0e10cSrcweir     public void checkWhere() throws Exception
61cdf0e10cSrcweir     {
62cdf0e10cSrcweir         final XSingleSelectQueryComposer composer = createQueryComposer();
63cdf0e10cSrcweir         final String SELECT = "SELECT \"products\".\"Name\" FROM \"products\" WHERE ";
64cdf0e10cSrcweir         final String[] queries = new String[]
65cdf0e10cSrcweir         {
66cdf0e10cSrcweir              "\"ID\" in ( 1,2,3,4)"
67cdf0e10cSrcweir             ,"not ( \"ID\" in ( 1,2,3,4))"
68cdf0e10cSrcweir             ,"(1 = 1) is true"
69cdf0e10cSrcweir             ,"(1 = 1) is not false"
70cdf0e10cSrcweir             ,"(1 = 1) is not null"
71cdf0e10cSrcweir             ,"not ( (1 = 1) is not null)"
72cdf0e10cSrcweir             ,"'a' like 'a%'"
73cdf0e10cSrcweir             ,"not ( 'a' like 'a%')"
74cdf0e10cSrcweir             ,"'a' not like 'a%'"
75cdf0e10cSrcweir             ,"1 between 0 and 2"
76cdf0e10cSrcweir             ,"not ( 1 between 0 and 2 )"
77cdf0e10cSrcweir             ,"1 not between 3 and 4"
78cdf0e10cSrcweir             ,"1 not between ( select \"ID\" from \"categories\") and ( select \"ID\" from \"categories\")"
79cdf0e10cSrcweir             ,"1 = 1"
80cdf0e10cSrcweir             ,"0 < 1"
81cdf0e10cSrcweir             ,"not(0 < 1)"
82cdf0e10cSrcweir             ,"1 > 0"
83cdf0e10cSrcweir             ,"not(1 > 0)"
84cdf0e10cSrcweir             ,"1 <> 0"
85cdf0e10cSrcweir             ,"(1 <> 0 and 'a' = 'a' and 'c' = 'd') or (1 = 1 and 2 = 2 and 3 = 4)"
86cdf0e10cSrcweir             ,"not ( 1 <> 0 )"
87cdf0e10cSrcweir             ,"\"CategoryID\" in ( select \"ID\" from \"categories\")"
88cdf0e10cSrcweir             ,"not (\"CategoryID\" in ( select \"ID\" from \"categories\"))"
89cdf0e10cSrcweir             ,"\"CategoryID\" not in ( select \"ID\" from \"categories\")"
90cdf0e10cSrcweir         };
91cdf0e10cSrcweir         for (int i = 0; i < queries.length; i++)
92cdf0e10cSrcweir         {
93cdf0e10cSrcweir             composer.setQuery( SELECT + queries[i]);
94cdf0e10cSrcweir         }
95cdf0e10cSrcweir     }
96cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
97cdf0e10cSrcweir     /** verifies that aliases for inner queries work as expected
98cdf0e10cSrcweir      */
99cdf0e10cSrcweir     @Test
checkJoinSyntax()100cdf0e10cSrcweir     public void checkJoinSyntax() throws Exception
101cdf0e10cSrcweir     {
102cdf0e10cSrcweir         final XSingleSelectQueryComposer composer = createQueryComposer();
103cdf0e10cSrcweir 
104cdf0e10cSrcweir         // feed the composer with some statements. If any of those cannot be parsed, the composer
105cdf0e10cSrcweir         // will throw an exception - which is a regression then
106cdf0e10cSrcweir         composer.setQuery(
107cdf0e10cSrcweir             "SELECT \"categories\".\"Name\", " +
108cdf0e10cSrcweir                     "\"products\".\"Name\" " +
109cdf0e10cSrcweir             "FROM \"products\" RIGHT OUTER JOIN \"categories\" AS \"categories\" ON \"products\".\"CategoryID\" = \"categories\".\"ID\"" );
110cdf0e10cSrcweir 
111cdf0e10cSrcweir         composer.setQuery(
112cdf0e10cSrcweir             "SELECT \"categories\".\"Name\", " +
113cdf0e10cSrcweir                     "\"products\".\"Name\" " +
114cdf0e10cSrcweir             "FROM \"products\" LEFT OUTER JOIN \"categories\" AS \"categories\" ON \"products\".\"CategoryID\" = \"categories\".\"ID\"" );
115cdf0e10cSrcweir 
116cdf0e10cSrcweir         composer.setQuery(
117cdf0e10cSrcweir             "SELECT \"categories\".\"Name\", " +
118cdf0e10cSrcweir                     "\"products\".\"Name\" " +
119cdf0e10cSrcweir             "FROM \"products\" CROSS JOIN \"categories\" AS \"categories\"" );
120cdf0e10cSrcweir 
121cdf0e10cSrcweir         composer.setQuery(
122cdf0e10cSrcweir             "SELECT \"categories\".\"Name\", " +
123cdf0e10cSrcweir                     "\"products\".\"Name\" " +
124cdf0e10cSrcweir             "FROM \"products\" INNER JOIN \"categories\" AS \"categories\" ON \"products\".\"CategoryID\" = \"categories\".\"ID\"" );
125cdf0e10cSrcweir 
126cdf0e10cSrcweir         // just to be sure the composer *really* parses upon setting the query: feed it with
127cdf0e10cSrcweir         // an unparseable statement
128cdf0e10cSrcweir         boolean caughtExpected = false;
129cdf0e10cSrcweir         try
130cdf0e10cSrcweir         {
131cdf0e10cSrcweir             composer.setQuery( "NONSENSE" );
132cdf0e10cSrcweir         }
133cdf0e10cSrcweir         catch( SQLException e )
134cdf0e10cSrcweir         {
135cdf0e10cSrcweir             caughtExpected = true;
136cdf0e10cSrcweir         }
137cdf0e10cSrcweir         assertTrue( "pre-condition not met: parser should except on unparseable statements, else the complete" +
138cdf0e10cSrcweir             "test is bogus!", caughtExpected );
139cdf0e10cSrcweir     }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
impl_checkParameters( final String _statement, final String[] _expectedParameterNames, final int[] _expectedParameterTypes,final String _context )142cdf0e10cSrcweir     private void impl_checkParameters( final String _statement, final String[] _expectedParameterNames, final int[] _expectedParameterTypes,final String _context ) throws Exception
143cdf0e10cSrcweir     {
144cdf0e10cSrcweir         final XSingleSelectQueryComposer composer = createQueryComposer();
145cdf0e10cSrcweir         composer.setQuery( _statement );
146cdf0e10cSrcweir 
147cdf0e10cSrcweir         assertEquals( "checkParameterTypes: internal error", _expectedParameterNames.length, _expectedParameterTypes.length );
148cdf0e10cSrcweir 
149cdf0e10cSrcweir         final XParametersSupplier paramSupp = UnoRuntime.queryInterface(XParametersSupplier.class, composer);
150cdf0e10cSrcweir         final XIndexAccess parameters = paramSupp.getParameters();
151cdf0e10cSrcweir 
152cdf0e10cSrcweir         assertEquals( "(ctx: " + _context + ") unexpected parameter count", _expectedParameterNames.length, parameters.getCount() );
153cdf0e10cSrcweir         for ( int i=0; i<parameters.getCount(); ++i )
154cdf0e10cSrcweir         {
155cdf0e10cSrcweir             final XPropertySet parameter = UnoRuntime.queryInterface(XPropertySet.class, parameters.getByIndex(i));
156cdf0e10cSrcweir 
157cdf0e10cSrcweir             final String name = (String)parameter.getPropertyValue( "Name" );
158cdf0e10cSrcweir             assertEquals( "(ctx: " + _context + ") unexpected parameter name for parameter number " + ( i + 1 ), _expectedParameterNames[i], name );
159cdf0e10cSrcweir 
160cdf0e10cSrcweir             final int type = ((Integer)parameter.getPropertyValue( "Type" )).intValue();
161cdf0e10cSrcweir             assertEquals( "(ctx: " + _context + ") unexpected data type for parameter number " + ( i + 1 ), _expectedParameterTypes[i], type );
162cdf0e10cSrcweir         }
163cdf0e10cSrcweir     }
164cdf0e10cSrcweir 
165cdf0e10cSrcweir     // --------------------------------------------------------------------------------------------------------
166cdf0e10cSrcweir     /** verifies that the parser properly recognizes the types of parameters
167cdf0e10cSrcweir      */
168cdf0e10cSrcweir     @Test
checkParameterTypes()169cdf0e10cSrcweir     public void checkParameterTypes() throws Exception
170cdf0e10cSrcweir     {
171cdf0e10cSrcweir         impl_checkParameters(
172cdf0e10cSrcweir             "SELECT * FROM \"all orders\" " +
173cdf0e10cSrcweir             "WHERE ( \"Order Date\" >= :order_date ) " +
174cdf0e10cSrcweir             "  AND (    ( \"Customer Name\" LIKE :customer ) " +
175cdf0e10cSrcweir             "      OR   ( \"Product Name\" LIKE ? ) " +
176cdf0e10cSrcweir             "      )",
177cdf0e10cSrcweir             new String[] { "order_date", "customer", "Product Name" },
178cdf0e10cSrcweir             new int[] { DataType.DATE, DataType.VARCHAR, DataType.VARCHAR },
179cdf0e10cSrcweir             ">= && LIKE"
180cdf0e10cSrcweir         );
181cdf0e10cSrcweir 
182cdf0e10cSrcweir         impl_checkParameters(
183cdf0e10cSrcweir             "SELECT * FROM \"categories\" " +
184cdf0e10cSrcweir             "WHERE \"ID\" BETWEEN :id_lo AND :id_hi",
185cdf0e10cSrcweir             new String[] { "id_lo", "id_hi" },
186cdf0e10cSrcweir             new int[] { DataType.INTEGER, DataType.INTEGER },
187cdf0e10cSrcweir             "BETWEEN"
188cdf0e10cSrcweir         );
189cdf0e10cSrcweir 
190cdf0e10cSrcweir         impl_checkParameters(
191cdf0e10cSrcweir             "SELECT CONCAT( :prefix, CONCAT( \"Name\", :suffix ) ) FROM \"customers\"",
192cdf0e10cSrcweir             new String[] { "prefix", "suffix" },
193cdf0e10cSrcweir             new int[] { DataType.VARCHAR, DataType.VARCHAR },
194cdf0e10cSrcweir             "CONCAT"
195cdf0e10cSrcweir         );
196cdf0e10cSrcweir     }
197cdf0e10cSrcweir }
198