Merge lp:~mmcm/akiban-sql-parser/more-node-to-string into lp:~akiban-technologies/akiban-sql-parser/trunk

Proposed by Mike McMahon
Status: Merged
Approved by: Nathan Williams
Approved revision: 305
Merged at revision: 302
Proposed branch: lp:~mmcm/akiban-sql-parser/more-node-to-string
Merge into: lp:~akiban-technologies/akiban-sql-parser/trunk
Diff against target: 367 lines (+209/-4)
7 files modified
src/main/java/com/akiban/sql/parser/LeftRightFuncOperatorNode.java (+2/-2)
src/main/java/com/akiban/sql/parser/TrimOperatorNode.java (+1/-1)
src/main/java/com/akiban/sql/parser/UnaryArithmeticOperatorNode.java (+1/-1)
src/main/java/com/akiban/sql/unparser/NodeToString.java (+188/-0)
src/test/java/com/akiban/sql/unparser/NodeToStringTest.java (+3/-0)
src/test/resources/com/akiban/sql/unparser/select-15.expected (+1/-0)
src/test/resources/com/akiban/sql/unparser/select-15.sql (+13/-0)
To merge this branch: bzr merge lp:~mmcm/akiban-sql-parser/more-node-to-string
Reviewer Review Type Date Requested Status
Thomas Jones-Low Needs Fixing
Nathan Williams Approve
Review via email: mp+177704@code.launchpad.net

Description of the change

Add unparser support for missing Value-like nodes.

See switch additions for which node types these are and new test for how those manifest in the parser.

To post a comment you must log in.
Revision history for this message
Nathan Williams (nwilliams) wrote :

Looks good.

review: Approve
Revision history for this message
Thomas Jones-Low (tjoneslo) wrote :

There were 2 failures during build/test:

* job sql-parser-build failed at build number 296: http://sneezy.softstart.com:8080/job/sql-parser-build/296/

* view must-pass failed: sql-parser-build is red

