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()
63 m_orgColumns
= nullptr;
67 void OPredicateCompiler::start(OSQLParseNode
* pSQLParseNode
)
73 // analyse Parse Tree (depending on Statement-type)
74 // and set pointer on WHERE-clause:
75 OSQLParseNode
* pWhereClause
= nullptr;
77 if (SQL_ISRULE(pSQLParseNode
,select_statement
))
79 OSQLParseNode
* pOrderbyClause
= nullptr;
80 DBG_ASSERT(pSQLParseNode
->count() >= 4,"OFILECursor: Fehler im Parse Tree");
82 OSQLParseNode
* pTableExp
= pSQLParseNode
->getChild(3);
83 DBG_ASSERT(pTableExp
!= nullptr,"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 (size_t 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
,nullptr);
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
!= nullptr,"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
= nullptr;
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 void 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() == SQLNodeType::String
||
230 pPredicateNode
->getChild(2)->getNodeType() == SQLNodeType::IntNum
||
231 pPredicateNode
->getChild(2)->getNodeType() == SQLNodeType::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
,nullptr);
246 sal_Int32
ePredicateType( SQLFilterOperator::EQUAL
);
247 OSQLParseNode
*pPrec
= pPredicateNode
->getChild(1);
249 if (pPrec
->getNodeType() == SQLNodeType::Equal
)
250 ePredicateType
= SQLFilterOperator::EQUAL
;
251 else if (pPrec
->getNodeType() == SQLNodeType::NotEqual
)
252 ePredicateType
= SQLFilterOperator::NOT_EQUAL
;
253 else if (pPrec
->getNodeType() == SQLNodeType::Less
)
254 ePredicateType
= SQLFilterOperator::LESS
;
255 else if (pPrec
->getNodeType() == SQLNodeType::LessEq
)
256 ePredicateType
= SQLFilterOperator::LESS_EQUAL
;
257 else if (pPrec
->getNodeType() == SQLNodeType::GreatEq
)
258 ePredicateType
= SQLFilterOperator::GREATER_EQUAL
;
259 else if (pPrec
->getNodeType() == SQLNodeType::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
) );
270 void OPredicateCompiler::execute_LIKE(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
272 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
273 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
275 sal_Unicode cEscape
= L
'\0';
276 const bool bNotLike
= pPart2
->getChild(0)->isToken();
278 OSQLParseNode
* pAtom
= pPart2
->getChild(pPart2
->count()-2);
279 OSQLParseNode
* pOptEscape
= pPart2
->getChild(pPart2
->count()-1);
281 if (!(pAtom
->getNodeType() == SQLNodeType::String
||
282 SQL_ISRULE(pAtom
,parameter
) ||
284 SQL_ISRULE(pAtom
,set_fct_spec
) ||
285 SQL_ISRULE(pAtom
,position_exp
) ||
286 SQL_ISRULE(pAtom
,char_substring_fct
) ||
288 SQL_ISRULE(pAtom
,fold
)) )
290 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,nullptr);
294 if (pOptEscape
->count() != 0)
296 if (pOptEscape
->count() != 2)
298 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,nullptr);
300 OSQLParseNode
*pEscNode
= pOptEscape
->getChild(1);
301 if (pEscNode
->getNodeType() != SQLNodeType::String
)
303 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,nullptr);
306 cEscape
= pEscNode
->getTokenValue().toChar();
309 execute(pPredicateNode
->getChild(0));
312 OBoolOperator
* pOperator
= bNotLike
313 ? new OOp_NOTLIKE(cEscape
)
314 : new OOp_LIKE(cEscape
);
315 m_aCodeList
.push_back(pOperator
);
318 void OPredicateCompiler::execute_BETWEEN(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
, std::exception
)
320 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
322 OSQLParseNode
* pColumn
= pPredicateNode
->getChild(0);
323 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
324 OSQLParseNode
* p1stValue
= pPart2
->getChild(2);
325 OSQLParseNode
* p2ndtValue
= pPart2
->getChild(4);
328 !(p1stValue
->getNodeType() == SQLNodeType::String
|| SQL_ISRULE(p1stValue
,parameter
))
329 && !(p2ndtValue
->getNodeType() == SQLNodeType::String
|| SQL_ISRULE(p2ndtValue
,parameter
))
332 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN
,nullptr);
335 bool bNot
= SQL_ISTOKEN(pPart2
->getChild(0),NOT
);
337 OOperand
* pColumnOp
= execute(pColumn
);
338 OOperand
* pOb1
= execute(p1stValue
);
339 OBoolOperator
* pOperator
= new OOp_COMPARE(bNot
? SQLFilterOperator::LESS_EQUAL
: SQLFilterOperator::GREATER
);
340 m_aCodeList
.push_back(pOperator
);
343 OOperand
* pOb2
= execute(p2ndtValue
);
344 pOperator
= new OOp_COMPARE(bNot
? SQLFilterOperator::GREATER_EQUAL
: SQLFilterOperator::LESS
);
345 m_aCodeList
.push_back(pOperator
);
347 if ( pColumnOp
&& pOb1
&& pOb2
)
349 switch(pColumnOp
->getDBType())
352 case DataType::VARCHAR
:
353 case DataType::LONGVARCHAR
:
354 pOb1
->setValue(pOb1
->getValue().getString());
355 pOb2
->setValue(pOb2
->getValue().getString());
357 case DataType::DECIMAL
:
358 case DataType::NUMERIC
:
359 pOb1
->setValue((double)pOb1
->getValue());
360 pOb2
->setValue((double)pOb2
->getValue());
362 case DataType::FLOAT
:
363 pOb1
->setValue((float)pOb1
->getValue());
364 pOb2
->setValue((float)pOb2
->getValue());
366 case DataType::DOUBLE
:
368 pOb1
->setValue((double)pOb1
->getValue());
369 pOb2
->setValue((double)pOb2
->getValue());
372 pOb1
->setValue(static_cast<util::Date
>(pOb1
->getValue()));
373 pOb2
->setValue(static_cast<util::Date
>(pOb2
->getValue()));
376 pOb1
->setValue(static_cast<util::Time
>(pOb1
->getValue()));
377 pOb2
->setValue(static_cast<util::Time
>(pOb2
->getValue()));
379 case DataType::TIMESTAMP
:
380 pOb1
->setValue(static_cast<util::DateTime
>(pOb1
->getValue()));
381 pOb2
->setValue(static_cast<util::DateTime
>(pOb2
->getValue()));
387 OBoolOperator
* pBoolOp
= nullptr;
389 pBoolOp
= new OOp_OR();
391 pBoolOp
= new OOp_AND();
392 m_aCodeList
.push_back(pBoolOp
);
395 void OPredicateCompiler::execute_ISNULL(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
397 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Fehler im Parse Tree");
398 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
399 DBG_ASSERT(SQL_ISTOKEN(pPart2
->getChild(0),IS
),"OFILECursor: Fehler im Parse Tree");
401 sal_Int32 ePredicateType
;
402 if (SQL_ISTOKEN(pPart2
->getChild(1),NOT
))
403 ePredicateType
= SQLFilterOperator::NOT_SQLNULL
;
405 ePredicateType
= SQLFilterOperator::SQLNULL
;
407 execute(pPredicateNode
->getChild(0));
408 OBoolOperator
* pOperator
= (ePredicateType
== SQLFilterOperator::SQLNULL
) ?
409 new OOp_ISNULL() : new OOp_ISNOTNULL();
410 m_aCodeList
.push_back(pOperator
);
413 OOperand
* OPredicateCompiler::execute_Operand(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
, std::exception
)
415 OOperand
* pOperand
= nullptr;
417 if (SQL_ISRULE(pPredicateNode
,column_ref
))
419 OUString aColumnName
;
420 if (pPredicateNode
->count() == 1)
422 aColumnName
= pPredicateNode
->getChild(0)->getTokenValue();
424 else if (pPredicateNode
->count() == 3)
426 if(SQL_ISRULE(pPredicateNode
->getChild(2),column_val
))
427 aColumnName
= pPredicateNode
->getChild(2)->getChild(0)->getTokenValue();
429 aColumnName
= pPredicateNode
->getChild(2)->getTokenValue();
432 if(!m_orgColumns
->hasByName(aColumnName
))
434 const OUString
sError( m_pAnalyzer
->getConnection()->getResources().getResourceStringWithSubstitution(
435 STR_INVALID_COLUMNNAME
,
436 "$columnname$", aColumnName
438 ::dbtools::throwGenericSQLException( sError
, nullptr );
440 css::uno::Reference
< css::beans::XPropertySet
> xCol
;
443 if (m_orgColumns
->getByName(aColumnName
) >>= xCol
)
445 pOperand
= OSQLAnalyzer::createOperandAttr(Reference
< XColumnLocate
>(m_orgColumns
,UNO_QUERY
)->findColumn(aColumnName
),xCol
,m_xIndexes
);
448 {// Column doesn't exist in the Result-set
449 const OUString
sError( m_pAnalyzer
->getConnection()->getResources().getResourceStringWithSubstitution(
450 STR_INVALID_COLUMNNAME
,
451 "$columnname$", aColumnName
453 ::dbtools::throwGenericSQLException( sError
, nullptr );
458 OSL_FAIL("OPredicateCompiler::execute_Operand Exception");
461 else if (SQL_ISRULE(pPredicateNode
,parameter
))
463 pOperand
= new OOperandParam(pPredicateNode
, ++m_nParamCounter
);
465 else if (pPredicateNode
->getNodeType() == SQLNodeType::String
||
466 pPredicateNode
->getNodeType() == SQLNodeType::IntNum
||
467 pPredicateNode
->getNodeType() == SQLNodeType::ApproxNum
||
468 pPredicateNode
->getNodeType() == SQLNodeType::Name
||
469 SQL_ISTOKEN(pPredicateNode
,TRUE
) ||
470 SQL_ISTOKEN(pPredicateNode
,FALSE
) ||
471 SQL_ISRULE(pPredicateNode
,parameter
))
473 pOperand
= new OOperandConst(*pPredicateNode
, pPredicateNode
->getTokenValue());
475 else if((pPredicateNode
->count() == 2) &&
476 (SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"-")) &&
477 pPredicateNode
->getChild(1)->getNodeType() == SQLNodeType::IntNum
)
478 { // if -1 or +1 is there
479 OUString aValue
= pPredicateNode
->getChild(0)->getTokenValue() + pPredicateNode
->getChild(1)->getTokenValue();
480 pOperand
= new OOperandConst(*pPredicateNode
->getChild(1), aValue
);
482 else if( SQL_ISRULE(pPredicateNode
,set_fct_spec
) && SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"{") )
484 const OSQLParseNode
* pODBCNode
= pPredicateNode
->getChild(1);
485 const OSQLParseNode
* pODBCNodeChild
= pODBCNode
->getChild(0);
488 if (pODBCNodeChild
->getNodeType() == SQLNodeType::Keyword
&& (
489 SQL_ISTOKEN(pODBCNodeChild
,D
) ||
490 SQL_ISTOKEN(pODBCNodeChild
,T
) ||
491 SQL_ISTOKEN(pODBCNodeChild
,TS
) ))
493 OUString sDateTime
= pODBCNode
->getChild(1)->getTokenValue();
494 pOperand
= new OOperandConst(*pODBCNode
->getChild(1), sDateTime
);
495 if(SQL_ISTOKEN(pODBCNodeChild
,D
))
497 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime
)));
499 else if(SQL_ISTOKEN(pODBCNodeChild
,T
))
501 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime
)));
503 else if(SQL_ISTOKEN(pODBCNodeChild
,TS
))
505 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime
)));
509 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,nullptr);
512 else if( SQL_ISRULE(pPredicateNode
,fold
) )
514 execute_Fold(pPredicateNode
);
516 else if( SQL_ISRULE(pPredicateNode
,set_fct_spec
)
517 || SQL_ISRULE(pPredicateNode
,position_exp
)
518 || SQL_ISRULE(pPredicateNode
,char_substring_fct
)
521 executeFunction(pPredicateNode
);
523 else if( SQL_ISRULE(pPredicateNode
,length_exp
) )
525 executeFunction(pPredicateNode
->getChild(0));
529 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,nullptr);
532 m_aCodeList
.push_back(pOperand
);
537 bool OPredicateInterpreter::evaluate(OCodeList
& rCodeList
)
541 OCodeList::iterator aIter
= rCodeList
.begin();
543 return true; // no Predicate
545 for(;aIter
!= rCodeList
.end();++aIter
)
547 OOperand
* pOperand
= dynamic_cast<OOperand
* >(*aIter
);
549 m_aStack
.push(pOperand
);
551 static_cast<OOperator
*>(*aIter
)->Exec(m_aStack
);
554 OOperand
* pOperand
= m_aStack
.top();
557 DBG_ASSERT(m_aStack
.empty(), "StackFehler");
558 DBG_ASSERT(pOperand
, "StackFehler");
560 bResult
= pOperand
->isValid();
561 if (typeid(OOperandResult
) == typeid(*pOperand
))
566 void OPredicateInterpreter::evaluateSelection(OCodeList
& rCodeList
,ORowSetValueDecoratorRef
& _rVal
)
568 OCodeList::iterator aIter
= rCodeList
.begin();
570 return ; // no Predicate
572 for(;aIter
!= rCodeList
.end();++aIter
)
574 OOperand
* pOperand
= dynamic_cast<OOperand
* >(*aIter
);
576 m_aStack
.push(pOperand
);
578 static_cast<OOperator
*>(*aIter
)->Exec(m_aStack
);
581 OOperand
* pOperand
= m_aStack
.top();
584 DBG_ASSERT(m_aStack
.empty(), "StackFehler");
585 DBG_ASSERT(pOperand
, "StackFehler");
587 (*_rVal
) = pOperand
->getValue();
588 if (typeid(OOperandResult
) == typeid(*pOperand
))
592 void OPredicateCompiler::execute_Fold(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
594 DBG_ASSERT(pPredicateNode
->count() >= 4,"OFILECursor: Fehler im Parse Tree");
596 bool bUpper
= SQL_ISTOKEN(pPredicateNode
->getChild(0),UPPER
);
598 execute(pPredicateNode
->getChild(2));
599 OOperator
* pOperator
= nullptr;
601 pOperator
= new OOp_Upper();
603 pOperator
= new OOp_Lower();
605 m_aCodeList
.push_back(pOperator
);
608 void OPredicateCompiler::executeFunction(OSQLParseNode
* pPredicateNode
) throw(SQLException
, RuntimeException
)
610 OOperator
* pOperator
= nullptr;
612 OSL_ENSURE(pPredicateNode
->getChild(0)->isToken(),"The first one must be the name of the function!");
613 sal_Int32 nTokenId
= pPredicateNode
->getChild(0)->getTokenID();
616 case SQL_TOKEN_CHAR_LENGTH
:
617 case SQL_TOKEN_LENGTH
:
618 case SQL_TOKEN_OCTET_LENGTH
:
619 case SQL_TOKEN_ASCII
:
620 case SQL_TOKEN_LCASE
:
621 case SQL_TOKEN_LTRIM
:
622 case SQL_TOKEN_RTRIM
:
623 case SQL_TOKEN_SPACE
:
624 case SQL_TOKEN_UCASE
:
629 case SQL_TOKEN_CEILING
:
631 case SQL_TOKEN_DEGREES
:
633 case SQL_TOKEN_FLOOR
:
634 case SQL_TOKEN_LOG10
:
636 case SQL_TOKEN_RADIANS
:
641 case SQL_TOKEN_DAYNAME
:
642 case SQL_TOKEN_DAYOFMONTH
:
643 case SQL_TOKEN_DAYOFWEEK
:
644 case SQL_TOKEN_DAYOFYEAR
:
646 case SQL_TOKEN_MINUTE
:
647 case SQL_TOKEN_MONTH
:
648 case SQL_TOKEN_MONTHNAME
:
649 case SQL_TOKEN_QUARTER
:
650 case SQL_TOKEN_SECOND
:
653 execute(pPredicateNode
->getChild(2));
657 case SQL_TOKEN_CHAR_LENGTH
:
658 case SQL_TOKEN_LENGTH
:
659 case SQL_TOKEN_OCTET_LENGTH
:
660 pOperator
= new OOp_CharLength();
662 case SQL_TOKEN_ASCII
:
663 pOperator
= new OOp_Ascii();
665 case SQL_TOKEN_LCASE
:
666 pOperator
= new OOp_Lower();
669 case SQL_TOKEN_LTRIM
:
670 pOperator
= new OOp_LTrim();
672 case SQL_TOKEN_RTRIM
:
673 pOperator
= new OOp_RTrim();
675 case SQL_TOKEN_SPACE
:
676 pOperator
= new OOp_Space();
678 case SQL_TOKEN_UCASE
:
679 pOperator
= new OOp_Upper();
682 pOperator
= new OOp_Abs();
685 pOperator
= new OOp_ACos();
688 pOperator
= new OOp_ASin();
691 pOperator
= new OOp_ATan();
693 case SQL_TOKEN_CEILING
:
694 pOperator
= new OOp_Ceiling();
697 pOperator
= new OOp_Cos();
699 case SQL_TOKEN_DEGREES
:
700 pOperator
= new OOp_Degrees();
703 pOperator
= new OOp_Exp();
705 case SQL_TOKEN_FLOOR
:
706 pOperator
= new OOp_Floor();
708 case SQL_TOKEN_LOG10
:
709 pOperator
= new OOp_Log10();
712 pOperator
= new OOp_Ln();
714 case SQL_TOKEN_RADIANS
:
715 pOperator
= new OOp_Radians();
718 pOperator
= new OOp_Sign();
721 pOperator
= new OOp_Sin();
724 pOperator
= new OOp_Sqrt();
727 pOperator
= new OOp_Tan();
729 case SQL_TOKEN_DAYOFWEEK
:
730 pOperator
= new OOp_DayOfWeek();
732 case SQL_TOKEN_DAYOFMONTH
:
733 pOperator
= new OOp_DayOfMonth();
735 case SQL_TOKEN_DAYOFYEAR
:
736 pOperator
= new OOp_DayOfYear();
738 case SQL_TOKEN_MONTH
:
739 pOperator
= new OOp_Month();
741 case SQL_TOKEN_DAYNAME
:
742 pOperator
= new OOp_DayName();
744 case SQL_TOKEN_MONTHNAME
:
745 pOperator
= new OOp_MonthName();
747 case SQL_TOKEN_QUARTER
:
748 pOperator
= new OOp_Quarter();
751 pOperator
= new OOp_Year();
754 pOperator
= new OOp_Hour();
756 case SQL_TOKEN_MINUTE
:
757 pOperator
= new OOp_Minute();
759 case SQL_TOKEN_SECOND
:
760 pOperator
= new OOp_Second();
763 OSL_FAIL("Error in switch!");
767 case SQL_TOKEN_CONCAT
:
768 case SQL_TOKEN_INSERT
:
770 case SQL_TOKEN_LOCATE
:
771 case SQL_TOKEN_LOCATE_2
:
772 case SQL_TOKEN_REPEAT
:
773 case SQL_TOKEN_REPLACE
:
774 case SQL_TOKEN_RIGHT
:
776 case SQL_TOKEN_ROUND
:
779 case SQL_TOKEN_POWER
:
780 case SQL_TOKEN_ATAN2
:
782 case SQL_TOKEN_CURDATE
:
783 case SQL_TOKEN_CURTIME
:
787 m_aCodeList
.push_back(new OStopOperand
);
788 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
789 for (size_t i
=0; i
< pList
->count(); ++i
)
790 execute(pList
->getChild(i
));
795 pOperator
= new OOp_Char();
797 case SQL_TOKEN_CONCAT
:
798 pOperator
= new OOp_Concat();
800 case SQL_TOKEN_INSERT
:
801 pOperator
= new OOp_Insert();
804 pOperator
= new OOp_Left();
806 case SQL_TOKEN_LOCATE
:
807 case SQL_TOKEN_LOCATE_2
:
808 pOperator
= new OOp_Locate();
810 case SQL_TOKEN_REPEAT
:
811 pOperator
= new OOp_Repeat();
813 case SQL_TOKEN_REPLACE
:
814 pOperator
= new OOp_Replace();
816 case SQL_TOKEN_RIGHT
:
817 pOperator
= new OOp_Right();
820 pOperator
= new OOp_Mod();
822 case SQL_TOKEN_ROUND
:
823 pOperator
= new OOp_Round();
827 pOperator
= new OOp_Log();
829 case SQL_TOKEN_POWER
:
830 pOperator
= new OOp_Pow();
832 case SQL_TOKEN_ATAN2
:
833 pOperator
= new OOp_ATan2();
836 pOperator
= new OOp_Pi();
838 case SQL_TOKEN_CURDATE
:
839 pOperator
= new OOp_CurDate();
841 case SQL_TOKEN_CURTIME
:
842 pOperator
= new OOp_CurTime();
845 pOperator
= new OOp_Now();
848 pOperator
= new OOp_Week();
851 OSL_FAIL("Error in switch!");
856 case SQL_TOKEN_SUBSTRING
:
857 m_aCodeList
.push_back(new OStopOperand
);
858 if ( pPredicateNode
->count() == 4 ) //char_substring_fct
860 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
861 for (size_t i
=0; i
< pList
->count(); ++i
)
862 execute(pList
->getChild(i
));
866 execute(pPredicateNode
->getChild(2));
867 execute(pPredicateNode
->getChild(4));
868 execute(pPredicateNode
->getChild(5)->getChild(1));
870 pOperator
= new OOp_SubString();
873 case SQL_TOKEN_POSITION
:
874 m_aCodeList
.push_back(new OStopOperand
);
875 if ( pPredicateNode
->count() == 4 ) //position_exp
877 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
878 for (size_t i
=0; i
< pList
->count(); ++i
)
879 execute(pList
->getChild(i
));
883 execute(pPredicateNode
->getChild(2));
884 execute(pPredicateNode
->getChild(4));
886 pOperator
= new OOp_Locate();
889 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED
,nullptr);
892 m_aCodeList
.push_back(pOperator
);
896 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */