diff --git a/core/src/sql/field.rs b/core/src/sql/field.rs
index 7badac24..eab2b37a 100644
--- a/core/src/sql/field.rs
+++ b/core/src/sql/field.rs
@@ -250,9 +250,10 @@ impl Fields {
 						_ => {
 							let expr = expr.compute(stk, ctx, opt, Some(doc)).await?;
 							// Check if this is a single VALUE field expression
-							match self.single().is_some() {
-								false => out.set(stk, ctx, opt, name.as_ref(), expr).await?,
-								true => out = expr,
+							if self.single().is_some() {
+								out = expr;
+							} else {
+								out.set(stk, ctx, opt, name.as_ref(), expr).await?;
 							}
 						}
 					}
diff --git a/core/src/sql/idiom.rs b/core/src/sql/idiom.rs
index a93c89ec..0a6489e8 100644
--- a/core/src/sql/idiom.rs
+++ b/core/src/sql/idiom.rs
@@ -116,9 +116,7 @@ impl Idiom {
 	pub(crate) fn simplify(&self) -> Idiom {
 		self.0
 			.iter()
-			.filter(|&p| {
-				matches!(p, Part::Field(_) | Part::Start(_) | Part::Value(_) | Part::Graph(_))
-			})
+			.filter(|&p| matches!(p, Part::Field(_) | Part::Start(_) | Part::Graph(_)))
 			.cloned()
 			.collect::<Vec<_>>()
 			.into()
diff --git a/core/src/sql/range.rs b/core/src/sql/range.rs
index 7c3159d9..f76de184 100644
--- a/core/src/sql/range.rs
+++ b/core/src/sql/range.rs
@@ -26,6 +26,84 @@ pub struct Range {
 	pub end: Bound<Value>,
 }
 
+impl Range {
+	pub fn slice<'a, T>(&self, s: &'a [T]) -> Option<&'a [T]> {
+		let r = match self.end {
+			Bound::Included(ref x) => {
+				let Value::Number(ref x) = x else {
+					return None;
+				};
+				let x = x.to_usize();
+				s.get(..=x)?
+			}
+			Bound::Excluded(ref x) => {
+				let Value::Number(ref x) = x else {
+					return None;
+				};
+				let x = x.to_usize();
+				s.get(..x)?
+			}
+			Bound::Unbounded => s,
+		};
+		let r = match self.beg {
+			Bound::Included(ref x) => {
+				let Value::Number(ref x) = x else {
+					return None;
+				};
+				let x = x.to_usize();
+				r.get(x..)?
+			}
+			Bound::Excluded(ref x) => {
+				let Value::Number(ref x) = x else {
+					return None;
+				};
+				let x = x.to_usize().saturating_add(1);
+				r.get(x..)?
+			}
+			Bound::Unbounded => r,
+		};
+		Some(r)
+	}
+
+	pub fn slice_mut<'a, T>(&self, s: &'a mut [T]) -> Option<&'a mut [T]> {
+		let r = match self.end {
+			Bound::Included(ref x) => {
+				let Value::Number(ref x) = x else {
+					return None;
+				};
+				let x = x.to_usize();
+				s.get_mut(..x)?
+			}
+			Bound::Excluded(ref x) => {
+				let Value::Number(ref x) = x else {
+					return None;
+				};
+				let x = x.to_usize();
+				s.get_mut(..=x)?
+			}
+			Bound::Unbounded => s,
+		};
+		let r = match self.beg {
+			Bound::Included(ref x) => {
+				let Value::Number(ref x) = x else {
+					return None;
+				};
+				let x = x.to_usize();
+				r.get_mut(x..)?
+			}
+			Bound::Excluded(ref x) => {
+				let Value::Number(ref x) = x else {
+					return None;
+				};
+				let x = x.to_usize().saturating_add(1);
+				r.get_mut(x..)?
+			}
+			Bound::Unbounded => r,
+		};
+		Some(r)
+	}
+}
+
 impl FromStr for Range {
 	type Err = ();
 	fn from_str(s: &str) -> Result<Self, Self::Err> {
diff --git a/core/src/sql/statements/select.rs b/core/src/sql/statements/select.rs
index 6693f9c2..e380d34b 100644
--- a/core/src/sql/statements/select.rs
+++ b/core/src/sql/statements/select.rs
@@ -19,10 +19,12 @@ use std::sync::Arc;
 #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
 #[non_exhaustive]
 pub struct SelectStatement {
+	/// The foo,bar part in SELECT foo,bar FROM baz.
 	pub expr: Fields,
 	pub omit: Option<Idioms>,
 	#[revision(start = 2)]
 	pub only: bool,
+	/// The baz part in SELECT foo,bar FROM baz.
 	pub what: Values,
 	pub with: Option<With>,
 	pub cond: Option<Cond>,
diff --git a/core/src/sql/value/fetch.rs b/core/src/sql/value/fetch.rs
index 681f1b42..9ef36e41 100644
--- a/core/src/sql/value/fetch.rs
+++ b/core/src/sql/value/fetch.rs
@@ -11,7 +11,6 @@ use futures::future::try_join_all;
 use reblessive::tree::Stk;
 
 impl Value {
-	/// Was marked recursive
 	pub(crate) async fn fetch(
 		&mut self,
 		stk: &mut Stk,
@@ -19,152 +18,222 @@ impl Value {
 		opt: &Options,
 		path: &[Part],
 	) -> Result<(), Error> {
-		match path.first() {
-			// Get the current path part
-			Some(p) => match self {
-				// Current path part is an object
-				Value::Object(v) => match p {
-					Part::Graph(_) => match v.rid() {
-						Some(v) => {
-							let mut v = Value::Thing(v);
-							stk.run(|stk| v.fetch(stk, ctx, opt, path.next())).await
+		let mut this = self;
+		let mut iter = path.iter();
+		let mut prev = path;
+
+		// Loop over the path.
+		// If the we just need to select a sub section of a value we update this to point to the
+		// new subsection of the value. Otherwise we call into fetch again and then immediately
+		// return.
+		// If we encounter a idiom application which does not make sense, like `(1).foo` just
+		// return Ok(())
+		while let Some(p) = iter.next() {
+			match p {
+				Part::Graph(g) => match this {
+					Value::Object(o) => {
+						let Some(v) = o.rid() else {
+							return Ok(());
+						};
+
+						let mut v = Value::Thing(v);
+						return stk.run(|stk| v.fetch(stk, ctx, opt, iter.as_slice())).await;
+					}
+					Value::Thing(x) => {
+						let stm = SelectStatement {
+							expr: Fields(vec![Field::All], false),
+							what: Values(vec![Value::from(Edges {
+								from: x.clone(),
+								dir: g.dir.clone(),
+								what: g.what.clone(),
+							})]),
+							cond: g.cond.clone(),
+							..SelectStatement::default()
+						};
+						*this = stm
+							.compute(stk, ctx, opt, None)
+							.await?
+							.all()
+							.get(stk, ctx, opt, None, path.next())
+							.await?
+							.flatten()
+							.ok()?;
+						return Ok(());
+					}
+					Value::Array(x) => {
+						// apply this path to every entry of the array.
+						stk.scope(|scope| {
+							let futs =
+								x.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, prev)));
+							try_join_all(futs)
+						})
+						.await?;
+						return Ok(());
+					}
+					// break her to be comp
+					_ => return Ok(()),
+				},
+				Part::Field(f) => match this {
+					Value::Object(o) => {
+						let Some(x) = o.get_mut(f.0.as_str()) else {
+							return Ok(());
+						};
+						this = x;
+					}
+					Value::Array(x) => {
+						// apply this path to every entry of the array.
+						stk.scope(|scope| {
+							let futs =
+								x.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, prev)));
+							try_join_all(futs)
+						})
+						.await?;
+						return Ok(());
+					}
+					_ => break,
+				},
+				Part::Index(i) => match this {
+					Value::Object(v) => {
+						let Some(x) = v.get_mut(&i.to_string()) else {
+							return Ok(());
+						};
+						this = x;
+					}
+					Value::Array(v) => {
+						let Some(x) = v.get_mut(i.to_usize()) else {
+							return Ok(());
+						};
+						this = x;
+					}
+					_ => break,
+				},
+				Part::Value(v) => {
+					let v = v.compute(stk, ctx, opt, None).await?;
+					match this {
+						Value::Object(obj) => {
+							let Some(x) = obj.get_mut(v.coerce_to_string()?.as_str()) else {
+								return Ok(());
+							};
+							this = x;
 						}
-						None => Ok(()),
-					},
-					Part::Field(f) => match v.get_mut(f as &str) {
-						Some(v) => stk.run(|stk| v.fetch(stk, ctx, opt, path.next())).await,
-						None => Ok(()),
-					},
-					Part::Index(i) => match v.get_mut(&i.to_string()) {
-						Some(v) => stk.run(|stk| v.fetch(stk, ctx, opt, path.next())).await,
-						None => Ok(()),
-					},
-					Part::All => stk.run(|stk| self.fetch(stk, ctx, opt, path.next())).await,
-					Part::Destructure(p) => {
+						Value::Array(array) => {
+							if let Value::Range(x) = v {
+								let Some(range) = x.slice(array) else {
+									return Ok(());
+								};
+								let mut range = Value::Array(range.to_vec().into());
+								return stk
+									.run(|stk| range.fetch(stk, ctx, opt, iter.as_slice()))
+									.await;
+							}
+							let Some(x) = array.get_mut(v.coerce_to_u64()? as usize) else {
+								return Ok(());
+							};
+							this = x;
+						}
+						_ => return Ok(()),
+					}
+				}
+				Part::Destructure(p) => match this {
+					Value::Array(x) => {
+						// apply this path to every entry of the array.
+						stk.scope(|scope| {
+							let futs =
+								x.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, prev)));
+							try_join_all(futs)
+						})
+						.await?;
+					}
+					Value::Object(_) => {
 						for p in p.iter() {
-							let path = [(p.path().as_slice()), path].concat();
-							stk.run(|stk| self.fetch(stk, ctx, opt, &path)).await?;
+							let mut destructure_path = p.path();
+							destructure_path.extend_from_slice(path);
+							stk.run(|stk| this.fetch(stk, ctx, opt, &destructure_path)).await?;
+						}
+						return Ok(());
+					}
+					_ => return Ok(()),
+				},
+				Part::All => match this {
+					Value::Object(_) => {
+						continue;
+					}
+					Value::Array(x) => {
+						let next_path = iter.as_slice();
+						// no need to spawn all those futures if their is no more paths to
+						// calculate
+						if next_path.is_empty() {
+							break;
 						}
 
-						Ok(())
-					}
-					_ => Ok(()),
-				},
-				// Current path part is an array
-				Value::Array(v) => match p {
-					Part::All => {
-						let path = path.next();
 						stk.scope(|scope| {
-							let futs =
-								v.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, path)));
+							let futs = x
+								.iter_mut()
+								.map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, next_path)));
 							try_join_all(futs)
 						})
 						.await?;
