LibreOffice Module connectivity (master) 1
fcomp.cxx
Go to the documentation of this file.
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>
23#include <file/fanalyzer.hxx>
24#include <com/sun/star/sdbc/XColumnLocate.hpp>
27#include <com/sun/star/sdb/SQLFilterOperator.hpp>
31#include <file/FConnection.hxx>
33#include <sqlbison.hxx>
34#include <strings.hrc>
35
36using namespace connectivity;
37using namespace connectivity::file;
38using namespace com::sun::star::uno;
39using namespace com::sun::star::sdbc;
40using namespace com::sun::star::sdb;
41using namespace ::com::sun::star::container;
42using namespace com::sun::star;
43
44OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer* pAnalyzer)//,OCursor& rCurs)
45 : m_pAnalyzer(pAnalyzer)
46 , m_nParamCounter(0)
47{
48}
49
50
52{
53 Clean();
54}
55
57{
58 Clean();
59 m_orgColumns = nullptr;
60}
61
62void OPredicateCompiler::start(OSQLParseNode const * pSQLParseNode)
63{
64 if (!pSQLParseNode)
65 return;
66
68 // analyse Parse Tree (depending on Statement-type)
69 // and set pointer on WHERE-clause:
70 OSQLParseNode * pWhereClause = nullptr;
71
72 if (SQL_ISRULE(pSQLParseNode,select_statement))
73 {
74 OSQLParseNode * pOrderbyClause = nullptr;
75 DBG_ASSERT(pSQLParseNode->count() >= 4,"OFILECursor: Error in Parse Tree");
76
77 OSQLParseNode * pTableExp = pSQLParseNode->getChild(3);
78 DBG_ASSERT(pTableExp != nullptr,"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");
81
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) )
85 {
86 for (size_t i = 0; i < pSelection->count(); i++)
87 {
88 OSQLParseNode *pColumnRef = pSelection->getChild(i)->getChild(0);
89 if ( SQL_ISRULE(pColumnRef,general_set_fct) && pColumnRef->count() != 4 )
90 {
91 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT,nullptr);
92 }
93 }
94 }
95
96
97 pWhereClause = pTableExp->getChild(1);
98 pOrderbyClause = pTableExp->getChild(ORDER_BY_CHILD_POS);
99 (void)pOrderbyClause;
100 }
101 else if (SQL_ISRULE(pSQLParseNode,update_statement_searched))
102 {
103 DBG_ASSERT(pSQLParseNode->count() == 5,"OFILECursor: Error in Parse Tree");
104 pWhereClause = pSQLParseNode->getChild(4);
105 }
106 else if (SQL_ISRULE(pSQLParseNode,delete_statement_searched))
107 {
108 DBG_ASSERT(pSQLParseNode->count() == 4,"Error in Parse Tree");
109 pWhereClause = pSQLParseNode->getChild(3);
110 }
111 else
112 // Other Statement. no selection-criteria
113 return;
114
115 if (SQL_ISRULE(pWhereClause,where_clause))
116 {
117 // a where-clause is not allowed to be empty:
118 DBG_ASSERT(pWhereClause->count() == 2,"OFILECursor: Error in Parse Tree");
119
120 OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1);
121 DBG_ASSERT(pComparisonPredicate != nullptr,"OFILECursor: Error in Parse Tree");
122
123 execute( pComparisonPredicate );
124 }
125 else
126 {
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");
129 }
130}
131
132
134{
135 OOperand* pOperand = nullptr;
136 if (pPredicateNode->count() == 3 && // Expression is bracketed
137 SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"(") &&
138 SQL_ISPUNCTUATION(pPredicateNode->getChild(2),")"))
139 {
140 execute(pPredicateNode->getChild(1));
141 }
142 else if ((SQL_ISRULE(pPredicateNode,search_condition) || SQL_ISRULE(pPredicateNode,boolean_term))
143 && // AND/OR-linkage:
144 pPredicateNode->count() == 3)
145 {
146 execute(pPredicateNode->getChild(0)); // process the left branch
147 execute(pPredicateNode->getChild(2)); // process the right branch
148
149 if (SQL_ISTOKEN(pPredicateNode->getChild(1),OR)) // OR-Operator
150 {
151 m_aCodeList.emplace_back(new OOp_OR);
152 }
153 else if (SQL_ISTOKEN(pPredicateNode->getChild(1),AND)) // AND-Operator
154 m_aCodeList.emplace_back(new OOp_AND);
155 else
156 {
157 OSL_FAIL("OPredicateCompiler: Error in Parse Tree");
158 }
159 }
160 else if (SQL_ISRULE(pPredicateNode,boolean_factor))
161 {
162 execute(pPredicateNode->getChild(1));
163 m_aCodeList.emplace_back(new OOp_NOT);
164 }
165 else if (SQL_ISRULE(pPredicateNode,comparison_predicate))
166 {
167 execute_COMPARE(pPredicateNode);
168 }
169 else if (SQL_ISRULE(pPredicateNode,like_predicate))
170 {
171 execute_LIKE(pPredicateNode);
172 }
173 else if (SQL_ISRULE(pPredicateNode,between_predicate))
174 {
175 execute_BETWEEN(pPredicateNode);
176 }
177 else if (SQL_ISRULE(pPredicateNode,test_for_null))
178 {
179 execute_ISNULL(pPredicateNode);
180 }
181 else if(SQL_ISRULE(pPredicateNode,num_value_exp))
182 {
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),"+"))
186 {
187 m_aCodeList.emplace_back(new OOp_ADD);
188 }
189 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"-"))
190 m_aCodeList.emplace_back(new OOp_SUB);
191 else
192 {
193 OSL_FAIL("OPredicateCompiler: Error in Parse Tree num_value_exp");
194 }
195 }
196 else if(SQL_ISRULE(pPredicateNode,term))
197 {
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),"*"))
201 {
202 m_aCodeList.emplace_back(new OOp_MUL);
203 }
204 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"/"))
205 m_aCodeList.emplace_back(new OOp_DIV);
206 else
207 {
208 OSL_FAIL("OPredicateCompiler: Error in Parse Tree num_value_exp");
209 }
210 }
211 else
212 pOperand = execute_Operand(pPredicateNode); // now only simple operands will be processed
213
214 return pOperand;
215}
216
217
219{
220 DBG_ASSERT(pPredicateNode->count() == 3,"OFILECursor: Error in Parse Tree");
221
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) ||
229 // odbc date
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) ||
233 // upper, lower etc.
234 SQL_ISRULE(pPredicateNode->getChild(2),fold)) )
235 {
236 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,nullptr);
237 return;
238 }
239
240 sal_Int32 ePredicateType( SQLFilterOperator::EQUAL );
241 OSQLParseNode *pPrec = pPredicateNode->getChild(1);
242
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;
255 else
256 OSL_FAIL( "OPredicateCompiler::execute_COMPARE: unexpected node type!" );
257
258 execute(pPredicateNode->getChild(0));
259 execute(pPredicateNode->getChild(2));
260 m_aCodeList.emplace_back( new OOp_COMPARE(ePredicateType) );
261}
262
263
265{
266 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Error in Parse Tree");
267 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
268
269 sal_Unicode cEscape = L'\0';
270 const bool bNotLike = pPart2->getChild(0)->isToken();
271
272 OSQLParseNode* pAtom = pPart2->getChild(pPart2->count()-2);
273 OSQLParseNode* pOptEscape = pPart2->getChild(pPart2->count()-1);
274
275 if (!(pAtom->getNodeType() == SQLNodeType::String ||
276 SQL_ISRULE(pAtom,parameter) ||
277 // odbc date
278 SQL_ISRULE(pAtom,set_fct_spec) ||
279 SQL_ISRULE(pAtom,position_exp) ||
280 SQL_ISRULE(pAtom,char_substring_fct) ||
281 // upper, lower etc.
282 SQL_ISRULE(pAtom,fold)) )
283 {
284 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,nullptr);
285 return;
286 }
287
288 if (pOptEscape->count() != 0)
289 {
290 if (pOptEscape->count() != 2)
291 {
292 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,nullptr);
293 }
294 OSQLParseNode *pEscNode = pOptEscape->getChild(1);
295 if (pEscNode->getNodeType() != SQLNodeType::String)
296 {
297 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,nullptr);
298 }
299 else
300 cEscape = pEscNode->getTokenValue().toChar();
301 }
302
303 execute(pPredicateNode->getChild(0));
304 execute(pAtom);
305
306 OBoolOperator* pOperator = bNotLike
307 ? new OOp_NOTLIKE(cEscape)
308 : new OOp_LIKE(cEscape);
309 m_aCodeList.emplace_back(pOperator);
310}
311
313{
314 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Error in Parse Tree");
315
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);
320
321 if (
322 !(p1stValue->getNodeType() == SQLNodeType::String || SQL_ISRULE(p1stValue,parameter))
323 && !(p2ndtValue->getNodeType() == SQLNodeType::String || SQL_ISRULE(p2ndtValue,parameter))
324 )
325 {
326 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN,nullptr);
327 }
328
329 bool bNot = SQL_ISTOKEN(pPart2->getChild(0),NOT);
330
331 OOperand* pColumnOp = execute(pColumn);
332 OOperand* pOb1 = execute(p1stValue);
333 OBoolOperator* pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::LESS_EQUAL : SQLFilterOperator::GREATER);
334 m_aCodeList.emplace_back(pOperator);
335
336 execute(pColumn);
337 OOperand* pOb2 = execute(p2ndtValue);
338 pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::GREATER_EQUAL : SQLFilterOperator::LESS);
339 m_aCodeList.emplace_back(pOperator);
340
341 if ( pColumnOp && pOb1 && pOb2 )
342 {
343 switch(pColumnOp->getDBType())
344 {
345 case DataType::CHAR:
346 case DataType::VARCHAR:
347 case DataType::LONGVARCHAR:
348 pOb1->setValue(pOb1->getValue().getString());
349 pOb2->setValue(pOb2->getValue().getString());
350 break;
351 case DataType::DECIMAL:
352 case DataType::NUMERIC:
353 pOb1->setValue(pOb1->getValue().getDouble());
354 pOb2->setValue(pOb2->getValue().getDouble());
355 break;
356 case DataType::FLOAT:
357 pOb1->setValue(pOb1->getValue().getFloat());
358 pOb2->setValue(pOb2->getValue().getFloat());
359 break;
360 case DataType::DOUBLE:
361 case DataType::REAL:
362 pOb1->setValue(pOb1->getValue().getDouble());
363 pOb2->setValue(pOb2->getValue().getDouble());
364 break;
365 case DataType::DATE:
366 pOb1->setValue(pOb1->getValue().getDate());
367 pOb2->setValue(pOb2->getValue().getDate());
368 break;
369 case DataType::TIME:
370 pOb1->setValue(pOb1->getValue().getTime());
371 pOb2->setValue(pOb2->getValue().getTime());
372 break;
373 case DataType::TIMESTAMP:
374 pOb1->setValue(pOb1->getValue().getDateTime());
375 pOb2->setValue(pOb2->getValue().getDateTime());
376 break;
377 }
378 }
379
380
381 OBoolOperator* pBoolOp = nullptr;
382 if ( bNot )
383 pBoolOp = new OOp_OR;
384 else
385 pBoolOp = new OOp_AND;
386 m_aCodeList.emplace_back(pBoolOp);
387}
388
390{
391 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Error in Parse Tree");
392 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
393 DBG_ASSERT(SQL_ISTOKEN(pPart2->getChild(0),IS),"OFILECursor: Error in Parse Tree");
394
395 sal_Int32 ePredicateType;
396 if (SQL_ISTOKEN(pPart2->getChild(1),NOT))
397 ePredicateType = SQLFilterOperator::NOT_SQLNULL;
398 else
399 ePredicateType = SQLFilterOperator::SQLNULL;
400
401 execute(pPredicateNode->getChild(0));
402 OBoolOperator* pOperator = (ePredicateType == SQLFilterOperator::SQLNULL) ?
403 new OOp_ISNULL : new OOp_ISNOTNULL;
404 m_aCodeList.emplace_back(pOperator);
405}
406
408{
409 OOperand* pOperand = nullptr;
410
411 if (SQL_ISRULE(pPredicateNode,column_ref))
412 {
413 OUString aColumnName;
414 if (pPredicateNode->count() == 1)
415 {
416 aColumnName = pPredicateNode->getChild(0)->getTokenValue();
417 }
418 else if (pPredicateNode->count() == 3)
419 {
420 if(SQL_ISRULE(pPredicateNode->getChild(2),column_val))
421 aColumnName = pPredicateNode->getChild(2)->getChild(0)->getTokenValue();
422 else
423 aColumnName = pPredicateNode->getChild(2)->getTokenValue();
424 }
425
426 if(!m_orgColumns->hasByName(aColumnName))
427 {
429 STR_INVALID_COLUMNNAME,
430 "$columnname$", aColumnName
431 ) );
432 ::dbtools::throwGenericSQLException( sError, nullptr );
433 }
434 css::uno::Reference< css::beans::XPropertySet> xCol;
435 try
436 {
437 if (m_orgColumns->getByName(aColumnName) >>= xCol)
438 {
439 pOperand = OSQLAnalyzer::createOperandAttr(Reference< XColumnLocate>(m_orgColumns,UNO_QUERY_THROW)->findColumn(aColumnName),xCol);
440 }
441 else
442 {// Column doesn't exist in the Result-set
444 STR_INVALID_COLUMNNAME,
445 "$columnname$", aColumnName
446 ) );
447 ::dbtools::throwGenericSQLException( sError, nullptr );
448 }
449 }
450 catch(Exception &)
451 {
452 TOOLS_WARN_EXCEPTION( "connectivity.drivers", "OPredicateCompiler::execute_Operand Exception");
453 }
454 }
455 else if (SQL_ISRULE(pPredicateNode,parameter))
456 {
457 pOperand = new OOperandParam(++m_nParamCounter);
458 }
459 else if (pPredicateNode->getNodeType() == SQLNodeType::String ||
460 pPredicateNode->getNodeType() == SQLNodeType::IntNum ||
461 pPredicateNode->getNodeType() == SQLNodeType::ApproxNum ||
462 pPredicateNode->getNodeType() == SQLNodeType::Name ||
463 SQL_ISTOKEN(pPredicateNode,TRUE) ||
464 SQL_ISTOKEN(pPredicateNode,FALSE) ||
465 SQL_ISRULE(pPredicateNode,parameter))
466 {
467 pOperand = new OOperandConst(*pPredicateNode, pPredicateNode->getTokenValue());
468 }
469 else if((pPredicateNode->count() == 2) &&
470 (SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"-")) &&
471 pPredicateNode->getChild(1)->getNodeType() == SQLNodeType::IntNum)
472 { // if -1 or +1 is there
473 OUString aValue = pPredicateNode->getChild(0)->getTokenValue() + pPredicateNode->getChild(1)->getTokenValue();
474 pOperand = new OOperandConst(*pPredicateNode->getChild(1), aValue);
475 }
476 else if( SQL_ISRULE(pPredicateNode,set_fct_spec) && SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"{") )
477 {
478 const OSQLParseNode* pODBCNode = pPredicateNode->getChild(1);
479 const OSQLParseNode* pODBCNodeChild = pODBCNode->getChild(0);
480
481 // Odbc Date or time
482 if (pODBCNodeChild->getNodeType() == SQLNodeType::Keyword && (
483 SQL_ISTOKEN(pODBCNodeChild,D) ||
484 SQL_ISTOKEN(pODBCNodeChild,T) ||
485 SQL_ISTOKEN(pODBCNodeChild,TS) ))
486 {
487 OUString sDateTime = pODBCNode->getChild(1)->getTokenValue();
488 pOperand = new OOperandConst(*pODBCNode->getChild(1), sDateTime);
489 if(SQL_ISTOKEN(pODBCNodeChild,D))
490 {
492 }
493 else if(SQL_ISTOKEN(pODBCNodeChild,T))
494 {
496 }
497 else if(SQL_ISTOKEN(pODBCNodeChild,TS))
498 {
500 }
501 }
502 else
503 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,nullptr);
504
505 }
506 else if( SQL_ISRULE(pPredicateNode,fold) )
507 {
508 execute_Fold(pPredicateNode);
509 }
510 else if( SQL_ISRULE(pPredicateNode,set_fct_spec)
511 || SQL_ISRULE(pPredicateNode,position_exp)
512 || SQL_ISRULE(pPredicateNode,char_substring_fct)
513 )
514 {
515 executeFunction(pPredicateNode);
516 }
517 else if( SQL_ISRULE(pPredicateNode,length_exp) )
518 {
519 executeFunction(pPredicateNode->getChild(0));
520 }
521 else
522 {
523 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,nullptr);
524 }
525 if (pOperand)
526 m_aCodeList.emplace_back(pOperand);
527 return pOperand;
528}
529
530
532{
533 if (!(rCodeList[0]))
534 return true; // no Predicate
535
536 for (auto const& code : rCodeList)
537 {
538 OOperand* pOperand = dynamic_cast<OOperand* >(code.get());
539 if (pOperand)
540 m_aStack.push(pOperand);
541 else
542 static_cast<OOperator *>(code.get())->Exec(m_aStack);
543 }
544
545 OOperand* pOperand = m_aStack.top();
546 m_aStack.pop();
547
548 DBG_ASSERT(m_aStack.empty(), "Stack error");
549 DBG_ASSERT(pOperand, "Stack error");
550
551 const bool bResult = pOperand->isValid();
552 if (typeid(OOperandResult) == typeid(*pOperand))
553 delete pOperand;
554 return bResult;
555}
556
558{
559 if (!(rCodeList[0]))
560 return ; // no Predicate
561
562 for (auto const& code : rCodeList)
563 {
564 OOperand* pOperand = dynamic_cast<OOperand* >(code.get());
565 if (pOperand)
566 m_aStack.push(pOperand);
567 else
568 static_cast<OOperator *>(code.get())->Exec(m_aStack);
569 }
570
571 OOperand* pOperand = m_aStack.top();
572 m_aStack.pop();
573
574 DBG_ASSERT(m_aStack.empty(), "Stack error");
575 DBG_ASSERT(pOperand, "Stack error");
576
577 (*_rVal) = pOperand->getValue();
578 if (typeid(OOperandResult) == typeid(*pOperand))
579 delete pOperand;
580}
581
583{
584 DBG_ASSERT(pPredicateNode->count() >= 4,"OFILECursor: Error in Parse Tree");
585
586 bool bUpper = SQL_ISTOKEN(pPredicateNode->getChild(0),UPPER);
587
588 execute(pPredicateNode->getChild(2));
589 OOperator* pOperator = nullptr;
590 if ( bUpper )
591 pOperator = new OOp_Upper;
592 else
593 pOperator = new OOp_Lower;
594
595 m_aCodeList.emplace_back(pOperator);
596}
597
599{
600 OOperator* pOperator = nullptr;
601
602 OSL_ENSURE(pPredicateNode->getChild(0)->isToken(),"The first one must be the name of the function!");
603 sal_Int32 nTokenId = pPredicateNode->getChild(0)->getTokenID();
604 switch ( nTokenId )
605 {
606 case SQL_TOKEN_CHAR_LENGTH:
607 case SQL_TOKEN_LENGTH:
608 case SQL_TOKEN_OCTET_LENGTH:
609 case SQL_TOKEN_ASCII:
610 case SQL_TOKEN_LCASE:
611 case SQL_TOKEN_LTRIM:
612 case SQL_TOKEN_RTRIM:
613 case SQL_TOKEN_SPACE:
614 case SQL_TOKEN_UCASE:
615 case SQL_TOKEN_ABS:
616 case SQL_TOKEN_ACOS:
617 case SQL_TOKEN_ASIN:
618 case SQL_TOKEN_ATAN:
619 case SQL_TOKEN_CEILING:
620 case SQL_TOKEN_COS:
621 case SQL_TOKEN_DEGREES:
622 case SQL_TOKEN_EXP:
623 case SQL_TOKEN_FLOOR:
624 case SQL_TOKEN_LOG10:
625 case SQL_TOKEN_LN:
626 case SQL_TOKEN_RADIANS:
627 case SQL_TOKEN_SIGN:
628 case SQL_TOKEN_SIN:
629 case SQL_TOKEN_SQRT:
630 case SQL_TOKEN_TAN:
631 case SQL_TOKEN_DAYNAME:
632 case SQL_TOKEN_DAYOFMONTH:
633 case SQL_TOKEN_DAYOFWEEK:
634 case SQL_TOKEN_DAYOFYEAR:
635 case SQL_TOKEN_HOUR:
636 case SQL_TOKEN_MINUTE:
637 case SQL_TOKEN_MONTH:
638 case SQL_TOKEN_MONTHNAME:
639 case SQL_TOKEN_QUARTER:
640 case SQL_TOKEN_SECOND:
641 case SQL_TOKEN_YEAR:
642
643 execute(pPredicateNode->getChild(2));
644
645 switch( nTokenId )
646 {
647 case SQL_TOKEN_CHAR_LENGTH:
648 case SQL_TOKEN_LENGTH:
649 case SQL_TOKEN_OCTET_LENGTH:
650 pOperator = new OOp_CharLength;
651 break;
652 case SQL_TOKEN_ASCII:
653 pOperator = new OOp_Ascii;
654 break;
655 case SQL_TOKEN_LCASE:
656 pOperator = new OOp_Lower;
657 break;
658
659 case SQL_TOKEN_LTRIM:
660 pOperator = new OOp_LTrim;
661 break;
662 case SQL_TOKEN_RTRIM:
663 pOperator = new OOp_RTrim;
664 break;
665 case SQL_TOKEN_SPACE:
666 pOperator = new OOp_Space;
667 break;
668 case SQL_TOKEN_UCASE:
669 pOperator = new OOp_Upper;
670 break;
671 case SQL_TOKEN_ABS:
672 pOperator = new OOp_Abs;
673 break;
674 case SQL_TOKEN_ACOS:
675 pOperator = new OOp_ACos;
676 break;
677 case SQL_TOKEN_ASIN:
678 pOperator = new OOp_ASin;
679 break;
680 case SQL_TOKEN_ATAN:
681 pOperator = new OOp_ATan;
682 break;
683 case SQL_TOKEN_CEILING:
684 pOperator = new OOp_Ceiling;
685 break;
686 case SQL_TOKEN_COS:
687 pOperator = new OOp_Cos;
688 break;
689 case SQL_TOKEN_DEGREES:
690 pOperator = new OOp_Degrees;
691 break;
692 case SQL_TOKEN_EXP:
693 pOperator = new OOp_Exp;
694 break;
695 case SQL_TOKEN_FLOOR:
696 pOperator = new OOp_Floor;
697 break;
698 case SQL_TOKEN_LOG10:
699 pOperator = new OOp_Log10;
700 break;
701 case SQL_TOKEN_LN:
702 pOperator = new OOp_Ln;
703 break;
704 case SQL_TOKEN_RADIANS:
705 pOperator = new OOp_Radians;
706 break;
707 case SQL_TOKEN_SIGN:
708 pOperator = new OOp_Sign;
709 break;
710 case SQL_TOKEN_SIN:
711 pOperator = new OOp_Sin;
712 break;
713 case SQL_TOKEN_SQRT:
714 pOperator = new OOp_Sqrt;
715 break;
716 case SQL_TOKEN_TAN:
717 pOperator = new OOp_Tan;
718 break;
719 case SQL_TOKEN_DAYOFWEEK:
720 pOperator = new OOp_DayOfWeek;
721 break;
722 case SQL_TOKEN_DAYOFMONTH:
723 pOperator = new OOp_DayOfMonth;
724 break;
725 case SQL_TOKEN_DAYOFYEAR:
726 pOperator = new OOp_DayOfYear;
727 break;
728 case SQL_TOKEN_MONTH:
729 pOperator = new OOp_Month;
730 break;
731 case SQL_TOKEN_DAYNAME:
732 pOperator = new OOp_DayName;
733 break;
734 case SQL_TOKEN_MONTHNAME:
735 pOperator = new OOp_MonthName;
736 break;
737 case SQL_TOKEN_QUARTER:
738 pOperator = new OOp_Quarter;
739 break;
740 case SQL_TOKEN_YEAR:
741 pOperator = new OOp_Year;
742 break;
743 case SQL_TOKEN_HOUR:
744 pOperator = new OOp_Hour;
745 break;
746 case SQL_TOKEN_MINUTE:
747 pOperator = new OOp_Minute;
748 break;
749 case SQL_TOKEN_SECOND:
750 pOperator = new OOp_Second;
751 break;
752 default:
753 OSL_FAIL("Error in switch!");
754 }
755 break;
756 case SQL_TOKEN_CHAR:
757 case SQL_TOKEN_CONCAT:
758 case SQL_TOKEN_INSERT:
759 case SQL_TOKEN_LEFT:
760 case SQL_TOKEN_LOCATE:
761 case SQL_TOKEN_LOCATE_2:
762 case SQL_TOKEN_REPEAT:
763 case SQL_TOKEN_REPLACE:
764 case SQL_TOKEN_RIGHT:
765 case SQL_TOKEN_MOD:
766 case SQL_TOKEN_ROUND:
767 case SQL_TOKEN_LOGF:
768 case SQL_TOKEN_LOG:
769 case SQL_TOKEN_POWER:
770 case SQL_TOKEN_ATAN2:
771 case SQL_TOKEN_PI:
772 case SQL_TOKEN_CURDATE:
773 case SQL_TOKEN_CURTIME:
774 case SQL_TOKEN_NOW:
775 case SQL_TOKEN_WEEK:
776 {
777 m_aCodeList.emplace_back(new OStopOperand);
778 OSQLParseNode* pList = pPredicateNode->getChild(2);
779 for (size_t i=0; i < pList->count(); ++i)
780 execute(pList->getChild(i));
781
782 switch( nTokenId )
783 {
784 case SQL_TOKEN_CHAR:
785 pOperator = new OOp_Char;
786 break;
787 case SQL_TOKEN_CONCAT:
788 pOperator = new OOp_Concat;
789 break;
790 case SQL_TOKEN_INSERT:
791 pOperator = new OOp_Insert;
792 break;
793 case SQL_TOKEN_LEFT:
794 pOperator = new OOp_Left;
795 break;
796 case SQL_TOKEN_LOCATE:
797 case SQL_TOKEN_LOCATE_2:
798 pOperator = new OOp_Locate;
799 break;
800 case SQL_TOKEN_REPEAT:
801 pOperator = new OOp_Repeat;
802 break;
803 case SQL_TOKEN_REPLACE:
804 pOperator = new OOp_Replace;
805 break;
806 case SQL_TOKEN_RIGHT:
807 pOperator = new OOp_Right;
808 break;
809 case SQL_TOKEN_MOD:
810 pOperator = new OOp_Mod;
811 break;
812 case SQL_TOKEN_ROUND:
813 pOperator = new OOp_Round;
814 break;
815 case SQL_TOKEN_LOGF:
816 case SQL_TOKEN_LOG:
817 pOperator = new OOp_Log;
818 break;
819 case SQL_TOKEN_POWER:
820 pOperator = new OOp_Pow;
821 break;
822 case SQL_TOKEN_ATAN2:
823 pOperator = new OOp_ATan2;
824 break;
825 case SQL_TOKEN_PI:
826 pOperator = new OOp_Pi;
827 break;
828 case SQL_TOKEN_CURDATE:
829 pOperator = new OOp_CurDate;
830 break;
831 case SQL_TOKEN_CURTIME:
832 pOperator = new OOp_CurTime;
833 break;
834 case SQL_TOKEN_NOW:
835 pOperator = new OOp_Now;
836 break;
837 case SQL_TOKEN_WEEK:
838 pOperator = new OOp_Week;
839 break;
840 default:
841 OSL_FAIL("Error in switch!");
842 }
843 }
844 break;
845
846 case SQL_TOKEN_SUBSTRING:
847 m_aCodeList.emplace_back(new OStopOperand);
848 if ( pPredicateNode->count() == 4 ) //char_substring_fct
849 {
850 OSQLParseNode* pList = pPredicateNode->getChild(2);
851 for (size_t i=0; i < pList->count(); ++i)
852 execute(pList->getChild(i));
853 }
854 else
855 {
856 execute(pPredicateNode->getChild(2));
857 execute(pPredicateNode->getChild(4));
858 execute(pPredicateNode->getChild(5)->getChild(1));
859 }
860 pOperator = new OOp_SubString;
861 break;
862
863 case SQL_TOKEN_POSITION:
864 m_aCodeList.emplace_back(new OStopOperand);
865 if ( pPredicateNode->count() == 4 ) //position_exp
866 {
867 OSQLParseNode* pList = pPredicateNode->getChild(2);
868 for (size_t i=0; i < pList->count(); ++i)
869 execute(pList->getChild(i));
870 }
871 else
872 {
873 execute(pPredicateNode->getChild(2));
874 execute(pPredicateNode->getChild(4));
875 }
876 pOperator = new OOp_Locate;
877 break;
878 default:
879 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED,nullptr);
880 }
881
882 m_aCodeList.emplace_back(pOperator);
883}
884
885
886/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static double toDouble(std::string_view rString)
Definition: DTable.cxx:1635
const SharedResources & getResources() const
Definition: TConnection.hxx:65
void throwGenericSQLException(TranslateId pErrorResourceId, const css::uno::Reference< css::uno::XInterface > &_xContext)
Definition: TConnection.cxx:74
css::util::Time getTime() const
Definition: FValue.cxx:1951
OUString getString() const
Definition: FValue.cxx:933
float getFloat() const
Definition: FValue.cxx:1669
css::util::Date getDate() const
Definition: FValue.cxx:1893
css::util::DateTime getDateTime() const
Definition: FValue.cxx:1995
double getDouble() const
Definition: FValue.cxx:1745
sal_uInt32 getTokenID() const
Definition: sqlnode.hxx:350
const OUString & getTokenValue() const
Definition: sqlnode.hxx:361
OSQLParseNode * getChild(sal_uInt32 nPos) const
Definition: sqlnode.hxx:433
SQLNodeType getNodeType() const
Definition: sqlnode.hxx:339
OUString getResourceStringWithSubstitution(TranslateId pResId, const char *_pAsciiPatternToReplace, const OUString &_rStringToSubstitute) const
loads a string from the shared resource file, and replaces a given ASCII pattern with a given string
ACOS(X) Returns the arc cosine of X, that is, the value whose cosine is X.
ASIN(X) Returns the arc sine of X, that is, the value whose sine is X.
ATAN2(Y,X) Returns the arc tangent of the two variables X and Y.
ATAN(X) Returns the arc tangent of X, that is, the value whose tangent is X:
ABS(X) Returns the absolute value of X:
ASCII(str) Returns the ASCII code value of the leftmost character of the string str.
CEILING(X) Returns the smallest integer value not less than X:
LENGTH(str) OCTET_LENGTH(str) CHAR_LENGTH(str) CHARACTER_LENGTH(str) Returns the length of the string...
CHAR(N,...) CHAR() interprets the arguments as integers and returns a string consisting of the charac...
CONCAT(str1,str2,...) Returns the string that results from concatenating the arguments.
COS(X) Returns the cosine of X, where X is given in radians:
CURDATE() CURRENT_DATE Returns today's date as a value in 'YYYY-MM-DD' or YYYYMMDD format,...
CURTIME() CURRENT_TIME Returns the current time as a value in 'HH:MM:SS' or HHMMSS format,...
DAYNAME(date) Returns the name of the weekday for date:
DAYOFMONTH(date) Returns the day of the month for date, in the range 1 to 31:
DAYOFWEEK(date) Returns the weekday index for date (1 = Sunday, 2 = Monday, ... 7 = Saturday).
DAYOFYEAR(date) Returns the day of the year for date, in the range 1 to 366:
DEGREES(X) Returns the argument X, converted from radians to degrees:
EXP(X) Returns the value of e (the base of natural logarithms) raised to the power of X:
FLOOR(X) Returns the largest integer value not greater than X:
HOUR(time) Returns the hour for time, in the range 0 to 23:
INSERT(str,pos,len,newstr) Returns the string str, with the substring beginning at position pos and l...
LTRIM(str) Returns the string str with leading space characters removed:
LEFT(str,len) Returns the leftmost len characters from the string str:
LN(X) Returns the natural logarithm of X:
LOCATE(substr,str) POSITION(substr IN str) Returns the position of the first occurrence of substring ...
LOG10(X) Returns the base-10 logarithm of X:
LOG(X) LOG(B,X) If called with one parameter, this function returns the natural logarithm of X:
LCASE(str) LOWER(str) Returns the string str with all characters changed to lowercase according to th...
MINUTE(time) Returns the minute for time, in the range 0 to 59:
MOD(N,M) % Modulo (like the % operator in C).
MONTHNAME(date) Returns the name of the month for date:
MONTH(date) Returns the month for date, in the range 1 to 12:
NOW() Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS format,...
PI() Returns the value of PI.
POWER(X,Y) Returns the value of X raised to the power of Y:
QUARTER(date) Returns the quarter of the year for date, in the range 1 to 4:
RTRIM(str) Returns the string str with trailing space characters removed:
RADIANS(X) Returns the argument X, converted from degrees to radians:
REPEAT(str,count) Returns a string consisting of the string str repeated count times.
REPLACE(str,from_str,to_str) Returns the string str with all occurrences of the string from_str repla...
RIGHT(str,len) Returns the rightmost len characters from the string str:
ROUND(X) ROUND(X,D) Returns the argument X, rounded to the nearest integer.
SECOND(time) Returns the second for time, in the range 0 to 59:
SIGN(X) Returns the sign of the argument as -1, 0, or 1, depending on whether X is negative,...
SIN(X) Returns the sine of X, where X is given in radians:
SPACE(N) Returns a string consisting of N space characters:
SQRT(X) Returns the non-negative square root of X:
SUBSTRING(str,pos) SUBSTRING(str FROM pos) Returns a substring from string str starting at position p...
TAN(X) Returns the tangent of X, where X is given in radians:
UCASE(str) UPPER(str) Returns the string str with all characters changed to uppercase according to th...
WEEK(date) WEEK(date,first) With a single argument, returns the week for date, in the range 0 to 53 (...
YEAR(date) Returns the year for date, in the range 1000 to 9999:
sal_Int32 getDBType() const
Definition: fcode.hxx:68
virtual void setValue(const ORowSetValue &_rVal)=0
virtual const ORowSetValue & getValue() const =0
void execute_LIKE(connectivity::OSQLParseNode const *pPredicateNode)
Definition: fcomp.cxx:264
void execute_COMPARE(connectivity::OSQLParseNode const *pPredicateNode)
Definition: fcomp.cxx:218
void execute_Fold(OSQLParseNode const *pPredicateNode)
Definition: fcomp.cxx:582
void execute_ISNULL(connectivity::OSQLParseNode const *pPredicateNode)
Definition: fcomp.cxx:389
void start(connectivity::OSQLParseNode const *pSQLParseNode)
Definition: fcomp.cxx:62
void executeFunction(OSQLParseNode const *pPredicateNode)
Definition: fcomp.cxx:598
void execute_BETWEEN(connectivity::OSQLParseNode const *pPredicateNode)
Definition: fcomp.cxx:312
OOperand * execute_Operand(connectivity::OSQLParseNode const *pPredicateNode)
Definition: fcomp.cxx:407
OOperand * execute(connectivity::OSQLParseNode const *pPredicateNode)
Definition: fcomp.cxx:133
css::uno::Reference< css::container::XNameAccess > m_orgColumns
Definition: fcomp.hxx:40
virtual ~OPredicateCompiler() override
Definition: fcomp.cxx:51
void evaluateSelection(OCodeList &rCodeList, ORowSetValueDecoratorRef const &_rVal)
Definition: fcomp.cxx:557
bool evaluate(OCodeList &rCodeList)
Definition: fcomp.cxx:531
OConnection * getConnection() const
Definition: fanalyzer.hxx:45
static OOperandAttr * createOperandAttr(sal_Int32 _nPos, const css::uno::Reference< css::beans::XPropertySet > &_xCol)
Definition: fanalyzer.cxx:139
special stop operand is appended when a list of arguments ends
Definition: fcode.hxx:169
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define TRUE
#define FALSE
@ Exception
std::vector< std::unique_ptr< OCode > > OCodeList
Definition: fcomp.hxx:31
OOO_DLLPUBLIC_DBTOOLS css::util::Date toDate(double dVal, const css::util::Date &_rNullDate=getStandardDate())
OOO_DLLPUBLIC_DBTOOLS css::util::Time toTime(double dVal, short nDigits=9)
OOO_DLLPUBLIC_DBTOOLS css::util::DateTime toDateTime(double dVal, const css::util::Date &_rNullDate=getStandardDate())
void throwGenericSQLException(const OUString &_rMsg, const css::uno::Reference< css::uno::XInterface > &_rxSource)
throw a generic SQLException, i.e.
int i
sal_Unicode code
#define SQL_ISRULE(pParseNode, eRule)
Definition: sqlnode.hxx:439
#define ORDER_BY_CHILD_POS
Definition: sqlnode.hxx:51
#define TABLE_EXPRESSION_CHILD_COUNT
Definition: sqlnode.hxx:52
#define SQL_ISPUNCTUATION(pParseNode, aString)
Definition: sqlnode.hxx:450
#define SQL_ISTOKEN(pParseNode, token)
Definition: sqlnode.hxx:447
NOT
IS
AND
OR
sal_uInt16 sal_Unicode