Ejemplo n.º 1
0
def get_matching_entries(entries, options_map, query):
    query_text = 'SELECT * ' + query
    parser = query_parser.Parser()
    parsed_query = parser.parse(query_text)
    c_from = None
    if parsed_query.from_clause:
        c_from = query_compile.compile_from(parsed_query.from_clause, query_env.FilterEntriesEnvironment())
    c_where = None
    if parsed_query.where_clause:
        c_where = query_compile.compile_expression(parsed_query.where_clause, query_env.FilterPostingsEnvironment())

    # Figure out if we need to compute balance.
    balance = None
    if c_where and query_execute.uses_balance_column(c_where):
        balance = inventory.Inventory()

    context = query_execute.RowContext()
    context.balance = balance
    

    # Initialize some global properties for use by some of the accessors.
    context.options_map = options_map
    context.account_types = options.get_account_types(options_map)
    context.open_close_map = getters.get_account_open_close(entries)
    #context.commodity_map = getters.get_commodity_map(entries)
    context.price_map = prices.build_price_map(entries) 

    if c_from is not None:
        filtered_entries = query_execute.filter_entries(c_from, entries, options_map)
    else:
        filtered_entries = entries
    return filtered_entries
Ejemplo n.º 2
0
    def __init__(self, is_interactive, loadfun, outfile):
        super().__init__(is_interactive, query_parser.Parser(), outfile)

        self.loadfun = loadfun
        self.entries = None
        self.errors = None
        self.options_map = None

        self.env_targets = query_env.TargetsEnvironment()
        self.env_entries = query_env.FilterEntriesEnvironment()
        self.env_postings = query_env.FilterPostingsEnvironment()
Ejemplo n.º 3
0
    def __init__(self, is_interactive, loadfun, outfile,
                 default_format='text', do_numberify=False):
        super().__init__(is_interactive, query_parser.Parser(), outfile,
                         default_format, do_numberify)

        self.loadfun = loadfun
        self.entries = None
        self.errors = None
        self.options_map = None

        self.env_targets = query_env.TargetsEnvironment()
        self.env_entries = query_env.FilterEntriesEnvironment()
        self.env_postings = query_env.FilterPostingsEnvironment()
Ejemplo n.º 4
0
def run_query(entries, options_map, query, *format_args, numberify=False):
    """Compile and execute a query, return the result types and rows.

    Args:
      entries: A list of entries, as produced by the loader.
      options_map: A dict of options, as produced by the loader.
      query: A string, a single BQL query, optionally containing some new-style
        (e.g., {}) formatting specifications.
      format_args: A tuple of arguments to be formatted in the query. This is
        just provided as a convenience.
      numberify: If true, numberify the results before returning them.
    Returns:
      A pair of result types and result rows.
    Raises:
      ParseError: If the statement cannot be parsed.
      CompilationError: If the statement cannot be compiled.
    """
    env_targets = query_env.TargetsEnvironment()
    env_entries = query_env.FilterEntriesEnvironment()
    env_postings = query_env.FilterPostingsEnvironment()

    # Apply formatting to the query.
    formatted_query = query.format(*format_args)

    # Parse the statement.
    parser = query_parser.Parser()
    statement = parser.parse(formatted_query)

    # Compile the SELECT statement.
    c_query = query_compile.compile(statement, env_targets, env_postings,
                                    env_entries)

    # Execute it to obtain the result rows.
    rtypes, rrows = query_execute.execute_query(c_query, entries, options_map)

    # Numberify the results, if requested.
    if numberify:
        dformat = options_map['dcontext'].build()
        rtypes, rrows = numberify_lib.numberify_results(rtypes, rrows, dformat)

    return rtypes, rrows
