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 <connectivity/sqlparse.hxx>
23 #include <file/fanalyzer.hxx>
24 #include <com/sun/star/sdbc/XColumnLocate.hpp>
25 #include <connectivity/dbexception.hxx>
26 #include <connectivity/dbconversion.hxx>
27 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
28 #include <file/FStringFunctions.hxx>
29 #include <file/FDateFunctions.hxx>
30 #include <file/FNumericFunctions.hxx>
31 #include <file/FConnection.hxx>
32 #include <comphelper/diagnose_ex.hxx>
33 #include <sqlbison.hxx>
34 #include <strings.hrc>
36 using namespace connectivity
;
37 using namespace connectivity::file
;
38 using namespace com::sun::star::uno
;
39 using namespace com::sun::star::sdbc
;
40 using namespace com::sun::star::sdb
;
41 using namespace ::com::sun::star::container
;
42 using namespace com::sun::star
;
44 OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer
* pAnalyzer
)//,OCursor& rCurs)
45 : m_pAnalyzer(pAnalyzer
)
51 OPredicateCompiler::~OPredicateCompiler()
56 void OPredicateCompiler::dispose()
59 m_orgColumns
= nullptr;
62 void OPredicateCompiler::start(OSQLParseNode
const * pSQLParseNode
)
68 // analyse Parse Tree (depending on Statement-type)
69 // and set pointer on WHERE-clause:
70 OSQLParseNode
* pWhereClause
= nullptr;
72 if (SQL_ISRULE(pSQLParseNode
,select_statement
))
74 OSQLParseNode
* pOrderbyClause
= nullptr;
75 DBG_ASSERT(pSQLParseNode
->count() >= 4,"OFILECursor: Error in Parse Tree");
77 OSQLParseNode
* pTableExp
= pSQLParseNode
->getChild(3);
78 assert(pTableExp
&& "Error in Parse Tree");
79 DBG_ASSERT(SQL_ISRULE(pTableExp
,table_exp
)," Error in Parse Tree");
80 DBG_ASSERT(pTableExp
->count() == TABLE_EXPRESSION_CHILD_COUNT
,"Error in Parse Tree");
82 // check that we don't use anything other than count(*) as function
83 OSQLParseNode
* pSelection
= pSQLParseNode
->getChild(2);
84 if ( SQL_ISRULE(pSelection
,scalar_exp_commalist
) )
86 for (size_t i
= 0; i
< pSelection
->count(); i
++)
88 OSQLParseNode
*pColumnRef
= pSelection
->getChild(i
)->getChild(0);
89 if ( SQL_ISRULE(pColumnRef
,general_set_fct
) && pColumnRef
->count() != 4 )
91 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT
,nullptr);
97 pWhereClause
= pTableExp
->getChild(1);
98 pOrderbyClause
= pTableExp
->getChild(ORDER_BY_CHILD_POS
);
101 else if (SQL_ISRULE(pSQLParseNode
,update_statement_searched
))
103 DBG_ASSERT(pSQLParseNode
->count() == 5,"OFILECursor: Error in Parse Tree");
104 pWhereClause
= pSQLParseNode
->getChild(4);
106 else if (SQL_ISRULE(pSQLParseNode
,delete_statement_searched
))
108 DBG_ASSERT(pSQLParseNode
->count() == 4,"Error in Parse Tree");
109 pWhereClause
= pSQLParseNode
->getChild(3);
112 // Other Statement. no selection-criteria
115 if (SQL_ISRULE(pWhereClause
,where_clause
))
117 // a where-clause is not allowed to be empty:
118 DBG_ASSERT(pWhereClause
->count() == 2,"OFILECursor: Error in Parse Tree");
120 OSQLParseNode
* pComparisonPredicate
= pWhereClause
->getChild(1);
121 DBG_ASSERT(pComparisonPredicate
!= nullptr,"OFILECursor: Error in Parse Tree");
123 execute( pComparisonPredicate
);
127 // The where-clause is optionally in the majority of cases, i.e. it might be an "optional-where-clause".
128 DBG_ASSERT(SQL_ISRULE(pWhereClause
,opt_where_clause
),"OPredicateCompiler: Error in Parse Tree");
133 OOperand
* OPredicateCompiler::execute(OSQLParseNode
const * pPredicateNode
)
135 OOperand
* pOperand
= nullptr;
136 if (pPredicateNode
->count() == 3 && // Expression is bracketed
137 SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"(") &&
138 SQL_ISPUNCTUATION(pPredicateNode
->getChild(2),")"))
140 execute(pPredicateNode
->getChild(1));
142 else if ((SQL_ISRULE(pPredicateNode
,search_condition
) || SQL_ISRULE(pPredicateNode
,boolean_term
))
143 && // AND/OR-linkage:
144 pPredicateNode
->count() == 3)
146 execute(pPredicateNode
->getChild(0)); // process the left branch
147 execute(pPredicateNode
->getChild(2)); // process the right branch
149 if (SQL_ISTOKEN(pPredicateNode
->getChild(1),OR
)) // OR-Operator
151 m_aCodeList
.emplace_back(new OOp_OR
);
153 else if (SQL_ISTOKEN(pPredicateNode
->getChild(1),AND
)) // AND-Operator
154 m_aCodeList
.emplace_back(new OOp_AND
);
157 OSL_FAIL("OPredicateCompiler: Error in Parse Tree");
160 else if (SQL_ISRULE(pPredicateNode
,boolean_factor
))
162 execute(pPredicateNode
->getChild(1));
163 m_aCodeList
.emplace_back(new OOp_NOT
);
165 else if (SQL_ISRULE(pPredicateNode
,comparison_predicate
))
167 execute_COMPARE(pPredicateNode
);
169 else if (SQL_ISRULE(pPredicateNode
,like_predicate
))
171 execute_LIKE(pPredicateNode
);
173 else if (SQL_ISRULE(pPredicateNode
,between_predicate
))
175 execute_BETWEEN(pPredicateNode
);
177 else if (SQL_ISRULE(pPredicateNode
,test_for_null
))
179 execute_ISNULL(pPredicateNode
);
181 else if(SQL_ISRULE(pPredicateNode
,num_value_exp
))
183 execute(pPredicateNode
->getChild(0)); // process the left branch
184 execute(pPredicateNode
->getChild(2)); // process the right branch
185 if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"+"))
187 m_aCodeList
.emplace_back(new OOp_ADD
);
189 else if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"-"))
190 m_aCodeList
.emplace_back(new OOp_SUB
);
193 OSL_FAIL("OPredicateCompiler: Error in Parse Tree num_value_exp");
196 else if(SQL_ISRULE(pPredicateNode
,term
))
198 execute(pPredicateNode
->getChild(0)); // process the left branch
199 execute(pPredicateNode
->getChild(2)); // process the right branch
200 if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"*"))
202 m_aCodeList
.emplace_back(new OOp_MUL
);
204 else if (SQL_ISPUNCTUATION(pPredicateNode
->getChild(1),"/"))
205 m_aCodeList
.emplace_back(new OOp_DIV
);
208 OSL_FAIL("OPredicateCompiler: Error in Parse Tree num_value_exp");
212 pOperand
= execute_Operand(pPredicateNode
); // now only simple operands will be processed
218 void OPredicateCompiler::execute_COMPARE(OSQLParseNode
const * pPredicateNode
)
220 DBG_ASSERT(pPredicateNode
->count() == 3,"OFILECursor: Error in Parse Tree");
222 if ( !(SQL_ISRULE(pPredicateNode
->getChild(0),column_ref
) ||
223 pPredicateNode
->getChild(2)->getNodeType() == SQLNodeType::String
||
224 pPredicateNode
->getChild(2)->getNodeType() == SQLNodeType::IntNum
||
225 pPredicateNode
->getChild(2)->getNodeType() == SQLNodeType::ApproxNum
||
226 SQL_ISTOKEN(pPredicateNode
->getChild(2),TRUE
) ||
227 SQL_ISTOKEN(pPredicateNode
->getChild(2),FALSE
) ||
228 SQL_ISRULE(pPredicateNode
->getChild(2),parameter
) ||
230 SQL_ISRULE(pPredicateNode
->getChild(2),set_fct_spec
) ||
231 SQL_ISRULE(pPredicateNode
->getChild(2),position_exp
) ||
232 SQL_ISRULE(pPredicateNode
->getChild(2),char_substring_fct
) ||
234 SQL_ISRULE(pPredicateNode
->getChild(2),fold
)) )
236 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,nullptr);
240 sal_Int32
ePredicateType( SQLFilterOperator::EQUAL
);
241 OSQLParseNode
*pPrec
= pPredicateNode
->getChild(1);
243 if (pPrec
->getNodeType() == SQLNodeType::Equal
)
244 ePredicateType
= SQLFilterOperator::EQUAL
;
245 else if (pPrec
->getNodeType() == SQLNodeType::NotEqual
)
246 ePredicateType
= SQLFilterOperator::NOT_EQUAL
;
247 else if (pPrec
->getNodeType() == SQLNodeType::Less
)
248 ePredicateType
= SQLFilterOperator::LESS
;
249 else if (pPrec
->getNodeType() == SQLNodeType::LessEq
)
250 ePredicateType
= SQLFilterOperator::LESS_EQUAL
;
251 else if (pPrec
->getNodeType() == SQLNodeType::GreatEq
)
252 ePredicateType
= SQLFilterOperator::GREATER_EQUAL
;
253 else if (pPrec
->getNodeType() == SQLNodeType::Great
)
254 ePredicateType
= SQLFilterOperator::GREATER
;
256 OSL_FAIL( "OPredicateCompiler::execute_COMPARE: unexpected node type!" );
258 execute(pPredicateNode
->getChild(0));
259 execute(pPredicateNode
->getChild(2));
260 m_aCodeList
.emplace_back( new OOp_COMPARE(ePredicateType
) );
264 void OPredicateCompiler::execute_LIKE(OSQLParseNode
const * pPredicateNode
)
266 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Error in Parse Tree");
267 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
269 sal_Unicode cEscape
= L
'\0';
270 const bool bNotLike
= pPart2
->getChild(0)->isToken();
272 OSQLParseNode
* pAtom
= pPart2
->getChild(pPart2
->count()-2);
273 OSQLParseNode
* pOptEscape
= pPart2
->getChild(pPart2
->count()-1);
275 if (!(pAtom
->getNodeType() == SQLNodeType::String
||
276 SQL_ISRULE(pAtom
,parameter
) ||
278 SQL_ISRULE(pAtom
,set_fct_spec
) ||
279 SQL_ISRULE(pAtom
,position_exp
) ||
280 SQL_ISRULE(pAtom
,char_substring_fct
) ||
282 SQL_ISRULE(pAtom
,fold
)) )
284 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,nullptr);
288 if (pOptEscape
->count() != 0)
290 if (pOptEscape
->count() != 2)
292 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,nullptr);
294 OSQLParseNode
*pEscNode
= pOptEscape
->getChild(1);
295 if (pEscNode
->getNodeType() != SQLNodeType::String
)
297 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING
,nullptr);
300 cEscape
= pEscNode
->getTokenValue().toChar();
303 execute(pPredicateNode
->getChild(0));
306 OBoolOperator
* pOperator
= bNotLike
307 ? new OOp_NOTLIKE(cEscape
)
308 : new OOp_LIKE(cEscape
);
309 m_aCodeList
.emplace_back(pOperator
);
312 void OPredicateCompiler::execute_BETWEEN(OSQLParseNode
const * pPredicateNode
)
314 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Error in Parse Tree");
316 OSQLParseNode
* pColumn
= pPredicateNode
->getChild(0);
317 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
318 OSQLParseNode
* p1stValue
= pPart2
->getChild(2);
319 OSQLParseNode
* p2ndtValue
= pPart2
->getChild(4);
322 !(p1stValue
->getNodeType() == SQLNodeType::String
|| SQL_ISRULE(p1stValue
,parameter
))
323 && !(p2ndtValue
->getNodeType() == SQLNodeType::String
|| SQL_ISRULE(p2ndtValue
,parameter
))
326 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN
,nullptr);
329 bool bNot
= SQL_ISTOKEN(pPart2
->getChild(0),NOT
);
331 OOperand
* pColumnOp
= execute(pColumn
);
332 OOperand
* pOb1
= execute(p1stValue
);
333 OBoolOperator
* pOperator
= new OOp_COMPARE(bNot
? SQLFilterOperator::LESS
: SQLFilterOperator::GREATER_EQUAL
);
334 m_aCodeList
.emplace_back(pOperator
);
337 OOperand
* pOb2
= execute(p2ndtValue
);
338 pOperator
= new OOp_COMPARE(bNot
? SQLFilterOperator::GREATER
: SQLFilterOperator::LESS_EQUAL
);
339 m_aCodeList
.emplace_back(pOperator
);
341 if ( pColumnOp
&& pOb1
&& pOb2
)
343 switch(pColumnOp
->getDBType())
346 case DataType::VARCHAR
:
347 case DataType::LONGVARCHAR
:
348 pOb1
->setValue(pOb1
->getValue().getString());
349 pOb2
->setValue(pOb2
->getValue().getString());
351 case DataType::DECIMAL
:
352 case DataType::NUMERIC
:
353 case DataType::DOUBLE
:
355 pOb1
->setValue(pOb1
->getValue().getDouble());
356 pOb2
->setValue(pOb2
->getValue().getDouble());
358 case DataType::FLOAT
:
359 pOb1
->setValue(pOb1
->getValue().getFloat());
360 pOb2
->setValue(pOb2
->getValue().getFloat());
363 pOb1
->setValue(pOb1
->getValue().getDate());
364 pOb2
->setValue(pOb2
->getValue().getDate());
367 pOb1
->setValue(pOb1
->getValue().getTime());
368 pOb2
->setValue(pOb2
->getValue().getTime());
370 case DataType::TIMESTAMP
:
371 pOb1
->setValue(pOb1
->getValue().getDateTime());
372 pOb2
->setValue(pOb2
->getValue().getDateTime());
378 OBoolOperator
* pBoolOp
= nullptr;
380 pBoolOp
= new OOp_OR
;
382 pBoolOp
= new OOp_AND
;
383 m_aCodeList
.emplace_back(pBoolOp
);
386 void OPredicateCompiler::execute_ISNULL(OSQLParseNode
const * pPredicateNode
)
388 DBG_ASSERT(pPredicateNode
->count() == 2,"OFILECursor: Error in Parse Tree");
389 const OSQLParseNode
* pPart2
= pPredicateNode
->getChild(1);
390 DBG_ASSERT(SQL_ISTOKEN(pPart2
->getChild(0),IS
),"OFILECursor: Error in Parse Tree");
392 sal_Int32 ePredicateType
;
393 if (SQL_ISTOKEN(pPart2
->getChild(1),NOT
))
394 ePredicateType
= SQLFilterOperator::NOT_SQLNULL
;
396 ePredicateType
= SQLFilterOperator::SQLNULL
;
398 execute(pPredicateNode
->getChild(0));
399 OBoolOperator
* pOperator
= (ePredicateType
== SQLFilterOperator::SQLNULL
) ?
400 new OOp_ISNULL
: new OOp_ISNOTNULL
;
401 m_aCodeList
.emplace_back(pOperator
);
404 OOperand
* OPredicateCompiler::execute_Operand(OSQLParseNode
const * pPredicateNode
)
406 OOperand
* pOperand
= nullptr;
408 if (SQL_ISRULE(pPredicateNode
,column_ref
))
410 OUString aColumnName
;
411 if (pPredicateNode
->count() == 1)
413 aColumnName
= pPredicateNode
->getChild(0)->getTokenValue();
415 else if (pPredicateNode
->count() == 3)
417 if(SQL_ISRULE(pPredicateNode
->getChild(2),column_val
))
418 aColumnName
= pPredicateNode
->getChild(2)->getChild(0)->getTokenValue();
420 aColumnName
= pPredicateNode
->getChild(2)->getTokenValue();
423 if(!m_orgColumns
->hasByName(aColumnName
))
425 const OUString
sError( m_pAnalyzer
->getConnection()->getResources().getResourceStringWithSubstitution(
426 STR_INVALID_COLUMNNAME
,
427 "$columnname$", aColumnName
429 ::dbtools::throwGenericSQLException( sError
, nullptr );
431 css::uno::Reference
< css::beans::XPropertySet
> xCol
;
434 if (m_orgColumns
->getByName(aColumnName
) >>= xCol
)
436 pOperand
= OSQLAnalyzer::createOperandAttr(Reference
< XColumnLocate
>(m_orgColumns
,UNO_QUERY_THROW
)->findColumn(aColumnName
),xCol
);
439 {// Column doesn't exist in the Result-set
440 const OUString
sError( m_pAnalyzer
->getConnection()->getResources().getResourceStringWithSubstitution(
441 STR_INVALID_COLUMNNAME
,
442 "$columnname$", aColumnName
444 ::dbtools::throwGenericSQLException( sError
, nullptr );
449 TOOLS_WARN_EXCEPTION( "connectivity.drivers", "OPredicateCompiler::execute_Operand Exception");
452 else if (SQL_ISRULE(pPredicateNode
,parameter
))
454 pOperand
= new OOperandParam(++m_nParamCounter
);
456 else if (pPredicateNode
->getNodeType() == SQLNodeType::String
||
457 pPredicateNode
->getNodeType() == SQLNodeType::IntNum
||
458 pPredicateNode
->getNodeType() == SQLNodeType::ApproxNum
||
459 pPredicateNode
->getNodeType() == SQLNodeType::Name
||
460 SQL_ISTOKEN(pPredicateNode
,TRUE
) ||
461 SQL_ISTOKEN(pPredicateNode
,FALSE
) ||
462 SQL_ISRULE(pPredicateNode
,parameter
))
464 pOperand
= new OOperandConst(*pPredicateNode
, pPredicateNode
->getTokenValue());
466 else if((pPredicateNode
->count() == 2) &&
467 (SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"-")) &&
468 pPredicateNode
->getChild(1)->getNodeType() == SQLNodeType::IntNum
)
469 { // if -1 or +1 is there
470 OUString aValue
= pPredicateNode
->getChild(0)->getTokenValue() + pPredicateNode
->getChild(1)->getTokenValue();
471 pOperand
= new OOperandConst(*pPredicateNode
->getChild(1), aValue
);
473 else if( SQL_ISRULE(pPredicateNode
,set_fct_spec
) && SQL_ISPUNCTUATION(pPredicateNode
->getChild(0),"{") )
475 const OSQLParseNode
* pODBCNode
= pPredicateNode
->getChild(1);
476 const OSQLParseNode
* pODBCNodeChild
= pODBCNode
->getChild(0);
479 if (pODBCNodeChild
->getNodeType() == SQLNodeType::Keyword
&& (
480 SQL_ISTOKEN(pODBCNodeChild
,D
) ||
481 SQL_ISTOKEN(pODBCNodeChild
,T
) ||
482 SQL_ISTOKEN(pODBCNodeChild
,TS
) ))
484 OUString sDateTime
= pODBCNode
->getChild(1)->getTokenValue();
485 pOperand
= new OOperandConst(*pODBCNode
->getChild(1), sDateTime
);
486 if(SQL_ISTOKEN(pODBCNodeChild
,D
))
488 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime
)));
490 else if(SQL_ISTOKEN(pODBCNodeChild
,T
))
492 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime
)));
494 else if(SQL_ISTOKEN(pODBCNodeChild
,TS
))
496 pOperand
->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime
)));
500 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,nullptr);
503 else if( SQL_ISRULE(pPredicateNode
,fold
) )
505 execute_Fold(pPredicateNode
);
507 else if( SQL_ISRULE(pPredicateNode
,set_fct_spec
)
508 || SQL_ISRULE(pPredicateNode
,position_exp
)
509 || SQL_ISRULE(pPredicateNode
,char_substring_fct
)
512 executeFunction(pPredicateNode
);
514 else if( SQL_ISRULE(pPredicateNode
,length_exp
) )
516 executeFunction(pPredicateNode
->getChild(0));
520 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX
,nullptr);
523 m_aCodeList
.emplace_back(pOperand
);
528 bool OPredicateInterpreter::evaluate(OCodeList
& rCodeList
)
531 return true; // no Predicate
533 for (auto const& code
: rCodeList
)
535 OOperand
* pOperand
= dynamic_cast<OOperand
* >(code
.get());
537 m_aStack
.push(pOperand
);
539 static_cast<OOperator
*>(code
.get())->Exec(m_aStack
);
542 OOperand
* pOperand
= m_aStack
.top();
545 DBG_ASSERT(m_aStack
.empty(), "Stack error");
546 assert(pOperand
&& "Stack error");
548 const bool bResult
= pOperand
->isValid();
549 if (typeid(OOperandResult
) == typeid(*pOperand
))
554 void OPredicateInterpreter::evaluateSelection(OCodeList
& rCodeList
, ORowSetValueDecoratorRef
const & _rVal
)
557 return ; // no Predicate
559 for (auto const& code
: rCodeList
)
561 OOperand
* pOperand
= dynamic_cast<OOperand
* >(code
.get());
563 m_aStack
.push(pOperand
);
565 static_cast<OOperator
*>(code
.get())->Exec(m_aStack
);
568 OOperand
* pOperand
= m_aStack
.top();
571 DBG_ASSERT(m_aStack
.empty(), "Stack error");
572 assert(pOperand
&& "Stack error");
574 (*_rVal
) = pOperand
->getValue();
575 if (typeid(OOperandResult
) == typeid(*pOperand
))
579 void OPredicateCompiler::execute_Fold(OSQLParseNode
const * pPredicateNode
)
581 DBG_ASSERT(pPredicateNode
->count() >= 4,"OFILECursor: Error in Parse Tree");
583 bool bUpper
= SQL_ISTOKEN(pPredicateNode
->getChild(0),UPPER
);
585 execute(pPredicateNode
->getChild(2));
586 OOperator
* pOperator
= nullptr;
588 pOperator
= new OOp_Upper
;
590 pOperator
= new OOp_Lower
;
592 m_aCodeList
.emplace_back(pOperator
);
595 void OPredicateCompiler::executeFunction(OSQLParseNode
const * pPredicateNode
)
597 OOperator
* pOperator
= nullptr;
599 OSL_ENSURE(pPredicateNode
->getChild(0)->isToken(),"The first one must be the name of the function!");
600 sal_Int32 nTokenId
= pPredicateNode
->getChild(0)->getTokenID();
603 case SQL_TOKEN_CHAR_LENGTH
:
604 case SQL_TOKEN_LENGTH
:
605 case SQL_TOKEN_OCTET_LENGTH
:
606 case SQL_TOKEN_ASCII
:
607 case SQL_TOKEN_LCASE
:
608 case SQL_TOKEN_LTRIM
:
609 case SQL_TOKEN_RTRIM
:
610 case SQL_TOKEN_SPACE
:
611 case SQL_TOKEN_UCASE
:
616 case SQL_TOKEN_CEILING
:
618 case SQL_TOKEN_DEGREES
:
620 case SQL_TOKEN_FLOOR
:
621 case SQL_TOKEN_LOG10
:
623 case SQL_TOKEN_RADIANS
:
628 case SQL_TOKEN_DAYNAME
:
629 case SQL_TOKEN_DAYOFMONTH
:
630 case SQL_TOKEN_DAYOFWEEK
:
631 case SQL_TOKEN_DAYOFYEAR
:
633 case SQL_TOKEN_MINUTE
:
634 case SQL_TOKEN_MONTH
:
635 case SQL_TOKEN_MONTHNAME
:
636 case SQL_TOKEN_QUARTER
:
637 case SQL_TOKEN_SECOND
:
640 execute(pPredicateNode
->getChild(2));
644 case SQL_TOKEN_CHAR_LENGTH
:
645 case SQL_TOKEN_LENGTH
:
646 case SQL_TOKEN_OCTET_LENGTH
:
647 pOperator
= new OOp_CharLength
;
649 case SQL_TOKEN_ASCII
:
650 pOperator
= new OOp_Ascii
;
652 case SQL_TOKEN_LCASE
:
653 pOperator
= new OOp_Lower
;
656 case SQL_TOKEN_LTRIM
:
657 pOperator
= new OOp_LTrim
;
659 case SQL_TOKEN_RTRIM
:
660 pOperator
= new OOp_RTrim
;
662 case SQL_TOKEN_SPACE
:
663 pOperator
= new OOp_Space
;
665 case SQL_TOKEN_UCASE
:
666 pOperator
= new OOp_Upper
;
669 pOperator
= new OOp_Abs
;
672 pOperator
= new OOp_ACos
;
675 pOperator
= new OOp_ASin
;
678 pOperator
= new OOp_ATan
;
680 case SQL_TOKEN_CEILING
:
681 pOperator
= new OOp_Ceiling
;
684 pOperator
= new OOp_Cos
;
686 case SQL_TOKEN_DEGREES
:
687 pOperator
= new OOp_Degrees
;
690 pOperator
= new OOp_Exp
;
692 case SQL_TOKEN_FLOOR
:
693 pOperator
= new OOp_Floor
;
695 case SQL_TOKEN_LOG10
:
696 pOperator
= new OOp_Log10
;
699 pOperator
= new OOp_Ln
;
701 case SQL_TOKEN_RADIANS
:
702 pOperator
= new OOp_Radians
;
705 pOperator
= new OOp_Sign
;
708 pOperator
= new OOp_Sin
;
711 pOperator
= new OOp_Sqrt
;
714 pOperator
= new OOp_Tan
;
716 case SQL_TOKEN_DAYOFWEEK
:
717 pOperator
= new OOp_DayOfWeek
;
719 case SQL_TOKEN_DAYOFMONTH
:
720 pOperator
= new OOp_DayOfMonth
;
722 case SQL_TOKEN_DAYOFYEAR
:
723 pOperator
= new OOp_DayOfYear
;
725 case SQL_TOKEN_MONTH
:
726 pOperator
= new OOp_Month
;
728 case SQL_TOKEN_DAYNAME
:
729 pOperator
= new OOp_DayName
;
731 case SQL_TOKEN_MONTHNAME
:
732 pOperator
= new OOp_MonthName
;
734 case SQL_TOKEN_QUARTER
:
735 pOperator
= new OOp_Quarter
;
738 pOperator
= new OOp_Year
;
741 pOperator
= new OOp_Hour
;
743 case SQL_TOKEN_MINUTE
:
744 pOperator
= new OOp_Minute
;
746 case SQL_TOKEN_SECOND
:
747 pOperator
= new OOp_Second
;
750 OSL_FAIL("Error in switch!");
754 case SQL_TOKEN_CONCAT
:
755 case SQL_TOKEN_INSERT
:
757 case SQL_TOKEN_LOCATE
:
758 case SQL_TOKEN_LOCATE_2
:
759 case SQL_TOKEN_REPEAT
:
760 case SQL_TOKEN_REPLACE
:
761 case SQL_TOKEN_RIGHT
:
763 case SQL_TOKEN_ROUND
:
766 case SQL_TOKEN_POWER
:
767 case SQL_TOKEN_ATAN2
:
769 case SQL_TOKEN_CURDATE
:
770 case SQL_TOKEN_CURTIME
:
774 m_aCodeList
.emplace_back(new OStopOperand
);
775 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
776 for (size_t i
=0; i
< pList
->count(); ++i
)
777 execute(pList
->getChild(i
));
782 pOperator
= new OOp_Char
;
784 case SQL_TOKEN_CONCAT
:
785 pOperator
= new OOp_Concat
;
787 case SQL_TOKEN_INSERT
:
788 pOperator
= new OOp_Insert
;
791 pOperator
= new OOp_Left
;
793 case SQL_TOKEN_LOCATE
:
794 case SQL_TOKEN_LOCATE_2
:
795 pOperator
= new OOp_Locate
;
797 case SQL_TOKEN_REPEAT
:
798 pOperator
= new OOp_Repeat
;
800 case SQL_TOKEN_REPLACE
:
801 pOperator
= new OOp_Replace
;
803 case SQL_TOKEN_RIGHT
:
804 pOperator
= new OOp_Right
;
807 pOperator
= new OOp_Mod
;
809 case SQL_TOKEN_ROUND
:
810 pOperator
= new OOp_Round
;
814 pOperator
= new OOp_Log
;
816 case SQL_TOKEN_POWER
:
817 pOperator
= new OOp_Pow
;
819 case SQL_TOKEN_ATAN2
:
820 pOperator
= new OOp_ATan2
;
823 pOperator
= new OOp_Pi
;
825 case SQL_TOKEN_CURDATE
:
826 pOperator
= new OOp_CurDate
;
828 case SQL_TOKEN_CURTIME
:
829 pOperator
= new OOp_CurTime
;
832 pOperator
= new OOp_Now
;
835 pOperator
= new OOp_Week
;
838 OSL_FAIL("Error in switch!");
843 case SQL_TOKEN_SUBSTRING
:
844 m_aCodeList
.emplace_back(new OStopOperand
);
845 if ( pPredicateNode
->count() == 4 ) //char_substring_fct
847 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
848 for (size_t i
=0; i
< pList
->count(); ++i
)
849 execute(pList
->getChild(i
));
853 execute(pPredicateNode
->getChild(2));
854 execute(pPredicateNode
->getChild(4));
855 execute(pPredicateNode
->getChild(5)->getChild(1));
857 pOperator
= new OOp_SubString
;
860 case SQL_TOKEN_POSITION
:
861 m_aCodeList
.emplace_back(new OStopOperand
);
862 if ( pPredicateNode
->count() == 4 ) //position_exp
864 OSQLParseNode
* pList
= pPredicateNode
->getChild(2);
865 for (size_t i
=0; i
< pList
->count(); ++i
)
866 execute(pList
->getChild(i
));
870 execute(pPredicateNode
->getChild(2));
871 execute(pPredicateNode
->getChild(4));
873 pOperator
= new OOp_Locate
;
876 m_pAnalyzer
->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED
,nullptr);
879 m_aCodeList
.emplace_back(pOperator
);
883 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */