jsonb.go 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837
  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. used := make([]bool, len(containerArray))
  917. for _, candidateElement := range candidateValue {
  918. matched := false
  919. for i, containerElement := range containerArray {
  920. if used[i] {
  921. continue
  922. }
  923. if jsonbContains(containerElement, candidateElement) {
  924. used[i] = true
  925. matched = true
  926. break
  927. }
  928. }
  929. if !matched {
  930. return false
  931. }
  932. }
  933. return true
  934. }
  935. // A non-array container can still contain a nested empty array? No.
  936. return false
  937. case nil:
  938. return container == nil
  939. case bool:
  940. other, ok := container.(bool)
  941. return ok && other == candidateValue
  942. case string:
  943. other, ok := container.(string)
  944. return ok && other == candidateValue
  945. case json.Number:
  946. candidateText, err := canonicalJSONBNumber(candidateValue)
  947. if err != nil {
  948. return false
  949. }
  950. other, ok := container.(json.Number)
  951. if !ok {
  952. return false
  953. }
  954. containerText, err := canonicalJSONBNumber(other)
  955. if err != nil {
  956. return false
  957. }
  958. return containerText == candidateText
  959. }
  960. return false
  961. }
  962. // jsonbNodeTypeName returns the PostgreSQL jsonb type name.
  963. func jsonbNodeTypeName(node interface{}) string {
  964. switch node.(type) {
  965. case nil:
  966. return "null"
  967. case bool:
  968. return "boolean"
  969. case json.Number:
  970. return "number"
  971. case string:
  972. return "string"
  973. case []interface{}:
  974. return "array"
  975. case map[string]interface{}:
  976. return "object"
  977. default:
  978. return "unknown"
  979. }
  980. }
  981. // jsonbPathArg resolves a path operand to path steps. A text[] value (canonical
  982. // array text) is PostgreSQL's path form; a $string is the JSON1 path form this
  983. // engine already uses for -> and json_extract.
  984. func jsonbPathArg(value interface{}) ([]jsonPathSeg, error) {
  985. text := strings.TrimSpace(toString(value))
  986. switch {
  987. case strings.HasPrefix(text, "{"):
  988. return parseJSONBArrayPath(text)
  989. case strings.HasPrefix(text, "$"):
  990. return parseJSONBJSONPath(text)
  991. default:
  992. return nil, pgerror.InvalidParameter("jsonb path must be a text[] array literal such as '{a,0}' or a $ path, got %q", text)
  993. }
  994. }
  995. // jsonbKeyListArg parses a text[] of object keys. Unlike a path, every element
  996. // is a key: a numeric-looking key such as "1" must not become an array index.
  997. func jsonbKeyListArg(value interface{}) ([]string, error) {
  998. text := strings.TrimSpace(toString(value))
  999. if !strings.HasPrefix(text, "{") {
  1000. return nil, pgerror.InvalidParameter("jsonb key list must be a text[] array literal, got %q", text)
  1001. }
  1002. elements, err := parseArrayLiteral(text)
  1003. if err != nil {
  1004. return nil, err
  1005. }
  1006. keys := make([]string, 0, len(elements))
  1007. for _, element := range elements {
  1008. if element == nil {
  1009. return nil, pgerror.InvalidParameter("jsonb key list element must not be NULL")
  1010. }
  1011. keys = append(keys, *element)
  1012. }
  1013. return keys, nil
  1014. }
  1015. // parseJSONBArrayPath parses PostgreSQL text[] path text into steps. A path
  1016. // element is kept as raw text because its meaning depends on the container it
  1017. // is applied to: an object key, or an integer array index. Numeric-looking
  1018. // object keys such as "1", "01", "-1", and "1.5" therefore stay keys when the
  1019. // container is an object.
  1020. func parseJSONBArrayPath(text string) ([]jsonPathSeg, error) {
  1021. elements, err := parseArrayLiteral(text)
  1022. if err != nil {
  1023. return nil, err
  1024. }
  1025. segs := make([]jsonPathSeg, 0, len(elements))
  1026. for _, element := range elements {
  1027. if element == nil {
  1028. return nil, pgerror.InvalidParameter("jsonb path element must not be NULL")
  1029. }
  1030. segs = append(segs, jsonPathSeg{dynamic: true, element: *element})
  1031. }
  1032. return segs, nil
  1033. }
  1034. // resolveJSONBPathSegment converts a PostgreSQL path element into a concrete
  1035. // object key or array index for the container it is applied to. Concrete steps
  1036. // (JSON1 $ paths and index/key steps) pass through unchanged. resolved is false
  1037. // when container is a scalar or missing; callers decide whether that is a
  1038. // not-found, an unchanged target, or an error. strict selects whether a
  1039. // non-integer element on an array is an error (jsonb path mutation and #-) or a
  1040. // non-match (jsonb #>).
  1041. func resolveJSONBPathSegment(seg jsonPathSeg, container interface{}, strict bool) (jsonPathSeg, bool, error) {
  1042. if !seg.dynamic {
  1043. return seg, true, nil
  1044. }
  1045. switch container.(type) {
  1046. case map[string]interface{}:
  1047. return jsonPathSeg{key: seg.element}, true, nil
  1048. case []interface{}:
  1049. index, err := strconv.Atoi(seg.element)
  1050. if err != nil {
  1051. if strict {
  1052. return seg, false, pgerror.InvalidText("path element %q is not an integer", seg.element)
  1053. }
  1054. return seg, false, nil
  1055. }
  1056. return jsonPathSeg{isIndex: true, index: index, fromEnd: index < 0}, true, nil
  1057. default:
  1058. return seg, false, nil
  1059. }
  1060. }
  1061. // parseJSONBJSONPath parses a JSON1 $ path for jsonb use and rejects the
  1062. // jsonpath shapes the engine cannot execute (wildcards, slices, unbounded
  1063. // expansion) with SQLSTATE 0A000.
  1064. func parseJSONBJSONPath(path string) ([]jsonPathSeg, error) {
  1065. if unsupportedJSONPathShape(path) {
  1066. return nil, pgerror.Unsupported("jsonpath wildcards, slices, and unbounded expansion are not supported; pass an explicit path")
  1067. }
  1068. segs, err := parseJSONPath(path)
  1069. if err != nil {
  1070. return nil, err
  1071. }
  1072. for _, segment := range segs {
  1073. if !segment.isIndex && (segment.key == "*" || strings.HasPrefix(segment.key, "**")) {
  1074. return nil, pgerror.Unsupported("jsonpath wildcards and unbounded expansion are not supported; pass an explicit path")
  1075. }
  1076. }
  1077. return segs, nil
  1078. }
  1079. // unsupportedJSONPathShape reports whether path text contains a jsonpath
  1080. // wildcard, slice, or deep-expansion marker inside brackets or as a bare member.
  1081. func unsupportedJSONPathShape(path string) bool {
  1082. for i := 0; i < len(path); i++ {
  1083. if path[i] != '[' {
  1084. continue
  1085. }
  1086. end := strings.IndexByte(path[i:], ']')
  1087. if end < 0 {
  1088. return false
  1089. }
  1090. inner := path[i+1 : i+end]
  1091. if strings.ContainsAny(inner, "*:") {
  1092. return true
  1093. }
  1094. i += end
  1095. }
  1096. return false
  1097. }
  1098. // jsonbSetPG implements PostgreSQL's jsonb_set path semantics. An empty path
  1099. // leaves the target unchanged. All steps except the last must exist and be
  1100. // containers; missing keys or a scalar on the way leave the target unchanged. A
  1101. // missing array position at the last step is appended when create is true, and
  1102. // an index before the start is clamped to the first position.
  1103. func jsonbSetPG(node interface{}, segs []jsonPathSeg, value interface{}, create bool) (interface{}, error) {
  1104. if len(segs) == 0 {
  1105. return node, nil
  1106. }
  1107. segment, resolved, err := resolveJSONBPathSegment(segs[0], node, true)
  1108. if err != nil {
  1109. return nil, err
  1110. }
  1111. if !resolved {
  1112. return nil, pgerror.InvalidParameter("cannot set path in scalar")
  1113. }
  1114. if len(segs) > 1 {
  1115. child, exists, err := jsonbPathChild(node, segment)
  1116. if err != nil {
  1117. return nil, err
  1118. }
  1119. if !exists {
  1120. return node, nil
  1121. }
  1122. switch child.(type) {
  1123. case map[string]interface{}, []interface{}:
  1124. default:
  1125. // PostgreSQL leaves the target unchanged when an intermediate step
  1126. // names a scalar rather than a container.
  1127. return node, nil
  1128. }
  1129. updated, err := jsonbSetPG(child, segs[1:], value, create)
  1130. if err != nil {
  1131. return nil, err
  1132. }
  1133. return jsonbReplaceChild(node, segment, updated)
  1134. }
  1135. switch container := node.(type) {
  1136. case map[string]interface{}:
  1137. if segment.isIndex {
  1138. return nil, pgerror.InvalidText("path element is not an object key")
  1139. }
  1140. if _, exists := container[segment.key]; !exists && !create {
  1141. return node, nil
  1142. }
  1143. out := make(map[string]interface{}, len(container)+1)
  1144. for key, item := range container {
  1145. out[key] = item
  1146. }
  1147. out[segment.key] = value
  1148. return out, nil
  1149. case []interface{}:
  1150. if !segment.isIndex {
  1151. return nil, pgerror.InvalidText("path element %q is not an integer", segment.key)
  1152. }
  1153. index := segment.index
  1154. if index < 0 {
  1155. index += len(container)
  1156. }
  1157. if index < 0 {
  1158. if !create {
  1159. return node, nil
  1160. }
  1161. out := make([]interface{}, 0, len(container)+1)
  1162. out = append(out, value)
  1163. return append(out, container...), nil
  1164. }
  1165. if index >= len(container) {
  1166. if !create {
  1167. return node, nil
  1168. }
  1169. out := append([]interface{}{}, container...)
  1170. return append(out, value), nil
  1171. }
  1172. out := append([]interface{}{}, container...)
  1173. out[index] = value
  1174. return out, nil
  1175. default:
  1176. return nil, pgerror.InvalidParameter("cannot set path in scalar")
  1177. }
  1178. }
  1179. // jsonbInsertPG implements PostgreSQL's jsonb_insert path semantics: array
  1180. // elements are inserted before or after an index (clamped into range), and an
  1181. // object key is inserted only when it is absent. An existing object key is an
  1182. // error, matching PostgreSQL.
  1183. func jsonbInsertPG(node interface{}, segs []jsonPathSeg, value interface{}, after bool) (interface{}, error) {
  1184. if len(segs) == 0 {
  1185. return node, nil
  1186. }
  1187. segment, resolved, err := resolveJSONBPathSegment(segs[0], node, true)
  1188. if err != nil {
  1189. return nil, err
  1190. }
  1191. if !resolved {
  1192. return nil, pgerror.InvalidParameter("cannot set path in scalar")
  1193. }
  1194. if len(segs) > 1 {
  1195. child, exists, err := jsonbPathChild(node, segment)
  1196. if err != nil {
  1197. return nil, err
  1198. }
  1199. if !exists {
  1200. return node, nil
  1201. }
  1202. switch child.(type) {
  1203. case map[string]interface{}, []interface{}:
  1204. default:
  1205. return node, nil
  1206. }
  1207. updated, err := jsonbInsertPG(child, segs[1:], value, after)
  1208. if err != nil {
  1209. return nil, err
  1210. }
  1211. return jsonbReplaceChild(node, segment, updated)
  1212. }
  1213. switch container := node.(type) {
  1214. case map[string]interface{}:
  1215. if segment.isIndex {
  1216. return nil, pgerror.InvalidText("path element is not an object key")
  1217. }
  1218. if _, exists := container[segment.key]; exists {
  1219. return nil, pgerror.InvalidParameter("cannot replace existing key")
  1220. }
  1221. out := make(map[string]interface{}, len(container)+1)
  1222. for key, item := range container {
  1223. out[key] = item
  1224. }
  1225. out[segment.key] = value
  1226. return out, nil
  1227. case []interface{}:
  1228. if !segment.isIndex {
  1229. return nil, pgerror.InvalidText("path element %q is not an integer", segment.key)
  1230. }
  1231. index := segment.index
  1232. if index < 0 {
  1233. index += len(container)
  1234. }
  1235. if index < 0 {
  1236. index = 0
  1237. }
  1238. if index > len(container) {
  1239. index = len(container)
  1240. }
  1241. if after {
  1242. index++
  1243. }
  1244. if index > len(container) {
  1245. index = len(container)
  1246. }
  1247. out := make([]interface{}, 0, len(container)+1)
  1248. out = append(out, container[:index]...)
  1249. out = append(out, value)
  1250. out = append(out, container[index:]...)
  1251. return out, nil
  1252. default:
  1253. return nil, pgerror.InvalidParameter("cannot set path in scalar")
  1254. }
  1255. }
  1256. // jsonbPathChild resolves one non-final path step to an existing child.
  1257. func jsonbPathChild(node interface{}, segment jsonPathSeg) (interface{}, bool, error) {
  1258. switch container := node.(type) {
  1259. case map[string]interface{}:
  1260. if segment.isIndex {
  1261. return nil, false, pgerror.InvalidParameter("jsonb path element %d does not identify an object key", segment.index)
  1262. }
  1263. child, exists := container[segment.key]
  1264. return child, exists, nil
  1265. case []interface{}:
  1266. if !segment.isIndex {
  1267. return nil, false, pgerror.InvalidParameter("jsonb path element %q does not identify an array index", segment.key)
  1268. }
  1269. index := segment.index
  1270. if index < 0 {
  1271. index += len(container)
  1272. }
  1273. if index < 0 || index >= len(container) {
  1274. return nil, false, nil
  1275. }
  1276. return container[index], true, nil
  1277. default:
  1278. return nil, false, pgerror.InvalidParameter("cannot walk a jsonb path through a %s", jsonbNodeTypeName(node))
  1279. }
  1280. }
  1281. // jsonbReplaceChild writes an updated child back into its container.
  1282. func jsonbReplaceChild(node interface{}, segment jsonPathSeg, child interface{}) (interface{}, error) {
  1283. switch container := node.(type) {
  1284. case map[string]interface{}:
  1285. if segment.isIndex {
  1286. return nil, pgerror.InvalidParameter("jsonb path element %d does not identify an object key", segment.index)
  1287. }
  1288. out := make(map[string]interface{}, len(container)+1)
  1289. for key, item := range container {
  1290. out[key] = item
  1291. }
  1292. out[segment.key] = child
  1293. return out, nil
  1294. case []interface{}:
  1295. if !segment.isIndex {
  1296. return nil, pgerror.InvalidParameter("jsonb path element %q does not identify an array index", segment.key)
  1297. }
  1298. index := segment.index
  1299. if index < 0 {
  1300. index += len(container)
  1301. }
  1302. if index < 0 || index >= len(container) {
  1303. return nil, pgerror.InvalidParameter("jsonb path array index %d is out of range", segment.index)
  1304. }
  1305. out := append([]interface{}{}, container...)
  1306. out[index] = child
  1307. return out, nil
  1308. default:
  1309. return nil, pgerror.InvalidParameter("cannot write a jsonb path through a %s", jsonbNodeTypeName(node))
  1310. }
  1311. }
  1312. // jsonbStripNulls removes object members whose value is JSON null. Array
  1313. // elements are kept, matching jsonb_strip_nulls.
  1314. func jsonbStripNulls(node interface{}) interface{} {
  1315. switch value := node.(type) {
  1316. case map[string]interface{}:
  1317. out := make(map[string]interface{}, len(value))
  1318. for key, item := range value {
  1319. if item == nil {
  1320. continue
  1321. }
  1322. out[key] = jsonbStripNulls(item)
  1323. }
  1324. return out
  1325. case []interface{}:
  1326. out := make([]interface{}, len(value))
  1327. for i, item := range value {
  1328. out[i] = jsonbStripNulls(item)
  1329. }
  1330. return out
  1331. default:
  1332. return node
  1333. }
  1334. }
  1335. // jsonbEncodeNode canonicalizes a tree that has already been validated.
  1336. func jsonbEncodeNode(node interface{}) (string, error) {
  1337. return encodeJSONB(node, false)
  1338. }
  1339. // evalJSONBFunction evaluates a native jsonb scalar function. handled is false
  1340. // for names it does not own, keeping the JSON1 surface untouched.
  1341. func (e *Executor) evalJSONBFunction(name string, fn *parser.FunctionCall, args []interface{}) (interface{}, bool, error) {
  1342. upper := strings.ToUpper(name)
  1343. switch upper {
  1344. case "TO_JSONB":
  1345. if len(args) != 1 {
  1346. return nil, true, pgerror.InvalidParameter("to_jsonb() requires exactly one argument")
  1347. }
  1348. if args[0] == nil {
  1349. return nil, true, nil
  1350. }
  1351. node, err := e.toJSONBNode(firstFunctionArg(fn), args[0])
  1352. if err != nil {
  1353. return nil, true, err
  1354. }
  1355. text, err := jsonbEncodeNode(node)
  1356. return text, true, err
  1357. case "JSONB_TYPEOF":
  1358. if len(args) != 1 {
  1359. return nil, true, pgerror.InvalidParameter("jsonb_typeof() requires exactly one argument")
  1360. }
  1361. node, err := jsonbNodeFromArg(args[0])
  1362. if err != nil {
  1363. return nil, true, err
  1364. }
  1365. if node == nil && args[0] == nil {
  1366. return nil, true, nil
  1367. }
  1368. return jsonbNodeTypeName(node), true, nil
  1369. case "JSONB_ARRAY_LENGTH":
  1370. if len(args) != 1 {
  1371. return nil, true, pgerror.InvalidParameter("jsonb_array_length() requires exactly one argument")
  1372. }
  1373. node, err := jsonbNodeFromArg(args[0])
  1374. if err != nil {
  1375. return nil, true, err
  1376. }
  1377. if node == nil && args[0] == nil {
  1378. return nil, true, nil
  1379. }
  1380. array, ok := node.([]interface{})
  1381. if !ok {
  1382. return nil, true, pgerror.InvalidParameter("cannot get array length of a jsonb %s", jsonbNodeTypeName(node))
  1383. }
  1384. return int64(len(array)), true, nil
  1385. case "JSONB_PRETTY":
  1386. if len(args) != 1 {
  1387. return nil, true, pgerror.InvalidParameter("jsonb_pretty() requires exactly one argument")
  1388. }
  1389. if args[0] == nil {
  1390. return nil, true, nil
  1391. }
  1392. node, err := jsonbNodeFromArg(args[0])
  1393. if err != nil {
  1394. return nil, true, err
  1395. }
  1396. text, err := encodeJSONB(node, true)
  1397. return text, true, err
  1398. case "JSONB_STRIP_NULLS":
  1399. if len(args) != 1 {
  1400. return nil, true, pgerror.InvalidParameter("jsonb_strip_nulls() requires exactly one argument")
  1401. }
  1402. if args[0] == nil {
  1403. return nil, true, nil
  1404. }
  1405. node, err := jsonbNodeFromArg(args[0])
  1406. if err != nil {
  1407. return nil, true, err
  1408. }
  1409. text, err := jsonbEncodeNode(jsonbStripNulls(node))
  1410. return text, true, err
  1411. case "JSONB_BUILD_ARRAY":
  1412. values := make([]interface{}, len(args))
  1413. for i, arg := range args {
  1414. node, err := e.toJSONBNode(functionArgAt(fn, i), arg)
  1415. if err != nil {
  1416. return nil, true, err
  1417. }
  1418. values[i] = node
  1419. }
  1420. text, err := jsonbEncodeNode(values)
  1421. return text, true, err
  1422. case "JSONB_BUILD_OBJECT":
  1423. if len(args)%2 != 0 {
  1424. return nil, true, pgerror.InvalidParameter("jsonb_build_object() argument list must have an even number of elements")
  1425. }
  1426. object := make(map[string]interface{}, len(args)/2)
  1427. for i := 0; i+1 < len(args); i += 2 {
  1428. if args[i] == nil {
  1429. return nil, true, pgerror.InvalidParameter("jsonb_build_object() argument %d: key must not be null", i+1)
  1430. }
  1431. key := toString(args[i])
  1432. node, err := e.toJSONBNode(functionArgAt(fn, i+1), args[i+1])
  1433. if err != nil {
  1434. return nil, true, err
  1435. }
  1436. object[key] = node
  1437. }
  1438. text, err := jsonbEncodeNode(object)
  1439. return text, true, err
  1440. case "JSONB_SET", "JSONB_INSERT", "JSONB_REPLACE", "JSONB_REMOVE":
  1441. value, err := e.evalJSONBPatch(upper, fn, args)
  1442. return value, true, err
  1443. case "JSONB_EACH", "JSONB_EACH_TEXT", "JSONB_ARRAY_ELEMENTS", "JSONB_ARRAY_ELEMENTS_TEXT", "JSONB_OBJECT_KEYS":
  1444. 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))
  1445. case "JSONB_PATH_EXISTS", "JSONB_PATH_EXISTS_TZ", "JSONB_PATH_MATCH", "JSONB_PATH_MATCH_TZ",
  1446. "JSONB_PATH_QUERY", "JSONB_PATH_QUERY_TZ", "JSONB_PATH_QUERY_ARRAY", "JSONB_PATH_QUERY_ARRAY_TZ",
  1447. "JSONB_PATH_QUERY_FIRST", "JSONB_PATH_QUERY_FIRST_TZ":
  1448. return nil, true, pgerror.Unsupported("jsonpath (%s) is not supported", strings.ToLower(name))
  1449. }
  1450. return nil, false, nil
  1451. }
  1452. // firstFunctionArg returns the first argument expression of a call, or nil when
  1453. // the call has no arguments.
  1454. func firstFunctionArg(fn *parser.FunctionCall) parser.Expr {
  1455. if fn == nil || len(fn.Args) == 0 {
  1456. return nil
  1457. }
  1458. return fn.Args[0]
  1459. }
  1460. func functionArgAt(fn *parser.FunctionCall, index int) parser.Expr {
  1461. if fn == nil || index < 0 || index >= len(fn.Args) {
  1462. return nil
  1463. }
  1464. return fn.Args[index]
  1465. }
  1466. // toJSONBNode converts a SQL value to a JSON tree node, decoding arrays into
  1467. // JSON arrays so to_jsonb(jsonb_build_array(...)) and to_jsonb(array_column)
  1468. // keep their element types.
  1469. func (e *Executor) toJSONBNode(expr parser.Expr, value interface{}) (interface{}, error) {
  1470. if value == nil {
  1471. return nil, nil
  1472. }
  1473. // to_jsonb(jsonb) is the identity: a jsonb argument is embedded as its
  1474. // document, not as a JSON string.
  1475. if e.isJSONBExpr(expr) {
  1476. return jsonbNodeFromArg(value)
  1477. }
  1478. if typeName, ok := e.arrayTypeOf(expr); ok {
  1479. elements, err := parseArrayLiteral(toString(value))
  1480. if err != nil {
  1481. return nil, err
  1482. }
  1483. elementType, _ := arrayElementType(typeName)
  1484. nodes := make([]interface{}, len(elements))
  1485. for i, element := range elements {
  1486. typed, valueErr := arrayElementValue(element, elementType)
  1487. if valueErr != nil {
  1488. return nil, valueErr
  1489. }
  1490. node, nodeErr := jsonbNodeFromSQLValue(typed)
  1491. if nodeErr != nil {
  1492. return nil, nodeErr
  1493. }
  1494. nodes[i] = node
  1495. }
  1496. return nodes, nil
  1497. }
  1498. return jsonbNodeFromSQLValue(value)
  1499. }
  1500. // evalJSONBPatch evaluates the jsonb_set/jsonb_insert/jsonb_replace/
  1501. // jsonb_remove family. A $ path keeps the JSON1 semantics the engine already
  1502. // exposed; a PostgreSQL text[] path uses PostgreSQL's jsonb_set/jsonb_insert
  1503. // rules and accepts the optional boolean fourth argument.
  1504. func (e *Executor) evalJSONBPatch(name string, fn *parser.FunctionCall, args []interface{}) (interface{}, error) {
  1505. minArgs := 2
  1506. if name != "JSONB_REMOVE" {
  1507. minArgs = 3
  1508. }
  1509. if len(args) < minArgs {
  1510. return nil, pgerror.InvalidParameter("%s() requires at least %d arguments", strings.ToLower(name), minArgs)
  1511. }
  1512. if args[0] == nil || args[1] == nil {
  1513. return nil, nil
  1514. }
  1515. node, err := jsonbNodeFromArg(args[0])
  1516. if err != nil {
  1517. return nil, err
  1518. }
  1519. if name == "JSONB_REMOVE" {
  1520. for _, path := range args[1:] {
  1521. if path == nil {
  1522. return nil, nil
  1523. }
  1524. segs, pathErr := jsonbPathArg(path)
  1525. if pathErr != nil {
  1526. return nil, pathErr
  1527. }
  1528. node, err = jsonRemove(node, segs)
  1529. if err != nil {
  1530. return nil, err
  1531. }
  1532. }
  1533. return jsonbEncodeNode(node)
  1534. }
  1535. // JSON1 multi-path form: jsonb_set(doc, path, value, path, value, ...).
  1536. // PostgreSQL's form has exactly three or four arguments.
  1537. pathText := strings.TrimSpace(toString(args[1]))
  1538. pgPath := strings.HasPrefix(pathText, "{")
  1539. if pgPath && len(args) > 4 {
  1540. return nil, pgerror.InvalidParameter("%s() with a PostgreSQL path accepts at most four arguments", strings.ToLower(name))
  1541. }
  1542. if len(args) == 4 && !pgPath {
  1543. 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))
  1544. }
  1545. flag := false
  1546. if len(args) == 4 {
  1547. if args[3] == nil {
  1548. return nil, nil
  1549. }
  1550. flag = toBool(args[3])
  1551. }
  1552. if !pgPath {
  1553. // JSON1 form: every path/value pair is applied in order. A plain SQL
  1554. // string becomes a JSON string, which is the behavior this engine exposed
  1555. // before JSONB became native; a jsonb-typed value embeds its document.
  1556. mode := "set"
  1557. switch name {
  1558. case "JSONB_INSERT":
  1559. mode = "insert"
  1560. case "JSONB_REPLACE":
  1561. mode = "replace"
  1562. }
  1563. for i := 1; i+1 < len(args); i += 2 {
  1564. if args[i] == nil || args[i+1] == nil {
  1565. return nil, nil
  1566. }
  1567. segs, pathErr := jsonbPathArg(args[i])
  1568. if pathErr != nil {
  1569. return nil, pathErr
  1570. }
  1571. var patchValue interface{}
  1572. if e.isJSONBExpr(functionArgAt(fn, i+1)) {
  1573. patchValue, err = jsonbNodeFromArg(args[i+1])
  1574. } else {
  1575. patchValue = jsonArgToNode(args[i+1])
  1576. }
  1577. if err != nil {
  1578. return nil, err
  1579. }
  1580. node, err = jsonApplyPatch(node, segs, patchValue, mode)
  1581. if err != nil {
  1582. return nil, err
  1583. }
  1584. }
  1585. return jsonbEncodeNode(node)
  1586. }
  1587. if args[2] == nil {
  1588. return nil, nil
  1589. }
  1590. newValueNode, err := jsonbNodeFromArg(args[2])
  1591. if err != nil {
  1592. return nil, err
  1593. }
  1594. segs, err := jsonbPathArg(args[1])
  1595. if err != nil {
  1596. return nil, err
  1597. }
  1598. switch name {
  1599. case "JSONB_SET":
  1600. create := true
  1601. if len(args) == 4 {
  1602. create = flag
  1603. }
  1604. node, err = jsonbSetPG(node, segs, newValueNode, create)
  1605. case "JSONB_INSERT":
  1606. node, err = jsonbInsertPG(node, segs, newValueNode, flag)
  1607. case "JSONB_REPLACE":
  1608. return nil, pgerror.Unsupported("jsonb_replace() with a PostgreSQL path is not supported; use jsonb_set or the JSON1 $ path form")
  1609. }
  1610. if err != nil {
  1611. return nil, err
  1612. }
  1613. return jsonbEncodeNode(node)
  1614. }
  1615. // jsonbTableFunction materializes a set-returning jsonb function as a relation.
  1616. // The returned types are the SQL type names used for result metadata.
  1617. func jsonbTableFunction(name string, value interface{}) (columns, types []string, rows [][]interface{}, err error) {
  1618. node, err := jsonbNodeFromArg(value)
  1619. if err != nil {
  1620. return nil, nil, nil, err
  1621. }
  1622. if value == nil {
  1623. switch strings.ToLower(name) {
  1624. case "jsonb_each":
  1625. return []string{"key", "value"}, []string{"TEXT", "JSONB"}, nil, nil
  1626. case "jsonb_each_text":
  1627. return []string{"key", "value"}, []string{"TEXT", "TEXT"}, nil, nil
  1628. case "jsonb_object_keys":
  1629. return []string{"jsonb_object_keys"}, []string{"TEXT"}, nil, nil
  1630. case "jsonb_array_elements_text":
  1631. return []string{"value"}, []string{"TEXT"}, nil, nil
  1632. default:
  1633. return []string{"value"}, []string{"JSONB"}, nil, nil
  1634. }
  1635. }
  1636. switch strings.ToLower(name) {
  1637. case "jsonb_each", "jsonb_each_text", "jsonb_object_keys":
  1638. object, ok := node.(map[string]interface{})
  1639. if !ok {
  1640. return nil, nil, nil, pgerror.InvalidParameter("cannot call %s() on a jsonb %s", strings.ToLower(name), jsonbNodeTypeName(node))
  1641. }
  1642. keys := make([]string, 0, len(object))
  1643. for key := range object {
  1644. keys = append(keys, key)
  1645. }
  1646. sort.Strings(keys)
  1647. if strings.EqualFold(name, "jsonb_object_keys") {
  1648. rows = make([][]interface{}, 0, len(keys))
  1649. for _, key := range keys {
  1650. rows = append(rows, []interface{}{key})
  1651. }
  1652. return []string{"jsonb_object_keys"}, []string{"TEXT"}, rows, nil
  1653. }
  1654. textValues := strings.EqualFold(name, "jsonb_each_text")
  1655. valueType := "JSONB"
  1656. if textValues {
  1657. valueType = "TEXT"
  1658. }
  1659. rows = make([][]interface{}, 0, len(keys))
  1660. for _, key := range keys {
  1661. var rendered interface{}
  1662. if textValues {
  1663. rendered, err = jsonbNodeToText(object[key])
  1664. } else {
  1665. rendered, err = encodeJSONB(object[key], false)
  1666. }
  1667. if err != nil {
  1668. return nil, nil, nil, err
  1669. }
  1670. rows = append(rows, []interface{}{key, rendered})
  1671. }
  1672. return []string{"key", "value"}, []string{"TEXT", valueType}, rows, nil
  1673. case "jsonb_array_elements", "jsonb_array_elements_text":
  1674. array, ok := node.([]interface{})
  1675. if !ok {
  1676. return nil, nil, nil, pgerror.InvalidParameter("cannot call %s() on a jsonb %s", strings.ToLower(name), jsonbNodeTypeName(node))
  1677. }
  1678. textValues := strings.EqualFold(name, "jsonb_array_elements_text")
  1679. valueType := "JSONB"
  1680. if textValues {
  1681. valueType = "TEXT"
  1682. }
  1683. rows = make([][]interface{}, 0, len(array))
  1684. for _, element := range array {
  1685. var rendered interface{}
  1686. if textValues {
  1687. rendered, err = jsonbNodeToText(element)
  1688. } else {
  1689. rendered, err = encodeJSONB(element, false)
  1690. }
  1691. if err != nil {
  1692. return nil, nil, nil, err
  1693. }
  1694. rows = append(rows, []interface{}{rendered})
  1695. }
  1696. return []string{"value"}, []string{valueType}, rows, nil
  1697. }
  1698. return nil, nil, nil, pgerror.Unsupported("table function %s() is not supported", name)
  1699. }
  1700. // normalizeJSONBRow canonicalizes every JSONB-typed column value before it is
  1701. // written, mirroring normalizeArrayRow. A value is canonicalized once, so a
  1702. // reload reads back the same bytes.
  1703. func (e *Executor) normalizeJSONBRow(schema *storage.Schema, row storage.Row) error {
  1704. if schema == nil {
  1705. return nil
  1706. }
  1707. for _, column := range schema.Columns {
  1708. if !strings.EqualFold(strings.TrimSpace(column.Type), "JSONB") {
  1709. continue
  1710. }
  1711. value, ok := lookupRowValue(row, column.Name)
  1712. if !ok || value == nil {
  1713. continue
  1714. }
  1715. text, isText := value.(string)
  1716. if !isText {
  1717. if jsonValue, isJSON := value.(jsonText); isJSON {
  1718. text = string(jsonValue)
  1719. } else {
  1720. return pgerror.InvalidText("column %q is %s and accepts JSON text, got %T", column.Name, column.Type, value)
  1721. }
  1722. }
  1723. canonical, err := CanonicalizeJSONB(text)
  1724. if err != nil {
  1725. return fmt.Errorf("column %q: %w", column.Name, err)
  1726. }
  1727. row[column.Name] = canonical
  1728. }
  1729. return nil
  1730. }
  1731. // canonicalJSONBDefault canonicalizes a constant DEFAULT for a JSONB column so
  1732. // the catalog and any ALTER TABLE backfill store the same bytes an INSERT would.
  1733. func canonicalJSONBDefault(typeName string, value interface{}, exprText string) (interface{}, string, error) {
  1734. if !strings.EqualFold(strings.TrimSpace(typeName), "JSONB") || exprText != "" || value == nil {
  1735. return value, exprText, nil
  1736. }
  1737. text, ok := value.(string)
  1738. if !ok {
  1739. if jsonValue, isJSON := value.(jsonText); isJSON {
  1740. text = string(jsonValue)
  1741. } else {
  1742. return nil, "", pgerror.InvalidText("DEFAULT for %s must be JSON text, got %T", typeName, value)
  1743. }
  1744. }
  1745. canonical, err := CanonicalizeJSONB(text)
  1746. if err != nil {
  1747. return nil, "", err
  1748. }
  1749. return canonical, "", nil
  1750. }