summary refs log tree commit diff stats
path: root/lib/filter.cpp
diff options
context:
space:
mode:
authorKelly Rauchenberger <fefferburbia@gmail.com>2017-02-06 20:58:37 -0500
committerKelly Rauchenberger <fefferburbia@gmail.com>2017-02-06 20:58:37 -0500
commitf1f67e62cebb4144f0599196263cd93b41fa972e (patch)
tree5d0f8fceeec63f47fb85846f5568bcb36f4a975f /lib/filter.cpp
parent6cc23ba387d0813b801ba094709673a61bac889c (diff)
downloadverbly-f1f67e62cebb4144f0599196263cd93b41fa972e.tar.gz
verbly-f1f67e62cebb4144f0599196263cd93b41fa972e.tar.bz2
verbly-f1f67e62cebb4144f0599196263cd93b41fa972e.zip
Made pronunciation::rhymes join dynamic
This involved adding a new type of filter; one that compares (currently
only equality and inequality) a field with another field located in an
enclosing join context.

In the process, it was discovered that simplifying the lemma::forms join
field earlier actually made some queries return inaccurate results
because the inflection of the form was being ignored and anything in the
lemma would be used because of the inner join. Because the existing
condition join did not allow for the condition field to be on the from
side of the join, two things were done: a condition version of
joinThrough was made, and lemma was finally eliminated as a top-level
object, replaced instead with a condition join between word and form
through lemmas_forms.

Queries are also now grouped by the first select field (assumed to be
the primary ID) of the top table, in order to eliminate duplicates
created by inner joins, so that there is a uniform distribution between
results for random queries.

Created a database index on pronunciations(rhyme) which decreases query
time for rhyming filters. The new database version is
backwards-compatible because no data or structure changed.
Diffstat (limited to 'lib/filter.cpp')
-rw-r--r--lib/filter.cpp201
1 files changed, 166 insertions, 35 deletions
diff --git a/lib/filter.cpp b/lib/filter.cpp index ecff8ac..c201618 100644 --- a/lib/filter.cpp +++ b/lib/filter.cpp
@@ -5,7 +5,6 @@
5#include "word.h" 5#include "word.h"
6#include "frame.h" 6#include "frame.h"
7#include "part.h" 7#include "part.h"
8#include "lemma.h"
9#include "form.h" 8#include "form.h"
10#include "pronunciation.h" 9#include "pronunciation.h"
11 10
@@ -73,6 +72,14 @@ namespace verbly {
73 72
74 break; 73 break;
75 } 74 }
75
76 case comparison::field_equals:
77 case comparison::field_does_not_equal:
78 {
79 new(&singleton_.compareField) field(other.singleton_.compareField);
80
81 break;
82 }
76 } 83 }
77 84
78 break; 85 break;
@@ -112,6 +119,7 @@ namespace verbly {
112 std::string tempStringValue; 119 std::string tempStringValue;
113 int tempIntValue; 120 int tempIntValue;
114 bool tempBoolValue; 121 bool tempBoolValue;
122 field tempCompareField;
115 std::list<filter> tempChildren; 123 std::list<filter> tempChildren;
116 bool tempOrlogic; 124 bool tempOrlogic;
117 125
@@ -173,6 +181,14 @@ namespace verbly {
173 181
174 break; 182 break;
175 } 183 }
184
185 case comparison::field_equals:
186 case comparison::field_does_not_equal:
187 {
188 tempCompareField = std::move(first.singleton_.compareField);
189
190 break;
191 }
176 } 192 }
177 193
178 break; 194 break;
@@ -249,6 +265,14 @@ namespace verbly {
249 265
250 break; 266 break;
251 } 267 }
268
269 case comparison::field_equals:
270 case comparison::field_does_not_equal:
271 {
272 new(&first.singleton_.compareField) field(std::move(second.singleton_.compareField));
273
274 break;
275 }
252 } 276 }
253 277
254 break; 278 break;
@@ -325,6 +349,14 @@ namespace verbly {
325 349
326 break; 350 break;
327 } 351 }
352
353 case comparison::field_equals:
354 case comparison::field_does_not_equal:
355 {
356 new(&second.singleton_.compareField) field(std::move(tempCompareField));
357
358 break;
359 }
328 } 360 }
329 361
330 break; 362 break;
@@ -391,6 +423,14 @@ namespace verbly {
391 423
392 break; 424 break;
393 } 425 }
426
427 case comparison::field_equals:
428 case comparison::field_does_not_equal:
429 {
430 singleton_.compareField.~field();
431
432 break;
433 }
394 } 434 }
395 435
396 break; 436 break;
@@ -446,6 +486,8 @@ namespace verbly {
446 case comparison::does_not_match: 486 case comparison::does_not_match:
447 case comparison::hierarchally_matches: 487 case comparison::hierarchally_matches:
448 case comparison::does_not_hierarchally_match: 488 case comparison::does_not_hierarchally_match:
489 case comparison::field_equals:
490 case comparison::field_does_not_equal:
449 { 491 {
450 throw std::invalid_argument("Invalid comparison for integer field"); 492 throw std::invalid_argument("Invalid comparison for integer field");
451 } 493 }
@@ -490,6 +532,8 @@ namespace verbly {
490 case comparison::does_not_match: 532 case comparison::does_not_match:
491 case comparison::hierarchally_matches: 533 case comparison::hierarchally_matches:
492 case comparison::does_not_hierarchally_match: 534 case comparison::does_not_hierarchally_match:
535 case comparison::field_equals:
536 case comparison::field_does_not_equal:
493 { 537 {
494 throw std::invalid_argument("Invalid comparison for string field"); 538 throw std::invalid_argument("Invalid comparison for string field");
495 } 539 }
@@ -534,6 +578,8 @@ namespace verbly {
534 case comparison::does_not_match: 578 case comparison::does_not_match:
535 case comparison::hierarchally_matches: 579 case comparison::hierarchally_matches:
536 case comparison::does_not_hierarchally_match: 580 case comparison::does_not_hierarchally_match:
581 case comparison::field_equals:
582 case comparison::field_does_not_equal:
537 { 583 {
538 throw std::invalid_argument("Invalid comparison for boolean field"); 584 throw std::invalid_argument("Invalid comparison for boolean field");
539 } 585 }
@@ -576,6 +622,8 @@ namespace verbly {
576 case comparison::does_not_match: 622 case comparison::does_not_match:
577 case comparison::hierarchally_matches: 623 case comparison::hierarchally_matches:
578 case comparison::does_not_hierarchally_match: 624 case comparison::does_not_hierarchally_match:
625 case comparison::field_equals:
626 case comparison::field_does_not_equal:
579 { 627 {
580 throw std::invalid_argument("Incorrect constructor for given comparison"); 628 throw std::invalid_argument("Incorrect constructor for given comparison");
581 } 629 }
@@ -596,6 +644,7 @@ namespace verbly {
596 case field::type::join: 644 case field::type::join:
597 case field::type::join_where: 645 case field::type::join_where:
598 case field::type::join_through: 646 case field::type::join_through:
647 case field::type::join_through_where:
599 { 648 {
600 switch (filterType) 649 switch (filterType)
601 { 650 {
@@ -624,6 +673,8 @@ namespace verbly {
624 case comparison::is_not_null: 673 case comparison::is_not_null:
625 case comparison::hierarchally_matches: 674 case comparison::hierarchally_matches:
626 case comparison::does_not_hierarchally_match: 675 case comparison::does_not_hierarchally_match:
676 case comparison::field_equals:
677 case comparison::field_does_not_equal:
627 { 678 {
628 throw std::invalid_argument("Incorrect constructor for given comparison"); 679 throw std::invalid_argument("Incorrect constructor for given comparison");
629 } 680 }
@@ -661,6 +712,8 @@ namespace verbly {
661 case comparison::is_not_null: 712 case comparison::is_not_null:
662 case comparison::matches: 713 case comparison::matches:
663 case comparison::does_not_match: 714 case comparison::does_not_match:
715 case comparison::field_equals:
716 case comparison::field_does_not_equal:
664 { 717 {
665 throw std::invalid_argument("Incorrect constructor for given comparison"); 718 throw std::invalid_argument("Incorrect constructor for given comparison");
666 } 719 }
@@ -679,6 +732,57 @@ namespace verbly {
679 } 732 }
680 } 733 }
681 734
735 filter::filter(
736 field filterField,
737 comparison filterType,
738 field compareField) :
739 type_(type::singleton)
740 {
741 switch (filterType)
742 {
743 case comparison::field_equals:
744 case comparison::field_does_not_equal:
745 {
746 if (filterField.getType() != compareField.getType())
747 {
748 throw std::invalid_argument("Cannot compare two fields of different types");
749 }
750
751 if (filterField.isJoin())
752 {
753 throw std::domain_error("Cannot compare join fields");
754 }
755
756 new(&singleton_.filterField) field(std::move(filterField));
757 singleton_.filterType = filterType;
758 new(&singleton_.compareField) field(std::move(compareField));
759
760 break;
761 }
762
763 case comparison::int_equals:
764 case comparison::int_does_not_equal:
765 case comparison::int_is_at_least:
766 case comparison::int_is_greater_than:
767 case comparison::int_is_at_most:
768 case comparison::int_is_less_than:
769 case comparison::boolean_equals:
770 case comparison::string_equals:
771 case comparison::string_does_not_equal:
772 case comparison::string_is_like:
773 case comparison::string_is_not_like:
774 case comparison::is_null:
775 case comparison::is_not_null:
776 case comparison::matches:
777 case comparison::does_not_match:
778 case comparison::hierarchally_matches:
779 case comparison::does_not_hierarchally_match:
780 {
781 throw std::domain_error("Incorrect constructor for given comparison");
782 }
783 }
784 }
785
682 field filter::getField() const 786 field filter::getField() const
683 { 787 {
684 if (type_ == type::singleton) 788 if (type_ == type::singleton)
@@ -726,6 +830,8 @@ namespace verbly {
726 case comparison::boolean_equals: 830 case comparison::boolean_equals:
727 case comparison::is_null: 831 case comparison::is_null:
728 case comparison::is_not_null: 832 case comparison::is_not_null:
833 case comparison::field_equals:
834 case comparison::field_does_not_equal:
729 { 835 {
730 throw std::domain_error("This filter does not have a join condition"); 836 throw std::domain_error("This filter does not have a join condition");
731 } 837 }
@@ -762,6 +868,8 @@ namespace verbly {
762 case comparison::does_not_match: 868 case comparison::does_not_match:
763 case comparison::hierarchally_matches: 869 case comparison::hierarchally_matches:
764 case comparison::does_not_hierarchally_match: 870 case comparison::does_not_hierarchally_match:
871 case comparison::field_equals:
872 case comparison::field_does_not_equal:
765 { 873 {
766 throw std::domain_error("This filter does not have a string argument"); 874 throw std::domain_error("This filter does not have a string argument");
767 } 875 }
@@ -798,6 +906,8 @@ namespace verbly {
798 case comparison::does_not_match: 906 case comparison::does_not_match:
799 case comparison::hierarchally_matches: 907 case comparison::hierarchally_matches:
800 case comparison::does_not_hierarchally_match: 908 case comparison::does_not_hierarchally_match:
909 case comparison::field_equals:
910 case comparison::field_does_not_equal:
801 { 911 {
802 throw std::domain_error("This filter does not have an integer argument"); 912 throw std::domain_error("This filter does not have an integer argument");
803 } 913 }
@@ -817,6 +927,47 @@ namespace verbly {
817 } 927 }
818 } 928 }
819 929
930 field filter::getCompareField() const
931 {
932 if (type_ != type::singleton)
933 {
934 throw std::domain_error("This filter does not have a compare field");
935 }
936
937 switch (singleton_.filterType)
938 {
939 case comparison::field_equals:
940 case comparison::field_does_not_equal:
941 {
942 return singleton_.compareField;
943
944 break;
945 }
946
947 case comparison::int_equals:
948 case comparison::int_does_not_equal:
949 case comparison::int_is_at_least:
950 case comparison::int_is_greater_than:
951 case comparison::int_is_at_most:
952 case comparison::int_is_less_than:
953 case comparison::boolean_equals:
954 case comparison::string_equals:
955 case comparison::string_does_not_equal:
956 case comparison::string_is_like:
957 case comparison::string_is_not_like:
958 case comparison::is_null:
959 case comparison::is_not_null:
960 case comparison::matches:
961 case comparison::does_not_match:
962 case comparison::hierarchally_matches:
963 case comparison::does_not_hierarchally_match:
964 {
965 throw std::domain_error("This filter doesn't have a compare field");
966 }
967 }
968
969 }
970
820 filter::filter(bool orlogic) : type_(type::group) 971 filter::filter(bool orlogic) : type_(type::group)
821 { 972 {
822 new(&group_.children) std::list<filter>(); 973 new(&group_.children) std::list<filter>();
@@ -970,6 +1121,16 @@ namespace verbly {
970 { 1121 {
971 return filter(singleton_.filterField, comparison::hierarchally_matches, *singleton_.join); 1122 return filter(singleton_.filterField, comparison::hierarchally_matches, *singleton_.join);
972 } 1123 }
1124
1125 case comparison::field_equals:
1126 {
1127 return filter(singleton_.filterField, comparison::field_does_not_equal, singleton_.compareField);
1128 }
1129
1130 case comparison::field_does_not_equal:
1131 {
1132 return filter(singleton_.filterField, comparison::field_equals, singleton_.compareField);
1133 }
973 } 1134 }
974 } 1135 }
975 1136
@@ -1111,7 +1272,6 @@ namespace verbly {
1111 case object::word: 1272 case object::word:
1112 case object::frame: 1273 case object::frame:
1113 case object::part: 1274 case object::part:
1114 case object::lemma:
1115 case object::form: 1275 case object::form:
1116 case object::pronunciation: 1276 case object::pronunciation:
1117 { 1277 {
@@ -1141,11 +1301,10 @@ namespace verbly {
1141 return (verbly::word::frames %= *this); 1301 return (verbly::word::frames %= *this);
1142 } 1302 }
1143 1303
1144 case object::lemma:
1145 case object::form: 1304 case object::form:
1146 case object::pronunciation: 1305 case object::pronunciation:
1147 { 1306 {
1148 return (verbly::word::lemmas %= *this); 1307 return (verbly::word::forms(inflection::base) %= *this);
1149 } 1308 }
1150 } 1309 }
1151 1310
@@ -1161,7 +1320,6 @@ namespace verbly {
1161 1320
1162 case object::notion: 1321 case object::notion:
1163 case object::word: 1322 case object::word:
1164 case object::lemma:
1165 case object::form: 1323 case object::form:
1166 case object::pronunciation: 1324 case object::pronunciation:
1167 { 1325 {
@@ -1188,7 +1346,6 @@ namespace verbly {
1188 case object::notion: 1346 case object::notion:
1189 case object::word: 1347 case object::word:
1190 case object::frame: 1348 case object::frame:
1191 case object::lemma:
1192 case object::form: 1349 case object::form:
1193 case object::pronunciation: 1350 case object::pronunciation:
1194 { 1351 {
@@ -1197,32 +1354,6 @@ namespace verbly {
1197 } 1354 }
1198 } 1355 }
1199 1356
1200 case object::lemma:
1201 {
1202 switch (singleton_.filterField.getObject())
1203 {
1204 case object::notion:
1205 case object::word:
1206 case object::frame:
1207 case object::part:
1208 {
1209 return verbly::lemma::words %= *this;
1210 }
1211
1212 case object::undefined:
1213 case object::lemma:
1214 {
1215 return *this;
1216 }
1217
1218 case object::form:
1219 case object::pronunciation:
1220 {
1221 return (verbly::lemma::forms(inflection::base) %= *this);
1222 }
1223 }
1224 }
1225
1226 case object::form: 1357 case object::form:
1227 { 1358 {
1228 switch (singleton_.filterField.getObject()) 1359 switch (singleton_.filterField.getObject())
@@ -1231,9 +1362,8 @@ namespace verbly {
1231 case object::word: 1362 case object::word:
1232 case object::frame: 1363 case object::frame:
1233 case object::part: 1364 case object::part:
1234 case object::lemma:
1235 { 1365 {
1236 return verbly::form::lemmas %= *this; 1366 return verbly::form::words(inflection::base) %= *this;
1237 } 1367 }
1238 1368
1239 case object::undefined: 1369 case object::undefined:
@@ -1257,7 +1387,6 @@ namespace verbly {
1257 case object::word: 1387 case object::word:
1258 case object::frame: 1388 case object::frame:
1259 case object::part: 1389 case object::part:
1260 case object::lemma:
1261 case object::form: 1390 case object::form:
1262 { 1391 {
1263 return verbly::pronunciation::forms %= *this; 1392 return verbly::pronunciation::forms %= *this;
@@ -1354,6 +1483,8 @@ namespace verbly {
1354 case comparison::string_is_not_like: 1483 case comparison::string_is_not_like:
1355 case comparison::is_null: 1484 case comparison::is_null:
1356 case comparison::is_not_null: 1485 case comparison::is_not_null:
1486 case comparison::field_equals:
1487 case comparison::field_does_not_equal:
1357 { 1488 {
1358 result += std::move(normalized); 1489 result += std::move(normalized);
1359 1490