Skip to content

Commit

Permalink
partial work towards embedded value
Browse files Browse the repository at this point in the history
  • Loading branch information
jpschorr committed Oct 22, 2024
1 parent bfb5e87 commit 55db028
Show file tree
Hide file tree
Showing 11 changed files with 226 additions and 2 deletions.
11 changes: 11 additions & 0 deletions extension/partiql-extension-ion/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ bench = false

[dependencies]
partiql-value = { path = "../../partiql-value", version = "0.11.*" }
partiql-common = { path = "../../partiql-common", version = "0.11.*" }

serde = { version = "1", features = ["derive"], optional = true }

ordered-float = "4"
itertools = "0.13"
unicase = "2.7"
Expand All @@ -35,7 +39,14 @@ regex = "1.10"
thiserror = "1.0"
delegate = "0.13"

typetag = "0.2"

[dev-dependencies]

[features]
default = []
serde = [
"dep:serde",
"partiql-value/serde",
"partiql-common/serde"
]
3 changes: 3 additions & 0 deletions extension/partiql-extension-ion/src/encode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ where
Value::List(l) => self.encode_list(l.as_ref()),
Value::Bag(b) => self.encode_bag(b.as_ref()),
Value::Tuple(t) => self.encode_tuple(t.as_ref()),
Value::EmbeddedDoc(_) => {
todo!("ion encode embedded doc")
}
}
}

Expand Down
37 changes: 37 additions & 0 deletions extension/partiql-extension-ion/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,49 @@
#![deny(rust_2018_idioms)]
#![deny(clippy::all)]

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

mod common;
pub mod decode;
pub mod encode;

pub use common::Encoding;

pub mod embedded {
use partiql_common::embedded_document::{EmbeddedDocument, EmbeddedDocumentType};
use std::fmt::{Debug, Formatter};
use std::hash::Hasher;

#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};

#[derive(Default, Copy, Clone)]
pub struct EmbeddedIonType {}
impl EmbeddedDocumentType for EmbeddedIonType {
type Doc = EmbeddedIon;

fn construct(&self, bytes: &[u8]) -> Self::Doc {
EmbeddedIon::Unparsed(bytes.into())
}
}

#[derive(Hash, Clone)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub enum EmbeddedIon {
Unparsed(Vec<u8>),
}

impl Debug for EmbeddedIon {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
todo!()
}
}

