You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by do...@apache.org on 2009/11/16 17:31:34 UTC

svn commit: r880835 [2/2] - in /ofbiz/trunk: ./ framework/ framework/base/src/org/ofbiz/base/util/ framework/entity/ framework/entity/src/org/ofbiz/entity/sql/ framework/sql/ framework/sql/src/ framework/sql/src/org/ framework/sql/src/org/ofbiz/ framew...

Copied: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Parser.jj (from r880822, ofbiz/trunk/framework/entity/src/org/ofbiz/entity/sql/Parser.jj)
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Parser.jj?p2=ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Parser.jj&p1=ofbiz/trunk/framework/entity/src/org/ofbiz/entity/sql/Parser.jj&r1=880822&r2=880835&rev=880835&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/sql/Parser.jj (original)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Parser.jj Mon Nov 16 16:31:32 2009
@@ -1,3 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 options {
   JAVA_UNICODE_ESCAPE = false;
   ERROR_REPORTING = true;
@@ -20,32 +38,22 @@
 }
 PARSER_BEGIN(Parser)
 
-package org.ofbiz.entity.sql;
+package org.ofbiz.sql;
 
 import java.io.*;
+import java.util.Collections;
 import java.util.List;
 import java.util.LinkedList;
+import java.util.Map;
 import java.util.Set;
 
 import javolution.util.FastList;
+import javolution.util.FastMap;
 import javolution.util.FastSet;
 
 import org.ofbiz.base.conversion.ConversionException;
 import org.ofbiz.base.conversion.Converter;
 import org.ofbiz.base.conversion.Converters;
-import org.ofbiz.entity.condition.EntityComparisonOperator;
-import org.ofbiz.entity.condition.EntityCondition;
-import org.ofbiz.entity.condition.EntityConditionValue;
-import org.ofbiz.entity.condition.EntityFieldValue;
-import org.ofbiz.entity.condition.EntityOperator;
-import org.ofbiz.entity.condition.OrderByItem;
-import org.ofbiz.entity.condition.OrderByList;
-import org.ofbiz.entity.model.DynamicViewEntity;
-import org.ofbiz.entity.model.ModelKeyMap;
-import org.ofbiz.entity.model.ModelViewEntity.ComplexAlias;
-import org.ofbiz.entity.model.ModelViewEntity.ComplexAliasField;
-import org.ofbiz.entity.model.ModelViewEntity.ComplexAliasMember;
-import org.ofbiz.entity.model.ModelViewEntity.ModelAlias;
 
 public class Parser {
 }
@@ -72,13 +80,12 @@
 |	<PERIOD: ".">
 |	<JOIN: "JOIN">
 |	<LEFT: "LEFT">
-|	<RIGHT: "RIGHT">
 |	<AS: "AS">
 |	<WHERE: "WHERE">
 |	<HAVING: "HAVING">
 |	<GROUP: "GROUP">
 |	<ORDER: "ORDER">
-|	<UNION: "UNION">
+//|	<UNION: "UNION">
 |	<BY: "BY">
 |	<ON: "ON">
 |	<USING: "USING">
@@ -87,8 +94,9 @@
 |	<SELECT: "SELECT">
 |	<DELETE: "DELETE">
 |	<UPDATE: "UPDATE">
+|	<INSERT: "INSERT">
 |	<RELATION: "RELATION">
-|	<COALESCE: "COALESCE">
+|	<EXCLUDE: "EXCLUDE">
 |	<TYPE: "TYPE">
 |	<TITLE: "TITLE">
 |	<SET: "SET">
@@ -98,7 +106,12 @@
 |	<COMMA: ",">
 |	<DESC: "DESC">
 |	<ASC: "ASC">
-|	<AGGREGATE_FUNCTION: "COUNT"|"COUNT-DISTINCT"|"MIN"|"MAX"|"SUM"|"AVG">
+|	<EQUALS: "=">
+|	<BETWEEN: "BETWEEN">
+|	<INTO: "INTO">
+|	<VALUES: "VALUES">
+|	<CREATE: "CREATE">
+|	<VIEW: "VIEW">
 |	<START_DQUOTE: "\""> { pushState(IN_DQUOTE); }
 |	<START_SQUOTE: "'"> { pushState(IN_SQUOTE); }
 |	<INTEGER:
@@ -108,7 +121,8 @@
 	)
 	| ["1"-"9"] (["0"-"9"])*
 	>
-|	<NAME:	(["a"-"z"])+>
+|	<NAME:	["a"-"z"] (["a"-"z","0"-"9","_","-"])*>
+|	<PARAMETER: "?" (["a"-"z"])+>
 //|	<WORD: (~["'", "\"", "/", " ", "\f", "\n", "\r", "\t", "*"])+>
 }
 
@@ -151,139 +165,330 @@
 
 // -------------------
 
+public List<SQLStatement<?, ?>> SQLFile():
+{
+	List<SQLStatement<?, ?>> list = FastList.newInstance();
+	SQLStatement<?, ?> statement;
+}
+{
+	( statement=Statement() ( <SEMI> )? { list.add(statement); } )*
+	<EOF>
+	{ return list; }
+}
 
-SQLSelect Select():
+public SQLStatement StandaloneStatement():
 {
-	EntityCondition condition;
-	int i;
-	DynamicViewEntity dve = new DynamicViewEntity();
-	SQLSelect sqlSelect = new SQLSelect();
-	sqlSelect.setDynamicViewEntity(dve);
-	List<String> fieldList;
-	List<String> orderBy;
-}
-{
-	<SELECT> FieldDefs(dve)
-	<FROM> Table(dve)
-	( <RELATION> RelationDef(dve) )*
-	( <WHERE> condition=ConditionExpression() { sqlSelect.setWhereCondition(condition); } )?
-	( <HAVING> condition=ConditionExpression() { sqlSelect.setHavingCondition(condition); } )?
-	( <GROUP> <BY> fieldList=FieldList() { dve.setGroupBy(fieldList); } )?
-	( <ORDER> <BY> orderBy=OrderByList() { sqlSelect.setOrderBy(orderBy); } )?
-	( <OFFSET> i=Integer() { sqlSelect.setOffset(i); } )?
-	( <LIMIT> i=Integer() { sqlSelect.setLimit(i); } )?
-	<SEMI>
-	{ return sqlSelect; }
+	SQLStatement statement;
+}
+{
+	statement=Statement() ( <SEMI> )? <EOF> { return statement; }
+}
+
+public SQLView ViewStatement():
+{
+	SQLView sqlView;
+}
+{
+	sqlView=View() ( <SEMI> )? <EOF> { return sqlView; }
+}
+
+public SQLSelect SelectStatement():
+{
+	SQLSelect sqlSelect;
+}
+{
+	sqlSelect=Select() ( <SEMI> )? <EOF> { return sqlSelect; }
+}
+
+public SQLDelete DeleteStatement():
+{
+	SQLDelete sqlDelete;
+}
+{
+	sqlDelete=Delete() ( <SEMI> )? <EOF> { return sqlDelete; }
+}
+
+public SQLUpdate UpdateStatement():
+{
+	SQLUpdate sqlUpdate;
+}
+{
+	sqlUpdate=Update() ( <SEMI> )? <EOF> { return sqlUpdate; }
+}
+
+public SQLInsert InsertStatement():
+{
+	SQLInsert sqlInsert;
+}
+{
+	sqlInsert=Insert() ( <SEMI> )? <EOF> { return sqlInsert; }
+}
+
+public Condition Condition():
+{ Condition c; }
+{
+	c=ConditionExpression() <EOF> { return c; }
+}
+
+private SQLStatement Statement():
+{
+	SQLStatement statement;
+}
+{
+	(
+		statement=Select() { return statement; }
+	|	statement=Delete() { return statement; }
+	|	statement=Update() { return statement; }
+	|	statement=Insert() { return statement; }
+	)
 }
 
-private void RelationDef(DynamicViewEntity dve):
+private SQLView View():
+{
+	String name;
+	SQLSelect sqlSelect;
+}
+{
+	<CREATE> <VIEW> name=NamePart() <AS> sqlSelect=Select()
+	{ return new SQLView(name, sqlSelect); }
+}
+
+private SQLSelect Select():
+{
+	Integer i;
+	List<String> orderBy = null, groupBy = null;
+	Map<String, FieldDef> fieldDefs = FastMap.newInstance();
+	List<FieldAll> fieldAlls = FastList.newInstance();
+	Table table;
+	List<Relation> relations = FastList.newInstance();
+	Relation relation;
+	Condition whereCondition = null, havingCondition = null;
+	int offset = -1, limit = -1;
+}
+{
+	<SELECT> (
+		FieldDef(fieldDefs, fieldAlls)
+		( <COMMA> FieldDef(fieldDefs, fieldAlls) )*
+	)
+	<FROM> table=Table()
+	( <RELATION> relation=Relation() { relations.add(relation); } )*
+	( <WHERE> whereCondition=ConditionExpression() )?
+	( <HAVING> havingCondition=ConditionExpression() )?
+	( <GROUP> <BY> groupBy=FieldList() )?
+	( <ORDER> <BY> orderBy=OrderByList() )?
+	( <OFFSET> offset=Integer() )?
+	( <LIMIT> limit=Integer() )?
+	{ return new SQLSelect(fieldAlls, fieldDefs, table, relations, whereCondition, havingCondition, groupBy, orderBy, offset, limit); }
+}
+
+private Relation Relation():
 {
 	String type = null, title = null, entityName;
-	List<ModelKeyMap> keyMaps;
+	List<KeyMap> keyMaps;
 }
 {
-	( LOOKAHEAD(2) <TYPE> type=NamePart() )?
-	( LOOKAHEAD(2) <TITLE> title=NamePart() )?
-	entityName=NamePart()
-	keyMaps=KeyMaps("cur", "other") {
-		System.err.println("addRelation(" + type + ", " + title + ", " + entityName + ", " + keyMaps + ")");
-		dve.addRelation(type, title, entityName, keyMaps);
-	}
+	( <TYPE> type=NamePart() )?
+	( <TITLE> title=NamePart() )?
+	<NAME> { entityName = getToken(0).image; }
+	keyMaps=KeyMaps("cur", "other")
+	{ return new Relation(type, title, entityName, keyMaps); }
+}
+
+
+private SQLUpdate Update():
+{
+	TableName tableName;
+	List<Table> tableList = null;
+	Condition whereCondition = null;
+	List<SetField> allSetFields = FastList.newInstance();
+	List<SetField> setFields;
+	Joined joined = null;
 }
-/*
-CSSUpdate Update():
-{}
 {
-	<UPDATE> Table()
-	( Set() )+
-	( <FROM> TableList() )?
-	( <WHERE> ConditionExpression() )?
-	<SEMI>
+	<UPDATE> tableName=TableName()
+	<SET>
+	setFields=SetField() { allSetFields.addAll(setFields); }
+	( <COMMA> setFields=SetField() { allSetFields.addAll(setFields); } )*
+	( <FROM> joined=JoinedRest(false, tableName) )?
+	( <WHERE> whereCondition=ConditionExpression() )?
+	{ return new SQLUpdate(new Table(tableName, joined), allSetFields, whereCondition); }
 }
 
-CSSDelete Delete():
-{}
+private SQLDelete Delete():
+{
+	TableName tableName;
+	List<Table> tableList = null;
+	Condition whereCondition = null;
+	Joined joined = null;
+}
+{
+	<DELETE> <FROM> tableName=TableName()
+	( <USING> joined=JoinedRest(false, tableName) )?
+	( <WHERE> whereCondition=ConditionExpression() )?
+	{ return new SQLDelete(new Table(tableName, joined), whereCondition); }
+}
+
+private SQLInsert Insert():
+{
+	TableName tableName;
+	List<String> columns = FastList.newInstance();
+	String n;
+	InsertSource source;
+}
+{
+	<INSERT> <INTO> tableName=TableName() (
+		<OPEN_PAREN>
+		n=NamePart() { columns.add(n); }
+		( <COMMA> n=NamePart() { columns.add(n); } )*
+		<CLOSE_PAREN>
+	)?
+	( source=InsertValues() | source=Select() )
+	{ return new SQLInsert(tableName, source, columns); }
+}
+
+private InsertValues InsertValues():
+{
+	List<InsertRow> list = FastList.newInstance();
+	InsertRow row;
+}
+{
+	<VALUES>
+	row=InsertRow() { list.add(row); }
+	( <COMMA> row=InsertRow() { list.add(row); } )*
+	{ return new InsertValues(list); }
+}
+
+private InsertRow InsertRow():
+{
+	List<Value> list = FastList.newInstance();
+	Value v;
+}
 {
-	<DELETE> <FROM>	Table()
-	( <USING> TableList() )?
-	( <WHERE> ConditionExpression() )?
-	<SEMI>
+	<OPEN_PAREN>
+	v=InsertValue() { list.add(v); }
+	( <COMMA> v=InsertValue() { list.add(v); } )*
+	<CLOSE_PAREN>
+	{ return new InsertRow(list); }
 }
-*/
 
-private void Table(DynamicViewEntity dve):
+private Value InsertValue():
 {
-	String leftAlias, rightAlias;
-	Boolean relOptional;
-	Set<String> availableAliases = FastSet.newInstance();
-	List<ModelKeyMap> keyMaps;
+	Value v;
+	Integer i;
+	String s;
+}
+{
+	v=ParameterValue() { return v; }
+|	i=Integer() { return new NumberValue<Integer>(i); }
+|	s=SQuoted() { return new StringValue(s); }
+}
+
+private List<SetField> SetField():
+{
+	List<SetField> setFields = FastList.newInstance();
+	String n;
+	Value v;
+	List<String> columnList = FastList.newInstance();
+	List<Value> valueList = FastList.newInstance();
 }
 {
-	leftAlias=TableName(dve) { availableAliases.add(leftAlias); }
 	(
-		relOptional=Joiner() rightAlias=TableName(dve) { availableAliases.add(rightAlias); }
-		keyMaps=KeyMaps(leftAlias, rightAlias) {
-    			dve.addViewLink(leftAlias, rightAlias, relOptional, keyMaps);
-		}
-		
-	)*
+		n=NamePart() <EQUALS> v=Value() { setFields.add(new SetField(n, v)); }
+	|	<OPEN_PAREN>
+		n=NamePart() { columnList.add(n); }
+		( <COMMA> n=NamePart() { columnList.add(n); } )*
+		<CLOSE_PAREN>
+		<EQUALS>
+		<OPEN_PAREN>
+		v=Value() { valueList.add(v); }
+		( <COMMA> v=Value() { valueList.add(v); } )*
+		<CLOSE_PAREN>
+	)
+	{ return setFields; }
+}
 
+private Table Table():
+{
+	TableName tableName;
+	Joined joined = null;
+}
+{
+	tableName=TableName()
+	( joined=Joined(tableName) )?
+	{ return new Table(tableName, joined); }
 }
 
-private List<ModelKeyMap> KeyMaps(String leftAlias, String rightAlias):
+private Joined Joined(TableName leftTableName):
 {
-	List<ModelKeyMap> keyMaps = FastList.newInstance();
-	ModelKeyMap keyMap;
+	Boolean isOptional;
+	Joined joined = null;
+}
+{
+	isOptional=Joiner() joined=JoinedRest(isOptional, leftTableName)
+	{ return joined; }
+}
+
+private Joined JoinedRest(boolean isOptional, TableName leftTableName):
+{
+	TableName rightTableName;
+	List<KeyMap> keyMaps;
+	Joined joined = null;
+}
+{
+	rightTableName=TableName()
+	keyMaps=KeyMaps(leftTableName.getAlias(), rightTableName.getAlias())
+	( joined=Joined(rightTableName) )?
+	{ return new Joined(isOptional, rightTableName, keyMaps, joined); }
+}
+
+private List<KeyMap> KeyMaps(String leftAlias, String rightAlias):
+{
+	List<KeyMap> keyMaps = FastList.newInstance();
 	String n;
 }
 {
 	(
 		<ON>
-		keyMap=KeyMap(leftAlias, rightAlias) { keyMaps.add(keyMap); }
-		( <AND> keyMap=KeyMap(leftAlias, rightAlias) { keyMaps.add(keyMap); } )*
+		KeyMap(keyMaps, leftAlias, rightAlias)
+		( <AND> KeyMap(keyMaps, leftAlias, rightAlias) )*
 	|
 		<USING>
-		n=NamePart() { keyMaps.add(new ModelKeyMap(n, n)); }
-		( <COMMA> n=NamePart() { keyMaps.add(new ModelKeyMap(n, n)); } )*
+		n=NamePart() { keyMaps.add(new KeyMap(n, n)); }
+		( <COMMA> n=NamePart() { keyMaps.add(new KeyMap(n, n)); } )*
 	)
 	{ return keyMaps; }
 }
 
-private ModelKeyMap KeyMap(String leftAlias, String rightAlias):
+private void KeyMap(List<KeyMap> keyMaps, String leftAlias, String rightAlias):
 {
 	String alias1, field1;
 	String alias2, field2;
-	EntityComparisonOperator op;
 }
 {
 	alias1=NamePart() <PERIOD> field1=NamePart()
-	op=ComparisonOperator()
+	<EQUALS>
 	alias2=NamePart() <PERIOD> field2=NamePart()
 	{
-		if (op != EntityOperator.EQUALS) throw new IllegalArgumentException(op + " not supported");
 		if (alias1.equals(leftAlias)) {
 			if (!alias2.equals(rightAlias)) throw new IllegalArgumentException("invalid right alias(" + alias2 + "), expected(" + rightAlias + ")");
-			return new ModelKeyMap(field1, field2);
+			keyMaps.add(new KeyMap(field1, field2));
 		} else if (alias1.equals(rightAlias)) {
 			if (!alias2.equals(leftAlias)) throw new IllegalArgumentException("invalid left alias(" + alias2 + "), expected(" + leftAlias + ")");
-			return new ModelKeyMap(field2, field1);
+			keyMaps.add(new KeyMap(field2, field1));
 		} else {
 			throw new IllegalArgumentException("invalid aliases, expected(" + leftAlias + " or " + rightAlias + ")");
 		}
 	}
 }
 
-private String TableName(DynamicViewEntity dve):
+private TableName TableName():
 {
-	String name, alias = null;
+	String tableName, alias = null;
 }
 {
-	name=NamePart() ( (<AS>)? alias=NamePart() )?
-	{
-		if (alias == null) alias = name;
-		dve.addMemberEntity(alias, name);
-		return alias;
-	}
+	tableName=NamePart()
+	( (<AS>)? alias=NamePart() )?
+	{ return new TableName(tableName, alias); }
 }
 
 private Boolean Joiner():
@@ -293,114 +498,90 @@
 |	<JOIN> { return Boolean.FALSE; }
 }
 
