update dev300-m58
[ooovba.git] / connectivity / source / drivers / file / fanalyzer.cxx
blob0755988258595492ffcf07d3fab138c4bc0d448b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fanalyzer.cxx,v $
10 * $Revision: 1.26.56.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_connectivity.hxx"
33 #include "file/fanalyzer.hxx"
34 #include "connectivity/sqlparse.hxx"
35 #include <osl/diagnose.h>
36 #include <tools/debug.hxx>
37 #include <comphelper/extract.hxx>
38 #include "connectivity/sqlnode.hxx"
39 #include "connectivity/dbexception.hxx"
40 #include "file/FConnection.hxx"
41 #include "resource/file_res.hrc"
43 using namespace ::connectivity;
44 using namespace ::connectivity::file;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::beans;
47 using namespace ::com::sun::star::sdbc;
48 using namespace ::com::sun::star::container;
50 DBG_NAME( file_OSQLAnalyzer )
51 //------------------------------------------------------------------
52 OSQLAnalyzer::OSQLAnalyzer(OConnection* _pConnection)
53 :m_pConnection(_pConnection)
54 ,m_bHasSelectionCode(sal_False)
55 ,m_bSelectionFirstTime(sal_True)
57 DBG_CTOR( file_OSQLAnalyzer, NULL );
58 m_aCompiler = new OPredicateCompiler(this);
59 m_aInterpreter = new OPredicateInterpreter(m_aCompiler);
62 // -----------------------------------------------------------------------------
63 OSQLAnalyzer::~OSQLAnalyzer()
65 DBG_DTOR( file_OSQLAnalyzer, NULL );
68 // -----------------------------------------------------------------------------
69 void OSQLAnalyzer::setIndexes(const Reference< XNameAccess>& _xIndexes)
71 m_aCompiler->m_xIndexes = _xIndexes;
73 //------------------------------------------------------------------
74 void OSQLAnalyzer::start(OSQLParseNode* pSQLParseNode)
76 if (SQL_ISRULE(pSQLParseNode,select_statement))
78 DBG_ASSERT(pSQLParseNode->count() >= 4,"OFILECursor: Fehler im Parse Tree");
80 // check that we don't use anything other than count(*) as function
81 OSQLParseNode* pSelection = pSQLParseNode->getChild(2);
82 if ( SQL_ISRULE(pSelection,scalar_exp_commalist) )
84 for (sal_uInt32 i = 0; i < pSelection->count(); i++)
86 OSQLParseNode *pColumnRef = pSelection->getChild(i)->getChild(0);
87 if ( ( SQL_ISRULE(pColumnRef,set_fct_spec) && pColumnRef->count() == 4 )
88 || SQL_ISRULE(pColumnRef,char_value_fct)
89 || SQL_ISRULE(pColumnRef,char_substring_fct)
90 || SQL_ISRULE(pColumnRef,position_exp)
91 || SQL_ISRULE(pColumnRef,fold)
92 || SQL_ISRULE(pColumnRef,length_exp)
93 || SQL_ISRULE(pColumnRef,num_value_exp)
94 || SQL_ISRULE(pColumnRef,term)
95 || SQL_ISRULE(pColumnRef,factor)
96 || SQL_ISRULE(pColumnRef,set_fct_spec) )
98 ::vos::ORef<OPredicateCompiler> pCompiler = new OPredicateCompiler(this);
99 pCompiler->setOrigColumns(m_aCompiler->getOrigColumns());
100 ::vos::ORef<OPredicateInterpreter> pInterpreter = new OPredicateInterpreter(pCompiler);
101 pCompiler->execute( pColumnRef );
102 m_aSelectionEvaluations.push_back( TPredicates(pCompiler,pInterpreter) );
104 else if ( ( SQL_ISRULE(pColumnRef,general_set_fct) && pColumnRef->count() != 4 ) )
106 m_pConnection->throwGenericSQLException(STR_QUERY_COMPLEX_COUNT,NULL);
108 else
109 m_aSelectionEvaluations.push_back( TPredicates() );
114 m_aCompiler->start(pSQLParseNode);
117 //------------------------------------------------------------------
118 void OSQLAnalyzer::bindRow(OCodeList& rCodeList,const OValueRefRow& _pRow,OEvaluateSetList& _rEvaluateSetList)
120 // Zaehlen, wieviele Kriterien
121 // wenn nur ein Kriterium, und das entsprechende Feld ist indiziert
122 // dann wird der Index verwendet
124 OEvaluateSet* pEvaluateSet = NULL;
126 for (OCodeList::iterator aIter = rCodeList.begin(); aIter != rCodeList.end(); ++aIter)
128 OOperandAttr* pAttr = PTR_CAST(OOperandAttr,(*aIter));
129 if (pAttr)
131 if (pAttr->isIndexed() && !m_aCompiler->hasORCondition())
133 OCode* pCode1 = *(aIter + 1);
134 OCode* pCode2 = *(aIter + 2);
136 if (PTR_CAST(OOperand,pCode1))
137 pEvaluateSet = pAttr->preProcess(PTR_CAST(OBoolOperator,pCode2), PTR_CAST(OOperand,pCode1));
138 else
139 pEvaluateSet = pAttr->preProcess(PTR_CAST(OBoolOperator,pCode1));
142 if (pEvaluateSet)
144 _rEvaluateSetList.push_back(pEvaluateSet);
145 pEvaluateSet = NULL;
147 pAttr->bindValue(_pRow);
151 //------------------------------------------------------------------
152 void OSQLAnalyzer::bindSelectRow(const OValueRefRow& _pRow)
154 // first the select part
155 OEvaluateSetList aEvaluateSetList;
156 for ( ::std::vector< TPredicates >::iterator aIter = m_aSelectionEvaluations.begin(); aIter != m_aSelectionEvaluations.end();++aIter)
158 if ( aIter->first.isValid() )
159 bindRow( aIter->first->m_aCodeList,_pRow,aEvaluateSetList);
162 //------------------------------------------------------------------
163 ::std::vector<sal_Int32>* OSQLAnalyzer::bindEvaluationRow(OValueRefRow& _pRow)
165 OEvaluateSetList aEvaluateSetList;
166 bindRow( m_aCompiler->m_aCodeList,_pRow,aEvaluateSetList);
168 ::std::vector<sal_Int32>* pKeySet = NULL;
169 OEvaluateSet* pEvaluateSet = NULL;
171 // Keyset erzeugen mit kleinster Liste
172 if(!aEvaluateSetList.empty())
174 // welche Liste hat den kleinsten count ?
175 OEvaluateSetList::iterator i = aEvaluateSetList.begin();
176 pEvaluateSet = *(i);
177 for(++i; i != aEvaluateSetList.end();++i)
179 OEvaluateSet* pEvaluateSetComp = (*i);
180 for(OEvaluateSet::reverse_iterator j = pEvaluateSet->rbegin(); j != pEvaluateSet->rend(); ++j)
182 if (pEvaluateSetComp->find(j->second) != pEvaluateSetComp->end())
183 pEvaluateSet->erase(j->second);
186 pKeySet = new ::std::vector<sal_Int32>(pEvaluateSet->size());
187 sal_Int32 k=0;
188 for(OEvaluateSet::iterator j = pEvaluateSet->begin(); j != pEvaluateSet->end(); ++j,++k)
190 (*pKeySet)[k] = j->second;
193 // alle loeschen
194 for(i = aEvaluateSetList.begin(); i != aEvaluateSetList.end();++i)
195 delete (*i);
198 return pKeySet;
201 //------------------------------------------------------------------
202 void OSQLAnalyzer::describeParam(::vos::ORef<OSQLColumns> rParameterColumns)
204 OCodeList& rCodeList = m_aCompiler->m_aCodeList;
205 OCodeStack aCodeStack;
207 if (!rCodeList.size())
208 return; // kein Praedikat
209 if (!rParameterColumns->get().size())
210 return; // keine Parameter
212 // Anlegen von Columns, die eine genauere Beschreibung fuer die enthalten
213 ::vos::ORef<OSQLColumns> aNewParamColumns = new OSQLColumns(*rParameterColumns);
216 // Anlegen einer Testzeile, wird benoetigt um die Parameter zu beschreiben
217 OValueRefRow aParameterRow = new OValueRefVector(rParameterColumns->get().size());
218 bindParameterRow(aParameterRow);
220 OValueRefRow aTestRow = new OValueRefVector(Reference< XIndexAccess>(m_aCompiler->getOrigColumns(),UNO_QUERY)->getCount());
221 delete bindEvaluationRow(aTestRow); // Binden der Attribute an die Values
223 for(OCodeList::iterator aIter = rCodeList.begin(); aIter != rCodeList.end(); ++aIter)
225 OOperand* pOperand = PTR_CAST(OOperand,(*aIter));
226 OOperator* pOperator = PTR_CAST(OOperator,(*aIter));
227 if (pOperand)
228 aCodeStack.push(pOperand);
229 else
231 if (pOperator->getRequestedOperands() == 2) // bei zwei Operatoren ist es moeglich
232 { // einen Parameter weiter zu spezifizieren
233 OOperandParam *pParam = PTR_CAST(OOperandParam,aCodeStack.top());
234 if (pParam) // Anpassen des ParameterTyps, wenn der linke Operand ein Attribut ist
236 OOperandAttr *pLeft = PTR_CAST(OOperandAttr,*(rCodeList.end() - 2));
237 if (pLeft)
239 Reference< XPropertySet> xCol;
240 Reference< XIndexAccess>(m_aCompiler->getOrigColumns(),UNO_QUERY)->getByIndex(pLeft->getRowPos()) >>= xCol;
241 OSL_ENSURE(xCol.is(), "Ungueltige Struktur");
242 pParam->describe(xCol, aNewParamColumns);
246 pOperator->Exec(aCodeStack);
249 OOperand* pOperand = aCodeStack.top();
250 aCodeStack.pop();
252 OSL_ENSURE(aCodeStack.size() == 0, "StackFehler");
253 OSL_ENSURE(pOperand, "StackFehler");
254 if (IS_TYPE(OOperandResult,pOperand))
255 delete pOperand;
256 else
257 OSL_ENSURE(0,"Illegal here!");
259 rParameterColumns = aNewParamColumns;
260 // m_aCompiler->setParameterColumns(rParameterColumns);
263 // -----------------------------------------------------------------------------
264 OOperandAttr* OSQLAnalyzer::createOperandAttr(sal_Int32 _nPos,
265 const Reference< XPropertySet>& _xCol,
266 const Reference< XNameAccess>& /*_xIndexes*/)
268 return new OOperandAttr(static_cast<sal_uInt16>(_nPos),_xCol);
270 // -----------------------------------------------------------------------------
271 BOOL OSQLAnalyzer::hasRestriction() const
273 return m_aCompiler->hasCode();
275 // -----------------------------------------------------------------------------
276 BOOL OSQLAnalyzer::hasFunctions() const
278 if ( m_bSelectionFirstTime )
280 m_bSelectionFirstTime = sal_False;
281 for ( ::std::vector< TPredicates >::const_iterator aIter = m_aSelectionEvaluations.begin(); aIter != m_aSelectionEvaluations.end() && !m_bHasSelectionCode ;++aIter)
283 if ( aIter->first.isValid() )
284 m_bHasSelectionCode = aIter->first->hasCode();
287 return m_bHasSelectionCode;;
289 // -----------------------------------------------------------------------------
290 void OSQLAnalyzer::setSelectionEvaluationResult(OValueRefRow& _pRow,const ::std::vector<sal_Int32>& _rColumnMapping)
292 sal_Int32 nPos = 1;
293 for ( ::std::vector< TPredicates >::iterator aIter = m_aSelectionEvaluations.begin(); aIter != m_aSelectionEvaluations.end();++aIter,++nPos)
295 if ( aIter->second.isValid() )
297 sal_Int32 map = nPos;
298 // the first column (index 0) is for convenience only. The first real select column is no 1.
299 if ( (nPos > 0) && (nPos < static_cast<sal_Int32>(_rColumnMapping.size())) )
300 map = _rColumnMapping[nPos];
301 aIter->second->startSelection((_pRow->get())[map]);
305 // -----------------------------------------------------------------------------
306 void OSQLAnalyzer::dispose()
308 m_aCompiler->dispose();
309 for ( ::std::vector< TPredicates >::iterator aIter = m_aSelectionEvaluations.begin(); aIter != m_aSelectionEvaluations.end();++aIter)
311 if ( aIter->first.isValid() )
312 aIter->first->dispose();
315 // -----------------------------------------------------------------------------
316 void OSQLAnalyzer::setOrigColumns(const OFileColumns& rCols)
318 m_aCompiler->setOrigColumns(rCols);
319 for ( ::std::vector< TPredicates >::iterator aIter = m_aSelectionEvaluations.begin(); aIter != m_aSelectionEvaluations.end();++aIter)
321 if ( aIter->first.isValid() )
322 aIter->first->setOrigColumns(rCols);
325 // -----------------------------------------------------------------------------