diff --git a/kexi/kexidb/drivers/mysql/mysqldriver.h b/kexi/kexidb/drivers/mysql/mysqldriver.h --- a/kexi/kexidb/drivers/mysql/mysqldriver.h +++ b/kexi/kexidb/drivers/mysql/mysqldriver.h @@ -2,7 +2,7 @@ Copyright (C) 2002 Lucijan Busch Daniel Molkentin Copyright (C) 2003 Joseph Wenninger -Copyright (C) 2003-2015 Jarosław Staniek +Copyright (C) 2003-2016 Jarosław Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -66,6 +66,11 @@ virtual QString unicodeFunctionToString(KexiDB::NArgExpr *args, QuerySchemaParameterValueListIterator* params) const; + //! Generates native (driver-specific) function call for concatenation of two strings. + //! Uses CONCAT(). + virtual QString concatenateFunctionToString(KexiDB::BinaryExpr *args, + QuerySchemaParameterValueListIterator* params) const; + protected: virtual QString drv_escapeIdentifier(const QString& str) const; virtual QByteArray drv_escapeIdentifier(const QByteArray& str) const; diff --git a/kexi/kexidb/drivers/mysql/mysqldriver.cpp b/kexi/kexidb/drivers/mysql/mysqldriver.cpp --- a/kexi/kexidb/drivers/mysql/mysqldriver.cpp +++ b/kexi/kexidb/drivers/mysql/mysqldriver.cpp @@ -2,7 +2,7 @@ Copyright (C) 2002 Lucijan Busch Daniel Molkentin Copyright (C) 2003 Joseph Wenninger -Copyright (C) 2003-2015 Jarosław Staniek +Copyright (C) 2003-2016 Jarosław Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -223,5 +223,10 @@ return QString::fromLatin1("ORD(CONVERT(%1 USING UTF16))").arg(args->arg(0)->toString(this, params)); } -#include "mysqldriver.moc" +QString MySqlDriver::concatenateFunctionToString(KexiDB::BinaryExpr *args, QuerySchemaParameterValueListIterator* params) const +{ + return QString::fromLatin1("CONCAT(%1, %2)").arg(args->left()->toString(this, params)) + .arg(args->right()->toString(this, params)); +} +#include "mysqldriver.moc" diff --git a/libs/db/driver.h b/libs/db/driver.h --- a/libs/db/driver.h +++ b/libs/db/driver.h @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2003-2015 Jarosław Staniek + Copyright (C) 2003-2016 Jarosław Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -41,6 +41,7 @@ class DriverManager; class DriverBehaviour; class DriverPrivate; +class BinaryExpr; class NArgExpr; class QuerySchemaParameterValueListIterator; @@ -341,6 +342,14 @@ virtual QString unicodeFunctionToString(KexiDB::NArgExpr *args, QuerySchemaParameterValueListIterator* params) const; + //! Generates native (driver-specific) function call for concatenation of two strings. + //! Default implementation USES infix "||" operator. + //! Special case is for MYSQL (CONCAT()). + //! @todo API supporting NArgExpr would be useful so instead of a||b||c can be expressed as + //! CONCAT(a,b,c), not by CONCAT(CONCAT(a,b),c). This requires changes to the SQL parser. + virtual QString concatenateFunctionToString(KexiDB::BinaryExpr *args, + QuerySchemaParameterValueListIterator* params) const; + protected: /*! Used by DriverManager. Note for driver developers: Reimplement this. diff --git a/libs/db/driver.cpp b/libs/db/driver.cpp --- a/libs/db/driver.cpp +++ b/libs/db/driver.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2003-2015 Jarosław Staniek + Copyright (C) 2003-2016 Jarosław Staniek This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -420,6 +420,11 @@ return KexiDB::FunctionExpr::toString(QLatin1String("UNICODE"), this, args, params); } +QString Driver::concatenateFunctionToString(KexiDB::BinaryExpr *args, QuerySchemaParameterValueListIterator* params) const +{ + return args->left()->toString(this, params) + QLatin1String("||") + args->right()->toString(this, params); +} + //--------------- K_GLOBAL_STATIC_WITH_ARGS(KexiDB::StaticSetOfStrings, KexiDB_kexiSQLKeywords, (DriverPrivate::kexiSQLKeywords)) diff --git a/libs/db/expression.cpp b/libs/db/expression.cpp --- a/libs/db/expression.cpp +++ b/libs/db/expression.cpp @@ -1,5 +1,5 @@ /* This file is part of the KDE project - Copyright (C) 2003-2015 Jarosław Staniek + Copyright (C) 2003-2016 Jarosław Staniek Based on nexp.cpp : Parser module of Python-like language (C) 2001 Jarosław Staniek, MIMUW (www.mimuw.edu.pl) @@ -537,9 +537,18 @@ switch (m_token) { case BITWISE_SHIFT_RIGHT: case BITWISE_SHIFT_LEFT: - case CONCATENATION: + return lt; + case '+': + case CONCATENATION: { + const bool ltText = Field::isTextType(lt); + const bool rtText = Field::isTextType(rt); + if (ltText || rtText) { + return (lt == Field::LongText || rt == Field::LongText) ? Field::LongText + : Field::Text; + } return lt; } + } const bool ltInt = Field::isIntegerType(lt); const bool rtInt = Field::isIntegerType(rt); @@ -597,6 +606,15 @@ QString BinaryExpr::toString(const Driver *driver, QuerySchemaParameterValueListIterator* params) { + switch (m_token) { + case '+': + case CONCATENATION: { + const Field::Type t = type(); + if (driver && (t == Field::Text || t == Field::LongText)) { + return driver->concatenateFunctionToString(this, params); + } + } + } #define INFIX(a) \ (m_larg ? m_larg->toString(driver, params) : "") + ' ' + a + ' ' + (m_rarg ? m_rarg->toString(driver, params) : "") return INFIX(tokenToString(driver));