Skip to content
Merged
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
40 changes: 35 additions & 5 deletions .github/workflows/snowflake.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,52 @@ jobs:
needs: test
runs-on: ubuntu-24.04
timeout-minutes: 20
strategy:
matrix:
include:
- account: SF_ACCOUNT_CD
database: SF_DATABASE_CD
user: SF_USER_CD
password: SF_PASSWORD_CD
role: SF_ROLE_CD
use_rsa_key: false
- account: SF_ACCOUNT_CI
database: SF_DATABASE_CI
user: SF_USER_CI
role: SF_ROLE_CI
use_rsa_key: true
env:
SF_ACCOUNT: ${{ secrets.SF_ACCOUNT_CD }}
SF_DATABASE: ${{ secrets.SF_DATABASE_CD }}
SF_USER: ${{ secrets.SF_USER_CD }}
SF_PASSWORD: ${{ secrets.SF_PASSWORD_CD }}
SF_ROLE: ${{ secrets.SF_ROLE_CD }}
SF_ACCOUNT: ${{ secrets[matrix.account] }}
SF_DATABASE: ${{ secrets[matrix.database] }}
SF_USER: ${{ secrets[matrix.user] }}
SF_ROLE: ${{ secrets[matrix.role] }}
steps:
- name: Checkout repo
uses: actions/checkout@v2
- name: Check diff
uses: technote-space/get-diff-action@v6
- name: Auth google (CI only)
if: matrix.use_rsa_key
uses: google-github-actions/auth@v2
with:
credentials_json: ${{ secrets.CARTO_AT_GH_ACTIONS_SERVICE_ACCOUNT_KEY }}
- name: Retrieve RSA secrets (CI only)
if: matrix.use_rsa_key
id: get-gcp-secrets
uses: google-github-actions/get-secretmanager-secrets@v2
with:
secrets: |-
SF_RSA_KEY:${{ secrets.SF_RSA_KEY_NAME_CI }}
SF_RSA_KEY_PASSWORD:${{ secrets.SF_RSA_KEY_PASSWORD_NAME_CI }}
- name: Setup node
uses: actions/setup-node@v1
with:
node-version: ${{ env.NODE_VERSION }}
- name: Run deploy
env:
SF_PASSWORD: ${{ secrets[matrix.password] || '' }}
SF_RSA_KEY: ${{ steps.get-gcp-secrets.outputs.SF_RSA_KEY || '' }}
SF_RSA_KEY_PASSWORD: ${{ steps.get-gcp-secrets.outputs.SF_RSA_KEY_PASSWORD || '' }}
run: |
cd clouds/snowflake
make deploy diff="$GIT_DIFF" production=1
Expand Down
2 changes: 2 additions & 0 deletions clouds/snowflake/common/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
"@rollup/plugin-commonjs": "^17.1.0",
"@rollup/plugin-json": "^4.1.0",
"@rollup/plugin-node-resolve": "^13.0.0",
"@turf/boolean-equal": "^7.2.0",
"@turf/truncate": "^7.2.0",
"cli-progress": "^3.11.2",
"eslint": "^7.25.0",
"jest": "^29.0.0",
Expand Down
14 changes: 13 additions & 1 deletion clouds/snowflake/common/test-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ const crypto = require('crypto');
const fs = require('fs');
const path = require('path');
const snowflake = require('snowflake-sdk');
const truncate = require('@turf/truncate').default;
const booleanEqual = require('@turf/boolean-equal').default;

snowflake.configure({ insecureConnect: true });

Expand Down Expand Up @@ -134,6 +136,15 @@ function arrayDictsKeysToLower (array) {
});
}

function isGeometryCloseTo(actual, expected, precision = 6) {
// Normalize both geometries to the same precision
const normalizedActual = truncate(actual, { precision, mutate: false });
const normalizedExpected = truncate(expected, { precision, mutate: false });

// Use Turf's boolean-equal for geometric comparison
return booleanEqual(normalizedActual, normalizedExpected);
}

