nss: upgrade to release 3.73
[LibreOffice.git] / include / connectivity / sqliterator.hxx
blobe4f0450ea4bb0f6a00c8fd12a55f050063b683ac
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_CONNECTIVITY_SQLITERATOR_HXX
20 #define INCLUDED_CONNECTIVITY_SQLITERATOR_HXX
22 #include <connectivity/dbtoolsdllapi.hxx>
23 #include <connectivity/IParseContext.hxx>
24 #include <com/sun/star/sdbc/DataType.hpp>
25 #include <com/sun/star/sdbc/SQLException.hpp>
26 #include <connectivity/CommonTools.hxx>
27 #include <rtl/ref.hxx>
29 #include <memory>
30 #include <optional>
31 #include <vector>
32 #include <o3tl/typed_flags_set.hxx>
34 namespace com::sun::star::sdbc { class XConnection; }
35 namespace com::sun::star::beans { class XPropertySet; }
37 namespace connectivity
39 enum class TraversalParts
41 Parameters = 0x0001,
42 TableNames = 0x0002,
43 SelectColumns = 0x0006, // note that this includes TableNames. No SelectColumns without TableNames
45 // Those are not implemented currently
46 // GroupColumns = 0x0008,
47 // OrderColumns = 0x0010,
48 // SelectColumns = 0x0020,
49 // CreateColumns = 0x0040,
51 All = 0xFFFF
54 namespace o3tl
56 template<> struct typed_flags<connectivity::TraversalParts> : is_typed_flags<connectivity::TraversalParts, 0xffff> {};
59 namespace connectivity
62 class OSQLParseNode;
63 class OSQLParser;
65 typedef ::std::pair<const OSQLParseNode*,const OSQLParseNode* > TNodePair;
67 enum class OSQLStatementType {
68 Unknown,
69 Select,
70 Insert,
71 Update,
72 Delete,
73 OdbcCall,
74 CreateTable
77 struct OSQLParseTreeIteratorImpl;
79 class OOO_DLLPUBLIC_DBTOOLS OSQLParseTreeIterator final
81 private:
82 std::optional<css::sdbc::SQLException> m_xErrors; // contains the error while iterating through the statement
83 const OSQLParseNode* m_pParseTree; // current ParseTree
84 const OSQLParser& m_rParser; // if set used for general error messages from the context
85 OSQLStatementType m_eStatementType;
86 ::rtl::Reference<OSQLColumns> m_aSelectColumns; // all columns from the Select clause
87 ::rtl::Reference<OSQLColumns> m_aParameters; // all parameters
88 ::rtl::Reference<OSQLColumns> m_aGroupColumns; // the group by columns
89 ::rtl::Reference<OSQLColumns> m_aOrderColumns; // the order by columns
90 ::rtl::Reference<OSQLColumns> m_aCreateColumns; // the columns for Create table clause
92 ::std::unique_ptr< OSQLParseTreeIteratorImpl > m_pImpl;
94 void traverseParameter(const OSQLParseNode* _pParseNode,const OSQLParseNode* _pColumnRef,const OUString& _aColumnName, OUString& _aTableRange, const OUString& _rColumnAlias);
95 // inserts a table into the map
96 void traverseOneTableName( OSQLTables& _rTables,const OSQLParseNode * pTableName, const OUString & rTableRange );
97 void traverseSearchCondition(OSQLParseNode const * pSearchCondition);
98 void traverseOnePredicate(
99 OSQLParseNode const * pColumnRef,
100 OUString& aValue,
101 OSQLParseNode const * pParameter);
102 void traverseByColumnNames(const OSQLParseNode* pSelectNode, bool _bOrder);
103 void traverseParameters(const OSQLParseNode* pSelectNode);
105 const OSQLParseNode* getTableNode( OSQLTables& _rTables, const OSQLParseNode* pTableRef, OUString& aTableRange );
106 void getQualified_join( OSQLTables& _rTables, const OSQLParseNode *pTableRef, OUString& aTableRange );
107 void getSelect_statement(OSQLTables& _rTables,const OSQLParseNode* pSelect);
108 OUString getUniqueColumnName(const OUString & rColumnName) const;
110 /** finds the column with a given name, belonging to a given table, in a given tables collection
111 @param _rTables
112 the tables collection to look in
113 @param rColumnName
114 the column name to look for
115 @param rTableRange
116 the table alias name; if empty, look in all tables
117 @return
118 the desired column object, or <NULL/> if no such column could be found
120 static css::uno::Reference< css::beans::XPropertySet > findColumn(
121 const OSQLTables& _rTables, const OUString & rColumnName, OUString & rTableRange );
123 /** finds a column with a given name, belonging to a given table
124 @param rColumnName
125 the column name to look for
126 @param rTableRange
127 the table alias name; if empty, look in all tables
128 @param _bLookInSubTables
129 <TRUE/> if and only if not only our direct tables, but also our sub tables (from sub selects)
130 should be searched
131 @return
133 css::uno::Reference< css::beans::XPropertySet > findColumn(
134 const OUString & rColumnName, OUString & rTableRange, bool _bLookInSubTables );
136 /** finds a column with a given name among the select columns
137 @param rColumnName
138 the column name to look for
139 @return
141 css::uno::Reference< css::beans::XPropertySet > findSelectColumn(
142 const OUString & rColumnName );
144 void setSelectColumnName(::rtl::Reference<OSQLColumns> const & _rColumns,const OUString & rColumnName,const OUString & rColumnAlias, const OUString & rTableRange, bool bFkt=false, sal_Int32 _nType = css::sdbc::DataType::VARCHAR, bool bAggFkt=false);
145 void appendColumns(::rtl::Reference<OSQLColumns> const & _rColumns,const OUString& _rTableAlias,const OSQLTable& _rTable);
146 // Other member variables that should be available in the "set" functions
147 // can be defined in the derived class. They can be initialized
148 // in its constructor and, after the "traverse" routines have been used,
149 // they can be queried using other functions.
151 OSQLParseTreeIterator(const OSQLParseTreeIterator & rIter) = delete;
153 public:
154 OSQLParseTreeIterator(
155 const css::uno::Reference< css::sdbc::XConnection >& _rxConnection,
156 const css::uno::Reference< css::container::XNameAccess >& _rxTables,
157 const OSQLParser& _rParser );
158 ~OSQLParseTreeIterator();
160 void dispose();
161 bool isCaseSensitive() const;
162 // The parse tree to be analysed/traversed:
163 // If NULL is passed, the current parse tree will be deleted and the error status cleared.
164 void setParseTree(const OSQLParseNode * pNewParseTree);
165 const OSQLParseNode * getParseTree() const { return m_pParseTree; };
167 // subtrees in case of a select statement
168 const OSQLParseNode* getWhereTree() const;
169 const OSQLParseNode* getOrderTree() const;
170 const OSQLParseNode* getGroupByTree() const;
171 const OSQLParseNode* getHavingTree() const;
173 const OSQLParseNode* getSimpleWhereTree() const;
174 const OSQLParseNode* getSimpleOrderTree() const;
175 const OSQLParseNode* getSimpleGroupByTree() const;
176 const OSQLParseNode* getSimpleHavingTree() const;
178 /** returns the errors which occurred during parsing.
180 The returned object contains a chain (via SQLException::NextException) of SQLExceptions.
182 const css::sdbc::SQLException& getErrors() const { return *m_xErrors; }
183 bool hasErrors() const { return bool(m_xErrors); }
185 // statement type (already set in setParseTree):
186 OSQLStatementType getStatementType() const { return m_eStatementType; }
188 /** traverses the complete statement tree, and fills all our data with
189 the information obatined during traversal.
191 Implemented by calling the single traverse* methods in the proper
192 order (depending on the statement type).
194 void traverseAll();
196 // The TableRangeMap contains all tables associated with the range name found first.
197 const OSQLTables& getTables() const;
199 const ::rtl::Reference<OSQLColumns>& getSelectColumns() const { return m_aSelectColumns;}
200 const ::rtl::Reference<OSQLColumns>& getGroupColumns() const { return m_aGroupColumns;}
201 const ::rtl::Reference<OSQLColumns>& getOrderColumns() const { return m_aOrderColumns;}
202 const ::rtl::Reference<OSQLColumns>& getParameters() const { return m_aParameters; }
204 /** return the columname and the table range
205 @param _pColumnRef
206 The column ref parse node.
207 @param _rColumnName
208 The column name to be set.
209 @param _rTableRange
210 The table range to be set.
212 void getColumnRange( const OSQLParseNode* _pColumnRef,
213 OUString &_rColumnName,
214 OUString& _rTableRange) const;
216 /** retrieves a column's name, table range, and alias
218 @param _pColumnRef
219 The column_ref parse node.
220 @param _out_rColumnName
221 The column name to be set.
222 @param _out_rTableRange
223 The table range to be set.
224 @param _out_rColumnAliasIfPresent
225 If the column specified by _pColumnRef is part of the select columns, and contains a column alias there,
226 this alias is returned here.
228 void getColumnRange( const OSQLParseNode* _pColumnRef,
229 OUString& _out_rColumnName,
230 OUString& _out_rTableRange,
231 OUString& _out_rColumnAliasIfPresent
232 ) const;
234 /** return the alias name of a column
235 @param _pDerivedColumn
236 The parse node where SQL_ISRULE(_pDerivedColumn,derived_column) must be true
237 @return
238 The alias name of the column or an empty string.
240 static OUString getColumnAlias(const OSQLParseNode* _pDerivedColumn);
242 /** return the columname and the table range
243 @param _pColumnRef
244 The column ref parse node.
245 @param _xMetaData
246 The database meta data.
247 @param _rColumnName
248 The column name to be set.
249 @param _rTableRange
250 The table range to be set.
252 static void getColumnRange( const OSQLParseNode* _pColumnRef,
253 const css::uno::Reference< css::sdbc::XConnection >& _rxConnection,
254 OUString &_rColumnName,
255 OUString& _rTableRange);
257 // return true when the tableNode is a rule like catalog_name, schema_name or table_name
258 static bool isTableNode(const OSQLParseNode* _pTableNode);
260 // tries to find the correct type of the function
261 sal_Int32 getFunctionReturnType(const OSQLParseNode* _pNode );
263 // returns a lis of all joined columns
264 ::std::vector< TNodePair >& getJoinConditions() const;
266 private:
268 /** traverses the list of table names, and fills _rTables
270 bool traverseTableNames( OSQLTables& _rTables );
272 /// traverses columns in a SELECT statement
273 bool traverseSelectColumnNames(const OSQLParseNode* pSelectNode);
274 /// traverses columns in a CREATE TABLE statement
275 void traverseCreateColumns(const OSQLParseNode* pSelectNode);
277 bool traverseOrderByColumnNames(const OSQLParseNode* pSelectNode);
278 bool traverseGroupByColumnNames(const OSQLParseNode* pSelectNode);
280 bool traverseSelectionCriteria(const OSQLParseNode* pSelectNode);
282 /** constructs a new iterator, which inherits some of the settings from a parent iterator
284 OSQLParseTreeIterator(
285 const OSQLParseTreeIterator& _rParentIterator,
286 const OSQLParser& _rParser,
287 const OSQLParseNode* pRoot );
289 /** creates a table object and inserts it into our tables collection
291 only used when we're iterating through a CREATE TABLE statement
293 OSQLTable impl_createTableObject(
294 const OUString& rTableName, const OUString& rCatalogName, const OUString& rSchemaName );
296 /** locates a record source (a table or query) with the given name
298 OSQLTable impl_locateRecordSource(
299 const OUString& _rComposedName
302 /** implementation for both traverseAll and traverseSome
304 void impl_traverse( TraversalParts _nIncludeMask );
306 /** retrieves the parameter columns of the given query
308 void impl_getQueryParameterColumns( const OSQLTable& _rQuery );
310 void setOrderByColumnName(const OUString & rColumnName, OUString & rTableRange, bool bAscending);
311 void setGroupByColumnName(const OUString & rColumnName, OUString & rTableRange);
313 /** appends an SQLException corresponding to the given error code to our error collection
315 @param _eError
316 the code of the error which occurred
317 @param _pReplaceToken1
318 if not <NULL/>, the first occurrence of '#' in the error message will be replaced
319 with the given token
320 @param _pReplaceToken2
321 if not <NULL/>, and if _rReplaceToken1 is not <NULL/>, the second occurrence of '#'
322 in the error message will be replaced with _rReplaceToken2
324 void impl_appendError( IParseContext::ErrorCode _eError,
325 const OUString* _pReplaceToken1 = nullptr, const OUString* _pReplaceToken2 = nullptr );
327 /** appends an SQLException corresponding to the given error code to our error collection
329 void impl_appendError( const css::sdbc::SQLException& _rError );
331 void impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition);
335 #endif // INCLUDED_CONNECTIVITY_SQLITERATOR_HXX
337 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */