Skip to content

Commit

Permalink
Format various PostgreSQL CREATE FUNCTION clauses
Browse files Browse the repository at this point in the history
  • Loading branch information
nene committed Jan 27, 2024
1 parent dbda44b commit ff2be62
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/node_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ export const isParenExpr = is("paren_expr");
export const isListExpr = is("list_expr");
export const isCreateFunctionStmt = is("create_function_stmt");
export const isLanguageClause = is("language_clause");
export const isDynamicallyLoadedFunction = is("dynamically_loaded_function");
18 changes: 17 additions & 1 deletion src/syntax/function.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { group, hardline, join } from "../print_utils";
import { isAsClause } from "../node_utils";
import { CstToDocMap } from "../CstToDocMap";

export const functionMap: Partial<CstToDocMap<AllFunctionNodes>> = {
export const functionMap: CstToDocMap<AllFunctionNodes> = {
create_function_stmt: (print, node) => [
print.spaced([
"createKw",
Expand All @@ -28,6 +28,22 @@ export const functionMap: Partial<CstToDocMap<AllFunctionNodes>> = {
function_param: (print) =>
print.spaced(["mode", "name", "dataType", "default"]),
function_param_default: (print) => print.spaced(["operator", "expr"]),
return_clause: (print) => print.spaced(["returnKw", "expr"]),
function_behavior_clause: (print) => print.spaced(["behaviorKw"]),
function_security_clause: (print) =>
print.spaced(["externalKw", "securityKw"]),
function_cost_clause: (print) => print.spaced(["costKw", "cost"]),
function_rows_clause: (print) => print.spaced(["rowsKw", "rows"]),
function_support_clause: (print) => print.spaced(["supportKw", "name"]),
function_window_clause: (print) => print.spaced("windowKw"),
function_transform_clause: (print) => print.spaced(["transformKw", "types"]),
transform_type: (print) => print.spaced(["forTypeKw", "dataType"]),
set_parameter_clause: (print) =>
print.spaced(["setKw", "name", "operator", "value"]),
set_parameter_from_current_clause: (print) =>
print.spaced(["setKw", "name", "fromCurrentKw"]),
dynamically_loaded_function: (print) =>
join(", ", print(["objectFile", "symbol"])),
drop_function_stmt: (print) =>
group([
print.spaced(["dropKw", "tableKw", "functionKw", "ifExistsKw", "name"]),
Expand Down
4 changes: 2 additions & 2 deletions src/syntax/proc_clause.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { AllProcClauseNodes } from "sql-parser-cst";
import { isStringLiteral } from "../node_utils";
import { isDynamicallyLoadedFunction, isStringLiteral } from "../node_utils";
import { CstToDocMap } from "../CstToDocMap";
import { hardline, indent } from "../print_utils";

Expand All @@ -8,7 +8,7 @@ export const procClauseMap: CstToDocMap<AllProcClauseNodes> = {
determinism_clause: (print) => print.spaced("deterministicKw"),
language_clause: (print) => print.spaced(["languageKw", "name"]),
as_clause: (print, node) => {
if (isStringLiteral(node.expr)) {
if (isStringLiteral(node.expr) || isDynamicallyLoadedFunction(node.expr)) {
return print.spaced(["asKw", "expr"]);
}
return [print("asKw"), indent([hardline, print("expr")])];
Expand Down
2 changes: 1 addition & 1 deletion src/syntax/transformMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { mysqlMap } from "./dialects/mysql";
import { sqliteMap } from "./dialects/sqlite";
import { postgresqlMap } from "./dialects/postgresql";

export const transformMap: Partial<CstToDocMap<Node>> = {
export const transformMap: CstToDocMap<Node> = {
...aliasMap,
...alterTableMap,
...analyzeMap,
Expand Down
41 changes: 41 additions & 0 deletions test/ddl/function.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,47 @@ describe("function", () => {
`);
});

it(`formats PostgreSQL-specific clauses`, async () => {
await testPostgresql(dedent`
CREATE FUNCTION my_func()
RETURNS INT
LANGUAGE SQL
IMMUTABLE
NOT LEAKPROOF
CALLED ON NULL INPUT
EXTERNAL SECURITY DEFINER
PARALLEL UNSAFE
COST 100
ROWS 1000
SUPPORT schm.foo
TRANSFORM FOR TYPE INT, FOR TYPE VARCHAR(100)
RETURN 5 + 5
`);
});

it(`formats WINDOW function loaded from object file`, async () => {
await testPostgresql(dedent`
CREATE FUNCTION my_func()
RETURNS INT
AS 'my_lib.so', 'my_func'
LANGUAGE C
WINDOW
STRICT
`);
});

it(`formats SET config variables`, async () => {
await testPostgresql(dedent`
CREATE FUNCTION my_func()
SET search_path TO my_schema, my_other_schema
SET check_function_bodies = DEFAULT
SET client_min_messages FROM CURRENT
BEGIN ATOMIC
RETURN 1;
END
`);
});

it(`formats JavaScript FUNCTION`, async () => {
await testBigquery(dedent`
CREATE FUNCTION gen_random()
Expand Down

0 comments on commit ff2be62

Please sign in to comment.