-						Ok(())
+						return Ok(());
 					}
-					Part::First => match v.first_mut() {
-						Some(v) => stk.run(|stk| v.fetch(stk, ctx, opt, path.next())).await,
-						None => Ok(()),
-					},
-					Part::Last => match v.last_mut() {
-						Some(v) => stk.run(|stk| v.fetch(stk, ctx, opt, path.next())).await,
-						None => Ok(()),
-					},
-					Part::Index(i) => match v.get_mut(i.to_usize()) {
-						Some(v) => stk.run(|stk| v.fetch(stk, ctx, opt, path.next())).await,
-						None => Ok(()),
-					},
-					Part::Where(w) => {
-						let path = path.next();
-						for v in v.iter_mut() {
-							let cur = v.clone().into();
-							if w.compute(stk, ctx, opt, Some(&cur)).await?.is_truthy() {
-								stk.run(|stk| v.fetch(stk, ctx, opt, path)).await?;
+					_ => break,
+				},
+				Part::First => match this {
+					Value::Array(x) => {
+						let Some(x) = x.first_mut() else {
+							return Ok(());
+						};
+						this = x;
+					}
+					_ => return Ok(()),
+				},
+				Part::Last => match this {
+					Value::Array(x) => {
+						let Some(x) = x.last_mut() else {
+							return Ok(());
+						};
+						this = x;
+					}
+					_ => return Ok(()),
+				},
+				Part::Where(w) => match this {
+					Value::Array(x) => {
+						for v in x.iter_mut() {
+							let doc = v.clone().into();
+							if w.compute(stk, ctx, opt, Some(&doc)).await?.is_truthy() {
+								stk.run(|stk| v.fetch(stk, ctx, opt, iter.as_slice())).await?;
 							}
 						}
-						Ok(())
-					}
-					_ => {
-						stk.scope(|scope| {
-							let futs =
-								v.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, path)));
-							try_join_all(futs)
-						})
-						.await?;
-						Ok(())
 					}
