diff options
author | Frank Schönheit <fs@openoffice.org> | 2000-10-05 07:39:29 +0000 |
---|---|---|
committer | Frank Schönheit <fs@openoffice.org> | 2000-10-05 07:39:29 +0000 |
commit | 8b1efd34bf563a1a8de9d7e78e52cdab8086cb38 (patch) | |
tree | 671f703fcaa1801676111a1256aa8d8bc4f23f81 /connectivity | |
parent | 59a91e9ebffef91bb1570846cba98ef4ca8e181e (diff) |
moved from ..\..\parse
Diffstat (limited to 'connectivity')
-rw-r--r-- | connectivity/source/drivers/file/fanalyzer.cxx | 298 | ||||
-rw-r--r-- | connectivity/source/drivers/file/fcode.cxx | 461 | ||||
-rw-r--r-- | connectivity/source/drivers/file/fcomp.cxx | 538 |
3 files changed, 1297 insertions, 0 deletions
diff --git a/connectivity/source/drivers/file/fanalyzer.cxx b/connectivity/source/drivers/file/fanalyzer.cxx new file mode 100644 index 000000000000..cfa98ae932ba --- /dev/null +++ b/connectivity/source/drivers/file/fanalyzer.cxx @@ -0,0 +1,298 @@ +/************************************************************************* + * + * $RCSfile: fanalyzer.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: fs $ $Date: 2000-10-05 08:39:11 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc.. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ +#ifndef _CONNECTIVITY_FILE_FANALYZER_HXX_ +#include "file/fanalyzer.hxx" +#endif +#ifndef _CONNECTIVITY_SQLPARSE_HXX +#include "connectivity/sqlparse.hxx" +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif + +#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_ +#include <com/sun/star/container/XIndexAccess.hpp> +#endif + +using namespace connectivity; +using namespace connectivity::file; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::container; + +typedef ::std::list<OEvaluateSet*> OEvaluateSetList; +//------------------------------------------------------------------ +OSQLAnalyzer::OSQLAnalyzer() + : m_aCompiler(this) + , m_aInterpreter(m_aCompiler) + // ,m_rCursor(rCurs) +{} +//------------------------------------------------------------------ +void OSQLAnalyzer::start(OSQLParseNode* pSQLParseNode) +{ + if (!pSQLParseNode) return; + + // 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)) + { + OSL_ENSHURE(pSQLParseNode->count() >= 4,"OFILECursor: Fehler im Parse Tree"); + + OSQLParseNode * pTableExp = pSQLParseNode->getChild(3); + OSL_ENSHURE(pTableExp != NULL,"Fehler im Parse Tree"); + OSL_ENSHURE(SQL_ISRULE(pTableExp,table_exp)," Fehler im Parse Tree"); + OSL_ENSHURE(pTableExp->count() == 5,"Fehler im Parse Tree"); + + pWhereClause = pTableExp->getChild(1); + pOrderbyClause = pTableExp->getChild(4); + } + else if (SQL_ISRULE(pSQLParseNode,update_statement_searched)) + { + OSL_ENSHURE(pSQLParseNode->count() == 5,"OFILECursor: Fehler im Parse Tree"); + pWhereClause = pSQLParseNode->getChild(4); + } + else if (SQL_ISRULE(pSQLParseNode,update_statement_positioned)) + { + // nyi + DBG_ERROR("OPredicateCompiler: update positioned nyi"); + } + else if (SQL_ISRULE(pSQLParseNode,delete_statement_searched)) + { + OSL_ENSHURE(pSQLParseNode->count() == 4,"Fehler im Parse Tree"); + pWhereClause = pSQLParseNode->getChild(3); + } + else if (SQL_ISRULE(pSQLParseNode,delete_statement_positioned)) + { + // nyi + DBG_ERROR("OPredicateCompiler: positioned nyi"); + } + 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: + OSL_ENSHURE(pWhereClause->count() == 2,"OFILECursor: Fehler im Parse Tree"); + + OSQLParseNode * pComparisonPredicate = pWhereClause->getChild(1); + OSL_ENSHURE(pComparisonPredicate != NULL,"OFILECursor: Fehler im Parse Tree"); + + m_aCompiler.execute(pComparisonPredicate); + } + else + { + // Die Where Clause ist meistens optional, d. h. es koennte sich auch + // um "optional_where_clause" handeln. + OSL_ENSHURE(SQL_ISRULE(pWhereClause,opt_where_clause),"OFILECursor: Fehler im Parse Tree"); + } +} + +//------------------------------------------------------------------ +::std::vector<sal_Int32>* OSQLAnalyzer::bindResultRow(OValueRow _pRow) +{ + OCodeList& rCodeList = m_aCompiler.m_aCodeList; + // Zaehlen, wieviele Kriterien + // wenn nur ein Kriterium, und das entsprechende Feld ist indiziert + // dann wird der Index verwendet + + OEvaluateSetList aEvaluateSetList; + OEvaluateSet* pEvaluateSet = NULL; + ::std::vector<sal_Int32>* pKeySet = NULL; + + for (OCodeList::iterator aIter = rCodeList.begin(); aIter != rCodeList.end(); ++aIter) + { + OOperandAttr* pAttr = PTR_CAST(OOperandAttr,(*aIter)); + if (pAttr) + { + if (pAttr->isIndexed() && !m_aCompiler.hasORCondition()) + { + OCode* pCode1 = *(aIter + 1); + OCode* pCode2 = *(aIter + 2); + + if (PTR_CAST(OOperand,pCode1)) + pEvaluateSet = pAttr->preProcess(PTR_CAST(OBoolOperator,pCode2), PTR_CAST(OOperand,pCode1)); + else + pEvaluateSet = pAttr->preProcess(PTR_CAST(OBoolOperator,pCode1)); + } + + if (pEvaluateSet) + { + aEvaluateSetList.push_back(pEvaluateSet); + pEvaluateSet = NULL; + } + else + pAttr->bindValue(_pRow); + } + } + + // Keyset erzeugen mit kleinster Liste + if(aEvaluateSetList.size()) + { + // welche Liste hat den kleinsten count ? + OEvaluateSetList::iterator i = aEvaluateSetList.begin(); + pEvaluateSet = *(i); + for(++i; i != aEvaluateSetList.end();++i) + { + OEvaluateSet* pEvaluateSetComp = (*i); + for(OEvaluateSet::reverse_iterator j = pEvaluateSet->rbegin(); j != pEvaluateSet->rend(); ++j) + { + if (pEvaluateSetComp->find(j->second) != pEvaluateSetComp->end()) + pEvaluateSet->erase(j->second); + } + } + pKeySet = new ::std::vector<sal_Int32>(pEvaluateSet->size()); + sal_Int32 k=0; + for(OEvaluateSet::iterator j = pEvaluateSet->begin(); j != pEvaluateSet->end(); ++j,++k) + { + (*pKeySet)[k] = j->second; + } + + // alle loeschen + for(i = aEvaluateSetList.begin(); i != aEvaluateSetList.end();++i) + delete (*i); + } + + return pKeySet; +} + +//------------------------------------------------------------------ +void OSQLAnalyzer::bindParameterRow(OValueRow _pRow) +{ + OCodeList& rCodeList = m_aCompiler.m_aCodeList; + for(OCodeList::iterator aIter = rCodeList.begin(); aIter != rCodeList.end();++aIter) + { + OOperandParam* pParam = PTR_CAST(OOperandParam,(*aIter)); + if (pParam) + pParam->bindValue(_pRow); + } +} + + +//------------------------------------------------------------------ +void OSQLAnalyzer::describeParam(::vos::ORef<OSQLColumns> rParameterColumns) +{ + OCodeList& rCodeList = m_aCompiler.m_aCodeList; + OCodeStack aCodeStack; + + if (!rCodeList.size()) + return; // kein Prdikat + if (!rParameterColumns->size()) + return; // keine Parameter + + // Anlegen von Columns, die eine genauere Beschreibung fr die enthalten + ::vos::ORef<OSQLColumns> aNewParamColumns = new OSQLColumns(*rParameterColumns); + + // Anlegen einer Testzeile, wird bentigt um die Parameter zu beschreiben + OValueRow aTestRow = new OValueVector(Reference< XIndexAccess>(m_aCompiler.getOrigColumns(),UNO_QUERY)->getCount()); + bindResultRow(aTestRow); // Binden der Attribute an die Values + + OValueRow aParameterRow = new OValueVector(rParameterColumns->size()); + bindParameterRow(aParameterRow); + + for(OCodeList::iterator aIter = rCodeList.begin(); aIter != rCodeList.end(); ++aIter) + { + OOperand* pOperand = PTR_CAST(OOperand,(*aIter)); + OOperator* pOperator = PTR_CAST(OOperator,(*aIter)); + if (pOperand) + aCodeStack.push(pOperand); + else + { + if (pOperator->getRequestedOperands() == 2) // bei zwei Operatoren ist es mglich + { // einen Parameter weiter zu spezifizieren + OOperandParam *pParam = PTR_CAST(OOperandParam,aCodeStack.top()); + if (pParam) // Anpassen des ParameterTyps, wenn der linke Operand ein Attribut ist + { + OOperandAttr *pLeft = PTR_CAST(OOperandAttr,*(rCodeList.end() - 2)); + if (pLeft) + { + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet> xCol; + Reference< XIndexAccess>(m_aCompiler.getOrigColumns(),UNO_QUERY)->getByIndex(pLeft->getRowPos()) >>= xCol; + OSL_ENSHURE(xCol.is(), "Ungltige Struktur"); + pParam->describe(xCol, aNewParamColumns); + } + } + } + pOperator->Exec(aCodeStack); + } + } + OOperand* pOperand = aCodeStack.top(); + aCodeStack.pop(); + + OSL_ENSHURE(aCodeStack.size() == 0, "StackFehler"); + OSL_ENSHURE(pOperand, "StackFehler"); + if (IS_TYPE(OOperandResult,pOperand)) + delete pOperand; + + rParameterColumns = aNewParamColumns; + m_aCompiler.setParameterColumns(rParameterColumns); +} + +//------------------------------------------------------------------ +void OSQLAnalyzer::clean() +{ + m_aCompiler.Clean(); +} + + diff --git a/connectivity/source/drivers/file/fcode.cxx b/connectivity/source/drivers/file/fcode.cxx new file mode 100644 index 000000000000..26c5e6194886 --- /dev/null +++ b/connectivity/source/drivers/file/fcode.cxx @@ -0,0 +1,461 @@ +/************************************************************************* + * + * $RCSfile: fcode.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: fs $ $Date: 2000-10-05 08:39:21 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc.. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CONNECTIVITY_FILE_FCODE_HXX_ +#include "file/fcode.hxx" +#endif +#ifndef _OSL_DIAGNOSE_H_ +#include <osl/diagnose.h> +#endif +#ifndef _CONNECTIVITY_SQLPARSE_HXX +#include "connectivity/sqlparse.hxx" +#endif +#ifndef _TOOLS_INTN_HXX +#include <tools/intn.hxx> +#endif +#ifndef _ISOLANG_HXX +#include <tools/isolang.hxx> +#endif +#ifndef _SV_SVAPP_HXX +#include <vcl/svapp.hxx> +#endif +#ifndef _RTL_CHAR_H_ +#include <rtl/char.h> +#endif +#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_ +#include <com/sun/star/container/XIndexAccess.hpp> +#endif + +using namespace connectivity; +using namespace connectivity::file; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::beans; + +TYPEINIT0(OCode); +TYPEINIT1(OOperand, OCode); +TYPEINIT1(OOperandRow, OOperand); +TYPEINIT1(OOperandAttr, OOperandRow); +TYPEINIT1(OFILEOperandAttr, OOperandAttr); +TYPEINIT1(OOperandParam, OOperandRow); +TYPEINIT1(OOperandValue, OOperand); +TYPEINIT1(OOperandConst, OOperandValue); +TYPEINIT1(OOperandResult, OOperandValue); + +TYPEINIT1(OOperator, OCode); +TYPEINIT1(OBoolOperator,OOperator); +TYPEINIT1(OOp_AND, OBoolOperator); +TYPEINIT1(OOp_OR, OBoolOperator); +TYPEINIT1(OOp_ISNULL, OBoolOperator); +TYPEINIT1(OOp_ISNOTNULL, OOp_ISNULL); +TYPEINIT1(OOp_LIKE, OBoolOperator); +TYPEINIT1(OOp_NOTLIKE, OOp_LIKE); +TYPEINIT1(OOp_COMPARE, OBoolOperator); +TYPEINIT1(ONumOperator, OOperator); + +//------------------------------------------------------------------ +sal_Int32 compareIgnoreCase(const rtl::OUString& rStr1, const rtl::OUString& rStr2, const ::rtl::OLocale& rLocale) +{ + rtl::OUString aString1 = rStr1.toUpperCase(rLocale); + rtl::OUString aString2 = rStr2.toUpperCase(rLocale); + return aString1.compareTo(aString2); +} +//------------------------------------------------------------------ +OCode::~OCode(){} + +//------------------------------------------------------------------ +OEvaluateSet* OOperand::preProcess(OBoolOperator* pOp, OOperand* pRight) +{ + return NULL; +} + +//------------------------------------------------------------------ +void OOperandRow::bindValue(OValueRow _pRow) +{ + OSL_ENSHURE(_pRow.isValid(),"NO EMPTY row allowed!"); + m_pRow = _pRow; +} + +//------------------------------------------------------------------ +Any OOperandRow::getValue() const +{ + OSL_ENSHURE(m_pRow.isValid() && m_nRowPos < m_pRow->size(),"Invalid RowPos is >= vector.size()"); + return (*m_pRow)[m_nRowPos]; +} +//------------------------------------------------------------------ +OOperandAttr::OOperandAttr(sal_uInt16 _nPos,const Reference< XFastPropertySet>& _xColumn) + : OOperandRow(_nPos,getINT32(_xColumn->getFastPropertyValue(PROPERTY_ID_TYPE))) + , m_xColumn(_xColumn) +{ +} +//------------------------------------------------------------------ +OFILEOperandAttr::OFILEOperandAttr(sal_uInt16 _nPos,const Reference< XFastPropertySet>& _xColumn) + :OOperandAttr(_nPos,_xColumn) +{ +} + +//------------------------------------------------------------------ +OEvaluateSet* OFILEOperandAttr::preProcess(OBoolOperator* pOp, OOperand* pRight) +{ + OEvaluateSet* pEvaluateSet = NULL; + if (isIndexed()) + { + OSL_ENSHURE(0,"TODO: OFILEOperandAttr::preProcess"); +// OFILEIndexIterator* pIter = pCol->GetIndex()->CreateIterator(pOp,pRight); +// +// if (pIter->Status().IsSuccessful()) +// { +// pEvaluateSet = new OEvaluateSet(); +// ULONG nRec = pIter->First(); +// while (nRec != SQL_INDEX_ENTRY_NOTFOUND) +// { +// pEvaluateSet->Insert(nRec); +// nRec = pIter->Next(); +// } +// } +// delete pIter; + } + return pEvaluateSet; +} + +//------------------------------------------------------------------ +OOperandParam::OOperandParam(OSQLParseNode* pNode, ::vos::ORef<connectivity::OSQLColumns> _xParamColumns) + : OOperandRow(_xParamColumns->size(), DataType::VARCHAR) // Standard-Typ +{ + OSL_ENSHURE(SQL_ISRULE(pNode,parameter),"Argument ist kein Parameter"); + OSL_ENSHURE(pNode->count() > 0,"Fehler im Parse Tree"); + OSQLParseNode *pMark = pNode->getChild(0); + + String aParameterName; + if (SQL_ISPUNCTUATION(pMark,"?")) + aParameterName = '?'; + else if (SQL_ISPUNCTUATION(pMark,":")) + aParameterName = pNode->getChild(1)->getTokenValue(); + else + { + OSL_ASSERT("Fehler im Parse Tree"); + } + + // Parameter-Column aufsetzen mit defult typ, kann zu einem spteren Zeitpunkt ber DescribeParameter + // genauer spezifiziert werden + + // Identitaet merken (hier eigentlich nicht erforderlich, aber aus + // Symmetriegruenden ...) + + // todo + // OColumn* pColumn = new OFILEColumn(aParameterName,eDBType,255,0,SQL_FLAGS_NULLALLOWED); + // rParamColumns->AddColumn(pColumn); + + // der Wert wird erst kurz vor der Auswertung gesetzt +} + + +//------------------------------------------------------------------ +void OOperandParam::describe(const Reference< XFastPropertySet>& rColumn, ::vos::ORef<connectivity::OSQLColumns> rParameterColumns) +{ + // den alten namen beibehalten + + Reference< XFastPropertySet> xColumn = (*rParameterColumns)[getRowPos()]; + + xColumn->setFastPropertyValue(PROPERTY_ID_TYPENAME,rColumn->getFastPropertyValue(PROPERTY_ID_TYPENAME)); + xColumn->setFastPropertyValue(PROPERTY_ID_DEFAULTVALUE,rColumn->getFastPropertyValue(PROPERTY_ID_DEFAULTVALUE)); + xColumn->setFastPropertyValue(PROPERTY_ID_PRECISION,rColumn->getFastPropertyValue(PROPERTY_ID_PRECISION)); + xColumn->setFastPropertyValue(PROPERTY_ID_TYPE,rColumn->getFastPropertyValue(PROPERTY_ID_TYPE)); + xColumn->setFastPropertyValue(PROPERTY_ID_SCALE,rColumn->getFastPropertyValue(PROPERTY_ID_SCALE)); + xColumn->setFastPropertyValue(PROPERTY_ID_ISNULLABLE,rColumn->getFastPropertyValue(PROPERTY_ID_ISNULLABLE)); + xColumn->setFastPropertyValue(PROPERTY_ID_ISAUTOINCREMENT,rColumn->getFastPropertyValue(PROPERTY_ID_ISAUTOINCREMENT)); + + m_eDBType = getINT32(rColumn->getFastPropertyValue(PROPERTY_ID_TYPE)); +} + +//------------------------------------------------------------------ +Any OOperandValue::getValue() const +{ + return m_aValue; +} + +//------------------------------------------------------------------ +OOperandConst::OOperandConst(const OSQLParseNode& rColumnRef, const rtl::OUString& aStrValue) +{ + switch (rColumnRef.getNodeType()) + { + case SQL_NODE_STRING: + m_aValue <<= aStrValue; + m_eDBType = DataType::VARCHAR; + return; + case SQL_NODE_INTNUM: + case SQL_NODE_APPROXNUM: + { + m_aValue <<= aStrValue.toDouble(); + + m_eDBType = DataType::DOUBLE; + return; + } + } + + if (SQL_ISTOKEN(&rColumnRef,TRUE)) + { + m_aValue <<= 1.0; + m_eDBType = DataType::BIT; + } + else if (SQL_ISTOKEN(&rColumnRef,FALSE)) + { + m_aValue <<= 0.0; + m_eDBType = DataType::BIT; + } + else + { + OSL_ASSERT("Parse Error"); + } +} + +///////////////////////////////////////////////////////////////////////////////////////// +// Implementation of the operators + +//------------------------------------------------------------------ +sal_uInt16 OOperator::getRequestedOperands() const {return 2;} + +//------------------------------------------------------------------ +sal_Bool OBoolOperator::operate(const OOperand*, const OOperand*) const +{ + return sal_False; +} + + +//------------------------------------------------------------------ +void OBoolOperator::Exec(OCodeStack& rCodeStack) +{ + OOperand *pRight = rCodeStack.top(); + rCodeStack.pop(); + OOperand *pLeft = rCodeStack.top(); + rCodeStack.pop(); + + rCodeStack.push(new OOperandResultBOOL(operate(pLeft, pRight))); + if (IS_TYPE(OOperandResult,pLeft)) delete pLeft; + if (IS_TYPE(OOperandResult,pRight)) delete pRight; +} + +//------------------------------------------------------------------ +sal_Bool OOp_AND::operate(const OOperand* pLeft, const OOperand* pRight) const +{ + return pLeft->isValid() && pRight->isValid(); +} + +//------------------------------------------------------------------ +sal_Bool OOp_OR::operate(const OOperand* pLeft, const OOperand* pRight) const +{ + return pLeft->isValid() || pRight->isValid(); +} + +//------------------------------------------------------------------ +sal_uInt16 OOp_ISNULL::getRequestedOperands() const {return 1;} + +//------------------------------------------------------------------ +void OOp_ISNULL::Exec(OCodeStack& rCodeStack) +{ + OOperand* pOperand = rCodeStack.top(); + rCodeStack.pop(); + + rCodeStack.push(new OOperandResultBOOL(operate(pOperand))); + if (IS_TYPE(OOperandResult,pOperand)) delete pOperand; +} + +//------------------------------------------------------------------ +sal_Bool OOp_ISNULL::operate(const OOperand* pOperand, const OOperand*) const +{ + Any aRet(pOperand->getValue()); + return !aRet.hasValue() || !aRet.getValue(); +} + +//------------------------------------------------------------------ +sal_Bool OOp_ISNOTNULL::operate(const OOperand* pOperand, const OOperand*) const +{ + return !OOp_ISNULL::operate(pOperand); +} + +//------------------------------------------------------------------ +sal_Bool OOp_LIKE::operate(const OOperand* pLeft, const OOperand* pRight) const +{ + sal_Bool bMatch; + Any aLH(pLeft->getValue()); + Any aRH(pRight->getValue()); + + if (!aLH.hasValue() || !aRH.hasValue()) + bMatch = TRUE; + else if (!aLH.getValue()) + bMatch = sal_False; + else + { + bMatch = match(getString(aRH), getString(aLH), cEscape); + } + return bMatch; +} + +//------------------------------------------------------------------ +sal_Bool OOp_NOTLIKE::operate(const OOperand* pLeft, const OOperand* pRight) const +{ + return !OOp_LIKE::operate(pLeft, pRight); +} + +//------------------------------------------------------------------ +sal_Bool OOp_COMPARE::operate(const OOperand* pLeft, const OOperand* pRight) const +{ + Any aLH(pLeft->getValue()); + Any aRH(pRight->getValue()); + +// if (!aLH.hasValue() || !aRH.hasValue()) +// return TRUE; + + if (!aLH.hasValue() || !aRH.hasValue()) // if (!aLH.getValue() || !aRH.getValue()) + return sal_False; + + sal_Bool bResult = sal_False; + sal_Int32 eDBType = pLeft->getDBType(); + + // Vergleich (je nach Datentyp): + switch (eDBType) + { + case DataType::CHAR: + case DataType::VARCHAR: + { + static String sLanguage; + static String sCountry; + if (!sLanguage.Len()) + ConvertLanguageToIsoNames(Application::GetAppInternational().GetLanguage(), sLanguage, sCountry); + + static rtl::OLocale aLocale = rtl::OLocale::registerLocale(sLanguage, sCountry); + + INT32 nRes = compareIgnoreCase(getString(aLH), getString(aRH), aLocale); + switch(aPredicateType) + { + case SQL_PRED_EQUAL: bResult = (nRes == 0); break; + case SQL_PRED_NOTEQUAL: bResult = (nRes != 0); break; + case SQL_PRED_LESS: bResult = (nRes < 0); break; + case SQL_PRED_LESSOREQUAL: bResult = (nRes <= 0); break; + case SQL_PRED_GREATER: bResult = (nRes > 0); break; + case SQL_PRED_GREATEROREQUAL: bResult = (nRes >= 0); break; + default: bResult = sal_False; + } + } break; + case DataType::TINYINT: + case DataType::SMALLINT: + case DataType::INTEGER: + case DataType::DECIMAL: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::DOUBLE: + case DataType::BIT: + case DataType::TIMESTAMP: + case DataType::DATE: + case DataType::TIME: + { + double n,m; + aLH >>= n; + aRH >>= m; + + switch (aPredicateType) + { + case SQL_PRED_EQUAL: bResult = (n == m); break; + case SQL_PRED_LIKE: bResult = (n == m); break; + case SQL_PRED_NOTEQUAL: bResult = (n != m); break; + case SQL_PRED_NOTLIKE: bResult = (n != m); break; + case SQL_PRED_LESS: bResult = (n < m); break; + case SQL_PRED_LESSOREQUAL: bResult = (n <= m); break; + case SQL_PRED_GREATER: bResult = (n > m); break; + case SQL_PRED_GREATEROREQUAL: bResult = (n >= m); break; + default: bResult = sal_False; + } + } break; + default: + DBG_ERROR("OFILECursor::ExecuteRow: Vergleich mit diesem Datentyp nicht implementiert"); + bResult = sal_False; + } + return bResult; +} + +//------------------------------------------------------------------ +void ONumOperator::Exec(OCodeStack& rCodeStack) +{ + + OOperand *pRight = rCodeStack.top(); + rCodeStack.pop(); + OOperand *pLeft = rCodeStack.top(); + rCodeStack.pop(); + + rCodeStack.push(new OOperandResultNUM(operate(getDouble(pLeft->getValue()), getDouble(pRight->getValue())))); + if (IS_TYPE(OOperandResult,pLeft)) delete pLeft; + if (IS_TYPE(OOperandResult,pRight)) delete pRight; +} +//------------------------------------------------------------------ +double OOp_ADD::operate(double fLeft, double fRight) const {return fLeft + fRight;}; + +//------------------------------------------------------------------ +double OOp_SUB::operate(double fLeft, double fRight) const {return fLeft - fRight;}; + +//------------------------------------------------------------------ +double OOp_MUL::operate(double fLeft, double fRight) const {return fLeft * fRight;}; + +//------------------------------------------------------------------ +double OOp_DIV::operate(double fLeft, double fRight) const {return fLeft / fRight;}; + + + diff --git a/connectivity/source/drivers/file/fcomp.cxx b/connectivity/source/drivers/file/fcomp.cxx new file mode 100644 index 000000000000..4f8bd12bb0ce --- /dev/null +++ b/connectivity/source/drivers/file/fcomp.cxx @@ -0,0 +1,538 @@ +/************************************************************************* + * + * $RCSfile: fcomp.cxx,v $ + * + * $Revision: 1.1 $ + * + * last change: $Author: fs $ $Date: 2000-10-05 08:39:29 $ + * + * The Contents of this file are made available subject to the terms of + * either of the following licenses + * + * - GNU Lesser General Public License Version 2.1 + * - Sun Industry Standards Source License Version 1.1 + * + * Sun Microsystems Inc., October, 2000 + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2000 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library 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 for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * + * Sun Industry Standards Source License Version 1.1 + * ================================================= + * The contents of this file are subject to the Sun Industry Standards + * Source License Version 1.1 (the "License"); You may not use this file + * except in compliance with the License. You may obtain a copy of the + * License at http://www.openoffice.org/license.html. + * + * Software provided under this License is provided on an "AS IS" basis, + * WITHOUT WARRUNTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING, + * WITHOUT LIMITATION, WARRUNTIES THAT THE SOFTWARE IS FREE OF DEFECTS, + * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING. + * See the License for the specific provisions governing your rights and + * obligations concerning the Software. + * + * The Initial Developer of the Original Code is: Sun Microsystems, Inc.. + * + * Copyright: 2000 by Sun Microsystems, Inc. + * + * All Rights Reserved. + * + * Contributor(s): _______________________________________ + * + * + ************************************************************************/ + +#ifndef _CONNECTIVITY_FILE_FCOMP_HXX_ +#include "file/fcomp.hxx" +#endif +#ifndef _TOOLS_DEBUG_HXX +#include <tools/debug.hxx> +#endif +#ifndef _CONNECTIVITY_SQLPARSE_HXX +#include "connectivity/sqlparse.hxx" +#endif +#ifndef _CONNECTIVITY_FILE_FANALYZER_HXX_ +#include "file/fanalyzer.hxx" +#endif +#ifndef _COM_SUN_STAR_SDBC_XCOLUMNLOCATE_HPP_ +#include <com/sun/star/sdbc/XColumnLocate.hpp> +#endif + +using namespace connectivity; +using namespace connectivity::file; +using namespace com::sun::star::uno; +using namespace com::sun::star::sdbc; +using namespace ::com::sun::star::container; + +DBG_NAME(OPredicateCompiler); +//------------------------------------------------------------------ +OPredicateCompiler::OPredicateCompiler(OSQLAnalyzer* pAnalyzer)//,OCursor& rCurs) + // : m_rCursor(rCurs) + : m_pAnalyzer(pAnalyzer) + , m_bORCondition(FALSE) +{ + DBG_CTOR(OPredicateCompiler,NULL); +} + +//------------------------------------------------------------------ +OPredicateCompiler::~OPredicateCompiler() +{ + Clean(); + DBG_DTOR(OPredicateCompiler,NULL); +} + +//------------------------------------------------------------------ +// inline OCursor& OPredicateCompiler::Cursor() const {return m_rCursor;} +//------------------------------------------------------------------ +void OPredicateCompiler::Clean() +{ + for(OCodeList::reverse_iterator aIter = m_aCodeList.rbegin(); aIter != m_aCodeList.rend();++aIter) + { + delete *aIter; + m_aCodeList.pop_back(); + } + // m_aCodeList.clear(); +} + +//------------------------------------------------------------------ +void OPredicateCompiler::start(OSQLParseNode* pSQLParseNode) +{ + if (!pSQLParseNode) + return; + + // 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() == 5,"Fehler im Parse Tree"); + + pWhereClause = pTableExp->getChild(1); + pOrderbyClause = pTableExp->getChild(4); + } + 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,update_statement_positioned)) + { + // nyi + DBG_ERROR("OPredicateCompiler: update positioned nyi"); + } + else if (SQL_ISRULE(pSQLParseNode,delete_statement_searched)) + { + DBG_ASSERT(pSQLParseNode->count() == 4,"Fehler im Parse Tree"); + pWhereClause = pSQLParseNode->getChild(3); + } + else if (SQL_ISRULE(pSQLParseNode,delete_statement_positioned)) + { + // nyi + DBG_ERROR("OPredicateCompiler: positioned nyi"); + } + 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),"OFILECursor: 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("OFILECursor: Fehler im Parse Tree"); + } + } + 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,test_for_null)) + { + execute_ISNULL(pPredicateNode); + } + else + pOperand = execute_Operand(pPredicateNode); // jetzt werden nur einfache Operanden verarbeitet + + return pOperand; +} + +//------------------------------------------------------------------ +OOperand* OPredicateCompiler::execute_COMPARE(OSQLParseNode* pPredicateNode) +{ + 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_ISPUNCTUATION(pPredicateNode->getChild(2)->getChild(0),"{")))) + { + // m_rCursor.aStatus.SetStatementTooComplex(); + return NULL; + } + + OSQLPredicateType ePredicateType; + OSQLParseNode *pPrec = pPredicateNode->getChild(1); + + if (pPrec->getNodeType() == SQL_NODE_EQUAL) + ePredicateType = SQL_PRED_EQUAL; + else if (pPrec->getNodeType() == SQL_NODE_NOTEQUAL) + ePredicateType = SQL_PRED_NOTEQUAL; + else if (pPrec->getNodeType() == SQL_NODE_LESS) + ePredicateType = SQL_PRED_LESS; + else if (pPrec->getNodeType() == SQL_NODE_LESSEQ) + ePredicateType = SQL_PRED_LESSOREQUAL; + else if (pPrec->getNodeType() == SQL_NODE_GREATEQ) + ePredicateType = SQL_PRED_GREATEROREQUAL; + else if (pPrec->getNodeType() == SQL_NODE_GREAT) + ePredicateType = SQL_PRED_GREATER; + + OOperand* pOb = execute(pPredicateNode->getChild(0)); + OOperand* pOperand = execute(pPredicateNode->getChild(2)); + + OBoolOperator* pOperator = new OOp_COMPARE(ePredicateType); + //pOb->PreProcess(pOperator, pOperand); + + m_aCodeList.push_back(pOperator); + + // wenn es sich um eine Vergleichsoperation auf datum/Zeit handelt, dann + // erfolgt jetzt bereits eine Umwandlung fuer die Konstante + if (pOb) + { + switch (pPredicateNode->getChild(2)->getNodeType()) + { + case SQL_NODE_STRING: + { + OOperandConst* pConst = PTR_CAST(OOperandConst,m_aCodeList[m_aCodeList.size() - 2]); + switch (pOb->getDBType()) + { + case DataType::DECIMAL: + case DataType::NUMERIC: + case DataType::REAL: + case DataType::DOUBLE: + case DataType::TIMESTAMP: + case DataType::DATE: + case DataType::TIME: + { + try + { + ::rtl::OUString aVal; + pConst->getValue() >>= aVal; + pConst->setValue(makeAny(aVal.toDouble())); + } + catch( ... ) + { +// m_rCursor.aStatus.Set(SQL_STAT_ERROR, +// String::CreateFromAscii("S1C00"), +// m_rCursor.aStatus.CreateErrorMessage(String(OResId(STR_STAT_SQL_DATATYPE_MISMATCH))), +// 0, String() ); + } + } break; + case DataType::TINYINT: + case DataType::SMALLINT: + case DataType::INTEGER: + case DataType::BIT: + ; +// m_rCursor.aStatus.Set(SQL_STAT_ERROR, +// String::CreateFromAscii("S1C00"), +// m_rCursor.aStatus.CreateErrorMessage(String(OResId(STR_STAT_SQL_DATATYPE_MISMATCH))), +// 0, String() ); + } + } + } + } + return NULL; +} + +//------------------------------------------------------------------ +OOperand* OPredicateCompiler::execute_LIKE(OSQLParseNode* pPredicateNode) +{ + DBG_ASSERT(pPredicateNode->count() >= 4,"OFILECursor: Fehler im Parse Tree"); + + if (!SQL_ISRULE(pPredicateNode->getChild(0),column_ref)) + { + // m_rCursor.aStatus.SetInvalidStatement(); + return NULL; + } + + OSQLPredicateType ePredicateType; + OSQLParseNode *pAtom; + OSQLParseNode *pOptEscape; + sal_Unicode cEscape = L'\0'; + + if (SQL_ISTOKEN(pPredicateNode->getChild(1),NOT)) + ePredicateType = SQL_PRED_NOTLIKE; + else + ePredicateType = SQL_PRED_LIKE; + + pAtom = pPredicateNode->getChild(3); + pOptEscape = pPredicateNode->getChild(4); + + if (!(pAtom->getNodeType() == SQL_NODE_STRING || SQL_ISRULE(pAtom,parameter))) + { + // m_rCursor.aStatus.SetInvalidStatement(); + return NULL; + } + if (pOptEscape->count() != 0) + { + if (pOptEscape->count() != 2) + { + // m_rCursor.aStatus.SetInvalidStatement(); + return NULL; + } + OSQLParseNode *pEscNode = pOptEscape->getChild(1); + if (pEscNode->getNodeType() != SQL_NODE_STRING) + { + // m_rCursor.aStatus.SetInvalidStatement(); + return NULL; + } + else + cEscape = pEscNode->getTokenValue().GetChar(0); + } + + OOperand* pOb = execute(pPredicateNode->getChild(0)); + OOperand* pOperand = execute(pAtom); + OBoolOperator* pOperator = (ePredicateType == SQL_PRED_LIKE) + ? new OOp_LIKE(cEscape) + : new OOp_NOTLIKE(cEscape); + m_aCodeList.push_back(pOperator); + return NULL; +} + +//------------------------------------------------------------------ +OOperand* OPredicateCompiler::execute_ISNULL(OSQLParseNode* pPredicateNode) +{ + if (!SQL_ISRULE(pPredicateNode->getChild(0),column_ref)) + { + // m_rCursor.aStatus.SetInvalidStatement(); + return NULL; + } + + DBG_ASSERT(pPredicateNode->count() >= 3,"OFILECursor: Fehler im Parse Tree"); + DBG_ASSERT(SQL_ISTOKEN(pPredicateNode->getChild(1),IS),"OFILECursor: Fehler im Parse Tree") + + OSQLPredicateType ePredicateType; + if (SQL_ISTOKEN(pPredicateNode->getChild(2),NOT)) + ePredicateType = SQL_PRED_ISNOTNULL; + else + ePredicateType = SQL_PRED_ISNULL; + + OOperand* pOb = execute(pPredicateNode->getChild(0)); + OBoolOperator* pOperator = (ePredicateType == SQL_PRED_ISNULL) ? + new OOp_ISNULL() : new OOp_ISNOTNULL(); + + //pOb->PreProcess(pOperator); + + + m_aCodeList.push_back(pOperator); + return NULL; +} +//------------------------------------------------------------------ +OOperand* OPredicateCompiler::execute_Operand(OSQLParseNode* pPredicateNode) +{ + OOperand* pOperand = NULL; + + if (SQL_ISRULE(pPredicateNode,column_ref)) + { + String aColumnName; + if (pPredicateNode->count() == 1) + { + aColumnName = pPredicateNode->getChild(0)->getTokenValue(); + } + else if (pPredicateNode->count() == 3) + { + String aTableName = pPredicateNode->getChild(0)->getTokenValue(); + aColumnName = pPredicateNode->getChild(2)->getTokenValue(); + } + + ::com::sun::star::uno::Reference< ::com::sun::star::beans::XFastPropertySet> xCol; + try + { + if (m_orgColumns->getByName(aColumnName) >>= xCol) // Column existiert nicht im Resultset + pOperand = m_pAnalyzer->createOperandAttr(Reference< XColumnLocate>(m_orgColumns,UNO_QUERY)->findColumn(aColumnName),xCol); //new OOperandAttr(pCol); + else + { + // m_rCursor.aStatus.SetInvalidStatement(); + } + } + catch(...) + { + } + } + else if (SQL_ISRULE(pPredicateNode,parameter)) + { + pOperand = new OOperandParam(pPredicateNode, m_aParameterColumns); + } + 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 + String 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) )) + { + pOperand = new OOperandConst(*pODBCNode->getChild(1), pODBCNode->getChild(1)->getTokenValue()); + + // setting the Date + try + { + ::rtl::OUString aVal; + pOperand->getValue() >>= aVal; + pOperand->setValue(makeAny(aVal.toDouble())); + } + catch( ... ) + { +// m_rCursor.aStatus.Set(SQL_STAT_ERROR, +// String::CreateFromAscii("S1C00"), +// m_rCursor.aStatus.CreateErrorMessage(String(OResId(STR_STAT_SQL_DATATYPE_MISMATCH))), +// 0, String() ); + } + } + else + ; + // m_rCursor.aStatus.SetStatementTooComplex(); + } + else + { + // m_rCursor.aStatus.SetStatementTooComplex(); + } + if (pOperand) + m_aCodeList.push_back(pOperand); + return pOperand; +} + +//////////////////////////////////////////////////////////////////////////////////////// + +//------------------------------------------------------------------ +OPredicateInterpreter::~OPredicateInterpreter() +{ + while(!m_aStack.empty()) + { + delete m_aStack.top(); + m_aStack.pop(); + } + // m_aStack.clear(); +} + +//------------------------------------------------------------------ +sal_Bool OPredicateInterpreter::evaluate(OCodeList& rCodeList) +{ + static sal_Bool bResult; + + OCodeList::iterator aIter = rCodeList.begin(); + if (!(*aIter)) + return sal_True; // kein Prdikat + + 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; +} + |