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"
38 using namespace connectivity
;
39 using namespace connectivity::file
;
40 using namespace com::sun::star::uno
;
41 using namespace com::sun::star::sdbc
;
42 using namespace com::sun::star::sdb
;
43 using namespace ::com::sun::star::container
;
44 using namespace com::sun::star
;
46 OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer
* pAnalyzer
)//,OCursor& rCurs)
47 : m_pAnalyzer(pAnalyzer
)
49 , m_bORCondition(false)
54 OPredicateCompiler::~OPredicateCompiler()
59 void OPredicateCompiler::dispose()
66 void OPredicateCompiler::start(OSQLParseNode
* pSQLParseNode
)
72 // analyse Parse Tree (depending on Statement-type)
73 // and set pointer on WHERE-clause:
74 OSQLParseNode
* pWhereClause
= NULL
;
75 OSQLParseNode
* pOrderbyClause
= NULL
;
77 if (SQL_ISRULE(pSQLParseNode
,select_statement
))
79 DBG_ASSERT(pSQLParseNode
->count() >= 4,"OFILECursor: Fehler im Parse Tree");
81 OSQLParseNode
* pTableExp
= pSQLParseNode
->getChild(3);
82 DBG_ASSERT(pTableExp
!= NULL
,"Fehler im Parse Tree");
83 DBG_ASSERT(SQL_ISRULE(pTableExp
,table_exp
)," Fehler im Parse Tree");
84 DBG_ASSERT(pTableExp
->count() == TABLE_EXPRESSION_CHILD_COUNT
,"Fehler im Parse Tree");
86 // check that we don't use anything other than count(*) as function
87 OSQLParseNode
* pSelection
= pSQLParseNode
->getChild(2);
88 if ( SQL_ISRULE(pSelection
,scalar_exp_commalist
) )
90 for (sal_uInt32 i
= 0; i
< pSelection
->count(); i
++)
92 OSQLParseNode
*pColumnRef
= pSelection
->getChild(i
)->getChild(0);
93 if ( SQL_ISRULE(pColumnRef
,general_set_fct
) && pColumnRef
->count() != 4 )
95 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT
,NULL
);
101 pWhereClause
= pTableExp
->getChild(1);
102 pOrderbyClause
= pTableExp
->getChild(ORDER_BY_CHILD_POS
);
103 (void)pOrderbyClause
;
105 else if (SQL_ISRULE(pSQLParseNode
,update_statement_searched
))
107 DBG_ASSERT(pSQLParseNode
->count() == 5,"OFILECursor: Fehler im Parse Tree");
108 pWhereClause
= pSQLParseNode
->getChild(4);
110 else if (SQL_ISRULE(pSQLParseNode
,delete_statement_searched
))
112 DBG_ASSERT(pSQLParseNode
->count() == 4,"Fehler im Parse Tree");
113 pWhereClause
= pSQLParseNode
->getChild(3);
116 // Other Statement. no selection-criteria
119 if (SQL_ISRULE(pWhereClause
,where_clause
))
121 // a where-clause is not allowed to be empty:
122 DBG_ASSERT(pWhereClause
->count() == 2,"OFILECursor: Fehler im Parse Tree");
124 OSQLParseNode
* pComparisonPredicate
= pWhereClause
->getChild(1);
125 DBG_ASSERT(pComparisonPredicate
!= NULL
,"OFILECursor: Fehler im Parse Tree");
127 execute( pComparisonPredicate
);
131 // The where-clause is optionally in the majority of cases, i.e. it might be an "optional-where-clause".
132 DBG_ASSERT(SQL_ISRULE(pWhereClause
,opt_where_clause
),"OPredicateCompiler: Fehler im Parse Tree");
137 OOperand
* OPredicateCompiler::execute(OSQLParseNode
* pPredicateNode
)
139 OOperand
* pOperand
= NULL
;
140 if (pPredicateNode
->count() == 3 && // Expression is bracketed
141 SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"(") &&
142 SQL_ISPUNCTUATION(pPredicateNode
->getChild(2),")"))
144 execute(pPredicateNode
->getChild(1));
146 else if ((SQL_ISRULE(pPredicateNode
,search_condition
) || (SQL_ISRULE(pPredicateNode
,boolean_term
)))
147 && // AND/OR-linkage:
148 pPredicateNode
->count() == 3)
150 execute(pPredicateNode
->getChild(0)); // process the left branch
151 execute(pPredicateNode
->getChild(2)); // process the right branch
153 if (SQL_ISTOKEN(pPredicateNode
->getChild(1),OR
)) // OR-Operator
155 m_aCodeList
.push_back(new OOp_OR());
156 m_bORCondition
= true;
158 else if (SQL_ISTOKEN(pPredicateNode
->getChild(1),AND
)) // AND-Operator
159 m_aCodeList
.push_back(new OOp_AND());
162 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree");
165 else if (SQL_ISRULE(pPredicateNode
,boolean_factor
))
167 execute(pPredicateNode
->getChild(1));
168 m_aCodeList
.push_back(new OOp_NOT());
170 else if (SQL_ISRULE(pPredicateNode
,comparison_predicate
))
172 execute_COMPARE(pPredicateNode
);
174 else if (SQL_ISRULE(pPredicateNode
,like_predicate
))
176 execute_LIKE(pPredicateNode
);
178 else if (SQL_ISRULE(pPredicateNode
,between_predicate
))
180 execute_BETWEEN(pPredicateNode
);
182 else if (SQL_ISRULE(pPredicateNode
,test_for_null
))
184 execute_ISNULL(pPredicateNode
);
186 else if(SQL_ISRULE(pPredicateNode
,num_value_exp
))
188 execute(pPredicateNode
->getChild(0)); // process the left branch
189 execute(pPredicateNode
->getChild(2)); // process the right branch
190 if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"+"))
192 m_aCodeList
.push_back(new OOp_ADD());
194 else if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"-"))
195 m_aCodeList
.push_back(new OOp_SUB());
198 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
201 else if(SQL_ISRULE(pPredicateNode
,term
))
203 execute(pPredicateNode
->getChild(0)); // process the left branch
204 execute(pPredicateNode
->getChild(2)); // process the right branch
205 if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"*"))
207 m_aCodeList
.push_back(new OOp_MUL());
209 else if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"/"))
210 m_aCodeList
.push_back(new OOp_DIV());
213 OSL_FAIL("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
217 pOperand
= execute_Operand(pPredicateNode
); // now only simple operands will be processed
223 OOperand
* OPredicateCompiler::execute_COMPARE(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
225 DBG_ASSERT(pPredicateNode
->count() == 3,"OFILECursor: Fehler im Parse Tree");
227 if ( !(SQL_ISRULE(pPredicateNode
->getChild(0),column_ref
) ||
228 pPredicateNode
->getChild(2)->getNodeType() == SQL_NODE_STRING
||
229 pPredicateNode
->getChild(2)->getNodeType() == SQL_NODE_INTNUM
||
230 pPredicateNode
->getChild(2)->getNodeType() == SQL_NODE_APPROXNUM
||
231 SQL_ISTOKEN(pPredicateNode
->getChild(2),TRUE
) ||
232 SQL_ISTOKEN(pPredicateNode
->getChild(2),FALSE
) ||
233 SQL_ISRULE(pPredicateNode
->getChild(2),parameter
) ||
235 SQL_ISRULE(pPredicateNode
->getChild(2),set_fct_spec
) ||
236 SQL_ISRULE(pPredicateNode
->getChild(2),position_exp
) ||
237 SQL_ISRULE(pPredicateNode
->getChild(2),char_substring_fct
) ||
239 SQL_ISRULE(pPredicateNode
->getChild(2),fold
)) )
241 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
245 sal_Int32
ePredicateType( SQLFilterOperator::EQUAL
);
246 OSQLParseNode
*pPrec
= pPredicateNode
->getChild(1);
248 if (pPrec
->getNodeType() == SQL_NODE_EQUAL
)
249 ePredicateType
= SQLFilterOperator::EQUAL
;
250 else if (pPrec
->getNodeType() == SQL_NODE_NOTEQUAL
)
251 ePredicateType
= SQLFilterOperator::NOT_EQUAL
;
252 else if (pPrec
->getNodeType() == SQL_NODE_LESS
)
253 ePredicateType
= SQLFilterOperator::LESS
;
254 else if (pPrec
->getNodeType() == SQL_NODE_LESSEQ
)
255 ePredicateType
= SQLFilterOperator::LESS_EQUAL
;
256 else if (pPrec
->getNodeType() == SQL_NODE_GREATEQ
)
257 ePredicateType
= SQLFilterOperator::GREATER_EQUAL
;
258 else if (pPrec
->getNodeType() == SQL_NODE_GREAT
)
259 ePredicateType
= SQLFilterOperator::GREATER
;
261 OSL_FAIL( "OPredicateCompiler::execute_COMPARE: unexpected node type!" );
263 execute(pPredicateNode
->getChild(0));
264 execute(pPredicateNode
->getChild(2));
265 m_aCodeList
.push_back( new OOp_COMPARE(ePredicateType
) );
271 OOperand
* OPredicateCompiler::execute_LIKE(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
273 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
274 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
276 sal_Unicode cEscape
= L
'\0';
277 const bool bNotLike
= pPart2
->getChild(0)->isToken();
279 OSQLParseNode
* pAtom
= pPart2
->getChild(pPart2
->count()-2);
280 OSQLParseNode
* pOptEscape
= pPart2
->getChild(pPart2
->count()-1);
282 if (!(pAtom
->getNodeType() == SQL_NODE_STRING
||
283 SQL_ISRULE(pAtom
,parameter
) ||
285 SQL_ISRULE(pAtom
,set_fct_spec
) ||
286 SQL_ISRULE(pAtom
,position_exp
) ||
287 SQL_ISRULE(pAtom
,char_substring_fct
) ||
289 SQL_ISRULE(pAtom
,fold
)) )
291 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
295 if (pOptEscape
->count() != 0)
297 if (pOptEscape
->count() != 2)
299 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,NULL
);
301 OSQLParseNode
*pEscNode
= pOptEscape
->getChild(1);
302 if (pEscNode
->getNodeType() != SQL_NODE_STRING
)
304 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,NULL
);
307 cEscape
= pEscNode
->getTokenValue().toChar();
310 execute(pPredicateNode
->getChild(0));
313 OBoolOperator
* pOperator
= bNotLike
314 ? new OOp_NOTLIKE(cEscape
)
315 : new OOp_LIKE(cEscape
);
316 m_aCodeList
.push_back(pOperator
);
321 OOperand
* OPredicateCompiler::execute_BETWEEN(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
323 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
325 OSQLParseNode
* pColumn
= pPredicateNode
->getChild(0);
326 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
327 OSQLParseNode
* p1stValue
= pPart2
->getChild(2);
328 OSQLParseNode
* p2ndtValue
= pPart2
->getChild(4);
331 !(p1stValue
->getNodeType() == SQL_NODE_STRING
|| SQL_ISRULE(p1stValue
,parameter
))
332 && !(p2ndtValue
->getNodeType() == SQL_NODE_STRING
|| SQL_ISRULE(p2ndtValue
,parameter
))
335 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN
,NULL
);
338 bool bNot
= SQL_ISTOKEN(pPart2
->getChild(0),NOT
);
340 OOperand
* pColumnOp
= execute(pColumn
);
341 OOperand
* pOb1
= execute(p1stValue
);
342 OBoolOperator
* pOperator
= new OOp_COMPARE(bNot
? SQLFilterOperator::LESS_EQUAL
: SQLFilterOperator::GREATER
);
343 m_aCodeList
.push_back(pOperator
);
346 OOperand
* pOb2
= execute(p2ndtValue
);
347 pOperator
= new OOp_COMPARE(bNot
? SQLFilterOperator::GREATER_EQUAL
: SQLFilterOperator::LESS
);
348 m_aCodeList
.push_back(pOperator
);
350 if ( pColumnOp
&& pOb1
&& pOb2
)
352 switch(pColumnOp
->getDBType())
355 case DataType::VARCHAR
:
356 case DataType::LONGVARCHAR
:
357 pOb1
->setValue(pOb1
->getValue().getString());
358 pOb2
->setValue(pOb2
->getValue().getString());
360 case DataType::DECIMAL
:
361 case DataType::NUMERIC
:
362 pOb1
->setValue((double)pOb1
->getValue());
363 pOb2
->setValue((double)pOb2
->getValue());
365 case DataType::FLOAT
:
366 pOb1
->setValue((float)pOb1
->getValue());
367 pOb2
->setValue((float)pOb2
->getValue());
369 case DataType::DOUBLE
:
371 pOb1
->setValue((double)pOb1
->getValue());
372 pOb2
->setValue((double)pOb2
->getValue());
375 pOb1
->setValue((util::Date
)pOb1
->getValue());
376 pOb2
->setValue((util::Date
)pOb2
->getValue());
379 pOb1
->setValue((util::Time
)pOb1
->getValue());
380 pOb2
->setValue((util::Time
)pOb2
->getValue());
382 case DataType::TIMESTAMP
:
383 pOb1
->setValue((util::DateTime
)pOb1
->getValue());
384 pOb2
->setValue((util::DateTime
)pOb2
->getValue());
391 OBoolOperator
* pBoolOp
= NULL
;
393 pBoolOp
= new OOp_OR();
395 pBoolOp
= new OOp_AND();
396 m_aCodeList
.push_back(pBoolOp
);
401 OOperand
* OPredicateCompiler::execute_ISNULL(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
403 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
404 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
405 DBG_ASSERT(SQL_ISTOKEN(pPart2
->getChild(0),IS
),"OFILECursor: Fehler im Parse Tree");
407 sal_Int32 ePredicateType
;
408 if (SQL_ISTOKEN(pPart2
->getChild(1),NOT
))
409 ePredicateType
= SQLFilterOperator::NOT_SQLNULL
;
411 ePredicateType
= SQLFilterOperator::SQLNULL
;
413 execute(pPredicateNode
->getChild(0));
414 OBoolOperator
* pOperator
= (ePredicateType
== SQLFilterOperator::SQLNULL
) ?
415 new OOp_ISNULL() : new OOp_ISNOTNULL();
416 m_aCodeList
.push_back(pOperator
);
421 OOperand
* OPredicateCompiler::execute_Operand(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
423 OOperand
* pOperand
= NULL
;
425 if (SQL_ISRULE(pPredicateNode
,column_ref
))
427 OUString aColumnName
;
428 if (pPredicateNode
->count() == 1)
430 aColumnName
= pPredicateNode
->getChild(0)->getTokenValue();
432 else if (pPredicateNode
->count() == 3)
434 if(SQL_ISRULE(pPredicateNode
->getChild(2),column_val
))
435 aColumnName
= pPredicateNode
->getChild(2)->getChild(0)->getTokenValue();
437 aColumnName
= pPredicateNode
->getChild(2)->getTokenValue();
440 if(!m_orgColumns
->hasByName(aColumnName
))
442 const OUString
sError( m_pAnalyzer
->getConnection()->getResources().getResourceStringWithSubstitution(
443 STR_INVALID_COLUMNNAME
,
444 "$columnname$", aColumnName
446 ::dbtools::throwGenericSQLException( sError
, NULL
);
448 ::com::sun::star::uno::Reference
< ::com::sun::star::beans::XPropertySet
> xCol
;
451 if (m_orgColumns
->getByName(aColumnName
) >>= xCol
)
453 pOperand
= m_pAnalyzer
->createOperandAttr(Reference
< XColumnLocate
>(m_orgColumns
,UNO_QUERY
)->findColumn(aColumnName
),xCol
,m_xIndexes
);
456 {// Column doesn't exist in the Result-set
457 const OUString
sError( m_pAnalyzer
->getConnection()->getResources().getResourceStringWithSubstitution(
458 STR_INVALID_COLUMNNAME
,
459 "$columnname$", aColumnName
461 ::dbtools::throwGenericSQLException( sError
, NULL
);
466 OSL_FAIL("OPredicateCompiler::execute_Operand Exception");
469 else if (SQL_ISRULE(pPredicateNode
,parameter
))
471 pOperand
= new OOperandParam(pPredicateNode
, ++m_nParamCounter
);
473 else if (pPredicateNode
->getNodeType() == SQL_NODE_STRING
||
474 pPredicateNode
->getNodeType() == SQL_NODE_INTNUM
||
475 pPredicateNode
->getNodeType() == SQL_NODE_APPROXNUM
||
476 pPredicateNode
->getNodeType() == SQL_NODE_NAME
||
477 SQL_ISTOKEN(pPredicateNode
,TRUE
) ||
478 SQL_ISTOKEN(pPredicateNode
,FALSE
) ||
479 SQL_ISRULE(pPredicateNode
,parameter
))
481 pOperand
= new OOperandConst(*pPredicateNode
, pPredicateNode
->getTokenValue());
483 else if((pPredicateNode
->count() == 2) &&
484 (SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"-")) &&
485 pPredicateNode
->getChild(1)->getNodeType() == SQL_NODE_INTNUM
)
486 { // if -1 or +1 is there
487 OUString
aValue(pPredicateNode
->getChild(0)->getTokenValue());
488 aValue
+= pPredicateNode
->getChild(1)->getTokenValue();
489 pOperand
= new OOperandConst(*pPredicateNode
->getChild(1), aValue
);
491 else if( SQL_ISRULE(pPredicateNode
,set_fct_spec
) && SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"{") )
493 const OSQLParseNode
* pODBCNode
= pPredicateNode
->getChild(1);
494 const OSQLParseNode
* pODBCNodeChild
= pODBCNode
->getChild(0);
497 if (pODBCNodeChild
->getNodeType() == SQL_NODE_KEYWORD
&& (
498 SQL_ISTOKEN(pODBCNodeChild
,D
) ||
499 SQL_ISTOKEN(pODBCNodeChild
,T
) ||
500 SQL_ISTOKEN(pODBCNodeChild
,TS
) ))
502 OUString sDateTime
= pODBCNode
->getChild(1)->getTokenValue();
503 pOperand
= new OOperandConst(*pODBCNode
->getChild(1), sDateTime
);
504 if(SQL_ISTOKEN(pODBCNodeChild
,D
))
506 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime
)));
508 else if(SQL_ISTOKEN(pODBCNodeChild
,T
))
510 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime
)));
512 else if(SQL_ISTOKEN(pODBCNodeChild
,TS
))
514 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime
)));
518 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
521 else if( SQL_ISRULE(pPredicateNode
,fold
) )
523 execute_Fold(pPredicateNode
);
525 else if( SQL_ISRULE(pPredicateNode
,set_fct_spec
)
526 || SQL_ISRULE(pPredicateNode
,position_exp
)
527 || SQL_ISRULE(pPredicateNode
,char_substring_fct
)
530 executeFunction(pPredicateNode
);
532 else if( SQL_ISRULE(pPredicateNode
,length_exp
) )
534 executeFunction(pPredicateNode
->getChild(0));
538 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,NULL
);
541 m_aCodeList
.push_back(pOperand
);
546 bool OPredicateInterpreter::evaluate(OCodeList
& rCodeList
)
550 OCodeList::iterator aIter
= rCodeList
.begin();
552 return true; // no Predicate
554 for(;aIter
!= rCodeList
.end();++aIter
)
556 OOperand
* pOperand
= PTR_CAST(OOperand
,(*aIter
));
558 m_aStack
.push(pOperand
);
560 ((OOperator
*)(*aIter
))->Exec(m_aStack
);
563 OOperand
* pOperand
= m_aStack
.top();
566 DBG_ASSERT(m_aStack
.empty(), "StackFehler");
567 DBG_ASSERT(pOperand
, "StackFehler");
569 bResult
= pOperand
->isValid();
570 if (IS_TYPE(OOperandResult
,pOperand
))
575 void OPredicateInterpreter::evaluateSelection(OCodeList
& rCodeList
,ORowSetValueDecoratorRef
& _rVal
)
577 OCodeList::iterator aIter
= rCodeList
.begin();
579 return ; // no Predicate
581 for(;aIter
!= rCodeList
.end();++aIter
)
583 OOperand
* pOperand
= PTR_CAST(OOperand
,(*aIter
));
585 m_aStack
.push(pOperand
);
587 ((OOperator
*)(*aIter
))->Exec(m_aStack
);
590 OOperand
* pOperand
= m_aStack
.top();
593 DBG_ASSERT(m_aStack
.empty(), "StackFehler");
594 DBG_ASSERT(pOperand
, "StackFehler");
596 (*_rVal
) = pOperand
->getValue();
597 if (IS_TYPE(OOperandResult
,pOperand
))
601 OOperand
* OPredicateCompiler::execute_Fold(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
603 DBG_ASSERT(pPredicateNode
->count() >= 4,"OFILECursor: Fehler im Parse Tree");
605 bool bUpper
= SQL_ISTOKEN(pPredicateNode
->getChild(0),UPPER
);
607 execute(pPredicateNode
->getChild(2));
608 OOperator
* pOperator
= NULL
;
610 pOperator
= new OOp_Upper();
612 pOperator
= new OOp_Lower();
614 m_aCodeList
.push_back(pOperator
);
618 OOperand
* OPredicateCompiler::executeFunction(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
620 OOperator
* pOperator
= NULL
;
622 OSL_ENSURE(pPredicateNode
->getChild(0)->isToken(),"The first one must be the name of the function!");
623 sal_Int32 nTokenId
= pPredicateNode
->getChild(0)->getTokenID();
626 case SQL_TOKEN_CHAR_LENGTH
:
627 case SQL_TOKEN_LENGTH
:
628 case SQL_TOKEN_OCTET_LENGTH
:
629 case SQL_TOKEN_ASCII
:
630 case SQL_TOKEN_LCASE
:
631 case SQL_TOKEN_LTRIM
:
632 case SQL_TOKEN_RTRIM
:
633 case SQL_TOKEN_SPACE
:
634 case SQL_TOKEN_UCASE
:
639 case SQL_TOKEN_CEILING
:
641 case SQL_TOKEN_DEGREES
:
643 case SQL_TOKEN_FLOOR
:
644 case SQL_TOKEN_LOG10
:
646 case SQL_TOKEN_RADIANS
:
651 case SQL_TOKEN_DAYNAME
:
652 case SQL_TOKEN_DAYOFMONTH
:
653 case SQL_TOKEN_DAYOFWEEK
:
654 case SQL_TOKEN_DAYOFYEAR
:
656 case SQL_TOKEN_MINUTE
:
657 case SQL_TOKEN_MONTH
:
658 case SQL_TOKEN_MONTHNAME
:
659 case SQL_TOKEN_QUARTER
:
660 case SQL_TOKEN_SECOND
:
663 execute(pPredicateNode
->getChild(2));
667 case SQL_TOKEN_CHAR_LENGTH
:
668 case SQL_TOKEN_LENGTH
:
669 case SQL_TOKEN_OCTET_LENGTH
:
670 pOperator
= new OOp_CharLength();
672 case SQL_TOKEN_ASCII
:
673 pOperator
= new OOp_Ascii();
675 case SQL_TOKEN_LCASE
:
676 pOperator
= new OOp_Lower();
679 case SQL_TOKEN_LTRIM
:
680 pOperator
= new OOp_LTrim();
682 case SQL_TOKEN_RTRIM
:
683 pOperator
= new OOp_RTrim();
685 case SQL_TOKEN_SPACE
:
686 pOperator
= new OOp_Space();
688 case SQL_TOKEN_UCASE
:
689 pOperator
= new OOp_Upper();
692 pOperator
= new OOp_Abs();
695 pOperator
= new OOp_ACos();
698 pOperator
= new OOp_ASin();
701 pOperator
= new OOp_ATan();
703 case SQL_TOKEN_CEILING
:
704 pOperator
= new OOp_Ceiling();
707 pOperator
= new OOp_Cos();
709 case SQL_TOKEN_DEGREES
:
710 pOperator
= new OOp_Degrees();
713 pOperator
= new OOp_Exp();
715 case SQL_TOKEN_FLOOR
:
716 pOperator
= new OOp_Floor();
718 case SQL_TOKEN_LOG10
:
719 pOperator
= new OOp_Log10();
722 pOperator
= new OOp_Ln();
724 case SQL_TOKEN_RADIANS
:
725 pOperator
= new OOp_Radians();
728 pOperator
= new OOp_Sign();
731 pOperator
= new OOp_Sin();
734 pOperator
= new OOp_Sqrt();
737 pOperator
= new OOp_Tan();
739 case SQL_TOKEN_DAYOFWEEK
:
740 pOperator
= new OOp_DayOfWeek();
742 case SQL_TOKEN_DAYOFMONTH
:
743 pOperator
= new OOp_DayOfMonth();
745 case SQL_TOKEN_DAYOFYEAR
:
746 pOperator
= new OOp_DayOfYear();
748 case SQL_TOKEN_MONTH
:
749 pOperator
= new OOp_Month();
751 case SQL_TOKEN_DAYNAME
:
752 pOperator
= new OOp_DayName();
754 case SQL_TOKEN_MONTHNAME
:
755 pOperator
= new OOp_MonthName();
757 case SQL_TOKEN_QUARTER
:
758 pOperator
= new OOp_Quarter();
761 pOperator
= new OOp_Year();
764 pOperator
= new OOp_Hour();
766 case SQL_TOKEN_MINUTE
:
767 pOperator
= new OOp_Minute();
769 case SQL_TOKEN_SECOND
:
770 pOperator
= new OOp_Second();
773 OSL_FAIL("Error in switch!");
777 case SQL_TOKEN_CONCAT
:
778 case SQL_TOKEN_INSERT
:
780 case SQL_TOKEN_LOCATE
:
781 case SQL_TOKEN_LOCATE_2
:
782 case SQL_TOKEN_REPEAT
:
783 case SQL_TOKEN_REPLACE
:
784 case SQL_TOKEN_RIGHT
:
786 case SQL_TOKEN_ROUND
:
789 case SQL_TOKEN_POWER
:
790 case SQL_TOKEN_ATAN2
:
792 case SQL_TOKEN_CURDATE
:
793 case SQL_TOKEN_CURTIME
:
797 m_aCodeList
.push_back(new OStopOperand
);
798 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
799 for (sal_uInt32 i
=0; i
< pList
->count(); ++i
)
800 execute(pList
->getChild(i
));
805 pOperator
= new OOp_Char();
807 case SQL_TOKEN_CONCAT
:
808 pOperator
= new OOp_Concat();
810 case SQL_TOKEN_INSERT
:
811 pOperator
= new OOp_Insert();
814 pOperator
= new OOp_Left();
816 case SQL_TOKEN_LOCATE
:
817 case SQL_TOKEN_LOCATE_2
:
818 pOperator
= new OOp_Locate();
820 case SQL_TOKEN_REPEAT
:
821 pOperator
= new OOp_Repeat();
823 case SQL_TOKEN_REPLACE
:
824 pOperator
= new OOp_Replace();
826 case SQL_TOKEN_RIGHT
:
827 pOperator
= new OOp_Right();
830 pOperator
= new OOp_Mod();
832 case SQL_TOKEN_ROUND
:
833 pOperator
= new OOp_Round();
837 pOperator
= new OOp_Log();
839 case SQL_TOKEN_POWER
:
840 pOperator
= new OOp_Pow();
842 case SQL_TOKEN_ATAN2
:
843 pOperator
= new OOp_ATan2();
846 pOperator
= new OOp_Pi();
848 case SQL_TOKEN_CURDATE
:
849 pOperator
= new OOp_CurDate();
851 case SQL_TOKEN_CURTIME
:
852 pOperator
= new OOp_CurTime();
855 pOperator
= new OOp_Now();
858 pOperator
= new OOp_Week();
861 OSL_FAIL("Error in switch!");
866 case SQL_TOKEN_SUBSTRING
:
867 m_aCodeList
.push_back(new OStopOperand
);
868 if ( pPredicateNode
->count() == 4 ) //char_substring_fct
870 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
871 for (sal_uInt32 i
=0; i
< pList
->count(); ++i
)
872 execute(pList
->getChild(i
));
876 execute(pPredicateNode
->getChild(2));
877 execute(pPredicateNode
->getChild(4));
878 execute(pPredicateNode
->getChild(5)->getChild(1));
880 pOperator
= new OOp_SubString();
883 case SQL_TOKEN_POSITION
:
884 m_aCodeList
.push_back(new OStopOperand
);
885 if ( pPredicateNode
->count() == 4 ) //position_exp
887 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
888 for (sal_uInt32 i
=0; i
< pList
->count(); ++i
)
889 execute(pList
->getChild(i
));
893 execute(pPredicateNode
->getChild(2));
894 execute(pPredicateNode
->getChild(4));
896 pOperator
= new OOp_Locate();
899 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED
,NULL
);
902 m_aCodeList
.push_back(pOperator
);
908 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */