User: obo Date: 2006/07/10 07:39:04 Modified: dba/connectivity/source/parse/sqlnode.cxx
Log: INTEGRATION: CWS qiq (1.38.62); FILE MERGED 2006/06/30 14:00:49 fs 1.38.62.13: #i10000# 2006/06/30 13:19:36 fs 1.38.62.12: #i51143# localize the error message about cyclic sub queries 2006/06/30 13:06:25 fs 1.38.62.11: #i51143# protect against cyclic references in the query names 2006/06/28 08:40:41 fs 1.38.62.10: #i10000# 2006/06/28 07:39:19 fs 1.38.62.9: #i10000# 2006/06/27 15:10:33 fs 1.38.62.8: RESYNC: (1.38-1.39); FILE MERGED 2006/06/07 12:31:17 fs 1.38.62.7: #i51143# allow subqueries in FROM 2006/06/01 09:47:31 fs 1.38.62.6: #i51143# only substitute sub queries if the connection really supports this 2006/05/15 14:43:05 fs 1.38.62.5: during #i51143#: parse 'as' as 'AS', not as empty string - this is much better understandable to the user 2006/05/15 13:46:19 fs 1.38.62.4: #i51143# respect return value of tableNameNodeToStr 2006/05/15 13:34:18 fs 1.38.62.3: #i51143# when parsing a query name to a sub select, don't append alias names if there already is an alias name 2006/05/12 14:11:40 fs 1.38.62.2: #i51143# parseNodeToExecutableStatement now also taking a SQLParser - this allows nested sub queries 2006/05/10 10:19:46 fs 1.38.62.1: #i51143# +parseNodeToExecutableStatement / +getKnownRuleID / some code cleanup File Changes: Directory: /dba/connectivity/source/parse/ ========================================== File [changed]: sqlnode.cxx Url: http://dba.openoffice.org/source/browse/dba/connectivity/source/parse/sqlnode.cxx?r1=1.39&r2=1.40 Delta lines: +540 -176 ----------------------- --- sqlnode.cxx 20 Jun 2006 02:09:05 -0000 1.39 +++ sqlnode.cxx 10 Jul 2006 14:39:02 -0000 1.40 @@ -70,6 +70,9 @@ #ifndef _COM_SUN_STAR_SDBC_DATATYPE_HPP_ #include <com/sun/star/sdbc/DataType.hpp> #endif +#ifndef _COM_SUN_STAR_SDB_XQUERIESSUPPLIER_HPP_ +#include <com/sun/star/sdb/XQueriesSupplier.hpp> +#endif #ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_ #include <com/sun/star/util/XNumberFormatter.hpp> #endif @@ -116,27 +119,35 @@ #ifndef _COMPHELPER_NUMBERS_HXX_ #include <comphelper/numbers.hxx> #endif +#ifndef _COMPHELPER_STLTYPES_HXX_ +#include <comphelper/stl_types.hxx> +#endif #ifndef _CONNECTIVITY_DBTOOLS_HXX_ #include "connectivity/dbtools.hxx" #endif +#ifndef CONNECTIVITY_INC_CONNECTIVITY_DBMETADATA_HXX +#include "connectivity/dbmetadata.hxx" +#endif +#ifndef TOOLS_DIAGNOSE_EX_H +#include <tools/diagnose_ex.h> +#endif using namespace ::com::sun::star::sdbc; using namespace ::com::sun::star::util; using namespace ::com::sun::star::beans; -using namespace ::com::sun::star::sdbc; +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 ::osl; -using namespace ::connectivity; using namespace ::dbtools; using namespace ::comphelper; extern int SQLyyparse (void); - -extern ::rtl::OUString ConvertLikeToken(const OSQLParseNode* pTokenNode, const OSQLParseNode* pEscapeNode, sal_Bool bInternational); +extern ::rtl::OUString ConvertLikeToken(const ::connectivity::OSQLParseNode* pTokenNode, const ::connectivity::OSQLParseNode* pEscapeNode, sal_Bool bInternational); +extern void setParser( ::connectivity::OSQLParser* ); namespace { @@ -155,7 +166,7 @@ return bRet; } // ----------------------------------------------------------------------------- - void replaceAndReset(OSQLParseNode*& _pResetNode,OSQLParseNode* _pNewNode) + void replaceAndReset(connectivity::OSQLParseNode*& _pResetNode,connectivity::OSQLParseNode* _pNewNode) { _pResetNode->getParent()->replace(_pResetNode, _pNewNode); delete _pResetNode; @@ -193,25 +204,44 @@ return rNewValue; } } -//------------------------------------------------------------------ -OSQLParseNode::SQLParseNodeParameter::SQLParseNodeParameter(const ::rtl::OUString& _rIdentifierQuote, const ::rtl::OUString& _rCatalogSep, - const Reference< XNumberFormatter > & _xFormatter, const Reference< XPropertySet > & _xField, const ::com::sun::star::lang::Locale& _rLocale, - const IParseContext* _pContext, sal_Bool _bIntl, sal_Bool _bQuote, sal_Char _cDecSep, - sal_Bool _bPredicate) + +namespace connectivity +{ + +//============================================================================= +//= SQLParseNodeParameter +//============================================================================= +//----------------------------------------------------------------------------- +SQLParseNodeParameter::SQLParseNodeParameter( const ::rtl::OUString& _rIdentifierQuote, const ::rtl::OUString& _rCatalogSep, + 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, bool _bCaseSensistiveIdentCompare ) :rLocale(_rLocale) ,aIdentifierQuote(_rIdentifierQuote) ,aCatalogSeparator(_rCatalogSep) + ,pParser( NULL ) + ,pSubQueryHistory( new QueryNameSet ) ,xFormatter(_xFormatter) ,xField(_xField) - ,m_pContext(_pContext ? _pContext : &OSQLParser::s_aDefaultContext) + ,m_rContext( _pContext ? (const IParseContext&)(*_pContext) : (const IParseContext&)OSQLParser::s_aDefaultContext ) ,cDecSep(_cDecSep) ,bQuote(_bQuote) ,bInternational(_bIntl) ,bPredicate(_bPredicate) + ,bParseToSDBCLevel( _bParseToSDBC ) + ,bCaseSensistiveIdentCompare( _bCaseSensistiveIdentCompare ) { } //----------------------------------------------------------------------------- +SQLParseNodeParameter::~SQLParseNodeParameter() +{ +} + +//============================================================================= +//= OSQLParseNode +//============================================================================= +//----------------------------------------------------------------------------- ::rtl::OUString OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const { Date aDate = DBTypeConversion::toDate(rString); @@ -259,7 +289,7 @@ parseNodeToStr( rString, xMeta, Reference< XNumberFormatter >(), Reference< XPropertySet >(), pContext ? pContext->getPreferredLocale() : OParseContext::getDefaultLocale(), - pContext, _bIntl, _bQuote, '.', sal_False); + pContext, _bIntl, _bQuote, '.', false, false ); } //----------------------------------------------------------------------------- @@ -274,7 +304,7 @@ OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!"); if (xFormatter.is()) - parseNodeToStr(rString, xMeta, xFormatter, Reference< XPropertySet >(), rIntl, pContext, sal_True, sal_True, _cDec, sal_True); + parseNodeToStr(rString, xMeta, xFormatter, Reference< XPropertySet >(), rIntl, pContext, sal_True, sal_True, _cDec, true, false); } //----------------------------------------------------------------------------- @@ -290,7 +320,7 @@ OSL_ENSURE(xFormatter.is(), "OSQLParseNode::parseNodeToPredicateStr:: no formatter!"); if (xFormatter.is()) - parseNodeToStr(rString, xMeta, xFormatter, _xField, rIntl, pContext, sal_True, sal_True, _cDec, sal_True); + parseNodeToStr(rString, xMeta, xFormatter, _xField, rIntl, pContext, true, true, _cDec, true, false); } //----------------------------------------------------------------------------- @@ -300,10 +330,11 @@ const Reference< XPropertySet > & _xField, const ::com::sun::star::lang::Locale& rIntl, const IParseContext* pContext, - sal_Bool _bIntl, - sal_Bool _bQuote, + bool _bIntl, + bool _bQuote, sal_Char _cDecSep, - sal_Bool bPredicate) const + bool _bPredicate, + bool _bSubstitute) const { OSL_ENSURE(xMeta.is(), "OSQLParseNode::parseNodeToStr:: no meta data!"); @@ -313,52 +344,183 @@ ::rtl::OUString aIdentifierQuote(xMeta->getIdentifierQuoteString()); ::rtl::OUString aCatalogSeparator(xMeta->getCatalogSeparator()); - OSQLParseNode::parseNodeToStr(rString, - SQLParseNodeParameter(aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, rIntl, pContext, _bIntl, _bQuote, _cDecSep, bPredicate)); + try + { + OSQLParseNode::impl_parseNodeToString_throw( rString, + SQLParseNodeParameter( + aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, rIntl, pContext, + _bIntl, _bQuote, _cDecSep, _bPredicate, _bSubstitute, + xMeta->storesMixedCaseQuotedIdentifiers() + ) ); + } + 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. + } } } //----------------------------------------------------------------------------- -void OSQLParseNode::parseNodeToStr(::rtl::OUString& rString, const SQLParseNodeParameter& rParam) const +bool OSQLParseNode::parseNodeToExecutableStatement( ::rtl::OUString& _out_rString, const Reference< XConnection >& _rxConnection, + OSQLParser& _rParser, ::com::sun::star::sdbc::SQLException* _pErrorHolder ) const { + OSL_PRECOND( _rxConnection.is(), "OSQLParseNode::parseNodeToExecutableStatement: invalid connection!" ); + Reference< XDatabaseMetaData > xMeta( _rxConnection->getMetaData() ); + SQLParseNodeParameter aParseParam( xMeta->getIdentifierQuoteString(), xMeta->getCatalogSeparator(), + NULL, NULL, OParseContext::getDefaultLocale(), NULL, false, true, '.', false, true, + xMeta->storesMixedCaseQuotedIdentifiers() ); - if (!isToken()) + DatabaseMetaData aMeta( _rxConnection ); + if ( aMeta.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(); + bool bSuccess = false; + try + { + impl_parseNodeToString_throw( _out_rString, aParseParam ); + bSuccess = true; + } + catch( const SQLException& e ) + { + if ( _pErrorHolder ) + *_pErrorHolder = e; + } + return bSuccess; +} + +//----------------------------------------------------------------------------- +namespace +{ + bool lcl_isAliasNamePresent( const OSQLParseNode& _rTableNameNode ) + { + OSL_ENSURE( _rTableNameNode.getKnownRuleID() == OSQLParseNode::table_name, "lcl_isAliasNamePresent: Must be a 'table_name' rule!" ); + OSL_ENSURE( _rTableNameNode.getParent()->getKnownRuleID() == OSQLParseNode::table_ref, "lcl_isAliasNamePresent: parent must be a 'table_ref'!" ); + + const OSQLParseNode* pTableRef = _rTableNameNode.getParent(); + if ( pTableRef->count() == 4 ) + { + // table_ref := table_node as range_variable op_column_commalist + // table_node := table_name | ... + if ( pTableRef->getChild(1)->getKnownRuleID() == OSQLParseNode::as ) + return true; + + // table_ref := '{' SQL_TOKEN_OJ joined_table '}' + OSL_ENSURE( SQL_ISPUNCTUATION( pTableRef->getChild(0), "(" ), "lcl_isAliasNamePresent: grammar changed(1)!" ); + return false; + } + + if ( pTableRef->count() == 6 ) + { // '(' joined_table ')' as range_variable op_column_commalist + OSL_ENSURE( SQL_ISPUNCTUATION( pTableRef->getChild(2), "(" ) + && SQL_ISRULE( pTableRef->getChild(3), as ), + "lcl_isAliasNamePresent: grammar changed(3)!" ); + return true; + } + + if ( pTableRef->count() == 3 ) + // subquery as range_variable + return true; + + if ( pTableRef->count() == 1 ) + return false; + +#if OSL_DEBUG_LEVEL > 0 + for ( size_t i=0; i<pTableRef->count(); ++i ) + { + const OSQLParseNode* pChildNode = pTableRef->getChild( i ); + OSQLParseNode::Rule eRuleID = pChildNode->getKnownRuleID(); + OSL_UNUSED( eRuleID ); + } +#endif + OSL_ENSURE( false, "lcl_isAliasNamePresent: unreachable code - except you extended the production rules for table_ref!" ); + return false; + } +} + +//----------------------------------------------------------------------------- +void OSQLParseNode::impl_parseNodeToString_throw(::rtl::OUString& rString, const SQLParseNodeParameter& rParam) const +{ + if ( isToken() ) + { + parseLeaf(rString,rParam); + return; + } + // einmal auswerten wieviel Subtrees dieser Knoten besitzt sal_uInt32 nCount = count(); - // parameter erhalten sonderbehandlung - if (SQL_ISRULE(this,parameter)) + bool bHandled = false; + switch ( getKnownRuleID() ) + { + // special handling for parameters + case parameter: { if(rString.getLength()) rString += ::rtl::OUString::createFromAscii(" "); if (nCount == 1) // ? - m_aChilds[0]->parseNodeToStr(rString, rParam); + m_aChilds[0]->impl_parseNodeToString_throw( rString, rParam ); else if (nCount == 2) // :Name { - m_aChilds[0]->parseNodeToStr(rString, rParam); + m_aChilds[0]->impl_parseNodeToString_throw( rString, rParam ); rString += m_aChilds[1]->m_aNodeValue; } // [Name] else { - m_aChilds[0]->parseNodeToStr(rString, rParam); + m_aChilds[0]->impl_parseNodeToString_throw( rString, rParam ); rString += m_aChilds[1]->m_aNodeValue; rString += m_aChilds[2]->m_aNodeValue; } + bHandled = true; + } + break; + + // table refs + case table_ref: + if ( ( nCount == 4 ) + || ( ( nCount == 6 ) && SQL_ISPUNCTUATION( m_aChilds[0], "(" ) ) + ) + { + 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: + rString += ::rtl::OUString::createFromAscii( " AS" ); + bHandled = true; + break; - else if(SQL_ISRULE(this,table_ref) && - (nCount == 4|| (nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"(")))) - tableRangeNodeToStr(rString, rParam); + case like_predicate: // je nachdem ob international angegeben wird oder nicht wird like anders behandelt // interanational: *, ? sind Platzhalter // sonst SQL92 konform: %, _ - else if (SQL_ISRULE(this,like_predicate)) - likeNodeToStr(rString, rParam); + impl_parseLikeNodeToString_throw( rString, rParam ); + bHandled = true; + break; - else if (SQL_ISRULE(this,general_set_fct) || SQL_ISRULE(this,set_fct_spec) || - SQL_ISRULE(this,position_exp) || SQL_ISRULE(this,extract_exp) || - SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct)) + 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)) { @@ -366,7 +528,7 @@ SQLParseNodeParameter aNewParam(rParam); aNewParam.bQuote = ( SQL_ISRULE(this,length_exp) || SQL_ISRULE(this,char_value_fct) ); - m_aChilds[0]->parseNodeToStr(rString, aNewParam); + m_aChilds[0]->impl_parseNodeToString_throw( rString, aNewParam ); aNewParam.bQuote = rParam.bQuote; aNewParam.bPredicate = sal_False; // disable [ ] around names ::rtl::OUString aStringPara; @@ -375,7 +537,7 @@ const OSQLParseNode * pSubTree = m_aChilds[i]; if (pSubTree) { - pSubTree->parseNodeToStr(aStringPara, aNewParam); + pSubTree->impl_parseNodeToString_throw( aStringPara, aNewParam ); // bei den CommaListen zwischen alle Subtrees Commas setzen if ((m_eNodeType == SQL_NODE_COMMALISTRULE) && (i < (nCount - 1))) @@ -385,15 +547,21 @@ aStringPara.trim(); rString += aStringPara; } + bHandled = true; } - else + break; + default: + break; + } // switch ( getKnownRuleID() ) + + if ( !bHandled ) { for (OSQLParseNodes::const_iterator i = m_aChilds.begin(); i != m_aChilds.end();) { const OSQLParseNode* pSubTree = *i; - if (pSubTree) - { + if ( !pSubTree ) + continue; SQLParseNodeParameter aNewParam(rParam); // don't replace the field for subqueries @@ -447,7 +615,7 @@ } else { - pSubTree->parseNodeToStr(rString, aNewParam); + pSubTree->impl_parseNodeToString_throw( rString, aNewParam ); i++; // bei den CommaListen zwischen alle Subtrees Commas setzen @@ -457,7 +625,7 @@ } else { - pSubTree->parseNodeToStr(rString, aNewParam); + pSubTree->impl_parseNodeToString_throw( rString, aNewParam ); i++; // bei den CommaListen zwischen alle Subtrees Commas setzen @@ -471,41 +639,118 @@ } } } +} + +//----------------------------------------------------------------------------- +bool OSQLParseNode::impl_parseTableNameNodeToString_throw( ::rtl::OUString& rString, const SQLParseNodeParameter& rParam ) const +{ + // 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" ) ) ); + if ( rParam.pParser ) + sMessage = rParam.pParser->getContext().getErrorMessage( IParseContext::ERROR_CYCLIC_SUB_QUERIES ); + ::dbtools::throwSQLException( sMessage, SQL_CYCLIC_SUB_QUERIES, NULL ); } + 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::OUString sSubSelect; + pSubQueryNode->impl_parseNodeToString_throw( sSubSelect, rParam ); + if ( sSubSelect.getLength() ) + sCommand = sSubSelect; } - else + } + + rString += ::rtl::OUString::createFromAscii( " ( " ); + rString += sCommand; + rString += ::rtl::OUString::createFromAscii( " )" ); + + // 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 ) ) { - parseLeaf(rString,rParam); + rString += ::rtl::OUString::createFromAscii( " AS " ); + if ( rParam.bQuote ) + rString += SetQuotation( sTableOrQueryName, rParam.aIdentifierQuote, rParam.aIdentifierQuote ); } + + return true; + } + catch( const SQLException& ) + { + throw; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return false; } + //----------------------------------------------------------------------------- -void OSQLParseNode::tableRangeNodeToStr(::rtl::OUString& rString, const SQLParseNodeParameter& rParam) const +void OSQLParseNode::impl_parseTableRangeNodeToString_throw(::rtl::OUString& rString, const SQLParseNodeParameter& rParam) const { sal_uInt32 nCount(count()); rString += ::rtl::OUString::createFromAscii(" "); - SQLParseNodeParameter aNewParam(rParam); - // aNewParam.bQuote = sal_False; if (nCount == 4) { - m_aChilds[0]->parseNodeToStr(rString, rParam); - m_aChilds[1]->parseNodeToStr(rString, rParam); - m_aChilds[2]->parseNodeToStr(rString, aNewParam); - m_aChilds[3]->parseNodeToStr(rString, rParam); + m_aChilds[0]->impl_parseNodeToString_throw( rString, rParam ); + m_aChilds[1]->impl_parseNodeToString_throw( rString, rParam ); + m_aChilds[2]->impl_parseNodeToString_throw( rString, rParam ); + m_aChilds[3]->impl_parseNodeToString_throw( rString, rParam ); } else if(nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"(")) { - m_aChilds[0]->parseNodeToStr(rString, rParam); - m_aChilds[1]->parseNodeToStr(rString, rParam); - m_aChilds[2]->parseNodeToStr(rString, rParam); - m_aChilds[3]->parseNodeToStr(rString, rParam); - m_aChilds[4]->parseNodeToStr(rString, aNewParam); - m_aChilds[5]->parseNodeToStr(rString, rParam); + m_aChilds[0]->impl_parseNodeToString_throw( rString, rParam ); + m_aChilds[1]->impl_parseNodeToString_throw( rString, rParam ); + m_aChilds[2]->impl_parseNodeToString_throw( rString, rParam ); + m_aChilds[3]->impl_parseNodeToString_throw( rString, rParam ); + m_aChilds[4]->impl_parseNodeToString_throw( rString, rParam ); + m_aChilds[5]->impl_parseNodeToString_throw( rString, rParam ); } } //----------------------------------------------------------------------------- -void OSQLParseNode::likeNodeToStr(::rtl::OUString& rString, const SQLParseNodeParameter& rParam) const +void OSQLParseNode::impl_parseLikeNodeToString_throw( ::rtl::OUString& rString, const SQLParseNodeParameter& rParam ) const { OSL_ENSURE(count() >= 4,"count != 5: Prepare for GPF"); @@ -530,7 +775,7 @@ } catch ( Exception& ) { - OSL_ENSURE(0,"OSQLParseNode::likeNodeToStr Exception occured!"); + OSL_ENSURE( false, "OSQLParseNode::impl_parseLikeNodeToString_throw Exception occured!" ); } if ( !m_aChilds[0]->isLeaf() ) { @@ -542,11 +787,11 @@ } if (bAddName) - m_aChilds[0]->parseNodeToStr(rString, aNewParam); + m_aChilds[0]->impl_parseNodeToString_throw( rString, aNewParam ); - m_aChilds[1]->parseNodeToStr(rString, aNewParam); + m_aChilds[1]->impl_parseNodeToString_throw( rString, aNewParam ); if(count() == 5) - m_aChilds[2]->parseNodeToStr(rString, aNewParam); + m_aChilds[2]->impl_parseNodeToString_throw( rString, aNewParam ); sal_Int32 nCurentPos = m_aChilds.size()-2; pParaNode = m_aChilds[nCurentPos]; @@ -559,9 +804,9 @@ rString += SetQuotation(aStr,::rtl::OUString::createFromAscii("\'"),::rtl::OUString::createFromAscii("\'\'")); } else - pParaNode->parseNodeToStr(rString, aNewParam); + pParaNode->impl_parseNodeToString_throw( rString, aNewParam ); - pEscNode->parseNodeToStr(rString, aNewParam); + pEscNode->impl_parseNodeToString_throw( rString, aNewParam ); } @@ -659,6 +904,7 @@ break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE); + break; } break; case SQL_NODE_ACCESS_DATE: @@ -675,6 +921,7 @@ break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_COMPARE); + break; } break; case SQL_NODE_INTNUM: @@ -708,6 +955,7 @@ break; default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_INT_COMPARE); + break; } break; case SQL_NODE_APPROXNUM: @@ -740,6 +988,7 @@ case DataType::INTEGER: default: m_sErrorMessage = m_pContext->getErrorMessage(IParseContext::ERROR_INVALID_REAL_COMPARE); + break; } break; default: @@ -816,15 +1065,15 @@ 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; } @@ -898,7 +1147,6 @@ return aMutex; } -extern void setParser(OSQLParser*); //----------------------------------------------------------------------------- OSQLParseNode* OSQLParser::predicateTree(::rtl::OUString& rErrorMessage, const ::rtl::OUString& rStatement, const Reference< ::com::sun::star::util::XNumberFormatter > & xFormatter, @@ -1102,6 +1350,114 @@ // 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" } + }; + 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; @@ -2001,7 +2357,7 @@ if (rString.getLength()) rString += ::rtl::OUString::createFromAscii(" "); - ::rtl::OString sT = OSQLParser::TokenIDToStr(m_nNodeID, rParam.m_pContext); + ::rtl::OString sT = OSQLParser::TokenIDToStr(m_nNodeID, &rParam.m_rContext); rString += ::rtl::OUString(sT,sT.getLength(),RTL_TEXTENCODING_UTF8); } break; case SQL_NODE_STRING: @@ -2160,3 +2516,11 @@ return nType; } // ----------------------------------------------------------------------------- +OSQLParseNode::Rule OSQLParseNode::getKnownRuleID() const +{ + if ( !isRule() ) + return UNKNOWN_RULE; + return OSQLParser::RuleIDToRule( getRuleID() ); +} + +} // namespace connectivity --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
