NDB Cluster v2.11 includes a version of ODBC and SQL.
This document has 4 sections.
Features which are currently incomplete or planned for next release are marked with v2.x.
We use RedHat package names to describe supporting software. Packages starting with perl- are perl modules. If your installation does not include them you can get them from a CPAN archive ( ftp://ftp.funet.fi/pub/languages/perl/CPAN ).
Version numbers are given only as examples. Other versions will work.
An ODBC driver manager is required, one of:
Additional packages are convenient. Following include perl scripting interface and an "interactive SQL" tool dbish:
The NDB ODBC driver is located under NDB Cluster installation directory and is named libNDB_ODBC.so. It includes NDB API. To use it create a text file /etc/odbc.ini or $HOME/.odbc.ini containing at least:
[ndb]
Driver = <path-to-your-NDB-installation>/lib/libNDB_ODBC.so
Then try the shell command dbish dbi:ODBC:ndb in an NDB API node directory.
| type | description |
|---|---|
| SQL_C_CHAR | character buffers |
| SQL_C_SLONG, etc | integer types |
| SQL_C_DOUBLE, etc | floating types |
| SQL_C_TYPE_TIMESTAMP | timestamp |
The driver implements basic ODBC functions. Main exceptions are:
Following lists main ODBC 3.0 functions and their status in the driver.
| function | supported |
|---|---|
| SQLAllocHandle | yes |
| SQLConnect | yes |
| SQLGetInfo | yes |
| SQLGetFunctions | yes |
| SQLGetTypeInfo | yes |
| SQLSetConnectAttr | yes |
| SQLGetConnectAttr | yes |
| SQLSetEnvAttr | yes |
| SQLGetEnvAttr | yes |
| SQLSetStmtAttr | yes |
| SQLGetStmtAttr | yes |
| SQLGetDescField | yes |
| SQLGetDescRec | yes |
| SQLSetDescField | yes |
| SQLSetDescRec | yes |
| SQLPrepare | yes |
| SQLBindParameter | yes |
| SQLGetCursorName | yes, but cursor names cannot be used in SQL |
| SQLSetCursorName | yes, but cursor names cannot be used in SQL |
| SQLSetScrollOptions | not implemented |
| SQLExecute | yes |
| SQLExecDirect | yes |
| SQLNativeSql | not implemented |
| SQLDescribeParam | not supported |
| SQLNumParams | yes |
| SQLParamData | yes |
| SQLPutData | yes |
| SQLRowCount | yes |
| SQLNumResultCols | yes |
| SQLDescribeCol | yes |
| SQLColAttribute | yes |
| SQLBindCol | yes |
| SQLFetch | yes |
| SQLFetchScroll | not implemented |
| SQLGetData | yes |
| SQLSetPos | not implemented |
| SQLBulkOperations | not implemented |
| SQLMoreResults | yes, but multiple result sets are not supported |
| SQLGetDiagField | yes |
| SQLGetDiagRec | yes |
| SQLColumnPrivileges | not applicable |
| SQLColumns | yes |
| SQLForeignKeys | not applicable |
| SQLPrimaryKeys | yes |
| SQLProcedureColumns | not applicable |
| SQLProcedures | not applicable |
| SQLSpecialColumns | yes v2.x |
| SQLStatistics | not applicable |
| SQLTablePrivileges | not applicable |
| SQLTables | yes |
| SQLFreeStmt | yes |
| SQLCloseCursor | yes |
| SQLCancel | yes |
| SQLEndTran | yes |
| SQLDisconnect | yes |
| SQLFreeHandle | yes |
| type | description |
|---|---|
| CHAR(n) | fixed-width blank-padded string |
| VARCHAR(n) | variable length string |
| INT INTEGER | integer 32 bits |
| BIGINT | integer 64 bits |
| DECIMAL(m,n) | exact number with precision and scale v2.x |
| REAL | float 32 bits |
| FLOAT DOUBLE PRECISION | float, at least 64 bits |
| DATE | date with precision 1 second v2.x |
| DATETIME | date with precision 1 nanosecond (SQL_TYPE_TIMESTAMP) |
Integer types may be qualified as UNSIGNED.
Strings and numbers are not converted to each other automatically.
Following is an error (unlike in oracle).
select 123 + '456' from tab
| syntax | description |
|---|---|
| NULL | null value |
| 12.34e5 | integer or decimal or float constant |
| 'abc' | string constant |
| + - * / ( ) | arithmetic operations |
| || | string concatenation v2.x |
| syntax | description |
|---|---|
| SUBSTR() LEFT() RIGHT() | substring |
| TO_NUMBER() TO_CHAR() | basic conversions v2.x |
| ROWNUM | row number in query |
| SYSDATE | current date as DATETIME |
| syntax | description |
|---|---|
| COUNT(*) COUNT(expr) | count rows or non-NULL values |
| MIN(expr) MAX(expr) | min and max of strings and numbers |
| SUM(expr) AVG(expr) | sum and average of numbers |
| syntax | description |
|---|---|
| IS NULL / IS NOT NULL | test if value is null |
| < <= = != > >= | comparisons |
| LIKE / NOT LIKE | string matching |
| AND OR NOT ( ) | boolean operators |
create table t (
a integer not null,
b char(20) not null,
c float,
primary key(a, b)
)
A column can be specified as AUTO_INCREMENT. The column has following requirements.
create table t (
a int unsigned auto_increment primary key,
b char(20) not null,
c float
)
The values of an AUTO_INCREMENT column are unique (until wrap-around) and form an ascending sequence. Gaps in the sequence are possible.
create table t (
a int primary key,
b int default 100
)
insert into t(a) values(1) -- inserts (1,100)
The value must evaluate to constant. Using SYSDATE (if allowed at all) evaluates to table creation time.
create table t1 (a int primary key, b int) logging
create table t1 (a int primary key, b int) nologging
create table mydb.mytable (a int primary key)
drop table t
create unique hash index x1 on t1(b, c) logging
Internally, a unique hash index is a table where index key is primary key. If the index is nologging, it is rebuilt on database restart before the database is opened.
Indexes can of course be dropped:
drop index x1
insert into t(a, c) values (123, 'abc') insert into t1(a, c) select a + 10 * b, c from t2
For convenience, the non-standard MySql syntax is also supported.
insert into t set a = 123, c = 'abc'
The non-standard operation WRITE is used exactly like INSERT. The record is updated if it exists. Otherwise a new record is inserted.
write into t(a, c) values (123, 'abc')
Message text format is
[Alzato][ODBC driver][NDB Cluster] NDB-ssccnnn error text (in SQLXxx)
Here ssccnnnn is native error code (decimal number), with following parts:
See NDB API guide for further information.
For non-database errors the last prefix [NDB Cluster] is omitted and native error code is always 02015001.
The driver has same thread-safety model as NDB API. In NDB API each thread must use its own Ndb object. In NDB ODBC a SQLConnect corresponds to an Ndb object. It is required that each thread allocates its own ODBC handles (of all types).
SQL types are represented as (old) NDB types as follows.
| SQL type | NDB type |
|---|---|
| CHAR(n) | String(n), blank-padded to n |
| VARCHAR(n) | String(n+2), zero-padded to n, length in last 2 bytes (big-endian) |
| integers | Signed(x) or UnSigned(x), x=16,32,64, native format |
| floats | Float(x), x=32,64, native format |
| DATETIME | String(12) = cc yy mm dd HH MM SS \0 ff ff ff ff (big-endian) |
Note: SQL types exist now in NDB API in NdbDictionary class. However they are not yet understood by NDB API operations.
Following lists specific known problems.