build fix
[LibreOffice.git] / connectivity / source / drivers / file / fcode.cxx
blob1a496de1647918fcec84d54f5a431da645650811
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "file/fcode.hxx"
21 #include <osl/diagnose.h>
22 #include <connectivity/sqlparse.hxx>
23 #include "sqlbison.hxx"
24 #include <i18nlangtag/mslangid.hxx>
25 #include "TConnection.hxx"
26 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
27 #include <comphelper/types.hxx>
29 using namespace ::comphelper;
30 using namespace connectivity;
31 using namespace connectivity::file;
32 using namespace ::com::sun::star::sdbc;
33 using namespace ::com::sun::star::sdb;
35 OCode::~OCode() = default;
37 OOperandRow::OOperandRow(sal_uInt16 _nPos, sal_Int32 _rType)
38 : OOperand(_rType)
39 , m_nRowPos(_nPos)
42 void OOperandRow::bindValue(const OValueRefRow& _pRow)
44 OSL_ENSURE(_pRow.is(),"NO EMPTY row allowed!");
45 m_pRow = _pRow;
46 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
47 (m_pRow->get())[m_nRowPos]->setBound(true);
50 void OOperandRow::setValue(const ORowSetValue& _rVal)
52 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
53 (*(m_pRow->get())[m_nRowPos]) = _rVal;
56 const ORowSetValue& OOperandRow::getValue() const
58 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->get().size(),"Invalid RowPos is >= vector.size()");
59 return (m_pRow->get())[m_nRowPos]->getValue();
63 void OOperandValue::setValue(const ORowSetValue& _rVal)
65 m_aValue = _rVal;
68 OOperandParam::OOperandParam(OSQLParseNode* pNode, sal_Int32 _nPos)
69 : OOperandRow(static_cast<sal_uInt16>(_nPos), DataType::VARCHAR) // Standard-Type
71 OSL_ENSURE(SQL_ISRULE(pNode,parameter),"Argument ist kein Parameter");
72 OSL_ENSURE(pNode->count() > 0,"Fehler im Parse Tree");
73 OSQLParseNode *pMark = pNode->getChild(0);
75 OUString aParameterName;
76 if (SQL_ISPUNCTUATION(pMark, "?"))
77 aParameterName = "?";
78 else if (SQL_ISPUNCTUATION(pMark, ":"))
79 aParameterName = pNode->getChild(1)->getTokenValue();
80 else
82 SAL_WARN( "connectivity.drivers","Fehler im Parse Tree");
85 // set up Parameter-Column with default type, can be specified more precisely later using Describe-Parameter
87 // save Identity (not escpecially necessary here, just for the sake of symmetry)
89 // todo
90 // OColumn* pColumn = new OFILEColumn(aParameterName,eDBType,255,0,SQL_FLAGS_NULLALLOWED);
91 // rParamColumns->AddColumn(pColumn);
93 // the value will be set just before the evaluation
97 const ORowSetValue& OOperandValue::getValue() const
99 return m_aValue;
103 OOperandConst::OOperandConst(const OSQLParseNode& rColumnRef, const OUString& aStrValue)
105 switch (rColumnRef.getNodeType())
107 case SQLNodeType::String:
108 m_aValue = aStrValue;
109 m_eDBType = DataType::VARCHAR;
110 m_aValue.setBound(true);
111 return;
112 case SQLNodeType::IntNum:
113 case SQLNodeType::ApproxNum:
114 m_aValue = aStrValue.toDouble();
115 m_eDBType = DataType::DOUBLE;
116 m_aValue.setBound(true);
117 return;
118 default:
119 break;
122 if (SQL_ISTOKEN(&rColumnRef, TRUE))
124 m_aValue = 1.0;
125 m_eDBType = DataType::BIT;
127 else if (SQL_ISTOKEN(&rColumnRef, FALSE))
129 m_aValue = 0.0;
130 m_eDBType = DataType::BIT;
132 else
134 SAL_WARN( "connectivity.drivers", "Parse Error");
136 m_aValue.setBound(true);
140 // Implementation of the operators
143 bool OBoolOperator::operate(const OOperand*, const OOperand*) const
145 return false;
149 void OBoolOperator::Exec(OCodeStack& rCodeStack)
151 OOperand *pRight = rCodeStack.top();
152 rCodeStack.pop();
153 OOperand *pLeft = rCodeStack.top();
154 rCodeStack.pop();
156 rCodeStack.push(new OOperandResultBOOL(operate(pLeft, pRight)));
157 if( typeid(OOperandResult) == typeid(*pLeft))
158 delete pLeft;
159 if( typeid(OOperandResult) == typeid(*pRight))
160 delete pRight;
163 bool OOp_NOT::operate(const OOperand* pLeft, const OOperand* ) const
165 return !pLeft->isValid();
168 void OOp_NOT::Exec(OCodeStack& rCodeStack)
170 OOperand* pOperand = rCodeStack.top();
171 rCodeStack.pop();
173 rCodeStack.push(new OOperandResultBOOL(operate(pOperand, nullptr)));
175 if( typeid(OOperandResult) == typeid(*pOperand))
176 delete pOperand;
179 bool OOp_AND::operate(const OOperand* pLeft, const OOperand* pRight) const
181 return pLeft->isValid() && pRight->isValid();
185 bool OOp_OR::operate(const OOperand* pLeft, const OOperand* pRight) const
187 return pLeft->isValid() || pRight->isValid();
191 void OOp_ISNULL::Exec(OCodeStack& rCodeStack)
193 OOperand* pOperand = rCodeStack.top();
194 rCodeStack.pop();
196 rCodeStack.push(new OOperandResultBOOL(operate(pOperand, nullptr)));
197 if( typeid(OOperandResult) == typeid(*pOperand))
198 delete pOperand;
202 bool OOp_ISNULL::operate(const OOperand* pOperand, const OOperand*) const
204 return pOperand->getValue().isNull();
208 bool OOp_ISNOTNULL::operate(const OOperand* pOperand, const OOperand*) const
210 return !OOp_ISNULL::operate(pOperand, nullptr);
214 bool OOp_LIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
216 bool bMatch;
217 ORowSetValue aLH(pLeft->getValue());
218 ORowSetValue aRH(pRight->getValue());
220 if (aLH.isNull() || aRH.isNull())
221 bMatch = false;
222 else
224 bMatch = match(aRH.getString(), aLH.getString(), cEscape);
226 return bMatch;
230 bool OOp_NOTLIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
232 return !OOp_LIKE::operate(pLeft, pRight);
236 bool OOp_COMPARE::operate(const OOperand* pLeft, const OOperand* pRight) const
238 ORowSetValue aLH(pLeft->getValue());
239 ORowSetValue aRH(pRight->getValue());
241 if (aLH.isNull() || aRH.isNull()) // if (!aLH.getValue() || !aRH.getValue())
242 return false;
244 bool bResult = false;
245 sal_Int32 eDBType = pLeft->getDBType();
247 // Comparison (depending on Data-type):
248 switch (eDBType)
250 case DataType::CHAR:
251 case DataType::VARCHAR:
252 case DataType::LONGVARCHAR:
254 OUString sLH = aLH, sRH = aRH;
255 sal_Int32 nRes = sLH.compareToIgnoreAsciiCase(sRH);
256 switch(aPredicateType)
258 case SQLFilterOperator::EQUAL: bResult = (nRes == 0); break;
259 case SQLFilterOperator::NOT_EQUAL: bResult = (nRes != 0); break;
260 case SQLFilterOperator::LESS: bResult = (nRes < 0); break;
261 case SQLFilterOperator::LESS_EQUAL: bResult = (nRes <= 0); break;
262 case SQLFilterOperator::GREATER: bResult = (nRes > 0); break;
263 case SQLFilterOperator::GREATER_EQUAL: bResult = (nRes >= 0); break;
264 default: bResult = false;
266 } break;
267 case DataType::TINYINT:
268 case DataType::SMALLINT:
269 case DataType::INTEGER:
270 case DataType::DECIMAL:
271 case DataType::NUMERIC:
272 case DataType::REAL:
273 case DataType::DOUBLE:
274 case DataType::BIT:
275 case DataType::TIMESTAMP:
276 case DataType::DATE:
277 case DataType::TIME:
279 double n = aLH ,m = aRH;
281 switch (aPredicateType)
283 case SQLFilterOperator::EQUAL: bResult = (n == m); break;
284 case SQLFilterOperator::LIKE: bResult = (n == m); break;
285 case SQLFilterOperator::NOT_EQUAL: bResult = (n != m); break;
286 case SQLFilterOperator::NOT_LIKE: bResult = (n != m); break;
287 case SQLFilterOperator::LESS: bResult = (n < m); break;
288 case SQLFilterOperator::LESS_EQUAL: bResult = (n <= m); break;
289 case SQLFilterOperator::GREATER: bResult = (n > m); break;
290 case SQLFilterOperator::GREATER_EQUAL: bResult = (n >= m); break;
291 default: bResult = false;
293 } break;
294 default:
295 bResult = aLH == aRH;
297 return bResult;
301 void ONumOperator::Exec(OCodeStack& rCodeStack)
303 OOperand *pRight = rCodeStack.top();
304 rCodeStack.pop();
305 OOperand *pLeft = rCodeStack.top();
306 rCodeStack.pop();
308 rCodeStack.push(new OOperandResultNUM(operate(pLeft->getValue(), pRight->getValue())));
309 if( typeid(OOperandResult) == typeid(*pLeft))
310 delete pLeft;
311 if( typeid(OOperandResult) == typeid(*pRight))
312 delete pRight;
315 double OOp_ADD::operate(const double& fLeft,const double& fRight) const
317 return fLeft + fRight;
321 double OOp_SUB::operate(const double& fLeft,const double& fRight) const
323 return fLeft - fRight;
327 double OOp_MUL::operate(const double& fLeft,const double& fRight) const
329 return fLeft * fRight;
333 double OOp_DIV::operate(const double& fLeft,const double& fRight) const
335 return fLeft / fRight;
338 void ONthOperator::Exec(OCodeStack& rCodeStack)
340 ::std::vector<ORowSetValue> aValues;
341 ::std::vector<OOperand*> aOperands;
342 OOperand* pOperand;
345 OSL_ENSURE(!rCodeStack.empty(),"Stack must be none empty!");
346 pOperand = rCodeStack.top();
347 rCodeStack.pop();
348 assert(pOperand);
349 if (pOperand && typeid(OStopOperand) != typeid(*pOperand))
350 aValues.push_back( pOperand->getValue() );
351 aOperands.push_back( pOperand );
353 while (pOperand && typeid(OStopOperand) != typeid(*pOperand));
355 rCodeStack.push(new OOperandResult(operate(aValues)));
357 ::std::vector<OOperand*>::iterator aIter = aOperands.begin();
358 ::std::vector<OOperand*>::const_iterator aEnd = aOperands.end();
359 for (; aIter != aEnd; ++aIter)
361 if (typeid(OOperandResult) == typeid(*(*aIter)))
362 delete *aIter;
366 void OBinaryOperator::Exec(OCodeStack& rCodeStack)
368 OOperand *pRight = rCodeStack.top();
369 rCodeStack.pop();
370 OOperand *pLeft = rCodeStack.top();
371 rCodeStack.pop();
373 if ( !rCodeStack.empty() && typeid(OStopOperand) == typeid(*rCodeStack.top()) )
374 rCodeStack.pop();
376 rCodeStack.push(new OOperandResult(operate(pLeft->getValue(),pRight->getValue())));
377 if(typeid(OOperandResult) == typeid(*pRight))
378 delete pRight;
379 if(typeid(OOperandResult) == typeid(*pLeft))
380 delete pLeft;
383 void OUnaryOperator::Exec(OCodeStack& rCodeStack)
385 OSL_ENSURE(!rCodeStack.empty(),"Stack is empty!");
386 OOperand* pOperand = rCodeStack.top();
387 rCodeStack.pop();
389 rCodeStack.push(new OOperandResult(operate(pOperand->getValue())));
390 if (typeid(OOperandResult) == typeid(*pOperand))
391 delete pOperand;
395 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */