1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_connectivity.hxx"
26 #include "file/fcomp.hxx"
27 #include <tools/debug.hxx>
28 #include "TConnection.hxx"
29 #include "connectivity/sqlparse.hxx"
30 #include "file/fanalyzer.hxx"
31 #include <com/sun/star/sdbc/XColumnLocate.hpp>
32 #include <com/sun/star/util/DateTime.hpp>
33 #include <com/sun/star/util/Date.hpp>
34 #include <com/sun/star/util/Time.hpp>
35 #include "connectivity/dbexception.hxx"
36 #include "connectivity/dbconversion.hxx"
37 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
38 #include "resource/file_res.hrc"
39 #include "file/FStringFunctions.hxx"
40 #include "file/FDateFunctions.hxx"
41 #include "file/FNumericFunctions.hxx"
42 #include "file/FConnection.hxx"
43 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
44
45 using namespace connectivity;
46 using namespace connectivity::file;
47 using namespace com::sun::star::uno;
48 using namespace com::sun::star::sdbc;
49 using namespace com::sun::star::sdb;
50 using namespace ::com::sun::star::container;
51 using namespace ::com::sun::star::util;
52
DBG_NAME(OPredicateCompiler)53 DBG_NAME(OPredicateCompiler)
54 //------------------------------------------------------------------
55 OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer* pAnalyzer)//,OCursor& rCurs)
56 // : m_rCursor(rCurs)
57 : m_pAnalyzer(pAnalyzer)
58 , m_nParamCounter(0)
59 , m_bORCondition(sal_False)
60 {
61 DBG_CTOR(OPredicateCompiler,NULL);
62 }
63
64 //------------------------------------------------------------------
~OPredicateCompiler()65 OPredicateCompiler::~OPredicateCompiler()
66 {
67 Clean();
68 DBG_DTOR(OPredicateCompiler,NULL);
69 }
70 // -----------------------------------------------------------------------------
dispose()71 void OPredicateCompiler::dispose()
72 {
73 Clean();
74 m_orgColumns = NULL;
75 m_xIndexes.clear();
76 }
77 //------------------------------------------------------------------
78 // inline OCursor& OPredicateCompiler::Cursor() const {return m_rCursor;}
79 //------------------------------------------------------------------
start(OSQLParseNode * pSQLParseNode)80 void OPredicateCompiler::start(OSQLParseNode* pSQLParseNode)
81 {
82 if (!pSQLParseNode)
83 return;
84
85 m_nParamCounter = 0;
86 // Parse Tree analysieren (je nach Statement-Typ)
87 // und Zeiger auf WHERE-Klausel setzen:
88 OSQLParseNode * pWhereClause = NULL;
89 OSQLParseNode * pOrderbyClause = NULL;
90
91 if (SQL_ISRULE(pSQLParseNode,select_statement))
92 {
93 DBG_ASSERT(pSQLParseNode->count() >= 4,"OFILECursor: Fehler im Parse Tree");
94
95 OSQLParseNode * pTableExp = pSQLParseNode->getChild(3);
96 DBG_ASSERT(pTableExp != NULL,"Fehler im Parse Tree");
97 DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp)," Fehler im Parse Tree");
98 DBG_ASSERT(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"Fehler im Parse Tree");
99
100 // check that we don't use anything other than count(*) as function
101 OSQLParseNode* pSelection = pSQLParseNode->getChild(2);
102 if ( SQL_ISRULE(pSelection,scalar_exp_commalist) )
103 {
104 for (sal_uInt32 i = 0; i < pSelection->count(); i++)
105 {
106 OSQLParseNode *pColumnRef = pSelection->getChild(i)->getChild(0);
107 if ( SQL_ISRULE(pColumnRef,general_set_fct) && pColumnRef->count() != 4 )
108 {
109 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT,NULL);
110 }
111 }
112 }
113
114
115 pWhereClause = pTableExp->getChild(1);
116 pOrderbyClause = pTableExp->getChild(ORDER_BY_CHILD_POS);
117 }
118 else if (SQL_ISRULE(pSQLParseNode,update_statement_searched))
119 {
120 DBG_ASSERT(pSQLParseNode->count() == 5,"OFILECursor: Fehler im Parse Tree");
121 pWhereClause = pSQLParseNode->getChild(4);
122 }
123 else if (SQL_ISRULE(pSQLParseNode,delete_statement_searched))
124 {
125 DBG_ASSERT(pSQLParseNode->count() == 4,"Fehler im Parse Tree");
126 pWhereClause = pSQLParseNode->getChild(3);
127 }
128 else
129 // Anderes Statement. Keine Selektionskriterien.
130 return;
131
132 if (SQL_ISRULE(pWhereClause,where_clause))
133 {
134 // Wenn es aber eine where_clause ist, dann darf sie nicht leer sein:
135 DBG_ASSERT(pWhereClause->count() == 2,"OFILECursor: Fehler im Parse Tree");
136
137 OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1);
138 DBG_ASSERT(pComparisonPredicate != NULL,"OFILECursor: Fehler im Parse Tree");
139
140 execute( pComparisonPredicate );
141 }
142 else
143 {
144 // Die Where Clause ist meistens optional, d. h. es koennte sich auch
145 // um "optional_where_clause" handeln.
146 DBG_ASSERT(SQL_ISRULE(pWhereClause,opt_where_clause),"OPredicateCompiler: Fehler im Parse Tree");
147 }
148 }
149
150 //------------------------------------------------------------------
execute(OSQLParseNode * pPredicateNode)151 OOperand* OPredicateCompiler::execute(OSQLParseNode* pPredicateNode)
152 {
153 OOperand* pOperand = NULL;
154 if (pPredicateNode->count() == 3 && // Ausdruck is geklammert
155 SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"(") &&
156 SQL_ISPUNCTUATION(pPredicateNode->getChild(2),")"))
157 {
158 execute(pPredicateNode->getChild(1));
159 }
160 else if ((SQL_ISRULE(pPredicateNode,search_condition) || (SQL_ISRULE(pPredicateNode,boolean_term)))
161 && // AND/OR-Verknuepfung:
162 pPredicateNode->count() == 3)
163 {
164 execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs
165 execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs
166
167 if (SQL_ISTOKEN(pPredicateNode->getChild(1),OR)) // OR-Operator
168 {
169 m_aCodeList.push_back(new OOp_OR());
170 m_bORCondition = sal_True;
171 }
172 else if (SQL_ISTOKEN(pPredicateNode->getChild(1),AND)) // AND-Operator
173 m_aCodeList.push_back(new OOp_AND());
174 else
175 {
176 DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree");
177 }
178 }
179 else if (SQL_ISRULE(pPredicateNode,boolean_factor))
180 {
181 execute(pPredicateNode->getChild(1));
182 m_aCodeList.push_back(new OOp_NOT());
183 }
184 else if (SQL_ISRULE(pPredicateNode,comparison_predicate))
185 {
186 execute_COMPARE(pPredicateNode);
187 }
188 else if (SQL_ISRULE(pPredicateNode,like_predicate))
189 {
190 execute_LIKE(pPredicateNode);
191 }
192 else if (SQL_ISRULE(pPredicateNode,between_predicate))
193 {
194 execute_BETWEEN(pPredicateNode);
195 }
196 else if (SQL_ISRULE(pPredicateNode,test_for_null))
197 {
198 execute_ISNULL(pPredicateNode);
199 }
200 else if(SQL_ISRULE(pPredicateNode,num_value_exp))
201 {
202 execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs
203 execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs
204 if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"+"))
205 {
206 m_aCodeList.push_back(new OOp_ADD());
207 }
208 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"-"))
209 m_aCodeList.push_back(new OOp_SUB());
210 else
211 {
212 DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
213 }
214 }
215 else if(SQL_ISRULE(pPredicateNode,term))
216 {
217 execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs
218 execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs
219 if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"*"))
220 {
221 m_aCodeList.push_back(new OOp_MUL());
222 }
223 else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"/"))
224 m_aCodeList.push_back(new OOp_DIV());
225 else
226 {
227 DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree num_value_exp");
228 }
229 }
230 else
231 pOperand = execute_Operand(pPredicateNode); // jetzt werden nur einfache Operanden verarbeitet
232
233 return pOperand;
234 }
235
236 //------------------------------------------------------------------
execute_COMPARE(OSQLParseNode * pPredicateNode)237 OOperand* OPredicateCompiler::execute_COMPARE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
238 {
239 DBG_ASSERT(pPredicateNode->count() == 3,"OFILECursor: Fehler im Parse Tree");
240
241 if ( !(SQL_ISRULE(pPredicateNode->getChild(0),column_ref) ||
242 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_STRING ||
243 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_INTNUM ||
244 pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_APPROXNUM ||
245 SQL_ISTOKEN(pPredicateNode->getChild(2),TRUE) ||
246 SQL_ISTOKEN(pPredicateNode->getChild(2),FALSE) ||
247 SQL_ISRULE(pPredicateNode->getChild(2),parameter) ||
248 // odbc date
249 SQL_ISRULE(pPredicateNode->getChild(2),set_fct_spec) ||
250 SQL_ISRULE(pPredicateNode->getChild(2),position_exp) ||
251 SQL_ISRULE(pPredicateNode->getChild(2),char_substring_fct) ||
252 // upper, lower etc.
253 SQL_ISRULE(pPredicateNode->getChild(2),fold)) )
254 {
255 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL);
256 return NULL;
257 }
258
259 sal_Int32 ePredicateType( SQLFilterOperator::EQUAL );
260 OSQLParseNode *pPrec = pPredicateNode->getChild(1);
261
262 if (pPrec->getNodeType() == SQL_NODE_EQUAL)
263 ePredicateType = SQLFilterOperator::EQUAL;
264 else if (pPrec->getNodeType() == SQL_NODE_NOTEQUAL)
265 ePredicateType = SQLFilterOperator::NOT_EQUAL;
266 else if (pPrec->getNodeType() == SQL_NODE_LESS)
267 ePredicateType = SQLFilterOperator::LESS;
268 else if (pPrec->getNodeType() == SQL_NODE_LESSEQ)
269 ePredicateType = SQLFilterOperator::LESS_EQUAL;
270 else if (pPrec->getNodeType() == SQL_NODE_GREATEQ)
271 ePredicateType = SQLFilterOperator::GREATER_EQUAL;
272 else if (pPrec->getNodeType() == SQL_NODE_GREAT)
273 ePredicateType = SQLFilterOperator::GREATER;
274 else
275 OSL_ENSURE( false, "OPredicateCompiler::execute_COMPARE: unexpected node type!" );
276
277 execute(pPredicateNode->getChild(0));
278 execute(pPredicateNode->getChild(2));
279 m_aCodeList.push_back( new OOp_COMPARE(ePredicateType) );
280
281 return NULL;
282 }
283
284 //------------------------------------------------------------------
execute_LIKE(OSQLParseNode * pPredicateNode)285 OOperand* OPredicateCompiler::execute_LIKE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
286 {
287 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
288 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
289
290 sal_Unicode cEscape = L'\0';
291 const bool bNotLike = pPart2->getChild(0)->isToken();
292
293 OSQLParseNode* pAtom = pPart2->getChild(pPart2->count()-2);
294 OSQLParseNode* pOptEscape = pPart2->getChild(pPart2->count()-1);
295
296 if (!(pAtom->getNodeType() == SQL_NODE_STRING ||
297 SQL_ISRULE(pAtom,parameter) ||
298 // odbc date
299 SQL_ISRULE(pAtom,set_fct_spec) ||
300 SQL_ISRULE(pAtom,position_exp) ||
301 SQL_ISRULE(pAtom,char_substring_fct) ||
302 // upper, lower etc.
303 SQL_ISRULE(pAtom,fold)) )
304 {
305 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL);
306 return NULL;
307 }
308
309 if (pOptEscape->count() != 0)
310 {
311 if (pOptEscape->count() != 2)
312 {
313 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,NULL);
314 }
315 OSQLParseNode *pEscNode = pOptEscape->getChild(1);
316 if (pEscNode->getNodeType() != SQL_NODE_STRING)
317 {
318 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,NULL);
319 }
320 else
321 cEscape = pEscNode->getTokenValue().toChar();
322 }
323
324 execute(pPredicateNode->getChild(0));
325 execute(pAtom);
326
327 OBoolOperator* pOperator = bNotLike
328 ? new OOp_NOTLIKE(cEscape)
329 : new OOp_LIKE(cEscape);
330 m_aCodeList.push_back(pOperator);
331
332 return NULL;
333 }
334 //------------------------------------------------------------------
execute_BETWEEN(OSQLParseNode * pPredicateNode)335 OOperand* OPredicateCompiler::execute_BETWEEN(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
336 {
337 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
338
339 OSQLParseNode* pColumn = pPredicateNode->getChild(0);
340 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
341 OSQLParseNode* p1stValue = pPart2->getChild(2);
342 OSQLParseNode* p2ndtValue = pPart2->getChild(4);
343
344 if (
345 !(p1stValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p1stValue,parameter))
346 && !(p2ndtValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p2ndtValue,parameter))
347 )
348 {
349 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN,NULL);
350 }
351
352 sal_Bool bNot = SQL_ISTOKEN(pPart2->getChild(0),NOT);
353
354 OOperand* pColumnOp = execute(pColumn);
355 OOperand* pOb1 = execute(p1stValue);
356 OBoolOperator* pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::LESS_EQUAL : SQLFilterOperator::GREATER);
357 m_aCodeList.push_back(pOperator);
358
359 execute(pColumn);
360 OOperand* pOb2 = execute(p2ndtValue);
361 pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::GREATER_EQUAL : SQLFilterOperator::LESS);
362 m_aCodeList.push_back(pOperator);
363
364 if ( pColumnOp && pOb1 && pOb2 )
365 {
366 switch(pColumnOp->getDBType())
367 {
368 case DataType::CHAR:
369 case DataType::VARCHAR:
370 case DataType::LONGVARCHAR:
371 pOb1->setValue(pOb1->getValue().getString());
372 pOb2->setValue(pOb2->getValue().getString());
373 break;
374 case DataType::DECIMAL:
375 case DataType::NUMERIC:
376 pOb1->setValue((double)pOb1->getValue());
377 pOb2->setValue((double)pOb2->getValue());
378 break;
379 case DataType::FLOAT:
380 pOb1->setValue((float)pOb1->getValue());
381 pOb2->setValue((float)pOb2->getValue());
382 break;
383 case DataType::DOUBLE:
384 case DataType::REAL:
385 pOb1->setValue((double)pOb1->getValue());
386 pOb2->setValue((double)pOb2->getValue());
387 break;
388 case DataType::DATE:
389 pOb1->setValue((Date)pOb1->getValue());
390 pOb2->setValue((Date)pOb2->getValue());
391 break;
392 case DataType::TIME:
393 pOb1->setValue((Time)pOb1->getValue());
394 pOb2->setValue((Time)pOb2->getValue());
395 break;
396 case DataType::TIMESTAMP:
397 pOb1->setValue((DateTime)pOb1->getValue());
398 pOb2->setValue((DateTime)pOb2->getValue());
399 break;
400 }
401 }
402
403
404
405 OBoolOperator* pBoolOp = NULL;
406 if ( bNot )
407 pBoolOp = new OOp_OR();
408 else
409 pBoolOp = new OOp_AND();
410 m_aCodeList.push_back(pBoolOp);
411
412 return NULL;
413 }
414 //------------------------------------------------------------------
execute_ISNULL(OSQLParseNode * pPredicateNode)415 OOperand* OPredicateCompiler::execute_ISNULL(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
416 {
417 DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree");
418 const OSQLParseNode* pPart2 = pPredicateNode->getChild(1);
419 DBG_ASSERT(SQL_ISTOKEN(pPart2->getChild(0),IS),"OFILECursor: Fehler im Parse Tree");
420
421 sal_Int32 ePredicateType;
422 if (SQL_ISTOKEN(pPart2->getChild(1),NOT))
423 ePredicateType = SQLFilterOperator::NOT_SQLNULL;
424 else
425 ePredicateType = SQLFilterOperator::SQLNULL;
426
427 execute(pPredicateNode->getChild(0));
428 OBoolOperator* pOperator = (ePredicateType == SQLFilterOperator::SQLNULL) ?
429 new OOp_ISNULL() : new OOp_ISNOTNULL();
430 m_aCodeList.push_back(pOperator);
431
432 return NULL;
433 }
434 //------------------------------------------------------------------
execute_Operand(OSQLParseNode * pPredicateNode)435 OOperand* OPredicateCompiler::execute_Operand(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
436 {
437 OOperand* pOperand = NULL;
438
439 if (SQL_ISRULE(pPredicateNode,column_ref))
440 {
441 ::rtl::OUString aColumnName;
442 if (pPredicateNode->count() == 1)
443 {
444 aColumnName = pPredicateNode->getChild(0)->getTokenValue();
445 }
446 else if (pPredicateNode->count() == 3)
447 {
448 ::rtl::OUString aTableName = pPredicateNode->getChild(0)->getTokenValue();
449 if(SQL_ISRULE(pPredicateNode->getChild(2),column_val))
450 aColumnName = pPredicateNode->getChild(2)->getChild(0)->getTokenValue();
451 else
452 aColumnName = pPredicateNode->getChild(2)->getTokenValue();
453 }
454
455 if(!m_orgColumns->hasByName(aColumnName))
456 {
457 const ::rtl::OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution(
458 STR_INVALID_COLUMNNAME,
459 "$columnname$", aColumnName
460 ) );
461 ::dbtools::throwGenericSQLException( sError, NULL );
462 }
463 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xCol;
464 try
465 {
466 if (m_orgColumns->getByName(aColumnName) >>= xCol)
467 {
468 pOperand = m_pAnalyzer->createOperandAttr(Reference< XColumnLocate>(m_orgColumns,UNO_QUERY)->findColumn(aColumnName),xCol,m_xIndexes);
469 }
470 else
471 {// Column existiert nicht im Resultset
472 const ::rtl::OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution(
473 STR_INVALID_COLUMNNAME,
474 "$columnname$", aColumnName
475 ) );
476 ::dbtools::throwGenericSQLException( sError, NULL );
477 }
478 }
479 catch(Exception &)
480 {
481 OSL_ENSURE(0,"OPredicateCompiler::execute_Operand Exception");
482 }
483 }
484 else if (SQL_ISRULE(pPredicateNode,parameter))
485 {
486 pOperand = new OOperandParam(pPredicateNode, ++m_nParamCounter);
487 }
488 else if (pPredicateNode->getNodeType() == SQL_NODE_STRING ||
489 pPredicateNode->getNodeType() == SQL_NODE_INTNUM ||
490 pPredicateNode->getNodeType() == SQL_NODE_APPROXNUM ||
491 pPredicateNode->getNodeType() == SQL_NODE_NAME ||
492 SQL_ISTOKEN(pPredicateNode,TRUE) ||
493 SQL_ISTOKEN(pPredicateNode,FALSE) ||
494 SQL_ISRULE(pPredicateNode,parameter))
495 {
496 pOperand = new OOperandConst(*pPredicateNode, pPredicateNode->getTokenValue());
497 }
498 else if((pPredicateNode->count() == 2) &&
499 (SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"-")) &&
500 pPredicateNode->getChild(1)->getNodeType() == SQL_NODE_INTNUM)
501 { // falls -1 bzw. +1 vorhanden ist
502 ::rtl::OUString aValue(pPredicateNode->getChild(0)->getTokenValue());
503 aValue += pPredicateNode->getChild(1)->getTokenValue();
504 pOperand = new OOperandConst(*pPredicateNode->getChild(1), aValue);
505 }
506 else if( SQL_ISRULE(pPredicateNode,set_fct_spec) && SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"{") )
507 {
508 const OSQLParseNode* pODBCNode = pPredicateNode->getChild(1);
509 const OSQLParseNode* pODBCNodeChild = pODBCNode->getChild(0);
510
511 // Odbc Date or time
512 if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && (
513 SQL_ISTOKEN(pODBCNodeChild,D) ||
514 SQL_ISTOKEN(pODBCNodeChild,T) ||
515 SQL_ISTOKEN(pODBCNodeChild,TS) ))
516 {
517 ::rtl::OUString sDateTime = pODBCNode->getChild(1)->getTokenValue();
518 pOperand = new OOperandConst(*pODBCNode->getChild(1), sDateTime);
519 if(SQL_ISTOKEN(pODBCNodeChild,D))
520 {
521 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime)));
522 }
523 else if(SQL_ISTOKEN(pODBCNodeChild,T))
524 {
525 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime)));
526 }
527 else if(SQL_ISTOKEN(pODBCNodeChild,TS))
528 {
529 pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime)));
530 }
531 }
532 else
533 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL);
534
535 }
536 else if( SQL_ISRULE(pPredicateNode,fold) )
537 {
538 execute_Fold(pPredicateNode);
539 }
540 else if( SQL_ISRULE(pPredicateNode,set_fct_spec)
541 || SQL_ISRULE(pPredicateNode,position_exp)
542 || SQL_ISRULE(pPredicateNode,char_substring_fct)
543 )
544 {
545 executeFunction(pPredicateNode);
546 }
547 else if( SQL_ISRULE(pPredicateNode,length_exp) )
548 {
549 executeFunction(pPredicateNode->getChild(0));
550 }
551 else
552 {
553 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL);
554 }
555 if (pOperand)
556 m_aCodeList.push_back(pOperand);
557 return pOperand;
558 }
559
560 ////////////////////////////////////////////////////////////////////////////////////////
evaluate(OCodeList & rCodeList)561 sal_Bool OPredicateInterpreter::evaluate(OCodeList& rCodeList)
562 {
563 static sal_Bool bResult;
564
565 OCodeList::iterator aIter = rCodeList.begin();
566 if (!(*aIter))
567 return sal_True; // kein Praedikat
568
569 for(;aIter != rCodeList.end();++aIter)
570 {
571 OOperand* pOperand = PTR_CAST(OOperand,(*aIter));
572 if (pOperand)
573 m_aStack.push(pOperand);
574 else
575 ((OOperator *)(*aIter))->Exec(m_aStack);
576 }
577
578 OOperand* pOperand = m_aStack.top();
579 m_aStack.pop();
580
581 DBG_ASSERT(m_aStack.size() == 0, "StackFehler");
582 DBG_ASSERT(pOperand, "StackFehler");
583
584 bResult = pOperand->isValid();
585 if (IS_TYPE(OOperandResult,pOperand))
586 delete pOperand;
587 return bResult;
588 }
589 // -----------------------------------------------------------------------------
evaluateSelection(OCodeList & rCodeList,ORowSetValueDecoratorRef & _rVal)590 void OPredicateInterpreter::evaluateSelection(OCodeList& rCodeList,ORowSetValueDecoratorRef& _rVal)
591 {
592 OCodeList::iterator aIter = rCodeList.begin();
593 if (!(*aIter))
594 return ; // kein Praedikat
595
596 for(;aIter != rCodeList.end();++aIter)
597 {
598 OOperand* pOperand = PTR_CAST(OOperand,(*aIter));
599 if (pOperand)
600 m_aStack.push(pOperand);
601 else
602 ((OOperator *)(*aIter))->Exec(m_aStack);
603 }
604
605 OOperand* pOperand = m_aStack.top();
606 m_aStack.pop();
607
608 DBG_ASSERT(m_aStack.size() == 0, "StackFehler");
609 DBG_ASSERT(pOperand, "StackFehler");
610
611 (*_rVal) = pOperand->getValue();
612 if (IS_TYPE(OOperandResult,pOperand))
613 delete pOperand;
614 }
615 // -----------------------------------------------------------------------------
execute_Fold(OSQLParseNode * pPredicateNode)616 OOperand* OPredicateCompiler::execute_Fold(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
617 {
618 DBG_ASSERT(pPredicateNode->count() >= 4,"OFILECursor: Fehler im Parse Tree");
619
620 sal_Bool bUpper = SQL_ISTOKEN(pPredicateNode->getChild(0),UPPER);
621
622 execute(pPredicateNode->getChild(2));
623 OOperator* pOperator = NULL;
624 if ( bUpper )
625 pOperator = new OOp_Upper();
626 else
627 pOperator = new OOp_Lower();
628
629 m_aCodeList.push_back(pOperator);
630 return NULL;
631 }
632 // -----------------------------------------------------------------------------
executeFunction(OSQLParseNode * pPredicateNode)633 OOperand* OPredicateCompiler::executeFunction(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException)
634 {
635 OOperator* pOperator = NULL;
636
637 OSL_ENSURE(pPredicateNode->getChild(0)->isToken(),"The first one must be the name of the function!");
638 sal_Int32 nTokenId = pPredicateNode->getChild(0)->getTokenID();
639 switch ( nTokenId )
640 {
641 case SQL_TOKEN_CHAR_LENGTH:
642 case SQL_TOKEN_LENGTH:
643 case SQL_TOKEN_OCTET_LENGTH:
644 case SQL_TOKEN_ASCII:
645 case SQL_TOKEN_LCASE:
646 case SQL_TOKEN_LTRIM:
647 case SQL_TOKEN_RTRIM:
648 case SQL_TOKEN_SPACE:
649 case SQL_TOKEN_UCASE:
650 case SQL_TOKEN_ABS:
651 case SQL_TOKEN_ACOS:
652 case SQL_TOKEN_ASIN:
653 case SQL_TOKEN_ATAN:
654 case SQL_TOKEN_CEILING:
655 case SQL_TOKEN_COS:
656 case SQL_TOKEN_DEGREES:
657 case SQL_TOKEN_EXP:
658 case SQL_TOKEN_FLOOR:
659 case SQL_TOKEN_LOG10:
660 case SQL_TOKEN_LN:
661 case SQL_TOKEN_RADIANS:
662 case SQL_TOKEN_SIGN:
663 case SQL_TOKEN_SIN:
664 case SQL_TOKEN_SQRT:
665 case SQL_TOKEN_TAN:
666 case SQL_TOKEN_DAYNAME:
667 case SQL_TOKEN_DAYOFMONTH:
668 case SQL_TOKEN_DAYOFWEEK:
669 case SQL_TOKEN_DAYOFYEAR:
670 case SQL_TOKEN_HOUR:
671 case SQL_TOKEN_MINUTE:
672 case SQL_TOKEN_MONTH:
673 case SQL_TOKEN_MONTHNAME:
674 case SQL_TOKEN_QUARTER:
675 case SQL_TOKEN_SECOND:
676 case SQL_TOKEN_YEAR:
677
678 execute(pPredicateNode->getChild(2));
679
680 switch( nTokenId )
681 {
682 case SQL_TOKEN_CHAR_LENGTH:
683 case SQL_TOKEN_LENGTH:
684 case SQL_TOKEN_OCTET_LENGTH:
685 pOperator = new OOp_CharLength();
686 break;
687 case SQL_TOKEN_ASCII:
688 pOperator = new OOp_Ascii();
689 break;
690 case SQL_TOKEN_LCASE:
691 pOperator = new OOp_Lower();
692 break;
693
694 case SQL_TOKEN_LTRIM:
695 pOperator = new OOp_LTrim();
696 break;
697 case SQL_TOKEN_RTRIM:
698 pOperator = new OOp_RTrim();
699 break;
700 case SQL_TOKEN_SPACE:
701 pOperator = new OOp_Space();
702 break;
703 case SQL_TOKEN_UCASE:
704 pOperator = new OOp_Upper();
705 break;
706 case SQL_TOKEN_ABS:
707 pOperator = new OOp_Abs();
708 break;
709 case SQL_TOKEN_ACOS:
710 pOperator = new OOp_ACos();
711 break;
712 case SQL_TOKEN_ASIN:
713 pOperator = new OOp_ASin();
714 break;
715 case SQL_TOKEN_ATAN:
716 pOperator = new OOp_ATan();
717 break;
718 case SQL_TOKEN_CEILING:
719 pOperator = new OOp_Ceiling();
720 break;
721 case SQL_TOKEN_COS:
722 pOperator = new OOp_Cos();
723 break;
724 case SQL_TOKEN_DEGREES:
725 pOperator = new OOp_Degrees();
726 break;
727 case SQL_TOKEN_EXP:
728 pOperator = new OOp_Exp();
729 break;
730 case SQL_TOKEN_FLOOR:
731 pOperator = new OOp_Floor();
732 break;
733 case SQL_TOKEN_LOG10:
734 pOperator = new OOp_Log10();
735 break;
736 case SQL_TOKEN_LN:
737 pOperator = new OOp_Ln();
738 break;
739 case SQL_TOKEN_RADIANS:
740 pOperator = new OOp_Radians();
741 break;
742 case SQL_TOKEN_SIGN:
743 pOperator = new OOp_Sign();
744 break;
745 case SQL_TOKEN_SIN:
746 pOperator = new OOp_Sin();
747 break;
748 case SQL_TOKEN_SQRT:
749 pOperator = new OOp_Sqrt();
750 break;
751 case SQL_TOKEN_TAN:
752 pOperator = new OOp_Tan();
753 break;
754 case SQL_TOKEN_DAYOFWEEK:
755 pOperator = new OOp_DayOfWeek();
756 break;
757 case SQL_TOKEN_DAYOFMONTH:
758 pOperator = new OOp_DayOfMonth();
759 break;
760 case SQL_TOKEN_DAYOFYEAR:
761 pOperator = new OOp_DayOfYear();
762 break;
763 case SQL_TOKEN_MONTH:
764 pOperator = new OOp_Month();
765 break;
766 case SQL_TOKEN_DAYNAME:
767 pOperator = new OOp_DayName();
768 break;
769 case SQL_TOKEN_MONTHNAME:
770 pOperator = new OOp_MonthName();
771 break;
772 case SQL_TOKEN_QUARTER:
773 pOperator = new OOp_Quarter();
774 break;
775 case SQL_TOKEN_YEAR:
776 pOperator = new OOp_Year();
777 break;
778 case SQL_TOKEN_HOUR:
779 pOperator = new OOp_Hour();
780 break;
781 case SQL_TOKEN_MINUTE:
782 pOperator = new OOp_Minute();
783 break;
784 case SQL_TOKEN_SECOND:
785 pOperator = new OOp_Second();
786 break;
787 default:
788 OSL_ENSURE(0,"Error in switch!");
789 }
790 break;
791 case SQL_TOKEN_CHAR:
792 case SQL_TOKEN_CONCAT:
793 case SQL_TOKEN_INSERT:
794 case SQL_TOKEN_LEFT:
795 case SQL_TOKEN_LOCATE:
796 case SQL_TOKEN_LOCATE_2:
797 case SQL_TOKEN_REPEAT:
798 case SQL_TOKEN_REPLACE:
799 case SQL_TOKEN_RIGHT:
800 case SQL_TOKEN_MOD:
801 case SQL_TOKEN_ROUND:
802 case SQL_TOKEN_LOGF:
803 case SQL_TOKEN_LOG:
804 case SQL_TOKEN_POWER:
805 case SQL_TOKEN_ATAN2:
806 case SQL_TOKEN_PI:
807 case SQL_TOKEN_CURDATE:
808 case SQL_TOKEN_CURTIME:
809 case SQL_TOKEN_NOW:
810 case SQL_TOKEN_WEEK:
811 {
812 m_aCodeList.push_back(new OStopOperand);
813 OSQLParseNode* pList = pPredicateNode->getChild(2);
814 for (sal_uInt32 i=0; i < pList->count(); ++i)
815 execute(pList->getChild(i));
816
817 switch( nTokenId )
818 {
819 case SQL_TOKEN_CHAR:
820 pOperator = new OOp_Char();
821 break;
822 case SQL_TOKEN_CONCAT:
823 pOperator = new OOp_Concat();
824 break;
825 case SQL_TOKEN_INSERT:
826 pOperator = new OOp_Insert();
827 break;
828 case SQL_TOKEN_LEFT:
829 pOperator = new OOp_Left();
830 break;
831 case SQL_TOKEN_LOCATE:
832 case SQL_TOKEN_LOCATE_2:
833 pOperator = new OOp_Locate();
834 break;
835 case SQL_TOKEN_REPEAT:
836 pOperator = new OOp_Repeat();
837 break;
838 case SQL_TOKEN_REPLACE:
839 pOperator = new OOp_Replace();
840 break;
841 case SQL_TOKEN_RIGHT:
842 pOperator = new OOp_Right();
843 break;
844 case SQL_TOKEN_MOD:
845 pOperator = new OOp_Mod();
846 break;
847 case SQL_TOKEN_ROUND:
848 pOperator = new OOp_Round();
849 break;
850 case SQL_TOKEN_LOGF:
851 case SQL_TOKEN_LOG:
852 pOperator = new OOp_Log();
853 break;
854 case SQL_TOKEN_POWER:
855 pOperator = new OOp_Pow();
856 break;
857 case SQL_TOKEN_ATAN2:
858 pOperator = new OOp_ATan2();
859 break;
860 case SQL_TOKEN_PI:
861 pOperator = new OOp_Pi();
862 break;
863 case SQL_TOKEN_CURDATE:
864 pOperator = new OOp_CurDate();
865 break;
866 case SQL_TOKEN_CURTIME:
867 pOperator = new OOp_CurTime();
868 break;
869 case SQL_TOKEN_NOW:
870 pOperator = new OOp_Now();
871 break;
872 case SQL_TOKEN_WEEK:
873 pOperator = new OOp_Week();
874 break;
875 default:
876 OSL_ENSURE(0,"Error in switch!");
877 }
878 }
879 break;
880
881 case SQL_TOKEN_SUBSTRING:
882 m_aCodeList.push_back(new OStopOperand);
883 if ( pPredicateNode->count() == 4 ) //char_substring_fct
884 {
885 OSQLParseNode* pList = pPredicateNode->getChild(2);
886 for (sal_uInt32 i=0; i < pList->count(); ++i)
887 execute(pList->getChild(i));
888 }
889 else
890 {
891 execute(pPredicateNode->getChild(2));
892 execute(pPredicateNode->getChild(4));
893 execute(pPredicateNode->getChild(5)->getChild(1));
894 }
895 pOperator = new OOp_SubString();
896 break;
897
898 case SQL_TOKEN_POSITION:
899 m_aCodeList.push_back(new OStopOperand);
900 if ( pPredicateNode->count() == 4 ) //position_exp
901 {
902 OSQLParseNode* pList = pPredicateNode->getChild(2);
903 for (sal_uInt32 i=0; i < pList->count(); ++i)
904 execute(pList->getChild(i));
905 }
906 else
907 {
908 execute(pPredicateNode->getChild(2));
909 execute(pPredicateNode->getChild(4));
910 }
911 pOperator = new OOp_Locate();
912 break;
913 default:
914 m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED,NULL);
915 }
916
917 m_aCodeList.push_back(pOperator);
918 return NULL;
919 }
920 // -----------------------------------------------------------------------------
921
922
923