00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "expression.h"
00024 #include "utils.h"
00025 #include "parser/sqlparser.h"
00026 #include "parser/parser_p.h"
00027
00028 #include <ctype.h>
00029
00030 #include <kdebug.h>
00031 #include <klocale.h>
00032
00033 #include <qdatetime.h>
00034
00035 KEXI_DB_EXPORT QString KexiDB::exprClassName(int c)
00036 {
00037 if (c==KexiDBExpr_Unary)
00038 return "Unary";
00039 else if (c==KexiDBExpr_Arithm)
00040 return "Arithm";
00041 else if (c==KexiDBExpr_Logical)
00042 return "Logical";
00043 else if (c==KexiDBExpr_Relational)
00044 return "Relational";
00045 else if (c==KexiDBExpr_SpecialBinary)
00046 return "SpecialBinary";
00047 else if (c==KexiDBExpr_Const)
00048 return "Const";
00049 else if (c==KexiDBExpr_Variable)
00050 return "Variable";
00051 else if (c==KexiDBExpr_Function)
00052 return "Function";
00053 else if (c==KexiDBExpr_Aggregation)
00054 return "Aggregation";
00055 else if (c==KexiDBExpr_TableList)
00056 return "TableList";
00057 else if (c==KexiDBExpr_QueryParameter)
00058 return "QueryParameter";
00059
00060 return "Unknown";
00061 }
00062
00063 using namespace KexiDB;
00064
00065
00066
00067 BaseExpr::BaseExpr(int token)
00068 : m_cl(KexiDBExpr_Unknown)
00069 , m_par(0)
00070 , m_token(token)
00071 {
00072 }
00073
00074 BaseExpr::~BaseExpr()
00075 {
00076 }
00077
00078 Field::Type BaseExpr::type()
00079 {
00080 return Field::InvalidType;
00081 }
00082
00083 QString BaseExpr::debugString()
00084 {
00085 return QString("BaseExpr(%1,type=%1)").arg(m_token).arg(Driver::defaultSQLTypeName(type()));
00086 }
00087
00088 bool BaseExpr::validate(ParseInfo& )
00089 {
00090 return true;
00091 }
00092
00093 extern const char * const tname(int offset);
00094 #define safe_tname(token) ((token>=255 && token<=__LAST_TOKEN) ? tname(token-255) : "")
00095
00096 QString BaseExpr::tokenToDebugString(int token)
00097 {
00098 if (token < 254) {
00099 if (isprint(token))
00100 return QString(QChar(uchar(token)));
00101 else
00102 return QString::number(token);
00103 }
00104 return QString(safe_tname(token));
00105 }
00106
00107 QString BaseExpr::tokenToString()
00108 {
00109 if (m_token < 255 && isprint(m_token))
00110 return tokenToDebugString();
00111 return QString::null;
00112 }
00113
00114 NArgExpr* BaseExpr::toNArg() { return dynamic_cast<NArgExpr*>(this); }
00115 UnaryExpr* BaseExpr::toUnary() { return dynamic_cast<UnaryExpr*>(this); }
00116 BinaryExpr* BaseExpr::toBinary() { return dynamic_cast<BinaryExpr*>(this); }
00117 ConstExpr* BaseExpr::toConst() { return dynamic_cast<ConstExpr*>(this); }
00118 VariableExpr* BaseExpr::toVariable() { return dynamic_cast<VariableExpr*>(this); }
00119 FunctionExpr* BaseExpr::toFunction() { return dynamic_cast<FunctionExpr*>(this); }
00120 QueryParameterExpr* BaseExpr::toQueryParameter() { return dynamic_cast<QueryParameterExpr*>(this); }
00121
00122
00123
00124 NArgExpr::NArgExpr(int aClass, int token)
00125 : BaseExpr(token)
00126 {
00127 m_cl = aClass;
00128 list.setAutoDelete(true);
00129 }
00130
00131 NArgExpr::NArgExpr(const NArgExpr& expr)
00132 : BaseExpr(expr)
00133 {
00134 foreach_list (BaseExpr::ListIterator, it, expr.list)
00135 add( it.current()->copy() );
00136 }
00137
00138 NArgExpr::~NArgExpr()
00139 {
00140 }
00141
00142 NArgExpr* NArgExpr::copy() const
00143 {
00144 return new NArgExpr(*this);
00145 }
00146
00147 QString NArgExpr::debugString()
00148 {
00149 QString s = QString("NArgExpr(")
00150 + "class=" + exprClassName(m_cl);
00151 for ( BaseExpr::ListIterator it(list); it.current(); ++it ) {
00152 s+=", ";
00153 s+=it.current()->debugString();
00154 }
00155 s+=")";
00156 return s;
00157 }
00158
00159 QString NArgExpr::toString( QuerySchemaParameterValueListIterator* params )
00160 {
00161 QString s;
00162 s.reserve(256);
00163 foreach_list( BaseExpr::ListIterator, it, list) {
00164 if (!s.isEmpty())
00165 s+=", ";
00166 s+=it.current()->toString(params);
00167 }
00168 return s;
00169 }
00170
00171 void NArgExpr::getQueryParameters(QuerySchemaParameterList& params)
00172 {
00173 foreach_list( BaseExpr::ListIterator, it, list)
00174 it.current()->getQueryParameters(params);
00175 }
00176
00177 BaseExpr* NArgExpr::arg(int nr)
00178 {
00179 return list.at(nr);
00180 }
00181
00182 void NArgExpr::add(BaseExpr *expr)
00183 {
00184 list.append(expr);
00185 expr->setParent(this);
00186 }
00187
00188 void NArgExpr::prepend(BaseExpr *expr)
00189 {
00190 list.prepend(expr);
00191 expr->setParent(this);
00192 }
00193
00194 int NArgExpr::args()
00195 {
00196 return list.count();
00197 }
00198
00199 bool NArgExpr::validate(ParseInfo& parseInfo)
00200 {
00201 if (!BaseExpr::validate(parseInfo))
00202 return false;
00203
00204 foreach_list(BaseExpr::ListIterator, it, list) {
00205 if (!it.current()->validate(parseInfo))
00206 return false;
00207 }
00208 return true;
00209 }
00210
00211
00212 UnaryExpr::UnaryExpr(int token, BaseExpr *arg)
00213 : BaseExpr(token)
00214 , m_arg(arg)
00215 {
00216 m_cl = KexiDBExpr_Unary;
00217 if (m_arg)
00218 m_arg->setParent(this);
00219 }
00220
00221 UnaryExpr::UnaryExpr(const UnaryExpr& expr)
00222 : BaseExpr(expr)
00223 , m_arg( expr.m_arg ? expr.m_arg->copy() : 0 )
00224 {
00225 if (m_arg)
00226 m_arg->setParent(this);
00227 }
00228
00229 UnaryExpr::~UnaryExpr()
00230 {
00231 delete m_arg;
00232 }
00233
00234 UnaryExpr* UnaryExpr::copy() const
00235 {
00236 return new UnaryExpr(*this);
00237 }
00238
00239 QString UnaryExpr::debugString()
00240 {
00241 return "UnaryExpr('"
00242 + tokenToDebugString() + "', "
00243 + (m_arg ? m_arg->debugString() : QString("<NONE>"))
00244 + QString(",type=%1)").arg(Driver::defaultSQLTypeName(type()));
00245 }
00246
00247 QString UnaryExpr::toString(QuerySchemaParameterValueListIterator* params)
00248 {
00249 if (m_token=='(')
00250 return "(" + (m_arg ? m_arg->toString(params) : "<NULL>") + ")";
00251 if (m_token < 255 && isprint(m_token))
00252 return tokenToDebugString() + (m_arg ? m_arg->toString(params) : "<NULL>");
00253 if (m_token==NOT)
00254 return "NOT " + (m_arg ? m_arg->toString(params) : "<NULL>");
00255 if (m_token==SQL_IS_NULL)
00256 return (m_arg ? m_arg->toString(params) : "<NULL>") + " IS NULL";
00257 if (m_token==SQL_IS_NOT_NULL)
00258 return (m_arg ? m_arg->toString(params) : "<NULL>") + " IS NOT NULL";
00259 return QString("{INVALID_OPERATOR#%1} ").arg(m_token) + (m_arg ? m_arg->toString(params) : "<NULL>");
00260 }
00261
00262 void UnaryExpr::getQueryParameters(QuerySchemaParameterList& params)
00263 {
00264 if (m_arg)
00265 m_arg->getQueryParameters(params);
00266 }
00267
00268 Field::Type UnaryExpr::type()
00269 {
00270
00271
00272 switch (m_token) {
00273 case SQL_IS_NULL:
00274 case SQL_IS_NOT_NULL:
00275 return Field::Boolean;
00276 }
00277 const Field::Type t = m_arg->type();
00278 if (t==Field::Null)
00279 return Field::Null;
00280 if (m_token==NOT)
00281 return Field::Boolean;
00282
00283 return t;
00284 }
00285
00286 bool UnaryExpr::validate(ParseInfo& parseInfo)
00287 {
00288 if (!BaseExpr::validate(parseInfo))
00289 return false;
00290
00291 if (!m_arg->validate(parseInfo))
00292 return false;
00293
00295
00296
00297 if (m_arg->toQueryParameter()) {
00298 m_arg->toQueryParameter()->setType(type());
00299 }
00300
00301 return true;
00302 #if 0
00303 BaseExpr *n = l.at(0);
00304
00305 n->check();
00306
00307
00308
00309
00310
00311 if (is(NOT) && n->nodeTypeIs(TYP_BOOL)) {
00312 node_type=new NConstType(TYP_BOOL);
00313 }
00314 else if (is('#') && n->nodeTypeIs(TYP_STR)) {
00315 node_type=new NConstType(TYP_INT);
00316 }
00317 else if ((is('+') || is('-')) && n->nodeTypeIs(TYP_INT)) {
00318 node_type=new NConstType(TYP_INT);
00319 }
00320 else {
00321 ERR("Niepoprawny argument typu '%s' dla operatora '%s'",
00322 n->nodeTypeName(),is(NOT)?QString("not"):QChar(typ()));
00323 }
00324 #endif
00325 }
00326
00327
00328 BinaryExpr::BinaryExpr(int aClass, BaseExpr *left_expr, int token, BaseExpr *right_expr)
00329 : BaseExpr(token)
00330 , m_larg(left_expr)
00331 , m_rarg(right_expr)
00332 {
00333 m_cl = aClass;
00334 if (m_larg)
00335 m_larg->setParent(this);
00336 if (m_rarg)
00337 m_rarg->setParent(this);
00338 }
00339
00340 BinaryExpr::BinaryExpr(const BinaryExpr& expr)
00341 : BaseExpr(expr)
00342 , m_larg( expr.m_larg ? expr.m_larg->copy() : 0 )
00343 , m_rarg( expr.m_rarg ? expr.m_rarg->copy() : 0 )
00344 {
00345 }
00346
00347 BinaryExpr::~BinaryExpr()
00348 {
00349 delete m_larg;
00350 delete m_rarg;
00351 }
00352
00353 BinaryExpr* BinaryExpr::copy() const
00354 {
00355 return new BinaryExpr(*this);
00356 }
00357
00358 bool BinaryExpr::validate(ParseInfo& parseInfo)
00359 {
00360 if (!BaseExpr::validate(parseInfo))
00361 return false;
00362
00363 if (!m_larg->validate(parseInfo))
00364 return false;
00365 if (!m_rarg->validate(parseInfo))
00366 return false;
00367
00369
00370
00371 QueryParameterExpr * queryParameter = m_larg->toQueryParameter();
00372 if (queryParameter)
00373 queryParameter->setType(m_rarg->type());
00374 queryParameter = m_rarg->toQueryParameter();
00375 if (queryParameter)
00376 queryParameter->setType(m_larg->type());
00377
00378 return true;
00379 }
00380
00381 Field::Type BinaryExpr::type()
00382 {
00383 const Field::Type lt = m_larg->type(), rt = m_rarg->type();
00384 if (lt==Field::InvalidType || rt == Field::InvalidType)
00385 return Field::InvalidType;
00386 if (lt==Field::Null || rt == Field::Null) {
00387 if (m_token!=OR)
00388 return Field::Null;
00389 }
00390
00391 switch (m_token) {
00392 case BITWISE_SHIFT_RIGHT:
00393 case BITWISE_SHIFT_LEFT:
00394 case CONCATENATION:
00395 return lt;
00396 }
00397
00398 const bool ltInt = Field::isIntegerType(lt);
00399 const bool rtInt = Field::isIntegerType(rt);
00400 if (ltInt && rtInt)
00401 return KexiDB::maximumForIntegerTypes(lt, rt);
00402
00403 if (Field::isFPNumericType(lt) && rtInt)
00404 return lt;
00405 if (Field::isFPNumericType(rt) && ltInt)
00406 return rt;
00407 if ((lt==Field::Double || lt==Field::Float) && rtInt)
00408 return lt;
00409 if ((rt==Field::Double || rt==Field::Float) && ltInt)
00410 return rt;
00411
00412 return Field::Boolean;
00413 }
00414
00415 QString BinaryExpr::debugString()
00416 {
00417 return QString("BinaryExpr(")
00418 + "class=" + exprClassName(m_cl)
00419 + "," + (m_larg ? m_larg->debugString() : QString("<NONE>"))
00420 + ",'" + tokenToDebugString() + "',"
00421 + (m_rarg ? m_rarg->debugString() : QString("<NONE>"))
00422 + QString(",type=%1)").arg(Driver::defaultSQLTypeName(type()));
00423 }
00424
00425 QString BinaryExpr::tokenToString()
00426 {
00427 if (m_token < 255 && isprint(m_token))
00428 return tokenToDebugString();
00429
00430 switch (m_token) {
00431 case BITWISE_SHIFT_RIGHT: return ">>";
00432 case BITWISE_SHIFT_LEFT: return "<<";
00433
00434 case NOT_EQUAL: return "<>";
00435 case NOT_EQUAL2: return "!=";
00436 case LESS_OR_EQUAL: return "<=";
00437 case GREATER_OR_EQUAL: return ">=";
00438 case LIKE: return "LIKE";
00439 case SQL_IN: return "IN";
00440
00441 case SIMILAR_TO: return "SIMILAR TO";
00442 case NOT_SIMILAR_TO: return "NOT SIMILAR TO";
00443 case OR: return "OR";
00444 case AND: return "AND";
00445 case XOR: return "XOR";
00446
00447 case CONCATENATION: return "||";
00448
00449
00450 default:;
00451 }
00452 return QString("{INVALID_BINARY_OPERATOR#%1} ").arg(m_token);
00453 }
00454
00455 QString BinaryExpr::toString(QuerySchemaParameterValueListIterator* params)
00456 {
00457 #define INFIX(a) \
00458 (m_larg ? m_larg->toString(params) : "<NULL>") + " " + a + " " + (m_rarg ? m_rarg->toString(params) : "<NULL>")
00459 return INFIX(tokenToString());
00460 }
00461
00462 void BinaryExpr::getQueryParameters(QuerySchemaParameterList& params)
00463 {
00464 if (m_larg)
00465 m_larg->getQueryParameters(params);
00466 if (m_rarg)
00467 m_rarg->getQueryParameters(params);
00468 }
00469
00470
00471 ConstExpr::ConstExpr( int token, const QVariant& val)
00472 : BaseExpr( token )
00473 , value(val)
00474 {
00475 m_cl = KexiDBExpr_Const;
00476 }
00477
00478 ConstExpr::ConstExpr(const ConstExpr& expr)
00479 : BaseExpr(expr)
00480 , value(expr.value)
00481 {
00482 }
00483
00484 ConstExpr::~ConstExpr()
00485 {
00486 }
00487
00488 ConstExpr* ConstExpr::copy() const
00489 {
00490 return new ConstExpr(*this);
00491 }
00492
00493 Field::Type ConstExpr::type()
00494 {
00495 if (m_token==SQL_NULL)
00496 return Field::Null;
00497 else if (m_token==INTEGER_CONST) {
00498
00499
00500 if (value.type() == QVariant::Int || value.type() == QVariant::UInt) {
00501 Q_LLONG v = value.toInt();
00502 if (v <= 0xff && v > -0x80)
00503 return Field::Byte;
00504 if (v <= 0xffff && v > -0x8000)
00505 return Field::ShortInteger;
00506 return Field::Integer;
00507 }
00508 return Field::BigInteger;
00509 }
00510 else if (m_token==CHARACTER_STRING_LITERAL) {
00511
00512 if (value.toString().length() > Field::defaultTextLength())
00513 return Field::LongText;
00514 else
00515 return Field::Text;
00516 }
00517 else if (m_token==REAL_CONST)
00518 return Field::Double;
00519 else if (m_token==DATE_CONST)
00520 return Field::Date;
00521 else if (m_token==DATETIME_CONST)
00522 return Field::DateTime;
00523 else if (m_token==TIME_CONST)
00524 return Field::Time;
00525
00526 return Field::InvalidType;
00527 }
00528
00529 QString ConstExpr::debugString()
00530 {
00531 return QString("ConstExpr('") + tokenToDebugString() +"'," + toString()
00532 + QString(",type=%1)").arg(Driver::defaultSQLTypeName(type()));
00533 }
00534
00535 QString ConstExpr::toString(QuerySchemaParameterValueListIterator* params)
00536 {
00537 Q_UNUSED(params);
00538 if (m_token==SQL_NULL)
00539 return "NULL";
00540 else if (m_token==CHARACTER_STRING_LITERAL)
00541
00542 return "'" + value.toString() + "'";
00543 else if (m_token==REAL_CONST)
00544 return QString::number(value.toPoint().x())+"."+QString::number(value.toPoint().y());
00545 else if (m_token==DATE_CONST)
00546 return "'" + value.toDate().toString(Qt::ISODate) + "'";
00547 else if (m_token==DATETIME_CONST)
00548 return "'" + value.toDateTime().date().toString(Qt::ISODate)
00549 + " " + value.toDateTime().time().toString(Qt::ISODate) + "'";
00550 else if (m_token==TIME_CONST)
00551 return "'" + value.toTime().toString(Qt::ISODate) + "'";
00552
00553 return value.toString();
00554 }
00555
00556 void ConstExpr::getQueryParameters(QuerySchemaParameterList& params)
00557 {
00558 Q_UNUSED(params);
00559 }
00560
00561 bool ConstExpr::validate(ParseInfo& parseInfo)
00562 {
00563 if (!BaseExpr::validate(parseInfo))
00564 return false;
00565
00566 return type()!=Field::InvalidType;
00567 }
00568
00569
00570 QueryParameterExpr::QueryParameterExpr(const QString& message)
00571 : ConstExpr( QUERY_PARAMETER, message )
00572 , m_type(Field::Text)
00573 {
00574 m_cl = KexiDBExpr_QueryParameter;
00575 }
00576
00577 QueryParameterExpr::QueryParameterExpr(const QueryParameterExpr& expr)
00578 : ConstExpr(expr)
00579 , m_type(expr.m_type)
00580 {
00581 }
00582
00583 QueryParameterExpr::~QueryParameterExpr()
00584 {
00585 }
00586
00587 QueryParameterExpr* QueryParameterExpr::copy() const
00588 {
00589 return new QueryParameterExpr(*this);
00590 }
00591
00592 Field::Type QueryParameterExpr::type()
00593 {
00594 return m_type;
00595 }
00596
00597 void QueryParameterExpr::setType(Field::Type type)
00598 {
00599 m_type = type;
00600 }
00601
00602 QString QueryParameterExpr::debugString()
00603 {
00604 return QString("QueryParameterExpr('") + QString::fromLatin1("[%2]").arg(value.toString())
00605 + QString("',type=%1)").arg(Driver::defaultSQLTypeName(type()));
00606 }
00607
00608 QString QueryParameterExpr::toString(QuerySchemaParameterValueListIterator* params)
00609 {
00610 return params ? params->getPreviousValueAsString(type()) : QString::fromLatin1("[%2]").arg(value.toString());
00611 }
00612
00613 void QueryParameterExpr::getQueryParameters(QuerySchemaParameterList& params)
00614 {
00615 QuerySchemaParameter param;
00616 param.message = value.toString();
00617 param.type = type();
00618 params.append( param );
00619 }
00620
00621 bool QueryParameterExpr::validate(ParseInfo& parseInfo)
00622 {
00623 Q_UNUSED(parseInfo);
00624 return type()!=Field::InvalidType;
00625 }
00626
00627
00628 VariableExpr::VariableExpr(const QString& _name)
00629 : BaseExpr( 0 )
00630 , name(_name)
00631 , field(0)
00632 , tablePositionForField(-1)
00633 , tableForQueryAsterisk(0)
00634 {
00635 m_cl = KexiDBExpr_Variable;
00636 }
00637
00638 VariableExpr::VariableExpr(const VariableExpr& expr)
00639 : BaseExpr(expr)
00640 , name(expr.name)
00641 , field(expr.field)
00642 , tablePositionForField(expr.tablePositionForField)
00643 , tableForQueryAsterisk(expr.tableForQueryAsterisk)
00644 {
00645 }
00646
00647 VariableExpr::~VariableExpr()
00648 {
00649 }
00650
00651 VariableExpr* VariableExpr::copy() const
00652 {
00653 return new VariableExpr(*this);
00654 }
00655
00656 QString VariableExpr::debugString()
00657 {
00658 return QString("VariableExpr(") + name
00659 + QString(",type=%1)").arg(field ? Driver::defaultSQLTypeName(type()) : QString("FIELD NOT DEFINED YET"));
00660 }
00661
00662 QString VariableExpr::toString(QuerySchemaParameterValueListIterator* params)
00663 {
00664 Q_UNUSED(params);
00665 return name;
00666 }
00667
00668 void VariableExpr::getQueryParameters(QuerySchemaParameterList& params)
00669 {
00670 Q_UNUSED(params);
00671 }
00672
00674 Field::Type VariableExpr::type()
00675 {
00676 if (field)
00677 return field->type();
00678
00679
00680 return Field::InvalidType;
00681 }
00682
00683 #define IMPL_ERROR(errmsg) parseInfo.errMsg = "Implementation error"; parseInfo.errDescr = errmsg
00684
00685 bool VariableExpr::validate(ParseInfo& parseInfo)
00686 {
00687 if (!BaseExpr::validate(parseInfo))
00688 return false;
00689 field = 0;
00690 tablePositionForField = -1;
00691 tableForQueryAsterisk = 0;
00692
00693
00694 KexiDBDbg << "checking variable name: " << name << endl;
00695 int dotPos = name.find('.');
00696 QString tableName, fieldName;
00697
00698 if (dotPos>0) {
00699 tableName = name.left(dotPos);
00700 fieldName = name.mid(dotPos+1);
00701 }
00702 if (tableName.isEmpty()) {
00703 fieldName = name;
00704 if (fieldName=="*") {
00705
00706 return true;
00707 }
00708
00709
00710 Field *firstField = 0;
00711 foreach_list(TableSchema::ListIterator, it, *parseInfo.querySchema->tables()) {
00712 Field *f = it.current()->field(fieldName);
00713 if (f) {
00714 if (!firstField) {
00715 firstField = f;
00716 }
00717 else if (f->table()!=firstField->table()) {
00718
00719 parseInfo.errMsg = i18n("Ambiguous field name");
00720 parseInfo.errDescr = i18n("Both table \"%1\" and \"%2\" have defined \"%3\" field. "
00721 "Use \"<tableName>.%4\" notation to specify table name.")
00722 .arg(firstField->table()->name()).arg(f->table()->name())
00723 .arg(fieldName).arg(fieldName);
00724 return false;
00725 }
00726 }
00727 }
00728 if (!firstField) {
00729 parseInfo.errMsg = i18n("Field not found");
00730 parseInfo.errDescr = i18n("Table containing \"%1\" field not found").arg(fieldName);
00731 return false;
00732 }
00733
00734 field = firstField;
00735
00736 return true;
00737 }
00738
00739
00740 tableName = tableName.lower();
00741 TableSchema *ts = parseInfo.querySchema->table( tableName );
00742 if (ts) {
00743
00744 const QValueList<int> tPositions = parseInfo.querySchema->tablePositions(tableName);
00745 QValueList<int>::ConstIterator it = tPositions.constBegin();
00746 QCString tableAlias;
00747 bool covered = true;
00748 for (; it!=tPositions.constEnd() && covered; ++it) {
00749 tableAlias = parseInfo.querySchema->tableAlias(*it);
00750 if (tableAlias.isEmpty() || tableAlias.lower()==tableName.latin1())
00751 covered = false;
00752 KexiDBDbg << " --" << "covered by " << tableAlias << " alias" << endl;
00753 }
00754 if (covered) {
00755 parseInfo.errMsg = i18n("Could not access the table directly using its name");
00756 parseInfo.errDescr = i18n("Table \"%1\" is covered by aliases. Instead of \"%2\", "
00757 "you can write \"%3\"").arg(tableName)
00758 .arg(tableName+"."+fieldName).arg(tableAlias+"."+fieldName.latin1());
00759 return false;
00760 }
00761 }
00762
00763 int tablePosition = -1;
00764 if (!ts) {
00765 tablePosition = parseInfo.querySchema->tablePositionForAlias( tableName.latin1() );
00766 if (tablePosition>=0) {
00767 ts = parseInfo.querySchema->tables()->at(tablePosition);
00768 if (ts) {
00769
00770 }
00771 }
00772 }
00773
00774 if (!ts) {
00775 parseInfo.errMsg = i18n("Table not found");
00776 parseInfo.errDescr = i18n("Unknown table \"%1\"").arg(tableName);
00777 return false;
00778 }
00779
00780 QValueList<int> *positionsList = parseInfo.repeatedTablesAndAliases[ tableName ];
00781 if (!positionsList) {
00782 IMPL_ERROR(tableName + "." + fieldName + ", !positionsList ");
00783 return false;
00784 }
00785
00786
00787 if (fieldName=="*") {
00788 if (positionsList->count()>1) {
00789 parseInfo.errMsg = i18n("Ambiguous \"%1.*\" expression").arg(tableName);
00790 parseInfo.errDescr = i18n("More than one \"%1\" table or alias defined").arg(tableName);
00791 return false;
00792 }
00793 tableForQueryAsterisk = ts;
00794
00795 return true;
00796 }
00797
00798
00799 Field *realField = ts->field(fieldName);
00800 if (!realField) {
00801 parseInfo.errMsg = i18n("Field not found");
00802 parseInfo.errDescr = i18n("Table \"%1\" has no \"%2\" field")
00803 .arg(tableName).arg(fieldName);
00804 return false;
00805 }
00806
00807
00808
00809 int numberOfTheSameFields = 0;
00810 for (QValueList<int>::iterator it = positionsList->begin();
00811 it!=positionsList->end();++it)
00812 {
00813 TableSchema *otherTS = parseInfo.querySchema->tables()->at(*it);
00814 if (otherTS->field(fieldName))
00815 numberOfTheSameFields++;
00816 if (numberOfTheSameFields>1) {
00817 parseInfo.errMsg = i18n("Ambiguous \"%1.%2\" expression")
00818 .arg(tableName).arg(fieldName);
00819 parseInfo.errDescr = i18n("More than one \"%1\" table or alias defined containing \"%2\" field")
00820 .arg(tableName).arg(fieldName);
00821 return false;
00822 }
00823 }
00824 field = realField;
00825 tablePositionForField = tablePosition;
00826
00827
00828 return true;
00829 }
00830
00831
00832 static QValueList<QCString> FunctionExpr_builtIns;
00833 static const char* FunctionExpr_builtIns_[] =
00834 {"SUM", "MIN", "MAX", "AVG", "COUNT", "STD", "STDDEV", "VARIANCE", 0 };
00835
00836 QValueList<QCString> FunctionExpr::builtInAggregates()
00837 {
00838 if (FunctionExpr_builtIns.isEmpty()) {
00839 for (const char **p = FunctionExpr_builtIns_; *p; p++)
00840 FunctionExpr_builtIns << *p;
00841 }
00842 return FunctionExpr_builtIns;
00843 }
00844
00845 FunctionExpr::FunctionExpr( const QString& _name, NArgExpr* args_ )
00846 : BaseExpr( 0 )
00847 , name(_name)
00848 , args(args_)
00849 {
00850 if (isBuiltInAggregate(name.latin1()))
00851 m_cl = KexiDBExpr_Aggregation;
00852 else
00853 m_cl = KexiDBExpr_Function;
00854 if (args)
00855 args->setParent( this );
00856 }
00857
00858 FunctionExpr::FunctionExpr( const FunctionExpr& expr )
00859 : BaseExpr( 0 )
00860 , name(expr.name)
00861 , args(expr.args ? args->copy() : 0)
00862 {
00863 if (args)
00864 args->setParent( this );
00865 }
00866
00867 FunctionExpr::~FunctionExpr()
00868 {
00869 delete args;
00870 }
00871
00872 FunctionExpr* FunctionExpr::copy() const
00873 {
00874 return new FunctionExpr(*this);
00875 }
00876
00877 QString FunctionExpr::debugString()
00878 {
00879 QString res;
00880 res.append( QString("FunctionExpr(") + name );
00881 if (args)
00882 res.append(QString(",") + args->debugString());
00883 res.append(QString(",type=%1)").arg(Driver::defaultSQLTypeName(type())));
00884 return res;
00885 }
00886
00887 QString FunctionExpr::toString(QuerySchemaParameterValueListIterator* params)
00888 {
00889 return name + "(" + (args ? args->toString(params) : QString::null) + ")";
00890 }
00891
00892 void FunctionExpr::getQueryParameters(QuerySchemaParameterList& params)
00893 {
00894 args->getQueryParameters(params);
00895 }
00896
00897 Field::Type FunctionExpr::type()
00898 {
00899
00900 return Field::InvalidType;
00901 }
00902
00903 bool FunctionExpr::validate(ParseInfo& parseInfo)
00904 {
00905 if (!BaseExpr::validate(parseInfo))
00906 return false;
00907
00908 return args ? args->validate(parseInfo) : true;
00909 }
00910
00911 bool FunctionExpr::isBuiltInAggregate(const QCString& fname)
00912 {
00913 return builtInAggregates().find(fname.upper())!=FunctionExpr_builtIns.end();
00914 }