fleet/frontend/utilities/sql_tools.tests.ts
Victor Lyuboslavsky 945b7e678a
The fix skips nodes where type === "column_ref", since those aren't table references (#42821)
<!-- Add the related story/sub-task/bug number, like Resolves #123, or
remove if NA -->
**Related issue:** Resolves #40117 

Fix:
<img width="1033" height="320" alt="image"
src="https://github.com/user-attachments/assets/a6a642ef-d174-4ca7-b89b-8bb127c5c961"
/>

# Checklist for submitter

If some of the following don't apply, delete the relevant line.

- [x] Changes file added for user-visible changes in `changes/`,
`orbit/changes/` or `ee/fleetd-chrome/changes`.


## Testing

- [x] QA'd all new/changed functionality manually




<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Fixed incorrect platform detection for SQL queries that use table
aliases (e.g., `FROM mounts m`).

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2026-04-01 14:22:10 -05:00

82 lines
3 KiB
TypeScript

import { checkTable } from "./sql_tools";
describe("checkTable", () => {
// from https://github.com/fleetdm/fleet/issues/26366
// and https://github.com/fleetdm/fleet/issues/30109
// and https://github.com/fleetdm/fleet/issues/34628
const SQL = `
WITH extension_safety_hub_menu_notifications AS (
SELECT
1 & 0x2 AS test_bitwise, -- test bitwise AND operator
parse_json.key,
parse_json.fullkey,
parse_json.path,
parse_json.value
FROM (
SELECT file.filename, file.path, file.btime FROM file WHERE path LIKE "/Users/%/Library/Application Support/Google/Chrome/%/Preferences" ORDER BY file.btime DESC limit 20
) as chrome_preferences
JOIN parse_json ON chrome_preferences.path = parse_json.path
WHERE parse_json.path LIKE "/Users/%/Library/Application Support/Google/Chrome/%/Preferences" AND (
fullkey IN ("profile/name", "profile/safety_hub_menu_notifications/extensions/isCurrentlyActive", "profile/safety_hub_menu_notifications/extensions/result/timestamp")
OR fullkey Like "profile/safety_hub_menu_notifications/extensions/result/triggeringExtensions%"
)
),
extension_details AS (
SELECT path,
CASE WHEN key = 'name' THEN value END AS profile_name,
CASE WHEN key = 'isCurrentlyActive' THEN value END AS notification_active,
CASE WHEN key GLOB '*[0-9]' THEN value END AS triggering_extension,
CASE WHEN key = 'timestamp' THEN value END AS timestamp
FROM extension_safety_hub_menu_notifications
GROUP BY path, profile_name, notification_active, triggering_extension, timestamp
),
problematic_extensions AS (
SELECT
path,
MAX(profile_name) OVER (PARTITION by path) AS profile_name,
MAX(notification_active) AS notification_active,
MAX(timestamp) AS timestamp,
triggering_extension
FROM extension_details
)
SELECT path,
profile_name,
notification_active,
timestamp,
triggering_extension
FROM problematic_extensions
WHERE triggering_extension IS NOT NULL AND username NOT LIKE '\\_%' ESCAPE '\\';
`;
it("should return only real tables by default", () => {
const { tables, error } = checkTable(SQL);
expect(error).toBeNull();
expect(tables).toEqual(["file", "parse_json"]);
});
it("should return all tables if 'includeVirtualTables' is set", () => {
const { tables, error } = checkTable(SQL, true);
expect(error).toBeNull();
// Note that json_each is _not_ returned here, as it is a function table.
expect(tables).toEqual([
"file",
"parse_json",
"extension_safety_hub_menu_notifications",
"extension_details",
"problematic_extensions",
]);
});
// from https://github.com/fleetdm/fleet/issues/40117
it("should not include table aliases from column references", () => {
const sql =
"SELECT * FROM mounts m, disk_encryption d WHERE m.device_alias = d.name";
const { tables, error } = checkTable(sql);
expect(error).toBeNull();
expect(tables).toEqual(["mounts", "disk_encryption"]);
});
it("should return an error if SQL is invalid", () => {
const result = checkTable("SELECTx * FROM users");
expect(result.error).not.toBeNull();
});
});