1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "file/fcomp.hxx"
21 #include <tools/debug.hxx>
22 #include "TConnection.hxx"
23 #include <connectivity/sqlparse.hxx>
24 #include "file/fanalyzer.hxx"
25 #include <com/sun/star/sdbc/XColumnLocate.hpp>
26 #include <com/sun/star/util/DateTime.hpp>
27 #include <com/sun/star/util/Date.hpp>
28 #include <com/sun/star/util/Time.hpp>
29 #include <connectivity/dbexception.hxx>
30 #include <connectivity/dbconversion.hxx>
31 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
32 #include "resource/file_res.hrc"
33 #include "file/FStringFunctions.hxx"
34 #include "file/FDateFunctions.hxx"
35 #include "file/FNumericFunctions.hxx"
36 #include "file/FConnection.hxx"
37 #include "sqlbison.hxx"
39 using namespace connectivity
;
40 using namespace connectivity::file
;
41 using namespace com::sun::star::uno
;
42 using namespace com::sun::star::sdbc
;
43 using namespace com::sun::star::sdb
;
44 using namespace ::com::sun::star::container
;
45 using namespace com::sun::star
;
47 OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer
* pAnalyzer
)//,OCursor& rCurs)
48 : m_pAnalyzer(pAnalyzer
)
50 , m_bORCondition(false)
55 OPredicateCompiler::~OPredicateCompiler()
60 void OPredicateCompiler::dispose()
67 void OPredicateCompiler::start(OSQLParseNode
* pSQLParseNode
)
73 // analyse Parse Tree (depending on Statement-type)
74 // and set pointer on WHERE-clause:
75 OSQLParseNode
* pWhereClause
= NULL
;
77 if (SQL_ISRULE(pSQLParseNode
,select_statement
))
79 OSQLParseNode
* pOrderbyClause
= NULL
;
80 DBG_ASSERT(pSQLParseNode
->count() >= 4,"OFILECursor: Fehler im Parse Tree");
82 OSQLParseNode
* pTableExp
= pSQLParseNode
->getChild(3);
83 DBG_ASSERT(pTableExp
!= NULL
,"Fehler im Parse Tree");
84 DBG_ASSERT(SQL_ISRULE(pTableExp
,table_exp
)," Fehler im Parse Tree");
85 DBG_ASSERT(pTableExp
->count() == TABLE_EXPRESSION_CHILD_COUNT
,"Fehler im Parse Tree");
87 // check that we don't use anything other than count(*) as function
88 OSQLParseNode
* pSelection
= pSQLParseNode
->getChild(2);
89 if ( SQL_ISRULE(pSelection
,scalar_exp_commalist
) )
91 for (sal_uInt32 i
= 0; i
< pSelection
->count(); i
++)
93 OSQLParseNode
*pColumnRef
= pSelection
->getChild(i
)->getChild(0);
94 if ( SQL_ISRULE(pColumnRef
,general_set_fct
) && pColumnRef
->count() != 4 )
96 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT
,NULL
);
102 pWhereClause
= pTableExp
->getChild(1);
103 pOrderbyClause
= pTableExp
->getChild(ORDER_BY_CHILD_POS
);
104 (void)pOrderbyClause
;
106 else if (SQL_ISRULE(pSQLParseNode
,update_statement_searched
))
108 DBG_ASSERT(pSQLParseNode
->count() == 5,"OFILECursor: Fehler im Parse Tree");
109 pWhereClause
= pSQLParseNode
->getChild(4);
111 else if (SQL_ISRULE(pSQLParseNode
,delete_statement_searched
))
113 DBG_ASSERT(pSQLParseNode
->count() == 4,"Fehler im Parse Tree");
114 pWhereClause
= pSQLParseNode
->getChild(3);
117 // Other Statement. no selection-criteria
120 if (SQL_ISRULE(pWhereClause
,where_clause
))
122 // a where-clause is not allowed to be empty:
123 DBG_ASSERT(pWhereClause
->count() == 2,"OFILECursor: Fehler im Parse Tree");
125 OSQLParseNode
* pComparisonPredicate
= pWhereClause
->getChild(1);
126 DBG_ASSERT(pComparisonPredicate
!= NULL
,"OFILECursor: Fehler im Parse Tree");
128 execute( pComparisonPredicate
);
132 // The where-clause is optionally in the majority of cases, i.e. it might be an "optional-where-clause".
133 DBG_ASSERT(SQL_ISRULE(pWhereClause
,opt_where_clause
),"OPredicateCompiler: Fehler im Parse Tree");
138 OOperand
* OPredicateCompiler::execute(OSQLParseNode
* pPredicateNode
)
140 OOperand
* pOperand
= NULL
;
141 if (pPredicateNode
->count() == 3 && // Expression is bracketed
142 SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"(") &&
143 SQL_ISPUNCTUATION(pPredicateNode
->getChild(2),")"))
145 execute(pPredicateNode
->getChild(1));
147 else if ((SQL_ISRULE(pPredicateNode
,search_condition
) || (SQL_ISRULE(pPredicateNode
,boolean_term
)))
148 && // AND/OR-linkage:
149 pPredicateNode
->count() == 3)
151 execute(pPredicateNode
->getChild(0)); // process the left branch
152 execute(pPredicateNode
->getChild(2)); // process the right branch
154 if (SQL_ISTOKEN(pPredicateNode
->getChild(1),OR
)) // OR-Operator
156 m_aCodeList
.push_back(new OOp_OR());
157 m_bORCondition
= true;
159 else if (SQL_ISTOKEN(pPredicateNode
->getChild(1),AND
)) // AND-Operator
160 m_aCodeList
.push_back(new OOp_AND());
163 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree");
166 else if (SQL_ISRULE(pPredicateNode
,boolean_factor
))
168 execute(pPredicateNode
->getChild(1));
169 m_aCodeList
.push_back(new OOp_NOT());
171 else if (SQL_ISRULE(pPredicateNode
,comparison_predicate
))
173 execute_COMPARE(pPredicateNode
);
175 else if (SQL_ISRULE(pPredicateNode
,like_predicate
))
177 execute_LIKE(pPredicateNode
);
179 else if (SQL_ISRULE(pPredicateNode
,between_predicate
))
181 execute_BETWEEN(pPredicateNode
);
183 else if (SQL_ISRULE(pPredicateNode
,test_for_null
))
185 execute_ISNULL(pPredicateNode
);
187 else if(SQL_ISRULE(pPredicateNode
,num_value_exp
))
189 execute(pPredicateNode
->getChild(0)); // process the left branch
190 execute(pPredicateNode
->getChild(2)); // process the right branch
191 if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"+"))
193 m_aCodeList
.push_back(new OOp_ADD());
195 else if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"-"))
196 m_aCodeList
.push_back(new OOp_SUB());
199 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
202 else if(SQL_ISRULE(pPredicateNode
,term
))
204 execute(pPredicateNode
->getChild(0)); // process the left branch
205 execute(pPredicateNode
->getChild(2)); // process the right branch
206 if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"*"))
208 m_aCodeList
.push_back(new OOp_MUL());
210 else if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"/"))
211 m_aCodeList
.push_back(new OOp_DIV());
214 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
218 pOperand
= execute_Operand(pPredicateNode
); // now only simple operands will be processed
224 OOperand
* OPredicateCompiler::execute_COMPARE(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
226 DBG_ASSERT(pPredicateNode
->count() == 3,"OFILECursor: Fehler im Parse Tree");
228 if ( !(SQL_ISRULE(pPredicateNode
->getChild(0),column_ref
) ||
229 pPredicateNode
->getChild(2)->getNodeType() == SQL_NODE_STRING
||
230 pPredicateNode
->getChild(2)->getNodeType() == SQL_NODE_INTNUM
||
231 pPredicateNode
->getChild(2)->getNodeType() == SQL_NODE_APPROXNUM
||
232 SQL_ISTOKEN(pPredicateNode
->getChild(2),TRUE
) ||
233 SQL_ISTOKEN(pPredicateNode
->getChild(2),FALSE
) ||
234 SQL_ISRULE(pPredicateNode
->getChild(2),parameter
) ||
236 SQL_ISRULE(pPredicateNode
->getChild(2),set_fct_spec
) ||
237 SQL_ISRULE(pPredicateNode
->getChild(2),position_exp
) ||
238 SQL_ISRULE(pPredicateNode
->getChild(2),char_substring_fct
) ||
240 SQL_ISRULE(pPredicateNode
->getChild(2),fold
)) )
242 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
246 sal_Int32
ePredicateType( SQLFilterOperator::EQUAL
);
247 OSQLParseNode
*pPrec
= pPredicateNode
->getChild(1);
249 if (pPrec
->getNodeType() == SQL_NODE_EQUAL
)
250 ePredicateType
= SQLFilterOperator::EQUAL
;
251 else if (pPrec
->getNodeType() == SQL_NODE_NOTEQUAL
)
252 ePredicateType
= SQLFilterOperator::NOT_EQUAL
;
253 else if (pPrec
->getNodeType() == SQL_NODE_LESS
)
254 ePredicateType
= SQLFilterOperator::LESS
;
255 else if (pPrec
->getNodeType() == SQL_NODE_LESSEQ
)
256 ePredicateType
= SQLFilterOperator::LESS_EQUAL
;
257 else if (pPrec
->getNodeType() == SQL_NODE_GREATEQ
)
258 ePredicateType
= SQLFilterOperator::GREATER_EQUAL
;
259 else if (pPrec
->getNodeType() == SQL_NODE_GREAT
)
260 ePredicateType
= SQLFilterOperator::GREATER
;
262 OSL_FAIL( "OPredicateCompiler::execute_COMPARE: unexpected node type!" );
264 execute(pPredicateNode
->getChild(0));
265 execute(pPredicateNode
->getChild(2));
266 m_aCodeList
.push_back( new OOp_COMPARE(ePredicateType
) );
272 OOperand
* OPredicateCompiler::execute_LIKE(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
274 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
275 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
277 sal_Unicode cEscape
= L
'\0';
278 const bool bNotLike
= pPart2
->getChild(0)->isToken();
280 OSQLParseNode
* pAtom
= pPart2
->getChild(pPart2
->count()-2);
281 OSQLParseNode
* pOptEscape
= pPart2
->getChild(pPart2
->count()-1);
283 if (!(pAtom
->getNodeType() == SQL_NODE_STRING
||
284 SQL_ISRULE(pAtom
,parameter
) ||
286 SQL_ISRULE(pAtom
,set_fct_spec
) ||
287 SQL_ISRULE(pAtom
,position_exp
) ||
288 SQL_ISRULE(pAtom
,char_substring_fct
) ||
290 SQL_ISRULE(pAtom
,fold
)) )
292 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
296 if (pOptEscape
->count() != 0)
298 if (pOptEscape
->count() != 2)
300 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,NULL
);
302 OSQLParseNode
*pEscNode
= pOptEscape
->getChild(1);
303 if (pEscNode
->getNodeType() != SQL_NODE_STRING
)
305 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,NULL
);
308 cEscape
= pEscNode
->getTokenValue().toChar();
311 execute(pPredicateNode
->getChild(0));
314 OBoolOperator
* pOperator
= bNotLike
315 ? new OOp_NOTLIKE(cEscape
)
316 : new OOp_LIKE(cEscape
);
317 m_aCodeList
.push_back(pOperator
);
322 OOperand
* OPredicateCompiler::execute_BETWEEN(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
324 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
326 OSQLParseNode
* pColumn
= pPredicateNode
->getChild(0);
327 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
328 OSQLParseNode
* p1stValue
= pPart2
->getChild(2);
329 OSQLParseNode
* p2ndtValue
= pPart2
->getChild(4);
332 !(p1stValue
->getNodeType() == SQL_NODE_STRING
|| SQL_ISRULE(p1stValue
,parameter
))
333 && !(p2ndtValue
->getNodeType() == SQL_NODE_STRING
|| SQL_ISRULE(p2ndtValue
,parameter
))
336 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN
,NULL
);
339 bool bNot
= SQL_ISTOKEN(pPart2
->getChild(0),NOT
);
341 OOperand
* pColumnOp
= execute(pColumn
);
342 OOperand
* pOb1
= execute(p1stValue
);
343 OBoolOperator
* pOperator
= new OOp_COMPARE(bNot
? SQLFilterOperator::LESS_EQUAL
: SQLFilterOperator::GREATER
);
344 m_aCodeList
.push_back(pOperator
);
347 OOperand
* pOb2
= execute(p2ndtValue
);
348 pOperator
= new OOp_COMPARE(bNot
? SQLFilterOperator::GREATER_EQUAL
: SQLFilterOperator::LESS
);
349 m_aCodeList
.push_back(pOperator
);
351 if ( pColumnOp
&& pOb1
&& pOb2
)
353 switch(pColumnOp
->getDBType())
356 case DataType::VARCHAR
:
357 case DataType::LONGVARCHAR
:
358 pOb1
->setValue(pOb1
->getValue().getString());
359 pOb2
->setValue(pOb2
->getValue().getString());
361 case DataType::DECIMAL
:
362 case DataType::NUMERIC
:
363 pOb1
->setValue((double)pOb1
->getValue());
364 pOb2
->setValue((double)pOb2
->getValue());
366 case DataType::FLOAT
:
367 pOb1
->setValue((float)pOb1
->getValue());
368 pOb2
->setValue((float)pOb2
->getValue());
370 case DataType::DOUBLE
:
372 pOb1
->setValue((double)pOb1
->getValue());
373 pOb2
->setValue((double)pOb2
->getValue());
376 pOb1
->setValue(static_cast<util::Date
>(pOb1
->getValue()));
377 pOb2
->setValue(static_cast<util::Date
>(pOb2
->getValue()));
380 pOb1
->setValue(static_cast<util::Time
>(pOb1
->getValue()));
381 pOb2
->setValue(static_cast<util::Time
>(pOb2
->getValue()));
383 case DataType::TIMESTAMP
:
384 pOb1
->setValue(static_cast<util::DateTime
>(pOb1
->getValue()));
385 pOb2
->setValue(static_cast<util::DateTime
>(pOb2
->getValue()));
392 OBoolOperator
* pBoolOp
= NULL
;
394 pBoolOp
= new OOp_OR();
396 pBoolOp
= new OOp_AND();
397 m_aCodeList
.push_back(pBoolOp
);
402 OOperand
* OPredicateCompiler::execute_ISNULL(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
404 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
405 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
406 DBG_ASSERT(SQL_ISTOKEN(pPart2
->getChild(0),IS
),"OFILECursor: Fehler im Parse Tree");
408 sal_Int32 ePredicateType
;
409 if (SQL_ISTOKEN(pPart2
->getChild(1),NOT
))
410 ePredicateType
= SQLFilterOperator::NOT_SQLNULL
;
412 ePredicateType
= SQLFilterOperator::SQLNULL
;
414 execute(pPredicateNode
->getChild(0));
415 OBoolOperator
* pOperator
= (ePredicateType
== SQLFilterOperator::SQLNULL
) ?
416 new OOp_ISNULL() : new OOp_ISNOTNULL();
417 m_aCodeList
.push_back(pOperator
);
422 OOperand
* OPredicateCompiler::execute_Operand(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
424 OOperand
* pOperand
= NULL
;
426 if (SQL_ISRULE(pPredicateNode
,column_ref
))
428 OUString aColumnName
;
429 if (pPredicateNode
->count() == 1)
431 aColumnName
= pPredicateNode
->getChild(0)->getTokenValue();
433 else if (pPredicateNode
->count() == 3)
435 if(SQL_ISRULE(pPredicateNode
->getChild(2),column_val
))
436 aColumnName
= pPredicateNode
->getChild(2)->getChild(0)->getTokenValue();
438 aColumnName
= pPredicateNode
->getChild(2)->getTokenValue();
441 if(!m_orgColumns
->hasByName(aColumnName
))
443 const OUString
sError( m_pAnalyzer
->getConnection()->getResources().getResourceStringWithSubstitution(
444 STR_INVALID_COLUMNNAME
,
445 "$columnname$", aColumnName
447 ::dbtools::throwGenericSQLException( sError
, NULL
);
449 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> xCol
;
452 if (m_orgColumns
->getByName(aColumnName
) >>= xCol
)
454 pOperand
= m_pAnalyzer
->createOperandAttr(Reference
< XColumnLocate
>(m_orgColumns
,UNO_QUERY
)->findColumn(aColumnName
),xCol
,m_xIndexes
);
457 {// Column doesn't exist in the Result-set
458 const OUString
sError( m_pAnalyzer
->getConnection()->getResources().getResourceStringWithSubstitution(
459 STR_INVALID_COLUMNNAME
,
460 "$columnname$", aColumnName
462 ::dbtools::throwGenericSQLException( sError
, NULL
);
467 OSL_FAIL("OPredicateCompiler::execute_Operand Exception");
470 else if (SQL_ISRULE(pPredicateNode
,parameter
))
472 pOperand
= new OOperandParam(pPredicateNode
, ++m_nParamCounter
);
474 else if (pPredicateNode
->getNodeType() == SQL_NODE_STRING
||
475 pPredicateNode
->getNodeType() == SQL_NODE_INTNUM
||
476 pPredicateNode
->getNodeType() == SQL_NODE_APPROXNUM
||
477 pPredicateNode
->getNodeType() == SQL_NODE_NAME
||
478 SQL_ISTOKEN(pPredicateNode
,TRUE
) ||
479 SQL_ISTOKEN(pPredicateNode
,FALSE
) ||
480 SQL_ISRULE(pPredicateNode
,parameter
))
482 pOperand
= new OOperandConst(*pPredicateNode
, pPredicateNode
->getTokenValue());
484 else if((pPredicateNode
->count() == 2) &&
485 (SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"-")) &&
486 pPredicateNode
->getChild(1)->getNodeType() == SQL_NODE_INTNUM
)
487 { // if -1 or +1 is there
488 OUString
aValue(pPredicateNode
->getChild(0)->getTokenValue());
489 aValue
+= pPredicateNode
->getChild(1)->getTokenValue();
490 pOperand
= new OOperandConst(*pPredicateNode
->getChild(1), aValue
);
492 else if( SQL_ISRULE(pPredicateNode
,set_fct_spec
) && SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"{") )
494 const OSQLParseNode
* pODBCNode
= pPredicateNode
->getChild(1);
495 const OSQLParseNode
* pODBCNodeChild
= pODBCNode
->getChild(0);
498 if (pODBCNodeChild
->getNodeType() == SQL_NODE_KEYWORD
&& (
499 SQL_ISTOKEN(pODBCNodeChild
,D
) ||
500 SQL_ISTOKEN(pODBCNodeChild
,T
) ||
501 SQL_ISTOKEN(pODBCNodeChild
,TS
) ))
503 OUString sDateTime
= pODBCNode
->getChild(1)->getTokenValue();
504 pOperand
= new OOperandConst(*pODBCNode
->getChild(1), sDateTime
);
505 if(SQL_ISTOKEN(pODBCNodeChild
,D
))
507 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime
)));
509 else if(SQL_ISTOKEN(pODBCNodeChild
,T
))
511 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime
)));
513 else if(SQL_ISTOKEN(pODBCNodeChild
,TS
))
515 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime
)));
519 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
522 else if( SQL_ISRULE(pPredicateNode
,fold
) )
524 execute_Fold(pPredicateNode
);
526 else if( SQL_ISRULE(pPredicateNode
,set_fct_spec
)
527 || SQL_ISRULE(pPredicateNode
,position_exp
)
528 || SQL_ISRULE(pPredicateNode
,char_substring_fct
)
531 executeFunction(pPredicateNode
);
533 else if( SQL_ISRULE(pPredicateNode
,length_exp
) )
535 executeFunction(pPredicateNode
->getChild(0));
539 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
542 m_aCodeList
.push_back(pOperand
);
547 bool OPredicateInterpreter::evaluate(OCodeList
& rCodeList
)
551 OCodeList::iterator aIter
= rCodeList
.begin();
553 return true; // no Predicate
555 for(;aIter
!= rCodeList
.end();++aIter
)
557 OOperand
* pOperand
= PTR_CAST(OOperand
,(*aIter
));
559 m_aStack
.push(pOperand
);
561 static_cast<OOperator
*>(*aIter
)->Exec(m_aStack
);
564 OOperand
* pOperand
= m_aStack
.top();
567 DBG_ASSERT(m_aStack
.empty(), "StackFehler");
568 DBG_ASSERT(pOperand
, "StackFehler");
570 bResult
= pOperand
->isValid();
571 if (IS_TYPE(OOperandResult
,pOperand
))
576 void OPredicateInterpreter::evaluateSelection(OCodeList
& rCodeList
,ORowSetValueDecoratorRef
& _rVal
)
578 OCodeList::iterator aIter
= rCodeList
.begin();
580 return ; // no Predicate
582 for(;aIter
!= rCodeList
.end();++aIter
)
584 OOperand
* pOperand
= PTR_CAST(OOperand
,(*aIter
));
586 m_aStack
.push(pOperand
);
588 static_cast<OOperator
*>(*aIter
)->Exec(m_aStack
);
591 OOperand
* pOperand
= m_aStack
.top();
594 DBG_ASSERT(m_aStack
.empty(), "StackFehler");
595 DBG_ASSERT(pOperand
, "StackFehler");
597 (*_rVal
) = pOperand
->getValue();
598 if (IS_TYPE(OOperandResult
,pOperand
))
602 OOperand
* OPredicateCompiler::execute_Fold(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
604 DBG_ASSERT(pPredicateNode
->count() >= 4,"OFILECursor: Fehler im Parse Tree");
606 bool bUpper
= SQL_ISTOKEN(pPredicateNode
->getChild(0),UPPER
);
608 execute(pPredicateNode
->getChild(2));
609 OOperator
* pOperator
= NULL
;
611 pOperator
= new OOp_Upper();
613 pOperator
= new OOp_Lower();
615 m_aCodeList
.push_back(pOperator
);
619 OOperand
* OPredicateCompiler::executeFunction(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
621 OOperator
* pOperator
= NULL
;
623 OSL_ENSURE(pPredicateNode
->getChild(0)->isToken(),"The first one must be the name of the function!");
624 sal_Int32 nTokenId
= pPredicateNode
->getChild(0)->getTokenID();
627 case SQL_TOKEN_CHAR_LENGTH
:
628 case SQL_TOKEN_LENGTH
:
629 case SQL_TOKEN_OCTET_LENGTH
:
630 case SQL_TOKEN_ASCII
:
631 case SQL_TOKEN_LCASE
:
632 case SQL_TOKEN_LTRIM
:
633 case SQL_TOKEN_RTRIM
:
634 case SQL_TOKEN_SPACE
:
635 case SQL_TOKEN_UCASE
:
640 case SQL_TOKEN_CEILING
:
642 case SQL_TOKEN_DEGREES
:
644 case SQL_TOKEN_FLOOR
:
645 case SQL_TOKEN_LOG10
:
647 case SQL_TOKEN_RADIANS
:
652 case SQL_TOKEN_DAYNAME
:
653 case SQL_TOKEN_DAYOFMONTH
:
654 case SQL_TOKEN_DAYOFWEEK
:
655 case SQL_TOKEN_DAYOFYEAR
:
657 case SQL_TOKEN_MINUTE
:
658 case SQL_TOKEN_MONTH
:
659 case SQL_TOKEN_MONTHNAME
:
660 case SQL_TOKEN_QUARTER
:
661 case SQL_TOKEN_SECOND
:
664 execute(pPredicateNode
->getChild(2));
668 case SQL_TOKEN_CHAR_LENGTH
:
669 case SQL_TOKEN_LENGTH
:
670 case SQL_TOKEN_OCTET_LENGTH
:
671 pOperator
= new OOp_CharLength();
673 case SQL_TOKEN_ASCII
:
674 pOperator
= new OOp_Ascii();
676 case SQL_TOKEN_LCASE
:
677 pOperator
= new OOp_Lower();
680 case SQL_TOKEN_LTRIM
:
681 pOperator
= new OOp_LTrim();
683 case SQL_TOKEN_RTRIM
:
684 pOperator
= new OOp_RTrim();
686 case SQL_TOKEN_SPACE
:
687 pOperator
= new OOp_Space();
689 case SQL_TOKEN_UCASE
:
690 pOperator
= new OOp_Upper();
693 pOperator
= new OOp_Abs();
696 pOperator
= new OOp_ACos();
699 pOperator
= new OOp_ASin();
702 pOperator
= new OOp_ATan();
704 case SQL_TOKEN_CEILING
:
705 pOperator
= new OOp_Ceiling();
708 pOperator
= new OOp_Cos();
710 case SQL_TOKEN_DEGREES
:
711 pOperator
= new OOp_Degrees();
714 pOperator
= new OOp_Exp();
716 case SQL_TOKEN_FLOOR
:
717 pOperator
= new OOp_Floor();
719 case SQL_TOKEN_LOG10
:
720 pOperator
= new OOp_Log10();
723 pOperator
= new OOp_Ln();
725 case SQL_TOKEN_RADIANS
:
726 pOperator
= new OOp_Radians();
729 pOperator
= new OOp_Sign();
732 pOperator
= new OOp_Sin();
735 pOperator
= new OOp_Sqrt();
738 pOperator
= new OOp_Tan();
740 case SQL_TOKEN_DAYOFWEEK
:
741 pOperator
= new OOp_DayOfWeek();
743 case SQL_TOKEN_DAYOFMONTH
:
744 pOperator
= new OOp_DayOfMonth();
746 case SQL_TOKEN_DAYOFYEAR
:
747 pOperator
= new OOp_DayOfYear();
749 case SQL_TOKEN_MONTH
:
750 pOperator
= new OOp_Month();
752 case SQL_TOKEN_DAYNAME
:
753 pOperator
= new OOp_DayName();
755 case SQL_TOKEN_MONTHNAME
:
756 pOperator
= new OOp_MonthName();
758 case SQL_TOKEN_QUARTER
:
759 pOperator
= new OOp_Quarter();
762 pOperator
= new OOp_Year();
765 pOperator
= new OOp_Hour();
767 case SQL_TOKEN_MINUTE
:
768 pOperator
= new OOp_Minute();
770 case SQL_TOKEN_SECOND
:
771 pOperator
= new OOp_Second();
774 OSL_FAIL("Error in switch!");
778 case SQL_TOKEN_CONCAT
:
779 case SQL_TOKEN_INSERT
:
781 case SQL_TOKEN_LOCATE
:
782 case SQL_TOKEN_LOCATE_2
:
783 case SQL_TOKEN_REPEAT
:
784 case SQL_TOKEN_REPLACE
:
785 case SQL_TOKEN_RIGHT
:
787 case SQL_TOKEN_ROUND
:
790 case SQL_TOKEN_POWER
:
791 case SQL_TOKEN_ATAN2
:
793 case SQL_TOKEN_CURDATE
:
794 case SQL_TOKEN_CURTIME
:
798 m_aCodeList
.push_back(new OStopOperand
);
799 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
800 for (sal_uInt32 i
=0; i
< pList
->count(); ++i
)
801 execute(pList
->getChild(i
));
806 pOperator
= new OOp_Char();
808 case SQL_TOKEN_CONCAT
:
809 pOperator
= new OOp_Concat();
811 case SQL_TOKEN_INSERT
:
812 pOperator
= new OOp_Insert();
815 pOperator
= new OOp_Left();
817 case SQL_TOKEN_LOCATE
:
818 case SQL_TOKEN_LOCATE_2
:
819 pOperator
= new OOp_Locate();
821 case SQL_TOKEN_REPEAT
:
822 pOperator
= new OOp_Repeat();
824 case SQL_TOKEN_REPLACE
:
825 pOperator
= new OOp_Replace();
827 case SQL_TOKEN_RIGHT
:
828 pOperator
= new OOp_Right();
831 pOperator
= new OOp_Mod();
833 case SQL_TOKEN_ROUND
:
834 pOperator
= new OOp_Round();
838 pOperator
= new OOp_Log();
840 case SQL_TOKEN_POWER
:
841 pOperator
= new OOp_Pow();
843 case SQL_TOKEN_ATAN2
:
844 pOperator
= new OOp_ATan2();
847 pOperator
= new OOp_Pi();
849 case SQL_TOKEN_CURDATE
:
850 pOperator
= new OOp_CurDate();
852 case SQL_TOKEN_CURTIME
:
853 pOperator
= new OOp_CurTime();
856 pOperator
= new OOp_Now();
859 pOperator
= new OOp_Week();
862 OSL_FAIL("Error in switch!");
867 case SQL_TOKEN_SUBSTRING
:
868 m_aCodeList
.push_back(new OStopOperand
);
869 if ( pPredicateNode
->count() == 4 ) //char_substring_fct
871 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
872 for (sal_uInt32 i
=0; i
< pList
->count(); ++i
)
873 execute(pList
->getChild(i
));
877 execute(pPredicateNode
->getChild(2));
878 execute(pPredicateNode
->getChild(4));
879 execute(pPredicateNode
->getChild(5)->getChild(1));
881 pOperator
= new OOp_SubString();
884 case SQL_TOKEN_POSITION
:
885 m_aCodeList
.push_back(new OStopOperand
);
886 if ( pPredicateNode
->count() == 4 ) //position_exp
888 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
889 for (sal_uInt32 i
=0; i
< pList
->count(); ++i
)
890 execute(pList
->getChild(i
));
894 execute(pPredicateNode
->getChild(2));
895 execute(pPredicateNode
->getChild(4));
897 pOperator
= new OOp_Locate();
900 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED
,NULL
);
903 m_aCodeList
.push_back(pOperator
);
909 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */