Re: RFC: "UPSERT" in PostgreSQL
On Sep 29, 2014, at 2:46 PM, shmengie <1st...@gmail.com> wrote: > Merge -- bulk loading foreign data -no guaranty > > upsert -- insert or update row w/confidence. Sounds like a difference without a distinction. Let spin it a different way: the MERGE syntax, and broad semantic, is fine as it is, for all use cases, in all its ISO glory. There is no compelling reasons to invent another one. The only point of contention is what guaranty, if any, the MERGE statement provides, which is formally none. The UPSERT statement as suggested identify a narrow use case where it can provide some sort of guaranties about atomicity and race condition [1]. Beautiful. Let this be an implementation detail of MERGE as understood by Postgres: under the right circumstances, Postgres' MERGE implementation guaranties such and such. This is a compelling implementation advantage. But not one that warrant a different syntax and semantic altogether. My 2¢. [1] http://www.depesz.com/2012/06/10/why-is-upsert-so-complicated/ -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/45E95C5A-31CE-4177-82A4-1BBCB0F0A5EA%40gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: RFC: "UPSERT" in PostgreSQL
On Sep 28, 2014, at 9:15 PM, Peter Geoghegan wrote: > Would you be happier with that? I would be happier with a clean MERGE statement implementation in Postgres, yes. And yes, I have followed Postgres' agonizing debate over the years about the subject. But I personally think it has been framed in the wrong light since the very beginning and that Postgres has convince itself that it somehow cannot support MERGE. Therefore it will not. To paraphrase Ian Grigg [1], albeit in a different context: we fixed what we could, not what we should, because it was easier. Anyway, these where my 2¢. Remember, you asked for feedback :) [1] http://www.mail-archive.com/cryptography%40metzdowd.com/msg01276.html -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/B947073A-F9E1-4CFF-A9D3-C37ABC78CF96%40gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: RFC: "UPSERT" in PostgreSQL
On Sep 28, 2014, at 3:32 PM, Aymeric Augustin wrote: > You're allowed to disagree with that decision, however: You are right. Apologies about that. Moving along. -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/82E739C0-E74E-4714-A765-BC3DB020B979%40gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: RFC: "UPSERT" in PostgreSQL
On Sep 28, 2014, at 11:21 AM, Peter Geoghegan wrote: > On Sun, Sep 28, 2014 at 1:51 AM, Petite Abeille > wrote: >> For diversity's sake, and for the record, I, for one, would definitively >> rather have the standard MERGE statement instead of yet another 'weird' >> UPSERT concoction peculiar to Postgres. > > A few people have said that, but then when you look at SQL MERGE in > detail it becomes apparent that it is really intended to serve the > bulk loading use-case. A bad case of confirmation bias :D > I took the time to delineate the differences > between SQL MERGE and what I call UPSERT in detail [1]. Again, your house, your choice. But it seems a bit self-indulgent to concoct your very own take on MERGE, with baroque syntax, peculiar semantic, and all, just because some abstract aspects of the MERGE specification is not to you liking... rather self-defeating altogether. Anyway, just my 2¢. -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/6F5E6744-BE21-43EA-A11E-EF8D9CF5E5C0%40gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: RFC: "UPSERT" in PostgreSQL
On Sep 28, 2014, at 1:01 AM, Peter Geoghegan wrote: > The SQL standard's MERGE statement is kind of weird... For diversity's sake, and for the record, I, for one, would definitively rather have the standard MERGE statement instead of yet another 'weird' UPSERT concoction peculiar to Postgres. Just saying :) -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/96DA6BA9-D53E-4944-8881-2DE6AF197562%40gmail.com. For more options, visit https://groups.google.com/d/optout.
Re: The model API and strong typing
On Mar 1, 2014, at 9:14 AM, Martin Matusiak wrote: > Is there a rationale for why we don't do this? Perhaps because handling data constraint is the db job? In the case of sqlite, which is very free form, simply define the proper check constraints. For example: create table foo ( bar text not null, check( typeof( bar ) = 'text' and length( bar ) <= 10 ) ); sqlite> insert into foo values( 1 ); Error: CHECK constraint failed: foo sqlite> insert into foo values( '12345678901' ); Error: CHECK constraint failed: foo -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/69E6D147-96ED-45FB-95CD-40D238C8CB20%40gmail.com. For more options, visit https://groups.google.com/groups/opt_out.
Re: Using EXISTS instead of IN for subqueries
On Mar 26, 2013, at 10:03 PM, Alex Gaynor wrote: > For what it's worth, SQL2011 does define OFFSET, finally. Perhaps worthwhile mentioning as well : "Do not try to implement a scrolling window using LIMIT and OFFSET. Doing so will become sluggish as the user scrolls down toward the bottom of the list." -- Scrolling Cursor, What Not To Do http://www.sqlite.org/cvstrac/wiki?p=ScrollingCursor Just saying... -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Using EXISTS instead of IN for subqueries
On Mar 26, 2013, at 4:19 PM, Michael Manfre wrote: > Maybe someday the non-standard LIMIT/OFFSET keywords will get added to the > standard (I truly hope this happens) so Oracle, MSSQL, DB2, and Informix > could share SQL with postgres and mysql without needing to mangle it. FWIW, Oracle 12c is rumored to support OFFSET/FETCH FIRST: • Top-N now using Row limiting clause eg. “OFFSET 10 ROWS FETCH FIRST 10 ROWS ONLY”. Similar to mySQL syntax. http://www.oracle-base.com/blog/2012/10/06/oracle-openworld-2012-day-5/ -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 9:36 PM, Ian Kelly wrote: > These particular lookups have a long history of being tweaked due to > users coming up with installations where the existing queries did not > work. See tickets #5985, #11017 and #14149. I'd rather not reopen > this issue unless the current implementation can documentably be shown > to be broken. Fair enough… Another point perhaps worthwhile mentioning: # There's no way for the DatabaseOperations class to know the # currently active Oracle version, so we do some setups here. https://github.com/django/django/blob/master/django/db/backends/oracle/base.py#L574 That information can be extracted from v$version, v$instance, dbms_db_version.version, product_component_version, etc, etc. The choice is yours. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 9:28 PM, Ian Kelly wrote: > Digging into the code a bit further, I see that the postgresql backend > accomplishes this by tacking '::text' onto the end of the field name > when the lookup is a string-based lookup like startswith. Oracle > could probably do something similar with the TO_CHAR function. Yep… explicitly convert the date column to a varchar and apply the like clause to it. And you are done. That said… from a db perspective… if you have more than an handful of rows… this is not going to fly much… just saying… -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 9:12 PM, Florian Apolloner wrote: > Interesting. Out of curiosity may I ask what brought you to this ML then? Ah, oh, yes, well… subscribed to the django mailing lists a while back to see what was all the fuss about :) That specific thread caught my eye, as I'm familiar with Oracle. And sympathize with the OP apparent frustration with the beast. > (Don't get me wrong, it's just not that often that people write to this > mailing list without using Python) Yeah, well, slow Sunday morning :D -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 8:28 PM, Aymeric Augustin wrote: > https://github.com/django/django/blob/master/django/db/backends/oracle/base.py#L548-L555 Last but not least… I couldn't help notice these suspicious looking operators: https://github.com/django/django/blob/master/django/db/backends/oracle/base.py#L479 https://github.com/django/django/blob/master/django/db/backends/oracle/base.py#L495 E.g. TRANSLATE … USING NCHAR_CS… and LIKEC… I suspect these are some sort of workarounds some fundamental charset encoding misunderstandings :) Perhaps best to revisit that in light of "Supporting Multilingual Databases with Unicode" and "Programming with Unicode": http://docs.oracle.com/cd/E14072_01/server.112/e10729/ch6unicode.htm http://docs.oracle.com/cd/E14072_01/server.112/e10729/ch7progrunicode.htm Just my 2¢ though. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 8:45 PM, Florian Apolloner wrote: > Patches welcome… Yes, I wish I knew Python. Sadly I don't. :) > Well the issue is that nobody wrote get_key_columns yet, so we'd need a > patch which adds this method to the oracle backend, examples can be taken > from postgres > https://github.com/django/django/blob/master/django/db/backends/postgresql_psycopg2/introspection.py#L70-85 > If this is about getting the various constraints, this looks like 'get_relations' method: https://github.com/django/django/blob/master/django/db/backends/oracle/introspection.py#L65 > Postgres supports information_schema which is part of the SQL standard, I > don't think Oracle supports it. No, but the Oracle data dictionary is much more extensive than the information schema, so it's rather straightforward to get what one wants: http://docs.oracle.com/cd/B28359_01/server.111/b28318/datadict.htm > If you know the oracle tables, please > provide us with the query which brings out the needed data… I'm not clear what 'get_key_columns' does, but based on the Postgres code, I suspect it tries to get all the referential constraints keys, right? Looks like this is what 'get_relations' does as well already. Perhaps just a name mismatch. Anyhow, for the record, here are various introspection queries examples which may or may not be of interest (these are aggregates, so not necessarily at the granularity you might want): PrimaryKey as ( select/*+ materialize */ all_cons_columns.owner, all_cons_columns.table_name, all_cons_columns.column_name, all_cons_columns.constraint_name from TableSet join all_constraints onall_constraints.owner = TableSet.owner and all_constraints.table_name = TableSet.table_name join all_cons_columns onall_cons_columns.owner = all_constraints.owner and all_cons_columns.constraint_name = all_constraints.constraint_name where all_constraints.constraint_type = 'P' ), UniqueKey as ( select/*+ materialize */ all_cons_columns.owner, all_cons_columns.table_name, all_cons_columns.column_name, listagg( all_cons_columns.constraint_name, ', ' ) within group( order by all_cons_columns.constraint_name ) as constraint_name, count( distinct all_cons_columns.constraint_name ) as constraint_count from TableSet join all_constraints onall_constraints.owner = TableSet.owner and all_constraints.table_name = TableSet.table_name join all_cons_columns onall_cons_columns.owner = all_constraints.owner and all_cons_columns.constraint_name = all_constraints.constraint_name where all_constraints.constraint_type = 'U' group by all_cons_columns.owner, all_cons_columns.table_name, all_cons_columns.column_name ), ForeignKey as ( select/*+ materialize */ all_cons_columns.owner, all_cons_columns.table_name, all_cons_columns.column_name, listagg( all_cons_columns.constraint_name, ', ' ) within group( order by all_cons_columns.constraint_name ) as constraint_name, count( distinct all_cons_columns.constraint_name ) as constraint_count, listagg( r_cons_columns.owner || '.' || r_cons_columns.table_name || '.' || r_cons_columns.column_name ) within group( order by r_cons_columns.owner, r_cons_columns.table_name, r_cons_columns.column_name ) as r_constraint_column, listagg( r_cons_columns.constraint_name, ', ' ) within group( order by r_cons_columns.constraint_name ) as r_constraint_name from TableSet join all_constraints onall_constraints.owner = TableSet.owner and all_constraints.table_name = TableSet.table_name join all_cons_columns onall_cons_columns.owner = all_constraints.owner and all_cons_columns.constraint_name = all_constraints.constraint_name join all_constraints r_constraints onr_constraints.owner = all_constraints.r_owner and r_constraints.constraint_name = all_constraints.r_constraint_name join all_cons_columns r_cons_columns onr_cons_columns.owner = r_constraints.owner and r_cons_columns.constraint_name = r_constraints.constraint_name and r_cons_columns.position = all_cons_columns.position where all_constraints.constraint_type = 'R' group by all_cons_columns.owner, all_cons_columns.table_name, all_cons_columns.column_name ), IndexName as ( select/*+ materialize */ all_ind_columns.table_owner as owner, all_ind_columns.table_name, all_ind_columns.column_name, listagg( all_ind_columns.index_name, ', ' ) within group( order by all_ind_columns.index_name ) as index_name from TableSet join all_i
Re: Test failures under Oracle
On Mar 10, 2013, at 8:28 PM, Aymeric Augustin wrote: > Django does this already: > https://github.com/django/django/blob/master/django/db/backends/oracle/base.py#L548-L555 Perfect. In the case of #20015, the issue is the other way round… the literal '2008%' cannot be implicitly converted to a date. Implicit conversion always go to the narrowest type. You would be better off converting it explicitly, e.g. to_date( '2008', '' ) or such. Then the query become date >= to_date( '2008', '' ). Alternatively, you could convert the date column to a varchar: to_char( date ) like '2008%'… -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 7:56 PM, Petite Abeille wrote: > If you are not explicit, the session NLS format is applied, with > unpredictable results. For the record, one can always set this explicitly at the session level as well, e.g.: alter session set nls_date_format = '-MM-DD"T"HH24:MI:SS' or such. Ditto for timestamps. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 7:11 PM, Ian Kelly wrote: > #20015 looks like an expected failure. Oracle supports lookups of > date fields using strings by implicitly converting the string to a > date. The test is doing a startswith lookup that is going to produce > sql that looks something like "WHERE date_column LIKE '2008%'". If you have a date type, stick to a date type. Converting to a varchar to run a like query is counterproductive. If one is looking for a date, just look for a date, e.g. ' extract( year from date_column ) = 2008 ' or such. Otherwise, you must explicitly convert the date to a specific varchar format, e.g. . to_char( date_column, 'MMDD' ) like '2008%' If you are not explicit, the session NLS format is applied, with unpredictable results. > That's not going to work because Oracle can't convert '2008%' into a > date. So the test here is testing that the > 'supports_date_lookup_using_string' feature is more comprehensive than > Oracle actually supports. Such string to date conversion depends on the session NSL settings if not explicit. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 7:04 PM, Florian Apolloner wrote: > It's not always just SQL and even then, before formulating them in SQL it's > easier to just ask the Oracle users to take a look at the failing issues > and provide help there… Eg: https://code.djangoproject.com/ticket/20014 is > a perfect example where someone with Oracle knowledge can chime in, but > everyone else has probably hours in front of him to figure out how the > query should look like (and once he has the query the issue is solved ;)). Assuming this are the tests: https://github.com/django/django/blob/master/tests/introspection/tests.py Picking a random example: # The following test fails on Oracle due to #17202 (can't correctly # inspect the length of character columns). @expectedFailureOnOracle def test_get_table_description_col_lengths(self): cursor = connection.cursor() desc = connection.introspection.get_table_description(cursor, Reporter._meta.db_table) self.assertEqual( [r[3] for r in desc if datatype(r[1], r) == 'CharField'], [30, 30, 75] ) get_table_description is define as: def get_table_description(self, cursor, table_name): "Returns a description of the table, with the DB-API cursor.description interface." cursor.execute("SELECT * FROM %s WHERE ROWNUM < 2" % self.connection.ops.quote_name(table_name)) description = [] for desc in cursor.description: description.append(FieldInfo(*((desc[0].lower(),) + desc[1:]))) return description https://github.com/django/django/blob/master/django/db/backends/oracle/introspection.py#L46 In this case, two factors are playing against you: (1) Whereabout way to get table metadata (i.e. query the table to figure out its data to figure out its meta data). Instead, using the data dictionary directly would be more reliable and to the point, e.g. select owner, table_name, column_name, ... from [user|all]_tab_columns. (2) Distinction between char length vs. byte length. See DATA_LENGTH vs. CHAR_LENGTH vs. CHAR_USED. Related to NLS_LENGTH_SEMANTICS. The short of it, bytes != chars. Some other random comments: (A) def table_name_converter(self, name): "Table name comparison is case insensitive under Oracle" return name.lower() https://github.com/django/django/blob/master/django/db/backends/oracle/introspection.py#L54 That's not quite the case, even if it would appear so. Contrast "Fubar" vs. "FUBAR" vs FUBAR. (note the double quotes). See quoted identifier vs. nonquoted identifier. The short of it, identifier can be case sensitive, even though it's best to stay clear from such a deep rabbit hole. (B) oracle / introspection.py uses the USER_ flavor of the data dictionary (e.g. USER_TABLES). The USER_ flavor only shows objects which are directly owned by the schema. Which may be quite restrictive. You may be better off using the ALL_ flavor, which shows all the objects visible to the schema, irrespectively of ownership. ( C ) Try to formulate queries using the ANSI join syntax instead of the legacy Oracle one (i.e. left join vs. (+) ). The ANSI syntax is clearer, less error prone, and, well, more portable. As far as that test_get_key_columns failure goes, I couldn't track down the code for connection.introspection.get_key_columns… but I suspect it has something to do with point (1)... -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 12:58 PM, Aymeric Augustin wrote: > On 10 mars 2013, at 10:34, Petite Abeille wrote: > >> On Mar 10, 2013, at 9:52 AM, Aymeric Augustin >> wrote: >> >>> Oracle's online docs are a sad joke >> >> Specifically? The Oracle document is rather extensive and detailed. What's >> confusing you? > > > They're purely reference docs. Yes, the reference documentation is very extensive. > They make lots of assumptions about things you're already supposed to know. Yes, references are not tutorials. > They aren't educational at all. Yes. On the other hand, there are large swath of more conceptual materials as well, such as the "Developer Essentials" series: http://www.oracle.com/pls/db112/homepage Granted, this can all be a bit of a mouthful due to the sheer amount of documentation and tutorial material available. But it's there. > If you're familiar with Oracle — ie. you paid for training & certification, > or you're using it regularly — that's probably OK. Sure enough. > I'm only dealing with Oracle to fix failures in Django's test suite or ensure > that new features are supported under Oracle. Clearly I'm not smart or > knowledgeable enough to take advantage of its docs. If you can formulate the issues in terms of SQL, then perhaps someone could try to help sort it out. -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
Re: Test failures under Oracle
On Mar 10, 2013, at 9:52 AM, Aymeric Augustin wrote: > Oracle's online docs are a sad joke Specifically? The Oracle document is rather extensive and detailed. What's confusing you? -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-developers+unsubscr...@googlegroups.com. To post to this group, send email to django-developers@googlegroups.com. Visit this group at http://groups.google.com/group/django-developers?hl=en. For more options, visit https://groups.google.com/groups/opt_out.