#[cfg_attr(feature = "serde", typetag::serde)]
impl EmbeddedDocument for EmbeddedIon {}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 4 additions & 0 deletions partiql-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ rust_decimal = { version = "1.36", default-features = false, features = ["std"]
smallvec = { version = "1" }
thiserror = "1"

dyn-clone = "1"
dyn-hash = "0.2"
typetag = "0.2"

[features]
default = []
serde = [
Expand Down
67 changes: 67 additions & 0 deletions partiql-common/src/embedded_document.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
use dyn_clone::DynClone;
use dyn_hash::DynHash;
use std::fmt::Debug;
use std::sync::Arc;

#[derive(Clone)]
pub struct LazyEmbeddedDocument {
bytes: Arc<Vec<u8>>,
typ: DynEmbeddedTypeTag,
}

impl LazyEmbeddedDocument {
pub fn new<B: Into<Vec<u8>>, T: Into<DynEmbeddedTypeTag>>(bytes: B, typ: T) -> Self {
let bytes = Arc::new(bytes.into());
let typ = typ.into();
Self { bytes, typ }
}
}

// dyn

pub type DynEmbeddedTypeTag = Box<dyn DynEmbeddedDocumentType>;

pub trait DynEmbeddedDocumentType: DynClone {
fn construct(&self, bytes: &[u8]) -> Box<dyn EmbeddedDocument>;
}

dyn_clone::clone_trait_object!(DynEmbeddedDocumentType);

pub trait DynEmbeddedDocumentTypeFactory {
fn to_dyn_type_tag(self) -> DynEmbeddedTypeTag;
}

// typed

pub type EmbeddedTypeTag<D> = Box<dyn EmbeddedDocumentType<Doc = D>>;
pub trait EmbeddedDocumentType: Clone {
type Doc: EmbeddedDocument + 'static;

fn construct(&self, bytes: &[u8]) -> Self::Doc;
}

#[cfg_attr(feature = "serde", typetag::serde)]
pub trait EmbeddedDocument: Debug + DynHash + DynClone {}

dyn_hash::hash_trait_object!(EmbeddedDocument);
dyn_clone::clone_trait_object!(EmbeddedDocument);

impl<T, D> DynEmbeddedDocumentType for T
where
T: EmbeddedDocumentType<Doc = D>,
D: EmbeddedDocument + 'static,
{
fn construct(&self, bytes: &[u8]) -> Box<dyn EmbeddedDocument> {
Box::new(EmbeddedDocumentType::construct(self, bytes))
}
}

impl<T, D> DynEmbeddedDocumentTypeFactory for T
where
T: EmbeddedDocumentType<Doc = D> + 'static,
D: EmbeddedDocument + 'static,
{
fn to_dyn_type_tag(self) -> DynEmbeddedTypeTag {
Box::new(self)
}
}
2 changes: 2 additions & 0 deletions partiql-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ pub mod pretty;
pub mod syntax;

pub mod catalog;

pub mod embedded_document;
19 changes: 17 additions & 2 deletions partiql-logical-planner/src/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use partiql_logical::{
};
use std::borrow::Cow;

use partiql_value::{BindingsName, Value};
use partiql_value::{BindingsName, EmbeddedDoc, Value};

use std::collections::{HashMap, HashSet};

Expand All @@ -35,8 +35,10 @@ use partiql_ast_passes::error::{AstTransformError, AstTransformationError};
use crate::functions::Function;
use partiql_ast_passes::name_resolver::NameRef;
use partiql_catalog::catalog::Catalog;
use partiql_common::embedded_document::{DynEmbeddedDocumentTypeFactory, LazyEmbeddedDocument};
use partiql_common::node::NodeId;
use partiql_extension_ion::decode::{IonDecoderBuilder, IonDecoderConfig};
use partiql_extension_ion::embedded::EmbeddedIonType;
use partiql_extension_ion::Encoding;
use partiql_logical::AggFunc::{AggAny, AggAvg, AggCount, AggEvery, AggMax, AggMin, AggSum};
use partiql_logical::ValueExpr::DynamicLookup;
Expand Down Expand Up @@ -1933,7 +1935,14 @@ fn lit_to_value(lit: &Lit) -> Result<Value, AstTransformError> {
Lit::FloatLit(f) => Value::Real(OrderedFloat::from(f64::from(*f))),
Lit::DoubleLit(f) => Value::Real(OrderedFloat::from(*f)),
Lit::BoolLit(b) => Value::Boolean(*b),
Lit::EmbeddedDocLit(s, _typ) => parse_embedded_ion_str(s)?,
Lit::EmbeddedDocLit(s, _typ) => {
let new_stuff = true;
if !new_stuff {
parse_embedded_ion_str(s)?
} else {
lazy_doc(s)?
}
}
Lit::CharStringLit(s) => Value::String(Box::new(s.clone())),
Lit::NationalCharStringLit(s) => Value::String(Box::new(s.clone())),
Lit::BitStringLit(_) => {
Expand Down Expand Up @@ -2002,6 +2011,12 @@ fn parse_embedded_ion_str(contents: &str) -> Result<Value, AstTransformError> {
.map_err(|e| lit_err(contents, e))
}

fn lazy_doc(contents: &str) -> Result<Value, AstTransformError> {
let ion_typ = EmbeddedIonType::default().to_dyn_type_tag();
let ion_doc = LazyEmbeddedDocument::new(contents, ion_typ);
Ok(Value::EmbeddedDoc(EmbeddedDoc::Lazy(ion_doc)))
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
76 changes: 76 additions & 0 deletions partiql-value/src/embedded_doc.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use partiql_common::embedded_document::{EmbeddedDocument, LazyEmbeddedDocument};
use partiql_common::pretty::{pretty_surrounded, pretty_surrounded_doc, PrettyDoc};
use pretty::{DocAllocator, DocBuilder};
#[cfg(feature = "serde")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::fmt::{Debug, Formatter};
use std::hash::{Hash, Hasher};

pub enum EmbeddedDoc {
Lazy(LazyEmbeddedDocument),
}

impl Debug for EmbeddedDoc {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.write_str("<<TODO: Debug for EmbeddedDoc>>")
}
}

impl Hash for EmbeddedDoc {
fn hash<H: Hasher>(&self, state: &mut H) {
todo!()
}
}

impl Clone for EmbeddedDoc {
fn clone(&self) -> Self {
match self {
EmbeddedDoc::Lazy(doc) => Self::Lazy(doc.clone()),
}
}
}

impl PartialEq<Self> for EmbeddedDoc {
fn eq(&self, other: &Self) -> bool {
todo!()
}
}

impl Eq for EmbeddedDoc {}

#[cfg(feature = "serde")]
impl Serialize for EmbeddedDoc {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
todo!()
}
}

#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for EmbeddedDoc {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
todo!()
}
}

impl PrettyDoc for EmbeddedDoc {
fn pretty_doc<'b, D, A>(&'b self, arena: &'b D) -> DocBuilder<'b, D, A>
where
D: DocAllocator<'b, A>,
D::Doc: Clone,
A: Clone,
{
todo!()
/*
//// TODO handle backticks better
let doc = self.data.pretty_doc(arena);
pretty_surrounded_doc(doc, "`````", "`````", arena)
*/
}
}
2 changes: 2 additions & 0 deletions partiql-value/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ mod bag;
mod bindings;
pub mod comparison;
mod datetime;
mod embedded_doc;
mod list;
mod pretty;
mod sort;
Expand All @@ -16,6 +17,7 @@ pub use bag::*;
pub use bindings::*;
pub use comparison::*;
pub use datetime::*;
pub use embedded_doc::*;
pub use list::*;
pub use pretty::*;
pub use sort::*;
Expand Down
1 change: 1 addition & 0 deletions partiql-value/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ impl PrettyDoc for Value {
Value::List(inner) => inner.pretty_doc(arena),
Value::Bag(inner) => inner.pretty_doc(arena),
Value::Tuple(inner) => inner.pretty_doc(arena),
Value::EmbeddedDoc(inner) => inner.pretty_doc(arena),
}
}
}
Expand Down
6 changes: 6 additions & 0 deletions partiql-value/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::hash::Hash;

