pspp-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[csv 09/10] SAVE: Fix UNSELECTED=RETAIN with a filter variable.


From: Ben Pfaff
Subject: [csv 09/10] SAVE: Fix UNSELECTED=RETAIN with a filter variable.
Date: Sun, 8 Aug 2010 10:17:51 -0700

Apparently this had never been tested.  It assert-failed consistently
because the filter variable being saved was from the dictionary before
reading the data, but the dictionary after reading the data was
different due to the temporary transformation used to drop the
filtered data.
---
 src/data/procedure.c           |   19 ++++++++++++++++---
 src/data/procedure.h           |    3 ++-
 src/language/data-io/save.c    |   11 ++---------
 tests/automake.mk              |    1 +
 tests/language/data-io/save.at |   31 +++++++++++++++++++++++++++++++
 5 files changed, 52 insertions(+), 13 deletions(-)
 create mode 100644 tests/language/data-io/save.at

diff --git a/src/data/procedure.c b/src/data/procedure.c
index c79e784..fa52806 100644
--- a/src/data/procedure.c
+++ b/src/data/procedure.c
@@ -163,10 +163,14 @@ proc_execute (struct dataset *ds)
 
 static const struct casereader_class proc_casereader_class;
 
-/* Opens dataset DS for reading cases with proc_read.
+/* Opens dataset DS for reading cases with proc_read.  If FILTER is true, then
+   cases filtered out with FILTER BY will not be included in the casereader
+   (which is usually desirable).  If FILTER is false, all cases will be
+   included regardless of FILTER BY settings.
+
    proc_commit must be called when done. */
 struct casereader *
-proc_open (struct dataset *ds)
+proc_open_filtering (struct dataset *ds, bool filter)
 {
   struct casereader *reader;
 
@@ -179,7 +183,8 @@ proc_open (struct dataset *ds)
 
   /* Finish up the collection of transformations. */
   add_case_limit_trns (ds);
-  add_filter_trns (ds);
+  if (filter)
+    add_filter_trns (ds);
   trns_chain_finalize (ds->cur_trns_chain);
 
   /* Make permanent_dict refer to the dictionary right before
@@ -237,6 +242,14 @@ proc_open (struct dataset *ds)
   return reader;
 }
 
+/* Opens dataset DS for reading cases with proc_read.
+   proc_commit must be called when done. */
+struct casereader *
+proc_open (struct dataset *ds)
+{
+  return proc_open_filtering (ds, true);
+}
+
 /* Returns true if a procedure is in progress, that is, if
    proc_open has been called but proc_commit has not. */
 bool
diff --git a/src/data/procedure.h b/src/data/procedure.h
index 09d44ee..bb4dad2 100644
--- a/src/data/procedure.h
+++ b/src/data/procedure.h
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2007, 2009 Free Software Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010 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
@@ -72,6 +72,7 @@ void proc_discard_output (struct dataset *ds);
 bool proc_execute (struct dataset *ds);
 time_t time_of_last_procedure (struct dataset *ds);
 
+struct casereader *proc_open_filtering (struct dataset *, bool filter);
 struct casereader *proc_open (struct dataset *);
 bool proc_is_open (const struct dataset *);
 bool proc_commit (struct dataset *);
diff --git a/src/language/data-io/save.c b/src/language/data-io/save.c
index c34d446..91fbc2f 100644
--- a/src/language/data-io/save.c
+++ b/src/language/data-io/save.c
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 1997-9, 2000, 2006, 2007, 2008, 2009 Free Software 
Foundation, Inc.
+   Copyright (C) 1997-9, 2000, 2006, 2007, 2008, 2009, 2010 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
@@ -105,7 +105,6 @@ parse_output_proc (struct lexer *lexer, struct dataset *ds,
                    enum writer_type writer_type)
 {
   bool retain_unselected;
-  struct variable *saved_filter_variable;
   struct casewriter *output;
   bool ok;
 
@@ -114,16 +113,10 @@ parse_output_proc (struct lexer *lexer, struct dataset 
*ds,
   if (output == NULL)
     return CMD_CASCADING_FAILURE;
 
-  saved_filter_variable = dict_get_filter (dataset_dict (ds));
-  if (retain_unselected)
-    dict_set_filter (dataset_dict (ds), NULL);
-
-  casereader_transfer (proc_open (ds), output);
+  casereader_transfer (proc_open_filtering (ds, !retain_unselected), output);
   ok = casewriter_destroy (output);
   ok = proc_commit (ds) && ok;
 
-  dict_set_filter (dataset_dict (ds), saved_filter_variable);
-
   return ok ? CMD_SUCCESS : CMD_CASCADING_FAILURE;
 }
 
diff --git a/tests/automake.mk b/tests/automake.mk
index 1d24735..a2ceef6 100644
--- a/tests/automake.mk
+++ b/tests/automake.mk
@@ -419,6 +419,7 @@ EXTRA_DIST += \
 TESTSUITE_AT = \
        tests/data/calendar.at \
        tests/language/data-io/data-list.at \
+       tests/language/data-io/save.at \
        tests/language/dictionary/mrsets.at \
        tests/language/expressions/evaluate.at \
        tests/language/stats/aggregate.at \
diff --git a/tests/language/data-io/save.at b/tests/language/data-io/save.at
new file mode 100644
index 0000000..28a186f
--- /dev/null
+++ b/tests/language/data-io/save.at
@@ -0,0 +1,31 @@
+AT_BANNER([SAVE])
+
+# UNSELECTED=DELETE used to cause a crash if there was actually a
+# filter variable.
+AT_SETUP([SAVE -- delete unselected])
+AT_DATA([data.txt], [dnl
+0 '1 9:30:05' 1/2/2003 "25/8/1995 15:30:00" "'a,b,c'",0
+, '-0 5:17' 10/31/2010 "9/4/2008 9:29:00" " xxx ",1
+1.625,'0 12:00',,,xyzzy,1
+])
+AT_DATA([save.pspp], [dnl
+SET DECIMAL=DOT.
+DATA LIST LIST NOTABLE FILE="data.txt"
+    /number(F8.3) time(DTIME10) date(ADATE10) datetime(DATETIME20) string(A8)
+     filter(F1.0).
+MISSING VALUES number(0) time('0 12:00') string('xyzzy').
+FILTER BY filter.
+SAVE /OUTFILE="data.sav" /UNSELECTED=DELETE.
+])
+AT_DATA([get.pspp], [dnl
+GET FILE='data.sav'.
+LIST.
+])
+AT_CHECK([pspp -O format=csv save.pspp])
+AT_CHECK([pspp -O format=csv get.pspp], [0], [dnl
+Table: Data List
+number,time,date,datetime,string,filter
+.   ,-0 05:17,10/31/2010,09-APR-2008 09:29:00,xxx    ,1
+1.625,0 12:00:00,.,.,xyzzy   ,1
+])
+AT_CLEANUP
-- 
1.7.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]