fixed proxy references without null option not being treated as proxies
This commit is contained in:
@ -351,6 +351,7 @@ The Queryer transforms Postgres into a pre-compiled Semantic Query Engine, desig
|
||||
* **Single-Table Bypass**: If the Physical Table is a leaf node with only one variation (e.g. `person` has variations `["person"]`), the compiler cleanly bypasses `CASE` generation and compiles a simple `SELECT` across the base table, as all schema extensions (e.g. `light.person`, `full.person`) are guaranteed to reside in the exact same physical row.
|
||||
* **Polymorphic Relation Type Filtering**: When a relationship maps to a polymorphic target with variations, the Queryer compiles an `IN` clause containing all allowed table variations (e.g., `counterparty_type IN ('bot', 'organization', 'person')`) rather than matching the base type literal, ensuring all polymorphic types are loaded correctly.
|
||||
* **Static Relation Constraints (Kind Constraints)**: When a relationship (such as a nested object or array) is defined with a schema that constrains a field value statically using a `const` or `enum` keyword (for example, `kind` constrained to `"cover"` in a `cover_attachment`), the Queryer automatically extracts these static assertions during AST compilation. It injects them directly as static filters into the SQL subquery's `WHERE` clause (e.g. `AND attachment.kind = 'cover'`), allowing developers to query pre-filtered subsets of related tables natively through the schema.
|
||||
* **Proxy Schema Dereferencing / Resolution**: To support punc endpoints that return non-polymorphic table-backed shapes (using `type: "full.X"` proxy schemas at the root response level), the Queryer compiler automatically dereferences non-table schema pointers to their target schemas prior to checking the types. This allows the Queryer to correctly resolve the table relationship edges pre-compiled on the full schema, while avoiding polluting the database registry with relations on ad-hoc punc response schemas during setup.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -211,6 +211,13 @@
|
||||
"gender": {},
|
||||
"gender.condition": {
|
||||
"type": "condition",
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq",
|
||||
"$ne",
|
||||
"$of",
|
||||
"$nof"
|
||||
],
|
||||
"properties": {
|
||||
"$eq": {
|
||||
"type": [
|
||||
@ -224,15 +231,6 @@
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"$of": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "gender"
|
||||
}
|
||||
},
|
||||
"$nof": {
|
||||
"type": [
|
||||
"array",
|
||||
@ -241,197 +239,158 @@
|
||||
"items": {
|
||||
"type": "gender"
|
||||
}
|
||||
}
|
||||
},
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq",
|
||||
"$ne",
|
||||
"$of",
|
||||
"$nof"
|
||||
]
|
||||
"$of": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "gender"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"person": {},
|
||||
"person.filter": {
|
||||
"type": "filter",
|
||||
"properties": {
|
||||
"first_name": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
},
|
||||
"age": {
|
||||
"type": [
|
||||
"integer.condition",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
},
|
||||
"billing_address": {
|
||||
"type": [
|
||||
"address.filter",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"city",
|
||||
"first_name",
|
||||
"age",
|
||||
"billing_address",
|
||||
"gender",
|
||||
"birth_date",
|
||||
"uuid_field",
|
||||
"tags",
|
||||
"ad_hoc",
|
||||
"$and",
|
||||
"$or"
|
||||
],
|
||||
"properties": {
|
||||
"$and": {
|
||||
"items": {
|
||||
"compiledPropertyNames": [
|
||||
"first_name",
|
||||
"age",
|
||||
"billing_address",
|
||||
"gender",
|
||||
"birth_date",
|
||||
"uuid_field",
|
||||
"tags",
|
||||
"ad_hoc",
|
||||
"$and",
|
||||
"$or"
|
||||
],
|
||||
"type": "person.filter"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"gender": {
|
||||
"type": [
|
||||
"gender.condition",
|
||||
"null"
|
||||
],
|
||||
"$or": {
|
||||
"items": {
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq",
|
||||
"$ne",
|
||||
"$of",
|
||||
"$nof"
|
||||
]
|
||||
"first_name",
|
||||
"age",
|
||||
"billing_address",
|
||||
"gender",
|
||||
"birth_date",
|
||||
"uuid_field",
|
||||
"tags",
|
||||
"ad_hoc",
|
||||
"$and",
|
||||
"$or"
|
||||
],
|
||||
"type": "person.filter"
|
||||
},
|
||||
"birth_date": {
|
||||
"type": [
|
||||
"date.condition",
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
},
|
||||
"uuid_field": {
|
||||
"type": [
|
||||
"uuid.condition",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
},
|
||||
"tags": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
},
|
||||
"ad_hoc": {
|
||||
"type": [
|
||||
"filter",
|
||||
"null"
|
||||
"compiledPropertyNames": [
|
||||
"foo"
|
||||
],
|
||||
"properties": {
|
||||
"foo": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
}
|
||||
},
|
||||
"compiledPropertyNames": [
|
||||
"foo"
|
||||
]
|
||||
},
|
||||
"$and": {
|
||||
"type": [
|
||||
"array",
|
||||
"filter",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "person.filter",
|
||||
"compiledPropertyNames": [
|
||||
"first_name",
|
||||
"age",
|
||||
"billing_address",
|
||||
"gender",
|
||||
"birth_date",
|
||||
"uuid_field",
|
||||
"tags",
|
||||
"ad_hoc",
|
||||
"$and",
|
||||
"$or"
|
||||
]
|
||||
}
|
||||
},
|
||||
"$or": {
|
||||
"age": {
|
||||
"type": [
|
||||
"array",
|
||||
"integer.condition",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"billing_address": {
|
||||
"type": [
|
||||
"address.filter",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"birth_date": {
|
||||
"type": [
|
||||
"date.condition",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"uuid_field": {
|
||||
"type": [
|
||||
"uuid.condition",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"first_name": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"gender": {
|
||||
"type": [
|
||||
"gender.condition",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"tags": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "person.filter",
|
||||
"compiledPropertyNames": [
|
||||
"first_name",
|
||||
"age",
|
||||
"billing_address",
|
||||
"gender",
|
||||
"birth_date",
|
||||
"uuid_field",
|
||||
"tags",
|
||||
"ad_hoc",
|
||||
"$and",
|
||||
"$or"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"compiledPropertyNames": [
|
||||
"first_name",
|
||||
"age",
|
||||
"billing_address",
|
||||
"gender",
|
||||
"birth_date",
|
||||
"uuid_field",
|
||||
"tags",
|
||||
"ad_hoc",
|
||||
"$and",
|
||||
"$or"
|
||||
]
|
||||
"type": "filter"
|
||||
},
|
||||
"address": {},
|
||||
"address.filter": {
|
||||
"type": "filter",
|
||||
"properties": {
|
||||
"city": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
},
|
||||
"city",
|
||||
"$and",
|
||||
"$or"
|
||||
],
|
||||
"properties": {
|
||||
"$and": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "address.filter",
|
||||
"compiledPropertyNames": [
|
||||
"city",
|
||||
"$and",
|
||||
"$or"
|
||||
]
|
||||
],
|
||||
"type": "address.filter"
|
||||
}
|
||||
},
|
||||
"$or": {
|
||||
@ -440,20 +399,21 @@
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "address.filter",
|
||||
"compiledPropertyNames": [
|
||||
"city",
|
||||
"$and",
|
||||
"$or"
|
||||
]
|
||||
}
|
||||
],
|
||||
"type": "address.filter"
|
||||
}
|
||||
},
|
||||
"compiledPropertyNames": [
|
||||
"city",
|
||||
"$and",
|
||||
"$or"
|
||||
"city": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"condition": {},
|
||||
"filter": {},
|
||||
@ -464,47 +424,28 @@
|
||||
"search": {},
|
||||
"search.filter": {
|
||||
"type": "filter",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
],
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"$eq"
|
||||
]
|
||||
},
|
||||
"filter": {
|
||||
"type": [
|
||||
"$kind.filter",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"$and": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "search.filter",
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"name",
|
||||
"filter",
|
||||
"$and",
|
||||
"$or"
|
||||
]
|
||||
],
|
||||
"properties": {
|
||||
"$and": {
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"name",
|
||||
"filter",
|
||||
"$and",
|
||||
"$or"
|
||||
],
|
||||
"type": "search.filter"
|
||||
}
|
||||
},
|
||||
"$or": {
|
||||
@ -513,24 +454,35 @@
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"type": "search.filter",
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"name",
|
||||
"filter",
|
||||
"$and",
|
||||
"$or"
|
||||
]
|
||||
}
|
||||
],
|
||||
"type": "search.filter"
|
||||
}
|
||||
},
|
||||
"compiledPropertyNames": [
|
||||
"kind",
|
||||
"name",
|
||||
"filter",
|
||||
"$and",
|
||||
"$or"
|
||||
"filter": {
|
||||
"type": [
|
||||
"$kind.filter",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"kind": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"name": {
|
||||
"type": [
|
||||
"string.condition",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2547,10 +2547,7 @@
|
||||
"type": "pet",
|
||||
"properties": {
|
||||
"cover_attachment": {
|
||||
"type": [
|
||||
"attachment",
|
||||
"null"
|
||||
],
|
||||
"type": "attachment",
|
||||
"properties": {
|
||||
"kind": {
|
||||
"const": "cover"
|
||||
|
||||
@ -29,23 +29,12 @@ impl Schema {
|
||||
if db.types.contains_key(&base_type_name) {
|
||||
parent_type_name = Some(base_type_name);
|
||||
}
|
||||
} else if let Some(t_or_arr) = &self.obj.type_ {
|
||||
match t_or_arr {
|
||||
crate::database::object::SchemaTypeOrArray::Single(t) => {
|
||||
} else if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
|
||||
// 3. Nested graphs trust their explicit struct pointer reference
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
parent_type_name = Some(t.split('.').next_back().unwrap_or(t).to_string());
|
||||
}
|
||||
}
|
||||
crate::database::object::SchemaTypeOrArray::Multiple(types) => {
|
||||
for t in types {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
parent_type_name = Some(t.split('.').next_back().unwrap_or(t).to_string());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(p_type) = parent_type_name {
|
||||
// Proceed only if the resolved table physically exists within the Postgres Type hierarchy
|
||||
@ -57,9 +46,9 @@ impl Schema {
|
||||
let mut is_array = false;
|
||||
|
||||
// Structurally unpack the inner target entity if the object maps to an array list
|
||||
if let Some(t_or_arr) = &prop_schema.obj.type_ {
|
||||
match t_or_arr {
|
||||
crate::database::object::SchemaTypeOrArray::Single(t) => {
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) =
|
||||
&prop_schema.obj.type_
|
||||
{
|
||||
if t == "array" {
|
||||
is_array = true;
|
||||
if let Some(items) = &prop_schema.obj.items {
|
||||
@ -67,36 +56,16 @@ impl Schema {
|
||||
}
|
||||
}
|
||||
}
|
||||
crate::database::object::SchemaTypeOrArray::Multiple(types) => {
|
||||
if types.contains(&"array".to_string()) {
|
||||
is_array = true;
|
||||
if let Some(items) = &prop_schema.obj.items {
|
||||
target_schema = items.clone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine the physical Postgres table backing the nested child schema recursively
|
||||
if let Some(family) = &target_schema.obj.family {
|
||||
child_type_name = Some(family.split('.').next_back().unwrap_or(family).to_string());
|
||||
} else if let Some(t_or_arr) = &target_schema.obj.type_ {
|
||||
match t_or_arr {
|
||||
crate::database::object::SchemaTypeOrArray::Single(t) => {
|
||||
} else if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) =
|
||||
&target_schema.obj.type_
|
||||
{
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
child_type_name = Some(t.split('.').next_back().unwrap_or(t).to_string());
|
||||
}
|
||||
}
|
||||
crate::database::object::SchemaTypeOrArray::Multiple(types) => {
|
||||
for t in types {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
child_type_name = Some(t.split('.').next_back().unwrap_or(t).to_string());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if let Some(arr) = &target_schema.obj.one_of {
|
||||
if let Some(first) = arr.first() {
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &first.obj.type_
|
||||
|
||||
@ -40,7 +40,6 @@ impl Schema {
|
||||
}
|
||||
|
||||
let mut props = IndexMap::new();
|
||||
let mut inherited_edges = IndexMap::new();
|
||||
|
||||
// 1. Resolve INHERITANCE dependencies first
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &self.obj.type_ {
|
||||
@ -50,9 +49,6 @@ impl Schema {
|
||||
if let Some(p_props) = parent.obj.compiled_properties.get() {
|
||||
props.extend(p_props.clone());
|
||||
}
|
||||
if let Some(p_edges) = parent.obj.compiled_edges.get() {
|
||||
inherited_edges.extend(p_edges.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -81,12 +77,6 @@ impl Schema {
|
||||
if !crate::database::object::is_primitive_type(t) && !t.starts_with('$') {
|
||||
if let Some(parent) = db.schemas.get(t).cloned() {
|
||||
parent.as_ref().compile(db, t, t.clone(), errors);
|
||||
if let Some(p_props) = parent.obj.compiled_properties.get() {
|
||||
props.extend(p_props.clone());
|
||||
}
|
||||
if let Some(p_edges) = parent.obj.compiled_edges.get() {
|
||||
inherited_edges.extend(p_edges.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -126,10 +116,7 @@ impl Schema {
|
||||
let _ = self.obj.compiled_property_names.set(names);
|
||||
|
||||
// 5. Compute Edges natively
|
||||
let mut schema_edges = self.compile_edges(db, root_id, &path, &props, errors);
|
||||
for (k, v) in inherited_edges {
|
||||
schema_edges.entry(k).or_insert(v);
|
||||
}
|
||||
let schema_edges = self.compile_edges(db, root_id, &path, &props, errors);
|
||||
let _ = self.obj.compiled_edges.set(schema_edges);
|
||||
|
||||
// 5. Build our inline children properties recursively NOW! (Depth-first search)
|
||||
|
||||
@ -87,9 +87,8 @@ impl<'a> Compiler<'a> {
|
||||
.next_back()
|
||||
.unwrap_or(family_target);
|
||||
resolved_type = self.db.types.get(base_type_name);
|
||||
} else if let Some(t_or_arr) = &items.obj.type_ {
|
||||
match t_or_arr {
|
||||
crate::database::object::SchemaTypeOrArray::Single(t) => {
|
||||
} else if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &items.obj.type_
|
||||
{
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
resolved_type = self
|
||||
.db
|
||||
@ -97,21 +96,6 @@ impl<'a> Compiler<'a> {
|
||||
.get(&t.split('.').next_back().unwrap_or(t).to_string());
|
||||
}
|
||||
}
|
||||
crate::database::object::SchemaTypeOrArray::Multiple(types) => {
|
||||
for t in types {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
resolved_type = self
|
||||
.db
|
||||
.types
|
||||
.get(&t.split('.').next_back().unwrap_or(t).to_string());
|
||||
if resolved_type.is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(type_def) = resolved_type {
|
||||
@ -137,6 +121,21 @@ impl<'a> Compiler<'a> {
|
||||
}
|
||||
|
||||
fn compile_reference(&mut self, node: Node<'a>) -> Result<(String, String), String> {
|
||||
// Handle Direct Refs via type pointer first
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &node.schema.obj.type_ {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
if !self.db.types.contains_key(t) {
|
||||
// If it's just an ad-hoc struct ref, we should resolve it
|
||||
if let Some(target_schema) = self.db.schemas.get(t).cloned() {
|
||||
let mut ref_node = node.clone();
|
||||
ref_node.schema = target_schema.clone();
|
||||
ref_node.schema_id = Some(t.clone());
|
||||
return self.compile_node(ref_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if this schema represents a Database Entity
|
||||
let mut resolved_type = None;
|
||||
|
||||
@ -152,43 +151,23 @@ impl<'a> Compiler<'a> {
|
||||
.next_back()
|
||||
.unwrap_or(family_target);
|
||||
resolved_type = self.db.types.get(base_type_name);
|
||||
} else if let Some(t_or_arr) = &node.schema.obj.type_ {
|
||||
match t_or_arr {
|
||||
crate::database::object::SchemaTypeOrArray::Single(t) => {
|
||||
} else if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) =
|
||||
&node.schema.obj.type_
|
||||
{
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
let base_type_name = t.split('.').next_back().unwrap_or(t).to_string();
|
||||
resolved_type = self.db.types.get(&base_type_name);
|
||||
}
|
||||
}
|
||||
crate::database::object::SchemaTypeOrArray::Multiple(types) => {
|
||||
for t in types {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
let base_type_name = t.split('.').next_back().unwrap_or(t).to_string();
|
||||
resolved_type = self.db.types.get(&base_type_name);
|
||||
if resolved_type.is_some() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(type_def) = resolved_type {
|
||||
return self.compile_entity(type_def, node.clone(), false);
|
||||
}
|
||||
|
||||
// Handle Direct Refs via type pointer
|
||||
// Fallback error if the schema pointer was unresolved
|
||||
if let Some(crate::database::object::SchemaTypeOrArray::Single(t)) = &node.schema.obj.type_ {
|
||||
if !crate::database::object::is_primitive_type(t) {
|
||||
// If it's just an ad-hoc struct ref, we should resolve it
|
||||
if let Some(target_schema) = self.db.schemas.get(t).cloned() {
|
||||
let mut ref_node = node.clone();
|
||||
ref_node.schema = target_schema.clone();
|
||||
ref_node.schema_id = Some(t.clone());
|
||||
return self.compile_node(ref_node);
|
||||
}
|
||||
return Err(format!("Unresolved schema type pointer: {}", t));
|
||||
}
|
||||
}
|
||||
@ -469,9 +448,6 @@ impl<'a> Compiler<'a> {
|
||||
Some(crate::database::object::SchemaTypeOrArray::Single(s)) => {
|
||||
!crate::database::object::is_primitive_type(s)
|
||||
}
|
||||
Some(crate::database::object::SchemaTypeOrArray::Multiple(v)) => {
|
||||
v.iter().any(|s| !crate::database::object::is_primitive_type(s))
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
|
||||
@ -157,10 +157,7 @@ fn test_library_api() {
|
||||
}
|
||||
},
|
||||
"name": { "type": ["string.condition", "null"] },
|
||||
"target": {
|
||||
"type": ["target_schema.filter", "null"],
|
||||
"compiledPropertyNames": ["value", "$and", "$or"]
|
||||
},
|
||||
"target": { "type": ["target_schema.filter", "null"] },
|
||||
"type": { "type": ["string.condition", "null"] }
|
||||
},
|
||||
"type": "filter"
|
||||
|
||||
Reference in New Issue
Block a user