formatting a table with @ (apply) to use lists as a format type (for example symbol "s" is "S")

https://learninghub.kx.com/forums/topic/formatting-a-table-with-apply-to-use-lists-as-a-format-type-for-example-symbol-s-is-s

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 empty 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

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!

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$();())"

 

 

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