{"version":3,"file":"pg-identifier.mjs","names":[],"sources":["../../src/sql/pg-identifier.ts"],"sourcesContent":["/**\n * Represents an identifier in postgres that is subject\n * to quoting rules. The {@link toString} rule behaves\n * exactly like calling `select quote_ident($1)` in postgres\n */\nexport class PgIdentifier {\n  private constructor(\n    private readonly value: string,\n    private readonly quoted: boolean,\n  ) {}\n\n  /**\n   * Constructs an identifier from a single part (column or table name).\n   * When quoting identifiers like `select table.col` use {@link fromParts} instead\n   */\n  static fromString(identifier: string): PgIdentifier {\n    const identifierRegex = /^[a-z_][a-z0-9_]*$/;\n    const match = identifier.match(/^\"(.+)\"$/);\n    if (match) {\n      const value = match[1];\n      const quoted =\n        !identifierRegex.test(value) ||\n        this.reservedKeywords.has(value.toLowerCase());\n      return new PgIdentifier(value, quoted);\n    }\n    const quoted =\n      !identifierRegex.test(identifier) ||\n      this.reservedKeywords.has(identifier.toLowerCase());\n    return new PgIdentifier(identifier, quoted);\n  }\n\n  /**\n   * Quotes parts of an identifier like `select schema.table.col`.\n   * A separate function is necessary because postgres will treat\n   * `select \"HELLO.WORLD\"` as a column name. It has to be like\n   * `select \"HELLO\".\"WORLD\"` instead.\n   */\n  static fromParts(...identifiers: (string | PgIdentifier)[]): PgIdentifier {\n    return new PgIdentifier(\n      identifiers\n        .map((identifier) => {\n          if (typeof identifier === \"string\") {\n            return PgIdentifier.fromString(identifier);\n          } else {\n            return identifier;\n          }\n        })\n        .join(\".\"),\n      false,\n    );\n  }\n\n  toString(): string {\n    if (this.quoted) {\n      return `\"${this.value.replace(/\"/g, '\"\"')}\"`;\n    }\n    return this.value;\n  }\n\n  toJSON(): string {\n    return this.toString();\n  }\n\n  // Every keyword that's not explicitly marked as\n  // unreserved in src/include/parser/kwlist.h\n  private static readonly reservedKeywords = new Set([\n    \"all\",\n    \"analyse\",\n    \"analyze\",\n    \"and\",\n    \"any\",\n    \"array\",\n    \"as\",\n    \"asc\",\n    \"asymmetric\",\n    \"authorization\",\n    \"between\",\n    \"bigint\",\n    \"binary\",\n    \"bit\",\n    \"boolean\",\n    \"both\",\n    \"case\",\n    \"cast\",\n    \"char\",\n    \"character\",\n    \"check\",\n    \"coalesce\",\n    \"collate\",\n    \"collation\",\n    \"column\",\n    \"concurrently\",\n    \"constraint\",\n    \"create\",\n    \"cross\",\n    \"current_catalog\",\n    \"current_date\",\n    \"current_role\",\n    \"current_schema\",\n    \"current_time\",\n    \"current_timestamp\",\n    \"current_user\",\n    \"dec\",\n    \"decimal\",\n    \"default\",\n    \"deferrable\",\n    \"desc\",\n    \"distinct\",\n    \"do\",\n    \"else\",\n    \"end\",\n    \"except\",\n    \"exists\",\n    \"extract\",\n    \"false\",\n    \"fetch\",\n    \"float\",\n    \"for\",\n    \"foreign\",\n    \"freeze\",\n    \"from\",\n    \"full\",\n    \"grant\",\n    \"greatest\",\n    \"group\",\n    \"grouping\",\n    \"having\",\n    \"ilike\",\n    \"in\",\n    \"initially\",\n    \"inner\",\n    \"inout\",\n    \"int\",\n    \"integer\",\n    \"intersect\",\n    \"interval\",\n    \"into\",\n    \"is\",\n    \"isnull\",\n    \"join\",\n    \"json\",\n    \"json_array\",\n    \"json_arrayagg\",\n    \"json_exists\",\n    \"json_object\",\n    \"json_objectagg\",\n    \"json_query\",\n    \"json_scalar\",\n    \"json_serialize\",\n    \"json_table\",\n    \"json_value\",\n    \"lateral\",\n    \"leading\",\n    \"least\",\n    \"left\",\n    \"like\",\n    \"limit\",\n    \"localtime\",\n    \"localtimestamp\",\n    \"merge_action\",\n    \"national\",\n    \"natural\",\n    \"nchar\",\n    \"none\",\n    \"normalize\",\n    \"not\",\n    \"notnull\",\n    \"null\",\n    \"nullif\",\n    \"numeric\",\n    \"offset\",\n    \"on\",\n    \"only\",\n    \"or\",\n    \"order\",\n    \"out\",\n    \"outer\",\n    \"overlaps\",\n    \"overlay\",\n    \"placing\",\n    \"position\",\n    \"precision\",\n    \"primary\",\n    \"real\",\n    \"references\",\n    \"returning\",\n    \"right\",\n    \"row\",\n    \"select\",\n    \"session_user\",\n    \"setof\",\n    \"similar\",\n    \"smallint\",\n    \"some\",\n    \"substring\",\n    \"symmetric\",\n    \"system_user\",\n    \"table\",\n    \"tablesample\",\n    \"then\",\n    \"time\",\n    \"timestamp\",\n    \"to\",\n    \"trailing\",\n    \"treat\",\n    \"trim\",\n    \"true\",\n    \"union\",\n    \"unique\",\n    \"user\",\n    \"using\",\n    \"values\",\n    \"varchar\",\n    \"variadic\",\n    \"verbose\",\n    \"when\",\n    \"where\",\n    \"window\",\n    \"with\",\n    \"xmlattributes\",\n    \"xmlconcat\",\n    \"xmlelement\",\n    \"xmlexists\",\n    \"xmlforest\",\n    \"xmlnamespaces\",\n    \"xmlparse\",\n    \"xmlpi\",\n    \"xmlroot\",\n    \"xmlserialize\",\n    \"xmltable\",\n  ]);\n}\n"],"mappings":";;;;;;;;AAKA,IAAa,eAAb,MAAa,aAAa;CACxB,YACE,OACA,QACA;AAFiB,OAAA,QAAA;AACA,OAAA,SAAA;;;;;;CAOnB,OAAO,WAAW,YAAkC;EAClD,MAAM,kBAAkB;EACxB,MAAM,QAAQ,WAAW,MAAM,WAAW;AAC1C,MAAI,OAAO;GACT,MAAM,QAAQ,MAAM;AAIpB,UAAO,IAAI,aAAa,OAFtB,CAAC,gBAAgB,KAAK,MAAM,IAC5B,KAAK,iBAAiB,IAAI,MAAM,aAAa,CAAC,CACV;;AAKxC,SAAO,IAAI,aAAa,YAFtB,CAAC,gBAAgB,KAAK,WAAW,IACjC,KAAK,iBAAiB,IAAI,WAAW,aAAa,CAAC,CACV;;;;;;;;CAS7C,OAAO,UAAU,GAAG,aAAsD;AACxE,SAAO,IAAI,aACT,YACG,KAAK,eAAe;AACnB,OAAI,OAAO,eAAe,SACxB,QAAO,aAAa,WAAW,WAAW;OAE1C,QAAO;IAET,CACD,KAAK,IAAI,EACZ,MACD;;CAGH,WAAmB;AACjB,MAAI,KAAK,OACP,QAAO,IAAI,KAAK,MAAM,QAAQ,MAAM,OAAK,CAAC;AAE5C,SAAO,KAAK;;CAGd,SAAiB;AACf,SAAO,KAAK,UAAU;;;8BAKA,oBAAmB,IAAI,IAAI;CACjD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD,CAAC,CAAC"}