@@ -691,8 +691,10 @@ fn test_copy_from() {
691
691
assert_eq ! (
692
692
stmt,
693
693
Statement :: Copy {
694
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
695
- columns: vec![ ] ,
694
+ source: CopySource :: Table {
695
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
696
+ columns: vec![ ] ,
697
+ } ,
696
698
to: false ,
697
699
target: CopyTarget :: File {
698
700
filename: "data.csv" . to_string( ) ,
@@ -707,8 +709,10 @@ fn test_copy_from() {
707
709
assert_eq ! (
708
710
stmt,
709
711
Statement :: Copy {
710
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
711
- columns: vec![ ] ,
712
+ source: CopySource :: Table {
713
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
714
+ columns: vec![ ] ,
715
+ } ,
712
716
to: false ,
713
717
target: CopyTarget :: File {
714
718
filename: "data.csv" . to_string( ) ,
@@ -723,8 +727,10 @@ fn test_copy_from() {
723
727
assert_eq ! (
724
728
stmt,
725
729
Statement :: Copy {
726
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
727
- columns: vec![ ] ,
730
+ source: CopySource :: Table {
731
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
732
+ columns: vec![ ] ,
733
+ } ,
728
734
to: false ,
729
735
target: CopyTarget :: File {
730
736
filename: "data.csv" . to_string( ) ,
@@ -745,8 +751,10 @@ fn test_copy_to() {
745
751
assert_eq ! (
746
752
stmt,
747
753
Statement :: Copy {
748
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
749
- columns: vec![ ] ,
754
+ source: CopySource :: Table {
755
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
756
+ columns: vec![ ] ,
757
+ } ,
750
758
to: true ,
751
759
target: CopyTarget :: File {
752
760
filename: "data.csv" . to_string( ) ,
@@ -761,8 +769,10 @@ fn test_copy_to() {
761
769
assert_eq ! (
762
770
stmt,
763
771
Statement :: Copy {
764
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
765
- columns: vec![ ] ,
772
+ source: CopySource :: Table {
773
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
774
+ columns: vec![ ] ,
775
+ } ,
766
776
to: true ,
767
777
target: CopyTarget :: File {
768
778
filename: "data.csv" . to_string( ) ,
@@ -777,8 +787,10 @@ fn test_copy_to() {
777
787
assert_eq ! (
778
788
stmt,
779
789
Statement :: Copy {
780
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
781
- columns: vec![ ] ,
790
+ source: CopySource :: Table {
791
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
792
+ columns: vec![ ] ,
793
+ } ,
782
794
to: true ,
783
795
target: CopyTarget :: File {
784
796
filename: "data.csv" . to_string( ) ,
@@ -816,8 +828,10 @@ fn parse_copy_from() {
816
828
assert_eq ! (
817
829
pg_and_generic( ) . one_statement_parses_to( sql, "" ) ,
818
830
Statement :: Copy {
819
- table_name: ObjectName ( vec![ "table" . into( ) ] ) ,
820
- columns: vec![ "a" . into( ) , "b" . into( ) ] ,
831
+ source: CopySource :: Table {
832
+ table_name: ObjectName ( vec![ "table" . into( ) ] ) ,
833
+ columns: vec![ "a" . into( ) , "b" . into( ) ] ,
834
+ } ,
821
835
to: false ,
822
836
target: CopyTarget :: File {
823
837
filename: "file.csv" . into( )
@@ -845,14 +859,25 @@ fn parse_copy_from() {
845
859
) ;
846
860
}
847
861
862
+ #[ test]
863
+ fn parse_copy_from_error ( ) {
864
+ let res = pg ( ) . parse_sql_statements ( "COPY (SELECT 42 AS a, 'hello' AS b) FROM 'query.csv'" ) ;
865
+ assert_eq ! (
866
+ ParserError :: ParserError ( "COPY ... FROM does not support query as a source" . to_string( ) ) ,
867
+ res. unwrap_err( )
868
+ ) ;
869
+ }
870
+
848
871
#[ test]
849
872
fn parse_copy_to ( ) {
850
873
let stmt = pg ( ) . verified_stmt ( "COPY users TO 'data.csv'" ) ;
851
874
assert_eq ! (
852
875
stmt,
853
876
Statement :: Copy {
854
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
855
- columns: vec![ ] ,
877
+ source: CopySource :: Table {
878
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
879
+ columns: vec![ ] ,
880
+ } ,
856
881
to: true ,
857
882
target: CopyTarget :: File {
858
883
filename: "data.csv" . to_string( ) ,
@@ -867,8 +892,10 @@ fn parse_copy_to() {
867
892
assert_eq ! (
868
893
stmt,
869
894
Statement :: Copy {
870
- table_name: ObjectName ( vec![ "country" . into( ) ] ) ,
871
- columns: vec![ ] ,
895
+ source: CopySource :: Table {
896
+ table_name: ObjectName ( vec![ "country" . into( ) ] ) ,
897
+ columns: vec![ ] ,
898
+ } ,
872
899
to: true ,
873
900
target: CopyTarget :: Stdout ,
874
901
options: vec![ CopyOption :: Delimiter ( '|' ) ] ,
@@ -882,8 +909,10 @@ fn parse_copy_to() {
882
909
assert_eq ! (
883
910
stmt,
884
911
Statement :: Copy {
885
- table_name: ObjectName ( vec![ "country" . into( ) ] ) ,
886
- columns: vec![ ] ,
912
+ source: CopySource :: Table {
913
+ table_name: ObjectName ( vec![ "country" . into( ) ] ) ,
914
+ columns: vec![ ] ,
915
+ } ,
887
916
to: true ,
888
917
target: CopyTarget :: Program {
889
918
command: "gzip > /usr1/proj/bray/sql/country_data.gz" . into( ) ,
@@ -893,6 +922,58 @@ fn parse_copy_to() {
893
922
values: vec![ ] ,
894
923
}
895
924
) ;
925
+
926
+ let stmt = pg ( ) . verified_stmt ( "COPY (SELECT 42 AS a, 'hello' AS b) TO 'query.csv'" ) ;
927
+ assert_eq ! (
928
+ stmt,
929
+ Statement :: Copy {
930
+ source: CopySource :: Query ( Box :: new( Query {
931
+ with: None ,
932
+ body: Box :: new( SetExpr :: Select ( Box :: new( Select {
933
+ distinct: false ,
934
+ top: None ,
935
+ projection: vec![
936
+ SelectItem :: ExprWithAlias {
937
+ expr: Expr :: Value ( number( "42" ) ) ,
938
+ alias: Ident {
939
+ value: "a" . into( ) ,
940
+ quote_style: None ,
941
+ } ,
942
+ } ,
943
+ SelectItem :: ExprWithAlias {
944
+ expr: Expr :: Value ( Value :: SingleQuotedString ( "hello" . into( ) ) ) ,
945
+ alias: Ident {
946
+ value: "b" . into( ) ,
947
+ quote_style: None ,
948
+ } ,
949
+ }
950
+ ] ,
951
+ into: None ,
952
+ from: vec![ ] ,
953
+ lateral_views: vec![ ] ,
954
+ selection: None ,
955
+ group_by: vec![ ] ,
956
+ having: None ,
957
+ cluster_by: vec![ ] ,
958
+ distribute_by: vec![ ] ,
959
+ sort_by: vec![ ] ,
960
+ qualify: None ,
961
+ } ) ) ) ,
962
+ order_by: vec![ ] ,
963
+ limit: None ,
964
+ offset: None ,
965
+ fetch: None ,
966
+ locks: vec![ ] ,
967
+ } ) ) ,
968
+ to: true ,
969
+ target: CopyTarget :: File {
970
+ filename: "query.csv" . into( ) ,
971
+ } ,
972
+ options: vec![ ] ,
973
+ legacy_options: vec![ ] ,
974
+ values: vec![ ] ,
975
+ }
976
+ )
896
977
}
897
978
898
979
#[ test]
@@ -901,8 +982,10 @@ fn parse_copy_from_before_v9_0() {
901
982
assert_eq ! (
902
983
stmt,
903
984
Statement :: Copy {
904
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
905
- columns: vec![ ] ,
985
+ source: CopySource :: Table {
986
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
987
+ columns: vec![ ] ,
988
+ } ,
906
989
to: false ,
907
990
target: CopyTarget :: File {
908
991
filename: "data.csv" . to_string( ) ,
@@ -928,8 +1011,10 @@ fn parse_copy_from_before_v9_0() {
928
1011
assert_eq ! (
929
1012
pg_and_generic( ) . one_statement_parses_to( sql, "" ) ,
930
1013
Statement :: Copy {
931
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
932
- columns: vec![ ] ,
1014
+ source: CopySource :: Table {
1015
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
1016
+ columns: vec![ ] ,
1017
+ } ,
933
1018
to: false ,
934
1019
target: CopyTarget :: File {
935
1020
filename: "data.csv" . to_string( ) ,
@@ -954,8 +1039,10 @@ fn parse_copy_to_before_v9_0() {
954
1039
assert_eq ! (
955
1040
stmt,
956
1041
Statement :: Copy {
957
- table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
958
- columns: vec![ ] ,
1042
+ source: CopySource :: Table {
1043
+ table_name: ObjectName ( vec![ "users" . into( ) ] ) ,
1044
+ columns: vec![ ] ,
1045
+ } ,
959
1046
to: true ,
960
1047
target: CopyTarget :: File {
961
1048
filename: "data.csv" . to_string( ) ,
0 commit comments