Skip to content

2-runtime/kv·get 取容器成员恒为 None(marker 在 p·k·,实读 p·k) #107

Description

@miaobyte

背景

本条已拆分:runtime 侧(取容器成员失败)留在本 issue,layout 侧(成员链 lower 为嵌套 kv·get 的值语义问题)见 #110两个根因叠加,只修一条链路仍不通。

成员容器(objindex / strkeymapindex)在存储层完全正确,但 kv·get 取「值为容器」的成员时恒返回 None。

kvlangBuiltinKvGetruntime/src/builtin.c:1409):

char *key = f->inst->nr >= 2 ? member_path(f, in) : ...;
kvlangKvGetOne(f->kv, key, &v);

member_path 拼出 p·k 后单次 Get。但容器成员的 marker 存在 p·k·(尾随分隔符),p·k 这个 key 根本不存在

实测(json·from("{\"a\":1,\"b\":{\"c\":2},\"d\":[7,8]}") -> /t):

存储层(kvspace CLI 逐 key 可读,结构与 kind 均正确):

/t·        → objindex:{3}
/t·a       → int64:1
/t·b·      → objindex:{1}          ← 注意:没有 /t·b 这个 key
/t·b·c     → int64:2
/t·d·      → strkeymapindex:map[2]{2}
/t·d·[0]   → int64:7
/t·d·[1]   → int64:8

kvlang 侧:

/t·a                  → 1     ✅ 成员值是标量
kv·get(/t, "b")       →       ❌ 成员值是容器

两行只差「成员值是标量还是容器」,这是本 issue 的最小对照。

/t·b·c/t·d·[0] 也失败,但那是 #110 的嵌套问题叠加,不由本条单独负责。

需求描述

kv·get(p, k) 在成员值为容器时返回该容器(marker),与标量成员行为一致。

预期结果

  • kv·get(/t, "b") 返回 /t·b· 的 objindex 值。
  • kv·get(/t, "d") 返回 /t·d· 的 strkeymapindex 值。
  • 成员确实不存在时返回 None(与「存在但是容器」区分开)。

方案简述

kvlangBuiltinKvGet 取值失败时回退探测 p·k·(marker key);或在 member_path 阶段先判定成员类型再决定拼哪个 key。前者少一次判定但多一次 Get,后者需要父 marker 的成员表信息——需确认 index body 的成员名列表是否已带类型标注(当前 body = [4B count][name\n...],不含类型,可能需要读子节点)。

补 tutorial 用例覆盖「容器成员取值」,纳入回归。

Related: #110, #55, #67

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions