Skip to content

Commit

Permalink
Refactor identifying function calls from pg_catalog
Browse files Browse the repository at this point in the history
  • Loading branch information
exAspArk committed Jan 6, 2025
1 parent ef143d9 commit 9b2f1a7
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 224 deletions.
134 changes: 129 additions & 5 deletions src/pg_constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@ const (
PG_SCHEMA_PG_CATALOG = "pg_catalog"
PG_SCHEMA_PUBLIC = "public"

PG_FUNCTION_ARRAY_TO_STRING = "array_to_string"
PG_FUNCTION_ARRAY_UPPER = "array_upper"
PG_FUNCTION_PG_GET_INDEXDEF = "pg_get_indexdef"
PG_FUNCTION_PG_EXPANDARRAY = "_pg_expandarray"
PG_FUNCTION_PG_GET_EXPR = "pg_get_expr"
PG_FUNCTION_PG_GET_KEYWORDS = "pg_get_keywords"
PG_FUNCTION_PG_IS_IN_RECOVERY = "pg_is_in_recovery"
PG_FUNCTION_PG_SHOW_ALL_SETTINGS = "pg_show_all_settings"
PG_FUNCTION_QUOTE_INDENT = "quote_ident"
PG_FUNCTION_PG_GET_EXPR = "pg_get_expr"
PG_FUNCTION_SET_CONFIG = "set_config"
PG_FUNCTION_ROW_TO_JSON = "row_to_json"
PG_FUNCTION_ARRAY_TO_STRING = "array_to_string"
PG_FUNCTION_PG_EXPANDARRAY = "_pg_expandarray"
PG_FUNCTION_SET_CONFIG = "set_config"

PG_TABLE_PG_AUTH_MEMBERS = "pg_auth_members"
PG_TABLE_PG_CLASS = "pg_class"
Expand All @@ -35,3 +34,128 @@ const (
PG_TABLE_PG_USER = "pg_user"
PG_TABLE_TABLES = "tables"
)

var PG_SYSTEM_TABLES = NewSet([]string{
"pg_aggregate",
"pg_am",
"pg_amop",
"pg_amproc",
"pg_attrdef",
"pg_attribute",
"pg_auth_members",
"pg_authid",
"pg_cast",
"pg_class",
"pg_collation",
"pg_constraint",
"pg_conversion",
"pg_database",
"pg_db_role_setting",
"pg_default_acl",
"pg_depend",
"pg_description",
"pg_enum",
"pg_event_trigger",
"pg_extension",
"pg_foreign_data_wrapper",
"pg_foreign_server",
"pg_foreign_table",
"pg_index",
"pg_inherits",
"pg_init_privs",
"pg_language",
"pg_largeobject",
"pg_largeobject_metadata",
"pg_matviews",
"pg_namespace",
"pg_opclass",
"pg_operator",
"pg_opfamily",
"pg_parameter_acl",
"pg_partitioned_table",
"pg_policy",
"pg_proc",
"pg_publication",
"pg_publication_namespace",
"pg_publication_rel",
"pg_user",
"pg_range",
"pg_replication_origin",
"pg_replication_slots",
"pg_rewrite",
"pg_roles",
"pg_seclabel",
"pg_sequence",
"pg_shadow",
"pg_shdepend",
"pg_shdescription",
"pg_shseclabel",
"pg_statistic",
"pg_statistic_ext",
"pg_statistic_ext_data",
"pg_subscription",
"pg_subscription_rel",
"pg_tablespace",
"pg_transform",
"pg_trigger",
"pg_ts_config",
"pg_ts_config_map",
"pg_ts_dict",
"pg_ts_parser",
"pg_ts_template",
"pg_type",
"pg_user_mapping",
})

var PG_SYSTEM_VIEWS = NewSet([]string{
"pg_stat_activity",
"pg_stat_replication",
"pg_stat_wal_receiver",
"pg_stat_recovery_prefetch",
"pg_stat_subscription",
"pg_stat_ssl",
"pg_stat_gssapi",
"pg_stat_progress_analyze",
"pg_stat_progress_create_index",
"pg_stat_progress_vacuum",
"pg_stat_progress_cluster",
"pg_stat_progress_basebackup",
"pg_stat_progress_copy",
"pg_stat_archiver",
"pg_stat_bgwriter",
"pg_stat_checkpointer",
"pg_stat_database",
"pg_stat_database_conflicts",
"pg_stat_io",
"pg_stat_replication_slots",
"pg_stat_slru",
"pg_stat_subscription_stats",
"pg_stat_wal",
"pg_stat_all_tables",
"pg_stat_sys_tables",
"pg_stat_user_tables",
"pg_stat_xact_all_tables",
"pg_stat_xact_sys_tables",
"pg_stat_xact_user_tables",
"pg_stat_all_indexes",
"pg_stat_sys_indexes",
"pg_stat_user_indexes",
"pg_stat_user_functions",
"pg_stat_xact_user_functions",
"pg_statio_all_tables",
"pg_statio_sys_tables",
"pg_statio_user_tables",
"pg_statio_all_indexes",
"pg_statio_sys_indexes",
"pg_statio_user_indexes",
"pg_statio_all_sequences",
"pg_statio_sys_sequences",
"pg_statio_user_sequences",
})

var PG_SYSTEM_FUNCTIONS = NewSet([]string{
"pg_get_expr",
"pg_get_keywords",
"pg_is_in_recovery",
"pg_show_all_settings",
})
16 changes: 1 addition & 15 deletions src/query_parser_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,7 @@ func (parser *QueryParserSelect) NestedFunctionCalls(functionCall *pgQuery.FuncC
}

func (parser *QueryParserSelect) SchemaFunction(functionCall *pgQuery.FuncCall) PgSchemaFunction {
if len(functionCall.Funcname) == 1 {
return PgSchemaFunction{
Schema: "",
Function: functionCall.Funcname[0].GetString_().Sval,
}
}

if len(functionCall.Funcname) == 2 {
return PgSchemaFunction{
Schema: functionCall.Funcname[0].GetString_().Sval,
Function: functionCall.Funcname[1].GetString_().Sval,
}
}

return PgSchemaFunction{}
return parser.utils.SchemaFunction(functionCall)
}

// quote_ident(str) -> concat("\""+str+"\"")
Expand Down
78 changes: 5 additions & 73 deletions src/query_parser_table.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,27 +175,19 @@ func (parser *QueryParserTable) MakeIcebergTableNode(tablePath string, qSchemaTa
return parser.utils.MakeSubselectFromNode(qSchemaTable.Table, []*pgQuery.Node{selectStarNode}, node, qSchemaTable.Alias)
}

// pg_catalog.pg_get_keywords()
func (parser *QueryParserTable) IsPgGetKeywordsFunction(node *pgQuery.Node) bool {
func (parser *QueryParserTable) SchemaFunction(node *pgQuery.Node) PgSchemaFunction {
for _, funcNode := range node.GetRangeFunction().Functions {
for _, funcItemNode := range funcNode.GetList().Items {
funcCallNode := funcItemNode.GetFuncCall()
if funcCallNode == nil {
continue
}
if len(funcCallNode.Funcname) != 2 {
continue
}

schema := funcCallNode.Funcname[0].GetString_().Sval
function := funcCallNode.Funcname[1].GetString_().Sval
if schema == PG_SCHEMA_PG_CATALOG && function == PG_FUNCTION_PG_GET_KEYWORDS {
return true
}
return parser.utils.SchemaFunction(funcCallNode)
}
}

return false
return PgSchemaFunction{}
}

// pg_catalog.pg_get_keywords() -> VALUES(values...) t(columns...)
Expand Down Expand Up @@ -255,35 +247,7 @@ 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 {
function := funcCallNode.Funcname[0].GetString_().Sval
if function == PG_FUNCTION_PG_SHOW_ALL_SETTINGS {
return true
}
}

if len(funcCallNode.Funcname) == 2 {
schema := funcCallNode.Funcname[0].GetString_().Sval
function := funcCallNode.Funcname[1].GetString_().Sval
if schema == PG_SCHEMA_PG_CATALOG && function == PG_FUNCTION_PG_SHOW_ALL_SETTINGS {
return true
}
}
}
}
return false
}

