Example #1
0
    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)))
Example #2
0
    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