Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
# Release History

## Unreleased

- Add the default-enabled `enableGeoSpatialSupport` option for kernel-backed GEOMETRY / GEOGRAPHY results. Enabled mode returns the canonical `{ srid, wkb }` Arrow value; disabled mode returns WKT / EWKT.
- Pin transitive `brace-expansion` 1.x / 2.x and `ip-address` dependencies to patched releases for GHSA-6j4f-fj2g-mc7p, GHSA-qhr7-859c-m2p7, and GHSA-2p57-rm9w-gvfp.

## 2.2.0

- Upgrade the kernel backend native packages to 1.1.0; the kernel dependency is now stable and no longer experimental.
Expand Down
11 changes: 6 additions & 5 deletions CONNECTION_PARAMETERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,12 @@ disabling verification.

## Results and type rendering

| Option | Type | Thrift | Kernel | Default Value | Note |
| ----------------------------- | --------- | :----: | :----: | ------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `preserveBigNumericPrecision` | `boolean` | ✅ | ✅ | `false` | Returns DECIMAL as an exact string and BIGINT as `bigint` on both. |
| `disableRowMaterialization` | `boolean` | ✅ | ✅ | `false` | Fetches and parses Arrow batches but returns `null` row placeholders instead of converting cells. Intended for fetch-throughput tests. |
| `enableMetricViewMetadata` | `boolean` | ✅ | ⚠️ | `false` | Injected into session configuration on both paths. Kernel may drop its non-allowlisted configuration key. |
| Option | Type | Thrift | Kernel | Default Value | Note |
| ----------------------------- | --------- | :----: | :----: | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `preserveBigNumericPrecision` | `boolean` | ✅ | ✅ | `false` | Returns DECIMAL as an exact string and BIGINT as `bigint` on both. |
| `disableRowMaterialization` | `boolean` | ✅ | ✅ | `false` | Fetches and parses Arrow batches but returns `null` row placeholders instead of converting cells. Intended for fetch-throughput tests. |
| `enableGeoSpatialSupport` | `boolean` | ❌ | ✅ | `true` | Returns GEOMETRY / GEOGRAPHY as canonical `{ srid: number, wkb: Buffer }` values when `true`, or WKT / EWKT strings when `false`. The choice is local and is not forwarded to SEA. |
| `enableMetricViewMetadata` | `boolean` | ✅ | ⚠️ | `false` | Injected into session configuration on both paths. Kernel may drop its non-allowlisted configuration key. |

## Session defaults (`openSession(request)`)

