Skip to content

Commit 467d091

Browse files
committed
refactor: address PR review feedback for column metadata optimizations
- Replace magic number 0x0015 with TypeDuration constant in readTypeInfo fast-path - Extract duplicated keyspaceTableTracker logic in parsePreparedMetadata - Add detailed inline comment explaining parseResultMetadata simplification
1 parent 4d502c7 commit 467d091

File tree

1 file changed

+38
-22
lines changed

1 file changed

+38
-22
lines changed

frame.go

Lines changed: 38 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -723,8 +723,9 @@ func (f *framer) readTypeInfo() TypeInfo {
723723
typ: Type(id),
724724
}
725725

726-
// Fast path: simple native types (0x0001-0x0015) need no further processing
727-
if id > 0 && id <= 0x0015 {
726+
// Fast path: simple native types (0x0001 through TypeDuration) need no further processing.
727+
// These are all scalar types that require no additional wire reads beyond the type ID.
728+
if id > 0 && id <= uint16(TypeDuration) {
728729
return simple
729730
}
730731

@@ -851,23 +852,16 @@ func (f *framer) parsePreparedMetadata() preparedMetadata {
851852
}
852853

853854
var cols []ColumnInfo
854-
sameKeyspaceTable := true
855-
firstKeyspace := ""
856-
firstTable := ""
857855
readPerColumnSpec := !globalSpec
856+
var tracker keyspaceTableTracker
858857
if meta.colCount < 1000 {
859858
// preallocate columninfo to avoid excess copying
860859
cols = make([]ColumnInfo, meta.colCount)
861860
for i := 0; i < meta.colCount; i++ {
862861
col := &cols[i]
863862
keyspace, table := f.readColWithSpec(col, &meta.resultMetadata, globalSpec, meta.keyspace, meta.table, i, readPerColumnSpec)
864863
if readPerColumnSpec {
865-
if i == 0 {
866-
firstKeyspace = keyspace
867-
firstTable = table
868-
} else if keyspace != firstKeyspace || table != firstTable {
869-
sameKeyspaceTable = false
870-
}
864+
tracker.track(i, keyspace, table)
871865
}
872866
}
873867
} else {
@@ -877,20 +871,15 @@ func (f *framer) parsePreparedMetadata() preparedMetadata {
877871
var col ColumnInfo
878872
keyspace, table := f.readColWithSpec(&col, &meta.resultMetadata, globalSpec, meta.keyspace, meta.table, i, readPerColumnSpec)
879873
if readPerColumnSpec {
880-
if i == 0 {
881-
firstKeyspace = keyspace
882-
firstTable = table
883-
} else if keyspace != firstKeyspace || table != firstTable {
884-
sameKeyspaceTable = false
885-
}
874+
tracker.track(i, keyspace, table)
886875
}
887876
cols = append(cols, col)
888877
}
889878
}
890879

891-
if !globalSpec && meta.colCount > 0 && sameKeyspaceTable {
892-
meta.keyspace = firstKeyspace
893-
meta.table = firstTable
880+
if !globalSpec && meta.colCount > 0 && tracker.allSame {
881+
meta.keyspace = tracker.keyspace
882+
meta.table = tracker.table
894883
}
895884

896885
meta.columns = cols
@@ -919,6 +908,24 @@ func (r resultMetadata) String() string {
919908
return fmt.Sprintf("[metadata flags=0x%x paging_state=% X columns=%v]", r.flags, r.pagingState, r.columns)
920909
}
921910

911+
// keyspaceTableTracker tracks whether all columns in a prepared statement
912+
// share the same keyspace and table, recording the first column's values.
913+
type keyspaceTableTracker struct {
914+
keyspace string
915+
table string
916+
allSame bool
917+
}
918+
919+
func (t *keyspaceTableTracker) track(colIndex int, keyspace, table string) {
920+
if colIndex == 0 {
921+
t.keyspace = keyspace
922+
t.table = table
923+
t.allSame = true
924+
} else if keyspace != t.keyspace || table != t.table {
925+
t.allSame = false
926+
}
927+
}
928+
922929
func (f *framer) readColWithSpec(col *ColumnInfo, meta *resultMetadata, globalSpec bool, keyspace, table string, colIndex int, readPerColumnSpec bool) (string, string) {
923930
if readPerColumnSpec {
924931
// In case of prepared statements with per-column spec, we need to read the keyspace and table for each column.
@@ -964,7 +971,16 @@ func (f *framer) parseResultMetadata() resultMetadata {
964971

965972
globalSpec := meta.flags&frm.FlagGlobalTableSpec == frm.FlagGlobalTableSpec
966973
if globalSpec || meta.colCount > 0 {
967-
// globalSpec: read from metadata position; !globalSpec: read from first column position
974+
// When globalSpec is set, keyspace/table are encoded once at the metadata level.
975+
// When !globalSpec, the protocol technically encodes keyspace/table per-column and
976+
// they *could* differ. However, CQL ROWS results always come from a single table
977+
// (SELECT cannot produce columns from multiple tables), so we read the first
978+
// column's keyspace/table and reuse them for all columns, avoiding per-column
979+
// string allocation. Note that parsePreparedMetadata() does NOT apply this
980+
// optimization — it uses readPerColumnSpec for the result-set part, where prepared
981+
// batch metadata may legitimately reference multiple tables.
982+
// See readColWithSpec: column 0 skips reading (already consumed here), columns 1+
983+
// skip the redundant per-column keyspace/table bytes on the wire.
968984
meta.keyspace = f.readString()
969985
meta.table = f.readString()
970986
}
@@ -1539,7 +1555,7 @@ func (f *framer) skipString() {
15391555
size := f.readShort()
15401556

15411557
if len(f.buf) < int(size) {
1542-
panic(fmt.Errorf("not enough bytes in buffer to skip string require %d got: %d", size, len(f.buf)))
1558+
panic(fmt.Errorf("not enough bytes in buffer to skip string, requires %d got %d", size, len(f.buf)))
15431559
}
15441560

15451561
f.buf = f.buf[size:]

0 commit comments

Comments
 (0)