-private void FieldDefs(DynamicViewEntity dve):
-{}
-{
-	FieldDef(dve) ( <COMMA> FieldDef(dve) )*
-}
-
-private String AggregateFunction():
-{}
-{
-	<AGGREGATE_FUNCTION> { return getToken(0).image.toLowerCase(); }
-}
-
-private void FieldDef(DynamicViewEntity dve):
+private void FieldDef(Map<String, FieldDef> fieldDefs, List<FieldAll> fieldAlls):
 {
-	List<String> fieldUse;
-	String tableAlias, fieldName, fieldAlias = null, function;
-	ComplexAliasMember complexAlias;
+	StaticValue v;
+	String n, fieldAlias = null, fieldName, exc;
+	FieldDef def;
+	List<String> excludeList = FastList.newInstance();
 }
 {
-	LOOKAHEAD(4) tableAlias=NamePart() <PERIOD>
 	(
-		<STAR> { dve.addAliasAll(tableAlias, null); }
-	|	fieldName=NamePart() ( <AS> fieldAlias=NamePart() )? {
-			if (fieldAlias == null) {
-				dve.addAlias(tableAlias, fieldName);
-			} else {
-				dve.addAlias(tableAlias, fieldAlias, fieldName, null, null, null, null);
-			}
-		}
-	)
-|	LOOKAHEAD(6) function=AggregateFunction()
-	<OPEN_PAREN>
-	tableAlias=NamePart() <PERIOD> fieldName=NamePart()
-	<CLOSE_PAREN>
-	( <AS> fieldAlias=NamePart() )? {
-		if (fieldAlias == null) {
-			dve.addAlias(tableAlias, fieldName, null, null, null, null, function);
-		} else {
-			dve.addAlias(tableAlias, fieldAlias, fieldName, null, null, null, function);
-		}
-	}
-|	complexAlias=ComplexAliasMember() <AS> fieldAlias=NamePart() {
-		dve.addAlias(null, fieldAlias, null, null, null, null, null, complexAlias);
+		n=NamePart() (
+			<PERIOD> (
+				<STAR>
+				(
+					<EXCLUDE> <OPEN_PAREN>
+					exc=NamePart() { excludeList.add(exc); }
+					( <COMMA> exc=NamePart() { excludeList.add(exc); } )*
+					<CLOSE_PAREN>
+				)?
+				{ fieldAlls.add(new FieldAll(n, excludeList)); return; }
+			| fieldName=NamePart() ( <AS> fieldAlias=NamePart() )? { def = new FieldDefValue(new FieldValue(n, fieldName), fieldAlias); }
+			)
+		|	v=FunctionCallRest(n) <AS> fieldAlias=NamePart() { def = new FieldDefValue(v, fieldAlias); }
+		|	( <AS> fieldAlias=NamePart() )? { def = new FieldDefFieldValue(new FieldValue(null, n), fieldAlias); }
+		)
+	|	v=MathValue() <AS> fieldAlias=NamePart() { def = new FieldDefValue(v, fieldAlias); }
+	) {
+		if (fieldDefs.containsKey(def.getAlias())) throw new IllegalArgumentException("duplicate alias(" + def.getAlias() + ")");
+		fieldDefs.put(def.getAlias(), def);
 	}
 }
 
-private ComplexAliasMember ComplexAlias():
+private StaticValue MathValue():
 {
-	List<ComplexAliasMember> list = FastList.newInstance();
-	ComplexAliasMember member;
+	StaticValue v;
+	List<StaticValue> values = FastList.newInstance();
 	String operator = null, newOperator;
 }
 {
 	<OPEN_PAREN>
-		member=ComplexAliasMember() { list.add(member); }
+		v=StaticValue() { values.add(v); }
 		(
-			( <AND> | <OR> ) { newOperator = getToken(0).image.toLowerCase(); }
-			member=ComplexAliasMember() {
+			newOperator=MathOperator()
+			v=StaticValue() {
 				if (operator == null) {
 					operator = newOperator;
 				} else if (!newOperator.equals(operator)) {
 					throw new IllegalArgumentException("Different operators in complex alias(" + operator + ":" + newOperator + ")");
 				}
-				list.add(member);
+				values.add(v);
 			}
 		)*
 	<CLOSE_PAREN>
 	{
-		if (list.size() == 1) return list.get(0);
-		ComplexAlias complexAlias = new ComplexAlias(operator);
-		complexAlias.addAllComplexAliasMembers(list);
-		return complexAlias;
+		if (values.size() == 1) return values.get(0);
+		return new MathValue(operator, values);
 	}
 }
 
-private ComplexAliasMember ComplexAliasMember():
+private FunctionCall FunctionCallRest(String name):
 {
-	ComplexAliasMember member;
+	Value arg;
+	List<Value> args = FastList.newInstance();
 }
 {
-	member=ComplexAlias() { return member; }
-|	member=ComplexAliasField() { return member; }
+	<OPEN_PAREN>
+	(
+		arg=Value() { args.add(arg); }
+		( <COMMA> arg=Value() { args.add(arg); } )*
+	) ?
+	<CLOSE_PAREN>
+	{ return new FunctionCall(name, args); }
 }
 
-private ComplexAliasMember ComplexAliasField():
+private StaticValue StaticValue():
 {
-	String function = null, tableName, fieldName;
-	Object dflt = null;
+	String n;
+	StaticValue v;
 }
 {
-	(
-		function=AggregateFunction() <OPEN_PAREN> (
-			<COALESCE> <OPEN_PAREN>
-				tableName=NamePart() <PERIOD> fieldName=NamePart()
-				<COMMA>
-				dflt=ConstantValue()
-			<CLOSE_PAREN>
-		|	tableName=NamePart() <PERIOD> fieldName=NamePart()
-		) <CLOSE_PAREN>
-	|	<COALESCE> <OPEN_PAREN>
-			tableName=NamePart() <PERIOD> fieldName=NamePart()
-			<COMMA>
-			dflt=ConstantValue()
-		<CLOSE_PAREN>
-	|	tableName=NamePart() <PERIOD> fieldName=NamePart()
-	) {
-		return new ComplexAliasField(tableName, fieldName, dflt != null ? dflt.toString() : null, function);
-	}
+	n=NamePart() (
+		v=FunctionCallRest(n) { return v; }
+	| v=FieldValue(n) { return v; }
+	)
+|	v=MathValue() { return v; }
 }
 
 private String NamePart():
@@ -439,14 +620,15 @@
 	{ return list; }
 }
 
