Bump for 3.6-28
[LibreOffice.git] / connectivity / source / drivers / file / fcomp.cxx
blob257232e5b5135985befe1bee418247f77137a895
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include "file/fcomp.hxx"
30 #include <tools/debug.hxx>
31 #include "TConnection.hxx"
32 #include "connectivity/sqlparse.hxx"
33 #include "file/fanalyzer.hxx"
34 #include <com/sun/star/sdbc/XColumnLocate.hpp>
35 #include <com/sun/star/util/DateTime.hpp>
36 #include <com/sun/star/util/Date.hpp>
37 #include <com/sun/star/util/Time.hpp>
38 #include "connectivity/dbexception.hxx"
39 #include "connectivity/dbconversion.hxx"
40 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
41 #include "resource/file_res.hrc"
42 #include "file/FStringFunctions.hxx"
43 #include "file/FDateFunctions.hxx"
44 #include "file/FNumericFunctions.hxx"
45 #include "file/FConnection.hxx"
47 using namespace connectivity;
48 using namespace connectivity::file;
49 using namespace com::sun::star::uno;
50 using namespace com::sun::star::sdbc;
51 using namespace com::sun::star::sdb;
52 using namespace ::com::sun::star::container;
53 using namespace ::com::sun::star::util;
55 DBG_NAME(OPredicateCompiler)
56 //------------------------------------------------------------------
57 OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer* pAnalyzer)//,OCursor& rCurs)
58 : m_pAnalyzer(pAnalyzer)
59 , m_nParamCounter(0)
60 , m_bORCondition(sal_False)
62 DBG_CTOR(OPredicateCompiler,NULL);
65 //------------------------------------------------------------------
66 OPredicateCompiler::~OPredicateCompiler()
68 Clean();
69 DBG_DTOR(OPredicateCompiler,NULL);
71 // -----------------------------------------------------------------------------
72 void OPredicateCompiler::dispose()
74 Clean();
75 m_orgColumns = NULL;
76 m_xIndexes.clear();
79 void OPredicateCompiler::start(OSQLParseNode* pSQLParseNode)
81 if (!pSQLParseNode)
82 return;
84 m_nParamCounter = 0;
85 // analyse Parse Tree (depending on Statement-type)
86 // and set pointer on WHERE-clause:
87 OSQLParseNode * pWhereClause = NULL;
88 OSQLParseNode * pOrderbyClause = NULL;
90 if (SQL_ISRULE(pSQLParseNode,select_statement))
92 DBG_ASSERT(pSQLParseNode->count() >= 4,"OFILECursor: Fehler im Parse Tree");
94 OSQLParseNode * pTableExp = pSQLParseNode->getChild(3);
95 DBG_ASSERT(pTableExp != NULL,"Fehler im Parse Tree");
96 DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp)," Fehler im Parse Tree");
97 DBG_ASSERT(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"Fehler im Parse Tree");
99 // check that we don't use anything other than count(*) as function
100 OSQLParseNode* pSelection = pSQLParseNode->getChild(2);
101 if ( SQL_ISRULE(pSelection,scalar_exp_commalist) )
103 for (sal_uInt32 i = 0; i < pSelection->count(); i++)
105 OSQLParseNode *pColumnRef = pSelection->getChild(i)->getChild(0);
106 if ( SQL_ISRULE(pColumnRef,general_set_fct) && pColumnRef->count() != 4 )
108 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT,NULL);
114 pWhereClause = pTableExp->getChild(1);
115 pOrderbyClause = pTableExp->getChild(ORDER_BY_CHILD_POS);
116 (void)pOrderbyClause;
118 else if (SQL_ISRULE(pSQLParseNode,update_statement_searched))
120 DBG_ASSERT(pSQLParseNode->count() == 5,"OFILECursor: Fehler im Parse Tree");
121 pWhereClause = pSQLParseNode->getChild(4);
123 else if (SQL_ISRULE(pSQLParseNode,delete_statement_searched))
125 DBG_ASSERT(pSQLParseNode->count() == 4,"Fehler im Parse Tree");
126 pWhereClause = pSQLParseNode->getChild(3);
128 else
129 // Other Statement. no selection-criteria
130 return;
132 if (SQL_ISRULE(pWhereClause,where_clause))
134 // a where-clause is not allowed to be empty:
135 DBG_ASSERT(pWhereClause->count() == 2,"OFILECursor: Fehler im Parse Tree");
137 OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1);
138 DBG_ASSERT(pComparisonPredicate != NULL,"OFILECursor: Fehler im Parse Tree");
140 execute( pComparisonPredicate );
142 else
144 // The where-clause is optionally in the majority of cases, i.e. it might be an "optional-where-clause".
145 DBG_ASSERT(SQL_ISRULE(pWhereClause,opt_where_clause),"OPredicateCompiler: Fehler im Parse Tree");
149 //------------------------------------------------------------------
150 OOperand* OPredicateCompiler::execute(OSQLParseNode* pPredicateNode)
152 OOperand* pOperand = NULL;
153 if (pPredicateNode->count() == 3 && // Expression is bracketed
154 SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"(") &&
155 SQL_ISPUNCTUATION(pPredicateNode->getChild(2),")"))
157 execute(pPredicateNode->getChild(1));
159 else if ((SQL_ISRULE(pPredicateNode,search_condition) || (SQL_ISRULE(pPredicateNode,boolean_term)))
160 && // AND/OR-linkage:
161 pPredicateNode->count() == 3)
163 execute(pPredicateNode->getChild(0)); // process the left branch
164 execute(pPredicateNode->getChild(2)); // process the right branch
166 if (SQL_ISTOKEN(pPredicateNode->getChild(1),OR)) // OR-Operator
168 m_aCodeList.push_back(new OOp_OR());
169 m_bORCondition = sal_True;
171 else if (SQL_ISTOKEN(pPredicateNode->getChild(1),AND)) // AND-Operator
172 m_aCodeList.push_back(new OOp_AND());
173 else
175 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree");
178 else if (SQL_ISRULE(pPredicateNode,boolean_factor))
180 execute(pPredicateNode->getChild(1));
181 m_aCodeList.push_back(new OOp_NOT());
183 else if (SQL_ISRULE(pPredicateNode,comparison_predicate))
185 execute_COMPARE(pPredicateNode);
187 else if (SQL_ISRULE(pPredicateNode,like_predicate))
189 execute_LIKE(pPredicateNode);
191 else if (SQL_ISRULE(pPredicateNode,between_predicate))
193 execute_BETWEEN(pPredicateNode);
195 else if (SQL_ISRULE(pPredicateNode,test_for_null))
197 execute_ISNULL(pPredicateNode);
199 else if(SQL_ISRULE(pPredicateNode,num_value_exp))
201 execute(pPredicateNode->getChild(0)); // process the left branch
202 execute(pPredicateNode->getChild(2)); // process the right branch
203 if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"+"))
205 m_aCodeList.push_back(new OOp_ADD());
207 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"-"))
208 m_aCodeList.push_back(new OOp_SUB());
209 else
211 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
214 else if(SQL_ISRULE(pPredicateNode,term))
216 execute(pPredicateNode->getChild(0)); // process the left branch
217 execute(pPredicateNode->getChild(2)); // process the right branch
218 if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"*"))
220 m_aCodeList.push_back(new OOp_MUL());
222 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"/"))
223 m_aCodeList.push_back(new OOp_DIV());
224 else
226 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
229 else
230 pOperand = execute_Operand(pPredicateNode); // now only simple operands will be processed
232 return pOperand;
235 //------------------------------------------------------------------
236 OOperand* OPredicateCompiler::execute_COMPARE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
238 DBG_ASSERT(pPredicateNode->count() == 3,"OFILECursor: Fehler im Parse Tree");
240 if ( !(SQL_ISRULE(pPredicateNode->getChild(0),column_ref) ||
241 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_STRING ||
242 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_INTNUM ||
243 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_APPROXNUM ||
244 SQL_ISTOKEN(pPredicateNode->getChild(2),TRUE) ||
245 SQL_ISTOKEN(pPredicateNode->getChild(2),FALSE) ||
246 SQL_ISRULE(pPredicateNode->getChild(2),parameter) ||
247 // odbc date
248 SQL_ISRULE(pPredicateNode->getChild(2),set_fct_spec) ||
249 SQL_ISRULE(pPredicateNode->getChild(2),position_exp) ||
250 SQL_ISRULE(pPredicateNode->getChild(2),char_substring_fct) ||
251 // upper, lower etc.
252 SQL_ISRULE(pPredicateNode->getChild(2),fold)) )
254 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL);
255 return NULL;
258 sal_Int32 ePredicateType( SQLFilterOperator::EQUAL );
259 OSQLParseNode *pPrec = pPredicateNode->getChild(1);
261 if (pPrec->getNodeType() == SQL_NODE_EQUAL)
262 ePredicateType = SQLFilterOperator::EQUAL;
263 else if (pPrec->getNodeType() == SQL_NODE_NOTEQUAL)
264 ePredicateType = SQLFilterOperator::NOT_EQUAL;
265 else if (pPrec->getNodeType() == SQL_NODE_LESS)
266 ePredicateType = SQLFilterOperator::LESS;
267 else if (pPrec->getNodeType() == SQL_NODE_LESSEQ)
268 ePredicateType = SQLFilterOperator::LESS_EQUAL;
269 else if (pPrec->getNodeType() == SQL_NODE_GREATEQ)
270 ePredicateType = SQLFilterOperator::GREATER_EQUAL;
271 else if (pPrec->getNodeType() == SQL_NODE_GREAT)
272 ePredicateType = SQLFilterOperator::GREATER;
273 else
274 OSL_FAIL( "OPredicateCompiler::execute_COMPARE: unexpected node type!" );
276 execute(pPredicateNode->getChild(0));
277 execute(pPredicateNode->getChild(2));
278 m_aCodeList.push_back( new OOp_COMPARE(ePredicateType) );
280 return NULL;
283 //------------------------------------------------------------------
284 OOperand* OPredicateCompiler::execute_LIKE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
286 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
287 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
289 sal_Unicode cEscape = L'\0';
290 const bool bNotLike = pPart2->getChild(0)->isToken();
292 OSQLParseNode* pAtom = pPart2->getChild(pPart2->count()-2);
293 OSQLParseNode* pOptEscape = pPart2->getChild(pPart2->count()-1);
295 if (!(pAtom->getNodeType() == SQL_NODE_STRING ||
296 SQL_ISRULE(pAtom,parameter) ||
297 // odbc date
298 SQL_ISRULE(pAtom,set_fct_spec) ||
299 SQL_ISRULE(pAtom,position_exp) ||
300 SQL_ISRULE(pAtom,char_substring_fct) ||
301 // upper, lower etc.
302 SQL_ISRULE(pAtom,fold)) )
304 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL);
305 return NULL;
308 if (pOptEscape->count() != 0)
310 if (pOptEscape->count() != 2)
312 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,NULL);
314 OSQLParseNode *pEscNode = pOptEscape->getChild(1);
315 if (pEscNode->getNodeType() != SQL_NODE_STRING)
317 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,NULL);
319 else
320 cEscape = pEscNode->getTokenValue().toChar();
323 execute(pPredicateNode->getChild(0));
324 execute(pAtom);
326 OBoolOperator* pOperator = bNotLike
327 ? new OOp_NOTLIKE(cEscape)
328 : new OOp_LIKE(cEscape);
329 m_aCodeList.push_back(pOperator);
331 return NULL;
333 //------------------------------------------------------------------
334 OOperand* OPredicateCompiler::execute_BETWEEN(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
336 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
338 OSQLParseNode* pColumn = pPredicateNode->getChild(0);
339 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
340 OSQLParseNode* p1stValue = pPart2->getChild(2);
341 OSQLParseNode* p2ndtValue = pPart2->getChild(4);
343 if (
344 !(p1stValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p1stValue,parameter))
345 && !(p2ndtValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p2ndtValue,parameter))
348 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN,NULL);
351 sal_Bool bNot = SQL_ISTOKEN(pPart2->getChild(0),NOT);
353 OOperand* pColumnOp = execute(pColumn);
354 OOperand* pOb1 = execute(p1stValue);
355 OBoolOperator* pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::LESS_EQUAL : SQLFilterOperator::GREATER);
356 m_aCodeList.push_back(pOperator);
358 execute(pColumn);
359 OOperand* pOb2 = execute(p2ndtValue);
360 pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::GREATER_EQUAL : SQLFilterOperator::LESS);
361 m_aCodeList.push_back(pOperator);
363 if ( pColumnOp && pOb1 && pOb2 )
365 switch(pColumnOp->getDBType())
367 case DataType::CHAR:
368 case DataType::VARCHAR:
369 case DataType::LONGVARCHAR:
370 pOb1->setValue(pOb1->getValue().getString());
371 pOb2->setValue(pOb2->getValue().getString());
372 break;
373 case DataType::DECIMAL:
374 case DataType::NUMERIC:
375 pOb1->setValue((double)pOb1->getValue());
376 pOb2->setValue((double)pOb2->getValue());
377 break;
378 case DataType::FLOAT:
379 pOb1->setValue((float)pOb1->getValue());
380 pOb2->setValue((float)pOb2->getValue());
381 break;
382 case DataType::DOUBLE:
383 case DataType::REAL:
384 pOb1->setValue((double)pOb1->getValue());
385 pOb2->setValue((double)pOb2->getValue());
386 break;
387 case DataType::DATE:
388 pOb1->setValue((Date)pOb1->getValue());
389 pOb2->setValue((Date)pOb2->getValue());
390 break;
391 case DataType::TIME:
392 pOb1->setValue((Time)pOb1->getValue());
393 pOb2->setValue((Time)pOb2->getValue());
394 break;
395 case DataType::TIMESTAMP:
396 pOb1->setValue((DateTime)pOb1->getValue());
397 pOb2->setValue((DateTime)pOb2->getValue());
398 break;
404 OBoolOperator* pBoolOp = NULL;
405 if ( bNot )
406 pBoolOp = new OOp_OR();
407 else
408 pBoolOp = new OOp_AND();
409 m_aCodeList.push_back(pBoolOp);
411 return NULL;
413 //------------------------------------------------------------------
414 OOperand* OPredicateCompiler::execute_ISNULL(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
416 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
417 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
418 DBG_ASSERT(SQL_ISTOKEN(pPart2->getChild(0),IS),"OFILECursor: Fehler im Parse Tree");
420 sal_Int32 ePredicateType;
421 if (SQL_ISTOKEN(pPart2->getChild(1),NOT))
422 ePredicateType = SQLFilterOperator::NOT_SQLNULL;
423 else
424 ePredicateType = SQLFilterOperator::SQLNULL;
426 execute(pPredicateNode->getChild(0));
427 OBoolOperator* pOperator = (ePredicateType == SQLFilterOperator::SQLNULL) ?
428 new OOp_ISNULL() : new OOp_ISNOTNULL();
429 m_aCodeList.push_back(pOperator);
431 return NULL;
433 //------------------------------------------------------------------
434 OOperand* OPredicateCompiler::execute_Operand(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
436 OOperand* pOperand = NULL;
438 if (SQL_ISRULE(pPredicateNode,column_ref))
440 ::rtl::OUString aColumnName;
441 if (pPredicateNode->count() == 1)
443 aColumnName = pPredicateNode->getChild(0)->getTokenValue();
445 else if (pPredicateNode->count() == 3)
447 ::rtl::OUString aTableName = pPredicateNode->getChild(0)->getTokenValue();
448 if(SQL_ISRULE(pPredicateNode->getChild(2),column_val))
449 aColumnName = pPredicateNode->getChild(2)->getChild(0)->getTokenValue();
450 else
451 aColumnName = pPredicateNode->getChild(2)->getTokenValue();
454 if(!m_orgColumns->hasByName(aColumnName))
456 const ::rtl::OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution(
457 STR_INVALID_COLUMNNAME,
458 "$columnname$", aColumnName
459 ) );
460 ::dbtools::throwGenericSQLException( sError, NULL );
462 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xCol;
465 if (m_orgColumns->getByName(aColumnName) >>= xCol)
467 pOperand = m_pAnalyzer->createOperandAttr(Reference< XColumnLocate>(m_orgColumns,UNO_QUERY)->findColumn(aColumnName),xCol,m_xIndexes);
469 else
470 {// Column doesn't exist in the Result-set
471 const ::rtl::OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution(
472 STR_INVALID_COLUMNNAME,
473 "$columnname$", aColumnName
474 ) );
475 ::dbtools::throwGenericSQLException( sError, NULL );
478 catch(Exception &)
480 OSL_FAIL("OPredicateCompiler::execute_Operand Exception");
483 else if (SQL_ISRULE(pPredicateNode,parameter))
485 pOperand = new OOperandParam(pPredicateNode, ++m_nParamCounter);
487 else if (pPredicateNode->getNodeType() == SQL_NODE_STRING ||
488 pPredicateNode->getNodeType() == SQL_NODE_INTNUM ||
489 pPredicateNode->getNodeType() == SQL_NODE_APPROXNUM ||
490 pPredicateNode->getNodeType() == SQL_NODE_NAME ||
491 SQL_ISTOKEN(pPredicateNode,TRUE) ||
492 SQL_ISTOKEN(pPredicateNode,FALSE) ||
493 SQL_ISRULE(pPredicateNode,parameter))
495 pOperand = new OOperandConst(*pPredicateNode, pPredicateNode->getTokenValue());
497 else if((pPredicateNode->count() == 2) &&
498 (SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"-")) &&
499 pPredicateNode->getChild(1)->getNodeType() == SQL_NODE_INTNUM)
500 { // if -1 or +1 is there
501 ::rtl::OUString aValue(pPredicateNode->getChild(0)->getTokenValue());
502 aValue += pPredicateNode->getChild(1)->getTokenValue();
503 pOperand = new OOperandConst(*pPredicateNode->getChild(1), aValue);
505 else if( SQL_ISRULE(pPredicateNode,set_fct_spec) && SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"{") )
507 const OSQLParseNode* pODBCNode = pPredicateNode->getChild(1);
508 const OSQLParseNode* pODBCNodeChild = pODBCNode->getChild(0);
510 // Odbc Date or time
511 if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && (
512 SQL_ISTOKEN(pODBCNodeChild,D) ||
513 SQL_ISTOKEN(pODBCNodeChild,T) ||
514 SQL_ISTOKEN(pODBCNodeChild,TS) ))
516 ::rtl::OUString sDateTime = pODBCNode->getChild(1)->getTokenValue();
517 pOperand = new OOperandConst(*pODBCNode->getChild(1), sDateTime);
518 if(SQL_ISTOKEN(pODBCNodeChild,D))
520 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime)));
522 else if(SQL_ISTOKEN(pODBCNodeChild,T))
524 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime)));
526 else if(SQL_ISTOKEN(pODBCNodeChild,TS))
528 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime)));
531 else
532 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL);
535 else if( SQL_ISRULE(pPredicateNode,fold) )
537 execute_Fold(pPredicateNode);
539 else if( SQL_ISRULE(pPredicateNode,set_fct_spec)
540 || SQL_ISRULE(pPredicateNode,position_exp)
541 || SQL_ISRULE(pPredicateNode,char_substring_fct)
544 executeFunction(pPredicateNode);
546 else if( SQL_ISRULE(pPredicateNode,length_exp) )
548 executeFunction(pPredicateNode->getChild(0));
550 else
552 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL);
554 if (pOperand)
555 m_aCodeList.push_back(pOperand);
556 return pOperand;
559 ////////////////////////////////////////////////////////////////////////////////////////
560 sal_Bool OPredicateInterpreter::evaluate(OCodeList& rCodeList)
562 static sal_Bool bResult;
564 OCodeList::iterator aIter = rCodeList.begin();
565 if (!(*aIter))
566 return sal_True; // no Predicate
568 for(;aIter != rCodeList.end();++aIter)
570 OOperand* pOperand = PTR_CAST(OOperand,(*aIter));
571 if (pOperand)
572 m_aStack.push(pOperand);
573 else
574 ((OOperator *)(*aIter))->Exec(m_aStack);
577 OOperand* pOperand = m_aStack.top();
578 m_aStack.pop();
580 DBG_ASSERT(m_aStack.empty(), "StackFehler");
581 DBG_ASSERT(pOperand, "StackFehler");
583 bResult = pOperand->isValid();
584 if (IS_TYPE(OOperandResult,pOperand))
585 delete pOperand;
586 return bResult;
588 // -----------------------------------------------------------------------------
589 void OPredicateInterpreter::evaluateSelection(OCodeList& rCodeList,ORowSetValueDecoratorRef& _rVal)
591 OCodeList::iterator aIter = rCodeList.begin();
592 if (!(*aIter))
593 return ; // no Predicate
595 for(;aIter != rCodeList.end();++aIter)
597 OOperand* pOperand = PTR_CAST(OOperand,(*aIter));
598 if (pOperand)
599 m_aStack.push(pOperand);
600 else
601 ((OOperator *)(*aIter))->Exec(m_aStack);
604 OOperand* pOperand = m_aStack.top();
605 m_aStack.pop();
607 DBG_ASSERT(m_aStack.empty(), "StackFehler");
608 DBG_ASSERT(pOperand, "StackFehler");
610 (*_rVal) = pOperand->getValue();
611 if (IS_TYPE(OOperandResult,pOperand))
612 delete pOperand;
614 // -----------------------------------------------------------------------------
615 OOperand* OPredicateCompiler::execute_Fold(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
617 DBG_ASSERT(pPredicateNode->count() >= 4,"OFILECursor: Fehler im Parse Tree");
619 sal_Bool bUpper = SQL_ISTOKEN(pPredicateNode->getChild(0),UPPER);
621 execute(pPredicateNode->getChild(2));
622 OOperator* pOperator = NULL;
623 if ( bUpper )
624 pOperator = new OOp_Upper();
625 else
626 pOperator = new OOp_Lower();
628 m_aCodeList.push_back(pOperator);
629 return NULL;
631 // -----------------------------------------------------------------------------
632 OOperand* OPredicateCompiler::executeFunction(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
634 OOperator* pOperator = NULL;
636 OSL_ENSURE(pPredicateNode->getChild(0)->isToken(),"The first one must be the name of the function!");
637 sal_Int32 nTokenId = pPredicateNode->getChild(0)->getTokenID();
638 switch ( nTokenId )
640 case SQL_TOKEN_CHAR_LENGTH:
641 case SQL_TOKEN_LENGTH:
642 case SQL_TOKEN_OCTET_LENGTH:
643 case SQL_TOKEN_ASCII:
644 case SQL_TOKEN_LCASE:
645 case SQL_TOKEN_LTRIM:
646 case SQL_TOKEN_RTRIM:
647 case SQL_TOKEN_SPACE:
648 case SQL_TOKEN_UCASE:
649 case SQL_TOKEN_ABS:
650 case SQL_TOKEN_ACOS:
651 case SQL_TOKEN_ASIN:
652 case SQL_TOKEN_ATAN:
653 case SQL_TOKEN_CEILING:
654 case SQL_TOKEN_COS:
655 case SQL_TOKEN_DEGREES:
656 case SQL_TOKEN_EXP:
657 case SQL_TOKEN_FLOOR:
658 case SQL_TOKEN_LOG10:
659 case SQL_TOKEN_LN:
660 case SQL_TOKEN_RADIANS:
661 case SQL_TOKEN_SIGN:
662 case SQL_TOKEN_SIN:
663 case SQL_TOKEN_SQRT:
664 case SQL_TOKEN_TAN:
665 case SQL_TOKEN_DAYNAME:
666 case SQL_TOKEN_DAYOFMONTH:
667 case SQL_TOKEN_DAYOFWEEK:
668 case SQL_TOKEN_DAYOFYEAR:
669 case SQL_TOKEN_HOUR:
670 case SQL_TOKEN_MINUTE:
671 case SQL_TOKEN_MONTH:
672 case SQL_TOKEN_MONTHNAME:
673 case SQL_TOKEN_QUARTER:
674 case SQL_TOKEN_SECOND:
675 case SQL_TOKEN_YEAR:
677 execute(pPredicateNode->getChild(2));
679 switch( nTokenId )
681 case SQL_TOKEN_CHAR_LENGTH:
682 case SQL_TOKEN_LENGTH:
683 case SQL_TOKEN_OCTET_LENGTH:
684 pOperator = new OOp_CharLength();
685 break;
686 case SQL_TOKEN_ASCII:
687 pOperator = new OOp_Ascii();
688 break;
689 case SQL_TOKEN_LCASE:
690 pOperator = new OOp_Lower();
691 break;
693 case SQL_TOKEN_LTRIM:
694 pOperator = new OOp_LTrim();
695 break;
696 case SQL_TOKEN_RTRIM:
697 pOperator = new OOp_RTrim();
698 break;
699 case SQL_TOKEN_SPACE:
700 pOperator = new OOp_Space();
701 break;
702 case SQL_TOKEN_UCASE:
703 pOperator = new OOp_Upper();
704 break;
705 case SQL_TOKEN_ABS:
706 pOperator = new OOp_Abs();
707 break;
708 case SQL_TOKEN_ACOS:
709 pOperator = new OOp_ACos();
710 break;
711 case SQL_TOKEN_ASIN:
712 pOperator = new OOp_ASin();
713 break;
714 case SQL_TOKEN_ATAN:
715 pOperator = new OOp_ATan();
716 break;
717 case SQL_TOKEN_CEILING:
718 pOperator = new OOp_Ceiling();
719 break;
720 case SQL_TOKEN_COS:
721 pOperator = new OOp_Cos();
722 break;
723 case SQL_TOKEN_DEGREES:
724 pOperator = new OOp_Degrees();
725 break;
726 case SQL_TOKEN_EXP:
727 pOperator = new OOp_Exp();
728 break;
729 case SQL_TOKEN_FLOOR:
730 pOperator = new OOp_Floor();
731 break;
732 case SQL_TOKEN_LOG10:
733 pOperator = new OOp_Log10();
734 break;
735 case SQL_TOKEN_LN:
736 pOperator = new OOp_Ln();
737 break;
738 case SQL_TOKEN_RADIANS:
739 pOperator = new OOp_Radians();
740 break;
741 case SQL_TOKEN_SIGN:
742 pOperator = new OOp_Sign();
743 break;
744 case SQL_TOKEN_SIN:
745 pOperator = new OOp_Sin();
746 break;
747 case SQL_TOKEN_SQRT:
748 pOperator = new OOp_Sqrt();
749 break;
750 case SQL_TOKEN_TAN:
751 pOperator = new OOp_Tan();
752 break;
753 case SQL_TOKEN_DAYOFWEEK:
754 pOperator = new OOp_DayOfWeek();
755 break;
756 case SQL_TOKEN_DAYOFMONTH:
757 pOperator = new OOp_DayOfMonth();
758 break;
759 case SQL_TOKEN_DAYOFYEAR:
760 pOperator = new OOp_DayOfYear();
761 break;
762 case SQL_TOKEN_MONTH:
763 pOperator = new OOp_Month();
764 break;
765 case SQL_TOKEN_DAYNAME:
766 pOperator = new OOp_DayName();
767 break;
768 case SQL_TOKEN_MONTHNAME:
769 pOperator = new OOp_MonthName();
770 break;
771 case SQL_TOKEN_QUARTER:
772 pOperator = new OOp_Quarter();
773 break;
774 case SQL_TOKEN_YEAR:
775 pOperator = new OOp_Year();
776 break;
777 case SQL_TOKEN_HOUR:
778 pOperator = new OOp_Hour();
779 break;
780 case SQL_TOKEN_MINUTE:
781 pOperator = new OOp_Minute();
782 break;
783 case SQL_TOKEN_SECOND:
784 pOperator = new OOp_Second();
785 break;
786 default:
787 OSL_FAIL("Error in switch!");
789 break;
790 case SQL_TOKEN_CHAR:
791 case SQL_TOKEN_CONCAT:
792 case SQL_TOKEN_INSERT:
793 case SQL_TOKEN_LEFT:
794 case SQL_TOKEN_LOCATE:
795 case SQL_TOKEN_LOCATE_2:
796 case SQL_TOKEN_REPEAT:
797 case SQL_TOKEN_REPLACE:
798 case SQL_TOKEN_RIGHT:
799 case SQL_TOKEN_MOD:
800 case SQL_TOKEN_ROUND:
801 case SQL_TOKEN_LOGF:
802 case SQL_TOKEN_LOG:
803 case SQL_TOKEN_POWER:
804 case SQL_TOKEN_ATAN2:
805 case SQL_TOKEN_PI:
806 case SQL_TOKEN_CURDATE:
807 case SQL_TOKEN_CURTIME:
808 case SQL_TOKEN_NOW:
809 case SQL_TOKEN_WEEK:
811 m_aCodeList.push_back(new OStopOperand);
812 OSQLParseNode* pList = pPredicateNode->getChild(2);
813 for (sal_uInt32 i=0; i < pList->count(); ++i)
814 execute(pList->getChild(i));
816 switch( nTokenId )
818 case SQL_TOKEN_CHAR:
819 pOperator = new OOp_Char();
820 break;
821 case SQL_TOKEN_CONCAT:
822 pOperator = new OOp_Concat();
823 break;
824 case SQL_TOKEN_INSERT:
825 pOperator = new OOp_Insert();
826 break;
827 case SQL_TOKEN_LEFT:
828 pOperator = new OOp_Left();
829 break;
830 case SQL_TOKEN_LOCATE:
831 case SQL_TOKEN_LOCATE_2:
832 pOperator = new OOp_Locate();
833 break;
834 case SQL_TOKEN_REPEAT:
835 pOperator = new OOp_Repeat();
836 break;
837 case SQL_TOKEN_REPLACE:
838 pOperator = new OOp_Replace();
839 break;
840 case SQL_TOKEN_RIGHT:
841 pOperator = new OOp_Right();
842 break;
843 case SQL_TOKEN_MOD:
844 pOperator = new OOp_Mod();
845 break;
846 case SQL_TOKEN_ROUND:
847 pOperator = new OOp_Round();
848 break;
849 case SQL_TOKEN_LOGF:
850 case SQL_TOKEN_LOG:
851 pOperator = new OOp_Log();
852 break;
853 case SQL_TOKEN_POWER:
854 pOperator = new OOp_Pow();
855 break;
856 case SQL_TOKEN_ATAN2:
857 pOperator = new OOp_ATan2();
858 break;
859 case SQL_TOKEN_PI:
860 pOperator = new OOp_Pi();
861 break;
862 case SQL_TOKEN_CURDATE:
863 pOperator = new OOp_CurDate();
864 break;
865 case SQL_TOKEN_CURTIME:
866 pOperator = new OOp_CurTime();
867 break;
868 case SQL_TOKEN_NOW:
869 pOperator = new OOp_Now();
870 break;
871 case SQL_TOKEN_WEEK:
872 pOperator = new OOp_Week();
873 break;
874 default:
875 OSL_FAIL("Error in switch!");
878 break;
880 case SQL_TOKEN_SUBSTRING:
881 m_aCodeList.push_back(new OStopOperand);
882 if ( pPredicateNode->count() == 4 ) //char_substring_fct
884 OSQLParseNode* pList = pPredicateNode->getChild(2);
885 for (sal_uInt32 i=0; i < pList->count(); ++i)
886 execute(pList->getChild(i));
888 else
890 execute(pPredicateNode->getChild(2));
891 execute(pPredicateNode->getChild(4));
892 execute(pPredicateNode->getChild(5)->getChild(1));
894 pOperator = new OOp_SubString();
895 break;
897 case SQL_TOKEN_POSITION:
898 m_aCodeList.push_back(new OStopOperand);
899 if ( pPredicateNode->count() == 4 ) //position_exp
901 OSQLParseNode* pList = pPredicateNode->getChild(2);
902 for (sal_uInt32 i=0; i < pList->count(); ++i)
903 execute(pList->getChild(i));
905 else
907 execute(pPredicateNode->getChild(2));
908 execute(pPredicateNode->getChild(4));
910 pOperator = new OOp_Locate();
911 break;
912 default:
913 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED,NULL);
916 m_aCodeList.push_back(pOperator);
917 return NULL;
919 // -----------------------------------------------------------------------------
922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */