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 "file/fcomp.hxx" 31 #include <tools/debug.hxx> 32 #include "TConnection.hxx" 33 #include "connectivity/sqlparse.hxx" 34 #include "file/fanalyzer.hxx" 35 #include <com/sun/star/sdbc/XColumnLocate.hpp> 36 #include <com/sun/star/util/DateTime.hpp> 37 #include <com/sun/star/util/Date.hpp> 38 #include <com/sun/star/util/Time.hpp> 39 #include "connectivity/dbexception.hxx" 40 #include "connectivity/dbconversion.hxx" 41 #include <com/sun/star/sdb/SQLFilterOperator.hpp> 42 #include "resource/file_res.hrc" 43 #include "file/FStringFunctions.hxx" 44 #include "file/FDateFunctions.hxx" 45 #include "file/FNumericFunctions.hxx" 46 #include "file/FConnection.hxx" 47 #include <com/sun/star/sdb/SQLFilterOperator.hpp> 48 49 using namespace connectivity; 50 using namespace connectivity::file; 51 using namespace com::sun::star::uno; 52 using namespace com::sun::star::sdbc; 53 using namespace com::sun::star::sdb; 54 using namespace ::com::sun::star::container; 55 using namespace ::com::sun::star::util; 56 57 DBG_NAME(OPredicateCompiler) 58 //------------------------------------------------------------------ 59 OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer* pAnalyzer)//,OCursor& rCurs) 60 // : m_rCursor(rCurs) 61 : m_pAnalyzer(pAnalyzer) 62 , m_nParamCounter(0) 63 , m_bORCondition(sal_False) 64 { 65 DBG_CTOR(OPredicateCompiler,NULL); 66 } 67 68 //------------------------------------------------------------------ 69 OPredicateCompiler::~OPredicateCompiler() 70 { 71 Clean(); 72 DBG_DTOR(OPredicateCompiler,NULL); 73 } 74 // ----------------------------------------------------------------------------- 75 void OPredicateCompiler::dispose() 76 { 77 Clean(); 78 m_orgColumns = NULL; 79 m_xIndexes.clear(); 80 } 81 //------------------------------------------------------------------ 82 // inline OCursor& OPredicateCompiler::Cursor() const {return m_rCursor;} 83 //------------------------------------------------------------------ 84 void OPredicateCompiler::start(OSQLParseNode* pSQLParseNode) 85 { 86 if (!pSQLParseNode) 87 return; 88 89 m_nParamCounter = 0; 90 // Parse Tree analysieren (je nach Statement-Typ) 91 // und Zeiger auf WHERE-Klausel setzen: 92 OSQLParseNode * pWhereClause = NULL; 93 OSQLParseNode * pOrderbyClause = NULL; 94 95 if (SQL_ISRULE(pSQLParseNode,select_statement)) 96 { 97 DBG_ASSERT(pSQLParseNode->count() >= 4,"OFILECursor: Fehler im Parse Tree"); 98 99 OSQLParseNode * pTableExp = pSQLParseNode->getChild(3); 100 DBG_ASSERT(pTableExp != NULL,"Fehler im Parse Tree"); 101 DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp)," Fehler im Parse Tree"); 102 DBG_ASSERT(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"Fehler im Parse Tree"); 103 104 // check that we don't use anything other than count(*) as function 105 OSQLParseNode* pSelection = pSQLParseNode->getChild(2); 106 if ( SQL_ISRULE(pSelection,scalar_exp_commalist) ) 107 { 108 for (sal_uInt32 i = 0; i < pSelection->count(); i++) 109 { 110 OSQLParseNode *pColumnRef = pSelection->getChild(i)->getChild(0); 111 if ( SQL_ISRULE(pColumnRef,general_set_fct) && pColumnRef->count() != 4 ) 112 { 113 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT,NULL); 114 } 115 } 116 } 117 118 119 pWhereClause = pTableExp->getChild(1); 120 pOrderbyClause = pTableExp->getChild(ORDER_BY_CHILD_POS); 121 } 122 else if (SQL_ISRULE(pSQLParseNode,update_statement_searched)) 123 { 124 DBG_ASSERT(pSQLParseNode->count() == 5,"OFILECursor: Fehler im Parse Tree"); 125 pWhereClause = pSQLParseNode->getChild(4); 126 } 127 else if (SQL_ISRULE(pSQLParseNode,delete_statement_searched)) 128 { 129 DBG_ASSERT(pSQLParseNode->count() == 4,"Fehler im Parse Tree"); 130 pWhereClause = pSQLParseNode->getChild(3); 131 } 132 else 133 // Anderes Statement. Keine Selektionskriterien. 134 return; 135 136 if (SQL_ISRULE(pWhereClause,where_clause)) 137 { 138 // Wenn es aber eine where_clause ist, dann darf sie nicht leer sein: 139 DBG_ASSERT(pWhereClause->count() == 2,"OFILECursor: Fehler im Parse Tree"); 140 141 OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1); 142 DBG_ASSERT(pComparisonPredicate != NULL,"OFILECursor: Fehler im Parse Tree"); 143 144 execute( pComparisonPredicate ); 145 } 146 else 147 { 148 // Die Where Clause ist meistens optional, d. h. es koennte sich auch 149 // um "optional_where_clause" handeln. 150 DBG_ASSERT(SQL_ISRULE(pWhereClause,opt_where_clause),"OPredicateCompiler: Fehler im Parse Tree"); 151 } 152 } 153 154 //------------------------------------------------------------------ 155 OOperand* OPredicateCompiler::execute(OSQLParseNode* pPredicateNode) 156 { 157 OOperand* pOperand = NULL; 158 if (pPredicateNode->count() == 3 && // Ausdruck is geklammert 159 SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"(") && 160 SQL_ISPUNCTUATION(pPredicateNode->getChild(2),")")) 161 { 162 execute(pPredicateNode->getChild(1)); 163 } 164 else if ((SQL_ISRULE(pPredicateNode,search_condition) || (SQL_ISRULE(pPredicateNode,boolean_term))) 165 && // AND/OR-Verknuepfung: 166 pPredicateNode->count() == 3) 167 { 168 execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs 169 execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs 170 171 if (SQL_ISTOKEN(pPredicateNode->getChild(1),OR)) // OR-Operator 172 { 173 m_aCodeList.push_back(new OOp_OR()); 174 m_bORCondition = sal_True; 175 } 176 else if (SQL_ISTOKEN(pPredicateNode->getChild(1),AND)) // AND-Operator 177 m_aCodeList.push_back(new OOp_AND()); 178 else 179 { 180 DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree"); 181 } 182 } 183 else if (SQL_ISRULE(pPredicateNode,boolean_factor)) 184 { 185 execute(pPredicateNode->getChild(1)); 186 m_aCodeList.push_back(new OOp_NOT()); 187 } 188 else if (SQL_ISRULE(pPredicateNode,comparison_predicate)) 189 { 190 execute_COMPARE(pPredicateNode); 191 } 192 else if (SQL_ISRULE(pPredicateNode,like_predicate)) 193 { 194 execute_LIKE(pPredicateNode); 195 } 196 else if (SQL_ISRULE(pPredicateNode,between_predicate)) 197 { 198 execute_BETWEEN(pPredicateNode); 199 } 200 else if (SQL_ISRULE(pPredicateNode,test_for_null)) 201 { 202 execute_ISNULL(pPredicateNode); 203 } 204 else if(SQL_ISRULE(pPredicateNode,num_value_exp)) 205 { 206 execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs 207 execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs 208 if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"+")) 209 { 210 m_aCodeList.push_back(new OOp_ADD()); 211 } 212 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"-")) 213 m_aCodeList.push_back(new OOp_SUB()); 214 else 215 { 216 DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree num_value_exp"); 217 } 218 } 219 else if(SQL_ISRULE(pPredicateNode,term)) 220 { 221 execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs 222 execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs 223 if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"*")) 224 { 225 m_aCodeList.push_back(new OOp_MUL()); 226 } 227 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"/")) 228 m_aCodeList.push_back(new OOp_DIV()); 229 else 230 { 231 DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree num_value_exp"); 232 } 233 } 234 else 235 pOperand = execute_Operand(pPredicateNode); // jetzt werden nur einfache Operanden verarbeitet 236 237 return pOperand; 238 } 239 240 //------------------------------------------------------------------ 241 OOperand* OPredicateCompiler::execute_COMPARE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) 242 { 243 DBG_ASSERT(pPredicateNode->count() == 3,"OFILECursor: Fehler im Parse Tree"); 244 245 if ( !(SQL_ISRULE(pPredicateNode->getChild(0),column_ref) || 246 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_STRING || 247 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_INTNUM || 248 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_APPROXNUM || 249 SQL_ISTOKEN(pPredicateNode->getChild(2),TRUE) || 250 SQL_ISTOKEN(pPredicateNode->getChild(2),FALSE) || 251 SQL_ISRULE(pPredicateNode->getChild(2),parameter) || 252 // odbc date 253 SQL_ISRULE(pPredicateNode->getChild(2),set_fct_spec) || 254 SQL_ISRULE(pPredicateNode->getChild(2),position_exp) || 255 SQL_ISRULE(pPredicateNode->getChild(2),char_substring_fct) || 256 // upper, lower etc. 257 SQL_ISRULE(pPredicateNode->getChild(2),fold)) ) 258 { 259 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL); 260 return NULL; 261 } 262 263 sal_Int32 ePredicateType( SQLFilterOperator::EQUAL ); 264 OSQLParseNode *pPrec = pPredicateNode->getChild(1); 265 266 if (pPrec->getNodeType() == SQL_NODE_EQUAL) 267 ePredicateType = SQLFilterOperator::EQUAL; 268 else if (pPrec->getNodeType() == SQL_NODE_NOTEQUAL) 269 ePredicateType = SQLFilterOperator::NOT_EQUAL; 270 else if (pPrec->getNodeType() == SQL_NODE_LESS) 271 ePredicateType = SQLFilterOperator::LESS; 272 else if (pPrec->getNodeType() == SQL_NODE_LESSEQ) 273 ePredicateType = SQLFilterOperator::LESS_EQUAL; 274 else if (pPrec->getNodeType() == SQL_NODE_GREATEQ) 275 ePredicateType = SQLFilterOperator::GREATER_EQUAL; 276 else if (pPrec->getNodeType() == SQL_NODE_GREAT) 277 ePredicateType = SQLFilterOperator::GREATER; 278 else 279 OSL_ENSURE( false, "OPredicateCompiler::execute_COMPARE: unexpected node type!" ); 280 281 execute(pPredicateNode->getChild(0)); 282 execute(pPredicateNode->getChild(2)); 283 m_aCodeList.push_back( new OOp_COMPARE(ePredicateType) ); 284 285 return NULL; 286 } 287 288 //------------------------------------------------------------------ 289 OOperand* OPredicateCompiler::execute_LIKE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) 290 { 291 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree"); 292 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1); 293 294 sal_Unicode cEscape = L'\0'; 295 const bool bNotLike = pPart2->getChild(0)->isToken(); 296 297 OSQLParseNode* pAtom = pPart2->getChild(pPart2->count()-2); 298 OSQLParseNode* pOptEscape = pPart2->getChild(pPart2->count()-1); 299 300 if (!(pAtom->getNodeType() == SQL_NODE_STRING || 301 SQL_ISRULE(pAtom,parameter) || 302 // odbc date 303 SQL_ISRULE(pAtom,set_fct_spec) || 304 SQL_ISRULE(pAtom,position_exp) || 305 SQL_ISRULE(pAtom,char_substring_fct) || 306 // upper, lower etc. 307 SQL_ISRULE(pAtom,fold)) ) 308 { 309 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL); 310 return NULL; 311 } 312 313 if (pOptEscape->count() != 0) 314 { 315 if (pOptEscape->count() != 2) 316 { 317 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,NULL); 318 } 319 OSQLParseNode *pEscNode = pOptEscape->getChild(1); 320 if (pEscNode->getNodeType() != SQL_NODE_STRING) 321 { 322 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,NULL); 323 } 324 else 325 cEscape = pEscNode->getTokenValue().toChar(); 326 } 327 328 execute(pPredicateNode->getChild(0)); 329 execute(pAtom); 330 331 OBoolOperator* pOperator = bNotLike 332 ? new OOp_NOTLIKE(cEscape) 333 : new OOp_LIKE(cEscape); 334 m_aCodeList.push_back(pOperator); 335 336 return NULL; 337 } 338 //------------------------------------------------------------------ 339 OOperand* OPredicateCompiler::execute_BETWEEN(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) 340 { 341 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree"); 342 343 OSQLParseNode* pColumn = pPredicateNode->getChild(0); 344 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1); 345 OSQLParseNode* p1stValue = pPart2->getChild(2); 346 OSQLParseNode* p2ndtValue = pPart2->getChild(4); 347 348 if ( 349 !(p1stValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p1stValue,parameter)) 350 && !(p2ndtValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p2ndtValue,parameter)) 351 ) 352 { 353 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN,NULL); 354 } 355 356 sal_Bool bNot = SQL_ISTOKEN(pPart2->getChild(0),NOT); 357 358 OOperand* pColumnOp = execute(pColumn); 359 OOperand* pOb1 = execute(p1stValue); 360 OBoolOperator* pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::LESS_EQUAL : SQLFilterOperator::GREATER); 361 m_aCodeList.push_back(pOperator); 362 363 execute(pColumn); 364 OOperand* pOb2 = execute(p2ndtValue); 365 pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::GREATER_EQUAL : SQLFilterOperator::LESS); 366 m_aCodeList.push_back(pOperator); 367 368 if ( pColumnOp && pOb1 && pOb2 ) 369 { 370 switch(pColumnOp->getDBType()) 371 { 372 case DataType::CHAR: 373 case DataType::VARCHAR: 374 case DataType::LONGVARCHAR: 375 pOb1->setValue(pOb1->getValue().getString()); 376 pOb2->setValue(pOb2->getValue().getString()); 377 break; 378 case DataType::DECIMAL: 379 case DataType::NUMERIC: 380 pOb1->setValue((double)pOb1->getValue()); 381 pOb2->setValue((double)pOb2->getValue()); 382 break; 383 case DataType::FLOAT: 384 pOb1->setValue((float)pOb1->getValue()); 385 pOb2->setValue((float)pOb2->getValue()); 386 break; 387 case DataType::DOUBLE: 388 case DataType::REAL: 389 pOb1->setValue((double)pOb1->getValue()); 390 pOb2->setValue((double)pOb2->getValue()); 391 break; 392 case DataType::DATE: 393 pOb1->setValue((Date)pOb1->getValue()); 394 pOb2->setValue((Date)pOb2->getValue()); 395 break; 396 case DataType::TIME: 397 pOb1->setValue((Time)pOb1->getValue()); 398 pOb2->setValue((Time)pOb2->getValue()); 399 break; 400 case DataType::TIMESTAMP: 401 pOb1->setValue((DateTime)pOb1->getValue()); 402 pOb2->setValue((DateTime)pOb2->getValue()); 403 break; 404 } 405 } 406 407 408 409 OBoolOperator* pBoolOp = NULL; 410 if ( bNot ) 411 pBoolOp = new OOp_OR(); 412 else 413 pBoolOp = new OOp_AND(); 414 m_aCodeList.push_back(pBoolOp); 415 416 return NULL; 417 } 418 //------------------------------------------------------------------ 419 OOperand* OPredicateCompiler::execute_ISNULL(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) 420 { 421 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree"); 422 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1); 423 DBG_ASSERT(SQL_ISTOKEN(pPart2->getChild(0),IS),"OFILECursor: Fehler im Parse Tree"); 424 425 sal_Int32 ePredicateType; 426 if (SQL_ISTOKEN(pPart2->getChild(1),NOT)) 427 ePredicateType = SQLFilterOperator::NOT_SQLNULL; 428 else 429 ePredicateType = SQLFilterOperator::SQLNULL; 430 431 execute(pPredicateNode->getChild(0)); 432 OBoolOperator* pOperator = (ePredicateType == SQLFilterOperator::SQLNULL) ? 433 new OOp_ISNULL() : new OOp_ISNOTNULL(); 434 m_aCodeList.push_back(pOperator); 435 436 return NULL; 437 } 438 //------------------------------------------------------------------ 439 OOperand* OPredicateCompiler::execute_Operand(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) 440 { 441 OOperand* pOperand = NULL; 442 443 if (SQL_ISRULE(pPredicateNode,column_ref)) 444 { 445 ::rtl::OUString aColumnName; 446 if (pPredicateNode->count() == 1) 447 { 448 aColumnName = pPredicateNode->getChild(0)->getTokenValue(); 449 } 450 else if (pPredicateNode->count() == 3) 451 { 452 ::rtl::OUString aTableName = pPredicateNode->getChild(0)->getTokenValue(); 453 if(SQL_ISRULE(pPredicateNode->getChild(2),column_val)) 454 aColumnName = pPredicateNode->getChild(2)->getChild(0)->getTokenValue(); 455 else 456 aColumnName = pPredicateNode->getChild(2)->getTokenValue(); 457 } 458 459 if(!m_orgColumns->hasByName(aColumnName)) 460 { 461 const ::rtl::OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution( 462 STR_INVALID_COLUMNNAME, 463 "$columnname$", aColumnName 464 ) ); 465 ::dbtools::throwGenericSQLException( sError, NULL ); 466 } 467 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xCol; 468 try 469 { 470 if (m_orgColumns->getByName(aColumnName) >>= xCol) 471 { 472 pOperand = m_pAnalyzer->createOperandAttr(Reference< XColumnLocate>(m_orgColumns,UNO_QUERY)->findColumn(aColumnName),xCol,m_xIndexes); 473 } 474 else 475 {// Column existiert nicht im Resultset 476 const ::rtl::OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution( 477 STR_INVALID_COLUMNNAME, 478 "$columnname$", aColumnName 479 ) ); 480 ::dbtools::throwGenericSQLException( sError, NULL ); 481 } 482 } 483 catch(Exception &) 484 { 485 OSL_ENSURE(0,"OPredicateCompiler::execute_Operand Exception"); 486 } 487 } 488 else if (SQL_ISRULE(pPredicateNode,parameter)) 489 { 490 pOperand = new OOperandParam(pPredicateNode, ++m_nParamCounter); 491 } 492 else if (pPredicateNode->getNodeType() == SQL_NODE_STRING || 493 pPredicateNode->getNodeType() == SQL_NODE_INTNUM || 494 pPredicateNode->getNodeType() == SQL_NODE_APPROXNUM || 495 pPredicateNode->getNodeType() == SQL_NODE_NAME || 496 SQL_ISTOKEN(pPredicateNode,TRUE) || 497 SQL_ISTOKEN(pPredicateNode,FALSE) || 498 SQL_ISRULE(pPredicateNode,parameter)) 499 { 500 pOperand = new OOperandConst(*pPredicateNode, pPredicateNode->getTokenValue()); 501 } 502 else if((pPredicateNode->count() == 2) && 503 (SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"-")) && 504 pPredicateNode->getChild(1)->getNodeType() == SQL_NODE_INTNUM) 505 { // falls -1 bzw. +1 vorhanden ist 506 ::rtl::OUString aValue(pPredicateNode->getChild(0)->getTokenValue()); 507 aValue += pPredicateNode->getChild(1)->getTokenValue(); 508 pOperand = new OOperandConst(*pPredicateNode->getChild(1), aValue); 509 } 510 else if( SQL_ISRULE(pPredicateNode,set_fct_spec) && SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"{") ) 511 { 512 const OSQLParseNode* pODBCNode = pPredicateNode->getChild(1); 513 const OSQLParseNode* pODBCNodeChild = pODBCNode->getChild(0); 514 515 // Odbc Date or time 516 if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && ( 517 SQL_ISTOKEN(pODBCNodeChild,D) || 518 SQL_ISTOKEN(pODBCNodeChild,T) || 519 SQL_ISTOKEN(pODBCNodeChild,TS) )) 520 { 521 ::rtl::OUString sDateTime = pODBCNode->getChild(1)->getTokenValue(); 522 pOperand = new OOperandConst(*pODBCNode->getChild(1), sDateTime); 523 if(SQL_ISTOKEN(pODBCNodeChild,D)) 524 { 525 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime))); 526 } 527 else if(SQL_ISTOKEN(pODBCNodeChild,T)) 528 { 529 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime))); 530 } 531 else if(SQL_ISTOKEN(pODBCNodeChild,TS)) 532 { 533 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime))); 534 } 535 } 536 else 537 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL); 538 539 } 540 else if( SQL_ISRULE(pPredicateNode,fold) ) 541 { 542 execute_Fold(pPredicateNode); 543 } 544 else if( SQL_ISRULE(pPredicateNode,set_fct_spec) 545 || SQL_ISRULE(pPredicateNode,position_exp) 546 || SQL_ISRULE(pPredicateNode,char_substring_fct) 547 ) 548 { 549 executeFunction(pPredicateNode); 550 } 551 else if( SQL_ISRULE(pPredicateNode,length_exp) ) 552 { 553 executeFunction(pPredicateNode->getChild(0)); 554 } 555 else 556 { 557 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL); 558 } 559 if (pOperand) 560 m_aCodeList.push_back(pOperand); 561 return pOperand; 562 } 563 564 //////////////////////////////////////////////////////////////////////////////////////// 565 sal_Bool OPredicateInterpreter::evaluate(OCodeList& rCodeList) 566 { 567 static sal_Bool bResult; 568 569 OCodeList::iterator aIter = rCodeList.begin(); 570 if (!(*aIter)) 571 return sal_True; // kein Praedikat 572 573 for(;aIter != rCodeList.end();++aIter) 574 { 575 OOperand* pOperand = PTR_CAST(OOperand,(*aIter)); 576 if (pOperand) 577 m_aStack.push(pOperand); 578 else 579 ((OOperator *)(*aIter))->Exec(m_aStack); 580 } 581 582 OOperand* pOperand = m_aStack.top(); 583 m_aStack.pop(); 584 585 DBG_ASSERT(m_aStack.size() == 0, "StackFehler"); 586 DBG_ASSERT(pOperand, "StackFehler"); 587 588 bResult = pOperand->isValid(); 589 if (IS_TYPE(OOperandResult,pOperand)) 590 delete pOperand; 591 return bResult; 592 } 593 // ----------------------------------------------------------------------------- 594 void OPredicateInterpreter::evaluateSelection(OCodeList& rCodeList,ORowSetValueDecoratorRef& _rVal) 595 { 596 OCodeList::iterator aIter = rCodeList.begin(); 597 if (!(*aIter)) 598 return ; // kein Praedikat 599 600 for(;aIter != rCodeList.end();++aIter) 601 { 602 OOperand* pOperand = PTR_CAST(OOperand,(*aIter)); 603 if (pOperand) 604 m_aStack.push(pOperand); 605 else 606 ((OOperator *)(*aIter))->Exec(m_aStack); 607 } 608 609 OOperand* pOperand = m_aStack.top(); 610 m_aStack.pop(); 611 612 DBG_ASSERT(m_aStack.size() == 0, "StackFehler"); 613 DBG_ASSERT(pOperand, "StackFehler"); 614 615 (*_rVal) = pOperand->getValue(); 616 if (IS_TYPE(OOperandResult,pOperand)) 617 delete pOperand; 618 } 619 // ----------------------------------------------------------------------------- 620 OOperand* OPredicateCompiler::execute_Fold(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) 621 { 622 DBG_ASSERT(pPredicateNode->count() >= 4,"OFILECursor: Fehler im Parse Tree"); 623 624 sal_Bool bUpper = SQL_ISTOKEN(pPredicateNode->getChild(0),UPPER); 625 626 execute(pPredicateNode->getChild(2)); 627 OOperator* pOperator = NULL; 628 if ( bUpper ) 629 pOperator = new OOp_Upper(); 630 else 631 pOperator = new OOp_Lower(); 632 633 m_aCodeList.push_back(pOperator); 634 return NULL; 635 } 636 // ----------------------------------------------------------------------------- 637 OOperand* OPredicateCompiler::executeFunction(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) 638 { 639 OOperator* pOperator = NULL; 640 641 OSL_ENSURE(pPredicateNode->getChild(0)->isToken(),"The first one must be the name of the function!"); 642 sal_Int32 nTokenId = pPredicateNode->getChild(0)->getTokenID(); 643 switch ( nTokenId ) 644 { 645 case SQL_TOKEN_CHAR_LENGTH: 646 case SQL_TOKEN_LENGTH: 647 case SQL_TOKEN_OCTET_LENGTH: 648 case SQL_TOKEN_ASCII: 649 case SQL_TOKEN_LCASE: 650 case SQL_TOKEN_LTRIM: 651 case SQL_TOKEN_RTRIM: 652 case SQL_TOKEN_SPACE: 653 case SQL_TOKEN_UCASE: 654 case SQL_TOKEN_ABS: 655 case SQL_TOKEN_ACOS: 656 case SQL_TOKEN_ASIN: 657 case SQL_TOKEN_ATAN: 658 case SQL_TOKEN_CEILING: 659 case SQL_TOKEN_COS: 660 case SQL_TOKEN_DEGREES: 661 case SQL_TOKEN_EXP: 662 case SQL_TOKEN_FLOOR: 663 case SQL_TOKEN_LOG10: 664 case SQL_TOKEN_LN: 665 case SQL_TOKEN_RADIANS: 666 case SQL_TOKEN_SIGN: 667 case SQL_TOKEN_SIN: 668 case SQL_TOKEN_SQRT: 669 case SQL_TOKEN_TAN: 670 case SQL_TOKEN_DAYNAME: 671 case SQL_TOKEN_DAYOFMONTH: 672 case SQL_TOKEN_DAYOFWEEK: 673 case SQL_TOKEN_DAYOFYEAR: 674 case SQL_TOKEN_HOUR: 675 case SQL_TOKEN_MINUTE: 676 case SQL_TOKEN_MONTH: 677 case SQL_TOKEN_MONTHNAME: 678 case SQL_TOKEN_QUARTER: 679 case SQL_TOKEN_SECOND: 680 case SQL_TOKEN_YEAR: 681 682 execute(pPredicateNode->getChild(2)); 683 684 switch( nTokenId ) 685 { 686 case SQL_TOKEN_CHAR_LENGTH: 687 case SQL_TOKEN_LENGTH: 688 case SQL_TOKEN_OCTET_LENGTH: 689 pOperator = new OOp_CharLength(); 690 break; 691 case SQL_TOKEN_ASCII: 692 pOperator = new OOp_Ascii(); 693 break; 694 case SQL_TOKEN_LCASE: 695 pOperator = new OOp_Lower(); 696 break; 697 698 case SQL_TOKEN_LTRIM: 699 pOperator = new OOp_LTrim(); 700 break; 701 case SQL_TOKEN_RTRIM: 702 pOperator = new OOp_RTrim(); 703 break; 704 case SQL_TOKEN_SPACE: 705 pOperator = new OOp_Space(); 706 break; 707 case SQL_TOKEN_UCASE: 708 pOperator = new OOp_Upper(); 709 break; 710 case SQL_TOKEN_ABS: 711 pOperator = new OOp_Abs(); 712 break; 713 case SQL_TOKEN_ACOS: 714 pOperator = new OOp_ACos(); 715 break; 716 case SQL_TOKEN_ASIN: 717 pOperator = new OOp_ASin(); 718 break; 719 case SQL_TOKEN_ATAN: 720 pOperator = new OOp_ATan(); 721 break; 722 case SQL_TOKEN_CEILING: 723 pOperator = new OOp_Ceiling(); 724 break; 725 case SQL_TOKEN_COS: 726 pOperator = new OOp_Cos(); 727 break; 728 case SQL_TOKEN_DEGREES: 729 pOperator = new OOp_Degrees(); 730 break; 731 case SQL_TOKEN_EXP: 732 pOperator = new OOp_Exp(); 733 break; 734 case SQL_TOKEN_FLOOR: 735 pOperator = new OOp_Floor(); 736 break; 737 case SQL_TOKEN_LOG10: 738 pOperator = new OOp_Log10(); 739 break; 740 case SQL_TOKEN_LN: 741 pOperator = new OOp_Ln(); 742 break; 743 case SQL_TOKEN_RADIANS: 744 pOperator = new OOp_Radians(); 745 break; 746 case SQL_TOKEN_SIGN: 747 pOperator = new OOp_Sign(); 748 break; 749 case SQL_TOKEN_SIN: 750 pOperator = new OOp_Sin(); 751 break; 752 case SQL_TOKEN_SQRT: 753 pOperator = new OOp_Sqrt(); 754 break; 755 case SQL_TOKEN_TAN: 756 pOperator = new OOp_Tan(); 757 break; 758 case SQL_TOKEN_DAYOFWEEK: 759 pOperator = new OOp_DayOfWeek(); 760 break; 761 case SQL_TOKEN_DAYOFMONTH: 762 pOperator = new OOp_DayOfMonth(); 763 break; 764 case SQL_TOKEN_DAYOFYEAR: 765 pOperator = new OOp_DayOfYear(); 766 break; 767 case SQL_TOKEN_MONTH: 768 pOperator = new OOp_Month(); 769 break; 770 case SQL_TOKEN_DAYNAME: 771 pOperator = new OOp_DayName(); 772 break; 773 case SQL_TOKEN_MONTHNAME: 774 pOperator = new OOp_MonthName(); 775 break; 776 case SQL_TOKEN_QUARTER: 777 pOperator = new OOp_Quarter(); 778 break; 779 case SQL_TOKEN_YEAR: 780 pOperator = new OOp_Year(); 781 break; 782 case SQL_TOKEN_HOUR: 783 pOperator = new OOp_Hour(); 784 break; 785 case SQL_TOKEN_MINUTE: 786 pOperator = new OOp_Minute(); 787 break; 788 case SQL_TOKEN_SECOND: 789 pOperator = new OOp_Second(); 790 break; 791 default: 792 OSL_ENSURE(0,"Error in switch!"); 793 } 794 break; 795 case SQL_TOKEN_CHAR: 796 case SQL_TOKEN_CONCAT: 797 case SQL_TOKEN_INSERT: 798 case SQL_TOKEN_LEFT: 799 case SQL_TOKEN_LOCATE: 800 case SQL_TOKEN_LOCATE_2: 801 case SQL_TOKEN_REPEAT: 802 case SQL_TOKEN_REPLACE: 803 case SQL_TOKEN_RIGHT: 804 case SQL_TOKEN_MOD: 805 case SQL_TOKEN_ROUND: 806 case SQL_TOKEN_LOGF: 807 case SQL_TOKEN_LOG: 808 case SQL_TOKEN_POWER: 809 case SQL_TOKEN_ATAN2: 810 case SQL_TOKEN_PI: 811 case SQL_TOKEN_CURDATE: 812 case SQL_TOKEN_CURTIME: 813 case SQL_TOKEN_NOW: 814 case SQL_TOKEN_WEEK: 815 { 816 m_aCodeList.push_back(new OStopOperand); 817 OSQLParseNode* pList = pPredicateNode->getChild(2); 818 for (sal_uInt32 i=0; i < pList->count(); ++i) 819 execute(pList->getChild(i)); 820 821 switch( nTokenId ) 822 { 823 case SQL_TOKEN_CHAR: 824 pOperator = new OOp_Char(); 825 break; 826 case SQL_TOKEN_CONCAT: 827 pOperator = new OOp_Concat(); 828 break; 829 case SQL_TOKEN_INSERT: 830 pOperator = new OOp_Insert(); 831 break; 832 case SQL_TOKEN_LEFT: 833 pOperator = new OOp_Left(); 834 break; 835 case SQL_TOKEN_LOCATE: 836 case SQL_TOKEN_LOCATE_2: 837 pOperator = new OOp_Locate(); 838 break; 839 case SQL_TOKEN_REPEAT: 840 pOperator = new OOp_Repeat(); 841 break; 842 case SQL_TOKEN_REPLACE: 843 pOperator = new OOp_Replace(); 844 break; 845 case SQL_TOKEN_RIGHT: 846 pOperator = new OOp_Right(); 847 break; 848 case SQL_TOKEN_MOD: 849 pOperator = new OOp_Mod(); 850 break; 851 case SQL_TOKEN_ROUND: 852 pOperator = new OOp_Round(); 853 break; 854 case SQL_TOKEN_LOGF: 855 case SQL_TOKEN_LOG: 856 pOperator = new OOp_Log(); 857 break; 858 case SQL_TOKEN_POWER: 859 pOperator = new OOp_Pow(); 860 break; 861 case SQL_TOKEN_ATAN2: 862 pOperator = new OOp_ATan2(); 863 break; 864 case SQL_TOKEN_PI: 865 pOperator = new OOp_Pi(); 866 break; 867 case SQL_TOKEN_CURDATE: 868 pOperator = new OOp_CurDate(); 869 break; 870 case SQL_TOKEN_CURTIME: 871 pOperator = new OOp_CurTime(); 872 break; 873 case SQL_TOKEN_NOW: 874 pOperator = new OOp_Now(); 875 break; 876 case SQL_TOKEN_WEEK: 877 pOperator = new OOp_Week(); 878 break; 879 default: 880 OSL_ENSURE(0,"Error in switch!"); 881 } 882 } 883 break; 884 885 case SQL_TOKEN_SUBSTRING: 886 m_aCodeList.push_back(new OStopOperand); 887 if ( pPredicateNode->count() == 4 ) //char_substring_fct 888 { 889 OSQLParseNode* pList = pPredicateNode->getChild(2); 890 for (sal_uInt32 i=0; i < pList->count(); ++i) 891 execute(pList->getChild(i)); 892 } 893 else 894 { 895 execute(pPredicateNode->getChild(2)); 896 execute(pPredicateNode->getChild(4)); 897 execute(pPredicateNode->getChild(5)->getChild(1)); 898 } 899 pOperator = new OOp_SubString(); 900 break; 901 902 case SQL_TOKEN_POSITION: 903 m_aCodeList.push_back(new OStopOperand); 904 if ( pPredicateNode->count() == 4 ) //position_exp 905 { 906 OSQLParseNode* pList = pPredicateNode->getChild(2); 907 for (sal_uInt32 i=0; i < pList->count(); ++i) 908 execute(pList->getChild(i)); 909 } 910 else 911 { 912 execute(pPredicateNode->getChild(2)); 913 execute(pPredicateNode->getChild(4)); 914 } 915 pOperator = new OOp_Locate(); 916 break; 917 default: 918 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED,NULL); 919 } 920 921 m_aCodeList.push_back(pOperator); 922 return NULL; 923 } 924 // ----------------------------------------------------------------------------- 925 926 927