~rdoering/ubuntu/intrepid/erlang/fix-535090

« back to all changes in this revision

Viewing changes to lib/odbc/c_src/odbcserver.c

  • Committer: Bazaar Package Importer
  • Author(s): Soren Hansen
  • Date: 2007-05-01 16:57:10 UTC
  • mfrom: (1.1.9 upstream)
  • Revision ID: james.westby@ubuntu.com-20070501165710-2sapk0hp2gf3o0ip
Tags: 1:11.b.4-2ubuntu1
* Merge with Debian Unstable. Remaining changes:
  - Add -fno-stack-protector to fix broken crypto_drv.
* DebianMaintainerField update.

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
 
27
27
  Erlang will start this c-process as a port-program and send information
28
28
  regarding inet-port nummbers through the erlang-port.
29
 
  After that c-process will communicate via sockets with erlang. 
 
29
  After that c-process will communicate via sockets with erlang. The
 
30
  reason for this is that some odbc-drivers do unexpected things with
 
31
  stdin/stdout messing up the erlang-port communication.
30
32
  
31
33
  
32
34
  Command protocol between Erlang and C
92
94
 
93
95
#include <stdlib.h>
94
96
#include <string.h>
 
97
#include <stdio.h>
95
98
 
96
99
#if defined WIN32
97
 
#include <winsock2.h>
 
100
#include <winsock2.h> 
 
101
/*  #include <ws2tcpip.h >  When we can support a newer c-compiler*/
98
102
#include <windows.h> 
99
103
#include <fcntl.h>
100
104
#include <sql.h>
113
117
#include "odbcserver.h"
114
118
 
115
119
/* ---------------- Main functions ---------------------------------------*/
116
 
 
117
 
static void spawn_odbc_connection(int port);
 
120
static void spawn_sup(const char *port);
118
121
#ifdef WIN32
119
 
DWORD WINAPI database_handler(int port);
 
122
DWORD WINAPI database_handler(const char *port);
120
123
#else
121
 
void database_handler(int port);
 
124
void database_handler(const char *port);
122
125
#endif
123
126
static db_result_msg handle_db_request(byte *reqstring, db_state *state);
124
 
 
 
127
static void supervise(const char *port);
125
128
/* ----------------- ODBC functions --------------------------------------*/
126
129
 
127
130
static db_result_msg db_connect(byte *connStrIn, db_state *state);
168
171
/* ------------- Socket communication functions --------------------------*/
169
172
 
170
173
#ifdef WIN32
171
 
static void connect_to_erlang(SOCKET socket, int port); 
172
 
static SOCKET create_socket(void);
 
174
static SOCKET connect_to_erlang(const char *port); 
173
175
static void send_msg(db_result_msg *msg, SOCKET socket);
174
 
static byte * receive_msg(SOCKET socket);
175
 
static Boolean receive_msg_part(SOCKET socket, byte * buffer, size_t msg_len);
 
176
static byte *receive_msg(SOCKET socket);
 
177
static Boolean receive_msg_part(SOCKET socket,
 
178
                                byte * buffer, size_t msg_len);
176
179
static Boolean send_msg_part(SOCKET socket, byte * buffer, size_t msg_len);
177
180
static void close_socket(SOCKET socket);
178
181
static void init_winsock(void);
179
182
#elif UNIX
180
 
static void connect_to_erlang(int socket, int port);
181
 
static int create_socket(void);
 
183
static int connect_to_erlang(const char *port);
182
184
static void send_msg(db_result_msg *msg, int socket);
183
 
static byte * receive_msg(int socket);
 
185
static byte *receive_msg(int socket);
184
186
static Boolean receive_msg_part(int socket, byte * buffer, size_t msg_len);
185
187
static Boolean send_msg_part(int socket, byte * buffer, size_t msg_len);
186
188
static void close_socket(int socket); 
203
205
static void init_param_column(param_array *params, byte *buffer, int *index,
204
206
                              int num_param_values);
205
207
 
206
 
static param_status init_param_statement(int cols,
207
 
                                           int num_param_values, 
208
 
                                           db_state *state);
 
208
static void init_param_statement(int cols,
 
209
                                 int num_param_values, 
 
210
                                 db_state *state,
 
211
                                 param_status *status);
209
212
 
210
213
static void map_dec_num_2_c_column(col_type *type, int precision,
211
214
                                   int scale);
