class_docstr: Interface for openlineage-sql.
  
  :param dialect: dialect specific to the database
  :param default_schema: schema applied to each table with no schema parsed
class_docstr_tok: ["Interface","for","openlineage-sql",".",":","param","dialect",":","dialect","specific","to","the","database",":","param","default_schema",":","schema","applied","to","each","table","with","no","schema","parsed"]
docstr: Attaches column lineage facet to the list of datasets.
  
  Note that currently each dataset has the same column lineage information set.
  This would be a matter of change after OpenLineage SQL Parser improvements.
docstr_tok: ["Attaches","column","lineage","facet","to","the","list","of","datasets",".","Note","that","currently","each","dataset","has","the","same","column","lineage","information","set",".","This","would","be","a","matter","of","change","after","OpenLineage","SQL","Parser","improvements","."]
code: def attach_column_lineage(
      self,
      datasets: list[Dataset],
      database: str | None,
      parse_result: SqlMeta,
  ) -> None:
      """
      Attaches column lineage facet to the list of datasets.
  
      Note that currently each dataset has the same column lineage information set.
      This would be a matter of change after OpenLineage SQL Parser improvements.
      """
      if not len(parse_result.column_lineage):
          return
      for dataset in datasets:
          dataset.facets["columnLineage"] = ColumnLineageDatasetFacet(
              fields={
                  column_lineage.descendant.name: ColumnLineageDatasetFacetFieldsAdditional(
                      inputFields=[
                          ColumnLineageDatasetFacetFieldsAdditionalInputFields(
                              namespace=dataset.namespace,
                              name=".".join(
                                  filter(
                                      None,
                                      (
                                          column_meta.origin.database
                                          or database,
                                          column_meta.origin.schema
                                          or self.default_schema,
                                          column_meta.origin.name,
                                      ),
                                  )
                              )
                              if column_meta.origin
                              else "",
                              field=column_meta.name,
                          )
                          for column_meta in column_lineage.lineage
                      ],
                      transformationType="",
                      transformationDescription="",
                  )
                  for column_lineage in parse_result.column_lineage
              }
          )
  
imports: from __future__ import annotations
  from typing import TYPE_CHECKING, Callable
  import sqlparse
  from attrs import define
  from openlineage.client.facet import BaseFacet, ColumnLineageDatasetFacet, ColumnLineageDatasetFacetFieldsAdditional, ColumnLineageDatasetFacetFieldsAdditionalInputFields, ExtractionError, ExtractionErrorRunFacet, SqlJobFacet
  from openlineage.common.sql import DbTableMeta, SqlMeta, parse
  from airflow.providers.openlineage.extractors.base import OperatorLineage
  from airflow.providers.openlineage.utils.sql import TablesHierarchy, create_information_schema_query, get_table_schemas
  from airflow.typing_compat import TypedDict
label_desc: Use image node_id 4 for calling the SQLParser obj's underlying member method code with example usage: obj.attach_column_lineage(datasets, database, parse_result) without return types