C++-Datei für UDTF erstellen
Verwenden Sie zunächst einen Texteditor Ihrer Wahl zum Erstellen der C++-Datei. Der Dateiname muss über die Erweiterung .cpp verfügen. Sie können beispielsweise das Verzeichnis /home/nz/udx_files als Bereich für die UDX-Codedateien erstellen.
Ihre C++-Datei muss die Header-Datei ' udxinc.h enthalten, die die erforderlichen Deklarationen für benutzerdefinierte Tabellenfunktionen und die Verarbeitung auf den SPUs enthält.
#include "udxinc.h"
#include "udxinc.h"
#include <string.h>Benutzerdefinierte gemeinsam genutzte Bibliotheken müssen in der Datenbank bereits vorhanden sein, um die UDTF registrieren und diese Bibliotheken als Abhängigkeiten angeben zu können. Sie können die UDTF registrieren, ohne Bibliotheksabhängigkeiten anzugeben. Nach dem Hinzufügen der Bibliotheken können Sie den Befehl ALTER FUNCTION verwenden, um die UDTF-Definition mit den korrekten Abhängigkeiten zu aktualisieren. Weitere Informationen zu benutzerdefinierten gemeinsamen Bibliotheken finden Sie unter Erstellen einer benutzerdefinierten gemeinsamen Bibliothek.
nz::udx_ver2 definiert. Ihr C++-Programm muss auf den korrekten Namensbereich verweisen. Beispiel:#include "udxinc.h"
using namespace nz::udx_ver2;#include "udxinc.h"
using namespace nz::udx_ver2;
class parseNames : public Udtf {
public:
}#include "udxinc.h"
using namespace nz::udx_ver2;
class parseNames : public Udtf {
private:
char value[1000];
int valuelen;
int i;
public:
}- Die Variable
valueenthält eine Kopie des Eingabeparameters. - Die Variable
valuelenenthält die Länge der Eingabezeichenfolge. - Die Variable
isteht für einen Zähler.
- Wie bei UDFs rufen Sie die ' instantiate() -Methode auf, um das UDTF-Objekt dynamisch zu erzeugen. In UDX Version 2 nimmt die ' instantiate -Methode ein ArgumentUdxInit *pInit), das den Zugriff auf die Speicherspezifikation, die Log-Einstellung und die UDX-Umgebung ermöglicht (siehe UDX-Umgebung). Der Konstruktor muss außerdem ein UdxInit-Objekt verwenden und es an den Basisklassenkonstruktor übergeben. Beispiel:
#include "udxinc.h" using namespace nz::udx_ver2; class parseNames : public Udtf { private: char value[1000]; int valuelen; int i; public: parseNames(UdxInit *pInit) : Udtf(pInit) {} static Udtf* instantiate(UdxInit*); }; Udtf* parseNames::instantiate (UdxInit* pInit) { return new parseNames(pInit); } - Für eine UDTF verwenden Sie die Methode newInputRow(), um Initialisierungsaktionen wie beispielsweise das Kopieren von Eingabeargumenten, das Initialisieren von Klassenvariablen sowie das Verwalten von Situationen wie z. B. Nulleingabevariablen auszuführen. Die Methode wird einmal für jede Eingabezeile aufgerufen. Im Beispiel für die UDTF
parseNames wird mit dem folgenden Beispielcode die Eingabeliste in den Variablenwert kopiert, für
valuelendie Länge der Eingabezeichenfolge angegeben und die Variableimit Null initialisiert:virtual void newInputRow() { StringArg *valuesa = stringArg(0); bool valuesaNull = isArgNull(0); if (valuesaNull) valuelen = 0; else { if (valuesa->length >= 1000) throwUdxException("Input value must be less than 1000 characters."); memcpy(value, valuesa->data, valuesa->length); value[valuesa->length] = 0; valuelen = valuesa->length; } i = 0; } - Mit der Methode nextOutputRow() können Sie die nächste Ausgabezeile der Tabelle erstellen und zurückgeben. Des Weiteren müssen Sie ermitteln, ob weitere Daten vorhanden sind, die zurückgegeben werden müssen, und dann 'Done' (Fertig) zurückgeben. Netezza Performance Server ruft diese Methode mindestens einmal pro Eingabezeile auf. Im Folgenden ist ein Beispielcode dargestellt:
virtual DataAvailable nextOutputRow() { if (i >= valuelen) return Done; // save starting position of name int start = i; // scan string for next comma while ((i < valuelen) && value[i] != ',') i++; // return word StringReturn *rk = stringReturnColumn(0); if (rk->size < i-start) throwUdxException("Value exceeds return size"); memcpy(rk->data, value+start, i-start); rk->size = i-start; i++; return MoreData; }Wie im Beispiel dargestellt, erstellen Sie unter Verwendung des geeigneten Spaltenrückgabetyps (z. B. stringReturnColumn() oder intReturnColumn()) eine Spalte und geben deren Position (z. B. 1, 2, 3 usw.) an. Das Syntaxelement für die Rückgabe weiterer Daten ('return MoreData') gibt an, dass eine weitere Zeile zur Verarbeitung ansteht. Wenn die Zählvariable
idas Ende der Eingabezeichenfolge erreicht, stehen keine weiteren Daten mehr zur Verarbeitung an, sodass nextOutputRow() die Meldung 'Done' (Fertig) zurückgibt. - Wenn Ihre UDTF die Syntax TABLE WITH FINAL unterstützt, dann verwenden Sie die Methode nextEoiOutputRow() mindestens einmal nach dem Ende der Eingabe, um alle Daten zu verarbeiten und auszugeben. Die Basisklasse verfügt über eine Standardimplementierung dieser Methode, die bei Aufruf keine Zeilen zurückgibt. Sie weist
Ähnlichkeiten mit nextOutputRow() auf. Eine Ausnahme bildet hierbei lediglich die Tatsache, dass newInputRow() nicht vor ihr aufgerufen
wird. Im Folgenden ist eine Beispielmethode dargestellt:
virtual DataAvailable nextEoiOutputRow() return Done; }