Función escalar en lenguaje Fortran

El siguiente ejemplo muestra una función escalar simple que suma un conjunto de números. Este ejemplo parte del principio para construir un AE sencillo. Utiliza el siguiente nombre de archivo: ' applyop.f

Código

  1. Crea el programa y llama a ' nzaeRun()' . Esta llamada configura el AE y luego hace un callback a ' nzaeHandleRequest(), que es necesario para la implementación Fortran. Esto puede lograrse normalmente utilizando:
    program applyopProgram
    call nzaeRun()
    stop
    end
    subroutine nzaeHandleRequest(handle)
    c Our custom Fortran code will go here.
    return
    end
  2. Completa el código Fortran personalizado. En esta UDF, se pasa un operador de cadena, que puede ser "+" (suma) o "*" (multiplicación), así como dos enteros. El código devuelve el producto o la suma de los enteros. En SQL, una versión simple de esto podría ser llamado por cualquiera de los dos:
    SELECT applyop('+', 3, 5);
    o
    SELECT applyop('*', 3, 5);
    Aunque el ejemplo mencionado sólo tiene una entrada, el sistema NPS trata con flujos de entrada. Por lo tanto, es más probable que se utilice el sistema NPS:
    SELECT applyop(mytable.operator, mytable.value1, mytable.value2) FROM mytable;

    En el primer ejemplo, el sistema NPS toma las constantes "+", 3 y 5 y las convierte en un flujo de longitud uno que contiene tres elementos. Internamente, todos los casos mencionados se manejan de la misma manera y se puede asumir que hay múltiples entradas al AE ' applyop.

  3. Se necesita un bucle que maneje la entrada, lo que en Fortran 77 puede conseguirse con una sentencia ' if ' y una ' goto. Por ejemplo:
    program applyopProgram
    call nzaeRun()
    stop
    end
    subroutine nzaeHandleRequest(handle)
    integer hasNext, leftInput, rightInput, result
    character operator
    hasNext = -1
    10 call nzaeGetNext(handle, hasNext)
    if (hasNext .eq. 0) then
    goto 20
    endif
    c Our loop work will go here.
    goto 10
    20 return
    end

    Observa la inicialización de la variable ' hasNext '. Esto es necesario para las variables "out" que llaman a la interfaz subyacente. Sin esto, el puntero ' hasNext ' permanece sin asignar y no puede recibir datos de la llamada subyacente. La función ' nzaeGetNext() ' pone la variable ' hasNext ' a 1 (TRUE) si hay otro elemento en el flujo, y a 0 (FALSE) si el flujo ha terminado.

  4. Añade la lógica:
    program applyOpProgram
    call nzaeRun()
    stop
    end
    subroutine nzaeHandleRequest(handle)
    integer hasNext, leftInput, rightInput, isNull, result
    character operator
    hasNext = -1
    leftInput = 0
    rightInput = 0
    operator = 'f'
    isNull = 0
    10 call nzaeGetNext(handle, hasNext)
    if (hasNext .eq. 0) then
    goto 20
    endif
    c GET OUR INPUT.
    call nzaeGetInputString(handle, 0, operator, isNull)
    call nzaeGetInputInt32(handle, 1, leftInput, isNull)
    call nzaeGetInputInt32(handle, 2, rightInput, isNull)
    c OPERATE.
    if (operator .eq. '+') then
    result = leftInput + rightInput
    else if (operator .eq. '*') then
    result = leftInput * rightInput
    else
    call nzaeUserError(handle, 'Unhandled operator.')
    endif
    c OUTPUT.
    call nzaeSetOutputInt32(handle, 0, result)
    call nzaeOutputResult(handle)
    goto 10
    20 return
    end

    Cada entrada del bucle contiene los tres elementos que se pasan a la función. La función ' nzaeGetInputX() ' toma el manejador que representa una petición del usuario, un índice de columna que en este caso especifica 0 para el operador, 1 para la entrada izquierda y 2 para la entrada derecha, y la variable de salida. La función ' nzaeUserError() ' informa de un error al usuario SQL. La función " nzaeSetOutputX() " emite el resultado. Dado que se ejecuta como una UDF, sólo puede haber una columna en el resultado. Un ejemplo posterior muestra cómo utilizar UDTFs para mostrar múltiples columnas. Cuando el código está completo, hay que compilarlo y registrarlo.

Una compilación

Compila el código:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language fortran --version 3 \
--template compile --exe applyopFortran applyop.f

Los ejecutables de salida, uno para el host y otro para la EPD, se colocan en los directorios " host " y " spu de " /nz/export/ae/applications/$NZ_USER/$NZ_DATABASE"

Registro

Registra los ejecutables:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language fortran --version 3 \
--template udf --exe applyopFortran \
--sig "applyop_fortran(varchar(1), int4, int4)" --return int4

En ejecución

Ahora puede ejecutar el AE en SQL:
SELECT applyop_fortran('+', 4, 10);
APPLYOP
---------
14
(1 row)
Observe que en el código, cuando se validan los tipos en ' nzaeHandleRequest(), se llama a ' nzaeUserError() para enviar un error. El siguiente ejemplo provoca un error:
SELECT applyop_fortran('-',1,2);
ERROR: Unhandled operator.