[teiid-commits] teiid SVN: r4510 - in trunk: connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc and 11 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Wed Oct 3 12:54:06 EDT 2012


Author: shawkins
Date: 2012-10-03 12:54:06 -0400 (Wed, 03 Oct 2012)
New Revision: 4510

Added:
   trunk/connectors/translator-olap/src/test/
   trunk/connectors/translator-olap/src/test/java/
   trunk/connectors/translator-olap/src/test/java/org/
   trunk/connectors/translator-olap/src/test/java/org/teiid/
   trunk/connectors/translator-olap/src/test/java/org/teiid/translator/
   trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/
   trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java
Modified:
   trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
   trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java
   trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java
   trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLDirectQueryExecution.java
   trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
   trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/DirectQueryExecution.java
   trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
Log:
TEIID-2177 adding jpa canned queries

Modified: trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java
===================================================================
--- trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java	2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/api/src/main/java/org/teiid/language/visitor/SQLStringVisitor.java	2012-10-03 16:54:06 UTC (rev 4510)
@@ -26,7 +26,6 @@
 
 import java.util.Arrays;
 import java.util.HashSet;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
 import java.util.regex.Matcher;
@@ -980,26 +979,29 @@
     	return false;
     }
     
-	public static List<Object> parseNativeQueryParts(String nativeQuery, List<Argument> list) {
+    public interface Substitutor {
+    	void substitute(Argument arg, StringBuilder builder, int index);
+    }
+    
+	public static void parseNativeQueryParts(String nativeQuery, List<Argument> list, StringBuilder stringBuilder, Substitutor substitutor) {
 		Pattern pattern = Pattern.compile("\\$+\\d+"); //$NON-NLS-1$
-		List<Object> parts = new LinkedList<Object>();
 		Matcher m = pattern.matcher(nativeQuery);
 		for (int i = 0; i < nativeQuery.length();) {
 			if (!m.find(i)) {
-				parts.add(nativeQuery.substring(i));
+				stringBuilder.append(nativeQuery.substring(i));
 				break;
 			}
 			if (m.start() != i) {
-				parts.add(nativeQuery.substring(i, m.start()));
+				stringBuilder.append(nativeQuery.substring(i, m.start()));
 			}
 			String match = m.group();
 			int end = match.lastIndexOf('$');
 			if ((end&0x1) == 1) {
 				//escaped
-				parts.add(match.substring((end+1)/2)); 
+				stringBuilder.append(match.substring((end+1)/2)); 
 			} else {
 				if (end != 0) {
-					parts.add(match.substring(0, end/2));
+					stringBuilder.append(match.substring(0, end/2));
 				}
 				int index = Integer.parseInt(match.substring(end + 1))-1;
 				if (index < 0 || index >= list.size()) {
@@ -1009,10 +1011,9 @@
 				if (arg.getDirection() != Direction.IN) {
 					throw new IllegalArgumentException(JDBCPlugin.Util.getString("SQLConversionVisitor.not_in_parameter", index+1)); //$NON-NLS-1$
 				}
-				parts.add(index);
+				substitutor.substitute(arg, stringBuilder, index);
 			}
 			i = m.end();
 		}
-		return parts;
 	}
 }

Modified: trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java
===================================================================
--- trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java	2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-jdbc/src/main/java/org/teiid/translator/jdbc/SQLConversionVisitor.java	2012-10-03 16:54:06 UTC (rev 4510)
@@ -52,7 +52,7 @@
  * This visitor takes an ICommand and does DBMS-specific conversion on it
  * to produce a SQL String.  This class is expected to be subclassed.
  */
-public class SQLConversionVisitor extends SQLStringVisitor{
+public class SQLConversionVisitor extends SQLStringVisitor implements SQLStringVisitor.Substitutor {
 	public static final String TEIID_NON_PREPARED = AbstractMetadataRecord.RELATIONAL_URI + "non-prepared"; //$NON-NLS-1$
 
     private static DecimalFormat DECIMAL_FORMAT = 
@@ -178,23 +178,11 @@
     	if (p != null) {
 	    	String nativeQuery = p.getProperty(TEIID_NATIVE_QUERY, false);
 	    	if (nativeQuery != null) {
-	    		List<Object> parts = parseNativeQueryParts(nativeQuery, obj.getArguments());
 	    		this.prepared = !Boolean.valueOf(p.getProperty(TEIID_NON_PREPARED, false));
 	    		if (this.prepared) {
 	    			this.preparedValues = new ArrayList<Object>();
 	    		}
-	    		for (Object o : parts) {
-	    			if (o instanceof String) {
-	    				buffer.append(o);
-	    			} else {
-	    				if (this.prepared) {
-	    					buffer.append('?');
-	    					this.preparedValues = obj.getArguments();
-	    				} else {
-	    					visit(obj.getArguments().get((Integer)o));
-	    				}
-	    			}
-	    		}
+	    		parseNativeQueryParts(nativeQuery, obj.getArguments(), buffer, this);
 	    		return;
 	    	}
     	}
@@ -394,5 +382,15 @@
 		}
 		super.appendBaseName(obj);
 	}
+
+	@Override
+	public void substitute(Argument arg, StringBuilder builder, int index) {
+		if (this.prepared) {
+			buffer.append('?');
+			this.preparedValues.add(arg);
+		} else {
+			visit(arg);
+		}
+	}
 	
 }

