use of herddb.model.Column in project herddb by diennea.
the class TableManager method validateAlterTable.
@Override
public void validateAlterTable(Table table, StatementEvaluationContext context) throws StatementExecutionException {
List<String> columnsChangedFromNullToNotNull = new ArrayList<>();
for (Column c : this.table.columns) {
Column newColumnSpecs = table.getColumn(c.name);
if (newColumnSpecs == null) {
// dropped column
LOGGER.log(Level.INFO, "Table {0}.{1} dropping column {2}", new Object[] { table.tablespace, table.name, c.name });
} else if (newColumnSpecs.type == c.type) {
// no data type change
} else if (ColumnTypes.isNotNullToNullConversion(c.type, newColumnSpecs.type)) {
LOGGER.log(Level.INFO, "Table {0}.{1} making column {2} NULLABLE", new Object[] { table.tablespace, table.name, newColumnSpecs.name });
} else if (ColumnTypes.isNullToNotNullConversion(c.type, newColumnSpecs.type)) {
LOGGER.log(Level.INFO, "Table {0}.{1} making column {2} NOT NULL", new Object[] { table.tablespace, table.name, newColumnSpecs.name });
columnsChangedFromNullToNotNull.add(c.name);
}
}
for (final String column : columnsChangedFromNullToNotNull) {
LOGGER.log(Level.INFO, "Table {0}.{1} validating column {2}, check for NULL values", new Object[] { table.tablespace, table.name, column });
ScanStatement scan = new ScanStatement(this.table.tablespace, this.table, new Predicate() {
@Override
public boolean evaluate(Record record, StatementEvaluationContext context) throws StatementExecutionException {
return record.getDataAccessor(table).get(column) == null;
}
});
// fast fail
scan.setLimits(new ScanLimitsImpl(1, 0));
boolean foundOneNull = false;
try (DataScanner scanner = this.scan(scan, context, null, false, false)) {
foundOneNull = scanner.hasNext();
} catch (DataScannerException err) {
throw new StatementExecutionException(err);
}
if (foundOneNull) {
throw new StatementExecutionException("Found a record in table " + table.name + " that contains a NULL value for column " + column + " ALTER command is not possible");
}
}
// if we are adding new FK we have to check that the FK is not violated
if (table.foreignKeys != null) {
List<ForeignKeyDef> newForeignKeys;
if (this.table.foreignKeys == null) {
newForeignKeys = Arrays.asList(table.foreignKeys);
} else {
Set<String> currentKfs = Stream.of(this.table.foreignKeys).map(f -> f.name.toLowerCase()).collect(Collectors.toSet());
newForeignKeys = Stream.of(table.foreignKeys).filter(fk -> !currentKfs.contains(fk.name)).collect(Collectors.toList());
}
for (ForeignKeyDef newFk : newForeignKeys) {
validateForeignKeyConsistency(newFk, context, null);
}
}
}
use of herddb.model.Column in project herddb by diennea.
the class DataAccessorForFullRecord method forEach.
@Override
public void forEach(BiConsumer<String, Object> consumer) {
// best case
if (table.physicalLayoutLikeLogicalLayout) {
// no need to create a Map
if (table.primaryKey.length == 1) {
String pkField = table.primaryKey[0];
Object value = RecordSerializer.deserialize(record.key, table.getColumn(pkField).type);
consumer.accept(pkField, value);
if (value instanceof RawString) {
((RawString) value).recycle();
}
} else {
try (final ByteArrayCursor din = record.key.newCursor()) {
for (String primaryKeyColumn : table.primaryKey) {
Bytes value = din.readBytesNoCopy();
Object theValue = RecordSerializer.deserialize(value, table.getColumn(primaryKeyColumn).type);
consumer.accept(primaryKeyColumn, theValue);
if (theValue instanceof RawString) {
((RawString) theValue).recycle();
}
}
} catch (IOException err) {
throw new IllegalStateException("bad data:" + err, err);
}
}
try (ByteArrayCursor din = record.value.newCursor()) {
while (!din.isEof()) {
int serialPosition;
serialPosition = din.readVIntNoEOFException();
if (din.isEof()) {
break;
}
Column col = table.getColumnBySerialPosition(serialPosition);
if (col != null) {
Object value = RecordSerializer.deserializeTypeAndValue(din);
consumer.accept(col.name, value);
} else {
// we have to deserialize always the value, even the column is no more present
RecordSerializer.skipTypeAndValue(din);
}
}
} catch (IOException err) {
throw new IllegalStateException("bad data:" + err, err);
}
} else {
// bad case
for (int i = 0; i < table.columnNames.length; i++) {
String columnName = table.columnNames[i];
Object value = get(i);
consumer.accept(columnName, value);
if (value instanceof RawString) {
((RawString) value).recycle();
}
}
}
}
use of herddb.model.Column in project herddb by diennea.
the class RecordSerializer method accessRawDataFromValue.
static Object accessRawDataFromValue(int index, Bytes value, Table table) throws IOException {
Column column = table.getColumn(index);
try (ByteArrayCursor din = value.newCursor()) {
while (!din.isEof()) {
int serialPosition;
serialPosition = din.readVIntNoEOFException();
if (din.isEof()) {
return null;
}
Column col = table.getColumnBySerialPosition(serialPosition);
if (col != null && col.serialPosition == column.serialPosition) {
return deserializeTypeAndValue(din);
} else {
// we have to deserialize always the value, even the column is no more present
skipTypeAndValue(din);
}
}
return null;
}
}
use of herddb.model.Column in project herddb by diennea.
the class RecordSerializer method serializeIndexKey.
public static Bytes serializeIndexKey(DataAccessor record, ColumnsList index, String[] columns) {
String[] indexedColumnsList = index.getPrimaryKey();
if (indexedColumnsList.length == 1) {
String pkColumn = indexedColumnsList[0];
if (columns.length != 1 && !columns[0].equals(pkColumn)) {
throw new IllegalArgumentException("SQLTranslator error, " + Arrays.toString(columns) + " != " + Arrays.asList(pkColumn));
}
Column c = index.getColumn(pkColumn);
Object v = record.get(c.name);
if (v == null) {
if (index.allowNullsForIndexedValues()) {
return null;
}
throw new IllegalArgumentException("key field " + pkColumn + " cannot be null. Record data: " + record);
}
byte[] fieldValue = serialize(v, c.type);
return Bytes.from_array(fieldValue);
} else {
VisibleByteArrayOutputStream key = new VisibleByteArrayOutputStream(columns.length * Long.BYTES);
// beware that sometime we serialize only a part of the PK, for instance of a prefix index scan
try (ExtendedDataOutputStream doo_key = new ExtendedDataOutputStream(key)) {
int i = 0;
for (String indexedColumn : columns) {
if (!indexedColumn.equals(indexedColumnsList[i])) {
throw new IllegalArgumentException("SQLTranslator error, " + Arrays.toString(columns) + " != " + Arrays.asList(indexedColumnsList));
}
Column c = index.getColumn(indexedColumn);
Object v = record.get(c.name);
if (v == null) {
if (!index.allowNullsForIndexedValues()) {
throw new IllegalArgumentException("key field " + indexedColumn + " cannot be null. Record data: " + record);
}
if (i == 0) {
// if the first column is null than we do not index the record at all
return null;
} else {
// we stop serializing the value at the first null
return Bytes.from_array(key.getBuffer(), 0, key.size());
}
}
serializeTo(v, c.type, doo_key);
i++;
}
} catch (IOException err) {
throw new RuntimeException(err);
}
return Bytes.from_array(key.getBuffer(), 0, key.size());
}
}
use of herddb.model.Column in project herddb by diennea.
the class RecordSerializer method serializeValueRaw.
public static byte[] serializeValueRaw(Map<String, Object> record, Table table, int expectedSize) {
VisibleByteArrayOutputStream value = new VisibleByteArrayOutputStream(expectedSize <= 0 ? INITIAL_BUFFER_SIZE : expectedSize);
try (ExtendedDataOutputStream doo = new ExtendedDataOutputStream(value)) {
for (Column c : table.columns) {
Object v = record.get(c.name);
if (v != null && !table.isPrimaryKeyColumn(c.name)) {
doo.writeVInt(c.serialPosition);
serializeTypeAndValue(v, c.type, doo);
}
}
} catch (IOException err) {
throw new RuntimeException(err);
}
return value.toByteArrayNoCopy();
}
Aggregations