jsonb.go 47 KB

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