review: Needs Fixing

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/main/java/com/akiban/sql/parser/LeftRightFuncOperatorNode.java'
2--- src/main/java/com/akiban/sql/parser/LeftRightFuncOperatorNode.java 2013-05-08 22:13:20 +0000
3+++ src/main/java/com/akiban/sql/parser/LeftRightFuncOperatorNode.java 2013-07-30 22:21:25 +0000
4@@ -36,11 +36,11 @@
5 switch(nodeType)
6 {
7 case NodeTypes.LEFT_FN_NODE:
8- op = "getLeft";
9+ op = "LEFT";
10 method = "getLeft";
11 break;
12 case NodeTypes.RIGHT_FN_NODE:
13- op = "getRight";
14+ op = "RIGHT";
15 method = "getRight";
16 break;
17 default:
18
19=== modified file 'src/main/java/com/akiban/sql/parser/TrimOperatorNode.java'
20--- src/main/java/com/akiban/sql/parser/TrimOperatorNode.java 2013-05-08 22:13:20 +0000
21+++ src/main/java/com/akiban/sql/parser/TrimOperatorNode.java 2013-07-30 22:21:25 +0000
22@@ -31,7 +31,7 @@
23 case TRIM:
24 case RTRIM: super.init(trimSource,
25 trimChar,
26- "TRIM",
27+ optype.name(),
28 optype.name().toLowerCase(),
29 ValueClassName.StringDataValue,
30 ValueClassName.StringDataValue);
31
32=== modified file 'src/main/java/com/akiban/sql/parser/UnaryArithmeticOperatorNode.java'
33--- src/main/java/com/akiban/sql/parser/UnaryArithmeticOperatorNode.java 2013-05-08 22:13:20 +0000
34+++ src/main/java/com/akiban/sql/parser/UnaryArithmeticOperatorNode.java 2013-07-30 22:21:25 +0000
35@@ -52,7 +52,7 @@
36 PLUS("+", "plus"),
37 MINUS("-", "minus"),
38 SQRT("SQRT", "sqrt"),
39- ABSOLUTE("ABS/ABSVAL", "absolute");
40+ ABSOLUTE("ABS", "absolute");
41
42 String operator, methodName;
43 OperatorType(String operator, String methodName) {
44
45=== modified file 'src/main/java/com/akiban/sql/unparser/NodeToString.java'
46--- src/main/java/com/akiban/sql/unparser/NodeToString.java 2013-05-08 22:13:20 +0000
47+++ src/main/java/com/akiban/sql/unparser/NodeToString.java 2013-07-30 22:21:25 +0000
48@@ -131,7 +131,10 @@
49 case NodeTypes.BINARY_DIVIDE_OPERATOR_NODE:
50 case NodeTypes.BINARY_DIV_OPERATOR_NODE:
51 case NodeTypes.BINARY_MINUS_OPERATOR_NODE:
52+ case NodeTypes.MOD_OPERATOR_NODE:
53 return binaryArithmeticOperatorNode((BinaryArithmeticOperatorNode)node);
54+ case NodeTypes.BINARY_BIT_OPERATOR_NODE:
55+ return binaryBitOperatorNode((BinaryBitOperatorNode)node);
56 case NodeTypes.CONCATENATION_OPERATOR_NODE:
57 return concatenationOperatorNode((ConcatenationOperatorNode)node);
58 case NodeTypes.NOT_NODE:
59@@ -141,10 +144,39 @@
60 return isNullNode((IsNullNode)node);
61 case NodeTypes.IS_NODE:
62 return isNode((IsNode)node);
63+ case NodeTypes.ABSOLUTE_OPERATOR_NODE:
64+ case NodeTypes.SQRT_OPERATOR_NODE:
65+ return unaryArithmeticOperatorNode((UnaryArithmeticOperatorNode)node);
66+ case NodeTypes.UNARY_PLUS_OPERATOR_NODE:
67+ case NodeTypes.UNARY_MINUS_OPERATOR_NODE:
68+ return unaryPrefixOperatorNode((UnaryArithmeticOperatorNode)node);
69+ case NodeTypes.UNARY_BITNOT_OPERATOR_NODE:
70+ return unaryBitOperatorNode((UnaryBitOperatorNode)node);
71 case NodeTypes.UNARY_DATE_TIMESTAMP_OPERATOR_NODE:
72 return unaryDateTimestampOperatorNode((UnaryDateTimestampOperatorNode)node);
73+ case NodeTypes.TIMESTAMP_OPERATOR_NODE:
74+ return timestampOperatorNode((TimestampOperatorNode)node);
75+ case NodeTypes.EXTRACT_OPERATOR_NODE:
76+ return extractOperatorNode((ExtractOperatorNode)node);
77+ case NodeTypes.CHAR_LENGTH_OPERATOR_NODE:
78+ return lengthOperatorNode((LengthOperatorNode)node);
79+ case NodeTypes.OCTET_LENGTH_OPERATOR_NODE:
80+ return octetLengthOperatorNode((OctetLengthOperatorNode)node);
81+ case NodeTypes.RIGHT_FN_NODE:
82+ case NodeTypes.LEFT_FN_NODE:
83+ return leftRightFuncOperatorNode((LeftRightFuncOperatorNode)node);
84+ case NodeTypes.SIMPLE_STRING_OPERATOR_NODE:
85+ return simpleStringOperatorNode((SimpleStringOperatorNode)node);
86 case NodeTypes.LIKE_OPERATOR_NODE:
87 return likeEscapeOperatorNode((LikeEscapeOperatorNode)node);
88+ case NodeTypes.LOCATE_FUNCTION_NODE:
89+ case NodeTypes.SUBSTRING_OPERATOR_NODE:
90+ return ternaryOperatorNode((TernaryOperatorNode)node);
91+ case NodeTypes.TIMESTAMP_ADD_FN_NODE:
92+ case NodeTypes.TIMESTAMP_DIFF_FN_NODE:
93+ return timestampFunctionNode((TernaryOperatorNode)node);
94+ case NodeTypes.TRIM_OPERATOR_NODE:
95+ return trimOperatorNode((TrimOperatorNode)node);
96 case NodeTypes.IN_LIST_OPERATOR_NODE:
97 return inListOperatorNode((InListOperatorNode)node);
98 case NodeTypes.ROW_CTOR_NODE:
99@@ -180,6 +212,8 @@
100 return constantNode((ConstantNode)node);
101 case NodeTypes.PARAMETER_NODE:
102 return parameterNode((ParameterNode)node);
103+ case NodeTypes.DEFAULT_NODE:
104+ return "DEFAULT";
105 case NodeTypes.USER_NODE:
106 return "USER";
107 case NodeTypes.CURRENT_USER_NODE:
108@@ -200,6 +234,12 @@
109 return currentDatetimeOperatorNode((CurrentDatetimeOperatorNode)node);
110 case NodeTypes.CAST_NODE:
111 return castNode((CastNode)node);
112+ case NodeTypes.EXPLICIT_COLLATE_NODE:
113+ return explicitCollateNode((ExplicitCollateNode)node);
114+ case NodeTypes.NEXT_SEQUENCE_NODE:
115+ return nextSequenceNode((NextSequenceNode)node);
116+ case NodeTypes.CURRENT_SEQUENCE_NODE:
117+ return currentSequenceNode((CurrentSequenceNode)node);
118 case NodeTypes.JAVA_TO_SQL_VALUE_NODE:
119 return javaToSQLValueNode((JavaToSQLValueNode)node);
120 case NodeTypes.SQL_TO_JAVA_VALUE_NODE:
121@@ -747,11 +787,26 @@
122 return infixBinary(node);
123 }
124
125+ protected String binaryBitOperatorNode(BinaryBitOperatorNode node)
126+ throws StandardException {
127+ return infixBinary(node);
128+ }
129+
130 protected String concatenationOperatorNode(ConcatenationOperatorNode node)
131 throws StandardException {
132 return infixBinary(node);
133 }
134
135+ protected String leftRightFuncOperatorNode(LeftRightFuncOperatorNode node)
136+ throws StandardException {
137+ return functionBinary(node);
138+ }
139+
140+ protected String simpleStringOperatorNode(SimpleStringOperatorNode node)
141+ throws StandardException {
142+ return functionUnary(node);
143+ }
144+
145 protected String notNode(NotNode node) throws StandardException {
146 return prefixUnary(node);
147 }
148@@ -760,11 +815,47 @@
149 return suffixUnary(node);
150 }
151
152+ protected String unaryArithmeticOperatorNode(UnaryArithmeticOperatorNode node)
153+ throws StandardException {
154+ return functionUnary(node);
155+ }
156+
157+ protected String unaryPrefixOperatorNode(UnaryArithmeticOperatorNode node)
158+ throws StandardException {
159+ return prefixUnary(node);
160+ }
161+
162+ protected String unaryBitOperatorNode(UnaryBitOperatorNode node)
163+ throws StandardException {
164+ return prefixUnary(node);
165+ }
166+
167+ protected String extractOperatorNode(ExtractOperatorNode node)
168+ throws StandardException {
169+ return node.getOperator().substring("EXTRACT ".length()).toUpperCase() + "(" +
170+ toString(node.getOperand()) + ")";
171+ }
172+
173 protected String unaryDateTimestampOperatorNode(UnaryDateTimestampOperatorNode node)
174 throws StandardException {
175 return functionUnary(node);
176 }
177
178+ protected String timestampOperatorNode(TimestampOperatorNode node)
179+ throws StandardException {
180+ return functionBinary(node);
181+ }
182+
183+ protected String lengthOperatorNode(LengthOperatorNode node)
184+ throws StandardException {
185+ return functionUnary(node);
186+ }
187+
188+ protected String octetLengthOperatorNode(OctetLengthOperatorNode node)
189+ throws StandardException {
190+ return functionUnary(node);
191+ }
192+
193 protected String isNode(IsNode node) throws StandardException {
194 StringBuilder str = new StringBuilder(maybeParens(node.getLeftOperand()));
195 str.append(" IS ");
196@@ -800,6 +891,81 @@
197 return like;
198 }
199
200+ protected String ternaryOperatorNode(TernaryOperatorNode node)
201+ throws StandardException {
202+ StringBuilder str = new StringBuilder(node.getOperator().toUpperCase());
203+ str.append("(");
204+ str.append(toString(node.getReceiver()));
205+ str.append(", ");
206+ str.append(toString(node.getLeftOperand()));
207+ if (node.getRightOperand() != null) {
208+ str.append(", ");
209+ str.append(toString(node.getRightOperand()));
210+ }
211+ return str.toString();
212+ }
213+
214+ protected String timestampFunctionNode(TernaryOperatorNode node)
215+ throws StandardException {
216+ String interval = toString(node.getReceiver());
217+ switch ((Integer)((ConstantNode)node.getReceiver()).getValue()) {
218+ case TernaryOperatorNode.YEAR_INTERVAL:
219+ interval = "YEAR";
220+ break;
221+ case TernaryOperatorNode.QUARTER_INTERVAL:
222+ interval = "QUARTER";
223+ break;
224+ case TernaryOperatorNode.MONTH_INTERVAL:
225+ interval = "MONTH";
226+ break;
227+ case TernaryOperatorNode.WEEK_INTERVAL:
228+ interval = "WEEK";
229+ break;
230+ case TernaryOperatorNode.DAY_INTERVAL:
231+ interval = "DAY";
232+ break;
233+ case TernaryOperatorNode.HOUR_INTERVAL:
234+ interval = "HOUR";
235+ break;
236+ case TernaryOperatorNode.MINUTE_INTERVAL:
237+ interval = "MINUTE";
238+ break;
239+ case TernaryOperatorNode.SECOND_INTERVAL:
240+ interval = "SECOND";
241+ break;
242+ case TernaryOperatorNode.FRAC_SECOND_INTERVAL:
243+ interval = "MICROSECOND>";
244+ break;
245+ }
246+ return node.getOperator().toUpperCase() + "(" +
247+ interval + ", " +
248+ toString(node.getLeftOperand()) + ", " +
249+ toString(node.getRightOperand()) + ")";
250+ }
251+
252+ protected String trimOperatorNode(TrimOperatorNode node)
253+ throws StandardException {
254+ if ((node.getRightOperand() instanceof ConstantNode) &&
255+ " ".equals(((ConstantNode)node.getRightOperand()).getValue())) {
256+ return node.getOperator().toUpperCase() + "(" +
257+ toString(node.getLeftOperand()) + ")";
258+ }
259+ else {
260+ StringBuilder str = new StringBuilder("TRIM(");
261+ if ("LTRIM".equals(node.getOperator()))
262+ str.append("LEADING");
263+ else if ("RTRIM".equals(node.getOperator()))
264+ str.append("TRAILING");
265+ else
266+ str.append("BOTH");
267+ str.append(" ");
268+ str.append(toString(node.getRightOperand()));
269+ str.append(" FROM ");
270+ str.append(toString(node.getLeftOperand()));
271+ return str.toString();
272+ }
273+ }
274+
275 protected String inListOperatorNode(InListOperatorNode node) throws StandardException {
276 return maybeParens(node.getLeftOperand()) +
277 " " + (node.isNegated() ? "NOT IN" : "IN") +
278@@ -880,6 +1046,12 @@
279 maybeParens(node.getRightOperand());
280 }
281
282+ protected String functionBinary(BinaryOperatorNode node) throws StandardException {
283+ return node.getOperator().toUpperCase() + "(" +
284+ toString(node.getLeftOperand()) + ", " +
285+ toString(node.getRightOperand()) + ")";
286+ }
287+
288 protected String functionCall(String functionName, ValueNodeList args)
289 throws StandardException {
290 return functionName + "(" + nodeList(args, true) + ")";
291@@ -946,6 +1118,22 @@
292 " AS " + node.getType().toString() + ")";
293 }
294
295+ protected String explicitCollateNode(ExplicitCollateNode node)
296+ throws StandardException {
297+ return maybeParens(node.getOperand()) +
298+ " COLLATE " + node.getCollation();
299+ }
300+
301+ protected String nextSequenceNode(NextSequenceNode node)
302+ throws StandardException {
303+ return "NEXT VALUE FOR " + toString(node.getSequenceName ());
304+ }
305+
306+ protected String currentSequenceNode(CurrentSequenceNode node)
307+ throws StandardException {
308+ return "CURRENT VALUE FOR " + toString(node.getSequenceName ());
309+ }
310+
311 protected String javaToSQLValueNode(JavaToSQLValueNode node)
312 throws StandardException {
313 return toString(node.getJavaValueNode());
314
315=== modified file 'src/test/java/com/akiban/sql/unparser/NodeToStringTest.java'
316--- src/test/java/com/akiban/sql/unparser/NodeToStringTest.java 2013-05-08 22:13:20 +0000
317+++ src/test/java/com/akiban/sql/unparser/NodeToStringTest.java 2013-07-30 22:21:25 +0000
318@@ -19,6 +19,7 @@
319 import com.akiban.sql.TestBase;
320
321 import com.akiban.sql.parser.SQLParser;
322+import com.akiban.sql.parser.SQLParserFeature;
323 import com.akiban.sql.parser.StatementNode;
324
325 import org.junit.Before;
326@@ -30,6 +31,7 @@
327
328 import java.io.File;
329 import java.util.Collection;
330+import java.util.EnumSet;
331
332 @RunWith(Parameterized.class)
333 public class NodeToStringTest extends TestBase implements TestBase.GenerateAndCheckResult
334@@ -45,6 +47,7 @@
335 public void before() throws Exception {
336 parser = new SQLParser();
337 unparser = new NodeToString();
338+ parser.getFeatures().addAll(EnumSet.of(SQLParserFeature.INFIX_BIT_OPERATORS));
339 }
340
341 @Parameters
342
343=== added file 'src/test/resources/com/akiban/sql/unparser/select-15.expected'
344--- src/test/resources/com/akiban/sql/unparser/select-15.expected 1970-01-01 00:00:00 +0000
345+++ src/test/resources/com/akiban/sql/unparser/select-15.expected 2013-07-30 22:21:25 +0000
346@@ -0,0 +1,1 @@
347+SELECT (ABS(- n)), (~ n), (n MOD 3), SQRT(n), CHAR_LENGTH(s), LENGTH(s), (LEFT(s, 3)), (RIGHT(s, 4)), UPPER(s), LOWER(s), (LOCATE(s, 'abc', 1), (LOCATE(s, 'xyz', 10), (SUBSTRING(s, 10), (SUBSTRING(s, 10, 3), LTRIM(s), (TRIM(TRAILING '!' FROM s), ((s || s) COLLATE en_us_ci), MONTH(d), (TIMESTAMP(d, '13:01:01')), (TIMESTAMPDIFF(DAY, d, CURRENT_TIMESTAMP)), (NEXT VALUE FOR seq), (CURRENT VALUE FOR seq) FROM t
348\ No newline at end of file
349
350=== added file 'src/test/resources/com/akiban/sql/unparser/select-15.sql'
351--- src/test/resources/com/akiban/sql/unparser/select-15.sql 1970-01-01 00:00:00 +0000
352+++ src/test/resources/com/akiban/sql/unparser/select-15.sql 2013-07-30 22:21:25 +0000
353@@ -0,0 +1,13 @@
354+SELECT abs(- n), ~n,
355+ mod(n, 3), sqrt(n),
356+ char_length(s), octet_length(s),
357+ left(s, 3), right(s, 4),
358+ upper(s), lower(s),
359+ locate(s, 'abc'), locate(s, 'xyz', 10),
360+ substring(s, 10), substring(s, 10, 3),
361+ ltrim(s), trim(trailing '!' from s),
362+ s||s collate en_us_ci,
363+ month(d), timestamp(d, '13:01:01'), timestampdiff(day, d, current_timestamp),
364+ next value for seq, current value for seq
365+FROM t
366+
367\ No newline at end of file

Subscribers

People subscribed via source and target branches