@@ -30,6 +30,7 @@ import (
3030 "github.com/dolthub/doltgresql/core/dataloader"
3131 "github.com/dolthub/doltgresql/core/id"
3232 pgexprs "github.com/dolthub/doltgresql/server/expression"
33+ "github.com/dolthub/doltgresql/server/functions/framework"
3334 "github.com/dolthub/doltgresql/server/node"
3435 pgtypes "github.com/dolthub/doltgresql/server/types"
3536)
@@ -147,9 +148,8 @@ func extractBindVarTypes(queryPlan sql.Node) ([]uint32, error) {
147148 return false
148149 }
149150 }
150- if _ , ok := types [e .Name ]; ok {
151- // sanity check
152- err = errors .Errorf ("double placeholder given for %s" , e .Name )
151+ if existingOid , ok := types [e .Name ]; ok {
152+ err = checkCompatibleTypes (existingOid , typOid , e .Name )
153153 }
154154 types [e .Name ] = typOid
155155 case * pgexprs.ExplicitCast :
@@ -164,9 +164,8 @@ func extractBindVarTypes(queryPlan sql.Node) ([]uint32, error) {
164164 return false
165165 }
166166 }
167- if _ , ok = types [bindVar .Name ]; ok {
168- // sanity check
169- err = errors .Errorf ("double placeholder given for %s" , bindVar .Name )
167+ if existingOid , ok := types [bindVar .Name ]; ok {
168+ err = checkCompatibleTypes (existingOid , typOid , bindVar .Name )
170169 }
171170 types [bindVar .Name ] = typOid
172171 return false
@@ -180,9 +179,8 @@ func extractBindVarTypes(queryPlan sql.Node) ([]uint32, error) {
180179 err = errors .Errorf ("could not determine OID for placeholder %s: %e" , bindVar .Name , err )
181180 return false
182181 }
183- if _ , ok = types [bindVar .Name ]; ok {
184- // sanity check
185- err = errors .Errorf ("double placeholder given for %s" , bindVar .Name )
182+ if existingOid , ok := types [bindVar .Name ]; ok {
183+ err = checkCompatibleTypes (existingOid , typOid , bindVar .Name )
186184 }
187185 types [bindVar .Name ] = typOid
188186 return false
@@ -225,3 +223,14 @@ func VitessTypeToObjectID(typ sql.Type) (uint32, error) {
225223 }
226224 return id .Cache ().ToOID (doltgresType .ID .AsId ()), nil
227225}
226+
227+ // checkCompatibleTypes checks if multiple types for which a parameter are used are compatible.
228+ func checkCompatibleTypes (existingOid , newOid uint32 , newName string ) error {
229+ var err error
230+ existing := pgtypes .GetTypeByID (id .Type (id .Cache ().ToInternal (existingOid )))
231+ newType := pgtypes .GetTypeByID (id .Type (id .Cache ().ToInternal (newOid )))
232+ if _ , _ , err = framework .FindCommonType ([]* pgtypes.DoltgresType {existing , newType }); err != nil {
233+ err = errors .Errorf ("parameter %s is used for incompatible types: %s and %s" , newName , existing .String (), newType .String ())
234+ }
235+ return err
236+ }
0 commit comments