Skip to content

Commit

Permalink
Update pg-query-emscripten to 5.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
valentin-nemcev committed Nov 15, 2024
1 parent e514486 commit d5b70b7
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 29 deletions.
6 changes: 4 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"jsonpath": "^1.1.1",
"knex": "3.1.0",
"pg": "8.13.0",
"pg-query-emscripten": "^0.1.0",
"pg-query-emscripten": "^5.1.0",
"ramda": "^0.30.0",
"tagged-comment-parser": "^1.3.3"
},
Expand Down
28 changes: 14 additions & 14 deletions src/kinds/parseViewDefinition.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { describe, expect, it } from "vitest";
import parseViewDefinition from "./parseViewDefinition";

describe("parseViewDefinition", () => {
it("should understand a trivial select", () => {
it("should understand a trivial select", async () => {
const query = `SELECT id FROM service`;

const def = parseViewDefinition(query, "public");
const def = await parseViewDefinition(query, "public");
expect(def).toEqual([
{
viewColumn: "id",
Expand All @@ -19,10 +19,10 @@ describe("parseViewDefinition", () => {
]);
});

it("should understand a select with explicit schema", () => {
it("should understand a select with explicit schema", async () => {
const query = `SELECT id FROM store.service`;

const def = parseViewDefinition(query, "public");
const def = await parseViewDefinition(query, "public");
expect(def).toEqual([
{
viewColumn: "id",
Expand All @@ -35,15 +35,15 @@ describe("parseViewDefinition", () => {
]);
});

it("should understand a select with join", () => {
it("should understand a select with join", async () => {
const query = `SELECT service.id,
service."createdAt",
service.name,
"oauthConnection"."createdBy" AS owner
FROM service
LEFT JOIN "oauthConnection" ON service."oauthConnectionId" = "oauthConnection".id;`;

const def = parseViewDefinition(query, "public");
const def = await parseViewDefinition(query, "public");
expect(def).toEqual([
{
viewColumn: "id",
Expand Down Expand Up @@ -80,14 +80,14 @@ describe("parseViewDefinition", () => {
]);
});

it("should work with multiple schemas and with aliases", () => {
it("should work with multiple schemas and with aliases", async () => {
const query = `
select u.id as uid, um.id as umid
from test1.users u
join test2.user_managers um
on um.user_id = u.id;`;

const def = parseViewDefinition(query, "public");
const def = await parseViewDefinition(query, "public");
expect(def).toEqual([
{
viewColumn: "uid",
Expand All @@ -108,7 +108,7 @@ describe("parseViewDefinition", () => {
]);
});

it("should return undefined for unresolvable columns", () => {
it("should return undefined for unresolvable columns", async () => {
const query = `
SELECT cu.customer_id AS id,
(cu.first_name::text || ' '::text) || cu.last_name::text AS name,
Expand All @@ -127,7 +127,7 @@ describe("parseViewDefinition", () => {
JOIN city ON a.city_id = city.city_id
JOIN country ON city.country_id = country.country_id;`;

const def = parseViewDefinition(query, "public");
const def = await parseViewDefinition(query, "public");
expect(def).toEqual([
{
viewColumn: "id",
Expand Down Expand Up @@ -196,7 +196,7 @@ describe("parseViewDefinition", () => {
]);
});

it("should work with a minimalistic WITH clause", () => {
it("should work with a minimalistic WITH clause", async () => {
const query = `
WITH RECURSIVE hierarchy_cte AS (
SELECT posting.date,
Expand All @@ -211,7 +211,7 @@ describe("parseViewDefinition", () => {
FROM hierarchy_cte;
`;

const def = parseViewDefinition(query, "public");
const def = await parseViewDefinition(query, "public");

expect(def).toEqual([
{
Expand Down Expand Up @@ -241,7 +241,7 @@ describe("parseViewDefinition", () => {
]);
});

it("should resolve kanel#481", () => {
it("should resolve kanel#481", async () => {
const query = `
WITH RECURSIVE hierarchy_cte AS (
SELECT posting.date,
Expand All @@ -262,7 +262,7 @@ describe("parseViewDefinition", () => {
FROM hierarchy_cte;
`;

const def = parseViewDefinition(query, "public");
const def = await parseViewDefinition(query, "public");

expect(def).toEqual([
{
Expand Down
33 changes: 22 additions & 11 deletions src/kinds/parseViewDefinition.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
import jp from "jsonpath";
import pgQuery from "pg-query-emscripten";
import { last } from "ramda";

let pgQueryInstance: any;
const getPgQuery = async () => {
if (!pgQueryInstance) {
const { default: pgQueryModule } = await import(
"pg-query-emscripten/pg_query_wasm"
);
pgQueryInstance = await new pgQueryModule();
}
return pgQueryInstance;
};

export type ViewReference = {
viewColumn: string;
source:
Expand All @@ -21,8 +31,8 @@ function parseSelectStmt(
if (selectAst.larg && selectAst.rarg) {
// This is a UNION, INTERSECT, or EXCEPT operation
return [
...parseSelectStmt(selectAst.larg.SelectStmt, defaultSchema, aliases),
...parseSelectStmt(selectAst.rarg.SelectStmt, defaultSchema, aliases),
...parseSelectStmt(selectAst.larg, defaultSchema, aliases),
...parseSelectStmt(selectAst.rarg, defaultSchema, aliases),
];
}

Expand All @@ -34,7 +44,7 @@ function parseSelectStmt(
const selectTargets = jp.query(selectAst, "$.targetList[*].ResTarget");

selectTargets.forEach((selectTarget: any) => {
const fields = jp.query(selectTarget, "$.val[*].fields[*].String.str");
const fields = jp.query(selectTarget, "$.val[*].fields[*].String.sval");
let sourceTable = fromTable?.relname;
let sourceSchema = fromTable?.schemaname;
if (fields.length === 2) {
Expand Down Expand Up @@ -65,12 +75,13 @@ function parseSelectStmt(

return viewReferences;
}
function parseViewDefinition(
async function parseViewDefinition(
selectStatement: string,
defaultSchema: string,
): ViewReference[] {
const ast = pgQuery.parse(selectStatement).parse_tree[0];
const selectAst = ast.RawStmt?.stmt?.SelectStmt;
): Promise<ViewReference[]> {
const pgQuery = await getPgQuery();
const ast = pgQuery.parse(selectStatement).parse_tree.stmts[0];
const selectAst = ast?.stmt?.SelectStmt;

if (!selectAst) {
throw new Error(
Expand All @@ -80,17 +91,17 @@ function parseViewDefinition(

const aliasDefinitions = jp.query(
ast,
"$.RawStmt.stmt.SelectStmt.fromClause..[?(@.alias)]",
"$.stmt.SelectStmt.fromClause..[?(@.alias)]",
);

const aliases = Object.fromEntries(
aliasDefinitions.map(({ schemaname, relname, alias }) => [
alias.Alias.aliasname,
alias.aliasname,
{ schema: schemaname, table: relname },
]),
);

const withClauses = selectAst.withClause?.WithClause?.ctes || [];
const withClauses = selectAst.withClause?.ctes || [];

const cteAliases: Record<string, ViewReference[]> = {};

Expand Down
2 changes: 1 addition & 1 deletion src/pg-query-emscripten.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
declare module "pg-query-emscripten";
declare module "pg-query-emscripten/pg_query_wasm";

0 comments on commit d5b70b7

Please sign in to comment.