KX Community

Find answers, ask questions, and connect with our KX Community around the world.

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

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

    Posted by simon_watson_sj on December 21, 2022 at 12:00 am

    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

    simon_watson_sj replied 2 weeks, 2 days ago 3 Members · 3 Replies
  • 3 Replies
  • rocuinneagain

    Member
    December 21, 2022 at 12:00 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$();())"

     

     

  • davidcrossey

    Member
    December 22, 2022 at 12:00 am

    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!

  • simon_watson_sj

    Member
    December 22, 2022 at 12:00 am

    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

Log in to reply.