~ubuntu-branches/ubuntu/precise/libdbi-drivers/precise

« back to all changes in this revision

Viewing changes to drivers/pgsql/dbd_pgsql.c

  • Committer: Bazaar Package Importer
  • Author(s): Steve Langasek
  • Date: 2008-08-02 09:00:11 UTC
  • mfrom: (3.1.6 intrepid)
  • Revision ID: james.westby@ubuntu.com-20080802090011-j05v2349u2ptvg05
Tags: 0.8.2-1-4.1
* Non-maintainer upload with maintainer's approval.
* High urgency upload for RC bugfix.
* Pass --freetds-inc-dir to configure, to bypass the ridiculous upstream
  AC_FIND_FILE() checks for files that *aren't used during the build*;
  fixes a build failure with FreeTDS 0.82.  Closes: #493349.

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * Copyright (C) 2001-2002, David A. Parker <david@neongoat.com>.
22
22
 * http://libdbi.sourceforge.net
23
23
 * 
24
 
 * $Id: dbd_pgsql.c,v 1.38 2004/01/04 00:43:20 mhoenicka Exp $
 
24
 * $Id: dbd_pgsql.c,v 1.51 2006/09/21 19:44:13 mhoenicka Exp $
25
25
 */
26
26
 
27
27
#ifdef HAVE_CONFIG_H
38
38
long long strtoll(const char *nptr, char **endptr, int base);
39
39
#endif
40
40
 
 
41
/* In 7.4 PQfreeNotify was deprecated and PQfreemem is used instead.  A
 
42
   macro exists in 7.4 for backwards compatibility. */
 
43
#ifndef PQfreeNotify   /* must be earlier than 7.4 */
 
44
#define PQfreemem PQfreeNotify
 
45
#endif
 
46
 
41
47
#include <stdio.h>
42
48
#include <stdlib.h>
43
49
#include <string.h>
 
50
#include <ctype.h> /* for isdigit() */
44
51
 
45
52
#include <dbi/dbi.h>
46
53
#include <dbi/dbi-dev.h>
61
68
static const char *custom_functions[] = {NULL}; // TODO
62
69
static const char *reserved_words[] = PGSQL_RESERVED_WORDS;
63
70
 
64
 
/* encoding strings, array is terminated by empty string */
 
71
/* encoding strings, array is terminated by a pair of empty strings */
65
72
static const char pgsql_encoding_hash[][16] = {
66
 
  /* from , to */
 
73
  /* PostgreSQL , www.iana.org */
67
74
  "SQL_ASCII", "US-ASCII",
68
75
  "EUC_JP", "EUC-JP",
69
76
  "EUC_KR", "EUC-KR",
85
92
  "KOI8", "KOI8-R",
86
93
  "WIN", "windows-1251",
87
94
  "ALT", "IBM866",
88
 
  ""
 
95
  "", ""
89
96
};
90
97
 
91
98
/* forward declarations of internal functions */
92
99
void _translate_postgresql_type(unsigned int oid, unsigned short *type, unsigned int *attribs);
93
100
void _get_field_info(dbi_result_t *result);
94
101
void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowidx);
 
102
int _dbd_real_connect(dbi_conn_t *conn, const char *db);
95
103
 
96
104
/* this function is available through the PostgreSQL client library, but it
97
105
   is not declared in any of their headers. I hope this won't break anything */
98
 
char *pg_encoding_to_char(int encoding_id);
 
106
const char *pg_encoding_to_char(int encoding_id);
99
107
 
100
108
 
101
109
/* real code starts here */
116
124
}
117
125
 
118
126
int dbd_connect(dbi_conn_t *conn) {
 
127
  return _dbd_real_connect(conn, NULL);
 
128
}
 
