Module: Pcrd::Sql

Defined in:
lib/pcrd/sql.rb

Overview

Centralized SQL identifier rendering. Every place that builds SQL (DDL, setup, apply, verify, validation) goes through here so quoting and schema qualification are consistent instead of three different conventions —some of which interpolated identifiers raw and broke on mixed-case, reserved-word, or non-public names.

Quoting follows PostgreSQL’s own quote_ident(): an identifier that is a safe lowercase word and not a reserved keyword is emitted bare (so normal DDL stays readable), otherwise it is double-quoted with internal quotes doubled. The reserved set is the common subset most likely to appear as a column or table name; anything not lowercase-simple is always quoted, so the only risk from an incomplete set is an unnecessary quote, never a broken statement.

Constant Summary collapse

SAFE_IDENT =
/\A[a-z_][a-z0-9_$]*\z/
RESERVED =
%w[
  all analyse analyze and any array as asc asymmetric authorization
  between binary both case cast check collate column constraint create
  cross current_catalog current_date current_role current_time
  current_timestamp current_user default deferrable desc distinct do else
  end except false fetch for foreign from grant group having ilike in
  initially inner intersect into is isnull join lateral leading left like
  limit localtime localtimestamp natural not notnull null offset on only or
  order outer overlaps placing primary references returning right select
  session_user similar some symmetric table tablesample then to trailing
  true union unique user using variadic verbose when where window with
].to_set.freeze

Class Method Summary collapse

Class Method Details

.quote_columns(names) ⇒ Object

Comma-joined list of quoted column identifiers.



51
52
53
# File 'lib/pcrd/sql.rb', line 51

def quote_columns(names)
  names.map { |n| quote_ident(n) }.join(", ")
end

.quote_ident(name) ⇒ Object

Quotes an identifier only when PostgreSQL would require it.



38
39
40
41
42
43
# File 'lib/pcrd/sql.rb', line 38

def quote_ident(name)
  str = name.to_s
  return str if str.match?(SAFE_IDENT) && !RESERVED.include?(str)

  %("#{str.gsub('"', '""')}")
end

.quote_table(name, schema: "public") ⇒ Object

Fully-qualified, quoted “schema.table”.



46
47
48
# File 'lib/pcrd/sql.rb', line 46

def quote_table(name, schema: "public")
  "#{quote_ident(schema)}.#{quote_ident(name)}"
end