Modified: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java	2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPA2ExecutionFactory.java	2012-10-03 16:54:06 UTC (rev 4510)
@@ -35,6 +35,7 @@
 import org.teiid.language.Call;
 import org.teiid.language.Command;
 import org.teiid.language.QueryExpression;
+import org.teiid.language.visitor.SQLStringVisitor;
 import org.teiid.metadata.MetadataFactory;
 import org.teiid.metadata.RuntimeMetadata;
 import org.teiid.translator.ExecutionContext;
@@ -87,7 +88,11 @@
 
 	@Override
 	public ProcedureExecution createProcedureExecution(Call command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager connection) throws TranslatorException {
-		return super.createProcedureExecution(command, executionContext, metadata, connection);
+		String nativeQuery = command.getMetadataObject().getProperty(SQLStringVisitor.TEIID_NATIVE_QUERY, false);
+		if (nativeQuery != null) {
+			return new JPQLDirectQueryExecution(command.getArguments(), command, executionContext, metadata, connection, nativeQuery, false);
+		}
+		throw new TranslatorException("Missing native-query extension metadata."); //$NON-NLS-1$
 	}
 
 	@Override
@@ -97,10 +102,9 @@
 	
 	@Override
 	public ProcedureExecution createDirectExecution(List<Argument> arguments, Command command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager connection) throws TranslatorException {
-		 return new JPQLDirectQueryExecution(arguments, command, executionContext, metadata, connection);
+		 return new JPQLDirectQueryExecution(arguments.subList(1, arguments.size()), command, executionContext, metadata, connection, (String)arguments.get(0).getArgumentValue().getValue(), true);
 	}	
 	
