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/fcode.hxx" 31 #include <osl/diagnose.h> 32 #include "connectivity/sqlparse.hxx" 33 #include <i18npool/mslangid.hxx> 34 #include <tools/debug.hxx> 35 #include <tools/string.hxx> 36 #include "TConnection.hxx" 37 #include <com/sun/star/sdb/SQLFilterOperator.hpp> 38 #include <comphelper/types.hxx> 39 #include <com/sun/star/sdb/SQLFilterOperator.hpp> 40 #include <rtl/logfile.hxx> 41 42 using namespace ::comphelper; 43 using namespace connectivity; 44 using namespace connectivity::file; 45 //using namespace ::com::sun::star::uno; 46 //using namespace ::com::sun::star::lang; 47 using namespace ::com::sun::star::sdbc; 48 using namespace ::com::sun::star::sdb; 49 //using namespace ::com::sun::star::container; 50 //using namespace ::com::sun::star::beans; 51 //using namespace ::com::sun::star::sdbcx; 52 53 TYPEINIT0(OCode); 54 TYPEINIT1(OOperand, OCode); 55 TYPEINIT1(OOperandRow, OOperand); 56 TYPEINIT1(OOperandAttr, OOperandRow); 57 TYPEINIT1(OOperandParam, OOperandRow); 58 TYPEINIT1(OOperandValue, OOperand); 59 TYPEINIT1(OOperandConst, OOperandValue); 60 TYPEINIT1(OOperandResult, OOperandValue); 61 TYPEINIT1(OStopOperand, OOperandValue); 62 63 TYPEINIT1(OOperator, OCode); 64 TYPEINIT1(OBoolOperator,OOperator); 65 TYPEINIT1(OOp_NOT, OBoolOperator); 66 TYPEINIT1(OOp_AND, OBoolOperator); 67 TYPEINIT1(OOp_OR, OBoolOperator); 68 TYPEINIT1(OOp_ISNULL, OBoolOperator); 69 TYPEINIT1(OOp_ISNOTNULL, OOp_ISNULL); 70 TYPEINIT1(OOp_LIKE, OBoolOperator); 71 TYPEINIT1(OOp_NOTLIKE, OOp_LIKE); 72 TYPEINIT1(OOp_COMPARE, OBoolOperator); 73 TYPEINIT1(ONumOperator, OOperator); 74 TYPEINIT1(ONthOperator, OOperator); 75 TYPEINIT1(OBinaryOperator, OOperator); 76 TYPEINIT1(OUnaryOperator, OOperator); 77 78 //------------------------------------------------------------------ 79 DBG_NAME(OCode ) 80 OCode::OCode() 81 { 82 DBG_CTOR(OCode ,NULL); 83 } 84 // ----------------------------------------------------------------------------- 85 OCode::~OCode() 86 { 87 DBG_DTOR(OCode,NULL); 88 } 89 90 //------------------------------------------------------------------ 91 OEvaluateSet* OOperand::preProcess(OBoolOperator* /*pOp*/, OOperand* /*pRight*/) 92 { 93 return NULL; 94 } 95 // ----------------------------------------------------------------------------- 96 OOperandRow::OOperandRow(sal_uInt16 _nPos, sal_Int32 _rType) 97 : OOperand(_rType) 98 , m_nRowPos(_nPos) 99 {} 100 //------------------------------------------------------------------ 101 void OOperandRow::bindValue(const OValueRefRow& _pRow) 102 { 103 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::OOperandRow" ); 104 OSL_ENSURE(_pRow.isValid(),"NO EMPTY row allowed!"); 105 m_pRow = _pRow; 106 OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()"); 107 (m_pRow->get())[m_nRowPos]->setBound(sal_True); 108 } 109 // ----------------------------------------------------------------------------- 110 void OOperandRow::setValue(const ORowSetValue& _rVal) 111 { 112 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::setValue" ); 113 OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()"); 114 (*(m_pRow->get())[m_nRowPos]) = _rVal; 115 } 116 //------------------------------------------------------------------ 117 const ORowSetValue& OOperandRow::getValue() const 118 { 119 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandRow::getValue" ); 120 OSL_ENSURE(m_pRow.isValid() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()"); 121 return (m_pRow->get())[m_nRowPos]->getValue(); 122 } 123 124 // ----------------------------------------------------------------------------- 125 void OOperandValue::setValue(const ORowSetValue& _rVal) 126 { 127 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandValue::setValue" ); 128 m_aValue = _rVal; 129 } 130 // ------------------------------------------------------------------------- 131 sal_Bool OOperandAttr::isIndexed() const 132 { 133 return sal_False; 134 } 135 //------------------------------------------------------------------ 136 OOperandParam::OOperandParam(OSQLParseNode* pNode, sal_Int32 _nPos) 137 : OOperandRow(static_cast<sal_uInt16>(_nPos), DataType::VARCHAR) // Standard-Typ 138 { 139 OSL_ENSURE(SQL_ISRULE(pNode,parameter),"Argument ist kein Parameter"); 140 OSL_ENSURE(pNode->count() > 0,"Fehler im Parse Tree"); 141 OSQLParseNode *pMark = pNode->getChild(0); 142 143 String aParameterName; 144 if (SQL_ISPUNCTUATION(pMark,"?")) 145 aParameterName = '?'; 146 else if (SQL_ISPUNCTUATION(pMark,":")) 147 aParameterName = pNode->getChild(1)->getTokenValue(); 148 else 149 { 150 OSL_ASSERT("Fehler im Parse Tree"); 151 } 152 153 // Parameter-Column aufsetzen mit defult typ, kann zu einem spaeteren Zeitpunkt ueber DescribeParameter 154 // genauer spezifiziert werden 155 156 // Identitaet merken (hier eigentlich nicht erforderlich, aber aus 157 // Symmetriegruenden ...) 158 159 // todo 160 // OColumn* pColumn = new OFILEColumn(aParameterName,eDBType,255,0,SQL_FLAGS_NULLALLOWED); 161 // rParamColumns->AddColumn(pColumn); 162 163 // der Wert wird erst kurz vor der Auswertung gesetzt 164 } 165 166 167 //------------------------------------------------------------------ 168 const ORowSetValue& OOperandValue::getValue() const 169 { 170 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandValue::getValue" ); 171 return m_aValue; 172 } 173 174 //------------------------------------------------------------------ 175 OOperandConst::OOperandConst(const OSQLParseNode& rColumnRef, const rtl::OUString& aStrValue) 176 { 177 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandConst::OOperandConst" ); 178 switch (rColumnRef.getNodeType()) 179 { 180 case SQL_NODE_STRING: 181 m_aValue = aStrValue; 182 m_eDBType = DataType::VARCHAR; 183 m_aValue.setBound(sal_True); 184 return; 185 case SQL_NODE_INTNUM: 186 case SQL_NODE_APPROXNUM: 187 { 188 m_aValue = aStrValue.toDouble(); 189 m_eDBType = DataType::DOUBLE; 190 m_aValue.setBound(sal_True); 191 return; 192 } 193 default: 194 break; 195 } 196 197 if (SQL_ISTOKEN(&rColumnRef,TRUE)) 198 { 199 m_aValue = 1.0; 200 m_eDBType = DataType::BIT; 201 } 202 else if (SQL_ISTOKEN(&rColumnRef,FALSE)) 203 { 204 m_aValue = 0.0; 205 m_eDBType = DataType::BIT; 206 } 207 else 208 { 209 OSL_ASSERT("Parse Error"); 210 } 211 m_aValue.setBound(sal_True); 212 } 213 214 ///////////////////////////////////////////////////////////////////////////////////////// 215 // Implementation of the operators 216 217 //------------------------------------------------------------------ 218 sal_uInt16 OOperator::getRequestedOperands() const {return 2;} 219 220 //------------------------------------------------------------------ 221 sal_Bool OBoolOperator::operate(const OOperand*, const OOperand*) const 222 { 223 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBoolOperator::operate" ); 224 return sal_False; 225 } 226 227 228 //------------------------------------------------------------------ 229 void OBoolOperator::Exec(OCodeStack& rCodeStack) 230 { 231 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBoolOperator::Exec" ); 232 OOperand *pRight = rCodeStack.top(); 233 rCodeStack.pop(); 234 OOperand *pLeft = rCodeStack.top(); 235 rCodeStack.pop(); 236 237 rCodeStack.push(new OOperandResultBOOL(operate(pLeft, pRight))); 238 if (IS_TYPE(OOperandResult,pLeft)) 239 delete pLeft; 240 if (IS_TYPE(OOperandResult,pRight)) 241 delete pRight; 242 } 243 //------------------------------------------------------------------ 244 sal_Bool OOp_NOT::operate(const OOperand* pLeft, const OOperand* ) const 245 { 246 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_AND::operate" ); 247 return !pLeft->isValid(); 248 } 249 //------------------------------------------------------------------ 250 void OOp_NOT::Exec(OCodeStack& rCodeStack) 251 { 252 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::Exec" ); 253 OOperand* pOperand = rCodeStack.top(); 254 rCodeStack.pop(); 255 256 rCodeStack.push(new OOperandResultBOOL(operate(pOperand))); 257 if (IS_TYPE(OOperandResult,pOperand)) 258 delete pOperand; 259 } 260 //------------------------------------------------------------------ 261 sal_uInt16 OOp_NOT::getRequestedOperands() const 262 { 263 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_NOT::getRequestedOperands" ); 264 return 1; 265 } 266 267 //------------------------------------------------------------------ 268 sal_Bool OOp_AND::operate(const OOperand* pLeft, const OOperand* pRight) const 269 { 270 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_AND::operate" ); 271 return pLeft->isValid() && pRight->isValid(); 272 } 273 274 //------------------------------------------------------------------ 275 sal_Bool OOp_OR::operate(const OOperand* pLeft, const OOperand* pRight) const 276 { 277 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_OR::operate" ); 278 return pLeft->isValid() || pRight->isValid(); 279 } 280 281 //------------------------------------------------------------------ 282 sal_uInt16 OOp_ISNULL::getRequestedOperands() const 283 { 284 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::getRequestedOperands" ); 285 return 1; 286 } 287 288 //------------------------------------------------------------------ 289 void OOp_ISNULL::Exec(OCodeStack& rCodeStack) 290 { 291 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::Exec" ); 292 OOperand* pOperand = rCodeStack.top(); 293 rCodeStack.pop(); 294 295 rCodeStack.push(new OOperandResultBOOL(operate(pOperand))); 296 if (IS_TYPE(OOperandResult,pOperand)) 297 delete pOperand; 298 } 299 300 //------------------------------------------------------------------ 301 sal_Bool OOp_ISNULL::operate(const OOperand* pOperand, const OOperand*) const 302 { 303 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::operate" ); 304 return pOperand->getValue().isNull(); 305 } 306 307 //------------------------------------------------------------------ 308 sal_Bool OOp_ISNOTNULL::operate(const OOperand* pOperand, const OOperand*) const 309 { 310 return !OOp_ISNULL::operate(pOperand); 311 } 312 313 //------------------------------------------------------------------ 314 sal_Bool OOp_LIKE::operate(const OOperand* pLeft, const OOperand* pRight) const 315 { 316 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ISNULL::operate" ); 317 sal_Bool bMatch; 318 ORowSetValue aLH(pLeft->getValue()); 319 ORowSetValue aRH(pRight->getValue()); 320 321 if (aLH.isNull() || aRH.isNull()) 322 bMatch = sal_False; 323 else 324 { 325 bMatch = match(aRH.getString(), aLH.getString(), cEscape); 326 } 327 return bMatch; 328 } 329 330 //------------------------------------------------------------------ 331 sal_Bool OOp_NOTLIKE::operate(const OOperand* pLeft, const OOperand* pRight) const 332 { 333 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_NOTLIKE::operate" ); 334 return !OOp_LIKE::operate(pLeft, pRight); 335 } 336 337 //------------------------------------------------------------------ 338 sal_Bool OOp_COMPARE::operate(const OOperand* pLeft, const OOperand* pRight) const 339 { 340 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_COMPARE::operate" ); 341 ORowSetValue aLH(pLeft->getValue()); 342 ORowSetValue aRH(pRight->getValue()); 343 344 if (aLH.isNull() || aRH.isNull()) // if (!aLH.getValue() || !aRH.getValue()) 345 return sal_False; 346 347 sal_Bool bResult = sal_False; 348 sal_Int32 eDBType = pLeft->getDBType(); 349 350 // Vergleich (je nach Datentyp): 351 switch (eDBType) 352 { 353 case DataType::CHAR: 354 case DataType::VARCHAR: 355 case DataType::LONGVARCHAR: 356 { 357 rtl::OUString sLH = aLH, sRH = aRH; 358 sal_Int32 nRes = rtl_ustr_compareIgnoreAsciiCase_WithLength 359 ( 360 sLH.pData->buffer, 361 sLH.pData->length, 362 sRH.pData->buffer, 363 sRH.pData->length ); 364 switch(aPredicateType) 365 { 366 case SQLFilterOperator::EQUAL: bResult = (nRes == 0); break; 367 case SQLFilterOperator::NOT_EQUAL: bResult = (nRes != 0); break; 368 case SQLFilterOperator::LESS: bResult = (nRes < 0); break; 369 case SQLFilterOperator::LESS_EQUAL: bResult = (nRes <= 0); break; 370 case SQLFilterOperator::GREATER: bResult = (nRes > 0); break; 371 case SQLFilterOperator::GREATER_EQUAL: bResult = (nRes >= 0); break; 372 default: bResult = sal_False; 373 } 374 } break; 375 case DataType::TINYINT: 376 case DataType::SMALLINT: 377 case DataType::INTEGER: 378 case DataType::DECIMAL: 379 case DataType::NUMERIC: 380 case DataType::REAL: 381 case DataType::DOUBLE: 382 case DataType::BIT: 383 case DataType::TIMESTAMP: 384 case DataType::DATE: 385 case DataType::TIME: 386 { 387 double n = aLH ,m = aRH; 388 389 switch (aPredicateType) 390 { 391 case SQLFilterOperator::EQUAL: bResult = (n == m); break; 392 case SQLFilterOperator::LIKE: bResult = (n == m); break; 393 case SQLFilterOperator::NOT_EQUAL: bResult = (n != m); break; 394 case SQLFilterOperator::NOT_LIKE: bResult = (n != m); break; 395 case SQLFilterOperator::LESS: bResult = (n < m); break; 396 case SQLFilterOperator::LESS_EQUAL: bResult = (n <= m); break; 397 case SQLFilterOperator::GREATER: bResult = (n > m); break; 398 case SQLFilterOperator::GREATER_EQUAL: bResult = (n >= m); break; 399 default: bResult = sal_False; 400 } 401 } break; 402 default: 403 bResult = aLH == aRH; 404 } 405 return bResult; 406 } 407 408 //------------------------------------------------------------------ 409 void ONumOperator::Exec(OCodeStack& rCodeStack) 410 { 411 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "ONumOperator::Exec" ); 412 413 OOperand *pRight = rCodeStack.top(); 414 rCodeStack.pop(); 415 OOperand *pLeft = rCodeStack.top(); 416 rCodeStack.pop(); 417 418 rCodeStack.push(new OOperandResultNUM(operate(pLeft->getValue(), pRight->getValue()))); 419 if (IS_TYPE(OOperandResult,pLeft)) 420 delete pLeft; 421 if (IS_TYPE(OOperandResult,pRight)) 422 delete pRight; 423 } 424 //------------------------------------------------------------------ 425 double OOp_ADD::operate(const double& fLeft,const double& fRight) const 426 { 427 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_ADD::operate" ); 428 return fLeft + fRight; 429 } 430 431 //------------------------------------------------------------------ 432 double OOp_SUB::operate(const double& fLeft,const double& fRight) const 433 { 434 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_SUB::operate" ); 435 return fLeft - fRight; 436 } 437 438 //------------------------------------------------------------------ 439 double OOp_MUL::operate(const double& fLeft,const double& fRight) const 440 { 441 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_MUL::operate" ); 442 return fLeft * fRight; 443 } 444 445 //------------------------------------------------------------------ 446 double OOp_DIV::operate(const double& fLeft,const double& fRight) const 447 { 448 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOp_DIV::operate" ); 449 return fLeft / fRight; 450 } 451 // ----------------------------------------------------------------------------- 452 OEvaluateSet* OOperandAttr::preProcess(OBoolOperator* /*pOp*/, OOperand* /*pRight*/) 453 { 454 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OOperandAttr::preProcess" ); 455 return NULL; 456 } 457 //------------------------------------------------------------------ 458 void ONthOperator::Exec(OCodeStack& rCodeStack) 459 { 460 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "ONthOperator::Exec" ); 461 ::std::vector<ORowSetValue> aValues; 462 ::std::vector<OOperand*> aOperands; 463 OOperand* pOperand; 464 do 465 { 466 OSL_ENSURE(!rCodeStack.empty(),"Stack must be none empty!"); 467 pOperand = rCodeStack.top(); 468 rCodeStack.pop(); 469 if ( !IS_TYPE(OStopOperand,pOperand) ) 470 aValues.push_back( pOperand->getValue() ); 471 aOperands.push_back( pOperand ); 472 } 473 while ( !IS_TYPE(OStopOperand,pOperand) ); 474 475 rCodeStack.push(new OOperandResult(operate(aValues))); 476 477 ::std::vector<OOperand*>::iterator aIter = aOperands.begin(); 478 ::std::vector<OOperand*>::iterator aEnd = aOperands.end(); 479 for (; aIter != aEnd; ++aIter) 480 { 481 if (IS_TYPE(OOperandResult,*aIter)) 482 delete *aIter; 483 } 484 } 485 //------------------------------------------------------------------ 486 void OBinaryOperator::Exec(OCodeStack& rCodeStack) 487 { 488 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OBinaryOperator::Exec" ); 489 OOperand *pRight = rCodeStack.top(); 490 rCodeStack.pop(); 491 OOperand *pLeft = rCodeStack.top(); 492 rCodeStack.pop(); 493 494 if ( !rCodeStack.empty() && IS_TYPE(OStopOperand,rCodeStack.top()) ) 495 rCodeStack.pop(); 496 497 rCodeStack.push(new OOperandResult(operate(pLeft->getValue(),pRight->getValue()))); 498 if (IS_TYPE(OOperandResult,pRight)) 499 delete pRight; 500 if (IS_TYPE(OOperandResult,pLeft)) 501 delete pLeft; 502 } 503 //------------------------------------------------------------------ 504 void OUnaryOperator::Exec(OCodeStack& rCodeStack) 505 { 506 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "file", "Ocke.Janssen@sun.com", "OUnaryOperator::Exec" ); 507 OSL_ENSURE(!rCodeStack.empty(),"Stack is empty!"); 508 OOperand* pOperand = rCodeStack.top(); 509 rCodeStack.pop(); 510 511 rCodeStack.push(new OOperandResult(operate(pOperand->getValue()))); 512 if (IS_TYPE(OOperandResult,pOperand)) 513 delete pOperand; 514 } 515 // ----------------------------------------------------------------------------- 516 sal_uInt16 OUnaryOperator::getRequestedOperands() const {return 1;} 517 518 519 520