This is an automated email from the ASF dual-hosted git repository. bereng pushed a commit to branch cassandra-4.0 in repository https://gitbox.apache.org/repos/asf/cassandra.git
commit f242ccbedd1e236b2288ea8158582eb05f623b03 Merge: 979ab72 99e1fcc Author: Bereng <[email protected]> AuthorDate: Fri Aug 13 08:42:35 2021 +0200 Merge branch 'cassandra-3.11' into cassandra-4.0 .../cassandra/cql3/functions/FunctionCall.java | 4 +- test/unit/org/apache/cassandra/cql3/ViewTest.java | 132 +++++++++++++++++++++ 2 files changed, 135 insertions(+), 1 deletion(-) diff --cc src/java/org/apache/cassandra/cql3/functions/FunctionCall.java index e0dae52,c0d616e..0083a31 --- a/src/java/org/apache/cassandra/cql3/functions/FunctionCall.java +++ b/src/java/org/apache/cassandra/cql3/functions/FunctionCall.java @@@ -227,7 -204,7 +227,9 @@@ public class FunctionCall extends Term. public String getText() { - return name + terms.stream().map(Term.Raw::getText).collect(Collectors.joining(", ", "(", ")")); - return name.toCQLString() + terms.stream().map(Term.Raw::getText).collect(Collectors.joining(", ", "(", ")")); ++ CqlBuilder cqlNameBuilder = new CqlBuilder(); ++ name.appendCqlTo(cqlNameBuilder); ++ return cqlNameBuilder + terms.stream().map(Term.Raw::getText).collect(Collectors.joining(", ", "(", ")")); } } } diff --cc test/unit/org/apache/cassandra/cql3/ViewTest.java index 16aa266,07a518b..a4da51a --- a/test/unit/org/apache/cassandra/cql3/ViewTest.java +++ b/test/unit/org/apache/cassandra/cql3/ViewTest.java @@@ -36,10 -51,14 +37,13 @@@ import org.apache.cassandra.db.ColumnFa import org.apache.cassandra.db.Keyspace; import org.apache.cassandra.db.SystemKeyspace; import org.apache.cassandra.db.compaction.CompactionManager; -import org.apache.cassandra.db.marshal.AsciiType; import org.apache.cassandra.db.view.View; + import org.apache.cassandra.exceptions.SyntaxException; -import org.apache.cassandra.schema.KeyspaceParams; ++import org.apache.cassandra.schema.SchemaConstants; + import org.apache.cassandra.schema.SchemaKeyspace; import org.apache.cassandra.service.ClientWarn; -import org.apache.cassandra.transport.ProtocolVersion; import org.apache.cassandra.utils.FBUtilities; +import org.awaitility.Awaitility; import org.jboss.byteman.contrib.bmunit.BMRule; import org.jboss.byteman.contrib.bmunit.BMRules; import org.jboss.byteman.contrib.bmunit.BMUnitRunner; @@@ -63,7 -75,49 +67,8 @@@ public class ViewTest extends ViewAbstr /** Latch used by {@link #testTruncateWhileBuilding()} Byteman injections. */ @SuppressWarnings("unused") private static final CountDownLatch blockViewBuild = new CountDownLatch(1); + private static final AtomicInteger viewNameSeqNumber = new AtomicInteger(); - private static final ProtocolVersion protocolVersion = ProtocolVersion.CURRENT; - private final List<String> views = new ArrayList<>(); - - @BeforeClass - public static void startup() - { - requireNetwork(); - } - @Before - public void begin() - { - views.clear(); - } - - @After - public void end() throws Throwable - { - for (String viewName : views) - executeNet(protocolVersion, "DROP MATERIALIZED VIEW " + viewName); - } - - private void createView(String name, String query) throws Throwable - { - executeNet(protocolVersion, String.format(query, name)); - // If exception is thrown, the view will not be added to the list; since it shouldn't have been created, this is - // the desired behavior - views.add(name); - } - - private void updateView(String query, Object... params) throws Throwable - { - executeNet(protocolVersion, query, params); - waitForViewMutations(); - } - - private void waitForViewMutations() - { - SEPExecutor executor = (SEPExecutor) StageManager.getStage(Stage.VIEW_MUTATION); - Util.spinAssertEquals(0L, () -> executor.getPendingTasks() + executor.getActiveCount(), 60); - } - @Test public void testNonExistingOnes() throws Throwable { @@@ -562,20 -1491,105 +567,114 @@@ } @Test - public void viewOnCompactTableTest() throws Throwable + public void testQuotedIdentifiersInWhereClause() throws Throwable { - createTable("CREATE TABLE %s (a int, b int, v int, PRIMARY KEY (a, b)) WITH COMPACT STORAGE"); - executeNet(protocolVersion, "USE " + keyspace()); - try - { - createView("mv", - "CREATE MATERIALIZED VIEW %s AS SELECT a, b, value FROM %%s WHERE b IS NOT NULL PRIMARY KEY (b, a)"); - fail("Should have thrown an exception"); - } - catch (Throwable t) - { - Assert.assertEquals("Undefined column name value", - t.getMessage()); - } + createTable("CREATE TABLE %s (\"theKey\" int, \"theClustering_1\" int, \"theClustering_2\" int, \"theValue\" int, PRIMARY KEY (\"theKey\", \"theClustering_1\", \"theClustering_2\"))"); + + executeNet("USE " + keyspace()); + + createView("view1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE \"theKey\" IS NOT NULL AND \"theClustering_1\" IS NOT NULL AND \"theClustering_2\" IS NOT NULL AND \"theValue\" IS NOT NULL PRIMARY KEY (\"theKey\", \"theClustering_1\", \"theClustering_2\");"); + createView("view2", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE \"theKey\" IS NOT NULL AND (\"theClustering_1\", \"theClustering_2\") = (1, 2) AND \"theValue\" IS NOT NULL PRIMARY KEY (\"theKey\", \"theClustering_1\", \"theClustering_2\");"); + + assertRows(execute("SELECT where_clause FROM system_schema.views"), + row("\"theKey\" IS NOT NULL AND \"theClustering_1\" IS NOT NULL AND \"theClustering_2\" IS NOT NULL AND \"theValue\" IS NOT NULL"), + row("\"theKey\" IS NOT NULL AND (\"theClustering_1\", \"theClustering_2\") = (1, 2) AND \"theValue\" IS NOT NULL")); + } + ++ @Test(expected = SyntaxException.class) ++ public void emptyViewNameTest() throws Throwable ++ { ++ execute("CREATE MATERIALIZED VIEW \"\" AS SELECT a, b FROM tbl WHERE b IS NOT NULL PRIMARY KEY (b, a)"); ++ } ++ ++ @Test(expected = SyntaxException.class) ++ public void emptyBaseTableNameTest() throws Throwable ++ { ++ execute("CREATE MATERIALIZED VIEW myview AS SELECT a, b FROM \"\" WHERE b IS NOT NULL PRIMARY KEY (b, a)"); + } + + @Test + public void testFunctionInWhereClause() throws Throwable + { + // Native token function with lowercase, should be unquoted in the schema where clause + assertEmpty(testFunctionInWhereClause("CREATE TABLE %s (k bigint PRIMARY KEY, v int)", + null, + "CREATE MATERIALIZED VIEW %s AS" + + " SELECT * FROM %%s WHERE k = token(1) AND v IS NOT NULL " + + " PRIMARY KEY (v, k)", + "k = token(1) AND v IS NOT NULL", + "INSERT INTO %s(k, v) VALUES (0, 1)", + "INSERT INTO %s(k, v) VALUES (2, 3)")); + + // Native token function with uppercase, should be unquoted and lowercased in the schema where clause + assertEmpty(testFunctionInWhereClause("CREATE TABLE %s (k bigint PRIMARY KEY, v int)", + null, + "CREATE MATERIALIZED VIEW %s AS" + + " SELECT * FROM %%s WHERE k = TOKEN(1) AND v IS NOT NULL" + + " PRIMARY KEY (v, k)", + "k = token(1) AND v IS NOT NULL", + "INSERT INTO %s(k, v) VALUES (0, 1)", + "INSERT INTO %s(k, v) VALUES (2, 3)")); + + // UDF with lowercase name, shouldn't be quoted in the schema where clause + assertRows(testFunctionInWhereClause("CREATE TABLE %s (k int PRIMARY KEY, v int)", + "CREATE FUNCTION fun()" + + " CALLED ON NULL INPUT" + + " RETURNS int LANGUAGE java" + + " AS 'return 2;'", + "CREATE MATERIALIZED VIEW %s AS " + + " SELECT * FROM %%s WHERE k = fun() AND v IS NOT NULL" + + " PRIMARY KEY (v, k)", + "k = fun() AND v IS NOT NULL", + "INSERT INTO %s(k, v) VALUES (0, 1)", + "INSERT INTO %s(k, v) VALUES (2, 3)"), row(3, 2)); + + // UDF with uppercase name, should be quoted in the schema where clause + assertRows(testFunctionInWhereClause("CREATE TABLE %s (k int PRIMARY KEY, v int)", + "CREATE FUNCTION \"FUN\"()" + + " CALLED ON NULL INPUT" + + " RETURNS int" + + " LANGUAGE java" + + " AS 'return 2;'", + "CREATE MATERIALIZED VIEW %s AS " + + " SELECT * FROM %%s WHERE k = \"FUN\"() AND v IS NOT NULL" + + " PRIMARY KEY (v, k)", + "k = \"FUN\"() AND v IS NOT NULL", + "INSERT INTO %s(k, v) VALUES (0, 1)", + "INSERT INTO %s(k, v) VALUES (2, 3)"), row(3, 2)); + + // UDF with uppercase name conflicting with TOKEN keyword but not with native token function name, + // should be quoted in the schema where clause + assertRows(testFunctionInWhereClause("CREATE TABLE %s (k int PRIMARY KEY, v int)", + "CREATE FUNCTION \"TOKEN\"(x int)" + + " CALLED ON NULL INPUT" + + " RETURNS int" + + " LANGUAGE java" + + " AS 'return x;'", + "CREATE MATERIALIZED VIEW %s AS" + + " SELECT * FROM %%s WHERE k = \"TOKEN\"(2) AND v IS NOT NULL" + + " PRIMARY KEY (v, k)", + "k = \"TOKEN\"(2) AND v IS NOT NULL", + "INSERT INTO %s(k, v) VALUES (0, 1)", + "INSERT INTO %s(k, v) VALUES (2, 3)"), row(3, 2)); + + // UDF with lowercase name conflicting with both TOKEN keyword and native token function name, + // requires specifying the keyspace and should be quoted in the schema where clause + assertRows(testFunctionInWhereClause("CREATE TABLE %s (k int PRIMARY KEY, v int)", + "CREATE FUNCTION \"token\"(x int)" + + " CALLED ON NULL INPUT" + + " RETURNS int" + + " LANGUAGE java" + + " AS 'return x;'", + "CREATE MATERIALIZED VIEW %s AS" + + " SELECT * FROM %%s " + + " WHERE k = " + keyspace() + ".\"token\"(2) AND v IS NOT NULL" + + " PRIMARY KEY (v, k)", + "k = " + keyspace() + ".\"token\"(2) AND v IS NOT NULL", + "INSERT INTO %s(k, v) VALUES (0, 1)", + "INSERT INTO %s(k, v) VALUES (2, 3)"), row(3, 2)); + } + /** * Tests that truncating a table stops the ongoing builds of its materialized views, * so they don't write into the MV data that has been truncated in the base table. @@@ -626,10 -1640,41 +725,43 @@@ assertRows(execute("SELECT * FROM mv")); } - private static int runningCompactions() + private static int runningViewBuilds() { - return CompactionManager.instance.getPendingTasks() + CompactionManager.instance.getActiveCompactions(); + return Metrics.getThreadPoolMetrics("ViewBuildExecutor") + .map(p -> p.activeTasks.getValue() + p.pendingTasks.getValue()) + .orElse(0); } + + private UntypedResultSet testFunctionInWhereClause(String createTableQuery, + String createFunctionQuery, + String createViewQuery, + String expectedSchemaWhereClause, + String... insertQueries) throws Throwable + { + createTable(createTableQuery); + + execute("USE " + keyspace()); - executeNet(protocolVersion, "USE " + keyspace()); ++ executeNet("USE " + keyspace()); + + if (createFunctionQuery != null) + { + execute(createFunctionQuery); + } + + String viewName = "view_" + viewNameSeqNumber.getAndIncrement(); + createView(viewName, createViewQuery); + + // Test the where clause stored in system_schema.views + String schemaQuery = String.format("SELECT where_clause FROM %s.%s WHERE keyspace_name = ? AND view_name = ?", + SchemaConstants.SCHEMA_KEYSPACE_NAME, + SchemaKeyspace.VIEWS); + assertRows(execute(schemaQuery, keyspace(), viewName), row(expectedSchemaWhereClause)); + + for (String insert : insertQueries) + { + execute(insert); + } + + return execute("SELECT * FROM " + viewName); + } } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