+					_ => return Ok(()),
 				},
-				// Current path part is a thing
-				Value::Thing(v) => {
-					// Clone the thing
-					let val = v.clone();
-					// Fetch the remote embedded record
-					match p {
-						// This is a graph traversal expression
-						Part::Graph(g) => {
-							let stm = SelectStatement {
-								expr: Fields(vec![Field::All], false),
-								what: Values(vec![Value::from(Edges {
-									from: val,
-									dir: g.dir.clone(),
-									what: g.what.clone(),
-								})]),
-								cond: g.cond.clone(),
-								..SelectStatement::default()
-							};
-							*self = stm
-								.compute(stk, ctx, opt, None)
-								.await?
-								.all()
-								.get(stk, ctx, opt, None, path.next())
-								.await?
-								.flatten()
-								.ok()?;
-							Ok(())
-						}
-						// This is a remote field expression
-						_ => {
-							let stm = SelectStatement {
-								expr: Fields(vec![Field::All], false),
-								what: Values(vec![Value::from(val)]),
-								..SelectStatement::default()
-							};
-							*self = stm.compute(stk, ctx, opt, None).await?.first();
-							Ok(())
-						}
-					}
-				}
-				// Ignore everything else
-				_ => Ok(()),
-			},
-			// No more parts so get the value
-			None => match self {
-				// Current path part is an array
-				Value::Array(v) => {
-					stk.scope(|scope| {
-						let futs =
-							v.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, path)));
-						try_join_all(futs)
-					})
-					.await?;
-					Ok(())
-				}
-				// Current path part is a thing
-				Value::Thing(v) => {
-					// Clone the thing
-					let val = v.clone();
-					// Fetch the remote embedded record
-					let stm = SelectStatement {
-						expr: Fields(vec![Field::All], false),
-						what: Values(vec![Value::from(val)]),
-						..SelectStatement::default()
-					};
-					*self = stm.compute(stk, ctx, opt, None).await?.first();
-					Ok(())
-				}
-				// Ignore everything else
-				_ => Ok(()),
-			},
+				_ => break,
+			}
+			prev = iter.as_slice();
+		}
+
+		// If the final value is on of following types we still need to compute it.
+		match this {
+			Value::Array(v) => {
+				stk.scope(|scope| {
+					let futs = v.iter_mut().map(|v| scope.run(|stk| v.fetch(stk, ctx, opt, path)));
+					try_join_all(futs)
+				})
+				.await?;
+				Ok(())
+			}
+			Value::Thing(v) => {
+				// Clone the thing
+				let val = v.clone();
+				// Fetch the remote embedded record
+				let stm = SelectStatement {
+					expr: Fields(vec![Field::All], false),
+					what: Values(vec![Value::from(val)]),
+					..SelectStatement::default()
+				};
+				*this = stm.compute(stk, ctx, opt, None).await?.first();
+				Ok(())
+			}
+			_ => Ok(()),
 		}
 	}
 }