Ejemplo n.º 5
0
    The lexer attribute only exists since PLY writes to it in case of a parser
    error.
    """
    __slots__ = ['type', 'value', 'lexer']

    def __init__(self, type_, value):
        self.type = type_
        self.value = value

    def __repr__(self):
        return 'Token({}, {})'.format(self.type, self.value)


QUERY_PARSER = query_parser.Parser()
ENV_ENTRIES = query_env.FilterEntriesEnvironment()


class FilterSyntaxLexer(object):
    """Lexer for Fava's filter syntax."""
    # pylint: disable=missing-docstring,invalid-name,no-self-use

    tokens = (
        'ANY',
        'KEY',
        'LINK',
        'STRING',
        'TAG',
    )

    RULES = (
Ejemplo n.º 6
0
class QueryBase(cmptest.TestCase):

    maxDiff = 8192

    # Default execution contexts.
    xcontext_entries = qe.FilterEntriesEnvironment()
    xcontext_targets = qe.TargetsEnvironment()
    xcontext_postings = qe.FilterPostingsEnvironment()

    def setUp(self):
        super().setUp()
        self.parser = query_parser.Parser()

    def parse(self, bql_string):
        """Parse a query.

        Args:
          bql_string: An SQL query to be parsed.
        Returns:
          A parsed statement (Select() node).
        """
        return self.parser.parse(bql_string.strip())

    def compile(self, bql_string):
        """Parse a query and compile it.

        Args:
          bql_string: An SQL query to be parsed.
        Returns:
          A compiled EvalQuery node.
        """
        return qc.compile_select(self.parse(bql_string), self.xcontext_targets,
                                 self.xcontext_postings, self.xcontext_entries)

    def check_query(self,
                    input_string,
                    bql_string,
                    expected_types,
                    expected_rows,
                    sort_rows=False,
                    debug=False):

        entries, _, options_map = loader.load_string(input_string)
        query = self.compile(bql_string)
        result_types, result_rows = qx.execute_query(query, entries,
                                                     options_map)

        if debug:
            with misc_utils.box('result_types'):
                print(result_types)
            with misc_utils.box('result_rows'):
                print(result_rows)
        self.assertEqual(expected_types, result_types)
        if sort_rows:
            result_rows.sort()
        self.assertEqual(expected_rows, result_rows)

    def check_sorted_query(self, input_string, bql_string, expected_types,
                           expected_rows):
        return self.check_query(input_string, bql_string, expected_types,
                                expected_rows, True)
Ejemplo n.º 7
0
class CompileSelectBase(unittest.TestCase):

    maxDiff = 8192

    # Default execution contexts.
    xcontext_entries = qe.FilterEntriesEnvironment()
    xcontext_targets = qe.TargetsEnvironment()
    xcontext_postings = qe.FilterPostingsEnvironment()

    def setUp(self):
        self.parser = qp.Parser()

    def parse(self, query):
        return self.parser.parse(query.strip())

    def compile(self, query):
        """Parse one query and compile it.

        Args:
          query: An SQL query to be parsed.
        Returns:
          The AST.
        """
        statement = self.parse(query)
        c_query = qc.compile(statement, self.xcontext_targets,
                             self.xcontext_postings, self.xcontext_entries)
        if isinstance(c_query, qp.Select):
            self.assertSelectInvariants(c_query)
        return c_query

    def assertSelectInvariants(self, query):
        """Assert the invariants on the query.

        Args:
          query: An instance of EvalQuery, a compiled query statement.
        Raises:
          AssertionError: if the check fails.
        """
        # Check that the group references cover all the simple indexes.
        if query.group_indexes is not None:
            non_aggregate_indexes = [
                index for index, c_target in enumerate(query.c_targets)
                if not qc.is_aggregate(c_target.c_expr)
            ]

            self.assertEqual(set(non_aggregate_indexes),
                             set(query.group_indexes),
                             "Invalid indexes: {}".format(query))

    def assertIndexes(self, query, expected_simple_indexes,
                      expected_aggregate_indexes, expected_group_indexes,
                      expected_order_indexes):
        """Check the four lists of indexes for comparison.

        Args:
          query: An instance of EvalQuery, a compiled query statement.
          expected_simple_indexes: The expected visible non-aggregate indexes.
          expected_aggregate_indexes: The expected visible aggregate indexes.
          expected_group_indexes: The expected group_indexes.
          expected_order_indexes: The expected order_indexes.
        Raises:
          AssertionError: if the check fails.
        """
        # Compute the list of _visible_ aggregates and non-aggregates.
        simple_indexes = [
            index for index, c_target in enumerate(query.c_targets)
            if c_target.name and not qc.is_aggregate(c_target.expression)
        ]
        aggregate_indexes = [
            index for index, c_target in enumerate(query.c_targets)
            if c_target.name and qc.is_aggregate(c_target.expression)
        ]

        self.assertEqual(set(expected_simple_indexes), set(simple_indexes))

        self.assertEqual(set(expected_aggregate_indexes),
                         set(aggregate_indexes))

        self.assertEqual(
            set(expected_group_indexes)
            if expected_group_indexes is not None else None,
            set(query.group_indexes)
            if query.group_indexes is not None else None)

        self.assertEqual(
            set(expected_order_indexes)
            if expected_order_indexes is not None else None,
            set(query.order_indexes)
            if query.order_indexes is not None else None)

    def assertCompile(self, expected, query, debug=False):
        """Assert parsed and compiled contents from 'query' is 'expected'.

        Args:
          expected: An expected AST to compare against the parsed value.
          query: An SQL query to be parsed.
          debug: A boolean, if true, print extra debugging information on the console.
        Raises:
          AssertionError: If the actual AST does not match the expected one.
        """
        actual = self.compile(query)
        if debug:
            print()
            print()
            print(actual)
            print()
        try:
            self.assertEqual(expected, actual)
            return actual
        except AssertionError:
            print()
            print("Expected: {}".format(expected))
            print("Actual  : {}".format(actual))
            raise
Ejemplo n.º 8
0
 def __init__(self):
     super().__init__()
     self.parser = query_parser.Parser()
     self.env_entries = query_env.FilterEntriesEnvironment()
     self.c_from = None