Skip to content

Commit cf3b98c

Browse files
committed
feat: support nullable EthereumSqlTypeWrapper
1 parent d4866a7 commit cf3b98c

File tree

2 files changed

+130
-13
lines changed

2 files changed

+130
-13
lines changed

core/src/database/postgres/sql_type_wrapper.rs

Lines changed: 124 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,13 @@ pub enum EthereumSqlTypeWrapper {
5353

5454
// 256-bit integers
5555
U256(U256),
56+
U256Nullable(U256),
5657
U256Bytes(U256),
58+
U256BytesNullable(U256),
5759
I256(I256),
60+
I256Nullable(I256),
5861
I256Bytes(I256),
62+
I256BytesNullable(I256),
5963
VecU256(Vec<U256>),
6064
VecU256Bytes(Vec<U256>),
6165
VecI256(Vec<I256>),
@@ -79,14 +83,18 @@ pub enum EthereumSqlTypeWrapper {
7983

8084
// Address
8185
Address(Address),
86+
AddressNullable(Address),
8287
AddressBytes(Address),
88+
AddressBytesNullable(Address),
8389
VecAddress(Vec<Address>),
8490
VecAddressBytes(Vec<Address>),
8591

8692
// Strings and Bytes
8793
String(String),
94+
StringNullable(String),
8895
VecString(Vec<String>),
8996
Bytes(Bytes),
97+
BytesNullable(Bytes),
9098
VecBytes(Vec<Bytes>),
9199

92100
DateTime(DateTime<Utc>),
@@ -131,9 +139,13 @@ impl EthereumSqlTypeWrapper {
131139

132140
// 256-bit integers
133141
EthereumSqlTypeWrapper::U256(_) => "U256",
142+
EthereumSqlTypeWrapper::U256Nullable(_) => "U256Nullable",
134143
EthereumSqlTypeWrapper::U256Bytes(_) => "U256Bytes",
144+
EthereumSqlTypeWrapper::U256BytesNullable(_) => "U256BytesNullable",
135145
EthereumSqlTypeWrapper::I256(_) => "I256",
146+
EthereumSqlTypeWrapper::I256Nullable(_) => "I256Nullable",
136147
EthereumSqlTypeWrapper::I256Bytes(_) => "I256Bytes",
148+
EthereumSqlTypeWrapper::I256BytesNullable(_) => "I256BytesNullable",
137149
EthereumSqlTypeWrapper::VecU256(_) => "VecU256",
138150
EthereumSqlTypeWrapper::VecU256Bytes(_) => "VecU256Bytes",
139151
EthereumSqlTypeWrapper::VecI256(_) => "VecI256",
@@ -157,14 +169,18 @@ impl EthereumSqlTypeWrapper {
157169

158170
// Address
159171
EthereumSqlTypeWrapper::Address(_) => "Address",
172+
EthereumSqlTypeWrapper::AddressNullable(_) => "AddressNullable",
160173
EthereumSqlTypeWrapper::AddressBytes(_) => "AddressBytes",
174+
EthereumSqlTypeWrapper::AddressBytesNullable(_) => "AddressBytesNullable",
161175
EthereumSqlTypeWrapper::VecAddress(_) => "VecAddress",
162176
EthereumSqlTypeWrapper::VecAddressBytes(_) => "VecAddressBytes",
163177

164178
// Strings and Bytes
165179
EthereumSqlTypeWrapper::String(_) => "String",
180+
EthereumSqlTypeWrapper::StringNullable(_) => "StringNullable",
166181
EthereumSqlTypeWrapper::VecString(_) => "VecString",
167182
EthereumSqlTypeWrapper::Bytes(_) => "Bytes",
183+
EthereumSqlTypeWrapper::BytesNullable(_) => "BytesNullable",
168184
EthereumSqlTypeWrapper::VecBytes(_) => "VecBytes",
169185

170186
EthereumSqlTypeWrapper::DateTime(_) => "DateTime",
@@ -208,10 +224,18 @@ impl EthereumSqlTypeWrapper {
208224
EthereumSqlTypeWrapper::VecI128(_) => PgType::NUMERIC_ARRAY,
209225

210226
// 256-bit integers (kept as VARCHAR for decimal string representation)
211-
EthereumSqlTypeWrapper::U256(_) => PgType::VARCHAR,
212-
EthereumSqlTypeWrapper::U256Bytes(_) => PgType::BYTEA,
213-
EthereumSqlTypeWrapper::I256(_) => PgType::VARCHAR,
214-
EthereumSqlTypeWrapper::I256Bytes(_) => PgType::BYTEA,
227+
EthereumSqlTypeWrapper::U256(_) | EthereumSqlTypeWrapper::U256Nullable(_) => {
228+
PgType::VARCHAR
229+
}
230+
EthereumSqlTypeWrapper::U256Bytes(_) | EthereumSqlTypeWrapper::U256BytesNullable(_) => {
231+
PgType::BYTEA
232+
}
233+
EthereumSqlTypeWrapper::I256(_) | EthereumSqlTypeWrapper::I256Nullable(_) => {
234+
PgType::VARCHAR
235+
}
236+
EthereumSqlTypeWrapper::I256Bytes(_) | EthereumSqlTypeWrapper::I256BytesNullable(_) => {
237+
PgType::BYTEA
238+
}
215239
EthereumSqlTypeWrapper::VecU256(_) => PgType::VARCHAR_ARRAY,
216240
EthereumSqlTypeWrapper::VecU256Bytes(_) => PgType::BYTEA_ARRAY,
217241
EthereumSqlTypeWrapper::VecI256(_) => PgType::VARCHAR_ARRAY,
@@ -236,15 +260,22 @@ impl EthereumSqlTypeWrapper {
236260
EthereumSqlTypeWrapper::VecH512(_) => PgType::BYTEA_ARRAY,
237261

238262
// Address
239-
EthereumSqlTypeWrapper::Address(_) => PgType::BPCHAR,
240-
EthereumSqlTypeWrapper::AddressBytes(_) => PgType::BYTEA,
263+
EthereumSqlTypeWrapper::Address(_) | EthereumSqlTypeWrapper::AddressNullable(_) => {
264+
PgType::BPCHAR
265+
}
266+
EthereumSqlTypeWrapper::AddressBytes(_) |
267+
EthereumSqlTypeWrapper::AddressBytesNullable(_) => PgType::BYTEA,
241268
EthereumSqlTypeWrapper::VecAddress(_) => PgType::TEXT_ARRAY,
242269
EthereumSqlTypeWrapper::VecAddressBytes(_) => PgType::BYTEA_ARRAY,
243270

244271
// Strings and Bytes
245-
EthereumSqlTypeWrapper::String(_) => PgType::TEXT,
272+
EthereumSqlTypeWrapper::String(_) | EthereumSqlTypeWrapper::StringNullable(_) => {
273+
PgType::TEXT
274+
}
246275
EthereumSqlTypeWrapper::VecString(_) => PgType::TEXT_ARRAY,
247-
EthereumSqlTypeWrapper::Bytes(_) => PgType::BYTEA,
276+
EthereumSqlTypeWrapper::Bytes(_) | EthereumSqlTypeWrapper::BytesNullable(_) => {
277+
PgType::BYTEA
278+
}
248279
EthereumSqlTypeWrapper::VecBytes(_) => PgType::BYTEA_ARRAY,
249280

250281
// DateTime
@@ -288,13 +319,32 @@ impl ToSql for EthereumSqlTypeWrapper {
288319
let i256_value = u256_to_i256(*value);
289320
String::to_sql(&i256_value.to_string(), ty, out)
290321
}
322+
EthereumSqlTypeWrapper::U256Nullable(value) => {
323+
if value.is_zero() {
324+
return Ok(IsNull::Yes);
325+
}
326+
// handle two’s complement without adding a new type
327+
let i256_value = u256_to_i256(*value);
328+
String::to_sql(&i256_value.to_string(), ty, out)
329+
}
291330
EthereumSqlTypeWrapper::U256Bytes(value) => {
292331
let mut bytes = [0u8; 32];
293332
value.to_big_endian(&mut bytes);
294333
let bytes = Bytes::from(bytes);
295334
out.extend_from_slice(&bytes);
296335
Ok(IsNull::No)
297336
}
337+
EthereumSqlTypeWrapper::U256BytesNullable(value) => {
338+
if value.is_zero() {
339+
return Ok(IsNull::Yes);
340+
}
341+
342+
let mut bytes = [0u8; 32];
343+
value.to_big_endian(&mut bytes);
344+
let bytes = Bytes::from(bytes);
345+
out.extend_from_slice(&bytes);
346+
Ok(IsNull::No)
347+
}
298348
EthereumSqlTypeWrapper::VecU256(values) => {
299349
if values.is_empty() {
300350
Ok(IsNull::Yes)
@@ -328,13 +378,32 @@ impl ToSql for EthereumSqlTypeWrapper {
328378
let value = value.to_string();
329379
String::to_sql(&value, ty, out)
330380
}
381+
EthereumSqlTypeWrapper::I256Nullable(value) => {
382+
if value.is_zero() {
383+
return Ok(IsNull::Yes);
384+
}
385+
386+
let value = value.to_string();
387+
String::to_sql(&value, ty, out)
388+
}
331389
EthereumSqlTypeWrapper::I256Bytes(value) => {
332390
let mut bytes = [0u8; 32];
333391
value.to_big_endian(&mut bytes);
334392
let bytes = Bytes::from(bytes);
335393
out.extend_from_slice(&bytes);
336394
Ok(IsNull::No)
337395
}
396+
EthereumSqlTypeWrapper::I256BytesNullable(value) => {
397+
if value.is_zero() {
398+
return Ok(IsNull::Yes);
399+
}
400+
401+
let mut bytes = [0u8; 32];
402+
value.to_big_endian(&mut bytes);
403+
let bytes = Bytes::from(bytes);
404+
out.extend_from_slice(&bytes);
405+
Ok(IsNull::No)
406+
}
338407
EthereumSqlTypeWrapper::VecI256(values) => {
339408
if values.is_empty() {
340409
Ok(IsNull::Yes)
@@ -444,11 +513,28 @@ impl ToSql for EthereumSqlTypeWrapper {
444513
let hex = format!("{:?}", value);
445514
String::to_sql(&hex, ty, out)
446515
}
516+
EthereumSqlTypeWrapper::AddressNullable(value) => {
517+
if value.is_zero() {
518+
return Ok(IsNull::Yes);
519+
}
520+
521+
let hex = format!("{:?}", value);
522+
String::to_sql(&hex, ty, out)
523+
}
447524
EthereumSqlTypeWrapper::AddressBytes(value) => {
448525
let bytes: Bytes = value.as_bytes().to_vec().into();
449526
out.extend_from_slice(&bytes);
450527
Ok(IsNull::No)
451528
}
529+
EthereumSqlTypeWrapper::AddressBytesNullable(value) => {
530+
if value.is_zero() {
531+
return Ok(IsNull::Yes);
532+
}
533+
534+
let bytes: Bytes = value.as_bytes().to_vec().into();
535+
out.extend_from_slice(&bytes);
536+
Ok(IsNull::No)
537+
}
452538
EthereumSqlTypeWrapper::VecAddress(values) => {
453539
let addresses: Vec<String> = values.iter().map(|s| format!("{:?}", s)).collect();
454540
if addresses.is_empty() {
@@ -495,6 +581,13 @@ impl ToSql for EthereumSqlTypeWrapper {
495581
Ok(IsNull::No)
496582
}
497583
EthereumSqlTypeWrapper::String(value) => String::to_sql(value, ty, out),
584+
EthereumSqlTypeWrapper::StringNullable(value) => {
585+
if value.is_empty() {
586+
return Ok(IsNull::Yes);
587+
}
588+
589+
String::to_sql(value, ty, out)
590+
}
498591
EthereumSqlTypeWrapper::VecString(values) => {
499592
if values.is_empty() {
500593
Ok(IsNull::Yes)
@@ -506,6 +599,14 @@ impl ToSql for EthereumSqlTypeWrapper {
506599
out.extend_from_slice(value);
507600
Ok(IsNull::No)
508601
}
602+
EthereumSqlTypeWrapper::BytesNullable(value) => {
603+
if value.is_empty() {
604+
return Ok(IsNull::Yes);
605+
}
606+
607+
out.extend_from_slice(value);
608+
Ok(IsNull::No)
609+
}
509610
EthereumSqlTypeWrapper::VecBytes(values) => {
510611
if values.is_empty() {
511612
Ok(IsNull::Yes)
@@ -1189,7 +1290,10 @@ pub fn map_ethereum_wrapper_to_json(
11891290
EthereumSqlTypeWrapper::VecI128(i128s) => {
11901291
json!(i128s.iter().map(|i| i.to_string()).collect::<Vec<_>>())
11911292
}
1192-
EthereumSqlTypeWrapper::U256(u) | EthereumSqlTypeWrapper::U256Bytes(u) => {
1293+
EthereumSqlTypeWrapper::U256(u) |
1294+
EthereumSqlTypeWrapper::U256Bytes(u) |
1295+
EthereumSqlTypeWrapper::U256Nullable(u) |
1296+
EthereumSqlTypeWrapper::U256BytesNullable(u) => {
11931297
// handle two's complement without adding a new type
11941298
let i256_value = u256_to_i256(*u);
11951299
json!(i256_value.to_string())
@@ -1205,7 +1309,10 @@ pub fn map_ethereum_wrapper_to_json(
12051309
})
12061310
.collect::<Vec<_>>())
12071311
}
1208-
EthereumSqlTypeWrapper::I256(i) | EthereumSqlTypeWrapper::I256Bytes(i) => {
1312+
EthereumSqlTypeWrapper::I256(i) |
1313+
EthereumSqlTypeWrapper::I256Bytes(i) |
1314+
EthereumSqlTypeWrapper::I256Nullable(i) |
1315+
EthereumSqlTypeWrapper::I256BytesNullable(i) => {
12091316
json!(i.to_string())
12101317
}
12111318
EthereumSqlTypeWrapper::VecI256(i256s) |
@@ -1228,7 +1335,9 @@ pub fn map_ethereum_wrapper_to_json(
12281335
EthereumSqlTypeWrapper::H512(h) => json!(h),
12291336
EthereumSqlTypeWrapper::VecH512(h512s) => json!(h512s),
12301337
EthereumSqlTypeWrapper::Address(address) |
1231-
EthereumSqlTypeWrapper::AddressBytes(address) => json!(address),
1338+
EthereumSqlTypeWrapper::AddressBytes(address) |
1339+
EthereumSqlTypeWrapper::AddressBytesNullable(address) |
1340+
EthereumSqlTypeWrapper::AddressNullable(address) => json!(address),
12321341
EthereumSqlTypeWrapper::VecAddress(addresses) |
12331342
EthereumSqlTypeWrapper::VecAddressBytes(addresses) => json!(addresses),
12341343
EthereumSqlTypeWrapper::Bool(b) => json!(b),
@@ -1245,9 +1354,11 @@ pub fn map_ethereum_wrapper_to_json(
12451354
EthereumSqlTypeWrapper::VecU8(u8s) => json!(u8s),
12461355
EthereumSqlTypeWrapper::I8(i) => json!(i),
12471356
EthereumSqlTypeWrapper::VecI8(i8s) => json!(i8s),
1248-
EthereumSqlTypeWrapper::String(s) => json!(s),
1357+
EthereumSqlTypeWrapper::String(s) |
1358+
EthereumSqlTypeWrapper::StringNullable(s) => json!(s),
12491359
EthereumSqlTypeWrapper::VecString(strings) => json!(strings),
1250-
EthereumSqlTypeWrapper::Bytes(bytes) => json!(hex::encode(bytes)),
1360+
EthereumSqlTypeWrapper::Bytes(bytes) |
1361+
EthereumSqlTypeWrapper::BytesNullable(bytes) => json!(hex::encode(bytes)),
12511362
EthereumSqlTypeWrapper::VecBytes(bytes) => {
12521363
json!(bytes.iter().map(hex::encode).collect::<Vec<_>>())
12531364
}

documentation/docs/pages/docs/start-building/rust-project-deep-dive/indexers.mdx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -796,9 +796,13 @@ pub enum EthereumSqlTypeWrapper {
796796
797797
// 256-bit integers
798798
U256(U256),
799+
U256Nullable(U256),
799800
U256Bytes(U256),
801+
U256BytesNullable(U256),
800802
I256(I256),
803+
I256Nullable(I256),
801804
I256Bytes(I256),
805+
I256BytesNullable(I256),
802806
VecU256(Vec<U256>),
803807
VecU256Bytes(Vec<U256>),
804808
VecI256(Vec<I256>),
@@ -828,8 +832,10 @@ pub enum EthereumSqlTypeWrapper {
828832
829833
// Strings and Bytes
830834
String(String),
835+
StringNullable(String),
831836
VecString(Vec<String>),
832837
Bytes(Bytes),
838+
BytesNullable(Bytes),
833839
VecBytes(Vec<Bytes>),
834840
835841
DateTime(DateTime<Utc>),

0 commit comments

Comments
 (0)