Skip to main content

skip to main content

developerWorks  >  Information Management  >

Node DataBlade Module

developerWorks
Document options

Document options requiring JavaScript are not displayed

Sample code


New site feature

Check out our new article design and features. Tell us what you think.


Rate this page

Help us improve this content


Level: Introductory

Paul BrownIBM
Chris Bosch, Contributing Author, IBM

20 Dec 2001

Creates an Informix DataBlade with a new type that solves hierarchical data queries. Includes C source code.

© 2001 International Business Machines Corporation. All rights reserved.

Overview

This demonstration DataBlade™ module implements a variable-length opaque data type (Node), its support routines, and other user-defined routines for accessing and manipulating data elements of that type.

The Node data type is intended to resolve one of the hardest problems in relational databases; transitive closure. It doesn't resolve the problem completely, but it does get us 80% of the way. The transitive closure problem is endemic to data management problems, and not particularly well addressed by the relational model. The same basic problem is found modeling organizational hierarchies, networks, manufacturing and process control databases.

There are a couple of optimizations for addressing the transitive closure problem, dealt with at length in Joe Celko's "SQL For Smarties" (Morgan Kaufmann, 1995). However, all of these optimizations introduce one of several kinds of anomalies, requiring that the database change more than one tuple in response to more than one fact. Also, the SQL needed to write the operations over the tree are complex, difficult to optimize and execute and -- even at their very best -- slow.

The Node data type introduced in this document and implemented by this demonstration DataBlade module provides a quite lateral solution to this problem. The basic idea is to create a type and operations over that type which models the tree structure itself and to represent the facts of the tree structure in that way, rather than reduce these facts to overly simple relations.

The external representation of the Node data type is an ordinal number (integer greater than 0), followed by either a single .0 or a set of ordinal numbers separated by dots. Examples of valid and invalid Node data elements are presented below.

Valid Nodes

{ 1.0, 1.1, 1.1.1, 1.2, 1.2.1, 999.0, 999.1.999 }

Invalid Nodes

{ 0, 0.0, 0.1, 1.0.1, 1.1.0, 1.-1.2, 1.A.4 }

There are several things to note about this type. First, it isn't enough to treat this as a simple string. The ordering of a set of Node objects is not the same as the conventional string ordering of their representations. Nor is it possible to define a collation sequence which would result in the correct ordering. This makes is impossible to use this kind of approach with a DBMS which does not support extensible types. The sorting algorithms necessary can be written outside the database, and client applications can make use of the approach when comparing two values. However, this has obvious limitations. Included below is an example showing the how data elements are ordered differently when they are treated as Nodes rather than as strings.

T is the following unordered set of data elements;

T := { 1.2, 1.0, 1.12, }

T ordered as strings;

T := { 1.0, 1.12, 1.2 }

T ordered as Nodes;

T := { 1.0, 1.2, 1.12 }

Secondly, incrementing elements of the Node data type is more complex than incrementing elements of a totally-ordered discrete data type such as the set of integers. Incrementing a Node (adding one to the least significant value in the Node) does not guarantee that the resulting data element will be the smallest Node greater than the original as would be guaranteed by the increment operation for integers.

For example, given the following set of Node objects, T := { 1.0, 1.2, 1.2.1, 1.2.2 }, we find there are Nodes between Node 1.2 and Increment (1.2) = 1.3.

 
1.2 < 1.3 
1.2 < 1.2.1 < 1.3
1.2 < 1.2.2 < 1.3

In general, there may be Nodes in any given set of Nodes which are between a Node and its increment. Furthermore, note that the Nodes which are 'BETWEEN' Node N and Increment(N) are 'Under' Node N. That is, both Nodes 1.2.1 and 1.2.2 are 'Under' 1.2. This 'Under' relation is the same as saying that the Node is BETWEEN the Node and its Increment. This is an extremely interesting and valuable property of the Node data type described here.

There are many other interesting properties of the Node data type that can be exploited in a variety of applications. To learn more about the functionality provided by the Node data type, download this demonstration DataBlade module and experiment with it. The sections to follow describe the software required for working with the Node DataBlade module as well as the procedures for downloading the distribution, building the shared object library, installing the DataBlade module, and registering the DataBlade module in a database. Examples demonstrating most of the Node DataBlade module's User-Defined Routines (UDRs) are included at the end of this document.



Back to top


Software Requirements

To build and run Node.1.0, you need a C compiler to build the shared object and Informix® Dynamic Server with Universal Data Option (IDS-UD) 9.14 or higher.

Node.1.0 was tested with the software releases listed below:

UNIX:

  • Solaris 2.5.1

  • IDS/UDO 9.14.UC6

  • SUNpro C Compiler

NT:

  • NT 4.0, Service Pack 3

  • IDS/UDO 9.14.TC4

  • Microsoft Visual C++ 6.0



Back to top


Getting Started

Download the distribution

Download the Node.1.0.tar.Z distribution file, found in the Download section, and uncompress and unarchive it using utilities available for your platform as follows:

UNIX:

To uncompress and unarchive the distribution file under UNIX, enter the following command at the shell prompt:

 
zcat Node.1.0.tar.Z | tar xvf - 

NT:

To uncompress and unarchive the distribution file under NT, use WinZip or a similar utility that can handle compressed UNIX tar files.

The distribution is extracted into a directory hierarchy under Node.1.0. The directory contents, summarized below, can be viewed on-line by clicking here.

demo/

Demo scripts that exercise the UDRs.

scripts/

SQL registration scripts. The contents of this directory should be copied to $INFORMIXDIR/extend/Node.1.0.

src/c

Source code for the UDRs.

Node.ibs

BladeSmith project generated with BladeSmith version 3.70.TC1.

Build the shared object library

The distribution for this demo DataBlade comes with pre-built shared object libraries for Solaris 2.5.1 and Windows NT 4.0. If you are not on one of those platforms or if you make modifications to the demo source code, you must recompile for your platform using the instructions provided below.

UNIX:

To build your DataBlade module on UNIX, first transport the generated files to your UNIX machine. On your UNIX machine, set the TARGET environment variable to the location/filename of the platform-specific make include file. For Solaris, this is "$INFORMIXDIR/incl/dbdk/makeinc.solaris".

UNIX.mak is the makefile used to build the DataBlade module under UNIX. To build the DataBlade module, type:

 
make -f UNIX.mak 

Detailed instructions for building a UNIX shared object library are included in the "DataBlade Developers Kit User Guide".

NT:

If you intend to compile your DataBlade module for NT, you may use either the WinNT.mak or Node.mak makefiles.

To build your DataBlade module from the command line, type

 
nmake -s -nologo -f WinNT.mak 

To load your DataBlade module's source files into Microsoft Visual C++ version 4.1, select "Open Workspace..." from the menus. When using versions 4.2 or later, select "Open Workspace..." from the menus. For the project name, type Node.mak. For version 5.0 and later, the makefile is automatically converted.

Detailed instructions for building an NT dynamically-linked library (DLL) are included in the "DataBlade Developers Kit User Guide".

Install the DataBlade module

Login as user informix, change to the Node.1.0 directory in which the distribution has been unarchived, and follow the steps outlined below for your platform.

