@@ -504,6 +504,7 @@ ProcessCopyOptions(ParseState *pstate,
504
504
bool on_error_specified = false;
505
505
bool log_verbosity_specified = false;
506
506
bool reject_limit_specified = false;
507
+ bool force_array_specified = false;
507
508
ListCell * option ;
508
509
509
510
/* Support external use for option sanity checking */
@@ -525,11 +526,13 @@ ProcessCopyOptions(ParseState *pstate,
525
526
errorConflictingDefElem (defel , pstate );
526
527
format_specified = true;
527
528
if (strcmp (fmt , "text" ) == 0 )
528
- /* default format */ ;
529
+ opts_out -> format = COPY_FORMAT_TEXT ;
529
530
else if (strcmp (fmt , "csv" ) == 0 )
530
- opts_out -> csv_mode = true ;
531
+ opts_out -> format = COPY_FORMAT_CSV ;
531
532
else if (strcmp (fmt , "binary" ) == 0 )
532
- opts_out -> binary = true;
533
+ opts_out -> format = COPY_FORMAT_BINARY ;
534
+ else if (strcmp (fmt , "json" ) == 0 )
535
+ opts_out -> format = COPY_FORMAT_JSON ;
533
536
else
534
537
ereport (ERROR ,
535
538
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
@@ -656,6 +659,13 @@ ProcessCopyOptions(ParseState *pstate,
656
659
defel -> defname ),
657
660
parser_errposition (pstate , defel -> location )));
658
661
}
662
+ else if (strcmp (defel -> defname , "force_array" ) == 0 )
663
+ {
664
+ if (force_array_specified )
665
+ errorConflictingDefElem (defel , pstate );
666
+ force_array_specified = true;
667
+ opts_out -> force_array = defGetBoolean (defel );
668
+ }
659
669
else if (strcmp (defel -> defname , "on_error" ) == 0 )
660
670
{
661
671
if (on_error_specified )
@@ -689,31 +699,47 @@ ProcessCopyOptions(ParseState *pstate,
689
699
* Check for incompatible options (must do these three before inserting
690
700
* defaults)
691
701
*/
692
- if (opts_out -> binary && opts_out -> delim )
702
+ if (opts_out -> format == COPY_FORMAT_BINARY && opts_out -> delim )
693
703
ereport (ERROR ,
694
704
(errcode (ERRCODE_SYNTAX_ERROR ),
695
705
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
696
706
errmsg ("cannot specify %s in BINARY mode" , "DELIMITER" )));
697
707
698
- if (opts_out -> binary && opts_out -> null_print )
708
+ if (opts_out -> format == COPY_FORMAT_JSON && opts_out -> delim )
709
+ ereport (ERROR ,
710
+ errcode (ERRCODE_SYNTAX_ERROR ),
711
+ /*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
712
+ errmsg ("cannot specify %s in JSON mode" , "DELIMITER" ));
713
+
714
+ if (opts_out -> format == COPY_FORMAT_BINARY && opts_out -> null_print )
699
715
ereport (ERROR ,
700
716
(errcode (ERRCODE_SYNTAX_ERROR ),
701
717
errmsg ("cannot specify %s in BINARY mode" , "NULL" )));
702
718
703
- if (opts_out -> binary && opts_out -> default_print )
719
+ if (opts_out -> format == COPY_FORMAT_JSON && opts_out -> null_print )
720
+ ereport (ERROR ,
721
+ errcode (ERRCODE_SYNTAX_ERROR ),
722
+ errmsg ("cannot specify %s in JSON mode" , "NULL" ));
723
+
724
+ if (opts_out -> format == COPY_FORMAT_BINARY && opts_out -> default_print )
704
725
ereport (ERROR ,
705
726
(errcode (ERRCODE_SYNTAX_ERROR ),
706
727
errmsg ("cannot specify %s in BINARY mode" , "DEFAULT" )));
707
728
729
+ if (opts_out -> format == COPY_FORMAT_JSON && opts_out -> default_print )
730
+ ereport (ERROR ,
731
+ errcode (ERRCODE_SYNTAX_ERROR ),
732
+ errmsg ("cannot specify %s in JSON mode" , "DEFAULT" ));
733
+
708
734
/* Set defaults for omitted options */
709
735
if (!opts_out -> delim )
710
- opts_out -> delim = opts_out -> csv_mode ? "," : "\t" ;
736
+ opts_out -> delim = opts_out -> format == COPY_FORMAT_CSV ? "," : "\t" ;
711
737
712
738
if (!opts_out -> null_print )
713
- opts_out -> null_print = opts_out -> csv_mode ? "" : "\\N" ;
739
+ opts_out -> null_print = opts_out -> format == COPY_FORMAT_CSV ? "" : "\\N" ;
714
740
opts_out -> null_print_len = strlen (opts_out -> null_print );
715
741
716
- if (opts_out -> csv_mode )
742
+ if (opts_out -> format == COPY_FORMAT_CSV )
717
743
{
718
744
if (!opts_out -> quote )
719
745
opts_out -> quote = "\"" ;
@@ -761,51 +787,56 @@ ProcessCopyOptions(ParseState *pstate,
761
787
* future-proofing. Likewise we disallow all digits though only octal
762
788
* digits are actually dangerous.
763
789
*/
764
- if (! opts_out -> csv_mode &&
790
+ if (opts_out -> format != COPY_FORMAT_CSV &&
765
791
strchr ("\\.abcdefghijklmnopqrstuvwxyz0123456789" ,
766
792
opts_out -> delim [0 ]) != NULL )
767
793
ereport (ERROR ,
768
794
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
769
795
errmsg ("COPY delimiter cannot be \"%s\"" , opts_out -> delim )));
770
796
771
797
/* Check header */
772
- if (opts_out -> binary && opts_out -> header_line )
798
+ if (opts_out -> format == COPY_FORMAT_BINARY && opts_out -> header_line )
773
799
ereport (ERROR ,
774
800
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
775
801
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
776
802
errmsg ("cannot specify %s in BINARY mode" , "HEADER" )));
777
803
804
+ if (opts_out -> format == COPY_FORMAT_JSON && opts_out -> header_line )
805
+ ereport (ERROR ,
806
+ errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
807
+ errmsg ("cannot specify %s in JSON mode" , "HEADER" ));
808
+
778
809
/* Check quote */
779
- if (! opts_out -> csv_mode && opts_out -> quote != NULL )
810
+ if (opts_out -> format != COPY_FORMAT_CSV && opts_out -> quote != NULL )
780
811
ereport (ERROR ,
781
812
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
782
813
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
783
814
errmsg ("COPY %s requires CSV mode" , "QUOTE" )));
784
815
785
- if (opts_out -> csv_mode && strlen (opts_out -> quote ) != 1 )
816
+ if (opts_out -> format == COPY_FORMAT_CSV && strlen (opts_out -> quote ) != 1 )
786
817
ereport (ERROR ,
787
818
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
788
819
errmsg ("COPY quote must be a single one-byte character" )));
789
820
790
- if (opts_out -> csv_mode && opts_out -> delim [0 ] == opts_out -> quote [0 ])
821
+ if (opts_out -> format == COPY_FORMAT_CSV && opts_out -> delim [0 ] == opts_out -> quote [0 ])
791
822
ereport (ERROR ,
792
823
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
793
824
errmsg ("COPY delimiter and quote must be different" )));
794
825
795
826
/* Check escape */
796
- if (! opts_out -> csv_mode && opts_out -> escape != NULL )
827
+ if (opts_out -> format != COPY_FORMAT_CSV && opts_out -> escape != NULL )
797
828
ereport (ERROR ,
798
829
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
799
830
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
800
831
errmsg ("COPY %s requires CSV mode" , "ESCAPE" )));
801
832
802
- if (opts_out -> csv_mode && strlen (opts_out -> escape ) != 1 )
833
+ if (opts_out -> format == COPY_FORMAT_CSV && strlen (opts_out -> escape ) != 1 )
803
834
ereport (ERROR ,
804
835
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
805
836
errmsg ("COPY escape must be a single one-byte character" )));
806
837
807
838
/* Check force_quote */
808
- if (! opts_out -> csv_mode && (opts_out -> force_quote || opts_out -> force_quote_all ))
839
+ if (opts_out -> format != COPY_FORMAT_CSV && (opts_out -> force_quote || opts_out -> force_quote_all ))
809
840
ereport (ERROR ,
810
841
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
811
842
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
@@ -819,8 +850,8 @@ ProcessCopyOptions(ParseState *pstate,
819
850
"COPY FROM" )));
820
851
821
852
/* Check force_notnull */
822
- if (! opts_out -> csv_mode && (opts_out -> force_notnull != NIL ||
823
- opts_out -> force_notnull_all ))
853
+ if (opts_out -> format != COPY_FORMAT_CSV && (opts_out -> force_notnull != NIL ||
854
+ opts_out -> force_notnull_all ))
824
855
ereport (ERROR ,
825
856
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
826
857
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
@@ -835,8 +866,8 @@ ProcessCopyOptions(ParseState *pstate,
835
866
"COPY TO" )));
836
867
837
868
/* Check force_null */
838
- if (! opts_out -> csv_mode && (opts_out -> force_null != NIL ||
839
- opts_out -> force_null_all ))
869
+ if (opts_out -> format != COPY_FORMAT_CSV && (opts_out -> force_null != NIL ||
870
+ opts_out -> force_null_all ))
840
871
ereport (ERROR ,
841
872
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
842
873
/*- translator: %s is the name of a COPY option, e.g. ON_ERROR */
@@ -860,7 +891,7 @@ ProcessCopyOptions(ParseState *pstate,
860
891
"NULL" )));
861
892
862
893
/* Don't allow the CSV quote char to appear in the null string. */
863
- if (opts_out -> csv_mode &&
894
+ if (opts_out -> format == COPY_FORMAT_CSV &&
864
895
strchr (opts_out -> null_print , opts_out -> quote [0 ]) != NULL )
865
896
ereport (ERROR ,
866
897
(errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
@@ -877,6 +908,17 @@ ProcessCopyOptions(ParseState *pstate,
877
908
errmsg ("COPY %s cannot be used with %s" , "FREEZE" ,
878
909
"COPY TO" )));
879
910
911
+ /* Check json format */
912
+ if (opts_out -> format == COPY_FORMAT_JSON && is_from )
913
+ ereport (ERROR ,
914
+ errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
915
+ errmsg ("COPY json mode cannot be used with %s" , "COPY FROM" ));
916
+
917
+ if (opts_out -> format != COPY_FORMAT_JSON && opts_out -> force_array )
918
+ ereport (ERROR ,
919
+ errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
920
+ errmsg ("COPY %s can only used with JSON mode" , "FORCE_ARRAY" ));
921
+
880
922
if (opts_out -> default_print )
881
923
{
882
924
if (!is_from )
@@ -896,7 +938,7 @@ ProcessCopyOptions(ParseState *pstate,
896
938
"DEFAULT" )));
897
939
898
940
/* Don't allow the CSV quote char to appear in the default string. */
899
- if (opts_out -> csv_mode &&
941
+ if (opts_out -> format == COPY_FORMAT_CSV &&
900
942
strchr (opts_out -> default_print , opts_out -> quote [0 ]) != NULL )
901
943
ereport (ERROR ,
902
944
(errcode (ERRCODE_FEATURE_NOT_SUPPORTED ),
@@ -913,7 +955,7 @@ ProcessCopyOptions(ParseState *pstate,
913
955
errmsg ("NULL specification and DEFAULT specification cannot be the same" )));
914
956
}
915
957
/* Check on_error */
916
- if (opts_out -> binary && opts_out -> on_error != COPY_ON_ERROR_STOP )
958
+ if (opts_out -> format == COPY_FORMAT_BINARY && opts_out -> on_error != COPY_ON_ERROR_STOP )
917
959
ereport (ERROR ,
918
960
(errcode (ERRCODE_SYNTAX_ERROR ),
919
961
errmsg ("only ON_ERROR STOP is allowed in BINARY mode" )));
0 commit comments