129
 
 
130
int _dbd_real_connect(dbi_conn_t *conn, const char *db) {
119
131
        const char *host = dbi_conn_get_option(conn, "host");
120
132
        const char *username = dbi_conn_get_option(conn, "username");
121
133
        const char *password = dbi_conn_get_option(conn, "password");
122
 
        const char *dbname = dbi_conn_get_option(conn, "dbname");
 
134
        const char *dbname;
 
135
        const char *encoding = dbi_conn_get_option(conn, "encoding");
123
136
        int port = dbi_conn_get_option_numeric(conn, "port");
124
137
 
125
138
        /* pgsql specific options */
131
144
        char *conninfo;
132
145
        char *conninfo_kludge;
133
146
 
134
 
        if (port > 0) asprintf(&port_str, "%d", port);
135
 
        else port_str = NULL;
 
147
        if (db && *db) {
 
148
          dbname = db;
 
149
        }
 
150
        else {
 
151
          dbname = dbi_conn_get_option(conn, "dbname");
 
152
        }
 
153
 
 
154
        if (port > 0) {
 
155
          asprintf(&port_str, "%d", port);
 
156
        }
 
157
        else {
 
158
          port_str = NULL;
 
159
        }
136
160
 
137
161
        /* YUCK YUCK YUCK YUCK YUCK. stupid libpq. */
138
162
        if (host && port_str) asprintf(&conninfo_kludge, "host='%s' port='%s'", host, port_str);
168
192
                if (dbname) conn->current_db = strdup(dbname);
169
193
        }
170
194
        
 
195
        if (encoding && *encoding) {
 
196
          /* set connection encoding */
 
197
          if (strcmp(encoding, "auto")) {
 
198
            if (PQsetClientEncoding(pgconn, dbd_encoding_from_iana(encoding))) {
 
199
/*            printf("could not set client encoding to %s\n", dbd_encoding_from_iana(encoding)); */
 
200
            }
 
201
          }
 
202
          /* else: by default, pgsql uses the database encoding
 
203
             as the client encoding, nothing to do */
 
204
        }
 
205
 
171
206
        return 0;
172
207
}
173
208
 
176
211
        return 0;
177
212
}
178
213
 
179
 