diff --git a/core/src/sql/value/get.rs b/core/src/sql/value/get.rs
index bf34dace..0ff6c87f 100644
--- a/core/src/sql/value/get.rs
+++ b/core/src/sql/value/get.rs
@@ -233,6 +233,21 @@ impl Value {
 							Some(v) => stk.run(|stk| v.get(stk, ctx, opt, doc, path.next())).await,
 							None => Ok(Value::None),
 						},
+						Value::Range(r) => {
+							if let Some(range) = r.slice(v.as_slice()) {
+								let path = path.next();
+								stk.scope(|scope| {
+									let futs = range
+										.iter()
+										.map(|v| scope.run(|stk| v.get(stk, ctx, opt, doc, path)));
+									try_join_all_buffered(futs)
+								})
+								.await
+								.map(Into::into)
+							} else {
+								Ok(Value::None)
+							}
+						}
 						_ => stk.run(|stk| Value::None.get(stk, ctx, opt, doc, path.next())).await,
 					},
 					Part::Method(name, args) => {
diff --git a/core/src/sql/value/set.rs b/core/src/sql/value/set.rs
index 3d633d74..bb63060c 100644
--- a/core/src/sql/value/set.rs
+++ b/core/src/sql/value/set.rs
@@ -1,10 +1,12 @@
+use std::collections::btree_map::Entry;
+
 use crate::ctx::Context;
 use crate::dbs::Options;
 use crate::err::Error;
 use crate::exe::try_join_all_buffered;
-use crate::sql::part::Next;
 use crate::sql::part::Part;
 use crate::sql::value::Value;
+use crate::sql::Object;
 use reblessive::tree::Stk;
 
 impl Value {
@@ -19,162 +21,254 @@ impl Value {
 		path: &[Part],
 		val: Value,
 	) -> Result<(), Error> {
-		match path.first() {
-			// Get the current value at path
-			Some(p) => match self {
-				// Current value at path is an object
-				Value::Object(v) => match p {
-					Part::Graph(g) => match v.get_mut(g.to_raw().as_str()) {
-						Some(v) if v.is_some() => {
-							stk.run(|stk| v.set(stk, ctx, opt, path.next(), val)).await
-						}
-						_ => {
-							let mut obj = Value::base();
-							stk.run(|stk| obj.set(stk, ctx, opt, path.next(), val)).await?;
-							v.insert(g.to_raw(), obj);
-							Ok(())
-						}
-					},
-					Part::Field(f) => match v.get_mut(f.as_str()) {
-						Some(v) if v.is_some() => {
-							stk.run(|stk| v.set(stk, ctx, opt, path.next(), val)).await
-						}
-						_ => {
-							let mut obj = Value::base();
-							stk.run(|stk| obj.set(stk, ctx, opt, path.next(), val)).await?;
-							v.insert(f.to_raw(), obj);
-							Ok(())
-						}
-					},
-					Part::Index(i) => match v.get_mut(&i.to_string()) {
-						Some(v) if v.is_some() => {
-							stk.run(|stk| v.set(stk, ctx, opt, path.next(), val)).await
-						}
-						_ => {
-							let mut obj = Value::base();
-							stk.run(|stk| obj.set(stk, ctx, opt, path.next(), val)).await?;
-							v.insert(i.to_string(), obj);
-							Ok(())
-						}
-					},
-					Part::Value(x) => match stk.run(|stk| x.compute(stk, ctx, opt, None)).await? {
-						Value::Strand(f) => match v.get_mut(f.as_str()) {
-							Some(v) if v.is_some() => {
-								stk.run(|stk| v.set(stk, ctx, opt, path.next(), val)).await
-							}
-							_ => {
-								let mut obj = Value::base();
-								stk.run(|stk| obj.set(stk, ctx, opt, path.next(), val)).await?;
-								v.insert(f.to_raw(), obj);
-								Ok(())
-							}
-						},
-						_ => Ok(()),
-					},
-					_ => Ok(()),
-				},
-				// Current value at path is an array
-				Value::Array(v) => match p {
-					Part::All => {
-						let path = path.next();
-
-						stk.scope(|scope| {
-							let futs = v
-								.iter_mut()
-								.map(|v| scope.run(|stk| v.set(stk, ctx, opt, path, val.clone())));
-							try_join_all_buffered(futs)
-						})
-						.await?;
-						Ok(())
-					}
-					Part::First => match v.first_mut() {
-						Some(v) => stk.run(|stk| v.set(stk, ctx, opt, path.next(), val)).await,
-						None => Ok(()),
-					},
-					Part::Last => match v.last_mut() {
-						Some(v) => stk.run(|stk| v.set(stk, ctx, opt, path.next(), val)).await,
-						None => Ok(()),
-					},
-					Part::Index(i) => match v.get_mut(i.to_usize()) {
-						Some(v) => stk.run(|stk| v.set(stk, ctx, opt, path.next(), val)).await,
-						None => Ok(()),
-					},
-					Part::Where(w) => match path.next().first() {
-						Some(Part::Index(_)) => {
-							let mut a = Vec::new();
-							let mut p = Vec::new();
-							// Store the elements and positions to update
-							for (i, o) in v.iter_mut().enumerate() {
-								let cur = o.clone().into();
-								if w.compute(stk, ctx, opt, Some(&cur)).await?.is_truthy() {
-									a.push(o.clone());
-									p.push(i);
-								}
-							}
-							// Convert the matched elements array to a value
-							let mut a = Value::from(a);
-							// Set the new value on the matches elements
-							stk.run(|stk| a.set(stk, ctx, opt, path.next(), val.clone())).await?;
-							// Push the new values into the original array
-							for (i, p) in p.into_iter().enumerate() {
-								v[p] = a.pick(&[Part::Index(i.into())]);
-							}
-							Ok(())
-						}
-						_ => {
-							let path = path.next();
-							for v in v.iter_mut() {
-								let cur = v.clone().into();
-								if w.compute(stk, ctx, opt, Some(&cur)).await?.is_truthy() {
-									stk.run(|stk| v.set(stk, ctx, opt, path, val.clone())).await?;
-								}
-							}
-							Ok(())
-						}
-					},
-					Part::Value(x) => match x.compute(stk, ctx, opt, None).await? {
-						Value::Number(i) => match v.get_mut(i.to_usize()) {
-							Some(v) => stk.run(|stk| v.set(stk, ctx, opt, path.next(), val)).await,
-							None => Ok(()),
-						},
-						_ => Ok(()),
-					},
-					_ => {
-						stk.scope(|scope| {
-							let futs = v
-								.iter_mut()
-								.map(|v| scope.run(|stk| v.set(stk, ctx, opt, path, val.clone())));
-							try_join_all_buffered(futs)
-						})
-						.await?;
-
-						Ok(())
-					}
-				},
-				// Current value at path is a record
-				Value::Thing(_) => {
-					*self = Value::base();
-					stk.run(|stk| self.set(stk, ctx, opt, path, val)).await
-				}
-				// Current value at path is empty
-				Value::Null => {
-					*self = Value::base();
-					stk.run(|stk| self.set(stk, ctx, opt, path, val)).await
-				}
-				// Current value at path is empty
-				Value::None => {
-					*self = Value::base();
-					stk.run(|stk| self.set(stk, ctx, opt, path, val)).await
-				}
-				// Ignore everything else
-				_ => Ok(()),
-			},
-			// No more parts so set the value
-			None => {
-				*self = val;
-				Ok(())
-			}
+		if path.is_empty() {
+			*self = val;
+			return Ok(());
 		}
+
+		let mut iter = path.iter();
+		let mut place = self;
+		let mut prev = path;
+
+		// Index forward trying to find the location where to insert the value
+		// Whenever we hit an existing path in the value we update place to point to the new value.
+		// If we hit a dead end, we then assign the into that dead end. If any path is not yet
+		// matched we use that to create an object to assign.
+		while let Some(p) = iter.next() {
+			match place {
+				Value::Thing(_) | Value::Null | Value::None => {
+					// any index is guaranteed to fail so just assign to this place.
+					return Self::assign(stk, ctx, opt, place, val, prev).await;
+				}
+				_ => {}
+			}
+
+			match p {
+				Part::Graph(g) => {
+					match place {
+						Value::Object(obj) => match obj.entry(g.to_raw()) {
+							Entry::Vacant(x) => {
+								let v = x.insert(Value::None);
+								return Self::assign(stk, ctx, opt, v, val, iter.as_slice()).await;
+							}
+							Entry::Occupied(x) => {
+								place = x.into_mut();
+							}
+						},
+						Value::Array(arr) => {
+							// Apply to all entries of the array
+							stk.scope(|scope| {
+								let futs = arr.iter_mut().map(|v| {
+									scope.run(|stk| v.set(stk, ctx, opt, prev, val.clone()))
+								});
+								try_join_all_buffered(futs)
+							})
+							.await?;
+							return Ok(());
+						}
+						_ => return Ok(()),
+					};
+				}
+				Part::Field(f) => {
+					match place {
+						Value::Object(obj) => match obj.entry(f.0.clone()) {
+							Entry::Vacant(x) => {
+								let v = x.insert(Value::None);
+								return Self::assign(stk, ctx, opt, v, val, iter.as_slice()).await;
+							}
+							Entry::Occupied(x) => {
+								place = x.into_mut();
+							}
+						},
+						Value::Array(arr) => {
+							// Apply to all entries of the array
+							stk.scope(|scope| {
+								let futs = arr.iter_mut().map(|v| {
+									scope.run(|stk| v.set(stk, ctx, opt, prev, val.clone()))
+								});
+								try_join_all_buffered(futs)
+							})
+							.await?;
+							return Ok(());
+						}
+						_ => return Ok(()),
+					};
+				}
+				Part::Index(f) => match place {
+					Value::Object(obj) => match obj.entry(f.to_string()) {
+						Entry::Vacant(x) => {
+							let v = x.insert(Value::None);
+							return Self::assign(stk, ctx, opt, v, val, prev).await;
+						}
+						Entry::Occupied(x) => {
+							place = x.into_mut();
+						}
+					},
+					Value::Array(arr) => {
+						if let Some(x) = arr.get_mut(f.to_usize()) {
+							place = x
+						} else {
+							return Ok(());
+						}
+					}
+					_ => return Ok(()),
+				},
+				Part::Value(x) => {
+					let v = stk.run(|stk| x.compute(stk, ctx, opt, None)).await?;
+
+					match place {
+						Value::Object(obj) => {
+							let v = match v {
+								Value::Strand(x) => x.0.clone(),
+								x => x.to_string(),
+							};
+
+							match obj.entry(v) {
+								Entry::Vacant(x) => {
+									let v = x.insert(Value::None);
+									return Self::assign(stk, ctx, opt, v, val, prev).await;
+								}
+								Entry::Occupied(x) => {
+									place = x.into_mut();
+								}
+							}
+						}
+						Value::Array(arr) => match v {
+							Value::Range(x) => {
+								if let Some(v) = x.slice_mut(arr) {
+									let path = iter.as_slice();
+									stk.scope(|scope| {
+										let futs = v.iter_mut().map(|v| {
+											scope.run(|stk| v.set(stk, ctx, opt, path, val.clone()))
+										});
+										try_join_all_buffered(futs)
+									})
+									.await?;
+									return Ok(());
+								} else {
+									return Ok(());
+								}
+							}
+							Value::Number(i) => {
+								if let Some(v) = arr.get_mut(i.to_usize()) {
+									place = v;
+								} else {
+									return Ok(());
+								}
+							}
+							_ => return Ok(()),
+						},
+						_ => return Ok(()),
+					}
+				}
+				Part::First => {
+					let Value::Array(arr) = place else {
+						return Ok(());
+					};
+					let Some(x) = arr.first_mut() else {
+						return Ok(());
+					};
+					place = x
+				}
+				Part::Last => {
+					let Value::Array(arr) = place else {
+						return Ok(());
+					};
+					let Some(x) = arr.last_mut() else {
+						return Ok(());
+					};
+					place = x
+				}
+				Part::All => {
+					let Value::Array(arr) = place else {
+						return Ok(());
+					};
+
+					let path = iter.as_slice();
+					stk.scope(|scope| {
+						let futs = arr
+							.iter_mut()
+							.map(|v| scope.run(|stk| v.set(stk, ctx, opt, path, val.clone())));
+						try_join_all_buffered(futs)
+					})
+					.await?;
+					return Ok(());
+				}
+				Part::Where(w) => {
+					let Value::Array(arr) = place else {
+						return Ok(());
+					};
+					if let Some(Part::Index(_)) = iter.as_slice().first() {
+						let mut a = Vec::new();
+						let mut p = Vec::new();
+						// Store the elements and positions to update
+						for (i, o) in arr.iter_mut().enumerate() {
+							let cur = o.clone().into();
+							if w.compute(stk, ctx, opt, Some(&cur)).await?.is_truthy() {
+								a.push(o.clone());
+								p.push(i);
+							}
+						}
+						// Convert the matched elements array to a value
+						let mut a = Value::from(a);
+						// Set the new value on the matches elements
+						stk.run(|stk| a.set(stk, ctx, opt, iter.as_slice(), val.clone())).await?;
+						// Push the new values into the original array
+						for (i, p) in p.into_iter().enumerate() {
+							arr[p] = a.pick(&[Part::Index(i.into())]);
+						}
+						return Ok(());
+					} else {
+						for v in arr.iter_mut() {
+							let cur = v.clone().into();
+							if w.compute(stk, ctx, opt, Some(&cur)).await?.is_truthy() {
+								stk.run(|stk| v.set(stk, ctx, opt, iter.as_slice(), val.clone()))
+									.await?;
+							}
+						}
+						return Ok(());
+					}
+				}
+				_ => return Ok(()),
+			}
+			prev = iter.as_slice();
+		}
+
+		*place = val;
+		Ok(())
+	}
+
+	async fn assign(
+		stk: &mut Stk,
+		ctx: &Context,
+		opt: &Options,
+		place: &mut Value,
+		mut val: Value,
+		path: &[Part],
+	) -> Result<(), Error> {
+		for p in path.iter().rev() {
+			let name = match p {
+				Part::Graph(x) => x.to_raw(),
+				Part::Field(f) => f.0.clone(),
+				Part::Index(i) => i.to_string(),
+				Part::Value(x) => {
+					let v = stk.run(|stk| x.compute(stk, ctx, opt, None)).await?;
+					match v {
+						Value::Strand(x) => x.0,
+						Value::Number(x) => x.to_string(),
+						Value::Range(x) => x.to_string(),
+						_ => return Ok(()),
+					}
+				}
+				_ => return Ok(()),
+			};
+			let mut object = Object::default();
+			object.insert(name, val);
+			val = object.into();
+		}
+
+		*place = val;
+		Ok(())
 	}
 }
 
diff --git a/core/src/syn/parser/idiom.rs b/core/src/syn/parser/idiom.rs
index 3de53dde..852f69a6 100644
--- a/core/src/syn/parser/idiom.rs
+++ b/core/src/syn/parser/idiom.rs
@@ -346,25 +346,18 @@ impl Parser<'_> {
 				self.pop_peek();
 				Part::Last
 			}
-			t!("+") | TokenKind::Digits | TokenKind::Glued(Glued::Number) => {
-				Part::Index(self.next_token_value()?)
-			}
-			t!("-") => {
-				if let TokenKind::Digits = self.peek_whitespace1().kind {
-					unexpected!(self, peek,"$, * or a number", => "An index can't be negative.");
-				}
-				unexpected!(self, peek, "$, * or a number");
-			}
 			t!("?") | t!("WHERE") => {
 				self.pop_peek();
 				let value = ctx.run(|ctx| self.parse_value_field(ctx)).await?;
 				Part::Where(value)
 			}
-			t!("$param") => Part::Value(Value::Param(self.next_token_value()?)),
-			TokenKind::Qoute(_x) => Part::Value(Value::Strand(self.next_token_value()?)),
 			_ => {
-				let idiom = self.parse_basic_idiom(ctx).await?;
-				Part::Value(Value::Idiom(idiom))
+				let value = ctx.run(|ctx| self.parse_value_inherit(ctx)).await?;
+				if let Value::Number(x) = value {
+					Part::Index(x)
+				} else {
+					Part::Value(value)
+				}
 			}
 		};
 		self.expect_closing_delimiter(t!("]"), start)?;
