(column *storepb.ColumnMetadata, tableName string, sequences []*storepb.SequenceMetadata)
| 3014 | } |
| 3015 | |
| 3016 | func isSerialColumn(column *storepb.ColumnMetadata, tableName string, sequences []*storepb.SequenceMetadata) (isSerial bool, serialType string) { |
| 3017 | // Serial columns must be NOT NULL |
| 3018 | if column.Nullable { |
| 3019 | return false, "" |
| 3020 | } |
| 3021 | |
| 3022 | // Serial columns must have a nextval() default |
| 3023 | if !strings.Contains(strings.ToLower(column.Default), "nextval(") { |
| 3024 | return false, "" |
| 3025 | } |
| 3026 | |
| 3027 | // Check type and map to serial type |
| 3028 | var expectedSerialType string |
| 3029 | switch strings.ToLower(column.Type) { |
| 3030 | case "integer": |
| 3031 | expectedSerialType = "serial" |
| 3032 | case "bigint": |
| 3033 | expectedSerialType = "bigserial" |
| 3034 | case "smallint": |
| 3035 | expectedSerialType = "smallserial" |
| 3036 | default: |
| 3037 | return false, "" |
| 3038 | } |
| 3039 | |
| 3040 | // IMPORTANT: Only treat as serial if the sequence is owned by this column |
| 3041 | // This prevents converting columns that use independent sequences to serial type |
| 3042 | sequenceName := extractSequenceNameFromNextval(column.Default) |
| 3043 | if sequenceName == "" { |
| 3044 | return false, "" |
| 3045 | } |
| 3046 | |
| 3047 | // Check if any sequence with this name is owned by this column |
| 3048 | for _, seq := range sequences { |
| 3049 | if seq.Name == sequenceName && seq.OwnerTable == tableName && seq.OwnerColumn == column.Name { |
| 3050 | return true, expectedSerialType |
| 3051 | } |
| 3052 | } |
| 3053 | |
| 3054 | // Sequence is not owned by this column, so don't convert to serial |
| 3055 | return false, "" |
| 3056 | } |
| 3057 | |
| 3058 | // writeColumnSDL writes a single column definition to the output writer |
| 3059 | // This function is extracted from writeCreateTableSDL to enable code reuse |
no test coverage detected