Scalable Database Server, HiRDB Version 8 UAP Development Guide
The hash function for table partitioning uses the partitioning key values to obtain the order of partitioning conditions that are specified for partitioning a table. If a UAP is executed using the hash function for table partitioning, the storage RDAREAs can be identified before data is stored in a table, even if the table is a hash-partitioned table. Because this function can identify each storage RDAREA, you can use the function for the following purposes:
The following describes the prerequisites for using the hash function for table partitioning.
When the hash function for table partitioning is used to create a UAP, the UAP can be written in either C or C++.
The hash function for table partitioning can be executed on a server machine in which a HiRDB server or HiRDB client has been installed.
However, certain combinations of a HiRDB server operating system and a HiRDB client operating system can produce incorrect results when the function is executed with a HiRDB client.
Table G-1 shows the UAP execution conditions in the HiRDB client.
Table G-1 Execution conditions in the HiRDB client
HiRDB server operating system | HiRDB client operating system | |
---|---|---|
HP-UX, Solaris, and AIX 5L | Linux and Windows | |
HP-UX, Solaris, and AIX 5L | E | |
Linux and Windows | E |
Create and execute a UAP according to the following procedure:
Specify function calling of the hash function for table partitioning in the source program written in C or C++. Because the hash function for table partitioning is presented in a shared library format, link the source program to use the function.
When the hash function for table partitioning is used, the distributed header files must be included when the source program is created. Include all header files required by the hash function for table partitioning. For details about the header files required by the hash function for table partitioning, see (3) Function details.
Compile and link the source program in a server machine that has either the HiRDB server or HiRDB client installed.
If SQL statements are embedded in the source program, preprocessing must be executed before compiling and linking.
For details about compiling, linking, and preprocessing, see 8. Preparation for UAP Execution.
cc -l $PDDIR/include sample.c -L$PDDIR/client/lib -l sqlauxf
cc +DD64 -l $PDDIR/include sample.c -L$PDDIR/client/lib -l sqlauxf64
CC -l $PDDIR/include sample.C -L$PDDIR/client/lib -l sqlauxf
CC +DD64 -l $PDDIR/include sample.C -L$PDDIR/client/lib -l sqlauxf64
cc -l /HiRDB/include sample.c -L/HiRDB/client/lib -l sqlauxf
cc +DD64 -l /HiRDB/include sample.c -L/HiRDB/client/lib -l sqlauxf64
CC -l /HiRDB/include sample.C -L/HiRDB/client/lib -l sqlauxf
CC +DD64 -l /HiRDB/include sample.C -L/HiRDB/client/lib -l sqlauxf64
Table G-2 Items to be set in the HiRDB server with Set Project or Set
Item | Category | Category setting | Setting value |
---|---|---|---|
Compiler | Code generation | Structure member alignment | 8 bytes |
Run time library to be used | Multi-thread | ||
Processor | Include file path | \HiRDB\client\include | |
Linker | Input | Library | \HiRDB\client\lib\pdsqlauxf.lib |
Table G-3 Items to be set in the HiRDB client with Set Project or Set
Item | Category | Category setting | Setting value |
---|---|---|---|
Compiler | Code generation | Structure member alignment | 8 bytes |
Run time library to be used | Multi-thread | ||
Processor | Include file path | \HiRDB\include | |
Linker | Input | Library | \HiRDB\lib\pdsqlauxf.lib |
To call the hash function for table partitioning, obtain the information for items 1 through 8, described as follows, and set the information to arguments.
Items 1 through 4 correspond to the following sections in the CREATE TABLE statement:
If the table is already defined, information for items 1 through 4 can be obtained by retrieving the dictionary table. For examples of dictionary table retrieval, see (6) Retrieval from dictionary tables (for hash partitioning).
For details about the space conversion level (space conversion facility) and the facility for conversion to a DECIMAL signed normalized number, see the HiRDB Version 8 System Operation Guide.
Details about the hash function for table partitioning are explained as follows:
int p_rdb_dbhash(short hashcode, short ncol, p_rdb_collst_t *collst, p_rdb_dadlst_t *dadlst, unsigned int ndiv, unsigned char ncspace[2], int flags, int *rdno); |
Table G-4 Double-byte space characters specified in ncspace
Character code type specified in pdsetup2 | ncspace | |
---|---|---|
ncspace[0] | ncspace[1] | |
sjis (shift JIS kanji code) | 0x81 | 0x40 |
Chinese (EUC Chinese kanji code) | 0xA1 | 0xA1 |
ujis (EUC Japanese kanji code) | 0xA1 | 0xA1 |
lang-c (single-byte character code)1 | 0x00 | 0x00 |
Unicode (UTF-8)3 | 0x00 | 0x00 |
Default value (sjis for HP-UX) | 0x81 | 0x40 |
Default value (sjis for AIX 5L) | 0x81 | 0x40 |
Default value (ujis for Solaris) | 0xA1 | 0xA1 |
Default value (ujis for Linux) | 0xA1 | 0xA1 |
Default value (sjis for Windows) | 0x81 | 0x40 |
HiRDB operating environment | Value of flags | |
---|---|---|
Space conversion level* | Omitted | p_rdb_FLG_SPLVL_0 |
0 | ||
1 | p_rdb_FLG_SPLVL_1 | |
3 | p_rdb_FLG_SPLVL_3 | |
Facility for conversion to a DECIMAL signed normalized number | Omitted | p_rdb_FLG_DECNRM_N |
N | ||
Y | p_rdb_FLG_DECNRM_Y |
Table G-5 shows the hash function codes that correspond to the hash functions specified in CREATE TABLE or ALTER TABLE.
Table G-5 Hash function codes for hash functions
Hash function name | Hash function code (value) |
---|---|
HASH1(when hash function name is omitted) | p_rdb_HASH1(1) |
HASH2 | p_rdb_HASH2(2) |
HASH3 | p_rdb_HASH3(3) |
HASH4 | p_rdb_HASH4(4) |
HASH5 | p_rdb_HASH5(5) |
HASH6 | p_rdb_HASH6(6) |
HASH0 | p_rdb_HASH0(100) |
HASHA | p_rdb_HASHA(101) |
HASHB | p_rdb_HASHB(102) |
HASHC | p_rdb_HASHC(103) |
HASHD | p_rdb_HASHD(104) |
HASHE | p_rdb_HASHE(105) |
HASHF | p_rdb_HASHF(106) |
The partitioning key list is a structure composed of data type codes and data length codes for partitioning keys, and is allocated a contiguous area for all partitioning keys. Table G-6 shows the area for setting partitioning keys. If there are multiple partitioning keys, the area must be specified as an array consisting of all columns specified as partitioning keys.
Table G-7 lists the data type codes and the data length codes.
Table G-6 Area for setting partitioning keys
Data type | Data type details | Explanation |
---|---|---|
p_rdb_collst_t | struct p_rdb_TG_collst { unsigned short datatype ; short datalen ; } p_rdb_collst_t ; |
Data type code Data length code |
Table G-7 Data type codes and data length codes
Data type | Data type code | Data length code |
---|---|---|
INTERVAL YEAR TO DAY | PDSQL_YEARTODAY | 8 256 |
INTERVAL HOUR TO SECOND | PDSQL_HOURTOSEC | 6 256 |
DATE | PDSQL_DATE | 4 |
TIME | PDSQL_TIME | 3 |
TIMESTAMP[(p)] | PDSQL_TIMESTAMP | 7 + p/2 (0 is assumed if p is omitted.) |
MVARCHAR(n) | PDSQL_MVARCHAR | n |
MCHAR[(n)] | PDSQL_MCHAR | n (default value is 1) |
NVARCHAR(n) | PDSQL_NVARCHAR | n |
NCHAR[(n)] | PDSQL_NCHAR | n (default value is 1) |
VARCHAR(n) | PDSQL_VARCHAR | n |
CHAR[(n)] | PDSQL_CHAR | n (default value is 1) |
FLOAT | PDSQL_FLOAT | 8 |
SMALLFLT | PDSQL_SMALLFLT | 4 |
DECIMAL[(p[,q])] | PDSQL_DECIMAL | p 256 + q (default values are 15 for p and 0 for q) |
INTEGER | PDSQL_INTEGER | 4 |
SMALLINT | PDSQL_SMALLINT | 2 |
The data address list is a structure composed of the addresses to the data storage areas for partitioning keys, and is allocated as a contiguous area for all partitioning keys. Table G-8 shows the area for setting the data address of a partitioning key. If there are multiple partitioning keys, the area must be specified as an array consisting of all columns specified as partitioning keys.
Specify the area in binary format. For details about the binary format, see the HiRDB Version 8 Command Reference manual.
Table G-8 Area for setting the data address of a partitioning key
Data type | Data type details | Explanation |
---|---|---|
p_rdb_dadlst_t | struct p_rdb_TG_dadlst { unsigned char * dataaddr ; } p_rdb_dadlst_t ; |
Address to data area |
Table G-9 lists the macros for maximum values.
Table G-9 Macros for maximum values
Macro name | Description (value) |
---|---|
p_rdb_MXDCL | Maximum number of partitioning key columns (16) |
p_rdb_MNCND | Maximum number of table partitions (1024) |
A partial coding example that uses C to describe hash partitioning is shown below. Use this coding example by customizing it to suit the user needs. However, because this example does not include error handling during SQL statement execution, code error handling as needed. For details about error handling, see 3.6 SQL error identification and corrective measures.
/***************************************************************/ /* ALL RIGHTS RESERVED. COPYRIGHT (C) 1999,2000, HITACH, LTD. */ /* LICENSED MATERIAL OF HITACHI,LTD. */ /* Sample Program that Uses the Hash Function for Table Partitioning */ /***************************************************************/ #include <stdio.h> #include <string.h> #include <pdbsqlda.h> #include <pddbhash.h> union data_area { /* Data storage area */ short data_smallint ; int data_int ; unsigned char data_dec[15] ; float data_smallflt ; double data_float ; unsigned char data_char[255] ; struct { short length ; unsigned char data[255] ; } data_varchar ; unsigned char data_date[4] ; unsigned char data_time[3] ; unsigned char data_timestamp[10] ; unsigned char data_iytd[5] ; unsigned char data_ihts[4] ; } ; void print_data(short , p_rdb_collst_t * , union data_area *) ; /***************************************************************/ /* Main Function */ /***************************************************************/ int main(int argc , char *argv[]) { short hashcode ; /* Hash function code */ short ncol ; /* Number of partitioning key columns */ p_rdb_collst_t collst[p_rdb_MXDCL] ;/* Partitioning key list */ p_rdb_dadlst_t dadlst[p_rdb_MXDCL] ;/* Data address list */ union data_area data[p_rdb_MXDCL] ; /* Data storage area */ unsigned int ndiv ; /* Number of storage RDAREAs */ unsigned char ncspace[2] ; /* Space code for each national character code type */ int flags ; /* Enhancement flag */ int rdno ; /* Partitioning condition specification order */ int rc ; /* Return value */ short i, j, k ; /* Counter variables */ struct rdarea { /* RDAREA list */ int rdareaid ; char rdareaname[31] ; } rdarealst [p_rdb_MNCND] ; EXEC SQL BEGIN DECLARE SECTION ; struct { /* Embedded variable for hash function name */ short length ; char data[9] ; } xhashname ; short xncol ; /* Embedded variable for number of partitioning key columns */ short xndiv ; /* Embedded variable for number of table partitions */ short xdatatype ; /* Embedded variable for data type code */ short xdatalen ; /* Embedded variable for data length code */ struct { /* Embedded variable for storage RDAREA name */ short length ; char data[31] ; } xrdname ; EXEC SQL END DECLARE SECTION ; EXEC SQL CONNECT ;
for (k = 0 ; k < p_rdb_MXDCL ; k ++) { dadlst[k].dataaddr = (unsigned char *)&data[k] ; } ncspace[0] = 0x81 ; /* Space code */ ncspace[1] = 0x40 ; /* Example of shift JIS kanji code */ flags = 0 ;
/****************************************************************/ /* (a) Specifying explicitly */ /* 1 specified for space conversion level and Y for facility */ /* for conversion to a DECIMAL signed normalized number */ /****************************************************************/ flags=p_rdb_FLG_SPLVL_1+p_rdb_FLG_DECNRM_Y;
/**********************************************************/ /*(a)Setting values with codes */ /**********************************************************/ hashcode = p_rdb_HASH6 ; /* When HASH6 is specified */ ncol = 4 ; /* For partitioning with 4 columns */ ndiv = 6 ; /* For 6 partitions */ /**********************************************************/ /* (b) Retrieving values from the dictionary table */ /**********************************************************/ EXEC SQL select HASH_NAME, value(N_DIV_COLUMN,1) , N_RDAREA into :xhashname , :xncol, :xndiv from MASTER.SQL_TABLES where TABLE_SCHEMA=USER and TABLE_NAME='TABLE1' ; xhashname.data[xhashname.length] = '\0' ; if (strcmp(xhashname.data,"HASH1") == 0) { hashcode=p_rdb_HASH1 ; /* HASH1 setting */ } else if (strcmp(xhashname.data,"HASH2") == 0) { hashcode=p_rdb_HASH2 ; /* HASH2 setting */ } else if (strcmp(xhashname.data,"HASH3") == 0) { hashcode=p_rdb_HASH3 ; /* HASH3 setting */ } else if (strcmp(xhashname.data,"HASH4") == 0) { hashcode=p_rdb_HASH4 ; /* HASH4 setting */ } else if (strcmp(xhashname.data,"HASH5") == 0) { hashcode=p_rdb_HASH5 ; /* HASH5 setting */ } else if (strcmp(xhashname.data,"HASH6") == 0) { hashcode=p_rdb_HASH6 ; /* HASH6 setting */ } else if (strcmp(xhashname.data,"HASHA") == 0) { hashcode=p_rdb_HASH0 ; /* HASH0 setting */ } else if (strcmp(xhashname.data,"HASHA") == 0) { hashcode=p_rdb_HASHA ; /* HASHA setting */ } else if (strcmp(xhashname.data,"HASHB") == 0) { hashcode=p_rdb_HASHB ; /* HASHB setting */ } else if (strcmp(xhashname.data,"HASHC") == 0) { hashcode=p_rdb_HASHC ; /* HASHC setting */ } else if (strcmp(xhashname.data,"HASHD") == 0) { hashcode=p_rdb_HASHD ; /* HASHD setting */ } else if (strcmp(xhashname.data,"HASHE") == 0) { hashcode=p_rdb_HASHE ; /* HASHE setting */ } else if (strcmp(xhashname.data,"HASHF") == 0) { hashcode=p_rdb_HASHF ; /* HASHF setting */ } else { /* Add when a hash function is added in the future. */ } ncol = xncol ; ndiv = xndiv ; /********************************************************/ /* Displaying table definition information */ /********************************************************/ printf("Hash function code:%d\n",hashcode); printf("Number of partitioning key columns:%d\n",ncol); printf("Number of table partitions:%d\n",ndiv); printf("\n") ;
/**********************************************************/ /* (a) Setting values with codes */ /**********************************************************/ collst[0].datatype=PDSQL_CHAR ; /* CHAR(10)*/ collst[0].datalen=10 ; collst[1].datatype=PDSQL_DECIMAL ; /* DEC(5,2) */ collst[1].datalen=5*256+2 ; collst[2].datatype=PDSQL_SMALLINT ; /* SMALLINT */ collst[2].datalen=2 ; collst[3].datatype=PDSQL_NVARCHAR ; /* NVARCHAR(4) */ collst[3].datalen=4 ; /**********************************************************/ /* (b) Retrieving values from the dictionary table */ /**********************************************************/ EXEC SQL declare cr1 cursor for select value(DIVCOL_ORDER,1) , DATA_TYPE_CODE, DATA_LENGTH_CODE from MASTER.SQL_COLUMNS where TABLE_SCHEMA=USER and TABLE_NAME='TABLE1' and DIVIDED_KEY='Y' order by 1 asc ; EXEC SQL open cr1 ; EXEC SQL whenever not found goto fetch_end1 ; for (i = 0 ; ; i++) { EXEC SQL fetch cr1 into :xncol , : xdatatype , : xdatalen ; collst[i].datatype = xdatatype ; collst[i].datalen = xdatalen ; } fetch_end1 : EXEC SQL close cr1 ;
/**********************************************************/ /* Retrieving values from the dictionary table */ /**********************************************************/ EXEC SQL declare cr2 cursor for select RDAREA_NAME from MASTER.SQL_DIV_TABLE where TABLE_SCHEMA=USER and TABLE_NAME='TABLE1' order by DIV_NO asc ; EXEC SQL open cr2 ; EXEC SQL whenever not found goto fetch_end2 ; for (j = 0 ; ; j++) { EXEC SQL fetch cr2 into :xrdname ; strncpy(rdarealst[j].rdareaname, xrdname.data, xrdname.length) ; rdarealst[j].rdareaname[xrdname.length] = '\0' ; } fetch_end2 : EXEC SQL close cr2 ; EXEC SQL DISCONNECT ; /**********************************************************/ /* Displaying RDAREA information */ /**********************************************************/ printf("RDAREA-name[") ; for (j = 0 ; j<ndiv ; j++) { printf("%s",rdarealst[j].rdareaname) ; if (j != ndiv-1) { printf(",") ; } else ; } printf("]\n") ; printf("\n") ;
/***************************************************************/ /* Assigning data in binary format. */ /* Setting data and call hash function for each line. */ /***************************************************************/ memcpy((char *)data[0].data_char,"abcdefg ",10) ;/*"abcdefg " */ data[1].data_dec[0] = 0x04 ; data[1].data_dec[1] = 0x32 ; data[1].data_dec[2] = 0x1D ; /* -43.21 */ data[2].data_smallint = 12345 ; /* 12345 */ /* NCHAR and NVARCHAR specify character codes used in the HiRDB server.*/ data[3].data_varchar.length = 6 ; data[3].data_varchar.data[0] = 0x82 ; /* Example of shift JIS kanji code */ data[3].data_varchar.data[1] = 0xa0 ; /* Example of shift JIS kanji code */ data[3].data_varchar.data[2] = 0x82 ; /* Example of shift JIS kanji code */ data[3].data_varchar.data[3] = 0xa2 ; /* Example of shift JIS kanji code */ data[3].data_varchar.data[4] = 0x82 ; /* Example of shift JIS kanji code */ data[3].data_varchar.data[5] = 0xa4 ; /* Example of shift JIS kanji code */ /***************************************************************/ /*Displaying data type code, data length code, and data area */ /***************************************************************/ print_data(ncol , collst , data) ; /***************************************************************/ /* Hash function call */ /***************************************************************/ rc = p_rdb_dbhash(hashcode,ncol,collst,dadlst,ndiv,ncspace,flags,&rdno); switch (rc) { case p_rdb_RC_RTRN : /*************************************************************/ /* Normal processing */ /*************************************************************/ printf("Partitioning condition specification order : %d -> %s\n", rdno,rdarealst[rdno-1].rdareaname) ; break ; default : /***************************************************************/ /* Adding error processing */ /***************************************************************/ printf("RETURN CODE=%d\n",rc) ; break ; } return ; } /***************************************************************/ /* Display function for data type code, data length code, */ /*and data area */ /***************************************************************/ void print_data( short ncol , p_rdb_collst_t *pcollst , union data_area *pdata ) { int i , j ; /* Counter variables */ int len; p_rdb_collst_t *ccollst ; union data_area *cdata ; printf("Partitioning key specification order Data type code Data length code Binary-format data value\n") ; for (i = 0 , ccollst = pcollst , cdata = pdata ; i<ncol ; i++ , ccollst++ , cdata++) { printf(" %2d %#.4x %#.4x ", i+1,ccollst->datatype, ccollst->datalen) ; switch (ccollst->datatype) { case PDSQL_CHAR : case PDSQL_MCHAR : case PDSQL_INTEGER : case PDSQL_SMALLFLT : case PDSQL_FLOAT : case PDSQL_SMALLINT : case PDSQL_DATE : case PDSQL_TIME : case PDSQL_TIMESTAMP : len=ccollst->datalen ; break ; case PDSQL_VARCHAR : case PDSQL_MVARCHAR : case PDSQL_NVARCHAR : len=cdata->data_varchar.length+2 ; break ; case PDSQL_NCHAR : len=ccollst->datalen*2 ; break ; case PDSQL_DECIMAL : case PDSQL_YEARTODAY : case PDSQL_HOURTOSEC : len=ccollst->datalen/256/2+1 ; break ; default : break ; } for=(j=0 ; j<len ;j++){ printf("%.2X",cdata->data_char[j]) ; } printf("\n") ; } printf("\n") ; return; }
Hash function code: 6 Number of partitioning key columns: 4 Number of table partitions: 6 RDAREA names: [RU01, RU02, RU03, RU04, RU05, RU06]
Partitioning key specification order | Data type code | Data length code | Binary format data value |
---|---|---|---|
1 | 0x00c4 | 0x000a | 61626364656667202020 |
2 | 0x00e4 | 0x0502 | 04321D |
3 | 0x00f4 | 0x0002 | 3039 |
4 | 0x00b0 | 0x0004 | 000682A082A282A4 |
Partitioning condition specification order: 1 > RU01
Examples of retrieval from dictionary tables for hash partitioning are shown below.
SELECT HASH_NAME, /* Hash function name */ VALUE(N_DIV_COLUMN,1), /* Number of partitioning key columns */ N_RDAREA /* Number of table partitioned */ FROM MASTER.SQL_TABLES WHERE TABLE_SCHEMA = authorization-identifier /* Item with matching authorization identifier */ AND TABLE_NAME = table-identifier /* Item with matching table identifier */
SELECT VALUE(DIVCOL_ORDER,1), /* Partitioning key specification order */ DATA_TYPE_CODE, /* Data type code */ DATA_LENGTH_CODE /* Data length code */ FROM MASTER.SQL_COLUMNS WHERE TABLE_SCHEMA = authorization-identifier /* Item with matching authorization identifier */ AND TABLE_NAME= table-identifier /* Item with matching table identifier */ AND DIVIDED_KEY='Y' /* Item that is a partitioning key*/ ORDER BY 1 ASC
SELECT DIV_NO, /* Partitioning condition specification order */ RDAREA_NAME /* Storage RDAREA name */ FROM MASTER.SQL_DIV_TABLE WHERE TABLE_SCHEMA = authorization-identifier /* Item with matching authorization identifier */ AND TABLE_NAME = table-identifier /* Item with matching table identifier */ ORDER BY 1 ASC
Examples of retrieval from dictionary tables for matrix partitioning are shown below.
select HASH_NAME, /* Hash function name */ value(N_DIV_COLUMN,1), /* Number of partitioning key columns */ KEY_NO /* Partitioning key number */ from MASTER.SQL_DIV_TYPE where TABLE_SCHEMA=authorization-identifier /* Item with matching authorization identifier */ and TABLE_NAME=table-identifier /* Item with matching table identifier */
select distinct N_DIVISION /* Number of partitions in key */ from MASTER.SQL_PARTKEY where TABLE_SCHEMA=authorization-identifier /* Item with matching authorization identifier */ and TABLE_NAME=table-identifier /* Item with matching table identifier */ and KEY_NO=partitioning-key-number /* Set partitioning key numbers */ /* for hash partitioning */
select DIVCOL_ORDER, /* Number of partitions in key */ DATA_TYPE_CODE, /* Data type code */ DATA_LENGTH_CODE /* Data length code */ from MASTER.SQL_COLUMNS X, MASTER.SQL_PARTKEY Y where X.TABLE_SCHEMA=Y.TABLE_SCHEMA and X.TABLE_NAME=Y.TABLE_NAME and X.COLUMN_ID=Y.COLUMN_ID and Y.TABLE_SCHEMA=authorization-identifier /* Item with matching authorization identifier */ and Y.TABLE_NAME=table-identifier /* Item with matching table identifier */ and Y.KEY_NO=partitioning-key-number /* Set partitioning key number */ /* for hash partitioning */ order by DIVCOL_ORDER asc
select DIV_NO, /* Partitioning condition specification order */ RDAREA_NAME /* Storage RDAREA name */ from MASTER.SQL_DIV_TABLE where TABLE_SCHEMA=authorization-identifier /* Item with matching authorization identifier */ and TABLE_NAME=table-identifier /* Item with matching table identifier */ order by 1 asc
N m - (N - n) N: Number of partitions in second dimension m: Partitioning key sequence number of first partitioning key n: Partitioning key sequence number of second partitioning key
All Rights Reserved. Copyright (C) 2007, Hitachi, Ltd.