def _bind_target(self, catalog: Catalog, source: CatSource): target_table_visitor = RangeVarVisitor() target_table_visitor(self._insert_table) logging.debug("Searching for: {}".format( target_table_visitor.search_string)) try: self._target_table = catalog.search_table( source_like=source.name, **target_table_visitor.search_string) except RuntimeError as error: logging.debug(str(error)) raise TableNotFound( '"{schema_like}"."{table_like}" is not found'.format( **target_table_visitor.search_string)) logging.debug("Bound target table: {}".format(self._target_table)) if len(self._insert_columns) == 0: self._target_columns = catalog.get_columns_for_table( self._target_table) logging.debug("Bound all columns in {}".format(self._target_table)) else: bound_cols = catalog.get_columns_for_table( self._target_table, column_names=self._insert_columns) # Handle error case if len(bound_cols) != len(self._insert_columns): for column in self._insert_columns: found = False for bound in bound_cols: if column == bound.name: found = True break if not found: raise ColumnNotFound( '"{}" not found in the following tables: {}'. format( column, json.dumps([self._target_table], cls=CatTableEncoder), )) self._target_columns = bound_cols logging.debug("Bound {} target columns".format(len(bound_cols)))
def bind(self, catalog: Catalog): target_table_visitor = RangeVarVisitor() target_table_visitor.visit(self._target_table) self.logger.debug( "Searching for: {}".format(target_table_visitor.search_string) ) self._target_table = catalog.search_table(**target_table_visitor.search_string) self.logger.debug("Bound target table: {}".format(self._target_table)) if len(self._target_columns) == 0: self._target_columns = catalog.get_columns_for_table(self._target_table) self.logger.debug("Bound all columns in {}".format(self._target_table)) else: bound_cols = catalog.get_columns_for_table( self._target_table, column_names=self._target_columns ) # Handle error case if len(bound_cols) != len(self._target_columns): for column in self._target_columns: found = False for bound in bound_cols: if column == bound.name: found = True break if not found: raise RuntimeError("'{}' column is not found".format(column)) self._target_columns = bound_cols self.logger.debug("Bound {} target columns".format(len(bound_cols))) alias_map = {} bound_tables = [] for table in self._source_tables: visitor = RangeVarVisitor() visitor.visit(table) if visitor.alias is not None: alias_map[visitor.alias] = visitor.search_string self.logger.debug("Searching for: {}".format(visitor.search_string)) candidate_table = catalog.search_table(**visitor.search_string) self.logger.debug("Bound source table: {}".format(candidate_table)) bound_tables.append(candidate_table) self._source_tables = bound_tables bound_cols = [] for column in self._source_columns: column_ref_visitor = ColumnRefVisitor() column_ref_visitor.visit(column) if column_ref_visitor.name[0] in alias_map: table_name = alias_map[column_ref_visitor.name[0]] else: table_name = {"table_like": column_ref_visitor.name[0]} self.logger.debug("Searching for: {}".format(table_name)) candidate_table = catalog.search_table(**table_name) bound = catalog.get_columns_for_table( table=candidate_table, column_names=[column_ref_visitor.name[1]] ) if len(bound) == 0: raise RuntimeError("{} not found in table".format(column)) elif len(bound) > 1: raise RuntimeError("Ambiguous column name. Multiple matches found") self.logger.debug("Bound source column: {}".format(bound[0])) bound_cols.append(bound[0]) self._source_columns = bound_cols