Tag: cws_src680_qiq User: fs Date: 06/05/10 03:19:49 Modified: /dba/connectivity/source/parse/ sqlnode.cxx
Log: #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.38&r2=1.38.62.1 Delta lines: +398 -186 ----------------------- --- sqlnode.cxx 16 Jan 2006 15:04:30 -0000 1.38 +++ sqlnode.cxx 10 May 2006 10:19:46 -0000 1.38.62.1 @@ -4,9 +4,9 @@ * * $RCSfile: sqlnode.cxx,v $ * - * $Revision: 1.38 $ + * $Revision: 1.38.62.1 $ * - * last change: $Author: obo $ $Date: 2006/01/16 15:04:30 $ + * last change: $Author: fs $ $Date: 2006/05/10 10:19:46 $ * * The Contents of this file are made available subject to * the terms of GNU Lesser General Public License Version 2.1. @@ -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 @@ -119,24 +122,26 @@ #ifndef _CONNECTIVITY_DBTOOLS_HXX_ #include "connectivity/dbtools.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 { @@ -154,25 +159,36 @@ return bRet; } } -//------------------------------------------------------------------ -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) + +::rtl::OUString SetQuotation(const ::rtl::OUString& rValue, const ::rtl::OUString& rQuot, const ::rtl::OUString& rQuotToReplace); + +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 ) :aIdentifierQuote(_rIdentifierQuote) ,aCatalogSeparator(_rCatalogSep) ,rLocale(_rLocale) - ,m_pContext(_pContext ? _pContext : &OSQLParser::s_aDefaultContext) + ,m_rContext( _pContext ? (const IParseContext&)(*_pContext) : (const IParseContext&)OSQLParser::s_aDefaultContext ) ,bInternational(_bIntl) ,bQuote(_bQuote) ,cDecSep(_cDecSep) ,xField(_xField) ,xFormatter(_xFormatter) ,bPredicate(_bPredicate) + ,bParseToSDBCLevel( _bParseToSDBC ) { } -::rtl::OUString SetQuotation(const ::rtl::OUString& rValue, const ::rtl::OUString& rQuot, const ::rtl::OUString& rQuotToReplace); +//============================================================================= +//= OSQLParseNode +//============================================================================= //----------------------------------------------------------------------------- ::rtl::OUString OSQLParseNode::convertDateString(const SQLParseNodeParameter& rParam, const ::rtl::OUString& rString) const { @@ -221,7 +237,7 @@ parseNodeToStr( rString, xMeta, Reference< XNumberFormatter >(), Reference< XPropertySet >(), pContext ? pContext->getPreferredLocale() : OParseContext::getDefaultLocale(), - pContext, _bIntl, _bQuote, '.', sal_False); + pContext, _bIntl, _bQuote, '.', false, false ); } //----------------------------------------------------------------------------- @@ -236,7 +252,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); } //----------------------------------------------------------------------------- @@ -252,7 +268,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); } //----------------------------------------------------------------------------- @@ -262,10 +278,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!"); @@ -275,22 +292,46 @@ ::rtl::OUString aIdentifierQuote(xMeta->getIdentifierQuoteString()); ::rtl::OUString aCatalogSeparator(xMeta->getCatalogSeparator()); - OSQLParseNode::parseNodeToStr(rString, - SQLParseNodeParameter(aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, rIntl, pContext, _bIntl, _bQuote, _cDecSep, bPredicate)); + OSQLParseNode::parseNodeToStr( rString, + SQLParseNodeParameter( + aIdentifierQuote, aCatalogSeparator, xFormatter, _xField, rIntl, pContext, _bIntl, _bQuote, _cDecSep, _bPredicate, _bSubstitute ) ); } } //----------------------------------------------------------------------------- -void OSQLParseNode::parseNodeToStr(::rtl::OUString& rString, const SQLParseNodeParameter& rParam) const +void OSQLParseNode::parseNodeToExecutableStatement( ::rtl::OUString& _out_rString, const Reference< XConnection >& _rxConnection ) 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 ); + + 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(); + _out_rString = ::rtl::OUString(); + parseNodeToStr( _out_rString, aParseParam ); +} - if (!isToken()) +//----------------------------------------------------------------------------- +void OSQLParseNode::parseNodeToStr(::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(" "); @@ -307,20 +348,81 @@ rString += m_aChilds[1]->m_aNodeValue; rString += m_aChilds[2]->m_aNodeValue; } + bHandled = true; } + break; - else if(SQL_ISRULE(this,table_ref) && - (nCount == 4|| (nCount == 6 && SQL_ISPUNCTUATION(m_aChilds[0],"(")))) + // table refs + case table_ref: + if ( ( nCount == 4 ) + || ( ( nCount == 6 ) && SQL_ISPUNCTUATION( m_aChilds[0], "(" ) ) + ) + { tableRangeNodeToStr(rString, rParam); + bHandled = true; + } + break; + + // table name - maybe a query name + case table_name: + { + // if it's a query, maybe we need to substitute the SQL statement ... + + if ( !rParam.bParseToSDBCLevel ) + break; + + if ( !rParam.xQueries.is() ) + { + OSL_ENSURE( false, "OSQLParseNode::parseNodeToStr: cannot substitute a (possible) query name!" ); + break; + } + + try + { + ::rtl::OUString sTableOrQueryName( getChild(0)->getTokenValue() ); + bool bIsQuery = rParam.xQueries->hasByName( sTableOrQueryName ); + if ( !bIsQuery ) + break; + + 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 ); + + 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 + rString += ::rtl::OUString::createFromAscii( " AS " ); + if ( rParam.bQuote ) + rString += SetQuotation( sTableOrQueryName, rParam.aIdentifierQuote, rParam.aIdentifierQuote ); + + bHandled = true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + break; + + 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); + 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)) { @@ -347,15 +449,19 @@ aStringPara.trim(); rString += aStringPara; } + bHandled = true; } - else + 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 @@ -433,12 +539,6 @@ } } } - } - } - else - { - parseLeaf(rString,rParam); - } } //----------------------------------------------------------------------------- void OSQLParseNode::tableRangeNodeToStr(::rtl::OUString& rString, const SQLParseNodeParameter& rParam) const @@ -857,7 +957,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, @@ -1061,6 +1160,111 @@ // 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" } + }; + 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; @@ -1151,3 +1355,11 @@ return nErg; } // ----------------------------------------------------------------------------- +OSQLParseNode::Rule OSQLParseNode::getKnownRuleID() const +{ + if ( !isRule() ) + return UNKNOWN_RULE; + return OSQLParser::RuleIDToRule( getRuleID() ); +} + +} // namespace connectivity \ No newline at end of file --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
