Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions terminusdb_client/scripts/scripts.py
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ def _df_to_schema(class_name, df):
if k in vars(builtins)
}
np_to_buildin[np.datetime64] = dt.datetime
np_to_buildin[str] = str
for col, dtype in dict(df.dtypes).items():
if embedded and col in embedded:
converted_type = class_name
Expand Down
244 changes: 239 additions & 5 deletions terminusdb_client/woqlquery/woql_query.py
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,240 @@ def triple(self, sub, pred, obj, opt=False):
self._cursor["object"] = self._clean_object(obj)
return self

def triple_slice(self, sub, pred, obj, low, high):
"""Creates a triple pattern matching rule for [S, P, O] with a half-open
value range [low, high) on the object. Returns triples whose typed object
value falls within the specified range.

Parameters
----------
sub : str
Subject, has to be a node (URI) or variable
pred : str
Predicate, can be variable (prefix with "v:") or node
obj : str
Object, can be variable or node or value
low : object
The inclusive lower bound as a typed value
high : object
The exclusive upper bound as a typed value

Returns
-------
WOQLQuery object
query object that can be chained and/or execute
"""
if self._cursor.get("@type"):
self._wrap_cursor_with_and()
self._cursor["@type"] = "TripleSlice"
self._cursor["subject"] = self._clean_subject(sub)
self._cursor["predicate"] = self._clean_predicate(pred)
self._cursor["object"] = self._clean_object(obj)
self._cursor["low"] = self._clean_object(low)
self._cursor["high"] = self._clean_object(high)
return self

def quad_slice(self, sub, pred, obj, low, high, graph):
"""Creates a triple pattern matching rule for [S, P, O, G] with a half-open
value range [low, high) on the object and an explicit graph selector.

Parameters
----------
sub : str
Subject, has to be a node (URI) or variable
pred : str
Predicate, can be variable (prefix with "v:") or node
obj : str
Object, can be variable or node or value
low : object
The inclusive lower bound as a typed value
high : object
The exclusive upper bound as a typed value
graph : str
Graph resource identifier (e.g. 'instance' or 'schema')

Returns
-------
WOQLQuery object
query object that can be chained and/or execute
"""
self.triple_slice(sub, pred, obj, low, high)
self._cursor["graph"] = self._clean_graph(graph)
return self

def triple_slice_rev(self, sub, pred, obj, low, high):
"""Creates a triple pattern matching rule for [S, P, O] with a half-open
value range [low, high) on the object, returning results in reverse
(descending) object order. Same semantics as triple_slice but iterates
from highest to lowest value.

Parameters
----------
sub : str
Subject, has to be a node (URI) or variable
pred : str
Predicate, can be variable (prefix with "v:") or node
obj : str
Object, can be variable or node or value
low : object
The inclusive lower bound as a typed value
high : object
The exclusive upper bound as a typed value

Returns
-------
WOQLQuery object
query object that can be chained and/or execute
"""
if self._cursor.get("@type"):
self._wrap_cursor_with_and()
self._cursor["@type"] = "TripleSliceRev"
self._cursor["subject"] = self._clean_subject(sub)
self._cursor["predicate"] = self._clean_predicate(pred)
self._cursor["object"] = self._clean_object(obj)
self._cursor["low"] = self._clean_object(low)
self._cursor["high"] = self._clean_object(high)
return self

def quad_slice_rev(self, sub, pred, obj, low, high, graph):
"""Creates a triple pattern matching rule for [S, P, O, G] with a half-open
value range [low, high) on the object in reverse order, with an explicit
graph selector.

Parameters
----------
sub : str
Subject, has to be a node (URI) or variable
pred : str
Predicate, can be variable (prefix with "v:") or node
obj : str
Object, can be variable or node or value
low : object
The inclusive lower bound as a typed value
high : object
The exclusive upper bound as a typed value
graph : str
Graph resource identifier (e.g. 'instance' or 'schema')

Returns
-------
WOQLQuery object
query object that can be chained and/or execute
"""
self.triple_slice_rev(sub, pred, obj, low, high)
self._cursor["graph"] = self._clean_graph(graph)
return self

