CREATE statement

The CREATE statement creates a new message field.

Syntax

Read syntax diagramSkip visual syntax diagramCREATEQualifierTargetAsClauseDomainClause1RepeatClauses2ValuesClausesFromClauseParseClause3
Qualifier
Read syntax diagramSkip visual syntax diagramFIELDPREVIOUSSIBLINGNEXTSIBLINGFIRSTCHILDLASTCHILDOF
AsClause
Read syntax diagramSkip visual syntax diagramASAliasFieldReferenceVariable
DomainClause
Read syntax diagramSkip visual syntax diagramDOMAINexpression
RepeatClauses
Read syntax diagramSkip visual syntax diagramREPEAT VALUE-expression
ValuesClauses
Read syntax diagramSkip visual syntax diagram NamesClauses VALUEexpression
NamesClauses
Read syntax diagramSkip visual syntax diagramTYPEExpressionNAMESPACEExpressionNAMEExpression4IDENTITYPathElement
FromClause
Read syntax diagramSkip visual syntax diagramFROMSourceFieldReference
ParseClause
Read syntax diagramSkip visual syntax diagram PARSE ( BitStreamExpression <<ENCODINGexpressionCCSIDexpressionSETexpressionTYPEexpressionFORMATexpressionOptions )
Options
Read syntax diagramSkip visual syntax diagramOPTIONS expression
Notes:
  • 1 Do not use the DomainClause and ParseClause with the FIELD qualifier.
  • 2 Use the RepeatClauses only with the PREVIOUSSIBLING and NEXTSIBLING qualifiers.
  • 3 Each subclause within the ParseClause can occur once only.
  • 4 If present, the TYPE, NAMESPACE, and NAME elements must appear in the order shown in the railroad diagram.

The new message field is positioned either at a given location (CREATE FIELD) or relative to a currently existing location (CREATE ... OF...). New fields can be created only when the target field reference points to a modifiable message; for example, Environment, InputLocalEnvironment, OutputLocalEnvironment, OutputRoot, or OutputExceptionList.

If you include a FIELD clause, the field that is specified by Target is navigated to (creating the fields, if necessary) and any values clause, or from clause, is processed. Including a FIELD clause does not necessarily create any fields; it ensures only that the given fields exist.

If you use array indexes in the target field reference, only one instance of a particular field can be created. Therefore, if you write a SET statement that starts:
 SET OutputRoot.XMLNS.Message.Structure[2].Field = ...  

at least one instance of Structure must already exist in the message. That is, the only fields in the tree that are created are ones on a direct path from the root to the field identified by the field reference.

If you include a PREVIOUSSIBLING, NEXTSIBLING, FIRSTCHILD, or LASTCHILD clause, the field that is specified by Target is navigated to (creating the fields if necessary) in exactly the same way as for the FIELD clause. A new field is then created and attached in the specified position (for example, as PREVIOUSSIBLING or FIRSTCHILD). A CREATE statement with one of these clauses always creates a new field, and places it in the specified position.

If you use two CREATE FIRSTCHILD OF target statements that specify the same target, the second statement creates a new field as the first child of the target, and displaces the previously created first child to the right in the message tree (so that it is no longer the first child). Similarly, CREATE LASTCHILD OF target navigates to the target field and adds a new field as its rightmost child, displacing the previous last child to the left.

CREATE PREVIOUSSIBLING OF Target creates a field to the immediate left of the field that is specified by Target (so the depth of the tree is not changed); similarly, CREATE NEXTSIBLING OF Target creates a field to the immediate right of the field that is specified by Target. When creating PREVIOUSSIBLING or NEXTSIBLING, you can use the REPEAT keyword to copy the type and name of the new field from the current field.

AS clause:

If present, the AS clause moves the named reference variable to point at the newly-created field. Use this clause if you want to involve the new field in some further processing.

DOMAIN clause:

If present, the DOMAIN clause associates the new field with a new parser of the specified type. This clause expects a root field name (for example, XMLNS or MQRFH2). If the DOMAIN clause is present, but the value supplied is a zero-length character string, a new parser of the same type as the parser that owns the field specified by target is created. An exception is thrown if the supplied domain name is not CHARACTER data type or its value is NULL. Do not specify the DOMAIN clause with the FIELD clause; it is not certain that a new field is created.

REPEAT clause:

Use the REPEAT clause to copy the new field's type and name from the target field. Alternatively, the new field's type, name, and value can be:
  • Copied from any existing field (using the FROM clause)
  • Specified explicitly (using the VALUES clause)
  • Defined by parsing a bit stream (using the PARSE clause)
In the case of the FROM and PARSE clauses, you can also create children of the new field.

VALUES clause:

For the VALUES clause, the type, name, and value (or any subset of these) can be specified by any expression that returns a suitable data type (INTEGER for type, CHARACTER for name, and any scalar type for value). An exception is thrown if the value supplied for a type or name is NULL.

NAMES clause:

The NAMES clause takes any expression that returns a non-null value of type character. The meaning depends on the presence of NAME and NAMESPACE clauses as follows:
NAMESPACE NAME Element named as follows
No No The element is nameless (the name flag is not automatically set).
No Yes The element is given the name in the default namespace.
Yes No The element is given the empty name in the given namespace.
Yes Yes The element is given the given name in the given namespace.

The IDENTITY operand takes a single path element in place of the TYPE and NAME clauses, where a path element contains (at most) a type, a namespace, a name, and an index. These elements specify the type, namespace, name, and index of the element to be created and follow all the rules described in the topic for field references (see ESQL field reference overview). For example:

	IDENTITY (XMLNS.attribute)Space1:Name1[42]

See the following Examples section for information about how to use the IDENTITY operand.

FROM clause:

For the FROM clause, the new field's type, name, and value are taken from the field pointed to by SourceFieldReference. Any existing child fields of the target are detached (the field might already exist in the case of a FIELD clause), and the new field is given copies of the source field's children.

PARSE clause:

If a PARSE clause is present, a subtree is built under the newly-created field from the supplied bit stream. The algorithm for building the subtree varies from parser to parser and according to the options specified. All parsers support the mode RootBitStream, in which the tree creation algorithm is the same as that used by an input node.

Some parsers also support a second mode, FolderBitStream, which generates a sub tree from a bit stream created by the ASBITSTREAM function (see ASBITSTREAM function) that is using that mode.

When you use the PARSE clause, specify a scalar value containing the bit stream that is to be parsed for BitStreamExpression. If you use a message tree field reference you must ensure it contains a scalar value that contains the bit stream. An existing message body folder such as InputRoot.XMLNSC does not contain a bit stream and therefore cannot be used this to serialize the XMLNS folder. If you pass a value other than a scalar containing the bit stream to the PARSE clause for BitStreamExpression, the message flow produces a BIP2906 error message. Instead, you must first call the ASBITSTREAM function to serialize the existing message tree folder. The result of the ASBITSTREAM function can then be passed as the BitStreamExpression to the PARSE clause.

The following example shows how to serialize the XMLNSC folder, then use the result of the ASBITSTREAM in the PARSE clause.
DECLARE inCCSID INT InputProperties.CodedCharSetId;                     
DECLARE inEncoding INT InputProperties.Encoding;                        
DECLARE inBitStream BLOB ASBITSTREAM(InputRoot.XMLNSC, inEncoding, inCCSID);
CREATE LASTCHILD OF OutputRoot DOMAIN('MRM')                            
       PARSE(inBitStream, inEncoding, inCCSID, 'DP3UK14002001',         
             'TestCase', 'XML1', options); 

When the PARSE statement is processed, any PARSE clause expressions are evaluated. An exception is thrown if any of the following expressions do not result in a non-null value of the appropriate type:

Clause Type Default value
OPTIONS Integer RootBitStream & ValidateNone
ENCODING Integer 0
CCSID Integer 0
SET Character Zero length string
TYPE Character Zero length string
FORMAT Character Zero length string

For details of the syntax of the TYPE clause, see Specifying namespaces in the Message property.

Although the OPTIONS clause accepts any expression that returns a value of type integer, it is only meaningful to generate option values from the list of supplied constants, using the BITOR function if more than one option is required.

Once generated, the value becomes an integer and you can save it in a variable or pass it as a parameter to a function, as well as using it directly with a CREATE statement. The list of globally defined constants is:
        Validate master options...
        ValidateContentAndValue
        ValidateValue		-- Can be used with ValidateContent
        ValidateContent		-- Can be used with ValidateValue
        ValidateNone

        Validate failure action options...
        ValidateException
        ValidateExceptionList
        ValidateLocalError
        ValidateUserTrace

        Validate timing options...
        ValidateComplete
        ValidateImmediate
        ValidateDeferred
Notes:
  1. For full details of the validation options, refer to Validation properties.
  2. The Validate timing options correspond to Parse Timing options and, in particular, ValidateDeferred corresponds to Parse Timing On Demand.
Note that not all the equivalent options are available in the C and Java™ equivalent APIs:
  • Equivalent validation options are not available in the C plugin node API methods cniCreateElementAsLastChildFromBitstream() and cniElementAsBitstream().
  • The Java plugin node API MBElement methods createElementAsLastChildFromBitstream() and toBitstream() provide validation options. However, the FolderBitStream and EmbeddedBitStream modes are not available. The only available mode is RootBitStream, which is the default value.

You can specify only one option from each group, with the exception of ValidateValue and ValidateContent, which you can use together to obtain the content and value validation. If you do not specify an option within a group, the option in bold is used.

The ENCODING clause accepts any expression that returns a value of type integer. However, it is only meaningful to generate option values from the list of supplied constants:
       MQENC_INTEGER_NORMAL
       MQENC_INTEGER_REVERSED
       MQENC_DECIMAL_NORMAL
       MQENC_DECIMAL_REVERSED
       MQENC_FLOAT_IEEE_NORMAL
       MQENC_FLOAT_IEEE_REVERSED
       MQENC_FLOAT_S390

The values used for the CCSID clause follow the normal numbering system. For example, 1200 = UCS-2, 1208 = UTF-8.

For absent clauses, the given default values are used. Use the CCSID and encoding default values because these take their values from the queue manager's encoding and CCSID settings.

Similarly, using the default values for each of the message set, type, and format options is useful, because many parsers do not require message set, type, or format information, and so any valid value is sufficient.

When any expressions have been evaluated, a bit stream is parsed using the results of the expressions.
Note: Because this function has a large number of clauses, an alternative syntax is supported, in which the parameters are supplied as a comma-separated list rather than by named clauses. In this case the expressions must be in the order:
ENCODING -> CCSID -> SET -> TYPE -> FORMAT -> OPTIONS

The list can be truncated at any point and an entirely empty expression can be used in any clauses where you do not supply a value.

