23#include "KDbExpression.h"
25#include "KDbQuerySchema.h"
28#include "KDbParser_p.h"
40class BuiltInAggregates
44 : data({ QStringLiteral(
"SUM"),
45 QStringLiteral(
"MIN"),
46 QStringLiteral(
"MAX"),
47 QStringLiteral(
"AVG"),
48 QStringLiteral(
"COUNT"),
49 QStringLiteral(
"STD"),
50 QStringLiteral(
"STDDEV"),
51 QStringLiteral(
"VARIANCE")
55 const QSet<QString> data;
58Q_GLOBAL_STATIC(BuiltInAggregates, _builtInAggregates)
62enum BuiltInFunctionArgumentType
74 if (argType == AnyText || argType == Any) {
77 else if (argType == AnyInt || argType == AnyNumber) {
80 else if (argType == AnyFloat) {
87class BuiltInFunctionDeclaration
90 inline BuiltInFunctionDeclaration()
91 : defaultReturnType(KDbField::InvalidType), copyReturnTypeFromArg(-1)
94 virtual ~BuiltInFunctionDeclaration() {}
95 virtual KDbField::Type returnType(
const KDbFunctionExpressionData* f, KDbParseInfo* parseInfo)
const {
97 const KDbNArgExpressionData *argsData = f->args.
constData()->convertConst<KDbNArgExpressionData>();
98 if (argsData->containsNullArgument()) {
101 if (copyReturnTypeFromArg >= 0 && copyReturnTypeFromArg < argsData->children.count()) {
102 KDbQueryParameterExpressionData *queryParameterExpressionData
103 = argsData->children.at(copyReturnTypeFromArg)
104 ->convert<KDbQueryParameterExpressionData>();
105 if (queryParameterExpressionData) {
108 for (
size_t i = 0; i < signatures.size(); ++i) {
109 int** signature = signatures[i];
110 const KDbField::Type t = anyMatchingType(signature[copyReturnTypeFromArg][0]);
112 queryParameterExpressionData->m_type = t;
117 return argsData->children.at(copyReturnTypeFromArg)->type();
119 return defaultReturnType;
121 std::vector<int**> signatures;
124 int copyReturnTypeFromArg;
125 friend class BuiltInFunctions;
127 Q_DISABLE_COPY(BuiltInFunctionDeclaration)
131class CoalesceFunctionDeclaration :
public BuiltInFunctionDeclaration
134 CoalesceFunctionDeclaration() {}
135 KDbField::Type returnType(
const KDbFunctionExpressionData* f, KDbParseInfo* parseInfo)
const override {
140 const KDbNArgExpressionData *argsData = f->args.
constData()->convertConst<KDbNArgExpressionData>();
141 foreach(
const ExplicitlySharedExpressionDataPointer &expr, argsData->children) {
142 KDbQueryParameterExpressionData *queryParameterExpressionData = expr->convert<KDbQueryParameterExpressionData>();
144 if (!queryParameterExpressionData && currentType !=
KDbField::Null) {
149 foreach(
const ExplicitlySharedExpressionDataPointer &expr, argsData->children) {
150 KDbQueryParameterExpressionData *queryParameterExpressionData = expr->convert<KDbQueryParameterExpressionData>();
151 if (queryParameterExpressionData) {
153 queryParameterExpressionData->m_type = t;
159 Q_DISABLE_COPY(CoalesceFunctionDeclaration)
167class MinMaxFunctionDeclaration :
public BuiltInFunctionDeclaration
169 Q_DECLARE_TR_FUNCTIONS(MinMaxFunctionDeclaration)
171 MinMaxFunctionDeclaration() {}
172 KDbField::Type returnType(
const KDbFunctionExpressionData* f, KDbParseInfo* parseInfo)
const override {
173 const KDbNArgExpressionData *argsData = f->args.
constData()->convertConst<KDbNArgExpressionData>();
174 if (argsData->children.isEmpty()) {
178 if (nullOrInvalid(type0)) {
182 bool prevTgIsAny = argsData->children.at(0)->convertConst<KDbQueryParameterExpressionData>();
183 for(
int i = 1; i < argsData->children.count(); ++i) {
184 const ExplicitlySharedExpressionDataPointer expr = argsData->children.at(i);
186 if (nullOrInvalid(t)) {
190 const bool tgIsAny = argsData->children.at(i)->convertConst<KDbQueryParameterExpressionData>();
197 }
else if (tgIsAny) {
200 if ((prevTg == KDbField::IntegerGroup || prevTg == KDbField::FloatGroup)
201 && (tg == KDbField::IntegerGroup || tg == KDbField::FloatGroup))
203 if (prevTg == KDbField::IntegerGroup && tg == KDbField::FloatGroup) {
204 prevTg = KDbField::FloatGroup;
212 parseInfo->setErrorMessage(
213 tr(
"Incompatible types in %1() function").arg(f->name));
214 parseInfo->setErrorDescription(
215 tr(
"Argument #%1 of type \"%2\" in function %3() is not "
216 "compatible with previous arguments of type \"%4\".")
230 for(ExplicitlySharedExpressionDataPointer expr : argsData->children) {
231 KDbQueryParameterExpressionData *queryParameterExpressionData = expr->convert<KDbQueryParameterExpressionData>();
232 if (queryParameterExpressionData) {
233 queryParameterExpressionData->m_type = resultType;
249 case KDbField::DateTimeGroup:
return KDbField::DateTime;
262 case KDbField::DateTimeGroup:
return KDbField::DateTime;
268 Q_DISABLE_COPY(MinMaxFunctionDeclaration)
276class RandomFunctionDeclaration :
public BuiltInFunctionDeclaration
278 Q_DECLARE_TR_FUNCTIONS(RandomFunctionDeclaration)
280 RandomFunctionDeclaration() {}
281 KDbField::Type returnType(
const KDbFunctionExpressionData* f, KDbParseInfo* parseInfo)
const override {
282 const KDbNArgExpressionData *argsData = f->args.
constData()->convertConst<KDbNArgExpressionData>();
283 if (argsData->children.isEmpty()) {
286 if (argsData->children.count() == 2) {
287 const KDbConstExpressionData *const0 = argsData->children.at(0)->convertConst<KDbConstExpressionData>();
288 const KDbConstExpressionData *const1 = argsData->children.at(1)->convertConst<KDbConstExpressionData>();
289 if (const0 && const1) {
291 const qlonglong val0 = const0->value.
toLongLong(&ok0);
293 const qlonglong val1 = const1->value.toLongLong(&ok1);
297 parseInfo->setErrorMessage(
298 tr(
"Invalid arguments of %1() function").arg(f->name));
299 parseInfo->setErrorDescription(
300 tr(
"Value of the first argument should be less than "
301 "value of the second argument."));
310 KDbQueryParameterExpressionData *queryParameterExpressionData0
311 = argsData->children.at(0)->convert<KDbQueryParameterExpressionData>();
312 KDbQueryParameterExpressionData *queryParameterExpressionData1
313 = argsData->children.at(1)->convert<KDbQueryParameterExpressionData>();
314 if (queryParameterExpressionData0 && queryParameterExpressionData1) {
319 }
else if (queryParameterExpressionData0 && !queryParameterExpressionData1) {
321 t0 = queryParameterExpressionData0->m_type;
322 t1 = argsData->children.at(1)->type();
323 }
else if (!queryParameterExpressionData0 && queryParameterExpressionData1) {
325 t0 = argsData->children.at(0)->type();
326 t1 = queryParameterExpressionData1->m_type;
328 t0 = argsData->children.at(0)->type();
329 t1 = argsData->children.at(1)->type();
336 Q_DISABLE_COPY(RandomFunctionDeclaration)
343class CeilingFloorFunctionDeclaration :
public BuiltInFunctionDeclaration
346 CeilingFloorFunctionDeclaration() {}
347 KDbField::Type returnType(
const KDbFunctionExpressionData* f, KDbParseInfo* parseInfo)
const override {
349 const KDbNArgExpressionData *argsData = f->args.
constData()->convertConst<KDbNArgExpressionData>();
350 if (argsData->children.count() == 1) {
351 KDbQueryParameterExpressionData *queryParameterExpressionData
352 = argsData->children.at(0)->convert<KDbQueryParameterExpressionData>();
353 if (queryParameterExpressionData) {
375 Q_DISABLE_COPY(CeilingFloorFunctionDeclaration)
380class BuiltInFunctions
386 qDeleteAll(m_functions);
392 BuiltInFunctionDeclaration* value(
const QString &name)
const;
395 QStringList aliases()
const;
397 static int multipleArgs[];
399 QHash<QString, BuiltInFunctionDeclaration*> m_functions;
400 QHash<QString, BuiltInFunctionDeclaration*> m_aliases;
401 Q_DISABLE_COPY(BuiltInFunctions)
404int BuiltInFunctions::multipleArgs[] = { 0 };
406BuiltInFunctions::BuiltInFunctions()
408 BuiltInFunctionDeclaration *decl;
409#define _TYPES(name, ...) static int name[] = { __VA_ARGS__, KDbField::InvalidType }
414 Q_UNUSED(argAnyFloatOrNull);
417 Q_UNUSED(argBLOBOrNull);
422#define _SIG(name, ...) \
423 static int* name[] = { __VA_ARGS__, nullptr }; \
424 decl->signatures.push_back(name)
428 decl->signatures.push_back(sig0)
430 static int* sig0[] = {
nullptr };
432 m_functions.insert(QLatin1String(
"ABS"), decl =
new BuiltInFunctionDeclaration);
441 decl->copyReturnTypeFromArg = 0;
442 _SIG(abs_1, argAnyNumberOrNull);
444 m_functions.insert(QLatin1String(
"CEILING"), decl =
new CeilingFloorFunctionDeclaration);
453 _SIG(ceiling, argAnyNumberOrNull);
455 m_functions.insert(QLatin1String(
"CHAR"), decl =
new BuiltInFunctionDeclaration);
462 static int char_min_args[] = { 0 };
463 _SIG(char_N, argAnyIntOrNull, multipleArgs, char_min_args);
465 m_functions.insert(QLatin1String(
"COALESCE"), decl =
new CoalesceFunctionDeclaration);
471 static int coalesce_min_args[] = { 2 };
472 _SIG(coalesce_N, argAnyOrNull, multipleArgs, coalesce_min_args);
474 m_functions.insert(QLatin1String(
"FLOOR"), decl =
new CeilingFloorFunctionDeclaration);
483 _SIG(floor, argAnyNumberOrNull);
485 m_functions.insert(QLatin1String(
"GREATEST"), decl =
new MinMaxFunctionDeclaration);
486 m_aliases.insert(QLatin1String(
"MAX"), decl);
514 static int greatest_min_args[] = { 2 };
515 _SIG(greatest_N, argAnyOrNull, multipleArgs, greatest_min_args);
517 m_functions.insert(QLatin1String(
"HEX"), decl =
new BuiltInFunctionDeclaration);
529 _SIG(hex_1, argAnyTextBLOBOrNull);
531 m_functions.insert(QLatin1String(
"IFNULL"), decl =
new CoalesceFunctionDeclaration);
539 _SIG(ifnull_2, argAnyOrNull, argAnyOrNull);
541 m_functions.insert(QLatin1String(
"INSTR"), decl =
new BuiltInFunctionDeclaration);
557 _SIG(instr_2, argAnyTextOrNull, argAnyTextOrNull);
559 m_functions.insert(QLatin1String(
"LEAST"), decl =
new MinMaxFunctionDeclaration);
560 m_aliases.insert(QLatin1String(
"MIN"), decl);
584 static int least_min_args[] = { 2 };
585 _SIG(least_N, argAnyOrNull, multipleArgs, least_min_args);
587 m_functions.insert(QLatin1String(
"LENGTH"), decl =
new BuiltInFunctionDeclaration);
604 _SIG(length_1, argAnyTextBLOBOrNull);
606 m_functions.insert(QLatin1String(
"LOWER"), decl =
new BuiltInFunctionDeclaration);
617 _SIG(lower_1, argAnyTextOrNull);
619 m_functions.insert(QLatin1String(
"LTRIM"), decl =
new BuiltInFunctionDeclaration);
633 _SIG(ltrim_1, argAnyTextOrNull);
634 _SIG(ltrim_2, argAnyTextOrNull, argAnyTextOrNull);
636 m_functions.insert(QLatin1String(
"NULLIF"), decl =
new BuiltInFunctionDeclaration);
647 decl->copyReturnTypeFromArg = 0;
648 _SIG(nullif_2, argAnyOrNull, argAnyOrNull);
650 m_functions.insert(QLatin1String(
"RANDOM"), decl =
new RandomFunctionDeclaration);
672 _SIG(random_2, argAnyIntOrNull, argAnyIntOrNull);
674 m_functions.insert(QLatin1String(
"ROUND"), decl =
new BuiltInFunctionDeclaration);
683 decl->copyReturnTypeFromArg = 0;
684 _SIG(round_1, argAnyNumberOrNull);
685 _SIG(round_2, argAnyNumberOrNull, argAnyIntOrNull);
687 m_functions.insert(QLatin1String(
"RTRIM"), decl =
new BuiltInFunctionDeclaration);
701 _SIG(rtrim_1, argAnyTextOrNull);
702 _SIG(rtrim_2, argAnyTextOrNull, argAnyTextOrNull);
704 m_functions.insert(QLatin1String(
"SOUNDEX"), decl =
new BuiltInFunctionDeclaration);
716 _SIG(soundex, argAnyTextOrNull);
718 m_functions.insert(QLatin1String(
"SUBSTR"), decl =
new BuiltInFunctionDeclaration);
726 _SIG(substr_2, argAnyTextOrNull, argAnyIntOrNull);
729 _SIG(substr_3, argAnyTextOrNull, argAnyIntOrNull, argAnyIntOrNull);
730 decl->copyReturnTypeFromArg = 0;
732 m_functions.insert(QLatin1String(
"TRIM"), decl =
new BuiltInFunctionDeclaration);
746 _SIG(trim_1, argAnyTextOrNull);
747 _SIG(trim_2, argAnyTextOrNull, argAnyTextOrNull);
749 m_functions.insert(QLatin1String(
"UNICODE"), decl =
new BuiltInFunctionDeclaration);
759 _SIG(unicode_1, argAnyTextOrNull);
761 m_functions.insert(QLatin1String(
"UPPER"), decl =
new BuiltInFunctionDeclaration);
772 _SIG(upper_1, argAnyTextOrNull);
774#ifdef KDB_ENABLE_SQLITE_SPECIFIC_FUNCTIONS
775 m_functions.insert(QLatin1String(
"GLOB"), decl =
new BuiltInFunctionDeclaration);
785 _SIG(glob_2, argAnyTextOrNull, argAnyOrNull );
787 m_functions.insert(QLatin1String(
"LIKE"), decl =
new BuiltInFunctionDeclaration);
796 _SIG(like_2, argAnyTextOrNull, argAnyTextOrNull);
797 _SIG(like_3, argAnyTextOrNull, argAnyTextOrNull, argAnyTextOrNull);
801BuiltInFunctionDeclaration* BuiltInFunctions::value(
const QString &name)
const
803 BuiltInFunctionDeclaration* f = m_functions.value(name);
805 f = m_aliases.value(name);
812 return m_aliases.keys();
815Q_GLOBAL_STATIC(BuiltInFunctions, _builtInFunctions)
819KDbFunctionExpressionData::KDbFunctionExpressionData()
822 ExpressionDebug <<
"FunctionExpressionData" << ref;
823 setArguments(ExplicitlySharedExpressionDataPointer());
826KDbFunctionExpressionData::KDbFunctionExpressionData(
const QString& aName,
827 ExplicitlySharedExpressionDataPointer arguments)
831 setArguments(arguments);
832 ExpressionDebug <<
"FunctionExpressionData" << ref << *args;
835KDbFunctionExpressionData::~KDbFunctionExpressionData()
837 ExpressionDebug <<
"~FunctionExpressionData" << ref;
842 ExpressionDebug <<
"FunctionExpressionData::clone" << *
this;
843 KDbFunctionExpressionData *cloned =
new KDbFunctionExpressionData(*
this);
844 ExpressionDebug <<
"FunctionExpressionData::clone" << *cloned;
845 cloned->args = args->clone();
851 dbg.
nospace() <<
"FunctionExp(" << name;
854 args.data()->debug(dbg, callStack);
873 KDb::ExpressionCallStack* callStack)
const
875 KDbNArgExpressionData *argsData = args->convert<KDbNArgExpressionData>();
876 if (name == QLatin1String(
"HEX")) {
881 else if (name == QLatin1String(
"IFNULL")) {
886 else if (name == QLatin1String(
"LENGTH")) {
891 else if (name == QLatin1String(
"GREATEST") || name == QLatin1String(
"MAX")
892 || name == QLatin1String(
"LEAST") || name == QLatin1String(
"MIN"))
896 QString::fromLatin1(greatestOrLeastName(name.toLatin1())), KDbNArgExpression(args), params, callStack);
900 else if (name == QLatin1String(
"RANDOM")) {
905 else if (name == QLatin1String(
"CEILING") || name == QLatin1String(
"FLOOR")) {
910 else if (name == QLatin1String(
"UNICODE")) {
915 return KDbFunctionExpressionData::toString(name, driver, argsData, params, callStack);
921 args->getQueryParameters(params);
927 const BuiltInFunctionDeclaration *decl = _builtInFunctions->value(name);
929 return decl->returnType(
this,
nullptr);
935static void setIncorrectNumberOfArgumentsErrorMessage(KDbParseInfo *parseInfo,
int count,
936 const std::vector<int> &argCounts,
939 parseInfo->setErrorMessage(
940 KDbFunctionExpressionData::tr(
"Incorrect number of arguments (%1)").arg(count));
941 const int maxArgCount = argCounts[argCounts.size() - 1];
942 const int minArgCount = argCounts[0];
944 if (count > maxArgCount) {
945 firstSentence = KDbFunctionExpressionData::tr(
"Too many arguments.%1",
"don't use space before %1")
948 if (count < minArgCount) {
949 firstSentence = KDbFunctionExpressionData::tr(
"Too few arguments.%1",
"don't use space before %1")
952 if (argCounts.size() == 1) {
953 const int c = argCounts[0];
955 parseInfo->setErrorDescription(
956 KDbFunctionExpressionData::tr(
"%1%2() function does not accept any arguments.")
957 .arg(firstSentence, name));
960 parseInfo->setErrorDescription(
961 KDbFunctionExpressionData::tr(
"%1%2() function requires 1 argument.")
962 .arg(firstSentence, name));
967 parseInfo->setErrorDescription(
968 KDbFunctionExpressionData::tr(
"%1%2() function requires %3 argument(s).",
"", c)
969 .arg(firstSentence, name).arg(c));
972 else if (argCounts.size() == 2) {
973 const int c1 = argCounts[0];
974 const int c2 = argCounts[1];
976 parseInfo->setErrorDescription(
977 KDbFunctionExpressionData::tr(
"%1%2() function requires 0 or 1 argument.",
978 "the function requires zero or one argument")
979 .arg(firstSentence, name));
984 parseInfo->setErrorDescription(
985 KDbFunctionExpressionData::tr(
"%1%2() function requires %3 or %4 argument(s).",
"", c2)
986 .arg(firstSentence, name).arg(c1).arg(c2));
989 else if (argCounts.size() == 3) {
992 parseInfo->setErrorDescription(
993 KDbFunctionExpressionData::tr(
"%1%2() function requires %3 or %4 or %5 argument(s).",
"", argCounts[2])
994 .arg(firstSentence, name).arg(argCounts[0])
995 .arg(argCounts[1]).arg(argCounts[2]));
999 for(std::vector<int>::const_iterator it(argCounts.begin()); it != argCounts.end(); ++it) {
1003 listCounts = KDbFunctionExpressionData::tr(
"%1 or %2").
arg(listCounts).
arg(*it);
1006 parseInfo->setErrorDescription(
1007 KDbFunctionExpressionData::tr(
"%1%2() function requires %3 argument(s).",
"",
1008 argCounts[argCounts.size() - 1])
1009 .arg(firstSentence, name, listCounts));
1013static void setIncorrectTypeOfArgumentsErrorMessage(KDbParseInfo *parseInfo,
int argNum,
1015 int *argTypes,
const QString &name)
1018 int *argType = argTypes;
1021 listTypes += KDbFunctionExpressionData::tr(
" or ");
1025 listTypes += KDbFunctionExpressionData::tr(
"\"%1\"")
1029 listTypes += KDbFunctionExpressionData::tr(
"\"%1\"")
1032 else if (*argType == AnyText) {
1033 listTypes += KDbFunctionExpressionData::tr(
"\"%1\"")
1036 else if (*argType == AnyInt) {
1037 listTypes += KDbFunctionExpressionData::tr(
"\"%1\"")
1040 else if (*argType == AnyFloat) {
1041 listTypes += KDbFunctionExpressionData::tr(
"\"%1\"")
1045 else if (*argType == AnyNumber) {
1046 listTypes += KDbFunctionExpressionData::tr(
"\"Number\"");
1048 else if (*argType == Any) {
1049 listTypes += KDbFunctionExpressionData::tr(
"\"Any\"",
"Any data type");
1053 parseInfo->setErrorMessage(KDbFunctionExpressionData::tr(
"Incorrect type of argument"));
1055 = KDbFunctionExpressionData::tr(
"Specified argument is of type \"%1\".")
1058 parseInfo->setErrorDescription(
1059 KDbFunctionExpressionData::tr(
"%1() function's first argument should be of type %2. %3")
1060 .arg(name, listTypes, lastSentence));
1062 else if (argNum == 1) {
1063 parseInfo->setErrorDescription(
1064 KDbFunctionExpressionData::tr(
"%1() function's second argument should be of type %2. %3")
1065 .arg(name, listTypes, lastSentence));
1067 else if (argNum == 2) {
1068 parseInfo->setErrorDescription(
1069 KDbFunctionExpressionData::tr(
"%1() function's third argument should be of type %2. %3")
1070 .arg(name, listTypes, lastSentence));
1072 else if (argNum == 3) {
1073 parseInfo->setErrorDescription(
1074 KDbFunctionExpressionData::tr(
"%1() function's fourth argument should be of type %2. %3")
1075 .arg(name, listTypes, lastSentence));
1077 else if (argNum == 4) {
1078 parseInfo->setErrorDescription(
1079 KDbFunctionExpressionData::tr(
"%1() function's fifth argument should be of type %2. %3")
1080 .arg(name, listTypes, lastSentence));
1083 parseInfo->setErrorDescription(
1084 KDbFunctionExpressionData::tr(
"%1() function's %2 argument should be of type %3. %4")
1085 .arg(name).arg(argNum + 1).arg(listTypes, lastSentence));
1092 if (argType == AnyText) {
1097 else if (argType == AnyInt) {
1102 else if (argType == AnyFloat) {
1107 else if (argType == AnyNumber) {
1112 else if (argType == Any) {
1116 if (argType == actualType) {
1123static int findMatchingType(
int *argTypePtr,
KDbField::Type actualType)
1126 if (typeMatches(*argTypePtr, actualType)) {
1134 KDb::ExpressionCallStack* callStack)
1136 if (!args->validate(parseInfo, callStack)) {
1139 if (args->token !=
',') {
1142 if (args->children.count() > KDB_MAX_FUNCTION_ARGS) {
1143 parseInfo->setErrorMessage(
1144 tr(
"Too many arguments for function."));
1145 parseInfo->setErrorDescription(
1146 tr(
"Maximum number of arguments for function %1() is %2.")
1147 .arg(args->children.count()).arg(KDB_MAX_FUNCTION_ARGS));
1150 if (!args->validate(parseInfo)) {
1153 if (name.isEmpty()) {
1156 const BuiltInFunctionDeclaration *decl = _builtInFunctions->value(name);
1161 if (argsData->containsInvalidArgument()) {
1166 int **signature =
nullptr;
1167 bool multipleArgs =
false;
1169 const int count = args->children.count();
1170 bool properArgCount =
false;
1171 std::vector<int> argCounts;
1173 argCounts.resize(decl->signatures.size());
1174 for(std::vector<int**>::const_iterator it(decl->signatures.begin());
1175 it != decl->signatures.end(); ++it, ++i)
1178 int **arg = signature;
1179 int expectedCount = 0;
1180 while(*arg && *arg != BuiltInFunctions::multipleArgs) {
1184 multipleArgs = *arg == BuiltInFunctions::multipleArgs;
1187 const int minArgs = arg[0][0];
1188 properArgCount = count >= minArgs;
1189 if (!properArgCount) {
1190 parseInfo->setErrorMessage(
1191 tr(
"Incorrect number of arguments (%1)").arg(count));
1193 parseInfo->setErrorDescription(
1194 tr(
"Too few arguments. %1() function requires "
1195 "at least one argument.").arg(name));
1197 else if (minArgs == 2) {
1198 parseInfo->setErrorDescription(
1199 tr(
"Too few arguments. %1() function requires "
1200 "at least two arguments.").arg(name));
1202 else if (minArgs == 3) {
1203 parseInfo->setErrorDescription(
1204 tr(
"Too few arguments. %1() function requires "
1205 "at least three arguments.").arg(name));
1208 parseInfo->setErrorDescription(
1209 tr(
"Too few arguments. %1() function requires "
1210 "at least %2 arguments.").arg(name).arg(minArgs));
1216 else if (count == expectedCount) {
1217 properArgCount =
true;
1221 argCounts[i] = expectedCount;
1224 if (!properArgCount) {
1225 const std::vector<int>::iterator last = std::unique(argCounts.begin(), argCounts.end());
1226 argCounts.erase(last, argCounts.end());
1227 std::sort(argCounts.begin(), argCounts.end());
1228 setIncorrectNumberOfArgumentsErrorMessage(parseInfo, count, argCounts, name);
1235 int **arg = signature;
1236 int *typesForAllArgs = arg[0];
1238 foreach(
const ExplicitlySharedExpressionDataPointer &expr, args->children) {
1241 if (!isQueryParameter) {
1242 const int matchingType = findMatchingType(typesForAllArgs, exprType);
1244 setIncorrectTypeOfArgumentsErrorMessage(parseInfo, i, exprType, typesForAllArgs, name);
1252 int **arg = signature;
1254 foreach(
const ExplicitlySharedExpressionDataPointer &expr, args->children) {
1257 if (!isQueryParameter) {
1258 const int matchingType = findMatchingType(arg[0], exprType);
1260 setIncorrectTypeOfArgumentsErrorMessage(parseInfo, i, exprType, arg[0], name);
1276void KDbFunctionExpressionData::setArguments(ExplicitlySharedExpressionDataPointer arguments)
1280 children.append(args);
1281 args->parent =
this;
1283 args->expressionClass = KDb::ArgumentListExpression;
1292 KDb::ExpressionCallStack* callStack)
1294 return KDbEscapedString(name + QLatin1Char(
'('))
1295 + args->toString(driver, params, callStack)
1296 + KDbEscapedString(
')');
1303 if (KDbFunctionExpression::isBuiltInAggregate(name))
1304 return KDb::AggregationExpression;
1306 return KDb::FunctionExpression;
1310 : KDbExpression(new KDbFunctionExpressionData)
1312 ExpressionDebug <<
"KDbFunctionExpression() ctor" << *
this;
1316 : KDbExpression(new KDbFunctionExpressionData(
name),
1323 : KDbExpression(new KDbFunctionExpressionData(
name.toUpper(),
arguments.
d),
1329 : KDbExpression(expr)
1336 ExpressionDebug <<
"KDbFunctionExpression ctor (KDbExpressionData*)" << *
this;
1344KDbFunctionExpression::~KDbFunctionExpression()
1349bool KDbFunctionExpression::isBuiltInAggregate(
const QString& function)
1351 return _builtInAggregates->data.contains(function.
toUpper());
1355QStringList KDbFunctionExpression::builtInAggregates()
1357 return _builtInAggregates->
data.values();
1364 const KDbNArgExpression& args,
1366 KDb::ExpressionCallStack* callStack)
1369 return KDbFunctionExpressionData::toString(
name, driver, argsData, params, callStack);
1374 return d->convert<KDbFunctionExpressionData>()->
name;
1379 d->convert<KDbFunctionExpressionData>()->
name =
name;
1384 return KDbNArgExpression(
d->convert<KDbFunctionExpressionData>()->args);
1396 const KDbNArgExpression &args,
1398 KDb::ExpressionCallStack* callStack)
1403 whenSql.reserve(256);
1404 foreach(
const ExplicitlySharedExpressionDataPointer &child, args.
d.
constData()->children) {
1405 if (!whenSql.isEmpty()) {
1408 whenSql +=
QLatin1Char(
'(') + child->toString(driver, params, callStack)
Database driver's abstraction.
virtual KDbEscapedString greatestOrLeastFunctionToString(const QString &name, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) GREATEST() and LEAST() function calls.
static QString defaultSqlTypeName(KDbField::Type type)
virtual KDbEscapedString ifnullFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) IFNULL() function call.
virtual KDbEscapedString randomFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) RANDOM() and RANDOM(X,Y) function calls.
virtual KDbEscapedString lengthFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) LENGTH() function call.
virtual KDbEscapedString hexFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) HEX() function call.
virtual KDbEscapedString ceilingOrFloorFunctionToString(const QString &name, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) CEILING() and FLOOR() function calls.
virtual KDbEscapedString unicodeFunctionToString(const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack) const
Generates native (driver-specific) UNICODE() function call.
Specialized string for escaping.
Internal data class used to implement implicitly shared class KDbExpression.
KDbField::Type type() const
The KDbExpression class represents a base class for all expressions.
ExplicitlySharedExpressionDataPointer d
bool isNumericType() const
static QString typeName(Type type)
static QString typeGroupName(TypeGroup typeGroup)
bool isFPNumericType() const
bool isIntegerType() const
TypeGroup typeGroup() const
Internal data class used to implement implicitly shared class KDbFunctionExpression.
bool validateInternal(KDbParseInfo *parseInfo, KDb::ExpressionCallStack *callStack) override
KDbField::Type typeInternal(KDb::ExpressionCallStack *callStack) const override
void debugInternal(QDebug dbg, KDb::ExpressionCallStack *callStack) const override
Sends information about this expression to debug output dbg (internal).
static KDbEscapedString greatestOrLeastFunctionUsingCaseToString(const QString &name, const KDbDriver *driver, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack)
static KDbEscapedString toString(const QString &name, const KDbDriver *driver, const KDbNArgExpression &args, KDbQuerySchemaParameterValueListIterator *params, KDb::ExpressionCallStack *callStack)
void setArguments(const KDbNArgExpression &arguments)
Sets the list of arguments to arguments.
KDbNArgExpression arguments()
void setName(const QString &name)
Sets name of the function to name.
Internal data class used to implement implicitly shared class KDbNArgExpression.
Internal data class used to implement implicitly shared class KDbQueryParameterExpression.
An iterator for a list of values of query schema parameters Allows to iterate over parameters and ret...
A type-safe KDbSQL token It can be used in KDb expressions.
Type type(const QSqlDatabase &db)
KDB_EXPORT KDbField::Type maximumForIntegerFieldTypes(KDbField::Type t1, KDbField::Type t2)
KDB_EXPORT KDbField::Type intToFieldType(int type)
ExpressionClass
Classes of expressions.
QString name(const QVariant &location)
const T * constData() const const
QString arg(Args &&... args) const const
QString fromLatin1(QByteArrayView str)
bool isEmpty() const const
QString number(double n, char format, int precision)
QString toUpper() const const
qlonglong toLongLong(bool *ok) const const