| /************************************************************** |
| * |
| * 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 <connectivity/sqlnode.hxx> |
| #include <connectivity/sqlerror.hxx> |
| #include <internalnode.hxx> |
| #define YYBISON 1 |
| #ifndef BISON_INCLUDED |
| #define BISON_INCLUDED |
| #include <sqlbison.hxx> |
| #endif |
| #include <connectivity/sqlparse.hxx> |
| #include <com/sun/star/lang/Locale.hpp> |
| #include <com/sun/star/util/XNumberFormatter.hpp> |
| #include <com/sun/star/util/XNumberFormatTypes.hpp> |
| #include <com/sun/star/i18n/NumberFormatIndex.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/sdbc/XDatabaseMetaData.hpp> |
| #include <com/sun/star/sdbc/DataType.hpp> |
| #include <com/sun/star/sdb/XQueriesSupplier.hpp> |
| #include <com/sun/star/sdb/ErrorCondition.hpp> |
| #include <com/sun/star/util/XNumberFormatter.hpp> |
| #include <com/sun/star/util/XNumberFormatsSupplier.hpp> |
| #include <com/sun/star/util/XNumberFormats.hpp> |
| #include <com/sun/star/util/NumberFormat.hpp> |
| #include <com/sun/star/util/XNumberFormatTypes.hpp> |
| #include <com/sun/star/lang/Locale.hpp> |
| #include <com/sun/star/i18n/KParseType.hpp> |
| #include <com/sun/star/i18n/KParseTokens.hpp> |
| #include "connectivity/dbconversion.hxx" |
| #include <com/sun/star/util/DateTime.hpp> |
| #include <com/sun/star/util/Time.hpp> |
| #include <com/sun/star/util/Date.hpp> |
| #include "TConnection.hxx" |
| #include "sqlscan.hxx" |
| #include <comphelper/numbers.hxx> |
| #include <comphelper/processfactory.hxx> |
| #include <comphelper/stl_types.hxx> |
| #include "connectivity/dbtools.hxx" |
| #include "connectivity/dbmetadata.hxx" |
| #include "connectivity/sqlerror.hxx" |
| #include <tools/diagnose_ex.h> |
| #include <string.h> |
| #include <boost/bind.hpp> |
| #include <algorithm> |
| #include <functional> |
| #include <rtl/logfile.hxx> |
| #include <rtl/ustrbuf.hxx> |
| |
| 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 |
| { |
| |
| //============================================================================= |
| struct OSQLParser_Data |
| { |
| ::com::sun::star::lang::Locale aLocale; |
| ::connectivity::SQLError aErrors; |
| |
| 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; i<nCount; i++) |
| { |
| const OSQLParseNode * pSubTree = m_aChildren[i]; |
| if (pSubTree) |
| { |
| pSubTree->impl_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<XCharacterClassification>(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<XLocaleData>(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;i<count();++i) |
| { |
| if (SQL_ISRULE(this,column_ref) && count() == 1 && getChild(0)->getTokenValue() == 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; j<nLevel; ++j) |
| _inout_rBuffer.appendAscii( " " ); |
| |
| if ( !isToken() ) |
| { |
| // Regelnamen als rule: ... |
| _inout_rBuffer.appendAscii( "RULE_ID: " ); |
| _inout_rBuffer.append( (sal_Int32)getRuleID() ); |
| _inout_rBuffer.append( sal_Unicode( '(' ) ); |
| _inout_rBuffer.append( OSQLParser::RuleIDToStr( getRuleID() ) ); |
| _inout_rBuffer.append( sal_Unicode( ')' ) ); |
| _inout_rBuffer.append( sal_Unicode( '\n' ) ); |
| |
| // hol dir den ersten Subtree |
| for ( OSQLParseNodes::const_iterator i = m_aChildren.begin(); |
| i != m_aChildren.end(); |
| ++i |
| ) |
| (*i)->showParseTree( _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 |