245
248
int main(void)
246
249
{
247
250
    byte *msg = NULL;
248
 
    int reason, msg_len, supervisor_port, odbc_port;
 
251
    char *temp = NULL, *supervisor_port = NULL, *odbc_port = NULL;
 
252
    size_t length;
249
253
#ifdef WIN32
250
 
    SOCKET socket;
251
 
    init_winsock();
252
254
    _setmode(_fileno( stdin),  _O_BINARY);
253
 
#elif UNIX
254
 
    int socket;
255
255
#endif
256
256
    
257
257
    msg = receive_erlang_port_msg();
258
 
  
259
 
    supervisor_port = atoi(strtok(msg, ";"));
260
 
    odbc_port =  atoi(strtok(NULL, ";"));
261
 
    
262
 
    free(msg);
263
 
 
264
 
    socket = create_socket();
265
 
  
266
 
    connect_to_erlang(socket, supervisor_port);
267
 
 
268
 
    spawn_odbc_connection(odbc_port);
269
 
    
270
 
    msg = receive_msg(socket);
271
 
  
272
 
    if(msg[0] == SHUTDOWN) {
273
 
        reason = EXIT_SUCCESS;
274
 
    } else {
275
 
        reason = EXIT_FAILURE; /* Should not happen */
276
 
    }
277
 
    free(msg);
278
 
    close_socket(socket);
279
 
    clean_socket_lib();
280
 
    DO_EXIT(reason);
 
258
 
 
259
    temp = strtok(msg, ";");
 
260
    length = strlen(temp);
 
261
    supervisor_port = safe_malloc(length + 1);
 
262
    strcpy(supervisor_port, temp);
 
263
 
 
264
    temp = strtok(NULL, ";");
 
265
    length = strlen(temp);
 
266
    odbc_port = safe_malloc(length + 1);
 
267
    strcpy(odbc_port, temp);
 
268
    
 
269
    free(msg);
 
270
 
 
271
    spawn_sup(supervisor_port);
 
272
    database_handler(odbc_port);
281
273
}
282
 
  
283
274
 
284
275
#ifdef WIN32
285
 
static void spawn_odbc_connection(int port)
 
276
static void spawn_sup(const char *port)
286
277
{
287
278
    DWORD threadId;
288
 
    (HANDLE)_beginthreadex(NULL, 0, database_handler, port, 0, &threadId);
 
279
    (HANDLE)_beginthreadex(NULL, 0, supervise, port, 0, &threadId);
289
280
}
290
281
#elif UNIX
291
 
static void spawn_odbc_connection(int port)
 
282
static void spawn_sup(const char *port)
292
283
{
293
284
    pthread_t thread;
294
285
    int result;
295
286
    
296
287
    result = pthread_create(&thread, NULL,
297
 
                            (void *(*)(void *))database_handler,
 
288
                            (void *(*)(void *))supervise,
298
289
                            (void *)port);
299
290
    if (result != 0)
300
291
        DO_EXIT(EXIT_THREAD);
301
292
}
302
293
#endif   
303
294
 
304
 
 
305
 
#ifdef WIN32
306
 
DWORD WINAPI database_handler(int port)
 
295
void supervise(const char *port) {
 
296
    byte *msg = NULL;
 
297
    int reason;
 
298
#ifdef WIN32
 
299
    SOCKET socket;
 
300
    init_winsock();
 
301
#elif UNIX
 
302
    int socket; 
 
303
#endif
 
304
    
 
305
    socket = connect_to_erlang(port);
 
306
    msg = receive_msg(socket);
 
307
 
 
308
    if(msg[0] == SHUTDOWN) {
 
309
        reason = EXIT_SUCCESS;
 
310
    } else {
 
311
        reason = EXIT_FAILURE; /* Should not happen */
 
312
    }
 
313
 
 
314
    free(msg);
 
315
    close_socket(socket);
 
316
    clean_socket_lib();
 
317
    DO_EXIT(reason);    
 
318
}
 
319
 
 
320
#ifdef WIN32
 
321
DWORD WINAPI database_handler(const char *port)
307
322
#else
308
 
    void database_handler(int port) 
 
323
    void database_handler(const char *port) 
309
324
#endif
310
325
311
326
    db_result_msg msg;
312
327
    byte *request_buffer = NULL;
313
328
    db_state state =
314
 
    {NULL, NULL, NULL, NULL, 0, {NULL, 0, 0}, FALSE, FALSE, FALSE, FALSE};
 
