1*9b5730f6SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*9b5730f6SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*9b5730f6SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*9b5730f6SAndrew Rist  * distributed with this work for additional information
6*9b5730f6SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*9b5730f6SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*9b5730f6SAndrew Rist  * "License"); you may not use this file except in compliance
9*9b5730f6SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*9b5730f6SAndrew Rist  *
11*9b5730f6SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*9b5730f6SAndrew Rist  *
13*9b5730f6SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*9b5730f6SAndrew Rist  * software distributed under the License is distributed on an
15*9b5730f6SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*9b5730f6SAndrew Rist  * KIND, either express or implied.  See the License for the
17*9b5730f6SAndrew Rist  * specific language governing permissions and limitations
18*9b5730f6SAndrew Rist  * under the License.
19*9b5730f6SAndrew Rist  *
20*9b5730f6SAndrew Rist  *************************************************************/
21*9b5730f6SAndrew Rist 
22*9b5730f6SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_connectivity.hxx"
26cdf0e10cSrcweir #include <connectivity/predicateinput.hxx>
27cdf0e10cSrcweir #include <comphelper/types.hxx>
28cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
29cdf0e10cSrcweir #include <com/sun/star/sdbc/DataType.hpp>
30cdf0e10cSrcweir #include <com/sun/star/sdbc/ColumnValue.hpp>
31cdf0e10cSrcweir #include <osl/diagnose.h>
32cdf0e10cSrcweir #include <connectivity/sqlnode.hxx>
33cdf0e10cSrcweir #include <connectivity/PColumn.hxx>
34cdf0e10cSrcweir #include <comphelper/numbers.hxx>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir //.........................................................................
37cdf0e10cSrcweir namespace dbtools
38cdf0e10cSrcweir {
39cdf0e10cSrcweir //.........................................................................
40cdf0e10cSrcweir 
41cdf0e10cSrcweir 	using ::com::sun::star::sdbc::XConnection;
42cdf0e10cSrcweir 	using ::com::sun::star::lang::XMultiServiceFactory;
43cdf0e10cSrcweir 	using ::com::sun::star::util::XNumberFormatsSupplier;
44cdf0e10cSrcweir 	using ::com::sun::star::util::XNumberFormatter;
45cdf0e10cSrcweir 	using ::com::sun::star::uno::UNO_QUERY;
46cdf0e10cSrcweir 	using ::com::sun::star::beans::XPropertySet;
47cdf0e10cSrcweir 	using ::com::sun::star::beans::XPropertySetInfo;
48cdf0e10cSrcweir 	using ::com::sun::star::lang::Locale;
49cdf0e10cSrcweir 	using ::com::sun::star::uno::Exception;
50cdf0e10cSrcweir 	using ::com::sun::star::i18n::XLocaleData;
51cdf0e10cSrcweir 	using ::com::sun::star::i18n::LocaleDataItem;
52cdf0e10cSrcweir 
53cdf0e10cSrcweir 	using namespace ::com::sun::star::sdbc;
54cdf0e10cSrcweir 	using namespace ::connectivity;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir 	using ::connectivity::OSQLParseNode;
57cdf0e10cSrcweir 
58cdf0e10cSrcweir 	#define Reference ::com::sun::star::uno::Reference
59cdf0e10cSrcweir 
60cdf0e10cSrcweir 	//=====================================================================
61cdf0e10cSrcweir 	//---------------------------------------------------------------------
lcl_getSeparatorChar(const::rtl::OUString & _rSeparator,sal_Unicode _nFallback)62cdf0e10cSrcweir 	static sal_Unicode lcl_getSeparatorChar( const ::rtl::OUString& _rSeparator, sal_Unicode _nFallback )
63cdf0e10cSrcweir 	{
64cdf0e10cSrcweir 		OSL_ENSURE( 0 < _rSeparator.getLength(), "::lcl_getSeparatorChar: invalid separator string!" );
65cdf0e10cSrcweir 
66cdf0e10cSrcweir 		sal_Unicode nReturn( _nFallback );
67cdf0e10cSrcweir 		if ( _rSeparator.getLength() )
68cdf0e10cSrcweir 			nReturn = static_cast< sal_Char >( _rSeparator.getStr()[0] );
69cdf0e10cSrcweir 		return nReturn;
70cdf0e10cSrcweir 	}
71cdf0e10cSrcweir 
72cdf0e10cSrcweir 	//=====================================================================
73cdf0e10cSrcweir 	//= OPredicateInputController
74cdf0e10cSrcweir 	//=====================================================================
75cdf0e10cSrcweir 	//---------------------------------------------------------------------
getSeparatorChars(const Locale & _rLocale,sal_Unicode & _rDecSep,sal_Unicode & _rThdSep) const76cdf0e10cSrcweir 	sal_Bool OPredicateInputController::getSeparatorChars( const Locale& _rLocale, sal_Unicode& _rDecSep, sal_Unicode& _rThdSep ) const
77cdf0e10cSrcweir 	{
78cdf0e10cSrcweir 		_rDecSep = '.';
79cdf0e10cSrcweir 		_rThdSep = ',';
80cdf0e10cSrcweir 		try
81cdf0e10cSrcweir 		{
82cdf0e10cSrcweir 			LocaleDataItem aLocaleData;
83cdf0e10cSrcweir 			if ( m_xLocaleData.is() )
84cdf0e10cSrcweir 			{
85cdf0e10cSrcweir 				aLocaleData = m_xLocaleData->getLocaleItem( _rLocale );
86cdf0e10cSrcweir 				_rDecSep = lcl_getSeparatorChar( aLocaleData.decimalSeparator, _rDecSep );
87cdf0e10cSrcweir 				_rThdSep = lcl_getSeparatorChar( aLocaleData.decimalSeparator, _rThdSep );
88cdf0e10cSrcweir 				return sal_True;
89cdf0e10cSrcweir 			}
90cdf0e10cSrcweir 		}
91cdf0e10cSrcweir 		catch( const Exception& )
92cdf0e10cSrcweir 		{
93cdf0e10cSrcweir 			OSL_ENSURE( sal_False, "OPredicateInputController::getSeparatorChars: caught an exception!" );
94cdf0e10cSrcweir 		}
95cdf0e10cSrcweir 		return sal_False;
96cdf0e10cSrcweir 	}
97cdf0e10cSrcweir 
98cdf0e10cSrcweir 	//---------------------------------------------------------------------
OPredicateInputController(const Reference<XMultiServiceFactory> & _rxORB,const Reference<XConnection> & _rxConnection,const IParseContext * _pParseContext)99cdf0e10cSrcweir 	OPredicateInputController::OPredicateInputController(
100cdf0e10cSrcweir 		const Reference< XMultiServiceFactory >& _rxORB, const Reference< XConnection >& _rxConnection, const IParseContext* _pParseContext )
101cdf0e10cSrcweir 		:m_xORB( _rxORB )
102cdf0e10cSrcweir 		,m_xConnection( _rxConnection )
103cdf0e10cSrcweir 		,m_aParser( m_xORB, _pParseContext )
104cdf0e10cSrcweir 	{
105cdf0e10cSrcweir 		try
106cdf0e10cSrcweir 		{
107cdf0e10cSrcweir 			// create a number formatter / number formats supplier pair
108cdf0e10cSrcweir 			OSL_ENSURE( m_xORB.is(), "OPredicateInputController::OPredicateInputController: need a service factory!" );
109cdf0e10cSrcweir 			if ( m_xORB.is() )
110cdf0e10cSrcweir 			{
111cdf0e10cSrcweir 				m_xFormatter = Reference< XNumberFormatter >( m_xORB->createInstance(
112cdf0e10cSrcweir 					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.NumberFormatter" ) ) ),
113cdf0e10cSrcweir 					UNO_QUERY
114cdf0e10cSrcweir 				);
115cdf0e10cSrcweir 			}
116cdf0e10cSrcweir 
117cdf0e10cSrcweir 			Reference< XNumberFormatsSupplier >  xNumberFormats = ::dbtools::getNumberFormats( m_xConnection, sal_True );
118cdf0e10cSrcweir 			if ( !xNumberFormats.is() )
119cdf0e10cSrcweir 				::comphelper::disposeComponent( m_xFormatter );
120cdf0e10cSrcweir 			else if ( m_xFormatter.is() )
121cdf0e10cSrcweir 				m_xFormatter->attachNumberFormatsSupplier( xNumberFormats );
122cdf0e10cSrcweir 
123cdf0e10cSrcweir 			// create the locale data
124cdf0e10cSrcweir 			if ( m_xORB.is() )
125cdf0e10cSrcweir 			{
126cdf0e10cSrcweir 				m_xLocaleData = m_xLocaleData.query( m_xORB->createInstance(
127cdf0e10cSrcweir 					::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.i18n.LocaleData" ) ) )
128cdf0e10cSrcweir 				);
129cdf0e10cSrcweir 			}
130cdf0e10cSrcweir 		}
131cdf0e10cSrcweir 		catch( const Exception& )
132cdf0e10cSrcweir 		{
133cdf0e10cSrcweir 			OSL_ENSURE( sal_False, "OPredicateInputController::OPredicateInputController: caught an exception!" );
134cdf0e10cSrcweir 		}
135cdf0e10cSrcweir 	}
136cdf0e10cSrcweir 
137cdf0e10cSrcweir 	//---------------------------------------------------------------------
implPredicateTree(::rtl::OUString & _rErrorMessage,const::rtl::OUString & _rStatement,const Reference<XPropertySet> & _rxField) const138cdf0e10cSrcweir 	OSQLParseNode* OPredicateInputController::implPredicateTree(::rtl::OUString& _rErrorMessage, const ::rtl::OUString& _rStatement, const Reference< XPropertySet > & _rxField) const
139cdf0e10cSrcweir 	{
140cdf0e10cSrcweir 		OSQLParseNode* pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, _rStatement, m_xFormatter, _rxField );
141cdf0e10cSrcweir 		if ( !pReturn )
142cdf0e10cSrcweir 		{	// is it a text field ?
143cdf0e10cSrcweir 			sal_Int32 nType = DataType::OTHER;
144cdf0e10cSrcweir 			_rxField->getPropertyValue( ::rtl::OUString::createFromAscii( "Type" ) ) >>= nType;
145cdf0e10cSrcweir 
146cdf0e10cSrcweir 			if	(	( DataType::CHAR		== nType )
147cdf0e10cSrcweir 				||	( DataType::VARCHAR		== nType )
148cdf0e10cSrcweir 				||	( DataType::LONGVARCHAR == nType )
149cdf0e10cSrcweir 				||	( DataType::CLOB		== nType )
150cdf0e10cSrcweir 				)
151cdf0e10cSrcweir 			{	// yes -> force a quoted text and try again
152cdf0e10cSrcweir 				::rtl::OUString sQuoted( _rStatement );
153cdf0e10cSrcweir 				if	(	sQuoted.getLength()
154cdf0e10cSrcweir 					&&	(	(sQuoted.getStr()[0] != '\'')
155cdf0e10cSrcweir 						||	(sQuoted.getStr()[ sQuoted.getLength() - 1 ] != '\'' )
156cdf0e10cSrcweir 						)
157cdf0e10cSrcweir 					)
158cdf0e10cSrcweir 				{
159cdf0e10cSrcweir 					static const ::rtl::OUString sSingleQuote( RTL_CONSTASCII_USTRINGPARAM( "'" ) );
160cdf0e10cSrcweir 					static const ::rtl::OUString sDoubleQuote( RTL_CONSTASCII_USTRINGPARAM( "''" ) );
161cdf0e10cSrcweir 
162cdf0e10cSrcweir 					sal_Int32 nIndex = -1;
163cdf0e10cSrcweir 					sal_Int32 nTemp = 0;
164cdf0e10cSrcweir 					while ( -1 != ( nIndex = sQuoted.indexOf( '\'',nTemp ) ) )
165cdf0e10cSrcweir 					{
166cdf0e10cSrcweir 						sQuoted = sQuoted.replaceAt( nIndex, 1, sDoubleQuote );
167cdf0e10cSrcweir 						nTemp = nIndex+2;
168cdf0e10cSrcweir 					}
169cdf0e10cSrcweir 
170cdf0e10cSrcweir 					::rtl::OUString sTemp( sSingleQuote );
171cdf0e10cSrcweir 					( sTemp += sQuoted ) += sSingleQuote;
172cdf0e10cSrcweir 					sQuoted = sTemp;
173cdf0e10cSrcweir 				}
174cdf0e10cSrcweir 				pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, sQuoted, m_xFormatter, _rxField );
175cdf0e10cSrcweir 			}
176cdf0e10cSrcweir 
177cdf0e10cSrcweir 			// one more fallback: for numeric fields, and value strings containing a decimal/thousands separator
178cdf0e10cSrcweir 			// problem which is to be solved with this:
179cdf0e10cSrcweir 			// * a system locale "german"
180cdf0e10cSrcweir 			// * a column formatted with an english number format
181cdf0e10cSrcweir 			// => the output is german (as we use the system locale for this), i.e. "3,4"
182cdf0e10cSrcweir 			// => the input does not recognize the german text, as predicateTree uses the number format
183cdf0e10cSrcweir 			//	  of the column to determine the main locale - the locale on the context is only a fallback
184cdf0e10cSrcweir 			if	(	( DataType::FLOAT == nType )
185cdf0e10cSrcweir 				||	( DataType::REAL == nType )
186cdf0e10cSrcweir 				||	( DataType::DOUBLE == nType )
187cdf0e10cSrcweir 				||	( DataType::NUMERIC == nType )
188cdf0e10cSrcweir 				||	( DataType::DECIMAL == nType )
189cdf0e10cSrcweir 				)
190cdf0e10cSrcweir 			{
191cdf0e10cSrcweir 				const IParseContext& rParseContext = m_aParser.getContext();
192cdf0e10cSrcweir 				// get the separators for the locale of our parse context
193cdf0e10cSrcweir 				sal_Unicode nCtxDecSep;
194cdf0e10cSrcweir 				sal_Unicode nCtxThdSep;
195cdf0e10cSrcweir 				getSeparatorChars( rParseContext.getPreferredLocale(), nCtxDecSep, nCtxThdSep );
196cdf0e10cSrcweir 
197cdf0e10cSrcweir 				// determine the locale of the column we're building a predicate string for
198cdf0e10cSrcweir 				sal_Unicode nFmtDecSep( nCtxDecSep );
199cdf0e10cSrcweir 				sal_Unicode nFmtThdSep( nCtxThdSep );
200cdf0e10cSrcweir 				try
201cdf0e10cSrcweir 				{
202cdf0e10cSrcweir 					Reference< XPropertySetInfo > xPSI( _rxField->getPropertySetInfo() );
203cdf0e10cSrcweir 					if ( xPSI.is() && xPSI->hasPropertyByName( ::rtl::OUString::createFromAscii( "FormatKey" ) ) )
204cdf0e10cSrcweir 					{
205cdf0e10cSrcweir 						sal_Int32 nFormatKey = 0;
206cdf0e10cSrcweir 						_rxField->getPropertyValue( ::rtl::OUString::createFromAscii( "FormatKey" ) ) >>= nFormatKey;
207cdf0e10cSrcweir 						if ( nFormatKey && m_xFormatter.is() )
208cdf0e10cSrcweir 						{
209cdf0e10cSrcweir 							Locale aFormatLocale;
210cdf0e10cSrcweir 							::comphelper::getNumberFormatProperty(
211cdf0e10cSrcweir 								m_xFormatter,
212cdf0e10cSrcweir 								nFormatKey,
213cdf0e10cSrcweir 								::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Locale" ) )
214cdf0e10cSrcweir 							) >>= aFormatLocale;
215cdf0e10cSrcweir 
216cdf0e10cSrcweir 							// valid locale
217cdf0e10cSrcweir 							if ( aFormatLocale.Language.getLength() )
218cdf0e10cSrcweir 							{
219cdf0e10cSrcweir 								getSeparatorChars( aFormatLocale, nFmtDecSep, nCtxThdSep );
220cdf0e10cSrcweir 							}
221cdf0e10cSrcweir 						}
222cdf0e10cSrcweir 					}
223cdf0e10cSrcweir 				}
224cdf0e10cSrcweir 				catch( const Exception& )
225cdf0e10cSrcweir 				{
226cdf0e10cSrcweir 					OSL_ENSURE( sal_False, "OPredicateInputController::implPredicateTree: caught an exception while dealing with the formats!" );
227cdf0e10cSrcweir 				}
228cdf0e10cSrcweir 
229cdf0e10cSrcweir 				sal_Bool bDecDiffers = ( nCtxDecSep != nFmtDecSep );
230cdf0e10cSrcweir 				sal_Bool bFmtDiffers = ( nCtxThdSep != nFmtThdSep );
231cdf0e10cSrcweir 				if ( bDecDiffers || bFmtDiffers )
232cdf0e10cSrcweir 				{	// okay, at least one differs
233cdf0e10cSrcweir 					// "translate" the value into the "format locale"
234cdf0e10cSrcweir 					::rtl::OUString sTranslated( _rStatement );
235cdf0e10cSrcweir 					const sal_Unicode nIntermediate( '_' );
236cdf0e10cSrcweir 					sTranslated = sTranslated.replace( nCtxDecSep,	nIntermediate );
237cdf0e10cSrcweir 					sTranslated = sTranslated.replace( nCtxThdSep,	nFmtThdSep );
238cdf0e10cSrcweir 					sTranslated = sTranslated.replace( nIntermediate, nFmtDecSep );
239cdf0e10cSrcweir 
240cdf0e10cSrcweir 					pReturn = const_cast< OSQLParser& >( m_aParser ).predicateTree( _rErrorMessage, sTranslated, m_xFormatter, _rxField );
241cdf0e10cSrcweir 				}
242cdf0e10cSrcweir 			}
243cdf0e10cSrcweir 		}
244cdf0e10cSrcweir 		return pReturn;
245cdf0e10cSrcweir 	}
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 	//---------------------------------------------------------------------
normalizePredicateString(::rtl::OUString & _rPredicateValue,const Reference<XPropertySet> & _rxField,::rtl::OUString * _pErrorMessage) const248cdf0e10cSrcweir 	sal_Bool OPredicateInputController::normalizePredicateString(
249cdf0e10cSrcweir 		::rtl::OUString& _rPredicateValue, const Reference< XPropertySet > & _rxField, ::rtl::OUString* _pErrorMessage ) const
250cdf0e10cSrcweir 	{
251cdf0e10cSrcweir 		OSL_ENSURE( m_xConnection.is() && m_xFormatter.is() && _rxField.is(),
252cdf0e10cSrcweir 			"OPredicateInputController::normalizePredicateString: invalid state or params!" );
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 		sal_Bool bSuccess = sal_False;
255cdf0e10cSrcweir 		if ( m_xConnection.is() && m_xFormatter.is() && _rxField.is() )
256cdf0e10cSrcweir 		{
257cdf0e10cSrcweir 			// parse the string
258cdf0e10cSrcweir 			::rtl::OUString sError;
259cdf0e10cSrcweir 			::rtl::OUString sTransformedText( _rPredicateValue );
260cdf0e10cSrcweir 			OSQLParseNode* pParseNode = implPredicateTree( sError, sTransformedText, _rxField );
261cdf0e10cSrcweir 			if ( _pErrorMessage ) *_pErrorMessage = sError;
262cdf0e10cSrcweir 
263cdf0e10cSrcweir 			if ( pParseNode )
264cdf0e10cSrcweir 			{
265cdf0e10cSrcweir 				const IParseContext& rParseContext = m_aParser.getContext();
266cdf0e10cSrcweir 				sal_Unicode nDecSeparator, nThousandSeparator;
267cdf0e10cSrcweir 				getSeparatorChars( rParseContext.getPreferredLocale(), nDecSeparator, nThousandSeparator );
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 				// translate it back into a string
270cdf0e10cSrcweir 				sTransformedText = ::rtl::OUString();
271cdf0e10cSrcweir 				pParseNode->parseNodeToPredicateStr(
272cdf0e10cSrcweir 					sTransformedText, m_xConnection, m_xFormatter, _rxField,
273cdf0e10cSrcweir 					rParseContext.getPreferredLocale(), (sal_Char)nDecSeparator, &rParseContext
274cdf0e10cSrcweir 				);
275cdf0e10cSrcweir 				_rPredicateValue = sTransformedText;
276cdf0e10cSrcweir 				delete pParseNode;
277cdf0e10cSrcweir 
278cdf0e10cSrcweir 				bSuccess = sal_True;
279cdf0e10cSrcweir 			}
280cdf0e10cSrcweir 		}
281cdf0e10cSrcweir 
282cdf0e10cSrcweir 		return bSuccess;
283cdf0e10cSrcweir 	}
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 	//---------------------------------------------------------------------
getPredicateValue(const::rtl::OUString & _rPredicateValue,const Reference<XPropertySet> & _rxField,sal_Bool _bForStatementUse,::rtl::OUString * _pErrorMessage) const286cdf0e10cSrcweir 	::rtl::OUString OPredicateInputController::getPredicateValue(
287cdf0e10cSrcweir 		const ::rtl::OUString& _rPredicateValue, const Reference< XPropertySet > & _rxField,
288cdf0e10cSrcweir 		sal_Bool _bForStatementUse, ::rtl::OUString* _pErrorMessage ) const
289cdf0e10cSrcweir 	{
290cdf0e10cSrcweir 		OSL_ENSURE( _rxField.is(), "OPredicateInputController::getPredicateValue: invalid params!" );
291cdf0e10cSrcweir 		::rtl::OUString sReturn;
292cdf0e10cSrcweir 		if ( _rxField.is() )
293cdf0e10cSrcweir 		{
294cdf0e10cSrcweir 			::rtl::OUString sValue( _rPredicateValue );
295cdf0e10cSrcweir 
296cdf0e10cSrcweir 			// a little problem : if the field is a text field, the normalizePredicateString added two
297cdf0e10cSrcweir 			// '-characters to the text. If we would give this to predicateTree this would add
298cdf0e10cSrcweir 			// two  additional '-characters which we don't want. So check the field format.
299cdf0e10cSrcweir 			// FS - 06.01.00 - 71532
300cdf0e10cSrcweir 			sal_Bool bValidQuotedText =	( sValue.getLength() >= 2 )
301cdf0e10cSrcweir 									&&	( sValue.getStr()[0] == '\'' )
302cdf0e10cSrcweir 									&&	( sValue.getStr()[ sValue.getLength() - 1 ] == '\'' );
303cdf0e10cSrcweir 				// again : as normalizePredicateString always did a conversion on the value text,
304cdf0e10cSrcweir 				// bValidQuotedText == sal_True implies that we have a text field, as no other field
305cdf0e10cSrcweir 				// values will be formatted with the quote characters
306cdf0e10cSrcweir 			if ( bValidQuotedText )
307cdf0e10cSrcweir 			{
308cdf0e10cSrcweir 				sValue = sValue.copy( 1, sValue.getLength() - 2 );
309cdf0e10cSrcweir 				static const ::rtl::OUString sSingleQuote( RTL_CONSTASCII_USTRINGPARAM( "'" ) );
310cdf0e10cSrcweir 				static const ::rtl::OUString sDoubleQuote( RTL_CONSTASCII_USTRINGPARAM( "''" ) );
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 				sal_Int32 nIndex = -1;
313cdf0e10cSrcweir 				sal_Int32 nTemp = 0;
314cdf0e10cSrcweir 				while ( -1 != ( nIndex = sValue.indexOf( sDoubleQuote,nTemp ) ) )
315cdf0e10cSrcweir 				{
316cdf0e10cSrcweir 					sValue = sValue.replaceAt( nIndex, 2, sSingleQuote );
317cdf0e10cSrcweir 					nTemp = nIndex+2;
318cdf0e10cSrcweir 				}
319cdf0e10cSrcweir 			}
320cdf0e10cSrcweir 
321cdf0e10cSrcweir 			// The following is mostly stolen from the former implementation in the parameter dialog
322cdf0e10cSrcweir 			// (dbaccess/source/ui/dlg/paramdialog.cxx). I do not fully understand this .....
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 			::rtl::OUString sError;
325cdf0e10cSrcweir 			OSQLParseNode* pParseNode = implPredicateTree( sError, sValue, _rxField );
326cdf0e10cSrcweir 			if ( _pErrorMessage )
327cdf0e10cSrcweir                 *_pErrorMessage = sError;
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 			sReturn = implParseNode(pParseNode,_bForStatementUse);
330cdf0e10cSrcweir 		}
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 		return sReturn;
333cdf0e10cSrcweir 	}
334cdf0e10cSrcweir 
getPredicateValue(const::rtl::OUString & _sField,const::rtl::OUString & _rPredicateValue,sal_Bool _bForStatementUse,::rtl::OUString * _pErrorMessage) const335cdf0e10cSrcweir     ::rtl::OUString OPredicateInputController::getPredicateValue(
336cdf0e10cSrcweir 		const ::rtl::OUString& _sField, const ::rtl::OUString& _rPredicateValue, sal_Bool _bForStatementUse, ::rtl::OUString* _pErrorMessage ) const
337cdf0e10cSrcweir 	{
338cdf0e10cSrcweir 		::rtl::OUString sReturn = _rPredicateValue;
339cdf0e10cSrcweir         ::rtl::OUString sError;
340cdf0e10cSrcweir         ::rtl::OUString sField = _sField;
341cdf0e10cSrcweir         sal_Int32 nIndex = 0;
342cdf0e10cSrcweir         sField = sField.getToken(0,'(',nIndex);
343cdf0e10cSrcweir         if(nIndex == -1)
344cdf0e10cSrcweir 			sField = _sField;
345cdf0e10cSrcweir         sal_Int32 nType = ::connectivity::OSQLParser::getFunctionReturnType(sField,&m_aParser.getContext());
346cdf0e10cSrcweir         if ( nType == DataType::OTHER || !sField.getLength() )
347cdf0e10cSrcweir         {
348cdf0e10cSrcweir             // first try the international version
349cdf0e10cSrcweir             ::rtl::OUString sSql;
350cdf0e10cSrcweir             sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("SELECT * "));
351cdf0e10cSrcweir             sSql += ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(" FROM x WHERE "));
352cdf0e10cSrcweir             sSql += sField;
353cdf0e10cSrcweir             sSql += _rPredicateValue;
354cdf0e10cSrcweir             ::std::auto_ptr<OSQLParseNode> pParseNode( const_cast< OSQLParser& >( m_aParser ).parseTree( sError, sSql, sal_True ) );
355cdf0e10cSrcweir             nType = DataType::DOUBLE;
356cdf0e10cSrcweir             if ( pParseNode.get() )
357cdf0e10cSrcweir             {
358cdf0e10cSrcweir                 OSQLParseNode* pColumnRef = pParseNode->getByRule(OSQLParseNode::column_ref);
359cdf0e10cSrcweir                 if ( pColumnRef )
360cdf0e10cSrcweir                 {
361cdf0e10cSrcweir                 }
362cdf0e10cSrcweir             }
363cdf0e10cSrcweir         }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir         Reference<XDatabaseMetaData> xMeta = m_xConnection->getMetaData();
366cdf0e10cSrcweir         parse::OParseColumn* pColumn = new parse::OParseColumn(	sField,
367cdf0e10cSrcweir 												                ::rtl::OUString(),
368cdf0e10cSrcweir 												                ::rtl::OUString(),
369cdf0e10cSrcweir                                                                 ::rtl::OUString(),
370cdf0e10cSrcweir 												                ColumnValue::NULLABLE_UNKNOWN,
371cdf0e10cSrcweir 												                0,
372cdf0e10cSrcweir 												                0,
373cdf0e10cSrcweir 												                nType,
374cdf0e10cSrcweir 												                sal_False,
375cdf0e10cSrcweir 												                sal_False,
376cdf0e10cSrcweir 												                xMeta.is() && xMeta->supportsMixedCaseQuotedIdentifiers());
377cdf0e10cSrcweir         Reference<XPropertySet> xColumn = pColumn;
378cdf0e10cSrcweir         pColumn->setFunction(sal_True);
379cdf0e10cSrcweir         pColumn->setRealName(sField);
380cdf0e10cSrcweir 
381cdf0e10cSrcweir 		OSQLParseNode* pParseNode = implPredicateTree( sError, _rPredicateValue, xColumn );
382cdf0e10cSrcweir 		if ( _pErrorMessage )
383cdf0e10cSrcweir             *_pErrorMessage = sError;
384cdf0e10cSrcweir         return pParseNode ? implParseNode(pParseNode,_bForStatementUse) : sReturn;
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir 
implParseNode(OSQLParseNode * pParseNode,sal_Bool _bForStatementUse) const387cdf0e10cSrcweir     ::rtl::OUString OPredicateInputController::implParseNode(OSQLParseNode* pParseNode,sal_Bool _bForStatementUse) const
388cdf0e10cSrcweir     {
389cdf0e10cSrcweir         ::rtl::OUString sReturn;
390cdf0e10cSrcweir         if ( pParseNode )
391cdf0e10cSrcweir 		{
392cdf0e10cSrcweir             ::std::auto_ptr<OSQLParseNode> pTemp(pParseNode);
393cdf0e10cSrcweir 			OSQLParseNode* pOdbcSpec = pParseNode->getByRule( OSQLParseNode::odbc_fct_spec );
394cdf0e10cSrcweir 			if ( pOdbcSpec )
395cdf0e10cSrcweir 			{
396cdf0e10cSrcweir 				if ( _bForStatementUse )
397cdf0e10cSrcweir 				{
398cdf0e10cSrcweir                     OSQLParseNode* pFuncSpecParent = pOdbcSpec->getParent();
399cdf0e10cSrcweir 					OSL_ENSURE( pFuncSpecParent, "OPredicateInputController::getPredicateValue: an ODBC func spec node without parent?" );
400cdf0e10cSrcweir 					if ( pFuncSpecParent )
401cdf0e10cSrcweir 						pFuncSpecParent->parseNodeToStr(sReturn, m_xConnection, &m_aParser.getContext(), sal_False, sal_True);
402cdf0e10cSrcweir 				}
403cdf0e10cSrcweir 				else
404cdf0e10cSrcweir 				{
405cdf0e10cSrcweir 					OSQLParseNode* pValueNode = pOdbcSpec->getChild(1);
406cdf0e10cSrcweir 					if ( SQL_NODE_STRING == pValueNode->getNodeType() )
407cdf0e10cSrcweir 						sReturn = pValueNode->getTokenValue();
408cdf0e10cSrcweir 					else
409cdf0e10cSrcweir 						pValueNode->parseNodeToStr(sReturn, m_xConnection, &m_aParser.getContext(), sal_False, sal_True);
410cdf0e10cSrcweir 					// sReturn = pOdbcSpec->getChild(1)->getTokenValue();
411cdf0e10cSrcweir 				}
412cdf0e10cSrcweir 			}
413cdf0e10cSrcweir 			else
414cdf0e10cSrcweir 			{
415cdf0e10cSrcweir 				if	( pParseNode->count() >= 3 )
416cdf0e10cSrcweir 				{
417cdf0e10cSrcweir 					OSQLParseNode* pValueNode = pParseNode->getChild(2);
418cdf0e10cSrcweir 					OSL_ENSURE( pValueNode, "OPredicateInputController::getPredicateValue: invalid node child!" );
419cdf0e10cSrcweir 					if ( !_bForStatementUse )
420cdf0e10cSrcweir 					{
421cdf0e10cSrcweir 						if ( SQL_NODE_STRING == pValueNode->getNodeType() )
422cdf0e10cSrcweir 							sReturn = pValueNode->getTokenValue();
423cdf0e10cSrcweir 						else
424cdf0e10cSrcweir 							pValueNode->parseNodeToStr(
425cdf0e10cSrcweir 								sReturn, m_xConnection, &m_aParser.getContext(), sal_False, sal_True
426cdf0e10cSrcweir 							);
427cdf0e10cSrcweir 					}
428cdf0e10cSrcweir 					else
429cdf0e10cSrcweir 						pValueNode->parseNodeToStr(
430cdf0e10cSrcweir 							sReturn, m_xConnection, &m_aParser.getContext(), sal_False, sal_True
431cdf0e10cSrcweir 						);
432cdf0e10cSrcweir 				}
433cdf0e10cSrcweir 				else
434cdf0e10cSrcweir 					OSL_ENSURE( sal_False, "OPredicateInputController::getPredicateValue: unknown/invalid structure (noodbc)!" );
435cdf0e10cSrcweir 			}
436cdf0e10cSrcweir 		}
437cdf0e10cSrcweir         return sReturn;
438cdf0e10cSrcweir     }
439cdf0e10cSrcweir //.........................................................................
440cdf0e10cSrcweir }	// namespace dbtools
441cdf0e10cSrcweir //.........................................................................
442cdf0e10cSrcweir 
443cdf0e10cSrcweir 
444