Forum Replies Created

  • dcrossey

    Member
    September 24, 2021 at 12:00 am in reply to: SQL query to Functional query[Parse Tree]

    You could update the type of each time column for each table in your dictionary as follows:

     

    q)t1:([]c1:`a`b`c;c2:1 2 3;c3:("10:00";"10:30";"11:00")) 
    q)t2:([]c1:`d`e`f;c2:4 5 6;c4:("09:00";"10:30";"11:30")) 
    q)d:`t1`t2!(t1;t2) 
    q)d[`t1] 
    c1 c2 c3 
    ------------- 
    a 1 "10:00" 
    b 2 "10:30" 
    c 3 "11:00" 
    
    q)d2:{![x;();0b;enlist[y]!enlist ($;"T";y)]}'[d;`c3`c4] 
    q)d2[`t1] 
    c1 c2 c3 
    ------------------ 
    a 1 10:00:00.000 
    b 2 10:30:00.000 
    c 3 11:00:00.000

     

    This is an example of using binary each (also known as each both), passing in one key/value of the dictionary and one column per iteration into the lambda.

    Note – I’ve used time only “T” as a brief example here. I noticed you were using lower case “p” – if your time/date column is a string column, you’ll need to use upper case “P” to cast correctly.

    Cheers,

    David

  • dcrossey

    Member
    September 24, 2021 at 12:00 am in reply to: SQL query to Functional query[Parse Tree]

    Hi Richard,

    Instead of using the list structure, try simply using the dictionary with the key as the first clause e.g.

    q)t1:([]c1:`a`b`c;c2:1 2 3); 
    q)t2:([]c1:`d`e`f;c2:4 5 6); 
    q)d:`t1`t2!(t1;t2); 
    q)d 
    t1| +`c1`c2!(`a`b`c;1 2 3) 
    t2| +`c1`c2!(`d`e`f;4 5 6)  
    q)?[d[`t1];();0b;()]; 
    c1 c2 
    ----- 
    a  1 
    b  2 
    c  3

    Note – If you are purely selecting from the dictionary, you don’t need to use functional form at all. Simply pass the table name key into your dictionary:

    q)d[`t1] 
    c1 c2 
    ----- 
    a  1 
    b  2 
    c  3  
    q)d[`t2] 
    c1 c2 
    ----- 
    d  4 
    e  5 
    f  6

    Hope this helps,

    David

  • dcrossey

    Member
    August 10, 2021 at 12:00 am in reply to: Dashboards – action triggers on page load

    Hi Nick,

    Using the following as an example:

     

    When I come to the dashboard, the text viewstate is present. There is a virtual query however it does not wipe this viewstate.

    When I press clear, it activates the viewstate and clears the text.

     

    If I refresh the screen, the default text “Hello World” is present:

     

    or if I click reset text it will add “Hello World (again):

     

    Button Actions

     

    Virtual query

     

    Result

     

    Output mapping

     

     

    Unfortunately I’m not able to attach json (example dashboard) on the Community portal yet, however I’ll drop you an email to see if it helps solve your issue.

    Kind regards,

    David

    Virtual Query

     

    function (source, enabled, callback) { 
       var result = { meta: { k:11, v:11 }, columns: [ "k", "v" ], rows: [] }; 
       if(enabled) { console.log('Clearing viewstates'); 
           result.rows = [ {k:'text', v:null}, {k:'triggerEnabled', v:false} ]; } 
       else { console.log('Returning current'); 
           result.rows= [ {k:'text', v:source}, {k:'triggerEnabled', v:enabled} ]; } 
       callback(result); }

     

     

  • dcrossey

    Member
    August 10, 2021 at 12:00 am in reply to: Dashboards – action triggers on page load

    Hi Nick,

    I’ve updated the skeleton to make it a little clearer. When the page first loads, this virtual query will run but will not clear your parameters if you return the input without modifying.

    It should only run the clear logic when you set the triggerEnabled to true (intentionally).

  • dcrossey

    Member
    August 9, 2021 at 12:00 am in reply to: KX Control – stopStateFunct?

    EDIT: See @rocuinneagain ‘s reply for the optimal solution for this question.

    Hi adrainosm_,

    You would need to define an analytic (or analyticgroup) that is loaded by your RTE process, then send a message to that process via IPC (for example) just prior to shutting down your, if there is some specific steps you want to take prior to shutdown.

    Alternatively, you could also add a wrapper around your eodFunct to carry out your steps if you RTE stops just after EOD, or you could also try using the timer functions on the process say e.g. once per day to achieve something similar.

    Hope this helps,

    David

  • dcrossey

    Member
    August 8, 2021 at 12:00 am in reply to: Dashboards – action triggers on page load

    Hi Nick,

    You could try passing in a boolean viewstate triggerEnabled to your virtual datasource, which has a default value as false when the page loads to prevent it clearing.

    Something like:

     

    function (x, triggerEnabled, callback){ if(!triggerEnabled) { callback(x) // i.e. just return x without modifying } else { callback ({ // i.e. your custom clear logic }); } }

     

    Set the viewstate to true when you actually want to clear the viewstates.

    You can also map an output viewstate to reset the triggerEnabled viewstate to false after execution.

    Hope this helps!

    Cheers,

    David

  • dcrossey

    Member
    August 5, 2021 at 12:00 am in reply to: Show or 0N!

    Note on the trailing semi-colon too; this supresses the file handle (1 or -1) being displayed

  • dcrossey

    Member
    August 2, 2021 at 12:00 am in reply to: Show or 0N!

    Hi @eletrofone,

    As you’ve mentioned, to print strings without the quotes you will need to send the string(s) to the file handle 1 (stdout).

    If you to avoid ambiguity with ‘1’ in your code, you could set a variable for re-use e.g.

     

    q)stdout:1; 
    q)stdout each (("hello";"world"),:"n"); 
    hello world // use negative to append newline by default 
    q)stdout:neg 1; 
    q)stdout ("hello";"world"); 
    hello world // note, trailing semi-colon to supress outputting the file handle

     

    Please see here for more info: Handles to files and processes | Basics | q and kdb+ documentation – Kdb+ and q documentation (kx.com)

    Cheers,

    David

  • dcrossey

    Member
    August 1, 2021 at 12:00 am in reply to: Fast Insert Line into Middle of An In-memory Table

    Hi Xiaocheng,

    A few questions to add more context here;

    • Assuming this process is an RDB, is there any particular reason you need to insert rows at a specific index?
    • What logic determines the insert index?

    For most RBD applications you probably want to avoid sorting until the end of day write down to disk.

    If you need to increase performance in querying your RBD process, you could perhaps look at the grouped attribute, which will keep a hash map of the indices for the new rows.

     

    q)tbl:update sym:`g#sym from ([]sym:upper 3?`4;price:3?10f); 
    q)meta tbl 
    c    | t f a 
    -----| ----- 
    sym  | s   g 
    price| f 
    
    q)tbl 
    sym price 
    -------------- 
    GMEH 7.125845 
    IKOK 1.392257 
    CJEK 2.701876 
    
    q)tbl:tbl upsert (`ABCD;10f); 
    q)tbl 
    sym price 
    -------------- 
    GMEH 7.125845 
    IKOK 1.392257 
    CJEK 2.701876 
    ABCD 10 
    
    q)meta tbl 
    c    | t f a 
    -----| ----- 
    sym  | s   g 
    price| f

     

    Resources:

    Hope this helps!

    Cheers,

    David

  • Hi Adriano,

    By “q does not like to perform the xkey directly on value table”, do you mean as follows:

     

    q)`name xkey value people

    ‘type

    [0] `name xkey value people ^

     

    Here, we are referring to the table with pass-by-value and q throws a type error. You don’t need to use ‘value’ if you are referring to a table in this manner (note the lack of backtick).

    If you used the ` people with ‘value’ this would have worked as expected (pass-by-reference) :

     

    q)`name xkey value `people 
    name  | age sym 
    ------| ---------- 
    ada   | 33 ada 
    maggie| 25 maggie

     

    In general, I would advise the following syntax for general usage (pass-by-value) :

     

    people:`name xkey people;

     

    Otherwise using pass-by-reference:

     

    people:`name xkey value `people;

     

    Hope this helps.

    Best,
    David