1caf5cd79SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3caf5cd79SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4caf5cd79SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5caf5cd79SAndrew Rist  * distributed with this work for additional information
6caf5cd79SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7caf5cd79SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8caf5cd79SAndrew Rist  * "License"); you may not use this file except in compliance
9caf5cd79SAndrew Rist  * with the License.  You may obtain a copy of the License at
10caf5cd79SAndrew Rist  *
11caf5cd79SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12caf5cd79SAndrew Rist  *
13caf5cd79SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14caf5cd79SAndrew Rist  * software distributed under the License is distributed on an
15caf5cd79SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16caf5cd79SAndrew Rist  * KIND, either express or implied.  See the License for the
17caf5cd79SAndrew Rist  * specific language governing permissions and limitations
18caf5cd79SAndrew Rist  * under the License.
19caf5cd79SAndrew Rist  *
20caf5cd79SAndrew Rist  *************************************************************/
21caf5cd79SAndrew Rist 
22caf5cd79SAndrew Rist 
23cdf0e10cSrcweir #ifndef _CONNECTIVITY_SQLNODE_HXX
24cdf0e10cSrcweir #define _CONNECTIVITY_SQLNODE_HXX
25cdf0e10cSrcweir 
26cdf0e10cSrcweir #include "connectivity/dbtoolsdllapi.hxx"
27cdf0e10cSrcweir #include "connectivity/dbmetadata.hxx"
28cdf0e10cSrcweir #include <com/sun/star/uno/Reference.hxx>
29cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatTypes.hpp>
30cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
31cdf0e10cSrcweir #include <vector>
32cdf0e10cSrcweir #include <functional>
33cdf0e10cSrcweir #include <set>
34cdf0e10cSrcweir #include <boost/shared_ptr.hpp>
35cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
36cdf0e10cSrcweir 
37cdf0e10cSrcweir // forward declarations
38cdf0e10cSrcweir namespace com
39cdf0e10cSrcweir {
40cdf0e10cSrcweir 	namespace sun
41cdf0e10cSrcweir 	{
42cdf0e10cSrcweir 		namespace star
43cdf0e10cSrcweir 		{
44cdf0e10cSrcweir 			namespace beans
45cdf0e10cSrcweir 			{
46cdf0e10cSrcweir 				class XPropertySet;
47cdf0e10cSrcweir 			}
48cdf0e10cSrcweir 			namespace util
49cdf0e10cSrcweir 			{
50cdf0e10cSrcweir 				class XNumberFormatter;
51cdf0e10cSrcweir 			}
52cdf0e10cSrcweir             namespace container
53cdf0e10cSrcweir             {
54cdf0e10cSrcweir                 class XNameAccess;
55cdf0e10cSrcweir             }
56cdf0e10cSrcweir 		}
57cdf0e10cSrcweir 	}
58cdf0e10cSrcweir }
59cdf0e10cSrcweir 
60cdf0e10cSrcweir namespace rtl
61cdf0e10cSrcweir {
62cdf0e10cSrcweir     class OUStringBuffer;
63cdf0e10cSrcweir }
64cdf0e10cSrcweir #define ORDER_BY_CHILD_POS  5
65cdf0e10cSrcweir #define TABLE_EXPRESSION_CHILD_COUNT    9
66cdf0e10cSrcweir 
67cdf0e10cSrcweir namespace connectivity
68cdf0e10cSrcweir {
69cdf0e10cSrcweir     class OSQLParser;
70cdf0e10cSrcweir 	class OSQLParseNode;
71cdf0e10cSrcweir 	class IParseContext;
72cdf0e10cSrcweir 
73cdf0e10cSrcweir     typedef ::std::vector< OSQLParseNode* >                  OSQLParseNodes;
74cdf0e10cSrcweir 
75cdf0e10cSrcweir 	enum SQLNodeType	{SQL_NODE_RULE, SQL_NODE_LISTRULE, SQL_NODE_COMMALISTRULE,
76cdf0e10cSrcweir 						 SQL_NODE_KEYWORD, SQL_NODE_COMPARISON, SQL_NODE_NAME,
77cdf0e10cSrcweir 						 SQL_NODE_STRING,	SQL_NODE_INTNUM, SQL_NODE_APPROXNUM,
78cdf0e10cSrcweir 						 SQL_NODE_EQUAL,SQL_NODE_LESS,SQL_NODE_GREAT,SQL_NODE_LESSEQ,SQL_NODE_GREATEQ,SQL_NODE_NOTEQUAL,
79cdf0e10cSrcweir 						 SQL_NODE_PUNCTUATION, SQL_NODE_AMMSC, SQL_NODE_ACCESS_DATE,SQL_NODE_DATE,SQL_NODE_CONCAT};
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     typedef ::std::set< ::rtl::OUString >   QueryNameSet;
82cdf0e10cSrcweir     //==================================================================
83cdf0e10cSrcweir     //= SQLParseNodeParameter
84cdf0e10cSrcweir     //==================================================================
85cdf0e10cSrcweir     struct OOO_DLLPUBLIC_DBTOOLS SQLParseNodeParameter
86cdf0e10cSrcweir     {
87cdf0e10cSrcweir 	    const ::com::sun::star::lang::Locale&	rLocale;
88cdf0e10cSrcweir         ::dbtools::DatabaseMetaData             aMetaData;
89cdf0e10cSrcweir         OSQLParser*                             pParser;
90cdf0e10cSrcweir         ::boost::shared_ptr< QueryNameSet >     pSubQueryHistory;
91cdf0e10cSrcweir 	    ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >    xFormatter;
92cdf0e10cSrcweir 	    ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >       xField;
93cdf0e10cSrcweir 	    ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess >    xQueries;  // see bParseToSDBCLevel
94cdf0e10cSrcweir 	    const IParseContext& m_rContext;
95cdf0e10cSrcweir 	    sal_Char			cDecSep;
96cdf0e10cSrcweir 	    bool                bQuote                      : 1;    /// should we quote identifiers?
97cdf0e10cSrcweir 	    bool                bInternational              : 1;    /// should we internationalize keywords and placeholders?
98cdf0e10cSrcweir 	    bool                bPredicate                  : 1;    /// are we going to parse a mere predicate?
99cdf0e10cSrcweir         bool                bParseToSDBCLevel           : 1;    /// should we create an SDBC-level statement (e.g. with substituted sub queries)?
100cdf0e10cSrcweir 
101cdf0e10cSrcweir 	    SQLParseNodeParameter(
102cdf0e10cSrcweir             const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
103cdf0e10cSrcweir 		    const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter >& _xFormatter,
104cdf0e10cSrcweir             const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& _xField,
105cdf0e10cSrcweir 		    const ::com::sun::star::lang::Locale& _rLocale,
106cdf0e10cSrcweir             const IParseContext* _pContext,
107cdf0e10cSrcweir 		    bool _bIntl,
108cdf0e10cSrcweir             bool _bQuote,
109cdf0e10cSrcweir             sal_Char _cDecSep,
110cdf0e10cSrcweir             bool _bPredicate,
111cdf0e10cSrcweir             bool _bParseToSDBC
112cdf0e10cSrcweir         );
113cdf0e10cSrcweir         ~SQLParseNodeParameter();
114cdf0e10cSrcweir     };
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 	//==========================================================================
117cdf0e10cSrcweir 	//= OSQLParseNode
118cdf0e10cSrcweir 	//==========================================================================
119cdf0e10cSrcweir 	class OOO_DLLPUBLIC_DBTOOLS OSQLParseNode
120cdf0e10cSrcweir 	{
121cdf0e10cSrcweir 		friend class OSQLParser;
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 		OSQLParseNodes					m_aChildren;
124cdf0e10cSrcweir 		OSQLParseNode*	 				m_pParent;		// pParent fuer Reuckverkettung im Baum
125cdf0e10cSrcweir 		::rtl::OUString 				m_aNodeValue;	// Token-Name oder leer bei Regeln oder ::rtl::OUString bei
126cdf0e10cSrcweir 														// ::rtl::OUString, INT, usw. -Werten
127cdf0e10cSrcweir 		SQLNodeType 					m_eNodeType;	// s. o.
128cdf0e10cSrcweir 		sal_uInt32						m_nNodeID; 		// ::com::sun::star::chaos::Rule ID (bei IsRule()) oder Token ID (bei !IsRule())
129cdf0e10cSrcweir 											// ::com::sun::star::chaos::Rule IDs und Token IDs koennen nicht anhand des Wertes
130cdf0e10cSrcweir 											// unterschieden werden, dafuer ist IsRule() abzufragen!
131cdf0e10cSrcweir 	public:
132cdf0e10cSrcweir 		enum Rule
133cdf0e10cSrcweir 		{
134cdf0e10cSrcweir 			select_statement = 0,
135cdf0e10cSrcweir 			table_exp,
136cdf0e10cSrcweir 			table_ref_commalist,
137cdf0e10cSrcweir 			table_ref,
138cdf0e10cSrcweir 			catalog_name,
139cdf0e10cSrcweir 			schema_name,
140cdf0e10cSrcweir 			table_name,
141cdf0e10cSrcweir 			opt_column_commalist,
142cdf0e10cSrcweir 			column_commalist,
143cdf0e10cSrcweir 			column_ref_commalist,
144cdf0e10cSrcweir 			column_ref,
145cdf0e10cSrcweir 			opt_order_by_clause,
146cdf0e10cSrcweir 			ordering_spec_commalist,
147cdf0e10cSrcweir 			ordering_spec,
148cdf0e10cSrcweir 			opt_asc_desc,
149cdf0e10cSrcweir 			where_clause,
150cdf0e10cSrcweir 			opt_where_clause,
151cdf0e10cSrcweir 			search_condition,
152cdf0e10cSrcweir 			comparison_predicate,
153cdf0e10cSrcweir 			between_predicate,
154cdf0e10cSrcweir 			like_predicate,
155cdf0e10cSrcweir 			opt_escape,
156cdf0e10cSrcweir 			test_for_null,
157cdf0e10cSrcweir 			scalar_exp_commalist,
158cdf0e10cSrcweir 			scalar_exp,
159cdf0e10cSrcweir 			parameter_ref,
160cdf0e10cSrcweir 			parameter,
161cdf0e10cSrcweir 			general_set_fct,
162cdf0e10cSrcweir 			range_variable,
163cdf0e10cSrcweir 			column,
164cdf0e10cSrcweir 			delete_statement_positioned,
165cdf0e10cSrcweir 			delete_statement_searched,
166cdf0e10cSrcweir 			update_statement_positioned,
167cdf0e10cSrcweir 			update_statement_searched,
168cdf0e10cSrcweir 			assignment_commalist,
169cdf0e10cSrcweir 			assignment,
170cdf0e10cSrcweir 			values_or_query_spec,
171cdf0e10cSrcweir 			insert_statement,
172cdf0e10cSrcweir 			insert_atom_commalist,
173cdf0e10cSrcweir 			insert_atom,
174cdf0e10cSrcweir 			predicate_check,
175cdf0e10cSrcweir 			from_clause,
176cdf0e10cSrcweir 			qualified_join,
177cdf0e10cSrcweir 			cross_union,
178cdf0e10cSrcweir 			select_sublist,
179cdf0e10cSrcweir 			derived_column,
180cdf0e10cSrcweir 			column_val,
181cdf0e10cSrcweir 			set_fct_spec,
182cdf0e10cSrcweir 			boolean_term,
183cdf0e10cSrcweir 			boolean_primary,
184cdf0e10cSrcweir 			num_value_exp,
185cdf0e10cSrcweir 			join_type,
186cdf0e10cSrcweir 			position_exp,
187cdf0e10cSrcweir 			extract_exp,
188cdf0e10cSrcweir 			length_exp,
189cdf0e10cSrcweir 			char_value_fct,
190cdf0e10cSrcweir 			odbc_call_spec,
191cdf0e10cSrcweir 			in_predicate,
192cdf0e10cSrcweir 			existence_test,
193cdf0e10cSrcweir 			unique_test,
194cdf0e10cSrcweir 			all_or_any_predicate,
195cdf0e10cSrcweir 			named_columns_join,
196cdf0e10cSrcweir 			join_condition,
197cdf0e10cSrcweir             joined_table,
198cdf0e10cSrcweir 			boolean_factor,
199cdf0e10cSrcweir 			sql_not,
200cdf0e10cSrcweir 			boolean_test,
201cdf0e10cSrcweir 			manipulative_statement,
202cdf0e10cSrcweir 			subquery,
203cdf0e10cSrcweir 			value_exp_commalist,
204cdf0e10cSrcweir 			odbc_fct_spec,
205cdf0e10cSrcweir 			union_statement,
206cdf0e10cSrcweir 			outer_join_type,
207cdf0e10cSrcweir 			char_value_exp,
208cdf0e10cSrcweir 			term,
209cdf0e10cSrcweir 			value_exp_primary,
210cdf0e10cSrcweir 			value_exp,
211cdf0e10cSrcweir 			selection,
212cdf0e10cSrcweir 			fold,
213cdf0e10cSrcweir 			char_substring_fct,
214cdf0e10cSrcweir 			factor,
215cdf0e10cSrcweir             base_table_def,
216cdf0e10cSrcweir             base_table_element_commalist,
217cdf0e10cSrcweir             data_type,
218cdf0e10cSrcweir             column_def,
219cdf0e10cSrcweir             table_node,
220cdf0e10cSrcweir             as,
221cdf0e10cSrcweir             op_column_commalist,
222cdf0e10cSrcweir             table_primary_as_range_column,
223cdf0e10cSrcweir             datetime_primary,
224cdf0e10cSrcweir             concatenation,
225cdf0e10cSrcweir             char_factor,
226cdf0e10cSrcweir             bit_value_fct,
227cdf0e10cSrcweir             comparison_predicate_part_2,
228cdf0e10cSrcweir             parenthesized_boolean_value_expression,
229cdf0e10cSrcweir             character_string_type,
230cdf0e10cSrcweir             other_like_predicate_part_2,
231cdf0e10cSrcweir             between_predicate_part_2,
232cdf0e10cSrcweir             cast_spec,
233cdf0e10cSrcweir             rule_count,             // letzter_wert
234cdf0e10cSrcweir             UNKNOWN_RULE            // ID indicating that a node is no rule with a matching Rule-enum value (see getKnownRuleID)
235cdf0e10cSrcweir 		};
236cdf0e10cSrcweir 
237cdf0e10cSrcweir 		// must be ascii encoding for the value
238cdf0e10cSrcweir 		OSQLParseNode(const sal_Char* _pValueStr,
239cdf0e10cSrcweir 					  SQLNodeType _eNodeType,
240cdf0e10cSrcweir 					  sal_uInt32 _nNodeID = 0);
241cdf0e10cSrcweir 
242cdf0e10cSrcweir 		OSQLParseNode(const ::rtl::OString& _rValue,
243cdf0e10cSrcweir 					  SQLNodeType eNewNodeType,
244cdf0e10cSrcweir 					  sal_uInt32 nNewNodeID=0);
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 		OSQLParseNode(const sal_Unicode* _pValue,
247cdf0e10cSrcweir 					  SQLNodeType _eNodeType,
248cdf0e10cSrcweir 					  sal_uInt32 _nNodeID = 0);
249cdf0e10cSrcweir 
250cdf0e10cSrcweir 		OSQLParseNode(const ::rtl::OUString& _rValue,
251cdf0e10cSrcweir 					  SQLNodeType _eNodeType,
252cdf0e10cSrcweir 					  sal_uInt32 _nNodeID = 0);
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 			// Kopiert den entsprechenden ParseNode
255cdf0e10cSrcweir 		OSQLParseNode(const OSQLParseNode& rParseNode);
256cdf0e10cSrcweir 		OSQLParseNode& operator=(const OSQLParseNode& rParseNode);
257cdf0e10cSrcweir 
258cdf0e10cSrcweir 		sal_Bool operator==(OSQLParseNode& rParseNode) const;
259cdf0e10cSrcweir 
260cdf0e10cSrcweir 		// Destruktor raeumt rekursiv den Baum ab
261cdf0e10cSrcweir 		virtual ~OSQLParseNode();
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 		// Parent gibt den Zeiger auf den Parent zurueck
getParent() const264cdf0e10cSrcweir 		OSQLParseNode* getParent() const {return m_pParent;};
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 		// SetParent setzt den Parent-Zeiger eines ParseNodes
setParent(OSQLParseNode * pParseNode)267cdf0e10cSrcweir 		void setParent(OSQLParseNode* pParseNode) {m_pParent = pParseNode;};
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 		// ChildCount liefert die Anzahl der Kinder eines Knotens
count() const270cdf0e10cSrcweir 		sal_uInt32 count() const {return m_aChildren.size();};
271cdf0e10cSrcweir 		inline OSQLParseNode* getChild(sal_uInt32 nPos) const;
272cdf0e10cSrcweir 
273cdf0e10cSrcweir 		void append(OSQLParseNode* pNewSubTree);
274cdf0e10cSrcweir 		void insert(sal_uInt32 nPos, OSQLParseNode* pNewSubTree);
275cdf0e10cSrcweir 
276cdf0e10cSrcweir 		OSQLParseNode* replaceAt(sal_uInt32 nPos, OSQLParseNode* pNewSubTree);
277cdf0e10cSrcweir 		OSQLParseNode* replace(OSQLParseNode* pOldSubTree, OSQLParseNode* pNewSubTree);
278cdf0e10cSrcweir 
279cdf0e10cSrcweir 		OSQLParseNode* removeAt(sal_uInt32 nPos);
280cdf0e10cSrcweir 		OSQLParseNode* remove(OSQLParseNode* pSubTree);
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 		void replaceNodeValue(const ::rtl::OUString& rTableAlias,const ::rtl::OUString& rColumnName);
283cdf0e10cSrcweir 
284cdf0e10cSrcweir         /** parses the node to a string which can be passed to a driver's connection for execution
285cdf0e10cSrcweir 
286cdf0e10cSrcweir             Any particles of the parse tree which represent application-level features - such
287cdf0e10cSrcweir             as queries appearing in the FROM part - are subsituted, so that the resulting statement can
288cdf0e10cSrcweir             be executed at an SDBC-level connection.
289cdf0e10cSrcweir 
290cdf0e10cSrcweir             @param  _out_rString
291cdf0e10cSrcweir                 is an output parameter taking the resulting SQL statement
292cdf0e10cSrcweir 
293cdf0e10cSrcweir             @param  _rxConnection
294cdf0e10cSrcweir                 the connection relative to which to parse. This must be an SDB-level connection (e.g.
295cdf0e10cSrcweir                 support the XQueriesSupplier interface) for the method to be able to do all necessary
296cdf0e10cSrcweir                 substitutions.
297cdf0e10cSrcweir 
298cdf0e10cSrcweir             @param _rParser
299cdf0e10cSrcweir                 the SQLParser used to create the node. This is needed in case we need to parse
300cdf0e10cSrcweir                 sub queries which are present in the SQL statement - those sub queries need to be parsed,
301cdf0e10cSrcweir                 too, to check whether they contain nested sub queries.
302cdf0e10cSrcweir 
303cdf0e10cSrcweir             @param _pErrorHolder
304*07a3d7f1SPedro Giffuni                 takes the error which occurred while generating the statement, if any. Might be <NULL/>,
305cdf0e10cSrcweir                 in this case the error is not reported back, and can only be recognized by examing the
306cdf0e10cSrcweir                 return value.
307cdf0e10cSrcweir 
308cdf0e10cSrcweir             @return
309cdf0e10cSrcweir                 <TRUE/> if and only if the parsing was successful.<br/>
310cdf0e10cSrcweir 
311cdf0e10cSrcweir                 Currently, there's only one condition how this method can fail: If it contains a nested
312cdf0e10cSrcweir                 query which causes a cycle. E.g., consider a statement <code>SELECT * from "foo"</code>,
313cdf0e10cSrcweir                 where <code>bar </code> is a query defined as <code>SELECT * FROM "bar"</code>, where
314cdf0e10cSrcweir                 <code>bar</code> is defined as <code>SELECT * FROM "foo"</code>. This statement obviously
315cdf0e10cSrcweir                 cannot be parsed to an executable statement.
316cdf0e10cSrcweir 
317cdf0e10cSrcweir                 If this method returns <FALSE/>, you're encouraged to check and handle the error in
318cdf0e10cSrcweir                 <arg>_pErrorHolder</arg>.
319cdf0e10cSrcweir         */
320cdf0e10cSrcweir         bool parseNodeToExecutableStatement( ::rtl::OUString& _out_rString,
321cdf0e10cSrcweir             const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
322cdf0e10cSrcweir             OSQLParser& _rParser,
323cdf0e10cSrcweir             ::com::sun::star::sdbc::SQLException* _pErrorHolder ) const;
324cdf0e10cSrcweir 
325cdf0e10cSrcweir 		void parseNodeToStr(::rtl::OUString& rString,
326cdf0e10cSrcweir 							const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
327cdf0e10cSrcweir 							const IParseContext* pContext = NULL,
328cdf0e10cSrcweir 							sal_Bool _bIntl = sal_False,
329cdf0e10cSrcweir 							sal_Bool _bQuote= sal_True) const;
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 		// quoted und internationalisert
332cdf0e10cSrcweir 		void parseNodeToPredicateStr(::rtl::OUString& rString,
333cdf0e10cSrcweir 									 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
334cdf0e10cSrcweir 									 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
335cdf0e10cSrcweir 									 const ::com::sun::star::lang::Locale& rIntl,
336cdf0e10cSrcweir 									 sal_Char _cDec,
337cdf0e10cSrcweir 									 const IParseContext* pContext = NULL ) const;
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 		void parseNodeToPredicateStr(::rtl::OUString& rString,
340cdf0e10cSrcweir 									 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
341cdf0e10cSrcweir 									 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
342cdf0e10cSrcweir 									 const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & _xField,
343cdf0e10cSrcweir 									 const ::com::sun::star::lang::Locale& rIntl,
344cdf0e10cSrcweir 									 sal_Char _cDec,
345cdf0e10cSrcweir 									 const IParseContext* pContext = NULL ) const;
346cdf0e10cSrcweir 
347cdf0e10cSrcweir 		OSQLParseNode* getByRule(OSQLParseNode::Rule eRule) const;
348cdf0e10cSrcweir 
349cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
350cdf0e10cSrcweir 			// zeigt den ParseTree mit tabs und linefeeds
351cdf0e10cSrcweir 		void showParseTree( ::rtl::OUString& rString ) const;
352cdf0e10cSrcweir 		void showParseTree( ::rtl::OUStringBuffer& _inout_rBuf, sal_uInt32 nLevel ) const;
353cdf0e10cSrcweir #endif
354cdf0e10cSrcweir 
355cdf0e10cSrcweir 			// GetNodeType gibt den Knotentyp zurueck
getNodeType() const356cdf0e10cSrcweir 		SQLNodeType getNodeType() const {return m_eNodeType;};
357cdf0e10cSrcweir 
358cdf0e10cSrcweir 			// RuleId liefert die RuleId der Regel des Knotens (nur bei IsRule())
getRuleID() const359cdf0e10cSrcweir 		sal_uInt32 getRuleID() const {return m_nNodeID;}
360cdf0e10cSrcweir 
361cdf0e10cSrcweir         /** returns the ID of the rule represented by the node
362cdf0e10cSrcweir 
363cdf0e10cSrcweir             If the node does not represent a rule, UNKNOWN_RULE is returned
364cdf0e10cSrcweir         */
365cdf0e10cSrcweir         Rule getKnownRuleID() const;
366cdf0e10cSrcweir 
367cdf0e10cSrcweir 			// RuleId liefert die TokenId des Tokens des Knotens (nur bei ! IsRule())
getTokenID() const368cdf0e10cSrcweir 		sal_uInt32 getTokenID() const {return m_nNodeID;}
369cdf0e10cSrcweir 
370cdf0e10cSrcweir 			// IsRule testet ob ein Node eine Regel (NonTerminal) ist
371cdf0e10cSrcweir 			// Achtung : Regeln koenne auch Blaetter sein, z.B. leere Listen
isRule() const372cdf0e10cSrcweir 		sal_Bool isRule() const
373cdf0e10cSrcweir 			{ return (m_eNodeType == SQL_NODE_RULE) || (m_eNodeType == SQL_NODE_LISTRULE)
374cdf0e10cSrcweir 				|| (m_eNodeType == SQL_NODE_COMMALISTRULE);}
375cdf0e10cSrcweir 
376cdf0e10cSrcweir 			// IsToken testet ob ein Node ein Token (Terminal) ist
isToken() const377cdf0e10cSrcweir 		sal_Bool isToken() const {return !isRule();} // ein Token ist keine Regel
378cdf0e10cSrcweir 
379cdf0e10cSrcweir 				// TokenValue liefert den NodeValue eines Tokens
getTokenValue() const380cdf0e10cSrcweir 		const ::rtl::OUString& getTokenValue() const {return m_aNodeValue;}
381cdf0e10cSrcweir 
382cdf0e10cSrcweir 			// SetTokenValue setzt den NodeValue
setTokenValue(const::rtl::OUString & rString)383cdf0e10cSrcweir 		void setTokenValue(const ::rtl::OUString& rString) {	if (isToken()) m_aNodeValue = rString;}
384cdf0e10cSrcweir 
385cdf0e10cSrcweir 			// IsLeaf testet ob ein Node ein Blatt ist
isLeaf() const386cdf0e10cSrcweir 		sal_Bool isLeaf() const {return m_aChildren.empty();}
387cdf0e10cSrcweir 
388cdf0e10cSrcweir 		// negate only a searchcondition, any other rule could cause a gpf
389cdf0e10cSrcweir 		static void negateSearchCondition(OSQLParseNode*& pSearchCondition,sal_Bool bNegate=sal_False);
390cdf0e10cSrcweir 
391cdf0e10cSrcweir 		// normalize a logic form
392cdf0e10cSrcweir 		// e.q. (a or b) and (c or d) <=> a and c or a and d or b and c or b and d
393cdf0e10cSrcweir 		static void disjunctiveNormalForm(OSQLParseNode*& pSearchCondition);
394cdf0e10cSrcweir 
395cdf0e10cSrcweir 		//	 Simplies logic expressions
396cdf0e10cSrcweir 		// a * a		= a
397cdf0e10cSrcweir 		// a + a		= a
398cdf0e10cSrcweir 		// a * ( a + b) = a
399cdf0e10cSrcweir 		// a + a * b	= a
400cdf0e10cSrcweir 		static void absorptions(OSQLParseNode*& pSearchCondition);
401cdf0e10cSrcweir 
402cdf0e10cSrcweir 		// erase not nessary braces
403cdf0e10cSrcweir 		static void eraseBraces(OSQLParseNode*& pSearchCondition);
404cdf0e10cSrcweir 
405cdf0e10cSrcweir 		// makes the logic formula a little more smaller
406cdf0e10cSrcweir 		static void compress(OSQLParseNode*& pSearchCondition);
407cdf0e10cSrcweir 		// return the catalog, schema and tablename form this node
408cdf0e10cSrcweir 		// _pTableNode must be a rule of that above or a SQL_TOKEN_NAME
409cdf0e10cSrcweir 		static sal_Bool getTableComponents(const OSQLParseNode* _pTableNode,
410cdf0e10cSrcweir 											::com::sun::star::uno::Any &_rCatalog,
411cdf0e10cSrcweir 											::rtl::OUString &_rSchema,
412cdf0e10cSrcweir 											::rtl::OUString &_rTable
413cdf0e10cSrcweir                                             ,const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XDatabaseMetaData >& _xMetaData);
414cdf0e10cSrcweir 
415*07a3d7f1SPedro Giffuni 		// susbtitute all occurrences of :var or [name] into the dynamic parameter ?
416cdf0e10cSrcweir 		// _pNode will be modified if parameters exists
417cdf0e10cSrcweir 		static void substituteParameterNames(OSQLParseNode* _pNode);
418cdf0e10cSrcweir 
419cdf0e10cSrcweir         /** return a table range when it exists.
420cdf0e10cSrcweir         */
421cdf0e10cSrcweir         static ::rtl::OUString getTableRange(const OSQLParseNode* _pTableRef);
422cdf0e10cSrcweir 
423cdf0e10cSrcweir 	protected:
424cdf0e10cSrcweir 		// ParseNodeToStr konkateniert alle Token (Blaetter) des ParseNodes
425cdf0e10cSrcweir 		void parseNodeToStr(::rtl::OUString& rString,
426cdf0e10cSrcweir 							const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection >& _rxConnection,
427cdf0e10cSrcweir 							const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter,
428cdf0e10cSrcweir 							const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > & _xField,
429cdf0e10cSrcweir 							const ::com::sun::star::lang::Locale& rIntl,
430cdf0e10cSrcweir 							const IParseContext* pContext,
431cdf0e10cSrcweir 							bool _bIntl,
432cdf0e10cSrcweir 							bool _bQuote,
433cdf0e10cSrcweir 							sal_Char _cDecSep,
434cdf0e10cSrcweir 							bool _bPredicate,
435cdf0e10cSrcweir                             bool _bSubstitute) const;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir 	private:
438cdf0e10cSrcweir 		void impl_parseNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const;
439cdf0e10cSrcweir 		void impl_parseLikeNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const;
440cdf0e10cSrcweir         void impl_parseTableRangeNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const;
441cdf0e10cSrcweir 
442cdf0e10cSrcweir         /** parses a table_name node into a SQL statement particle.
443cdf0e10cSrcweir             @return
444cdf0e10cSrcweir                 <TRUE/> if and only if parsing was successful, <FALSE/> if default handling should
445cdf0e10cSrcweir                 be applied.
446cdf0e10cSrcweir         */
447cdf0e10cSrcweir 		bool impl_parseTableNameNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir         sal_Bool addDateValue(::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const;
450cdf0e10cSrcweir 		::rtl::OUString convertDateTimeString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const;
451cdf0e10cSrcweir 		::rtl::OUString convertDateString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const;
452cdf0e10cSrcweir 		::rtl::OUString convertTimeString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const;
453cdf0e10cSrcweir 		void parseLeaf(::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const;
454cdf0e10cSrcweir 	};
455cdf0e10cSrcweir 
456cdf0e10cSrcweir 	//-----------------------------------------------------------------------------
getChild(sal_uInt32 nPos) const457cdf0e10cSrcweir 	inline OSQLParseNode* OSQLParseNode::getChild(sal_uInt32 nPos) const
458cdf0e10cSrcweir 	{
459cdf0e10cSrcweir 		OSL_ENSURE(nPos < m_aChildren.size(), "Invalid Position");
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 		//	return m_aChildren[nPos];
462cdf0e10cSrcweir 		return m_aChildren.at(nPos);
463cdf0e10cSrcweir 	}
464cdf0e10cSrcweir 
465cdf0e10cSrcweir 	// Utility-Methoden zum Abfragen auf bestimmte Rules, Token oder Punctuation:
466cdf0e10cSrcweir 	#define SQL_ISRULE(pParseNode, eRule) 	((pParseNode)->isRule() && (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::eRule))
467cdf0e10cSrcweir 	#define SQL_ISTOKEN(pParseNode, token) ((pParseNode)->isToken() && (pParseNode)->getTokenID() == SQL_TOKEN_##token)
468cdf0e10cSrcweir 	#define SQL_ISPUNCTUATION(pParseNode, aString) ((pParseNode)->getNodeType() == SQL_NODE_PUNCTUATION && !(pParseNode)->getTokenValue().compareToAscii(aString))
469cdf0e10cSrcweir }
470cdf0e10cSrcweir 
471cdf0e10cSrcweir #endif	//_CONNECTIVITY_SQLNODE_HXX
472