diff --git a/src/sql-parser/src/ast/defs/ddl.rs b/src/sql-parser/src/ast/defs/ddl.rs
index 7c28ab84419e6..edc742301d0cc 100644
--- a/src/sql-parser/src/ast/defs/ddl.rs
+++ b/src/sql-parser/src/ast/defs/ddl.rs
@@ -156,10 +156,7 @@ pub enum DocOnSchema {
 
 #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
 pub enum DocOnIdentifier<T: AstInfo> {
-    Column {
-        item_name: T::ItemName,
-        column_name: Ident,
-    },
+    Column(T::ColumnName),
     Type(T::ItemName),
 }
 
@@ -171,14 +168,9 @@ impl<T: AstInfo> AstDisplay for AvroDocOn<T> {
             DocOnSchema::All => {}
         }
         match &self.identifier {
-            DocOnIdentifier::Column {
-                item_name,
-                column_name,
-            } => {
+            DocOnIdentifier::Column(name) => {
                 f.write_str("DOC ON COLUMN ");
-                f.write_node(item_name);
-                f.write_str(".");
-                f.write_str(column_name);
+                f.write_node(name);
             }
             DocOnIdentifier::Type(name) => {
                 f.write_str("DOC ON TYPE ");
diff --git a/src/sql-parser/src/parser.rs b/src/sql-parser/src/parser.rs
index 0c4e280278bb6..51dcf473b76c0 100644
--- a/src/sql-parser/src/parser.rs
+++ b/src/sql-parser/src/parser.rs
@@ -2084,39 +2084,11 @@ impl<'a> Parser<'a> {
     fn parse_avro_doc_on_option_name(&mut self) -> Result<DocOnIdentifier<Raw>, ParserError> {
         match self.expect_one_of_keywords(&[TYPE, COLUMN])? {
             TYPE => Ok(DocOnIdentifier::Type(self.parse_raw_name()?)),
-            COLUMN => {
-                let (item_name, column_name) = self.parse_column_name()?;
-                Ok(DocOnIdentifier::Column {
-                    item_name,
-                    column_name,
-                })
-            }
+            COLUMN => Ok(DocOnIdentifier::Column(self.parse_column_name()?)),
             _ => unreachable!(),
         }
     }
 
-    fn parse_column_name(&mut self) -> Result<(RawItemName, Ident), ParserError> {
-        let start = self.peek_pos();
-        let mut item_name = self.parse_raw_name()?;
-        let column_name = match &mut item_name {
-            RawItemName::Name(UnresolvedItemName(identifiers)) => {
-                if identifiers.len() < 2 {
-                    return Err(ParserError::new(
-                        start,
-                        "need to specify an object and a column",
-                    ));
-                }
-                identifiers.pop().unwrap()
-            }
-            RawItemName::Id(_, _) => {
-                self.expect_token(&Token::Dot)?;
-                self.parse_identifier()?
-            }
-        };
-
-        Ok((item_name, column_name))
-    }
-
     fn parse_csr_connection_avro(&mut self) -> Result<CsrConnectionAvro<Raw>, ParserError> {
         let connection = self.parse_csr_connection_reference()?;
         let seed = if self.parse_keyword(SEED) {
diff --git a/src/sql/src/names.rs b/src/sql/src/names.rs
index 5a4838bd1cf32..9c00beafbe7e7 100644
--- a/src/sql/src/names.rs
+++ b/src/sql/src/names.rs
@@ -2303,6 +2303,12 @@ impl<'ast, 'a> VisitMut<'ast, Aug> for NameSimplifier<'a> {
         }
     }
 
+    fn visit_column_name_mut(&mut self, name: &mut ResolvedColumnName) {
+        if let ResolvedColumnName::Column { relation, .. } = name {
+            self.visit_item_name_mut(relation);
+        }
+    }
+
     fn visit_data_type_mut(&mut self, name: &mut ResolvedDataType) {
         if let ResolvedDataType::Named {
             id,
diff --git a/src/sql/src/plan/statement/ddl.rs b/src/sql/src/plan/statement/ddl.rs
index 505bd3097fd20..d2884056ad2c5 100644
--- a/src/sql/src/plan/statement/ddl.rs
+++ b/src/sql/src/plan/statement/ddl.rs
@@ -96,8 +96,8 @@ use crate::catalog::{
 use crate::kafka_util::{self, KafkaConfigOptionExtracted, KafkaStartOffsetType};
 use crate::names::{
     Aug, CommentObjectId, DatabaseId, ObjectId, PartialItemName, QualifiedItemName,
-    RawDatabaseSpecifier, ResolvedClusterName, ResolvedDataType, ResolvedDatabaseSpecifier,
-    ResolvedItemName, SchemaSpecifier, SystemObjectId,
+    RawDatabaseSpecifier, ResolvedClusterName, ResolvedColumnName, ResolvedDataType,
+    ResolvedDatabaseSpecifier, ResolvedItemName, SchemaSpecifier, SystemObjectId,
 };
 use crate::normalize::{self, ident};
 use crate::plan::error::PlanError;
@@ -2348,29 +2348,6 @@ fn update_avro_format_with_comments(
             })
             .collect::<BTreeSet<_>>();
 
-        // validate column names exist
-        for avro_doc_on in user_provided_comments.iter() {
-            match &avro_doc_on.identifier {
-                DocOnIdentifier::Column {
-                    item_name: ResolvedItemName::Item { id, full_name, .. },
-                    column_name,
-                } => {
-                    let item = scx.catalog.get_item(id);
-                    let column_name = normalize::column_name(column_name.clone());
-                    let desc = item.desc(&scx.catalog.resolve_full_name(item.name()))?;
-
-                    // Check to make sure mentioned column exists.
-                    let _ =
-                        desc.get_by_name(&column_name)
-                            .ok_or_else(|| PlanError::UnknownColumn {
-                                table: Some(full_name.clone().into()),
-                                column: column_name,
-                            })?;
-                }
-                _ => {}
-            }
-        }
-
         // Adding existing comments if not already provided by user
         for object_id in object_ids {
             let item = scx.catalog.get_item(&object_id);
@@ -2413,10 +2390,13 @@ fn update_avro_format_with_comments(
                             let comment = comments_map.get(&Some(pos + 1));
                             if let Some(comment_str) = comment {
                                 let doc_on_column_key = AvroDocOn {
-                                    identifier: DocOnIdentifier::Column {
-                                        item_name: full_resolved_name.clone(),
-                                        column_name: column_name.as_str().into(),
-                                    },
+                                    identifier: DocOnIdentifier::Column(
+                                        ResolvedColumnName::Column {
+                                            relation: full_resolved_name.clone(),
+                                            name: column_name.to_owned(),
+                                            index: pos,
+                                        },
+                                    ),
                                     for_schema: DocOnSchema::All,
                                 };
                                 if !user_provided_comments.contains(&doc_on_column_key) {
@@ -2511,12 +2491,13 @@ impl std::convert::TryFrom<Vec<CsrConfigOption<Aug>>> for CsrConfigOptionExtract
                     })?)
                     .map_err(better_error)?;
                     let key = match doc_on.identifier {
-                        DocOnIdentifier::Column {
-                            item_name: ResolvedItemName::Item { id, .. },
-                            column_name,
-                        } => DocTarget::Field {
+                        DocOnIdentifier::Column(ResolvedColumnName::Column {
+                            relation: ResolvedItemName::Item { id, .. },
+                            name,
+                            index: _,
+                        }) => DocTarget::Field {
                             object_id: id,
-                            column_name: column_name.to_string().into(),
+                            column_name: name,
                         },
                         DocOnIdentifier::Type(ResolvedItemName::Item { id, .. }) => {
                             DocTarget::Type(id)