UNIX:

 
mkdir $INFORMIXDIR/extend/Node.1.0 
cp ./scripts/* $INFORMIXDIR/extend/Node.1.0 
cp ./src/solaris-sparc/Node.bld $INFORMIXDIR/extend/Node.1.0 

NT:

 
mkdir %INFORMIXDIR%\extend\Node.1.0 
cp .\scripts\* %INFORMIXDIR%\extend\Node.1.0 
cp .\src\WinNT-i386\Node.bld %INFORMIXDIR%\extend\Node.1.0 

Register the DataBlade module in a database

Start BladeManager from either the UNIX system prompt or the MS-DOS command prompt as appropriate for your platform and register the demo DataBlade module as shown in the example below.

 
blademgr 
shm>register Node.1.0 demodb 
Register module Node.1.0 into database demodb? [Y/n]y 
Registering DataBlade module... (may take a while). 
DataBlade Node.1.0 was successfully registered in database demodb. 
shm>bye 
Disconnecting... 



Back to top


User-Defined Types (UDTs)

This demonstration DataBlade module defines a variable-length opaque data type as follows:

 
create opaque type Node( 
	internallength = variable, 
	maxlen = 64, 
	alignment = 4 
); 



Back to top


User-Defined Routines (UDRs)

Basic Text Input/Output

User-defined routines supporting basic text input/output for the Node data type are listed below.

  • NodeIn (lvarchar) returns Node

  • NodeOut (Node) returns lvarchar

Binary Send/Receive

User-defined routines supporting binary send/receive with clients for the Node data type are listed below.

  • NodeSend (Node) returns sendrecv

  • NodeRecv (sendrecv) returns Node

Text File Import/Export

User-defined routines supporting text file import/export for the Node data type are listed below.

  • NodeImpT (impexp) returns Node

  • NodeExpT (Node) returns impexp

Binary File Import/Export

User-defined routines supporting binary file import/export for the Node data type are listed below.

  • NodeImpB (impexpbin) returns Node

  • NodeExpB (Node) returns impexpbin

Type Compare and B-tree Indexing Support

User-defined routines supporting type comparison and b-tree indexing operations for the Node data type are listed below.

  • Compare (Node,Node) returns integer

  • Equal (Node,Node) returns boolean

  • NotEqual (Node,Node) returns boolean

  • LessThan (Node,Node) returns boolean

  • GreaterThan (Node,Node) returns boolean

  • LessThanOrEqual (Node,Node) returns boolean

  • GreaterThanOrEqual (Node,Node) returns boolean

Other UDRs

Other user-defined routines for accessing and manipulating Node data elements are listed below.

  • Length (Node) returns integer

  • GetMember (Node,integer) returns integer

  • GetParent (Node) returns Node

  • Increment (Node) returns Node

  • Increment (Node,integer) returns Node

  • IsParent (Node,Node) returns boolean

  • IsChild (Node,Node) returns boolean

  • IsAncestor (Node,Node) returns boolean

  • IsDescendant (Node,Node) returns boolean

  • Ancestors (Node) returns Node

  • NewLevel (Node) returns Node

  • Graft (Node,Node,Node) returns Node



Back to top


Examples of Use

Type compare support functions

 
 
SELECT 
	a.n a, 
	b.n b, 
	compare(a.n,b.n) compare_a_b, 
	a.n = b.n eq_a_b, 
	a.n != b.n neq_a_b 
FROM 
	nodes a, 
	nodes b; 
 
a            b            compare_a_b  eq_a_b       neq_a_b 
----------------------------------------------------------------- 
1.0          1.0          0            t            f 
1.2          1.0          1            f            t 
1.2.1        1.0          1            f            t 
3.0          1.0          1            f            t 
3.1          1.0          1            f            t 
1.0          1.2          -1           f            t 
1.2          1.2          0            t            f 
1.2.1        1.2          1            f            t 
3.0          1.2          1            f            t 
3.1          1.2          1            f            t 
1.0          1.2.1        -1           f            t 
1.2          1.2.1        -1           f            t 
1.2.1        1.2.1        0            t            f 
3.0          1.2.1        1            f            t 
3.1          1.2.1        1            f            t 
1.0          3.0          -1           f            t 
1.2          3.0          -1           f            t 
1.2.1        3.0          -1           f            t 
3.0          3.0          0            t            f 
3.1          3.0          1            f            t 
1.0          3.1          -1           f            t 
1.2          3.1          -1           f            t 
1.2.1        3.1          -1           f            t 
3.0          3.1          -1           f            t 
3.1          3.1          0            t            f 
 
25 rows affected by select command 
 

B-tree indexing support functions

 
 
 
SELECT 
	a.n a, 
	b.n b, 
	a.n >= b.n gte_a_b, 
	a.n > b.n gt_a_b, 
	a.n < b.n lt_a_b, 
	a.n <= b.n lte_a_b 
FROM 
	nodes a, 
	nodes b; 
 
a            b            gte_a_b      gt_a_b       lt_a_b       lte_a_b 
------------------------------------------------------------------------------ 
1.0          1.0          t            f            f            t 
1.2          1.0          t            t            f            f 
1.2.1        1.0          t            t            f            f 
3.0          1.0          t            t            f            f 
3.1          1.0          t            t            f            f 
1.0          1.2          f            f            t            t 
1.2          1.2          t            f            f            t 
1.2.1        1.2          t            t            f            f 
3.0          1.2          t            t            f            f 
3.1          1.2          t            t            f            f 
1.0          1.2.1        f            f            t            t 
1.2          1.2.1        f            f            t            t 
1.2.1        1.2.1        t            f            f            t 
3.0          1.2.1        t            t            f            f 
3.1          1.2.1        t            t            f            f 
1.0          3.0          f            f            t            t 
1.2          3.0          f            f            t            t 
1.2.1        3.0          f            f            t            t 
3.0          3.0          t            f            f            t 
3.1          3.0          t            t            f            f 
1.0          3.1          f            f            t            t 
1.2          3.1          f            f            t            t 
1.2.1        3.1          f            f            t            t 
3.0          3.1          f            f            t            t 
3.1          3.1          t            f            f            t 
 
25 rows affected by select command 
 

Length function

 
 
SELECT 
	a.n a, 
	length(a.n) len_a 
FROM 
	nodes a; 
 
a            len_a 
-------------------------- 
1.0          1 
1.2          2 
1.2.1        3 
3.0          1 
3.1          2 
 
5 rows affected by select command 
 

GetMember function

 
 
SELECT 
	a.n a, 
	getmember(a.n, 1) getmem_a_1, 
	getmember(a.n, 2) getmem_a_2, 
	getmember(a.n, 3) getmem_a_3 
FROM 
	nodes a; 
 
a            getmem_a_1   getmem_a_2   getmem_a_3 
---------------------------------------------------- 
1.0          1            0            NULL 
1.2          1            2            NULL 
1.2.1        1            2            1 
3.0          3            0            NULL 
3.1          3            1            NULL 
 
5 rows affected by select command 
 

GetParent function

 
 
SELECT 
	a.n a, 
	getparent(a.n) getpar_a 
FROM 
	nodes a; 
 
a            getpar_a 
-------------------------- 
1.0          NULL 
1.2          1.0 
1.2.1        1.2 
3.0          NULL 
3.1          3.0 
 
5 rows affected by select command 
 

Increment functions

 
 
SELECT 
	a.n a, 
	increment(a.n) incr_a, 
	increment(a.n,1) incr_a_1, 
	increment(a.n,2) incr_a_2, 
	increment(a.n,3) incr_a_3 
FROM 
	nodes a; 
 
a            incr_a       incr_a_1     incr_a_2     incr_a_3 
----------------------------------------------------------------- 
1.0          2.0          2.0          1.1          NULL 
1.2          1.3          2.0          1.3          NULL 
1.2.1        1.2.2        2.0          1.3          1.2.2 
3.0          4.0          4.0          3.1          NULL 
3.1          3.2          4.0          3.2          NULL 
 
5 rows affected by select command 
 

IsAncestor, IsParent, IsChild, IsDescendant functions

 
 
SELECT 
	a.n a, 
	b.n b, 
	isancestor(a.n,b.n) isanc_a_b, 
	isparent(a.n,b.n) ispar_a_b, 
	ischild(a.n,b.n) ischi_a_b, 
	isdescendant(a.n,b.n) isdes_a_b 
FROM 
	nodes a, 
	nodes b; 
 
a            b            isanc_a_b    ispar_a_b    ischi_a_b    isdes_a_b 
------------------------------------------------------------------------------ 
1.0          1.0          f            f            f            f 
1.2          1.0          f            f            t            t 
1.2.1        1.0          f            f            f            t 
3.0          1.0          f            f            f            f 
3.1          1.0          f            f            f            f 
1.0          1.2          t            t            f            f 
1.2          1.2          f            f            f            f 
1.2.1        1.2          f            f            t            t 
3.0          1.2          f            f            f            f 
3.1          1.2          f            f            f            f 
1.0          1.2.1        t            f            f            f 
1.2          1.2.1        t            t            f            f 
1.2.1        1.2.1        f            f            f            f 
3.0          1.2.1        f            f            f            f 
3.1          1.2.1        f            f            f            f 
1.0          3.0          f            f            f            f 
1.2          3.0          f            f            f            f 
1.2.1        3.0          f            f            f            f 
3.0          3.0          f            f            f            f 
3.1          3.0          f            f            t            t 
1.0          3.1          f            f            f            f 
1.2          3.1          f            f            f            f 
1.2.1        3.1          f            f            f            f 
3.0          3.1          t            t            f            f 
3.1          3.1          f            f            f            f 
 
25 rows affected by select command 
 

Ancestors iterator function

 
 
EXECUTE FUNCTION ancestors('1.2.3.4.5.6.7.8.9'); 
 
(expression) 
--------------- 
1.2.3.4.5.6.7.8 
1.2.3.4.5.6.7 
1.2.3.4.5.6 
1.2.3.4.5 
1.2.3.4 
1.2.3 
1.2 
1.0 
 
8 rows affected by execute function command 
 

NewLevel function

 
 
SELECT 
	a.n a, 
	newlevel(a.n) newlvl_a 
FROM 
	nodes a; 
 
a            newlvl_a 
-------------------------- 
1.0          1.1 
1.2          1.2.1 
1.2.1        1.2.1.1 
3.0          3.1 
3.1          3.1.1 
 
5 rows affected by select command 
 

Graft function

 
 
SELECT 
	a.n a, 
	b.n b, 
	c.n c, 
	graft(a.n,b.n,c.n) graft_a_b_c 
FROM 
	nodes a, 
	nodes b, 
	nodes c 
WHERE 
	isancestor(a.n, c.n); 
 
a            b            c            graft_a_b_c 
---------------------------------------------------- 
1.0          1.0          1.2          1.2 
1.0          1.2          1.2          1.2.2 
1.0          1.2.1        1.2          1.2.1.2 
1.0          3.0          1.2          3.2 
1.0          3.1          1.2          3.1.2 
1.0          1.0          1.2.1        1.2.1 
1.0          1.2          1.2.1        1.2.2.1 
1.0          1.2.1        1.2.1        1.2.1.2.1 
1.0          3.0          1.2.1        3.2.1 
1.0          3.1          1.2.1        3.1.2.1 
1.2          1.0          1.2.1        1.1 
1.2          1.2          1.2.1        1.2.1 
1.2          1.2.1        1.2.1        1.2.1.1 
1.2          3.0          1.2.1        3.1 
1.2          3.1          1.2.1        3.1.1 
3.0          1.0          3.1          1.1 
3.0          1.2          3.1          1.2.1 
3.0          1.2.1        3.1          1.2.1.1 
3.0          3.0          3.1          3.1 
3.0          3.1          3.1          3.1.1 
 
20 rows affected by select command 
 

IBM, DB2, Informix, and WebSphere are trademarks or registered trademarks of IBM Corporation in the United States, other countries, or both.

Windows and Windows NT are registered trademarks of Microsoft Corporation in the United States, other countries, or both.

Java and all Java-based trademarks and logos are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both.

Other company, product, and service names may be trademarks or service marks of others.

IBM copyright and trademark information




Back to top


Download

DescriptionNameSizeDownload method
Distribution fileNode.1.0.tar.Z200 KBHTTP
Information about download methods


Resources

Learn

Get products and technologies
  • Build your next development project with IBM trial software, available for download directly from developerWorks.


Discuss


About the authors

Paul Brown is an IBM contributing author.


Chris Bosch is an IBM contributing author.




Rate this page


Please take a moment to complete this form to help us better serve you.



 


 


Not
useful
Extremely
useful
 


Share this....

digg Digg this story del.icio.us del.icio.us Slashdot Slashdot it!



Back to top