329
    {NULL, NULL, NULL, NULL, 0, {NULL, 0, 0},
 
330
     FALSE, FALSE, FALSE, FALSE, FALSE};
315
331
    byte request_id;
316
332
#ifdef WIN32
317
333
    SOCKET socket;
 
334
    init_winsock();
318
335
#elif UNIX
319
336
    int socket;
320
337
#endif
321
338
 
322
 
    socket = create_socket();
323
 
    connect_to_erlang(socket, port);
 
339
    socket = connect_to_erlang(port);
324
340
  
325
341
    do {      
326
342
        request_buffer = receive_msg(socket);
336
352
            free(msg.buffer);
337
353
            msg.buffer = NULL;
338
354
        }   
339
 
    
 
355
        
340
356
        free(request_buffer);
341
357
        request_buffer = NULL;
342
358
    
534
550
 
535
551
    ei_x_new_with_version(&dynamic_buffer(state));
536
552
 
537
 
    if (result == SQL_NO_DATA_FOUND) { /* OTP-5759, fails when 0 rows deleted */
538
 
        ei_x_encode_tuple_header(&dynamic_buffer(state), 2);
539
 
        ei_x_encode_atom(&dynamic_buffer(state), "updated");
540
 
        ei_x_encode_long(&dynamic_buffer(state), 0);
 
553
    /* OTP-5759, fails when 0 rows deleted */
 
554
    if (result == SQL_NO_DATA_FOUND) {
 
555
        msg = encode_result(state);
541
556
    } else {
542
557
        /* Handle multiple result sets */
543
558
        do {
563
578
        ei_x_free(&(dynamic_buffer(state))); 
564
579
        return msg;
565
580
    } else {
566
 
        msg.buffer = (byte *)dynamic_buffer(state).buff;
 
581
        msg.buffer = dynamic_buffer(state).buff;
567
582
        msg.length = dynamic_buffer(state).index;
568
583
        msg.dyn_alloc = TRUE;
569
584
        return msg;
687
702
        ei_x_free(&(dynamic_buffer(state))); 
688
703
        return msg;
689
704
    } else {
690
 
        msg.buffer = (byte *)dynamic_buffer(state).buff;
691
 
        msg.length = dynamic_buffer(state).index;
 
705
        msg.buffer = dynamic_buffer(state).buff;
 
706
        msg.length = dynamic_buffer(state).index; 
692
707
        msg.dyn_alloc = TRUE;
693
708
        return msg;
694
709
    }
700
715
{
701
716
    byte *sql; 
702
717
    db_result_msg msg; 
703
 
    int i,j, ver, num_param_values,
 
718
    int i, num_param_values, ver = 0,
704
719
        erl_type = 0, index = 0, size = 0, cols = 0; 
705
720
    long long_num_param_values;  
706
721
    param_status param_status;
707
722
    diagnos diagnos;
708
723
    param_array *params; 
709
 
    
 
724
 
710
725
    if (associated_result_set(state)) {
711
726
        clean_state(state);
712
727
    }
713
728
    associated_result_set(state) = FALSE;
714
 
    
 
729
    param_query(state) = TRUE;
 
730
 
715
731
    msg = encode_empty_message();
716
 
    
 
732
 
717
733
    ei_decode_version(buffer, &index, &ver);
 
734
    
718
735
    ei_decode_tuple_header(buffer, &index, &size);
719
 
    
720
 
    ei_get_type(buffer, &index, &erl_type, &size); 
 
736
 
 
737
    ei_get_type(buffer, &index, &erl_type, &size);
 
738
 
721
739
    sql = (byte*)safe_malloc((sizeof(byte) * (size + 1)));
722
740
    ei_decode_string(buffer, &index, sql); 
723
741
 
724
742
    ei_decode_long(buffer, &index, &long_num_param_values);
 
743
 
725
744
    num_param_values = (int)long_num_param_values;
726
745
    ei_decode_list_header(buffer, &index, &cols);
727
746
 
728
 
 
729
 
    param_status =
730
 
        init_param_statement(cols, num_param_values, state);
731
747
    
 
748
    init_param_statement(cols, num_param_values, state, &param_status);
 
749
 
732
750
    params = bind_parameter_arrays(buffer, &index, cols,  
733
751
                                   num_param_values, state);  
734
 
 
 
752
    
735
753
    if(params != NULL) {
736
754
        if(!sql_success(SQLExecDirect(statement_handle(state),
737
755
                                      sql, SQL_NTS))) {
755
773
                ei_x_new_with_version(&dynamic_buffer(state));
756
774
                msg = encode_result(state);
757
775
                if(msg.length == 0) {
758
 
                    msg.buffer = (byte *)dynamic_buffer(state).buff;
759
 
                    msg.length = dynamic_buffer(state).index;
 
776
                    msg.buffer = dynamic_buffer(state).buff;
 
777
                    msg.length = dynamic_buffer(state).index; 
760
778
                    msg.dyn_alloc = TRUE;
761
779
                } else { /* Error occurred */
762
780
                    ei_x_free(&(dynamic_buffer(state)));
782
800
                                  statement_handle(state)))){
783
801
        DO_EXIT(EXIT_FREE);
784
802
    }
785
 
    statement_handle(state) = NULL;   
 
803
    statement_handle(state) = NULL;
 
804
    param_query(state) = FALSE;
786
805
    return msg;
787
806
}
788
807
 
847
866
    ei_x_encode_empty_list(&dynamic_buffer(state));
848
867
    
849
868
    clean_state(state);
850
 
    msg.buffer = (byte *)dynamic_buffer(state).buff;
851
 
    msg.length = dynamic_buffer(state).index;
 
869
    msg.buffer = dynamic_buffer(state).buff;
 
870
    msg.length = dynamic_buffer(state).index; 
852
871
    msg.dyn_alloc = TRUE;
853
872
    return msg;
854
873
}
918
937
   term to be returned to the erlang client. */
919
938
static db_result_msg encode_result(db_state *state)
920
939
{
921
 
    SQLSMALLINT num_of_columns;
922
 
    SQLINTEGER RowCountPtr;
 
940
    SQLSMALLINT num_of_columns = 0;
 
941
    SQLINTEGER RowCountPtr = 0, paramBatch = 0;
923
942
    db_result_msg msg;
924
 
    int elements, update, num_of_rows;
 
943
    int elements, update, num_of_rows = 0;
925
944
    char *atom;
926
945
 
927
946
    msg = encode_empty_message();
945
964
        DO_EXIT(EXIT_ROWS); 
946
965
    }
947
966
 
948
 
    num_of_rows = (int)RowCountPtr;
949
 
    
 
967
    if(param_query(state) && update) {
 
968
        if(!sql_success(SQLGetInfo(connection_handle(state),
 
969
                                   SQL_PARAM_ARRAY_ROW_COUNTS,
 
970
                                   (SQLPOINTER)&paramBatch,
 
971
                                   sizeof(paramBatch),
 
972
                                   NULL))) {
 
973
            DO_EXIT(EXIT_DRIVER_INFO);
 
974
        }
 
975
        
 
976
        if(paramBatch == SQL_PARC_BATCH ) {
 
977
            /* Individual row counts (one for each parameter set)
 
978
               are available, sum them up */
 
979
            do {
 
980
                num_of_rows = num_of_rows + (int)RowCountPtr;
 
981
                msg = more_result_sets(state);
 
982
                /* We don't want to continue if an error occured */
 
983
                if (msg.length != 0) { 
 
984
                    return msg;
 
985
                }
 
986
                if(exists_more_result_sets(state)) {
 
987
                    if(!sql_success(SQLRowCount(statement_handle(state),
 
988
                                                &RowCountPtr))) { 
 
989
                        DO_EXIT(EXIT_ROWS); 
 
990
                    }
 
991
                }
 
992
            } while (exists_more_result_sets(state));
 
993
        } else {
 
994
            /* Row counts are rolled up into one (SQL_PARC_NO_BATCH) */
 
995
            num_of_rows = (int)RowCountPtr;
 
996
        }    
 
997
    } else { 
 
998
        num_of_rows = (int)RowCountPtr;
 
999
    }
950
1000
    ei_x_encode_tuple_header(&dynamic_buffer(state), elements);
951
1001
    ei_x_encode_atom(&dynamic_buffer(state), atom);
952
1002
    if (update) {
958
1008
    } else {
959
1009
        msg = encode_result_set(num_of_columns, state);
960
1010
    }
961
 
    
962
1011
    return msg;
963
1012
}
964
1013
 
