TRANSFORM Structure<indexterm> <primary>TRANSFORM structure</primary> </indexterm> resulttype funcname ( parameterlist ) := TRANSFORM TRANSFORM [, SKIP SKIP ( condition )] [ locals ] SELF SELF .outfield := transformation; END; TRANSFORM( resulttype, assignments ) TRANSFORM( datarow ) resulttype The name of a RECORD structure Attribute that specifies the output format of the function. You may use TYPEOF here to specify a dataset. Any implicit relationality of the input dataset is not inherited. funcname The name of the function the TRANSFORM structure defines. parameterlist The value types and labels of the parameters that will be passed to the TRANSFORM function. These are usually the dataset records or COUNTER parameters but are not limited to those. SKIP Optional. Specifies the condition under which the TRANSFORM function operation is skipped. condition A logical expression defining under what circumstances the TRANSFORM operation does not occur. This may use data from the parameterlist in the same manner as a transformation expression. locals Optional. Definitions of local Attributes useful within the TRANSFORM function. These may be defined to receive parameters and may use any parameters passed to the TRANSFORM. SELF Specifies the resulting output recordset from the TRANSFORM. outfield The name of a field in the resulttype structure. transformation An expression specifying how to produce the value for the outfield. This may include other TRANSFORM function operations (nested transforms). assignments A semi-colon delimited list of SELF.outfield:= transformation definitions. datarow A single record to transform, typically the keyword LEFT. The TRANSFORM structure makes operations that must be performed on entire datasets (such as a JOIN) and any iterative type of record processing (PROJECT, ITERATE, etc.), possible. A TRANSFORM defines the specific operations that must occur on a record-by-record basis. It defines the function that is called each time the operation that uses the TRANSFORM needs to process record(s). One TRANSFORM function may be defined in terms of another, and they may be nested. The TRANSFORM structure specifies exactly how each field in the output record set is to receive its value. That result value may simply be the value of a field in an input record set, or it may be the result of some complex calculation or conditional expression evaluation. The TRANSFORM structure itself is a generic tool; each operation that uses a TRANSFORM function defines what its TRANSFORM needs to receive and what basic functionality it should provide. Therefore, the real key to understanding TRANSFORM structures is in understanding how it is used by the calling function -- each function that uses a TRANSFORM documents the type of TRANSFORM required to accomplish the goal, although the TRANSFORM itself may also provide extra functionality and receive extra parameters beyond those required by the operation itself. The SKIP option specifies the condition that results in no output from that iteration of the TRANSFORM. However, COUNTER values are incremented even when SKIP eliminates generating the current record. Transformation Attribute Definitions The attribute definitions inside the TRANSFORM structure are used to convert the data passed in as parameters to the output resulttype format. Every field in the resulttype record layout must be fully defined in the TRANSFORM. You can explicitly define each field, using the SELF.outfield := transformation; expression, or you can use one of these shortcuts: SELF := [ ]; clears all fields in the resulttype output that have not previously been defined in the transform function, while this form: SELF.outfield := []; //the outfield names a child DATASET in // the resulttype RECORD Structure clears only the child fields in the outfield, and this form: SELF := label; //the label names a RECORD structure RECORD structure parameter // in the parameterlist defines the output for each field in the resulttype output format that has not previously been defined as coming from the label parameter's matching named field. You may also define local attributes inside the TRANSFORM structure to better organize the code. These local attributes may receive parameters. TRANSFORM Functions This form of TRANSFORM must be terminated by the END keyword. The resulttype must be specified, and the function itself takes parameters in the parameterlist. These parameters are typically RECORD structures, but may be any type of parameter depending upon the type of TRANSFORM function the using function expects to call. The exact form a TRANSFORM function must take is always directly associated with the operation that uses it. Example: Ages := RECORD AgedRecs.id; AgedRecs.id1; AgedRecs.id2; END; SequencedAges := RECORD Ages; INTEGER4 Sequence := 0; END; SequencedAges AddSequence(AgedRecs L, INTEGER C) := TRANSFORM, SKIP(C % 2 = 0) //skip even recs INTEGER1 rangex(UNSIGNED4 divisor) := (l.id DIV divisor) % 100; SELF.id1 := rangex(10000); SELF.id2 := rangex(100); SELF.Sequence := C; SELF := L; END; SequencedAgedRecs := PROJECT(AgedRecs, AddSequence(LEFT,COUNTER COUNTER )); //Example of defining a TRANSFORM function in terms of another namesIdRecord assignId(namesRecord l, UNSIGNED value) := TRANSFORM SELF.id := value; SELF := l; END; assignId1(namesRecord l) := assignId(l, 1); //creates an assignId1 TRANSFORM that uses assignId assignId2(namesRecord l) := assignId(l, 2); //creates an assignId2 TRANSFORM that uses assignId Inline TRANSFORMs<indexterm> <primary>Inline TRANSFORMs</primary> </indexterm> This form of TRANSFORM is used in-line within the operation that uses it. The resulttype must be specified along with all the assignments. This form is mainly for use where the transform assignments are trivial (such as SELF := LEFT;). Example: namesIdRecord assignId(namesRecord L) := TRANSFORM SELF := L; //more like-named fields across SELF := []; //clear all other fields END; projected1 := PROJECT(namesTable, assignId(LEFT)); projected2 := PROJECT(namesTable, TRANSFORM(namesIdRecord, SELF := LEFT; SELF := [])); //projected1 and projected2 do the same thing Shorthand Inline TRANSFORMs<indexterm> <primary>Inline TRANSFORMs</primary> </indexterm> This form of TRANSFORM is a shorthand version of Inline TRANSFORMs. In this form, TRANSFORM(LEFT) is directly equivalent to TRANSFORM(RECORDOF(LEFT), SELF := LEFT) Example: namesIdRecord assignId(namesRecord L) := TRANSFORM SELF := L; //move like-named fields across END; projected1 := PROJECT(namesTable, assignId(LEFT)); projected2 := PROJECT(namesTable, TRANSFORM(namesIdRecord, SELF := LEFT)); projected3 := PROJECT(namesTable, TRANSFORM(LEFT)); //projected1, projected2, and projected3 all do the same thing See Also: RECORD Structure, RECORDOF, TYPEOF, JOIN, PROJECT, ITERATE, ROLLUP, NORMALIZE, DENORMALIZE, FETCH, PARSE, ROW