Sat Mar 23, 2019 12:21 pm
Login Register Lost Password? Contact Us


Slicing a set of dataset does not work

Questions around writing code and queries

Mon Mar 11, 2019 6:33 pm Change Time Zone

I was playing with one of the documented examples and I came across an issue which i am trying to understand.
The following code works and gives the result as [1,2,3]
Code: Select all
SetInt := [1,2,3,4,5];
SetInt[1..3];


But, the following does not work:
Code: Select all
Rec := RECORD
  STRING1  Letter;
  UNSIGNED1    DS;
END;

ds1 := DATASET([{'A',1},{'B',1},{'C',1},{'D',1},{'E',1}],Rec);
ds2 := DATASET([{'A',2},{'B',2},{'H',2},{'I',2},{'J',2}],Rec);
ds3 := DATASET([{'B',3},{'C',3},{'M',3},{'N',3},{'O',3}],Rec);
ds4 := DATASET([{'A',4},{'B',4},{'R',4},{'S',4},{'T',4}],Rec);
ds5 := DATASET([{'B',5},{'V',5},{'W',5},{'X',5},{'Y',5}],Rec);
SetDS := [ds1,ds2,ds3,ds4,ds5];
Setds[1..3];


Am I making a mistake here or is it because the set of dataset is internally not looked as a set but a syntax sugar to better express merge joins.
Thanks
Srini
omnibuzz
 
Posts: 89
Joined: Wed Feb 06, 2013 2:02 pm

Mon Mar 11, 2019 8:29 pm Change Time Zone

Srini,

For sets of DATASETs you need to use the RANGE function instead of the set-range-of-values syntax, like this:
Code: Select all
Rec := RECORD
  STRING1  Letter;
  UNSIGNED1    DS;
END;
ds1 := DATASET([{'A',1},{'B',1},{'C',1},{'D',1},{'E',1}],Rec);
ds2 := DATASET([{'A',2},{'B',2},{'H',2},{'I',2},{'J',2}],Rec);
ds3 := DATASET([{'B',3},{'C',3},{'M',3},{'N',3},{'O',3}],Rec);
ds4 := DATASET([{'A',4},{'B',4},{'R',4},{'S',4},{'T',4}],Rec);
ds5 := DATASET([{'B',5},{'V',5},{'W',5},{'X',5},{'Y',5}],Rec);
SetDS := [ds1,ds2,ds3,ds4,ds5];
OutDS1 := RANGE(Setds,[1,3,5]);
OUTPUT(outDS1[1]);
OUTPUT(outDS1[2]);
OUTPUT(outDS1[3]);
OUTPUT(outDS1[1] & outDS1[2] & outDS1[3] & outDS1[4] & outDS1[5]); 

HTH,

Richard
rtaylor
Community Advisory Board Member
Community Advisory Board Member
 
Posts: 1431
Joined: Wed Oct 26, 2011 7:40 pm

Mon Mar 11, 2019 9:03 pm Change Time Zone

This definitely helped, Richard. Thanks a lot. I got what I wanted. I am, however, stuck with another issue in getting a set of datasets from a denormalized dataset. Do you have any trick to achieve this.

Here is a setup for what I am trying to achieve.
Code: Select all
Rec := RECORD
  STRING1  Letter;
  UNSIGNED1    DS;
END;

ds1 := DATASET([{'A',1},{'B',1},{'C',1},{'D',1},{'E',1}],Rec);
ds2 := DATASET([{'A',2},{'B',2},{'H',2},{'I',2},{'J',2}],Rec);
ds3 := DATASET([{'B',3},{'C',3},{'M',3},{'N',3},{'O',3}],Rec);
ds4 := DATASET([{'A',4},{'B',4},{'R',4},{'S',4},{'T',4}],Rec);
ds5 := DATASET([{'B',5},{'V',5},{'W',5},{'X',5},{'Y',5}],Rec);

ParentRec := RECORD
   DATASET(Rec) Child;
END;
dsParent := DATASET([{ds1},{ds2},{ds3},{ds4},{ds5}],ParentRec);

//Assuming dsParent is what I have to start with, I want to rewrite this line to get the set of datasets from dsparent
SET(dsParent,Child);


Thank you again for the help.
Cheers
Srini
omnibuzz
 
Posts: 89
Joined: Wed Feb 06, 2013 2:02 pm

Mon Mar 11, 2019 11:51 pm Change Time Zone

Srini,

Why do you need a set of child datasets when you can simply use the child dataset as if it were a separate dataset, like this:
Code: Select all
Rec := RECORD
  STRING1  Letter;
  UNSIGNED1    DS;
END;