-private EntityConditionValue FieldUse():
+private FieldValue FieldValue(String fieldName):
 {
-	String tableAlias = null, fieldName, s;
+	String tableAlias = null, s;
 }
 {
-	s=NamePart() { fieldName = s; }
 	( <PERIOD> s=NamePart() { tableAlias = fieldName; fieldName = s; } )?
-	{ return EntityFieldValue.makeFieldValue(fieldName, tableAlias, null, null); }
+	{
+		return new FieldValue(tableAlias, fieldName);
+	}
 }
 
 private List<String> OrderByList():
@@ -489,100 +671,103 @@
 	}
 }
 
-private Object Expression():
+private Value Value():
 {
-	EntityConditionValue ecv;
-	Object v;
+	String n;
+	Value v;
+	int i;
+	String s;
 }
 {
-	ecv=FieldUse() { return ecv; }
-|	v=ConstantValue() { return v; }
+	n=NamePart() (
+		v=FunctionCallRest(n) { return v; }
+	|	v=FieldValue(n) { return v; }
+	)
+|	i=Integer() { return new NumberValue<Integer>(i); }
+|	s=SQuoted() { return new StringValue(s); }
 }
 
-private Object ConstantValue():
-{
-	String s;
-	int i;
-}
+private Condition ConditionExpression():
+{ Condition c; }
 {
-	i=Integer() { return i; }
-|	s=SQuoted() { return s; }
+	c=OrExpression() { return c; }
 }
 
-public EntityCondition EntityCondition():
-{ EntityCondition ec; }
+private Condition AndExpression():
 {
-	ec=ConditionExpression() <EOF> { return ec; }
+	List<Condition> list = FastList.newInstance();
+	Condition c;
 }
-
-private EntityCondition ConditionExpression():
-{ EntityCondition ec; }
 {
-	ec=OrExpression() { return ec; }
+	c=BooleanExpression() { list.add(c); }
+        ( <AND> c=BooleanExpression() { list.add(c); } )*
+	{ return list.size() == 1 ? list.get(0) : new ConditionList(Joiner.AND, list); }
 }
 
-private EntityCondition AndExpression():
+private Condition OrExpression():
 {
-	List<EntityCondition> list = FastList.newInstance();
-	EntityCondition ec;
+	List<Condition> list = FastList.newInstance();
+	Condition c;
 }
 {
-	ec=BooleanExpression() { list.add(ec); }
-        ( <AND> ec=BooleanExpression() { list.add(ec); } )*
-	{
-		if (list.size() == 1) return list.get(0);
-		return EntityCondition.makeCondition(list, EntityOperator.AND);
-	}
+	c=AndExpression() { list.add(c); }
+        ( <OR> c=AndExpression() { list.add(c); } )*
+	{ return list.size() == 1 ? list.get(0) : new ConditionList(Joiner.OR, list); }
 }
 
-private EntityCondition OrExpression():
+private Value RightValue():
 {
-	List<EntityCondition> list = FastList.newInstance();
-	EntityCondition ec;
+	Value v;
 }
 {
-	ec=AndExpression() { list.add(ec); }
-        ( <OR> ec=AndExpression() { list.add(ec); } )*
-	{
-		if (list.size() == 1) return list.get(0);
-		return EntityCondition.makeCondition(list, EntityOperator.OR);
-	}
+	v=Value() { return v; }
+|	v=ParameterValue() { return v; }
 }
 
-private Object RightExpression(EntityComparisonOperator op):
-{
-	Object v;
-	List<Object> list;
-}
+private ParameterValue ParameterValue():
+{}
 {
-	LOOKAHEAD({ op == EntityOperator.BETWEEN }) { list = FastList.newInstance(); }
-	v=Expression() { list.add(v); }
-	<AND>
-	v=Expression() { list.add(v); }
-	{ return list; }
-|	v=Expression() { return v; }
-|	<OPEN_PAREN> { list = FastList.newInstance(); }
-	v=Expression() { list.add(v); }
-	( <COMMA> v=Expression() { list.add(v); } )*
-	<CLOSE_PAREN>
-	{ return list; }
+	<PARAMETER> { return new ParameterValue(getToken(0).image.substring(1)); }
 }
 
-private EntityCondition BooleanExpression():
+private Condition BooleanExpression():
 {
-	Object v1, v2;
-	EntityComparisonOperator op;
-	EntityCondition ec;
+	Value v1, v2, v;
+	String op;
+	Condition c;
+	List<Value> list = FastList.newInstance();
+}
+{
+	v1=Value() (
+		<BETWEEN>
+		v=RightValue() { list.add(v); }
+		<AND>
+		v=RightValue() { list.add(v); }
+		{ v2 = new ListValue(list); op = "between"; }
+	|	op=ComparisonOperator() (
+			v2=RightValue()
+		|	<OPEN_PAREN>
+			v=RightValue() { list.add(v); }
+			( <COMMA> v=RightValue() { list.add(v); } )*
+			<CLOSE_PAREN>
+			{ v2 = new ListValue(list); }
+		)
+	)
+	{ return new BooleanCondition(v1, op, v2); }
+|	<OPEN_PAREN> c=ConditionExpression() <CLOSE_PAREN> { return c; }
 }
+
+private String ComparisonOperator():
+{}
 {
-	v1=Expression() op=ComparisonOperator() v2=RightExpression(op)
-	{ return EntityCondition.makeCondition(v1, op, v2); }
-|	<OPEN_PAREN> ec=ConditionExpression() <CLOSE_PAREN> { return ec; }
+	( <TEXT> )+ { return getToken(0).image; }
+|	<NAME> { return getToken(0).image; }
+|	<EQUALS> { return getToken(0).image.toLowerCase(); }
 }
 