use rust_decimal::Decimal as RustDecimal;

use crate::embedded_doc::EmbeddedDoc;
use crate::{Bag, BindingIntoIter, BindingIter, DateTime, List, Tuple};
use rust_decimal::prelude::FromPrimitive;
#[cfg(feature = "serde")]
Expand Down Expand Up @@ -36,6 +37,7 @@ pub enum Value {
List(Box<List>),
Bag(Box<Bag>),
Tuple(Box<Tuple>),
EmbeddedDoc(EmbeddedDoc),
// TODO: add other supported PartiQL values -- sexp
}

Expand Down Expand Up @@ -232,6 +234,7 @@ impl Debug for Value {
Value::List(l) => l.fmt(f),
Value::Bag(b) => b.fmt(f),
Value::Tuple(t) => t.fmt(f),
Value::EmbeddedDoc(doc) => doc.fmt(f),
}
}
}
Expand All @@ -247,6 +250,9 @@ impl PartialOrd for Value {
impl Ord for Value {
fn cmp(&self, other: &Self) -> Ordering {
match (self, other) {
(Value::EmbeddedDoc(_), _) => todo!("EmbeddedDoc Ord"),
(_, Value::EmbeddedDoc(_)) => todo!("EmbeddedDoc Ord"),

(Value::Null, Value::Null) => Ordering::Equal,
(Value::Missing, Value::Null) => Ordering::Equal,

Expand Down

0 comments on commit 55db028

Please sign in to comment.