docs: protected void parseColumnDefinition( DdlTokenStream tokens,
                                            AstNode tableNode,
                                            boolean isAlterTable ) throws ParsingException {
          assert tokens != null;
          assert tableNode != null;
  
          tokens.canConsume("COLUMN");
          String columnName = parseName(tokens);
          DataType datatype = getDatatypeParser().parse(tokens);
  
          AstNode columnNode = nodeFactory().node(columnName, tableNode, TYPE_COLUMN_DEFINITION);
  
          getDatatypeParser().setPropertiesOnNode(columnNode, datatype);
  
          // Now clauses and constraints can be defined in any order, so we need to keep parsing until we get to a comma
          StringBuilder unusedTokensSB = new StringBuilder();
  
          while (tokens.hasNext() && !tokens.matches(COMMA)) {
              boolean parsedDefaultClause = parseDefaultClause(tokens, columnNode);
              if (!parsedDefaultClause) {
                  boolean parsedCollate = parseCollateClause(tokens, columnNode);
                  boolean parsedConstraint = parseColumnConstraint(tokens, columnNode, isAlterTable);
                  if (!parsedCollate && !parsedConstraint) {
                      // THIS IS AN ERROR. NOTHING FOUND.
                      // NEED TO absorb tokens
                      unusedTokensSB.append(SPACE).append(tokens.consume());
                  }
              }
              tokens.canConsume(DdlTokenizer.COMMENT);
          }
  
          if (unusedTokensSB.length() > 0) {
              String msg = DdlSequencerI18n.unusedTokensParsingColumnDefinition.text(tableNode.getName());
              DdlParserProblem problem = new DdlParserProblem(Problems.WARNING, Position.EMPTY_CONTENT_POSITION, msg);
              problem.setUnusedSource(unusedTokensSB.toString());
              addProblem(problem, tableNode);
          }
      }