cid#1636677 Uninitialized scalar field
[LibreOffice.git] / connectivity / source / drivers / file / fcode.cxx
blobec56032c8491ab12b27d3ab2d0a6fd29bb7a8c86
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/sqlnode.hxx>
24 #include <sqlbison.hxx>
25 #include <com/sun/star/sdb/SQLFilterOperator.hpp>
27 using namespace connectivity;
28 using namespace connectivity::file;
29 using namespace ::com::sun::star::sdbc;
30 using namespace ::com::sun::star::sdb;
32 OCode::~OCode() = default;
34 OOperandRow::OOperandRow(sal_uInt16 _nPos, sal_Int32 _rType)
35 : OOperand(_rType)
36 , m_nRowPos(_nPos)
39 void OOperandRow::bindValue(const OValueRefRow& _pRow)
41 OSL_ENSURE(_pRow.is(),"NO EMPTY row allowed!");
42 m_pRow = _pRow;
43 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->size(),"Invalid RowPos is >= vector.size()");
44 (*m_pRow)[m_nRowPos]->setBound(true);
47 void OOperandRow::setValue(const ORowSetValue& _rVal)
49 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->size(),"Invalid RowPos is >= vector.size()");
50 (*(*m_pRow)[m_nRowPos]) = _rVal;
53 const ORowSetValue& OOperandRow::getValue() const
55 OSL_ENSURE(m_pRow.is() && m_nRowPos < m_pRow->size(),"Invalid RowPos is >= vector.size()");
56 return (*m_pRow)[m_nRowPos]->getValue();
60 void OOperandValue::setValue(const ORowSetValue& _rVal)
62 m_aValue = _rVal;
65 OOperandParam::OOperandParam(sal_Int32 _nPos)
66 : OOperandRow(static_cast<sal_uInt16>(_nPos), DataType::VARCHAR) // Standard-Type
68 //TODO: Actually do something here (the current state of OOperandParam appears to be "the
69 // remains of the very beginnings of a never finished implementation of support for parameters
70 // in this code", as Lionel put it in the comments at <https://gerrit.libreoffice.org/c/core/+/
71 // 116839/1#message-7b2bbf3543f559a0b67dc35cd940e2ab8829c274> "-Werror,-Wunused-but-set-variable
72 // (Clang 13 trunk)").
76 const ORowSetValue& OOperandValue::getValue() const
78 return m_aValue;
82 OOperandConst::OOperandConst(const OSQLParseNode& rColumnRef, const OUString& aStrValue)
84 switch (rColumnRef.getNodeType())
86 case SQLNodeType::String:
87 m_aValue = aStrValue;
88 m_eDBType = DataType::VARCHAR;
89 m_aValue.setBound(true);
90 return;
91 case SQLNodeType::IntNum:
92 case SQLNodeType::ApproxNum:
93 m_aValue = aStrValue.toDouble();
94 m_eDBType = DataType::DOUBLE;
95 m_aValue.setBound(true);
96 return;
97 default:
98 break;
101 if (SQL_ISTOKEN(&rColumnRef, TRUE))
103 m_aValue = 1.0;
104 m_eDBType = DataType::BIT;
106 else if (SQL_ISTOKEN(&rColumnRef, FALSE))
108 m_aValue = 0.0;
109 m_eDBType = DataType::BIT;
111 else
113 SAL_WARN( "connectivity.drivers", "Parse Error");
115 m_aValue.setBound(true);
119 // Implementation of the operators
122 bool OBoolOperator::operate(const OOperand*, const OOperand*) const
124 return false;
128 void OBoolOperator::Exec(OCodeStack& rCodeStack)
130 OOperand *pRight = rCodeStack.top();
131 rCodeStack.pop();
132 OOperand *pLeft = rCodeStack.top();
133 rCodeStack.pop();
135 rCodeStack.push(new OOperandResultBOOL(operate(pLeft, pRight)));
136 if( typeid(OOperandResult) == typeid(*pLeft))
137 delete pLeft;
138 if( typeid(OOperandResult) == typeid(*pRight))
139 delete pRight;
142 bool OOp_NOT::operate(const OOperand* pLeft, const OOperand* ) const
144 return !pLeft->isValid();
147 void OOp_NOT::Exec(OCodeStack& rCodeStack)
149 OOperand* pOperand = rCodeStack.top();
150 rCodeStack.pop();
152 rCodeStack.push(new OOperandResultBOOL(operate(pOperand, nullptr)));
154 if( typeid(OOperandResult) == typeid(*pOperand))
155 delete pOperand;
158 bool OOp_AND::operate(const OOperand* pLeft, const OOperand* pRight) const
160 return pLeft->isValid() && pRight->isValid();
164 bool OOp_OR::operate(const OOperand* pLeft, const OOperand* pRight) const
166 return pLeft->isValid() || pRight->isValid();
170 void OOp_ISNULL::Exec(OCodeStack& rCodeStack)
172 OOperand* pOperand = rCodeStack.top();
173 rCodeStack.pop();
175 rCodeStack.push(new OOperandResultBOOL(operate(pOperand, nullptr)));
176 if( typeid(OOperandResult) == typeid(*pOperand))
177 delete pOperand;
181 bool OOp_ISNULL::operate(const OOperand* pOperand, const OOperand*) const
183 return pOperand->getValue().isNull();
187 bool OOp_ISNOTNULL::operate(const OOperand* pOperand, const OOperand*) const
189 return !OOp_ISNULL::operate(pOperand, nullptr);
193 bool OOp_LIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
195 bool bMatch;
196 const ORowSetValue& aLH(pLeft->getValue());
197 const ORowSetValue& aRH(pRight->getValue());
199 if (aLH.isNull() || aRH.isNull())
200 bMatch = false;
201 else
203 bMatch = match(aRH.getString(), aLH.getString(), cEscape);
205 return bMatch;
209 bool OOp_NOTLIKE::operate(const OOperand* pLeft, const OOperand* pRight) const
211 return !OOp_LIKE::operate(pLeft, pRight);
215 bool OOp_COMPARE::operate(const OOperand* pLeft, const OOperand* pRight) const
217 const ORowSetValue& aLH(pLeft->getValue());
218 const ORowSetValue& aRH(pRight->getValue());
220 if (aLH.isNull() || aRH.isNull()) // if (!aLH.getValue() || !aRH.getValue())
221 return false;
223 bool bResult = false;
224 sal_Int32 eDBType = pLeft->getDBType();
226 // Comparison (depending on Data-type):
227 switch (eDBType)
229 case DataType::CHAR:
230 case DataType::VARCHAR:
231 case DataType::LONGVARCHAR:
233 OUString sLH = aLH.getString(), sRH = aRH.getString();
234 sal_Int32 nRes = sLH.compareToIgnoreAsciiCase(sRH);
235 switch(aPredicateType)
237 case SQLFilterOperator::EQUAL: bResult = (nRes == 0); break;
238 case SQLFilterOperator::NOT_EQUAL: bResult = (nRes != 0); break;
239 case SQLFilterOperator::LESS: bResult = (nRes < 0); break;
240 case SQLFilterOperator::LESS_EQUAL: bResult = (nRes <= 0); break;
241 case SQLFilterOperator::GREATER: bResult = (nRes > 0); break;
242 case SQLFilterOperator::GREATER_EQUAL: bResult = (nRes >= 0); break;
243 default: bResult = false;
245 } break;
246 case DataType::TINYINT:
247 case DataType::SMALLINT:
248 case DataType::INTEGER:
249 case DataType::DECIMAL:
250 case DataType::NUMERIC:
251 case DataType::REAL:
252 case DataType::DOUBLE:
253 case DataType::BIT:
254 case DataType::TIMESTAMP:
255 case DataType::DATE:
256 case DataType::TIME:
258 double n = aLH.getDouble(), m = aRH.getDouble();
260 switch (aPredicateType)
262 case SQLFilterOperator::EQUAL: bResult = (n == m); break;
263 case SQLFilterOperator::LIKE: bResult = (n == m); break;
264 case SQLFilterOperator::NOT_EQUAL: bResult = (n != m); break;
265 case SQLFilterOperator::NOT_LIKE: bResult = (n != m); break;
266 case SQLFilterOperator::LESS: bResult = (n < m); break;
267 case SQLFilterOperator::LESS_EQUAL: bResult = (n <= m); break;
268 case SQLFilterOperator::GREATER: bResult = (n > m); break;
269 case SQLFilterOperator::GREATER_EQUAL: bResult = (n >= m); break;
270 default: bResult = false;
272 } break;
273 default:
274 bResult = aLH == aRH;
276 return bResult;
280 void ONumOperator::Exec(OCodeStack& rCodeStack)
282 OOperand *pRight = rCodeStack.top();
283 rCodeStack.pop();
284 OOperand *pLeft = rCodeStack.top();
285 rCodeStack.pop();
287 rCodeStack.push(new OOperandResultNUM(operate(pLeft->getValue().getDouble(), pRight->getValue().getDouble())));
288 if( typeid(OOperandResult) == typeid(*pLeft))
289 delete pLeft;
290 if( typeid(OOperandResult) == typeid(*pRight))
291 delete pRight;
294 double OOp_ADD::operate(const double& fLeft,const double& fRight) const
296 return fLeft + fRight;
300 double OOp_SUB::operate(const double& fLeft,const double& fRight) const
302 return fLeft - fRight;
306 double OOp_MUL::operate(const double& fLeft,const double& fRight) const
308 return fLeft * fRight;
312 double OOp_DIV::operate(const double& fLeft,const double& fRight) const
314 return fLeft / fRight;
317 void ONthOperator::Exec(OCodeStack& rCodeStack)
319 std::vector<ORowSetValue> aValues;
320 std::vector<OOperand*> aOperands;
321 OOperand* pOperand;
324 OSL_ENSURE(!rCodeStack.empty(),"Stack must be none empty!");
325 pOperand = rCodeStack.top();
326 rCodeStack.pop();
327 assert(pOperand);
328 if (pOperand && typeid(OStopOperand) != typeid(*pOperand))
329 aValues.push_back( pOperand->getValue() );
330 aOperands.push_back( pOperand );
332 while (pOperand && typeid(OStopOperand) != typeid(*pOperand));
334 rCodeStack.push(new OOperandResult(operate(aValues)));
336 for (const auto& rpOperand : aOperands)
338 if (typeid(OOperandResult) == typeid(*rpOperand))
339 delete rpOperand;
343 void OBinaryOperator::Exec(OCodeStack& rCodeStack)
345 OOperand *pRight = rCodeStack.top();
346 rCodeStack.pop();
347 OOperand *pLeft = rCodeStack.top();
348 rCodeStack.pop();
350 if ( !rCodeStack.empty() && typeid(OStopOperand) == typeid(*rCodeStack.top()) )
351 rCodeStack.pop();
353 rCodeStack.push(new OOperandResult(operate(pLeft->getValue(),pRight->getValue())));
354 if(typeid(OOperandResult) == typeid(*pRight))
355 delete pRight;
356 if(typeid(OOperandResult) == typeid(*pLeft))
357 delete pLeft;
360 void OUnaryOperator::Exec(OCodeStack& rCodeStack)
362 OSL_ENSURE(!rCodeStack.empty(),"Stack is empty!");
363 OOperand* pOperand = rCodeStack.top();
364 rCodeStack.pop();
366 rCodeStack.push(new OOperandResult(operate(pOperand->getValue())));
367 if (typeid(OOperandResult) == typeid(*pOperand))
368 delete pOperand;
372 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */