xref: /AOO41X/main/connectivity/source/drivers/file/fcomp.cxx (revision 9b5730f6ddef7eb82608ca4d31dc0d7678e652cf)
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