1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
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 <com/sun/star/util/DateTime.hpp>
26 #include <com/sun/star/util/Date.hpp>
27 #include <com/sun/star/util/Time.hpp>
28 #include <connectivity/dbexception.hxx>
29 #include <connectivity/dbconversion.hxx>
30 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
31 #include <file/FStringFunctions.hxx>
32 #include <file/FDateFunctions.hxx>
33 #include <file/FNumericFunctions.hxx>
34 #include <file/FConnection.hxx>
35 #include <tools/diagnose_ex.h>
36 #include <sqlbison.hxx>
37 #include <strings.hrc>
38
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;
46
OPredicateCompiler(OSQLAnalyzer * pAnalyzer)47 OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer* pAnalyzer)//,OCursor& rCurs)
48 : m_pAnalyzer(pAnalyzer)
49 , m_nParamCounter(0)
50 {
51 }
52
53
~OPredicateCompiler()54 OPredicateCompiler::~OPredicateCompiler()
55 {
56 Clean();
57 }
58
dispose()59 void OPredicateCompiler::dispose()
60 {
61 Clean();
62 m_orgColumns = nullptr;
63 }
64
start(OSQLParseNode const * pSQLParseNode)65 void OPredicateCompiler::start(OSQLParseNode const * pSQLParseNode)
66 {
67 if (!pSQLParseNode)
68 return;
69
70 m_nParamCounter = 0;
71 // analyse Parse Tree (depending on Statement-type)
72 // and set pointer on WHERE-clause:
73 OSQLParseNode * pWhereClause = nullptr;
74
75 if (SQL_ISRULE(pSQLParseNode,select_statement))
76 {
77 OSQLParseNode * pOrderbyClause = nullptr;
78 DBG_ASSERT(pSQLParseNode->count() >= 4,"OFILECursor: Error in Parse Tree");
79
80 OSQLParseNode * pTableExp = pSQLParseNode->getChild(3);
81 DBG_ASSERT(pTableExp != nullptr,"Error in Parse Tree");
82 DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp)," Error in Parse Tree");
83 DBG_ASSERT(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"Error in Parse Tree");
84
85 // check that we don't use anything other than count(*) as function
86 OSQLParseNode* pSelection = pSQLParseNode->getChild(2);
87 if ( SQL_ISRULE(pSelection,scalar_exp_commalist) )
88 {
89 for (size_t i = 0; i < pSelection->count(); i++)
90 {
91 OSQLParseNode *pColumnRef = pSelection->getChild(i)->getChild(0);
92 if ( SQL_ISRULE(pColumnRef,general_set_fct) && pColumnRef->count() != 4 )
93 {
94 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT,nullptr);
95 }
96 }
97 }
98
99
100 pWhereClause = pTableExp->getChild(1);
101 pOrderbyClause = pTableExp->getChild(ORDER_BY_CHILD_POS);
102 (void)pOrderbyClause;
103 }
104 else if (SQL_ISRULE(pSQLParseNode,update_statement_searched))
105 {
106 DBG_ASSERT(pSQLParseNode->count() == 5,"OFILECursor: Error in Parse Tree");
107 pWhereClause = pSQLParseNode->getChild(4);
108 }
109 else if (SQL_ISRULE(pSQLParseNode,delete_statement_searched))
110 {
111 DBG_ASSERT(pSQLParseNode->count() == 4,"Error in Parse Tree");
112 pWhereClause = pSQLParseNode->getChild(3);
113 }
114 else
115 // Other Statement. no selection-criteria
116 return;
117
118 if (SQL_ISRULE(pWhereClause,where_clause))
119 {
120 // a where-clause is not allowed to be empty:
121 DBG_ASSERT(pWhereClause->count() == 2,"OFILECursor: Error in Parse Tree");
122
123 OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1);
124 DBG_ASSERT(pComparisonPredicate != nullptr,"OFILECursor: Error in Parse Tree");
125
126 execute( pComparisonPredicate );
127 }
128 else
129 {
130 // The where-clause is optionally in the majority of cases, i.e. it might be an "optional-where-clause".
131 DBG_ASSERT(SQL_ISRULE(pWhereClause,opt_where_clause),"OPredicateCompiler: Error in Parse Tree");
132 }
133 }
134
135
execute(OSQLParseNode const * pPredicateNode)136 OOperand* OPredicateCompiler::execute(OSQLParseNode const * pPredicateNode)
137 {
138 OOperand* pOperand = nullptr;
139 if (pPredicateNode->count() == 3 && // Expression is bracketed
140 SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"(") &&
141 SQL_ISPUNCTUATION(pPredicateNode->getChild(2),")"))
142 {
143 execute(pPredicateNode->getChild(1));
144 }
145 else if ((SQL_ISRULE(pPredicateNode,search_condition) || SQL_ISRULE(pPredicateNode,boolean_term))
146 && // AND/OR-linkage:
147 pPredicateNode->count() == 3)
148 {
149 execute(pPredicateNode->getChild(0)); // process the left branch
150 execute(pPredicateNode->getChild(2)); // process the right branch
151
152 if (SQL_ISTOKEN(pPredicateNode->getChild(1),OR)) // OR-Operator
153 {
154 m_aCodeList.emplace_back(new OOp_OR);
155 }
156 else if (SQL_ISTOKEN(pPredicateNode->getChild(1),AND)) // AND-Operator
157 m_aCodeList.emplace_back(new OOp_AND);
158 else
159 {
160 OSL_FAIL("OPredicateCompiler: Error in Parse Tree");
161 }
162 }
163 else if (SQL_ISRULE(pPredicateNode,boolean_factor))
164 {
165 execute(pPredicateNode->getChild(1));
166 m_aCodeList.emplace_back(new OOp_NOT);
167 }
168 else if (SQL_ISRULE(pPredicateNode,comparison_predicate))
169 {
170 execute_COMPARE(pPredicateNode);
171 }
172 else if (SQL_ISRULE(pPredicateNode,like_predicate))
173 {
174 execute_LIKE(pPredicateNode);
175 }
176 else if (SQL_ISRULE(pPredicateNode,between_predicate))
177 {
178 execute_BETWEEN(pPredicateNode);
179 }
180 else if (SQL_ISRULE(pPredicateNode,test_for_null))
181 {
182 execute_ISNULL(pPredicateNode);
183 }
184 else if(SQL_ISRULE(pPredicateNode,num_value_exp))
185 {
186 execute(pPredicateNode->getChild(0)); // process the left branch
187 execute(pPredicateNode->getChild(2)); // process the right branch
188 if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"+"))
189 {
190 m_aCodeList.emplace_back(new OOp_ADD);
191 }
192 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"-"))
193 m_aCodeList.emplace_back(new OOp_SUB);
194 else
195 {
196 OSL_FAIL("OPredicateCompiler: Error in Parse Tree num_value_exp");
197 }
198 }
199 else if(SQL_ISRULE(pPredicateNode,term))
200 {
201 execute(pPredicateNode->getChild(0)); // process the left branch
202 execute(pPredicateNode->getChild(2)); // process the right branch
203 if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"*"))
204 {
205 m_aCodeList.emplace_back(new OOp_MUL);
206 }
207 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"/"))
208 m_aCodeList.emplace_back(new OOp_DIV);
209 else
210 {
211 OSL_FAIL("OPredicateCompiler: Error in Parse Tree num_value_exp");
212 }
213 }
214 else
215 pOperand = execute_Operand(pPredicateNode); // now only simple operands will be processed
216
217 return pOperand;
218 }
219
220
execute_COMPARE(OSQLParseNode const * pPredicateNode)221 void OPredicateCompiler::execute_COMPARE(OSQLParseNode const * pPredicateNode)
222 {
223 DBG_ASSERT(pPredicateNode->count() == 3,"OFILECursor: Error in Parse Tree");
224
225 if ( !(SQL_ISRULE(pPredicateNode->getChild(0),column_ref) ||
226 pPredicateNode->getChild(2)->getNodeType() == SQLNodeType::String ||
227 pPredicateNode->getChild(2)->getNodeType() == SQLNodeType::IntNum ||
228 pPredicateNode->getChild(2)->getNodeType() == SQLNodeType::ApproxNum ||
229 SQL_ISTOKEN(pPredicateNode->getChild(2),TRUE) ||
230 SQL_ISTOKEN(pPredicateNode->getChild(2),FALSE) ||
231 SQL_ISRULE(pPredicateNode->getChild(2),parameter) ||
232 // odbc date
233 SQL_ISRULE(pPredicateNode->getChild(2),set_fct_spec) ||
234 SQL_ISRULE(pPredicateNode->getChild(2),position_exp) ||
235 SQL_ISRULE(pPredicateNode->getChild(2),char_substring_fct) ||
236 // upper, lower etc.
237 SQL_ISRULE(pPredicateNode->getChild(2),fold)) )
238 {
239 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,nullptr);
240 return;
241 }
242
243 sal_Int32 ePredicateType( SQLFilterOperator::EQUAL );
244 OSQLParseNode *pPrec = pPredicateNode->getChild(1);
245
246 if (pPrec->getNodeType() == SQLNodeType::Equal)
247 ePredicateType = SQLFilterOperator::EQUAL;
248 else if (pPrec->getNodeType() == SQLNodeType::NotEqual)
249 ePredicateType = SQLFilterOperator::NOT_EQUAL;
250 else if (pPrec->getNodeType() == SQLNodeType::Less)
251 ePredicateType = SQLFilterOperator::LESS;
252 else if (pPrec->getNodeType() == SQLNodeType::LessEq)
253 ePredicateType = SQLFilterOperator::LESS_EQUAL;
254 else if (pPrec->getNodeType() == SQLNodeType::GreatEq)
255 ePredicateType = SQLFilterOperator::GREATER_EQUAL;
256 else if (pPrec->getNodeType() == SQLNodeType::Great)
257 ePredicateType = SQLFilterOperator::GREATER;
258 else
259 OSL_FAIL( "OPredicateCompiler::execute_COMPARE: unexpected node type!" );
260
261 execute(pPredicateNode->getChild(0));
262 execute(pPredicateNode->getChild(2));
263 m_aCodeList.emplace_back( new OOp_COMPARE(ePredicateType) );
264 }
265
266
execute_LIKE(OSQLParseNode const * pPredicateNode)267 void OPredicateCompiler::execute_LIKE(OSQLParseNode const * pPredicateNode)
268 {
269 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Error in Parse Tree");
270 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
271
272 sal_Unicode cEscape = L'\0';
273 const bool bNotLike = pPart2->getChild(0)->isToken();
274
275 OSQLParseNode* pAtom = pPart2->getChild(pPart2->count()-2);
276 OSQLParseNode* pOptEscape = pPart2->getChild(pPart2->count()-1);
277
278 if (!(pAtom->getNodeType() == SQLNodeType::String ||
279 SQL_ISRULE(pAtom,parameter) ||
280 // odbc date
281 SQL_ISRULE(pAtom,set_fct_spec) ||
282 SQL_ISRULE(pAtom,position_exp) ||
283 SQL_ISRULE(pAtom,char_substring_fct) ||
284 // upper, lower etc.
285 SQL_ISRULE(pAtom,fold)) )
286 {
287 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,nullptr);
288 return;
289 }
290
291 if (pOptEscape->count() != 0)
292 {
293 if (pOptEscape->count() != 2)
294 {
295 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,nullptr);
296 }
297 OSQLParseNode *pEscNode = pOptEscape->getChild(1);
298 if (pEscNode->getNodeType() != SQLNodeType::String)
299 {
300 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,nullptr);
301 }
302 else
303 cEscape = pEscNode->getTokenValue().toChar();
304 }
305
306 execute(pPredicateNode->getChild(0));
307 execute(pAtom);
308
309 OBoolOperator* pOperator = bNotLike
310 ? new OOp_NOTLIKE(cEscape)
311 : new OOp_LIKE(cEscape);
312 m_aCodeList.emplace_back(pOperator);
313 }
314
execute_BETWEEN(OSQLParseNode const * pPredicateNode)315 void OPredicateCompiler::execute_BETWEEN(OSQLParseNode const * pPredicateNode)
316 {
317 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Error in Parse Tree");
318
319 OSQLParseNode* pColumn = pPredicateNode->getChild(0);
320 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
321 OSQLParseNode* p1stValue = pPart2->getChild(2);
322 OSQLParseNode* p2ndtValue = pPart2->getChild(4);
323
324 if (
325 !(p1stValue->getNodeType() == SQLNodeType::String || SQL_ISRULE(p1stValue,parameter))
326 && !(p2ndtValue->getNodeType() == SQLNodeType::String || SQL_ISRULE(p2ndtValue,parameter))
327 )
328 {
329 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN,nullptr);
330 }
331
332 bool bNot = SQL_ISTOKEN(pPart2->getChild(0),NOT);
333
334 OOperand* pColumnOp = execute(pColumn);
335 OOperand* pOb1 = execute(p1stValue);
336 OBoolOperator* pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::LESS_EQUAL : SQLFilterOperator::GREATER);
337 m_aCodeList.emplace_back(pOperator);
338
339 execute(pColumn);
340 OOperand* pOb2 = execute(p2ndtValue);
341 pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::GREATER_EQUAL : SQLFilterOperator::LESS);
342 m_aCodeList.emplace_back(pOperator);
343
344 if ( pColumnOp && pOb1 && pOb2 )
345 {
346 switch(pColumnOp->getDBType())
347 {
348 case DataType::CHAR:
349 case DataType::VARCHAR:
350 case DataType::LONGVARCHAR:
351 pOb1->setValue(pOb1->getValue().getString());
352 pOb2->setValue(pOb2->getValue().getString());
353 break;
354 case DataType::DECIMAL:
355 case DataType::NUMERIC:
356 pOb1->setValue(static_cast<double>(pOb1->getValue()));
357 pOb2->setValue(static_cast<double>(pOb2->getValue()));
358 break;
359 case DataType::FLOAT:
360 pOb1->setValue(static_cast<float>(pOb1->getValue()));
361 pOb2->setValue(static_cast<float>(pOb2->getValue()));
362 break;
363 case DataType::DOUBLE:
364 case DataType::REAL:
365 pOb1->setValue(static_cast<double>(pOb1->getValue()));
366 pOb2->setValue(static_cast<double>(pOb2->getValue()));
367 break;
368 case DataType::DATE:
369 pOb1->setValue(static_cast<util::Date>(pOb1->getValue()));
370 pOb2->setValue(static_cast<util::Date>(pOb2->getValue()));
371 break;
372 case DataType::TIME:
373 pOb1->setValue(static_cast<util::Time>(pOb1->getValue()));
374 pOb2->setValue(static_cast<util::Time>(pOb2->getValue()));
375 break;
376 case DataType::TIMESTAMP:
377 pOb1->setValue(static_cast<util::DateTime>(pOb1->getValue()));
378 pOb2->setValue(static_cast<util::DateTime>(pOb2->getValue()));
379 break;
380 }
381 }
382
383
384 OBoolOperator* pBoolOp = nullptr;
385 if ( bNot )
386 pBoolOp = new OOp_OR;
387 else
388 pBoolOp = new OOp_AND;
389 m_aCodeList.emplace_back(pBoolOp);
390 }
391
execute_ISNULL(OSQLParseNode const * pPredicateNode)392 void OPredicateCompiler::execute_ISNULL(OSQLParseNode const * pPredicateNode)
393 {
394 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Error in Parse Tree");
395 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
396 DBG_ASSERT(SQL_ISTOKEN(pPart2->getChild(0),IS),"OFILECursor: Error in Parse Tree");
397
398 sal_Int32 ePredicateType;
399 if (SQL_ISTOKEN(pPart2->getChild(1),NOT))
400 ePredicateType = SQLFilterOperator::NOT_SQLNULL;
401 else
402 ePredicateType = SQLFilterOperator::SQLNULL;
403
404 execute(pPredicateNode->getChild(0));
405 OBoolOperator* pOperator = (ePredicateType == SQLFilterOperator::SQLNULL) ?
406 new OOp_ISNULL : new OOp_ISNOTNULL;
407 m_aCodeList.emplace_back(pOperator);
408 }
409
execute_Operand(OSQLParseNode const * pPredicateNode)410 OOperand* OPredicateCompiler::execute_Operand(OSQLParseNode const * pPredicateNode)
411 {
412 OOperand* pOperand = nullptr;
413
414 if (SQL_ISRULE(pPredicateNode,column_ref))
415 {
416 OUString aColumnName;
417 if (pPredicateNode->count() == 1)
418 {
419 aColumnName = pPredicateNode->getChild(0)->getTokenValue();
420 }
421 else if (pPredicateNode->count() == 3)
422 {
423 if(SQL_ISRULE(pPredicateNode->getChild(2),column_val))
424 aColumnName = pPredicateNode->getChild(2)->getChild(0)->getTokenValue();
425 else
426 aColumnName = pPredicateNode->getChild(2)->getTokenValue();
427 }
428
429 if(!m_orgColumns->hasByName(aColumnName))
430 {
431 const OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution(
432 STR_INVALID_COLUMNNAME,
433 "$columnname$", aColumnName
434 ) );
435 ::dbtools::throwGenericSQLException( sError, nullptr );
436 }
437 css::uno::Reference< css::beans::XPropertySet> xCol;
438 try
439 {
440 if (m_orgColumns->getByName(aColumnName) >>= xCol)
441 {
442 pOperand = OSQLAnalyzer::createOperandAttr(Reference< XColumnLocate>(m_orgColumns,UNO_QUERY_THROW)->findColumn(aColumnName),xCol);
443 }
444 else
445 {// Column doesn't exist in the Result-set
446 const OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution(
447 STR_INVALID_COLUMNNAME,
448 "$columnname$", aColumnName
449 ) );
450 ::dbtools::throwGenericSQLException( sError, nullptr );
451 }
452 }
453 catch(Exception &)
454 {
455 TOOLS_WARN_EXCEPTION( "connectivity.drivers", "OPredicateCompiler::execute_Operand Exception");
456 }
457 }
458 else if (SQL_ISRULE(pPredicateNode,parameter))
459 {
460 pOperand = new OOperandParam(++m_nParamCounter);
461 }
462 else if (pPredicateNode->getNodeType() == SQLNodeType::String ||
463 pPredicateNode->getNodeType() == SQLNodeType::IntNum ||
464 pPredicateNode->getNodeType() == SQLNodeType::ApproxNum ||
465 pPredicateNode->getNodeType() == SQLNodeType::Name ||
466 SQL_ISTOKEN(pPredicateNode,TRUE) ||
467 SQL_ISTOKEN(pPredicateNode,FALSE) ||
468 SQL_ISRULE(pPredicateNode,parameter))
469 {
470 pOperand = new OOperandConst(*pPredicateNode, pPredicateNode->getTokenValue());
471 }
472 else if((pPredicateNode->count() == 2) &&
473 (SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"-")) &&
474 pPredicateNode->getChild(1)->getNodeType() == SQLNodeType::IntNum)
475 { // if -1 or +1 is there
476 OUString aValue = pPredicateNode->getChild(0)->getTokenValue() + pPredicateNode->getChild(1)->getTokenValue();
477 pOperand = new OOperandConst(*pPredicateNode->getChild(1), aValue);
478 }
479 else if( SQL_ISRULE(pPredicateNode,set_fct_spec) && SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"{") )
480 {
481 const OSQLParseNode* pODBCNode = pPredicateNode->getChild(1);
482 const OSQLParseNode* pODBCNodeChild = pODBCNode->getChild(0);
483
484 // Odbc Date or time
485 if (pODBCNodeChild->getNodeType() == SQLNodeType::Keyword && (
486 SQL_ISTOKEN(pODBCNodeChild,D) ||
487 SQL_ISTOKEN(pODBCNodeChild,T) ||
488 SQL_ISTOKEN(pODBCNodeChild,TS) ))
489 {
490 OUString sDateTime = pODBCNode->getChild(1)->getTokenValue();
491 pOperand = new OOperandConst(*pODBCNode->getChild(1), sDateTime);
492 if(SQL_ISTOKEN(pODBCNodeChild,D))
493 {
494 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime)));
495 }
496 else if(SQL_ISTOKEN(pODBCNodeChild,T))
497 {
498 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime)));
499 }
500 else if(SQL_ISTOKEN(pODBCNodeChild,TS))
501 {
502 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime)));
503 }
504 }
505 else
506 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,nullptr);
507
508 }
509 else if( SQL_ISRULE(pPredicateNode,fold) )
510 {
511 execute_Fold(pPredicateNode);
512 }
513 else if( SQL_ISRULE(pPredicateNode,set_fct_spec)
514 || SQL_ISRULE(pPredicateNode,position_exp)
515 || SQL_ISRULE(pPredicateNode,char_substring_fct)
516 )
517 {
518 executeFunction(pPredicateNode);
519 }
520 else if( SQL_ISRULE(pPredicateNode,length_exp) )
521 {
522 executeFunction(pPredicateNode->getChild(0));
523 }
524 else
525 {
526 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,nullptr);
527 }
528 if (pOperand)
529 m_aCodeList.emplace_back(pOperand);
530 return pOperand;
531 }
532
533
evaluate(OCodeList & rCodeList)534 bool OPredicateInterpreter::evaluate(OCodeList& rCodeList)
535 {
536 if (!(rCodeList[0]))
537 return true; // no Predicate
538
539 for (auto const& code : rCodeList)
540 {
541 OOperand* pOperand = dynamic_cast<OOperand* >(code.get());
542 if (pOperand)
543 m_aStack.push(pOperand);
544 else
545 static_cast<OOperator *>(code.get())->Exec(m_aStack);
546 }
547
548 OOperand* pOperand = m_aStack.top();
549 m_aStack.pop();
550
551 DBG_ASSERT(m_aStack.empty(), "Stack error");
552 DBG_ASSERT(pOperand, "Stack error");
553
554 const bool bResult = pOperand->isValid();
555 if (typeid(OOperandResult) == typeid(*pOperand))
556 delete pOperand;
557 return bResult;
558 }
559
evaluateSelection(OCodeList & rCodeList,ORowSetValueDecoratorRef const & _rVal)560 void OPredicateInterpreter::evaluateSelection(OCodeList& rCodeList, ORowSetValueDecoratorRef const & _rVal)
561 {
562 if (!(rCodeList[0]))
563 return ; // no Predicate
564
565 for (auto const& code : rCodeList)
566 {
567 OOperand* pOperand = dynamic_cast<OOperand* >(code.get());
568 if (pOperand)
569 m_aStack.push(pOperand);
570 else
571 static_cast<OOperator *>(code.get())->Exec(m_aStack);
572 }
573
574 OOperand* pOperand = m_aStack.top();
575 m_aStack.pop();
576
577 DBG_ASSERT(m_aStack.empty(), "Stack error");
578 DBG_ASSERT(pOperand, "Stack error");
579
580 (*_rVal) = pOperand->getValue();
581 if (typeid(OOperandResult) == typeid(*pOperand))
582 delete pOperand;
583 }
584
execute_Fold(OSQLParseNode const * pPredicateNode)585 void OPredicateCompiler::execute_Fold(OSQLParseNode const * pPredicateNode)
586 {
587 DBG_ASSERT(pPredicateNode->count() >= 4,"OFILECursor: Error in Parse Tree");
588
589 bool bUpper = SQL_ISTOKEN(pPredicateNode->getChild(0),UPPER);
590
591 execute(pPredicateNode->getChild(2));
592 OOperator* pOperator = nullptr;
593 if ( bUpper )
594 pOperator = new OOp_Upper;
595 else
596 pOperator = new OOp_Lower;
597
598 m_aCodeList.emplace_back(pOperator);
599 }
600
executeFunction(OSQLParseNode const * pPredicateNode)601 void OPredicateCompiler::executeFunction(OSQLParseNode const * pPredicateNode)
602 {
603 OOperator* pOperator = nullptr;
604
605 OSL_ENSURE(pPredicateNode->getChild(0)->isToken(),"The first one must be the name of the function!");
606 sal_Int32 nTokenId = pPredicateNode->getChild(0)->getTokenID();
607 switch ( nTokenId )
608 {
609 case SQL_TOKEN_CHAR_LENGTH:
610 case SQL_TOKEN_LENGTH:
611 case SQL_TOKEN_OCTET_LENGTH:
612 case SQL_TOKEN_ASCII:
613 case SQL_TOKEN_LCASE:
614 case SQL_TOKEN_LTRIM:
615 case SQL_TOKEN_RTRIM:
616 case SQL_TOKEN_SPACE:
617 case SQL_TOKEN_UCASE:
618 case SQL_TOKEN_ABS:
619 case SQL_TOKEN_ACOS:
620 case SQL_TOKEN_ASIN:
621 case SQL_TOKEN_ATAN:
622 case SQL_TOKEN_CEILING:
623 case SQL_TOKEN_COS:
624 case SQL_TOKEN_DEGREES:
625 case SQL_TOKEN_EXP:
626 case SQL_TOKEN_FLOOR:
627 case SQL_TOKEN_LOG10:
628 case SQL_TOKEN_LN:
629 case SQL_TOKEN_RADIANS:
630 case SQL_TOKEN_SIGN:
631 case SQL_TOKEN_SIN:
632 case SQL_TOKEN_SQRT:
633 case SQL_TOKEN_TAN:
634 case SQL_TOKEN_DAYNAME:
635 case SQL_TOKEN_DAYOFMONTH:
636 case SQL_TOKEN_DAYOFWEEK:
637 case SQL_TOKEN_DAYOFYEAR:
638 case SQL_TOKEN_HOUR:
639 case SQL_TOKEN_MINUTE:
640 case SQL_TOKEN_MONTH:
641 case SQL_TOKEN_MONTHNAME:
642 case SQL_TOKEN_QUARTER:
643 case SQL_TOKEN_SECOND:
644 case SQL_TOKEN_YEAR:
645
646 execute(pPredicateNode->getChild(2));
647
648 switch( nTokenId )
649 {
650 case SQL_TOKEN_CHAR_LENGTH:
651 case SQL_TOKEN_LENGTH:
652 case SQL_TOKEN_OCTET_LENGTH:
653 pOperator = new OOp_CharLength;
654 break;
655 case SQL_TOKEN_ASCII:
656 pOperator = new OOp_Ascii;
657 break;
658 case SQL_TOKEN_LCASE:
659 pOperator = new OOp_Lower;
660 break;
661
662 case SQL_TOKEN_LTRIM:
663 pOperator = new OOp_LTrim;
664 break;
665 case SQL_TOKEN_RTRIM:
666 pOperator = new OOp_RTrim;
667 break;
668 case SQL_TOKEN_SPACE:
669 pOperator = new OOp_Space;
670 break;
671 case SQL_TOKEN_UCASE:
672 pOperator = new OOp_Upper;
673 break;
674 case SQL_TOKEN_ABS:
675 pOperator = new OOp_Abs;
676 break;
677 case SQL_TOKEN_ACOS:
678 pOperator = new OOp_ACos;
679 break;
680 case SQL_TOKEN_ASIN:
681 pOperator = new OOp_ASin;
682 break;
683 case SQL_TOKEN_ATAN:
684 pOperator = new OOp_ATan;
685 break;
686 case SQL_TOKEN_CEILING:
687 pOperator = new OOp_Ceiling;
688 break;
689 case SQL_TOKEN_COS:
690 pOperator = new OOp_Cos;
691 break;
692 case SQL_TOKEN_DEGREES:
693 pOperator = new OOp_Degrees;
694 break;
695 case SQL_TOKEN_EXP:
696 pOperator = new OOp_Exp;
697 break;
698 case SQL_TOKEN_FLOOR:
699 pOperator = new OOp_Floor;
700 break;
701 case SQL_TOKEN_LOG10:
702 pOperator = new OOp_Log10;
703 break;
704 case SQL_TOKEN_LN:
705 pOperator = new OOp_Ln;
706 break;
707 case SQL_TOKEN_RADIANS:
708 pOperator = new OOp_Radians;
709 break;
710 case SQL_TOKEN_SIGN:
711 pOperator = new OOp_Sign;
712 break;
713 case SQL_TOKEN_SIN:
714 pOperator = new OOp_Sin;
715 break;
716 case SQL_TOKEN_SQRT:
717 pOperator = new OOp_Sqrt;
718 break;
719 case SQL_TOKEN_TAN:
720 pOperator = new OOp_Tan;
721 break;
722 case SQL_TOKEN_DAYOFWEEK:
723 pOperator = new OOp_DayOfWeek;
724 break;
725 case SQL_TOKEN_DAYOFMONTH:
726 pOperator = new OOp_DayOfMonth;
727 break;
728 case SQL_TOKEN_DAYOFYEAR:
729 pOperator = new OOp_DayOfYear;
730 break;
731 case SQL_TOKEN_MONTH:
732 pOperator = new OOp_Month;
733 break;
734 case SQL_TOKEN_DAYNAME:
735 pOperator = new OOp_DayName;
736 break;
737 case SQL_TOKEN_MONTHNAME:
738 pOperator = new OOp_MonthName;
739 break;
740 case SQL_TOKEN_QUARTER:
741 pOperator = new OOp_Quarter;
742 break;
743 case SQL_TOKEN_YEAR:
744 pOperator = new OOp_Year;
745 break;
746 case SQL_TOKEN_HOUR:
747 pOperator = new OOp_Hour;
748 break;
749 case SQL_TOKEN_MINUTE:
750 pOperator = new OOp_Minute;
751 break;
752 case SQL_TOKEN_SECOND:
753 pOperator = new OOp_Second;
754 break;
755 default:
756 OSL_FAIL("Error in switch!");
757 }
758 break;
759 case SQL_TOKEN_CHAR:
760 case SQL_TOKEN_CONCAT:
761 case SQL_TOKEN_INSERT:
762 case SQL_TOKEN_LEFT:
763 case SQL_TOKEN_LOCATE:
764 case SQL_TOKEN_LOCATE_2:
765 case SQL_TOKEN_REPEAT:
766 case SQL_TOKEN_REPLACE:
767 case SQL_TOKEN_RIGHT:
768 case SQL_TOKEN_MOD:
769 case SQL_TOKEN_ROUND:
770 case SQL_TOKEN_LOGF:
771 case SQL_TOKEN_LOG:
772 case SQL_TOKEN_POWER:
773 case SQL_TOKEN_ATAN2:
774 case SQL_TOKEN_PI:
775 case SQL_TOKEN_CURDATE:
776 case SQL_TOKEN_CURTIME:
777 case SQL_TOKEN_NOW:
778 case SQL_TOKEN_WEEK:
779 {
780 m_aCodeList.emplace_back(new OStopOperand);
781 OSQLParseNode* pList = pPredicateNode->getChild(2);
782 for (size_t i=0; i < pList->count(); ++i)
783 execute(pList->getChild(i));
784
785 switch( nTokenId )
786 {
787 case SQL_TOKEN_CHAR:
788 pOperator = new OOp_Char;
789 break;
790 case SQL_TOKEN_CONCAT:
791 pOperator = new OOp_Concat;
792 break;
793 case SQL_TOKEN_INSERT:
794 pOperator = new OOp_Insert;
795 break;
796 case SQL_TOKEN_LEFT:
797 pOperator = new OOp_Left;
798 break;
799 case SQL_TOKEN_LOCATE:
800 case SQL_TOKEN_LOCATE_2:
801 pOperator = new OOp_Locate;
802 break;
803 case SQL_TOKEN_REPEAT:
804 pOperator = new OOp_Repeat;
805 break;
806 case SQL_TOKEN_REPLACE:
807 pOperator = new OOp_Replace;
808 break;
809 case SQL_TOKEN_RIGHT:
810 pOperator = new OOp_Right;
811 break;
812 case SQL_TOKEN_MOD:
813 pOperator = new OOp_Mod;
814 break;
815 case SQL_TOKEN_ROUND:
816 pOperator = new OOp_Round;
817 break;
818 case SQL_TOKEN_LOGF:
819 case SQL_TOKEN_LOG:
820 pOperator = new OOp_Log;
821 break;
822 case SQL_TOKEN_POWER:
823 pOperator = new OOp_Pow;
824 break;
825 case SQL_TOKEN_ATAN2:
826 pOperator = new OOp_ATan2;
827 break;
828 case SQL_TOKEN_PI:
829 pOperator = new OOp_Pi;
830 break;
831 case SQL_TOKEN_CURDATE:
832 pOperator = new OOp_CurDate;
833 break;
834 case SQL_TOKEN_CURTIME:
835 pOperator = new OOp_CurTime;
836 break;
837 case SQL_TOKEN_NOW:
838 pOperator = new OOp_Now;
839 break;
840 case SQL_TOKEN_WEEK:
841 pOperator = new OOp_Week;
842 break;
843 default:
844 OSL_FAIL("Error in switch!");
845 }
846 }
847 break;
848
849 case SQL_TOKEN_SUBSTRING:
850 m_aCodeList.emplace_back(new OStopOperand);
851 if ( pPredicateNode->count() == 4 ) //char_substring_fct
852 {
853 OSQLParseNode* pList = pPredicateNode->getChild(2);
854 for (size_t i=0; i < pList->count(); ++i)
855 execute(pList->getChild(i));
856 }
857 else
858 {
859 execute(pPredicateNode->getChild(2));
860 execute(pPredicateNode->getChild(4));
861 execute(pPredicateNode->getChild(5)->getChild(1));
862 }
863 pOperator = new OOp_SubString;
864 break;
865
866 case SQL_TOKEN_POSITION:
867 m_aCodeList.emplace_back(new OStopOperand);
868 if ( pPredicateNode->count() == 4 ) //position_exp
869 {
870 OSQLParseNode* pList = pPredicateNode->getChild(2);
871 for (size_t i=0; i < pList->count(); ++i)
872 execute(pList->getChild(i));
873 }
874 else
875 {
876 execute(pPredicateNode->getChild(2));
877 execute(pPredicateNode->getChild(4));
878 }
879 pOperator = new OOp_Locate;
880 break;
881 default:
882 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED,nullptr);
883 }
884
885 m_aCodeList.emplace_back(pOperator);
886 }
887
888
889 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
890