ds1 := DATASET([{'A',1},{'B',1},{'C',1},{'D',1},{'E',1}],Rec);
ds2 := DATASET([{'A',2},{'B',2},{'H',2},{'I',2},{'J',2}],Rec);
ds3 := DATASET([{'B',3},{'C',3},{'M',3},{'N',3},{'O',3}],Rec);
ds4 := DATASET([{'A',4},{'B',4},{'R',4},{'S',4},{'T',4}],Rec);
ds5 := DATASET([{'B',5},{'V',5},{'W',5},{'X',5},{'Y',5}],Rec);

ParentRec := RECORD
   DATASET(Rec) Child;
END;
dsParent := DATASET([{ds1},{ds2},{ds3},{ds4},{ds5}],ParentRec);
OUTPUT(dsParent.Child);  //produces all child recs

HTH,

Richard
rtaylor
Community Advisory Board Member
Community Advisory Board Member
 
Posts: 1431
Joined: Wed Oct 26, 2011 7:40 pm

Tue Mar 12, 2019 12:57 am Change Time Zone

I need to pass it to the MERGEJOIN construct as a set of datasets to find matches between the children.
omnibuzz
 
Posts: 89
Joined: Wed Feb 06, 2013 2:02 pm

Tue Mar 12, 2019 3:04 pm Change Time Zone

Srini,

Try throwing in a bit of Template Language to generate the set definition, like this:
Code: Select all
Rec := RECORD
  STRING1  Letter;
  UNSIGNED1    DS;
END;

ds1 := DATASET([{'A',1},{'B',1},{'C',1},{'D',1},{'E',1}],Rec);
ds2 := DATASET([{'A',2},{'B',2},{'H',2},{'I',2},{'J',2}],Rec);
ds3 := DATASET([{'B',3},{'C',3},{'M',3},{'N',3},{'O',3}],Rec);
ds4 := DATASET([{'A',4},{'B',4},{'R',4},{'S',4},{'T',4}],Rec);
ds5 := DATASET([{'B',5},{'V',5},{'W',5},{'X',5},{'Y',5}],Rec);

ParentRec := RECORD
   UNSIGNED RecID;
   DATASET(Rec) Child;
END;
dsParent := DATASET([{1,ds1},{2,ds2},{3,ds3},{4,ds4},{5,ds5}],ParentRec);

  #DECLARE (SetString)
  #DECLARE (Ndx)
  #SET (SetString, 'SetDS := [');    //initialize SetString
  #SET (Ndx, 1);            //initialize Ndx to 1
  #LOOP
    #IF (%Ndx% = COUNT(dsParent))   //if on last rec
      #BREAK         // break out of the loop
    #ELSE             //otherwise
      #APPEND (SetString, 'dsParent[' + %'Ndx'% + '].Child,');
      #SET (Ndx, %Ndx% + 1)
    #END
  #END
      //add last element and closing ];
  #APPEND (SetString, 'dsParent[' + %'Ndx'% + '].Child];');
 
  %SetString%; //generate the SetDS definition
    // This generates:
    // SetDS := [dsParent[1].Child,dsParent[2].Child,dsParent[3].Child,
                 dsParent[4].Child,dsParent[5].Child];

j1 := MERGEJOIN(SetDS,
                STEPPED(LEFT.Letter=RIGHT.Letter),
                SORTED(Letter));
j2 := MERGEJOIN(SetDS,
                STEPPED(LEFT.Letter=RIGHT.Letter),
                SORTED(Letter),LEFT OUTER);
j3 := MERGEJOIN(SetDS,
                STEPPED(LEFT.Letter=RIGHT.Letter),
                SORTED(Letter),LEFT ONLY);
j4 := MERGEJOIN(SetDS,
                STEPPED(LEFT.Letter=RIGHT.Letter),
                SORTED(Letter),MOFN(3));
j5 := MERGEJOIN(SetDS,
                STEPPED(LEFT.Letter=RIGHT.Letter),
                SORTED(Letter),MOFN(3,4));
OUTPUT(j1);
OUTPUT(j2);
OUTPUT(j3);
OUTPUT(j4);
OUTPUT(j5);

And you could also submit a JIRA asking for the SET function to expand its functionality to include creating the set of datasets the easy way:
Code: Select all
SetDS := SET(DsParent,Child);


HTH,

Richard
rtaylor
Community Advisory Board Member
Community Advisory Board Member
 
Posts: 1431
Joined: Wed Oct 26, 2011 7:40 pm

Tue Mar 12, 2019 3:27 pm Change Time Zone

I believe template route will not work as it will require me to know the number of records at compile time.

I think the core team might have intentionally kept the SET functionality out of child datasets, as managing a large set of big datasets may create its own issues.

I will anyway submit a JIRA ticket.

Thanks for checking it out.
Regards
Srini
omnibuzz
 
Posts: 89
Joined: Wed Feb 06, 2013 2:02 pm


Return to Programming

Who is online

Users browsing this forum: No registered users and 0 guests

cron