nss: upgrade to release 3.73
[LibreOffice.git] / connectivity / source / drivers / file / fcode.cxx
blob36cba4a7348543dbe3292e1ecf1653c9e8a42a58
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 <sal/log.hxx>
23 #include <connectivity/sqlparse.hxx>
24 #include <sqlbison.hxx>
25 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
27 using namespace ::comphelper;
28 using namespace connectivity;
29 using namespace connectivity::file;
30 using namespace ::com::sun::star::sdbc;
31 using namespace ::com::sun::star::sdb;
33 OCode::~OCode() = default;
35 OOperandRow::OOperandRow(sal_uInt16 _nPos, sal_Int32 _rType)
36 : OOperand(_rType)
37 , m_nRowPos(_nPos)
40 void OOperandRow::bindValue(const OValueRefRow& _pRow)
42 OSL_ENSURE(_pRow.is(),"NO EMPTY row allowed!");
43 m_pRow = _pRow;
44 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->size(),"Invalid RowPos is >= vector.size()");
45 (*m_pRow)[m_nRowPos]->setBound(true);
48 void OOperandRow::setValue(const ORowSetValue& _rVal)
50 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->size(),"Invalid RowPos is >= vector.size()");
51 (*(*m_pRow)[m_nRowPos]) = _rVal;
54 const ORowSetValue& OOperandRow::getValue() const
56 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->size(),"Invalid RowPos is >= vector.size()");
57 return (*m_pRow)[m_nRowPos]->getValue();
61 void OOperandValue::setValue(const ORowSetValue& _rVal)
63 m_aValue = _rVal;
66 OOperandParam::OOperandParam(OSQLParseNode const * pNode, sal_Int32 _nPos)
67 : OOperandRow(static_cast<sal_uInt16>(_nPos), DataType::VARCHAR) // Standard-Type
69 OSL_ENSURE(SQL_ISRULE(pNode,parameter),"Argument is not a parameter");
70 OSL_ENSURE(pNode->count() > 0,"Error in Parse Tree");
71 OSQLParseNode *pMark = pNode->getChild(0);
73 OUString aParameterName;
74 if (SQL_ISPUNCTUATION(pMark, "?"))
75 aParameterName = "?";
76 else if (SQL_ISPUNCTUATION(pMark, ":"))
77 aParameterName = pNode->getChild(1)->getTokenValue();
78 else
80 SAL_WARN( "connectivity.drivers","Error in Parse Tree");
83 // set up Parameter-Column with default type, can be specified more precisely later using Describe-Parameter
85 // save Identity (not especially necessary here, just for the sake of symmetry)
87 // todo
88 // OColumn* pColumn = new OFILEColumn(aParameterName,eDBType,255,0,SQL_FLAGS_NULLALLOWED);
89 // rParamColumns->AddColumn(pColumn);
91 // the value will be set just before the evaluation
95 const ORowSetValue& OOperandValue::getValue() const
97 return m_aValue;
101 OOperandConst::OOperandConst(const OSQLParseNode& rColumnRef, const OUString& aStrValue)
103 switch (rColumnRef.getNodeType())
105 case SQLNodeType::String:
106 m_aValue = aStrValue;
107 m_eDBType = DataType::VARCHAR;
108 m_aValue.setBound(true);
109 return;
110 case SQLNodeType::IntNum:
111 case SQLNodeType::ApproxNum:
112 m_aValue = aStrValue.toDouble();
113 m_eDBType = DataType::DOUBLE;
114 m_aValue.setBound(true);
115 return;
116 default:
117 break;
120 if (SQL_ISTOKEN(&rColumnRef, TRUE))
122 m_aValue = 1.0;
123 m_eDBType = DataType::BIT;
125 else if (SQL_ISTOKEN(&rColumnRef, FALSE))
127 m_aValue = 0.0;
128 m_eDBType = DataType::BIT;
130 else
132 SAL_WARN( "connectivity.drivers", "Parse Error");
134 m_aValue.setBound(true);
138 // Implementation of the operators
141 bool OBoolOperator::operate(const OOperand*, const OOperand*) const
143 return false;
147 void OBoolOperator::Exec(OCodeStack& rCodeStack)
149 OOperand *pRight = rCodeStack.top();
150 rCodeStack.pop();
151 OOperand *pLeft = rCodeStack.top();
152 rCodeStack.pop();
154 rCodeStack.push(new OOperandResultBOOL(operate(pLeft, pRight)));
155 if( typeid(OOperandResult) == typeid(*pLeft))
156 delete pLeft;
157 if( typeid(OOperandResult) == typeid(*pRight))
158 delete pRight;
161 bool OOp_NOT::operate(const OOperand* pLeft, const OOperand* ) const
163 return !pLeft->isValid();
166 void OOp_NOT::Exec(OCodeStack& rCodeStack)
168 OOperand* pOperand = rCodeStack.top();
169 rCodeStack.pop();
171 rCodeStack.push(new OOperandResultBOOL(operate(pOperand, nullptr)));
173 if( typeid(OOperandResult) == typeid(*pOperand))
174 delete pOperand;
177 bool OOp_AND::operate(const OOperand* pLeft, const OOperand* pRight) const
179 return pLeft->isValid() && pRight->isValid();
183 bool OOp_OR::operate(const OOperand* pLeft, const OOperand* pRight) const
185 return pLeft->isValid() || pRight->isValid();
189 void OOp_ISNULL::Exec(OCodeStack& rCodeStack)
191 OOperand* pOperand = rCodeStack.top();
192 rCodeStack.pop();
194 rCodeStack.push(new OOperandResultBOOL(operate(pOperand, nullptr)));
195 if( typeid(OOperandResult) == typeid(*pOperand))
196 delete pOperand;
200 bool OOp_ISNULL::operate(const OOperand* pOperand, const OOperand*) const
202 return pOperand->getValue().isNull();
206 bool OOp_ISNOTNULL::operate(const OOperand* pOperand, const OOperand*) const
208 return !OOp_ISNULL::operate(pOperand, nullptr);
212 bool OOp_LIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
214 bool bMatch;
215 const ORowSetValue& aLH(pLeft->getValue());
216 const ORowSetValue& aRH(pRight->getValue());
218 if (aLH.isNull() || aRH.isNull())
219 bMatch = false;
220 else
222 bMatch = match(aRH.getString(), aLH.getString(), cEscape);
224 return bMatch;
228 bool OOp_NOTLIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
230 return !OOp_LIKE::operate(pLeft, pRight);
234 bool OOp_COMPARE::operate(const OOperand* pLeft, const OOperand* pRight) const
236 const ORowSetValue& aLH(pLeft->getValue());
237 const ORowSetValue& aRH(pRight->getValue());
239 if (aLH.isNull() || aRH.isNull()) // if (!aLH.getValue() || !aRH.getValue())
240 return false;
242 bool bResult = false;
243 sal_Int32 eDBType = pLeft->getDBType();
245 // Comparison (depending on Data-type):
246 switch (eDBType)
248 case DataType::CHAR:
249 case DataType::VARCHAR:
250 case DataType::LONGVARCHAR:
252 OUString sLH = aLH, sRH = aRH;
253 sal_Int32 nRes = sLH.compareToIgnoreAsciiCase(sRH);
254 switch(aPredicateType)
256 case SQLFilterOperator::EQUAL: bResult = (nRes == 0); break;
257 case SQLFilterOperator::NOT_EQUAL: bResult = (nRes != 0); break;
258 case SQLFilterOperator::LESS: bResult = (nRes < 0); break;
259 case SQLFilterOperator::LESS_EQUAL: bResult = (nRes <= 0); break;
260 case SQLFilterOperator::GREATER: bResult = (nRes > 0); break;
261 case SQLFilterOperator::GREATER_EQUAL: bResult = (nRes >= 0); break;
262 default: bResult = false;
264 } break;
265 case DataType::TINYINT:
266 case DataType::SMALLINT:
267 case DataType::INTEGER:
268 case DataType::DECIMAL:
269 case DataType::NUMERIC:
270 case DataType::REAL:
271 case DataType::DOUBLE:
272 case DataType::BIT:
273 case DataType::TIMESTAMP:
274 case DataType::DATE:
275 case DataType::TIME:
277 double n = aLH ,m = aRH;
279 switch (aPredicateType)
281 case SQLFilterOperator::EQUAL: bResult = (n == m); break;
282 case SQLFilterOperator::LIKE: bResult = (n == m); break;
283 case SQLFilterOperator::NOT_EQUAL: bResult = (n != m); break;
284 case SQLFilterOperator::NOT_LIKE: bResult = (n != m); break;
285 case SQLFilterOperator::LESS: bResult = (n < m); break;
286 case SQLFilterOperator::LESS_EQUAL: bResult = (n <= m); break;
287 case SQLFilterOperator::GREATER: bResult = (n > m); break;
288 case SQLFilterOperator::GREATER_EQUAL: bResult = (n >= m); break;
289 default: bResult = false;
291 } break;
292 default:
293 bResult = aLH == aRH;
295 return bResult;
299 void ONumOperator::Exec(OCodeStack& rCodeStack)
301 OOperand *pRight = rCodeStack.top();
302 rCodeStack.pop();
303 OOperand *pLeft = rCodeStack.top();
304 rCodeStack.pop();
306 rCodeStack.push(new OOperandResultNUM(operate(pLeft->getValue(), pRight->getValue())));
307 if( typeid(OOperandResult) == typeid(*pLeft))
308 delete pLeft;
309 if( typeid(OOperandResult) == typeid(*pRight))
310 delete pRight;
313 double OOp_ADD::operate(const double& fLeft,const double& fRight) const
315 return fLeft + fRight;
319 double OOp_SUB::operate(const double& fLeft,const double& fRight) const
321 return fLeft - fRight;
325 double OOp_MUL::operate(const double& fLeft,const double& fRight) const
327 return fLeft * fRight;
331 double OOp_DIV::operate(const double& fLeft,const double& fRight) const
333 return fLeft / fRight;
336 void ONthOperator::Exec(OCodeStack& rCodeStack)
338 std::vector<ORowSetValue> aValues;
339 std::vector<OOperand*> aOperands;
340 OOperand* pOperand;
343 OSL_ENSURE(!rCodeStack.empty(),"Stack must be none empty!");
344 pOperand = rCodeStack.top();
345 rCodeStack.pop();
346 assert(pOperand);
347 if (pOperand && typeid(OStopOperand) != typeid(*pOperand))
348 aValues.push_back( pOperand->getValue() );
349 aOperands.push_back( pOperand );
351 while (pOperand && typeid(OStopOperand) != typeid(*pOperand));
353 rCodeStack.push(new OOperandResult(operate(aValues)));
355 for (const auto& rpOperand : aOperands)
357 if (typeid(OOperandResult) == typeid(*rpOperand))
358 delete rpOperand;
362 void OBinaryOperator::Exec(OCodeStack& rCodeStack)
364 OOperand *pRight = rCodeStack.top();
365 rCodeStack.pop();
366 OOperand *pLeft = rCodeStack.top();
367 rCodeStack.pop();
369 if ( !rCodeStack.empty() && typeid(OStopOperand) == typeid(*rCodeStack.top()) )
370 rCodeStack.pop();
372 rCodeStack.push(new OOperandResult(operate(pLeft->getValue(),pRight->getValue())));
373 if(typeid(OOperandResult) == typeid(*pRight))
374 delete pRight;
375 if(typeid(OOperandResult) == typeid(*pLeft))
376 delete pLeft;
379 void OUnaryOperator::Exec(OCodeStack& rCodeStack)
381 OSL_ENSURE(!rCodeStack.empty(),"Stack is empty!");
382 OOperand* pOperand = rCodeStack.top();
383 rCodeStack.pop();
385 rCodeStack.push(new OOperandResult(operate(pOperand->getValue())));
386 if (typeid(OOperandResult) == typeid(*pOperand))
387 delete pOperand;
391 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */