xref: /AOO41X/main/connectivity/inc/connectivity/sqliterator.hxx (revision caf5cd79edad04a48dcaf209068b3b89eae4622e)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #ifndef _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
24 #define _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
25 
26 #include "connectivity/dbtoolsdllapi.hxx"
27 #include "connectivity/sqlnode.hxx"
28 #include <connectivity/IParseContext.hxx>
29 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
30 #include <com/sun/star/sdbc/DataType.hpp>
31 #include <com/sun/star/sdbc/SQLWarning.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include "connectivity/CommonTools.hxx"
34 #include <vos/ref.hxx>
35 #include <cppuhelper/weak.hxx>
36 
37 #include <map>
38 #include <memory>
39 #include <vector>
40 
41 namespace connectivity
42 {
43 
44     class OSQLParseNode;
45     class OSQLParser;
46 
47     typedef ::std::pair<const OSQLParseNode*,const OSQLParseNode* > TNodePair;
48 
49     enum OSQLStatementType {
50         SQL_STATEMENT_UNKNOWN,
51         SQL_STATEMENT_SELECT,
52         SQL_STATEMENT_INSERT,
53         SQL_STATEMENT_UPDATE,
54         SQL_STATEMENT_DELETE,
55         SQL_STATEMENT_ODBC_CALL,
56         SQL_STATEMENT_CREATE_TABLE
57     };
58 
59     struct OSQLParseTreeIteratorImpl;
60 
61     class OOO_DLLPUBLIC_DBTOOLS OSQLParseTreeIterator
62     {
63     private:
64         ::com::sun::star::sdbc::SQLException            m_aErrors;          // conatins the error while iterating through the statement
65         const OSQLParseNode*                            m_pParseTree;       // aktueller ParseTree
66         const OSQLParser&                               m_rParser;          // if set used for general error messages from the context
67         OSQLStatementType                               m_eStatementType;   // Art des Statements
68         ::vos::ORef<OSQLColumns>                        m_aSelectColumns;   // alle Spalten aus dem Select-Clause
69         ::vos::ORef<OSQLColumns>                        m_aParameters;      // all parameters
70         ::vos::ORef<OSQLColumns>                        m_aGroupColumns;    // the group by columns
71         ::vos::ORef<OSQLColumns>                        m_aOrderColumns;    // the order by columns
72         ::vos::ORef<OSQLColumns>                        m_aCreateColumns;   // the columns for Create table clause
73 
74         ::std::auto_ptr< OSQLParseTreeIteratorImpl >    m_pImpl;
75 
76         void                traverseParameter(const OSQLParseNode* _pParseNode,const OSQLParseNode* _pColumnRef,const ::rtl::OUString& _aColumnName,const ::rtl::OUString& _aTableRange, const ::rtl::OUString& _rColumnAlias);
77         // F"ugt eine Tabelle in die Map ein
78         void                traverseOneTableName( OSQLTables& _rTables,const OSQLParseNode * pTableName, const ::rtl::OUString & rTableRange );
79         void                traverseORCriteria(OSQLParseNode * pSearchCondition);
80         void                traverseANDCriteria(OSQLParseNode * pSearchCondition);
81         void                traverseOnePredicate(
82                                                 OSQLParseNode * pColumnRef,
83                                                 ::rtl::OUString& aValue,
84                                                 OSQLParseNode * pParameter);
85         void traverseByColumnNames(const OSQLParseNode* pSelectNode,sal_Bool _bOrder);
86         void                traverseParameters(const OSQLParseNode* pSelectNode);
87 
88         const OSQLParseNode*    getTableNode( OSQLTables& _rTables, const OSQLParseNode* pTableRef, ::rtl::OUString& aTableRange );
89         void                    getQualified_join( OSQLTables& _rTables, const OSQLParseNode *pTableRef, ::rtl::OUString& aTableRange );
90         void                    getSelect_statement(OSQLTables& _rTables,const OSQLParseNode* pSelect);
91         ::rtl::OUString         getUniqueColumnName(const ::rtl::OUString & rColumnName)    const;
92 
93         /** finds the column with a given name, belonging to a given table, in a given tables collection
94             @param  _rTables
95                 the tables collection to look in
96             @param  rColumnName
97                 the column name to look for
98             @param  rTableRange
99                 the table alias name
100             @return
101                 the desired column object, or <NULL/> if no such column could be found
102         */
103         static ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findColumn(
104             const OSQLTables& _rTables, const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange );
105 
106         /** finds a column with a given name, belonging to a given table
107             @param  rColumnName
108                 the column name to look for
109             @param  rTableRange
110                     the table alias name
111             @param  _bLookInSubTables
112                 <TRUE/> if and only if not only our direct tables, but also our sub tables (from sub selects)
113                 should be searched
114             @return
115         */
116         ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > findColumn(
117             const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange, bool _bLookInSubTables );
118 
119       protected:
120         void setSelectColumnName(::vos::ORef<OSQLColumns>& _rColumns,const ::rtl::OUString & rColumnName,const ::rtl::OUString & rColumnAlias, const ::rtl::OUString & rTableRange,sal_Bool bFkt=sal_False,sal_Int32 _nType = com::sun::star::sdbc::DataType::VARCHAR,sal_Bool bAggFkt=sal_False);
121         void appendColumns(::vos::ORef<OSQLColumns>& _rColumns,const ::rtl::OUString& _rTableAlias,const OSQLTable& _rTable);
122         // Weitere Member-Variable, die in den "set"-Funktionen zur
123         // Verfuegung stehen sollen, koennen in der abgeleiteten Klasse
124         // definiert werden und z. B. in deren Konstruktor initialisiert
125         // bzw. nach Benutzung der "traverse"-Routinen mit Hilfe weiterer
126         // Funktionen abgefragt werden.
127 
128 
129       private:
130         OSQLParseTreeIterator();                                        // never implemented
131         OSQLParseTreeIterator(const OSQLParseTreeIterator & rIter);     // never implemented
132 
133       public:
134         OSQLParseTreeIterator(
135             const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
136             const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >& _rxTables,
137             const OSQLParser& _rParser,
138             const OSQLParseNode* pRoot = NULL );
139         ~OSQLParseTreeIterator();
140 
operator new(size_t nSize)141         inline static void * SAL_CALL operator new( size_t nSize ) SAL_THROW( () )
142             { return ::rtl_allocateMemory( nSize ); }
operator new(size_t,void * _pHint)143         inline static void * SAL_CALL operator new( size_t,void* _pHint ) SAL_THROW( () )
144             { return _pHint; }
operator delete(void * pMem)145         inline static void SAL_CALL operator delete( void * pMem ) SAL_THROW( () )
146             { ::rtl_freeMemory( pMem ); }
operator delete(void *,void *)147         inline static void SAL_CALL operator delete( void *,void* ) SAL_THROW( () )
148             {  }
149 
150         void dispose();
151         bool isCaseSensitive() const;
152         // Der zu analysierende/zu traversierende Parse Tree:
153         // bei "Ubergabe von NULL wird der aktuelle Parsetree gel"oscht und der Fehlerstatus gecleared
154         void setParseTree(const OSQLParseNode * pNewParseTree);
155 //      void setParser(const OSQLParser* _pParser) { m_pParser = _pParser; }
getParseTree() const156         const OSQLParseNode * getParseTree() const { return m_pParseTree; };
157 
158         // Teilbaueme bei einem select statement
159         const OSQLParseNode* getWhereTree() const;
160         const OSQLParseNode* getOrderTree() const;
161         const OSQLParseNode* getGroupByTree() const;
162         const OSQLParseNode* getHavingTree() const;
163 
164         const OSQLParseNode* getSimpleWhereTree() const;
165         const OSQLParseNode* getSimpleOrderTree() const;
166         const OSQLParseNode* getSimpleGroupByTree() const;
167         const OSQLParseNode* getSimpleHavingTree() const;
168 
169         /** returns the errors which occured during parsing.
170 
171             The returned object contains a chain (via SQLException::NextException) of SQLExceptions.
172         */
getErrors() const173         inline const ::com::sun::star::sdbc::SQLException&   getErrors() const { return m_aErrors; }
hasErrors() const174         inline bool hasErrors() const { return m_aErrors.Message.getLength() > 0; }
175 
176         // Statement-Typ (wird bereits in setParseTree gesetzt):
getStatementType() const177         OSQLStatementType getStatementType() const { return m_eStatementType; }
178 
179         /** traverses the complete statement tree, and fills all our data with
180             the information obatined during traversal.
181 
182             Implemented by calling the single traverse* methods in the proper
183             order (depending on the statement type).
184         */
185         void traverseAll();
186 
187         enum TraversalParts
188         {
189             Parameters      = 0x0001,
190             TableNames      = 0x0002,
191             SelectColumns   = 0x0006,   // note that this includes TableNames. No SelectColumns without TableNames
192 
193             // Those are not implemented currently
194             // GroupColumns    = 0x0008,
195             // OrderColumns    = 0x0010,
196             // SelectColumns   = 0x0020,
197             // CreateColumns   = 0x0040,
198 
199             All             = 0xFFFF
200         };
201         /** traverses selected parts of the statement tree, and fills our data with
202             the information obtained during traversal
203 
204             @param _nIncludeMask
205                 set of TraversalParts bits, specifying which information is to be collected.
206                 Note TraversalParts is currently not
207         */
208         void traverseSome( sal_uInt32 _nIncludeMask );
209 
210         // Die TableRangeMap enth"alt alle Tabellen unter dem zugeh"origen Rangenamen der zuerst gefunden wird
211         const OSQLTables& getTables() const;
212 
getSelectColumns() const213         ::vos::ORef<OSQLColumns> getSelectColumns() const { return m_aSelectColumns;}
getGroupColumns() const214         ::vos::ORef<OSQLColumns> getGroupColumns() const { return m_aGroupColumns;}
getOrderColumns() const215         ::vos::ORef<OSQLColumns> getOrderColumns() const { return m_aOrderColumns;}
getParameters() const216         ::vos::ORef<OSQLColumns> getParameters()    const { return m_aParameters; }
getCreateColumns() const217         ::vos::ORef<OSQLColumns> getCreateColumns() const { return m_aCreateColumns;}
218 
219         /** return the columname and the table range
220             @param  _pColumnRef
221                 The column ref parse node.
222             @param  _rColumnName
223                 The column name to be set.
224             @param  _rTableRange
225                 The table range to be set.
226         */
227         void getColumnRange(    const OSQLParseNode* _pColumnRef,
228                                 ::rtl::OUString &_rColumnName,
229                                 ::rtl::OUString& _rTableRange) const;
230 
231         /** retrieves a column's name, table range, and alias
232 
233             @param  _pColumnRef
234                 The column_ref parse node.
235             @param  _out_rColumnName
236                 The column name to be set.
237             @param  _out_rTableRange
238                 The table range to be set.
239             @param _out_rColumnAliasIfPresent
240                 If the column specified by _pColumnRef is part of the select columns, and contains a column alias there,
241                 this alias is returned here.
242         */
243         void getColumnRange(    const OSQLParseNode* _pColumnRef,
244                                 ::rtl::OUString& _out_rColumnName,
245                                 ::rtl::OUString& _out_rTableRange,
246                                 ::rtl::OUString& _out_rColumnAliasIfPresent
247                                 ) const;
248 
249         /** return the alias name of a column
250             @param  _pDerivedColumn
251                 The parse node where SQL_ISRULE(_pDerivedColumn,derived_column) must be true
252             @return
253                 The alias name of the column or an empty string.
254         */
255         static ::rtl::OUString getColumnAlias(const OSQLParseNode* _pDerivedColumn);
256 
257         /** return the columname and the table range
258             @param  _pColumnRef
259                 The column ref parse node.
260             @param  _xMetaData
261                 The database meta data.
262             @param  _rColumnName
263                 The column name to be set.
264             @param  _rTableRange
265                 The table range to be set.
266         */
267         static void getColumnRange( const OSQLParseNode* _pColumnRef,
268                                     const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
269                                     ::rtl::OUString &_rColumnName,
270                                     ::rtl::OUString& _rTableRange);
271 
272         // Ermittelt fuer eine Funktion, Spalten den zugehoeren TableRange,
273         // wenn nicht eindeutig, dann leer
274         sal_Bool getColumnTableRange(const OSQLParseNode* pNode, ::rtl::OUString &rTableRange) const;
275 
276         // return true when the tableNode is a rule like catalog_name, schema_name or table_name
277         sal_Bool isTableNode(const OSQLParseNode* _pTableNode) const;
278 
279         // tries to find the correct type of the function
280         sal_Int32 getFunctionReturnType(const OSQLParseNode* _pNode );
281 
282         // returns a lis of all joined columns
283         ::std::vector< TNodePair >& getJoinConditions() const;
284 
285     private:
286         /** traverses the list of table names, and filles _rTables
287         */
288         bool traverseTableNames( OSQLTables& _rTables );
289 
290         /// traverses columns in a SELECT statement
291         bool traverseSelectColumnNames(const OSQLParseNode* pSelectNode);
292         /// traverses columns in a CREATE TABLE statement
293         void traverseCreateColumns(const OSQLParseNode* pSelectNode);
294 
295         bool traverseOrderByColumnNames(const OSQLParseNode* pSelectNode);
296         bool traverseGroupByColumnNames(const OSQLParseNode* pSelectNode);
297 
298         bool traverseSelectionCriteria(const OSQLParseNode* pSelectNode);
299 
300     private:
301         /** constructs a new iterator, which inherits some of the settings from a parent iterator
302         */
303         OSQLParseTreeIterator(
304             const OSQLParseTreeIterator& _rParentIterator,
305             const OSQLParser& _rParser,
306             const OSQLParseNode* pRoot );
307 
308         /** creates a table object and inserts it into our tables collection
309 
310             only used when we're iterating through a CREATE TABLE statement
311         */
312         OSQLTable   impl_createTableObject(
313             const ::rtl::OUString& rTableName, const ::rtl::OUString& rCatalogName, const ::rtl::OUString& rSchemaName );
314 
315         /** locates a record source (a table or query) with the given name
316         */
317         OSQLTable   impl_locateRecordSource(
318             const ::rtl::OUString& _rComposedName
319         );
320 
321         /** implementation for both traverseAll and traverseSome
322         */
323         void    impl_traverse( sal_uInt32 _nIncludeMask );
324 
325         /** retrieves the parameter columns of the given query
326         */
327         void    impl_getQueryParameterColumns( const OSQLTable& _rQuery );
328 
329         void setOrderByColumnName(const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange, sal_Bool bAscending);
330         void setGroupByColumnName(const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange);
331 
332     private:
333         /** appends an SQLException corresponding to the given error code to our error collection
334 
335             @param  _eError
336                 the code of the error which occured
337             @param  _pReplaceToken1
338                 if not <NULL/>, the first occurance of '#' in the error message will be replaced
339                 with the given token
340             @param  _pReplaceToken2
341                 if not <NULL/>, and if _rReplaceToken1 is not <NULL/>, the second occurance of '#'
342                 in the error message will be replaced with _rReplaceToken2
343         */
344         void impl_appendError( IParseContext::ErrorCode _eError,
345             const ::rtl::OUString* _pReplaceToken1 = NULL, const ::rtl::OUString* _pReplaceToken2 = NULL );
346 
347         /** appends an SQLException corresponding to the given error code to our error collection
348         */
349         void impl_appendError( const ::com::sun::star::sdbc::SQLException& _rError );
350 
351         /** resets our errors
352         */
impl_resetErrors()353         inline void impl_resetErrors()
354         {
355             m_aErrors = ::com::sun::star::sdbc::SQLException();
356         }
357         void impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition);
358     };
359 }
360 
361 #endif // _CONNECTIVITY_PARSE_SQLITERATOR_HXX_
362 
363