/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_connectivity.hxx" #include #include #include #define YYBISON 1 #ifndef BISON_INCLUDED #define BISON_INCLUDED #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "connectivity/dbconversion.hxx" #include #include #include #include "TConnection.hxx" #include "sqlscan.hxx" #include #include #include #include "connectivity/dbtools.hxx" #include "connectivity/dbmetadata.hxx" #include "connectivity/sqlerror.hxx" #include #include #include #include #include #include #include using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::util; using namespace ::com::sun::star::beans; using namespace ::com::sun::star::sdb; using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; using namespace ::com::sun::star::i18n; using namespace ::com::sun::star; using namespace ::osl; using namespace ::dbtools; using namespace ::comphelper; extern int SQLyyparse (void); extern ::rtl::OUString ConvertLikeToken(const ::connectivity::OSQLParseNode* pTokenNode, const ::connectivity::OSQLParseNode* pEscapeNode, sal_Bool bInternational); extern void setParser( ::connectivity::OSQLParser* ); namespace { // ----------------------------------------------------------------------------- sal_Bool lcl_saveConvertToNumber(const Reference< XNumberFormatter > & _xFormatter,sal_Int32 _nKey,const ::rtl::OUString& _sValue,double& _nrValue) { sal_Bool bRet = sal_False; try { _nrValue = _xFormatter->convertStringToNumber(_nKey, _sValue); bRet = sal_True; } catch(Exception&) { } return bRet; } // ----------------------------------------------------------------------------- void replaceAndReset(connectivity::OSQLParseNode*& _pResetNode,connectivity::OSQLParseNode* _pNewNode) { _pResetNode->getParent()->replace(_pResetNode, _pNewNode); delete _pResetNode; _pResetNode = _pNewNode; } // ----------------------------------------------------------------------------- /** quotes a string and search for quotes inside the string and replace them with the new quote @param rValue The value to be quoted. @param rQuot The quote @param rQuotToReplace The quote to replace with @return The quoted string. */ ::rtl::OUString SetQuotation(const ::rtl::OUString& rValue, const ::rtl::OUString& rQuot, const ::rtl::OUString& rQuotToReplace) { ::rtl::OUString rNewValue = rQuot; rNewValue += rValue; sal_Int32 nIndex = (sal_Int32)-1; // Quotes durch zweifache Quotes ersetzen, sonst kriegt der Parser Probleme if (rQuot.getLength()) { do { nIndex += 2; nIndex = rNewValue.indexOf(rQuot,nIndex); if(nIndex != -1) rNewValue = rNewValue.replaceAt(nIndex,rQuot.getLength(),rQuotToReplace); } while (nIndex != -1); } rNewValue += rQuot; return rNewValue; } } namespace connectivity { //============================================================================= //= OSQLParser_Data //============================================================================= //----------------------------------------------------------------------------- OSQLParser_Data::OSQLParser_Data( const Reference< XMultiServiceFactory >& _xServiceFactory ) :aErrors( _xServiceFactory ) { } //============================================================================= //= SQLParseNodeParameter //============================================================================= //----------------------------------------------------------------------------- SQLParseNodeParameter::SQLParseNodeParameter( const Reference< XConnection >& _rxConnection, const Reference< XNumberFormatter >& _xFormatter, const Reference< XPropertySet >& _xField, const Locale& _rLocale, const IParseContext* _pContext, bool _bIntl, bool _bQuote, sal_Char _cDecSep, bool _bPredicate, bool _bParseToSDBC ) :rLocale(_rLocale) ,aMetaData( _rxConnection ) ,pParser( NULL ) ,pSubQueryHistory( new QueryNameSet ) ,xFormatter(_xFormatter) ,xField(_xField) ,m_rContext( _pContext ? (const IParseContext&)(*_pContext) : (const IParseContext&)OSQLParser::s_aDefaultContext ) ,cDecSep(_cDecSep) ,bQuote(_bQuote) ,bInternational(_bIntl) ,bPredicate(_bPredicate) ,bParseToSDBCLevel( _bParseToSDBC ) { } //----------------------------------------------------------------------------- SQLParseNodeParameter::~SQLParseNodeParameter() { } //============================================================================= //= OSQLParseNode //============================================================================= //----------------------------------------------------------------------------- ::rtl::OUString OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::convertDateString" ); Date aDate = DBTypeConversion::toDate(rString); Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier()); Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY); double fDate = DBTypeConversion::toDouble(aDate,DBTypeConversion::getNULLDate(xSupplier)); sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 36; // XXX hack return rParam.xFormatter->convertNumberToString(nKey, fDate); } //----------------------------------------------------------------------------- ::rtl::OUString OSQLParseNode::convertDateTimeString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::convertDateTimeString" ); DateTime aDate = DBTypeConversion::toDateTime(rString); Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier()); Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY); double fDateTime = DBTypeConversion::toDouble(aDate,DBTypeConversion::getNULLDate(xSupplier)); sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 51; // XXX hack return rParam.xFormatter->convertNumberToString(nKey, fDateTime); } //----------------------------------------------------------------------------- ::rtl::OUString OSQLParseNode::convertTimeString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::convertTimeString" ); Time aTime = DBTypeConversion::toTime(rString); Reference< XNumberFormatsSupplier > xSupplier(rParam.xFormatter->getNumberFormatsSupplier()); Reference< XNumberFormatTypes > xTypes(xSupplier->getNumberFormats(), UNO_QUERY); double fTime = DBTypeConversion::toDouble(aTime); sal_Int32 nKey = xTypes->getStandardIndex(rParam.rLocale) + 41; // XXX hack return rParam.xFormatter->convertNumberToString(nKey, fTime); } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToStr(::rtl::OUString& rString, const Reference< XConnection >& _rxConnection, const IParseContext* pContext, sal_Bool _bIntl, sal_Bool _bQuote) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToStr" ); parseNodeToStr( rString, _rxConnection, NULL, NULL, pContext ? pContext->getPreferredLocale() : OParseContext::getDefaultLocale(), pContext, _bIntl, _bQuote, '.', false, false ); } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToPredicateStr(::rtl::OUString& rString, const Reference< XConnection >& _rxConnection, const Reference< XNumberFormatter > & xFormatter, const ::com::sun::star::lang::Locale& rIntl, sal_Char _cDec, const IParseContext* pContext ) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToPredicateStr" ); OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!"); if (xFormatter.is()) parseNodeToStr(rString, _rxConnection, xFormatter, NULL, rIntl, pContext, sal_True, sal_True, _cDec, true, false); } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToPredicateStr(::rtl::OUString& rString, const Reference< XConnection > & _rxConnection, const Reference< XNumberFormatter > & xFormatter, const Reference< XPropertySet > & _xField, const ::com::sun::star::lang::Locale& rIntl, sal_Char _cDec, const IParseContext* pContext ) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToPredicateStr" ); OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!"); if (xFormatter.is()) parseNodeToStr( rString, _rxConnection, xFormatter, _xField, rIntl, pContext, true, true, _cDec, true, false ); } //----------------------------------------------------------------------------- void OSQLParseNode::parseNodeToStr(::rtl::OUString& rString, const Reference< XConnection > & _rxConnection, const Reference< XNumberFormatter > & xFormatter, const Reference< XPropertySet > & _xField, const ::com::sun::star::lang::Locale& rIntl, const IParseContext* pContext, bool _bIntl, bool _bQuote, sal_Char _cDecSep, bool _bPredicate, bool _bSubstitute) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToStr" ); OSL_ENSURE( _rxConnection.is(), "OSQLParseNode::parseNodeToStr: invalid connection!" ); if ( _rxConnection.is() ) { ::rtl::OUStringBuffer sBuffer = rString; try { OSQLParseNode::impl_parseNodeToString_throw( sBuffer, SQLParseNodeParameter( _rxConnection, xFormatter, _xField, rIntl, pContext, _bIntl, _bQuote, _cDecSep, _bPredicate, _bSubstitute ) ); } catch( const SQLException& ) { OSL_ENSURE( false, "OSQLParseNode::parseNodeToStr: this should not throw!" ); // our callers don't expect this method to throw anything. The only known situation // where impl_parseNodeToString_throw can throw is when there is a cyclic reference // in the sub queries, but this cannot be the case here, as we do not parse to // SDBC level. } rString = sBuffer.makeStringAndClear(); } } //----------------------------------------------------------------------------- bool OSQLParseNode::parseNodeToExecutableStatement( ::rtl::OUString& _out_rString, const Reference< XConnection >& _rxConnection, OSQLParser& _rParser, ::com::sun::star::sdbc::SQLException* _pErrorHolder ) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseNodeToExecutableStatement" ); OSL_PRECOND( _rxConnection.is(), "OSQLParseNode::parseNodeToExecutableStatement: invalid connection!" ); SQLParseNodeParameter aParseParam( _rxConnection, NULL, NULL, OParseContext::getDefaultLocale(), NULL, false, true, '.', false, true ); if ( aParseParam.aMetaData.supportsSubqueriesInFrom() ) { Reference< XQueriesSupplier > xSuppQueries( _rxConnection, UNO_QUERY ); OSL_ENSURE( xSuppQueries.is(), "OSQLParseNode::parseNodeToExecutableStatement: cannot substitute everything without a QueriesSupplier!" ); if ( xSuppQueries.is() ) aParseParam.xQueries = xSuppQueries->getQueries(); } aParseParam.pParser = &_rParser; _out_rString = ::rtl::OUString(); ::rtl::OUStringBuffer sBuffer; bool bSuccess = false; try { impl_parseNodeToString_throw( sBuffer, aParseParam ); bSuccess = true; } catch( const SQLException& e ) { if ( _pErrorHolder ) *_pErrorHolder = e; } _out_rString = sBuffer.makeStringAndClear(); return bSuccess; } //----------------------------------------------------------------------------- namespace { bool lcl_isAliasNamePresent( const OSQLParseNode& _rTableNameNode ) { return OSQLParseNode::getTableRange(_rTableNameNode.getParent()).getLength() != 0; } } //----------------------------------------------------------------------------- void OSQLParseNode::impl_parseNodeToString_throw(::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::getTableRange" ); if ( isToken() ) { parseLeaf(rString,rParam); return; } // einmal auswerten wieviel Subtrees dieser Knoten besitzt sal_uInt32 nCount = count(); bool bHandled = false; switch ( getKnownRuleID() ) { // special handling for parameters case parameter: { if(rString.getLength()) rString.appendAscii(" "); if (nCount == 1) // ? m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam ); else if (nCount == 2) // :Name { m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam ); rString.append(m_aChildren[1]->m_aNodeValue); } // [Name] else { m_aChildren[0]->impl_parseNodeToString_throw( rString, rParam ); rString.append(m_aChildren[1]->m_aNodeValue); rString.append(m_aChildren[2]->m_aNodeValue); } bHandled = true; } break; // table refs case table_ref: if ( ( nCount == 2 ) || ( nCount == 3 ) || ( nCount == 5 ) ) { impl_parseTableRangeNodeToString_throw( rString, rParam ); bHandled = true; } break; // table name - might be a query name case table_name: bHandled = impl_parseTableNameNodeToString_throw( rString, rParam ); break; case as: if ( rParam.aMetaData.generateASBeforeCorrelationName() ) rString.append(::rtl::OUString::createFromAscii( " AS" )); bHandled = true; break; case like_predicate: // je nachdem ob international angegeben wird oder nicht wird like anders behandelt // interanational: *, ? sind Platzhalter // sonst SQL92 konform: %, _ impl_parseLikeNodeToString_throw( rString, rParam ); bHandled = true; break; case general_set_fct: case set_fct_spec: case position_exp: case extract_exp: case length_exp: case char_value_fct: { if (!addDateValue(rString, rParam)) { // Funktionsname nicht quoten SQLParseNodeParameter aNewParam(rParam); aNewParam.bQuote = ( SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct) ); m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam ); aNewParam.bQuote = rParam.bQuote; //aNewParam.bPredicate = sal_False; // disable [ ] around names // look at i73215 ::rtl::OUStringBuffer aStringPara; for (sal_uInt32 i=1; iimpl_parseNodeToString_throw( aStringPara, aNewParam ); // bei den CommaListen zwischen alle Subtrees Commas setzen if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i < (nCount - 1))) aStringPara.appendAscii(","); } else i++; } rString.append(aStringPara.makeStringAndClear()); } bHandled = true; } break; default: break; } // switch ( getKnownRuleID() ) if ( !bHandled ) { for (OSQLParseNodes::const_iterator i = m_aChildren.begin(); i != m_aChildren.end();) { const OSQLParseNode* pSubTree = *i; if ( !pSubTree ) { ++i; continue; } SQLParseNodeParameter aNewParam(rParam); // don't replace the field for subqueries if (rParam.xField.is() && SQL_ISRULE(pSubTree,subquery)) aNewParam.xField = NULL; // if there is a field given we don't display the fieldname, if there is any if (rParam.xField.is() && SQL_ISRULE(pSubTree,column_ref)) { sal_Bool bFilter = sal_False; // retrieve the fields name ::rtl::OUString aFieldName; try { sal_Int32 nNamePropertyId = PROPERTY_ID_NAME; if ( rParam.xField->getPropertySetInfo()->hasPropertyByName( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_REALNAME ) ) ) nNamePropertyId = PROPERTY_ID_REALNAME; rParam.xField->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( nNamePropertyId ) ) >>= aFieldName; } catch ( Exception& ) { } if(pSubTree->count()) { const OSQLParseNode* pCol = pSubTree->m_aChildren[pSubTree->count()-1]; if ( ( SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().equalsIgnoreAsciiCase(aFieldName) ) || pCol->getTokenValue().equalsIgnoreAsciiCase(aFieldName) ) bFilter = sal_True; } // ok we found the field, if the following node is the // comparison operator '=' we filter it as well if (bFilter) { if (SQL_ISRULE(this, comparison_predicate)) { ++i; if(i != m_aChildren.end()) { pSubTree = *i; if (pSubTree && pSubTree->getNodeType() == SQL_NODE_EQUAL) i++; } } else i++; } else { pSubTree->impl_parseNodeToString_throw( rString, aNewParam ); i++; // bei den CommaListen zwischen alle Subtrees Commas setzen if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChildren.end())) rString.appendAscii(","); } } else { pSubTree->impl_parseNodeToString_throw( rString, aNewParam ); i++; // bei den CommaListen zwischen alle Subtrees Commas setzen if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i != m_aChildren.end())) { if (SQL_ISRULE(this,value_exp_commalist) && rParam.bPredicate) rString.appendAscii(";"); else rString.appendAscii(","); } } } } } //----------------------------------------------------------------------------- bool OSQLParseNode::impl_parseTableNameNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::impl_parseTableNameNodeToString_throw" ); // is the table_name part of a table_ref? OSL_ENSURE( getParent(), "OSQLParseNode::impl_parseTableNameNodeToString_throw: table_name without parent?" ); if ( !getParent() || ( getParent()->getKnownRuleID() != table_ref ) ) return false; // if it's a query, maybe we need to substitute the SQL statement ... if ( !rParam.bParseToSDBCLevel ) return false; if ( !rParam.xQueries.is() ) // connection does not support queries in queries, or was no query supplier return false; try { ::rtl::OUString sTableOrQueryName( getChild(0)->getTokenValue() ); bool bIsQuery = rParam.xQueries->hasByName( sTableOrQueryName ); if ( !bIsQuery ) return false; // avoid recursion (e.g. "foo" defined as "SELECT * FROM bar" and "bar" defined as "SELECT * FROM foo". if ( rParam.pSubQueryHistory->find( sTableOrQueryName ) != rParam.pSubQueryHistory->end() ) { ::rtl::OUString sMessage( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "cyclic sub queries" ) ) ); OSL_ENSURE( rParam.pParser, "OSQLParseNode::impl_parseTableNameNodeToString_throw: no parser?" ); if ( rParam.pParser ) { const SQLError& rErrors( rParam.pParser->getErrorHelper() ); rErrors.raiseException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES ); } else { SQLError aErrors( ::comphelper::getProcessServiceFactory() ); aErrors.raiseException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES ); } } rParam.pSubQueryHistory->insert( sTableOrQueryName ); Reference< XPropertySet > xQuery( rParam.xQueries->getByName( sTableOrQueryName ), UNO_QUERY_THROW ); // substitute the query name with the constituting command ::rtl::OUString sCommand; OSL_VERIFY( xQuery->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_COMMAND ) ) >>= sCommand ); sal_Bool bEscapeProcessing = sal_False; OSL_VERIFY( xQuery->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ) ) >>= bEscapeProcessing ); // the query we found here might itself be based on another query, so parse it recursively OSL_ENSURE( rParam.pParser, "OSQLParseNode::impl_parseTableNameNodeToString_throw: cannot analyze sub queries without a parser!" ); if ( bEscapeProcessing && rParam.pParser ) { ::rtl::OUString sError; ::std::auto_ptr< OSQLParseNode > pSubQueryNode( rParam.pParser->parseTree( sError, sCommand, sal_False ) ); if ( pSubQueryNode.get() ) { // parse the sub-select to SDBC level, too ::rtl::OUStringBuffer sSubSelect; pSubQueryNode->impl_parseNodeToString_throw( sSubSelect, rParam ); if ( sSubSelect.getLength() ) sCommand = sSubSelect.makeStringAndClear(); } } rString.appendAscii( " ( " ); rString.append(sCommand); rString.appendAscii( " )" ); // append the query name as table alias, since it might be referenced in other // parts of the statement - but only if there's no other alias name present if ( !lcl_isAliasNamePresent( *this ) ) { rString.appendAscii( " AS " ); if ( rParam.bQuote ) rString.append(SetQuotation( sTableOrQueryName, rParam.aMetaData.getIdentifierQuoteString(), rParam.aMetaData.getIdentifierQuoteString() )); } // don't forget to remove the query name from the history, else multiple inclusions // won't work // #i69227# / 2006-10-10 / frank.schoenheit@sun.com rParam.pSubQueryHistory->erase( sTableOrQueryName ); return true; } catch( const SQLException& ) { throw; } catch( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); } return false; } //----------------------------------------------------------------------------- void OSQLParseNode::impl_parseTableRangeNodeToString_throw(::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::impl_parseTableRangeNodeToString_throw" ); OSL_PRECOND( ( count() == 2 ) || ( count() == 3 ) || ( count() == 5 ) ,"Illegal count"); // rString += ::rtl::OUString::createFromAscii(" "); ::std::for_each(m_aChildren.begin(),m_aChildren.end(), boost::bind( &OSQLParseNode::impl_parseNodeToString_throw, _1, boost::ref( rString ), boost::cref( rParam ) )); } //----------------------------------------------------------------------------- void OSQLParseNode::impl_parseLikeNodeToString_throw( ::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam ) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::impl_parseLikeNodeToString_throw" ); OSL_ENSURE(count() == 2,"count != 2: Prepare for GPF"); const OSQLParseNode* pEscNode = NULL; const OSQLParseNode* pParaNode = NULL; SQLParseNodeParameter aNewParam(rParam); //aNewParam.bQuote = sal_True; // why setting this to true? @see http://www.openoffice.org/issues/show_bug.cgi?id=75557 // if there is a field given we don't display the fieldname, if there are any sal_Bool bAddName = sal_True; if (rParam.xField.is()) { // retrieve the fields name ::rtl::OUString aFieldName; try { // retrieve the fields name rtl::OUString aString; rParam.xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aString; aFieldName = aString.getStr(); } catch ( Exception& ) { OSL_ENSURE( false, "OSQLParseNode::impl_parseLikeNodeToString_throw Exception occurred!" ); } if ( !m_aChildren[0]->isLeaf() ) { const OSQLParseNode* pCol = m_aChildren[0]->getChild(m_aChildren[0]->count()-1); if ((SQL_ISRULE(pCol,column_val) && pCol->getChild(0)->getTokenValue().equalsIgnoreAsciiCase(aFieldName)) || pCol->getTokenValue().equalsIgnoreAsciiCase(aFieldName) ) bAddName = sal_False; } } if (bAddName) m_aChildren[0]->impl_parseNodeToString_throw( rString, aNewParam ); const OSQLParseNode* pPart2 = m_aChildren[1]; pPart2->getChild(0)->impl_parseNodeToString_throw( rString, aNewParam ); pPart2->getChild(1)->impl_parseNodeToString_throw( rString, aNewParam ); pParaNode = pPart2->getChild(2); pEscNode = pPart2->getChild(3); if (pParaNode->isToken()) { ::rtl::OUString aStr = ConvertLikeToken(pParaNode, pEscNode, rParam.bInternational); rString.appendAscii(" "); rString.append(SetQuotation(aStr,::rtl::OUString::createFromAscii("\'"),::rtl::OUString::createFromAscii("\'\'"))); } else pParaNode->impl_parseNodeToString_throw( rString, aNewParam ); pEscNode->impl_parseNodeToString_throw( rString, aNewParam ); } // ----------------------------------------------------------------------------- sal_Bool OSQLParseNode::getTableComponents(const OSQLParseNode* _pTableNode, ::com::sun::star::uno::Any &_rCatalog, ::rtl::OUString &_rSchema, ::rtl::OUString &_rTable, const Reference< XDatabaseMetaData >& _xMetaData) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::getTableComponents" ); OSL_ENSURE(_pTableNode,"Wrong use of getTableComponents! _pTableNode is not allowed to be null!"); if(_pTableNode) { const sal_Bool bSupportsCatalog = _xMetaData.is() && _xMetaData->supportsCatalogsInDataManipulation(); const sal_Bool bSupportsSchema = _xMetaData.is() && _xMetaData->supportsSchemasInDataManipulation(); const OSQLParseNode* pTableNode = _pTableNode; // clear the parameter given _rCatalog = Any(); _rSchema = _rTable = ::rtl::OUString(); // see rule catalog_name: in sqlbison.y if (SQL_ISRULE(pTableNode,catalog_name)) { OSL_ENSURE(pTableNode->getChild(0) && pTableNode->getChild(0)->isToken(),"Invalid parsenode!"); _rCatalog <<= pTableNode->getChild(0)->getTokenValue(); pTableNode = pTableNode->getChild(2); } // check if we have schema_name rule if(SQL_ISRULE(pTableNode,schema_name)) { if ( bSupportsCatalog && !bSupportsSchema ) _rCatalog <<= pTableNode->getChild(0)->getTokenValue(); else _rSchema = pTableNode->getChild(0)->getTokenValue(); pTableNode = pTableNode->getChild(2); } // check if we have table_name rule if(SQL_ISRULE(pTableNode,table_name)) { _rTable = pTableNode->getChild(0)->getTokenValue(); } else { OSL_ENSURE(0,"Error in parse tree!"); } } return _rTable.getLength() != 0; } // ----------------------------------------------------------------------------- void OSQLParser::killThousandSeparator(OSQLParseNode* pLiteral) { if ( pLiteral ) { if ( s_xLocaleData->getLocaleItem( m_pData->aLocale ).decimalSeparator.toChar() == ',' ) { pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace('.', sal_Unicode()); // and replace decimal pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace(',', '.'); } else pLiteral->m_aNodeValue = pLiteral->m_aNodeValue.replace(',', sal_Unicode()); } } // ----------------------------------------------------------------------------- OSQLParseNode* OSQLParser::convertNode(sal_Int32 nType,OSQLParseNode*& pLiteral) { if ( !pLiteral ) return NULL; OSQLParseNode* pReturn = pLiteral; if ( ( pLiteral->isRule() && !SQL_ISRULE(pLiteral,value_exp) ) || SQL_ISTOKEN(pLiteral,FALSE) || SQL_ISTOKEN(pLiteral,TRUE) ) { switch(nType) { case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: case DataType::CLOB: if ( !SQL_ISRULE(pReturn,char_value_exp) && !buildStringNodes(pReturn) ) pReturn = NULL; default: break; } } else { switch(pLiteral->getNodeType()) { case SQL_NODE_STRING: switch(nType) { case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: case DataType::CLOB: break; case DataType::DATE: case DataType::TIME: case DataType::TIMESTAMP: if (m_xFormatter.is()) pReturn = buildDate( nType, pReturn); break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE); break; } break; case SQL_NODE_ACCESS_DATE: switch(nType) { case DataType::DATE: case DataType::TIME: case DataType::TIMESTAMP: if ( m_xFormatter.is() ) pReturn = buildDate( nType, pReturn); else m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_DATE_COMPARE); break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE); break; } break; case SQL_NODE_INTNUM: switch(nType) { case DataType::BIT: case DataType::BOOLEAN: case DataType::DECIMAL: case DataType::NUMERIC: case DataType::TINYINT: case DataType::SMALLINT: case DataType::INTEGER: case DataType::BIGINT: case DataType::FLOAT: case DataType::REAL: case DataType::DOUBLE: // kill thousand seperators if any killThousandSeparator(pReturn); break; case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: case DataType::CLOB: pReturn = buildNode_STR_NUM(pReturn); break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_INT_COMPARE); break; } break; case SQL_NODE_APPROXNUM: switch(nType) { case DataType::DECIMAL: case DataType::NUMERIC: case DataType::FLOAT: case DataType::REAL: case DataType::DOUBLE: // kill thousand seperators if any killThousandSeparator(pReturn); break; case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: case DataType::CLOB: pReturn = buildNode_STR_NUM(pReturn); break; case DataType::INTEGER: default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_REAL_COMPARE); break; } break; default: ; } } return pReturn; } // ----------------------------------------------------------------------------- sal_Int16 OSQLParser::buildPredicateRule(OSQLParseNode*& pAppend,OSQLParseNode* pLiteral,OSQLParseNode*& pCompare,OSQLParseNode* pLiteral2) { OSL_ENSURE(inPredicateCheck(),"Only in predicate check allowed!"); sal_Int16 nErg = 0; if ( m_xField.is() ) { sal_Int32 nType = 0; try { m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType; } catch( Exception& ) { return nErg; } OSQLParseNode* pNode1 = convertNode(nType,pLiteral); if ( pNode1 ) { OSQLParseNode* pNode2 = convertNode(nType,pLiteral2); if ( !m_sErrorMessage.getLength() ) nErg = buildNode(pAppend,pCompare,pNode1,pNode2); } } if (!pCompare->getParent()) // I have no parent so I was not used and I must die :-) delete pCompare; return nErg; } // ----------------------------------------------------------------------------- sal_Int16 OSQLParser::buildLikeRule(OSQLParseNode*& pAppend, OSQLParseNode*& pLiteral, const OSQLParseNode* pEscape) { sal_Int16 nErg = 0; sal_Int32 nType = 0; if (!m_xField.is()) return nErg; try { Any aValue; { aValue = m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)); aValue >>= nType; } } catch( Exception& ) { return nErg; } switch (nType) { case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: case DataType::CLOB: if(pLiteral->isRule()) { pAppend->append(pLiteral); nErg = 1; } else { switch(pLiteral->getNodeType()) { case SQL_NODE_STRING: pLiteral->m_aNodeValue = ConvertLikeToken(pLiteral, pEscape, sal_False); pAppend->append(pLiteral); nErg = 1; break; case SQL_NODE_APPROXNUM: if (m_xFormatter.is() && m_nFormatKey) { sal_Int16 nScale = 0; try { Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, ::rtl::OUString::createFromAscii("Decimals") ); aValue >>= nScale; } catch( Exception& ) { } pAppend->append(new OSQLInternalNode(stringToDouble(pLiteral->getTokenValue(),nScale),SQL_NODE_STRING)); } else pAppend->append(new OSQLInternalNode(pLiteral->getTokenValue(),SQL_NODE_STRING)); delete pLiteral; nErg = 1; break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_VALUE_NO_LIKE); m_sErrorMessage = m_sErrorMessage.replaceAt(m_sErrorMessage.indexOf(::rtl::OUString::createFromAscii("#1")),2,pLiteral->getTokenValue()); break; } } break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_FIELD_NO_LIKE); break; } return nErg; } //----------------------------------------------------------------------------- OSQLParseNode* OSQLParser::buildNode_Date(const double& fValue, sal_Int32 nType) { ::rtl::OUString aEmptyString; OSQLParseNode* pNewNode = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::set_fct_spec)); pNewNode->append(new OSQLInternalNode(::rtl::OUString::createFromAscii("{"), SQL_NODE_PUNCTUATION)); OSQLParseNode* pDateNode = new OSQLInternalNode(aEmptyString, SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::odbc_fct_spec)); pNewNode->append(pDateNode); pNewNode->append(new OSQLInternalNode(::rtl::OUString::createFromAscii("}"), SQL_NODE_PUNCTUATION)); switch (nType) { case DataType::DATE: { Date aDate = DBTypeConversion::toDate(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier())); ::rtl::OUString aString = DBTypeConversion::toDateString(aDate); pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_D)); pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING)); break; } case DataType::TIME: { Time aTime = DBTypeConversion::toTime(fValue); ::rtl::OUString aString = DBTypeConversion::toTimeString(aTime); pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_T)); pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING)); break; } case DataType::TIMESTAMP: { DateTime aDateTime = DBTypeConversion::toDateTime(fValue,DBTypeConversion::getNULLDate(m_xFormatter->getNumberFormatsSupplier())); if (aDateTime.Seconds || aDateTime.Minutes || aDateTime.Hours) { ::rtl::OUString aString = DBTypeConversion::toDateTimeString(aDateTime); pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_TS)); pDateNode->append(new OSQLInternalNode(aString, SQL_NODE_STRING)); } else { Date aDate(aDateTime.Day,aDateTime.Month,aDateTime.Year); pDateNode->append(new OSQLInternalNode(aEmptyString, SQL_NODE_KEYWORD, SQL_TOKEN_D)); pDateNode->append(new OSQLInternalNode(DBTypeConversion::toDateString(aDate), SQL_NODE_STRING)); } break; } } return pNewNode; } // ----------------------------------------------------------------------------- OSQLParseNode* OSQLParser::buildNode_STR_NUM(OSQLParseNode*& _pLiteral) { OSQLParseNode* pReturn = NULL; if ( _pLiteral ) { if (m_nFormatKey) { sal_Int16 nScale = 0; ::rtl::OUString aDec; try { Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Decimals")) ); aValue >>= nScale; } catch( Exception& ) { } pReturn = new OSQLInternalNode(stringToDouble(_pLiteral->getTokenValue(),nScale),SQL_NODE_STRING); } else pReturn = new OSQLInternalNode(_pLiteral->getTokenValue(),SQL_NODE_STRING); delete _pLiteral; _pLiteral = NULL; } return pReturn; } // ----------------------------------------------------------------------------- ::rtl::OUString OSQLParser::stringToDouble(const ::rtl::OUString& _rValue,sal_Int16 _nScale) { ::rtl::OUString aValue; if(!m_xCharClass.is()) m_xCharClass = Reference(m_xServiceFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.CharacterClassification")),UNO_QUERY); if(m_xCharClass.is() && s_xLocaleData.is()) { try { ParseResult aResult = m_xCharClass->parsePredefinedToken(KParseType::ANY_NUMBER,_rValue,0,m_pData->aLocale,0,::rtl::OUString(),KParseType::ANY_NUMBER,::rtl::OUString()); if((aResult.TokenType & KParseType::IDENTNAME) && aResult.EndPos == _rValue.getLength()) { aValue = ::rtl::OUString::valueOf(aResult.Value); sal_Int32 nPos = aValue.lastIndexOf(::rtl::OUString::createFromAscii(".")); if((nPos+_nScale) < aValue.getLength()) aValue = aValue.replaceAt(nPos+_nScale,aValue.getLength()-nPos-_nScale,::rtl::OUString()); aValue = aValue.replaceAt(aValue.lastIndexOf(::rtl::OUString::createFromAscii(".")),1,s_xLocaleData->getLocaleItem(m_pData->aLocale).decimalSeparator); return aValue; } } catch(Exception&) { } } return aValue; } // ----------------------------------------------------------------------------- ::osl::Mutex& OSQLParser::getMutex() { static ::osl::Mutex aMutex; return aMutex; } //----------------------------------------------------------------------------- OSQLParseNode* OSQLParser::predicateTree(::rtl::OUString& rErrorMessage, const ::rtl::OUString& rStatement, const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter, const Reference< XPropertySet > & xField) { // mutex for parsing static ::osl::Mutex aMutex; // Guard the parsing ::osl::MutexGuard aGuard(getMutex()); // must be reset setParser(this); // reset the parser m_xField = xField; m_xFormatter = xFormatter; if (m_xField.is()) { sal_Int32 nType=0; try { // get the field name rtl::OUString aString; // retrieve the fields name // #75243# use the RealName of the column if there is any otherwise the name which could be the alias // of the field Reference< XPropertySetInfo> xInfo = m_xField->getPropertySetInfo(); if ( xInfo->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME))) m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_REALNAME)) >>= aString; else m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_NAME)) >>= aString; m_sFieldName = aString; // get the field format key if ( xInfo->hasPropertyByName(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY))) m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_FORMATKEY)) >>= m_nFormatKey; else m_nFormatKey = 0; // get the field type m_xField->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE)) >>= nType; } catch ( Exception& ) { OSL_ASSERT(0); } if (m_nFormatKey && m_xFormatter.is()) { Any aValue = getNumberFormatProperty( m_xFormatter, m_nFormatKey, OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_LOCALE) ); OSL_ENSURE(aValue.getValueType() == ::getCppuType((const ::com::sun::star::lang::Locale*)0), "OSQLParser::PredicateTree : invalid language property !"); if (aValue.getValueType() == ::getCppuType((const ::com::sun::star::lang::Locale*)0)) aValue >>= m_pData->aLocale; } else m_pData->aLocale = m_pContext->getPreferredLocale(); if ( m_xFormatter.is() ) { try { Reference< ::com::sun::star::util::XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier(); if ( xFormatSup.is() ) { Reference< ::com::sun::star::util::XNumberFormats > xFormats = xFormatSup->getNumberFormats(); if ( xFormats.is() ) { ::com::sun::star::lang::Locale aLocale; aLocale.Language = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("en")); aLocale.Country = ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("US")); ::rtl::OUString sFormat(RTL_CONSTASCII_USTRINGPARAM("YYYY-MM-DD")); m_nDateFormatKey = xFormats->queryKey(sFormat,aLocale,sal_False); if ( m_nDateFormatKey == sal_Int32(-1) ) m_nDateFormatKey = xFormats->addNew(sFormat, aLocale); } } } catch ( Exception& ) { OSL_ENSURE(0,"DateFormatKey"); } } switch (nType) { case DataType::DATE: case DataType::TIME: case DataType::TIMESTAMP: s_pScanner->SetRule(s_pScanner->GetDATERule()); break; case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: case DataType::CLOB: s_pScanner->SetRule(s_pScanner->GetSTRINGRule()); break; default: if ( s_xLocaleData->getLocaleItem( m_pData->aLocale ).decimalSeparator.toChar() == ',' ) s_pScanner->SetRule(s_pScanner->GetGERRule()); else s_pScanner->SetRule(s_pScanner->GetENGRule()); } } else s_pScanner->SetRule(s_pScanner->GetSQLRule()); s_pScanner->prepareScan(rStatement, m_pContext, sal_True); SQLyylval.pParseNode = NULL; // SQLyypvt = NULL; m_pParseTree = NULL; m_sErrorMessage= ::rtl::OUString(); // ... und den Parser anwerfen ... if (SQLyyparse() != 0) { m_sFieldName= ::rtl::OUString(); m_xField.clear(); m_xFormatter.clear(); m_nFormatKey = 0; m_nDateFormatKey = 0; if (!m_sErrorMessage.getLength()) m_sErrorMessage = s_pScanner->getErrorMessage(); if (!m_sErrorMessage.getLength()) m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_GENERAL); rErrorMessage = m_sErrorMessage; // clear the garbage collector (*s_pGarbageCollector)->clearAndDelete(); return NULL; } else { (*s_pGarbageCollector)->clear(); m_sFieldName= ::rtl::OUString(); m_xField.clear(); m_xFormatter.clear(); m_nFormatKey = 0; m_nDateFormatKey = 0; // Das Ergebnis liefern (den Root Parse Node): // Stattdessen setzt die Parse-Routine jetzt den Member pParseTree // - einfach diesen zurueckliefern: OSL_ENSURE(m_pParseTree != NULL,"OSQLParser: Parser hat keinen ParseTree geliefert"); return m_pParseTree; } } //============================================================================= //----------------------------------------------------------------------------- OSQLParser::OSQLParser(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _xServiceFactory,const IParseContext* _pContext) :m_pContext(_pContext) ,m_pParseTree(NULL) ,m_pData( new OSQLParser_Data( _xServiceFactory ) ) ,m_nFormatKey(0) ,m_nDateFormatKey(0) ,m_xServiceFactory(_xServiceFactory) { setParser(this); #ifdef SQLYYDEBUG #ifdef SQLYYDEBUG_ON SQLyydebug = 1; #endif #endif ::osl::MutexGuard aGuard(getMutex()); // do we have to initialize the data if (s_nRefCount == 0) { s_pScanner = new OSQLScanner(); s_pScanner->setScanner(); s_pGarbageCollector = new OSQLParseNodesGarbageCollector(); if(!s_xLocaleData.is()) s_xLocaleData = Reference(m_xServiceFactory->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.LocaleData")),UNO_QUERY); // auf 0 zuruecksetzen memset(OSQLParser::s_nRuleIDs,0,sizeof(OSQLParser::s_nRuleIDs[0]) * (OSQLParseNode::rule_count+1)); struct { OSQLParseNode::Rule eRule; // the parse node's ID for the rule ::rtl::OString sRuleName; // the name of the rule ("select_statement") } aRuleDescriptions[] = { { OSQLParseNode::select_statement, "select_statement" }, { OSQLParseNode::table_exp, "table_exp" }, { OSQLParseNode::table_ref_commalist, "table_ref_commalist" }, { OSQLParseNode::table_ref, "table_ref" }, { OSQLParseNode::catalog_name, "catalog_name" }, { OSQLParseNode::schema_name, "schema_name" }, { OSQLParseNode::table_name, "table_name" }, { OSQLParseNode::opt_column_commalist, "opt_column_commalist" }, { OSQLParseNode::column_commalist, "column_commalist" }, { OSQLParseNode::column_ref_commalist, "column_ref_commalist" }, { OSQLParseNode::column_ref, "column_ref" }, { OSQLParseNode::opt_order_by_clause, "opt_order_by_clause" }, { OSQLParseNode::ordering_spec_commalist, "ordering_spec_commalist" }, { OSQLParseNode::ordering_spec, "ordering_spec" }, { OSQLParseNode::opt_asc_desc, "opt_asc_desc" }, { OSQLParseNode::where_clause, "where_clause" }, { OSQLParseNode::opt_where_clause, "opt_where_clause" }, { OSQLParseNode::search_condition, "search_condition" }, { OSQLParseNode::comparison_predicate, "comparison_predicate" }, { OSQLParseNode::between_predicate, "between_predicate" }, { OSQLParseNode::like_predicate, "like_predicate" }, { OSQLParseNode::opt_escape, "opt_escape" }, { OSQLParseNode::test_for_null, "test_for_null" }, { OSQLParseNode::scalar_exp_commalist, "scalar_exp_commalist" }, { OSQLParseNode::scalar_exp, "scalar_exp" }, { OSQLParseNode::parameter_ref, "parameter_ref" }, { OSQLParseNode::parameter, "parameter" }, { OSQLParseNode::general_set_fct, "general_set_fct" }, { OSQLParseNode::range_variable, "range_variable" }, { OSQLParseNode::column, "column" }, { OSQLParseNode::delete_statement_positioned, "delete_statement_positioned" }, { OSQLParseNode::delete_statement_searched, "delete_statement_searched" }, { OSQLParseNode::update_statement_positioned, "update_statement_positioned" }, { OSQLParseNode::update_statement_searched, "update_statement_searched" }, { OSQLParseNode::assignment_commalist, "assignment_commalist" }, { OSQLParseNode::assignment, "assignment" }, { OSQLParseNode::values_or_query_spec, "values_or_query_spec" }, { OSQLParseNode::insert_statement, "insert_statement" }, { OSQLParseNode::insert_atom_commalist, "insert_atom_commalist" }, { OSQLParseNode::insert_atom, "insert_atom" }, { OSQLParseNode::predicate_check, "predicate_check" }, { OSQLParseNode::from_clause, "from_clause" }, { OSQLParseNode::qualified_join, "qualified_join" }, { OSQLParseNode::cross_union, "cross_union" }, { OSQLParseNode::select_sublist, "select_sublist" }, { OSQLParseNode::derived_column, "derived_column" }, { OSQLParseNode::column_val, "column_val" }, { OSQLParseNode::set_fct_spec, "set_fct_spec" }, { OSQLParseNode::boolean_term, "boolean_term" }, { OSQLParseNode::boolean_primary, "boolean_primary" }, { OSQLParseNode::num_value_exp, "num_value_exp" }, { OSQLParseNode::join_type, "join_type" }, { OSQLParseNode::position_exp, "position_exp" }, { OSQLParseNode::extract_exp, "extract_exp" }, { OSQLParseNode::length_exp, "length_exp" }, { OSQLParseNode::char_value_fct, "char_value_fct" }, { OSQLParseNode::odbc_call_spec, "odbc_call_spec" }, { OSQLParseNode::in_predicate, "in_predicate" }, { OSQLParseNode::existence_test, "existence_test" }, { OSQLParseNode::unique_test, "unique_test" }, { OSQLParseNode::all_or_any_predicate, "all_or_any_predicate" }, { OSQLParseNode::named_columns_join, "named_columns_join" }, { OSQLParseNode::join_condition, "join_condition" }, { OSQLParseNode::joined_table, "joined_table" }, { OSQLParseNode::boolean_factor, "boolean_factor" }, { OSQLParseNode::sql_not, "sql_not" }, { OSQLParseNode::boolean_test, "boolean_test" }, { OSQLParseNode::manipulative_statement, "manipulative_statement" }, { OSQLParseNode::subquery, "subquery" }, { OSQLParseNode::value_exp_commalist, "value_exp_commalist" }, { OSQLParseNode::odbc_fct_spec, "odbc_fct_spec" }, { OSQLParseNode::union_statement, "union_statement" }, { OSQLParseNode::outer_join_type, "outer_join_type" }, { OSQLParseNode::char_value_exp, "char_value_exp" }, { OSQLParseNode::term, "term" }, { OSQLParseNode::value_exp_primary, "value_exp_primary" }, { OSQLParseNode::value_exp, "value_exp" }, { OSQLParseNode::selection, "selection" }, { OSQLParseNode::fold, "fold" }, { OSQLParseNode::char_substring_fct, "char_substring_fct" }, { OSQLParseNode::factor, "factor" }, { OSQLParseNode::base_table_def, "base_table_def" }, { OSQLParseNode::base_table_element_commalist, "base_table_element_commalist" }, { OSQLParseNode::data_type, "data_type" }, { OSQLParseNode::column_def, "column_def" }, { OSQLParseNode::table_node, "table_node" }, { OSQLParseNode::as, "as" }, { OSQLParseNode::op_column_commalist, "op_column_commalist" }, { OSQLParseNode::table_primary_as_range_column, "table_primary_as_range_column" }, { OSQLParseNode::datetime_primary, "datetime_primary" }, { OSQLParseNode::concatenation, "concatenation" }, { OSQLParseNode::char_factor, "char_factor" }, { OSQLParseNode::bit_value_fct, "bit_value_fct" }, { OSQLParseNode::comparison_predicate_part_2, "comparison_predicate_part_2" }, { OSQLParseNode::parenthesized_boolean_value_expression, "parenthesized_boolean_value_expression" }, { OSQLParseNode::character_string_type, "character_string_type" }, { OSQLParseNode::other_like_predicate_part_2, "other_like_predicate_part_2" }, { OSQLParseNode::between_predicate_part_2, "between_predicate_part_2" }, { OSQLParseNode::cast_spec, "cast_spec" } }; size_t nRuleMapCount = sizeof( aRuleDescriptions ) / sizeof( aRuleDescriptions[0] ); OSL_ENSURE( nRuleMapCount == size_t( OSQLParseNode::rule_count ), "OSQLParser::OSQLParser: added a new rule? Adjust this map!" ); for ( size_t mapEntry = 0; mapEntry < nRuleMapCount; ++mapEntry ) { // look up the rule description in the our identifier map sal_uInt32 nParserRuleID = StrToRuleID( aRuleDescriptions[ mapEntry ].sRuleName ); // map the parser's rule ID to the OSQLParseNode::Rule s_aReverseRuleIDLookup[ nParserRuleID ] = aRuleDescriptions[ mapEntry ].eRule; // and map the OSQLParseNode::Rule to the parser's rule ID s_nRuleIDs[ aRuleDescriptions[ mapEntry ].eRule ] = nParserRuleID; } } ++s_nRefCount; if (m_pContext == NULL) // take the default context m_pContext = &s_aDefaultContext; m_pData->aLocale = m_pContext->getPreferredLocale(); } //----------------------------------------------------------------------------- OSQLParser::~OSQLParser() { { ::osl::MutexGuard aGuard(getMutex()); OSL_ENSURE(s_nRefCount > 0, "OSQLParser::~OSQLParser() : suspicious call : have a refcount of 0 !"); if (!--s_nRefCount) { s_pScanner->setScanner(sal_True); delete s_pScanner; s_pScanner = NULL; delete s_pGarbageCollector; s_pGarbageCollector = NULL; // is only set the first time so we should delete it only when there no more instances s_xLocaleData = NULL; RuleIDMap aEmpty; s_aReverseRuleIDLookup.swap( aEmpty ); } m_pParseTree = NULL; } } // ----------------------------------------------------------------------------- void OSQLParseNode::substituteParameterNames(OSQLParseNode* _pNode) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::substituteParameterNames" ); sal_Int32 nCount = _pNode->count(); for(sal_Int32 i=0;i < nCount;++i) { OSQLParseNode* pChildNode = _pNode->getChild(i); if(SQL_ISRULE(pChildNode,parameter) && pChildNode->count() > 1) { OSQLParseNode* pNewNode = new OSQLParseNode(::rtl::OUString::createFromAscii("?") ,SQL_NODE_PUNCTUATION,0); delete pChildNode->replace(pChildNode->getChild(0),pNewNode); sal_Int32 nChildCount = pChildNode->count(); for(sal_Int32 j=1;j < nChildCount;++j) delete pChildNode->removeAt(1); } else substituteParameterNames(pChildNode); } } // ----------------------------------------------------------------------------- bool OSQLParser::extractDate(OSQLParseNode* pLiteral,double& _rfValue) { Reference< XNumberFormatsSupplier > xFormatSup = m_xFormatter->getNumberFormatsSupplier(); Reference< XNumberFormatTypes > xFormatTypes; if ( xFormatSup.is() ) xFormatTypes = xFormatTypes.query( xFormatSup->getNumberFormats() ); // if there is no format key, yet, make sure we have a feasible one for our locale try { if ( !m_nFormatKey && xFormatTypes.is() ) m_nFormatKey = ::dbtools::getDefaultNumberFormat( m_xField, xFormatTypes, m_pData->aLocale ); } catch( Exception& ) { } ::rtl::OUString sValue = pLiteral->getTokenValue(); sal_Int32 nTryFormat = m_nFormatKey; bool bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue ); // If our format key didn't do, try the default date format for our locale. if ( !bSuccess && xFormatTypes.is() ) { try { nTryFormat = xFormatTypes->getStandardFormat( NumberFormat::DATE, m_pData->aLocale ); } catch( Exception& ) { } bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue ); } // if this also didn't do, try ISO format if ( !bSuccess && xFormatTypes.is() ) { try { nTryFormat = xFormatTypes->getFormatIndex( NumberFormatIndex::DATE_DIN_YYYYMMDD, m_pData->aLocale ); } catch( Exception& ) { } bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue ); } // if this also didn't do, try fallback date format (en-US) if ( !bSuccess ) { nTryFormat = m_nDateFormatKey; bSuccess = lcl_saveConvertToNumber( m_xFormatter, nTryFormat, sValue, _rfValue ); } return bSuccess; } // ----------------------------------------------------------------------------- OSQLParseNode* OSQLParser::buildDate(sal_Int32 _nType,OSQLParseNode*& pLiteral) { // try converting the string into a date, according to our format key double fValue = 0.0; OSQLParseNode* pFCTNode = NULL; if ( extractDate(pLiteral,fValue) ) pFCTNode = buildNode_Date( fValue, _nType); delete pLiteral; pLiteral = NULL; if ( !pFCTNode ) m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_DATE_COMPARE); return pFCTNode; } // ----------------------------------------------------------------------------- //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const sal_Char * pNewValue, SQLNodeType eNewNodeType, sal_uInt32 nNewNodeID) :m_pParent(NULL) ,m_aNodeValue(pNewValue,strlen(pNewValue),RTL_TEXTENCODING_UTF8) ,m_eNodeType(eNewNodeType) ,m_nNodeID(nNewNodeID) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::OSQLParseNode" ); OSL_ENSURE(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_CONCAT,"OSQLParseNode: mit unzulaessigem NodeType konstruiert"); } //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const ::rtl::OString &_rNewValue, SQLNodeType eNewNodeType, sal_uInt32 nNewNodeID) :m_pParent(NULL) ,m_aNodeValue( rtl::OStringToOUString( _rNewValue, RTL_TEXTENCODING_UTF8)) ,m_eNodeType(eNewNodeType) ,m_nNodeID(nNewNodeID) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::OSQLParseNode" ); OSL_ENSURE(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_CONCAT,"OSQLParseNode: mit unzulaessigem NodeType konstruiert"); } //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const sal_Unicode * pNewValue, SQLNodeType eNewNodeType, sal_uInt32 nNewNodeID) :m_pParent(NULL) ,m_aNodeValue(pNewValue) ,m_eNodeType(eNewNodeType) ,m_nNodeID(nNewNodeID) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::OSQLParseNode" ); OSL_ENSURE(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_CONCAT,"OSQLParseNode: mit unzulaessigem NodeType konstruiert"); } //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const ::rtl::OUString &_rNewValue, SQLNodeType eNewNodeType, sal_uInt32 nNewNodeID) :m_pParent(NULL) ,m_aNodeValue(_rNewValue) ,m_eNodeType(eNewNodeType) ,m_nNodeID(nNewNodeID) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::OSQLParseNode" ); OSL_ENSURE(m_eNodeType >= SQL_NODE_RULE && m_eNodeType <= SQL_NODE_CONCAT,"OSQLParseNode: mit unzulaessigem NodeType konstruiert"); } //----------------------------------------------------------------------------- OSQLParseNode::OSQLParseNode(const OSQLParseNode& rParseNode) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::OSQLParseNode" ); // klemm den getParent auf NULL m_pParent = NULL; // kopiere die member m_aNodeValue = rParseNode.m_aNodeValue; m_eNodeType = rParseNode.m_eNodeType; m_nNodeID = rParseNode.m_nNodeID; // denk dran, dass von Container abgeleitet wurde, laut SV-Help erzeugt // copy-Constructor des Containers einen neuen Container mit den gleichen // Zeigern als Inhalt -> d.h. nach dem Kopieren des Container wird fuer // alle Zeiger ungleich NULL eine Kopie hergestellt und anstelle des alten // Zeigers wieder eingehangen. // wenn kein Blatt, dann SubTrees bearbeiten for (OSQLParseNodes::const_iterator i = rParseNode.m_aChildren.begin(); i != rParseNode.m_aChildren.end(); i++) append(new OSQLParseNode(**i)); } // ----------------------------------------------------------------------------- //----------------------------------------------------------------------------- OSQLParseNode& OSQLParseNode::operator=(const OSQLParseNode& rParseNode) { if (this != &rParseNode) { // kopiere die member - pParent bleibt der alte m_aNodeValue = rParseNode.m_aNodeValue; m_eNodeType = rParseNode.m_eNodeType; m_nNodeID = rParseNode.m_nNodeID; for (OSQLParseNodes::const_iterator i = m_aChildren.begin(); i != m_aChildren.end(); i++) delete *i; m_aChildren.clear(); for (OSQLParseNodes::const_iterator j = rParseNode.m_aChildren.begin(); j != rParseNode.m_aChildren.end(); j++) append(new OSQLParseNode(**j)); } return *this; } //----------------------------------------------------------------------------- sal_Bool OSQLParseNode::operator==(OSQLParseNode& rParseNode) const { // die member muessen gleich sein sal_Bool bResult = (m_nNodeID == rParseNode.m_nNodeID) && (m_eNodeType == rParseNode.m_eNodeType) && (m_aNodeValue == rParseNode.m_aNodeValue) && count() == rParseNode.count(); // Parameters are not equal! bResult = bResult && !SQL_ISRULE(this, parameter); // compare childs for (sal_uInt32 i=0; bResult && i < count(); i++) bResult = *getChild(i) == *rParseNode.getChild(i); return bResult; } //----------------------------------------------------------------------------- OSQLParseNode::~OSQLParseNode() { for (OSQLParseNodes::const_iterator i = m_aChildren.begin(); i != m_aChildren.end(); i++) delete *i; m_aChildren.clear(); } //----------------------------------------------------------------------------- void OSQLParseNode::append(OSQLParseNode* pNewNode) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::append" ); OSL_ENSURE(pNewNode != NULL, "OSQLParseNode: ungueltiger NewSubTree"); OSL_ENSURE(pNewNode->getParent() == NULL, "OSQLParseNode: Knoten ist kein Waise"); OSL_ENSURE(::std::find(m_aChildren.begin(), m_aChildren.end(), pNewNode) == m_aChildren.end(), "OSQLParseNode::append() Node already element of parent"); // stelle Verbindung zum getParent her: pNewNode->setParent( this ); // und haenge den SubTree hinten an m_aChildren.push_back(pNewNode); } // ----------------------------------------------------------------------------- sal_Bool OSQLParseNode::addDateValue(::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::addDateValue" ); // special display for date/time values if (SQL_ISRULE(this,set_fct_spec) && SQL_ISPUNCTUATION(m_aChildren[0],"{")) { const OSQLParseNode* pODBCNode = m_aChildren[1]; const OSQLParseNode* pODBCNodeChild = pODBCNode->m_aChildren[0]; if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && ( SQL_ISTOKEN(pODBCNodeChild, D) || SQL_ISTOKEN(pODBCNodeChild, T) || SQL_ISTOKEN(pODBCNodeChild, TS) )) { ::rtl::OUString suQuote(::rtl::OUString::createFromAscii("'")); if (rParam.bPredicate) { if (rParam.aMetaData.shouldEscapeDateTime()) { suQuote = ::rtl::OUString::createFromAscii("#"); } } else { if (rParam.aMetaData.shouldEscapeDateTime()) { // suQuote = ::rtl::OUString::createFromAscii("'"); return sal_False; } } if (rString.getLength()) rString.appendAscii(" "); rString.append(suQuote); const ::rtl::OUString sTokenValue = pODBCNode->m_aChildren[1]->getTokenValue(); if (SQL_ISTOKEN(pODBCNodeChild, D)) { rString.append(rParam.bPredicate ? convertDateString(rParam, sTokenValue) : sTokenValue); } else if (SQL_ISTOKEN(pODBCNodeChild, T)) { rString.append(rParam.bPredicate ? convertTimeString(rParam, sTokenValue) : sTokenValue); } else { rString.append(rParam.bPredicate ? convertDateTimeString(rParam, sTokenValue) : sTokenValue); } rString.append(suQuote); return sal_True; } } return sal_False; } // ----------------------------------------------------------------------------- void OSQLParseNode::replaceNodeValue(const ::rtl::OUString& rTableAlias,const ::rtl::OUString& rColumnName) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::replaceNodeValue" ); for (sal_uInt32 i=0;igetTokenValue() == rColumnName) { OSQLParseNode * pCol = removeAt((sal_uInt32)0); append(new OSQLParseNode(rTableAlias,SQL_NODE_NAME)); append(new OSQLParseNode(::rtl::OUString::createFromAscii("."),SQL_NODE_PUNCTUATION)); append(pCol); } else getChild(i)->replaceNodeValue(rTableAlias,rColumnName); } } //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::getByRule(OSQLParseNode::Rule eRule) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::getByRule" ); OSQLParseNode* pRetNode = 0; if (isRule() && OSQLParser::RuleID(eRule) == getRuleID()) pRetNode = (OSQLParseNode*)this; else { for (OSQLParseNodes::const_iterator i = m_aChildren.begin(); !pRetNode && i != m_aChildren.end(); i++) pRetNode = (*i)->getByRule(eRule); } return pRetNode; } //----------------------------------------------------------------------------- OSQLParseNode* MakeANDNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf) { OSQLParseNode* pNewNode = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term)); pNewNode->append(pLeftLeaf); pNewNode->append(new OSQLParseNode(::rtl::OUString::createFromAscii("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND)); pNewNode->append(pRightLeaf); return pNewNode; } //----------------------------------------------------------------------------- OSQLParseNode* MakeORNode(OSQLParseNode *pLeftLeaf,OSQLParseNode *pRightLeaf) { OSQLParseNode* pNewNode = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition)); pNewNode->append(pLeftLeaf); pNewNode->append(new OSQLParseNode(::rtl::OUString::createFromAscii("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR)); pNewNode->append(pRightLeaf); return pNewNode; } //----------------------------------------------------------------------------- void OSQLParseNode::disjunctiveNormalForm(OSQLParseNode*& pSearchCondition) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::disjunctiveNormalForm" ); if(!pSearchCondition) // no where condition at entry point return; OSQLParseNode::absorptions(pSearchCondition); // '(' search_condition ')' if (SQL_ISRULE(pSearchCondition,boolean_primary)) { OSQLParseNode* pLeft = pSearchCondition->getChild(1); disjunctiveNormalForm(pLeft); } // search_condition SQL_TOKEN_OR boolean_term else if (SQL_ISRULE(pSearchCondition,search_condition)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); disjunctiveNormalForm(pLeft); OSQLParseNode* pRight = pSearchCondition->getChild(2); disjunctiveNormalForm(pRight); } // boolean_term SQL_TOKEN_AND boolean_factor else if (SQL_ISRULE(pSearchCondition,boolean_term)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); disjunctiveNormalForm(pLeft); OSQLParseNode* pRight = pSearchCondition->getChild(2); disjunctiveNormalForm(pRight); OSQLParseNode* pNewNode = NULL; // '(' search_condition ')' on left side if(pLeft->count() == 3 && SQL_ISRULE(pLeft,boolean_primary) && SQL_ISRULE(pLeft->getChild(1),search_condition)) { // and-or tree on left side OSQLParseNode* pOr = pLeft->getChild(1); OSQLParseNode* pNewLeft = NULL; OSQLParseNode* pNewRight = NULL; // cut right from parent pSearchCondition->removeAt(2); pNewRight = MakeANDNode(pOr->removeAt(2) ,pRight); pNewLeft = MakeANDNode(pOr->removeAt((sal_uInt32)0) ,new OSQLParseNode(*pRight)); pNewNode = MakeORNode(pNewLeft,pNewRight); // and append new Node replaceAndReset(pSearchCondition,pNewNode); disjunctiveNormalForm(pSearchCondition); } else if(pRight->count() == 3 && SQL_ISRULE(pRight,boolean_primary) && SQL_ISRULE(pRight->getChild(1),search_condition)) { // '(' search_condition ')' on right side // and-or tree on right side // a and (b or c) OSQLParseNode* pOr = pRight->getChild(1); OSQLParseNode* pNewLeft = NULL; OSQLParseNode* pNewRight = NULL; // cut left from parent pSearchCondition->removeAt((sal_uInt32)0); pNewRight = MakeANDNode(pLeft,pOr->removeAt(2)); pNewLeft = MakeANDNode(new OSQLParseNode(*pLeft),pOr->removeAt((sal_uInt32)0)); pNewNode = MakeORNode(pNewLeft,pNewRight); // and append new Node replaceAndReset(pSearchCondition,pNewNode); disjunctiveNormalForm(pSearchCondition); } else if(SQL_ISRULE(pLeft,boolean_primary) && (!SQL_ISRULE(pLeft->getChild(1),search_condition) || !SQL_ISRULE(pLeft->getChild(1),boolean_term))) pSearchCondition->replace(pLeft, pLeft->removeAt(1)); else if(SQL_ISRULE(pRight,boolean_primary) && (!SQL_ISRULE(pRight->getChild(1),search_condition) || !SQL_ISRULE(pRight->getChild(1),boolean_term))) pSearchCondition->replace(pRight, pRight->removeAt(1)); } } //----------------------------------------------------------------------------- void OSQLParseNode::negateSearchCondition(OSQLParseNode*& pSearchCondition,sal_Bool bNegate) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::negateSearchCondition" ); if(!pSearchCondition) // no where condition at entry point return; // '(' search_condition ')' if (pSearchCondition->count() == 3 && SQL_ISRULE(pSearchCondition,boolean_primary)) { OSQLParseNode* pRight = pSearchCondition->getChild(1); negateSearchCondition(pRight,bNegate); } // search_condition SQL_TOKEN_OR boolean_term else if (SQL_ISRULE(pSearchCondition,search_condition)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); OSQLParseNode* pRight = pSearchCondition->getChild(2); if(bNegate) { OSQLParseNode* pNewNode = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_term)); pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0)); pNewNode->append(new OSQLParseNode(::rtl::OUString::createFromAscii("AND"),SQL_NODE_KEYWORD,SQL_TOKEN_AND)); pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1)); replaceAndReset(pSearchCondition,pNewNode); pLeft = pNewNode->getChild(0); pRight = pNewNode->getChild(2); } negateSearchCondition(pLeft,bNegate); negateSearchCondition(pRight,bNegate); } // boolean_term SQL_TOKEN_AND boolean_factor else if (SQL_ISRULE(pSearchCondition,boolean_term)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); OSQLParseNode* pRight = pSearchCondition->getChild(2); if(bNegate) { OSQLParseNode* pNewNode = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::search_condition)); pNewNode->append(pSearchCondition->removeAt((sal_uInt32)0)); pNewNode->append(new OSQLParseNode(::rtl::OUString::createFromAscii("OR"),SQL_NODE_KEYWORD,SQL_TOKEN_OR)); pNewNode->append(pSearchCondition->removeAt((sal_uInt32)1)); replaceAndReset(pSearchCondition,pNewNode); pLeft = pNewNode->getChild(0); pRight = pNewNode->getChild(2); } negateSearchCondition(pLeft,bNegate); negateSearchCondition(pRight,bNegate); } // SQL_TOKEN_NOT ( boolean_test ) else if (SQL_ISRULE(pSearchCondition,boolean_factor)) { OSQLParseNode *pNot = pSearchCondition->removeAt((sal_uInt32)0); delete pNot; OSQLParseNode *pBooleanTest = pSearchCondition->removeAt((sal_uInt32)0); // TODO is this needed // pBooleanTest->setParent(NULL); replaceAndReset(pSearchCondition,pBooleanTest); if (!bNegate) negateSearchCondition(pSearchCondition,sal_True); // negate all deeper values } // row_value_constructor comparison row_value_constructor // row_value_constructor comparison any_all_some subquery else if(bNegate && (SQL_ISRULE(pSearchCondition,comparison_predicate) || SQL_ISRULE(pSearchCondition,all_or_any_predicate))) { OSQLParseNode* pComparison = pSearchCondition->getChild(1); OSQLParseNode* pNewComparison = NULL; switch(pComparison->getNodeType()) { case SQL_NODE_EQUAL: pNewComparison = new OSQLParseNode(::rtl::OUString::createFromAscii("<>"),SQL_NODE_NOTEQUAL,SQL_NOTEQUAL); break; case SQL_NODE_LESS: pNewComparison = new OSQLParseNode(::rtl::OUString::createFromAscii(">="),SQL_NODE_GREATEQ,SQL_GREATEQ); break; case SQL_NODE_GREAT: pNewComparison = new OSQLParseNode(::rtl::OUString::createFromAscii("<="),SQL_NODE_LESSEQ,SQL_LESSEQ); break; case SQL_NODE_LESSEQ: pNewComparison = new OSQLParseNode(::rtl::OUString::createFromAscii(">"),SQL_NODE_GREAT,SQL_GREAT); break; case SQL_NODE_GREATEQ: pNewComparison = new OSQLParseNode(::rtl::OUString::createFromAscii("<"),SQL_NODE_LESS,SQL_LESS); break; case SQL_NODE_NOTEQUAL: pNewComparison = new OSQLParseNode(::rtl::OUString::createFromAscii("="),SQL_NODE_EQUAL,SQL_EQUAL); break; default: OSL_ENSURE( false, "OSQLParseNode::negateSearchCondition: unexpected node type!" ); break; } pSearchCondition->replace(pComparison, pNewComparison); delete pComparison; } else if(bNegate && (SQL_ISRULE(pSearchCondition,test_for_null) || SQL_ISRULE(pSearchCondition,in_predicate) || SQL_ISRULE(pSearchCondition,between_predicate) || SQL_ISRULE(pSearchCondition,boolean_test) )) { OSQLParseNode* pPart2 = pSearchCondition; if ( !SQL_ISRULE(pSearchCondition,boolean_test) ) pPart2 = pSearchCondition->getChild(1); sal_uInt32 nNotPos = 0; if ( SQL_ISRULE( pSearchCondition, test_for_null ) ) nNotPos = 1; else if ( SQL_ISRULE( pSearchCondition, boolean_test ) ) nNotPos = 2; OSQLParseNode* pNot = pPart2->getChild(nNotPos); OSQLParseNode* pNotNot = NULL; if(pNot->isRule()) pNotNot = new OSQLParseNode(::rtl::OUString::createFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT); else pNotNot = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not)); pPart2->replace(pNot, pNotNot); delete pNot; } else if(bNegate && (SQL_ISRULE(pSearchCondition,like_predicate))) { OSQLParseNode* pNot = pSearchCondition->getChild( 1 )->getChild( 0 ); OSQLParseNode* pNotNot = NULL; if(pNot->isRule()) pNotNot = new OSQLParseNode(::rtl::OUString::createFromAscii("NOT"),SQL_NODE_KEYWORD,SQL_TOKEN_NOT); else pNotNot = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::sql_not)); pSearchCondition->getChild( 1 )->replace(pNot, pNotNot); delete pNot; } } //----------------------------------------------------------------------------- void OSQLParseNode::eraseBraces(OSQLParseNode*& pSearchCondition) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::eraseBraces" ); if (pSearchCondition && (SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") && SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")")))) { OSQLParseNode* pRight = pSearchCondition->getChild(1); absorptions(pRight); // if child is not a or or and tree then delete () around child if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) || SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || // and can always stand without () (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition))) { OSQLParseNode* pNode = pSearchCondition->removeAt(1); replaceAndReset(pSearchCondition,pNode); } } } //----------------------------------------------------------------------------- void OSQLParseNode::absorptions(OSQLParseNode*& pSearchCondition) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::absorptions" ); if(!pSearchCondition) // no where condition at entry point return; eraseBraces(pSearchCondition); if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); absorptions(pLeft); OSQLParseNode* pRight = pSearchCondition->getChild(2); absorptions(pRight); } sal_uInt32 nPos = 0; // a and a || a or a OSQLParseNode* pNewNode = NULL; if(( SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition)) && *pSearchCondition->getChild(0) == *pSearchCondition->getChild(2)) { pNewNode = pSearchCondition->removeAt((sal_uInt32)0); replaceAndReset(pSearchCondition,pNewNode); } // (a or b) and a || ( b or c ) and a // a and ( a or b) || a and ( b or c ) else if ( SQL_ISRULE(pSearchCondition,boolean_term) && ( ( SQL_ISRULE(pSearchCondition->getChild(nPos = 0),boolean_primary) || SQL_ISRULE(pSearchCondition->getChild(nPos),search_condition) ) || ( SQL_ISRULE(pSearchCondition->getChild(nPos = 2),boolean_primary) || SQL_ISRULE(pSearchCondition->getChild(nPos),search_condition) ) ) ) { OSQLParseNode* p2ndSearch = pSearchCondition->getChild(nPos); if ( SQL_ISRULE(p2ndSearch,boolean_primary) ) p2ndSearch = p2ndSearch->getChild(1); if ( *p2ndSearch->getChild(0) == *pSearchCondition->getChild(2-nPos) ) // a and ( a or b) -> a or b { pNewNode = pSearchCondition->removeAt((sal_uInt32)0); replaceAndReset(pSearchCondition,pNewNode); } else if ( *p2ndSearch->getChild(2) == *pSearchCondition->getChild(2-nPos) ) // a and ( b or a) -> a or b { pNewNode = pSearchCondition->removeAt((sal_uInt32)2); replaceAndReset(pSearchCondition,pNewNode); } else if ( p2ndSearch->getByRule(OSQLParseNode::search_condition) ) { // a and ( b or c ) -> ( a and b ) or ( a and c ) // ( b or c ) and a -> ( a and b ) or ( a and c ) OSQLParseNode* pC = p2ndSearch->removeAt((sal_uInt32)2); OSQLParseNode* pB = p2ndSearch->removeAt((sal_uInt32)0); OSQLParseNode* pA = pSearchCondition->removeAt((sal_uInt32)2-nPos); OSQLParseNode* p1stAnd = MakeANDNode(pA,pB); OSQLParseNode* p2ndAnd = MakeANDNode(new OSQLParseNode(*pA),pC); pNewNode = MakeORNode(p1stAnd,p2ndAnd); OSQLParseNode* pNode = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNode->append(new OSQLParseNode(::rtl::OUString::createFromAscii("("),SQL_NODE_PUNCTUATION)); pNode->append(pNewNode); pNode->append(new OSQLParseNode(::rtl::OUString::createFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(p1stAnd); OSQLParseNode::eraseBraces(p2ndAnd); replaceAndReset(pSearchCondition,pNode); } } // a or a and b || a or b and a else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term)) { if(*pSearchCondition->getChild(2)->getChild(0) == *pSearchCondition->getChild(0)) { pNewNode = pSearchCondition->removeAt((sal_uInt32)0); replaceAndReset(pSearchCondition,pNewNode); } else if(*pSearchCondition->getChild(2)->getChild(2) == *pSearchCondition->getChild(0)) { pNewNode = pSearchCondition->removeAt((sal_uInt32)0); replaceAndReset(pSearchCondition,pNewNode); } } // a and b or a || b and a or a else if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term)) { if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)) { pNewNode = pSearchCondition->removeAt((sal_uInt32)2); replaceAndReset(pSearchCondition,pNewNode); } else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)) { pNewNode = pSearchCondition->removeAt((sal_uInt32)2); replaceAndReset(pSearchCondition,pNewNode); } } eraseBraces(pSearchCondition); } //----------------------------------------------------------------------------- void OSQLParseNode::compress(OSQLParseNode *&pSearchCondition) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::compress" ); if(!pSearchCondition) // no where condition at entry point return; OSQLParseNode::eraseBraces(pSearchCondition); if(SQL_ISRULE(pSearchCondition,boolean_term) || SQL_ISRULE(pSearchCondition,search_condition)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0); compress(pLeft); OSQLParseNode* pRight = pSearchCondition->getChild(2); compress(pRight); } else if( SQL_ISRULE(pSearchCondition,boolean_primary) || (pSearchCondition->count() == 3 && SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") && SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")"))) { OSQLParseNode* pRight = pSearchCondition->getChild(1); compress(pRight); // if child is not a or or and tree then delete () around child if(!(SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) || SQL_ISRULE(pSearchCondition->getChild(1),search_condition)) || (SQL_ISRULE(pSearchCondition->getChild(1),boolean_term) && SQL_ISRULE(pSearchCondition->getParent(),boolean_term)) || (SQL_ISRULE(pSearchCondition->getChild(1),search_condition) && SQL_ISRULE(pSearchCondition->getParent(),search_condition))) { OSQLParseNode* pNode = pSearchCondition->removeAt(1); replaceAndReset(pSearchCondition,pNode); } } // or with two and trees where one element of the and trees are equal if(SQL_ISRULE(pSearchCondition,search_condition) && SQL_ISRULE(pSearchCondition->getChild(0),boolean_term) && SQL_ISRULE(pSearchCondition->getChild(2),boolean_term)) { if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(0)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2); OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2); OSQLParseNode* pNode = MakeORNode(pLeft,pRight); OSQLParseNode* pNewRule = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNewRule->append(new OSQLParseNode(::rtl::OUString::createFromAscii("("),SQL_NODE_PUNCTUATION)); pNewRule->append(pNode); pNewRule->append(new OSQLParseNode(::rtl::OUString::createFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(pLeft); OSQLParseNode::eraseBraces(pRight); pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule); replaceAndReset(pSearchCondition,pNode); } else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(0)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0); OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt(2); OSQLParseNode* pNode = MakeORNode(pLeft,pRight); OSQLParseNode* pNewRule = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNewRule->append(new OSQLParseNode(::rtl::OUString::createFromAscii("("),SQL_NODE_PUNCTUATION)); pNewRule->append(pNode); pNewRule->append(new OSQLParseNode(::rtl::OUString::createFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(pLeft); OSQLParseNode::eraseBraces(pRight); pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule); replaceAndReset(pSearchCondition,pNode); } else if(*pSearchCondition->getChild(0)->getChild(0) == *pSearchCondition->getChild(2)->getChild(2)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt(2); OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0); OSQLParseNode* pNode = MakeORNode(pLeft,pRight); OSQLParseNode* pNewRule = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNewRule->append(new OSQLParseNode(::rtl::OUString::createFromAscii("("),SQL_NODE_PUNCTUATION)); pNewRule->append(pNode); pNewRule->append(new OSQLParseNode(::rtl::OUString::createFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(pLeft); OSQLParseNode::eraseBraces(pRight); pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt((sal_uInt32)0),pNewRule); replaceAndReset(pSearchCondition,pNode); } else if(*pSearchCondition->getChild(0)->getChild(2) == *pSearchCondition->getChild(2)->getChild(2)) { OSQLParseNode* pLeft = pSearchCondition->getChild(0)->removeAt((sal_uInt32)0); OSQLParseNode* pRight = pSearchCondition->getChild(2)->removeAt((sal_uInt32)0); OSQLParseNode* pNode = MakeORNode(pLeft,pRight); OSQLParseNode* pNewRule = new OSQLParseNode(::rtl::OUString(),SQL_NODE_RULE,OSQLParser::RuleID(OSQLParseNode::boolean_primary)); pNewRule->append(new OSQLParseNode(::rtl::OUString::createFromAscii("("),SQL_NODE_PUNCTUATION)); pNewRule->append(pNode); pNewRule->append(new OSQLParseNode(::rtl::OUString::createFromAscii(")"),SQL_NODE_PUNCTUATION)); OSQLParseNode::eraseBraces(pLeft); OSQLParseNode::eraseBraces(pRight); pNode = MakeANDNode(pSearchCondition->getChild(0)->removeAt(1),pNewRule); replaceAndReset(pSearchCondition,pNode); } } } #if OSL_DEBUG_LEVEL > 0 // ----------------------------------------------------------------------------- void OSQLParseNode::showParseTree( ::rtl::OUString& rString ) const { ::rtl::OUStringBuffer aBuf; showParseTree( aBuf, 0 ); rString = aBuf.makeStringAndClear(); } // ----------------------------------------------------------------------------- void OSQLParseNode::showParseTree( ::rtl::OUStringBuffer& _inout_rBuffer, sal_uInt32 nLevel ) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::showParseTree" ); for ( sal_uInt32 j=0; jshowParseTree( _inout_rBuffer, nLevel+1 ); } else { // ein Token gefunden switch (m_eNodeType) { case SQL_NODE_KEYWORD: _inout_rBuffer.appendAscii( "SQL_KEYWORD: " ); _inout_rBuffer.append( ::rtl::OStringToOUString( OSQLParser::TokenIDToStr( getTokenID() ), RTL_TEXTENCODING_UTF8 ) ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_COMPARISON: _inout_rBuffer.appendAscii( "SQL_COMPARISON: " ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_NAME: _inout_rBuffer.appendAscii( "SQL_NAME: " ); _inout_rBuffer.append( sal_Unicode( '"' ) ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '"' ) ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_STRING: _inout_rBuffer.appendAscii( "SQL_STRING: " ); _inout_rBuffer.append( sal_Unicode( '\'' ) ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\'' ) ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_INTNUM: _inout_rBuffer.appendAscii( "SQL_INTNUM: " ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_APPROXNUM: _inout_rBuffer.appendAscii( "SQL_APPROXNUM: " ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_PUNCTUATION: _inout_rBuffer.appendAscii( "SQL_PUNCTUATION: " ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_AMMSC: _inout_rBuffer.appendAscii( "SQL_AMMSC: " ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_EQUAL: case SQL_NODE_LESS: case SQL_NODE_GREAT: case SQL_NODE_LESSEQ: case SQL_NODE_GREATEQ: case SQL_NODE_NOTEQUAL: _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_ACCESS_DATE: _inout_rBuffer.appendAscii( "SQL_ACCESS_DATE: " ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_DATE: _inout_rBuffer.appendAscii( "SQL_DATE: " ); _inout_rBuffer.append( m_aNodeValue ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; case SQL_NODE_CONCAT: _inout_rBuffer.appendAscii( "||" ); _inout_rBuffer.append( sal_Unicode( '\n' ) ); break; default: OSL_TRACE( "-- %i", int( m_eNodeType ) ); OSL_ENSURE( false, "OSQLParser::ShowParseTree: unzulaessiger NodeType" ); } } } #endif // OSL_DEBUG_LEVEL > 0 // ----------------------------------------------------------------------------- // Insert-Methoden //----------------------------------------------------------------------------- void OSQLParseNode::insert(sal_uInt32 nPos, OSQLParseNode* pNewSubTree) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::insert" ); OSL_ENSURE(pNewSubTree != NULL, "OSQLParseNode: ungueltiger NewSubTree"); OSL_ENSURE(pNewSubTree->getParent() == NULL, "OSQLParseNode: Knoten ist kein Waise"); // stelle Verbindung zum getParent her: pNewSubTree->setParent( this ); m_aChildren.insert(m_aChildren.begin() + nPos, pNewSubTree); } // removeAt-Methoden //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::removeAt(sal_uInt32 nPos) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::removeAt" ); OSL_ENSURE(nPos < m_aChildren.size(),"Illegal position for removeAt"); OSQLParseNodes::iterator aPos(m_aChildren.begin() + nPos); OSQLParseNode* pNode = *aPos; // setze den getParent des removeten auf NULL pNode->setParent( NULL ); m_aChildren.erase(aPos); return pNode; } //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::remove(OSQLParseNode* pSubTree) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::remove" ); OSL_ENSURE(pSubTree != NULL, "OSQLParseNode: ungueltiger SubTree"); OSQLParseNodes::iterator aPos = ::std::find(m_aChildren.begin(), m_aChildren.end(), pSubTree); if (aPos != m_aChildren.end()) { // setze den getParent des removeten auf NULL pSubTree->setParent( NULL ); m_aChildren.erase(aPos); return pSubTree; } else return NULL; } // Replace-Methoden //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::replaceAt(sal_uInt32 nPos, OSQLParseNode* pNewSubNode) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::replaceAt" ); OSL_ENSURE(pNewSubNode != NULL, "OSQLParseNode: invalid nodes"); OSL_ENSURE(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent"); OSL_ENSURE(nPos < m_aChildren.size(), "OSQLParseNode: invalid position"); OSL_ENSURE(::std::find(m_aChildren.begin(), m_aChildren.end(), pNewSubNode) == m_aChildren.end(), "OSQLParseNode::Replace() Node already element of parent"); OSQLParseNode* pOldSubNode = m_aChildren[nPos]; // stelle Verbindung zum getParent her: pNewSubNode->setParent( this ); pOldSubNode->setParent( NULL ); m_aChildren[nPos] = pNewSubNode; return pOldSubNode; } //----------------------------------------------------------------------------- OSQLParseNode* OSQLParseNode::replace (OSQLParseNode* pOldSubNode, OSQLParseNode* pNewSubNode ) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::replace " ); OSL_ENSURE(pOldSubNode != NULL && pNewSubNode != NULL, "OSQLParseNode: invalid nodes"); OSL_ENSURE(pNewSubNode->getParent() == NULL, "OSQLParseNode: node already has getParent"); OSL_ENSURE(::std::find(m_aChildren.begin(), m_aChildren.end(), pOldSubNode) != m_aChildren.end(), "OSQLParseNode::Replace() Node not element of parent"); OSL_ENSURE(::std::find(m_aChildren.begin(), m_aChildren.end(), pNewSubNode) == m_aChildren.end(), "OSQLParseNode::Replace() Node already element of parent"); pOldSubNode->setParent( NULL ); pNewSubNode->setParent( this ); ::std::replace(m_aChildren.begin(), m_aChildren.end(), pOldSubNode, pNewSubNode); return pOldSubNode; } // ----------------------------------------------------------------------------- void OSQLParseNode::parseLeaf(::rtl::OUStringBuffer& rString, const SQLParseNodeParameter& rParam) const { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::parseLeaf" ); // ein Blatt ist gefunden // Inhalt dem Ausgabestring anfuegen switch (m_eNodeType) { case SQL_NODE_KEYWORD: { if (rString.getLength()) rString.appendAscii(" "); const ::rtl::OString sT = OSQLParser::TokenIDToStr(m_nNodeID, rParam.bInternational ? &rParam.m_rContext : NULL); rString.append( ::rtl::OStringToOUString( sT, RTL_TEXTENCODING_UTF8)); } break; case SQL_NODE_STRING: if (rString.getLength()) rString.appendAscii(" "); rString.append(SetQuotation(m_aNodeValue,::rtl::OUString::createFromAscii("\'"),::rtl::OUString::createFromAscii("\'\'"))); break; case SQL_NODE_NAME: if (rString.getLength()) { switch(rString.charAt(rString.getLength()-1) ) { case ' ' : case '.' : break; default : if ( !rParam.aMetaData.getCatalogSeparator().getLength() || rString.charAt( rString.getLength()-1 ) != rParam.aMetaData.getCatalogSeparator().toChar() ) rString.appendAscii(" "); break; } } if (rParam.bQuote) { if (rParam.bPredicate) { rString.appendAscii("["); rString.append(m_aNodeValue); rString.appendAscii("]"); } else rString.append(SetQuotation(m_aNodeValue, rParam.aMetaData.getIdentifierQuoteString(), rParam.aMetaData.getIdentifierQuoteString() )); } else rString.append(m_aNodeValue); break; case SQL_NODE_ACCESS_DATE: if (rString.getLength()) rString.appendAscii(" "); rString.appendAscii("#"); rString.append(m_aNodeValue); rString.appendAscii("#"); break; case SQL_NODE_INTNUM: case SQL_NODE_APPROXNUM: { ::rtl::OUString aTmp = m_aNodeValue; if (rParam.bInternational && rParam.bPredicate && rParam.cDecSep != '.') aTmp = aTmp.replace('.', rParam.cDecSep); if (rString.getLength()) rString.appendAscii(" "); rString.append(aTmp); } break; case SQL_NODE_PUNCTUATION: if ( getParent() && SQL_ISRULE(getParent(),cast_spec) && m_aNodeValue.toChar() == '(' ) // no spaces in front of '(' { rString.append(m_aNodeValue); break; } // fall through default: if (rString.getLength() && m_aNodeValue.toChar() != '.' && m_aNodeValue.toChar() != ':' ) { switch( rString.charAt(rString.getLength()-1) ) { case ' ' : case '.' : break; default : if ( !rParam.aMetaData.getCatalogSeparator().getLength() || rString.charAt( rString.getLength()-1 ) != rParam.aMetaData.getCatalogSeparator().toChar() ) rString.appendAscii(" "); break; } } rString.append(m_aNodeValue); } } // ----------------------------------------------------------------------------- sal_Int32 OSQLParser::getFunctionReturnType(const ::rtl::OUString& _sFunctionName, const IParseContext* pContext) { sal_Int32 nType = DataType::VARCHAR; ::rtl::OString sFunctionName( rtl::OUStringToOString( _sFunctionName, RTL_TEXTENCODING_UTF8)); if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ASCII,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_BIT_LENGTH,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CHAR,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CHAR_LENGTH,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CONCAT,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DIFFERENCE,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_INSERT,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LCASE,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LEFT,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LENGTH,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOCATE,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOCATE_2,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LTRIM,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_OCTET_LENGTH,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_POSITION,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_REPEAT,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_REPLACE,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RIGHT,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RTRIM,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SOUNDEX,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SPACE,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SUBSTRING,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_UCASE,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_DATE,pContext))) nType = DataType::DATE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_TIME,pContext))) nType = DataType::TIME; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURRENT_TIMESTAMP,pContext))) nType = DataType::TIMESTAMP; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURDATE,pContext))) nType = DataType::DATE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DATEDIFF,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DATEVALUE,pContext))) nType = DataType::DATE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CURTIME,pContext))) nType = DataType::TIME; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYNAME,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFMONTH,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFWEEK,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DAYOFYEAR,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_EXTRACT,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_HOUR,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MINUTE,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MONTH,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MONTHNAME,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_NOW,pContext))) nType = DataType::TIMESTAMP; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_QUARTER,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SECOND,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMESTAMPADD,pContext))) nType = DataType::TIMESTAMP; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMESTAMPDIFF,pContext))) nType = DataType::TIMESTAMP; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TIMEVALUE,pContext))) nType = DataType::TIMESTAMP; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_WEEK,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_YEAR,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ABS,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ACOS,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ASIN,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ATAN,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ATAN2,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_CEILING,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COS,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COT,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_DEGREES,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_EXP,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_FLOOR,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOGF,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOG,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOG10,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LN,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MOD,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_PI,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_POWER,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RADIANS,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_RAND,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ROUND,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_ROUNDMAGIC,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SIGN,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SIN,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SQRT,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TAN,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_TRUNCATE,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_COUNT,pContext))) nType = DataType::INTEGER; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MAX,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_MIN,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_AVG,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_SUM,pContext))) nType = DataType::DOUBLE; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_LOWER,pContext))) nType = DataType::VARCHAR; else if(sFunctionName.equalsIgnoreAsciiCase(TokenIDToStr(SQL_TOKEN_UPPER,pContext))) nType = DataType::VARCHAR; return nType; } // ----------------------------------------------------------------------------- sal_Int32 OSQLParser::getFunctionParameterType(sal_uInt32 _nTokenId, sal_uInt32 _nPos) { sal_Int32 nType = DataType::VARCHAR; if(_nTokenId == SQL_TOKEN_CHAR) nType = DataType::INTEGER; else if(_nTokenId == SQL_TOKEN_INSERT) { if ( _nPos == 2 || _nPos == 3 ) nType = DataType::INTEGER; } else if(_nTokenId == SQL_TOKEN_LEFT) { if ( _nPos == 2 ) nType = DataType::INTEGER; } else if(_nTokenId == SQL_TOKEN_LOCATE) { if ( _nPos == 3 ) nType = DataType::INTEGER; } else if(_nTokenId == SQL_TOKEN_LOCATE_2) { if ( _nPos == 3 ) nType = DataType::INTEGER; } else if( _nTokenId == SQL_TOKEN_REPEAT || _nTokenId == SQL_TOKEN_RIGHT ) { if ( _nPos == 2 ) nType = DataType::INTEGER; } else if(_nTokenId == SQL_TOKEN_SPACE ) { nType = DataType::INTEGER; } else if(_nTokenId == SQL_TOKEN_SUBSTRING) { if ( _nPos != 1 ) nType = DataType::INTEGER; } else if(_nTokenId == SQL_TOKEN_DATEDIFF) { if ( _nPos != 1 ) nType = DataType::TIMESTAMP; } else if(_nTokenId == SQL_TOKEN_DATEVALUE) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_DAYNAME) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_DAYOFMONTH) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_DAYOFWEEK) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_DAYOFYEAR) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_EXTRACT) nType = DataType::VARCHAR; else if(_nTokenId == SQL_TOKEN_HOUR) nType = DataType::TIME; else if(_nTokenId == SQL_TOKEN_MINUTE) nType = DataType::TIME; else if(_nTokenId == SQL_TOKEN_MONTH) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_MONTHNAME) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_NOW) nType = DataType::TIMESTAMP; else if(_nTokenId == SQL_TOKEN_QUARTER) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_SECOND) nType = DataType::TIME; else if(_nTokenId == SQL_TOKEN_TIMESTAMPADD) nType = DataType::TIMESTAMP; else if(_nTokenId == SQL_TOKEN_TIMESTAMPDIFF) nType = DataType::TIMESTAMP; else if(_nTokenId == SQL_TOKEN_TIMEVALUE) nType = DataType::TIMESTAMP; else if(_nTokenId == SQL_TOKEN_WEEK) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_YEAR) nType = DataType::DATE; else if(_nTokenId == SQL_TOKEN_ABS) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_ACOS) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_ASIN) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_ATAN) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_ATAN2) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_CEILING) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_COS) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_COT) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_DEGREES) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_EXP) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_FLOOR) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_LOGF) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_LOG) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_LOG10) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_LN) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_MOD) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_PI) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_POWER) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_RADIANS) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_RAND) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_ROUND) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_ROUNDMAGIC) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_SIGN) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_SIN) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_SQRT) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_TAN) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_TRUNCATE) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_COUNT) nType = DataType::INTEGER; else if(_nTokenId == SQL_TOKEN_MAX) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_MIN) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_AVG) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_SUM) nType = DataType::DOUBLE; else if(_nTokenId == SQL_TOKEN_LOWER) nType = DataType::VARCHAR; else if(_nTokenId == SQL_TOKEN_UPPER) nType = DataType::VARCHAR; return nType; } // ----------------------------------------------------------------------------- const SQLError& OSQLParser::getErrorHelper() const { return m_pData->aErrors; } // ----------------------------------------------------------------------------- OSQLParseNode::Rule OSQLParseNode::getKnownRuleID() const { if ( !isRule() ) return UNKNOWN_RULE; return OSQLParser::RuleIDToRule( getRuleID() ); } // ----------------------------------------------------------------------------- ::rtl::OUString OSQLParseNode::getTableRange(const OSQLParseNode* _pTableRef) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseNode::getTableRange" ); OSL_ENSURE(_pTableRef && _pTableRef->count() > 1 && _pTableRef->getKnownRuleID() == OSQLParseNode::table_ref,"Invalid node give, only table ref is allowed!"); const sal_uInt32 nCount = _pTableRef->count(); ::rtl::OUString sTableRange; if ( nCount == 2 || (nCount == 3 && !_pTableRef->getChild(0)->isToken()) || nCount == 5 ) { const OSQLParseNode* pNode = _pTableRef->getChild(nCount - (nCount == 2 ? 1 : 2)); OSL_ENSURE(pNode && (pNode->getKnownRuleID() == OSQLParseNode::table_primary_as_range_column || pNode->getKnownRuleID() == OSQLParseNode::range_variable) ,"SQL grammar changed!"); if ( !pNode->isLeaf() ) sTableRange = pNode->getChild(1)->getTokenValue(); } // if ( nCount == 2 || nCount == 3 || nCount == 5) return sTableRange; } // ----------------------------------------------------------------------------- OSQLParseNodesContainer::OSQLParseNodesContainer() { } // ----------------------------------------------------------------------------- OSQLParseNodesContainer::~OSQLParseNodesContainer() { } // ----------------------------------------------------------------------------- void OSQLParseNodesContainer::push_back(OSQLParseNode* _pNode) { ::osl::MutexGuard aGuard(m_aMutex); m_aNodes.push_back(_pNode); } // ----------------------------------------------------------------------------- void OSQLParseNodesContainer::erase(OSQLParseNode* _pNode) { ::osl::MutexGuard aGuard(m_aMutex); if ( !m_aNodes.empty() ) { ::std::vector< OSQLParseNode* >::iterator aFind = ::std::find(m_aNodes.begin(), m_aNodes.end(),_pNode); if ( aFind != m_aNodes.end() ) m_aNodes.erase(aFind); } } // ----------------------------------------------------------------------------- bool OSQLParseNodesContainer::empty() const { return m_aNodes.empty(); } // ----------------------------------------------------------------------------- void OSQLParseNodesContainer::clear() { ::osl::MutexGuard aGuard(m_aMutex); m_aNodes.clear(); } // ----------------------------------------------------------------------------- void OSQLParseNodesContainer::clearAndDelete() { ::osl::MutexGuard aGuard(m_aMutex); // clear the garbage collector while ( !m_aNodes.empty() ) { OSQLParseNode* pNode = m_aNodes[0]; while ( pNode->getParent() ) { pNode = pNode->getParent(); } delete pNode; } } } // namespace connectivity