2022.12.20 09:08 PM - edited 2022.12.20 10:04 PM
Hi Team,
I'm wondering how to use the @ (apply) paradigm to set a table column so that it accepts lists rather than atoms.
The below illustrates my problem. I can use @ (apply) to cast a column to an atomic data type but can't seem to manage to get it to a listed datatype.
// define an empy table
tbl:flip `ref`stamp`note`usr!(`symbol$();`timestamp$();"";())
//use apply to make column usr a symbol type:
@[tbl;`usr;{y$x};"s"]
// works (test using meta tbl)
//use apply to make column note a string type (nested character):
@[tbl;`usr;{y$x};"C"]
// does not work - result is a column of type c (single character) (test using meta tbl)
My question is:
Is there a way to use apply (@) to set a column in a table to a nested data type (so "C" for a string or "S" for a list of symbols for each record)?
Regards,
Simon
2022.12.21 07:23 PM - edited 2022.12.21 07:24 PM
Hi Simon,
You can leave the type of the (future) string column as empty in the table definition and let q infer the type once the first upsert occurs:
q)test: ([]test: `$(); uptar:());
q)test upsert ([]test: `rta; uptar: enlist "ra")
test uptar
----------
rta "ra"
q)meta test upsert ([]test: `rta; uptar: enlist "ra")
c | t f a
-----| -----
test | s
uptar| C
Happy Christmas!
2022.12.21 12:34 AM
meta
on an empty table will never show C
. This is because kdb+ does not have a dedicated datatype for lists of lists. The empty list will be ()
which is of type 0h
. On a populated table meta inspects the first item in a list of lists and uses it's type to populate it's result. It cannot do this on an empty table.
q)tb:([] a:1 2;b:("wo";"rd"))
q)tb
a b
------
1 "wo"
2 "rd"
q)meta tb
c| t f a
-| -----
a| j
b| C
q)delete from `tb
`tb
q)tb
a b
---
q)meta tb
c| t f a
-| -----
a| j
b|
q).Q.s1 tb
"+`a`b!(`long$();())"
2022.12.21 07:04 PM
Thanks rocuinneagain - that's good insight.
Given the above constraint, I have the following issue:
// define a table with the intention of loading a string to a columnn.
// as discussed, it is empty so 'uptar' is defined as having type "c".
test: ([]test: `$(); uptar:"C"$());
// With this done, I can't see a valid upsert to get a string into the uptar column.
test upsert ([]test: `rta; uptar: enlist "ra");
test upsert ([]test: enlist `rta; uptar: "ra");
test upsert ([]test: enlist `rta; uptar:enlist enlist "ra");
// finally, this one projects - so works but still not correctly.
test upsert ([]test: `rta; uptar: "ra");
Is it possible to insert a nested list into an empty table or must we use a 'set' workaround?
Thanks and regards,
Simon
2022.12.21 07:23 PM - edited 2022.12.21 07:24 PM
Hi Simon,
You can leave the type of the (future) string column as empty in the table definition and let q infer the type once the first upsert occurs:
q)test: ([]test: `$(); uptar:());
q)test upsert ([]test: `rta; uptar: enlist "ra")
test uptar
----------
rta "ra"
q)meta test upsert ([]test: `rta; uptar: enlist "ra")
c | t f a
-----| -----
test | s
uptar| C
Happy Christmas!
2022.12.21 09:19 PM
I AM NOT WORTHY!!!! 😉
Great to hear from you David!
Thanks to you and rocuinneagain.
I appreciate both of you taking the time.
Both of you have a eGuinness on me.
🍻 (eDrinks: like real ones but rubbish)
EMEA
Tel: +44 (0)28 3025 2242
AMERICAS
Tel: +1 (212) 447 6700
APAC
Tel: +61 (0)2 9236 5700
KX. All Rights Reserved.
KX and kdb+ are registered trademarks of KX Systems, Inc., a subsidiary of FD Technologies plc.