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