967
1016
static db_result_msg encode_result_set(SQLSMALLINT num_of_columns,
968
1017
                                       db_state *state)
969
1018
{
970
 
 
971
1019
    db_result_msg msg;
972
1020
 
973
1021
    columns(state) = alloc_column_buffer(num_of_columns);
1466
1514
}
1467
1515
 
1468
1516
/* ------------- Socket communication functions --------------------------*/
1469
 
 
1470
 
#ifdef WIN32
1471
 
static SOCKET create_socket(void)
1472
 
{
1473
 
    return socket(AF_INET, SOCK_STREAM, 0);
1474
 
    
1475
 
}
1476
 
#elif UNIX
1477
 
static int create_socket(void)
1478
 
{
1479
 
    struct protoent *protocol;
1480
 
    
1481
 
    protocol = getprotobyname("tcp");
1482
 
    return socket(AF_INET, SOCK_STREAM, protocol->p_proto);
1483
 
}
1484
 
#endif   
1485
 
 
1486
 
 
1487
 
#ifdef WIN32
1488
 
static void connect_to_erlang(SOCKET socket, int port)
1489
 
#elif UNIX
1490
 
static void connect_to_erlang(int socket, int port)
1491
 
#endif
1492
 
{
 
1517
#ifdef WIN32
 
1518
/* Currently only an old windows compiler is supported so we do not have ipv6
 
1519
  capabilities */
 
1520
static SOCKET connect_to_erlang(const char *port)
 
1521
{
 
1522
    SOCKET sock;
1493
1523
    struct sockaddr_in sin;
1494
1524
    
 
1525
    sock = socket(AF_INET, SOCK_STREAM, 0);
 
1526
    
1495
1527
    memset(&sin, 0, sizeof(sin));
1496
 
    sin.sin_port = htons ((unsigned short)port);
 
1528
    sin.sin_port = htons ((unsigned short)atoi(port));
1497
1529
    sin.sin_family = AF_INET;
1498
1530
    sin.sin_addr.s_addr = inet_addr("127.0.0.1");
1499
1531
    
1500
 
    if (connect(socket, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
1501
 
        close_socket(socket);
1502
 
        DO_EXIT(EXIT_SOCKET_CONNECT);
1503
 
    }    
1504
 
}
 
1532
    if (connect(sock, (struct sockaddr*)&sin, sizeof(sin)) != 0) {
 
1533
        close_socket(sock);
 
1534
        DO_EXIT(EXIT_SOCKET_CONNECT);
 
1535
    }
 
1536
    return sock;
 
1537
}
 
1538
#elif UNIX
 
1539
static int connect_to_erlang(const char *port)
 
1540
{
 
1541
    int sock;
 
1542
    
 
1543
    struct addrinfo hints;
 
1544
    struct addrinfo *erlang_ai, *first;
 
1545
    
 
1546
    memset(&hints, 0, sizeof(hints));
 
1547
    hints.ai_family = PF_UNSPEC; /* PF_INET or PF_INET6 */
 
1548
    hints.ai_socktype = SOCK_STREAM;
 
1549
    hints.ai_protocol = IPPROTO_TCP;
 
1550
    
 
1551
    if (getaddrinfo("localhost", port, &hints, &first) != 0) {
 
1552
        DO_EXIT(EXIT_FAILURE);
 
1553
    }
 
1554
    
 
1555
    for (erlang_ai = first; erlang_ai; erlang_ai = erlang_ai->ai_next) {
 
1556
        
 
1557
        sock = socket(erlang_ai->ai_family, erlang_ai->ai_socktype,
 
1558
                      erlang_ai->ai_protocol);
 
1559
        if (sock < 0)
 
1560
            continue;
 
1561
        if (connect(sock,  (struct sockaddr*)erlang_ai->ai_addr,
 
1562
                    erlang_ai->ai_addrlen) < 0) {
 
1563
            close(sock); 
 
1564
            sock = -1;
 
1565
            continue;
 
1566
        } else {
 
1567
            break;
 
1568
        }
 
1569
    }
 
1570
    freeaddrinfo(first); 
 
1571
    
 
1572
    if (sock < 0){
 
1573
        close_socket(sock); 
 
1574
        DO_EXIT(EXIT_SOCKET_CONNECT); 
 
1575
    }
 
1576
    
 
1577
    return sock;
 
1578
}
 
1579
#endif
1505
1580
 
1506
1581
#ifdef WIN32
1507
1582
static void close_socket(SOCKET socket)
1518
1593
#ifdef WIN32
1519
1594
static byte * receive_msg(SOCKET socket) 
1520
1595
#elif UNIX
1521
 
    static byte * receive_msg(int socket) 
 
1596
static byte * receive_msg(int socket) 
1522
1597
#endif
1523
1598
{
1524
1599
    byte lengthstr[LENGTH_INDICATOR_SIZE];
1525
1600
    size_t msg_len = 0;
1526
1601
    int i;
1527
 
    byte * buffer;
 
1602
    byte *buffer = NULL;
1528
1603
    
1529
1604
    if(!receive_msg_part(socket, lengthstr, LENGTH_INDICATOR_SIZE)) {
1530
1605
        close_socket(socket);
1572
1647
#ifdef WIN32
1573
1648
static void send_msg(db_result_msg *msg, SOCKET socket)
1574
1649
#elif UNIX   
1575
 
    static void send_msg(db_result_msg *msg, int socket)
 
1650
static void send_msg(db_result_msg *msg, int socket)
1576
1651
#endif
1577
1652
{
1578
1653
    byte lengthstr[LENGTH_INDICATOR_SIZE];
1579
1654
    int len;
1580
 
 
1581
 
    len = msg->length;
 
1655
    len = msg ->length;
1582
1656
    
1583
1657
    lengthstr[0] = (len >> 24) & 0x000000FF;
1584
1658
    lengthstr[1] = (len >> 16) & 0x000000FF;
1900
1974
    params->offset = 0;
1901
1975
}
1902
1976
 
1903
 
static param_status  init_param_statement(int cols, int num_param_values, 
1904
 
                                           db_state *state)
 
1977
static void init_param_statement(int cols, int num_param_values, 
 
1978
                                 db_state *state, param_status *status)
1905
1979
{
1906
 
    param_status status;
1907
 
    
1908
 
    status.param_status_array =
1909
 
        (SQLUSMALLINT *)malloc(num_param_values * sizeof(SQLUSMALLINT));
1910
 
    status.params_processed = 0;
 
1980
    status -> param_status_array =
 
1981
        (SQLUSMALLINT *)safe_malloc(num_param_values * sizeof(SQLUSMALLINT));
 
1982
    status -> params_processed = 0;
1911
1983
    
1912
1984
    if(!sql_success(SQLAllocHandle(SQL_HANDLE_STMT,
1913
1985
                                   connection_handle(state),
1921
1993
                                   SQL_PARAM_BIND_BY_COLUMN, 0))) {
1922
1994
        DO_EXIT(EXIT_PARAM_ARRAY);
1923
1995
    }
1924
 
    
 
1996
 
 
1997
    /* Note the (int *) cast is correct as the API function SQLSetStmtAttr
 
1998
       takes either an interger or a pointer depending on the attribute */
1925
1999
    if(!sql_success(SQLSetStmtAttr(statement_handle(state),
1926
2000
                                   SQL_ATTR_PARAMSET_SIZE,
1927
2001
                                   (int *)num_param_values,
1931
2005
    
1932
2006
    if(!sql_success(SQLSetStmtAttr(statement_handle(state),
1933
2007
                                   SQL_ATTR_PARAM_STATUS_PTR,
1934
 
                                   status.param_status_array, 0))) {
 
2008
                                   (status -> param_status_array), 0))) {
1935
2009
        DO_EXIT(EXIT_PARAM_ARRAY);
1936
2010
    }
1937
2011
    
1938
2012
    if(!sql_success(SQLSetStmtAttr(statement_handle(state),
1939
2013
                                   SQL_ATTR_PARAMS_PROCESSED_PTR,
1940
 
                                   &status.params_processed, 0))) {
 
2014
                                   &(status -> params_processed), 0))) {
1941
2015
        DO_EXIT(EXIT_PARAM_ARRAY);
1942
2016
    }
1943
 
    
1944
 
    return status;
1945
2017
}
1946
2018
 
1947
2019
static void map_dec_num_2_c_column(col_type *type, int precision, int scale)
2193
2265
    } else { /* Scrollable cursors disabled by the user */
2194
2266
        ei_x_encode_atom(&dynamic_buffer(state), "false");  
2195
2267
        ei_x_encode_atom(&dynamic_buffer(state), "false");
2196
 
    }
2197
 
  
2198
 
    msg.buffer = (byte *)dynamic_buffer(state).buff;
2199
 
    msg.length = dynamic_buffer(state).index;
 
2268
    } 
 
2269
    msg.buffer = dynamic_buffer(state).buff;
 
2270
    msg.length = dynamic_buffer(state).index; 
2200
2271
    msg.dyn_alloc = TRUE;
2201
2272
    return msg;
2202
2273
}