diff --git a/core/src/syn/parser/mac.rs b/core/src/syn/parser/mac.rs
index 0c981c00..95e65141 100644
--- a/core/src/syn/parser/mac.rs
+++ b/core/src/syn/parser/mac.rs
@@ -22,7 +22,7 @@ macro_rules! unexpected {
 				$crate::syn::error::bail!("Unexpected whitespace, expected token {} to continue",$expected,  @__found.span$( $($t)* )?)
 			}
 			x => {
-				$crate::syn::error::bail!("Unexpected token {}, expected {}",x,$expected, @__found.span$( $($t)* )?)
+				$crate::syn::error::bail!("Unexpected token `{}`, expected {}",x,$expected, @__found.span$( $($t)* )?)
 			}
 		}
 	}};
diff --git a/core/src/syn/parser/test/value.rs b/core/src/syn/parser/test/value.rs
index 5efb494a..6dcc6ecd 100644
--- a/core/src/syn/parser/test/value.rs
+++ b/core/src/syn/parser/test/value.rs
@@ -4,15 +4,37 @@ use reblessive::Stack;
 
 use crate::{
 	sql::{
-		Array, Constant, Id, Idiom, Number, Object, Part, Query, Statement, Statements, Strand,
-		Thing, Value,
+		Array, Constant, Expression, Geometry, Id, Ident, Idiom, Number, Object, Operator, Part,
+		Query, Statement, Statements, Strand, Thing, Value,
 	},
 	syn::parser::{mac::test_parse, Parser},
 };
 
