Skip to content

Commit ed07f24

Browse files
committed
Format protocol preparation sources and reject empty formatter checks
1 parent 96099e3 commit ed07f24

16 files changed

Lines changed: 688 additions & 319 deletions

‎example-worker/catalog_def.cpp‎

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,9 @@ void declare_catalog(vgi::Worker& worker) {
565565
// In `main`, not `data`: a view is looked up by the schema the user names,
566566
// and the suite names `main` for these two.
567567
auto& main = worker.catalog().schema("main");
568-
main.tables.push_back(backed_by("projection_rows", "projection_sequence", arrow::schema({arrow::field("n", arrow::int32(), true)}), "Finite optional scalar projection example"));
568+
main.tables.push_back(backed_by("projection_rows", "projection_sequence",
569+
arrow::schema({arrow::field("n", arrow::int32(), true)}),
570+
"Finite optional scalar projection example"));
569571
main.comment = "Example functions for testing VGI";
570572
main.tables.push_back(backed_by("test_same_name_table", "test_same_name_table_scan",
571573
columns({{"tag", arrow::utf8()}}),
@@ -632,7 +634,8 @@ void declare_catalog(vgi::Worker& worker) {
632634
"Department reference table");
633635
departments.cardinality = 3;
634636
departments.constraints = constraint_fixtures::records("departments");
635-
departments.columns = constraint_fixtures::required_schema(departments.columns, "departments");
637+
departments.columns =
638+
constraint_fixtures::required_schema(departments.columns, "departments");
636639
// Bounds wider than the three rows on purpose: they describe the table
637640
// the fixture stands in for, and `column_statistics.test` folds
638641
// `id > 100` to EMPTY_RESULT against them, not against the data.
@@ -746,10 +749,16 @@ void declare_catalog(vgi::Worker& worker) {
746749
// computes the other two.
747750
auto generated = backed_by(
748751
"generated_sequence", "sequence",
749-
arrow::schema({arrow::field("n", arrow::int64(), /*nullable=*/true),
750-
tagged("doubled", arrow::int64(), {"vgi.column.generated.v1", "vgi.column.generation.v1"}, {vgi::generated_expression_metadata("n * 2", {"data"}), "virtual"}),
751-
tagged("label", arrow::utf8(), {"vgi.column.generated.v1", "vgi.column.generation.v1"},
752-
{vgi::generated_expression_metadata("'item_' || CAST(n AS VARCHAR)", {"data"}), "virtual"})}),
752+
arrow::schema(
753+
{arrow::field("n", arrow::int64(), /*nullable=*/true),
754+
tagged("doubled", arrow::int64(),
755+
{"vgi.column.generated.v1", "vgi.column.generation.v1"},
756+
{vgi::generated_expression_metadata("n * 2", {"data"}), "virtual"}),
757+
tagged(
758+
"label", arrow::utf8(),
759+
{"vgi.column.generated.v1", "vgi.column.generation.v1"},
760+
{vgi::generated_expression_metadata("'item_' || CAST(n AS VARCHAR)", {"data"}),
761+
"virtual"})}),
753762
"Table with generated columns backed by sequence(10)");
754763
generated.scan_arguments = vgi::serialize_scan_arguments({int64_arg(10)});
755764
generated.cardinality = 10;
@@ -904,7 +913,8 @@ void declare_catalog(vgi::Worker& worker) {
904913
vgi::TimeTravelVersion entry;
905914
entry.version = version;
906915
entry.columns = constraint_fixtures::required_schema(
907-
columns(per_version[static_cast<size_t>(version) - 1]), "versioned_constraints", version);
916+
columns(per_version[static_cast<size_t>(version) - 1]), "versioned_constraints",
917+
version);
908918
entry.scan_function = "versioned_constraints_scan";
909919
entry.scan_arguments = vgi::serialize_scan_arguments({int64_arg(version)});
910920
entry.timestamp_year = constraint_years[version - 1];

‎example-worker/constraint_fixtures.h‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,12 @@ inline std::vector<std::string> definitions(const std::string& table, int64_t ve
137137
constraint(table, "fixture:versioned_constraints:nn:id", "NOT_NULL", {{"id"}}),
138138
};
139139
if (version >= 2) {
140-
result.push_back(constraint(table, "fixture:versioned_constraints:nn:name", "NOT_NULL", {{"name"}}));
141-
result.push_back(constraint(table, "fixture:versioned_constraints:primary", "PRIMARY_KEY", {{"id"}}));
142-
result.push_back(constraint(table, "fixture:versioned_constraints:unique:email", "UNIQUE", {{"email"}}));
140+
result.push_back(
141+
constraint(table, "fixture:versioned_constraints:nn:name", "NOT_NULL", {{"name"}}));
142+
result.push_back(constraint(table, "fixture:versioned_constraints:primary",
143+
"PRIMARY_KEY", {{"id"}}));
144+
result.push_back(constraint(table, "fixture:versioned_constraints:unique:email",
145+
"UNIQUE", {{"email"}}));
143146
}
144147
if (version >= 3)
145148
result.push_back(constraint(table, "fixture:versioned_constraints:fk:department",

‎example-worker/table/rff.cpp‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,8 @@ void register_rff(vgi::Worker& worker) {
266266
// The `rff_*` tables, declared by the catalog.
267267
std::vector<vgi::CatalogTable> rff_tables() {
268268
const auto table = [](std::string name, std::shared_ptr<arrow::Schema> columns,
269-
std::string scan, std::vector<std::vector<std::vector<std::string>>> required) {
269+
std::string scan,
270+
std::vector<std::vector<std::vector<std::string>>> required) {
270271
vgi::CatalogTable entry;
271272
entry.name = std::move(name);
272273
entry.columns = std::move(columns);

‎example-worker/table/sequence.cpp‎

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,9 @@ class Sequence : public vgi::TableFunction {
147147
};
148148

149149
class ProjectionRows : public vgi::TableProducer {
150-
vgi::ProcessParams params_; bool done_ = false;
150+
vgi::ProcessParams params_;
151+
bool done_ = false;
152+
151153
public:
152154
explicit ProjectionRows(vgi::ProcessParams params) : params_(std::move(params)) {}
153155
std::shared_ptr<arrow::RecordBatch> next_batch() override {
@@ -156,8 +158,17 @@ class ProjectionRows : public vgi::TableProducer {
156158
arrow::ArrayVector arrays;
157159
for (const auto& field : params_.output_schema->fields()) {
158160
std::shared_ptr<arrow::Array> array;
159-
if (field->name() == "n") { arrow::Int32Builder b; for (int n = 0; n < 10; ++n) (void)b.Append(n); (void)b.Finish(&array); }
160-
else { if (params_.bind_opaque_data.empty()) throw std::invalid_argument("projection state missing"); arrow::Int64Builder b; for (int64_t n = 0; n < 10; ++n) (void)b.Append(n); (void)b.Finish(&array); }
161+
if (field->name() == "n") {
162+
arrow::Int32Builder b;
163+
for (int n = 0; n < 10; ++n) (void)b.Append(n);
164+
(void)b.Finish(&array);
165+
} else {
166+
if (params_.bind_opaque_data.empty())
167+
throw std::invalid_argument("projection state missing");
168+
arrow::Int64Builder b;
169+
for (int64_t n = 0; n < 10; ++n) (void)b.Append(n);
170+
(void)b.Finish(&array);
171+
}
161172
arrays.push_back(array);
162173
}
163174
return arrow::RecordBatch::Make(params_.output_schema, 10, arrays);
@@ -166,24 +177,49 @@ class ProjectionRows : public vgi::TableProducer {
166177
class ProjectionSequence : public vgi::TableFunction {
167178
public:
168179
std::string name() const override { return "projection_sequence"; }
169-
vgi::FunctionMetadata metadata() const override { vgi::FunctionMetadata md; md.projection_pushdown = true; return md; }
180+
vgi::FunctionMetadata metadata() const override {
181+
vgi::FunctionMetadata md;
182+
md.projection_pushdown = true;
183+
return md;
184+
}
170185
std::vector<vgi::ArgSpec> argument_specs() const override { return {}; }
171-
std::shared_ptr<arrow::Schema> bind(const vgi::BindParams&) const override { return arrow::schema({arrow::field("n", arrow::int32(), true)}); }
172-
std::vector<std::string> projection_expression_profiles(const vgi::BindParams&) const override { return {vgi::SCALAR_PROJECTION_PROFILE}; }
173-
vgi::BindRepeatability repeatability(const vgi::BindParams&) const override { return vgi::BindRepeatability::StableWithinQuery; }
174-
vgi::ProjectionAcceptance projection(const vgi::BindParams&, const vgi::ProjectionProposal& p) const override {
175-
vgi::ProjectionAcceptance result; auto fields = p.source_schema->fields();
186+
std::shared_ptr<arrow::Schema> bind(const vgi::BindParams&) const override {
187+
return arrow::schema({arrow::field("n", arrow::int32(), true)});
188+
}
189+
std::vector<std::string> projection_expression_profiles(const vgi::BindParams&) const override {
190+
return {vgi::SCALAR_PROJECTION_PROFILE};
191+
}
192+
vgi::BindRepeatability repeatability(const vgi::BindParams&) const override {
193+
return vgi::BindRepeatability::StableWithinQuery;
194+
}
195+
vgi::ProjectionAcceptance projection(const vgi::BindParams&,
196+
const vgi::ProjectionProposal& p) const override {
197+
vgi::ProjectionAcceptance result;
198+
auto fields = p.source_schema->fields();
176199
for (size_t i = 0; i < p.expressions.size(); ++i) {
177200
const auto& row = p.expressions[i];
178201
auto sql = std::static_pointer_cast<arrow::StringArray>(row->column(0))->GetString(0);
179202
auto c = std::static_pointer_cast<arrow::StructArray>(row->column(3));
180-
const auto str = [&](int n) { return std::static_pointer_cast<arrow::StringArray>(c->field(n))->GetString(0); };
181-
if (sql == "CAST(\"n\" AS BIGINT)" && str(0) == "UTC" && str(1) == "binary" && str(2) == "asc" && str(3) == "nulls_last" && std::static_pointer_cast<arrow::BooleanArray>(c->field(4))->Value(0) && p.result_schema->field(static_cast<int>(i))->type()->id() == arrow::Type::INT64) { result.accepted_indices.push_back(static_cast<int64_t>(i)); fields.push_back(p.result_schema->field(static_cast<int>(i))); }
203+
const auto str = [&](int n) {
204+
return std::static_pointer_cast<arrow::StringArray>(c->field(n))->GetString(0);
205+
};
206+
if (sql == "CAST(\"n\" AS BIGINT)" && str(0) == "UTC" && str(1) == "binary" &&
207+
str(2) == "asc" && str(3) == "nulls_last" &&
208+
std::static_pointer_cast<arrow::BooleanArray>(c->field(4))->Value(0) &&
209+
p.result_schema->field(static_cast<int>(i))->type()->id() == arrow::Type::INT64) {
210+
result.accepted_indices.push_back(static_cast<int64_t>(i));
211+
fields.push_back(p.result_schema->field(static_cast<int>(i)));
212+
}
213+
}
214+
if (!result.accepted_indices.empty()) {
215+
result.output_schema = arrow::schema(fields, p.source_schema->metadata());
216+
result.opaque_data = std::to_string(result.accepted_indices.size());
182217
}
183-
if (!result.accepted_indices.empty()) { result.output_schema = arrow::schema(fields, p.source_schema->metadata()); result.opaque_data = std::to_string(result.accepted_indices.size()); }
184218
return result;
185219
}
186-
std::unique_ptr<vgi::TableProducer> init(const vgi::ProcessParams& p) const override { return std::make_unique<ProjectionRows>(p); }
220+
std::unique_ptr<vgi::TableProducer> init(const vgi::ProcessParams& p) const override {
221+
return std::make_unique<ProjectionRows>(p);
222+
}
187223
};
188224
} // namespace
189225

‎example-worker/table/static_scan.cpp‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -364,8 +364,8 @@ class VersionedConstraintsScan : public vgi::TableFunction {
364364

365365
std::shared_ptr<arrow::Schema> bind(const vgi::BindParams& params) const override {
366366
const auto version = params.arguments.const_int64(0).value_or(3);
367-
return constraint_fixtures::required_schema(
368-
columns_schema(constraints_version(version)), "versioned_constraints", version);
367+
return constraint_fixtures::required_schema(columns_schema(constraints_version(version)),
368+
"versioned_constraints", version);
369369
}
370370

371371
vgi::TableCardinality cardinality(const vgi::ProcessParams& params) const override {
@@ -690,8 +690,8 @@ void register_static_scans(vgi::Worker& worker) {
690690
// Catalog facts and scans share these immutable arrays. Validate before
691691
// registration, so an invalid fixture cannot publish trusted constraints.
692692
for (const std::string table : {"departments", "products", "employees", "projects"}) {
693-
worker.register_table(std::make_shared<StaticScan>(
694-
table + "_scan", constraint_fixtures::rows(table), table));
693+
worker.register_table(
694+
std::make_shared<StaticScan>(table + "_scan", constraint_fixtures::rows(table), table));
695695
}
696696
// Ordered by id, not by the ENUM ordinal the statistics are derived from:
697697
// the two disagreeing is exactly what `column_statistics.test` checks.

‎include/vgi/table_function.h‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -174,11 +174,17 @@ class TableFunction {
174174

175175
virtual std::unique_ptr<TableProducer> init(const ProcessParams& params) const = 0;
176176
// Explicit per-bind offer. Ordinary column selection never enables this hook.
177-
virtual std::vector<std::string> projection_expression_profiles(const BindParams&) const { return {}; }
177+
virtual std::vector<std::string> projection_expression_profiles(const BindParams&) const {
178+
return {};
179+
}
178180
// Opt in only when the bound source/transaction fixes the logical rows.
179-
virtual BindRepeatability repeatability(const BindParams&) const { return BindRepeatability::Unknown; }
181+
virtual BindRepeatability repeatability(const BindParams&) const {
182+
return BindRepeatability::Unknown;
183+
}
180184
// Pure planning: no resources allocated, rows consumed, or effects produced.
181-
virtual ProjectionAcceptance projection(const BindParams&, const ProjectionProposal&) const { return {}; }
185+
virtual ProjectionAcceptance projection(const BindParams&, const ProjectionProposal&) const {
186+
return {};
187+
}
182188

183189
// The planner's estimate. The default declines to guess, which is what
184190
// most generators should do.

‎scripts/format.sh‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,16 @@ CF="$(find_clang_format)" || {
3737
# Generated sources are excluded: they are rewritten from the protocol
3838
# definition, and formatting them only guarantees the next regeneration
3939
# produces a diff.
40+
if ! git -C "$ROOT" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
41+
echo "format.sh requires a Git checkout to enumerate source files." >&2
42+
exit 2
43+
fi
4044
mapfile -t FILES < <(cd "$ROOT" && git ls-files '*.cpp' '*.h' '*.hpp' \
4145
| grep -v '^include/vgi/generated/' | grep -v '^src/generated/' | grep -v '^vcpkg/')
46+
if [[ ${#FILES[@]} == 0 ]]; then
47+
echo "format.sh found no tracked C++ sources." >&2
48+
exit 2
49+
fi
4250

4351
if [[ "${1:-}" == "--check" ]]; then
4452
failed=0

0 commit comments

Comments
 (0)