Skip to content

Commit

Permalink
fix: wrap columns 'proallargtypes' and 'proargtypes' to split string …
Browse files Browse the repository at this point in the history
…into string array (#354)
  • Loading branch information
VWagen1989 committed Jan 17, 2025
1 parent ee1139f commit 5a2a168
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 21 deletions.
21 changes: 18 additions & 3 deletions catalog/internal_macro.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ type MacroDefinition struct {
DDL string
}

var SchemaNameMyListContains string = "__sys__"
var MacroNameMyListContains string = "my_list_contains"
var (
SchemaNameSYS string = "__sys__"
MacroNameMyListContains string = "my_list_contains"

MacroNameMySplitListStr string = "my_split_list_str"
)

type InternalMacro struct {
Schema string
Expand Down Expand Up @@ -76,7 +80,7 @@ var InternalMacros = []InternalMacro{
},
},
{
Schema: SchemaNameMyListContains,
Schema: SchemaNameSYS,
Name: MacroNameMyListContains,
IsTableMacro: false,
Definitions: []MacroDefinition{
Expand All @@ -91,4 +95,15 @@ var InternalMacros = []InternalMacro{
},
},
},
{
Schema: SchemaNameSYS,
Name: MacroNameMySplitListStr,
IsTableMacro: false,
Definitions: []MacroDefinition{
{
Params: []string{"l"},
DDL: `regexp_split_to_array(l::VARCHAR, '[{},\s]+')`,
},
},
},
}
4 changes: 2 additions & 2 deletions pgserver/in_place_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,11 @@ var selectionConversions = []SelectionConversion{
needConvert: func(query *ConvertedStatement) bool {
sqlStr := RemoveComments(query.String)
// TODO(sean): Evaluate the conditions by iterating over the AST.
return getTypeCastRegex().MatchString(sqlStr)
return getSimpleStringMatchingRegex().MatchString(sqlStr)
},
doConvert: func(h *ConnectionHandler, query *ConvertedStatement) error {
sqlStr := RemoveComments(query.String)
sqlStr = ConvertTypeCast(sqlStr)
sqlStr = SimpleStrReplacement(sqlStr)
query.String = sqlStr
return nil
},
Expand Down
38 changes: 22 additions & 16 deletions pgserver/stmt.go
Original file line number Diff line number Diff line change
Expand Up @@ -310,36 +310,42 @@ func getPgAnyOpRegex() *regexp.Regexp {
// Replace the operator 'ANY' with a function call.
func ConvertAnyOp(sql string) string {
re := getPgAnyOpRegex()
return re.ReplaceAllString(sql, catalog.SchemaNameMyListContains+"."+catalog.MacroNameMyListContains+"($2, $1)")
return re.ReplaceAllString(sql, catalog.SchemaNameSYS+"."+catalog.MacroNameMyListContains+"($2, $1)")
}

var (
typeCastRegex *regexp.Regexp
initTypeCastRegex sync.Once
simpleStrMatchingRegex *regexp.Regexp
initSimpleStrMatchingRegex sync.Once
)

// TODO(sean): This is a temporary solution. We need to find a better way to handle type cast conversion and column conversion. e.g. Iterating the AST with a visitor pattern.
// The Key must be in lowercase. Because the key used for value retrieval is in lowercase.
var typeCastConversion = map[string]string{
var simpleStringsConversion = map[string]string{
// type cast conversion
"::regclass": "::varchar",
"::regtype": "::integer",
"::regtype": "::varchar",

// column conversion
"proallargtypes": catalog.SchemaNameSYS + "." + catalog.MacroNameMySplitListStr + "(proallargtypes)",
"proargtypes": catalog.SchemaNameSYS + "." + catalog.MacroNameMySplitListStr + "(proargtypes)",
}

// This function will return a regex that matches all type casts in the query.
func getTypeCastRegex() *regexp.Regexp {
initTypeCastRegex.Do(func() {
var typeCasts []string
for typeCast := range typeCastConversion {
typeCasts = append(typeCasts, regexp.QuoteMeta(typeCast))
func getSimpleStringMatchingRegex() *regexp.Regexp {
initSimpleStrMatchingRegex.Do(func() {
var simpleStrings []string
for simpleString := range simpleStringsConversion {
simpleStrings = append(simpleStrings, regexp.QuoteMeta(simpleString))
}
typeCastRegex = regexp.MustCompile(`(?i)(` + strings.Join(typeCasts, "|") + `)`)
simpleStrMatchingRegex = regexp.MustCompile(`(?i)(` + strings.Join(simpleStrings, "|") + `)`)
})
return typeCastRegex
return simpleStrMatchingRegex
}

// This function will replace all type casts in the query with the corresponding type cast in the typeCastConversion map.
func ConvertTypeCast(sql string) string {
return getTypeCastRegex().ReplaceAllStringFunc(sql, func(m string) string {
return typeCastConversion[strings.ToLower(m)]
// This function will replace all type casts in the query with the corresponding type cast in the simpleStringsConversion map.
func SimpleStrReplacement(sql string) string {
return getSimpleStringMatchingRegex().ReplaceAllStringFunc(sql, func(m string) string {
return simpleStringsConversion[strings.ToLower(m)]
})
}

Expand Down

0 comments on commit 5a2a168

Please sign in to comment.