-	
 	@Override
 	public void getMetadata(MetadataFactory mf, EntityManager em) throws TranslatorException {
 		JPAMetadataProcessor metadataProcessor = new JPAMetadataProcessor();

Modified: trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLDirectQueryExecution.java
===================================================================
--- trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLDirectQueryExecution.java	2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-jpa/src/main/java/org/teiid/translator/jpa/JPQLDirectQueryExecution.java	2012-10-03 16:54:06 UTC (rev 4510)
@@ -21,8 +21,8 @@
  */
 package org.teiid.translator.jpa;
 
-import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
@@ -31,6 +31,8 @@
 
 import org.teiid.language.Argument;
 import org.teiid.language.Command;
+import org.teiid.language.Literal;
+import org.teiid.language.visitor.SQLStringVisitor;
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
 import org.teiid.metadata.RuntimeMetadata;
@@ -42,41 +44,50 @@
 public class JPQLDirectQueryExecution extends JPQLBaseExecution implements ProcedureExecution{
 	private Iterator<?> resultsIterator;
 	private List<Argument> arguments;
-	private int updateCount = -1;
-	private boolean updateQuery;
+	private boolean returnsArray = true;
+	private String query;
 
 	@SuppressWarnings("unused")
-	public JPQLDirectQueryExecution(List<Argument> arguments, Command command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager em) {
+	public JPQLDirectQueryExecution(List<Argument> arguments, Command command, ExecutionContext executionContext, RuntimeMetadata metadata, EntityManager em, String query, boolean returnsArray) {
 		super(executionContext, metadata, em);
 		this.arguments = arguments;
+		this.returnsArray = returnsArray;
+		this.query = query;
 	}
 
 	@Override
 	public void execute() throws TranslatorException {
-		String query = (String)arguments.get(0).getArgumentValue().getValue();
 		if (query.length() < 7) {
 			throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14008));
 		}
-		String firstToken = query.substring(0, 6);
+		String firstToken = query.substring(0, 7);
 		
 		String jpql = query.substring(7);
 		LogManager.logTrace(LogConstants.CTX_CONNECTOR, "JPA Source-Query:", jpql); //$NON-NLS-1$
 
-		if (firstToken.equalsIgnoreCase("search")) { // //$NON-NLS-1$
+		if (firstToken.equalsIgnoreCase("search;")) { // //$NON-NLS-1$
+			StringBuilder buffer = new StringBuilder();
+			SQLStringVisitor.parseNativeQueryParts(jpql, arguments, buffer, new SQLStringVisitor.Substitutor() {
+				
+				@Override
+				public void substitute(Argument arg, StringBuilder builder, int index) {
+					Literal argumentValue = arg.getArgumentValue();
+					builder.append(argumentValue);
+				}
+			});
+			jpql = buffer.toString();
 			Query queryCommand = this.enityManager.createQuery(jpql);
 			List<?> results = queryCommand.getResultList();
 			this.resultsIterator = results.iterator();
 		}		
-		else if (firstToken.equalsIgnoreCase("create")) { // //$NON-NLS-1$
-			Object entity = arguments.get(1).getArgumentValue().getValue();
+		else if (firstToken.equalsIgnoreCase("create;")) { // //$NON-NLS-1$
+			Object entity = arguments.get(0).getArgumentValue().getValue();
 			this.enityManager.merge(entity);
-			this.updateCount = 1;
-			this.updateQuery = true;
+			this.resultsIterator = Arrays.asList(1).iterator();
 		}
-		else if (firstToken.equalsIgnoreCase("update") || firstToken.equalsIgnoreCase("delete")) { // //$NON-NLS-1$ //$NON-NLS-2$
+		else if (firstToken.equalsIgnoreCase("update;") || firstToken.equalsIgnoreCase("delete;")) { // //$NON-NLS-1$ //$NON-NLS-2$
 			Query queryCmd = this.enityManager.createQuery(jpql);
-			this.updateCount = queryCmd.executeUpdate();
-			this.updateQuery = true;
+			this.resultsIterator = Arrays.asList(queryCmd.executeUpdate()).iterator();
 		} else {
 			throw new TranslatorException(JPAPlugin.Util.gs(JPAPlugin.Event.TEIID14008));
 		}
@@ -84,27 +95,20 @@
 
 	@Override
 	public List<?> next() throws TranslatorException, DataNotAvailableException {
-		
-		// for insert/update/delete clauses
-		if (this.updateQuery) {
-			if (this.updateCount != -1) {
-				List<Object[]> row = new ArrayList<Object[]>(1);
-				row.add(new Object[] {this.updateCount});
-				this.updateCount = -1;
-				return row;
-			}
-			return null;
-		}		
-		
 		if (this.resultsIterator != null && this.resultsIterator.hasNext()) {
 			Object obj = this.resultsIterator.next();
 			if (obj instanceof Object[]) {
-				List<Object[]> row = new ArrayList<Object[]>(1);
-				row.add((Object[])obj);
-				return row;
+				if (returnsArray) {
+					return Arrays.asList(obj);
+				}
+				return Arrays.asList((Object[])obj);
 			}
-			return Arrays.asList(new Object[] {obj});
+			if (returnsArray) {
+				return Collections.singletonList(new Object[] {obj});
+			}
+			return Arrays.asList(obj);
 		}
+		this.resultsIterator = null;
 		return null;
 	}
 	

Modified: trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java
===================================================================
--- trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java	2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-olap/src/main/java/org/teiid/translator/olap/OlapQueryExecution.java	2012-10-03 16:54:06 UTC (rev 4510)
@@ -24,6 +24,7 @@
 import java.sql.SQLException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 import java.util.ListIterator;
 
@@ -37,6 +38,7 @@
 import org.olap4j.metadata.Member;
 import org.teiid.language.Argument;
 import org.teiid.language.Command;
+import org.teiid.language.Literal;
 import org.teiid.language.visitor.SQLStringVisitor;
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
@@ -65,15 +67,24 @@
 		this.mdxQuery = mdxQuery;
 		if (arguments.size() > 0 || !returnsArray) { //TODO this is a hack at backwards compatibility 
 			StringBuilder buffer = new StringBuilder();
-			List<Object> parts = SQLStringVisitor.parseNativeQueryParts(this.mdxQuery, arguments);
-			for (Object o : parts) {
-				if (o instanceof String) {
-					buffer.append(o);
-				} else {
-					Integer i = (Integer)o;
-					buffer.append(arguments.get(i).getArgumentValue().getValue());
+			SQLStringVisitor.parseNativeQueryParts(mdxQuery, arguments, buffer, new SQLStringVisitor.Substitutor() {
+				
+				@Override
+				public void substitute(Argument arg, StringBuilder builder, int index) {
+					Literal argumentValue = arg.getArgumentValue();
+					Object value = argumentValue.getValue();
+					if (value == null || value instanceof Number || value instanceof Boolean || value instanceof String) {
+						builder.append(argumentValue);
+					} else if (value instanceof Date) {
+						//bind as a string literal
+						builder.append(new Literal(value.toString(), String.class));
+					} else {
+						//bind as a string literal using the teiid format - this is likely not what the user wants
+						builder.append(new Literal(argumentValue.toString(), String.class));
+					}
 				}
-			}
+			});
+			this.mdxQuery = buffer.toString();
 		}
 		this.command = command;
 		this.connection = connection;

Added: trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java
===================================================================
--- trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java	                        (rev 0)
+++ trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java	2012-10-03 16:54:06 UTC (rev 4510)
@@ -0,0 +1,74 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * See the COPYRIGHT.txt file distributed with this work for information
+ * regarding copyright ownership.  Some portions may be licensed
+ * to Red Hat, Inc. under one or more contributor license agreements.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA.
+ */
+
+package org.teiid.translator.olap;
+
+import static org.junit.Assert.*;
+
+import java.sql.Connection;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.olap4j.OlapConnection;
+import org.olap4j.OlapStatement;
+import org.olap4j.OlapWrapper;
+import org.teiid.cdk.CommandBuilder;
+import org.teiid.core.TeiidRuntimeException;
+import org.teiid.dqp.internal.datamgr.RuntimeMetadataImpl;
+import org.teiid.language.Call;
+import org.teiid.language.Command;
+import org.teiid.query.metadata.TransformationMetadata;
+import org.teiid.query.unittest.RealMetadataFactory;
+import org.teiid.translator.ExecutionContext;
+import org.teiid.translator.ProcedureExecution;
+
+ at SuppressWarnings("nls")
+public class TestOlapTranslator {
+
+	@Test public void testCannedProcedure() throws Exception {
+		String ddl = "create foreign procedure proc(arg integer, arg1 date) returns table (x string) options (\"teiid_rel:native-query\" '$2 $1 something')";
+		String query = "exec proc(2, {d'1970-01-01'})";
+		
+		TransformationMetadata tm = RealMetadataFactory.fromDDL(ddl, "x", "phy");
+		
+		CommandBuilder commandBuilder = new CommandBuilder(tm);
+        Command obj = commandBuilder.getCommand(query);
+	        
+		OlapExecutionFactory oef = new OlapExecutionFactory();
+		Connection mock = Mockito.mock(java.sql.Connection.class);
+		OlapWrapper mock2 = Mockito.mock(OlapWrapper.class);
+		OlapConnection mock3 = Mockito.mock(OlapConnection.class);
+		OlapStatement mock4 = Mockito.mock(OlapStatement.class);
+		Mockito.stub(mock4.executeOlapQuery(Mockito.anyString())).toThrow(new TeiidRuntimeException());
+		Mockito.stub(mock3.createStatement()).toReturn(mock4);
+		Mockito.stub(mock2.unwrap(OlapConnection.class)).toReturn(mock3);
+		Mockito.stub(mock.unwrap(OlapWrapper.class)).toReturn(mock2);
+		ProcedureExecution pe = oef.createProcedureExecution((Call)obj, Mockito.mock(ExecutionContext.class), new RuntimeMetadataImpl(tm), mock);
+		try {
+			pe.execute();
+			fail();
+		} catch (TeiidRuntimeException e) {
+			Mockito.verify(mock4).executeOlapQuery("'1970-01-01' 2 something");
+		}
+	}
+	
+}


Property changes on: trunk/connectors/translator-olap/src/test/java/org/teiid/translator/olap/TestOlapTranslator.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Modified: trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/DirectQueryExecution.java
===================================================================
--- trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/DirectQueryExecution.java	2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/connectors/translator-salesforce/src/main/java/org/teiid/translator/salesforce/execution/DirectQueryExecution.java	2012-10-03 16:54:06 UTC (rev 4510)
@@ -32,6 +32,7 @@
 
 import org.teiid.language.Argument;
 import org.teiid.language.Command;
+import org.teiid.language.Literal;
 import org.teiid.language.visitor.SQLStringVisitor;
 import org.teiid.metadata.RuntimeMetadata;
 import org.teiid.translator.DataNotAvailableException;
@@ -89,15 +90,14 @@
 	public void execute() throws TranslatorException {
 		if (query.startsWith(SEARCH)) { 
 			StringBuilder buffer = new StringBuilder();
-			List<Object> parts = SQLStringVisitor.parseNativeQueryParts(query, arguments);
-			for (Object o : parts) {
-				if (o instanceof String) {
-					buffer.append(o);
-				} else {
-					Integer i = (Integer)o;
-					CriteriaVisitor.appendLiteralValue(buffer, arguments.get(i).getArgumentValue());
+			SQLStringVisitor.parseNativeQueryParts(query, arguments, buffer, new SQLStringVisitor.Substitutor() {
+				
+				@Override
+				public void substitute(Argument arg, StringBuilder builder, int index) {
+					Literal argumentValue = arg.getArgumentValue();
+					CriteriaVisitor.appendLiteralValue(builder, argumentValue);
 				}
-			}
+			});
 			doSelect(buffer.toString().substring(7));
 		}
 		else if (query.startsWith("create;")) { //$NON-NLS-1$

Modified: trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java
===================================================================
--- trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java	2012-10-03 14:27:31 UTC (rev 4509)
+++ trunk/test-integration/common/src/test/java/org/teiid/connector/visitor/util/TestSQLStringVisitor.java	2012-10-03 16:54:06 UTC (rev 4510)
@@ -37,6 +37,7 @@
 import org.teiid.language.Argument.Direction;
 import org.teiid.language.SQLConstants.NonReserved;
 import org.teiid.language.visitor.SQLStringVisitor;
+import org.teiid.language.visitor.SQLStringVisitor.Substitutor;
 import org.teiid.metadata.RuntimeMetadata;
 import org.teiid.query.sql.lang.CompareCriteria;
 import org.teiid.query.sql.lang.JoinType;
@@ -410,14 +411,34 @@
     
     @Test public void testNativeParsing() throws Exception {
     	String sql = "select $1 from $2";
-    	List<Object> parts = SQLStringVisitor.parseNativeQueryParts(sql, Arrays.asList(new Argument(Direction.IN, null, String.class, null), new Argument(Direction.IN, null, String.class, null)));
-    	assertEquals(Arrays.asList((Object)"select ", 0, " from ", 1), parts);
+    	String expected = "select *0 from *1";
+    	helpTestNativeParsing(sql, expected);
     }
+
+	private void helpTestNativeParsing(String sql, String expected) {
+		StringBuilder sb = new StringBuilder();
+    	
+    	Substitutor sub = new Substitutor() {
+			@Override
+			public void substitute(Argument arg, StringBuilder builder, int index) {
+				builder.append("*").append(index);
+			}
+		};
+		
+    	SQLStringVisitor.parseNativeQueryParts(sql, Arrays.asList(new Argument(Direction.IN, null, String.class, null), new Argument(Direction.IN, null, String.class, null)), sb, sub);
+    	assertEquals(expected, sb.toString());
+	}
     
     @Test public void testNativeParsing1() throws Exception {
     	String sql = "select $$1 from $$$2";
-    	List<Object> parts = SQLStringVisitor.parseNativeQueryParts(sql, Arrays.asList(new Argument(Direction.IN, null, String.class, null), new Argument(Direction.IN, null, String.class, null)));
-    	assertEquals(Arrays.asList((Object)"select ", "$1", " from ", "$", 1), parts);
+    	String expected = "select $1 from $*1";
+    	helpTestNativeParsing(sql, expected);
     }
+    
+    @Test(expected=IllegalArgumentException.class) public void testNativeParsing2() throws Exception {
+    	String sql = "select $$1 from $$$3";
+    	String expected = "select $1 from $*1";
+    	helpTestNativeParsing(sql, expected);
+    }
 
 }



More information about the teiid-commits mailing list