001package gudusoft.gsqlparser.ir.semantic.catalog; 002 003/** 004 * Slice 76 — minimal column descriptor inside a {@link Catalog}. 005 * 006 * <p>Slice 173 (join-analysis S12) extends it with optional, additive 007 * metadata — declared data type, nullability, and PRIMARY KEY / UNIQUE / 008 * indexed flags — that external callers <em>may</em> supply. The parser 009 * never fetches these; they are accepted and surfaced verbatim. The 010 * one-arg constructor and all prior behaviour are unchanged: a column 011 * built with just a name reports {@code null} type, {@code null} 012 * nullability (unknown), and {@code false} key/index flags. 013 * 014 * <p>Identifier semantics (case folding, quoted vs unquoted, vendor 015 * rules) are delegated to {@code TSQLEnv} via the analyzer's internal 016 * bridge — names are stored exactly as written by the caller. 017 * 018 * <p>This class is immutable and safe to share across threads. 019 */ 020public final class CatalogColumn { 021 022 private final String name; 023 private final String dataType; 024 private final Boolean nullable; 025 private final boolean primaryKey; 026 private final boolean unique; 027 private final boolean indexed; 028 029 /** 030 * @param name the column name as written by the caller; must be non-null 031 * and non-empty. 032 * @throws IllegalArgumentException when {@code name} is {@code null} or empty. 033 */ 034 public CatalogColumn(String name) { 035 this(name, null, null, false, false, false); 036 } 037 038 /** 039 * Full constructor (slice 173). All metadata is optional: 040 * {@code dataType} may be null, {@code nullable} may be null (unknown), 041 * and the key/index flags default to {@code false}. 042 */ 043 public CatalogColumn(String name, String dataType, Boolean nullable, 044 boolean primaryKey, boolean unique, boolean indexed) { 045 if (name == null) { 046 throw new IllegalArgumentException("column name must not be null"); 047 } 048 if (name.isEmpty()) { 049 throw new IllegalArgumentException("column name must not be empty"); 050 } 051 this.name = name; 052 this.dataType = dataType; 053 this.nullable = nullable; 054 this.primaryKey = primaryKey; 055 this.unique = unique; 056 this.indexed = indexed; 057 } 058 059 /** A fresh builder for a column with the given name. */ 060 public static Builder builder(String name) { 061 return new Builder(name); 062 } 063 064 public String getName() { 065 return name; 066 } 067 068 /** Declared data type, or {@code null} when not supplied. */ 069 public String getDataType() { 070 return dataType; 071 } 072 073 /** {@code TRUE}/{@code FALSE} when known, {@code null} when unknown. */ 074 public Boolean getNullable() { 075 return nullable; 076 } 077 078 public boolean isPrimaryKey() { 079 return primaryKey; 080 } 081 082 public boolean isUnique() { 083 return unique; 084 } 085 086 public boolean isIndexed() { 087 return indexed; 088 } 089 090 @Override 091 public String toString() { 092 return "CatalogColumn{name=" + name 093 + (dataType != null ? ", type=" + dataType : "") 094 + (nullable != null ? ", nullable=" + nullable : "") 095 + (primaryKey ? ", pk" : "") 096 + (unique ? ", unique" : "") 097 + (indexed ? ", indexed" : "") 098 + "}"; 099 } 100 101 /** Fluent builder for a {@link CatalogColumn} with optional metadata. */ 102 public static final class Builder { 103 private final String name; 104 private String dataType; 105 private Boolean nullable; 106 private boolean primaryKey; 107 private boolean unique; 108 private boolean indexed; 109 110 private Builder(String name) { 111 this.name = name; 112 } 113 114 public Builder dataType(String dataType) { 115 this.dataType = dataType; 116 return this; 117 } 118 119 public Builder nullable(Boolean nullable) { 120 this.nullable = nullable; 121 return this; 122 } 123 124 public Builder primaryKey(boolean primaryKey) { 125 this.primaryKey = primaryKey; 126 return this; 127 } 128 129 public Builder unique(boolean unique) { 130 this.unique = unique; 131 return this; 132 } 133 134 public Builder indexed(boolean indexed) { 135 this.indexed = indexed; 136 return this; 137 } 138 139 public CatalogColumn build() { 140 return new CatalogColumn(name, dataType, nullable, primaryKey, unique, indexed); 141 } 142 } 143}