Merge lp:~mmcm/akiban-sql-parser/copy-statement into lp:~akiban-technologies/akiban-sql-parser/trunk

Proposed by Mike McMahon
Status: Merged
Approved by: Nathan Williams
Approved revision: 283
Merged at revision: 278
Proposed branch: lp:~mmcm/akiban-sql-parser/copy-statement
Merge into: lp:~akiban-technologies/akiban-sql-parser/trunk
Diff against target: 888 lines (+628/-1)
23 files modified
src/main/java/com/akiban/sql/parser/CopyStatementNode.java (+270/-0)
src/main/java/com/akiban/sql/parser/NodeFactoryImpl.java (+3/-0)
src/main/java/com/akiban/sql/parser/NodeNames.java (+2/-0)
src/main/java/com/akiban/sql/parser/NodeTypes.java (+1/-1)
src/main/java/com/akiban/sql/unparser/NodeToString.java (+86/-0)
src/main/javacc/SQLGrammar.jj (+132/-0)
src/test/resources/com/akiban/sql/parser/copy-1.expected (+12/-0)
src/test/resources/com/akiban/sql/parser/copy-1.sql (+1/-0)
src/test/resources/com/akiban/sql/parser/copy-2.expected (+39/-0)
src/test/resources/com/akiban/sql/parser/copy-2.sql (+1/-0)
src/test/resources/com/akiban/sql/parser/copy-3.expected (+12/-0)
src/test/resources/com/akiban/sql/parser/copy-3.sql (+1/-0)
src/test/resources/com/akiban/sql/parser/copy-4.expected (+47/-0)
src/test/resources/com/akiban/sql/parser/copy-4.sql (+1/-0)
src/test/resources/com/akiban/sql/parser/copy-5.expected (+12/-0)
src/test/resources/com/akiban/sql/parser/copy-5.sql (+1/-0)
src/test/resources/com/akiban/sql/parser/junk-1.error (+1/-0)
src/test/resources/com/akiban/sql/unparser/copy-3.expected (+1/-0)
src/test/resources/com/akiban/sql/unparser/copy-3.sql (+1/-0)
src/test/resources/com/akiban/sql/unparser/copy-5.expected (+1/-0)
src/test/resources/com/akiban/sql/unparser/copy-5.sql (+1/-0)
src/test/resources/com/akiban/sql/unparser/copy-6.expected (+1/-0)
src/test/resources/com/akiban/sql/unparser/copy-6.sql (+1/-0)
To merge this branch: bzr merge lp:~mmcm/akiban-sql-parser/copy-statement
Reviewer Review Type Date Requested Status
Akiban Build User Needs Fixing
Nathan Williams Approve
Review via email: mp+141472@code.launchpad.net

This proposal supersedes a proposal from 2012-12-28.

Description of the change

Add a COPY statement, a subset of the one in Postgres plus a commit frequency.

The options part of the command is meant to be extensible, leaving us room for more formats than just CSV.

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

Should there be a junk-1.sql?

Otherwise looks fine. Feel free to big-A after.

review: Approve
Revision history for this message
Mike McMahon (mmcm) wrote :

junk-1 is an existing test. It needs to change every time a new top-level statement is added, because its error message lists them all as valid parse alternatives.

Revision history for this message
Nathan Williams (nwilliams) wrote :

Ah, right. Modified, not added, file.

Revision history for this message
Akiban Build User (build-akiban) wrote :

There were 2 failures during build/test:

* job server-build failed at build number 3594: http://172.16.20.104:8080/job/server-build/3594/

* view must-pass failed: server-build is yellow

review: Needs Fixing
Revision history for this message
Nathan Williams (nwilliams) wrote :

Strange but unrelated.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'src/main/java/com/akiban/sql/parser/CopyStatementNode.java'
2--- src/main/java/com/akiban/sql/parser/CopyStatementNode.java 1970-01-01 00:00:00 +0000
3+++ src/main/java/com/akiban/sql/parser/CopyStatementNode.java 2012-12-30 01:41:22 +0000
4@@ -0,0 +1,270 @@
5+/**
6+ * Copyright © 2012 Akiban Technologies, Inc. All rights
7+ * reserved.
8+ *
9+ * This program and the accompanying materials are made available
10+ * under the terms of the Eclipse Public License v1.0 which
11+ * accompanies this distribution, and is available at
12+ * http://www.eclipse.org/legal/epl-v10.html
13+ *
14+ * This program may also be available under different license terms.
15+ * For more information, see www.akiban.com or contact
16+ * licensing@akiban.com.
17+ *
18+ * Contributors:
19+ * Akiban Technologies, Inc.
20+ */
21+
22+package com.akiban.sql.parser;
23+
24+import com.akiban.sql.StandardException;
25+
26+/**
27+ * An CopyStatementNode represents the COPY command.
28+ *
29+ */
30+
31+public class CopyStatementNode extends StatementNode
32+{
33+ public static enum Mode { TO_TABLE, FROM_TABLE, FROM_SUBQUERY };
34+ public static enum Format { CSV };
35+ private Mode mode;
36+ private TableName tableName;
37+ private ResultColumnList columnList;
38+ private SubqueryNode subquery;
39+ private String filename;
40+ private Format format;
41+ private String delimiter, nullString, quote, escape, encoding;
42+ private boolean header;
43+ private long commitFrequency;
44+
45+ /**
46+ * Initializer for an CopyStatementNode
47+ *
48+ * @param mode The copy direction.
49+ * @param subquery The derived table.
50+ * @param filename The file name or <code>null</code>.
51+ */
52+
53+ public void init(Object mode, Object subquery, Object filename) {
54+ this.mode = (Mode)mode;
55+ this.subquery = (SubqueryNode)subquery;
56+ this.filename = (String)filename;
57+ }
58+
59+ /**
60+ * Initializer for an CopyStatementNode
61+ *
62+ * @param mode The copy direction.
63+ * @param tableName The table name.
64+ * @param columnList The list of columns.
65+ * @param filename The file name or <code>null</code>.
66+ */
67+
68+ public void init(Object mode, Object tableName, Object columnList, Object filename) {
69+ this.mode = (Mode)mode;
70+ this.tableName = (TableName)tableName;
71+ this.columnList = (ResultColumnList)columnList;
72+ this.filename = (String)filename;
73+ }
74+
75+ public Mode getMode() {
76+ return mode;
77+ }
78+ public SubqueryNode getSubquery() {
79+ return subquery;
80+ }
81+ public TableName getTableName() {
82+ return tableName;
83+ }
84+ public ResultColumnList getColumnList() {
85+ return columnList;
86+ }
87+ public String getFilename() {
88+ return filename;
89+ }
90+
91+ public Format getFormat() {
92+ return format;
93+ }
94+ public void setFormat(Format format) {
95+ this.format = format;
96+ }
97+ public String getDelimiter() {
98+ return delimiter;
99+ }
100+ public void setDelimiter(String delimiter) {
101+ this.delimiter = delimiter;
102+ }
103+ public String getNullString() {
104+ return nullString;
105+ }
106+ public void setNullString(String nullString) {
107+ this.nullString = nullString;
108+ }
109+ public boolean isHeader() {
110+ return header;
111+ }
112+ public void setHeader(boolean header) {
113+ this.header = header;
114+ }
115+ public String getQuote() {
116+ return quote;
117+ }
118+ public void setQuote(String quote) {
119+ this.quote = quote;
120+ }
121+ public String getEscape() {
122+ return escape;
123+ }
124+ public void setEscape(String escape) {
125+ this.escape = escape;
126+ }
127+ public String getEncoding() {
128+ return encoding;
129+ }
130+ public void setEncoding(String encoding) {
131+ this.encoding = encoding;
132+ }
133+ public long getCommitFrequency() {
134+ return commitFrequency;
135+ }
136+ public void setCommitFrequency(long commitFrequency) {
137+ this.commitFrequency = commitFrequency;
138+ }
139+
140+ /**
141+ * Fill this node with a deep copy of the given node.
142+ */
143+ public void copyFrom(QueryTreeNode node) throws StandardException {
144+ super.copyFrom(node);
145+
146+ CopyStatementNode other = (CopyStatementNode)node;
147+ this.tableName = (TableName)getNodeFactory().copyNode(other.tableName,
148+ getParserContext());
149+ this.subquery = (SubqueryNode)getNodeFactory().copyNode(other.subquery,
150+ getParserContext());
151+ this.columnList = (ResultColumnList)getNodeFactory().copyNode(other.columnList,
152+ getParserContext());
153+ this.filename = other.filename;
154+ this.format = other.format;
155+ this.delimiter = other.delimiter;
156+ this.nullString = other.nullString;
157+ this.quote = other.quote;
158+ this.escape = other.escape;
159+ this.encoding = other.encoding;
160+ }
161+
162+ /**
163+ * Convert this object to a String. See comments in QueryTreeNode.java
164+ * for how this should be done for tree printing.
165+ *
166+ * @return This object as a String
167+ */
168+
169+ public String toString() {
170+ return "mode: " + mode + "\n" +
171+ "tableName: " + tableName + "\n" +
172+ "filename: " + filename + "\n" +
173+ "format: " + format + "\n" +
174+ "delimiter: " + delimiter + "\n" +
175+ "nullString: " + nullString + "\n" +
176+ "quote: " + quote + "\n" +
177+ "escape: " + escape + "\n" +
178+ "encoding: " + encoding + "\n" +
179+ "commitFrequency: " + commitFrequency + "\n" +
180+ super.toString();
181+ }
182+
183+ public String statementToString() {
184+ return "COPY";
185+ }
186+
187+ /**
188+ * Prints the sub-nodes of this object. See QueryTreeNode.java for
189+ * how tree printing is supposed to work.
190+ *
191+ * @param depth The depth of this node in the tree
192+ */
193+
194+ public void printSubNodes(int depth) {
195+ super.printSubNodes(depth);
196+
197+ if (subquery != null) {
198+ printLabel(depth, "subquery: ");
199+ subquery.treePrint(depth + 1);
200+ }
201+ if (columnList != null) {
202+ printLabel(depth, "columnList: ");
203+ columnList.treePrint(depth + 1);
204+ }
205+ }
206+
207+ /**
208+ * Accept the visitor for all visitable children of this node.
209+ *
210+ * @param v the visitor
211+ *
212+ * @exception StandardException on error
213+ */
214+ void acceptChildren(Visitor v) throws StandardException {
215+ super.acceptChildren(v);
216+
217+ if (subquery != null) {
218+ subquery = (SubqueryNode)subquery.accept(v);
219+ }
220+ if (columnList != null) {
221+ columnList = (ResultColumnList)columnList.accept(v);
222+ }
223+ }
224+
225+ /** Turn the source portion into a regular Select query. */
226+ public CursorNode asQuery() throws StandardException {
227+ NodeFactory nodeFactory = getNodeFactory();
228+ SQLParserContext parserContext = getParserContext();
229+
230+ ResultSetNode resultSet;
231+ OrderByList orderBy = null;
232+ ValueNode offset = null, limit = null;
233+ if (subquery != null) {
234+ // Easy case: already specified as a subquery.
235+ resultSet = subquery.getResultSet();
236+ orderBy = subquery.getOrderByList();
237+ offset = subquery.getOffset();
238+ limit = subquery.getFetchFirst();
239+ }
240+ else {
241+ // Table case.
242+ FromList fromList = (FromList)nodeFactory.getNode(NodeTypes.FROM_LIST,
243+ parserContext);
244+ FromTable fromTable = (FromTable)nodeFactory.getNode(NodeTypes.FROM_BASE_TABLE,
245+ tableName,
246+ null, null,
247+ parserContext);
248+ fromList.addFromTable(fromTable);
249+ ResultColumnList selectList = columnList;
250+ if (selectList == null) {
251+ selectList = (ResultColumnList)nodeFactory.getNode(NodeTypes.RESULT_COLUMN_LIST,
252+ parserContext);
253+ ResultColumn star = (ResultColumn)nodeFactory.getNode(NodeTypes.ALL_RESULT_COLUMN,
254+ Boolean.FALSE,
255+ parserContext);
256+ selectList.addResultColumn(star);
257+ }
258+ resultSet = (SelectNode)nodeFactory.getNode(NodeTypes.SELECT_NODE,
259+ selectList,
260+ null,
261+ fromList,
262+ null, null, null, null,
263+ parserContext);
264+ }
265+ return (CursorNode)nodeFactory.getNode(NodeTypes.CURSOR_NODE,
266+ "SELECT",
267+ resultSet,
268+ null,
269+ orderBy, offset, limit,
270+ null, null,
271+ parserContext);
272+ }
273+
274+}
275
276=== modified file 'src/main/java/com/akiban/sql/parser/NodeFactoryImpl.java'
277--- src/main/java/com/akiban/sql/parser/NodeFactoryImpl.java 2012-12-13 23:27:56 +0000
278+++ src/main/java/com/akiban/sql/parser/NodeFactoryImpl.java 2012-12-30 01:41:22 +0000
279@@ -593,6 +593,9 @@
280 case NodeTypes.EXPLAIN_STATEMENT_NODE:
281 return NodeNames.EXPLAIN_STATEMENT_NODE_NAME;
282
283+ case NodeTypes.COPY_STATEMENT_NODE:
284+ return NodeNames.COPY_STATEMENT_NODE_NAME;
285+
286 case NodeTypes.INDEX_COLUMN:
287 return NodeNames.INDEX_COLUMN_NAME;
288
289
290=== modified file 'src/main/java/com/akiban/sql/parser/NodeNames.java'
291--- src/main/java/com/akiban/sql/parser/NodeNames.java 2012-12-13 23:01:21 +0000
292+++ src/main/java/com/akiban/sql/parser/NodeNames.java 2012-12-30 01:41:22 +0000
293@@ -118,6 +118,8 @@
294
295 static final String CONSTRAINT_DEFINITION_NODE_NAME = "com.akiban.sql.parser.ConstraintDefinitionNode";
296
297+ static final String COPY_STATEMENT_NODE_NAME = "com.akiban.sql.parser.CopyStatementNode";
298+
299 static final String CREATE_ALIAS_NODE_NAME = "com.akiban.sql.parser.CreateAliasNode";
300
301 static final String CREATE_INDEX_NODE_NAME = "com.akiban.sql.parser.CreateIndexNode";
302
303=== modified file 'src/main/java/com/akiban/sql/parser/NodeTypes.java'
304--- src/main/java/com/akiban/sql/parser/NodeTypes.java 2012-12-13 22:33:51 +0000
305+++ src/main/java/com/akiban/sql/parser/NodeTypes.java 2012-12-30 01:41:22 +0000
306@@ -166,7 +166,7 @@
307 public static final int AGGREGATE_NODE = 115;
308 public static final int COLUMN_DEFINITION_NODE = 116;
309 public static final int EXPLAIN_STATEMENT_NODE = 117;
310- // 118 available
311+ public static final int COPY_STATEMENT_NODE = 118;
312 public static final int FK_CONSTRAINT_DEFINITION_NODE = 119;
313 public static final int FROM_VTI = 120;
314 public static final int MATERIALIZE_RESULT_SET_NODE = 121;
315
316=== modified file 'src/main/java/com/akiban/sql/unparser/NodeToString.java'
317--- src/main/java/com/akiban/sql/unparser/NodeToString.java 2012-12-13 23:46:31 +0000
318+++ src/main/java/com/akiban/sql/unparser/NodeToString.java 2012-12-30 01:41:22 +0000
319@@ -223,6 +223,8 @@
320 return executeStatementNode((ExecuteStatementNode)node);
321 case NodeTypes.DEALLOCATE_STATEMENT_NODE:
322 return deallocateStatementNode((DeallocateStatementNode)node);
323+ case NodeTypes.COPY_STATEMENT_NODE:
324+ return copyStatementNode((CopyStatementNode)node);
325 default:
326 return "**UNKNOWN(" + node.getNodeType() +")**";
327 }
328@@ -1061,6 +1063,90 @@
329 return "DEALLOCATE " + node.getName();
330 }
331
332+ protected String copyStatementNode(CopyStatementNode node)
333+ throws StandardException {
334+ StringBuilder str = new StringBuilder("COPY ");
335+ if (node.getSubquery() != null) {
336+ str.append("(");
337+ str.append(toString(node.getSubquery()));
338+ str.append(")");
339+ }
340+ else {
341+ str.append(node.getTableName());
342+ if (node.getColumnList() != null) {
343+ str.append("(");
344+ str.append(toString(node.getColumnList()));
345+ str.append(")");
346+ }
347+ }
348+ switch (node.getMode()) {
349+ case FROM_TABLE:
350+ case FROM_SUBQUERY:
351+ str.append(" TO ");
352+ break;
353+ case TO_TABLE:
354+ str.append(" FROM ");
355+ break;
356+ }
357+ if (node.getFilename() != null) {
358+ str.append("'");
359+ str.append(node.getFilename());
360+ str.append("'");
361+ }
362+ else if (node.getMode() == CopyStatementNode.Mode.TO_TABLE) {
363+ str.append("STDIN");
364+ }
365+ else {
366+ str.append("STDOUT");
367+ }
368+ boolean options = false;
369+ if (node.getFormat() != null) {
370+ options = copyOption(str, "FORMAT", node.getFormat().name(), options);
371+ }
372+ if (node.getDelimiter() != null) {
373+ options = copyOptionString(str, "DELIMITER", node.getDelimiter(), options);
374+ }
375+ if (node.getNullString() != null) {
376+ options = copyOptionString(str, "NULL", node.getNullString(), options);
377+ }
378+ if (node.isHeader()) {
379+ options = copyOption(str, "HEADER", "TRUE", options);
380+ }
381+ if (node.getQuote() != null) {
382+ options = copyOptionString(str, "QUOTE", node.getQuote(), options);
383+ }
384+ if (node.getEscape() != null) {
385+ options = copyOptionString(str, "ESCAPE", node.getEscape(), options);
386+ }
387+ if (node.getEncoding() != null) {
388+ options = copyOptionString(str, "ENCODING", node.getEncoding(), options);
389+ }
390+ if (node.getCommitFrequency() != 0) {
391+ options = copyOption(str, "COMMIT", node.getCommitFrequency() + " ROWS", options);
392+ }
393+ if (options) {
394+ str.append(")");
395+ }
396+ return str.toString();
397+ }
398+
399+ protected boolean copyOptionString(StringBuilder str, String keyword, String value, boolean options) {
400+ return copyOption(str, keyword, "'" + value + "'", options);
401+ }
402+
403+ protected boolean copyOption(StringBuilder str, String keyword, String value, boolean options) {
404+ if (!options) {
405+ str.append(" WITH (");
406+ }
407+ else {
408+ str.append(", ");
409+ }
410+ str.append(keyword);
411+ str.append(" " );
412+ str.append(value);
413+ return true;
414+ }
415+
416 protected void doPrint(QueryTreeNode node, StringBuilder bd) throws StandardException
417 {
418 if (node instanceof RowConstructorNode)
419
420=== modified file 'src/main/javacc/SQLGrammar.jj'
421--- src/main/javacc/SQLGrammar.jj 2012-12-14 19:27:44 +0000
422+++ src/main/javacc/SQLGrammar.jj 2012-12-30 01:41:22 +0000
423@@ -2410,7 +2410,9 @@
424 | <CLASS: "class">
425 | <COMPRESS: "compress">
426 | <CONTENT: "content">
427+| <COPY: "copy">
428 | <CS: "cs">
429+| <CSV: "csv">
430 | <CURSORS: "cursors">
431 | <DAY_HOUR: "day_hour">
432 | <DAY_MICROSECOND: "day_microsecond">
433@@ -2418,13 +2420,17 @@
434 | <DAY_SECOND: "day_second">
435 | <DB2SQL: "db2sql">
436 | <DEFRAGMENT: "defragment">
437+| <DELIMITER: "delimiter">
438 | <DIRTY: "dirty">
439 | <DOCUMENT: "document">
440 | <EACH: "each">
441 | <EMPTY: "empty">
442+| <ENCODING: "encoding">
443 | <EXCLUSIVE: "exclusive">
444 | <FN: "fn">
445 | <FORCE: "force">
446+| <FORMAT: "format">
447+| <HEADER: "header">
448 | <HOUR_MICROSECOND: "hour_microsecond">
449 | <HOUR_MINUTE: "hour_minute">
450 | <HOUR_SECOND: "hour_second">
451@@ -2456,6 +2462,7 @@
452 | <PROPERTIES: "properties">
453 | <PURGE: "purge">
454 | <QUARTER: "quarter">
455+| <_QUOTE: "quote">
456 | <READS: "reads">
457 | <REF: "ref">
458 | <REFERENCING: "referencing">
459@@ -2477,6 +2484,8 @@
460 | <SQRT: "sqrt">
461 | <STABILITY: "stability">
462 | <STATISTICS: "statistics">
463+| <STDIN: "stdin">
464+| <STDOUT: "stdout">
465 | <STRIP: "strip">
466 | <STYLE: "style">
467 | <TRIGGER: "trigger">
468@@ -3000,6 +3009,8 @@
469 statementNode = explainStatement()
470 |
471 statementNode = transactionControlStatement()
472+|
473+ statementNode = copyStatement()
474 )
475 {
476 return statementNode;
477@@ -14223,6 +14234,118 @@
478 }
479 }
480
481+StatementNode
482+copyStatement() throws StandardException :
483+{
484+ CopyStatementNode stmt;
485+}
486+{
487+ <COPY> stmt = copyStatementBase()
488+ [ [<WITH>] <LEFT_PAREN> copyOption(stmt)
489+ ( <COMMA> copyOption(stmt) )*
490+ <RIGHT_PAREN> ]
491+ {
492+ return stmt;
493+ }
494+}
495+
496+CopyStatementNode
497+copyStatementBase() throws StandardException :
498+{
499+ CopyStatementNode.Mode mode;
500+ TableName tableName = null;
501+ ResultColumnList columnList = null;
502+ SubqueryNode subquery = null;
503+ String filename = null;
504+}
505+{
506+(
507+ LOOKAHEAD( { getToken(1).kind == LEFT_PAREN && getToken(2).kind == SELECT } )
508+ subquery = derivedTable()
509+ <TO> ( filename = string() | <STDOUT> )
510+ { mode = CopyStatementNode.Mode.FROM_SUBQUERY; }
511+|
512+ tableName = qualifiedName()
513+ [ <LEFT_PAREN> columnList = insertColumnList() <RIGHT_PAREN> ]
514+ ( <TO> ( filename = string() | <STDOUT> )
515+ { mode = CopyStatementNode.Mode.FROM_TABLE; }
516+ | <FROM> ( filename = string() | <STDIN> )
517+ { mode = CopyStatementNode.Mode.TO_TABLE; }
518+ )
519+)
520+ {
521+ if (subquery != null)
522+ return (CopyStatementNode)nodeFactory.getNode(NodeTypes.COPY_STATEMENT_NODE,
523+ mode,
524+ subquery,
525+ filename,
526+ parserContext);
527+ else
528+ return (CopyStatementNode)nodeFactory.getNode(NodeTypes.COPY_STATEMENT_NODE,
529+ mode,
530+ tableName, columnList,
531+ filename,
532+ parserContext);
533+ }
534+}
535+
536+void
537+copyOption(CopyStatementNode stmt) throws StandardException :
538+{
539+ String value;
540+ long lvalue;
541+ CopyStatementNode.Format format;
542+}
543+{
544+ <FORMAT> format = copyFormat()
545+ {
546+ stmt.setFormat(format);
547+ }
548+|
549+ <DELIMITER> value = string()
550+ {
551+ stmt.setDelimiter(value);
552+ }
553+|
554+ <NULL> value = string()
555+ {
556+ stmt.setNullString(value);
557+ }
558+|
559+ <HEADER> token = booleanLiteral()
560+ {
561+ stmt.setHeader(token.kind == TRUE);
562+ }
563+|
564+ <_QUOTE> value = string()
565+ {
566+ stmt.setQuote(value);
567+ }
568+|
569+ <ESCAPE> value = string()
570+ {
571+ stmt.setEscape(value);
572+ }
573+|
574+ <ENCODING> value = string()
575+ {
576+ stmt.setEncoding(value);
577+ }
578+|
579+ <COMMIT> lvalue = exactNumber() [<ROWS>]
580+ {
581+ stmt.setCommitFrequency(lvalue);
582+ }
583+}
584+
585+CopyStatementNode.Format
586+copyFormat() throws StandardException :
587+{
588+}
589+{
590+ <CSV> { return CopyStatementNode.Format.CSV; }
591+}
592+
593 String
594 internalIdentifier() throws StandardException :
595 {
596@@ -14586,8 +14709,10 @@
597 | tok = <CONCAT>
598 | tok = <CONTAINS>
599 | tok = <CONTENT>
600+| tok = <COPY>
601 | tok = <COUNT>
602 | tok = <CS>
603+| tok = <CSV>
604 | tok = <CURDATE>
605 | tok = <CURTIME>
606 | tok = <D>
607@@ -14600,6 +14725,7 @@
608 | tok = <DAY_MINUTE>
609 | tok = <DAY_SECOND>
610 | tok = <DEFRAGMENT>
611+| tok = <DELIMITER>
612 | tok = <DIRTY>
613 | tok = <DIV>
614 | tok = <DUMMY>
615@@ -14609,12 +14735,15 @@
616 | tok = <DOCUMENT>
617 | tok = <EACH>
618 | tok = <EMPTY>
619+| tok = <ENCODING>
620 | tok = <EXCLUSIVE>
621 | tok = <EXTRACT>
622 | tok = <FN>
623 | tok = <FORCE>
624+| tok = <FORMAT>
625 | tok = <FORTRAN>
626 | tok = <GENERATED>
627+| tok = <HEADER>
628 | tok = <HOUR_MICROSECOND>
629 | tok = <HOUR_MINUTE>
630 | tok = <HOUR_SECOND>
631@@ -14676,6 +14805,7 @@
632 | tok = <PROPERTIES>
633 | tok = <PURGE>
634 | tok = <QUARTER>
635+| tok = <_QUOTE>
636 | tok = <READS>
637 | tok = <REF>
638 // SQL92 says RELEASE is reserved, but we want it to be non-reserved.
639@@ -14723,6 +14853,8 @@
640 | tok = <START>
641 | tok = <STATEMENT>
642 | tok = <STATISTICS>
643+| tok = <STDIN>
644+| tok = <STDOUT>
645 | tok = <STRIP>
646 | tok = <SYNONYM>
647 | tok = <STYLE>
648
649=== added file 'src/test/resources/com/akiban/sql/parser/copy-1.expected'
650--- src/test/resources/com/akiban/sql/parser/copy-1.expected 1970-01-01 00:00:00 +0000
651+++ src/test/resources/com/akiban/sql/parser/copy-1.expected 2012-12-30 01:41:22 +0000
652@@ -0,0 +1,12 @@
653+com.akiban.sql.parser.CopyStatementNode@5bbf3d87
654+mode: FROM_TABLE
655+tableName: t1
656+filename: null
657+format: null
658+delimiter: null
659+nullString: null
660+quote: null
661+escape: null
662+encoding: null
663+commitFrequency: 0
664+statementType: COPY
665\ No newline at end of file
666
667=== added file 'src/test/resources/com/akiban/sql/parser/copy-1.sql'
668--- src/test/resources/com/akiban/sql/parser/copy-1.sql 1970-01-01 00:00:00 +0000
669+++ src/test/resources/com/akiban/sql/parser/copy-1.sql 2012-12-30 01:41:22 +0000
670@@ -0,0 +1,1 @@
671+COPY t1 TO STDOUT
672\ No newline at end of file
673
674=== added file 'src/test/resources/com/akiban/sql/parser/copy-2.expected'
675--- src/test/resources/com/akiban/sql/parser/copy-2.expected 1970-01-01 00:00:00 +0000
676+++ src/test/resources/com/akiban/sql/parser/copy-2.expected 2012-12-30 01:41:22 +0000
677@@ -0,0 +1,39 @@
678+com.akiban.sql.parser.CopyStatementNode@44c9d92c
679+mode: FROM_TABLE
680+tableName: t2
681+filename: /tmp/t2.csv
682+format: null
683+delimiter: null
684+nullString: null
685+quote: null
686+escape: null
687+encoding: null
688+commitFrequency: 0
689+statementType: COPY
690+columnList:
691+ com.akiban.sql.parser.ResultColumnList@1fd0fafc
692+
693+ [0]:
694+ com.akiban.sql.parser.ResultColumn@510dc6b5
695+ exposedName: c1
696+ name: c1
697+ tableName: null
698+ isDefaultColumn: false
699+ type: null
700+ reference:
701+ com.akiban.sql.parser.ColumnReference@5f70bea5
702+ columnName: c1
703+ tableName: null
704+ type: null
705+ [1]:
706+ com.akiban.sql.parser.ResultColumn@62f47396
707+ exposedName: c2
708+ name: c2
709+ tableName: null
710+ isDefaultColumn: false
711+ type: null
712+ reference:
713+ com.akiban.sql.parser.ColumnReference@1ed0af9b
714+ columnName: c2
715+ tableName: null
716+ type: null
717\ No newline at end of file
718
719=== added file 'src/test/resources/com/akiban/sql/parser/copy-2.sql'
720--- src/test/resources/com/akiban/sql/parser/copy-2.sql 1970-01-01 00:00:00 +0000
721+++ src/test/resources/com/akiban/sql/parser/copy-2.sql 2012-12-30 01:41:22 +0000
722@@ -0,0 +1,1 @@
723+COPY t2(c1,c2) TO '/tmp/t2.csv'
724\ No newline at end of file
725
726=== added file 'src/test/resources/com/akiban/sql/parser/copy-3.expected'
727--- src/test/resources/com/akiban/sql/parser/copy-3.expected 1970-01-01 00:00:00 +0000
728+++ src/test/resources/com/akiban/sql/parser/copy-3.expected 2012-12-30 01:41:22 +0000
729@@ -0,0 +1,12 @@
730+com.akiban.sql.parser.CopyStatementNode@16b8f8eb
731+mode: TO_TABLE
732+tableName: t1
733+filename: /tmp/t1.csv
734+format: null
735+delimiter: null
736+nullString: null
737+quote: null
738+escape: null
739+encoding: null
740+commitFrequency: 0
741+statementType: COPY
742\ No newline at end of file
743
744=== added file 'src/test/resources/com/akiban/sql/parser/copy-3.sql'
745--- src/test/resources/com/akiban/sql/parser/copy-3.sql 1970-01-01 00:00:00 +0000
746+++ src/test/resources/com/akiban/sql/parser/copy-3.sql 2012-12-30 01:41:22 +0000
747@@ -0,0 +1,1 @@
748+COPY t1 FROM '/tmp/t1.csv'
749\ No newline at end of file
750
751=== added file 'src/test/resources/com/akiban/sql/parser/copy-4.expected'
752--- src/test/resources/com/akiban/sql/parser/copy-4.expected 1970-01-01 00:00:00 +0000
753+++ src/test/resources/com/akiban/sql/parser/copy-4.expected 2012-12-30 01:41:22 +0000
754@@ -0,0 +1,47 @@
755+com.akiban.sql.parser.CopyStatementNode@49de17f4
756+mode: FROM_SUBQUERY
757+tableName: null
758+filename: /tmp/t12.txt
759+format: null
760+delimiter: null
761+nullString: null
762+quote: null
763+escape: null
764+encoding: null
765+commitFrequency: 0
766+statementType: COPY
767+subquery:
768+ com.akiban.sql.parser.SubqueryNode@13f6ba0f
769+ subqueryType: FROM
770+ type: null
771+ resultSet:
772+ com.akiban.sql.parser.SelectNode@2b313906
773+ isDistinct: false
774+ resultColumns:
775+ com.akiban.sql.parser.ResultColumnList@2c96cf11
776+
777+ [0]:
778+ com.akiban.sql.parser.AllResultColumn@60f47bf5
779+ tableName: null
780+ exposedName: null
781+ name: null
782+ tableName: null
783+ isDefaultColumn: false
784+ type: null
785+ fromList:
786+ com.akiban.sql.parser.FromList@52f6438d
787+
788+ [0]:
789+ com.akiban.sql.parser.FromBaseTable@25cd0888
790+ tableName: t1
791+ updateOrDelete: null
792+ null
793+ correlation Name: null
794+ null
795+ [1]:
796+ com.akiban.sql.parser.FromBaseTable@37eb2c1b
797+ tableName: t2
798+ updateOrDelete: null
799+ null
800+ correlation Name: null
801+ null
802\ No newline at end of file
803
804=== added file 'src/test/resources/com/akiban/sql/parser/copy-4.sql'
805--- src/test/resources/com/akiban/sql/parser/copy-4.sql 1970-01-01 00:00:00 +0000
806+++ src/test/resources/com/akiban/sql/parser/copy-4.sql 2012-12-30 01:41:22 +0000
807@@ -0,0 +1,1 @@
808+COPY (SELECT * FROM t1,t2) TO '/tmp/t12.txt'
809\ No newline at end of file
810
811=== added file 'src/test/resources/com/akiban/sql/parser/copy-5.expected'
812--- src/test/resources/com/akiban/sql/parser/copy-5.expected 1970-01-01 00:00:00 +0000
813+++ src/test/resources/com/akiban/sql/parser/copy-5.expected 2012-12-30 01:41:22 +0000
814@@ -0,0 +1,12 @@
815+com.akiban.sql.parser.CopyStatementNode@24f9fdc
816+mode: FROM_TABLE
817+tableName: t1
818+filename: null
819+format: CSV
820+delimiter: |
821+nullString: null
822+quote: null
823+escape: null
824+encoding: null
825+commitFrequency: 0
826+statementType: COPY
827\ No newline at end of file
828
829=== added file 'src/test/resources/com/akiban/sql/parser/copy-5.sql'
830--- src/test/resources/com/akiban/sql/parser/copy-5.sql 1970-01-01 00:00:00 +0000
831+++ src/test/resources/com/akiban/sql/parser/copy-5.sql 2012-12-30 01:41:22 +0000
832@@ -0,0 +1,1 @@
833+COPY t1 TO STDOUT (FORMAT CSV, DELIMITER '|', NULL 'null')
834\ No newline at end of file
835
836=== modified file 'src/test/resources/com/akiban/sql/parser/junk-1.error'
837--- src/test/resources/com/akiban/sql/parser/junk-1.error 2012-12-13 22:38:28 +0000
838+++ src/test/resources/com/akiban/sql/parser/junk-1.error 2012-12-30 01:41:22 +0000
839@@ -20,6 +20,7 @@
840 "truncate" ...
841 "call" ...
842 "explain" ...
843+ "copy" ...
844 "lock" ...
845 "rename" ...
846 "{" ...
847
848=== added file 'src/test/resources/com/akiban/sql/unparser/copy-3.expected'
849--- src/test/resources/com/akiban/sql/unparser/copy-3.expected 1970-01-01 00:00:00 +0000
850+++ src/test/resources/com/akiban/sql/unparser/copy-3.expected 2012-12-30 01:41:22 +0000
851@@ -0,0 +1,1 @@
852+COPY t1 FROM '/tmp/t1.csv'
853\ No newline at end of file
854
855=== added file 'src/test/resources/com/akiban/sql/unparser/copy-3.sql'
856--- src/test/resources/com/akiban/sql/unparser/copy-3.sql 1970-01-01 00:00:00 +0000
857+++ src/test/resources/com/akiban/sql/unparser/copy-3.sql 2012-12-30 01:41:22 +0000
858@@ -0,0 +1,1 @@
859+COPY t1 FROM '/tmp/t1.csv'
860\ No newline at end of file
861
862=== added file 'src/test/resources/com/akiban/sql/unparser/copy-5.expected'
863--- src/test/resources/com/akiban/sql/unparser/copy-5.expected 1970-01-01 00:00:00 +0000
864+++ src/test/resources/com/akiban/sql/unparser/copy-5.expected 2012-12-30 01:41:22 +0000
865@@ -0,0 +1,1 @@
866+COPY t1(c1, c2) TO 'file' WITH (FORMAT CSV, DELIMITER '|', NULL 'null', HEADER TRUE)
867\ No newline at end of file
868
869=== added file 'src/test/resources/com/akiban/sql/unparser/copy-5.sql'
870--- src/test/resources/com/akiban/sql/unparser/copy-5.sql 1970-01-01 00:00:00 +0000
871+++ src/test/resources/com/akiban/sql/unparser/copy-5.sql 2012-12-30 01:41:22 +0000
872@@ -0,0 +1,1 @@
873+COPY t1(c1,c2) TO 'file' (FORMAT csv, null 'null', delimiter '|', HEADER true)
874\ No newline at end of file
875
876=== added file 'src/test/resources/com/akiban/sql/unparser/copy-6.expected'
877--- src/test/resources/com/akiban/sql/unparser/copy-6.expected 1970-01-01 00:00:00 +0000
878+++ src/test/resources/com/akiban/sql/unparser/copy-6.expected 2012-12-30 01:41:22 +0000
879@@ -0,0 +1,1 @@
880+COPY t1 FROM 't1.csv' WITH (COMMIT 10000 ROWS)
881\ No newline at end of file
882
883=== added file 'src/test/resources/com/akiban/sql/unparser/copy-6.sql'
884--- src/test/resources/com/akiban/sql/unparser/copy-6.sql 1970-01-01 00:00:00 +0000
885+++ src/test/resources/com/akiban/sql/unparser/copy-6.sql 2012-12-30 01:41:22 +0000
886@@ -0,0 +1,1 @@
887+COPY t1 FROM 't1.csv' WITH (HEADER false, COMMIT 10000)
888\ No newline at end of file

Subscribers

People subscribed via source and target branches