From 95b4621b8b83d75c00864b09d79387eebddb84c4 Mon Sep 17 00:00:00 2001 From: Martin Vahlensieck Date: Mon, 25 Sep 2023 11:58:52 +0200 Subject: [PATCH] Fix prepared statements with named parameters --- .../protointerface/NamedValueProcessor.java | 25 +++++++++---------- .../statements/PIPreparedNamedStatement.java | 7 ++---- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/plugins/proto-interface/src/main/java/org/polypheny/db/protointerface/NamedValueProcessor.java b/plugins/proto-interface/src/main/java/org/polypheny/db/protointerface/NamedValueProcessor.java index 2c76cc8e38..c6b2db78ee 100644 --- a/plugins/proto-interface/src/main/java/org/polypheny/db/protointerface/NamedValueProcessor.java +++ b/plugins/proto-interface/src/main/java/org/polypheny/db/protointerface/NamedValueProcessor.java @@ -16,12 +16,9 @@ package org.polypheny.db.protointerface; -import com.google.common.collect.ImmutableBiMap; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; import java.util.regex.Matcher; import java.util.regex.Pattern; import lombok.Getter; @@ -30,12 +27,11 @@ public class NamedValueProcessor { // matches tags such as :name - private static final Pattern PLACEHOLDER_PATTERN = Pattern.compile( "(? namedIndexes; + private final List replacements = new ArrayList<>(); public NamedValueProcessor( String statement ) { @@ -43,28 +39,31 @@ public NamedValueProcessor( String statement ) { } - public void processStatement( String statement ) { - HashMap indexByName = new HashMap<>(); - AtomicInteger valueIndex = new AtomicInteger(); + private void processStatement( String statement ) { Matcher matcher = PLACEHOLDER_PATTERN.matcher( statement ); if ( !matcher.find() ) { this.processedQuery = statement; + return; } StringBuilder stringBuilder = new StringBuilder(); - String currentGroup = matcher.group( 1 ); do { + replacements.add( matcher.group( 1 ) ); matcher.appendReplacement( stringBuilder, REPLACEMENT_CHARACTER ); - indexByName.put( currentGroup, valueIndex.getAndIncrement() ); } while ( matcher.find() ); matcher.appendTail( stringBuilder ); this.processedQuery = stringBuilder.toString(); - this.namedIndexes = ImmutableBiMap.copyOf( indexByName ); } public List transformValueMap( Map values ) { List image = new ArrayList<>(); - values.forEach( ( key, value ) -> image.set( namedIndexes.get( key ), value ) ); + for ( String placeholder : replacements ) { + PolyValue value = values.get( placeholder ); + if ( value == null ) { + throw new RuntimeException( "Missing named parameter: " + placeholder ); + } + image.add( values.get( placeholder ) ); + } return image; } diff --git a/plugins/proto-interface/src/main/java/org/polypheny/db/protointerface/statements/PIPreparedNamedStatement.java b/plugins/proto-interface/src/main/java/org/polypheny/db/protointerface/statements/PIPreparedNamedStatement.java index 566d94c4ae..eb91811882 100644 --- a/plugins/proto-interface/src/main/java/org/polypheny/db/protointerface/statements/PIPreparedNamedStatement.java +++ b/plugins/proto-interface/src/main/java/org/polypheny/db/protointerface/statements/PIPreparedNamedStatement.java @@ -64,11 +64,8 @@ public StatementResult execute( Map values, int fetchSize ) t statement = client.getCurrentOrCreateNewTransaction().createStatement(); } List valueList = namedValueProcessor.transformValueMap( values ); - long index = 0; - for ( PolyValue value : valueList ) { - if ( value != null ) { - statement.getDataContext().addParameterValues( index++, null, List.of( value ) ); - } + for ( int i = 0; i < valueList.size(); i++ ) { + statement.getDataContext().addParameterValues( i, null, List.of( valueList.get( i ) ) ); } StatementProcessor.implement( this ); return StatementProcessor.executeAndGetResult( this, fetchSize );