1use crate::conversions::{AddressArrayRecycler, PrimitiveArrayRecycler, StringViewArrayRecycler};
2use crate::DEFAULT_BATCH_SIZE;
3use arrow::array::RecordBatch;
4use arrow::datatypes::{DataType, Field, Int32Type, Schema, SchemaRef};
5use arrow::error::ArrowError;
6use arrow::record_batch::RecordBatchReader;
7use std::sync::{Arc, LazyLock};
8use tpcdsgen::config::{Session, Table};
9use tpcdsgen::row::{CustomerAddressRow, CustomerAddressRowGenerator};
10
11pub struct CustomerAddressArrow {
19 inner: CustomerAddressRowGenerator,
20 batch_size: usize,
21 scratch: Vec<CustomerAddressRow>,
23 ca_address_sk: PrimitiveArrayRecycler<Int32Type>,
24 ca_address_id: StringViewArrayRecycler,
25 ca_address: AddressArrayRecycler,
26 ca_location_type: StringViewArrayRecycler,
27}
28
29impl CustomerAddressArrow {
30 pub fn schema_ref() -> SchemaRef {
32 Arc::clone(&SCHEMA)
33 }
34
35 pub fn new(session: Session) -> Self {
36 let row_count = session.get_scaling().get_row_count(Table::CustomerAddress);
37 Self {
38 inner: CustomerAddressRowGenerator::new(session, row_count),
39 batch_size: DEFAULT_BATCH_SIZE,
40 scratch: Vec::with_capacity(DEFAULT_BATCH_SIZE),
41 ca_address_sk: PrimitiveArrayRecycler::new(),
42 ca_address_id: StringViewArrayRecycler::new(),
43 ca_address: AddressArrayRecycler::new(),
44 ca_location_type: StringViewArrayRecycler::new(),
45 }
46 }
47 pub fn skip_rows_until_starting_row_number(&mut self, starting_row_number: u64) {
48 self.inner
49 .skip_rows_until_starting_row_number(starting_row_number);
50 }
51
52 pub fn with_source_row_range(
56 mut self,
57 starting_row_number: u64,
58 ending_row_number: u64,
59 ) -> Self {
60 self.inner
61 .set_source_row_range(starting_row_number, ending_row_number);
62 self
63 }
64
65 pub fn with_batch_size(mut self, batch_size: usize) -> Self {
66 self.batch_size = batch_size;
67 self
68 }
69}
70
71impl RecordBatchReader for CustomerAddressArrow {
72 fn schema(&self) -> SchemaRef {
73 Self::schema_ref()
74 }
75}
76
77impl Iterator for CustomerAddressArrow {
78 type Item = Result<RecordBatch, ArrowError>;
79
80 fn next(&mut self) -> Option<Self::Item> {
81 self.scratch.clear();
82 self.scratch
83 .extend(self.inner.by_ref().take(self.batch_size));
84 let rows = &self.scratch;
85 if rows.is_empty() {
86 return None;
87 }
88
89 let schema = self.schema();
90 let Self {
91 ca_address_sk,
92 ca_address_id,
93 ca_address,
94 ca_location_type,
95 ..
96 } = self;
97 let nbm = CustomerAddressRow::null_bit_map;
98
99 let ca_address_sk =
100 ca_address_sk.int32_sk(rows, 0, nbm, CustomerAddressRow::get_ca_addr_sk);
101 let ca_address_id = ca_address_id.str(rows, 1, nbm, CustomerAddressRow::get_ca_addr_id);
102 let address = ca_address.build(rows, 2, nbm, CustomerAddressRow::get_ca_address);
103 let ca_location_type =
104 ca_location_type.str(rows, 12, nbm, CustomerAddressRow::get_ca_location_type);
105
106 let batch = RecordBatch::try_new(
107 schema,
108 vec![
109 Arc::new(ca_address_sk),
110 Arc::new(ca_address_id),
111 Arc::new(address.street_number),
112 Arc::new(address.street_name),
113 Arc::new(address.street_type),
114 Arc::new(address.suite_number),
115 Arc::new(address.city),
116 Arc::new(address.county),
117 Arc::new(address.state),
118 Arc::new(address.zip),
119 Arc::new(address.country),
120 Arc::new(address.gmt_offset),
121 Arc::new(ca_location_type),
122 ],
123 );
124 Some(batch)
125 }
126}
127
128static SCHEMA: LazyLock<SchemaRef> = LazyLock::new(make_schema);
129
130fn make_schema() -> SchemaRef {
131 Arc::new(Schema::new(vec![
132 Field::new("ca_address_sk", DataType::Int32, false),
133 Field::new("ca_address_id", DataType::Utf8View, false),
134 Field::new("ca_street_number", DataType::Utf8View, true),
135 Field::new("ca_street_name", DataType::Utf8View, true),
136 Field::new("ca_street_type", DataType::Utf8View, true),
137 Field::new("ca_suite_number", DataType::Utf8View, true),
138 Field::new("ca_city", DataType::Utf8View, true),
139 Field::new("ca_county", DataType::Utf8View, true),
140 Field::new("ca_state", DataType::Utf8View, true),
141 Field::new("ca_zip", DataType::Utf8View, true),
142 Field::new("ca_country", DataType::Utf8View, true),
143 Field::new("ca_gmt_offset", DataType::Decimal128(5, 2), true),
144 Field::new("ca_location_type", DataType::Utf8View, true),
145 ]))
146}