docs: @Override
      protected void parseColumnDefinition( DdlTokenStream tokens,
                                            AstNode tableNode,
                                            boolean isAlterTable ) throws ParsingException {
          // column-definition
          //
          // Simple-column-Name DataType
          // [ ColumnDefinition-level-constraint ]*
          // [ [ WITH ] DEFAULT { ConstantExpression | NULL } |generated-column-spec ]
          // [ ColumnDefinition-level-constraint ]*
  
          // generated-column-spec
          //
          // [ GENERATED { ALWAYS | BY DEFAULT } AS IDENTITY [ ( START WITH IntegerConstant [ ,INCREMENT BY IntegerConstant] ) ] ] ]
  
          // EXAMPLE COLUMNS
          // (i INT GENERATED BY DEFAULT AS IDENTITY (START WITH 2, INCREMENT BY 1),
          // ch CHAR(50));
  
          tokens.canConsume("COLUMN"); // FOR ALTER TABLE ADD [COLUMN] case
          String columnName = parseName(tokens);
          DataType datatype = getDatatypeParser().parse(tokens);
  
          AstNode columnNode = nodeFactory().node(columnName, tableNode, TYPE_COLUMN_DEFINITION);
  
          columnNode.setProperty(StandardDdlLexicon.DATATYPE_NAME, datatype.getName());
          if (datatype.getLength() >= 0) {
              columnNode.setProperty(StandardDdlLexicon.DATATYPE_LENGTH, datatype.getLength());
          }
          if (datatype.getPrecision() >= 0) {
              columnNode.setProperty(StandardDdlLexicon.DATATYPE_PRECISION, datatype.getPrecision());
          }
          if (datatype.getScale() >= 0) {
              columnNode.setProperty(StandardDdlLexicon.DATATYPE_SCALE, datatype.getScale());
          }
  
          // Now clauses and constraints can be defined in any order, so we need to keep parsing until we get to a comma
          // 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);
                  boolean parsedGeneratedColumn = parseGeneratedColumnSpecClause(tokens, columnNode);
                  if (!parsedCollate && !parsedConstraint && !parsedGeneratedColumn) {
                      // 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, getCurrentMarkedPosition(), msg);
              problem.setUnusedSource(unusedTokensSB.toString());
              addProblem(problem, tableNode);
          }
  
      }