// pg_show_all_settings() -> duckdb_settings() mapped to pg format
// pg_catalog.pg_show_all_settings() -> duckdb_settings() mapped to pg format
func (parser *QueryParserTable) MakePgShowAllSettingsNode(node *pgQuery.Node) *pgQuery.Node {
targetList := []*pgQuery.Node{
pgQuery.MakeResTargetNodeWithNameAndVal(
Expand Down Expand Up @@ -392,35 +356,7 @@ func (parser *QueryParserTable) MakePgShowAllSettingsNode(node *pgQuery.Node) *p
return parser.utils.MakeSubselectFromNode(PG_FUNCTION_PG_SHOW_ALL_SETTINGS, targetList, fromNode, alias)
}

// pg_is_in_recovery()
func (parser *QueryParserTable) IsPgIsInRecoveryFunction(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 {
function := funcCallNode.Funcname[0].GetString_().Sval
if function == PG_FUNCTION_PG_IS_IN_RECOVERY {
return true
}
}

if len(funcCallNode.Funcname) == 2 {
schema := funcCallNode.Funcname[0].GetString_().Sval
function := funcCallNode.Funcname[1].GetString_().Sval
if schema == PG_SCHEMA_PG_CATALOG && function == PG_FUNCTION_PG_IS_IN_RECOVERY {
return true
}
}
}
}
return false
}

// pg_is_in_recovery() -> 'f'::bool
// pg_catalog.pg_is_in_recovery() -> 'f'::bool
func (parser *QueryParserTable) MakePgIsInRecoveryNode(node *pgQuery.Node) *pgQuery.Node {
var alias string
if node.GetAlias() != nil {
Expand All @@ -435,10 +371,6 @@ func (parser *QueryParserTable) MakePgIsInRecoveryNode(node *pgQuery.Node) *pgQu
)
}

func (parser *QueryParserTable) isPgCatalogSchema(qSchemaTable QuerySchemaTable) bool {
return qSchemaTable.Schema == PG_SCHEMA_PG_CATALOG || qSchemaTable.Schema == ""
}

var PG_SHADOW_VALUE_BY_COLUMN = NewOrderedMap([][]string{
{"usename", "bemidb"},
{"usesysid", "10"},
Expand Down
17 changes: 17 additions & 0 deletions src/query_parser_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,23 @@ func NewQueryParserUtils(config *Config) *QueryParserUtils {
return &QueryParserUtils{config: config}
}

func (utils *QueryParserUtils) SchemaFunction(functionCall *pgQuery.FuncCall) PgSchemaFunction {
switch len(functionCall.Funcname) {
case 1:
return PgSchemaFunction{
Schema: "",
Function: functionCall.Funcname[0].GetString_().Sval,
}
case 2:
return PgSchemaFunction{
Schema: functionCall.Funcname[0].GetString_().Sval,
Function: functionCall.Funcname[1].GetString_().Sval,
}
default:
panic("Invalid function call")
}
}

func (utils *QueryParserUtils) MakeSubselectWithRowsNode(tableName string, columns []string, rowsValues [][]string, alias string) *pgQuery.Node {
parserType := NewQueryParserType(utils.config)

Expand Down
4 changes: 2 additions & 2 deletions src/select_remapper_select.go
Original file line number Diff line number Diff line change
Expand Up @@ -123,8 +123,8 @@ func (remapper *SelectRemapperSelect) remappedFunctionName(functionCall *pgQuery
func (remapper *SelectRemapperSelect) remappedFunctionArgs(functionCall *pgQuery.FuncCall) *pgQuery.FuncCall {
schemaFunction := remapper.parserSelect.SchemaFunction(functionCall)

// pg_get_expr(pg_node_tree, relation_oid, pretty_bool) -> pg_get_expr(pg_node_tree, relation_oid)
if schemaFunction.Schema == PG_SCHEMA_PG_CATALOG && schemaFunction.Function == PG_FUNCTION_PG_GET_EXPR {
// pg_catalog.pg_get_expr(pg_node_tree, relation_oid, pretty_bool) -> pg_catalog.pg_get_expr(pg_node_tree, relation_oid)
if (schemaFunction.Schema == PG_SCHEMA_PG_CATALOG || schemaFunction.Schema == "") && schemaFunction.Function == PG_FUNCTION_PG_GET_EXPR {
return remapper.parserSelect.RemoveThirdArgumentFromPgGetExpr(functionCall)
}

Expand Down
Loading

0 comments on commit 9b2f1a7

Please sign in to comment.