-private EntityComparisonOperator ComparisonOperator():
+private String MathOperator():
 {}
 {
-	( <TEXT> )+ { return EntityOperator.lookupComparison(getToken(0).image); }
-|	<NAME> { return EntityOperator.lookupComparison(getToken(0).image); }
+	( <TEXT> )+ { return getToken(0).image.toLowerCase(); }
+|	<NAME> { return getToken(0).image.toLowerCase(); }
 }

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Planner.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Planner.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Planner.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Planner.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+public interface Planner<P extends Planner<P, D, I, S, U, V>, D extends DeletePlan<D>, I extends InsertPlan<I>, S extends SelectPlan<S>, U extends UpdatePlan<U>, V extends ViewPlan<V>> {
+    D plan(SQLDelete<?> deleteStatement);
+    I plan(SQLInsert<?> insertStatement);
+    S plan(SQLSelect<?> selectStatement);
+    U plan(SQLUpdate<?> updateStatement);
+    V plan(SQLView<?> viewStatement);
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Relation.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Relation.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Relation.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Relation.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.ofbiz.base.util.Appender;
+
+public final class Relation implements Appender<StringBuilder>, Iterable<KeyMap> {
+    private final String type;
+    private final String title;
+    private final String entityName;
+    private final List<KeyMap> keyMaps;
+
+    public Relation(String type, String title, String entityName, List<KeyMap> keyMaps) {
+        this.type = type;
+        this.title = title;
+        this.entityName = entityName;
+        this.keyMaps = keyMaps;
+    }
+
+    public String getType() {
+        return type;
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public String getEntityName() {
+        return entityName;
+    }
+
+    public Iterator<KeyMap> iterator() {
+        return keyMaps.iterator();
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append("RELATION");
+        if (type != null) {
+            sb.append(' ').append(type);
+        }
+        if (title != null) {
+            sb.append(' ').append(title);
+        }
+        sb.append(' ').append(entityName);
+        sb.append(" ON");
+        for (int i = 0; i < keyMaps.size(); i++) {
+            sb.append(' ');
+            keyMaps.get(i).appendTo("cur", "other", sb);
+        }
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLDelete.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLDelete.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLDelete.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLDelete.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+public final class SQLDelete<P extends DeletePlan<P>> extends SQLStatement<SQLDelete<P>, P> {
+    private final Table table;
+    private final Condition whereCondition;
+
+    public SQLDelete(Table table, Condition whereCondition) {
+        this.table = table;
+        this.whereCondition = whereCondition;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <PP extends P> PP plan(Planner<?, ?, ?, ?, ?, ?> planner) {
+        return (PP) planner.plan(this);
+    }
+
+    public Table getTable() {
+        return table;
+    }
+
+    public Condition getWhereCondition() {
+        return whereCondition;
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append("DELETE FROM ");
+        table.getTableName().appendTo(sb);
+        if (table.getJoined() != null) {
+            sb.append(" USING");
+            table.getJoined().appendToRest(table.getTableName().getAlias(), sb);
+        }
+        if (whereCondition != null) {
+            sb.append(" WHERE ");
+            whereCondition.appendTo(sb);
+        }
+        sb.append(';');
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLInsert.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLInsert.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLInsert.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLInsert.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import java.util.List;
+
+import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilGenerics;
+
+public final class SQLInsert<P extends InsertPlan<P>> extends SQLStatement<SQLInsert<P>, P> {
+    private final TableName tableName;
+    private final InsertSource source;
+    private final List<String> columns;
+
+    public SQLInsert(TableName tableName, InsertSource source, List<String> columns) {
+        this.tableName = tableName;
+        this.source = source;
+        this.columns = columns;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <PP extends P> PP plan(Planner<?, ?, ?, ?, ?, ?> planner) {
+        return (PP) planner.plan(this);
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append("INSERT INTO ");
+        tableName.appendTo(sb);
+        if (columns != null && !columns.isEmpty()) {
+            sb.append(" (");
+            StringUtil.append(sb, columns, null, null, ", ");
+            sb.append(')');
+        }
+        sb.append(' ');
+        source.appendTo(sb);
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLPlan.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLPlan.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLPlan.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLPlan.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,24 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import java.util.Map;
+
+public abstract class SQLPlan<P extends SQLPlan<P>> {
+}

Copied: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLSelect.java (from r880823, ofbiz/trunk/framework/entity/src/org/ofbiz/entity/sql/SQLSelect.java)
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLSelect.java?p2=ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLSelect.java&p1=ofbiz/trunk/framework/entity/src/org/ofbiz/entity/sql/SQLSelect.java&r1=880823&r2=880835&rev=880835&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/sql/SQLSelect.java (original)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLSelect.java Mon Nov 16 16:31:32 2009
@@ -16,103 +16,121 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.ofbiz.entity.sql;
+package org.ofbiz.sql;
 
+import java.util.Collection;
+import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 import java.util.Map;
 
-import javolution.util.FastList;
-import javolution.util.FastMap;
+import org.ofbiz.base.util.StringUtil;
 
-import org.ofbiz.entity.Delegator;
-import org.ofbiz.entity.GenericEntityException;
-import org.ofbiz.entity.condition.EntityCondition;
-import org.ofbiz.entity.model.DynamicViewEntity;
-import org.ofbiz.entity.model.ModelKeyMap;
-import org.ofbiz.entity.util.EntityListIterator;
-
-public class SQLSelect {
-    private DynamicViewEntity dve;
-    private EntityCondition whereCondition;
-    private EntityCondition havingCondition;
-    private int offset = -1;
-    private int limit = -1;
-    private List<String> orderBy;
+public final class SQLSelect<P extends SelectPlan<P>> extends SQLStatement<SQLSelect<P>, P> implements InsertSource {
+    private final List<FieldAll> fieldAlls;
+    private final Map<String, FieldDef> fieldDefs;
+    private final Table table;
+    private final List<Relation> relations;
+    private final Condition whereCondition;
+    private final Condition havingCondition;
+    private final int offset;
+    private final int limit;
+    private final List<String> orderBy;
+    private final List<String> groupBy;
+
+    public SQLSelect(List<FieldAll> fieldAlls, Map<String, FieldDef> fieldDefs, Table table, List<Relation> relations, Condition whereCondition, Condition havingCondition, List<String> groupBy, List<String> orderBy, int offset, int limit) {
+        this.fieldAlls = fieldAlls;
+        this.fieldDefs = fieldDefs;
+        this.table = table;
+        this.relations = relations;
+        this.whereCondition = whereCondition;
+        this.havingCondition = havingCondition;
+        this.groupBy = groupBy;
+        this.orderBy = orderBy;
+        this.offset = offset;
+        this.limit = limit;
+    }
 
-    public EntityListIterator getEntityListIterator(Delegator delegator) throws GenericEntityException {
-        return delegator.findListIteratorByCondition(dve, whereCondition, havingCondition, null, orderBy, null);
+    @SuppressWarnings("unchecked")
+    public <PP extends P> PP plan(Planner<?, ?, ?, ?, ?, ?> planner) {
+        return (PP) planner.plan(this);
     }
 
-    void setDynamicViewEntity(DynamicViewEntity dve) {
-        this.dve = dve;
+    public Collection<FieldAll> getFieldAlls() {
+        return fieldAlls;
     }
 
-    public DynamicViewEntity getDynamicViewEntity() {
-        return dve;
+    public Collection<FieldDef> getFieldDefs() {
+        return fieldDefs.values();
     }
 
-    void setWhereCondition(EntityCondition whereCondition) {
-        this.whereCondition = whereCondition;
+    public Table getTable() {
+        return table;
     }
 
-    public EntityCondition getWhereCondition() {
-        return whereCondition;
+    public List<Relation> getRelations() {
+        return relations;
     }
 
-    void setHavingCondition(EntityCondition havingCondition) {
-        this.havingCondition = havingCondition;
+    public Condition getWhereCondition() {
+        return whereCondition;
     }
 
-    public EntityCondition getHavingCondition() {
+    public Condition getHavingCondition() {
         return havingCondition;
     }
 
-    void setOrderBy(List<String> orderBy) {
-        this.orderBy = orderBy;
+    public List<String> getGroupBy() {
+        return groupBy;
     }
 
     public List<String> getOrderBy() {
         return orderBy;
     }
 
-    void setOffset(int offset) {
-        this.offset = offset;
-    }
-
     public int getOffset() {
         return offset;
     }
 
-    void setLimit(int limit) {
-        this.limit = limit;
-    }
-
     public int getLimit() {
         return limit;
     }
 
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("dve=" + dve);
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append("SELECT");
+        StringUtil.appendTo(sb, fieldAlls, " ", null, ",");
+        if (!fieldAlls.isEmpty() && !fieldDefs.isEmpty()) {
+            sb.append(',');
+        }
+        StringUtil.appendTo(sb, fieldDefs.values(), " ", null, ",");
+        sb.append(" FROM ");
+        table.appendTo(sb);
+        if (!relations.isEmpty()) {
+            StringUtil.appendTo(sb, relations, " ", null, ",");
+        }
         if (whereCondition != null) {
-            if (sb.length() > 0) sb.append(", ");
-            sb.append("where=(").append(whereCondition).append(")");
+            sb.append(" WHERE ");
+            whereCondition.appendTo(sb);
         }
         if (havingCondition != null) {
-            if (sb.length() > 0) sb.append(", ");
-            sb.append("having=(").append(havingCondition).append(")");
+            sb.append(" HAVING ");
+            havingCondition.appendTo(sb);
         }
         if (offset != -1) {
-            if (sb.length() > 0) sb.append(", ");
-            sb.append("offset=").append(offset);
+            sb.append(" OFFSET ").append(offset);
         }
         if (limit != -1) {
-            if (sb.length() > 0) sb.append(", ");
-            sb.append("limit=").append(limit);
+            sb.append(" LIMIT ").append(limit);
+        }
+        if (groupBy != null) {
+            sb.append(" GROUP BY ");
+            StringUtil.append(sb, groupBy, null, null, ", ");
+        }
+        if (orderBy != null) {
+            sb.append(" ORDER BY ");
+            StringUtil.append(sb, orderBy, null, null, ", ");
         }
-        sb.append("]");
-        sb.insert(0, "[").insert(0, super.toString());
-        return sb.toString();
+        sb.append(';');
+        return sb;
     }
 }
-/* JavaCC - OriginalChecksum=49309c1a721b16d029f160d2568a03bc (do not edit this line) */

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLStatement.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLStatement.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLStatement.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLStatement.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import org.ofbiz.base.util.Appender;
+
+public abstract class SQLStatement<S extends SQLStatement<S, P>, P extends SQLPlan<P>> implements Appender<StringBuilder> {
+    public abstract <PP extends P> PP plan(Planner<?, ?, ?, ?, ?, ?> planner);
+
+    public String toString() {
+        return appendTo(new StringBuilder()).toString();
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLUpdate.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLUpdate.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLUpdate.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLUpdate.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.ofbiz.base.util.StringUtil;
+
+public final class SQLUpdate<P extends UpdatePlan<P>> extends SQLStatement<SQLUpdate<P>, P> {
+    private final Table table;
+    private final List<SetField> setFields;
+    private final Condition whereCondition;
+
+    public SQLUpdate(Table table, List<SetField> setFields, Condition whereCondition) {
+        this.table = table;
+        this.setFields = setFields;
+        this.whereCondition = whereCondition;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <PP extends P> PP plan(Planner<?, ?, ?, ?, ?, ?> planner) {
+        return (PP) planner.plan(this);
+    }
+
+    public Table getTable() {
+        return table;
+    }
+
+    public List<SetField> getSetFields() {
+        return setFields;
+    }
+
+    public Condition getWhereCondition() {
+        return whereCondition;
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append("UPDATE ");
+        table.getTableName().appendTo(sb);
+        // n=4;1+(n-1)*2+3+(n-1)*2+1;3*n+(n-1)*2
+        // 17
+        // 18
+        sb.append(" SET ");
+        if (setFields.size() <= 3) {
+            StringUtil.appendTo(sb, setFields, null, null, ", ");
+        } else {
+            Iterator<SetField> it = setFields.iterator();
+            sb.append('(');
+            while (it.hasNext()) {
+                SetField setField = it.next();
+                sb.append(setField.getName());
+                if (it.hasNext()) {
+                    sb.append(", ");
+                }
+            }
+            sb.append(") = (");
+            it = setFields.iterator();
+            while (it.hasNext()) {
+                SetField setField = it.next();
+                setField.getValue().appendTo(sb);
+                if (it.hasNext()) {
+                    sb.append(", ");
+                }
+            }
+            sb.append(')');
+            it = setFields.iterator();
+        }
+        if (table.getJoined() != null) {
+            sb.append(" FROM ");
+            table.getJoined().appendToRest(table.getTableName().getAlias(), sb);
+        }
+        if (whereCondition != null) {
+            sb.append(" WHERE ");
+            whereCondition.appendTo(sb);
+        }
+        sb.append(';');
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLView.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLView.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLView.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SQLView.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import java.util.ListIterator;
+
+public final class SQLView<P extends ViewPlan<P>> extends SQLStatement<SQLView<P>, P> {
+    private final String name;
+    private final SQLSelect sqlSelect;
+
+    public SQLView(String name, SQLSelect sqlSelect) {
+        this.name = name;
+        this.sqlSelect = sqlSelect;
+    }
+
+    @SuppressWarnings("unchecked")
+    public <PP extends P> PP plan(Planner<?, ?, ?, ?, ?, ?> planner) {
+        return (PP) planner.plan(this);
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public SQLSelect getSelect() {
+        return sqlSelect;
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append("CREATE VIEW ").append(name).append(" AS ");
+        sqlSelect.appendTo(sb);
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SelectPlan.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SelectPlan.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SelectPlan.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SelectPlan.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+public abstract class SelectPlan<P extends SelectPlan<P>> extends SQLPlan<P> {
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SetField.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SetField.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SetField.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/SetField.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import org.ofbiz.base.util.Appender;
+
+public final class SetField implements Appender<StringBuilder> {
+    private final String name;
+    private final Value value;
+
+    public SetField(String name, Value value) {
+        this.name = name;
+        this.value = value;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public Value getValue() {
+        return value;
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append(name).append(" = ");
+        value.appendTo(sb);
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/StaticValue.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/StaticValue.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/StaticValue.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/StaticValue.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,23 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+public abstract class StaticValue extends Value {
+    public abstract String getDefaultName();
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/StringValue.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/StringValue.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/StringValue.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/StringValue.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+public final class StringValue extends ConstantValue {
+    private final String str;
+
+    public StringValue(String str) {
+        this.str = str;
+    }
+
+    public String getString() {
+        return str;
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append('\'').append(str.replaceAll("'", "''")).append('\'');
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Table.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Table.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Table.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Table.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import org.ofbiz.base.util.Appender;
+
+public final class Table implements Appender<StringBuilder> {
+    private final TableName tableName;
+    private final Joined joined;
+
+    public Table(TableName tableName) {
+        this(tableName, null);
+    }
+
+    public Table(TableName tableName, Joined joined) {
+        this.tableName = tableName;
+        this.joined = joined;
+    }
+
+    public TableName getTableName() {
+        return tableName;
+    }
+
+    public Joined getJoined() {
+        return joined;
+    }
+
+    public String toString() {
+        return appendTo(new StringBuilder()).toString();
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        tableName.appendTo(sb);
+        if (joined != null) {
+            joined.appendTo(tableName.getAlias(), sb);
+        }
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/TableName.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/TableName.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/TableName.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/TableName.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,51 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import org.ofbiz.base.util.Appender;
+
+public final class TableName implements Appender<StringBuilder> {
+    private final String tableName;
+    private final String alias;
+
+    public TableName(String tableName, String alias) {
+        this.tableName = tableName;
+        this.alias = alias != null ? alias : tableName;
+    }
+
+    public final String getTableName() {
+        return tableName;
+    }
+
+    public final String getAlias() {
+        return alias;
+    }
+
+    public String toString() {
+        return appendTo(new StringBuilder()).toString();
+    }
+
+    public StringBuilder appendTo(StringBuilder sb) {
+        sb.append(tableName);
+        if (!alias.equals(tableName)) {
+            sb.append(' ').append(alias);
+        }
+        return sb;
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/UpdatePlan.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/UpdatePlan.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/UpdatePlan.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/UpdatePlan.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+public abstract class UpdatePlan<P extends UpdatePlan<P>> extends SQLPlan<P> {
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Value.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Value.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Value.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/Value.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+import org.ofbiz.base.util.Appender;
+
+public abstract class Value implements Appender<StringBuilder> {
+    public String toString() {
+        return appendTo(new StringBuilder()).toString();
+    }
+}

Added: ofbiz/trunk/framework/sql/src/org/ofbiz/sql/ViewPlan.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/sql/src/org/ofbiz/sql/ViewPlan.java?rev=880835&view=auto
==============================================================================
--- ofbiz/trunk/framework/sql/src/org/ofbiz/sql/ViewPlan.java (added)
+++ ofbiz/trunk/framework/sql/src/org/ofbiz/sql/ViewPlan.java Mon Nov 16 16:31:32 2009
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.ofbiz.sql;
+
+public abstract class ViewPlan<P extends ViewPlan<P>> extends SQLPlan<P> {
+}

Modified: ofbiz/trunk/framework/webslinger/websites/webslinger/www/TestSQL.groovy
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/webslinger/websites/webslinger/www/TestSQL.groovy?rev=880835&r1=880834&r2=880835&view=diff
==============================================================================
--- ofbiz/trunk/framework/webslinger/websites/webslinger/www/TestSQL.groovy (original)
+++ ofbiz/trunk/framework/webslinger/websites/webslinger/www/TestSQL.groovy Mon Nov 16 16:31:32 2009
@@ -4,28 +4,28 @@
 response.contentType = 'text/html'
 def delegator = request.delegator
 
-def ec1 = SQLUtil.parseCondition("partyId = 'foo' AND partyTypeId = 'PARTY_GROUP'")
+/*
+def ec1 = SQLUtil.parseCondition("partyId = 'foo' AND partyTypeId = 'PARTY_GROUP' OR sequenceNum IN (1, 2) or foo BETWEEN 'a' and 'b'")
+println("ec1=$ec1")
 response.writer.println("ec1=$ec1<br />")
 def ec2 = SQLUtil.parseCondition(ec1.toString())
+println("ec2=$ec2")
 response.writer.println("ec2=$ec2<br />")
 //return
+*/
 
 def sql = """
-select
+SELECT
     a.partyId,
-    a.partyTypeId as type,
-	b.firstName,
-	b.lastName,
-    c.groupName
+    a.partyTypeId AS type,
+    COALESCE(b.firstName, '') AS firstName,
+    COALESCE(b.lastName, '') AS lastName,
+    COALESCE(c.groupName, '') AS groupName
 FROM
 	Party a LEFT JOIN Person b USING partyId LEFT JOIN PartyGroup c USING partyId
 RELATION TYPE one Party USING partyId
-RELATION TYPE one Person USING partyId
-RELATION TYPE one PartyGroup USING partyId
 WHERE
     partyId = 'admin'
-ORDER BY
-    lastName
 ;
 """
 def sqlSelect = SQLUtil.parseSelect(sql)
@@ -37,10 +37,8 @@
         def gv;
         while ((gv = eli.next()) != null) {
             response.writer.println("gv=$gv<br />")
-            def party = gv.getRelatedOneCache('Party')
-            def person = gv.getRelatedOneCache('Person')
-            response.writer.println("\tparty=$party<br />")
-            response.writer.println("\tperson=$person<br />")
+            def party = gv.getRelatedOneCache('Party'); response.writer.println("\tparty=$party<br />")
+            //def person = gv.getRelatedOneCache('Person'); response.writer.println("\tperson=$person<br />")
         }
     } finally {
         if (eli != null) eli.close()