From 8c0a9a870a8b06e8149624bec1aacafd51affe0a Mon Sep 17 00:00:00 2001 From: silverqx Date: Tue, 31 Oct 2023 15:27:31 +0100 Subject: [PATCH] bugfix column aliases quoting - added unit tests --- src/orm/basegrammar.cpp | 2 +- .../tst_mysql_querybuilder.cpp | 54 +++++++++++++++++++ .../tst_postgresql_querybuilder.cpp | 54 +++++++++++++++++++ .../tst_sqlite_querybuilder.cpp | 54 +++++++++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) diff --git a/src/orm/basegrammar.cpp b/src/orm/basegrammar.cpp index 36ab72c5f..e4d18c5c3 100644 --- a/src/orm/basegrammar.cpp +++ b/src/orm/basegrammar.cpp @@ -48,7 +48,7 @@ QString BaseGrammar::wrap(const QString &value, const bool prefixAlias) const /* If the value being wrapped has a column alias we will need to separate out the pieces so we can wrap each of the segments of the expression on its own, and then join these both back together using the "as" connector. */ - if (value.contains(QStringLiteral(" as "))) + if (value.contains(QStringLiteral(" as "), Qt::CaseInsensitive)) return wrapAliasedValue(value, prefixAlias); // FEATURE json columns, this code has to be in the Grammars::Grammar silverqx diff --git a/tests/auto/unit/orm/query/mysql_querybuilder/tst_mysql_querybuilder.cpp b/tests/auto/unit/orm/query/mysql_querybuilder/tst_mysql_querybuilder.cpp index d395bd028..c909bc61c 100644 --- a/tests/auto/unit/orm/query/mysql_querybuilder/tst_mysql_querybuilder.cpp +++ b/tests/auto/unit/orm/query/mysql_querybuilder/tst_mysql_querybuilder.cpp @@ -102,8 +102,11 @@ private Q_SLOTS: void select() const; void select_ColumnExpression() const; + void select_ColumnAlias() const; + void addSelect() const; void addSelect_ColumnExpression() const; + void addSelect_ColumnAlias() const; void selectRaw() const; void selectRaw_WithBindings_WithWhere() const; @@ -790,6 +793,29 @@ void tst_MySql_QueryBuilder::select_ColumnExpression() const "select count(*) as user_count, status from `torrents`"); } +void tst_MySql_QueryBuilder::select_ColumnAlias() const +{ + auto builder = createQuery(); + + builder->from("torrents"); + + builder->select({ID, "name as username"}); + QCOMPARE(builder->toSql(), + "select `id`, `name` as `username` from `torrents`"); + + builder->select({ID, "name as username"}); + QCOMPARE(builder->toSql(), + "select `id`, `name` as `username` from `torrents`"); + + builder->select({ID, "name AS username"}); + QCOMPARE(builder->toSql(), + "select `id`, `name` as `username` from `torrents`"); + + builder->select({ID, "name AS username"}); + QCOMPARE(builder->toSql(), + "select `id`, `name` as `username` from `torrents`"); +} + void tst_MySql_QueryBuilder::addSelect() const { auto builder = createQuery(); @@ -829,6 +855,34 @@ void tst_MySql_QueryBuilder::addSelect_ColumnExpression() const "from `torrents`"); } +void tst_MySql_QueryBuilder::addSelect_ColumnAlias() const +{ + auto builder = createQuery(); + + builder->from("torrents"); + + builder->addSelect("name as username"); + QCOMPARE(builder->toSql(), + "select `name` as `username` from `torrents`"); + + builder->addSelect({ID, "name1 as username1"}); + QCOMPARE(builder->toSql(), + "select `name` as `username`, `id`, `name1` as `username1` " + "from `torrents`"); + + builder->addSelect("name2 AS username2"); + QCOMPARE(builder->toSql(), + "select `name` as `username`, `id`, `name1` as `username1`, " + "`name2` as `username2` " + "from `torrents`"); + + builder->addSelect({"note", "name3 AS username3"}); + QCOMPARE(builder->toSql(), + "select `name` as `username`, `id`, `name1` as `username1`, " + "`name2` as `username2`, `note`, `name3` as `username3` " + "from `torrents`"); +} + void tst_MySql_QueryBuilder::selectRaw() const { auto builder = createQuery(); diff --git a/tests/auto/unit/orm/query/postgresql_querybuilder/tst_postgresql_querybuilder.cpp b/tests/auto/unit/orm/query/postgresql_querybuilder/tst_postgresql_querybuilder.cpp index fb1a61cb6..b6ba94aad 100644 --- a/tests/auto/unit/orm/query/postgresql_querybuilder/tst_postgresql_querybuilder.cpp +++ b/tests/auto/unit/orm/query/postgresql_querybuilder/tst_postgresql_querybuilder.cpp @@ -51,8 +51,11 @@ private Q_SLOTS: void select() const; void select_ColumnExpression() const; + void select_ColumnAlias() const; + void addSelect() const; void addSelect_ColumnExpression() const; + void addSelect_ColumnAlias() const; void distinct() const; void distinct_on() const; @@ -367,6 +370,29 @@ void tst_PostgreSQL_QueryBuilder::select_ColumnExpression() const "select count(*) as user_count, status from \"torrents\""); } +void tst_PostgreSQL_QueryBuilder::select_ColumnAlias() const +{ + auto builder = createQuery(); + + builder->from("torrents"); + + builder->select({ID, "name as username"}); + QCOMPARE(builder->toSql(), + "select \"id\", \"name\" as \"username\" from \"torrents\""); + + builder->select({ID, "name as username"}); + QCOMPARE(builder->toSql(), + "select \"id\", \"name\" as \"username\" from \"torrents\""); + + builder->select({ID, "name AS username"}); + QCOMPARE(builder->toSql(), + "select \"id\", \"name\" as \"username\" from \"torrents\""); + + builder->select({ID, "name AS username"}); + QCOMPARE(builder->toSql(), + "select \"id\", \"name\" as \"username\" from \"torrents\""); +} + void tst_PostgreSQL_QueryBuilder::addSelect() const { auto builder = createQuery(); @@ -406,6 +432,34 @@ void tst_PostgreSQL_QueryBuilder::addSelect_ColumnExpression() const "from \"torrents\""); } +void tst_PostgreSQL_QueryBuilder::addSelect_ColumnAlias() const +{ + auto builder = createQuery(); + + builder->from("torrents"); + + builder->addSelect("name as username"); + QCOMPARE(builder->toSql(), + "select \"name\" as \"username\" from \"torrents\""); + + builder->addSelect({ID, "name1 as username1"}); + QCOMPARE(builder->toSql(), + "select \"name\" as \"username\", \"id\", \"name1\" as \"username1\" " + "from \"torrents\""); + + builder->addSelect("name2 AS username2"); + QCOMPARE(builder->toSql(), + "select \"name\" as \"username\", \"id\", \"name1\" as \"username1\", " + "\"name2\" as \"username2\" " + "from \"torrents\""); + + builder->addSelect({"note", "name3 AS username3"}); + QCOMPARE(builder->toSql(), + "select \"name\" as \"username\", \"id\", \"name1\" as \"username1\", " + "\"name2\" as \"username2\", \"note\", \"name3\" as \"username3\" " + "from \"torrents\""); +} + void tst_PostgreSQL_QueryBuilder::distinct() const { auto builder = createQuery(); diff --git a/tests/auto/unit/orm/query/sqlite_querybuilder/tst_sqlite_querybuilder.cpp b/tests/auto/unit/orm/query/sqlite_querybuilder/tst_sqlite_querybuilder.cpp index 9f274ec80..a40a84a3c 100644 --- a/tests/auto/unit/orm/query/sqlite_querybuilder/tst_sqlite_querybuilder.cpp +++ b/tests/auto/unit/orm/query/sqlite_querybuilder/tst_sqlite_querybuilder.cpp @@ -51,8 +51,11 @@ private Q_SLOTS: void select() const; void select_ColumnExpression() const; + void select_ColumnAlias() const; + void addSelect() const; void addSelect_ColumnExpression() const; + void addSelect_ColumnAlias() const; void distinct() const; @@ -366,6 +369,29 @@ void tst_SQLite_QueryBuilder::select_ColumnExpression() const "select count(*) as user_count, status from \"torrents\""); } +void tst_SQLite_QueryBuilder::select_ColumnAlias() const +{ + auto builder = createQuery(); + + builder->from("torrents"); + + builder->select({ID, "name as username"}); + QCOMPARE(builder->toSql(), + "select \"id\", \"name\" as \"username\" from \"torrents\""); + + builder->select({ID, "name as username"}); + QCOMPARE(builder->toSql(), + "select \"id\", \"name\" as \"username\" from \"torrents\""); + + builder->select({ID, "name AS username"}); + QCOMPARE(builder->toSql(), + "select \"id\", \"name\" as \"username\" from \"torrents\""); + + builder->select({ID, "name AS username"}); + QCOMPARE(builder->toSql(), + "select \"id\", \"name\" as \"username\" from \"torrents\""); +} + void tst_SQLite_QueryBuilder::addSelect() const { auto builder = createQuery(); @@ -405,6 +431,34 @@ void tst_SQLite_QueryBuilder::addSelect_ColumnExpression() const "from \"torrents\""); } +void tst_SQLite_QueryBuilder::addSelect_ColumnAlias() const +{ + auto builder = createQuery(); + + builder->from("torrents"); + + builder->addSelect("name as username"); + QCOMPARE(builder->toSql(), + "select \"name\" as \"username\" from \"torrents\""); + + builder->addSelect({ID, "name1 as username1"}); + QCOMPARE(builder->toSql(), + "select \"name\" as \"username\", \"id\", \"name1\" as \"username1\" " + "from \"torrents\""); + + builder->addSelect("name2 AS username2"); + QCOMPARE(builder->toSql(), + "select \"name\" as \"username\", \"id\", \"name1\" as \"username1\", " + "\"name2\" as \"username2\" " + "from \"torrents\""); + + builder->addSelect({"note", "name3 AS username3"}); + QCOMPARE(builder->toSql(), + "select \"name\" as \"username\", \"id\", \"name1\" as \"username1\", " + "\"name2\" as \"username2\", \"note\", \"name3\" as \"username3\" " + "from \"torrents\""); +} + void tst_SQLite_QueryBuilder::distinct() const { auto builder = createQuery();