jsonb.go 53 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835
  1. package executor
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "math/big"
  8. "sort"
  9. "strconv"
  10. "strings"
  11. "unicode/utf8"
  12. "github.com/danfragoso/pizzasql-next/pkg/lexer"
  13. "github.com/danfragoso/pizzasql-next/pkg/parser"
  14. "github.com/danfragoso/pizzasql-next/pkg/pgerror"
  15. "github.com/danfragoso/pizzasql-next/pkg/storage"
  16. )
  17. // JSONB values are carried as canonical JSON text: object keys sorted, duplicate
  18. // keys collapsed last-wins, no insignificant whitespace, and numbers written as
  19. // exact normalized decimals. The canonical form is idempotent and is what every
  20. // write path stores, so a reload returns the same bytes and equality can be
  21. // defined on them.
  22. //
  23. // A JSONB column is distinguished from JSON/TEXT by its declared type. The
  24. // executor resolves that type from the statement's column-type scopes (the same
  25. // mechanism arrays use), so operators and functions know whether a text value is
  26. // a jsonb document or ordinary SQL text.
  27. // maxJSONBNumberDigits bounds the decimal expansion of a jsonb number. It
  28. // matches PostgreSQL's numeric digit limit and keeps a short exponent such as
  29. // 1e1000000 from allocating an enormous canonical string.
  30. const maxJSONBNumberDigits = 131072
  31. // CanonicalizeJSONB validates JSON text and returns its canonical JSONB form.
  32. // It is exported so the protocol layer can canonicalize a text-format jsonb
  33. // parameter at Bind time.
  34. func CanonicalizeJSONB(text string) (string, error) {
  35. node, err := decodeJSONB(text)
  36. if err != nil {
  37. return "", invalidJSONBInput(text)
  38. }
  39. canonical, err := encodeJSONB(node, false)
  40. if err != nil {
  41. return "", invalidJSONBInput(text)
  42. }
  43. return canonical, nil
  44. }
  45. func invalidJSONBInput(text string) error {
  46. return pgerror.InvalidText("invalid input syntax for type jsonb: %q", text)
  47. }
  48. // decodeJSONB parses one JSON document strictly. Duplicate object keys collapse
  49. // last-wins (encoding/json's map decoding), invalid UTF-8 and trailing content
  50. // are rejected, and numbers stay exact as json.Number.
  51. func decodeJSONB(text string) (interface{}, error) {
  52. if !utf8.ValidString(text) {
  53. return nil, invalidJSONBInput(text)
  54. }
  55. if err := validateJSONBUnicodeEscapes(text); err != nil {
  56. return nil, err
  57. }
  58. dec := json.NewDecoder(strings.NewReader(text))
  59. dec.UseNumber()
  60. var node interface{}
  61. if err := dec.Decode(&node); err != nil {
  62. return nil, invalidJSONBInput(text)
  63. }
  64. var trailing interface{}
  65. if err := dec.Decode(&trailing); err != io.EOF {
  66. return nil, invalidJSONBInput(text)
  67. }
  68. return node, nil
  69. }
  70. // validateJSONBUnicodeEscapes rejects escapes that encoding/json would accept
  71. // by rewriting them: U+0000 and unpaired UTF-16 surrogates. PostgreSQL rejects
  72. // both in jsonb input with 22P02 instead of silently producing U+FFFD.
  73. func validateJSONBUnicodeEscapes(text string) error {
  74. inString := false
  75. for i := 0; i < len(text); i++ {
  76. c := text[i]
  77. if !inString {
  78. if c == '"' {
  79. inString = true
  80. }
  81. continue
  82. }
  83. if c == '"' {
  84. inString = false
  85. continue
  86. }
  87. if c != '\\' {
  88. continue
  89. }
  90. if i+1 >= len(text) {
  91. return invalidJSONBInput(text)
  92. }
  93. i++
  94. if text[i] != 'u' {
  95. continue
  96. }
  97. if i+4 >= len(text) {
  98. return invalidJSONBInput(text)
  99. }
  100. value, ok := parseJSONBHex4(text[i+1 : i+5])
  101. if !ok {
  102. return invalidJSONBInput(text)
  103. }
  104. i += 4
  105. switch {
  106. case value == 0:
  107. return invalidJSONBInput(text)
  108. case value >= 0xD800 && value <= 0xDBFF:
  109. // A high surrogate must be followed by a low surrogate escape.
  110. if i+7 > len(text) || text[i+1] != '\\' || text[i+2] != 'u' {
  111. return invalidJSONBInput(text)
  112. }
  113. low, ok := parseJSONBHex4(text[i+3 : i+7])
  114. if !ok || low < 0xDC00 || low > 0xDFFF {
  115. return invalidJSONBInput(text)
  116. }
  117. i += 6
  118. case value >= 0xDC00 && value <= 0xDFFF:
  119. return invalidJSONBInput(text)
  120. }
  121. }
  122. return nil
  123. }
  124. func parseJSONBHex4(text string) (uint32, bool) {
  125. var value uint32
  126. for i := 0; i < 4; i++ {
  127. digit := text[i]
  128. var nibble uint32
  129. switch {
  130. case digit >= '0' && digit <= '9':
  131. nibble = uint32(digit - '0')
  132. case digit >= 'a' && digit <= 'f':
  133. nibble = uint32(digit-'a') + 10
  134. case digit >= 'A' && digit <= 'F':
  135. nibble = uint32(digit-'A') + 10
  136. default:
  137. return 0, false
  138. }
  139. value = value<<4 | nibble
  140. }
  141. return value, true
  142. }
  143. // encodeJSONB writes a decoded JSON tree in canonical form. pretty selects the
  144. // four-space indented jsonb_pretty rendering.
  145. func encodeJSONB(node interface{}, pretty bool) (string, error) {
  146. var buf bytes.Buffer
  147. if err := writeJSONBNode(&buf, node, pretty, 0); err != nil {
  148. return "", err
  149. }
  150. return buf.String(), nil
  151. }
  152. func writeJSONBNode(buf *bytes.Buffer, node interface{}, pretty bool, depth int) error {
  153. switch value := node.(type) {
  154. case nil:
  155. buf.WriteString("null")
  156. case bool:
  157. if value {
  158. buf.WriteString("true")
  159. } else {
  160. buf.WriteString("false")
  161. }
  162. case json.Number:
  163. text, err := canonicalJSONBNumber(value)
  164. if err != nil {
  165. return err
  166. }
  167. buf.WriteString(text)
  168. case string:
  169. writeJSONBString(buf, value)
  170. case []interface{}:
  171. if len(value) == 0 {
  172. buf.WriteString("[]")
  173. return nil
  174. }
  175. buf.WriteByte('[')
  176. for i, element := range value {
  177. if i > 0 {
  178. buf.WriteByte(',')
  179. }
  180. if pretty {
  181. buf.WriteByte('\n')
  182. writeJSONBIndent(buf, depth+1)
  183. }
  184. if err := writeJSONBNode(buf, element, pretty, depth+1); err != nil {
  185. return err
  186. }
  187. }
  188. if pretty {
  189. buf.WriteByte('\n')
  190. writeJSONBIndent(buf, depth)
  191. }
  192. buf.WriteByte(']')
  193. case map[string]interface{}:
  194. if len(value) == 0 {
  195. buf.WriteString("{}")
  196. return nil
  197. }
  198. keys := make([]string, 0, len(value))
  199. for key := range value {
  200. keys = append(keys, key)
  201. }
  202. sort.Strings(keys)
  203. buf.WriteByte('{')
  204. for i, key := range keys {
  205. if i > 0 {
  206. buf.WriteByte(',')
  207. }
  208. if pretty {
  209. buf.WriteByte('\n')
  210. writeJSONBIndent(buf, depth+1)
  211. }
  212. writeJSONBString(buf, key)
  213. buf.WriteByte(':')
  214. if pretty {
  215. buf.WriteByte(' ')
  216. }
  217. if err := writeJSONBNode(buf, value[key], pretty, depth+1); err != nil {
  218. return err
  219. }
  220. }
  221. if pretty {
  222. buf.WriteByte('\n')
  223. writeJSONBIndent(buf, depth)
  224. }
  225. buf.WriteByte('}')
  226. default:
  227. return pgerror.InvalidParameter("unsupported jsonb node type %T", node)
  228. }
  229. return nil
  230. }
  231. func writeJSONBIndent(buf *bytes.Buffer, depth int) {
  232. for i := 0; i < depth; i++ {
  233. buf.WriteString(" ")
  234. }
  235. }
  236. // writeJSONBString writes a JSON string literal without HTML escaping and
  237. // without rewriting valid UTF-8. Control characters use the short escapes JSON
  238. // defines, or \u00XX for the rest.
  239. func writeJSONBString(buf *bytes.Buffer, value string) {
  240. buf.WriteByte('"')
  241. for _, r := range value {
  242. switch r {
  243. case '"':
  244. buf.WriteString(`\"`)
  245. case '\\':
  246. buf.WriteString(`\\`)
  247. case '\n':
  248. buf.WriteString(`\n`)
  249. case '\r':
  250. buf.WriteString(`\r`)
  251. case '\t':
  252. buf.WriteString(`\t`)
  253. case '\b':
  254. buf.WriteString(`\b`)
  255. case '\f':
  256. buf.WriteString(`\f`)
  257. default:
  258. if r < 0x20 {
  259. const hex = "0123456789abcdef"
  260. buf.WriteString(`\u00`)
  261. buf.WriteByte(hex[byte(r)>>4])
  262. buf.WriteByte(hex[byte(r)&0x0f])
  263. continue
  264. }
  265. buf.WriteRune(r)
  266. }
  267. }
  268. buf.WriteByte('"')
  269. }
  270. // canonicalJSONBNumber normalizes a JSON number to an exact decimal spelling:
  271. // no exponent, no trailing fractional zeros, and no negative zero. The input is
  272. // a finite decimal, so the exact expansion always terminates.
  273. func canonicalJSONBNumber(number json.Number) (string, error) {
  274. text := string(number)
  275. negative := false
  276. i := 0
  277. if i < len(text) && text[i] == '-' {
  278. negative = true
  279. i++
  280. }
  281. start := i
  282. for i < len(text) && text[i] >= '0' && text[i] <= '9' {
  283. i++
  284. }
  285. digits := text[start:i]
  286. if digits == "" {
  287. return "", invalidJSONBInput(text)
  288. }
  289. fraction := ""
  290. if i < len(text) && text[i] == '.' {
  291. i++
  292. fractionStart := i
  293. for i < len(text) && text[i] >= '0' && text[i] <= '9' {
  294. i++
  295. }
  296. fraction = text[fractionStart:i]
  297. }
  298. exponent := 0
  299. if i < len(text) && (text[i] == 'e' || text[i] == 'E') {
  300. i++
  301. parsed, err := strconv.Atoi(text[i:])
  302. if err != nil {
  303. return "", invalidJSONBInput(text)
  304. }
  305. exponent = parsed
  306. } else if i != len(text) {
  307. return "", invalidJSONBInput(text)
  308. }
  309. allDigits := digits + fraction
  310. if len(allDigits) > maxJSONBNumberDigits {
  311. return "", pgerror.InvalidText("jsonb number field overflow")
  312. }
  313. mantissa := new(big.Int)
  314. if _, ok := mantissa.SetString(allDigits, 10); !ok {
  315. return "", invalidJSONBInput(text)
  316. }
  317. if mantissa.Sign() == 0 {
  318. return "0", nil
  319. }
  320. // value = mantissa / 10^scale, where scale = len(fraction) - exponent.
  321. scale := len(fraction) - exponent
  322. rendered := mantissa.String()
  323. if scale <= 0 {
  324. if len(rendered)-scale > maxJSONBNumberDigits {
  325. return "", pgerror.InvalidText("jsonb number field overflow")
  326. }
  327. rendered += strings.Repeat("0", -scale)
  328. } else {
  329. // Strip trailing zeros in the fractional part before rendering.
  330. for scale > 0 && len(rendered) > 1 && rendered[len(rendered)-1] == '0' {
  331. rendered = rendered[:len(rendered)-1]
  332. scale--
  333. }
  334. if scale >= len(rendered) {
  335. if scale > maxJSONBNumberDigits {
  336. return "", pgerror.InvalidText("jsonb number field overflow")
  337. }
  338. rendered = "0." + strings.Repeat("0", scale-len(rendered)) + rendered
  339. } else if scale > 0 {
  340. rendered = rendered[:len(rendered)-scale] + "." + rendered[len(rendered)-scale:]
  341. }
  342. }
  343. if negative {
  344. return "-" + rendered, nil
  345. }
  346. return rendered, nil
  347. }
  348. // jsonbNodeFromArg resolves a jsonb function or operator operand to a decoded
  349. // tree. NULL stays SQL NULL; text and the JSON subtype are parsed as a document.
  350. func jsonbNodeFromArg(value interface{}) (interface{}, error) {
  351. switch typed := value.(type) {
  352. case nil:
  353. return nil, nil
  354. case string:
  355. return decodeJSONB(typed)
  356. case jsonText:
  357. return decodeJSONB(string(typed))
  358. case []byte:
  359. return decodeJSONB(string(typed))
  360. default:
  361. return nil, pgerror.DatatypeMismatch("jsonb value must be JSON text, got %T", value)
  362. }
  363. }
  364. // jsonbNodeFromSQLValue converts a SQL value into a JSON tree node for
  365. // to_jsonb, jsonb_build_array, and jsonb_build_object values. NULL maps to JSON
  366. // null; callers decide whether a top-level NULL stays SQL NULL.
  367. func jsonbNodeFromSQLValue(value interface{}) (interface{}, error) {
  368. switch typed := value.(type) {
  369. case nil:
  370. return nil, nil
  371. case bool:
  372. return typed, nil
  373. case int:
  374. return json.Number(strconv.FormatInt(int64(typed), 10)), nil
  375. case int8:
  376. return json.Number(strconv.FormatInt(int64(typed), 10)), nil
  377. case int16:
  378. return json.Number(strconv.FormatInt(int64(typed), 10)), nil
  379. case int32:
  380. return json.Number(strconv.FormatInt(int64(typed), 10)), nil
  381. case int64:
  382. return json.Number(strconv.FormatInt(typed, 10)), nil
  383. case uint:
  384. return json.Number(strconv.FormatUint(uint64(typed), 10)), nil
  385. case uint32:
  386. return json.Number(strconv.FormatUint(uint64(typed), 10)), nil
  387. case uint64:
  388. return json.Number(strconv.FormatUint(typed, 10)), nil
  389. case float32:
  390. return json.Number(strconv.FormatFloat(float64(typed), 'g', -1, 32)), nil
  391. case float64:
  392. if typed != typed {
  393. return nil, pgerror.InvalidParameter("cannot convert NaN to jsonb")
  394. }
  395. if typed > 1.7976931348623157e308 || typed < -1.7976931348623157e308 {
  396. return nil, pgerror.InvalidParameter("cannot convert infinity to jsonb")
  397. }
  398. return json.Number(strconv.FormatFloat(typed, 'g', -1, 64)), nil
  399. case string:
  400. return typed, nil
  401. case jsonText:
  402. return string(typed), nil
  403. case []byte:
  404. return string(typed), nil
  405. default:
  406. return toString(value), nil
  407. }
  408. }
  409. // jsonbNodeToText renders a jsonb node as the SQL text that ->> and the *_text
  410. // set-returning functions return. JSON null becomes SQL NULL.
  411. func jsonbNodeToText(node interface{}) (interface{}, error) {
  412. switch value := node.(type) {
  413. case nil:
  414. return nil, nil
  415. case bool:
  416. if value {
  417. return "true", nil
  418. }
  419. return "false", nil
  420. case json.Number:
  421. return canonicalJSONBNumber(value)
  422. case string:
  423. return value, nil
  424. default:
  425. return encodeJSONB(node, false)
  426. }
  427. }
  428. // isJSONBExpr reports whether an expression produces a jsonb value. It follows
  429. // the statement's column-type scopes, so a JSONB column, a cast, and a jsonb
  430. // function are all recognized even though their runtime carrier is text.
  431. func (e *Executor) isJSONBExpr(expr parser.Expr) bool {
  432. switch typed := expr.(type) {
  433. case nil:
  434. return false
  435. case *parser.ParenExpr:
  436. return e.isJSONBExpr(typed.Expr)
  437. case *parser.CastExpr:
  438. return strings.EqualFold(strings.TrimSpace(typed.Type.Name), "JSONB")
  439. case *parser.BinaryExpr:
  440. switch typed.Op {
  441. case lexer.TokenArrow, lexer.TokenHashArrow, lexer.TokenHashMinus:
  442. return e.isJSONBExpr(typed.Left)
  443. case lexer.TokenConcat:
  444. return e.isJSONBExpr(typed.Left) || e.isJSONBExpr(typed.Right)
  445. case lexer.TokenMinus:
  446. return e.isJSONBExpr(typed.Left)
  447. }
  448. return false
  449. case *parser.FunctionCall:
  450. if jsonbFunctionReturnsJSONB(typed.Name) {
  451. return true
  452. }
  453. }
  454. return strings.EqualFold(strings.TrimSpace(inferExprType(expr, e.resolveColumnType)), "JSONB")
  455. }
  456. // jsonbFunctionReturnsJSONB reports whether a scalar function returns jsonb.
  457. func jsonbFunctionReturnsJSONB(name string) bool {
  458. switch strings.ToUpper(name) {
  459. case "TO_JSONB", "JSONB_SET", "JSONB_INSERT", "JSONB_REPLACE", "JSONB_REMOVE",
  460. "JSONB_STRIP_NULLS", "JSONB_BUILD_OBJECT", "JSONB_BUILD_ARRAY":
  461. return true
  462. default:
  463. return false
  464. }
  465. }
  466. // evalJSONBBinary applies the jsonb operators. handled is false when the operator
  467. // and operands are not a jsonb form, leaving ordinary SQL semantics untouched.
  468. func (e *Executor) evalJSONBBinary(op lexer.TokenType, leftExpr, rightExpr parser.Expr, left, right interface{}) (interface{}, bool, error) {
  469. leftJSONB := e.isJSONBExpr(leftExpr)
  470. rightJSONB := e.isJSONBExpr(rightExpr)
  471. if isComparisonOp(op) && (leftJSONB || rightJSONB) {
  472. if left == nil || right == nil {
  473. return nil, true, nil
  474. }
  475. if (leftJSONB && !jsonbComparisonValue(right)) || (rightJSONB && !jsonbComparisonValue(left)) {
  476. return nil, true, pgerror.DatatypeMismatch("jsonb comparison requires jsonb or text operands")
  477. }
  478. // jsonb equality and ordering compare the exact canonical bytes. Using
  479. // the engine's numeric-aware compare here would round through float64 and
  480. // report 1 = 1.0000000000000000001 or collapse integers above 2^53.
  481. leftText, err := CanonicalizeJSONB(toString(left))
  482. if err != nil {
  483. return nil, true, err
  484. }
  485. rightText, err := CanonicalizeJSONB(toString(right))
  486. if err != nil {
  487. return nil, true, err
  488. }
  489. result, err := comparisonOperatorResult(op, strings.Compare(leftText, rightText))
  490. return result, true, err
  491. }
  492. switch op {
  493. case lexer.TokenArrow, lexer.TokenArrowText:
  494. if !leftJSONB {
  495. return nil, false, nil
  496. }
  497. value, err := jsonbArrowExtract(left, right, op == lexer.TokenArrowText)
  498. return value, true, err
  499. case lexer.TokenHashArrow, lexer.TokenHashArrowText:
  500. value, err := jsonbPathExtract(left, right, op == lexer.TokenHashArrowText)
  501. return value, true, err
  502. case lexer.TokenHashMinus:
  503. value, err := jsonbPathDelete(left, right)
  504. return value, true, err
  505. case lexer.TokenAtArrow, lexer.TokenLtAt:
  506. value, err := e.jsonbContainment(op, leftExpr, rightExpr, left, right)
  507. return value, true, err
  508. case lexer.TokenQuestion:
  509. value, err := jsonbKeyExists(left, right)
  510. return value, true, err
  511. case lexer.TokenQuestionPipe, lexer.TokenQuestionAmp:
  512. value, err := jsonbAnyKeysExist(op, left, right)
  513. return value, true, err
  514. case lexer.TokenConcat:
  515. if !leftJSONB && !rightJSONB {
  516. return nil, false, nil
  517. }
  518. if left == nil || right == nil {
  519. return nil, true, nil
  520. }
  521. leftNode, err := jsonbNodeFromArg(left)
  522. if err != nil {
  523. return nil, true, err
  524. }
  525. rightNode, err := jsonbNodeFromArg(right)
  526. if err != nil {
  527. return nil, true, err
  528. }
  529. text, err := encodeJSONB(jsonbConcatNodes(leftNode, rightNode), false)
  530. return text, true, err
  531. case lexer.TokenMinus:
  532. if !leftJSONB {
  533. if rightJSONB {
  534. return nil, true, pgerror.DatatypeMismatch("cannot subtract a jsonb value from a non-jsonb value")
  535. }
  536. return nil, false, nil
  537. }
  538. if left == nil || right == nil {
  539. return nil, true, nil
  540. }
  541. value, err := e.jsonbDeleteValue(leftExpr, rightExpr, left, right)
  542. return value, true, err
  543. case lexer.TokenPlus, lexer.TokenStar, lexer.TokenSlash, lexer.TokenPercent:
  544. if leftJSONB || rightJSONB {
  545. return nil, true, pgerror.DatatypeMismatch("arithmetic operator %s requires numeric operands, got jsonb", op.String())
  546. }
  547. }
  548. return nil, false, nil
  549. }
  550. // jsonbComparisonValue reports whether a runtime value can be read as a jsonb
  551. // document on the other side of a comparison. SQL numbers and booleans are not
  552. // silently reinterpreted as JSON (PostgreSQL has no jsonb = integer operator).
  553. func jsonbComparisonValue(value interface{}) bool {
  554. switch value.(type) {
  555. case string, jsonText, []byte:
  556. return true
  557. default:
  558. return false
  559. }
  560. }
  561. // canonicalizeJSONBReadValue canonicalizes a JSONB-typed value on read so a
  562. // legacy row written before native JSONB still presents canonical text to
  563. // projections, DISTINCT, GROUP BY, and ORDER BY.
  564. func canonicalizeJSONBReadValue(typeName string, value interface{}) (interface{}, error) {
  565. if value == nil || !strings.EqualFold(strings.TrimSpace(typeName), "JSONB") {
  566. return value, nil
  567. }
  568. text, ok := value.(string)
  569. if !ok {
  570. if jsonValue, isJSON := value.(jsonText); isJSON {
  571. text = string(jsonValue)
  572. } else {
  573. return value, nil
  574. }
  575. }
  576. return CanonicalizeJSONB(text)
  577. }
  578. // canonicalizeJSONBColumnValue applies read canonicalization to a column
  579. // reference. It is a no-op for columns whose declared type is not JSONB.
  580. func (e *Executor) canonicalizeJSONBColumnValue(ref *parser.ColumnRef, value interface{}) (interface{}, error) {
  581. if ref == nil || value == nil {
  582. return value, nil
  583. }
  584. typeName, ok := e.resolveColumnType(ref.Table, ref.Column)
  585. if !ok {
  586. return value, nil
  587. }
  588. return canonicalizeJSONBReadValue(typeName, value)
  589. }
  590. // jsonbArrowPath resolves the right operand of -> and ->> for a jsonb document.
  591. // A $ path is validated like every other jsonb path, so wildcards and slices
  592. // are rejected with 0A000 rather than misinterpreted as member names.
  593. func jsonbArrowPath(key interface{}) ([]jsonPathSeg, error) {
  594. switch typed := key.(type) {
  595. case string:
  596. if strings.HasPrefix(strings.TrimSpace(typed), "$") {
  597. return parseJSONBJSONPath(typed)
  598. }
  599. return jsonArrowPath(key)
  600. case jsonText:
  601. if strings.HasPrefix(strings.TrimSpace(string(typed)), "$") {
  602. return parseJSONBJSONPath(string(typed))
  603. }
  604. return jsonArrowPath(key)
  605. default:
  606. return jsonArrowPath(key)
  607. }
  608. }
  609. // jsonbArrowExtract evaluates -> and ->> against a jsonb document. A missing
  610. // path is SQL NULL; a JSON null member is the jsonb value "null" for -> and SQL
  611. // NULL for ->>.
  612. func jsonbArrowExtract(document, key interface{}, scalar bool) (interface{}, error) {
  613. if document == nil || key == nil {
  614. return nil, nil
  615. }
  616. node, err := jsonbNodeFromArg(document)
  617. if err != nil {
  618. return nil, err
  619. }
  620. segs, err := jsonbArrowPath(key)
  621. if err != nil {
  622. return nil, err
  623. }
  624. found, ok := jsonLookup(node, segs)
  625. if !ok {
  626. return nil, nil
  627. }
  628. if scalar {
  629. return jsonbNodeToText(found)
  630. }
  631. return encodeJSONB(found, false)
  632. }
  633. // jsonbPathExtract evaluates #> and #>>. The path operand is a PostgreSQL
  634. // text[] (canonical array text) or a $ path.
  635. func jsonbPathExtract(document, path interface{}, scalar bool) (interface{}, error) {
  636. if document == nil || path == nil {
  637. return nil, nil
  638. }
  639. node, err := jsonbNodeFromArg(document)
  640. if err != nil {
  641. return nil, err
  642. }
  643. segs, err := jsonbPathArg(path)
  644. if err != nil {
  645. return nil, err
  646. }
  647. found, ok, err := jsonLookupE(node, segs)
  648. if err != nil {
  649. return nil, err
  650. }
  651. if !ok {
  652. return nil, nil
  653. }
  654. if scalar {
  655. return jsonbNodeToText(found)
  656. }
  657. return encodeJSONB(found, false)
  658. }
  659. // jsonbPathDelete evaluates #-. A missing path leaves the document unchanged.
  660. func jsonbPathDelete(document, path interface{}) (interface{}, error) {
  661. if document == nil || path == nil {
  662. return nil, nil
  663. }
  664. node, err := jsonbNodeFromArg(document)
  665. if err != nil {
  666. return nil, err
  667. }
  668. segs, err := jsonbPathArg(path)
  669. if err != nil {
  670. return nil, err
  671. }
  672. updated, err := jsonRemove(node, segs)
  673. if err != nil {
  674. return nil, err
  675. }
  676. return encodeJSONB(updated, false)
  677. }
  678. // jsonbContainment evaluates @> and <@. The jsonb operand must be present on at
  679. // least one side so a text-only comparison is not silently reinterpreted.
  680. func (e *Executor) jsonbContainment(op lexer.TokenType, leftExpr, rightExpr parser.Expr, left, right interface{}) (interface{}, error) {
  681. leftJSONB := e.isJSONBExpr(leftExpr)
  682. rightJSONB := e.isJSONBExpr(rightExpr)
  683. if !leftJSONB && !rightJSONB {
  684. return nil, pgerror.DatatypeMismatch("jsonb containment requires a jsonb operand; cast one side with ::jsonb")
  685. }
  686. if left == nil || right == nil {
  687. return nil, nil
  688. }
  689. leftNode, err := jsonbNodeFromArg(left)
  690. if err != nil {
  691. return nil, err
  692. }
  693. rightNode, err := jsonbNodeFromArg(right)
  694. if err != nil {
  695. return nil, err
  696. }
  697. switch op {
  698. case lexer.TokenAtArrow:
  699. return jsonbContains(leftNode, rightNode), nil
  700. case lexer.TokenLtAt:
  701. return jsonbContains(rightNode, leftNode), nil
  702. }
  703. return nil, pgerror.InvalidParameter("unsupported jsonb containment operator")
  704. }
  705. // jsonbKeyExists evaluates the ? operator: an object key or a top-level string
  706. // array element.
  707. func jsonbKeyExists(left, right interface{}) (interface{}, error) {
  708. if left == nil || right == nil {
  709. return nil, nil
  710. }
  711. node, err := jsonbNodeFromArg(left)
  712. if err != nil {
  713. return nil, err
  714. }
  715. key := toString(right)
  716. switch value := node.(type) {
  717. case map[string]interface{}:
  718. _, exists := value[key]
  719. return exists, nil
  720. case []interface{}:
  721. for _, element := range value {
  722. if text, ok := element.(string); ok && text == key {
  723. return true, nil
  724. }
  725. }
  726. return false, nil
  727. case string:
  728. // A scalar JSON string counts as the key itself: '"x"' ? 'x' is true.
  729. return value == key, nil
  730. default:
  731. return false, nil
  732. }
  733. }
  734. // jsonbAnyKeysExist evaluates ?| and ?& against a text[] of keys.
  735. func jsonbAnyKeysExist(op lexer.TokenType, left, right interface{}) (interface{}, error) {
  736. if left == nil || right == nil {
  737. return nil, nil
  738. }
  739. node, err := jsonbNodeFromArg(left)
  740. if err != nil {
  741. return nil, err
  742. }
  743. keys, err := jsonbKeyListArg(right)
  744. if err != nil {
  745. return nil, err
  746. }
  747. matches := 0
  748. switch value := node.(type) {
  749. case map[string]interface{}:
  750. for _, key := range keys {
  751. if _, exists := value[key]; exists {
  752. matches++
  753. }
  754. }
  755. case []interface{}:
  756. for _, key := range keys {
  757. for _, element := range value {
  758. if text, ok := element.(string); ok && text == key {
  759. matches++
  760. break
  761. }
  762. }
  763. }
  764. default:
  765. return false, nil
  766. }
  767. if op == lexer.TokenQuestionAmp {
  768. return matches == len(keys), nil
  769. }
  770. return matches > 0, nil
  771. }
  772. // jsonbDeleteValue evaluates jsonb - text, jsonb - integer, and jsonb - text[].
  773. func (e *Executor) jsonbDeleteValue(leftExpr, rightExpr parser.Expr, left, right interface{}) (interface{}, error) {
  774. if e.isJSONBExpr(rightExpr) {
  775. return nil, pgerror.DatatypeMismatch("jsonb deletion requires a text key, integer index, or text[] path, not a jsonb operand")
  776. }
  777. node, err := jsonbNodeFromArg(left)
  778. if err != nil {
  779. return nil, err
  780. }
  781. if _, isArray := e.arrayTypeOf(rightExpr); isArray {
  782. elements, parseErr := parseArrayLiteral(toString(right))
  783. if parseErr != nil {
  784. return nil, parseErr
  785. }
  786. keys := make([]string, 0, len(elements))
  787. for _, element := range elements {
  788. if element == nil {
  789. return nil, pgerror.InvalidParameter("jsonb delete path contains a NULL element")
  790. }
  791. keys = append(keys, *element)
  792. }
  793. return encodeJSONB(jsonbDeleteKeys(node, keys), false)
  794. }
  795. switch value := right.(type) {
  796. case int64:
  797. array, ok := node.([]interface{})
  798. if !ok {
  799. if _, isObject := node.(map[string]interface{}); isObject {
  800. return nil, pgerror.InvalidParameter("cannot delete from object using integer index")
  801. }
  802. return nil, pgerror.InvalidParameter("cannot delete an array element from a jsonb %s", jsonbNodeTypeName(node))
  803. }
  804. return encodeJSONB(jsonbDeleteIndex(array, int(value)), false)
  805. case int:
  806. return e.jsonbDeleteValue(leftExpr, rightExpr, left, int64(value))
  807. case string, jsonText:
  808. // jsonb - text deletes an object key, or every string element equal to
  809. // the text when the document is an array.
  810. key := toString(value)
  811. return encodeJSONB(jsonbDeleteKeys(node, []string{key}), false)
  812. default:
  813. return nil, pgerror.DatatypeMismatch("cannot delete %T from jsonb", right)
  814. }
  815. }
  816. func jsonbDeleteKeys(node interface{}, keys []string) interface{} {
  817. switch container := node.(type) {
  818. case map[string]interface{}:
  819. out := make(map[string]interface{}, len(container))
  820. for key, value := range container {
  821. out[key] = value
  822. }
  823. for _, key := range keys {
  824. delete(out, key)
  825. }
  826. return out
  827. case []interface{}:
  828. out := make([]interface{}, 0, len(container))
  829. for _, element := range container {
  830. remove := false
  831. if text, ok := element.(string); ok {
  832. for _, key := range keys {
  833. if text == key {
  834. remove = true
  835. break
  836. }
  837. }
  838. }
  839. if !remove {
  840. out = append(out, element)
  841. }
  842. }
  843. return out
  844. default:
  845. return node
  846. }
  847. }
  848. func jsonbDeleteIndex(array []interface{}, index int) []interface{} {
  849. if index < 0 {
  850. index += len(array)
  851. }
  852. if index < 0 || index >= len(array) {
  853. return array
  854. }
  855. out := make([]interface{}, 0, len(array)-1)
  856. out = append(out, array[:index]...)
  857. out = append(out, array[index+1:]...)
  858. return out
  859. }
  860. // jsonbConcatNodes implements jsonb || jsonb: objects merge right-wins, arrays
  861. // concatenate, and any non-array operand becomes a single-element array.
  862. func jsonbConcatNodes(left, right interface{}) interface{} {
  863. leftObject, leftIsObject := left.(map[string]interface{})
  864. rightObject, rightIsObject := right.(map[string]interface{})
  865. if leftIsObject && rightIsObject {
  866. out := make(map[string]interface{}, len(leftObject)+len(rightObject))
  867. for key, value := range leftObject {
  868. out[key] = value
  869. }
  870. for key, value := range rightObject {
  871. out[key] = value
  872. }
  873. return out
  874. }
  875. asArray := func(node interface{}) []interface{} {
  876. if array, ok := node.([]interface{}); ok {
  877. return array
  878. }
  879. return []interface{}{node}
  880. }
  881. out := append([]interface{}{}, asArray(left)...)
  882. return append(out, asArray(right)...)
  883. }
  884. // jsonbContains implements jsonb containment: object keys/values recurse, array
  885. // elements are order-independent, top-level arrays contain scalars, and scalars
  886. // compare by type.
  887. func jsonbContains(container, candidate interface{}) bool {
  888. // A top-level array contains a scalar candidate when any element does.
  889. switch candidate.(type) {
  890. case nil, bool, string, json.Number:
  891. if containerArray, ok := container.([]interface{}); ok {
  892. for _, element := range containerArray {
  893. if jsonbContains(element, candidate) {
  894. return true
  895. }
  896. }
  897. return false
  898. }
  899. }
  900. switch candidateValue := candidate.(type) {
  901. case map[string]interface{}:
  902. containerObject, ok := container.(map[string]interface{})
  903. if !ok {
  904. return false
  905. }
  906. for key, value := range candidateValue {
  907. other, exists := containerObject[key]
  908. if !exists || !jsonbContains(other, value) {
  909. return false
  910. }
  911. }
  912. return true
  913. case []interface{}:
  914. containerArray, ok := container.([]interface{})
  915. if ok {
  916. // PostgreSQL array containment does not require multiplicity: each
  917. // candidate element only needs some container element, and duplicates
  918. // may match the same element.
  919. for _, candidateElement := range candidateValue {
  920. matched := false
  921. for _, containerElement := range containerArray {
  922. if jsonbContains(containerElement, candidateElement) {
  923. matched = true
  924. break
  925. }
  926. }
  927. if !matched {
  928. return false
  929. }
  930. }
  931. return true
  932. }
  933. // A non-array container can still contain a nested empty array? No.
  934. return false
  935. case nil:
  936. return container == nil
  937. case bool:
  938. other, ok := container.(bool)
  939. return ok && other == candidateValue
  940. case string:
  941. other, ok := container.(string)
  942. return ok && other == candidateValue
  943. case json.Number:
  944. candidateText, err := canonicalJSONBNumber(candidateValue)
  945. if err != nil {
  946. return false
  947. }
  948. other, ok := container.(json.Number)
  949. if !ok {
  950. return false
  951. }
  952. containerText, err := canonicalJSONBNumber(other)
  953. if err != nil {
  954. return false
  955. }
  956. return containerText == candidateText
  957. }
  958. return false
  959. }
  960. // jsonbNodeTypeName returns the PostgreSQL jsonb type name.
  961. func jsonbNodeTypeName(node interface{}) string {
  962. switch node.(type) {
  963. case nil:
  964. return "null"
  965. case bool:
  966. return "boolean"
  967. case json.Number:
  968. return "number"
  969. case string:
  970. return "string"
  971. case []interface{}:
  972. return "array"
  973. case map[string]interface{}:
  974. return "object"
  975. default:
  976. return "unknown"
  977. }
  978. }
  979. // jsonbPathArg resolves a path operand to path steps. A text[] value (canonical
  980. // array text) is PostgreSQL's path form; a $string is the JSON1 path form this
  981. // engine already uses for -> and json_extract.
  982. func jsonbPathArg(value interface{}) ([]jsonPathSeg, error) {
  983. text := strings.TrimSpace(toString(value))
  984. switch {
  985. case strings.HasPrefix(text, "{"):
  986. return parseJSONBArrayPath(text)
  987. case strings.HasPrefix(text, "$"):
  988. return parseJSONBJSONPath(text)
  989. default:
  990. return nil, pgerror.InvalidParameter("jsonb path must be a text[] array literal such as '{a,0}' or a $ path, got %q", text)
  991. }
  992. }
  993. // jsonbKeyListArg parses a text[] of object keys. Unlike a path, every element
  994. // is a key: a numeric-looking key such as "1" must not become an array index.
  995. func jsonbKeyListArg(value interface{}) ([]string, error) {
  996. text := strings.TrimSpace(toString(value))
  997. if !strings.HasPrefix(text, "{") {
  998. return nil, pgerror.InvalidParameter("jsonb key list must be a text[] array literal, got %q", text)
  999. }
  1000. elements, err := parseArrayLiteral(text)
  1001. if err != nil {
  1002. return nil, err
  1003. }
  1004. keys := make([]string, 0, len(elements))
  1005. for _, element := range elements {
  1006. if element == nil {
  1007. return nil, pgerror.InvalidParameter("jsonb key list element must not be NULL")
  1008. }
  1009. keys = append(keys, *element)
  1010. }
  1011. return keys, nil
  1012. }
  1013. // parseJSONBArrayPath parses PostgreSQL text[] path text into steps. A path
  1014. // element is kept as raw text because its meaning depends on the container it
  1015. // is applied to: an object key, or an integer array index. Numeric-looking
  1016. // object keys such as "1", "01", "-1", and "1.5" therefore stay keys when the
  1017. // container is an object.
  1018. func parseJSONBArrayPath(text string) ([]jsonPathSeg, error) {
  1019. elements, err := parseArrayLiteral(text)
  1020. if err != nil {
  1021. return nil, err
  1022. }
  1023. segs := make([]jsonPathSeg, 0, len(elements))
  1024. for _, element := range elements {
  1025. if element == nil {
  1026. return nil, pgerror.InvalidParameter("jsonb path element must not be NULL")
  1027. }
  1028. segs = append(segs, jsonPathSeg{dynamic: true, element: *element})
  1029. }
  1030. return segs, nil
  1031. }
  1032. // resolveJSONBPathSegment converts a PostgreSQL path element into a concrete
  1033. // object key or array index for the container it is applied to. Concrete steps
  1034. // (JSON1 $ paths and index/key steps) pass through unchanged. resolved is false
  1035. // when container is a scalar or missing; callers decide whether that is a
  1036. // not-found, an unchanged target, or an error. strict selects whether a
  1037. // non-integer element on an array is an error (jsonb path mutation and #-) or a
  1038. // non-match (jsonb #>).
  1039. func resolveJSONBPathSegment(seg jsonPathSeg, container interface{}, strict bool) (jsonPathSeg, bool, error) {
  1040. if !seg.dynamic {
  1041. return seg, true, nil
  1042. }
  1043. switch container.(type) {
  1044. case map[string]interface{}:
  1045. return jsonPathSeg{key: seg.element}, true, nil
  1046. case []interface{}:
  1047. index, err := strconv.Atoi(seg.element)
  1048. if err != nil {
  1049. if strict {
  1050. return seg, false, pgerror.InvalidText("path element %q is not an integer", seg.element)
  1051. }
  1052. return seg, false, nil
  1053. }
  1054. return jsonPathSeg{isIndex: true, index: index, fromEnd: index < 0}, true, nil
  1055. default:
  1056. return seg, false, nil
  1057. }
  1058. }
  1059. // parseJSONBJSONPath parses a JSON1 $ path for jsonb use and rejects the
  1060. // jsonpath shapes the engine cannot execute (wildcards, slices, unbounded
  1061. // expansion) with SQLSTATE 0A000.
  1062. func parseJSONBJSONPath(path string) ([]jsonPathSeg, error) {
  1063. if unsupportedJSONPathShape(path) {
  1064. return nil, pgerror.Unsupported("jsonpath wildcards, slices, and unbounded expansion are not supported; pass an explicit path")
  1065. }
  1066. segs, err := parseJSONPath(path)
  1067. if err != nil {
  1068. return nil, err
  1069. }
  1070. for _, segment := range segs {
  1071. if !segment.isIndex && (segment.key == "*" || strings.HasPrefix(segment.key, "**")) {
  1072. return nil, pgerror.Unsupported("jsonpath wildcards and unbounded expansion are not supported; pass an explicit path")
  1073. }
  1074. }
  1075. return segs, nil
  1076. }
  1077. // unsupportedJSONPathShape reports whether path text contains a jsonpath
  1078. // wildcard, slice, or deep-expansion marker inside brackets or as a bare member.
  1079. func unsupportedJSONPathShape(path string) bool {
  1080. for i := 0; i < len(path); i++ {
  1081. if path[i] != '[' {
  1082. continue
  1083. }
  1084. end := strings.IndexByte(path[i:], ']')
  1085. if end < 0 {
  1086. return false
  1087. }
  1088. inner := path[i+1 : i+end]
  1089. if strings.ContainsAny(inner, "*:") {
  1090. return true
  1091. }
  1092. i += end
  1093. }
  1094. return false
  1095. }
  1096. // jsonbSetPG implements PostgreSQL's jsonb_set path semantics. An empty path
  1097. // leaves the target unchanged. All steps except the last must exist and be
  1098. // containers; missing keys or a scalar on the way leave the target unchanged. A
  1099. // missing array position at the last step is appended when create is true, and
  1100. // an index before the start is clamped to the first position.
  1101. func jsonbSetPG(node interface{}, segs []jsonPathSeg, value interface{}, create bool) (interface{}, error) {
  1102. if len(segs) == 0 {
  1103. return node, nil
  1104. }
  1105. segment, resolved, err := resolveJSONBPathSegment(segs[0], node, true)
  1106. if err != nil {
  1107. return nil, err
  1108. }
  1109. if !resolved {
  1110. return nil, pgerror.InvalidParameter("cannot set path in scalar")
  1111. }
  1112. if len(segs) > 1 {
  1113. child, exists, err := jsonbPathChild(node, segment)
  1114. if err != nil {
  1115. return nil, err
  1116. }
  1117. if !exists {
  1118. return node, nil
  1119. }
  1120. switch child.(type) {
  1121. case map[string]interface{}, []interface{}:
  1122. default:
  1123. // PostgreSQL leaves the target unchanged when an intermediate step
  1124. // names a scalar rather than a container.
  1125. return node, nil
  1126. }
  1127. updated, err := jsonbSetPG(child, segs[1:], value, create)
  1128. if err != nil {
  1129. return nil, err
  1130. }
  1131. return jsonbReplaceChild(node, segment, updated)
  1132. }
  1133. switch container := node.(type) {
  1134. case map[string]interface{}:
  1135. if segment.isIndex {
  1136. return nil, pgerror.InvalidText("path element is not an object key")
  1137. }
  1138. if _, exists := container[segment.key]; !exists && !create {
  1139. return node, nil
  1140. }
  1141. out := make(map[string]interface{}, len(container)+1)
  1142. for key, item := range container {
  1143. out[key] = item
  1144. }
  1145. out[segment.key] = value
  1146. return out, nil
  1147. case []interface{}:
  1148. if !segment.isIndex {
  1149. return nil, pgerror.InvalidText("path element %q is not an integer", segment.key)
  1150. }
  1151. index := segment.index
  1152. if index < 0 {
  1153. index += len(container)
  1154. }
  1155. if index < 0 {
  1156. if !create {
  1157. return node, nil
  1158. }
  1159. out := make([]interface{}, 0, len(container)+1)
  1160. out = append(out, value)
  1161. return append(out, container...), nil
  1162. }
  1163. if index >= len(container) {
  1164. if !create {
  1165. return node, nil
  1166. }
  1167. out := append([]interface{}{}, container...)
  1168. return append(out, value), nil
  1169. }
  1170. out := append([]interface{}{}, container...)
  1171. out[index] = value
  1172. return out, nil
  1173. default:
  1174. return nil, pgerror.InvalidParameter("cannot set path in scalar")
  1175. }
  1176. }
  1177. // jsonbInsertPG implements PostgreSQL's jsonb_insert path semantics: array
  1178. // elements are inserted before or after an index (clamped into range), and an
  1179. // object key is inserted only when it is absent. An existing object key is an
  1180. // error, matching PostgreSQL.
  1181. func jsonbInsertPG(node interface{}, segs []jsonPathSeg, value interface{}, after bool) (interface{}, error) {
  1182. if len(segs) == 0 {
  1183. return node, nil
  1184. }
  1185. segment, resolved, err := resolveJSONBPathSegment(segs[0], node, true)
  1186. if err != nil {
  1187. return nil, err
  1188. }
  1189. if !resolved {
  1190. return nil, pgerror.InvalidParameter("cannot set path in scalar")
  1191. }
  1192. if len(segs) > 1 {
  1193. child, exists, err := jsonbPathChild(node, segment)
  1194. if err != nil {
  1195. return nil, err
  1196. }
  1197. if !exists {
  1198. return node, nil
  1199. }
  1200. switch child.(type) {
  1201. case map[string]interface{}, []interface{}:
  1202. default:
  1203. return node, nil
  1204. }
  1205. updated, err := jsonbInsertPG(child, segs[1:], value, after)
  1206. if err != nil {
  1207. return nil, err
  1208. }
  1209. return jsonbReplaceChild(node, segment, updated)
  1210. }
  1211. switch container := node.(type) {
  1212. case map[string]interface{}:
  1213. if segment.isIndex {
  1214. return nil, pgerror.InvalidText("path element is not an object key")
  1215. }
  1216. if _, exists := container[segment.key]; exists {
  1217. return nil, pgerror.InvalidParameter("cannot replace existing key")
  1218. }
  1219. out := make(map[string]interface{}, len(container)+1)
  1220. for key, item := range container {
  1221. out[key] = item
  1222. }
  1223. out[segment.key] = value
  1224. return out, nil
  1225. case []interface{}:
  1226. if !segment.isIndex {
  1227. return nil, pgerror.InvalidText("path element %q is not an integer", segment.key)
  1228. }
  1229. index := segment.index
  1230. if index < 0 {
  1231. index += len(container)
  1232. }
  1233. if index < 0 {
  1234. index = 0
  1235. }
  1236. if index > len(container) {
  1237. index = len(container)
  1238. }
  1239. if after {
  1240. index++
  1241. }
  1242. if index > len(container) {
  1243. index = len(container)
  1244. }
  1245. out := make([]interface{}, 0, len(container)+1)
  1246. out = append(out, container[:index]...)
  1247. out = append(out, value)
  1248. out = append(out, container[index:]...)
  1249. return out, nil
  1250. default:
  1251. return nil, pgerror.InvalidParameter("cannot set path in scalar")
  1252. }
  1253. }
  1254. // jsonbPathChild resolves one non-final path step to an existing child.
  1255. func jsonbPathChild(node interface{}, segment jsonPathSeg) (interface{}, bool, error) {
  1256. switch container := node.(type) {
  1257. case map[string]interface{}:
  1258. if segment.isIndex {
  1259. return nil, false, pgerror.InvalidParameter("jsonb path element %d does not identify an object key", segment.index)
  1260. }
  1261. child, exists := container[segment.key]
  1262. return child, exists, nil
  1263. case []interface{}:
  1264. if !segment.isIndex {
  1265. return nil, false, pgerror.InvalidParameter("jsonb path element %q does not identify an array index", segment.key)
  1266. }
  1267. index := segment.index
  1268. if index < 0 {
  1269. index += len(container)
  1270. }
  1271. if index < 0 || index >= len(container) {
  1272. return nil, false, nil
  1273. }
  1274. return container[index], true, nil
  1275. default:
  1276. return nil, false, pgerror.InvalidParameter("cannot walk a jsonb path through a %s", jsonbNodeTypeName(node))
  1277. }
  1278. }
  1279. // jsonbReplaceChild writes an updated child back into its container.
  1280. func jsonbReplaceChild(node interface{}, segment jsonPathSeg, child interface{}) (interface{}, error) {
  1281. switch container := node.(type) {
  1282. case map[string]interface{}:
  1283. if segment.isIndex {
  1284. return nil, pgerror.InvalidParameter("jsonb path element %d does not identify an object key", segment.index)
  1285. }
  1286. out := make(map[string]interface{}, len(container)+1)
  1287. for key, item := range container {
  1288. out[key] = item
  1289. }
  1290. out[segment.key] = child
  1291. return out, nil
  1292. case []interface{}:
  1293. if !segment.isIndex {
  1294. return nil, pgerror.InvalidParameter("jsonb path element %q does not identify an array index", segment.key)
  1295. }
  1296. index := segment.index
  1297. if index < 0 {
  1298. index += len(container)
  1299. }
  1300. if index < 0 || index >= len(container) {
  1301. return nil, pgerror.InvalidParameter("jsonb path array index %d is out of range", segment.index)
  1302. }
  1303. out := append([]interface{}{}, container...)
  1304. out[index] = child
  1305. return out, nil
  1306. default:
  1307. return nil, pgerror.InvalidParameter("cannot write a jsonb path through a %s", jsonbNodeTypeName(node))
  1308. }
  1309. }
  1310. // jsonbStripNulls removes object members whose value is JSON null. Array
  1311. // elements are kept, matching jsonb_strip_nulls.
  1312. func jsonbStripNulls(node interface{}) interface{} {
  1313. switch value := node.(type) {
  1314. case map[string]interface{}:
  1315. out := make(map[string]interface{}, len(value))
  1316. for key, item := range value {
  1317. if item == nil {
  1318. continue
  1319. }
  1320. out[key] = jsonbStripNulls(item)
  1321. }
  1322. return out
  1323. case []interface{}:
  1324. out := make([]interface{}, len(value))
  1325. for i, item := range value {
  1326. out[i] = jsonbStripNulls(item)
  1327. }
  1328. return out
  1329. default:
  1330. return node
  1331. }
  1332. }
  1333. // jsonbEncodeNode canonicalizes a tree that has already been validated.
  1334. func jsonbEncodeNode(node interface{}) (string, error) {
  1335. return encodeJSONB(node, false)
  1336. }
  1337. // evalJSONBFunction evaluates a native jsonb scalar function. handled is false
  1338. // for names it does not own, keeping the JSON1 surface untouched.
  1339. func (e *Executor) evalJSONBFunction(name string, fn *parser.FunctionCall, args []interface{}) (interface{}, bool, error) {
  1340. upper := strings.ToUpper(name)
  1341. switch upper {
  1342. case "TO_JSONB":
  1343. if len(args) != 1 {
  1344. return nil, true, pgerror.InvalidParameter("to_jsonb() requires exactly one argument")
  1345. }
  1346. if args[0] == nil {
  1347. return nil, true, nil
  1348. }
  1349. node, err := e.toJSONBNode(firstFunctionArg(fn), args[0])
  1350. if err != nil {
  1351. return nil, true, err
  1352. }
  1353. text, err := jsonbEncodeNode(node)
  1354. return text, true, err
  1355. case "JSONB_TYPEOF":
  1356. if len(args) != 1 {
  1357. return nil, true, pgerror.InvalidParameter("jsonb_typeof() requires exactly one argument")
  1358. }
  1359. node, err := jsonbNodeFromArg(args[0])
  1360. if err != nil {
  1361. return nil, true, err
  1362. }
  1363. if node == nil && args[0] == nil {
  1364. return nil, true, nil
  1365. }
  1366. return jsonbNodeTypeName(node), true, nil
  1367. case "JSONB_ARRAY_LENGTH":
  1368. if len(args) != 1 {
  1369. return nil, true, pgerror.InvalidParameter("jsonb_array_length() requires exactly one argument")
  1370. }
  1371. node, err := jsonbNodeFromArg(args[0])
  1372. if err != nil {
  1373. return nil, true, err
  1374. }
  1375. if node == nil && args[0] == nil {
  1376. return nil, true, nil
  1377. }
  1378. array, ok := node.([]interface{})
  1379. if !ok {
  1380. return nil, true, pgerror.InvalidParameter("cannot get array length of a jsonb %s", jsonbNodeTypeName(node))
  1381. }
  1382. return int64(len(array)), true, nil
  1383. case "JSONB_PRETTY":
  1384. if len(args) != 1 {
  1385. return nil, true, pgerror.InvalidParameter("jsonb_pretty() requires exactly one argument")
  1386. }
  1387. if args[0] == nil {
  1388. return nil, true, nil
  1389. }
  1390. node, err := jsonbNodeFromArg(args[0])
  1391. if err != nil {
  1392. return nil, true, err
  1393. }
  1394. text, err := encodeJSONB(node, true)
  1395. return text, true, err
  1396. case "JSONB_STRIP_NULLS":
  1397. if len(args) != 1 {
  1398. return nil, true, pgerror.InvalidParameter("jsonb_strip_nulls() requires exactly one argument")
  1399. }
  1400. if args[0] == nil {
  1401. return nil, true, nil
  1402. }
  1403. node, err := jsonbNodeFromArg(args[0])
  1404. if err != nil {
  1405. return nil, true, err
  1406. }
  1407. text, err := jsonbEncodeNode(jsonbStripNulls(node))
  1408. return text, true, err
  1409. case "JSONB_BUILD_ARRAY":
  1410. values := make([]interface{}, len(args))
  1411. for i, arg := range args {
  1412. node, err := e.toJSONBNode(functionArgAt(fn, i), arg)
  1413. if err != nil {
  1414. return nil, true, err
  1415. }
  1416. values[i] = node
  1417. }
  1418. text, err := jsonbEncodeNode(values)
  1419. return text, true, err
  1420. case "JSONB_BUILD_OBJECT":
  1421. if len(args)%2 != 0 {
  1422. return nil, true, pgerror.InvalidParameter("jsonb_build_object() argument list must have an even number of elements")
  1423. }
  1424. object := make(map[string]interface{}, len(args)/2)
  1425. for i := 0; i+1 < len(args); i += 2 {
  1426. if args[i] == nil {
  1427. return nil, true, pgerror.InvalidParameter("jsonb_build_object() argument %d: key must not be null", i+1)
  1428. }
  1429. key := toString(args[i])
  1430. node, err := e.toJSONBNode(functionArgAt(fn, i+1), args[i+1])
  1431. if err != nil {
  1432. return nil, true, err
  1433. }
  1434. object[key] = node
  1435. }
  1436. text, err := jsonbEncodeNode(object)
  1437. return text, true, err
  1438. case "JSONB_SET", "JSONB_INSERT", "JSONB_REPLACE", "JSONB_REMOVE":
  1439. value, err := e.evalJSONBPatch(upper, fn, args)
  1440. return value, true, err
  1441. case "JSONB_EACH", "JSONB_EACH_TEXT", "JSONB_ARRAY_ELEMENTS", "JSONB_ARRAY_ELEMENTS_TEXT", "JSONB_OBJECT_KEYS":
  1442. return nil, true, pgerror.Unsupported("%s() is a set-returning function and is only supported as the single FROM item, as in SELECT * FROM %s(jsonb_column)", name, strings.ToLower(name))
  1443. case "JSONB_PATH_EXISTS", "JSONB_PATH_EXISTS_TZ", "JSONB_PATH_MATCH", "JSONB_PATH_MATCH_TZ",
  1444. "JSONB_PATH_QUERY", "JSONB_PATH_QUERY_TZ", "JSONB_PATH_QUERY_ARRAY", "JSONB_PATH_QUERY_ARRAY_TZ",
  1445. "JSONB_PATH_QUERY_FIRST", "JSONB_PATH_QUERY_FIRST_TZ":
  1446. return nil, true, pgerror.Unsupported("jsonpath (%s) is not supported", strings.ToLower(name))
  1447. }
  1448. return nil, false, nil
  1449. }
  1450. // firstFunctionArg returns the first argument expression of a call, or nil when
  1451. // the call has no arguments.
  1452. func firstFunctionArg(fn *parser.FunctionCall) parser.Expr {
  1453. if fn == nil || len(fn.Args) == 0 {
  1454. return nil
  1455. }
  1456. return fn.Args[0]
  1457. }
  1458. func functionArgAt(fn *parser.FunctionCall, index int) parser.Expr {
  1459. if fn == nil || index < 0 || index >= len(fn.Args) {
  1460. return nil
  1461. }
  1462. return fn.Args[index]
  1463. }
  1464. // toJSONBNode converts a SQL value to a JSON tree node, decoding arrays into
  1465. // JSON arrays so to_jsonb(jsonb_build_array(...)) and to_jsonb(array_column)
  1466. // keep their element types.
  1467. func (e *Executor) toJSONBNode(expr parser.Expr, value interface{}) (interface{}, error) {
  1468. if value == nil {
  1469. return nil, nil
  1470. }
  1471. // to_jsonb(jsonb) is the identity: a jsonb argument is embedded as its
  1472. // document, not as a JSON string.
  1473. if e.isJSONBExpr(expr) {
  1474. return jsonbNodeFromArg(value)
  1475. }
  1476. if typeName, ok := e.arrayTypeOf(expr); ok {
  1477. elements, err := parseArrayLiteral(toString(value))
  1478. if err != nil {
  1479. return nil, err
  1480. }
  1481. elementType, _ := arrayElementType(typeName)
  1482. nodes := make([]interface{}, len(elements))
  1483. for i, element := range elements {
  1484. typed, valueErr := arrayElementValue(element, elementType)
  1485. if valueErr != nil {
  1486. return nil, valueErr
  1487. }
  1488. node, nodeErr := jsonbNodeFromSQLValue(typed)
  1489. if nodeErr != nil {
  1490. return nil, nodeErr
  1491. }
  1492. nodes[i] = node
  1493. }
  1494. return nodes, nil
  1495. }
  1496. return jsonbNodeFromSQLValue(value)
  1497. }
  1498. // evalJSONBPatch evaluates the jsonb_set/jsonb_insert/jsonb_replace/
  1499. // jsonb_remove family. A $ path keeps the JSON1 semantics the engine already
  1500. // exposed; a PostgreSQL text[] path uses PostgreSQL's jsonb_set/jsonb_insert
  1501. // rules and accepts the optional boolean fourth argument.
  1502. func (e *Executor) evalJSONBPatch(name string, fn *parser.FunctionCall, args []interface{}) (interface{}, error) {
  1503. minArgs := 2
  1504. if name != "JSONB_REMOVE" {
  1505. minArgs = 3
  1506. }
  1507. if len(args) < minArgs {
  1508. return nil, pgerror.InvalidParameter("%s() requires at least %d arguments", strings.ToLower(name), minArgs)
  1509. }
  1510. if args[0] == nil || args[1] == nil {
  1511. return nil, nil
  1512. }
  1513. node, err := jsonbNodeFromArg(args[0])
  1514. if err != nil {
  1515. return nil, err
  1516. }
  1517. if name == "JSONB_REMOVE" {
  1518. for _, path := range args[1:] {
  1519. if path == nil {
  1520. return nil, nil
  1521. }
  1522. segs, pathErr := jsonbPathArg(path)
  1523. if pathErr != nil {
  1524. return nil, pathErr
  1525. }
  1526. node, err = jsonRemove(node, segs)
  1527. if err != nil {
  1528. return nil, err
  1529. }
  1530. }
  1531. return jsonbEncodeNode(node)
  1532. }
  1533. // JSON1 multi-path form: jsonb_set(doc, path, value, path, value, ...).
  1534. // PostgreSQL's form has exactly three or four arguments.
  1535. pathText := strings.TrimSpace(toString(args[1]))
  1536. pgPath := strings.HasPrefix(pathText, "{")
  1537. if pgPath && len(args) > 4 {
  1538. return nil, pgerror.InvalidParameter("%s() with a PostgreSQL path accepts at most four arguments", strings.ToLower(name))
  1539. }
  1540. if len(args) == 4 && !pgPath {
  1541. return nil, pgerror.Unsupported("%s() accepts the optional insert_after/create_if_missing argument only with a PostgreSQL text[] path; a $ path uses the JSON1 form", strings.ToLower(name))
  1542. }
  1543. flag := false
  1544. if len(args) == 4 {
  1545. if args[3] == nil {
  1546. return nil, nil
  1547. }
  1548. flag = toBool(args[3])
  1549. }
  1550. if !pgPath {
  1551. // JSON1 form: every path/value pair is applied in order. A plain SQL
  1552. // string becomes a JSON string, which is the behavior this engine exposed
  1553. // before JSONB became native; a jsonb-typed value embeds its document.
  1554. mode := "set"
  1555. switch name {
  1556. case "JSONB_INSERT":
  1557. mode = "insert"
  1558. case "JSONB_REPLACE":
  1559. mode = "replace"
  1560. }
  1561. for i := 1; i+1 < len(args); i += 2 {
  1562. if args[i] == nil || args[i+1] == nil {
  1563. return nil, nil
  1564. }
  1565. segs, pathErr := jsonbPathArg(args[i])
  1566. if pathErr != nil {
  1567. return nil, pathErr
  1568. }
  1569. var patchValue interface{}
  1570. if e.isJSONBExpr(functionArgAt(fn, i+1)) {
  1571. patchValue, err = jsonbNodeFromArg(args[i+1])
  1572. } else {
  1573. patchValue = jsonArgToNode(args[i+1])
  1574. }
  1575. if err != nil {
  1576. return nil, err
  1577. }
  1578. node, err = jsonApplyPatch(node, segs, patchValue, mode)
  1579. if err != nil {
  1580. return nil, err
  1581. }
  1582. }
  1583. return jsonbEncodeNode(node)
  1584. }
  1585. if args[2] == nil {
  1586. return nil, nil
  1587. }
  1588. newValueNode, err := jsonbNodeFromArg(args[2])
  1589. if err != nil {
  1590. return nil, err
  1591. }
  1592. segs, err := jsonbPathArg(args[1])
  1593. if err != nil {
  1594. return nil, err
  1595. }
  1596. switch name {
  1597. case "JSONB_SET":
  1598. create := true
  1599. if len(args) == 4 {
  1600. create = flag
  1601. }
  1602. node, err = jsonbSetPG(node, segs, newValueNode, create)
  1603. case "JSONB_INSERT":
  1604. node, err = jsonbInsertPG(node, segs, newValueNode, flag)
  1605. case "JSONB_REPLACE":
  1606. return nil, pgerror.Unsupported("jsonb_replace() with a PostgreSQL path is not supported; use jsonb_set or the JSON1 $ path form")
  1607. }
  1608. if err != nil {
  1609. return nil, err
  1610. }
  1611. return jsonbEncodeNode(node)
  1612. }
  1613. // jsonbTableFunction materializes a set-returning jsonb function as a relation.
  1614. // The returned types are the SQL type names used for result metadata.
  1615. func jsonbTableFunction(name string, value interface{}) (columns, types []string, rows [][]interface{}, err error) {
  1616. node, err := jsonbNodeFromArg(value)
  1617. if err != nil {
  1618. return nil, nil, nil, err
  1619. }
  1620. if value == nil {
  1621. switch strings.ToLower(name) {
  1622. case "jsonb_each":
  1623. return []string{"key", "value"}, []string{"TEXT", "JSONB"}, nil, nil
  1624. case "jsonb_each_text":
  1625. return []string{"key", "value"}, []string{"TEXT", "TEXT"}, nil, nil
  1626. case "jsonb_object_keys":
  1627. return []string{"jsonb_object_keys"}, []string{"TEXT"}, nil, nil
  1628. case "jsonb_array_elements_text":
  1629. return []string{"value"}, []string{"TEXT"}, nil, nil
  1630. default:
  1631. return []string{"value"}, []string{"JSONB"}, nil, nil
  1632. }
  1633. }
  1634. switch strings.ToLower(name) {
  1635. case "jsonb_each", "jsonb_each_text", "jsonb_object_keys":
  1636. object, ok := node.(map[string]interface{})
  1637. if !ok {
  1638. return nil, nil, nil, pgerror.InvalidParameter("cannot call %s() on a jsonb %s", strings.ToLower(name), jsonbNodeTypeName(node))
  1639. }
  1640. keys := make([]string, 0, len(object))
  1641. for key := range object {
  1642. keys = append(keys, key)
  1643. }
  1644. sort.Strings(keys)
  1645. if strings.EqualFold(name, "jsonb_object_keys") {
  1646. rows = make([][]interface{}, 0, len(keys))
  1647. for _, key := range keys {
  1648. rows = append(rows, []interface{}{key})
  1649. }
  1650. return []string{"jsonb_object_keys"}, []string{"TEXT"}, rows, nil
  1651. }
  1652. textValues := strings.EqualFold(name, "jsonb_each_text")
  1653. valueType := "JSONB"
  1654. if textValues {
  1655. valueType = "TEXT"
  1656. }
  1657. rows = make([][]interface{}, 0, len(keys))
  1658. for _, key := range keys {
  1659. var rendered interface{}
  1660. if textValues {
  1661. rendered, err = jsonbNodeToText(object[key])
  1662. } else {
  1663. rendered, err = encodeJSONB(object[key], false)
  1664. }
  1665. if err != nil {
  1666. return nil, nil, nil, err
  1667. }
  1668. rows = append(rows, []interface{}{key, rendered})
  1669. }
  1670. return []string{"key", "value"}, []string{"TEXT", valueType}, rows, nil
  1671. case "jsonb_array_elements", "jsonb_array_elements_text":
  1672. array, ok := node.([]interface{})
  1673. if !ok {
  1674. return nil, nil, nil, pgerror.InvalidParameter("cannot call %s() on a jsonb %s", strings.ToLower(name), jsonbNodeTypeName(node))
  1675. }
  1676. textValues := strings.EqualFold(name, "jsonb_array_elements_text")
  1677. valueType := "JSONB"
  1678. if textValues {
  1679. valueType = "TEXT"
  1680. }
  1681. rows = make([][]interface{}, 0, len(array))
  1682. for _, element := range array {
  1683. var rendered interface{}
  1684. if textValues {
  1685. rendered, err = jsonbNodeToText(element)
  1686. } else {
  1687. rendered, err = encodeJSONB(element, false)
  1688. }
  1689. if err != nil {
  1690. return nil, nil, nil, err
  1691. }
  1692. rows = append(rows, []interface{}{rendered})
  1693. }
  1694. return []string{"value"}, []string{valueType}, rows, nil
  1695. }
  1696. return nil, nil, nil, pgerror.Unsupported("table function %s() is not supported", name)
  1697. }
  1698. // normalizeJSONBRow canonicalizes every JSONB-typed column value before it is
  1699. // written, mirroring normalizeArrayRow. A value is canonicalized once, so a
  1700. // reload reads back the same bytes.
  1701. func (e *Executor) normalizeJSONBRow(schema *storage.Schema, row storage.Row) error {
  1702. if schema == nil {
  1703. return nil
  1704. }
  1705. for _, column := range schema.Columns {
  1706. if !strings.EqualFold(strings.TrimSpace(column.Type), "JSONB") {
  1707. continue
  1708. }
  1709. value, ok := lookupRowValue(row, column.Name)
  1710. if !ok || value == nil {
  1711. continue
  1712. }
  1713. text, isText := value.(string)
  1714. if !isText {
  1715. if jsonValue, isJSON := value.(jsonText); isJSON {
  1716. text = string(jsonValue)
  1717. } else {
  1718. return pgerror.InvalidText("column %q is %s and accepts JSON text, got %T", column.Name, column.Type, value)
  1719. }
  1720. }
  1721. canonical, err := CanonicalizeJSONB(text)
  1722. if err != nil {
  1723. return fmt.Errorf("column %q: %w", column.Name, err)
  1724. }
  1725. row[column.Name] = canonical
  1726. }
  1727. return nil
  1728. }
  1729. // canonicalJSONBDefault canonicalizes a constant DEFAULT for a JSONB column so
  1730. // the catalog and any ALTER TABLE backfill store the same bytes an INSERT would.
  1731. func canonicalJSONBDefault(typeName string, value interface{}, exprText string) (interface{}, string, error) {
  1732. if !strings.EqualFold(strings.TrimSpace(typeName), "JSONB") || exprText != "" || value == nil {
  1733. return value, exprText, nil
  1734. }
  1735. text, ok := value.(string)
  1736. if !ok {
  1737. if jsonValue, isJSON := value.(jsonText); isJSON {
  1738. text = string(jsonValue)
  1739. } else {
  1740. return nil, "", pgerror.InvalidText("DEFAULT for %s must be JSON text, got %T", typeName, value)
  1741. }
  1742. }
  1743. canonical, err := CanonicalizeJSONB(text)
  1744. if err != nil {
  1745. return nil, "", err
  1746. }
  1747. return canonical, "", nil
  1748. }