blob: 3bf3543ef6b65bd0d45beea207fd338361f22ef0 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.cassandra.cql3.functions;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import org.apache.cassandra.schema.SchemaConstants;
import org.assertj.core.api.Assertions;
public class NativeFunctionsTest
{
/**
* Map associating old functions that don't satisfy the naming conventions adopted by CASSANDRA-18037 to their
* new names according to those conventions.
*/
private static final Map<String, String> LEGACY_FUNCTION_NAMES = new HashMap<String, String>()
{
{
put("castAsAscii", "cast_as_ascii");
put("castAsBigint", "cast_as_bigint");
put("castAsDate", "cast_as_date");
put("castAsDecimal", "cast_as_decimal");
put("castAsDouble", "cast_as_double");
put("castAsFloat", "cast_as_float");
put("castAsInt", "cast_as_int");
put("castAsSmallint", "cast_as_smallint");
put("castAsText", "cast_as_text");
put("castAsTimestamp", "cast_as_timestamp");
put("castAsTinyint", "cast_as_tinyint");
put("castAsVarint", "cast_as_varint");
put("blobasascii", "blob_as_ascii");
put("blobasbigint", "blob_as_bigint");
put("blobasboolean", "blob_as_boolean");
put("blobascounter", "blob_as_counter");
put("blobasdate", "blob_as_date");
put("blobasdecimal", "blob_as_decimal");
put("blobasdouble", "blob_as_double");
put("blobasduration", "blob_as_duration");
put("blobasempty", "blob_as_empty");
put("blobasfloat", "blob_as_float");
put("blobasinet", "blob_as_inet");
put("blobasint", "blob_as_int");
put("blobassmallint", "blob_as_smallint");
put("blobastext", "blob_as_text");
put("blobastime", "blob_as_time");
put("blobastimestamp", "blob_as_timestamp");
put("blobastimeuuid", "blob_as_timeuuid");
put("blobastinyint", "blob_as_tinyint");
put("blobasuuid", "blob_as_uuid");
put("blobasvarchar", "blob_as_varchar");
put("blobasvarint", "blob_as_varint");
put("asciiasblob", "ascii_as_blob");
put("bigintasblob", "bigint_as_blob");
put("booleanasblob", "boolean_as_blob");
put("counterasblob", "counter_as_blob");
put("dateasblob", "date_as_blob");
put("decimalasblob", "decimal_as_blob");
put("doubleasblob", "double_as_blob");
put("durationasblob", "duration_as_blob");
put("emptyasblob", "empty_as_blob");
put("floatasblob", "float_as_blob");
put("inetasblob", "inet_as_blob");
put("intasblob", "int_as_blob");
put("smallintasblob", "smallint_as_blob");
put("textasblob", "text_as_blob");
put("timeasblob", "time_as_blob");
put("timestampasblob", "timestamp_as_blob");
put("timeuuidasblob", "timeuuid_as_blob");
put("tinyintasblob", "tinyint_as_blob");
put("uuidasblob", "uuid_as_blob");
put("varcharasblob", "varchar_as_blob");
put("varintasblob", "varint_as_blob");
put("countRows", "count_rows");
put("maxtimeuuid", "max_timeuuid");
put("mintimeuuid", "min_timeuuid");
put("currentdate", "current_date");
put("currenttime", "current_time");
put("currenttimestamp", "current_timestamp");
put("currenttimeuuid", "current_timeuuid");
put("todate", "to_date");
put("totimestamp", "to_timestamp");
put("tounixtimestamp", "to_unix_timestamp");
}
};
/**
* Map associating old functions factories that don't satisfy the naming conventions adopted by CASSANDRA-18037 to
* their new names according to those conventions.
*/
private static final Map<String, String> LEGACY_FUNCTION_FACTORY_NAMES = new HashMap<String, String>()
{
{
put("tojson", "to_json");
put("fromjson", "from_json");
}
};
/**
* Verify that the old functions that don't satisfy the naming conventions adopted by CASSANDRA-18037 have a
* replacement function that satisfies those conventions.
*/
@Test
public void testDeprectedFunctionNames()
{
NativeFunctions nativeFunctions = NativeFunctions.instance;
LEGACY_FUNCTION_NAMES.forEach((oldName, newName) -> {
Assertions.assertThat(nativeFunctions.getFunctions(FunctionName.nativeFunction(oldName))).isNotEmpty();
Assertions.assertThat(nativeFunctions.getFunctions(FunctionName.nativeFunction(newName))).isNotEmpty();
});
for (NativeFunction function : nativeFunctions.getFunctions())
{
String name = function.name.name;
if (satisfiesConventions(function.name))
continue;
Assertions.assertThat(LEGACY_FUNCTION_NAMES).containsKey(name);
FunctionName newName = FunctionName.nativeFunction(LEGACY_FUNCTION_NAMES.get(name));
Function newFunction = FunctionResolver.get(SchemaConstants.SYSTEM_KEYSPACE_NAME,
newName,
function.argTypes,
null,
null,
function.returnType);
Assertions.assertThat(newFunction).isNotNull();
Assertions.assertThat(function).isNotEqualTo(newFunction);
Assertions.assertThat(function).isEqualTo(((NativeFunction) newFunction).withLegacyName());
Assertions.assertThat(function.argTypes()).isEqualTo(newFunction.argTypes());
Assertions.assertThat(function.returnType()).isEqualTo(newFunction.returnType());
Assertions.assertThat(function.getClass()).isEqualTo(newFunction.getClass());
Assertions.assertThat(function.name().name.toLowerCase())
.isEqualTo(StringUtils.remove(newFunction.name().name, '_'));
}
}
/**
* Verify that the old functions function factories that don't satisfy the naming conventions adopted by
* CASSANDRA-18037 have a replacement function factory that satisfies those conventions.
*/
@Test
public void testDeprectedFunctionFactoryNames()
{
NativeFunctions nativeFunctions = NativeFunctions.instance;
LEGACY_FUNCTION_FACTORY_NAMES.forEach((oldName, newName) -> {
Assertions.assertThat(nativeFunctions.getFactories(FunctionName.nativeFunction(oldName))).isNotEmpty();
Assertions.assertThat(nativeFunctions.getFactories(FunctionName.nativeFunction(newName))).isNotEmpty();
});
for (FunctionFactory factory : nativeFunctions.getFactories())
{
String name = factory.name.name;
if (satisfiesConventions(factory.name))
continue;
Assertions.assertThat(LEGACY_FUNCTION_FACTORY_NAMES).containsKey(name);
FunctionName newName = FunctionName.nativeFunction(LEGACY_FUNCTION_FACTORY_NAMES.get(name));
Collection<FunctionFactory> newFactories = NativeFunctions.instance.getFactories(newName);
Assertions.assertThat(newFactories).hasSize(1);
FunctionFactory newFactory = newFactories.iterator().next();
Assertions.assertThat(factory).isNotEqualTo(newFactory);
Assertions.assertThat(factory.name).isNotEqualTo(newFactory.name);
Assertions.assertThat(factory.parameters).isEqualTo(newFactory.parameters);
Assertions.assertThat(factory.getClass()).isEqualTo(newFactory.getClass());
Assertions.assertThat(factory.name().name.toLowerCase())
.isEqualTo(StringUtils.remove(newFactory.name().name, '_'));
}
}
private static boolean satisfiesConventions(FunctionName functionName)
{
String name = functionName.name;
return name.equals(name.toLowerCase()) &&
!LEGACY_FUNCTION_NAMES.containsKey(name);
}
}