def testComplexSelect(self): query = ("(SELECT proc.parent.pid AS ppid, proc.pid FROM pslist(10) " "WHERE COUNT(proc.open_files) > 10) and True") expected = ast.Intersection( ast.Map( ast.Filter( ast.Apply(ast.Var("pslist"), ast.Literal(10)), ast.StrictOrderedSet( ast.Apply( ast.Var("COUNT"), ast.Resolve(ast.Var("proc"), ast.Literal("open_files"))), ast.Literal(10))), ast.Bind( ast.Pair( ast.Literal("ppid"), ast.Resolve( ast.Resolve(ast.Var("proc"), ast.Literal("parent")), ast.Literal("pid"))), ast.Pair(ast.Literal("pid"), ast.Resolve(ast.Var("proc"), ast.Literal("pid"))))), ast.Literal(True)) self.assertQueryMatches(query, expected)
def testSelectWhat(self): self.assertQueryMatches( "SELECT proc.parent.pid AS ppid," "proc.pid," "'foo'," "asdate(proc.starttime)," "proc.fd[5]" "FROM pslist()", ast.Map( ast.Apply(ast.Var("pslist")), ast.Bind( ast.Pair( ast.Literal("ppid"), ast.Resolve( ast.Resolve(ast.Var("proc"), ast.Literal("parent")), ast.Literal("pid"))), ast.Pair(ast.Literal("pid"), ast.Resolve(ast.Var("proc"), ast.Literal("pid"))), ast.Pair(ast.Literal("column_2"), ast.Literal("foo")), ast.Pair( ast.Literal("asdate"), ast.Apply( ast.Var("asdate"), ast.Resolve(ast.Var("proc"), ast.Literal("starttime")))), ast.Pair( ast.Literal("fd_5"), ast.Select( ast.Resolve(ast.Var("proc"), ast.Literal("fd")), ast.Literal(5))))))
def testFormatters(self): """Creating a query with raw AST should generate the source.""" q = query.Query( ast.Complement( ast.Equivalence(ast.Map(ast.Var("Process"), ast.Var("pid")), ast.Literal(10)))) self.assertEqual(q.source, "Process.pid != 10")
def select_what(self): # Each value we select is in form EXPRESSION [AS SYMBOL]. Values are # separated by commas. start = self.tokens.matched.start used_names = set() # Keeps track of named values to prevent duplicates. vars = [] for idx in itertools.count(): value_expression = self.expression() if self.tokens.accept(grammar.select_as): # If there's an AS then we have an explicit name for this value. self.tokens.expect(common_grammar.symbol) if self.tokens.matched.value in used_names: return self.error( "Duplicate 'AS' name %r." % self.tokens.matched.value) key_expression = ast.Literal(self.tokens.matched.value, start=self.tokens.matched.start, end=self.tokens.matched.end, source=self.original) # Record the value expression of the alias. self.aliases[-1][self.tokens.matched.value] = value_expression used_names.add(self.tokens.matched.value) else: # Try to guess the appropriate name of the column based on what # the expression is. name = self._guess_name_of(value_expression) if (not name or name in used_names or (self.scope and name in self.scope)): # Give up and just use the current idx for key. name = "column_%d" % (idx,) else: used_names.add(name) key_expression = ast.Literal(name) end = key_expression.end or value_expression.end vars.append(ast.Pair(key_expression, value_expression, start=value_expression.start, end=end, source=self.original)) if self.tokens.accept(grammar.select_from): # Make ast.Bind here. source_expression = self.select_from() return ast.Map( source_expression, ast.Bind(*vars, start=start, end=vars[-1].end, source=self.original), start=start, end=self.tokens.matched.end, source=self.original) self.tokens.expect(common_grammar.comma)
def testFullSelect(self): query = ("SELECT proc.parent.pid AS ppid_column, proc.pid" " FROM pslist(pid: 10, ppid: 20)" " WHERE count(proc.open_files) > 10" " ORDER BY proc.command DESC" " LIMIT 10 - 9 OFFSET add(5, 10)") expected = ast.Map( ast.Apply( ast.Var("take"), ast.Difference(ast.Literal(10), ast.Literal(9)), ast.Apply( ast.Var("drop"), ast.Apply(ast.Var("add"), ast.Literal(5), ast.Literal(10)), ast.Apply( ast.Var("reverse"), ast.Sort( ast.Filter( ast.Apply( ast.Var("pslist"), ast.Pair(ast.Var("pid"), ast.Literal(10)), ast.Pair(ast.Var("ppid"), ast.Literal(20))), ast.StrictOrderedSet( ast.Literal(10), ast.Apply( ast.Var("count"), ast.Resolve( ast.Var("proc"), ast.Literal("open_files"))), )), ast.Resolve(ast.Var("proc"), ast.Literal("command")))))), ast.Bind( ast.Pair( ast.Literal("ppid_column"), ast.Resolve( ast.Resolve(ast.Var("proc"), ast.Literal("parent")), ast.Literal("pid"))), ast.Pair(ast.Literal("pid"), ast.Resolve(ast.Var("proc"), ast.Literal("pid"))))) self.assertQueryMatches(query, expected)
def testBuiltins(self): self.assertQueryMatches( "filter(pslist(), proc.pid == 1)", ast.Filter( ast.Apply(ast.Var("pslist")), ast.Equivalence( ast.Resolve(ast.Var("proc"), ast.Literal("pid")), ast.Literal(1)))) self.assertQueryMatches( "map(pslist(), [proc.pid, proc['command']])", ast.Map( ast.Apply(ast.Var("pslist")), ast.Tuple(ast.Resolve(ast.Var("proc"), ast.Literal("pid")), ast.Select(ast.Var("proc"), ast.Literal("command"))))) self.assertQueryMatches( "bind(x: 1, y: 2)", ast.Bind(ast.Pair(ast.Var("x"), ast.Literal(1)), ast.Pair(ast.Var("y"), ast.Literal(2)))) self.assertQueryRaises("bind (x: 1, y: 2)")
def testExpression(self): query = ast.Map(ast.Var("x"), ast.Var("y")) expected = ("map", ("var", "x"), ("var", "y")) self.assertEqual(aslisp.aslisp(query), expected)