Skip to content

Commit 8811517

Browse files
committed
Fix adding fixed length columns to an existing table. fixes #159
Retrofit from git-svn-id: https://svn.code.sf.net/p/jackcess/code/jackcess/trunk@1418 f203690c-595d-4dc9-a70b-905162fa7fd2
1 parent d46da1f commit 8811517

5 files changed

Lines changed: 36 additions & 26 deletions

File tree

src/main/java/io/github/spannm/jackcess/ColumnBuilder.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,14 @@ public void setTextSortOrder(ColumnImpl.SortOrder newTextSortOrder) {
353353
_sortOrder = newTextSortOrder;
354354
}
355355

356+
public boolean storeInNullMask() {
357+
return (getType() == DataType.BOOLEAN);
358+
}
359+
360+
public int getFixedDataSize() {
361+
return _type.getFixedSize(_length);
362+
}
363+
356364
/**
357365
* Checks that this column definition is valid.
358366
*

src/main/java/io/github/spannm/jackcess/DataType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ public enum DataType {
4343
* Corresponds to a java {@link Boolean}. Accepts Boolean or {@code null} (which is considered {@code false}).
4444
* Equivalent to SQL {@link Types#BOOLEAN}.
4545
*/
46-
BOOLEAN((byte) 0x01, "Bit", Types.BOOLEAN, 0),
46+
BOOLEAN((byte) 0x01, "Bit", Types.BOOLEAN, 1),
4747
/**
4848
* Corresponds to a java {@link Byte}. Accepts any {@link Number} (using {@link Number#byteValue}), Boolean as 1 or
4949
* 0, any Object converted to a String and parsed as Double, or {@code null}. Equivalent to SQL

src/main/java/io/github/spannm/jackcess/impl/ColumnImpl.java

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -231,13 +231,8 @@ protected ColumnImpl(TableImpl _table, String _name, DataType _type, int _colNum
231231

232232
mautoNumberGenerator = createAutoNumberGenerator();
233233

234-
if (mvariableLength) {
235-
mvarLenTableIndex = args.buffer.getShort(args.offset + getFormat().OFFSET_COLUMN_VARIABLE_TABLE_INDEX);
236-
mfixedDataOffset = 0;
237-
} else {
238-
mfixedDataOffset = args.buffer.getShort(args.offset + getFormat().OFFSET_COLUMN_FIXED_DATA_OFFSET);
239-
mvarLenTableIndex = 0;
240-
}
234+
mvarLenTableIndex = args.buffer.getShort(args.offset + getFormat().OFFSET_COLUMN_VARIABLE_TABLE_INDEX);
235+
mfixedDataOffset = args.buffer.getShort(args.offset + getFormat().OFFSET_COLUMN_FIXED_DATA_OFFSET);
241236
}
242237

243238
/**
@@ -426,6 +421,10 @@ public int getFixedDataOffset() {
426421
return mfixedDataOffset;
427422
}
428423

424+
protected int getFixedDataSize() {
425+
return mtype.getFixedSize(mcolumnLength);
426+
}
427+
429428
protected Charset getCharset() {
430429
return getDatabase().getCharset();
431430
}
@@ -1312,7 +1311,7 @@ protected ByteBuffer writeRealData(Object obj, int remainingRowLength, ByteOrder
13121311
* @return A buffer containing the bytes
13131312
*/
13141313
protected ByteBuffer writeFixedLengthField(Object obj, ByteOrder order) throws IOException {
1315-
int size = getType().getFixedSize(mcolumnLength);
1314+
int size = getFixedDataSize();
13161315

13171316
ByteBuffer buffer = writeFixedLengthField(obj, PageChannel.createBuffer(size, order));
13181317
buffer.flip();
@@ -1802,11 +1801,7 @@ protected static void writeDefinition(TableMutator mutator, ColumnBuilder col, B
18021801
buffer.putInt(TableImpl.MAGIC_TABLE_NUMBER); // constant magic number
18031802
buffer.putShort(col.getColumnNumber()); // Column Number
18041803

1805-
if (col.isVariableLength()) {
1806-
buffer.putShort(colOffsets.getNextVariableOffset(col));
1807-
} else {
1808-
buffer.putShort((short) 0);
1809-
}
1804+
buffer.putShort(colOffsets.getNextVariableOffset(col));
18101805

18111806
buffer.putShort(col.getColumnNumber()); // Column Number again
18121807

src/main/java/io/github/spannm/jackcess/impl/TableImpl.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ private static Object getRowColumn(JetFormat format, ByteBuffer rowBuffer, Colum
718718
// read fixed length value (non-boolean at this point)
719719
int dataStart = rowStart + format.OFFSET_COLUMN_FIXED_DATA_ROW_OFFSET;
720720
colDataPos = dataStart + column.getFixedDataOffset();
721-
colDataLen = column.getType().getFixedSize(column.getLength());
721+
colDataLen = column.getFixedDataSize();
722722

723723
} else {
724724
int varDataStart;
@@ -1085,20 +1085,20 @@ protected ColumnImpl mutateAddColumn(TableUpdater mutator) throws IOException {
10851085
tableBuffer.position(format.SIZE_TDEF_HEADER + _indexCount * format.SIZE_INDEX_DEFINITION + _columns.size() * format.SIZE_COLUMN_DEF_BLOCK);
10861086

10871087
// figure out the data offsets for the new column
1088-
int fixedOffset = 0;
10891088
int varOffset = 0;
1090-
if (column.isVariableLength()) {
1091-
// find the variable offset
1092-
for (ColumnImpl col : _varColumns) {
1093-
if (col.getVarLenTableIndex() >= varOffset) {
1094-
varOffset = col.getVarLenTableIndex() + 1;
1095-
}
1089+
// find the variable offset
1090+
for (ColumnImpl col : _varColumns) {
1091+
if (col.isVariableLength() && (col.getVarLenTableIndex() >= varOffset)) {
1092+
varOffset = col.getVarLenTableIndex() + 1;
10961093
}
1097-
} else {
1094+
}
1095+
1096+
int fixedOffset = 0;
1097+
if (!column.isVariableLength() && !column.storeInNullMask()) {
10981098
// find the fixed offset
10991099
for (ColumnImpl col : _columns) {
1100-
if (!col.isVariableLength() && col.getFixedDataOffset() >= fixedOffset) {
1101-
fixedOffset = col.getFixedDataOffset() + col.getType().getFixedSize(col.getLength());
1100+
if (!col.isVariableLength() && (col.getFixedDataOffset() >= fixedOffset)) {
1101+
fixedOffset = col.getFixedDataOffset() + col.getFixedDataSize();
11021102
}
11031103
}
11041104
}

src/main/java/io/github/spannm/jackcess/impl/TableMutator.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,15 +106,22 @@ public void set(int fixedOffset, int varOffset, int longVarOffset) {
106106
}
107107

108108
public short getNextVariableOffset(ColumnBuilder col) {
109+
if (!col.isVariableLength()) {
110+
return _varOffset;
111+
}
109112
if (!col.getType().isLongValue()) {
110113
return _varOffset++;
111114
}
112115
return _longVarOffset++;
113116
}
114117

115118
public short getNextFixedOffset(ColumnBuilder col) {
119+
if (col.storeInNullMask()) {
120+
// booleans are stored in null mask, not in fixed data section
121+
return 0;
122+
}
116123
short offset = _fixedOffset;
117-
_fixedOffset += (short) col.getType().getFixedSize(col.getLength());
124+
_fixedOffset += col.getFixedDataSize();
118125
return offset;
119126
}
120127
}

0 commit comments

Comments
 (0)