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