def execute(self, soql, parameters=None, query_all=False): self._clean() parameters = parameters or [] sqltype = soql.split(None, 1)[0].upper() if sqltype == 'SELECT': self.execute_select(soql, parameters, query_all=query_all) else: # INSERT UPDATE DELETE EXPLAIN raise ProgrammingError("Unexpected command '{}'".format(sqltype))
def _from_sql(self, soql: str) -> None: """Create Force.com SOQL tree structure from SOQL""" # pylint:disable=too-many-branches,too-many-nested-blocks assert not self.soql, "Don't use _from_sql method directly" self.soql = soql soql, self.subqueries = split_subquery(soql) match_parse = re.match(r'SELECT (.*) FROM (\w+)\b(.*)$', soql, re.I) if not match_parse: raise ProgrammingError('Invalid SQL: %s' % self.soql) fields_sql, self.root_table, self.extra_soql = match_parse.groups() fields = [x.strip() for x in fields_sql.split(',')] self.is_aggregation = bool( pattern_groupby.search(self.extra_soql) or pattern_aggregation.search(fields[0])) self.is_plain_count = fields[0].upper() == 'COUNT()' consumed_subqueries = 0 expr_alias_counter = 0 # if not self.is_plain_count: out_field = '' # type: Union[str, QQuery] for field in fields: if self.is_aggregation: match = re.search(r'\b\w+$', field) if match: alias = match.group() assert alias not in RESERVED_WORDS, "invalid alias name" if match.start() > 0 and field[match.start() - 1] == ' ': out_field = field = field[match.start() - 1] else: alias = 'expr{}'.format(expr_alias_counter) expr_alias_counter += 1 assert '&' not in field, "Subquery not expected as field in aggregation query" elif '&' in field: assert field == '(&)' # verify that the subquery was in parentheses subquery = QQuery(self.subqueries[consumed_subqueries][0]) consumed_subqueries += 1 self.has_child_rel_field = True out_field = subquery # TODO more child relationships to the same table alias = nz(subquery.root_table) else: alias = out_field = field if '.' in alias: if alias.split( '.', 1)[0].lower() == self.root_table.lower(): alias = alias.split('.', 1)[1] if '.' in alias: # prepare paths for possible empty outer joins subroots = self.subroots root_crumbs = alias.lower().split('.')[:-1] for scrumb in root_crumbs: subroots.setdefault(scrumb, {}) subroots = subroots[scrumb] self.aliases.append(alias) self.fields.append(out_field)
def execute(self, soql: str, parameters: Optional[Iterable[Any]] = None, query_all: bool = False, tooling_api: bool = False) -> None: self._clean() parameters = parameters or [] sqltype = soql.split(None, 1)[0].upper() if sqltype == 'SELECT': self.execute_select(soql, parameters, query_all=query_all, tooling_api=tooling_api) elif sqltype == 'EXPLAIN': assert not tooling_api self.execute_explain(soql, parameters, query_all=query_all) else: # INSERT UPDATE DELETE EXPLAIN raise ProgrammingError("Unexpected command '{}'".format(sqltype))
def _check_data(self): if not self._iter: raise ProgrammingError( 'No previous .execute("select...") before .fetch...()')