From 8fbfd4c45c621fdcefc0dc1a225e7d36c8818bbc Mon Sep 17 00:00:00 2001 From: Ben Kurtovic Date: Sun, 18 May 2014 23:11:23 -0400 Subject: [PATCH] Fix _parse_node; _parse_term quote handling; should probably refactor. --- bitshift/database/__init__.py | 25 ++++++++++++------------- bitshift/query/__init__.py | 4 ++++ 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/bitshift/database/__init__.py b/bitshift/database/__init__.py index 4e5b8b8..51cf83d 100644 --- a/bitshift/database/__init__.py +++ b/bitshift/database/__init__.py @@ -55,45 +55,44 @@ class Database(object): def _explode_query_tree(self, tree): """Convert a query tree into components of an SQL SELECT statement.""" - def _parse_node(node): + def _parse_node(node, tables): if isinstance(node, Text): tables |= {"code", "symbols"} # (FTS: codelet_name, =: symbol_name, FTS: code_code) vs. node.text (_Literal) pass elif isinstance(node, Language): tables |= {"code"} - return "(code_lang = ?)", [node.lang] + return "(code_lang = ?)", tables, [node.lang] elif isinstance(node, Author): tables |= {"authors"} if isinstance(node.name, Regex): return "(author_name REGEXP ?)", [node.name.regex] cond = "(MATCH(author_name) AGAINST (? IN BOOLEAN MODE))" - return cond, [node.name.string] + return cond, tables, [node.name.string] elif isinstance(node, Date): column = {node.CREATE: "codelet_date_created", node.MODIFY: "codelet_date_modified"}[node.type] op = {node.BEFORE: "<=", node.AFTER: ">="}[node.relation] - return "(" + column + " " + op + " ?)", [node.date] + return "(" + column + " " + op + " ?)", tables, [node.date] elif isinstance(node, Symbol): tables |= {"symbols"} cond_base = "(symbol_type = ? AND symbol_name = ?)" if node.type != node.ALL: - return cond_base, [node.type, node.name] + return cond_base, tables, [node.type, node.name] cond = "(" + " OR ".join([cond_base] * len(node.TYPES)) + ")" args = zip(node.TYPES.keys(), [node.name] * len(node.TYPES)) - return cond, [arg for tup in args for arg in tup] + return cond, tables, [arg for tup in args for arg in tup] elif isinstance(node, BinaryOp): - left_cond, left_args = _parse_node(node.left) - right_cond, right_args = _parse_node(node.right) + left_cond, tbls, left_args = _parse_node(node.left, tables) + right_cond, tables, right_args = _parse_node(node.right, tbls) op = node.OPS[node.op] cond = "(" + left_cond + " " + op + " " + right_cond + ")" - return cond, left_args + right_args + return cond, tables, left_args + right_args elif isinstance(node, UnaryOp): - cond, args = _parse_node(node.node) - return "(" + node.OPS[node.op] + " " + cond + ")", args + cond, tables, args = _parse_node(node.node, tables) + return "(" + node.OPS[node.op] + " " + cond + ")", tables, args - tables = set() - conditional, arglist = _parse_node(tree.root) + conditional, tables, arglist = _parse_node(tree.root, set()) # joins = " ".join(tables) return conditional, joins, tuple(arglist) diff --git a/bitshift/query/__init__.py b/bitshift/query/__init__.py index 474f434..6e5d63b 100644 --- a/bitshift/query/__init__.py +++ b/bitshift/query/__init__.py @@ -116,6 +116,10 @@ class _QueryParser(object): def _parse_term(self, term): """Parse a query term into a tree node and return it.""" + try: + term = term.decode("unicode_escape") + except UnicodeDecodeError: + raise QueryParseException('Invalid query term: "%s"' % term) if ":" in term and not term[0] == ":": prefix, arg = term.split(":", 1) invert = prefix.lower() == "not"