int dbd_fetch_row(dbi_result_t *result, unsigned long long rownum) {
 
214
int dbd_fetch_row(dbi_result_t *result, unsigned long long rowidx) {
180
215
        dbi_row_t *row = NULL;
181
216
 
182
 
        if (result->result_state == NOTHING_RETURNED) return -1;
 
217
        if (result->result_state == NOTHING_RETURNED) return 0;
183
218
        
184
219
        if (result->result_state == ROWS_RETURNED) {
185
220
                /* get row here */
186
221
                row = _dbd_row_allocate(result->numfields);
187
 
                _get_row_data(result, row, rownum);
188
 
                _dbd_row_finalize(result, row, rownum);
 
222
                _get_row_data(result, row, rowidx);
 
223
                _dbd_row_finalize(result, row, rowidx);
189
224
        }
190
225
        
191
226
        return 1; /* 0 on error, 1 on successful fetchrow */
196
231
        return 0;
197
232
}
198
233
 
199
 
int dbd_goto_row(dbi_result_t *result, unsigned long long row) {
 
234
int dbd_goto_row(dbi_result_t *result, unsigned long long rowidx) {
200
235
        /* libpq doesn't have to do anything, the row index is specified when
201
236
         * fetching fields */
202
237
        return 1;
212
247
}
213
248
 
214
249
const char *dbd_get_encoding(dbi_conn_t *conn){
215
 
 
216
 
        char* my_enc;
 
250
        const char* my_enc;
 
251
        int n_encoding;
 
252
        const char* encodingopt;
 
253
        char* sql_cmd;
 
254
        dbi_result dbires = NULL;
217
255
        PGconn *pgconn = (PGconn*) conn->connection;
218
256
        
219
257
        if(!pgconn) return NULL;
220
258
 
221
 
        /* this is somewhat murky as the pg_encoding_to_char()
222
 
         function is not declared properly by the PostgreSQL client
223
 
         library headers.  This may indicate that it is not supposed
224
 
         to be exported or that it may disappear without a trace
225
 
         eventually. If it breaks, use a query "SHOW CLIENT_ENCODING"
226
 
         instead */
227
 
        my_enc = pg_encoding_to_char(PQclientEncoding(pgconn));
 
259
        encodingopt = dbi_conn_get_option(conn, "encoding");
 
260
        if (encodingopt && !strcmp(encodingopt, "auto")) {
 
261
 
 
262
          /* this is somewhat murky as the pg_encoding_to_char()
 
263
             function is not declared properly by the PostgreSQL client
 
264
             library headers.  This may indicate that it is not supposed
 
265
             to be exported or that it may disappear without a trace
 
266
             eventually. If it breaks, use a query "SHOW CLIENT_ENCODING"
 
267
             instead */
 
268
          my_enc = pg_encoding_to_char(PQclientEncoding(pgconn));
 
269
/*        printf("use PQclientEncoding, auto\n"); */
 
270
        }
 
271
        else if (encodingopt) {
 
272
          my_enc = pg_encoding_to_char(PQclientEncoding(pgconn));
 
273
/*        printf("use PQclientEncoding, %s\n", encodingopt); */
 
274
        }
 
275
        else {
 
276
          asprintf(&sql_cmd, "SELECT encoding FROM pg_database WHERE datname='%s'", conn->current_db);
 
277
          
 
278
          dbires = dbi_conn_query(conn, sql_cmd);
 
279
          free(sql_cmd);
 
280
 
 
281
          if (dbires && dbi_result_next_row(dbires)) {
 
282
            n_encoding = dbi_result_get_int_idx(dbires, 1);
 
283
            my_enc = pg_encoding_to_char(n_encoding);
 
284
/*          printf("select returned encoding %d<<%s\n", n_encoding, my_enc); */
 
285
          }
 
286
        }
228
287
 
229
288
        if (!my_enc) {
230
289
          return NULL;
231
290
        }
232
291
        else {
233
 
          int i = 0;
234
 
 
235
 
          /* loop over all even entries in hash and compare to my_enc */
236
 
          while (*pgsql_encoding_hash[i]) {
237
 
            if (!strcmp(pgsql_encoding_hash[i], my_enc)) {
238
 
              /* return corresponding odd entry */
239
 
              return pgsql_encoding_hash[i+1];
240
 
            }
241
 
            i+=2;
242
 
          }
243
 
 
244
 
          /* don't know how to translate, return original string */
245
 
          return my_enc;
246
 
        }
 
292
          return dbd_encoding_to_iana(my_enc);
 
293
        }
 
294
}
 
295
 
 
296
const char* dbd_encoding_to_iana(const char *db_encoding) {
 
297
  int i = 0;
 
298
 
 
299
  /* loop over all even entries in hash and compare to penc */
 
300
  while (*pgsql_encoding_hash[i]) {
 
301
    if (!strcmp(pgsql_encoding_hash[i], db_encoding)) {
 
302
      /* return corresponding odd entry */
 
303
      return pgsql_encoding_hash[i+1];
 
304
    }
 
305
    i+=2;
 
306
  }
 
307
 
 
308
  /* don't know how to translate, return original encoding */
 
309
  return db_encoding;
 
310
}
 
311
 
 
312
const char* dbd_encoding_from_iana(const char *iana_encoding) {
 
313
  int i = 0;
 
314
 
 
315
  /* loop over all odd entries in hash and compare to ienc */
 
316
  while (*pgsql_encoding_hash[i+1]) {
 
317
    if (!strcmp(pgsql_encoding_hash[i+1], iana_encoding)) {
 
318
      /* return corresponding even entry */
 
319
      return pgsql_encoding_hash[i];
 
320
    }
 
321
    i+=2;
 
322
  }
 
323
 
 
324
  /* don't know how to translate, return original encoding */
 
325
  return iana_encoding;
 
326
}
 
327
 
 
328
char *dbd_get_engine_version(dbi_conn_t *conn, char *versionstring) {
 
329
  dbi_result_t *dbi_result;
 
330
  const char *versioninfo = NULL;
 
331
 
 
332
  /* initialize return string */
 
333
  *versionstring = '\0';
 
334
 
 
335
  dbi_result = dbd_query(conn, "SELECT VERSION()");
 
336
 
 
337
  /* this query will return something like:
 
338
     PostgreSQL 8.0.1 on i386-portbld-freebsd5.4, compiled by GCC cc (GCC) 3.4.2 [FreeBSD] 20040728
 
339
  */
 
340
  if (dbi_result) {
 
341
    if (dbi_result_next_row(dbi_result)) {
 
342
      char *dot = NULL;
 
343
      char *start = NULL;
 
344
      char *stop = NULL;
 
345
      versioninfo = dbi_result_get_string_idx(dbi_result, 1);
 
346
 
 
347
      /* try to locate the version number. Look for the first dot, go
 
348
         back where the number before the dot starts, then walk
 
349
         forward to the last dot or number */
 
350
      dot = strchr(versioninfo, (int)'.');
 
351
      if (dot) {
 
352
        start = dot-1;
 
353
        while (start>versioninfo && isdigit((int)(*(start-1)))) {
 
354
          start--;
 
355
        }
 
356
 
 
357
        stop = start;
 
358
        while (*(stop+1) && (isdigit((int)(*(stop+1))) || *(stop+1)=='.')) {
 
359
          stop++;
 
360
        }
 
361
 
 
362
        if (stop-start < VERSIONSTRING_LENGTH) {
 
363
          strncpy(versionstring, start, stop-start+1);
 
364
          versionstring[stop-start+1] = '\0';
 
365
        }
 
366
      }
 
367
    }
 
368
    dbi_result_free(dbi_result);
 
369
  }
 
370
 
 
371
  return versionstring;
247
372
}
248
373
 
249
374
dbi_result_t *dbd_list_dbs(dbi_conn_t *conn, const char *pattern) {
274
399
        }
275
400
}
276
401
 
