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
)
60 , m_bORCondition(sal_False
)
62 DBG_CTOR(OPredicateCompiler
,NULL
);
65 //------------------------------------------------------------------
66 OPredicateCompiler::~OPredicateCompiler()
69 DBG_DTOR(OPredicateCompiler
,NULL
);
71 // -----------------------------------------------------------------------------
72 void OPredicateCompiler::dispose()
79 void OPredicateCompiler::start(OSQLParseNode
* pSQLParseNode
)
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);
129 // Other Statement. no selection-criteria
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
);
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());
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());
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());
226 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
230 pOperand
= execute_Operand(pPredicateNode
); // now only simple operands will be processed
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
) ||
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
) ||
252 SQL_ISRULE(pPredicateNode
->getChild(2),fold
)) )
254 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,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
;
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
) );
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
) ||
298 SQL_ISRULE(pAtom
,set_fct_spec
) ||
299 SQL_ISRULE(pAtom
,position_exp
) ||
300 SQL_ISRULE(pAtom
,char_substring_fct
) ||
302 SQL_ISRULE(pAtom
,fold
)) )
304 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,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
);
320 cEscape
= pEscNode
->getTokenValue().toChar();
323 execute(pPredicateNode
->getChild(0));
326 OBoolOperator
* pOperator
= bNotLike
327 ? new OOp_NOTLIKE(cEscape
)
328 : new OOp_LIKE(cEscape
);
329 m_aCodeList
.push_back(pOperator
);
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);
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
);
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())
368 case DataType::VARCHAR
:
369 case DataType::LONGVARCHAR
:
370 pOb1
->setValue(pOb1
->getValue().getString());
371 pOb2
->setValue(pOb2
->getValue().getString());
373 case DataType::DECIMAL
:
374 case DataType::NUMERIC
:
375 pOb1
->setValue((double)pOb1
->getValue());
376 pOb2
->setValue((double)pOb2
->getValue());
378 case DataType::FLOAT
:
379 pOb1
->setValue((float)pOb1
->getValue());
380 pOb2
->setValue((float)pOb2
->getValue());
382 case DataType::DOUBLE
:
384 pOb1
->setValue((double)pOb1
->getValue());
385 pOb2
->setValue((double)pOb2
->getValue());
388 pOb1
->setValue((Date
)pOb1
->getValue());
389 pOb2
->setValue((Date
)pOb2
->getValue());
392 pOb1
->setValue((Time
)pOb1
->getValue());
393 pOb2
->setValue((Time
)pOb2
->getValue());
395 case DataType::TIMESTAMP
:
396 pOb1
->setValue((DateTime
)pOb1
->getValue());
397 pOb2
->setValue((DateTime
)pOb2
->getValue());
404 OBoolOperator
* pBoolOp
= NULL
;
406 pBoolOp
= new OOp_OR();
408 pBoolOp
= new OOp_AND();
409 m_aCodeList
.push_back(pBoolOp
);
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
;
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
);
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();
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
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
);
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
475 ::dbtools::throwGenericSQLException( sError
, NULL
);
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);
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
)));
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));
552 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
555 m_aCodeList
.push_back(pOperand
);
559 ////////////////////////////////////////////////////////////////////////////////////////
560 sal_Bool
OPredicateInterpreter::evaluate(OCodeList
& rCodeList
)
562 static sal_Bool bResult
;
564 OCodeList::iterator aIter
= rCodeList
.begin();
566 return sal_True
; // no Predicate
568 for(;aIter
!= rCodeList
.end();++aIter
)
570 OOperand
* pOperand
= PTR_CAST(OOperand
,(*aIter
));
572 m_aStack
.push(pOperand
);
574 ((OOperator
*)(*aIter
))->Exec(m_aStack
);
577 OOperand
* pOperand
= m_aStack
.top();
580 DBG_ASSERT(m_aStack
.empty(), "StackFehler");
581 DBG_ASSERT(pOperand
, "StackFehler");
583 bResult
= pOperand
->isValid();
584 if (IS_TYPE(OOperandResult
,pOperand
))
588 // -----------------------------------------------------------------------------
589 void OPredicateInterpreter::evaluateSelection(OCodeList
& rCodeList
,ORowSetValueDecoratorRef
& _rVal
)
591 OCodeList::iterator aIter
= rCodeList
.begin();
593 return ; // no Predicate
595 for(;aIter
!= rCodeList
.end();++aIter
)
597 OOperand
* pOperand
= PTR_CAST(OOperand
,(*aIter
));
599 m_aStack
.push(pOperand
);
601 ((OOperator
*)(*aIter
))->Exec(m_aStack
);
604 OOperand
* pOperand
= m_aStack
.top();
607 DBG_ASSERT(m_aStack
.empty(), "StackFehler");
608 DBG_ASSERT(pOperand
, "StackFehler");
610 (*_rVal
) = pOperand
->getValue();
611 if (IS_TYPE(OOperandResult
,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
;
624 pOperator
= new OOp_Upper();
626 pOperator
= new OOp_Lower();
628 m_aCodeList
.push_back(pOperator
);
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();
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
:
653 case SQL_TOKEN_CEILING
:
655 case SQL_TOKEN_DEGREES
:
657 case SQL_TOKEN_FLOOR
:
658 case SQL_TOKEN_LOG10
:
660 case SQL_TOKEN_RADIANS
:
665 case SQL_TOKEN_DAYNAME
:
666 case SQL_TOKEN_DAYOFMONTH
:
667 case SQL_TOKEN_DAYOFWEEK
:
668 case SQL_TOKEN_DAYOFYEAR
:
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
:
677 execute(pPredicateNode
->getChild(2));
681 case SQL_TOKEN_CHAR_LENGTH
:
682 case SQL_TOKEN_LENGTH
:
683 case SQL_TOKEN_OCTET_LENGTH
:
684 pOperator
= new OOp_CharLength();
686 case SQL_TOKEN_ASCII
:
687 pOperator
= new OOp_Ascii();
689 case SQL_TOKEN_LCASE
:
690 pOperator
= new OOp_Lower();
693 case SQL_TOKEN_LTRIM
:
694 pOperator
= new OOp_LTrim();
696 case SQL_TOKEN_RTRIM
:
697 pOperator
= new OOp_RTrim();
699 case SQL_TOKEN_SPACE
:
700 pOperator
= new OOp_Space();
702 case SQL_TOKEN_UCASE
:
703 pOperator
= new OOp_Upper();
706 pOperator
= new OOp_Abs();
709 pOperator
= new OOp_ACos();
712 pOperator
= new OOp_ASin();
715 pOperator
= new OOp_ATan();
717 case SQL_TOKEN_CEILING
:
718 pOperator
= new OOp_Ceiling();
721 pOperator
= new OOp_Cos();
723 case SQL_TOKEN_DEGREES
:
724 pOperator
= new OOp_Degrees();
727 pOperator
= new OOp_Exp();
729 case SQL_TOKEN_FLOOR
:
730 pOperator
= new OOp_Floor();
732 case SQL_TOKEN_LOG10
:
733 pOperator
= new OOp_Log10();
736 pOperator
= new OOp_Ln();
738 case SQL_TOKEN_RADIANS
:
739 pOperator
= new OOp_Radians();
742 pOperator
= new OOp_Sign();
745 pOperator
= new OOp_Sin();
748 pOperator
= new OOp_Sqrt();
751 pOperator
= new OOp_Tan();
753 case SQL_TOKEN_DAYOFWEEK
:
754 pOperator
= new OOp_DayOfWeek();
756 case SQL_TOKEN_DAYOFMONTH
:
757 pOperator
= new OOp_DayOfMonth();
759 case SQL_TOKEN_DAYOFYEAR
:
760 pOperator
= new OOp_DayOfYear();
762 case SQL_TOKEN_MONTH
:
763 pOperator
= new OOp_Month();
765 case SQL_TOKEN_DAYNAME
:
766 pOperator
= new OOp_DayName();
768 case SQL_TOKEN_MONTHNAME
:
769 pOperator
= new OOp_MonthName();
771 case SQL_TOKEN_QUARTER
:
772 pOperator
= new OOp_Quarter();
775 pOperator
= new OOp_Year();
778 pOperator
= new OOp_Hour();
780 case SQL_TOKEN_MINUTE
:
781 pOperator
= new OOp_Minute();
783 case SQL_TOKEN_SECOND
:
784 pOperator
= new OOp_Second();
787 OSL_FAIL("Error in switch!");
791 case SQL_TOKEN_CONCAT
:
792 case SQL_TOKEN_INSERT
:
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
:
800 case SQL_TOKEN_ROUND
:
803 case SQL_TOKEN_POWER
:
804 case SQL_TOKEN_ATAN2
:
806 case SQL_TOKEN_CURDATE
:
807 case SQL_TOKEN_CURTIME
:
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
));
819 pOperator
= new OOp_Char();
821 case SQL_TOKEN_CONCAT
:
822 pOperator
= new OOp_Concat();
824 case SQL_TOKEN_INSERT
:
825 pOperator
= new OOp_Insert();
828 pOperator
= new OOp_Left();
830 case SQL_TOKEN_LOCATE
:
831 case SQL_TOKEN_LOCATE_2
:
832 pOperator
= new OOp_Locate();
834 case SQL_TOKEN_REPEAT
:
835 pOperator
= new OOp_Repeat();
837 case SQL_TOKEN_REPLACE
:
838 pOperator
= new OOp_Replace();
840 case SQL_TOKEN_RIGHT
:
841 pOperator
= new OOp_Right();
844 pOperator
= new OOp_Mod();
846 case SQL_TOKEN_ROUND
:
847 pOperator
= new OOp_Round();
851 pOperator
= new OOp_Log();
853 case SQL_TOKEN_POWER
:
854 pOperator
= new OOp_Pow();
856 case SQL_TOKEN_ATAN2
:
857 pOperator
= new OOp_ATan2();
860 pOperator
= new OOp_Pi();
862 case SQL_TOKEN_CURDATE
:
863 pOperator
= new OOp_CurDate();
865 case SQL_TOKEN_CURTIME
:
866 pOperator
= new OOp_CurTime();
869 pOperator
= new OOp_Now();
872 pOperator
= new OOp_Week();
875 OSL_FAIL("Error in switch!");
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
));
890 execute(pPredicateNode
->getChild(2));
891 execute(pPredicateNode
->getChild(4));
892 execute(pPredicateNode
->getChild(5)->getChild(1));
894 pOperator
= new OOp_SubString();
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
));
907 execute(pPredicateNode
->getChild(2));
908 execute(pPredicateNode
->getChild(4));
910 pOperator
= new OOp_Locate();
913 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED
,NULL
);
916 m_aCodeList
.push_back(pOperator
);
919 // -----------------------------------------------------------------------------
922 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */