CloneRows

El código de esta sección se guarda en un archivo llamado CloneRows.

Conceptos

Este ejemplo muestra tres conceptos principales:
  • Una función AE llamada desde una función de tabla que devuelve más de una fila de salida por fila de entrada.
  • Una función AE llamada desde una función de tabla que utiliza un modelador.
  • Uso de variables dinámicas de entorno AE en una llamada a función SQL.

Este AE puede aceptar cualquier firma de entrada. Utilizando metadatos de consulta, establece la definición del tipo de datos de la fila de salida igual a la firma de la fila de entrada. En función de la variable de entorno CLONE_COUNT AE clona la fila de entrada el número de veces especificado. También utiliza la variable de entorno CLONE_COLUMN_NAMES para establecer los nombres de las columnas de salida.

Código

Tenga en cuenta que este código admite dos API: la API AE shaper para realizar el shaping y la API AE function para procesar los datos. Este código se utilizará en la sección ApplyDriver Versión 3.

// CloneRows.java
// Function AE
// Handles a variable number of input columns and data types
// Returns a clone of each input row a multiplier number of times
// Clone multiplier is an integer >= 1
// Uses a shaper
// Receives clone multiplier as an environment variable
// Receives return column names as an environment variable
// Must be called as a table function
package org.netezza.education;

import org.netezza.ae.*;

public class CloneRows {
    public static void runShaper(NzaeShaper ae) {
        try {
            runShaperImpl(ae);
        } catch (Throwable t) {
            t.printStackTrace();
            try { ae.userError(t.getMessage()); }
            catch (Throwable t2) {}
        }
    }

    private static void runShaperImpl(NzaeShaper aeShp) {
        String strCloneCount =
            aeShp.getEnvironment().getValue("CLONE_COUNT");
        if (strCloneCount == null) {
            String msg =
                "CLONE_COUNT environment variable not set";
            System.err.println(msg);
            aeShp.userError(msg);
            return;
        }
        int cloneCount = 0;
        try {
            cloneCount = Integer.parseInt(strCloneCount);
        } catch (NumberFormatException e) {}
        if (cloneCount < 1) {
            String msg =
                "CLONE_COUNT must be a positive integer";
            System.err.println(msg);
            aeShp.userError(msg);
            return;
        }

        String [] columnNames = new String[0];
        String strCloneNames =
            aeShp.getEnvironment().getValue(
                "CLONE_COLUMN_NAMES");
        if (strCloneNames != null)
        {
            columnNames = strCloneNames.split(",");
            for (int i = 0; i < columnNames.length; i++) {
                if (columnNames[i] == null
                        || columnNames[i].length() == 0) {
                    String msg = "column name "
                        + i + " is invalid";
                    System.err.println(msg);
                    aeShp.userError(msg);
                    return;
                }
            }
        }

        NzaeMetadata meta = aeShp.getMetadata();

        if (aeShp.catalogIsUpper()) {
            for (int i = 0; i < columnNames.length; i++) {
                columnNames[i] = columnNames[i].toUpperCase();
            }
        }

        int numInputColumns = meta.getInputColumnCount();
        for (int i = 0; i < numInputColumns; i++) {
            String name;
            if (i < columnNames.length) {
                name = columnNames[i];
            } else {
                name = "F" + (i + 1);
            }

            switch (meta.getInputNzType(i)) {
            case NzaeDataTypes.NZUDSUDX_FIXED:
            case NzaeDataTypes.NZUDSUDX_VARIABLE:
            case NzaeDataTypes.NZUDSUDX_NATIONAL_FIXED:
            case NzaeDataTypes.NZUDSUDX_NATIONAL_VARIABLE:
                aeShp.addOutputColumnString(
                    meta.getInputNzType(i),
                    name, meta.getInputSize(i));
                break;
            case NzaeDataTypes.NZUDSUDX_NUMERIC32:
            case NzaeDataTypes.NZUDSUDX_NUMERIC64:
            case NzaeDataTypes.NZUDSUDX_NUMERIC128:
                aeShp.addOutputColumnNumeric(
                    meta.getInputNzType(i),
                    name, meta.getInputSize(i),
                    meta.getInputScale(i));
                break;
            default:
                aeShp.addOutputColumn(
                    meta.getInputNzType(i), name);
                break;
            }
        }
        aeShp.update();
    }

    public static void runAe(Nzae ae) {
        try {
            runAeImpl(ae);
        } catch (Throwable t) {
            t.printStackTrace();
            try { ae.userError(t.getMessage()); }
            catch (Throwable t2) {}
        }
    }

    private static void runAeImpl(Nzae ae) {
        String strCloneCount =
            ae.getEnvironment().getValue("CLONE_COUNT");
        if (strCloneCount == null) {
            String msg =
                "CLONE_COUNT environment variable not set";
            System.err.println(msg);
            ae.userError(msg);
            return;
        }
        int cloneCount = 0;
        try {
            cloneCount = Integer.parseInt(strCloneCount);
        } catch (NumberFormatException e) {}
        if (cloneCount < 1) {
            String msg =
                "CLONE_COUNT must be a positive integer";
            System.err.println(msg);
            ae.userError(msg);
            return;
        }
        // input row loop
        for (;;) {
            NzaeRecord input = ae.next();
            if (input == null) break;
            for (int i = 0; i < cloneCount; i++) {
                ae.outputResult(input);
            }
        }

        // it's critical that done get called
        ae.done();
    }
}