File indexing completed on 2024-12-01 10:28:56
0001 /* This file is part of the KDE project 0002 Copyright (C) 2003-2016 Jarosław Staniek <staniek@kde.org> 0003 0004 Based on nexp.cpp : Parser module of Python-like language 0005 (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl) 0006 0007 This library is free software; you can redistribute it and/or 0008 modify it under the terms of the GNU Library General Public 0009 License as published by the Free Software Foundation; either 0010 version 2 of the License, or (at your option) any later version. 0011 0012 This library is distributed in the hope that it will be useful, 0013 but WITHOUT ANY WARRANTY; without even the implied warranty of 0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0015 Library General Public License for more details. 0016 0017 You should have received a copy of the GNU Library General Public License 0018 along with this library; see the file COPYING.LIB. If not, write to 0019 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0020 * Boston, MA 02110-1301, USA. 0021 */ 0022 0023 #include "KDbExpression.h" 0024 #include "KDb.h" 0025 #include "KDbDriver.h" 0026 #include "KDbQuerySchema.h" 0027 #include "KDbParser_p.h" 0028 #include "kdb_debug.h" 0029 0030 KDbNArgExpressionData::KDbNArgExpressionData() 0031 : KDbExpressionData() 0032 { 0033 ExpressionDebug << "NArgExpressionData" << ref; 0034 } 0035 0036 KDbNArgExpressionData::~KDbNArgExpressionData() 0037 { 0038 ExpressionDebug << "~NArgExpressionData" << ref; 0039 } 0040 0041 KDbField::Type KDbNArgExpressionData::typeInternal(KDb::ExpressionCallStack *callStack) const 0042 { 0043 if (token == KDbToken::BETWEEN_AND || token == KDbToken::NOT_BETWEEN_AND) { 0044 for (int i = 0; i < children.count(); i++) { 0045 KDbField::Type t = children.at(0)->type(callStack); 0046 if (t == KDbField::InvalidType || t == KDbField::Null) { 0047 return t; 0048 } 0049 } 0050 return KDbField::Boolean; 0051 } 0052 return KDbField::Tuple; 0053 } 0054 0055 KDbNArgExpressionData* KDbNArgExpressionData::clone() 0056 { 0057 ExpressionDebug << "NArgExpressionData::clone" << *this; 0058 return new KDbNArgExpressionData(*this); 0059 } 0060 0061 bool KDbNArgExpressionData::validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack* callStack) 0062 { 0063 foreach(ExplicitlySharedExpressionDataPointer data, children) { 0064 if (!data->validate(parseInfo, callStack)) 0065 return false; 0066 } 0067 0068 if (token == KDbToken::BETWEEN_AND || token == KDbToken::NOT_BETWEEN_AND) { 0069 if (children.count() != 3) { 0070 parseInfo->setErrorMessage(tr("Three arguments required")); 0071 parseInfo->setErrorDescription( 0072 tr("%1 operator requires exactly three arguments.", "BETWEEN..AND error") 0073 .arg(QLatin1String("BETWEEN...AND"))); 0074 return false; 0075 } 0076 const KDbField::Type t0 = children[0]->type(); 0077 const KDbField::Type t1 = children[1]->type(); 0078 const KDbField::Type t2 = children[2]->type(); 0079 if (t0 == KDbField::Null || t1 == KDbField::Null || t2 == KDbField::Null) { 0080 return true; 0081 } 0082 if (!( !KDbField::isNumericType(t0) 0083 || !KDbField::isNumericType(t1) 0084 || !KDbField::isNumericType(t2))) 0085 { 0086 return true; 0087 } else if (!( !KDbField::isTextType(t0) 0088 || !KDbField::isTextType(t1) 0089 || !KDbField::isTextType(t2))) 0090 { 0091 return true; 0092 } 0093 0094 if (t0 == t1 && t1 == t2) { 0095 return true; 0096 } 0097 0098 parseInfo->setErrorMessage(tr("Incompatible types of arguments")); 0099 parseInfo->setErrorDescription( 0100 tr("Operator \"%1\" requires compatible types of arguments. " 0101 "Specified arguments are of type %2, %3, %4.", 0102 "BETWEEN..AND arguments type error") 0103 .arg(QLatin1String("BETWEEN..AND"), 0104 KDbField::typeName(t0), 0105 KDbField::typeName(t1), 0106 KDbField::typeName(t2))); 0107 return false; 0108 } 0109 return true; 0110 } 0111 0112 void KDbNArgExpressionData::debugInternal(QDebug dbg, KDb::ExpressionCallStack* callStack) const 0113 { 0114 dbg.nospace() << "NArgExp(" 0115 << token.name() << ", class=" << expressionClassName(expressionClass); 0116 foreach(ExplicitlySharedExpressionDataPointer data, children) { 0117 dbg.nospace() << ", "; 0118 data->debug(dbg, callStack); 0119 } 0120 dbg.nospace() << ",type=" << KDbDriver::defaultSqlTypeName(type()) << ")"; 0121 } 0122 0123 KDbEscapedString KDbNArgExpressionData::toStringInternal( 0124 const KDbDriver *driver, 0125 KDbQuerySchemaParameterValueListIterator* params, 0126 KDb::ExpressionCallStack* callStack) const 0127 { 0128 if (token == KDbToken::BETWEEN_AND && children.count() == 3) { 0129 return children[0]->toString(driver, params, callStack) + " BETWEEN " 0130 + children[1]->toString(driver, params, callStack) + " AND " 0131 + children[2]->toString(driver, params, callStack); 0132 } 0133 if (token == KDbToken::NOT_BETWEEN_AND && children.count() == 3) { 0134 return children[0]->toString(driver, params, callStack) + " NOT BETWEEN " 0135 + children[1]->toString(driver, params, callStack) + " AND " 0136 + children[2]->toString(driver, params, callStack); 0137 } 0138 0139 KDbEscapedString s; 0140 s.reserve(256); 0141 foreach(ExplicitlySharedExpressionDataPointer data, children) { 0142 if (!s.isEmpty()) 0143 s += ", "; 0144 s += data->toString(driver, params, callStack); 0145 } 0146 return s; 0147 } 0148 0149 void KDbNArgExpressionData::getQueryParameters(QList<KDbQuerySchemaParameter>* params) 0150 { 0151 Q_ASSERT(params); 0152 foreach(ExplicitlySharedExpressionDataPointer data, children) { 0153 data->getQueryParameters(params); 0154 } 0155 } 0156 0157 bool KDbNArgExpressionData::containsInvalidArgument() const 0158 { 0159 foreach(ExplicitlySharedExpressionDataPointer data, children) { 0160 const KDbField::Type type = data->type(); 0161 if (type == KDbField::InvalidType) { 0162 return true; 0163 } 0164 } 0165 return false; 0166 } 0167 0168 bool KDbNArgExpressionData::containsNullArgument() const 0169 { 0170 foreach(ExplicitlySharedExpressionDataPointer data, children) { 0171 const KDbField::Type type = data->type(); 0172 if (type == KDbField::Null) { 0173 return true; 0174 } 0175 } 0176 return false; 0177 } 0178 0179 //========================================= 0180 0181 KDbNArgExpression::KDbNArgExpression() 0182 : KDbExpression(new KDbNArgExpressionData) 0183 { 0184 ExpressionDebug << "KDbNArgExpression() ctor" << *this; 0185 } 0186 0187 KDbNArgExpression::KDbNArgExpression(KDbExpressionData* data) 0188 : KDbExpression(data) 0189 { 0190 ExpressionDebug << "KDbNArgExpression(KDbExpressionData*) ctor" << *this; 0191 } 0192 0193 KDbNArgExpression::KDbNArgExpression(KDb::ExpressionClass aClass, KDbToken token) 0194 : KDbExpression(new KDbNArgExpressionData, aClass, token) 0195 { 0196 ExpressionDebug << "KDbNArgExpression(KDb::ExpressionClass, int) ctor" << *this; 0197 } 0198 0199 KDbNArgExpression::KDbNArgExpression(const KDbNArgExpression& expr) 0200 : KDbExpression(expr) 0201 { 0202 } 0203 0204 KDbNArgExpression::KDbNArgExpression(const ExplicitlySharedExpressionDataPointer &ptr) 0205 : KDbExpression(ptr) 0206 { 0207 } 0208 0209 KDbNArgExpression::~KDbNArgExpression() 0210 { 0211 } 0212 0213 void KDbNArgExpression::append(const KDbExpression& expr) 0214 { 0215 appendChild(expr); 0216 } 0217 0218 void KDbNArgExpression::prepend(const KDbExpression& expr) 0219 { 0220 prependChild(expr); 0221 } 0222 0223 KDbExpression KDbNArgExpression::arg(int i) const 0224 { 0225 return KDbExpression(d->children.value(i)); 0226 } 0227 0228 void KDbNArgExpression::insert(int i, const KDbExpression& expr) 0229 { 0230 insertChild(i, expr); 0231 } 0232 0233 void KDbNArgExpression::replace(int i, const KDbExpression& expr) 0234 { 0235 if (!checkBeforeInsert(expr.d)) 0236 return; 0237 if (i < 0 || i > d->children.count()) 0238 return; 0239 d->children.at(i)->parent.reset(); 0240 d->children.replace(i, expr.d); 0241 expr.d->parent = d; 0242 } 0243 0244 bool KDbNArgExpression::remove(const KDbExpression& expr) 0245 { 0246 return removeChild(expr); 0247 } 0248 0249 void KDbNArgExpression::removeAt(int i) 0250 { 0251 removeChild(i); 0252 } 0253 0254 KDbExpression KDbNArgExpression::takeAt(int i) 0255 { 0256 return takeChild(i); 0257 } 0258 0259 int KDbNArgExpression::indexOf(const KDbExpression& expr, int from) const 0260 { 0261 return indexOfChild(expr, from); 0262 } 0263 0264 int KDbNArgExpression::lastIndexOf(const KDbExpression& expr, int from) const 0265 { 0266 return lastIndexOfChild(expr, from); 0267 } 0268 0269 int KDbNArgExpression::argCount() const 0270 { 0271 return d->children.count(); 0272 } 0273 0274 bool KDbNArgExpression::isEmpty() const 0275 { 0276 return d->children.isEmpty(); 0277 } 0278 0279 bool KDbNArgExpression::containsInvalidArgument() const 0280 { 0281 return d->convert<KDbNArgExpressionData>()->containsInvalidArgument(); 0282 } 0283 0284 bool KDbNArgExpression::containsNullArgument() const 0285 { 0286 return d->convert<KDbNArgExpressionData>()->containsNullArgument(); 0287 }