feat: expand protocol
This commit is contained in:
1 parent
b94896cb62
commit
96ab73e9e3
1 file changed
+161
@@ -3452,3 +3452,164 @@ test "empty txn_op entry list round trips" {
|
||||
try std.testing.expectEqual(@as(usize, 0), decoded.len);
|
||||
}
|
||||
|
||||
test "decodeTxnOp rejects an unknown verb byte" {
|
||||
const allocator = std.testing.allocator;
|
||||
var buf = std.ArrayList(u8).init(allocator);
|
||||
defer buf.deinit();
|
||||
const w = encode.ByteWriter.init(&buf);
|
||||
try w.putU32(1);
|
||||
try w.byte(9);
|
||||
try std.testing.expectError(error.Malformed, decodeTxnOp(allocator, buf.items));
|
||||
}
|
||||
|
||||
test "txn_op result round trips the applied count" {
|
||||
const allocator = std.testing.allocator;
|
||||
const payload = try encodeTxnResult(allocator, 7);
|
||||
defer allocator.free(payload);
|
||||
try std.testing.expectEqual(@as(u32, 7), try decodeTxnResult(payload));
|
||||
}
|
||||
|
||||
test "table_window args round trip a ranking spec with a partition, an order-by, and an expr" {
|
||||
const allocator = std.testing.allocator;
|
||||
const orderBy = [_]querymod.OrderBy{.{ .field = "day", .descending = false }};
|
||||
const partitionBy = [_][]const u8{"city"};
|
||||
const specs = [_]windowmod.WindowSpec{.{ .field = "", .kind = .row_number }};
|
||||
const payload = try encodeTableWindow(allocator, "orders", &specs, &partitionBy, &orderBy, 0, 0, "total gt i:10", .rows);
|
||||
defer allocator.free(payload);
|
||||
const args = try decodeTableWindow(allocator, payload);
|
||||
defer allocator.free(args.specs);
|
||||
defer allocator.free(args.partitionBy);
|
||||
defer allocator.free(args.orderBy);
|
||||
|
||||
try std.testing.expectEqualStrings("orders", args.table);
|
||||
try std.testing.expectEqual(@as(usize, 1), args.specs.len);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.row_number, args.specs[0].kind);
|
||||
try std.testing.expectEqualStrings("", args.specs[0].field);
|
||||
try std.testing.expectEqual(@as(usize, 1), args.partitionBy.len);
|
||||
try std.testing.expectEqualStrings("city", args.partitionBy[0]);
|
||||
try std.testing.expectEqual(@as(usize, 1), args.orderBy.len);
|
||||
try std.testing.expectEqualStrings("day", args.orderBy[0].field);
|
||||
try std.testing.expect(!args.orderBy[0].descending);
|
||||
try std.testing.expectEqualStrings("total gt i:10", args.exprText);
|
||||
}
|
||||
|
||||
test "table_window args round trip a sum spec with no partition, no order-by, and an empty expr" {
|
||||
const allocator = std.testing.allocator;
|
||||
const specs = [_]windowmod.WindowSpec{.{ .field = "total", .kind = .sum }};
|
||||
const payload = try encodeTableWindow(allocator, "orders", &specs, &.{}, &.{}, 0, 0, "", .rows);
|
||||
defer allocator.free(payload);
|
||||
const args = try decodeTableWindow(allocator, payload);
|
||||
defer allocator.free(args.specs);
|
||||
defer allocator.free(args.partitionBy);
|
||||
defer allocator.free(args.orderBy);
|
||||
|
||||
try std.testing.expectEqual(@as(usize, 1), args.specs.len);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.sum, args.specs[0].kind);
|
||||
try std.testing.expectEqualStrings("total", args.specs[0].field);
|
||||
try std.testing.expectEqual(@as(usize, 0), args.partitionBy.len);
|
||||
try std.testing.expectEqual(@as(usize, 0), args.orderBy.len);
|
||||
try std.testing.expectEqualStrings("", args.exprText);
|
||||
}
|
||||
|
||||
test "table_window args round trip a count_distinct spec alongside sum, no extra wire bytes needed" {
|
||||
const allocator = std.testing.allocator;
|
||||
const orderBy = [_]querymod.OrderBy{.{ .field = "day" }};
|
||||
const specs = [_]windowmod.WindowSpec{
|
||||
.{ .field = "tag", .kind = .count_distinct },
|
||||
.{ .field = "amount", .kind = .sum },
|
||||
};
|
||||
const payload = try encodeTableWindow(allocator, "orders", &specs, &.{}, &orderBy, 0, 0, "", .rows);
|
||||
defer allocator.free(payload);
|
||||
const args = try decodeTableWindow(allocator, payload);
|
||||
defer allocator.free(args.specs);
|
||||
defer allocator.free(args.partitionBy);
|
||||
defer allocator.free(args.orderBy);
|
||||
|
||||
try std.testing.expectEqual(@as(usize, 2), args.specs.len);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.count_distinct, args.specs[0].kind);
|
||||
try std.testing.expectEqualStrings("tag", args.specs[0].field);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.sum, args.specs[1].kind);
|
||||
}
|
||||
|
||||
test "table_window args round trip first_value/last_value specs alongside a partition/order/RANGE frame" {
|
||||
const allocator = std.testing.allocator;
|
||||
const orderBy = [_]querymod.OrderBy{.{ .field = "day" }};
|
||||
const partitionBy = [_][]const u8{"city"};
|
||||
const specs = [_]windowmod.WindowSpec{
|
||||
.{ .field = "amount", .kind = .first_value },
|
||||
.{ .field = "amount", .kind = .last_value },
|
||||
};
|
||||
const payload = try encodeTableWindow(allocator, "orders", &specs, &partitionBy, &orderBy, 0, 0, "", .range);
|
||||
defer allocator.free(payload);
|
||||
const args = try decodeTableWindow(allocator, payload);
|
||||
defer allocator.free(args.specs);
|
||||
defer allocator.free(args.partitionBy);
|
||||
defer allocator.free(args.orderBy);
|
||||
|
||||
try std.testing.expectEqual(@as(usize, 2), args.specs.len);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.first_value, args.specs[0].kind);
|
||||
try std.testing.expectEqualStrings("amount", args.specs[0].field);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.last_value, args.specs[1].kind);
|
||||
try std.testing.expectEqualStrings("amount", args.specs[1].field);
|
||||
try std.testing.expectEqual(windowmod.FrameMode.range, args.frame);
|
||||
}
|
||||
|
||||
test "table_window args round trip MULTIPLE specs sharing one partition/order/frame" {
|
||||
const allocator = std.testing.allocator;
|
||||
const specs = [_]windowmod.WindowSpec{
|
||||
.{ .field = "total", .kind = .sum },
|
||||
.{ .field = "total", .kind = .avg },
|
||||
.{ .field = "", .kind = .rank },
|
||||
};
|
||||
const payload = try encodeTableWindow(allocator, "orders", &specs, &.{}, &.{}, 0, 0, "", .rows);
|
||||
defer allocator.free(payload);
|
||||
const args = try decodeTableWindow(allocator, payload);
|
||||
defer allocator.free(args.specs);
|
||||
defer allocator.free(args.partitionBy);
|
||||
defer allocator.free(args.orderBy);
|
||||
|
||||
try std.testing.expectEqual(@as(usize, 3), args.specs.len);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.sum, args.specs[0].kind);
|
||||
try std.testing.expectEqualStrings("total", args.specs[0].field);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.avg, args.specs[1].kind);
|
||||
try std.testing.expectEqualStrings("total", args.specs[1].field);
|
||||
try std.testing.expectEqual(windowmod.WindowKind.rank, args.specs[2].kind);
|
||||
try std.testing.expectEqualStrings("", args.specs[2].field);
|
||||
}
|
||||
|
||||
test "table_window args round trip a nonzero offset and limit" {
|
||||
const allocator = std.testing.allocator;
|
||||
const specs = [_]windowmod.WindowSpec{.{ .field = "", .kind = .rank }};
|
||||
const payload = try encodeTableWindow(allocator, "orders", &specs, &.{}, &.{}, 2, 5, "", .rows);
|
||||
defer allocator.free(payload);
|
||||
const args = try decodeTableWindow(allocator, payload);
|
||||
defer allocator.free(args.specs);
|
||||
defer allocator.free(args.partitionBy);
|
||||
defer allocator.free(args.orderBy);
|
||||
|
||||
try std.testing.expectEqual(@as(u32, 2), args.offset);
|
||||
try std.testing.expectEqual(@as(u32, 5), args.limit);
|
||||
}
|
||||
|
||||
test "table_window args round trip a RANGE frame, and default to ROWS when the byte is 0" {
|
||||
const allocator = std.testing.allocator;
|
||||
const order = [_]querymod.OrderBy{.{ .field = "day", .descending = false }};
|
||||
const specs = [_]windowmod.WindowSpec{.{ .field = "amount", .kind = .sum }};
|
||||
|
||||
const rangePayload = try encodeTableWindow(allocator, "orders", &specs, &.{}, &order, 0, 0, "", .range);
|
||||
defer allocator.free(rangePayload);
|
||||
const rangeArgs = try decodeTableWindow(allocator, rangePayload);
|
||||
defer allocator.free(rangeArgs.specs);
|
||||
defer allocator.free(rangeArgs.partitionBy);
|
||||
defer allocator.free(rangeArgs.orderBy);
|
||||
try std.testing.expectEqual(windowmod.FrameMode.range, rangeArgs.frame);
|
||||
|
||||
const rowsPayload = try encodeTableWindow(allocator, "orders", &specs, &.{}, &order, 0, 0, "", .rows);
|
||||
defer allocator.free(rowsPayload);
|
||||
const rowsArgs = try decodeTableWindow(allocator, rowsPayload);
|
||||
defer allocator.free(rowsArgs.specs);
|
||||
defer allocator.free(rowsArgs.partitionBy);
|
||||
defer allocator.free(rowsArgs.orderBy);
|
||||
try std.testing.expectEqual(windowmod.FrameMode.rows, rowsArgs.frame);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user