Examples of how to use the CREATE statement

  1. The following example creates the specified field:
    CREATE FIELD OutputRoot.XMLNS.Data;
  2. The following example creates a field with no name, type, or value as the first child of ref1:
    CREATE FIRSTCHILD OF ref1;
  3. The following example creates a field using the specified type, name, and value:
    CREATE NEXTSIBLING OF ref1 TYPE NameValue NAME 'Price' VALUE 92.3;
  4. The following example creates a field with a type and name, but no value; the field is added before the sibling indicated by the dynamic reference (ref1):
    CREATE PREVIOUSSIBLING OF ref1 TYPE Name NAME 'Quantity';
  5. The following example creates a field named Component, and moves the reference variable targetCursor to point at it:
    CREATE FIRSTCHILD OF targetCursor AS targetCursor NAME 'Component';
  6. The following example creates a new field as the right sibling of the field pointed to by the reference variable targetCursor having the same type and name as that field. The statement then moves targetCursor to point at the new field:
    CREATE NEXTSIBLING OF targetCursor AS targetCursor REPEAT;
  7. The following example shows how to use the PARSE clause:
    DECLARE bodyBlob BLOB ASBITSTREAM(InputRoot.XMLNS, InputProperties.Encoding,
     InputProperties.CodedCharSetId);
    DECLARE creationPtr REFERENCE TO OutputRoot;
    CREATE LASTCHILD OF creationPtr DOMAIN('XMLNS') PARSE(bodyBlob,
                        InputProperties.Encoding,
     InputProperties.CodedCharSetId);

    This example can be extended to show the serializing and parsing of a field or folder:

    DECLARE bodyBlob BLOB ASBITSTREAM(InputRoot.XMLNS.TestCase.myFolder,
                        InputProperties.Encoding,
    InputProperties.CodedCharSetId,",",",FolderBitStream);
    DECLARE creationPtr REFERENCE TO OutputRoot;
    CREATE LASTCHILD OF creationPtr DOMAIN('XMLNS') PARSE(bodyBlob,
                        InputProperties.Encoding,
    InputProperties.CodedCharSetId,",",",FolderBitStream);
  8. The following example shows how to use the IDENTITY operand:
    CREATE FIELD OutputRoot.XMLNS.TestCase.Root IDENTITY (XML.ParserRoot)Root;
    CREATE FIELD OutputRoot.XMLNS.TestCase.Root.Attribute 
           IDENTITY (XML.Attribute)NSpace1:Attribute VALUE 'Attrib Value';
    CREATE LASTCHILD OF OutputRoot.XMLNS.TestCase.Root 
           IDENTITY (XML.Element)NSpace1:Element1[1] VALUE 'Element 1 Value';
    CREATE LASTCHILD OF OutputRoot.XMLNS.TestCase.Root 
           IDENTITY (XML.Element)NSpace1:Element1[2] VALUE 'Element 2 Value';

    This produces the following output message:

    <TestCase>
     <Root xmlns:NS1="NSpace1" NS1:Attribute="Attrib Value">
      <NS1:Element1>Element 1 Value</NS1:Element1>
      <NS1:Element1>Element 2 Value</NS1:Element1>
     </Root>
    </TestCase>
  9. The following example shows how you can use the DOMAIN clause to avoid losing information unique to the XMLNS parser when an unlike parser copy occurs:
    DECLARE bodyBlob BLOB ASBITSTREAM(InputRoot.XMLNS, InputProperties.Encoding,
    InputProperties.CodedCharSetId);
    CREATE FIELD Environment.Variables.myXMLTree;
    DECLARE creationPtr REFERENCE TO Environment.Variables.myXMLTree;
    CREATE FIRSTCHILD OF creationPtr DOMAIN('XMLNS') PARSE(bodyBlob, 
                        InputProperties.Encoding, 
    InputProperties.CodedCharSetId);

An example of a CREATE statement

This example provides sample ESQL and an input message.

CREATE COMPUTE MODULE CreateStatement_Compute
	CREATE FUNCTION Main() RETURNS BOOLEAN
	BEGIN
	  CALL CopyMessageHeaders();

        CREATE FIELD OutputRoot.XMLNS.TestCase.description TYPE NameValue VALUE 'This is my TestCase' ;
        DECLARE cursor REFERENCE TO OutputRoot.XMLNS.TestCase;
        CREATE FIRSTCHILD OF cursor Domain('XMLNS') 
               NAME 'Identifier' VALUE InputRoot.XMLNS.TestCase.Identifier;
        CREATE LASTCHILD  OF cursor Domain('XMLNS') NAME 'Sport' VALUE InputRoot.XMLNS.TestCase.Sport;
        CREATE LASTCHILD  OF cursor Domain('XMLNS') NAME 'Date' VALUE InputRoot.XMLNS.TestCase.Date;
        CREATE LASTCHILD  OF cursor Domain('XMLNS') NAME 'Type' VALUE InputRoot.XMLNS.TestCase.Type;
        CREATE FIELD         cursor.Division[1].Number TYPE NameValue VALUE 'Premiership';
        CREATE FIELD         cursor.Division[1].Result[1].Number TYPE NameValue VALUE  '1' ;
        CREATE FIELD         cursor.Division[1].Result[1].Home TYPE Name;
        CREATE LASTCHILD OF  cursor.Division[1].Result[1].Home NAME 'Team' VALUE 'Liverpool' ;
        CREATE LASTCHILD OF  cursor.Division[1].Result[1].Home NAME 'Score' VALUE '4';
        CREATE FIELD         cursor.Division[1].Result[1].Away TYPE Name;
        CREATE LASTCHILD OF  cursor.Division[1].Result[1].Away NAME 'Team' VALUE 'Everton';
        CREATE LASTCHILD OF  cursor.Division[1].Result[1].Away NAME 'Score' VALUE '0';
        CREATE FIELD         cursor.Division[1].Result[2].Number TYPE NameValue VALUE  '2';
        CREATE FIELD         cursor.Division[1].Result[2].Home TYPE Name;
        CREATE LASTCHILD OF  cursor.Division[1].Result[2].Home NAME 'Team' VALUE 'Manchester United';
        CREATE LASTCHILD OF  cursor.Division[1].Result[2].Home NAME 'Score' VALUE '2';
        CREATE FIELD         cursor.Division[1].Result[2].Away TYPE Name;
        CREATE LASTCHILD OF  cursor.Division[1].Result[2].Away NAME 'Team' VALUE 'Arsenal';
        CREATE LASTCHILD OF  cursor.Division[1].Result[2].Away NAME 'Score' VALUE '3';
        CREATE FIELD         cursor.Division[2].Number TYPE NameValue  VALUE '2';
        CREATE FIELD         cursor.Division[2].Result[1].Number TYPE NameValue  VALUE  '1';
        CREATE FIELD         cursor.Division[2].Result[1].Home TYPE Name;
        CREATE LASTCHILD OF  cursor.Division[2].Result[1].Home NAME 'Team' VALUE 'Port Vale';
        CREATE LASTCHILD OF  cursor.Division[2].Result[1].Home NAME 'Score' VALUE '9' ;
        CREATE FIELD         cursor.Division[2].Result[1].Away TYPE Name;
        CREATE LASTCHILD OF  cursor.Division[2].Result[1].Away NAME 'Team' VALUE 'Brentford';
        CREATE LASTCHILD OF  cursor.Division[2].Result[1].Away NAME 'Score' VALUE '5';

	END;

	CREATE PROCEDURE CopyMessageHeaders() BEGIN
		DECLARE I INTEGER 1;
		DECLARE J INTEGER CARDINALITY(InputRoot.*[]);
		WHILE I < J DO
			SET OutputRoot.*[I] = InputRoot.*[I];
			SET I = I + 1;
		END WHILE;
	END;

END MODULE;