Ejemplo n.º 1
0
 def select(self, name, columns, where):
   results = ResultsTable(name, columns)
   for row in self.rows:
     match = True
     if where:
       ctx = RqlContext()
       ctx.variables.update(row)
       match = ctx.evaluate(where.predicate)
     if match:
       results.insert([row[field] for field in columns])
   return results
Ejemplo n.º 2
0
  def Select(self, stmt):
    alias_map = {}
    alias_rmap = {}

    # Extract the tables to scan
    source_tables = set()
    tables = {}
    for source in stmt.get_data_sources():
      if source.query:
        name = source.alias or str(source.query)
        tables[name] = Select(source.query)
      else:
        name = source.name.name
        source_tables.add(name)
        tables[name] = self.tables[name]
        if source.alias:
          alias_map[source.alias] = name
          alias_rmap[name] = source.aliases

    # Map where-clauses result-fields to tables
    expr_fields = []
    table_results_map = defaultdict(list)
    for index, result in enumerate(stmt.results):
      if isinstance(result, SqlColumnWild):
        for source in source_tables:
          table_results_map[source].extend(alias_map.get(k, k) for k in self.tables[source].columns)
      elif isinstance(result, SqlTableWild):
        table_results_map[result.table].extend(alias_map.get(k, k) for k in self.tables[source].columns)
      elif isinstance(result.expr, RqlIdentifier):
        field_name = result.expr.name
        index = field_name.rfind('.')
        if index > 0:
          source = field_name[:index]
          field_name = field_name[1+index:]
          table_results_map[source].append(field_name)
        else:
          for source in source_tables:
            table = self.tables[source]
            if field_name in table.columns:
              table_results_map[source].append(field_name)
              break
        # TODO: Extract where clause for the field
      else:
        # TODO: Expr may contains references to a table
        expr_fields.append((index, result))

      if result.alias:
        name = str(result.expr)
        alias_map[result.alias] = name
        alias_rmap[name] = result.alias

    # Scan each source
    results = []
    for source, fields in table_results_map.iteritems():
      result = self.tables[source].select(source, fields, stmt.where)
      results.append(result)

    # Join and apply where-clauses
    if len(results) > 1:
      results = list(reversed(results))
      # TODO: Apply the proper join...
      while len(results) >= 2:
        res_a = results.pop()
        res_b = results.pop()
        join_result = cross_join(res_a, res_b)
        results.append(join_result)
    results = results[0]

    if expr_fields:
      for row in results.rows:
        new_values = []
        for index, field in expr_fields:
          ctx = RqlContext()
          ctx.variables.update(dict(zip(results.columns, row)))
          ctx.variables.update({alias_map.get(k, k): v for k, v in zip(results.columns, row)})
          value = ctx.evaluate(field.expr)
          new_values.append((index, value))
        for index, value in new_values:
          row.insert(index, value)

      for index, field in expr_fields:
        results.columns.insert(index, str(field.expr))

    # Replace column names with the alias
    # blah.. move up to the result_table.aliases
    results.columns = [alias_map.get(name, name) for name in results.columns]

    if stmt.group_by:
      key = stmt.group_by.groups[0].name
      results = group_by(results, key)

    if stmt.order_by:
      results.sort([(o.column, -1 if o.order_type == 'DESC' else 1) for o in stmt.order_by])

    return results
Ejemplo n.º 3
0
 def Insert(self, stmt):
   table = self.tables[stmt.destination.name]
   ctx = RqlContext()
   table.insert({name: ctx.evaluate(expr) for name, expr in zip(stmt.columns, stmt.values)})