parseColumnConstraint parses a single column constraint Returns (constraint, found, error)
()
| 132 | // parseColumnConstraint parses a single column constraint |
| 133 | // Returns (constraint, found, error) |
| 134 | func (p *Parser) parseColumnConstraint() (*ast.ColumnConstraint, bool, error) { |
| 135 | constraint := &ast.ColumnConstraint{} |
| 136 | |
| 137 | // PRIMARY KEY |
| 138 | if p.isType(models.TokenTypePrimary) { |
| 139 | p.advance() // Consume PRIMARY |
| 140 | if !p.isType(models.TokenTypeKey) { |
| 141 | return nil, false, p.expectedError("KEY after PRIMARY") |
| 142 | } |
| 143 | p.advance() // Consume KEY |
| 144 | constraint.Type = "PRIMARY KEY" |
| 145 | return constraint, true, nil |
| 146 | } |
| 147 | |
| 148 | // NOT NULL |
| 149 | if p.isType(models.TokenTypeNot) { |
| 150 | p.advance() // Consume NOT |
| 151 | if !p.isType(models.TokenTypeNull) { |
| 152 | return nil, false, p.expectedError("NULL after NOT") |
| 153 | } |
| 154 | p.advance() // Consume NULL |
| 155 | constraint.Type = "NOT NULL" |
| 156 | return constraint, true, nil |
| 157 | } |
| 158 | |
| 159 | // NULL (explicit nullable) |
| 160 | if p.isType(models.TokenTypeNull) { |
| 161 | p.advance() // Consume NULL |
| 162 | constraint.Type = "NULL" |
| 163 | return constraint, true, nil |
| 164 | } |
| 165 | |
| 166 | // UNIQUE |
| 167 | if p.isType(models.TokenTypeUnique) { |
| 168 | p.advance() // Consume UNIQUE |
| 169 | constraint.Type = "UNIQUE" |
| 170 | return constraint, true, nil |
| 171 | } |
| 172 | |
| 173 | // DEFAULT value |
| 174 | if p.isType(models.TokenTypeDefault) { |
| 175 | p.advance() // Consume DEFAULT |
| 176 | constraint.Type = "DEFAULT" |
| 177 | |
| 178 | // Parse default value - can be a literal, function call, or expression in parentheses |
| 179 | expr, err := p.parseExpression() |
| 180 | if err != nil { |
| 181 | return nil, false, err |
| 182 | } |
| 183 | constraint.Default = expr |
| 184 | return constraint, true, nil |
| 185 | } |
| 186 | |
| 187 | // CHECK (expression) |
| 188 | if p.isType(models.TokenTypeCheck) { |
| 189 | p.advance() // Consume CHECK |
| 190 | constraint.Type = "CHECK" |
| 191 |
no test coverage detected