use of org.apache.cassandra.cql3.functions.Function in project cassandra by apache.
the class SerializationHeaderTest method testWrittenAsDifferentKind.
@Test
public void testWrittenAsDifferentKind() throws Exception {
final String tableName = "testWrittenAsDifferentKind";
// final String schemaCqlWithStatic = String.format("CREATE TABLE %s (k int, c int, v int static, PRIMARY KEY(k, c))", tableName);
// final String schemaCqlWithRegular = String.format("CREATE TABLE %s (k int, c int, v int, PRIMARY KEY(k, c))", tableName);
ColumnIdentifier v = ColumnIdentifier.getInterned("v", false);
TableMetadata schemaWithStatic = TableMetadata.builder(KEYSPACE, tableName).addPartitionKeyColumn("k", Int32Type.instance).addClusteringColumn("c", Int32Type.instance).addStaticColumn("v", Int32Type.instance).build();
TableMetadata schemaWithRegular = TableMetadata.builder(KEYSPACE, tableName).addPartitionKeyColumn("k", Int32Type.instance).addClusteringColumn("c", Int32Type.instance).addRegularColumn("v", Int32Type.instance).build();
ColumnMetadata columnStatic = schemaWithStatic.getColumn(v);
ColumnMetadata columnRegular = schemaWithRegular.getColumn(v);
schemaWithStatic = schemaWithStatic.unbuild().recordColumnDrop(columnRegular, 0L).build();
schemaWithRegular = schemaWithRegular.unbuild().recordColumnDrop(columnStatic, 0L).build();
final AtomicInteger generation = new AtomicInteger();
File dir = new File(Files.createTempDir());
try {
BiFunction<TableMetadata, Function<ByteBuffer, Clustering<?>>, Callable<Descriptor>> writer = (schema, clusteringFunction) -> () -> {
Descriptor descriptor = new Descriptor(BigFormat.latestVersion, dir, schema.keyspace, schema.name, generation.incrementAndGet(), SSTableFormat.Type.BIG);
SerializationHeader header = SerializationHeader.makeWithoutStats(schema);
try (LifecycleTransaction txn = LifecycleTransaction.offline(OperationType.WRITE);
SSTableWriter sstableWriter = BigTableWriter.create(TableMetadataRef.forOfflineTools(schema), descriptor, 1, 0L, null, false, 0, header, Collections.emptyList(), txn)) {
ColumnMetadata cd = schema.getColumn(v);
for (int i = 0; i < 5; ++i) {
final ByteBuffer value = Int32Type.instance.decompose(i);
Cell<?> cell = BufferCell.live(cd, 1L, value);
Clustering<?> clustering = clusteringFunction.apply(value);
Row row = BTreeRow.singleCellRow(clustering, cell);
sstableWriter.append(PartitionUpdate.singleRowUpdate(schema, value, row).unfilteredIterator());
}
sstableWriter.finish(false);
txn.finish();
}
return descriptor;
};
Descriptor sstableWithRegular = writer.apply(schemaWithRegular, BufferClustering::new).call();
Descriptor sstableWithStatic = writer.apply(schemaWithStatic, value -> Clustering.STATIC_CLUSTERING).call();
SSTableReader readerWithStatic = SSTableReader.openNoValidation(sstableWithStatic, TableMetadataRef.forOfflineTools(schemaWithRegular));
SSTableReader readerWithRegular = SSTableReader.openNoValidation(sstableWithRegular, TableMetadataRef.forOfflineTools(schemaWithStatic));
try (ISSTableScanner partitions = readerWithStatic.getScanner()) {
for (int i = 0; i < 5; ++i) {
UnfilteredRowIterator partition = partitions.next();
Assert.assertFalse(partition.hasNext());
long value = Int32Type.instance.compose(partition.staticRow().getCell(columnStatic).buffer());
Assert.assertEquals(value, (long) i);
}
Assert.assertFalse(partitions.hasNext());
}
try (ISSTableScanner partitions = readerWithRegular.getScanner()) {
for (int i = 0; i < 5; ++i) {
UnfilteredRowIterator partition = partitions.next();
long value = Int32Type.instance.compose(((Row) partition.next()).getCell(columnRegular).buffer());
Assert.assertEquals(value, (long) i);
Assert.assertTrue(partition.staticRow().isEmpty());
Assert.assertFalse(partition.hasNext());
}
Assert.assertFalse(partitions.hasNext());
}
} finally {
FileUtils.deleteRecursive(dir);
}
}
use of org.apache.cassandra.cql3.functions.Function in project cassandra by apache.
the class FunctionResolver method matchAguments.
private static AssignmentTestable.TestResult matchAguments(String keyspace, Function fun, List<? extends AssignmentTestable> providedArgs, String receiverKs, String receiverCf) {
if (providedArgs.size() != fun.argTypes().size())
return AssignmentTestable.TestResult.NOT_ASSIGNABLE;
// It's an exact match if all are exact match, but is not assignable as soon as any is non assignable.
AssignmentTestable.TestResult res = AssignmentTestable.TestResult.EXACT_MATCH;
for (int i = 0; i < providedArgs.size(); i++) {
AssignmentTestable provided = providedArgs.get(i);
if (provided == null) {
res = AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE;
continue;
}
ColumnSpecification expected = makeArgSpec(receiverKs, receiverCf, fun, i);
AssignmentTestable.TestResult argRes = provided.testAssignment(keyspace, expected);
if (argRes == AssignmentTestable.TestResult.NOT_ASSIGNABLE)
return AssignmentTestable.TestResult.NOT_ASSIGNABLE;
if (argRes == AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE)
res = AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE;
}
return res;
}
use of org.apache.cassandra.cql3.functions.Function in project cassandra by apache.
the class BytesConversionFcts method all.
public static Collection<Function> all() {
Collection<Function> functions = new ArrayList<>();
// for varchar, so we special case it below. We also skip blob for obvious reasons.
for (CQL3Type type : CQL3Type.Native.values()) {
if (type != CQL3Type.Native.VARCHAR && type != CQL3Type.Native.BLOB) {
functions.add(makeToBlobFunction(type.getType()));
functions.add(makeFromBlobFunction(type.getType()));
}
}
functions.add(VarcharAsBlobFct);
functions.add(BlobAsVarcharFct);
return functions;
}
use of org.apache.cassandra.cql3.functions.Function in project cassandra by apache.
the class SelectTest method testSelectWithAlias.
/**
* Migrated from cql_tests.py:TestCQL.select_with_alias_test()
*/
@Test
public void testSelectWithAlias() throws Throwable {
createTable("CREATE TABLE %s (id int PRIMARY KEY, name text)");
for (int id = 0; id < 5; id++) execute("INSERT INTO %s (id, name) VALUES (?, ?) USING TTL 10 AND TIMESTAMP 0", id, "name" + id);
// test aliasing count( *)
UntypedResultSet rs = execute("SELECT count(*) AS user_count FROM %s");
assertEquals("user_count", rs.metadata().get(0).name.toString());
assertEquals(5L, rs.one().getLong(rs.metadata().get(0).name.toString()));
// test aliasing regular value
rs = execute("SELECT name AS user_name FROM %s WHERE id = 0");
assertEquals("user_name", rs.metadata().get(0).name.toString());
assertEquals("name0", rs.one().getString(rs.metadata().get(0).name.toString()));
// test aliasing writetime
rs = execute("SELECT writeTime(name) AS name_writetime FROM %s WHERE id = 0");
assertEquals("name_writetime", rs.metadata().get(0).name.toString());
assertEquals(0, rs.one().getInt(rs.metadata().get(0).name.toString()));
// test aliasing ttl
rs = execute("SELECT ttl(name) AS name_ttl FROM %s WHERE id = 0");
assertEquals("name_ttl", rs.metadata().get(0).name.toString());
int ttl = rs.one().getInt(rs.metadata().get(0).name.toString());
assertTrue(ttl == 9 || ttl == 10);
// test aliasing a regular function
rs = execute("SELECT intAsBlob(id) AS id_blob FROM %s WHERE id = 0");
assertEquals("id_blob", rs.metadata().get(0).name.toString());
assertEquals(ByteBuffer.wrap(new byte[4]), rs.one().getBlob(rs.metadata().get(0).name.toString()));
// test that select throws a meaningful exception for aliases in where clause
assertInvalidMessage("Undefined column name user_id", "SELECT id AS user_id, name AS user_name FROM %s WHERE user_id = 0");
// test that select throws a meaningful exception for aliases in order by clause
assertInvalidMessage("Undefined column name user_name", "SELECT id AS user_id, name AS user_name FROM %s WHERE id IN (0) ORDER BY user_name");
}
use of org.apache.cassandra.cql3.functions.Function in project cassandra by apache.
the class CreateAggregateStatement method apply.
public Keyspaces apply(Keyspaces schema) {
if (ifNotExists && orReplace)
throw ire("Cannot use both 'OR REPLACE' and 'IF NOT EXISTS' directives");
rawArgumentTypes.stream().filter(raw -> !raw.isTuple() && raw.isFrozen()).findFirst().ifPresent(t -> {
throw ire("Argument '%s' cannot be frozen; remove frozen<> modifier from '%s'", t, t);
});
if (!rawStateType.isTuple() && rawStateType.isFrozen())
throw ire("State type '%s' cannot be frozen; remove frozen<> modifier from '%s'", rawStateType, rawStateType);
KeyspaceMetadata keyspace = schema.getNullable(keyspaceName);
if (null == keyspace)
throw ire("Keyspace '%s' doesn't exist", keyspaceName);
/*
* Resolve the state function
*/
List<AbstractType<?>> argumentTypes = rawArgumentTypes.stream().map(t -> t.prepare(keyspaceName, keyspace.types).getType()).collect(toList());
AbstractType<?> stateType = rawStateType.prepare(keyspaceName, keyspace.types).getType();
List<AbstractType<?>> stateFunctionArguments = Lists.newArrayList(concat(singleton(stateType), argumentTypes));
Function stateFunction = keyspace.functions.find(stateFunctionName, stateFunctionArguments).orElseThrow(() -> ire("State function %s doesn't exist", stateFunctionString()));
if (stateFunction.isAggregate())
throw ire("State function %s isn't a scalar function", stateFunctionString());
if (!stateFunction.returnType().equals(stateType)) {
throw ire("State function %s return type must be the same as the first argument type - check STYPE, argument and return types", stateFunctionString());
}
/*
* Resolve the final function and return type
*/
Function finalFunction = null;
AbstractType<?> returnType = stateFunction.returnType();
if (null != finalFunctionName) {
finalFunction = keyspace.functions.find(finalFunctionName, singletonList(stateType)).orElse(null);
if (null == finalFunction)
throw ire("Final function %s doesn't exist", finalFunctionString());
if (finalFunction.isAggregate())
throw ire("Final function %s isn't a scalar function", finalFunctionString());
// override return type with that of the final function
returnType = finalFunction.returnType();
}
/*
* Validate initial condition
*/
ByteBuffer initialValue = null;
if (null != rawInitialValue) {
initialValue = Terms.asBytes(keyspaceName, rawInitialValue.toString(), stateType);
if (null != initialValue) {
try {
stateType.validate(initialValue);
} catch (MarshalException e) {
throw ire("Invalid value for INITCOND of type %s", stateType.asCQL3Type());
}
}
// Converts initcond to a CQL literal and parse it back to avoid another CASSANDRA-11064
String initialValueString = stateType.asCQL3Type().toCQLLiteral(initialValue, ProtocolVersion.CURRENT);
assert Objects.equal(initialValue, Terms.asBytes(keyspaceName, initialValueString, stateType));
if (Constants.NULL_LITERAL != rawInitialValue && UDHelper.isNullOrEmpty(stateType, initialValue))
throw ire("INITCOND must not be empty for all types except TEXT, ASCII, BLOB");
}
if (!((UDFunction) stateFunction).isCalledOnNullInput() && null == initialValue) {
throw ire("Cannot create aggregate '%s' without INITCOND because state function %s does not accept 'null' arguments", aggregateName, stateFunctionName);
}
/*
* Create or replace
*/
UDAggregate aggregate = new UDAggregate(new FunctionName(keyspaceName, aggregateName), argumentTypes, returnType, (ScalarFunction) stateFunction, (ScalarFunction) finalFunction, initialValue);
Function existingAggregate = keyspace.functions.find(aggregate.name(), argumentTypes).orElse(null);
if (null != existingAggregate) {
if (!existingAggregate.isAggregate())
throw ire("Aggregate '%s' cannot replace a function", aggregateName);
if (ifNotExists)
return schema;
if (!orReplace)
throw ire("Aggregate '%s' already exists", aggregateName);
if (!returnType.isCompatibleWith(existingAggregate.returnType())) {
throw ire("Cannot replace aggregate '%s', the new return type %s isn't compatible with the return type %s of existing function", aggregateName, returnType.asCQL3Type(), existingAggregate.returnType().asCQL3Type());
}
}
return schema.withAddedOrUpdated(keyspace.withSwapped(keyspace.functions.withAddedOrUpdated(aggregate)));
}
Aggregations