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