MCPcopy
hub / github.com/sqldef/sqldef / normalizeCheckExpr

Function normalizeCheckExpr

schema/normalize.go:269–580  ·  view source on GitHub ↗

normalizeCheckExpr normalizes a CHECK constraint expression AST for comparison mode parameter controls PostgreSQL-specific normalization (IN to ANY conversion)

(expr parser.Expr, mode GeneratorMode)

Source from the content-addressed store, hash-verified

267// normalizeCheckExpr normalizes a CHECK constraint expression AST for comparison
268// mode parameter controls PostgreSQL-specific normalization (IN to ANY conversion)
269func normalizeCheckExpr(expr parser.Expr, mode GeneratorMode) parser.Expr {
270 if expr == nil {
271 return nil
272 }
273
274 switch e := expr.(type) {
275 case *parser.IntervalExpr:
276 if mode == GeneratorModePostgres {
277 return normalizeExpr(e, mode)
278 }
279 return expr
280 case *parser.CastExpr:
281 // Numeric/money/interval casts fold to a value-independent form, so reuse the
282 // value-context path; otherwise CHECK keeps its own cast simplification below.
283 if mode == GeneratorModePostgres && e.Type != nil && isFoldableValueCastTypeName(strings.ToLower(e.Type.Type)) {
284 return normalizeExpr(e, mode)
285 }
286 // Remove certain casts that PostgreSQL simplifies
287 // - text, character varying: Always removed
288 // - date, timestamp without time zone: Removed when cast from string literals
289 // - time, time without time zone: Kept but normalized (PostgreSQL preserves these for precision)
290 if e.Type != nil {
291 typeStr := strings.ToLower(e.Type.Type)
292
293 // Always remove text casts
294 if typeStr == "text" || typeStr == "character varying" {
295 return normalizeCheckExpr(e.Expr, mode)
296 }
297
298 normalizedTypeStr := normalizeTypeName(typeStr, mode)
299
300 // Remove date/timestamp casts from string literals
301 // PostgreSQL simplifies '2020-01-01'::date to '2020-01-01' in CHECK constraints
302 if normalizedTypeStr == "date" || normalizedTypeStr == "timestamp" {
303 return normalizeCheckExpr(e.Expr, mode)
304 }
305
306 // Remove redundant array typecasts on ARRAY constructors
307 // PostgreSQL normalizes ARRAY['a'::varchar]::text[] to ARRAY['a'::varchar::text]
308 // by pushing down the array typecast to each element. Since we strip ::text casts
309 // on elements, we also need to strip ::text[] on the ARRAY constructor itself.
310 // e.g., ARRAY['a'::varchar]::text[] -> ARRAY['a'::varchar] (after stripping ::text[])
311 // ARRAY['a'::varchar::text] -> ARRAY['a'::varchar] (after stripping ::text on element)
312 // Empty arrays (ARRAY[]) need the typecast or PostgreSQL can't determine the type.
313 normalizedExpr := normalizeCheckExpr(e.Expr, mode)
314 if arrayConstructor, isArrayConstructor := normalizedExpr.(*parser.ArrayConstructor); isArrayConstructor {
315 if strings.HasSuffix(typeStr, "[]") && len(arrayConstructor.Elements) > 0 {
316 // Non-empty array with array typecast: strip the redundant typecast
317 return normalizedExpr
318 }
319 }
320
321 // For time types, keep the cast but use normalized type name
322 return &parser.CastExpr{
323 Expr: normalizedExpr,
324 Type: &parser.ConvertType{Type: normalizedTypeStr},
325 }
326 }

Calls 13

TransformSliceFunction · 0.92
ValTupleTypeAlias · 0.92
NewIdentFunction · 0.92
normalizeExprFunction · 0.85
normalizeTypeNameFunction · 0.85
unwrapOutermostParenExprFunction · 0.85
tryConvertOrChainToInFunction · 0.85
normalizeOperatorFunction · 0.85
sortAndDeduplicateValuesFunction · 0.85
NewNormalizedIdentFunction · 0.85