X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fdata%2Fpsql-reader.c;h=741bf36e44c079196d608df94c1a6b5f6ee7a9e4;hb=5c3291dc396b795696e94f47780308fd7ace6fc4;hp=72e14be4fce9542eb8f7c92b6a21563fc2842f0c;hpb=89a1e7f479414c1a2345e33210d69e91e61b33ac;p=pspp-builds.git diff --git a/src/data/psql-reader.c b/src/data/psql-reader.c index 72e14be4..741bf36e 100644 --- a/src/data/psql-reader.c +++ b/src/data/psql-reader.c @@ -1,5 +1,5 @@ /* PSPP - a program for statistical analysis. - Copyright (C) 2008 Free Software Foundation, Inc. + Copyright (C) 2008, 2009 Free Software Foundation, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "psql-reader.h" @@ -28,8 +29,11 @@ #include "calendar.h" #include +#include #include +#include "minmax.h" + #include "gettext.h" #define _(msgid) gettext (msgid) #define N_(msgid) (msgid) @@ -37,7 +41,7 @@ #if !PSQL_SUPPORT struct casereader * -psql_open_reader (struct psql_read_info *info, struct dictionary **dict) +psql_open_reader (struct psql_read_info *info UNUSED, struct dictionary **dict UNUSED) { msg (ME, _("Support for reading postgres databases was not compiled into this installation of PSPP")); @@ -75,8 +79,7 @@ psql_open_reader (struct psql_read_info *info, struct dictionary **dict) static void psql_casereader_destroy (struct casereader *reader UNUSED, void *r_); -static bool psql_casereader_read (struct casereader *, void *, - struct ccase *); +static struct ccase *psql_casereader_read (struct casereader *, void *); static const struct casereader_class psql_casereader_class = { @@ -96,7 +99,7 @@ struct psql_reader double postgres_epoch; - size_t value_cnt; + struct caseproto *proto; struct dictionary *dict; /* An array of ints, which maps psql column numbers into @@ -109,8 +112,7 @@ struct psql_reader }; -static bool set_value (struct psql_reader *r, - struct ccase *cc); +static struct ccase *set_value (struct psql_reader *r); @@ -177,8 +179,6 @@ create_var (struct psql_reader *r, const struct fmt_spec *fmt, struct variable *var; char name[VAR_NAME_LEN + 1]; - r->value_cnt += value_cnt_from_width (width); - if ( ! dict_make_unique_var_name (r->dict, suggested_name, &vx, name)) { msg (ME, _("Cannot create variable name from %s"), suggested_name); @@ -290,10 +290,22 @@ psql_open_reader (struct psql_read_info *info, struct dictionary **dict) /* Create the dictionary and populate it */ *dict = r->dict = dict_create (); + { + const int enc = PQclientEncoding (r->conn); + + /* According to section 22.2 of the Postgresql manual + a value of zero (SQL_ASCII) indicates + "a declaration of ignorance about the encoding". + Accordingly, we don't set the dictionary's encoding + if we find this value. + */ + if ( enc != 0 ) + dict_set_encoding (r->dict, pg_encoding_to_char (enc)); + } + /* select count (*) from (select * from medium) stupid_sql_standard; */ - ds_init_cstr (&query, "BEGIN READ ONLY ISOLATION LEVEL SERIALIZABLE; " "DECLARE pspp BINARY CURSOR FOR "); @@ -347,7 +359,7 @@ psql_open_reader (struct psql_read_info *info, struct dictionary **dict) n_tuples = PQntuples (qres); n_fields = PQnfields (qres); - r->value_cnt = 0; + r->proto = NULL; r->vmap = NULL; r->vmapsize = 0; @@ -442,6 +454,10 @@ psql_open_reader (struct psql_read_info *info, struct dictionary **dict) break; } + if ( width == 0 && fmt_is_string (fmt.type)) + fmt.w = width = MAX_SHORT_STRING; + + var = create_var (r, &fmt, width, PQfname (qres, i), i); if ( type == NUMERICOID && n_tuples > 0) { @@ -514,10 +530,11 @@ psql_open_reader (struct psql_read_info *info, struct dictionary **dict) ds_put_format (&r->fetch_cmd, "FETCH FORWARD %d FROM pspp", r->cache_size); reload_cache (r); + r->proto = caseproto_ref (dict_get_proto (*dict)); return casereader_create_sequential (NULL, - r->value_cnt, + r->proto, n_cases, &psql_casereader_class, r); @@ -540,15 +557,15 @@ psql_casereader_destroy (struct casereader *reader UNUSED, void *r_) free (r->vmap); if (r->res) PQclear (r->res); PQfinish (r->conn); + caseproto_unref (r->proto); free (r); } -static bool -psql_casereader_read (struct casereader *reader UNUSED, void *r_, - struct ccase *cc) +static struct ccase * +psql_casereader_read (struct casereader *reader UNUSED, void *r_) { struct psql_reader *r = r_; @@ -558,25 +575,25 @@ psql_casereader_read (struct casereader *reader UNUSED, void *r_, return false; } - return set_value (r, cc); + return set_value (r); } -static bool -set_value (struct psql_reader *r, - struct ccase *c) +static struct ccase * +set_value (struct psql_reader *r) { - int i; + struct ccase *c; int n_vars; + int i; assert (r->res); n_vars = PQnfields (r->res); if ( r->tuple >= PQntuples (r->res)) - return false; + return NULL; - case_create (c, r->value_cnt); - memset (case_data_rw_idx (c, 0)->s, ' ', MAX_SHORT_STRING * r->value_cnt); + c = case_create (r->proto); + case_set_missing (c); for (i = 0 ; i < n_vars ; ++i ) @@ -818,7 +835,8 @@ set_value (struct psql_reader *r, case VARCHAROID: case BPCHAROID: case BYTEAOID: - memcpy (val->s, (char *) vptr, MIN (length, var_width)); + memcpy (value_str_rw (val, var_width), (char *) vptr, + MIN (length, var_width)); break; case NUMERICOID: @@ -870,7 +888,7 @@ set_value (struct psql_reader *r, r->tuple++; - return true; + return c; } #endif