Skip to content

Commit

Permalink
Add pg_show_all_settings() support
Browse files Browse the repository at this point in the history
  • Loading branch information
arjunlol committed Dec 12, 2024
1 parent 9afc001 commit 46a3767
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"time"
)

const VERSION = "0.25.0"
const VERSION = "0.25.1"

func main() {
config := LoadConfig()
Expand Down
4 changes: 4 additions & 0 deletions src/query_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ func TestHandleQuery(t *testing.T) {
"description": {"quote_ident"},
"values": {"\"fooBar\""},
},
"SELECT setting from pg_show_all_settings() WHERE name = 'default_null_order'": {
"description": {"setting"},
"values": {"nulls_last"},
},
// pg_get_partkeydef
"SELECT pg_catalog.pg_get_partkeydef(c.oid) FROM pg_catalog.pg_class c LIMIT 1": {
"description": {"pg_get_partkeydef"},
Expand Down
127 changes: 125 additions & 2 deletions src/query_parser_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ const (
PG_SCHEMA_INFORMATION_SCHEMA = "information_schema"
PG_TABLE_TABLES = "tables"

PG_FUNCTION_PG_GET_KEYWORDS = "pg_get_keywords"
PG_FUNCTION_ARRAY_UPPER = "array_upper"
PG_FUNCTION_PG_GET_KEYWORDS = "pg_get_keywords"
PG_FUNCTION_ARRAY_UPPER = "array_upper"
PG_FUNCTION_PG_SHOW_ALL_SETTINGS = "pg_show_all_settings"
)

type QueryParserTable struct {
Expand Down Expand Up @@ -267,6 +268,128 @@ func (parser *QueryParserTable) MakeArrayUpperNode(funcCallNode *pgQuery.FuncCal
).GetFuncCall()
}

// pg_show_all_settings()
func (parser *QueryParserTable) IsPgShowAllSettingsFunction(node *pgQuery.Node) bool {
for _, funcNode := range node.GetRangeFunction().Functions {
for _, funcItemNode := range funcNode.GetList().Items {
funcCallNode := funcItemNode.GetFuncCall()
if funcCallNode == nil {
continue
}
if len(funcCallNode.Funcname) != 1 {
continue
}

function := funcCallNode.Funcname[0].GetString_().Sval
if function == PG_FUNCTION_PG_SHOW_ALL_SETTINGS {
return true
}
}
}

return false
}

// pg_show_all_settings() -> duckdb_settings() mapped to pg format
func (parser *QueryParserTable) MakePgShowAllSettingsNode(node *pgQuery.Node) *pgQuery.Node {
return &pgQuery.Node{
Node: &pgQuery.Node_RangeSubselect{
RangeSubselect: &pgQuery.RangeSubselect{
Subquery: &pgQuery.Node{
Node: &pgQuery.Node_SelectStmt{
SelectStmt: &pgQuery.SelectStmt{
TargetList: []*pgQuery.Node{
parser.utils.MakeResTargetNode(
pgQuery.MakeColumnRefNode([]*pgQuery.Node{pgQuery.MakeStrNode("name")}, 0),
"name",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeColumnRefNode([]*pgQuery.Node{pgQuery.MakeStrNode("value")}, 0),
"setting",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("", 0),
"unit",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("Settings", 0),
"category",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeColumnRefNode([]*pgQuery.Node{pgQuery.MakeStrNode("description")}, 0),
"short_desc",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("", 0),
"extra_desc",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeColumnRefNode([]*pgQuery.Node{pgQuery.MakeStrNode("scope")}, 0),
"context",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeColumnRefNode([]*pgQuery.Node{pgQuery.MakeStrNode("input_type")}, 0),
"vartype",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("default", 0),
"source",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("", 0),
"min_val",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("", 0),
"max_val",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("", 0),
"enumvals",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeColumnRefNode([]*pgQuery.Node{pgQuery.MakeStrNode("value")}, 0),
"boot_val",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeColumnRefNode([]*pgQuery.Node{pgQuery.MakeStrNode("value")}, 0),
"reset_val",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("", 0),
"sourcefile",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("0", 0),
"sourceline",
),
parser.utils.MakeResTargetNode(
pgQuery.MakeAConstStrNode("f", 0),
"pending_restart",
),
},
FromClause: []*pgQuery.Node{
pgQuery.MakeSimpleRangeFunctionNode([]*pgQuery.Node{
pgQuery.MakeListNode([]*pgQuery.Node{
pgQuery.MakeFuncCallNode(
[]*pgQuery.Node{
pgQuery.MakeStrNode("duckdb_settings"),
},
nil,
0,
),
}),
}),
},
},
},
},
Alias: node.GetAlias(),
},
},
}
}

func (parser *QueryParserTable) isPgCatalogSchema(qSchemaTable QuerySchemaTable) bool {
return qSchemaTable.Schema == PG_SCHEMA_PG_CATALOG || qSchemaTable.Schema == ""
}
Expand Down
11 changes: 11 additions & 0 deletions src/query_parser_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,14 @@ func (utils *QueryParserUtils) MakeAConstBoolNode(val bool) *pgQuery.Node {
},
}
}

func (utils *QueryParserUtils) MakeResTargetNode(val *pgQuery.Node, name string) *pgQuery.Node {
return &pgQuery.Node{
Node: &pgQuery.Node_ResTarget{
ResTarget: &pgQuery.ResTarget{
Name: name,
Val: val,
},
},
}
}
5 changes: 5 additions & 0 deletions src/select_remapper_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,11 @@ func (remapper *SelectRemapperTable) RemapTableFunction(node *pgQuery.Node) *pgQ
return remapper.parserTable.MakePgGetKeywordsNode(node)
}

// pg_show_all_settings() -> duckdb_settings()
if remapper.parserTable.IsPgShowAllSettingsFunction(node) {
return remapper.parserTable.MakePgShowAllSettingsNode(node)
}

return node
}

Expand Down

0 comments on commit 46a3767

Please sign in to comment.