Without naming a schema, a serialized predicate's column references
are ambiguous: the same field name can refer to different field IDs
across schema-evolution events, and Substrait field-reference IDs
mean nothing without saying which schema they index into.
Make the request shape unambiguous:
- Add ParquetPushdownRequest.SchemaId (Iceberg schema id) to the
proto and to the design's API sketch.
- Document the binding contract in the design: the predicate must
carry only field-id references; the connector binds before
sending, the server checks ids against the schema.
- Validation now rejects (predicate set, schema_id == 0) with
InvalidArgument before any work is done. Deeper "every field id
exists in the snapshot's schema" check needs catalog access and
lands in M3.
- Update / add tests covering the new gate.
Implement the gRPC service surface of the pushdown daemon:
- Service struct embeds the generated UnimplementedSeaweed
ParquetPushdownServer, exposes Ping (returns version + trust mode)
and Pushdown (returns Unimplemented after request-shape validation).
- request_validation.go enforces hard caps (max data files, columns,
predicate bytes, row-id cap, vector dim, top_k) and content-type
rules (Puffin DV requires blob_length + referenced_data_file;
equality delete requires equality_field_ids; predicate_kind and
predicate must be set together).
- stats.go is a small accumulator that produces a PushdownStats
message stamped with trust_mode and elapsed micros; M0 wires it
into the Unimplemented status's details so the stats wire format
is exercised end to end.
- TrustMode constants encode the design's catalog-validated
(default) and connector-trusted (dev-only) modes.
Unit tests cover the validation matrix (rejects empty/oversize
requests, accepts well-formed vector queries, accepts well-formed
deletion-vector descriptors, rejects DVs missing blob_length /
referenced_data_file).