1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_connectivity.hxx" 30 #include "connectivity/sqliterator.hxx" 31 #include "connectivity/sdbcx/VTable.hxx" 32 #include <connectivity/sqlparse.hxx> 33 #include <connectivity/dbtools.hxx> 34 #include <connectivity/sqlerror.hxx> 35 #include <com/sun/star/sdbc/ColumnValue.hpp> 36 #include <com/sun/star/sdbc/DataType.hpp> 37 #include <com/sun/star/sdbc/XRow.hpp> 38 #include <com/sun/star/sdb/XQueriesSupplier.hpp> 39 #include <com/sun/star/sdb/ErrorCondition.hpp> 40 #ifdef SQL_TEST_PARSETREEITERATOR 41 #include <iostream> 42 #endif 43 #include "connectivity/PColumn.hxx" 44 #include "connectivity/dbtools.hxx" 45 #include <tools/diagnose_ex.h> 46 #include "TConnection.hxx" 47 #include <comphelper/types.hxx> 48 #include <connectivity/dbmetadata.hxx> 49 #include <com/sun/star/sdb/SQLFilterOperator.hpp> 50 #include "diagnose_ex.h" 51 #include <rtl/logfile.hxx> 52 53 #define SQL_ISRULEOR2(pParseNode, e1,e2) ((pParseNode)->isRule() && (\ 54 (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e1) || \ 55 (pParseNode)->getRuleID() == OSQLParser::RuleID(OSQLParseNode::e2))) 56 57 using namespace ::comphelper; 58 using namespace ::connectivity; 59 using namespace ::connectivity::sdbcx; 60 using namespace ::dbtools; 61 using namespace ::connectivity::parse; 62 using namespace ::com::sun::star; 63 using namespace ::com::sun::star::uno; 64 using namespace ::com::sun::star::container; 65 using namespace ::com::sun::star::sdbcx; 66 using namespace ::com::sun::star::beans; 67 using namespace ::com::sun::star::sdbc; 68 using namespace ::com::sun::star::sdb; 69 70 namespace connectivity 71 { 72 struct OSQLParseTreeIteratorImpl 73 { 74 ::std::vector< TNodePair > m_aJoinConditions; 75 Reference< XConnection > m_xConnection; 76 Reference< XDatabaseMetaData > m_xDatabaseMetaData; 77 Reference< XNameAccess > m_xTableContainer; 78 Reference< XNameAccess > m_xQueryContainer; 79 80 ::boost::shared_ptr< OSQLTables > m_pTables; /// all tables which participate in the SQL statement 81 ::boost::shared_ptr< OSQLTables > m_pSubTables; /// all tables from sub queries not the tables from the select tables 82 ::boost::shared_ptr< QueryNameSet > m_pForbiddenQueryNames; 83 84 sal_uInt32 m_nIncludeMask; 85 86 bool m_bIsCaseSensitive; 87 88 OSQLParseTreeIteratorImpl( const Reference< XConnection >& _rxConnection, const Reference< XNameAccess >& _rxTables ) 89 :m_xConnection( _rxConnection ) 90 ,m_nIncludeMask( OSQLParseTreeIterator::All ) 91 ,m_bIsCaseSensitive( true ) 92 { 93 OSL_PRECOND( m_xConnection.is(), "OSQLParseTreeIteratorImpl::OSQLParseTreeIteratorImpl: invalid connection!" ); 94 m_xDatabaseMetaData = m_xConnection->getMetaData(); 95 96 m_bIsCaseSensitive = m_xDatabaseMetaData.is() && m_xDatabaseMetaData->supportsMixedCaseQuotedIdentifiers(); 97 m_pTables.reset( new OSQLTables( m_bIsCaseSensitive ) ); 98 m_pSubTables.reset( new OSQLTables( m_bIsCaseSensitive ) ); 99 100 m_xTableContainer = _rxTables; 101 102 DatabaseMetaData aMetaData( m_xConnection ); 103 if ( aMetaData.supportsSubqueriesInFrom() ) 104 { 105 // connections might support the XQueriesSupplier interface, if they implement the css.sdb.Connection 106 // service 107 Reference< XQueriesSupplier > xSuppQueries( m_xConnection, UNO_QUERY ); 108 if ( xSuppQueries.is() ) 109 m_xQueryContainer = xSuppQueries->getQueries(); 110 } 111 } 112 113 public: 114 inline bool isQueryAllowed( const ::rtl::OUString& _rQueryName ) 115 { 116 if ( !m_pForbiddenQueryNames.get() ) 117 return true; 118 if ( m_pForbiddenQueryNames->find( _rQueryName ) == m_pForbiddenQueryNames->end() ) 119 return true; 120 return false; 121 } 122 }; 123 124 //------------------------------------------------------------------------- 125 /** helper class for temporarily adding a query name to a list of forbidden query names 126 */ 127 class ForbidQueryName 128 { 129 ::boost::shared_ptr< QueryNameSet >& m_rpAllForbiddenNames; 130 ::rtl::OUString m_sForbiddenQueryName; 131 132 public: 133 ForbidQueryName( OSQLParseTreeIteratorImpl& _rIteratorImpl, const ::rtl::OUString _rForbiddenQueryName ) 134 :m_rpAllForbiddenNames( _rIteratorImpl.m_pForbiddenQueryNames ) 135 ,m_sForbiddenQueryName( _rForbiddenQueryName ) 136 { 137 if ( !m_rpAllForbiddenNames.get() ) 138 m_rpAllForbiddenNames.reset( new QueryNameSet ); 139 m_rpAllForbiddenNames->insert( m_sForbiddenQueryName ); 140 } 141 142 ~ForbidQueryName() 143 { 144 m_rpAllForbiddenNames->erase( m_sForbiddenQueryName ); 145 } 146 }; 147 } 148 //----------------------------------------------------------------------------- 149 OSQLParseTreeIterator::OSQLParseTreeIterator(const Reference< XConnection >& _rxConnection, 150 const Reference< XNameAccess >& _rxTables, 151 const OSQLParser& _rParser, 152 const OSQLParseNode* pRoot ) 153 :m_rParser( _rParser ) 154 ,m_pImpl( new OSQLParseTreeIteratorImpl( _rxConnection, _rxTables ) ) 155 { 156 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::OSQLParseTreeIterator" ); 157 setParseTree(pRoot); 158 } 159 160 //----------------------------------------------------------------------------- 161 OSQLParseTreeIterator::OSQLParseTreeIterator( const OSQLParseTreeIterator& _rParentIterator, const OSQLParser& _rParser, const OSQLParseNode* pRoot ) 162 :m_rParser( _rParser ) 163 ,m_pImpl( new OSQLParseTreeIteratorImpl( _rParentIterator.m_pImpl->m_xConnection, _rParentIterator.m_pImpl->m_xTableContainer ) ) 164 { 165 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::OSQLParseTreeIterator" ); 166 m_pImpl->m_pForbiddenQueryNames = _rParentIterator.m_pImpl->m_pForbiddenQueryNames; 167 setParseTree( pRoot ); 168 } 169 170 //----------------------------------------------------------------------------- 171 OSQLParseTreeIterator::~OSQLParseTreeIterator() 172 { 173 dispose(); 174 } 175 176 // ----------------------------------------------------------------------------- 177 const OSQLTables& OSQLParseTreeIterator::getTables() const 178 { 179 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getTables" ); 180 return *m_pImpl->m_pTables; 181 } 182 183 // ----------------------------------------------------------------------------- 184 bool OSQLParseTreeIterator::isCaseSensitive() const 185 { 186 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::isCaseSensitive" ); 187 return m_pImpl->m_bIsCaseSensitive; 188 } 189 190 // ----------------------------------------------------------------------------- 191 void OSQLParseTreeIterator::dispose() 192 { 193 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::dispose" ); 194 m_aSelectColumns = NULL; 195 m_aGroupColumns = NULL; 196 m_aOrderColumns = NULL; 197 m_aParameters = NULL; 198 m_pImpl->m_xTableContainer = NULL; 199 m_pImpl->m_xDatabaseMetaData = NULL; 200 m_aCreateColumns = NULL; 201 m_pImpl->m_pTables->clear(); 202 m_pImpl->m_pSubTables->clear(); 203 } 204 //----------------------------------------------------------------------------- 205 void OSQLParseTreeIterator::setParseTree(const OSQLParseNode * pNewParseTree) 206 { 207 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setParseTree" ); 208 m_pImpl->m_pTables->clear(); 209 m_pImpl->m_pSubTables->clear(); 210 211 m_aSelectColumns = new OSQLColumns(); 212 m_aGroupColumns = new OSQLColumns(); 213 m_aOrderColumns = new OSQLColumns(); 214 m_aParameters = new OSQLColumns(); 215 m_aCreateColumns = new OSQLColumns(); 216 217 m_pParseTree = pNewParseTree; 218 if (!m_pParseTree) 219 { 220 m_eStatementType = SQL_STATEMENT_UNKNOWN; 221 return; 222 } 223 224 // falls m_pParseTree aber keine Connection, dann Fehler 225 if ( !m_pImpl->m_xTableContainer.is() ) 226 return; 227 228 m_aErrors = SQLException(); 229 230 231 // Statement-Typ ermitteln ... 232 if (SQL_ISRULE(m_pParseTree,select_statement) || SQL_ISRULE(m_pParseTree,union_statement) ) 233 { 234 m_eStatementType = SQL_STATEMENT_SELECT; 235 } 236 else if (SQL_ISRULE(m_pParseTree,insert_statement)) 237 { 238 m_eStatementType = SQL_STATEMENT_INSERT; 239 } 240 else if (SQL_ISRULE(m_pParseTree,update_statement_searched)) 241 { 242 m_eStatementType = SQL_STATEMENT_UPDATE; 243 } 244 else if (SQL_ISRULE(m_pParseTree,delete_statement_searched)) 245 { 246 m_eStatementType = SQL_STATEMENT_DELETE; 247 } 248 else if (m_pParseTree->count() == 3 && SQL_ISRULE(m_pParseTree->getChild(1),odbc_call_spec)) 249 { 250 m_eStatementType = SQL_STATEMENT_ODBC_CALL; 251 } 252 else if (SQL_ISRULE(m_pParseTree->getChild(0),base_table_def)) 253 { 254 m_eStatementType = SQL_STATEMENT_CREATE_TABLE; 255 m_pParseTree = m_pParseTree->getChild(0); 256 } 257 else 258 { 259 m_eStatementType = SQL_STATEMENT_UNKNOWN; 260 //aIteratorStatus.setInvalidStatement(); 261 return; 262 } 263 } 264 265 //----------------------------------------------------------------------------- 266 namespace 267 { 268 //......................................................................... 269 static void impl_getRowString( const Reference< XRow >& _rxRow, const sal_Int32 _nColumnIndex, ::rtl::OUString& _out_rString ) 270 { 271 _out_rString = _rxRow->getString( _nColumnIndex ); 272 if ( _rxRow->wasNull() ) 273 _out_rString= ::rtl::OUString(); 274 } 275 276 //......................................................................... 277 static ::rtl::OUString lcl_findTableInMetaData( 278 const Reference< XDatabaseMetaData >& _rxDBMeta, const ::rtl::OUString& _rCatalog, 279 const ::rtl::OUString& _rSchema, const ::rtl::OUString& _rTableName ) 280 { 281 ::rtl::OUString sComposedName; 282 283 static const ::rtl::OUString s_sTableTypeView(RTL_CONSTASCII_USTRINGPARAM("VIEW")); 284 static const ::rtl::OUString s_sTableTypeTable(RTL_CONSTASCII_USTRINGPARAM("TABLE")); 285 static const ::rtl::OUString s_sWildcard = ::rtl::OUString::createFromAscii("%"); 286 287 // we want all catalogues, all schemas, all tables 288 Sequence< ::rtl::OUString > sTableTypes(3); 289 sTableTypes[0] = s_sTableTypeView; 290 sTableTypes[1] = s_sTableTypeTable; 291 sTableTypes[2] = s_sWildcard; // just to be sure to include anything else .... 292 293 if ( _rxDBMeta.is() ) 294 { 295 sComposedName = ::rtl::OUString(); 296 297 Reference< XResultSet> xRes = _rxDBMeta->getTables( 298 _rCatalog.getLength() ? makeAny( _rCatalog ) : Any(), _rSchema.getLength() ? _rSchema : s_sWildcard, _rTableName, sTableTypes ); 299 300 Reference< XRow > xCurrentRow( xRes, UNO_QUERY ); 301 if ( xCurrentRow.is() && xRes->next() ) 302 { 303 ::rtl::OUString sCatalog, sSchema, sName; 304 305 impl_getRowString( xCurrentRow, 1, sCatalog ); 306 impl_getRowString( xCurrentRow, 2, sSchema ); 307 impl_getRowString( xCurrentRow, 3, sName ); 308 309 sComposedName = ::dbtools::composeTableName( 310 _rxDBMeta, 311 sCatalog, 312 sSchema, 313 sName, 314 sal_False, 315 ::dbtools::eInDataManipulation 316 ); 317 } 318 } 319 return sComposedName; 320 } 321 } 322 323 //----------------------------------------------------------------------------- 324 void OSQLParseTreeIterator::impl_getQueryParameterColumns( const OSQLTable& _rQuery ) 325 { 326 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_getQueryParameterColumns" ); 327 if ( ( m_pImpl->m_nIncludeMask & Parameters ) != Parameters ) 328 // parameters not to be included in the traversal 329 return; 330 331 ::vos::ORef< OSQLColumns > pSubQueryParameterColumns( new OSQLColumns() ); 332 333 // get the command and the EscapeProcessing properties from the sub query 334 ::rtl::OUString sSubQueryCommand; 335 sal_Bool bEscapeProcessing = sal_False; 336 try 337 { 338 Reference< XPropertySet > xQueryProperties( _rQuery, UNO_QUERY_THROW ); 339 OSL_VERIFY( xQueryProperties->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_COMMAND ) ) >>= sSubQueryCommand ); 340 OSL_VERIFY( xQueryProperties->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_ESCAPEPROCESSING ) ) >>= bEscapeProcessing ); 341 } 342 catch( const Exception& ) 343 { 344 DBG_UNHANDLED_EXCEPTION(); 345 } 346 347 // parse the sub query 348 do { 349 350 if ( !bEscapeProcessing || ( sSubQueryCommand.getLength() == 0 ) ) 351 break; 352 353 ::rtl::OUString sError; 354 ::std::auto_ptr< OSQLParseNode > pSubQueryNode( const_cast< OSQLParser& >( m_rParser ).parseTree( sError, sSubQueryCommand, sal_False ) ); 355 if ( !pSubQueryNode.get() ) 356 break; 357 358 OSQLParseTreeIterator aSubQueryIterator( *this, m_rParser, pSubQueryNode.get() ); 359 aSubQueryIterator.traverseSome( Parameters | SelectColumns ); 360 // SelectColumns might also contain parameters 361 // #i77635# - 2007-07-23 / frank.schoenheit@sun.com 362 pSubQueryParameterColumns = aSubQueryIterator.getParameters(); 363 aSubQueryIterator.dispose(); 364 365 } while ( false ); 366 367 // copy the parameters of the sub query to our own parameter array 368 ::std::copy( pSubQueryParameterColumns->get().begin(), pSubQueryParameterColumns->get().end(), 369 ::std::insert_iterator< OSQLColumns::Vector >( m_aParameters->get(), m_aParameters->get().end() ) ); 370 } 371 372 //----------------------------------------------------------------------------- 373 OSQLTable OSQLParseTreeIterator::impl_locateRecordSource( const ::rtl::OUString& _rComposedName ) 374 { 375 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_locateRecordSource" ); 376 if ( !_rComposedName.getLength() ) 377 { 378 OSL_ENSURE( false, "OSQLParseTreeIterator::impl_locateRecordSource: no object name at all?" ); 379 return OSQLTable(); 380 } 381 382 OSQLTable aReturn; 383 ::rtl::OUString sComposedName( _rComposedName ); 384 385 try 386 { 387 ::rtl::OUString sCatalog, sSchema, sName; 388 qualifiedNameComponents( m_pImpl->m_xDatabaseMetaData, sComposedName, sCatalog, sSchema, sName, ::dbtools::eInDataManipulation ); 389 390 // check whether there is a query with the given name 391 bool bQueryDoesExist = m_pImpl->m_xQueryContainer.is() && m_pImpl->m_xQueryContainer->hasByName( sComposedName ); 392 393 // check whether the table container contains an object with the given name 394 if ( !bQueryDoesExist && !m_pImpl->m_xTableContainer->hasByName( sComposedName ) ) 395 sComposedName = lcl_findTableInMetaData( m_pImpl->m_xDatabaseMetaData, sCatalog, sSchema, sName ); 396 bool bTableDoesExist = m_pImpl->m_xTableContainer->hasByName( sComposedName ); 397 398 // now obtain the object 399 400 // if we're creating a table, and there already is a table or query with the same name, 401 // this is worth an error 402 if ( SQL_STATEMENT_CREATE_TABLE == m_eStatementType ) 403 { 404 if ( bQueryDoesExist ) 405 impl_appendError( IParseContext::ERROR_INVALID_QUERY_EXIST, &sName ); 406 else if ( bTableDoesExist ) 407 impl_appendError( IParseContext::ERROR_INVALID_TABLE_EXIST, &sName ); 408 else 409 aReturn = impl_createTableObject( sName, sCatalog, sSchema ); 410 } 411 else 412 { 413 // queries win over tables, so if there's a query with this name, take this, no matter if 414 // there's a table, too 415 if ( bQueryDoesExist ) 416 { 417 if ( !m_pImpl->isQueryAllowed( sComposedName ) ) 418 { 419 impl_appendError( m_rParser.getErrorHelper().getSQLException( sdb::ErrorCondition::PARSER_CYCLIC_SUB_QUERIES, NULL ) ); 420 return NULL; 421 } 422 423 m_pImpl->m_xQueryContainer->getByName( sComposedName ) >>= aReturn; 424 425 // collect the parameters from the sub query 426 ForbidQueryName aForbidName( *m_pImpl, sComposedName ); 427 impl_getQueryParameterColumns( aReturn ); 428 } 429 else if ( bTableDoesExist ) 430 m_pImpl->m_xTableContainer->getByName( sComposedName ) >>= aReturn; 431 else 432 { 433 if ( m_pImpl->m_xQueryContainer.is() ) 434 // the connection on which we're working supports sub queries in from (else 435 // m_xQueryContainer would not have been set), so emit a better error message 436 impl_appendError( IParseContext::ERROR_INVALID_TABLE_OR_QUERY, &sName ); 437 else 438 impl_appendError( IParseContext::ERROR_INVALID_TABLE, &sName ); 439 } 440 } 441 } 442 catch(Exception&) 443 { 444 impl_appendError( IParseContext::ERROR_INVALID_TABLE, &sComposedName ); 445 } 446 447 return aReturn; 448 } 449 450 //----------------------------------------------------------------------------- 451 void OSQLParseTreeIterator::traverseOneTableName( OSQLTables& _rTables,const OSQLParseNode * pTableName, const ::rtl::OUString & rTableRange ) 452 { 453 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOneTableName" ); 454 if ( ( m_pImpl->m_nIncludeMask & TableNames ) != TableNames ) 455 // tables should not be included in the traversal 456 return; 457 458 OSL_ENSURE(pTableName != NULL,"OSQLParseTreeIterator::traverseOneTableName: pTableName == NULL"); 459 460 Any aCatalog; 461 ::rtl::OUString aSchema,aTableName,aComposedName; 462 ::rtl::OUString aTableRange(rTableRange); 463 464 // Tabellenname abholen 465 OSQLParseNode::getTableComponents(pTableName,aCatalog,aSchema,aTableName,m_pImpl->m_xDatabaseMetaData); 466 467 // create the composed name like DOMAIN.USER.TABLE1 468 aComposedName = ::dbtools::composeTableName(m_pImpl->m_xDatabaseMetaData, 469 aCatalog.hasValue() ? ::comphelper::getString(aCatalog) : ::rtl::OUString(), 470 aSchema, 471 aTableName, 472 sal_False, 473 ::dbtools::eInDataManipulation); 474 475 // if there is no alias for the table name assign the orignal name to it 476 if ( !aTableRange.getLength() ) 477 aTableRange = aComposedName; 478 479 // get the object representing this table/query 480 OSQLTable aTable = impl_locateRecordSource( aComposedName ); 481 if ( aTable.is() ) 482 _rTables[ aTableRange ] = aTable; 483 } 484 //----------------------------------------------------------------------------- 485 void OSQLParseTreeIterator::impl_fillJoinConditions(const OSQLParseNode* i_pJoinCondition) 486 { 487 if (i_pJoinCondition->count() == 3 && // Ausdruck is geklammert 488 SQL_ISPUNCTUATION(i_pJoinCondition->getChild(0),"(") && 489 SQL_ISPUNCTUATION(i_pJoinCondition->getChild(2),")")) 490 { 491 impl_fillJoinConditions(i_pJoinCondition->getChild(1)); 492 } 493 else if (SQL_ISRULEOR2(i_pJoinCondition,search_condition,boolean_term) && // AND/OR-Verknuepfung: 494 i_pJoinCondition->count() == 3) 495 { 496 // nur AND Verkn�pfung zulassen 497 if ( SQL_ISTOKEN(i_pJoinCondition->getChild(1),AND) ) 498 { 499 impl_fillJoinConditions(i_pJoinCondition->getChild(0)); 500 impl_fillJoinConditions(i_pJoinCondition->getChild(1)); 501 } 502 } 503 else if (SQL_ISRULE(i_pJoinCondition,comparison_predicate)) 504 { 505 // only the comparison of columns is allowed 506 OSL_ENSURE(i_pJoinCondition->count() == 3,"OQueryDesignView::InsertJoinConnection: Fehler im Parse Tree"); 507 if (SQL_ISRULE(i_pJoinCondition->getChild(0),column_ref) && 508 SQL_ISRULE(i_pJoinCondition->getChild(2),column_ref) && 509 i_pJoinCondition->getChild(1)->getNodeType() == SQL_NODE_EQUAL) 510 { 511 m_pImpl->m_aJoinConditions.push_back( TNodePair(i_pJoinCondition->getChild(0),i_pJoinCondition->getChild(2)) ); 512 } 513 } 514 } 515 //----------------------------------------------------------------------------- 516 ::std::vector< TNodePair >& OSQLParseTreeIterator::getJoinConditions() const 517 { 518 return m_pImpl->m_aJoinConditions; 519 } 520 //----------------------------------------------------------------------------- 521 void OSQLParseTreeIterator::getQualified_join( OSQLTables& _rTables, const OSQLParseNode *pTableRef, ::rtl::OUString& aTableRange ) 522 { 523 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getQualified_join" ); 524 OSL_PRECOND( SQL_ISRULE( pTableRef, cross_union ) || SQL_ISRULE( pTableRef, qualified_join ) , 525 "OSQLParseTreeIterator::getQualified_join: illegal node!" ); 526 527 aTableRange = ::rtl::OUString(); 528 529 const OSQLParseNode* pNode = getTableNode(_rTables,pTableRef->getChild(0),aTableRange); 530 if ( isTableNode( pNode ) ) 531 traverseOneTableName( _rTables, pNode, aTableRange ); 532 533 sal_uInt32 nPos = 4; 534 if( SQL_ISRULE(pTableRef,cross_union) || pTableRef->getChild(1)->getTokenID() != SQL_TOKEN_NATURAL) 535 { 536 nPos = 3; 537 // join_condition,named_columns_join 538 if ( SQL_ISRULE( pTableRef, qualified_join ) ) 539 { 540 const OSQLParseNode* pJoin_spec = pTableRef->getChild(4); 541 if ( SQL_ISRULE( pJoin_spec, join_condition ) ) 542 { 543 impl_fillJoinConditions(pJoin_spec->getChild(1)); 544 } 545 else 546 { 547 const OSQLParseNode* pColumnCommalist = pJoin_spec->getChild(2); 548 // Alle Columns in der column_commalist ... 549 for (sal_uInt32 i = 0; i < pColumnCommalist->count(); i++) 550 { 551 const OSQLParseNode * pCol = pColumnCommalist->getChild(i); 552 // add twice because the column must exists in both tables 553 m_pImpl->m_aJoinConditions.push_back( TNodePair(pCol,pCol) ); 554 } 555 } 556 } 557 } 558 559 pNode = getTableNode(_rTables,pTableRef->getChild(nPos),aTableRange); 560 if ( isTableNode( pNode ) ) 561 traverseOneTableName( _rTables, pNode, aTableRange ); 562 } 563 //----------------------------------------------------------------------------- 564 const OSQLParseNode* OSQLParseTreeIterator::getTableNode( OSQLTables& _rTables, const OSQLParseNode *pTableRef,::rtl::OUString& rTableRange ) 565 { 566 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getTableNode" ); 567 OSL_PRECOND( SQL_ISRULE( pTableRef, table_ref ) || SQL_ISRULE( pTableRef, joined_table ) 568 || SQL_ISRULE( pTableRef, qualified_join ) || SQL_ISRULE( pTableRef, cross_union ), 569 "OSQLParseTreeIterator::getTableNode: only to be called for table_ref nodes!" ); 570 571 const OSQLParseNode* pTableNameNode = NULL; 572 573 if ( SQL_ISRULE( pTableRef, joined_table ) ) 574 { 575 getQualified_join( _rTables, pTableRef->getChild(1), rTableRange ); 576 } 577 if ( SQL_ISRULE( pTableRef, qualified_join ) || SQL_ISRULE( pTableRef, cross_union ) ) 578 { 579 getQualified_join( _rTables, pTableRef, rTableRange ); 580 } 581 else 582 { 583 rTableRange = OSQLParseNode::getTableRange(pTableRef); 584 if ( ( pTableRef->count() == 4 ) // '{' SQL_TOKEN_OJ joined_table '}' 585 || ( pTableRef->count() == 5 ) // '(' joined_table ')' range_variable op_column_commalist 586 ) 587 { 588 getQualified_join( _rTables, pTableRef->getChild(6 - pTableRef->count()), rTableRange ); 589 } 590 else if ( pTableRef->count() == 3 ) // subquery range_variable op_column_commalist || '(' joined_table ')' 591 { 592 const OSQLParseNode* pSubQuery = pTableRef->getChild(0); 593 if ( pSubQuery->isToken() ) 594 { 595 getQualified_join( _rTables, pTableRef->getChild(1), rTableRange ); 596 } 597 else 598 { 599 OSL_ENSURE( pSubQuery->count() == 3, "sub queries should have 3 children!" ); 600 const OSQLParseNode* pQueryExpression = pSubQuery->getChild(1); 601 if ( SQL_ISRULE( pQueryExpression, select_statement ) ) 602 { 603 getSelect_statement( *m_pImpl->m_pSubTables, pQueryExpression ); 604 } 605 else 606 { 607 OSL_ENSURE( false, "OSQLParseTreeIterator::getTableNode: subquery which is no select_statement: not yet implemented!" ); 608 } 609 } 610 } 611 else if ( pTableRef->count() == 2 ) // table_node table_primary_as_range_column 612 { 613 pTableNameNode = pTableRef->getChild(0); 614 } 615 else 616 OSL_ENSURE( false, "OSQLParseTreeIterator::getTableNode: unhandled case!" ); 617 } 618 619 return pTableNameNode; 620 } 621 //----------------------------------------------------------------------------- 622 void OSQLParseTreeIterator::getSelect_statement(OSQLTables& _rTables,const OSQLParseNode* pSelect) 623 { 624 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSelect_statement" ); 625 if(SQL_ISRULE(pSelect,union_statement)) 626 { 627 getSelect_statement(_rTables,pSelect->getChild(0)); 628 //getSelect_statement(pSelect->getChild(3)); 629 return; 630 } 631 OSQLParseNode * pTableRefCommalist = pSelect->getChild(3)->getChild(0)->getChild(1); 632 633 OSL_ENSURE(pTableRefCommalist != NULL,"OSQLParseTreeIterator: error in parse tree!"); 634 OSL_ENSURE(SQL_ISRULE(pTableRefCommalist,table_ref_commalist),"OSQLParseTreeIterator: error in parse tree!"); 635 636 const OSQLParseNode* pTableName = NULL; 637 ::rtl::OUString aTableRange; 638 for (sal_uInt32 i = 0; i < pTableRefCommalist->count(); i++) 639 { // from clause durchlaufen 640 aTableRange = ::rtl::OUString(); 641 642 const OSQLParseNode* pTableListElement = pTableRefCommalist->getChild(i); 643 if ( isTableNode( pTableListElement ) ) 644 { 645 traverseOneTableName( _rTables, pTableListElement, aTableRange ); 646 } 647 else if ( SQL_ISRULE( pTableListElement, table_ref ) ) 648 { 649 // Tabellenreferenz kann aus Tabellennamen, Tabellennamen (+),'('joined_table')'(+) bestehen 650 pTableName = pTableListElement->getChild(0); 651 if( isTableNode( pTableName ) ) 652 { // Tabellennamen gefunden 653 aTableRange = OSQLParseNode::getTableRange(pTableListElement); 654 traverseOneTableName( _rTables, pTableName, aTableRange ); 655 } 656 else if(SQL_ISPUNCTUATION(pTableName,"{")) 657 { // '{' SQL_TOKEN_OJ joined_table '}' 658 getQualified_join( _rTables, pTableListElement->getChild(2), aTableRange ); 659 } 660 else 661 { // '(' joined_table ')' range_variable op_column_commalist 662 getTableNode( _rTables, pTableListElement, aTableRange ); 663 } 664 } 665 else if (SQL_ISRULE( pTableListElement, qualified_join ) || SQL_ISRULE( pTableListElement, cross_union ) ) 666 { 667 getQualified_join( _rTables, pTableListElement, aTableRange ); 668 } 669 else if ( SQL_ISRULE( pTableListElement, joined_table ) ) 670 { 671 getQualified_join( _rTables, pTableListElement->getChild(1), aTableRange ); 672 } 673 674 // if (! aIteratorStatus.IsSuccessful()) break; 675 } 676 } 677 //----------------------------------------------------------------------------- 678 bool OSQLParseTreeIterator::traverseTableNames(OSQLTables& _rTables) 679 { 680 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseTableNames" ); 681 if ( m_pParseTree == NULL ) 682 return false; 683 684 OSQLParseNode* pTableName = NULL; 685 686 switch ( m_eStatementType ) 687 { 688 case SQL_STATEMENT_SELECT: 689 getSelect_statement( _rTables, m_pParseTree ); 690 break; 691 692 case SQL_STATEMENT_CREATE_TABLE: 693 case SQL_STATEMENT_INSERT: 694 case SQL_STATEMENT_DELETE: 695 pTableName = m_pParseTree->getChild(2); 696 break; 697 698 case SQL_STATEMENT_UPDATE: 699 pTableName = m_pParseTree->getChild(1); 700 break; 701 default: 702 break; 703 } 704 705 if ( pTableName ) 706 { 707 ::rtl::OUString sTableRange; 708 traverseOneTableName( _rTables, pTableName, sTableRange ); 709 } 710 711 return !hasErrors(); 712 } 713 //----------------------------------------------------------------------------- 714 ::rtl::OUString OSQLParseTreeIterator::getColumnAlias(const OSQLParseNode* _pDerivedColumn) 715 { 716 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnAlias" ); 717 OSL_ENSURE(SQL_ISRULE(_pDerivedColumn,derived_column),"No derived column!"); 718 ::rtl::OUString sColumnAlias; 719 if(_pDerivedColumn->getChild(1)->count() == 2) 720 sColumnAlias = _pDerivedColumn->getChild(1)->getChild(1)->getTokenValue(); 721 else if(!_pDerivedColumn->getChild(1)->isRule()) 722 sColumnAlias = _pDerivedColumn->getChild(1)->getTokenValue(); 723 return sColumnAlias; 724 } 725 726 // ----------------------------------------------------------------------------- 727 namespace 728 { 729 void lcl_getColumnRange( const OSQLParseNode* _pColumnRef, const Reference< XConnection >& _rxConnection, 730 ::rtl::OUString& _out_rColumnName, ::rtl::OUString& _out_rTableRange, 731 const OSQLColumns* _pSelectColumns, ::rtl::OUString& _out_rColumnAliasIfPresent ) 732 { 733 _out_rColumnName = _out_rTableRange = _out_rColumnAliasIfPresent = ::rtl::OUString(); 734 if ( SQL_ISRULE( _pColumnRef, column_ref ) ) 735 { 736 if( _pColumnRef->count() > 1 ) 737 { 738 for ( sal_Int32 i=0; i<((sal_Int32)_pColumnRef->count())-2; ++i ) 739 _pColumnRef->getChild(i)->parseNodeToStr( _out_rTableRange, _rxConnection, NULL, sal_False, sal_False ); 740 _out_rColumnName = _pColumnRef->getChild( _pColumnRef->count()-1 )->getChild(0)->getTokenValue(); 741 } 742 else 743 _out_rColumnName = _pColumnRef->getChild(0)->getTokenValue(); 744 745 // look up the column in the select column, to find an possible alias 746 if ( _pSelectColumns ) 747 { 748 for ( OSQLColumns::Vector::const_iterator lookupColumn = _pSelectColumns->get().begin(); 749 lookupColumn != _pSelectColumns->get().end(); 750 ++lookupColumn 751 ) 752 { 753 Reference< XPropertySet > xColumn( *lookupColumn ); 754 try 755 { 756 ::rtl::OUString sName, sTableName; 757 xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_REALNAME ) ) >>= sName; 758 xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_TABLENAME ) ) >>= sTableName; 759 if ( sName == _out_rColumnName && sTableName == _out_rTableRange ) 760 xColumn->getPropertyValue( OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_NAME ) ) >>= _out_rColumnAliasIfPresent; 761 } 762 catch( const Exception& ) 763 { 764 DBG_UNHANDLED_EXCEPTION(); 765 } 766 } 767 } 768 } 769 else if(SQL_ISRULE(_pColumnRef,general_set_fct) || SQL_ISRULE(_pColumnRef,set_fct_spec)) 770 { // Funktion 771 _pColumnRef->parseNodeToStr( _out_rColumnName, _rxConnection ); 772 } 773 else if(_pColumnRef->getNodeType() == SQL_NODE_NAME) 774 _out_rColumnName = _pColumnRef->getTokenValue(); 775 } 776 } 777 778 // ----------------------------------------------------------------------------- 779 void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef, 780 ::rtl::OUString& _rColumnName, 781 ::rtl::OUString& _rTableRange) const 782 { 783 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" ); 784 ::rtl::OUString sDummy; 785 lcl_getColumnRange( _pColumnRef, m_pImpl->m_xConnection, _rColumnName, _rTableRange, NULL, sDummy ); 786 } 787 788 // ----------------------------------------------------------------------------- 789 void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef, 790 ::rtl::OUString& _rColumnName, 791 ::rtl::OUString& _rTableRange, 792 ::rtl::OUString& _out_rColumnAliasIfPresent ) const 793 { 794 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" ); 795 lcl_getColumnRange( _pColumnRef, m_pImpl->m_xConnection, _rColumnName, _rTableRange, &*m_aSelectColumns, _out_rColumnAliasIfPresent ); 796 } 797 798 //----------------------------------------------------------------------------- 799 void OSQLParseTreeIterator::getColumnRange( const OSQLParseNode* _pColumnRef, 800 const Reference< XConnection >& _rxConnection, ::rtl::OUString& _out_rColumnName, ::rtl::OUString& _out_rTableRange ) 801 { 802 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnRange" ); 803 ::rtl::OUString sDummy; 804 lcl_getColumnRange( _pColumnRef, _rxConnection, _out_rColumnName, _out_rTableRange, NULL, sDummy ); 805 } 806 807 //----------------------------------------------------------------------------- 808 sal_Bool OSQLParseTreeIterator::getColumnTableRange(const OSQLParseNode* pNode, ::rtl::OUString &rTableRange) const 809 { 810 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getColumnTableRange" ); 811 // Ermitteln ob alle Spalten zu einer Tabelle gehoeren 812 if (SQL_ISRULE(pNode,column_ref)) 813 { 814 ::rtl::OUString aColName, aTableRange; 815 getColumnRange(pNode, aColName, aTableRange); 816 if (!aTableRange.getLength()) // keinen gefunden 817 { 818 // dann die Spalte in den Tabellen suchen 819 for (ConstOSQLTablesIterator aIter = m_pImpl->m_pTables->begin(); aIter != m_pImpl->m_pTables->end(); ++aIter) 820 { 821 if (aIter->second.is()) 822 { 823 try 824 { 825 Reference< XNameAccess > xColumns = aIter->second->getColumns(); 826 if(xColumns->hasByName(aColName)) 827 { 828 Reference< XPropertySet > xColumn; 829 if (xColumns->getByName(aColName) >>= xColumn) 830 { 831 OSL_ENSURE(xColumn.is(),"Column isn't a propertyset!"); 832 aTableRange = aIter->first; 833 break; 834 } 835 } 836 } 837 catch(Exception&) 838 { 839 } 840 } 841 } 842 if (!aTableRange.getLength()) 843 return sal_False; 844 } 845 846 847 if (!rTableRange.getLength()) 848 rTableRange = aTableRange; 849 else if (rTableRange != aTableRange) 850 return sal_False; 851 } 852 else 853 { 854 for (sal_uInt32 i = 0, ncount = pNode->count(); i < ncount; i++) 855 { 856 if (!getColumnTableRange(pNode->getChild(i), rTableRange)) 857 return sal_False; 858 } 859 } 860 return sal_True; 861 } 862 863 //----------------------------------------------------------------------------- 864 void OSQLParseTreeIterator::traverseCreateColumns(const OSQLParseNode* pSelectNode) 865 { 866 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseCreateColumns" ); 867 // aIteratorStatus.Clear(); 868 869 if (!pSelectNode || m_eStatementType != SQL_STATEMENT_CREATE_TABLE || m_pImpl->m_pTables->empty()) 870 { 871 impl_appendError( IParseContext::ERROR_GENERAL ); 872 return; 873 } 874 if (!SQL_ISRULE(pSelectNode,base_table_element_commalist)) 875 return ; 876 877 for (sal_uInt32 i = 0; i < pSelectNode->count(); i++) 878 { 879 OSQLParseNode *pColumnRef = pSelectNode->getChild(i); 880 881 if (SQL_ISRULE(pColumnRef,column_def)) 882 { 883 ::rtl::OUString aColumnName; 884 ::rtl::OUString aTypeName; 885 ::rtl::OUString aTableRange; 886 sal_Int32 nType = DataType::VARCHAR; 887 sal_Int32 nLen = 0; 888 aColumnName = pColumnRef->getChild(0)->getTokenValue(); 889 890 OSQLParseNode *pDatatype = pColumnRef->getChild(1); 891 if (pDatatype && SQL_ISRULE(pDatatype,character_string_type)) 892 { 893 const OSQLParseNode *pType = pDatatype->getChild(0); 894 aTypeName = pType->getTokenValue(); 895 if (pDatatype->count() == 2 && (pType->getTokenID() == SQL_TOKEN_CHAR || pType->getTokenID() == SQL_TOKEN_CHARACTER )) 896 nType = DataType::CHAR; 897 898 const OSQLParseNode *pParams = pDatatype->getChild(pDatatype->count()-1); 899 if ( pParams->count() ) 900 { 901 nLen = pParams->getChild(1)->getTokenValue().toInt32(); 902 } 903 } 904 else if(pDatatype && pDatatype->getNodeType() == SQL_NODE_KEYWORD) 905 { 906 aTypeName = ::rtl::OUString::createFromAscii("VARCHAR"); 907 } 908 909 if (aTypeName.getLength()) 910 { 911 //TODO:Create a new class for create statement to handle field length 912 OParseColumn* pColumn = new OParseColumn(aColumnName,aTypeName,::rtl::OUString(),::rtl::OUString(), 913 ColumnValue::NULLABLE_UNKNOWN,0,0,nType,sal_False,sal_False,isCaseSensitive()); 914 pColumn->setFunction(sal_False); 915 pColumn->setRealName(aColumnName); 916 917 Reference< XPropertySet> xCol = pColumn; 918 m_aCreateColumns->get().push_back(xCol); 919 } 920 } 921 922 } 923 } 924 //----------------------------------------------------------------------------- 925 bool OSQLParseTreeIterator::traverseSelectColumnNames(const OSQLParseNode* pSelectNode) 926 { 927 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSelectColumnNames" ); 928 if ( ( m_pImpl->m_nIncludeMask & SelectColumns ) != SelectColumns ) 929 return true; 930 931 if (!pSelectNode || m_eStatementType != SQL_STATEMENT_SELECT || m_pImpl->m_pTables->empty()) 932 { 933 impl_appendError( IParseContext::ERROR_GENERAL ); 934 return false; 935 } 936 937 if(SQL_ISRULE(pSelectNode,union_statement)) 938 { 939 return traverseSelectColumnNames( pSelectNode->getChild( 0 ) ) 940 /*&& traverseSelectColumnNames( pSelectNode->getChild( 3 ) )*/; 941 } 942 943 static ::rtl::OUString aEmptyString; 944 // nyi: mehr Pruefung auf korrekte Struktur! 945 if (pSelectNode->getChild(2)->isRule() && SQL_ISPUNCTUATION(pSelectNode->getChild(2)->getChild(0),"*")) 946 { 947 // SELECT * ... 948 setSelectColumnName(m_aSelectColumns,::rtl::OUString::createFromAscii("*"), aEmptyString,aEmptyString); 949 } 950 else if (SQL_ISRULE(pSelectNode->getChild(2),scalar_exp_commalist)) 951 { 952 // SELECT column[,column] oder SELECT COUNT(*) ... 953 OSQLParseNode * pSelection = pSelectNode->getChild(2); 954 955 for (sal_uInt32 i = 0; i < pSelection->count(); i++) 956 { 957 OSQLParseNode *pColumnRef = pSelection->getChild(i); 958 959 //if (SQL_ISRULE(pColumnRef,select_sublist)) 960 if (SQL_ISRULE(pColumnRef,derived_column) && 961 SQL_ISRULE(pColumnRef->getChild(0),column_ref) && 962 pColumnRef->getChild(0)->count() == 3 && 963 SQL_ISPUNCTUATION(pColumnRef->getChild(0)->getChild(2),"*")) 964 { 965 // alle Spalten der Tabelle 966 ::rtl::OUString aTableRange; 967 pColumnRef->getChild(0)->parseNodeToStr( aTableRange, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 968 setSelectColumnName(m_aSelectColumns,::rtl::OUString::createFromAscii("*"), aEmptyString,aTableRange); 969 continue; 970 } 971 else if (SQL_ISRULE(pColumnRef,derived_column)) 972 { 973 ::rtl::OUString aColumnAlias(getColumnAlias(pColumnRef)); // kann leer sein 974 ::rtl::OUString sColumnName; 975 ::rtl::OUString aTableRange; 976 sal_Int32 nType = DataType::VARCHAR; 977 sal_Bool bFkt(sal_False); 978 pColumnRef = pColumnRef->getChild(0); 979 if ( 980 pColumnRef->count() == 3 && 981 SQL_ISPUNCTUATION(pColumnRef->getChild(0),"(") && 982 SQL_ISPUNCTUATION(pColumnRef->getChild(2),")") 983 ) 984 pColumnRef = pColumnRef->getChild(1); 985 986 if (SQL_ISRULE(pColumnRef,column_ref)) 987 { 988 getColumnRange(pColumnRef,sColumnName,aTableRange); 989 OSL_ENSURE(sColumnName.getLength(),"Columnname darf nicht leer sein"); 990 } 991 else /*if (SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec) || 992 SQL_ISRULE(pColumnRef,position_exp) || SQL_ISRULE(pColumnRef,extract_exp) || 993 SQL_ISRULE(pColumnRef,length_exp) || SQL_ISRULE(pColumnRef,char_value_fct)|| 994 SQL_ISRULE(pColumnRef,num_value_exp) || SQL_ISRULE(pColumnRef,term))*/ 995 { 996 /* Funktionsaufruf vorhanden */ 997 pColumnRef->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_True ); 998 ::rtl::OUString sTableRange; 999 // check if the column is also a parameter 1000 traverseORCriteria(pColumnRef); // num_value_exp 1001 1002 // gehoeren alle beteiligten Spalten der Funktion zu einer Tabelle 1003 if (m_pImpl->m_pTables->size() == 1) 1004 { 1005 aTableRange = m_pImpl->m_pTables->begin()->first; 1006 } 1007 else 1008 { 1009 getColumnTableRange(pColumnRef,aTableRange); 1010 } 1011 if ( pColumnRef->isRule() ) 1012 { 1013 bFkt = sal_True; 1014 nType = getFunctionReturnType(pColumnRef); 1015 } 1016 } 1017 /* 1018 else 1019 { 1020 aIteratorStatus.setStatementTooComplex(); 1021 return; 1022 } 1023 */ 1024 if(!aColumnAlias.getLength()) 1025 aColumnAlias = sColumnName; 1026 setSelectColumnName(m_aSelectColumns,sColumnName,aColumnAlias,aTableRange,bFkt,nType,SQL_ISRULE(pColumnRef,general_set_fct) || SQL_ISRULE(pColumnRef,set_fct_spec)); 1027 } 1028 } 1029 } 1030 1031 return !hasErrors(); 1032 } 1033 1034 1035 //----------------------------------------------------------------------------- 1036 bool OSQLParseTreeIterator::traverseOrderByColumnNames(const OSQLParseNode* pSelectNode) 1037 { 1038 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOrderByColumnNames" ); 1039 traverseByColumnNames( pSelectNode, sal_True ); 1040 return !hasErrors(); 1041 } 1042 //----------------------------------------------------------------------------- 1043 void OSQLParseTreeIterator::traverseByColumnNames(const OSQLParseNode* pSelectNode,sal_Bool _bOrder) 1044 { 1045 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseByColumnNames" ); 1046 // aIteratorStatus.Clear(); 1047 1048 if (pSelectNode == NULL) 1049 { 1050 //aIteratorStatus.setInvalidStatement(); 1051 return; 1052 } 1053 1054 if (m_eStatementType != SQL_STATEMENT_SELECT) 1055 { 1056 //aIteratorStatus.setInvalidStatement(); 1057 return; 1058 } 1059 1060 if(SQL_ISRULE(pSelectNode,union_statement)) 1061 { 1062 traverseByColumnNames(pSelectNode->getChild(0),_bOrder); 1063 return; 1064 } 1065 1066 OSL_ENSURE(pSelectNode->count() >= 4,"OSQLParseTreeIterator: error in parse tree!"); 1067 1068 OSQLParseNode * pTableExp = pSelectNode->getChild(3); 1069 OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1070 OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator:table_exp error in parse tree!"); 1071 OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!"); 1072 1073 sal_uInt32 nPos = ( _bOrder ? ORDER_BY_CHILD_POS : 2 ); 1074 1075 OSQLParseNode * pOptByClause = pTableExp->getChild(nPos); 1076 OSL_ENSURE(pOptByClause != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1077 if ( pOptByClause->count() == 0 ) 1078 return; 1079 1080 OSL_ENSURE(pOptByClause->count() == 3,"OSQLParseTreeIterator: error in parse tree!"); 1081 1082 OSQLParseNode * pOrderingSpecCommalist = pOptByClause->getChild(2); 1083 OSL_ENSURE(pOrderingSpecCommalist != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1084 OSL_ENSURE(!_bOrder || SQL_ISRULE(pOrderingSpecCommalist,ordering_spec_commalist),"OSQLParseTreeIterator:ordering_spec_commalist error in parse tree!"); 1085 OSL_ENSURE(pOrderingSpecCommalist->count() > 0,"OSQLParseTreeIterator: error in parse tree!"); 1086 1087 ::rtl::OUString sColumnName,aColumnAlias; 1088 ::rtl::OUString aTableRange; 1089 sal_uInt32 nCount = pOrderingSpecCommalist->count(); 1090 for (sal_uInt32 i = 0; i < nCount; ++i) 1091 { 1092 OSQLParseNode* pColumnRef = pOrderingSpecCommalist->getChild(i); 1093 OSL_ENSURE(pColumnRef != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1094 if ( _bOrder ) 1095 { 1096 OSL_ENSURE(SQL_ISRULE(pColumnRef,ordering_spec),"OSQLParseTreeIterator:ordering_spec error in parse tree!"); 1097 OSL_ENSURE(pColumnRef->count() == 2,"OSQLParseTreeIterator: error in parse tree!"); 1098 1099 pColumnRef = pColumnRef->getChild(0); 1100 } 1101 aTableRange = ::rtl::OUString(); 1102 sColumnName = ::rtl::OUString(); 1103 if ( SQL_ISRULE(pColumnRef,column_ref) ) 1104 { 1105 // Column-Name (und TableRange): 1106 if(SQL_ISRULE(pColumnRef,column_ref)) 1107 getColumnRange(pColumnRef,sColumnName,aTableRange); 1108 else // eine Expression 1109 pColumnRef->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 1110 1111 OSL_ENSURE(sColumnName.getLength(),"sColumnName darf nicht leer sein"); 1112 } 1113 else 1114 { // here I found a predicate 1115 pColumnRef->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 1116 } 1117 OSL_ENSURE(pColumnRef != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1118 if ( _bOrder ) 1119 { 1120 // Ascending/Descending 1121 OSQLParseNode * pOptAscDesc = pColumnRef->getParent()->getChild(1); 1122 OSL_ENSURE(pOptAscDesc != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1123 1124 sal_Bool bAscending = pOptAscDesc && SQL_ISTOKEN(pOptAscDesc,ASC); 1125 setOrderByColumnName(sColumnName, aTableRange,bAscending); 1126 } 1127 else 1128 setGroupByColumnName(sColumnName, aTableRange); 1129 } 1130 } 1131 //----------------------------------------------------------------------------- 1132 bool OSQLParseTreeIterator::traverseGroupByColumnNames(const OSQLParseNode* pSelectNode) 1133 { 1134 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseGroupByColumnNames" ); 1135 traverseByColumnNames( pSelectNode, sal_False ); 1136 return !hasErrors(); 1137 } 1138 1139 // ----------------------------------------------------------------------------- 1140 namespace 1141 { 1142 ::rtl::OUString lcl_generateParameterName( const OSQLParseNode& _rParentNode, const OSQLParseNode& _rParamNode ) 1143 { 1144 ::rtl::OUString sColumnName( RTL_CONSTASCII_USTRINGPARAM( "param" ) ); 1145 const sal_Int32 nCount = (sal_Int32)_rParentNode.count(); 1146 for ( sal_Int32 i = 0; i < nCount; ++i ) 1147 { 1148 if ( _rParentNode.getChild(i) == &_rParamNode ) 1149 { 1150 sColumnName += ::rtl::OUString::valueOf( i+1 ); 1151 break; 1152 } 1153 } 1154 return sColumnName; 1155 } 1156 } 1157 1158 // ----------------------------------------------------------------------------- 1159 void OSQLParseTreeIterator::traverseParameters(const OSQLParseNode* _pNode) 1160 { 1161 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseParameters" ); 1162 if ( _pNode == NULL ) 1163 return; 1164 1165 ::rtl::OUString sColumnName, sTableRange, aColumnAlias; 1166 const OSQLParseNode* pParent = _pNode->getParent(); 1167 if ( pParent != NULL ) 1168 { 1169 if ( SQL_ISRULE(pParent,comparison_predicate) ) // x = X 1170 { 1171 sal_uInt32 nPos = 0; 1172 if ( pParent->getChild(nPos) == _pNode ) 1173 nPos = 2; 1174 const OSQLParseNode* pOther = pParent->getChild(nPos); 1175 if ( SQL_ISRULE( pOther, column_ref ) ) 1176 getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias); 1177 else 1178 pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 1179 } // if ( SQL_ISRULE(pParent,comparison_predicate) ) // x = X 1180 else if ( SQL_ISRULE(pParent,other_like_predicate_part_2) ) 1181 { 1182 const OSQLParseNode* pOther = pParent->getParent()->getChild(0); 1183 if ( SQL_ISRULE( pOther, column_ref ) ) 1184 getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias); 1185 else 1186 pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 1187 } 1188 else if ( SQL_ISRULE(pParent,between_predicate_part_2) ) 1189 { 1190 const OSQLParseNode* pOther = pParent->getParent()->getChild(0); 1191 if ( SQL_ISRULE( pOther, column_ref ) ) 1192 getColumnRange( pOther, sColumnName, sTableRange, aColumnAlias); 1193 else 1194 { 1195 pOther->parseNodeToStr( sColumnName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 1196 lcl_generateParameterName( *pParent, *_pNode ); 1197 } 1198 } 1199 else if ( pParent->getNodeType() == SQL_NODE_COMMALISTRULE ) 1200 { 1201 lcl_generateParameterName( *pParent, *_pNode ); 1202 } 1203 } 1204 traverseParameter( _pNode, pParent, sColumnName, sTableRange, aColumnAlias ); 1205 const sal_uInt32 nCount = _pNode->count(); 1206 for (sal_uInt32 i = 0; i < nCount; ++i) 1207 { 1208 const OSQLParseNode* pChild = _pNode->getChild(i); 1209 traverseParameters( pChild ); 1210 } 1211 } 1212 //----------------------------------------------------------------------------- 1213 bool OSQLParseTreeIterator::traverseSelectionCriteria(const OSQLParseNode* pSelectNode) 1214 { 1215 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSelectionCriteria" ); 1216 if ( pSelectNode == NULL ) 1217 return false; 1218 1219 1220 // Parse Tree analysieren (je nach Statement-Typ) 1221 // und Zeiger auf WHERE-Klausel setzen: 1222 OSQLParseNode * pWhereClause = NULL; 1223 1224 if (m_eStatementType == SQL_STATEMENT_SELECT) 1225 { 1226 if(SQL_ISRULE(pSelectNode,union_statement)) 1227 { 1228 return traverseSelectionCriteria( pSelectNode->getChild( 0 ) ) 1229 && traverseSelectionCriteria( pSelectNode->getChild( 3 ) ); 1230 } 1231 OSL_ENSURE(pSelectNode->count() >= 4,"OSQLParseTreeIterator: error in parse tree!"); 1232 1233 OSQLParseNode * pTableExp = pSelectNode->getChild(3); 1234 OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1235 OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!"); 1236 OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!"); 1237 1238 pWhereClause = pTableExp->getChild(1); 1239 } else if (SQL_ISRULE(pSelectNode,update_statement_searched)) { 1240 OSL_ENSURE(pSelectNode->count() == 5,"OSQLParseTreeIterator: error in parse tree!"); 1241 pWhereClause = pSelectNode->getChild(4); 1242 } else if (SQL_ISRULE(pSelectNode,delete_statement_searched)) { 1243 OSL_ENSURE(pSelectNode->count() == 4,"OSQLParseTreeIterator: error in parse tree!"); 1244 pWhereClause = pSelectNode->getChild(3); 1245 } else if (SQL_ISRULE(pSelectNode,delete_statement_positioned)) { 1246 // nyi 1247 OSL_ASSERT("OSQLParseTreeIterator::getSelectionCriteria: positioned nyi"); 1248 } else { 1249 // Anderes Statement. Keine Selektionskriterien. 1250 return false; 1251 } 1252 1253 if (! SQL_ISRULE(pWhereClause,where_clause)) { 1254 // Die Where Clause ist meistens optional, d. h. es koennte sich auch 1255 // um "optional_where_clause" handeln. 1256 OSL_ENSURE(SQL_ISRULE(pWhereClause,opt_where_clause),"OSQLParseTreeIterator: error in parse tree!"); 1257 return false; 1258 } 1259 1260 // Wenn es aber eine where_clause ist, dann darf sie nicht leer sein: 1261 OSL_ENSURE(pWhereClause->count() == 2,"OSQLParseTreeIterator: error in parse tree!"); 1262 1263 OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1); 1264 OSL_ENSURE(pComparisonPredicate != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1265 1266 // 1267 // Und nun die Vergleichskriterien abarbeiten (rekursiv, alles ist erstmal ein OR-Kriterium): 1268 // 1269 1270 traverseORCriteria(pComparisonPredicate); 1271 1272 return !hasErrors(); 1273 } 1274 1275 //----------------------------------------------------------------------------- 1276 void OSQLParseTreeIterator::traverseORCriteria(OSQLParseNode * pSearchCondition) 1277 { 1278 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseORCriteria" ); 1279 1280 1281 if ( 1282 pSearchCondition->count() == 3 && 1283 SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") && 1284 SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")") 1285 ) 1286 { 1287 // Runde Klammern um den Ausdruck 1288 traverseORCriteria(pSearchCondition->getChild(1)); 1289 } else if (SQL_ISRULE(pSearchCondition,search_condition) && 1290 pSearchCondition->count() == 3 && 1291 SQL_ISTOKEN(pSearchCondition->getChild(1),OR)) 1292 { 1293 // OR-Verknuepfung: 1294 1295 for (int i = 0; i < 3; i++) { 1296 if (i == 1) continue; // Schluesselwort OR ueberspringen 1297 1298 // Ist das erste Element wieder eine OR-Verknuepfung? 1299 if (i == 0 && 1300 SQL_ISRULE(pSearchCondition->getChild(0),search_condition) && 1301 pSearchCondition->getChild(0)->count() == 3 && 1302 SQL_ISTOKEN(pSearchCondition->getChild(0)->getChild(1),OR)) 1303 { 1304 // Dann rekursiv absteigen ... 1305 traverseORCriteria(pSearchCondition->getChild(0)); 1306 1307 } else { 1308 // AND-Kriterien ... 1309 traverseANDCriteria(pSearchCondition->getChild(i)); 1310 // if (! aIteratorStatus.IsSuccessful()) break; 1311 } 1312 1313 // if (! aIteratorStatus.IsSuccessful()) break; 1314 } 1315 } else { 1316 // Nur *ein* Kriterium oder eine AND-Verknuepfung von Kriterien. 1317 // Direkt die AND-Kriterien behandeln. 1318 traverseANDCriteria(pSearchCondition); 1319 // if (! aIteratorStatus.IsSuccessful()) return; 1320 } 1321 1322 // Fehler einfach weiterreichen. 1323 } 1324 1325 //----------------------------------------------------------------------------- 1326 void OSQLParseTreeIterator::traverseANDCriteria(OSQLParseNode * pSearchCondition) 1327 { 1328 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseANDCriteria" ); 1329 1330 1331 if ( 1332 SQL_ISRULE(pSearchCondition,boolean_primary) && 1333 pSearchCondition->count() == 3 && 1334 SQL_ISPUNCTUATION(pSearchCondition->getChild(0),"(") && 1335 SQL_ISPUNCTUATION(pSearchCondition->getChild(2),")") 1336 ) 1337 { 1338 // Runde Klammern 1339 traverseANDCriteria(pSearchCondition->getChild(1)); 1340 } 1341 // Das erste Element ist eine OR-Verknuepfung 1342 else if ( SQL_ISRULE(pSearchCondition,search_condition) && pSearchCondition->count() == 3 ) 1343 { 1344 // Dann rekursiv absteigen (dieselbe Row benutzen) ... 1345 traverseORCriteria(pSearchCondition->getChild(0)); 1346 // if (! aIteratorStatus.IsSuccessful()) 1347 // return; 1348 1349 // Und mit dem rechten Child weitermachen: 1350 traverseANDCriteria(pSearchCondition->getChild(2)); 1351 } 1352 // Das erste Element ist (wieder) eine AND-Verknuepfung 1353 else if ( SQL_ISRULE(pSearchCondition,boolean_term) && pSearchCondition->count() == 3 ) 1354 { 1355 // Dann rekursiv absteigen (dieselbe Row benutzen) ... 1356 traverseANDCriteria(pSearchCondition->getChild(0)); 1357 // if (! aIteratorStatus.IsSuccessful()) 1358 // return; 1359 1360 // Und mit dem rechten Child weitermachen: 1361 traverseANDCriteria(pSearchCondition->getChild(2)); 1362 } 1363 // Sonst einzelne Suchkriterien wie =, !=, ..., LIKE, IS NULL usw. behandeln: 1364 else if (SQL_ISRULE(pSearchCondition,comparison_predicate) ) 1365 { 1366 ::rtl::OUString aValue; 1367 pSearchCondition->getChild(2)->parseNodeToStr( aValue, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 1368 traverseOnePredicate(pSearchCondition->getChild(0),aValue,pSearchCondition->getChild(2)); 1369 impl_fillJoinConditions(pSearchCondition); 1370 // if (! aIteratorStatus.IsSuccessful()) 1371 // return; 1372 } 1373 else if (SQL_ISRULE(pSearchCondition,like_predicate) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/) 1374 { 1375 OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!"); 1376 const OSQLParseNode* pPart2 = pSearchCondition->getChild(1); 1377 1378 sal_Int32 nCurentPos = pPart2->count()-2; 1379 1380 OSQLParseNode * pNum_value_exp = pPart2->getChild(nCurentPos); 1381 OSQLParseNode * pOptEscape = pPart2->getChild(nCurentPos+1); 1382 1383 OSL_ENSURE(pNum_value_exp != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1384 OSL_ENSURE(pOptEscape != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1385 1386 if (pOptEscape->count() != 0) 1387 { 1388 // aIteratorStatus.setStatementTooComplex(); 1389 return; 1390 } 1391 1392 ::rtl::OUString aValue; 1393 OSQLParseNode * pParam = NULL; 1394 if (SQL_ISRULE(pNum_value_exp,parameter)) 1395 pParam = pNum_value_exp; 1396 else if(pNum_value_exp->isToken()) 1397 // Normaler Wert 1398 aValue = pNum_value_exp->getTokenValue(); 1399 else 1400 { 1401 pNum_value_exp->parseNodeToStr( aValue, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 1402 pParam = pNum_value_exp; 1403 } 1404 1405 traverseOnePredicate(pSearchCondition->getChild(0),aValue,pParam); 1406 // if (! aIteratorStatus.IsSuccessful()) 1407 // return; 1408 } 1409 else if (SQL_ISRULE(pSearchCondition,in_predicate)) 1410 { 1411 OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!"); 1412 const OSQLParseNode* pPart2 = pSearchCondition->getChild(1); 1413 1414 traverseORCriteria(pSearchCondition->getChild(0)); 1415 // if (! aIteratorStatus.IsSuccessful()) return; 1416 1417 OSQLParseNode* pChild = pPart2->getChild(2); 1418 if ( SQL_ISRULE(pChild->getChild(0),subquery) ) 1419 { 1420 traverseTableNames( *m_pImpl->m_pSubTables ); 1421 traverseSelectionCriteria(pChild->getChild(0)->getChild(1)); 1422 } 1423 else 1424 { // '(' value_exp_commalist ')' 1425 pChild = pChild->getChild(1); 1426 sal_Int32 nCount = pChild->count(); 1427 for (sal_Int32 i=0; i < nCount; ++i) 1428 { 1429 traverseANDCriteria(pChild->getChild(i)); 1430 } 1431 } 1432 } 1433 else if (SQL_ISRULE(pSearchCondition,test_for_null) /*&& SQL_ISRULE(pSearchCondition->getChild(0),column_ref)*/) 1434 { 1435 OSL_ENSURE(pSearchCondition->count() == 2,"OSQLParseTreeIterator: error in parse tree!"); 1436 const OSQLParseNode* pPart2 = pSearchCondition->getChild(1); 1437 (void)pPart2; 1438 OSL_ENSURE(SQL_ISTOKEN(pPart2->getChild(0),IS),"OSQLParseTreeIterator: error in parse tree!"); 1439 1440 ::rtl::OUString aString; 1441 traverseOnePredicate(pSearchCondition->getChild(0),aString,NULL); 1442 // if (! aIteratorStatus.IsSuccessful()) return; 1443 } 1444 else if (SQL_ISRULE(pSearchCondition,num_value_exp) || SQL_ISRULE(pSearchCondition,term)) 1445 { 1446 ::rtl::OUString aString; 1447 traverseOnePredicate(pSearchCondition->getChild(0),aString,pSearchCondition->getChild(0)); 1448 traverseOnePredicate(pSearchCondition->getChild(2),aString,pSearchCondition->getChild(2)); 1449 } 1450 // Fehler einfach weiterreichen. 1451 } 1452 //----------------------------------------------------------------------------- 1453 void OSQLParseTreeIterator::traverseParameter(const OSQLParseNode* _pParseNode 1454 ,const OSQLParseNode* _pParentNode 1455 ,const ::rtl::OUString& _aColumnName 1456 ,const ::rtl::OUString& _aTableRange 1457 ,const ::rtl::OUString& _rColumnAlias) 1458 { 1459 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseParameter" ); 1460 if ( !SQL_ISRULE( _pParseNode, parameter ) ) 1461 return; 1462 1463 if ( ( m_pImpl->m_nIncludeMask & Parameters ) != Parameters ) 1464 // parameters not to be included in the traversal 1465 return; 1466 1467 OSL_ENSURE(_pParseNode->count() > 0,"OSQLParseTreeIterator: error in parse tree!"); 1468 OSQLParseNode * pMark = _pParseNode->getChild(0); 1469 ::rtl::OUString sParameterName; 1470 1471 if (SQL_ISPUNCTUATION(pMark,"?")) 1472 { 1473 sParameterName = _rColumnAlias.getLength() 1474 ? _rColumnAlias 1475 : _aColumnName.getLength() 1476 ? _aColumnName 1477 : ::rtl::OUString::createFromAscii("?"); 1478 } 1479 else if (SQL_ISPUNCTUATION(pMark,":")) 1480 { 1481 sParameterName = _pParseNode->getChild(1)->getTokenValue(); 1482 } 1483 else if (SQL_ISPUNCTUATION(pMark,"[")) 1484 { 1485 sParameterName = _pParseNode->getChild(1)->getTokenValue(); 1486 } 1487 else 1488 { 1489 OSL_ASSERT("OSQLParseTreeIterator: error in parse tree!"); 1490 } 1491 1492 // found a parameter 1493 if ( _pParentNode && (SQL_ISRULE(_pParentNode,general_set_fct) || SQL_ISRULE(_pParentNode,set_fct_spec)) ) 1494 {// found a function as column_ref 1495 ::rtl::OUString sFunctionName; 1496 _pParentNode->getChild(0)->parseNodeToStr( sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 1497 const sal_uInt32 nCount = _pParentNode->count(); 1498 sal_uInt32 i = 0; 1499 for(; i < nCount;++i) 1500 { 1501 if ( _pParentNode->getChild(i) == _pParseNode ) 1502 break; 1503 } 1504 sal_Int32 nType = ::connectivity::OSQLParser::getFunctionParameterType( _pParentNode->getChild(0)->getTokenID(), i-1); 1505 1506 OParseColumn* pColumn = new OParseColumn( sParameterName, 1507 ::rtl::OUString(), 1508 ::rtl::OUString(), 1509 ::rtl::OUString(), 1510 ColumnValue::NULLABLE_UNKNOWN, 1511 0, 1512 0, 1513 nType, 1514 sal_False, 1515 sal_False, 1516 isCaseSensitive()); 1517 pColumn->setFunction(sal_True); 1518 pColumn->setAggregateFunction(sal_True); 1519 pColumn->setRealName(sFunctionName); 1520 m_aParameters->get().push_back(pColumn); 1521 } 1522 else 1523 { 1524 sal_Bool bNotFound = sal_True; 1525 OSQLColumns::Vector::const_iterator aIter = ::connectivity::find( 1526 m_aSelectColumns->get().begin(), 1527 m_aSelectColumns->get().end(), 1528 _aColumnName,::comphelper::UStringMixEqual( isCaseSensitive() ) 1529 ); 1530 if(aIter != m_aSelectColumns->get().end()) 1531 { 1532 OParseColumn* pNewColumn = new OParseColumn(*aIter,isCaseSensitive()); 1533 pNewColumn->setName(sParameterName); 1534 pNewColumn->setRealName(_aColumnName); 1535 m_aParameters->get().push_back(pNewColumn); 1536 bNotFound = sal_False; 1537 } 1538 else if(_aColumnName.getLength())// search in the tables for the right one 1539 { 1540 1541 Reference<XPropertySet> xColumn = findColumn( _aColumnName, _aTableRange, true ); 1542 1543 if ( xColumn.is() ) 1544 { 1545 OParseColumn* pNewColumn = new OParseColumn(xColumn,isCaseSensitive()); 1546 pNewColumn->setName(sParameterName); 1547 pNewColumn->setRealName(_aColumnName); 1548 m_aParameters->get().push_back(pNewColumn); 1549 bNotFound = sal_False; 1550 } 1551 } 1552 if ( bNotFound ) 1553 { 1554 sal_Int32 nType = DataType::VARCHAR; 1555 OSQLParseNode* pParent = _pParentNode ? _pParentNode->getParent() : NULL; 1556 if ( pParent && (SQL_ISRULE(pParent,general_set_fct) || SQL_ISRULE(pParent,set_fct_spec)) ) 1557 { 1558 const sal_uInt32 nCount = _pParentNode->count(); 1559 sal_uInt32 i = 0; 1560 for(; i < nCount;++i) 1561 { 1562 if ( _pParentNode->getChild(i) == _pParseNode ) 1563 break; 1564 } 1565 nType = ::connectivity::OSQLParser::getFunctionParameterType( pParent->getChild(0)->getTokenID(), i+1); 1566 } 1567 1568 ::rtl::OUString aNewColName( getUniqueColumnName( sParameterName ) ); 1569 1570 OParseColumn* pColumn = new OParseColumn(aNewColName, 1571 ::rtl::OUString(), 1572 ::rtl::OUString(), 1573 ::rtl::OUString(), 1574 ColumnValue::NULLABLE_UNKNOWN, 1575 0, 1576 0, 1577 nType, 1578 sal_False, 1579 sal_False, 1580 isCaseSensitive() ); 1581 pColumn->setName(aNewColName); 1582 pColumn->setRealName(sParameterName); 1583 m_aParameters->get().push_back(pColumn); 1584 } 1585 } 1586 } 1587 //----------------------------------------------------------------------------- 1588 void OSQLParseTreeIterator::traverseOnePredicate( 1589 OSQLParseNode * pColumnRef, 1590 ::rtl::OUString& rValue, 1591 OSQLParseNode * pParseNode) 1592 { 1593 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseOnePredicate" ); 1594 if ( !pParseNode ) 1595 return; 1596 1597 // Column-Name (und TableRange): 1598 ::rtl::OUString aColumnName, aTableRange, sColumnAlias; 1599 getColumnRange( pColumnRef, aColumnName, aTableRange, sColumnAlias); 1600 1601 ::rtl::OUString aName; 1602 1603 /*if (SQL_ISRULE(pParseNode,parameter)) 1604 traverseParameter( pParseNode, pColumnRef, aColumnName, aTableRange, sColumnAlias ); 1605 else */if (SQL_ISRULE(pParseNode,column_ref))// Column-Name (und TableRange): 1606 getColumnRange(pParseNode,aName,rValue); 1607 else 1608 { 1609 traverseORCriteria(pParseNode); 1610 // if (! aIteratorStatus.IsSuccessful()) return; 1611 } 1612 } 1613 1614 //----------------------------------------------------------------------------- 1615 void OSQLParseTreeIterator::traverseSome( sal_uInt32 _nIncludeMask ) 1616 { 1617 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseSome" ); 1618 impl_traverse( _nIncludeMask ); 1619 } 1620 1621 //----------------------------------------------------------------------------- 1622 void OSQLParseTreeIterator::traverseAll() 1623 { 1624 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::traverseAll" ); 1625 impl_traverse( All ); 1626 } 1627 1628 //----------------------------------------------------------------------------- 1629 void OSQLParseTreeIterator::impl_traverse( sal_uInt32 _nIncludeMask ) 1630 { 1631 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_traverse" ); 1632 impl_resetErrors(); 1633 m_pImpl->m_nIncludeMask = _nIncludeMask; 1634 1635 if ( !traverseTableNames( *m_pImpl->m_pTables ) ) 1636 return; 1637 1638 switch ( m_eStatementType ) 1639 { 1640 case SQL_STATEMENT_SELECT: 1641 { 1642 const OSQLParseNode* pSelectNode = m_pParseTree; 1643 traverseParameters( pSelectNode ); 1644 if ( !traverseSelectColumnNames( pSelectNode ) 1645 || !traverseOrderByColumnNames( pSelectNode ) 1646 || !traverseGroupByColumnNames( pSelectNode ) 1647 || !traverseSelectionCriteria( pSelectNode ) 1648 ) 1649 return; 1650 } 1651 break; 1652 case SQL_STATEMENT_CREATE_TABLE: 1653 { 1654 //0 | 1 | 2 |3| 4 |5 1655 //create table sc.foo ( a char(20), b char ) 1656 const OSQLParseNode* pCreateNode = m_pParseTree->getChild(4); 1657 traverseCreateColumns(pCreateNode); 1658 } 1659 break; 1660 case SQL_STATEMENT_INSERT: 1661 break; 1662 default: 1663 break; 1664 } 1665 } 1666 1667 // Dummy-Implementationen: 1668 1669 //----------------------------------------------------------------------------- 1670 OSQLTable OSQLParseTreeIterator::impl_createTableObject( const ::rtl::OUString& rTableName, 1671 const ::rtl::OUString& rCatalogName, const ::rtl::OUString& rSchemaName ) 1672 { 1673 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_createTableObject" ); 1674 OSL_PRECOND( m_eStatementType == SQL_STATEMENT_CREATE_TABLE, 1675 "OSQLParseTreeIterator::impl_createTableObject: only to be called for CREATE TABLE statements!" ); 1676 // (in all other cases, m_pTables is to contain the table objects as obtained from the tables 1677 // container of the connection (m_xTablesContainer) 1678 1679 OSQLTable aReturnTable = new OTable( 1680 NULL, 1681 sal_False, 1682 rTableName, 1683 ::rtl::OUString::createFromAscii("Table"), 1684 ::rtl::OUString::createFromAscii("New Created Table"), 1685 rSchemaName, 1686 rCatalogName 1687 ); 1688 return aReturnTable; 1689 } 1690 //----------------------------------------------------------------------------- 1691 void OSQLParseTreeIterator::appendColumns(::vos::ORef<OSQLColumns>& _rColumns,const ::rtl::OUString& _rTableAlias,const OSQLTable& _rTable) 1692 { 1693 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::appendColumns" ); 1694 1695 if (!_rTable.is()) 1696 return; 1697 1698 Reference<XNameAccess> xColumns = _rTable->getColumns(); 1699 if ( !xColumns.is() ) 1700 return; 1701 1702 Sequence< ::rtl::OUString > aColNames = xColumns->getElementNames(); 1703 const ::rtl::OUString* pBegin = aColNames.getConstArray(); 1704 const ::rtl::OUString* pEnd = pBegin + aColNames.getLength(); 1705 1706 for(;pBegin != pEnd;++pBegin) 1707 { 1708 1709 ::rtl::OUString aName(getUniqueColumnName(*pBegin)); 1710 Reference< XPropertySet > xColumn; 1711 if(xColumns->hasByName(*pBegin) && (xColumns->getByName(*pBegin) >>= xColumn) && xColumn.is()) 1712 { 1713 OParseColumn* pColumn = new OParseColumn(aName 1714 , getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPENAME))) 1715 , getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DEFAULTVALUE))) 1716 , getString(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_DESCRIPTION))) 1717 , getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISNULLABLE))) 1718 , getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_PRECISION))) 1719 , getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_SCALE))) 1720 , getINT32(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_TYPE))) 1721 , getBOOL(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISAUTOINCREMENT))) 1722 , getBOOL(xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex(PROPERTY_ID_ISCURRENCY))) 1723 , isCaseSensitive() ); 1724 1725 pColumn->setTableName(_rTableAlias); 1726 pColumn->setRealName(*pBegin); 1727 Reference< XPropertySet> xCol = pColumn; 1728 _rColumns->get().push_back(xCol); 1729 } 1730 else 1731 impl_appendError( IParseContext::ERROR_INVALID_COLUMN, pBegin, &_rTableAlias ); 1732 } 1733 } 1734 //----------------------------------------------------------------------------- 1735 void OSQLParseTreeIterator::setSelectColumnName(::vos::ORef<OSQLColumns>& _rColumns,const ::rtl::OUString & rColumnName,const ::rtl::OUString & rColumnAlias, const ::rtl::OUString & rTableRange,sal_Bool bFkt,sal_Int32 _nType,sal_Bool bAggFkt) 1736 { 1737 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setSelectColumnName" ); 1738 if(rColumnName.toChar() == '*' && !rTableRange.getLength()) 1739 { // SELECT * ... 1740 OSL_ENSURE(_rColumns == m_aSelectColumns,"Invalid columns used here!"); 1741 for(ConstOSQLTablesIterator aIter = m_pImpl->m_pTables->begin(); aIter != m_pImpl->m_pTables->end();++aIter) 1742 appendColumns(_rColumns,aIter->first,aIter->second); 1743 } 1744 else if( rColumnName.toChar() == '*' && rTableRange.getLength() ) 1745 { // SELECT <table>.* 1746 OSL_ENSURE(_rColumns == m_aSelectColumns,"Invalid columns used here!"); 1747 ConstOSQLTablesIterator aFind = m_pImpl->m_pTables->find(rTableRange); 1748 1749 if(aFind != m_pImpl->m_pTables->end()) 1750 appendColumns(_rColumns,rTableRange,aFind->second); 1751 } 1752 else if ( !rTableRange.getLength() ) 1753 { // SELECT <something> ... 1754 // without table specified 1755 if ( !bFkt ) 1756 { 1757 Reference< XPropertySet> xNewColumn; 1758 1759 for ( OSQLTablesIterator aIter = m_pImpl->m_pTables->begin(); aIter != m_pImpl->m_pTables->end(); ++aIter ) 1760 { 1761 if ( !aIter->second.is() ) 1762 continue; 1763 1764 Reference<XNameAccess> xColumns = aIter->second->getColumns(); 1765 Reference< XPropertySet > xColumn; 1766 if ( !xColumns->hasByName( rColumnName ) 1767 || !( xColumns->getByName( rColumnName ) >>= xColumn ) 1768 ) 1769 continue; 1770 1771 ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias)); 1772 1773 OParseColumn* pColumn = new OParseColumn(xColumn,isCaseSensitive()); 1774 xNewColumn = pColumn; 1775 pColumn->setTableName(aIter->first); 1776 pColumn->setName(aNewColName); 1777 pColumn->setRealName(rColumnName); 1778 1779 break; 1780 } 1781 1782 if ( !xNewColumn.is() ) 1783 { 1784 // no function (due to the above !bFkt), no existing column 1785 // => assume an expression 1786 ::rtl::OUString aNewColName( getUniqueColumnName( rColumnAlias ) ); 1787 // did not find a column with this name in any of the tables 1788 OParseColumn* pColumn = new OParseColumn( 1789 aNewColName, 1790 ::rtl::OUString::createFromAscii( "VARCHAR" ), 1791 // TODO: does this match with _nType? 1792 // Or should be fill this from the getTypeInfo of the connection? 1793 ::rtl::OUString(), 1794 ::rtl::OUString(), 1795 ColumnValue::NULLABLE_UNKNOWN, 1796 0, 1797 0, 1798 _nType, 1799 sal_False, 1800 sal_False, 1801 isCaseSensitive() 1802 ); 1803 1804 xNewColumn = pColumn; 1805 pColumn->setRealName( rColumnName ); 1806 } 1807 1808 _rColumns->get().push_back( xNewColumn ); 1809 } 1810 else 1811 { 1812 ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias)); 1813 1814 OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),::rtl::OUString(), 1815 ColumnValue::NULLABLE_UNKNOWN,0,0,_nType,sal_False,sal_False,isCaseSensitive()); 1816 pColumn->setFunction(sal_True); 1817 pColumn->setAggregateFunction(bAggFkt); 1818 pColumn->setRealName(rColumnName); 1819 1820 Reference< XPropertySet> xCol = pColumn; 1821 _rColumns->get().push_back(xCol); 1822 } 1823 } 1824 else // ColumnName und Tablename vorhanden 1825 { 1826 ConstOSQLTablesIterator aFind = m_pImpl->m_pTables->find(rTableRange); 1827 1828 sal_Bool bError = sal_False; 1829 if (aFind != m_pImpl->m_pTables->end() && aFind->second.is()) 1830 { 1831 if (bFkt) 1832 { 1833 ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias)); 1834 1835 OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),::rtl::OUString(), 1836 ColumnValue::NULLABLE_UNKNOWN,0,0,_nType,sal_False,sal_False,isCaseSensitive()); 1837 pColumn->setFunction(sal_True); 1838 pColumn->setAggregateFunction(bAggFkt); 1839 pColumn->setRealName(rColumnName); 1840 pColumn->setTableName(aFind->first); 1841 1842 Reference< XPropertySet> xCol = pColumn; 1843 _rColumns->get().push_back(xCol); 1844 } 1845 else 1846 { 1847 Reference< XPropertySet > xColumn; 1848 if (aFind->second->getColumns()->hasByName(rColumnName) && (aFind->second->getColumns()->getByName(rColumnName) >>= xColumn)) 1849 { 1850 ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias)); 1851 1852 OParseColumn* pColumn = new OParseColumn(xColumn,isCaseSensitive()); 1853 pColumn->setName(aNewColName); 1854 pColumn->setRealName(rColumnName); 1855 pColumn->setTableName(aFind->first); 1856 1857 Reference< XPropertySet> xCol = pColumn; 1858 _rColumns->get().push_back(xCol); 1859 } 1860 else 1861 bError = sal_True; 1862 } 1863 } 1864 else 1865 bError = sal_True; 1866 1867 // Tabelle existiert nicht oder Feld nicht vorhanden 1868 if (bError) 1869 { 1870 ::rtl::OUString aNewColName(getUniqueColumnName(rColumnAlias)); 1871 1872 OParseColumn* pColumn = new OParseColumn(aNewColName,::rtl::OUString(),::rtl::OUString(),::rtl::OUString(), 1873 ColumnValue::NULLABLE_UNKNOWN,0,0,DataType::VARCHAR,sal_False,sal_False,isCaseSensitive()); 1874 pColumn->setFunction(sal_True); 1875 pColumn->setAggregateFunction(bAggFkt); 1876 1877 Reference< XPropertySet> xCol = pColumn; 1878 _rColumns->get().push_back(xCol); 1879 } 1880 } 1881 } 1882 //----------------------------------------------------------------------------- 1883 ::rtl::OUString OSQLParseTreeIterator::getUniqueColumnName(const ::rtl::OUString & rColumnName) const 1884 { 1885 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getUniqueColumnName" ); 1886 ::rtl::OUString aAlias(rColumnName); 1887 1888 OSQLColumns::Vector::const_iterator aIter = find( 1889 m_aSelectColumns->get().begin(), 1890 m_aSelectColumns->get().end(), 1891 aAlias, 1892 ::comphelper::UStringMixEqual( isCaseSensitive() ) 1893 ); 1894 sal_Int32 i=1; 1895 while(aIter != m_aSelectColumns->get().end()) 1896 { 1897 (aAlias = rColumnName) += ::rtl::OUString::valueOf(i++); 1898 aIter = find( 1899 m_aSelectColumns->get().begin(), 1900 m_aSelectColumns->get().end(), 1901 aAlias, 1902 ::comphelper::UStringMixEqual( isCaseSensitive() ) 1903 ); 1904 } 1905 return aAlias; 1906 } 1907 //----------------------------------------------------------------------------- 1908 void OSQLParseTreeIterator::setOrderByColumnName(const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange,sal_Bool bAscending) 1909 { 1910 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setOrderByColumnName" ); 1911 Reference<XPropertySet> xColumn = findColumn( rColumnName, rTableRange, false ); 1912 if ( xColumn.is() ) 1913 m_aOrderColumns->get().push_back(new OOrderColumn( xColumn, rTableRange, isCaseSensitive(), bAscending ) ); 1914 else 1915 { 1916 sal_Int32 nId = rColumnName.toInt32(); 1917 if ( nId > 0 && nId < static_cast<sal_Int32>(m_aSelectColumns->get().size()) ) 1918 m_aOrderColumns->get().push_back( new OOrderColumn( ( m_aSelectColumns->get() )[nId-1], isCaseSensitive(), bAscending ) ); 1919 } 1920 1921 #ifdef SQL_TEST_PARSETREEITERATOR 1922 cout << "OSQLParseTreeIterator::setOrderByColumnName: " 1923 << (const char *) rColumnName << ", " 1924 << (const char *) rTableRange << ", " 1925 << (bAscending ? "sal_True" : "sal_False") 1926 << "\n"; 1927 #endif 1928 } 1929 //----------------------------------------------------------------------------- 1930 void OSQLParseTreeIterator::setGroupByColumnName(const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange) 1931 { 1932 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::setGroupByColumnName" ); 1933 Reference<XPropertySet> xColumn = findColumn( rColumnName, rTableRange, false ); 1934 if ( xColumn.is() ) 1935 m_aGroupColumns->get().push_back(new OParseColumn(xColumn,isCaseSensitive())); 1936 else 1937 { 1938 sal_Int32 nId = rColumnName.toInt32(); 1939 if ( nId > 0 && nId < static_cast<sal_Int32>(m_aSelectColumns->get().size()) ) 1940 m_aGroupColumns->get().push_back(new OParseColumn((m_aSelectColumns->get())[nId-1],isCaseSensitive())); 1941 } 1942 1943 #ifdef SQL_TEST_PARSETREEITERATOR 1944 cout << "OSQLParseTreeIterator::setOrderByColumnName: " 1945 << (const char *) rColumnName << ", " 1946 << (const char *) rTableRange << ", " 1947 << (bAscending ? "sal_True" : "sal_False") 1948 << "\n"; 1949 #endif 1950 } 1951 1952 //----------------------------------------------------------------------------- 1953 const OSQLParseNode* OSQLParseTreeIterator::getWhereTree() const 1954 { 1955 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getWhereTree" ); 1956 1957 1958 if (!m_pParseTree) 1959 return NULL; 1960 1961 // Parse Tree analysieren (je nach Statement-Typ) 1962 // und Zeiger auf WHERE-Klausel setzen: 1963 OSQLParseNode * pWhereClause = NULL; 1964 if(getStatementType() == SQL_STATEMENT_SELECT) 1965 { 1966 OSL_ENSURE(m_pParseTree->count() >= 4,"ParseTreeIterator: error in parse tree!"); 1967 OSQLParseNode * pTableExp = m_pParseTree->getChild(3); 1968 OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1969 OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!"); 1970 OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!"); 1971 1972 pWhereClause = pTableExp->getChild(1); 1973 } 1974 else if (SQL_ISRULE(m_pParseTree,update_statement_searched) || 1975 SQL_ISRULE(m_pParseTree,delete_statement_searched)) 1976 { 1977 pWhereClause = m_pParseTree->getChild(m_pParseTree->count()-1); 1978 } 1979 if(pWhereClause->count() != 2) 1980 pWhereClause = NULL; 1981 return pWhereClause; 1982 } 1983 1984 //----------------------------------------------------------------------------- 1985 const OSQLParseNode* OSQLParseTreeIterator::getOrderTree() const 1986 { 1987 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getOrderTree" ); 1988 1989 1990 if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT) 1991 return NULL; 1992 1993 // Parse Tree analysieren (je nach Statement-Typ) 1994 // und Zeiger auf ORDER-Klausel setzen: 1995 OSQLParseNode * pOrderClause = NULL; 1996 OSL_ENSURE(m_pParseTree->count() >= 4,"ParseTreeIterator: error in parse tree!"); 1997 OSQLParseNode * pTableExp = m_pParseTree->getChild(3); 1998 OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!"); 1999 OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!"); 2000 OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!"); 2001 2002 pOrderClause = pTableExp->getChild(ORDER_BY_CHILD_POS); 2003 // Wenn es aber eine order_by ist, dann darf sie nicht leer sein: 2004 if(pOrderClause->count() != 3) 2005 pOrderClause = NULL; 2006 return pOrderClause; 2007 } 2008 //----------------------------------------------------------------------------- 2009 const OSQLParseNode* OSQLParseTreeIterator::getGroupByTree() const 2010 { 2011 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getGroupByTree" ); 2012 if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT) 2013 return NULL; 2014 2015 // Parse Tree analysieren (je nach Statement-Typ) 2016 // und Zeiger auf ORDER-Klausel setzen: 2017 OSQLParseNode * pGroupClause = NULL; 2018 OSL_ENSURE(m_pParseTree->count() >= 4,"ParseTreeIterator: error in parse tree!"); 2019 OSQLParseNode * pTableExp = m_pParseTree->getChild(3); 2020 OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!"); 2021 OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!"); 2022 OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!"); 2023 2024 pGroupClause = pTableExp->getChild(2); 2025 // Wenn es aber eine order_by ist, dann darf sie nicht leer sein: 2026 if(pGroupClause->count() != 3) 2027 pGroupClause = NULL; 2028 return pGroupClause; 2029 } 2030 //----------------------------------------------------------------------------- 2031 const OSQLParseNode* OSQLParseTreeIterator::getHavingTree() const 2032 { 2033 if (!m_pParseTree || getStatementType() != SQL_STATEMENT_SELECT) 2034 return NULL; 2035 2036 // Parse Tree analysieren (je nach Statement-Typ) 2037 // und Zeiger auf ORDER-Klausel setzen: 2038 OSQLParseNode * pHavingClause = NULL; 2039 OSL_ENSURE(m_pParseTree->count() >= 4,"ParseTreeIterator: error in parse tree!"); 2040 OSQLParseNode * pTableExp = m_pParseTree->getChild(3); 2041 OSL_ENSURE(pTableExp != NULL,"OSQLParseTreeIterator: error in parse tree!"); 2042 OSL_ENSURE(SQL_ISRULE(pTableExp,table_exp),"OSQLParseTreeIterator: error in parse tree!"); 2043 OSL_ENSURE(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"OSQLParseTreeIterator: error in parse tree!"); 2044 2045 pHavingClause = pTableExp->getChild(3); 2046 // Wenn es aber eine order_by ist, dann darf sie nicht leer sein: 2047 if(pHavingClause->count() < 1) 2048 pHavingClause = NULL; 2049 return pHavingClause; 2050 } 2051 // ----------------------------------------------------------------------------- 2052 sal_Bool OSQLParseTreeIterator::isTableNode(const OSQLParseNode* _pTableNode) const 2053 { 2054 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::isTableNode" ); 2055 return _pTableNode && (SQL_ISRULE(_pTableNode,catalog_name) || 2056 SQL_ISRULE(_pTableNode,schema_name) || 2057 SQL_ISRULE(_pTableNode,table_name)); 2058 } 2059 // ----------------------------------------------------------------------------- 2060 const OSQLParseNode* OSQLParseTreeIterator::getSimpleWhereTree() const 2061 { 2062 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleWhereTree" ); 2063 const OSQLParseNode* pNode = getWhereTree(); 2064 return pNode ? pNode->getChild(1) : NULL; 2065 } 2066 // ----------------------------------------------------------------------------- 2067 const OSQLParseNode* OSQLParseTreeIterator::getSimpleOrderTree() const 2068 { 2069 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleOrderTree" ); 2070 const OSQLParseNode* pNode = getOrderTree(); 2071 return pNode ? pNode->getChild(2) : NULL; 2072 } 2073 // ----------------------------------------------------------------------------- 2074 const OSQLParseNode* OSQLParseTreeIterator::getSimpleGroupByTree() const 2075 { 2076 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleGroupByTree" ); 2077 const OSQLParseNode* pNode = getGroupByTree(); 2078 return pNode ? pNode->getChild(2) : NULL; 2079 } 2080 // ----------------------------------------------------------------------------- 2081 const OSQLParseNode* OSQLParseTreeIterator::getSimpleHavingTree() const 2082 { 2083 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::getSimpleHavingTree" ); 2084 const OSQLParseNode* pNode = getHavingTree(); 2085 return pNode ? pNode->getChild(1) : NULL; 2086 } 2087 2088 // ----------------------------------------------------------------------------- 2089 Reference< XPropertySet > OSQLParseTreeIterator::findColumn( const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange, bool _bLookInSubTables ) 2090 { 2091 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::findColumn" ); 2092 Reference< XPropertySet > xColumn = findColumn( *m_pImpl->m_pTables, rColumnName, rTableRange ); 2093 if ( !xColumn.is() && _bLookInSubTables ) 2094 xColumn = findColumn( *m_pImpl->m_pSubTables, rColumnName, rTableRange ); 2095 return xColumn; 2096 } 2097 2098 // ----------------------------------------------------------------------------- 2099 Reference< XPropertySet > OSQLParseTreeIterator::findColumn(const OSQLTables& _rTables,const ::rtl::OUString & rColumnName, const ::rtl::OUString & rTableRange) 2100 { 2101 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::findColumn" ); 2102 Reference< XPropertySet > xColumn; 2103 if ( rTableRange.getLength() ) 2104 { 2105 ConstOSQLTablesIterator aFind = _rTables.find(rTableRange); 2106 2107 if ( aFind != _rTables.end() 2108 && aFind->second.is() 2109 && aFind->second->getColumns().is() 2110 && aFind->second->getColumns()->hasByName(rColumnName) ) 2111 aFind->second->getColumns()->getByName(rColumnName) >>= xColumn; 2112 } 2113 if ( !xColumn.is() ) 2114 { 2115 OSQLTables::const_iterator aEnd = _rTables.end(); 2116 for(OSQLTables::const_iterator aIter = _rTables.begin(); aIter != aEnd; ++aIter) 2117 { 2118 if ( aIter->second.is() ) 2119 { 2120 Reference<XNameAccess> xColumns = aIter->second->getColumns(); 2121 if( xColumns.is() && xColumns->hasByName(rColumnName) && (xColumns->getByName(rColumnName) >>= xColumn) ) 2122 { 2123 OSL_ENSURE(xColumn.is(),"Column isn't a propertyset!"); 2124 break; // diese Column darf nur einmal vorkommen 2125 } 2126 } 2127 } 2128 } 2129 return xColumn; 2130 } 2131 2132 // ----------------------------------------------------------------------------- 2133 void OSQLParseTreeIterator::impl_appendError( IParseContext::ErrorCode _eError, const ::rtl::OUString* _pReplaceToken1, const ::rtl::OUString* _pReplaceToken2 ) 2134 { 2135 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_appendError" ); 2136 ::rtl::OUString sErrorMessage = m_rParser.getContext().getErrorMessage( _eError ); 2137 if ( _pReplaceToken1 ) 2138 { 2139 bool bTwoTokens = ( _pReplaceToken2 != NULL ); 2140 const sal_Char* pPlaceHolder1 = bTwoTokens ? "#1" : "#"; 2141 const ::rtl::OUString sPlaceHolder1 = ::rtl::OUString::createFromAscii( pPlaceHolder1 ); 2142 2143 sErrorMessage = sErrorMessage.replaceAt( sErrorMessage.indexOf( sPlaceHolder1 ), sPlaceHolder1.getLength(), *_pReplaceToken1 ); 2144 if ( _pReplaceToken2 ) 2145 sErrorMessage = sErrorMessage.replaceAt( sErrorMessage.indexOf( ::rtl::OUString::createFromAscii( "#2" ) ), 2, *_pReplaceToken2 ); 2146 } 2147 2148 impl_appendError( SQLException( 2149 sErrorMessage, NULL, getStandardSQLState( SQL_GENERAL_ERROR ), 1000, Any() ) ); 2150 } 2151 2152 // ----------------------------------------------------------------------------- 2153 void OSQLParseTreeIterator::impl_appendError( const SQLException& _rError ) 2154 { 2155 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "parse", "Ocke.Janssen@sun.com", "OSQLParseTreeIterator::impl_appendError" ); 2156 if ( m_aErrors.Message.getLength() ) 2157 { 2158 SQLException* pErrorChain = &m_aErrors; 2159 while ( pErrorChain->NextException.hasValue() ) 2160 pErrorChain = static_cast< SQLException* >( pErrorChain->NextException.pData ); 2161 pErrorChain->NextException <<= _rError; 2162 } 2163 else 2164 m_aErrors = _rError; 2165 } 2166 // ----------------------------------------------------------------------------- 2167 sal_Int32 OSQLParseTreeIterator::getFunctionReturnType(const OSQLParseNode* _pNode ) 2168 { 2169 sal_Int32 nType = DataType::OTHER; 2170 ::rtl::OUString sFunctionName; 2171 if ( SQL_ISRULE(_pNode,length_exp) ) 2172 { 2173 _pNode->getChild(0)->getChild(0)->parseNodeToStr(sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 2174 nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() ); 2175 } 2176 else if ( SQL_ISRULE(_pNode,num_value_exp) || SQL_ISRULE(_pNode,term) || SQL_ISRULE(_pNode,factor) ) 2177 { 2178 nType = DataType::DOUBLE; 2179 } 2180 else 2181 { 2182 _pNode->getChild(0)->parseNodeToStr(sFunctionName, m_pImpl->m_xConnection, NULL, sal_False, sal_False ); 2183 2184 // MIN and MAX have another return type, we have to check the expression itself. 2185 // @see http://qa.openoffice.org/issues/show_bug.cgi?id=99566 2186 if ( SQL_ISRULE(_pNode,general_set_fct) && (SQL_ISTOKEN(_pNode->getChild(0),MIN) || SQL_ISTOKEN(_pNode->getChild(0),MAX) )) 2187 { 2188 const OSQLParseNode* pValueExp = _pNode->getChild(3); 2189 if (SQL_ISRULE(pValueExp,column_ref)) 2190 { 2191 ::rtl::OUString sColumnName; 2192 ::rtl::OUString aTableRange; 2193 getColumnRange(pValueExp,sColumnName,aTableRange); 2194 OSL_ENSURE(sColumnName.getLength(),"Columnname darf nicht leer sein"); 2195 Reference<XPropertySet> xColumn = findColumn( sColumnName, aTableRange, true ); 2196 2197 if ( xColumn.is() ) 2198 { 2199 xColumn->getPropertyValue(OMetaConnection::getPropMap().getNameByIndex( PROPERTY_ID_TYPE)) >>= nType; 2200 } 2201 } 2202 else 2203 { 2204 if ( SQL_ISRULE(pValueExp,num_value_exp) || SQL_ISRULE(pValueExp,term) || SQL_ISRULE(pValueExp,factor) ) 2205 { 2206 nType = DataType::DOUBLE; 2207 } 2208 else if ( SQL_ISRULE(pValueExp,datetime_primary) ) 2209 { 2210 switch(pValueExp->getChild(0)->getTokenID() ) 2211 { 2212 case SQL_TOKEN_CURRENT_DATE: 2213 nType = DataType::DATE; 2214 break; 2215 case SQL_TOKEN_CURRENT_TIME: 2216 nType = DataType::TIME; 2217 break; 2218 case SQL_TOKEN_CURRENT_TIMESTAMP: 2219 nType = DataType::TIMESTAMP; 2220 break; 2221 } 2222 } 2223 else if ( SQL_ISRULE(pValueExp,value_exp_primary) ) 2224 { 2225 nType = getFunctionReturnType(pValueExp->getChild(1)); 2226 } 2227 else if ( SQL_ISRULE(pValueExp,concatenation) 2228 || SQL_ISRULE(pValueExp,char_factor) 2229 || SQL_ISRULE(pValueExp,bit_value_fct) 2230 || SQL_ISRULE(pValueExp,char_value_fct) 2231 || SQL_ISRULE(pValueExp,char_substring_fct) 2232 || SQL_ISRULE(pValueExp,fold) 2233 || SQL_ISTOKEN(pValueExp,STRING) ) 2234 { 2235 nType = DataType::VARCHAR; 2236 } 2237 } 2238 if ( nType == DataType::OTHER ) 2239 nType = DataType::DOUBLE; 2240 } 2241 else 2242 nType = ::connectivity::OSQLParser::getFunctionReturnType( sFunctionName, &m_rParser.getContext() ); 2243 } 2244 2245 return nType; 2246 } 2247 2248