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