module.exports = {
runQuery,
createTable,
Expand All @@ -145,5 +156,6 @@ module.exports = {
readJSONFixture,
writeJSONFixture,
writeNDJSONFixture,
arrayDictsKeysToLower
arrayDictsKeysToLower,
isGeometryCloseTo
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,41 @@
const { runQuery } = require('../../../common/test-utils');
const { runQuery, isGeometryCloseTo } = require('../../../common/test-utils');

test('ST_GREATCIRCLE should work', async () => {
const query = `SELECT ST_GREATCIRCLE(ST_POINT(0, 0), ST_POINT(0, 10), 11) as greatcircle1,
ST_GREATCIRCLE(ST_POINT(-1.70325, 1.4167), ST_POINT(1.70325, -1.4167), 5) as greatcircle2,
ST_GREATCIRCLE(ST_POINT(5, 5), ST_POINT(-5, -5), 9) as greatcircle3`;
// ST_ASGEOJSON returns GeoJSON objects directly (no PARSE_JSON needed)
const query = `SELECT
ST_ASGEOJSON(ST_GREATCIRCLE(ST_POINT(0, 0), ST_POINT(0, 10), 11)) as greatcircle1,
ST_ASGEOJSON(ST_GREATCIRCLE(ST_POINT(-1.70325, 1.4167), ST_POINT(1.70325, -1.4167), 5)) as greatcircle2,
ST_ASGEOJSON(ST_GREATCIRCLE(ST_POINT(5, 5), ST_POINT(-5, -5), 9)) as greatcircle3`;
const rows = await runQuery(query);
expect(rows.length).toEqual(1);
expect(JSON.stringify(rows[0].GREATCIRCLE1)).toEqual('{"coordinates":[[0,0],[0,1],[0,1.9999999999999996],[0,3.0000000000000004],[0,4],[0,4.999999999999999],[0,6],[0,7],[0,7.999999999999998],[0,9.000000000000002],[0,10]],"type":"LineString"}');
expect(JSON.stringify(rows[0].GREATCIRCLE2)).toEqual('{"coordinates":[[-1.7032500000000002,1.4166999999999998],[-0.8514948107357666,0.7084282465414006],[0,0],[0.8514948107357666,-0.7084282465414006],[1.7032500000000002,-1.4166999999999998]],"type":"LineString"}');
expect(JSON.stringify(rows[0].GREATCIRCLE3)).toEqual('{"coordinates":[[4.999999999999999,4.999999999999999],[3.7458253753562287,3.7520830815016724],[2.4952312784633994,2.5023786781263677],[1.2470204043859645,1.2514859293872385],[0,0],[-1.2470204043859645,-1.2514859293872385],[-2.4952312784633994,-2.5023786781263677],[-3.7458253753562287,-3.7520830815016724],[-4.999999999999999,-4.999999999999999]],"type":"LineString"}');

// Test GREATCIRCLE1 - simple north-south line
expect(isGeometryCloseTo(rows[0].GREATCIRCLE1, {
type: 'LineString',
coordinates: [
[0, 0], [0, 1], [0, 2], [0, 3], [0, 4], [0, 5],
[0, 6], [0, 7], [0, 8], [0, 9], [0, 10]
]
})).toBe(true);

// Test GREATCIRCLE2 - diagonal line
expect(isGeometryCloseTo(rows[0].GREATCIRCLE2, {
type: 'LineString',
coordinates: [
[-1.70325, 1.4167], [-0.851495, 0.708428], [0, 0],
[0.851495, -0.708428], [1.70325, -1.4167]
]
})).toBe(true);

// Test GREATCIRCLE3 - longer diagonal line
expect(isGeometryCloseTo(rows[0].GREATCIRCLE3, {
type: 'LineString',
coordinates: [
[5, 5], [3.745825, 3.752083], [2.495231, 2.502379],
[1.24702, 1.251486], [0, 0], [-1.24702, -1.251486],
[-2.495231, -2.502379], [-3.745825, -3.752083], [-5, -5]
]
})).toBe(true);
});

test('ST_GREATCIRCLE should return NULL if any NULL mandatory argument', async () => {
Expand Down