rql package¶
Submodules¶
rql.analyze module¶
Analyze of the RQL syntax tree to get possible types for RQL variables.
- rql.analyze.CSPProblem¶
alias of
ConstraintCSPProblem
- class rql.analyze.ETypeResolver(schema: rql.interfaces.ISchema, uid_func_mapping: Dict[str, Callable[[int], str]] | None = None)[source]¶
Bases:
object
Resolve variables types according to the schema.
- CSP modelisation:
variable <-> RQL variable
domains <-> different entity’s types defined in the schema
constraints <-> relations between (RQL) variables
- set_schema(schema: rql.interfaces.ISchema) None [source]¶
- solve(node: rql.stmts.AnyScopeNode, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- var_solkey: str = 'possibletypes'¶
- visit(node: rql.stmts.AnyStatement, uid_func_mapping: Dict[str, Callable[[int], str]] | None = None, kwargs: Dict | None = None, debug: bool = False) Set[str] [source]¶
- visit_and(et: rql.nodes.And, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_comparison(comparison: rql.nodes.Comparison, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_constant(constant: rql.nodes.Constant, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_delete(node: rql.stmts.Delete) None [source]¶
- visit_exists(exists: rql.nodes.Exists, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_function(function: rql.nodes.Function, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_insert(node: rql.stmts.Insert) None [source]¶
- visit_keyword(keyword: Any, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_mathexpression(mathexpression: rql.nodes.MathExpression, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_not(et: rql.nodes.Not, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_or(ou: rql.nodes.Or, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_relation(relation: rql.nodes.Relation, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
extract constraints for an relation according to it’s type
- visit_select(node: rql.stmts.Select) None [source]¶
- visit_set(node: rql.stmts.Set) None [source]¶
- visit_type_restriction(relation: rql.nodes.Relation, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- visit_union(node: rql.stmts.Union) None [source]¶
- visit_variableref(variableref: rql.nodes.VariableRef, constraints: ConstraintCSPProblem | GecodeCSPProblem) None [source]¶
- class rql.analyze.ETypeResolverIgnoreTypeRestriction(schema: rql.interfaces.ISchema, uid_func_mapping: Dict[str, Callable[[int], str]] | None = None)[source]¶
Bases:
ETypeResolver
same as ETypeResolver but ignore type restriction relation
results are stored in as the ‘allpossibletypes’ key in variable’stinfo
- debug: int¶
- uid_func: Callable | None¶
- uid_func_mapping: Dict[str, Callable[[int], str]] | None¶
- var_solkey: str = 'allpossibletypes'¶
- class rql.analyze.GecodeCSPProblem[source]¶
Bases:
object
Builds an internal representation of the constraint that will be passed to the rql_solve module which implements a gecode-based solver
The internal representation is a tree builds with lists of lists the first item of the list is the node type (_AND,_OR,_EQ,_EQV)
an example : [“and”, [ “eq”,0,0 ], [“or”, [“eq”, 1, 1], [“eq”, 1, 2] ] ]
means Var(0) == Value(0) and ( Var(1)==Val(1) or Var(1) == Val(2)
TODO: at the moment the solver makes no type checking on the structure of the tree thus can crash badly if something wrong is handled to it this should not happend as the building of the tree is done internally but it should be fixed anyways. When fixing that we should also replace string nodes by integers
rql.base module¶
Base classes for RQL syntax tree nodes.
Note: this module uses __slots__ to limit memory usage.
- class rql.base.BaseNode[source]¶
Bases:
VisitableMixIn
- copy(stmt: rql.stmts.Statement | None = None) BaseNode [source]¶
- get_nodes(klass: Type[_Y]) List[_Y] [source]¶
Return the list of nodes of a given class in the subtree.
- iget_nodes(klass: Type[_Y]) Iterator[_Y] [source]¶
Return an iterator over nodes of a given class in the subtree.
- initargs(stmt: rql.stmts.Statement | None) Tuple[Any, ...] [source]¶
Return list of arguments to give to __init__ to clone this node.
I don’t use __getinitargs__ because I’m not sure it should interfer with copy/pickle
- property scope: rql.stmts.Statement | BaseNode | None¶
Return the scope node to which this node belong (eg Select or Exists node)
- property stmt: rql.stmts.Statement | None¶
Return the Select node to which this node belong
- class rql.base.BinaryNode(lhs: BaseNode | None = None, rhs: BaseNode | None = None)[source]¶
Bases:
Node
- class rql.base.LeafNode[source]¶
Bases:
BaseNode
Class optimized for leaf nodes.
- property children¶
- copy(stmt: rql.stmts.Statement | None = None) BaseNode [source]¶
Create and return a copy of this node and its descendant.
stmt is the root node, which should be use to get new variables.
- class rql.base.Node[source]¶
Bases:
BaseNode
Class for nodes of the tree which may have children (almost all…)
- copy(stmt: rql.stmts.Statement | None = None) Node [source]¶
Create and return a copy of this node and its descendant.
stmt is the root node, which should be use to get new variables
rql.interfaces module¶
Interfaces used by the RQL package.
- class rql.interfaces.IEntitySchema(*args, **kwargs)[source]¶
Bases:
Protocol
Interface for Entity schema.
- class rql.interfaces.IRelationSchema(*args, **kwargs)[source]¶
Bases:
Protocol
Interface for Relation schema (a relation is a named oriented link between two entities).
- class rql.interfaces.ISchema(*args, **kwargs)[source]¶
Bases:
Protocol
RQL expects some base types to exists: String, Float, Int, Boolean, Date and a base relation : is
- entities(schema: Any | None = None)[source]¶
Return the list of possible types.
If schema is not None, return a list of schemas instead of types.
rql.nodes module¶
RQL syntax tree nodes.
This module defines all the nodes we can find in a RQL Syntax tree, except root nodes, defined in the stmts module.
- class rql.nodes.And(lhs: BaseNode | None = None, rhs: BaseNode | None = None)[source]¶
Bases:
BinaryNode
a logical AND node (binary)
- class rql.nodes.ColumnAlias(alias, colnum, query=None)[source]¶
Bases:
Referenceable
- colnum¶
- get_description(mainindex: int, tr: TranslationFunction, none_allowed: bool = False) str | None [source]¶
return entity type of this object, ‘Any’ if not found
- get_type(solution: Dict[str, str] | None = None, kwargs: Dict | None = None) str [source]¶
return entity type of this object, ‘Any’ if not found
- query¶
- class rql.nodes.Comparison(operator: str, value: Function | Constant | VariableRef | MathExpression | None = None, optional: str | None = None)[source]¶
-
handle comparisons:
<, <=, =, >=, > LIKE and ILIKE operators have a unique children.
- initargs(stmt: rql.stmts.Statement | None) Tuple[str, Any | None, str | None] [source]¶
return list of arguments to give to __init__ to clone this node
- operator¶
- optional¶
- class rql.nodes.Constant(value: float | int | bool | str | None, c_type: str, _uid: bool = False, _uidtype: str = '')[source]¶
-
String, Int, TRUE, FALSE, TODAY, NULL…
- as_string(kwargs: Dict | None = None) str [source]¶
return the tree as an encoded rql string (an unicode string is returned if encoding is None)
- initargs(stmt: rql.stmts.Statement | None) Tuple[float | int | bool | str | None, str, bool, str | None] [source]¶
return list of arguments to give to __init__ to clone this node
- type¶
- uid¶
- uidtype¶
- value¶
- class rql.nodes.EditableMixIn[source]¶
Bases:
object
mixin class to add edition functionalities to some nodes, eg root nodes (statement) and Exists nodes
- add_constant_restriction(var: Variable | ColumnAlias, rtype: str, value: str, ctype: str, operator: str = '=') Relation [source]¶
builds a restriction node to express a constant restriction:
variable rtype = value
- add_eid_restriction(var: Variable, eid: str, c_type: str = 'Int') Relation [source]¶
builds a restriction node to express ‘<var> eid <eid>’
- add_relation(lhsvar: Variable, rtype: str, rhsvar: rql.nodes.Variable) Relation [source]¶
builds a restriction node to express ‘<var> eid <eid>’
- add_restriction(relation: Relation) rql.nodes.Relation [source]¶
add a restriction relation
- add_type_restriction(var: Variable | ColumnAlias, etype: str) Relation [source]¶
builds a restriction node to express : variable is etype
- remove_node(node: Any, undefine: bool = False) None [source]¶
remove the given node from the tree
USE THIS METHOD INSTEAD OF .remove to get correct variable references handling
- property should_register_op: bool¶
- property undo_manager: rql.undo.SelectionManager¶
- class rql.nodes.Exists(restriction: Any | None = None)[source]¶
Bases:
EditableMixIn
,BaseNode
EXISTS sub query
- append(node: rql.base.BaseNode) None [source]¶
- property children¶
- copy(stmt: rql.stmts.Statement | None = None) Exists [source]¶
- neged(traverse_scope: bool = False, _fromnode: Any | None = None, strict: bool | None = None) Not | bool [source]¶
- query: Any¶
- remove(child: rql.base.BaseNode) Tuple[rql.base.BaseNode, rql.base.BaseNode | None, int | None] [source]¶
- replace(oldnode: rql.base.BaseNode, newnode: rql.base.BaseNode) Tuple[rql.base.BaseNode, rql.base.BaseNode, int | None] [source]¶
- property scope¶
Return the scope node to which this node belong (eg Select or Exists node)
- set_where(node: rql.base.BaseNode) None [source]¶
- property where¶
- class rql.nodes.Function(name: str)[source]¶
-
Class used to deal with aggregat functions (sum, min, max, count, avg) and latter upper(), lower() and other RQL transformations functions
- descr() logilab.database.FunctionDescr [source]¶
return the type of object returned by this function if known
- get_description(mainindex: int, tr: TranslationFunction) str | None [source]¶
- get_type(solution: Dict[str, str] | None = None, kwargs: Dict | None = None) str [source]¶
return the type of object returned by this function if known
solution is an optional variable/etype mapping
- initargs(stmt: rql.stmts.Statement | None) Tuple[str] [source]¶
return list of arguments to give to __init__ to clone this node
- name¶
- class rql.nodes.HSMixin[source]¶
Bases:
object
mixin class for classes which may be the lhs or rhs of an expression
- get_description(mainindex: int, tr: TranslationFunction) str | None [source]¶
- class rql.nodes.MathExpression(operator: str, lhs: Node | None = None, rhs: Node | None = None)[source]¶
Bases:
OperatorExpressionMixin
,HSMixin
,BinaryNode
Mathematical Operators
- get_type(solution: Dict[str, str] | None = None, kwargs: Dict | None = None) str [source]¶
return the type of object returned by this function if known
solution is an optional variable/etype mapping
- operator¶
- class rql.nodes.Not(expr: Any | None = None)[source]¶
Bases:
Node
a logical NOT node (unary)
- neged(traverse_scope: bool = False, _fromnode: Any | None = None, strict: bool = False) Not [source]¶
- remove(child: rql.base.BaseNode) Tuple[rql.base.BaseNode, rql.base.BaseNode | None, int | None] [source]¶
Remove a child node. Return the removed node, its old parent and index in the children list.
- class rql.nodes.OperatorExpressionMixin[source]¶
Bases:
object
- get_description(mainindex: int, tr: TranslationFunction) str | None [source]¶
if there is a variable in the math expr used as rhs of a relation, return the name of this relation, else return the type of the math expression
- initargs(stmt: rql.stmts.Statement | None) Tuple[str, str | None] [source]¶
return list of arguments to give to __init__ to clone this node
- class rql.nodes.Or(lhs: BaseNode | None = None, rhs: BaseNode | None = None)[source]¶
Bases:
BinaryNode
a logical OR node (binary)
- class rql.nodes.Referenceable(name)[source]¶
Bases:
VisitableMixIn
- get_description(mainindex: int, tr: TranslationFunction, none_allowed: bool = False) str | None [source]¶
return : * the name of a relation where this variable is used as lhs, * the entity type of this object if specified by a ‘is’ relation, * ‘Any’ if nothing nicer has been found…
give priority to relation name
- get_type(solution: Dict[str, str] | None = None, kwargs: Dict | None = None) str [source]¶
return entity type of this object, ‘Any’ if not found
- main_relation()[source]¶
Return the relation where this variable is used in the rhs.
It is useful for cases where this variable is final and we are looking for the entity to which it belongs.
- name¶
- register_reference(vref: VariableRef) None [source]¶
add a reference to this variable
- property schema¶
- property scope¶
- selected_index()[source]¶
return the index of this variable in the selection if it’s selected, else None
- stinfo¶
- stmt¶
- unregister_reference(vref: VariableRef) None [source]¶
remove a reference to this variable
- class rql.nodes.Relation(r_type: str, optional: str | None = None)[source]¶
Bases:
Node
a RQL relation
- get_parts() Tuple[Any, Any] [source]¶
return the left hand side and the right hand side of this relation
- get_variable_parts() Tuple[Any, Any] [source]¶
return the left hand side and the right hand side of this relation, ignoring comparison
- initargs(stmt: rql.stmts.Statement | None) Tuple[str, str | None] [source]¶
return list of arguments to give to __init__ to clone this node
- neged(traverse_scope: bool = False, _fromnode: Any | None = None, strict: bool | None = None) Not | bool [source]¶
- operator() str [source]¶
return the operator of the relation <, <=, =, >=, > and LIKE
- (relations used in SET, INSERT and DELETE definitions don’t have
an operator as rhs)
- optional: str | None¶
- r_type¶
- class rql.nodes.SortTerm(variable: Any, asc: int = 1, nulls_sort: int = 0, copy: Any | None = None)[source]¶
Bases:
Node
a sort term bind a variable to the boolean <asc> if <asc> ascendant sort else descendant sort
- asc¶
- initargs(stmt: rql.stmts.Statement | None) Tuple[None, int, int, bool] [source]¶
return list of arguments to give to __init__ to clone this node
- property term¶
- class rql.nodes.SubQuery(aliases: List[VariableRef] | None = None, query: rql.stmts.Union | None = None)[source]¶
Bases:
BaseNode
WITH clause
- aliases¶
- property children¶
- copy(stmt: rql.stmts.Statement | None = None) SubQuery [source]¶
- query¶
- set_aliases(aliases: List[VariableRef]) None [source]¶
- set_query(node: rql.stmts.Union) None [source]¶
- class rql.nodes.UnaryExpression(operator: str, child: Any | None = None)[source]¶
Bases:
OperatorExpressionMixin
,Node
Unary Operators
- get_type(solution: Dict[str, str] | None = None, kwargs: Dict | None = None) str [source]¶
return the type of object returned by this expression if known
solution is an optional variable/etype mapping
- operator¶
- class rql.nodes.Variable(name)[source]¶
Bases:
Referenceable
a variable definition, should not be directly added to the syntax tree (use VariableRef instead)
collects information about a variable use in a syntax tree
- class rql.nodes.VariableRef(variable: Variable | ColumnAlias, noautoref: int | None = None)[source]¶
-
a reference to a variable in the syntax tree
- copy(stmt: rql.stmts.Statement | None = None) VariableRef [source]¶
Create and return a copy of this node and its descendant.
stmt is the root node, which should be use to get new variables.
- get_description(mainindex: int, tr: TranslationFunction) str | None [source]¶
- name: str¶
- root_selection_index() int | None [source]¶
return the index of this variable reference in the root selection if it’s selected, else None
- variable¶
- class rql.nodes.VariableRefAttributeAccess(variable: Variable | ColumnAlias, attribute: str, noautoref: int | None = None)[source]¶
Bases:
VariableRef
- copy(stmt: rql.stmts.Statement | None = None) VariableRefAttributeAccess [source]¶
Create and return a copy of this node and its descendant.
stmt is the root node, which should be use to get new variables.
- name: str¶
- variable¶
- class rql.nodes.VariableRefMethodCall(variable: Variable | ColumnAlias, method_to_call: str, args: List[Constant], noautoref: int | None = None)[source]¶
Bases:
VariableRef
- copy(stmt: rql.stmts.Statement | None = None) VariableRefMethodCall [source]¶
Create and return a copy of this node and its descendant.
stmt is the root node, which should be use to get new variables.
- name: str¶
- variable¶
- rql.nodes.etype_from_pyobj(value: bool | int | float | Decimal | str | datetime | date | time | timedelta) str [source]¶
guess yams type from python value
- rql.nodes.make_constant_restriction(var: Variable | ColumnAlias, rtype: str, value: str, ctype: str, operator: str = '=') Relation [source]¶
- rql.nodes.make_relation(var: Variable | ColumnAlias, rel: str, rhsargs: Tuple[Any, ...], rhsclass: type, operator: str = '=') Relation [source]¶
build an relation equivalent to ‘<var> rel = <cst>’
- rql.nodes.variable_ref(var: Variable | rql.nodes.VariableRef) VariableRef [source]¶
get a VariableRef
- rql.nodes.variable_refs(node: VariableRef) Iterator[rql.base.BaseNode | VariableRef] [source]¶
rql.parser module¶
yapps input grammar for RQL.
- organization:
Logilab
- copyright:
2003-2021 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
- contact:
Select statement grammar¶
query = <squery> | <union>
union = (<squery>) UNION (<squery>) [UNION (<squery>)]*
- squery = Any <selection>
[GROUPBY <variables>] [ORDERBY <sortterms>] [LIMIT <nb> OFFSET <nb>] [WHERE <restriction>] [HAVING <aggregat restriction>] [WITH <subquery> [,<subquery]*]
subquery = <variables> BEING (<query>)
variables = <variable> [, <variable>]*
Abbreviations in this code¶
rules: * rel -> relation * decl -> declaration * expr -> expression * restr -> restriction * var -> variable * func -> function * const -> constant * cmp -> comparison
variables: * R -> syntax tree root * S -> select node * P -> parent node
- class rql.parser.Hercule(scanner)[source]¶
Bases:
Parser
- class Context(parent, scanner, rule, args=())¶
Bases:
object
Class to represent the parser’s call stack.
Every rule creates a Context that links to its parent rule. The contexts can be used for debugging.
- class rql.parser.HerculeScanner(str, *args, **kw)[source]¶
Bases:
Scanner
- patterns = [("'IN'", re.compile('IN')), ("'\\)'", re.compile('\\)')), ("'\\('", re.compile('\\(')), ("','", re.compile(',')), ('r"\\)"', re.compile('\\)')), ('r"\\("', re.compile('\\(')), ('":"', re.compile(':')), ("';'", re.compile(';')), ('\\s+', re.compile('\\s+')), ('/\\*(?:[^*]|\\*(?!/))*\\*/', re.compile('/\\*(?:[^*]|\\*(?!/))*\\*/')), ('DELETE', re.compile('(?i)DELETE', re.IGNORECASE)), ('SET', re.compile('(?i)SET', re.IGNORECASE)), ('INSERT', re.compile('(?i)INSERT', re.IGNORECASE)), ('UNION', re.compile('(?i)UNION', re.IGNORECASE)), ('DISTINCT', re.compile('(?i)DISTINCT', re.IGNORECASE)), ('WITH', re.compile('(?i)WITH', re.IGNORECASE)), ('WHERE', re.compile('(?i)WHERE', re.IGNORECASE)), ('BEING', re.compile('(?i)BEING', re.IGNORECASE)), ('OR', re.compile('(?i)OR', re.IGNORECASE)), ('AND', re.compile('(?i)AND', re.IGNORECASE)), ('NOT', re.compile('(?i)NOT', re.IGNORECASE)), ('GROUPBY', re.compile('(?i)GROUPBY', re.IGNORECASE)), ('HAVING', re.compile('(?i)HAVING', re.IGNORECASE)), ('ORDERBY', re.compile('(?i)ORDERBY', re.IGNORECASE)), ('SORT_ASC', re.compile('(?i)ASC', re.IGNORECASE)), ('SORT_DESC', re.compile('(?i)DESC', re.IGNORECASE)), ('SORT_NULLSFIRST', re.compile('(?i)NULLSFIRST', re.IGNORECASE)), ('SORT_NULLSLAST', re.compile('(?i)NULLSLAST', re.IGNORECASE)), ('LIMIT', re.compile('(?i)LIMIT', re.IGNORECASE)), ('OFFSET', re.compile('(?i)OFFSET', re.IGNORECASE)), ('DATE', re.compile('(?i)TODAY', re.IGNORECASE)), ('DATETIME', re.compile('(?i)NOW', re.IGNORECASE)), ('TRUE', re.compile('(?i)TRUE', re.IGNORECASE)), ('FALSE', re.compile('(?i)FALSE', re.IGNORECASE)), ('NULL', re.compile('(?i)NULL', re.IGNORECASE)), ('EXISTS', re.compile('(?i)EXISTS', re.IGNORECASE)), ('CMP_OP', re.compile('(?i)<=|<|>=|>|!=|=|~=|LIKE|ILIKE|REGEXP', re.IGNORECASE)), ('ADD_OP', re.compile('\\+|-|\\||#')), ('MUL_OP', re.compile('\\*|/|%|&')), ('POW_OP', re.compile('\\^|>>|<<')), ('UNARY_OP', re.compile('-|~')), ('FUNCTION', re.compile('[A-Za-z_]+\\s*(?=\\()')), ('R_TYPE', re.compile('[a-z_][a-z0-9_]*')), ('E_TYPE', re.compile('[A-Z][A-Za-z0-9]*[a-z]+[A-Z0-9]*')), ('VARIABLE', re.compile('[A-Z][A-Z0-9_]*')), ('QMARK', re.compile('\\?')), ('FUNCTION_CALL', re.compile('[A-Z][A-Z0-9_]*\\.[a-z_][a-zA-Z0-9_]+')), ('STRING', re.compile('\'([^\\\'\\\\]|\\\\.)*\'|\\"([^\\\\\\"\\\\]|\\\\.)*\\"')), ('FLOAT', re.compile('-?\\d+\\.\\d*')), ('INT', re.compile('-?\\d+')), ('SUBSTITUTE', re.compile('%\\([A-Za-z_0-9]+\\)s'))]¶
rql.stcheck module¶
RQL Syntax tree annotator
- exception rql.stcheck.GoTo(node: rql.nodes.Relation)[source]¶
Bases:
Exception
Exception used to control the visit of the tree.
- class rql.stcheck.RQLSTAnnotator(schema, special_relations=None)[source]¶
Bases:
object
Annotate RQL syntax tree to ease further code generation from it.
If an optional variable is shared among multiple scopes, it’s rewritten to use identity relation.
if variable is shared across multiple scopes, need some tree rewriting
- visit_delete(node)¶
- visit_insert(node)¶
- visit_or(node, scope)¶
- visit_set(node)¶
- class rql.stcheck.RQLSTChecker(schema: DummySchema, special_relations: Dict[str, str] | None = None, backend: Any | None = None)[source]¶
Bases:
object
Check a RQL syntax tree for errors not detected on parsing.
Some simple rewriting of the tree may be done too: * if a OR is used on a symmetric relation * IN function with a single child
use assertions for internal error but specific BadRQLQuery exception for errors due to a bad rql input
- has_unique_value_path(select: rql.stmts.Select, fromvar: str, tovar: str) bool [source]¶
- leave_select(node: rql.stmts.Select, state: STCheckState) None [source]¶
- visit_insert(insert: rql.stmts.Set | rql.stmts.Insert | rql.stmts.Delete | rql.stmts.Select, state: STCheckState) None [source]¶
- visit_select(node: rql.stmts.Select, state: STCheckState) None [source]¶
- visit_set(update: rql.stmts.Set | rql.stmts.Insert | rql.stmts.Delete | rql.stmts.Select, state: STCheckState) None [source]¶
- visit_union(node: rql.stmts.Union, state: STCheckState) None [source]¶
- class rql.stcheck.STCheckState[source]¶
Bases:
object
- add_var_info(var: rql.nodes.ColumnAlias | rql.nodes.Variable, vi: int) None [source]¶
- rql.stcheck.bloc_simplification(variable: rql.nodes.ColumnAlias | rql.nodes.Variable, term: rql.nodes.Relation) None [source]¶
rql.stmts module¶
Construction and manipulation of RQL syntax trees.
This module defines only first level nodes (i.e. statements). Child nodes are defined in the nodes module
- class rql.stmts.Delete[source]¶
-
the Delete node is the root of the syntax tree for deletion statement
- TYPE = 'delete'¶
- add_main_variable(etype: str, vref: rql.nodes.VariableRef) None [source]¶
add a variable to the list of deleted variables
- property children¶
- parent: 'BaseNode' | None¶
- property selection: List[rql.nodes.VariableRef]¶
- class rql.stmts.Insert[source]¶
-
the Insert node is the root of the syntax tree for insertion statement
- TYPE = 'insert'¶
- add_main_relation(relation: rql.nodes.Relation) None [source]¶
add a relation to the list of inserted relations
- add_main_variable(etype: str, vref: rql.nodes.VariableRef) None [source]¶
add a variable to the list of inserted variables
- property children¶
- parent: 'BaseNode' | None¶
- property selection¶
- class rql.stmts.ScopeNode[source]¶
Bases:
BaseNode
- copy(stmt: Statement | None = None, copy_solutions: bool = True, solutions: List[Dict[str, str]] = None) rql.base.BaseNode [source]¶
- get_etype(name: str) rql.nodes.Constant [source]¶
return the type object for the given entity’s type name
raise BadRQLQuery on unknown type
- get_variable(name: str) rql.nodes.Variable | rql.nodes.ColumnAlias [source]¶
get a variable instance from its name
the variable is created if it doesn’t exist yet
- make_variable() rql.nodes.Variable [source]¶
create a new variable with an unique name for this tree
- set_having(terms: Iterable[rql.base.Node]) None [source]¶
- set_possible_types(solutions: ~typing.List[~typing.Dict[str, str]], kwargs: object | ~typing.Dict[str, str] | None = <object object>, key: str = 'possibletypes') None [source]¶
- set_where(node: rql.base.Node) None [source]¶
- property should_register_op¶
- property undo_manager¶
- class rql.stmts.Select[source]¶
Bases:
Statement
,EditableMixIn
,ScopeNode
the select node is the base statement of the syntax tree for selection statement, always child of a UNION root.
- add_group_var(var: rql.nodes.Variable | rql.nodes.VariableRef, index: int | None = None)[source]¶
add var in ‘orderby’ constraints asc is a boolean indicating the group order (ascendent or descendent)
- add_selected(term: rql.nodes.Variable | rql.nodes.VariableRef, index: int | None = None) None [source]¶
override Select.add_selected to memoize modification when needed
- add_sort_term(term: rql.nodes.SortTerm, index: int | None = None) None [source]¶
- add_sort_var(var: rql.nodes.Variable, asc: bool | None = True) None [source]¶
add var in ‘orderby’ constraints asc is a boolean indicating the sort order (ascendent or descendent)
- add_subquery(node: rql.nodes.SubQuery, check: bool = True) None [source]¶
- append_selected(term: rql.nodes.Function | rql.nodes.MathExpression | rql.nodes.VariableRef | rql.nodes.Constant) None [source]¶
- as_string(kwargs: Dict | None = None, userepr: bool = False) str [source]¶
return the tree as an encoded rql string
- property children¶
- clean_solutions(solutions: List[Dict[str, str]] | None = None) None [source]¶
when a rqlst has been extracted from another, this method returns solutions which make sense for this sub syntax tree
- copy(stmt: Statement | None = None, copy_solutions: bool = True, solutions: List[Dict[str, str]] | None = None) Select [source]¶
- distinct: bool = False¶
- get_description(mainindex: int | None = None, tr: rql.nodes.TranslationFunction | None = None) List[str] [source]¶
return the list of types or relations (if not found) associated to selected variables. mainindex is an optional selection index which should be considered has ‘pivot’ entity.
- get_selected_variables() Iterator[rql.nodes.VariableRef] [source]¶
returns all selected variables, including those used in aggregate functions
- get_selection_solutions() Set[Tuple[str, ...]] [source]¶
return the set of variable names which take different type according to the solutions
- get_variable(name: str, colnum: int | None = None) rql.nodes.Variable | rql.nodes.ColumnAlias [source]¶
get a variable instance from its name
the variable is created if it doesn’t exist yet
- has_aggregat: bool = False¶
- limit: int | None = None¶
- offset: int = 0¶
- parent: 'BaseNode' | None = None¶
- remove(node: rql.nodes.SortTerm) Tuple[BaseNode, BaseNode | None, int | None] [source]¶
- remove_group_term(term: rql.base.BaseNode) None [source]¶
remove the group variable and the group node if necessary
- remove_group_var(term: rql.base.BaseNode) Callable ¶
- remove_selected(var: rql.nodes.Variable | rql.nodes.VariableRef) None [source]¶
deletes var from selection variable
- remove_sort_term(term: rql.nodes.SortTerm) None [source]¶
remove a sort term and the sort node if necessary
- remove_subquery(node: rql.nodes.SubQuery) None [source]¶
- replace(oldnode: rql.base.BaseNode, newnode: rql.base.BaseNode) Tuple[rql.base.BaseNode, rql.base.BaseNode, int | None] [source]¶
- property root¶
return the root node of the tree
- set_groupby(terms: List[rql.nodes.Function | rql.nodes.VariableRef]) None [source]¶
- set_orderby(terms: List[rql.nodes.SortTerm]) None [source]¶
- set_possible_types(solutions: ~typing.List[~typing.Dict[str, str]], kwargs: object | ~typing.Dict[str, str] | None = <object object>, key: str = 'possibletypes') None [source]¶
- set_statement_type(etype: str) None [source]¶
set the statement type for this selection this method must be called last (i.e. once selected variables has been added)
- set_with(terms: List[rql.nodes.SubQuery], check: bool = True) None [source]¶
- undefine_variable(var: rql.nodes.Variable) None [source]¶
undefine the given variable and remove all relations where it appears
- vargraph: Dict[Tuple[str, str] | str, List[str]] = {}¶
- class rql.stmts.Set[source]¶
-
the Set node is the root of the syntax tree for update statement
- TYPE = 'set'¶
- add_main_relation(relation: rql.nodes.Relation) None [source]¶
add a relation to the list of modified relations
- property children¶
- parent: 'BaseNode' | None¶
- property selection¶
- class rql.stmts.Statement[source]¶
Bases:
object
base class for statement nodes
- annotated: bool = False¶
- neged(traverse_scope: bool = False, _fromnode: rql.nodes.Or | None = None) rql.nodes.Not | None [source]¶
- ored(traverse_scope: bool = False, _fromnode: rql.nodes.And | None = None) rql.nodes.Or | None [source]¶
- property root¶
return the root node of the tree
- schema: rql.interfaces.ISchema | None = None¶
- property scope¶
- property stmt¶
- class rql.stmts.Union[source]¶
-
the select node is the root of the syntax tree for selection statement using UNION
- TYPE: str = 'select'¶
- copy(stmt: Statement | None = None, copy_children: bool = True) Union [source]¶
Create and return a copy of this node and its descendant.
stmt is the root node, which should be use to get new variables
- get_description(mainindex: int | None = None, tr: rql.nodes.TranslationFunction | None = None) List[List[str]] [source]¶
- mainindex:
selection index to consider as main column, useful to get smarter results
- tr:
optional translation function taking a string as argument and returning a string
- get_variable_indices() Set[int] [source]¶
return the set of selection indexes which take different types according to the solutions
- property limit¶
- locate_subquery(col: int, etype: str, kwargs: Dict | None = None) Any [source]¶
return a select node and associated selection index where root variable at column col is of type etype
- memorizing: int = 0¶
- property offset: int¶
- property root¶
return the root node of the tree
- property should_register_op¶
- subquery_selection_index(subselect: Any, col: int) int [source]¶
given a select sub-query and a column index in the root query, return the selection index for this column in the sub-query
- property undo_manager: rql.undo.SelectionManager¶
- undo_modification() undo_modification [source]¶
- undoing: bool = False¶
rql.undo module¶
Manages undos on RQL syntax trees.
- class rql.undo.AddGroupOperation(node: rql.nodes.ColumnAlias | rql.nodes.Variable | rql.nodes.VariableRef | rql.nodes.Relation | rql.nodes.SortTerm, stmt: rql.stmts.Statement | None = None)[source]¶
Bases:
NodeOperation
Defines how to undo ‘add group’.
- class rql.undo.AddNodeOperation(node: rql.nodes.ColumnAlias | rql.nodes.Variable | rql.nodes.VariableRef | rql.nodes.Relation | rql.nodes.SortTerm, stmt: rql.stmts.Statement | None = None)[source]¶
Bases:
NodeOperation
Defines how to undo add_node().
- class rql.undo.AddSortOperation(node: rql.nodes.ColumnAlias | rql.nodes.Variable | rql.nodes.VariableRef | rql.nodes.Relation | rql.nodes.SortTerm, stmt: rql.stmts.Statement | None = None)[source]¶
Bases:
NodeOperation
Defines how to undo ‘add sort’.
- class rql.undo.MakeVarOperation(node: rql.nodes.ColumnAlias | rql.nodes.Variable | rql.nodes.VariableRef | rql.nodes.Relation | rql.nodes.SortTerm, stmt: rql.stmts.Statement | None = None)[source]¶
Bases:
NodeOperation
Defines how to undo make_variable().
- class rql.undo.RemoveNodeOperation(node, parent, stmt, index)[source]¶
Bases:
NodeOperation
Defines how to undo remove_node().
- class rql.undo.ReplaceNodeOperation(old_node, new_node)[source]¶
Bases:
object
Defines how to undo ‘replace node’.
- class rql.undo.SelectVarOperation(node: rql.nodes.ColumnAlias | rql.nodes.Variable | rql.nodes.VariableRef | rql.nodes.Relation | rql.nodes.SortTerm, stmt: rql.stmts.Statement | None = None)[source]¶
Bases:
NodeOperation
Defines how to undo add_selected().
- class rql.undo.SelectionManager(selection: rql.stmts.ScopeNode | rql.stmts.Union)[source]¶
Bases:
object
Manage the operation stacks.
- add_operation(operation: NodeOperation | MakeVarOperation | UndefineVarOperation | SelectVarOperation | UnselectVarOperation | AddNodeOperation | ReplaceNodeOperation | RemoveNodeOperation | AddSortOperation | RemoveSortOperation | AddGroupOperation | RemoveGroupOperation | SetDistinctOperation | SetOffsetOperation | SetLimitOperation | SetOptionalOperation | SetHavingOperation | AppendSelectOperation | RemoveSelectOperation) None [source]¶
add an operation to the current ones
- class rql.undo.SetDistinctOperation(previous_value, node=None)[source]¶
Bases:
ChangeValueOperation
Defines how to undo ‘set_distinct’.
- class rql.undo.SetOptionalOperation(rel, previous_value)[source]¶
Bases:
ChangeValueOperation
Defines how to undo ‘set_limit’.
rql.utils module¶
Miscellaneous utilities for RQL.
- class rql.utils.RQLVisitorHandler[source]¶
Bases:
object
Handler providing a dummy implementation of all callbacks necessary to visit a RQL syntax tree.
- class rql.utils.VisitableMixIn[source]¶
Bases:
object
- accept(visitor: rql.stcheck.RQLSTChecker | rql.stcheck.RQLSTAnnotator, *args: rql.stcheck.STCheckState | None, **kwargs: Any | None) None [source]¶
- leave(visitor: rql.stcheck.RQLSTChecker | rql.stcheck.RQLSTAnnotator, *args: rql.stcheck.STCheckState | None, **kwargs: Any | None) None [source]¶
- rql.utils.common_parent(node1: BaseNode | None, node2: BaseNode | None) BaseNode [source]¶
return the first common parent between node1 and node2
- algorithm :
index node1’s parents
climb among node2’s parents until we find a common parent
- rql.utils.decompose_b26(index: int, table: str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') str [source]¶
Return a letter (base-26) decomposition of index.
- rql.utils.function_description(funcname: str) logilab.database.FunctionDescr [source]¶
Return the description (
FunctionDescr
) for a RQL function.
- rql.utils.iter_funcnode_variables(funcnode: rql.nodes.Function) Generator [source]¶
- rql.utils.rql_return_type(self, funcnode: rql.nodes.Function) str [source]¶
- class rql.utils.rqlvar_maker(stop: int | None = None, index: int = 0, defined: Mapping[str, Any] | None = None, aliases: Mapping[str, Any] | None = None)[source]¶
Bases:
object
Yields consistent RQL variable names.
- Parameters:
stop – optional argument to stop iteration after the Nth variable default is None which means ‘never stop’
defined – optional dict of already defined vars
- next() str ¶
- rql.utils.st_check_backend(self, backend: Any, funcnode: rql.nodes.Function) None [source]¶
- rql.utils.st_description(self, funcnode: rql.nodes.Function, mainindex: int | None, tr: Callable[[str], str]) str [source]¶
Module contents¶
RQL library (implementation independant).
- class rql.RQLHelper(schema: rql.interfaces.ISchema, uid_func_mapping: rql.analyze.UIDFuncMapping = None, special_relations: Dict[str, str] = {}, backend: Any | None = None)[source]¶
Bases:
object
Helper class for RQL handling
- give access to methods for :
parsing RQL strings
variables type resolving
comparison of two queries
- annotate(rqlst: rql.stmts.Statement) None [source]¶
- property backend: Any¶
- compute_all_solutions(rqlst, uid_func_mapping=None, kwargs=None, debug=False)[source]¶
compute syntax tree solutions with all types restriction (eg is/instance_of relations) ignored
- compute_solutions(rqlst: rql.stmts.AnyStatement, uid_func_mapping: rql.analyze.UIDFuncMapping = None, kwargs: Dict | None = None, debug: bool = False) Set [source]¶
Set solutions for variables of the syntax tree.
Each solution is a dictionary with variable’s name as key and variable’s type as value.
- parse(rqlstring: str, annotate: bool = True) rql.stmts.AnyStatement [source]¶
Return a syntax tree created from a RQL string.
- set_schema(schema: rql.interfaces.ISchema) None [source]¶
- simplify(rqlst: rql.stmts.Union) None [source]¶
Simplify rqlst by rewriting non-final variables associated to a const node (if annotator say we can…)
The tree is modified in-place.
- rql.copy_uid_node(select: rql.stmts.Select, node: rql.nodes.Constant, vconsts: List[rql.nodes.Constant]) rql.nodes.Constant [source]¶