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