summaryrefslogtreecommitdiff
path: root/connectivity
diff options
context:
space:
mode:
authorFrank Schönheit <fs@openoffice.org>2000-10-05 07:39:29 +0000
committerFrank Schönheit <fs@openoffice.org>2000-10-05 07:39:29 +0000
commit8b1efd34bf563a1a8de9d7e78e52cdab8086cb38 (patch)
tree671f703fcaa1801676111a1256aa8d8bc4f23f81 /connectivity
parent59a91e9ebffef91bb1570846cba98ef4ca8e181e (diff)
moved from ..\..\parse
Diffstat (limited to 'connectivity')
-rw-r--r--connectivity/source/drivers/file/fanalyzer.cxx298
-rw-r--r--connectivity/source/drivers/file/fcode.cxx461
-rw-r--r--connectivity/source/drivers/file/fcomp.cxx538
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;
+}
+