def triple_next(self, sub, pred, obj, next_val):
"""Finds the next object value after a reference for a given subject-predicate pair.
When object is bound and next is free, finds the smallest next > object.
When next is bound and object is free, finds the largest object < next.

Parameters
----------
sub : str
Subject, has to be a node (URI) or variable
pred : str
Predicate, can be variable (prefix with "v:") or node
obj : str
Object value or variable
next_val : object
Next object value or variable

Returns
-------
WOQLQuery object
query object that can be chained and/or execute
"""
if self._cursor.get("@type"):
self._wrap_cursor_with_and()
self._cursor["@type"] = "TripleNext"
self._cursor["subject"] = self._clean_subject(sub)
self._cursor["predicate"] = self._clean_predicate(pred)
self._cursor["object"] = self._clean_object(obj)
self._cursor["next"] = self._clean_object(next_val)
return self

def quad_next(self, sub, pred, obj, next_val, graph):
"""Finds the next object value with an explicit graph selector.

Parameters
----------
sub : str
Subject, has to be a node (URI) or variable
pred : str
Predicate, can be variable (prefix with "v:") or node
obj : str
Object value or variable
next_val : object
Next object value or variable
graph : str
Graph resource identifier (e.g. 'instance' or 'schema')

Returns
-------
WOQLQuery object
query object that can be chained and/or execute
"""
self.triple_next(sub, pred, obj, next_val)
self._cursor["graph"] = self._clean_graph(graph)
return self

def triple_previous(self, sub, pred, obj, prev_val):
"""Finds the previous object value before a reference for a given subject-predicate pair.
When object is bound and previous is free, finds the largest previous < object.
When previous is bound and object is free, finds the smallest object > previous.

Parameters
----------
sub : str
Subject, has to be a node (URI) or variable
pred : str
Predicate, can be variable (prefix with "v:") or node
obj : str
Object value or variable
prev_val : object
Previous object value or variable

Returns
-------
WOQLQuery object
query object that can be chained and/or execute
"""
if self._cursor.get("@type"):
self._wrap_cursor_with_and()
self._cursor["@type"] = "TriplePrevious"
self._cursor["subject"] = self._clean_subject(sub)
self._cursor["predicate"] = self._clean_predicate(pred)
self._cursor["object"] = self._clean_object(obj)
self._cursor["previous"] = self._clean_object(prev_val)
return self

def quad_previous(self, sub, pred, obj, prev_val, graph):
"""Finds the previous object value with an explicit graph selector.

Parameters
----------
sub : str
Subject, has to be a node (URI) or variable
pred : str
Predicate, can be variable (prefix with "v:") or node
obj : str
Object value or variable
prev_val : object
Previous object value or variable
graph : str
Graph resource identifier (e.g. 'instance' or 'schema')

Returns
-------
WOQLQuery object
query object that can be chained and/or execute
"""
self.triple_previous(sub, pred, obj, prev_val)
self._cursor["graph"] = self._clean_graph(graph)
return self

def added_triple(self, sub, pred, obj, opt=False):
"""Creates a triple pattern matching rule for the triple [S, P, O] (Subject, Predicate, Object) added to the current commit.

Expand Down Expand Up @@ -3430,7 +3664,7 @@ def localize(self, param_spec):
"""Build a localized scope for variables to prevent leaking local variables to outer scope.

Returns a tuple (localized_fn, v) where:
- localized_fn: function that wraps queries with select("") and eq() bindings
- localized_fn: function that wraps queries with select() (empty variable list) and eq() bindings
- v: VarsUnique object with unique variable names for use in the inner query

Parameters with non-None values are bound from outer scope via eq().
Expand Down Expand Up @@ -3460,7 +3694,7 @@ def localize(self, param_spec):
v = VarsUnique(*param_names)

def localized_fn(query=None):
# Create eq bindings for outer parameters OUTSIDE select("")
# Create eq bindings for outer parameters OUTSIDE select()
# This ensures outer parameters are visible in query results
outer_eq_bindings = []
for param_name in param_names:
Expand All @@ -3474,17 +3708,17 @@ def localized_fn(query=None):
outer_eq_bindings.append(
WOQLQuery().eq(outer_value, outer_value)
)
# Bind the unique variable to the outer parameter OUTSIDE the select("")
# Bind the unique variable to the outer parameter OUTSIDE the select()
outer_eq_bindings.append(
WOQLQuery().eq(getattr(v, param_name), outer_value)
)

if query is not None:
# Functional mode: wrap query in select(""), then add outer eq bindings
# Functional mode: wrap query in select() with empty variable list
localized_query = WOQLQuery().select(query)

if outer_eq_bindings:
# Wrap: eq(outer) AND select("") { query }
# Wrap: eq(outer) AND select() { query }
return WOQLQuery().woql_and(*outer_eq_bindings, localized_query)
return localized_query

Expand Down