+#[test]
+fn parse_index_expression() {
+	let value = test_parse!(parse_value_table, "a[1 + 1]").unwrap();
+	let Value::Idiom(x) = value else {
+		panic!("not the right value type");
+	};
+	assert_eq!(x.0[0], Part::Field(Ident("a".to_string())));
+	assert_eq!(
+		x.0[1],
+		Part::Value(Value::Expression(Box::new(Expression::Binary {
+			l: Value::Number(Number::Int(1)),
+			o: Operator::Add,
+			r: Value::Number(Number::Int(1)),
+		})))
+	)
+}
+
 #[test]
 fn parse_coordinate() {
-	test_parse!(parse_value_table, "(1.88, -18.0)").unwrap();
+	let coord = test_parse!(parse_value_table, "(1.88, -18.0)").unwrap();
+	let Value::Geometry(Geometry::Point(x)) = coord else {
+		panic!("not the right value");
+	};
+	assert_eq!(x.x(), 1.88);
+	assert_eq!(x.y(), -18.0);
 }
 
 #[test]
diff --git a/sdk/tests/idiom.rs b/sdk/tests/idiom.rs
index c6583921..0a7a3352 100644
--- a/sdk/tests/idiom.rs
+++ b/sdk/tests/idiom.rs
@@ -12,3 +12,47 @@ async fn idiom_chain_part_optional() -> Result<(), Error> {
 	Test::new(sql).await?.expect_val("false")?.expect_val("None")?;
 	Ok(())
 }
