Skip to content

Commit

Permalink
playground: fix the where clause checker (#1065)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mini256 committed Dec 27, 2022
1 parent 1f845c8 commit a986083
Showing 1 changed file with 52 additions and 58 deletions.
110 changes: 52 additions & 58 deletions packages/api-server/src/core/playground/playground.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,20 +85,6 @@ const LIMIT_AST_NODE = {
],
};

// const WHERE_AST_NODE = (fieldName: string, value: number) => ({
// type: "binary_expr",
// operator: "=",
// left: {
// type: "column_ref",
// table: null,
// column: fieldName,
// },
// right: {
// type: "number",
// value,
// },
// });

declare module "node-sql-parser" {
interface Select {
_next?: AST;
Expand All @@ -112,72 +98,80 @@ function parseSelectAst(
value: number,
depth = 0
) {
// only handle select statement
// Only handle select statement.
if (ast.type !== "select") {
return;
}
const { where, from, limit, with: astWith, union } = ast;
// Only add LIMIT to the outermost layer of SQL expression
if (depth === 0 && !union) {
// Add limit
if (limit?.value && limit.value[0]?.value > 100) {
limit.value[0].value = 100;
} else if (!limit?.value?.length) {
ast.limit = LIMIT_AST_NODE;
}
}
// Check FROM clause
from &&
from.length > 0 &&

// Check FROM clause.
if (from && from.length > 0) {
from.forEach((fromItem: any) => {
const fromItemAst = fromItem?.expr?.ast as Select | undefined;
fromItemAst && parseSelectAst(fromItemAst, fieldName, value, depth + 1);
});
// Check WITH clause
}

// Check WITH clause.
const astWithList = Array.isArray(astWith)
? (astWith as With[])
: astWith
? [astWith]
: [];

astWithList.forEach((withItem) => {
const stmt = withItem?.stmt as any;
const withItemAst = stmt.ast as Select | undefined;
withItemAst && parseSelectAst(withItemAst, fieldName, value, depth + 1);
});
// Wrap where clause
// 30-Sep-2021: We don't need to add "repo_id = xxx" condition into where clause anymore
if (!where) {
// ast.where = WHERE_AST_NODE(fieldName, value);
if (from && from?.length > 0) {
throw new BadParamsError(
"playground",
`WHERE is required. Please add "WHERE ${fieldName} = ${value}" to your query.`
);
}
} else {
// Check if where clause already has the repo_id = xxx or actor_id = xxx
const whereLimitExist = isWhereLimitExist(where, fieldName, value);
if (whereLimitExist) {
// do nothing
} else {
// where.parentheses = true;
// ast.where = {
// type: "binary_expr",
// operator: "AND",
// left: WHERE_AST_NODE(fieldName, value),
// right: where,
// };
throw new BadParamsError(
"playground",
`Please add "${fieldName} = ${value}" to your each WHERE clause.`
);
}
}
// Check UNION clause

// Check UNION clause.
if (union) {
const unionAst = ast._next as Select;
parseSelectAst(unionAst, fieldName, value, depth);
}

// Only add LIMIT to the outermost layer of SQL expression.
if (depth === 0 && !union) {
// Add limit
if (limit?.value && limit.value[0]?.value > 100) {
limit.value[0].value = 100;
} else if (!limit?.value?.length) {
ast.limit = LIMIT_AST_NODE;
}
}

// Check there is no repo_id or actor_id in the WHERE clause.
if (isFromContainTable(from, "github_events")) {
if (!where) {
// ast.where = WHERE_AST_NODE(fieldName, value);
if (from && from?.length > 0) {
throw new BadParamsError(
"playground",
`WHERE is required. Please add "WHERE ${fieldName} = ${value}" to your query.`
);
}
} else {
// Check if where clause already has the repo_id = xxx or actor_id = xxx
const whereLimitExist = isWhereLimitExist(where, fieldName, value);
if (!whereLimitExist) {
throw new BadParamsError(
"playground",
`Please add "${fieldName} = ${value}" to your each WHERE clause.`
);
}
}
}
}

function isFromContainTable(from: any, tableName: string) {
return from.some((fromItem: any) => {
if (fromItem.table && fromItem.table === tableName) {
return true;
} else {
return false;
}
});
}

const isWhereLimitExist = (
Expand Down

0 comments on commit a986083

Please sign in to comment.