diff --git a/src/frontend/org/voltcore/logging/VoltLogger.java b/src/frontend/org/voltcore/logging/VoltLogger.java index 6afbfe2818d..bacd6d42495 100644 --- a/src/frontend/org/voltcore/logging/VoltLogger.java +++ b/src/frontend/org/voltcore/logging/VoltLogger.java @@ -343,6 +343,23 @@ public void l7dlog(final Level level, final String key, final Object[] params, f submitl7d(level, key, params, t); } + public void log(Level level, Object message, Throwable t) { + switch (level) { + case WARN: + case INFO: + case DEBUG: + case TRACE: + execute(level, message, t); + break; + case FATAL: + case ERROR: + submit(level, message, t); + break; + default: + throw new AssertionError("Unrecognized level " + level); + } + } + public long getLogLevels(VoltLogger loggers[]) { return m_logger.getLogLevels(loggers); } diff --git a/src/hsqldb19b3/org/hsqldb_voltpatches/Expression.java b/src/hsqldb19b3/org/hsqldb_voltpatches/Expression.java index 52ea0eaf2df..c6ed92054c7 100644 --- a/src/hsqldb19b3/org/hsqldb_voltpatches/Expression.java +++ b/src/hsqldb19b3/org/hsqldb_voltpatches/Expression.java @@ -552,7 +552,16 @@ boolean isComposedOf(Expression exprList[], int start, int end, } switch (opType) { - + // For ENG-18549 + // treat ? as constant value, allow ? in aggregate functions + // TODO: this fix only lift the restriction for cast function + // generalize to other functions in the future if needed + case OpTypes.CAST: + assert(1 == nodes.length); + if (nodes[0].opType == OpTypes.DYNAMIC_PARAM) { + return true; + } + break; case OpTypes.LIKE : case OpTypes.MATCH_SIMPLE : case OpTypes.MATCH_PARTIAL : diff --git a/tests/frontend/org/voltdb/regressionsuites/TestGroupBySuite.java b/tests/frontend/org/voltdb/regressionsuites/TestGroupBySuite.java index ab7f0c1728a..7c384c4c718 100644 --- a/tests/frontend/org/voltdb/regressionsuites/TestGroupBySuite.java +++ b/tests/frontend/org/voltdb/regressionsuites/TestGroupBySuite.java @@ -777,6 +777,31 @@ public void testPartialIndexAggregate() throws IOException, ProcCallException, I } } + // ENG-18549 + // GROUP BY doesn't allow ? in aggregate functions, doesn't treat ? as constant + public void testGroupByWithParameterizeInAggregateExpression() throws IOException, ProcCallException { + Client client = this.getClient(); + String sql1 = "SELECT A, CAST(1 as integer) + count(B) from R2 group by A;"; + VoltTable vt1 = client.callProcedure("@Explain", sql1).getResults()[0]; + String sql2 = "SELECT A, CAST(? as integer) + count(B) from R2 group by A;"; + VoltTable vt2 = client.callProcedure("@Explain", sql2).getResults()[0]; + // check the plan is same + assertTablesAreEqual("Plans for two sqls should be same", vt1, vt2); + + // Populate some data + String insert = "insert into R2 values (?,?,?,?)"; + client.callProcedure("@AdHoc", insert, 1, 3, 1, 2); + client.callProcedure("@AdHoc", insert, 2, 3, 4, 2); + client.callProcedure("@AdHoc", insert, 3, 2, 4, 1); + client.callProcedure("@AdHoc", insert, 4, 2, 5, 1); + client.callProcedure("@AdHoc", insert, 5, 5, 1, 3); + client.callProcedure("@AdHoc", insert, 6, 5, 2, 3); + vt1 = client.callProcedure("@AdHoc", sql1).getResults()[0]; + vt2 = client.callProcedure("@AdHoc",sql2, "1").getResults()[0]; + // check the result table is same + assertTablesAreEqual("Result for two sqls should be same", vt1, vt2); + } + // // Suite builder boilerplate //