Fortran language aggregates

This example uses the following file name: penultimate.f.

Code

program penultimateUda
call nzaeRun()
stop
end
subroutine order(valueOne, valueTwo, valueThree)
if (valueTwo > valueOne) then
tempValue = valueOne
valueOne = valueTwo
valueTwo = tempValue
endif
if (valueThree > valueTwo) then
tempValue = valueTwo
valueTwo = valueThree
valueThree = tempValue
endif
if (valueTwo > valueOne) then
tempValue = valueOne
valueOne = valueTwo
valueTwo = tempValue
endif
if (valueThree > valueTwo) then
tempValue = valueTwo
valueTwo = valueThree
valueThree = tempValue
endif
return
end
subroutine nzaeHandleRequest(handle)
integer stateBoolean, value1, value2, value3, value4, tempValue
stateBoolean = 0
value1 = 0
value2 = 0
value3 = 0
value4 = 0
tempValue = 0

c GET THE NEXT AGGREGATION TYPE.
10 call nzaeGetNextAggregation(handle)
c HANDLE initializeState().
call nzaeIsAggStateInitializeState(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeSetAggregateInt32(handle, 0, -2147483647)
call nzaeSetAggregateInt32(handle, 1, -2147483647)
call nzaeSaveAggregateResult(handle)
goto 10
endif
c HANDLE accumulate().
call nzaeIsAggStateAccumulate(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeGetStateInt32(handle, 0, value1, isNull)
call nzaeGetStateInt32(handle, 1, value2, isNull)
call nzaeGetInputInt32(handle, 0, value3, isNull)
if (isNull .eq. 0) then
call order(value1, value2, value3)
endif
call nzaeSetAggregateInt32(handle, 0, value1)
call nzaeSetAggregateInt32(handle, 1, value2)
call nzaeSaveAggregateResult(handle)
goto 10
endif
c HANDLE merge().
c The two calls to order() below ensure that value1 and value2
c are the largest two values.
call nzaeIsAggStateMerge(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeGetStateInt32(handle, 0, value1, isNull)
call nzaeGetStateInt32(handle, 1, value2, isNull)
call nzaeGetInputStateInt32(handle, 0, value3, isNull)
value4 = 22
call nzaeGetInputStateInt32(handle, 1, value4, isNull)
if (isNull .eq. 0) then
call order(value1, value2, value3)
call order(value2, value3, value4)
endif
call nzaeSetAggregateInt32(handle, 0, value1)
call nzaeSetAggregateInt32(handle, 1, value2)
call nzaeSaveAggregateResult(handle)
goto 10
endif
c HANDLE finalResult().
call nzaeIsAggStateFinalResult(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeGetStateInt32(handle, 0, value1, isNull)
call nzaeGetStateInt32(handle, 1, value2, isNull)
if (value1 < value2) then
call nzaeSetAggregateInt32(handle, 0, value1)
else
call nzaeSetAggregateInt32(handle, 0, value2)
endif
call nzaeSaveAggregateResult(handle)
goto 10
endif
c HANDLE DONE.
call nzaeIsAggDone(handle, stateBoolean)
if (stateBoolean .eq. 1) then
return
endif
c HANDLE ERRORS.
call nzaeIsAggError(handle, stateBoolean)
if (stateBoolean .eq. 1) then
call nzaeUserError(handle,
+ "Aggregate error state encountered.")
return
endif
c HANDLE INVALID STATE.
call nzaeUserError(handle, "Invalid aggregate state.")
return
end

Compilation

Use the standard compilation:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language fortran --version 3 \
--template compile penultimate.f

Registration

Register the example as a UDA by using the state parameter:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language fortran --version 3 \
--template uda --exe penultimate --sig "penultimate(int4)" \
--state "(int4, int4)" --return int4

Running

To run, first create a dummy table and then run the aggregate:
CREATE TABLE grp_test(value int4);
CREATE TABLE
INSERT INTO grp_test VALUES (1);
INSERT 0 1
INSERT INTO grp_test VALUES (2);
INSERT 0 1
INSERT INTO grp_test VALUES (3);
INSERT 0 1
INSERT INTO grp_test VALUES (4);
INSERT 0 1
INSERT INTO grp_test VALUES (5);
INSERT 0 1
SELECT penultimate(value) FROM grp_test;
PENULTIMATE
-------------
4
(1 row)