+
+#[tokio::test]
+async fn idiom_index_expression() -> Result<(), Error> {
+	let sql = r#"
+		[1,2,3,4][1 + 1];
+	"#;
+	Test::new(sql).await?.expect_val("3")?;
+	Ok(())
+}
+
+#[tokio::test]
+async fn idiom_index_call() -> Result<(), Error> {
+	let sql = r#"
+		DEFINE FUNCTION fn::foo() {
+			return 1 + 1;
+		};
+		RETURN [1,2,3,4][fn::foo()];
+	"#;
+	Test::new(sql).await?.expect_val("None")?.expect_val("3")?;
+	Ok(())
+}
+
+#[tokio::test]
+async fn idiom_index_range() -> Result<(), Error> {
+	let sql = r#"
+		[1,2,3,4][1..2];
+		[1,2,3,4][1..=2];
+		[1,2,3,4][1>..=2];
+		[1,2,3,4][1>..];
+		[1,2,3,4][1..];
+		[1,2,3,4][..2];
+		[1,2,3,4][..=2];
+	"#;
+	Test::new(sql)
+		.await?
+		.expect_val("[2]")?
+		.expect_val("[2,3]")?
+		.expect_val("[3]")?
+		.expect_val("[3,4]")?
+		.expect_val("[2,3,4]")?
+		.expect_val("[1,2]")?
+		.expect_val("[1,2,3]")?;
+	Ok(())
+}