/************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_connectivity.hxx" #include "file/fcomp.hxx" #include #include "TConnection.hxx" #include "connectivity/sqlparse.hxx" #include "file/fanalyzer.hxx" #include #include #include #include #include "connectivity/dbexception.hxx" #include "connectivity/dbconversion.hxx" #include #include "resource/file_res.hrc" #include "file/FStringFunctions.hxx" #include "file/FDateFunctions.hxx" #include "file/FNumericFunctions.hxx" #include "file/FConnection.hxx" #include using namespace connectivity; using namespace connectivity::file; using namespace com::sun::star::uno; using namespace com::sun::star::sdbc; using namespace com::sun::star::sdb; using namespace ::com::sun::star::container; using namespace ::com::sun::star::util; DBG_NAME(OPredicateCompiler) //------------------------------------------------------------------ OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer* pAnalyzer)//,OCursor& rCurs) // : m_rCursor(rCurs) : m_pAnalyzer(pAnalyzer) , m_nParamCounter(0) , m_bORCondition(sal_False) { DBG_CTOR(OPredicateCompiler,NULL); } //------------------------------------------------------------------ OPredicateCompiler::~OPredicateCompiler() { Clean(); DBG_DTOR(OPredicateCompiler,NULL); } // ----------------------------------------------------------------------------- void OPredicateCompiler::dispose() { Clean(); m_orgColumns = NULL; m_xIndexes.clear(); } //------------------------------------------------------------------ // inline OCursor& OPredicateCompiler::Cursor() const {return m_rCursor;} //------------------------------------------------------------------ void OPredicateCompiler::start(OSQLParseNode* pSQLParseNode) { if (!pSQLParseNode) return; m_nParamCounter = 0; // Parse Tree analysieren (je nach Statement-Typ) // und Zeiger auf WHERE-Klausel setzen: OSQLParseNode * pWhereClause = NULL; OSQLParseNode * pOrderbyClause = NULL; if (SQL_ISRULE(pSQLParseNode,select_statement)) { DBG_ASSERT(pSQLParseNode->count() >= 4,"OFILECursor: Fehler im Parse Tree"); OSQLParseNode * pTableExp = pSQLParseNode->getChild(3); DBG_ASSERT(pTableExp != NULL,"Fehler im Parse Tree"); DBG_ASSERT(SQL_ISRULE(pTableExp,table_exp)," Fehler im Parse Tree"); DBG_ASSERT(pTableExp->count() == TABLE_EXPRESSION_CHILD_COUNT,"Fehler im Parse Tree"); // check that we don't use anything other than count(*) as function OSQLParseNode* pSelection = pSQLParseNode->getChild(2); if ( SQL_ISRULE(pSelection,scalar_exp_commalist) ) { for (sal_uInt32 i = 0; i < pSelection->count(); i++) { OSQLParseNode *pColumnRef = pSelection->getChild(i)->getChild(0); if ( SQL_ISRULE(pColumnRef,general_set_fct) && pColumnRef->count() != 4 ) { m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT,NULL); } } } pWhereClause = pTableExp->getChild(1); pOrderbyClause = pTableExp->getChild(ORDER_BY_CHILD_POS); } else if (SQL_ISRULE(pSQLParseNode,update_statement_searched)) { DBG_ASSERT(pSQLParseNode->count() == 5,"OFILECursor: Fehler im Parse Tree"); pWhereClause = pSQLParseNode->getChild(4); } else if (SQL_ISRULE(pSQLParseNode,delete_statement_searched)) { DBG_ASSERT(pSQLParseNode->count() == 4,"Fehler im Parse Tree"); pWhereClause = pSQLParseNode->getChild(3); } else // Anderes Statement. Keine Selektionskriterien. return; if (SQL_ISRULE(pWhereClause,where_clause)) { // Wenn es aber eine where_clause ist, dann darf sie nicht leer sein: DBG_ASSERT(pWhereClause->count() == 2,"OFILECursor: Fehler im Parse Tree"); OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1); DBG_ASSERT(pComparisonPredicate != NULL,"OFILECursor: Fehler im Parse Tree"); execute( pComparisonPredicate ); } else { // Die Where Clause ist meistens optional, d. h. es koennte sich auch // um "optional_where_clause" handeln. DBG_ASSERT(SQL_ISRULE(pWhereClause,opt_where_clause),"OPredicateCompiler: Fehler im Parse Tree"); } } //------------------------------------------------------------------ OOperand* OPredicateCompiler::execute(OSQLParseNode* pPredicateNode) { OOperand* pOperand = NULL; if (pPredicateNode->count() == 3 && // Ausdruck is geklammert SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"(") && SQL_ISPUNCTUATION(pPredicateNode->getChild(2),")")) { execute(pPredicateNode->getChild(1)); } else if ((SQL_ISRULE(pPredicateNode,search_condition) || (SQL_ISRULE(pPredicateNode,boolean_term))) && // AND/OR-Verknuepfung: pPredicateNode->count() == 3) { execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs if (SQL_ISTOKEN(pPredicateNode->getChild(1),OR)) // OR-Operator { m_aCodeList.push_back(new OOp_OR()); m_bORCondition = sal_True; } else if (SQL_ISTOKEN(pPredicateNode->getChild(1),AND)) // AND-Operator m_aCodeList.push_back(new OOp_AND()); else { DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree"); } } else if (SQL_ISRULE(pPredicateNode,boolean_factor)) { execute(pPredicateNode->getChild(1)); m_aCodeList.push_back(new OOp_NOT()); } else if (SQL_ISRULE(pPredicateNode,comparison_predicate)) { execute_COMPARE(pPredicateNode); } else if (SQL_ISRULE(pPredicateNode,like_predicate)) { execute_LIKE(pPredicateNode); } else if (SQL_ISRULE(pPredicateNode,between_predicate)) { execute_BETWEEN(pPredicateNode); } else if (SQL_ISRULE(pPredicateNode,test_for_null)) { execute_ISNULL(pPredicateNode); } else if(SQL_ISRULE(pPredicateNode,num_value_exp)) { execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"+")) { m_aCodeList.push_back(new OOp_ADD()); } else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"-")) m_aCodeList.push_back(new OOp_SUB()); else { DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree num_value_exp"); } } else if(SQL_ISRULE(pPredicateNode,term)) { execute(pPredicateNode->getChild(0)); // Bearbeiten des linken Zweigs execute(pPredicateNode->getChild(2)); // Bearbeiten des rechten Zweigs if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"*")) { m_aCodeList.push_back(new OOp_MUL()); } else if (SQL_ISPUNCTUATION(pPredicateNode->getChild(1),"/")) m_aCodeList.push_back(new OOp_DIV()); else { DBG_ERROR("OPredicateCompiler: Fehler im Parse Tree num_value_exp"); } } else pOperand = execute_Operand(pPredicateNode); // jetzt werden nur einfache Operanden verarbeitet return pOperand; } //------------------------------------------------------------------ OOperand* OPredicateCompiler::execute_COMPARE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) { DBG_ASSERT(pPredicateNode->count() == 3,"OFILECursor: Fehler im Parse Tree"); if ( !(SQL_ISRULE(pPredicateNode->getChild(0),column_ref) || pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_STRING || pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_INTNUM || pPredicateNode->getChild(2)->getNodeType() == SQL_NODE_APPROXNUM || SQL_ISTOKEN(pPredicateNode->getChild(2),TRUE) || SQL_ISTOKEN(pPredicateNode->getChild(2),FALSE) || SQL_ISRULE(pPredicateNode->getChild(2),parameter) || // odbc date SQL_ISRULE(pPredicateNode->getChild(2),set_fct_spec) || SQL_ISRULE(pPredicateNode->getChild(2),position_exp) || SQL_ISRULE(pPredicateNode->getChild(2),char_substring_fct) || // upper, lower etc. SQL_ISRULE(pPredicateNode->getChild(2),fold)) ) { m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL); return NULL; } sal_Int32 ePredicateType( SQLFilterOperator::EQUAL ); OSQLParseNode *pPrec = pPredicateNode->getChild(1); if (pPrec->getNodeType() == SQL_NODE_EQUAL) ePredicateType = SQLFilterOperator::EQUAL; else if (pPrec->getNodeType() == SQL_NODE_NOTEQUAL) ePredicateType = SQLFilterOperator::NOT_EQUAL; else if (pPrec->getNodeType() == SQL_NODE_LESS) ePredicateType = SQLFilterOperator::LESS; else if (pPrec->getNodeType() == SQL_NODE_LESSEQ) ePredicateType = SQLFilterOperator::LESS_EQUAL; else if (pPrec->getNodeType() == SQL_NODE_GREATEQ) ePredicateType = SQLFilterOperator::GREATER_EQUAL; else if (pPrec->getNodeType() == SQL_NODE_GREAT) ePredicateType = SQLFilterOperator::GREATER; else OSL_ENSURE( false, "OPredicateCompiler::execute_COMPARE: unexpected node type!" ); execute(pPredicateNode->getChild(0)); execute(pPredicateNode->getChild(2)); m_aCodeList.push_back( new OOp_COMPARE(ePredicateType) ); return NULL; } //------------------------------------------------------------------ OOperand* OPredicateCompiler::execute_LIKE(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) { DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree"); const OSQLParseNode* pPart2 = pPredicateNode->getChild(1); sal_Unicode cEscape = L'\0'; const bool bNotLike = pPart2->getChild(0)->isToken(); OSQLParseNode* pAtom = pPart2->getChild(pPart2->count()-2); OSQLParseNode* pOptEscape = pPart2->getChild(pPart2->count()-1); if (!(pAtom->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(pAtom,parameter) || // odbc date SQL_ISRULE(pAtom,set_fct_spec) || SQL_ISRULE(pAtom,position_exp) || SQL_ISRULE(pAtom,char_substring_fct) || // upper, lower etc. SQL_ISRULE(pAtom,fold)) ) { m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL); return NULL; } if (pOptEscape->count() != 0) { if (pOptEscape->count() != 2) { m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,NULL); } OSQLParseNode *pEscNode = pOptEscape->getChild(1); if (pEscNode->getNodeType() != SQL_NODE_STRING) { m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_LIKE_STRING,NULL); } else cEscape = pEscNode->getTokenValue().toChar(); } execute(pPredicateNode->getChild(0)); execute(pAtom); OBoolOperator* pOperator = bNotLike ? new OOp_NOTLIKE(cEscape) : new OOp_LIKE(cEscape); m_aCodeList.push_back(pOperator); return NULL; } //------------------------------------------------------------------ OOperand* OPredicateCompiler::execute_BETWEEN(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) { DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree"); OSQLParseNode* pColumn = pPredicateNode->getChild(0); const OSQLParseNode* pPart2 = pPredicateNode->getChild(1); OSQLParseNode* p1stValue = pPart2->getChild(2); OSQLParseNode* p2ndtValue = pPart2->getChild(4); if ( !(p1stValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p1stValue,parameter)) && !(p2ndtValue->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(p2ndtValue,parameter)) ) { m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_INVALID_BETWEEN,NULL); } sal_Bool bNot = SQL_ISTOKEN(pPart2->getChild(0),NOT); OOperand* pColumnOp = execute(pColumn); OOperand* pOb1 = execute(p1stValue); OBoolOperator* pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::LESS_EQUAL : SQLFilterOperator::GREATER); m_aCodeList.push_back(pOperator); execute(pColumn); OOperand* pOb2 = execute(p2ndtValue); pOperator = new OOp_COMPARE(bNot ? SQLFilterOperator::GREATER_EQUAL : SQLFilterOperator::LESS); m_aCodeList.push_back(pOperator); if ( pColumnOp && pOb1 && pOb2 ) { switch(pColumnOp->getDBType()) { case DataType::CHAR: case DataType::VARCHAR: case DataType::LONGVARCHAR: pOb1->setValue(pOb1->getValue().getString()); pOb2->setValue(pOb2->getValue().getString()); break; case DataType::DECIMAL: case DataType::NUMERIC: pOb1->setValue((double)pOb1->getValue()); pOb2->setValue((double)pOb2->getValue()); break; case DataType::FLOAT: pOb1->setValue((float)pOb1->getValue()); pOb2->setValue((float)pOb2->getValue()); break; case DataType::DOUBLE: case DataType::REAL: pOb1->setValue((double)pOb1->getValue()); pOb2->setValue((double)pOb2->getValue()); break; case DataType::DATE: pOb1->setValue((Date)pOb1->getValue()); pOb2->setValue((Date)pOb2->getValue()); break; case DataType::TIME: pOb1->setValue((Time)pOb1->getValue()); pOb2->setValue((Time)pOb2->getValue()); break; case DataType::TIMESTAMP: pOb1->setValue((DateTime)pOb1->getValue()); pOb2->setValue((DateTime)pOb2->getValue()); break; } } OBoolOperator* pBoolOp = NULL; if ( bNot ) pBoolOp = new OOp_OR(); else pBoolOp = new OOp_AND(); m_aCodeList.push_back(pBoolOp); return NULL; } //------------------------------------------------------------------ OOperand* OPredicateCompiler::execute_ISNULL(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) { DBG_ASSERT(pPredicateNode->count() == 2,"OFILECursor: Fehler im Parse Tree"); const OSQLParseNode* pPart2 = pPredicateNode->getChild(1); DBG_ASSERT(SQL_ISTOKEN(pPart2->getChild(0),IS),"OFILECursor: Fehler im Parse Tree"); sal_Int32 ePredicateType; if (SQL_ISTOKEN(pPart2->getChild(1),NOT)) ePredicateType = SQLFilterOperator::NOT_SQLNULL; else ePredicateType = SQLFilterOperator::SQLNULL; execute(pPredicateNode->getChild(0)); OBoolOperator* pOperator = (ePredicateType == SQLFilterOperator::SQLNULL) ? new OOp_ISNULL() : new OOp_ISNOTNULL(); m_aCodeList.push_back(pOperator); return NULL; } //------------------------------------------------------------------ OOperand* OPredicateCompiler::execute_Operand(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) { OOperand* pOperand = NULL; if (SQL_ISRULE(pPredicateNode,column_ref)) { ::rtl::OUString aColumnName; if (pPredicateNode->count() == 1) { aColumnName = pPredicateNode->getChild(0)->getTokenValue(); } else if (pPredicateNode->count() == 3) { ::rtl::OUString aTableName = pPredicateNode->getChild(0)->getTokenValue(); if(SQL_ISRULE(pPredicateNode->getChild(2),column_val)) aColumnName = pPredicateNode->getChild(2)->getChild(0)->getTokenValue(); else aColumnName = pPredicateNode->getChild(2)->getTokenValue(); } if(!m_orgColumns->hasByName(aColumnName)) { const ::rtl::OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution( STR_INVALID_COLUMNNAME, "$columnname$", aColumnName ) ); ::dbtools::throwGenericSQLException( sError, NULL ); } ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet> xCol; try { if (m_orgColumns->getByName(aColumnName) >>= xCol) { pOperand = m_pAnalyzer->createOperandAttr(Reference< XColumnLocate>(m_orgColumns,UNO_QUERY)->findColumn(aColumnName),xCol,m_xIndexes); } else {// Column existiert nicht im Resultset const ::rtl::OUString sError( m_pAnalyzer->getConnection()->getResources().getResourceStringWithSubstitution( STR_INVALID_COLUMNNAME, "$columnname$", aColumnName ) ); ::dbtools::throwGenericSQLException( sError, NULL ); } } catch(Exception &) { OSL_ENSURE(0,"OPredicateCompiler::execute_Operand Exception"); } } else if (SQL_ISRULE(pPredicateNode,parameter)) { pOperand = new OOperandParam(pPredicateNode, ++m_nParamCounter); } else if (pPredicateNode->getNodeType() == SQL_NODE_STRING || pPredicateNode->getNodeType() == SQL_NODE_INTNUM || pPredicateNode->getNodeType() == SQL_NODE_APPROXNUM || pPredicateNode->getNodeType() == SQL_NODE_NAME || SQL_ISTOKEN(pPredicateNode,TRUE) || SQL_ISTOKEN(pPredicateNode,FALSE) || SQL_ISRULE(pPredicateNode,parameter)) { pOperand = new OOperandConst(*pPredicateNode, pPredicateNode->getTokenValue()); } else if((pPredicateNode->count() == 2) && (SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"+") || SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"-")) && pPredicateNode->getChild(1)->getNodeType() == SQL_NODE_INTNUM) { // falls -1 bzw. +1 vorhanden ist ::rtl::OUString aValue(pPredicateNode->getChild(0)->getTokenValue()); aValue += pPredicateNode->getChild(1)->getTokenValue(); pOperand = new OOperandConst(*pPredicateNode->getChild(1), aValue); } else if( SQL_ISRULE(pPredicateNode,set_fct_spec) && SQL_ISPUNCTUATION(pPredicateNode->getChild(0),"{") ) { const OSQLParseNode* pODBCNode = pPredicateNode->getChild(1); const OSQLParseNode* pODBCNodeChild = pODBCNode->getChild(0); // Odbc Date or time if (pODBCNodeChild->getNodeType() == SQL_NODE_KEYWORD && ( SQL_ISTOKEN(pODBCNodeChild,D) || SQL_ISTOKEN(pODBCNodeChild,T) || SQL_ISTOKEN(pODBCNodeChild,TS) )) { ::rtl::OUString sDateTime = pODBCNode->getChild(1)->getTokenValue(); pOperand = new OOperandConst(*pODBCNode->getChild(1), sDateTime); if(SQL_ISTOKEN(pODBCNodeChild,D)) { pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDate(sDateTime))); } else if(SQL_ISTOKEN(pODBCNodeChild,T)) { pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toTime(sDateTime))); } else if(SQL_ISTOKEN(pODBCNodeChild,TS)) { pOperand->setValue(::dbtools::DBTypeConversion::toDouble(::dbtools::DBTypeConversion::toDateTime(sDateTime))); } } else m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL); } else if( SQL_ISRULE(pPredicateNode,fold) ) { execute_Fold(pPredicateNode); } else if( SQL_ISRULE(pPredicateNode,set_fct_spec) || SQL_ISRULE(pPredicateNode,position_exp) || SQL_ISRULE(pPredicateNode,char_substring_fct) ) { executeFunction(pPredicateNode); } else if( SQL_ISRULE(pPredicateNode,length_exp) ) { executeFunction(pPredicateNode->getChild(0)); } else { m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_TOO_COMPLEX,NULL); } if (pOperand) m_aCodeList.push_back(pOperand); return pOperand; } //////////////////////////////////////////////////////////////////////////////////////// sal_Bool OPredicateInterpreter::evaluate(OCodeList& rCodeList) { static sal_Bool bResult; OCodeList::iterator aIter = rCodeList.begin(); if (!(*aIter)) return sal_True; // kein Praedikat for(;aIter != rCodeList.end();++aIter) { OOperand* pOperand = PTR_CAST(OOperand,(*aIter)); if (pOperand) m_aStack.push(pOperand); else ((OOperator *)(*aIter))->Exec(m_aStack); } OOperand* pOperand = m_aStack.top(); m_aStack.pop(); DBG_ASSERT(m_aStack.size() == 0, "StackFehler"); DBG_ASSERT(pOperand, "StackFehler"); bResult = pOperand->isValid(); if (IS_TYPE(OOperandResult,pOperand)) delete pOperand; return bResult; } // ----------------------------------------------------------------------------- void OPredicateInterpreter::evaluateSelection(OCodeList& rCodeList,ORowSetValueDecoratorRef& _rVal) { OCodeList::iterator aIter = rCodeList.begin(); if (!(*aIter)) return ; // kein Praedikat for(;aIter != rCodeList.end();++aIter) { OOperand* pOperand = PTR_CAST(OOperand,(*aIter)); if (pOperand) m_aStack.push(pOperand); else ((OOperator *)(*aIter))->Exec(m_aStack); } OOperand* pOperand = m_aStack.top(); m_aStack.pop(); DBG_ASSERT(m_aStack.size() == 0, "StackFehler"); DBG_ASSERT(pOperand, "StackFehler"); (*_rVal) = pOperand->getValue(); if (IS_TYPE(OOperandResult,pOperand)) delete pOperand; } // ----------------------------------------------------------------------------- OOperand* OPredicateCompiler::execute_Fold(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) { DBG_ASSERT(pPredicateNode->count() >= 4,"OFILECursor: Fehler im Parse Tree"); sal_Bool bUpper = SQL_ISTOKEN(pPredicateNode->getChild(0),UPPER); execute(pPredicateNode->getChild(2)); OOperator* pOperator = NULL; if ( bUpper ) pOperator = new OOp_Upper(); else pOperator = new OOp_Lower(); m_aCodeList.push_back(pOperator); return NULL; } // ----------------------------------------------------------------------------- OOperand* OPredicateCompiler::executeFunction(OSQLParseNode* pPredicateNode) throw(SQLException, RuntimeException) { OOperator* pOperator = NULL; OSL_ENSURE(pPredicateNode->getChild(0)->isToken(),"The first one must be the name of the function!"); sal_Int32 nTokenId = pPredicateNode->getChild(0)->getTokenID(); switch ( nTokenId ) { case SQL_TOKEN_CHAR_LENGTH: case SQL_TOKEN_LENGTH: case SQL_TOKEN_OCTET_LENGTH: case SQL_TOKEN_ASCII: case SQL_TOKEN_LCASE: case SQL_TOKEN_LTRIM: case SQL_TOKEN_RTRIM: case SQL_TOKEN_SPACE: case SQL_TOKEN_UCASE: case SQL_TOKEN_ABS: case SQL_TOKEN_ACOS: case SQL_TOKEN_ASIN: case SQL_TOKEN_ATAN: case SQL_TOKEN_CEILING: case SQL_TOKEN_COS: case SQL_TOKEN_DEGREES: case SQL_TOKEN_EXP: case SQL_TOKEN_FLOOR: case SQL_TOKEN_LOG10: case SQL_TOKEN_LN: case SQL_TOKEN_RADIANS: case SQL_TOKEN_SIGN: case SQL_TOKEN_SIN: case SQL_TOKEN_SQRT: case SQL_TOKEN_TAN: case SQL_TOKEN_DAYNAME: case SQL_TOKEN_DAYOFMONTH: case SQL_TOKEN_DAYOFWEEK: case SQL_TOKEN_DAYOFYEAR: case SQL_TOKEN_HOUR: case SQL_TOKEN_MINUTE: case SQL_TOKEN_MONTH: case SQL_TOKEN_MONTHNAME: case SQL_TOKEN_QUARTER: case SQL_TOKEN_SECOND: case SQL_TOKEN_YEAR: execute(pPredicateNode->getChild(2)); switch( nTokenId ) { case SQL_TOKEN_CHAR_LENGTH: case SQL_TOKEN_LENGTH: case SQL_TOKEN_OCTET_LENGTH: pOperator = new OOp_CharLength(); break; case SQL_TOKEN_ASCII: pOperator = new OOp_Ascii(); break; case SQL_TOKEN_LCASE: pOperator = new OOp_Lower(); break; case SQL_TOKEN_LTRIM: pOperator = new OOp_LTrim(); break; case SQL_TOKEN_RTRIM: pOperator = new OOp_RTrim(); break; case SQL_TOKEN_SPACE: pOperator = new OOp_Space(); break; case SQL_TOKEN_UCASE: pOperator = new OOp_Upper(); break; case SQL_TOKEN_ABS: pOperator = new OOp_Abs(); break; case SQL_TOKEN_ACOS: pOperator = new OOp_ACos(); break; case SQL_TOKEN_ASIN: pOperator = new OOp_ASin(); break; case SQL_TOKEN_ATAN: pOperator = new OOp_ATan(); break; case SQL_TOKEN_CEILING: pOperator = new OOp_Ceiling(); break; case SQL_TOKEN_COS: pOperator = new OOp_Cos(); break; case SQL_TOKEN_DEGREES: pOperator = new OOp_Degrees(); break; case SQL_TOKEN_EXP: pOperator = new OOp_Exp(); break; case SQL_TOKEN_FLOOR: pOperator = new OOp_Floor(); break; case SQL_TOKEN_LOG10: pOperator = new OOp_Log10(); break; case SQL_TOKEN_LN: pOperator = new OOp_Ln(); break; case SQL_TOKEN_RADIANS: pOperator = new OOp_Radians(); break; case SQL_TOKEN_SIGN: pOperator = new OOp_Sign(); break; case SQL_TOKEN_SIN: pOperator = new OOp_Sin(); break; case SQL_TOKEN_SQRT: pOperator = new OOp_Sqrt(); break; case SQL_TOKEN_TAN: pOperator = new OOp_Tan(); break; case SQL_TOKEN_DAYOFWEEK: pOperator = new OOp_DayOfWeek(); break; case SQL_TOKEN_DAYOFMONTH: pOperator = new OOp_DayOfMonth(); break; case SQL_TOKEN_DAYOFYEAR: pOperator = new OOp_DayOfYear(); break; case SQL_TOKEN_MONTH: pOperator = new OOp_Month(); break; case SQL_TOKEN_DAYNAME: pOperator = new OOp_DayName(); break; case SQL_TOKEN_MONTHNAME: pOperator = new OOp_MonthName(); break; case SQL_TOKEN_QUARTER: pOperator = new OOp_Quarter(); break; case SQL_TOKEN_YEAR: pOperator = new OOp_Year(); break; case SQL_TOKEN_HOUR: pOperator = new OOp_Hour(); break; case SQL_TOKEN_MINUTE: pOperator = new OOp_Minute(); break; case SQL_TOKEN_SECOND: pOperator = new OOp_Second(); break; default: OSL_ENSURE(0,"Error in switch!"); } break; case SQL_TOKEN_CHAR: case SQL_TOKEN_CONCAT: case SQL_TOKEN_INSERT: case SQL_TOKEN_LEFT: case SQL_TOKEN_LOCATE: case SQL_TOKEN_LOCATE_2: case SQL_TOKEN_REPEAT: case SQL_TOKEN_REPLACE: case SQL_TOKEN_RIGHT: case SQL_TOKEN_MOD: case SQL_TOKEN_ROUND: case SQL_TOKEN_LOGF: case SQL_TOKEN_LOG: case SQL_TOKEN_POWER: case SQL_TOKEN_ATAN2: case SQL_TOKEN_PI: case SQL_TOKEN_CURDATE: case SQL_TOKEN_CURTIME: case SQL_TOKEN_NOW: case SQL_TOKEN_WEEK: { m_aCodeList.push_back(new OStopOperand); OSQLParseNode* pList = pPredicateNode->getChild(2); for (sal_uInt32 i=0; i < pList->count(); ++i) execute(pList->getChild(i)); switch( nTokenId ) { case SQL_TOKEN_CHAR: pOperator = new OOp_Char(); break; case SQL_TOKEN_CONCAT: pOperator = new OOp_Concat(); break; case SQL_TOKEN_INSERT: pOperator = new OOp_Insert(); break; case SQL_TOKEN_LEFT: pOperator = new OOp_Left(); break; case SQL_TOKEN_LOCATE: case SQL_TOKEN_LOCATE_2: pOperator = new OOp_Locate(); break; case SQL_TOKEN_REPEAT: pOperator = new OOp_Repeat(); break; case SQL_TOKEN_REPLACE: pOperator = new OOp_Replace(); break; case SQL_TOKEN_RIGHT: pOperator = new OOp_Right(); break; case SQL_TOKEN_MOD: pOperator = new OOp_Mod(); break; case SQL_TOKEN_ROUND: pOperator = new OOp_Round(); break; case SQL_TOKEN_LOGF: case SQL_TOKEN_LOG: pOperator = new OOp_Log(); break; case SQL_TOKEN_POWER: pOperator = new OOp_Pow(); break; case SQL_TOKEN_ATAN2: pOperator = new OOp_ATan2(); break; case SQL_TOKEN_PI: pOperator = new OOp_Pi(); break; case SQL_TOKEN_CURDATE: pOperator = new OOp_CurDate(); break; case SQL_TOKEN_CURTIME: pOperator = new OOp_CurTime(); break; case SQL_TOKEN_NOW: pOperator = new OOp_Now(); break; case SQL_TOKEN_WEEK: pOperator = new OOp_Week(); break; default: OSL_ENSURE(0,"Error in switch!"); } } break; case SQL_TOKEN_SUBSTRING: m_aCodeList.push_back(new OStopOperand); if ( pPredicateNode->count() == 4 ) //char_substring_fct { OSQLParseNode* pList = pPredicateNode->getChild(2); for (sal_uInt32 i=0; i < pList->count(); ++i) execute(pList->getChild(i)); } else { execute(pPredicateNode->getChild(2)); execute(pPredicateNode->getChild(4)); execute(pPredicateNode->getChild(5)->getChild(1)); } pOperator = new OOp_SubString(); break; case SQL_TOKEN_POSITION: m_aCodeList.push_back(new OStopOperand); if ( pPredicateNode->count() == 4 ) //position_exp { OSQLParseNode* pList = pPredicateNode->getChild(2); for (sal_uInt32 i=0; i < pList->count(); ++i) execute(pList->getChild(i)); } else { execute(pPredicateNode->getChild(2)); execute(pPredicateNode->getChild(4)); } pOperator = new OOp_Locate(); break; default: m_pAnalyzer->getConnection()->throwGenericSQLException(STR_QUERY_FUNCTION_NOT_SUPPORTED,NULL); } m_aCodeList.push_back(pOperator); return NULL; } // -----------------------------------------------------------------------------