277
 
int dbd_quote_string(dbi_driver_t *driver, const char *orig, char *dest) {
 
402
size_t dbd_quote_string(dbi_driver_t *driver, const char *orig, char *dest) {
278
403
        /* foo's -> 'foo\'s' */
279
 
        int len;
 
404
        size_t len;
280
405
 
281
406
        strcpy(dest, "'");
282
407
        len = PQescapeString(dest+1, orig, strlen(orig));
285
410
        return len+2;
286
411
}
287
412
 
 
413
size_t dbd_conn_quote_string(dbi_conn_t *conn, const char *orig, char *dest) {
 
414
  return dbd_quote_string(conn->driver, orig, dest);
 
415
}
 
416
 
 
417
size_t dbd_quote_binary(dbi_conn_t *conn, const unsigned char* orig, size_t from_length, unsigned char **ptr_dest) {
 
418
  unsigned char *temp = NULL;
 
419
  unsigned char *quoted_temp = NULL;
 
420
  size_t to_length;
 
421
 
 
422
  temp = PQescapeBytea(orig, from_length, &to_length);
 
423
 
 
424
  if (!temp) {
 
425
    return 0;
 
426
  }
 
427
 
 
428
  if ((quoted_temp = malloc(to_length+2)) == NULL) {
 
429
    PQfreemem((void *)temp);
 
430
    return 0;
 
431
  }
 
432
  
 
433
  strcpy((char *)quoted_temp, "'");
 
434
  strcpy((char *)(quoted_temp+1), (char *)temp);
 
435
  strcat((char *)quoted_temp, "'");
 
436
 
 
437
  PQfreemem((void*)temp);
 
438
 
 
439
  *ptr_dest = quoted_temp;
 
440
  return to_length;
 
441
}
 
442
 
288
443
dbi_result_t *dbd_query(dbi_conn_t *conn, const char *statement) {
289
444
        /* allocate a new dbi_result_t and fill its applicable members:
290
445
         * 
302
457
                return NULL;
303
458
        }
304
459
 
305
 
        result = _dbd_result_create(conn, (void *)res, PQntuples(res), atol(PQcmdTuples(res)));
306
 
        _dbd_result_set_numfields(result, PQnfields((PGresult *)result->result_handle));
 
460
        result = _dbd_result_create(conn, (void *)res, (unsigned long long)PQntuples(res), (unsigned long long)atoll(PQcmdTuples(res)));
 
461
        _dbd_result_set_numfields(result, (unsigned int)PQnfields((PGresult *)result->result_handle));
307
462
        _get_field_info(result);
308
463
 
309
464
        return result;
310
465
}
311
466
 
312
 
dbi_result_t *dbd_query_null(dbi_conn_t *conn, const unsigned char *statement, unsigned long st_length) {
 
467
dbi_result_t *dbd_query_null(dbi_conn_t *conn, const unsigned char *statement, size_t st_length) {
313
468
        return NULL;
314
469
}
315
470
 
316
 
char *dbd_select_db(dbi_conn_t *conn, const char *db) {
 
471
const char *dbd_select_db(dbi_conn_t *conn, const char *db) {
317
472
  /* postgresql doesn't support switching databases without reconnecting */
318
473
  if (!db || !*db) {
319
474
    return NULL;
324
479
    conn->connection = NULL;
325
480
  }
326
481
 
327
 
  dbi_conn_set_option(conn, "dbname", db);
328
 
  if (dbd_connect(conn)) {
 
482
  if (_dbd_real_connect(conn, db)) {
329
483
    return NULL;
330
484
  }
331
485
 
332
 
  return (char *)db;
 
486
  return db;
333
487
}
334
488
 
335
489
int dbd_geterror(dbi_conn_t *conn, int *errno, char **errstr) {
356
510
        if (result) {
357
511
                rawdata = PQgetvalue((PGresult *)result->result_handle, 0, 0);
358
512
                if (rawdata) {
359
 
                        seq_last = atoll(rawdata);
 
513
                        seq_last = (unsigned long long)atoll(rawdata);
360
514
                }
361
515
                dbi_result_free((dbi_result)result);
362
516
        }
378
532
        if (result) {   
379
533
                rawdata = PQgetvalue((PGresult *)result->result_handle, 0, 0);
380
534
                if (rawdata) {
381
 
                        seq_next = atoll(rawdata);
 
535
                        seq_next = (unsigned long long)atoll(rawdata);
382
536
                }
383
537
                dbi_result_free((dbi_result)result);
384
538
        }
388
542
 
389
543
int dbd_ping(dbi_conn_t *conn) {
390
544
        PGconn *pgsql = (PGconn *)conn->connection;
 
545
        PGresult *res;
391
546
 
392
 
        PQexec(pgsql, "SELECT 1");
 
547
        res = PQexec(pgsql, "SELECT 1");
 
548
        if (res) {
 
549
          PQclear (res);
 
550
        }
393
551
 
394
552
        if (PQstatus(pgsql) == CONNECTION_OK) {
395
553
                return 1;
410
568
        unsigned int _type = 0;
411
569
        unsigned int _attribs = 0;
412
570
 
 
571
/*        fprintf(stderr, "oid went to %d\n", oid); */
413
572
        switch (oid) {
414
573
                case PG_TYPE_CHAR:
415
574
                        _type = DBI_TYPE_INTEGER;
441
600
                        _type = DBI_TYPE_DECIMAL;
442
601
                        _attribs |= DBI_DECIMAL_SIZE8;
443
602
                        break;
444
 
                case PG_TYPE_DATE:
445
 
                       _type = DBI_TYPE_DATETIME;
446
 
                       _attribs |= DBI_DATETIME_DATE;
447
 
                       break;
448
 
                case PG_TYPE_TIME:
449
 
                       _type = DBI_TYPE_DATETIME;
450
 
                       _attribs |= DBI_DATETIME_TIME;
451
 
                       break;
452
 
        case PG_TYPE_DATETIME:
453
 
        case PG_TYPE_TIMESTAMP:
 
603
 
 
604
        case PG_TYPE_DATE:
 
605
                _type = DBI_TYPE_DATETIME;
 
606
            _attribs |= DBI_DATETIME_DATE;
 
607
            break;
 
608
        case PG_TYPE_TIME:
 
609
        case PG_TYPE_TIMETZ:
 
610
            _type = DBI_TYPE_DATETIME;
 
611
            _attribs |= DBI_DATETIME_TIME;
 
612
            break;
 
613
        case PG_TYPE_TIMESTAMP:
 
614
        case PG_TYPE_TIMESTAMPTZ:
454
615
                        _type = DBI_TYPE_DATETIME;
455
616
                        _attribs |= DBI_DATETIME_DATE;
456
617
                        _attribs |= DBI_DATETIME_TIME;
457
618
                        break;
 
619
 
458
620
                case PG_TYPE_NAME:
459
621
                case PG_TYPE_TEXT:
460
622
                case PG_TYPE_CHAR2:
495
657
}
496
658
 
497
659
void _get_row_data(dbi_result_t *result, dbi_row_t *row, unsigned long long rowidx) {
498
 
        int curfield = 0;
 
660
        unsigned int curfield = 0;
499
661
        char *raw = NULL;
500
 
        unsigned long long strsize = 0;
501
 
        unsigned long sizeattrib;
 
662
        size_t strsize = 0;
 
663
        unsigned int sizeattrib;
502
664
        dbi_data_t *data;
 
665
        unsigned char *temp = NULL;
 
666
        size_t unquoted_length;
 
667
 
503
668
 
504
669
        while (curfield < result->numfields) {
505
670
                raw = PQgetvalue((PGresult *)result->result_handle, rowidx, curfield);
506
 
                strsize = (unsigned long long) PQfmod((PGresult *)result->result_handle, curfield);
507
671
                data = &row->field_values[curfield];
508
672
 
509
673
                row->field_sizes[curfield] = 0;
510
674
                /* will be set to strlen later on for strings */
511
675
                
512
676
                if (PQgetisnull((PGresult *)result->result_handle, rowidx, curfield) == 1) {
 
677
                        _set_field_flag( row, curfield, DBI_VALUE_NULL, 1);
513
678
                        curfield++;
514
679
                        continue;
515
680
                }
516
681
                
517
682
                switch (result->field_types[curfield]) {
518
683
                        case DBI_TYPE_INTEGER:
519
 
                                sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_INTEGER_SIZE1, DBI_INTEGER_SIZE8);
520
 
                                switch (sizeattrib) {
 
684
                                switch (result->field_attribs[curfield] & DBI_INTEGER_SIZEMASK) {
521
685
                                        case DBI_INTEGER_SIZE1:
522
686
                                                data->d_char = (char) atol(raw); break;
523
687
                                        case DBI_INTEGER_SIZE2:
524
688
                                                data->d_short = (short) atol(raw); break;
525
689
                                        case DBI_INTEGER_SIZE3:
526
690
                                        case DBI_INTEGER_SIZE4:
527
 
                                                data->d_long = (long) atol(raw); break;
 
691
                                                data->d_long = (int) atol(raw); break;
528
692
                                        case DBI_INTEGER_SIZE8:
529
693
                                                data->d_longlong = (long long) atoll(raw); break; /* hah, wonder if that'll work */
530
694
                                        default:
532
696
                                }
533
697
                                break;
534
698
                        case DBI_TYPE_DECIMAL:
535
 
                                sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DECIMAL_SIZE4, DBI_DECIMAL_SIZE8);
536
 
                                switch (sizeattrib) {
 
699
                                switch (result->field_attribs[curfield] & DBI_DECIMAL_SIZEMASK) {
537
700
                                        case DBI_DECIMAL_SIZE4:
538
701
                                                data->d_float = (float) strtod(raw, NULL); break;
539
702
                                        case DBI_DECIMAL_SIZE8:
543
706
                                }
544
707
                                break;
545
708
                        case DBI_TYPE_STRING:
 
709
                            strsize = (size_t)PQgetlength((PGresult *)result->result_handle, rowidx, curfield);
546
710
                                data->d_string = strdup(raw);
547
711
                                row->field_sizes[curfield] = strsize;
548
712
                                break;
549
 
                        case DBI_TYPE_BINARY:
550
 
                                row->field_sizes[curfield] = strsize;
551
 
                                data->d_string = malloc(strsize);
552
 
                                memcpy(data->d_string, raw, strsize);
 
713
                        case DBI_TYPE_BINARY:   
 
714
                          temp = PQunescapeBytea((const unsigned char *)raw, &unquoted_length);
 
715
                          if ((data->d_string = malloc(unquoted_length)) == NULL) {
 
716
                            PQfreemem(temp);
 
717
                            break;
 
718
                          }
 
719
                          memmove(data->d_string, temp, unquoted_length);
 
720
                          PQfreemem(temp);
 
721
                          row->field_sizes[curfield] = unquoted_length;
 
722
                          /* todo: is raw ever unescaped binary data? */
 
723
/*                                      strsize = PQgetlength((PGresult *)result->result_handle, rowidx, curfield); */
 
724
/*                              row->field_sizes[curfield] = strsize; */
 
725
/*                              data->d_string = malloc(strsize); */
 
726
/*                              memcpy(data->d_string, raw, strsize); */
553
727
                                break;
554
728
                                
555
729
                        case DBI_TYPE_DATETIME:
556
 
                                sizeattrib = _isolate_attrib(result->field_attribs[curfield], DBI_DATETIME_DATE, DBI_DATETIME_TIME);
 
730
                                sizeattrib = result->field_attribs[curfield] & (DBI_DATETIME_DATE|DBI_DATETIME_TIME);
557
731
                                data->d_datetime = _dbd_parse_datetime(raw, sizeattrib);
558
732
                                break;
559
733