1
1
/* dynamic SQL support routines
2
2
*
3
- * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.33 2009/08/07 10:51:20 meskes Exp $
3
+ * $PostgreSQL: pgsql/src/interfaces/ecpg/ecpglib/descriptor.c,v 1.34 2010/01/15 10:44:34 meskes Exp $
4
4
*/
5
5
6
6
#define POSTGRES_ECPG_INTERNAL
13
13
#include "ecpgerrno.h"
14
14
#include "extern.h"
15
15
#include "sqlca.h"
16
+ #include "sqlda.h"
16
17
#include "sql3types.h"
17
18
18
19
static void descriptor_free (struct descriptor * desc );
@@ -226,6 +227,12 @@ get_char_item(int lineno, void *var, enum ECPGttype vartype, char *value, int va
226
227
return (true);
227
228
}
228
229
230
+ #define RETURN_IF_NO_DATA if (ntuples < 1) \
231
+ { \
232
+ ecpg_raise(lineno, ECPG_NOT_FOUND, ECPG_SQLSTATE_NO_DATA, NULL); \
233
+ return (false); \
234
+ }
235
+
229
236
bool
230
237
ECPGget_desc (int lineno , const char * desc_name , int index ,...)
231
238
{
@@ -244,11 +251,6 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
244
251
return (false);
245
252
246
253
ntuples = PQntuples (ECPGresult );
247
- if (ntuples < 1 )
248
- {
249
- ecpg_raise (lineno , ECPG_NOT_FOUND , ECPG_SQLSTATE_NO_DATA , NULL );
250
- return (false);
251
- }
252
254
253
255
if (index < 1 || index > PQnfields (ECPGresult ))
254
256
{
@@ -283,6 +285,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
283
285
switch (type )
284
286
{
285
287
case (ECPGd_indicator ):
288
+ RETURN_IF_NO_DATA ;
286
289
data_var .ind_type = vartype ;
287
290
data_var .ind_pointer = var ;
288
291
data_var .ind_varcharsize = varcharsize ;
@@ -295,6 +298,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
295
298
break ;
296
299
297
300
case ECPGd_data :
301
+ RETURN_IF_NO_DATA ;
298
302
data_var .type = vartype ;
299
303
data_var .pointer = var ;
300
304
data_var .varcharsize = varcharsize ;
@@ -377,6 +381,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
377
381
case ECPGd_ret_length :
378
382
case ECPGd_ret_octet :
379
383
384
+ RETURN_IF_NO_DATA ;
380
385
/*
381
386
* this is like ECPGstore_result
382
387
*/
@@ -480,6 +485,7 @@ ECPGget_desc(int lineno, const char *desc_name, int index,...)
480
485
sqlca -> sqlerrd [2 ] = ntuples ;
481
486
return (true);
482
487
}
488
+ #undef RETURN_IF_NO_DATA
483
489
484
490
bool
485
491
ECPGset_desc_header (int lineno , const char * desc_name , int count )
@@ -723,8 +729,140 @@ ecpg_find_desc(int line, const char *name)
723
729
}
724
730
725
731
bool
726
- ECPGdescribe (int line , bool input , const char * statement , ...)
732
+ ECPGdescribe (int line , int compat , bool input , const char * connection_name , const char * stmt_name , ...)
727
733
{
728
- ecpg_log ("ECPGdescribe called on line %d for %s: %s\n" , line , input ? "input" : "output" , statement );
729
- return false;
734
+ bool ret = false;
735
+ struct connection * con ;
736
+ struct prepared_statement * prep ;
737
+ PGresult * res ;
738
+ va_list args ;
739
+
740
+ /* DESCRIBE INPUT is not yet supported */
741
+ if (input )
742
+ return ret ;
743
+
744
+ con = ecpg_get_connection (connection_name );
745
+ if (!con )
746
+ return false;
747
+ prep = ecpg_find_prepared_statement (stmt_name , con , NULL );
748
+ if (!prep )
749
+ return ret ;
750
+
751
+ va_start (args , stmt_name );
752
+
753
+ for (;;)
754
+ {
755
+ enum ECPGttype type , dummy_type ;
756
+ void * ptr , * dummy_ptr ;
757
+ long dummy ;
758
+
759
+ /* variable type */
760
+ type = va_arg (args , enum ECPGttype );
761
+
762
+ if (type == ECPGt_EORT )
763
+ break ;
764
+
765
+ /* rest of variable parameters*/
766
+ ptr = va_arg (args , void * );
767
+ dummy = va_arg (args , long );
768
+ dummy = va_arg (args , long );
769
+ dummy = va_arg (args , long );
770
+
771
+ /* variable indicator */
772
+ dummy_type = va_arg (args , enum ECPGttype );
773
+ dummy_ptr = va_arg (args , void * );
774
+ dummy = va_arg (args , long );
775
+ dummy = va_arg (args , long );
776
+ dummy = va_arg (args , long );
777
+
778
+ switch (type )
779
+ {
780
+ case ECPGt_descriptor :
781
+ {
782
+ char * name = ptr ;
783
+ struct descriptor * desc = ecpg_find_desc (line , name );
784
+
785
+ if (desc == NULL )
786
+ break ;
787
+
788
+ res = PQdescribePrepared (con -> connection , stmt_name );
789
+ if (!ecpg_check_PQresult (res , line , con -> connection , compat ))
790
+ break ;
791
+
792
+ if (desc -> result != NULL )
793
+ PQclear (desc -> result );
794
+
795
+ desc -> result = res ;
796
+ ret = true;
797
+ break ;
798
+ }
799
+ case ECPGt_sqlda :
800
+ {
801
+ if (INFORMIX_MODE (compat ))
802
+ {
803
+ struct sqlda_compat * * _sqlda = ptr ;
804
+ struct sqlda_compat * sqlda ;
805
+
806
+ res = PQdescribePrepared (con -> connection , stmt_name );
807
+ if (!ecpg_check_PQresult (res , line , con -> connection , compat ))
808
+ break ;
809
+
810
+ sqlda = ecpg_build_compat_sqlda (line , res , -1 , compat );
811
+ if (sqlda )
812
+ {
813
+ struct sqlda_compat * sqlda_old = * _sqlda ;
814
+ struct sqlda_compat * sqlda_old1 ;
815
+
816
+ while (sqlda_old )
817
+ {
818
+ sqlda_old1 = sqlda_old -> desc_next ;
819
+ free (sqlda_old );
820
+ sqlda_old = sqlda_old1 ;
821
+ }
822
+
823
+ * _sqlda = sqlda ;
824
+ ret = true;
825
+ }
826
+
827
+ PQclear (res );
828
+ }
829
+ else
830
+ {
831
+ struct sqlda_struct * * _sqlda = ptr ;
832
+ struct sqlda_struct * sqlda ;
833
+
834
+ res = PQdescribePrepared (con -> connection , stmt_name );
835
+ if (!ecpg_check_PQresult (res , line , con -> connection , compat ))
836
+ break ;
837
+
838
+ sqlda = ecpg_build_native_sqlda (line , res , -1 , compat );
839
+ if (sqlda )
840
+ {
841
+ struct sqlda_struct * sqlda_old = * _sqlda ;
842
+ struct sqlda_struct * sqlda_old1 ;
843
+
844
+ while (sqlda_old )
845
+ {
846
+ sqlda_old1 = sqlda_old -> desc_next ;
847
+ free (sqlda_old );
848
+ sqlda_old = sqlda_old1 ;
849
+ }
850
+
851
+ * _sqlda = sqlda ;
852
+ ret = true;
853
+ }
854
+
855
+ PQclear (res );
856
+ }
857
+ break ;
858
+ }
859
+ default :
860
+ /* nothing else may come */
861
+ ;
862
+ }
863
+ }
864
+
865
+ va_end (args );
866
+
867
+ return ret ;
730
868
}
0 commit comments