Skip to content

Commit 4af3fc0

Browse files
committed
Initial WIP on adding new Int8 scalar
fixes and tests wip
1 parent 08da7cb commit 4af3fc0

File tree

31 files changed

+428
-13
lines changed

31 files changed

+428
-13
lines changed

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
}
@@ -180,6 +183,7 @@ impl ValueType {
180183
pub enum Value {
181184
String(String),
182185
Int(i32),
186+
Int8(i64),
183187
BigDecimal(scalar::BigDecimal),
184188
Bool(bool),
185189
List(Vec<Value>),
@@ -217,6 +221,9 @@ impl stable_hash_legacy::StableHash for Value {
217221
Int(inner) => {
218222
stable_hash_legacy::StableHash::stable_hash(inner, sequence_number, state)
219223
}
224+
Int8(inner) => {
225+
stable_hash_legacy::StableHash::stable_hash(inner, sequence_number, state)
226+
}
220227
BigDecimal(inner) => {
221228
stable_hash_legacy::StableHash::stable_hash(inner, sequence_number, state)
222229
}
@@ -275,6 +282,10 @@ impl StableHash for Value {
275282
inner.stable_hash(field_address.child(0), state);
276283
7
277284
}
285+
Int8(inner) => {
286+
inner.stable_hash(field_address.child(0), state);
287+
8
288+
}
278289
};
279290

280291
state.write(field_address, &[variant])
@@ -318,6 +329,9 @@ impl Value {
318329
QueryExecutionError::ValueParseError("BigInt".to_string(), format!("{}", e))
319330
})?),
320331
BIG_DECIMAL_SCALAR => Value::BigDecimal(scalar::BigDecimal::from_str(s)?),
332+
INT8_SCALAR => Value::Int8(s.parse::<i64>().map_err(|_| {
333+
QueryExecutionError::ValueParseError("Int8".to_string(), format!("{}", s))
334+
})?),
321335
_ => Value::String(s.clone()),
322336
}
323337
}
@@ -409,6 +423,7 @@ impl Value {
409423
Value::Bool(_) => "Boolean".to_owned(),
410424
Value::Bytes(_) => "Bytes".to_owned(),
411425
Value::Int(_) => "Int".to_owned(),
426+
Value::Int8(_) => "Int8".to_owned(),
412427
Value::List(values) => {
413428
if let Some(v) = values.first() {
414429
format!("[{}]", v.type_name())
@@ -429,6 +444,7 @@ impl Value {
429444
| (Value::Bool(_), ValueType::Boolean)
430445
| (Value::Bytes(_), ValueType::Bytes)
431446
| (Value::Int(_), ValueType::Int)
447+
| (Value::Int8(_), ValueType::Int8)
432448
| (Value::Null, _) => true,
433449
(Value::List(values), _) if is_list => values
434450
.iter()
@@ -450,6 +466,7 @@ impl fmt::Display for Value {
450466
match self {
451467
Value::String(s) => s.to_string(),
452468
Value::Int(i) => i.to_string(),
469+
Value::Int8(i) => i.to_string(),
453470
Value::BigDecimal(d) => d.to_string(),
454471
Value::Bool(b) => b.to_string(),
455472
Value::Null => "null".to_string(),
@@ -467,6 +484,7 @@ impl fmt::Debug for Value {
467484
match self {
468485
Self::String(s) => f.debug_tuple("String").field(s).finish(),
469486
Self::Int(i) => f.debug_tuple("Int").field(i).finish(),
487+
Self::Int8(i) => f.debug_tuple("Int8").field(i).finish(),
470488
Self::BigDecimal(d) => d.fmt(f),
471489
Self::Bool(arg0) => f.debug_tuple("Bool").field(arg0).finish(),
472490
Self::List(arg0) => f.debug_tuple("List").field(arg0).finish(),
@@ -482,6 +500,7 @@ impl From<Value> for q::Value {
482500
match value {
483501
Value::String(s) => q::Value::String(s),
484502
Value::Int(i) => q::Value::Int(q::Number::from(i)),
503+
Value::Int8(i) => q::Value::String(i.to_string()),
485504
Value::BigDecimal(d) => q::Value::String(d.to_string()),
486505
Value::Bool(b) => q::Value::Boolean(b),
487506
Value::Null => q::Value::Null,
@@ -499,6 +518,7 @@ impl From<Value> for r::Value {
499518
match value {
500519
Value::String(s) => r::Value::String(s),
501520
Value::Int(i) => r::Value::Int(i as i64),
521+
Value::Int8(i) => r::Value::String(i.to_string()),
502522
Value::BigDecimal(d) => r::Value::String(d.to_string()),
503523
Value::Bool(b) => r::Value::Boolean(b),
504524
Value::Null => r::Value::Null,
@@ -565,6 +585,12 @@ impl From<u64> for Value {
565585
}
566586
}
567587

588+
impl From<i64> for Value {
589+
fn from(value: i64) -> Value {
590+
Value::Int8(value.into())
591+
}
592+
}
593+
568594
impl TryFrom<Value> for Option<scalar::BigInt> {
569595
type Error = Error;
570596

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 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);

runtime/test/wasm_test/api_version_0_0_4/abi_store_value.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ enum ValueKind {
1111
NULL = 5,
1212
BYTES = 6,
1313
BIG_INT = 7,
14+
INT8 = 8,
1415
}
1516

1617
// Big enough to fit any pointer or native `this.data`.
@@ -43,6 +44,13 @@ export function value_from_int(int: i32): Value {
4344
return value
4445
}
4546

47+
export function value_from_int8(int: i64): Value {
48+
let value = new Value();
49+
value.kind = ValueKind.INT8;
50+
value.data = int as i64
51+
return value
52+
}
53+
4654
export function value_from_big_decimal(float: BigInt): Value {
4755
let value = new Value();
4856
value.kind = ValueKind.BIG_DECIMAL;

0 commit comments

Comments
 (0)