Skip to content
Open
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
26 changes: 25 additions & 1 deletion .github/workflows/_build-python-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ jobs:
"os": "windows-latest",
"container": "",
"cargo_lib": "sf_core_python.dll",
"cargo_extra_args": "--features vendored-openssl --config profile.release.opt-level=2 --config profile.release.strip=false",
"cargo_extra_args": "--config profile.release.opt-level=2 --config profile.release.strip=false",
"wheel_method": "cibuildwheel",
"cibw_arch": "win_amd64",
"artifact_id": "win_amd64",
Expand Down Expand Up @@ -270,6 +270,22 @@ jobs:
uv python install "$v"
done

# Use the same vcpkg-provided OpenSSL setup as the Windows ARM64 build.
# Building vendored OpenSSL here delegates to the runner's MSYS2 Perl,
# whose incomplete core-module installation is not suitable for OpenSSL's
# Configure script (for example, Locale::Maketext::Simple may be absent).
- name: Setup OpenSSL (Windows x86_64)
if: runner.os == 'Windows'
uses: ./.github/actions/setup-windows-openssl
with:
arch: x86_64

- name: Setup MSVC environment (Windows x86_64)
if: runner.os == 'Windows'
uses: ./.github/actions/setup-msvc
with:
arch: x64

# ── python_bridge build: Linux (Docker + manylinux for glibc compat) ──
# Cannot use job-level container: because cibuildwheel needs Docker.
# Instead, build python_bridge via docker run with the manylinux image.
Expand Down Expand Up @@ -487,6 +503,8 @@ jobs:
CIBW_ENVIRONMENT_WINDOWS: >-
SKIP_CORE_BUILD=true
SKIP_PROTO_GENERATION=true
DISTUTILS_USE_SDK=1
MSSdk=1
CIBW_ENVIRONMENT_MACOS: >-
SKIP_CORE_BUILD=true
SKIP_PROTO_GENERATION=true
Expand Down Expand Up @@ -646,6 +664,12 @@ jobs:
working-directory: ./python
shell: cmd
run: uv run --python ${{ matrix.py }} --with hatch --with cython --with setuptools --with "virtualenv<21.0.0" hatch build
env:
# setup-msvc already exported a complete ARM64 compiler environment.
# Re-running vcvarsall from setuptools appends that environment to an
# already-long PATH and can exceed cmd.exe's input-line limit.
DISTUTILS_USE_SDK: "1"
MSSdk: "1"

- name: Inspect wheel
working-directory: ./python
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1284,19 +1284,24 @@ void shouldReturnTablePrivilegesForGetTablePrivileges() throws Exception {
assertMetadataColumn(rsMeta, 6, "PRIVILEGE");
assertMetadataColumn(rsMeta, 7, "IS_GRANTABLE");

assertTrue(resultSet.next());
assertEquals(currentDatabase, resultSet.getString("TABLE_CAT"));
assertEquals(currentSchema, resultSet.getString("TABLE_SCHEM"));
assertEquals(targetTable, resultSet.getString("TABLE_NAME"));
String grantor = resultSet.getString("GRANTOR");
assertNotNull(grantor);
assertFalse(grantor.isEmpty());
String grantee = resultSet.getString("GRANTEE");
assertNotNull(grantee);
assertFalse(grantee.isEmpty());
assertEquals("OWNERSHIP", resultSet.getString("PRIVILEGE"));
assertEquals("YES", resultSet.getString("IS_GRANTABLE"));
assertFalse(resultSet.next());
boolean ownershipFound = false;
while (resultSet.next()) {
assertEquals(currentDatabase, resultSet.getString("TABLE_CAT"));
assertEquals(currentSchema, resultSet.getString("TABLE_SCHEM"));
assertEquals(targetTable, resultSet.getString("TABLE_NAME"));
String grantor = resultSet.getString("GRANTOR");
assertNotNull(grantor);
assertFalse(grantor.isEmpty());
String grantee = resultSet.getString("GRANTEE");
assertNotNull(grantee);
assertFalse(grantee.isEmpty());

if ("OWNERSHIP".equals(resultSet.getString("PRIVILEGE"))) {
assertEquals("YES", resultSet.getString("IS_GRANTABLE"));
ownershipFound = true;
}
}
assertTrue(ownershipFound, "expected an OWNERSHIP privilege row");
}

try (ResultSet resultSet =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Types;
import java.util.List;
Expand All @@ -25,12 +26,27 @@ class SnowflakeResultSetMetaDataImplStructuredTypesTest extends SnowflakeIntegra
private Connection openStructuredTypesConnection() throws Exception {
Connection conn = openConnection();
try (Statement stmt = conn.createStatement()) {
stmt.execute("ALTER SESSION SET ENABLE_STRUCTURED_TYPES_IN_CLIENT_RESPONSE = TRUE");
stmt.execute("ALTER SESSION SET IGNORE_CLIENT_VESRION_IN_STRUCTURED_TYPES_RESPONSE = TRUE");
setSessionParameterIfSupported(stmt, "ENABLE_STRUCTURED_TYPES_IN_CLIENT_RESPONSE");
setSessionParameterIfSupported(stmt, "IGNORE_CLIENT_VESRION_IN_STRUCTURED_TYPES_RESPONSE");
}
return conn;
}

private static void setSessionParameterIfSupported(Statement stmt, String parameter)
throws SQLException {
try {
stmt.execute("ALTER SESSION SET " + parameter + " = TRUE");
} catch (SQLException exception) {
// These feature gates are absent after structured types become enabled by
// default. Preserve failures other than the expected retired-parameter
// response so connection and query regressions remain visible.
String message = exception.getMessage();
if (message == null || !message.contains("invalid parameter '" + parameter + "'")) {
throw exception;
}
}
}

@Test
@SkipNewDriver("not yet implemented - structured types field metadata")
void shouldDescribeStructuredObjectFieldMetadata() throws Exception {
Expand Down
16 changes: 9 additions & 7 deletions nodejs/tests/e2e/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,28 @@ import type {
StatementOption,
} from 'snowflake-sdk';
import oldSnowflakeSDK from 'snowflake-sdk';
// TODO:
// Ensure tests run against the built package to catch any missing files in the build output.
// Namespace import (not default): src/index.js only has named exports. A default import
// works under Vitest interop but fails under plain Node/tsx with
// "does not provide an export named 'default'".
import * as newSnowflakeSDK from '../../../src/index.js';
import getTestParameter from './getTestParameter';

export function isRunningForOldDriver() {
return !!process.env.SNOWFLAKE_NODEJS_E2E_USE_OLD_DRIVER;
}

// Importing src/index.js loads the platform-specific native core immediately.
// Keep that import out of the old-driver project: its CI job intentionally does
// not build the new core and should exercise only the published legacy SDK.
// TODO: Import the built package in new-driver tests to catch missing output files.
const newSnowflakeSDK = isRunningForOldDriver()
? undefined
: ((await import('../../../src/index.js')) as unknown as typeof oldSnowflakeSDK);

export function getSnowflakeSDK() {
if (isRunningForOldDriver()) {
return oldSnowflakeSDK;
} else {
// TODO:
// temporary using `as SnowflakeSDK` to satisfy the type checker until
// new SDK is fully implemented
return newSnowflakeSDK as typeof oldSnowflakeSDK;
return newSnowflakeSDK!;
}
}

Expand Down
Loading