Expand Down
2 changes: 1 addition & 1 deletion KERNEL_REV
Original file line number Diff line number Diff line change
@@ -1 +1 @@
80f2aee7d884994d7b0af9a9ea6078872859a9cd
b7e9310b27be16a6c42490e58c4b5c4a525320bc
11 changes: 11 additions & 0 deletions lib/contracts/IDBSQLClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,17 @@ export type ConnectionOptions = {
*/
disableRowMaterialization?: boolean;

/**
* Enable native kernel-backed `GEOMETRY` and `GEOGRAPHY` results. `true`
* (the default) returns the canonical Arrow value as
* `{ srid: number, wkb: Buffer }`; `false` returns WKT / EWKT strings.
* This is a client-side conversion choice and is never forwarded to the SQL
* Execution API.
*
* Only the kernel backend uses this option.
*/
enableGeoSpatialSupport?: boolean;

/**
* Extra HTTP headers attached to driver-owned out-of-band requests
* (telemetry POSTs and feature-flag GETs). Not applied to the primary
Expand Down
19 changes: 19 additions & 0 deletions lib/kernel/KernelAuth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,12 @@ export interface KernelSessionDefaults {
* remove one.
*/
complexTypesAsJson?: boolean;
/**
* Enable native GEOMETRY / GEOGRAPHY values. `true` (the default) returns
* canonical `struct<srid:int32,wkb:binary>` values; `false` returns WKT /
* EWKT strings. Applied locally by the kernel and never sent to SEA.
*/
enableGeoSpatialSupport?: boolean;
/**
* Per-session kernel connection-pool size
* (kernel `ConnectionOptions.max_connections`). Validated as a positive
Expand Down Expand Up @@ -819,6 +825,7 @@ export function buildKernelConnectionOptions(options: ConnectionOptions): Kernel
hostName: string;
httpPath: string;
intervalsAsString: boolean;
enableGeoSpatialSupport: boolean;
maxConnections?: number;
} & KernelTlsOptions &
KernelHttpOptions &
Expand All @@ -833,6 +840,9 @@ export function buildKernelConnectionOptions(options: ConnectionOptions): Kernel
// (native Arrow) — they already decode identically to Thrift via the
// shared Arrow converter, so `complexTypesAsJson` is not forced on.
intervalsAsString: true,
// Match the public driver contract and the kernel default: geospatial
// support is enabled unless the caller explicitly requests WKT / EWKT.
enableGeoSpatialSupport: true,
// TLS knobs (server-cert verification toggle + custom CA + mTLS client
// identity). Validated and normalised (string PEM → Buffer) here so the
// napi shape only sees a Buffer.
Expand All @@ -843,6 +853,15 @@ export function buildKernelConnectionOptions(options: ConnectionOptions): Kernel
...buildKernelProxyOptions(options),
};

if (options.enableGeoSpatialSupport !== undefined) {
if (typeof options.enableGeoSpatialSupport !== 'boolean') {
throw new HiveDriverError(
`kernel backend: \`enableGeoSpatialSupport\` must be a boolean; got ${typeof options.enableGeoSpatialSupport}.`,
);
}
base.enableGeoSpatialSupport = options.enableGeoSpatialSupport;
}

// kernel-only pool sizing; read via cast to match how this function reads the
// other kernel-specific options (TLS) — they live on the internal options
// surface, not the published public `ConnectionOptions` `.d.ts`.
Expand Down
17 changes: 13 additions & 4 deletions native/kernel/index.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

56 changes: 28 additions & 28 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,9 +104,11 @@
"basic-ftp": "^5.3.1",
"@75lb/deep-merge": "^1.1.2",
"ws": "^8.18.0",
"ip-address": "^10.1.1",
"ip-address": "10.7.1",
"form-data": "^4.0.4",
"uuid": "^11.1.1",
"serialize-javascript": "^7.0.5"
"serialize-javascript": "^7.0.5",
"brace-expansion@1": "1.1.21",
"brace-expansion@2": "2.1.7"
}
}
41 changes: 41 additions & 0 deletions tests/unit/kernel/KernelOperationBackend.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,47 @@ describe('KernelOperationBackend — M0 datatype round-trip via napi → ArrowRe
expect(row.s).to.deep.equal({ a: 1, b: 'hi' });
});

it('surfaces geospatial string and binary values in idiomatic JS shapes', async () => {
const wkb = new Uint8Array([
0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x40,
]);
const geoType = new Struct([
new Field('srid', new Int32(), false),
new Field(
'wkb',
new Binary(),
false,
new Map([
['geometry', 'true'],
['srid', '-1'],
]),
),
]);
const schema = new Schema([
withTypeName(new Field('geom_text', new Utf8(), true), 'GEOMETRY'),
withTypeName(new Field('geom_binary', geoType, true), 'GEOMETRY'),
]);
const stub = new StatementStub(ipcSchemaOnly(schema), [
ipcFromColumns(schema, {
geom_text: ['SRID=4326;POINT(1 2)', null],
geom_binary: [{ srid: 4326, wkb }, null],
}),
]);
const backend = new KernelOperationBackend({
statement: stub,
context: new ClientContextStub(),
});

const rows = (await backend.fetchChunk({ limit: 100 })) as Array<Record<string, unknown>>;
expect(rows[0].geom_text).to.equal('SRID=4326;POINT(1 2)');
expect(rows[0].geom_binary).to.deep.equal({
srid: 4326,
wkb: Buffer.from(wkb),
});
expect(rows[1]).to.deep.equal({ geom_text: null, geom_binary: null });
});

it('streams multiple batches and reports hasMore correctly', async () => {
const schema = new Schema([withTypeName(new Field('x', new Int32(), true), 'INT')]);
const schemaIpc = ipcSchemaOnly(schema);
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/kernel/_helpers/nativeOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export default function expectNativeConnectionOptions(actual: unknown, expectedR
]) {
delete rest[key];
}
expect(rest).to.deep.equal(expectedRest);
expect(rest).to.deep.equal({ enableGeoSpatialSupport: true, ...expectedRest });
expect(customHeaders, 'customHeaders').to.be.an('array').with.lengthOf(1);
expect(customHeaders?.[0].name).to.equal('User-Agent');
expect(customHeaders?.[0].value).to.match(/NodejsDatabricksSqlConnector\//);
Expand Down
23 changes: 23 additions & 0 deletions tests/unit/kernel/connectionOptions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,29 @@ describe('KernelAuth connection options — intervalsAsString default', () => {
});
});

describe('KernelAuth connection options — geospatial result representation', () => {
it('enables native geospatial support by default', () => {
const native = buildKernelConnectionOptions(opts({})) as { enableGeoSpatialSupport?: boolean };
expect(native.enableGeoSpatialSupport).to.equal(true);
});

for (const value of [true, false]) {
it(`forwards enableGeoSpatialSupport=${value}`, () => {
const native = buildKernelConnectionOptions(opts({ enableGeoSpatialSupport: value })) as {
enableGeoSpatialSupport?: boolean;
};
expect(native.enableGeoSpatialSupport).to.equal(value);
});
}

it('rejects non-boolean values at runtime', () => {
expect(() => buildKernelConnectionOptions(opts({ enableGeoSpatialSupport: 'false' }))).to.throw(
HiveDriverError,
/must be a boolean/,
);
});
});

describe('KernelAuth connection options — maxConnections', () => {
it('forwards a valid positive integer', () => {
const native = buildKernelConnectionOptions(opts({ maxConnections: 10 })) as { maxConnections?: number };
Expand Down
Loading
Loading