use of org.apache.cassandra.exceptions.InvalidRequestException in project cassandra by apache.
the class SchemaKeyspace method createUDAFromRow.
private static UDAggregate createUDAFromRow(UntypedResultSet.Row row, Functions functions, Types types) {
String ksName = row.getString("keyspace_name");
String functionName = row.getString("aggregate_name");
FunctionName name = new FunctionName(ksName, functionName);
List<AbstractType<?>> argTypes = row.getFrozenList("argument_types", UTF8Type.instance).stream().map(t -> CQLTypeParser.parse(ksName, t, types)).collect(toList());
AbstractType<?> returnType = CQLTypeParser.parse(ksName, row.getString("return_type"), types);
FunctionName stateFunc = new FunctionName(ksName, (row.getString("state_func")));
FunctionName finalFunc = row.has("final_func") ? new FunctionName(ksName, row.getString("final_func")) : null;
AbstractType<?> stateType = row.has("state_type") ? CQLTypeParser.parse(ksName, row.getString("state_type"), types) : null;
ByteBuffer initcond = row.has("initcond") ? Terms.asBytes(ksName, row.getString("initcond"), stateType) : null;
try {
return UDAggregate.create(functions, name, argTypes, returnType, stateFunc, finalFunc, stateType, initcond);
} catch (InvalidRequestException reason) {
return UDAggregate.createBroken(name, argTypes, returnType, initcond, reason);
}
}
use of org.apache.cassandra.exceptions.InvalidRequestException in project cassandra by apache.
the class Schema method validateTable.
public TableMetadata validateTable(String keyspaceName, String tableName) {
if (tableName.isEmpty())
throw new InvalidRequestException("non-empty table is required");
KeyspaceMetadata keyspace = keyspaces.getNullable(keyspaceName);
if (keyspace == null)
throw new KeyspaceNotDefinedException(format("keyspace %s does not exist", keyspaceName));
TableMetadata metadata = keyspace.getTableOrViewNullable(tableName);
if (metadata == null)
throw new InvalidRequestException(format("table %s does not exist", tableName));
return metadata;
}
use of org.apache.cassandra.exceptions.InvalidRequestException in project cassandra by apache.
the class Json method parseJson.
/**
* Given a JSON string, return a map of columns to their values for the insert.
*/
public static Map<ColumnIdentifier, Term> parseJson(String jsonString, Collection<ColumnMetadata> expectedReceivers) {
try {
Map<String, Object> valueMap = JSON_OBJECT_MAPPER.readValue(jsonString, Map.class);
if (valueMap == null)
throw new InvalidRequestException("Got null for INSERT JSON values");
handleCaseSensitivity(valueMap);
Map<ColumnIdentifier, Term> columnMap = new HashMap<>(expectedReceivers.size());
for (ColumnSpecification spec : expectedReceivers) {
// explicit null value from no value
if (!valueMap.containsKey(spec.name.toString()))
continue;
Object parsedJsonObject = valueMap.remove(spec.name.toString());
if (parsedJsonObject == null) {
// This is an explicit user null
columnMap.put(spec.name, Constants.NULL_VALUE);
} else {
try {
columnMap.put(spec.name, spec.type.fromJSONObject(parsedJsonObject));
} catch (MarshalException exc) {
throw new InvalidRequestException(String.format("Error decoding JSON value for %s: %s", spec.name, exc.getMessage()));
}
}
}
if (!valueMap.isEmpty()) {
throw new InvalidRequestException(String.format("JSON values map contains unrecognized column: %s", valueMap.keySet().iterator().next()));
}
return columnMap;
} catch (IOException exc) {
throw new InvalidRequestException(String.format("Could not decode JSON string as a map: %s. (String was: %s)", exc.toString(), jsonString));
} catch (MarshalException exc) {
throw new InvalidRequestException(exc.getMessage());
}
}
use of org.apache.cassandra.exceptions.InvalidRequestException in project cassandra by apache.
the class QueryOptions method getJsonColumnValue.
/**
* Returns the term corresponding to column {@code columnName} in the JSON value of bind index {@code bindIndex}.
*
* This is functionally equivalent to:
* {@code Json.parseJson(UTF8Type.instance.getSerializer().deserialize(getValues().get(bindIndex)), expectedReceivers).get(columnName)}
* but this cache the result of parsing the JSON so that while this might be called for multiple columns on the same {@code bindIndex}
* value, the underlying JSON value is only parsed/processed once.
*
* Note: this is a bit more involved in CQL specifics than this class generally is but we as we need to cache this per-query and in an object
* that is available when we bind values, this is the easier place to have this.
*
* @param bindIndex the index of the bind value that should be interpreted as a JSON value.
* @param columnName the name of the column we want the value of.
* @param expectedReceivers the columns expected in the JSON value at index {@code bindIndex}. This is only used when parsing the
* json initially and no check is done afterwards. So in practice, any call of this method on the same QueryOptions object and with the same
* {@code bindIndx} values should use the same value for this parameter, but this isn't validated in any way.
*
* @return the value correspong to column {@code columnName} in the (JSON) bind value at index {@code bindIndex}. This may return null if the
* JSON value has no value for this column.
*/
public Term getJsonColumnValue(int bindIndex, ColumnIdentifier columnName, Collection<ColumnMetadata> expectedReceivers) throws InvalidRequestException {
if (jsonValuesCache == null)
jsonValuesCache = new ArrayList<>(Collections.<Map<ColumnIdentifier, Term>>nCopies(getValues().size(), null));
Map<ColumnIdentifier, Term> jsonValue = jsonValuesCache.get(bindIndex);
if (jsonValue == null) {
ByteBuffer value = getValues().get(bindIndex);
if (value == null)
throw new InvalidRequestException("Got null for INSERT JSON values");
jsonValue = Json.parseJson(UTF8Type.instance.getSerializer().deserialize(value), expectedReceivers);
jsonValuesCache.set(bindIndex, jsonValue);
}
return jsonValue.get(columnName);
}
use of org.apache.cassandra.exceptions.InvalidRequestException in project cassandra by apache.
the class AlterViewStatement method announceMigration.
public Event.SchemaChange announceMigration(QueryState queryState, boolean isLocalOnly) throws RequestValidationException {
TableMetadata meta = Schema.instance.validateTable(keyspace(), columnFamily());
if (!meta.isView())
throw new InvalidRequestException("Cannot use ALTER MATERIALIZED VIEW on Table");
ViewMetadata current = Schema.instance.getView(keyspace(), columnFamily());
if (attrs == null)
throw new InvalidRequestException("ALTER MATERIALIZED VIEW WITH invoked, but no parameters found");
attrs.validate();
TableParams params = attrs.asAlteredTableParams(current.metadata.params);
if (params.gcGraceSeconds == 0) {
throw new InvalidRequestException("Cannot alter gc_grace_seconds of a materialized view to 0, since this " + "value is used to TTL undelivered updates. Setting gc_grace_seconds too " + "low might cause undelivered updates to expire before being replayed.");
}
if (params.defaultTimeToLive > 0) {
throw new InvalidRequestException("Cannot set or alter default_time_to_live for a materialized view. " + "Data in a materialized view always expire at the same time than " + "the corresponding data in the parent table.");
}
ViewMetadata updated = current.copy(current.metadata.unbuild().params(params).build());
MigrationManager.announceViewUpdate(updated, isLocalOnly);
return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
Aggregations