Skip to content

Commit dc4def8

Browse files
authored
feat(all): Add new GraphQL scalar type Int8 (#4511)
1 parent 3d6645e commit dc4def8

File tree

32 files changed

+442
-19
lines changed

32 files changed

+442
-19
lines changed

Cargo.lock

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

graph/src/data/store/mod.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ pub type Attribute = String;
138138
pub const BYTES_SCALAR: &str = "Bytes";
139139
pub const BIG_INT_SCALAR: &str = "BigInt";
140140
pub const BIG_DECIMAL_SCALAR: &str = "BigDecimal";
141+
pub const INT8_SCALAR: &str = "Int8";
141142

142143
#[derive(Clone, Debug, PartialEq)]
143144
pub enum ValueType {
@@ -146,6 +147,7 @@ pub enum ValueType {
146147
Bytes,
147148
BigDecimal,
148149
Int,
150+
Int8,
149151
String,
150152
}
151153

@@ -159,6 +161,7 @@ impl FromStr for ValueType {
159161
"Bytes" => Ok(ValueType::Bytes),
160162
"BigDecimal" => Ok(ValueType::BigDecimal),
161163
"Int" => Ok(ValueType::Int),
164+
"Int8" => Ok(ValueType::Int8),
162165
"String" | "ID" => Ok(ValueType::String),
163166
s => Err(anyhow!("Type not available in this context: {}", s)),
164167
}
@@ -187,6 +190,7 @@ pub enum IdType {
187190
pub enum Value {
188191
String(String),
189192
Int(i32),
193+
Int8(i64),
190194
BigDecimal(scalar::BigDecimal),
191195
Bool(bool),
192196
List(Vec<Value>),
@@ -224,6 +228,9 @@ impl stable_hash_legacy::StableHash for Value {
224228
Int(inner) => {
225229
stable_hash_legacy::StableHash::stable_hash(inner, sequence_number, state)
226230
}
231+
Int8(inner) => {
232+
stable_hash_legacy::StableHash::stable_hash(inner, sequence_number, state)
233+
}
227234
BigDecimal(inner) => {
228235
stable_hash_legacy::StableHash::stable_hash(inner, sequence_number, state)
229236
}
@@ -282,6 +289,10 @@ impl StableHash for Value {
282289
inner.stable_hash(field_address.child(0), state);
283290
7
284291
}
292+
Int8(inner) => {
293+
inner.stable_hash(field_address.child(0), state);
294+
8
295+
}
285296
};
286297

287298
state.write(field_address, &[variant])
@@ -325,6 +336,9 @@ impl Value {
325336
QueryExecutionError::ValueParseError("BigInt".to_string(), format!("{}", e))
326337
})?),
327338
BIG_DECIMAL_SCALAR => Value::BigDecimal(scalar::BigDecimal::from_str(s)?),
339+
INT8_SCALAR => Value::Int8(s.parse::<i64>().map_err(|_| {
340+
QueryExecutionError::ValueParseError("Int8".to_string(), format!("{}", s))
341+
})?),
328342
_ => Value::String(s.clone()),
329343
}
330344
}
@@ -416,6 +430,7 @@ impl Value {
416430
Value::Bool(_) => "Boolean".to_owned(),
417431
Value::Bytes(_) => "Bytes".to_owned(),
418432
Value::Int(_) => "Int".to_owned(),
433+
Value::Int8(_) => "Int8".to_owned(),
419434
Value::List(values) => {
420435
if let Some(v) = values.first() {
421436
format!("[{}]", v.type_name())
@@ -436,6 +451,7 @@ impl Value {
436451
| (Value::Bool(_), ValueType::Boolean)
437452
| (Value::Bytes(_), ValueType::Bytes)
438453
| (Value::Int(_), ValueType::Int)
454+
| (Value::Int8(_), ValueType::Int8)
439455
| (Value::Null, _) => true,
440456
(Value::List(values), _) if is_list => values
441457
.iter()
@@ -457,6 +473,7 @@ impl fmt::Display for Value {
457473
match self {
458474
Value::String(s) => s.to_string(),
459475
Value::Int(i) => i.to_string(),
476+
Value::Int8(i) => i.to_string(),
460477
Value::BigDecimal(d) => d.to_string(),
461478
Value::Bool(b) => b.to_string(),
462479
Value::Null => "null".to_string(),
@@ -474,6 +491,7 @@ impl fmt::Debug for Value {
474491
match self {
475492
Self::String(s) => f.debug_tuple("String").field(s).finish(),
476493
Self::Int(i) => f.debug_tuple("Int").field(i).finish(),
494+
Self::Int8(i) => f.debug_tuple("Int8").field(i).finish(),
477495
Self::BigDecimal(d) => d.fmt(f),
478496
Self::Bool(arg0) => f.debug_tuple("Bool").field(arg0).finish(),
479497
Self::List(arg0) => f.debug_tuple("List").field(arg0).finish(),
@@ -489,6 +507,7 @@ impl From<Value> for q::Value {
489507
match value {
490508
Value::String(s) => q::Value::String(s),
491509
Value::Int(i) => q::Value::Int(q::Number::from(i)),
510+
Value::Int8(i) => q::Value::String(i.to_string()),
492511
Value::BigDecimal(d) => q::Value::String(d.to_string()),
493512
Value::Bool(b) => q::Value::Boolean(b),
494513
Value::Null => q::Value::Null,
@@ -506,6 +525,7 @@ impl From<Value> for r::Value {
506525
match value {
507526
Value::String(s) => r::Value::String(s),
508527
Value::Int(i) => r::Value::Int(i as i64),
528+
Value::Int8(i) => r::Value::String(i.to_string()),
509529
Value::BigDecimal(d) => r::Value::String(d.to_string()),
510530
Value::Bool(b) => r::Value::Boolean(b),
511531
Value::Null => r::Value::Null,
@@ -572,6 +592,12 @@ impl From<u64> for Value {
572592
}
573593
}
574594

595+
impl From<i64> for Value {
596+
fn from(value: i64) -> Value {
597+
Value::Int8(value.into())
598+
}
599+
}
600+
575601
impl TryFrom<Value> for Option<scalar::BigInt> {
576602
type Error = Error;
577603

graph/src/data/store/sql.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use anyhow::anyhow;
22
use diesel::pg::Pg;
33
use diesel::serialize::{self, Output, ToSql};
4-
use diesel::sql_types::{Binary, Bool, Integer, Text};
4+
use diesel::sql_types::{Binary, Bool, Int8, Integer, Text};
55

66
use std::io::Write;
77
use std::str::FromStr;
@@ -34,6 +34,19 @@ impl ToSql<Integer, Pg> for Value {
3434
}
3535
}
3636

37+
impl ToSql<Int8, Pg> for Value {
38+
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
39+
match self {
40+
Value::Int8(i) => <i64 as ToSql<Int8, Pg>>::to_sql(i, out),
41+
v => Err(anyhow!(
42+
"Failed to convert non-int8 attribute value to int8 in SQL: {}",
43+
v
44+
)
45+
.into()),
46+
}
47+
}
48+
}
49+
3750
impl ToSql<Text, Pg> for Value {
3851
fn to_sql<W: Write>(&self, out: &mut Output<W, Pg>) -> serialize::Result {
3952
match self {

graph/src/data/value.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ impl Value {
330330
Err(Value::Int(num))
331331
}
332332
}
333+
("Int8", Value::Int(num)) => Ok(Value::String(num.to_string())),
334+
("Int8", Value::String(num)) => Ok(Value::String(num)),
333335
("String", Value::String(s)) => Ok(Value::String(s)),
334336
("ID", Value::String(s)) => Ok(Value::String(s)),
335337
("ID", Value::Int(n)) => Ok(Value::String(n.to_string())),

graph/src/runtime/gas/size_of.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ impl GasSizeOf for Value {
1515
Value::Null => Gas(1),
1616
Value::List(list) => list.gas_size_of(),
1717
Value::Int(int) => int.gas_size_of(),
18+
Value::Int8(int) => int.gas_size_of(),
1819
Value::Bytes(bytes) => bytes.gas_size_of(),
1920
Value::Bool(bool) => bool.gas_size_of(),
2021
Value::BigInt(big_int) => big_int.gas_size_of(),

graph/src/schema/api.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,7 @@ fn field_scalar_filter_input_values(
587587
"BigDecimal" => vec!["", "not", "gt", "lt", "gte", "lte", "in", "not_in"],
588588
"ID" => vec!["", "not", "gt", "lt", "gte", "lte", "in", "not_in"],
589589
"Int" => vec!["", "not", "gt", "lt", "gte", "lte", "in", "not_in"],
590+
"Int8" => vec!["", "not", "gt", "lt", "gte", "lte", "in", "not_in"],
590591
"String" => vec![
591592
"",
592593
"not",
@@ -1114,6 +1115,9 @@ mod tests {
11141115
schema
11151116
.get_named_type("String")
11161117
.expect("String type is missing in API schema");
1118+
schema
1119+
.get_named_type("Int8")
1120+
.expect("Int8 type is missing in API schema");
11171121
}
11181122

11191123
#[test]

graph/src/schema/meta.graphql

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# GraphQL core functionality
22
scalar Boolean
33
scalar ID
4+
""" 4 bytes signed integer """
45
scalar Int
56
scalar Float
67
scalar String
@@ -19,9 +20,12 @@ directive @subgraphId(id: String!) on OBJECT
1920
"creates a virtual field on the entity that may be queried but cannot be set manually through the mappings API."
2021
directive @derivedFrom(field: String!) on FIELD_DEFINITION
2122

23+
# Additional scalar types
2224
scalar BigDecimal
2325
scalar Bytes
2426
scalar BigInt
27+
""" 8 bytes signed integer """
28+
scalar Int8
2529

2630
# The type names are purposely awkward to minimize the risk of them
2731
# colliding with user-supplied types

graph/src/util/cache_weight.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl CacheWeight for Value {
9393
Value::List(values) => values.indirect_weight(),
9494
Value::Bytes(bytes) => bytes.indirect_weight(),
9595
Value::BigInt(n) => n.indirect_weight(),
96-
Value::Int(_) | Value::Bool(_) | Value::Null => 0,
96+
Value::Int8(_) | Value::Int(_) | Value::Bool(_) | Value::Null => 0,
9797
}
9898
}
9999
}

graphql/src/values/coercion.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ impl MaybeCoercible<ScalarType> for q::Value {
4242
Err(q::Value::Int(num))
4343
}
4444
}
45+
("Int8", q::Value::Int(num)) => {
46+
let n = num.as_i64().ok_or_else(|| q::Value::Int(num.clone()))?;
47+
Ok(r::Value::Int(n))
48+
}
4549
("String", q::Value::String(s)) => Ok(r::Value::String(s)),
4650
("ID", q::Value::String(s)) => Ok(r::Value::String(s)),
4751
("ID", q::Value::Int(n)) => Ok(r::Value::String(
@@ -395,6 +399,21 @@ mod tests {
395399
);
396400
}
397401

402+
#[test]
403+
fn coerce_int8_scalar() {
404+
let int8_type = TypeDefinition::Scalar(ScalarType::new("Int8".to_string()));
405+
let resolver = |_: &str| Some(&int8_type);
406+
407+
assert_eq!(
408+
coerce_to_definition(Value::Int(1234.into()), "", &resolver),
409+
Ok(Value::String("1234".to_string()))
410+
);
411+
assert_eq!(
412+
coerce_to_definition(Value::Int((-1234_i32).into()), "", &resolver,),
413+
Ok(Value::String("-1234".to_string()))
414+
);
415+
}
416+
398417
#[test]
399418
fn coerce_bytes_scalar() {
400419
let bytes_type = TypeDefinition::Scalar(ScalarType::new("Bytes".to_string()));

runtime/test/src/test/abi.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,12 @@ async fn test_abi_store_value(api_version: Version) {
291291
let new_value: Value = module.asc_get(new_value_ptr).unwrap();
292292
assert_eq!(new_value, Value::Int(int));
293293

294+
// Value::Int8
295+
let int8 = i64::min_value();
296+
let new_value_ptr = module.takes_val_returns_ptr("value_from_int8", int8);
297+
let new_value: Value = module.asc_get(new_value_ptr).unwrap();
298+
assert_eq!(new_value, Value::Int8(int8));
299+
294300
// Value::BigDecimal
295301
let big_decimal = BigDecimal::from_str("3.14159001").unwrap();
296302
let new_value_ptr = module.invoke_export1("value_from_big_decimal", &big_decimal);

0 commit comments

Comments
 (0)