Click here to monitor SSC
SQLServerCentral is supported by Red Gate Software Ltd.
 
Log in  ::  Register  ::  Not logged in
 
 
 
        
Home       Members    Calendar    Who's On


Add to briefcase «««1112131415»»

Normalization Expand / Collapse
Author
Message
Posted Thursday, April 28, 2011 5:10 AM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Today @ 2:08 PM
Points: 8,844, Visits: 9,405
Steven993 (4/28/2011)
So there is no logical difference between Relation and Table ?

There's a semantic difference. So far as I'm aware neither is a term of logic, so there can't be a logical difference.

I suggested a definition for a relation in a given state a few posts back. Did you look at that? Do you think that defintion could imaginably be the definition of a table?

Try not to be so boringly patronising.


Tom
Post #1100124
Posted Thursday, April 28, 2011 2:10 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Today @ 2:08 PM
Points: 8,844, Visits: 9,405
Tom.Thomson (4/27/2011)
But a relational equality can easily be defined in the Codd system: two relational systems are equal if they both contain the same rows; two rows are the same if every attribute of one is the same as the corresponding attribute in the other; two attributes are the same they have the same type and [both are a-NULL or both are i-NULL or [neither is null] and they have equal values]. That definition of sameness of rows has an implication for uniqueness that Codd might have disapproved of (he wanted two attribute which are both a-NULL to be regarded as different for the purpose of evaluating constraints, including UNIQUE constraints, so pehaps including the implicit UNIQUE constraint on the complete attribute maps in collection of rows that make up a relation; but that seems to me to be clearly a dead end when looking at relation). I don't know how to define a relational equality that Codd would definitely have approved of (because it seems necessary to define row sameness to define relational equality), so yes, there's some incompleteness in Codd's work - just as there is in every scientist's or mathematician's work.

That's been bothering me, because I should know what Codd's view was on tuple equality, so I did some digging. There's a partial answer in his "Extending the Database Relational Model to Capture More Meaning" which he submitted to ACM in March '79. It turns out that in 1979 he chose pretty much what I suggested using above (apart from the misplaced "]" - the two "]"s should have been together at the point where the second one is, otherwise the inner bracketing doesn't resolve the ambiguity or the English), so he presumably would have mostly agreed with my proposed definition or equality between relations with nulls. But that isn't 100% certain because although he begain by talking about the 2 NULL system he then said he would consider them both as just a single "missing value" NULL and use a 3VL instead of a 4VL, before going on to say when checking two tuples for equality for the purpose of considering whether one tuple was a duplicate of the other two nulls would be considered as equal; so we don't know whether in the 4VL version he would have considered a-NULL ands i-NULL equal to each other for this purpose or would have treated them as unequal (My suggestion above treats them as unequal in for that test, but I think it would be better to treat them as equal - not as much better as not having i-NULL at all would be, of course).
Next time I'll wait before posting if I think I'm nissing something like that.


Tom
Post #1100582
Posted Friday, April 29, 2011 2:42 PM


SSCarpal Tunnel

SSCarpal TunnelSSCarpal TunnelSSCarpal TunnelSSCarpal TunnelSSCarpal TunnelSSCarpal TunnelSSCarpal TunnelSSCarpal TunnelSSCarpal Tunnel

Group: General Forum Members
Last Login: 2 days ago @ 7:44 PM
Points: 4,240, Visits: 4,284
I did not state my intent correctly.

When I said Billing Address or Mailing Address I meant a separate table with an Address Type.

I have normalize beyond the 3rd Normal Form when appropriate, so I will take the hit and I apologize for offending anyone and I would appreciate it if we could all move on and agree to disagree and respect each others differences.

With respect to a separate table for each address line with an address line type that is a judgement decision and I did not mean to offend anyone.

I regret some of the comments that I said but can we put our differences aside and play nice in the sandbox?




For better, quicker answers on T-SQL questions, click on the following...
http://www.sqlservercentral.com/articles/Best+Practices/61537/

For better answers on performance questions, click on the following...
http://www.sqlservercentral.com/articles/SQLServerCentral/66909/

Post #1101061
Posted Friday, April 29, 2011 7:04 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Today @ 2:08 PM
Points: 8,844, Visits: 9,405
Welsh, I don't think you need to worry about offending anyone, you haven't done anything outside the bounds of normal conversation (except perhaps that long string of short messages when you were distracted by something, none of which were in any way offensive). If we're kicking sand at each other here it's not your fault.

Tom
Post #1101125
Posted Tuesday, May 10, 2011 1:20 PM
SSC-Addicted

SSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-Addicted

Group: General Forum Members
Last Login: Today @ 4:28 AM
Points: 448, Visits: 3,354
Tom.Thomson (4/27/2011)
Ted Codd
There are two options:
1. warn users not to use tautologies as conditions in their relational-lan-
guage statements (tautologies waste the computer's resources);
2. develop a DBMS that examines all conditions not in excess of some
clearly specified complexity, and determines whether each condition is
a tautology or not.

Naturally, in this latter case, it would be necessary to place some limitation
on the complexity of each and every query, because with predicate logic the
general problem is unsolvable. In my opinion, option 1 is good enough for
now because this is not a burning issue.

In other words he took the view that tautology detection was unneccessary at present. So that answer's your question: assume the deduction rules don't contain any tautology detection. If you have a 4VL make your language warn you clearly when the i and a truth values crop up; and if you have a 3VL make your language warn you when the u truth value turns up.

I had always assumed that the detection mechanism mentioned by Codd would have to be applied at runtime and evaluated for each tuple involved in a query rather than just be based on static analysis of the query syntax. The reason I thought runtime evaluation was necessary was because of situations like the following one. Using the Codd table:

z x
---- ----
4 2
0 a-null

A restriction based on the condition that z / x = 0 would apparently return no tuples (based on RM2 page 185) even though z = 0 divided by any applicable value is known to be 0. I certainly don't share Codd's curious optimism that this is "not a burning issue" - but for the purposes of this discussion I will assume for the time being that it isn't.

I'm prepared to consider some other 3VL system but I'm not sure exactly what you are proposing if your system is not Codd's 4VL and not SQL's 3VL. Just to restate your explanation of relational equality and join dependency. I understand that you think null marks of the same kind for the same attribute should be considered equal for the purposes of relational comparison but not for joins. So where T is a table then T = T is always true (with nulls or without) but T |X| T = T is not necessarily true. In other words a table does not necessarily satisfy even trivial join dependencies. Is that correct?

So for example if I have some things (in the DB: some maps in a relation) such that for each thing (in the DB: map - I suppose I have to call it tuple in a RDB context although it's mathematically inappropriate) R it is true that if R.Y has a non-null value then R.Z must be inapplicable and vice-versa then that constrain in the modelled world is a functional dependency in the model - a functional dependency requiring something to be NULL. If I ignore nulls, normalisation will not eliminate non-trivial functional dependencies like this one, so I can't ignore NULLs for normalisation. If I throw away i-NULL and just have one pure NULL, I can't construct functional dependencies like this, so goodbye i-NULL and 4VL, let's get back to a single pure null and a 3VL.

Wouldn't you want to define funcational dependency in an analogous way to how you've defined join dependency? I mean that an FD A->B is never satisfied by any table where B permits nulls? If you allow the FD A->B to be satisfied when B permits nulls then you would have FDs that were not also JDs. To comply with Fagin's definition of PJ/NF the set of join dependencies satisfied by a Codd table would have to be equivalent to the set of all key dependencies (FDs, MVDs and JDs implied by the keys of the table). So if A->B is a permissable FD where B allows nulls then by your definition of a JD you could have a Codd table which satisfied PJ/NF but not 3NF.

Alternatively, assume the FD A->B is never satisfied if B permits nulls. Now we seem to have a situation even worse than the kludge that Codd suggested for applying normalization with nulls. Codd proposed that an FD could be in effect if you ignored only the rows where nulls occurred. However, if we insist that an FD is also a JD then by your definition of JDs it seems that a FD doesn't permit nullable attributes either. So we would have a strange situation where we can add any nullable attributes we like to a Codd table, without any risk of creating a non-key dependency and so normalization becomes a useless exercise in the face of those nullable attributes.

I can believe that it might just be possible to devise some hypothetical system of nulls and tables with a set of derivation rules that makes sense of the normal forms we know. That hypothetical system is certainly not SQL. Nor will it be RM2 if you want 3VL instead of 4VL. In the absence of the definition of any such system (please define it if you think you can) I stand by my orginal comments on nulls, which are borne out when the consequences of RM2 are considered: None of 1NF,2NF,3NF,BCNF,4NF,5NF,PJ/NF,DKNF allow nulls. A table that permits nulls is not an accurate representation of a relation that satisfies any of those NFs.

In the design of a database one does not normalise views. In fact it is utter nonsense to want to talk about 3NF for views

It certainly isn't nonsense in the relational model without nulls. In the absence of nulls a view is a derived relation and a derived relation appears the same and has all the same essential properties as any base relation. Normalization is orthogonal to whether relations are base or derived and the database designer ought to be able to apply normalization to any relation schema without concerning himself about whether relations are base or not. If normalization theory is rendered useless (as I think it must be) by the presence of derived Codd tables then that is a problem caused by Codd's model of keyless tables. It is not a problem that exists in the relational model without nulls.


David
Post #1106479
Posted Tuesday, May 10, 2011 1:46 PM
SSC-Addicted

SSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-Addicted

Group: General Forum Members
Last Login: Today @ 4:28 AM
Points: 448, Visits: 3,354
Belatedly I realised that normalization isn't entirely defeated by Codd tables without keys. Given the definition of JDs already discussed, the Codd table T(a) would satisfy the JD * (a,{}) where {} is a projection on the empty set of attributes. This is a trivial join dependency. But if T doesn't have any keys then this trivial JD must be a JD not implied by keys. So T is not in PJ/NF.

David
Post #1106489
Posted Tuesday, May 10, 2011 5:42 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Today @ 2:08 PM
Points: 8,844, Visits: 9,405
David Portas (5/10/2011)
I had always assumed that the detection mechanism mentioned by Codd would have to be applied at runtime and evaluated for each tuple involved in a query rather than just be based on static analysis of the query syntax. The reason I thought runtime evaluation was necessary was because of situations like the following one. Using the Codd table:

z x
---- ----
4 2
0 a-null

A restriction based on the condition that z / x = 0 would apparently return no tuples (based on RM2 page 185) even though z = 0 divided by any applicable value is known to be 0. I certainly don't share Codd's curious optimism that this is "not a burning issue" - but for the purposes of this discussion I will assume for the time being that it isn't.

Well, presumably one of the applicable values that a-null could be is 0, and it surely is not true that 0/0 delivers 0 (it should deliver something like "error: indeterminate value" or "error: zero-divide" if it's a bit less good at distinguishing between errors); so if we look at Codd's true selection we get no rows, and if we look at his maybe-selection we get 1 row (I can't remember whether the true-op and maybe-op distinction is explicitly mentioned in teh RM2 paper, but the earlier papers with nulls and MVL certainly have it). Also, although a-null and i-null appear to be mutually exclusive, the RM2 model does explicitly allow a-null to become i-null, so a-null doesn't really mean there is known to be an applicable value, so that's another case of a valid substitution for the a-null that would leave no rows delivering true.
I'm prepared to consider some other 3VL system but I'm not sure exactly what you are proposing if your system is not Codd's 4VL and not SQL's 3VL. Just to restate your explanation of relational equality and join dependency. I understand that you think null marks of the same kind for the same attribute should be considered equal for the purposes of relational comparison but not for joins. So where T is a table then T = T is always true (with nulls or without) but T |X| T = T is not necessarily true. In other words a table does not necessarily satisfy even trivial join dependencies. Is that correct?

If T has any columns that allow NULLs, the it doesn't satisfy T |X| T = T; because if T has a nullable column C and P1 and P2 are both projections of T that contain C then P1 |X| P2 = /= T. That doesn't prevent the table from satisfying some trivial join dependencies (if your definition of a trivial join dependency is that it is one in which every projection concerned includes the whole of the primary key, which is the one I remember from a long time ago) since the set of distinct projections each of which is on the key columns plus one other column always delivers a trivial join dependency that is satisfied. If you mean some things which are trivial join dependencies (and hence are satisfied) in the null-free model are not join dependencies (because they are not satisfied) in a null-containing model that is absolutelyabsolutely correct. If you mean no trivial join dependencies are satisfied in a null containing model, that is incorrect.

So for example if I have some things (in the DB: some maps in a relation) such that for each thing (in the DB: map - I suppose I have to call it tuple in a RDB context although it's mathematically inappropriate) R it is true that if R.Y has a non-null value then R.Z must be inapplicable and vice-versa then that constrain in the modelled world is a functional dependency in the model - a functional dependency requiring something to be NULL. If I ignore nulls, normalisation will not eliminate non-trivial functional dependencies like this one, so I can't ignore NULLs for normalisation. If I throw away i-NULL and just have one pure NULL, I can't construct functional dependencies like this, so goodbye i-NULL and 4VL, let's get back to a single pure null and a 3VL.

Wouldn't you want to define funcational dependency in an analogous way to how you've defined join dependency? I mean that an FD A->B is never satisfied by any table where B permits nulls? If you allow the FD A->B to be satisfied when B permits nulls then you would have FDs that were not also JDs. To comply with Fagin's definition of PJ/NF the set of join dependencies satisfied by a Codd table would have to be equivalent to the set of all key dependencies (FDs, MVDs and JDs implied by the keys of the table). So if A->B is a permissable FD where B allows nulls then by your definition of a JD you could have a Codd table which satisfied PJ/NF but not 3NF.

That's a perfectly reasonable reformulation of my argument (which you quoted) for throwing away the i-null concept; I don't see how a real null (as opposed to an i-null) could reasonably be possible in a column which is the target of a functional dependency (or of an MFD).
Alternatively, assume the FD A->B is never satisfied if B permits nulls. Now we seem to have a situation even worse than the kludge that Codd suggested for applying normalization with nulls. Codd proposed that an FD could be in effect if you ignored only the rows where nulls occurred. However, if we insist that an FD is also a JD then by your definition of JDs it seems that a FD doesn't permit nullable attributes either. So we would have a strange situation where we can add any nullable attributes we like to a Codd table, without any risk of creating a non-key dependency and so normalization becomes a useless exercise in the face of those nullable attributes.

I'm more optimistic. I think a straightforward Kleene logic 3VL with a single NULL which means nothing more than "this value is not in the database" works fine (that, unfortuantely for SQL, is nothing like the SQL NULL). I don't envisage a vast proliferation of nullable columns, since most of the time nulls aren't needed, and only a fool will permit them where they are unneccessary. And in a system with just the one sort of NULL I don't see any real problem with normalisation; for 2NF,3nF and 4NF we could define FDs as A->B when the value of A determines the value of B except where B is null, and MFDs as A->>B where the except that the any of the B attributes are permitted to be NULL (which was Codd's original proposal on Nulls and normalisation) or go with the rule that a nullable column is never in the target of an FD or an MFD (which is the easy way, but maybe not sensible). I would perhaps also be happy with using a separate calculus (where NULL = NULL delivers true) for defining 2nd, 3rd, and 4th normal forms (and maybe even for defining 5NF, although that feels sort of bizarre) if someone were to demonstrate the need for it, but I can't envisage the need being demonstrated and without the demonstration I'd be unhappy with such a definition. And I certainly do need that one NULL (or something for practical purposes equivalent) for real world problems where the application needs to know that data is missing and decide how to deal with it, and not be fobbed off with "default values" or the result of some really complex heterogenous union as a substitute for the natural result delivered by open join (which entails NULL) or by something built from open union (which also entails NULL).

I can believe that it might just be possible to devise some hypothetical system of nulls and tables with a set of derivation rules that makes sense of the normal forms we know. That hypothetical system is certainly not SQL. Nor will it be RM2 if you want 3VL instead of 4VL.

I guess we agree on that then - it won't be SQL and it won't be RM2. Nor will it be RM-T.
In the absence of the definition of any such system (please define it if you think you can) I stand by my orginal comments on nulls, which are borne out when the consequences of RM2 are considered: None of 1NF,2NF,3NF,BCNF,4NF,5NF,PJ/NF,DKNF allow nulls. A table that permits nulls is not an accurate representation of a relation that satisfies any of those NFs.

I don'tunderstand how that claim can imaginably be made in regard of 1NF by any intelligent person (although I do know perfectly well that several intelligent people have made it: you, Chris Date, Fabian Pascal,... it's a long list). Are you claiming for example that the domain consisting of the (fully defined) integers plus "bottom" is not a valid domain? If so, ouch! So we have a definition of domain for relational algebra that is radically different from the usual mathematical definition - that would be news to me, if true. I don't believe it makes sense for 1NF, 2NF, 3NF, BCNF, 4NF either, and of course DKNF is just a Ron Fagin fantasy (Chris Date has described the pointlessness of the DKNF definition very clearly, surely you've seen that?) which is guaranteed not to be obtainable for almost any real database (not just "not practically obtainable" but "provably unobtainable") - "almost any real database" here means every nontrivial database and most of the trivial ones too. For 5NF and PJ/NF (why list both, when they are the same thing?) I don't see any problem either.

In the design of a database one does not normalise views. In fact it is utter nonsense to want to talk about 3NF for views

It certainly isn't nonsense in the relational model without nulls. In the absence of nulls a view is a derived relation and a derived relation appears the same and has all the same essential properties as any base relation. Normalization is orthogonal to whether relations are base or derived and the database designer ought to be able to apply normalization to any relation schema without concerning himself about whether relations are base or not. If normalization theory is rendered useless (as I think it must be) by the presence of derived Codd tables then that is a problem caused by Codd's model of keyless tables. It is not a problem that exists in the relational model without nulls.[/quote]
True. But the relational model without NULL is not a model which is of sufficiently general applicability to be really useful, so even if it were a fact that it can consider normalisation of views that would be rather irrelevant; however, it can't. I have never seen any suggestion for rewriting queries in such a way that the output is guaranteed to be in 3NF (or even 2NF), and none of the databases I've seen that claim to implement the null-free relational model provides any feature to make that happen (a view would have to be a multitude of relations and constraints connecting them, for that to be possible). Suppose there is a base relation R with attributes named A,B,C,D,E,F (all using the integer domain), no nulls allowed, the relation is in 5NF and the primary key is (A,B,C); look at the operation expressed in SQL by
create view V as SELECT A,B,C,D,E,F from R where D=A+B and E=B-C and F = C*A
The derived relation V that this produces can't be in 3NF because it violates 2NF at least 3 times: (A,B,C) is the primary key of V, but each of D, E, and F is dependednt on only 2 of the 3 key attributes. But that operation is a perfectly valid one in every null-excluding system I have encountered - in fact it is surely a fundamental requirement of the relational model that such a restriction operation can be implemented. Obviously I could write much nastier queries than that, where the output (in order to be in 3NF) would have to be broken into dozens of relations, but it seems reasonable to restrict myself to this extremely simple example (which requires splitting into at least 3 separate derived tables to reach 2NF - and of course almost certainly what the application using the database wants is not several separate relations that it has to join to get the single relation it needs, it wants the single relation and is not interested in 2NF).


Tom
Post #1106577
Posted Tuesday, May 10, 2011 5:49 PM


SSCrazy Eights

SSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy EightsSSCrazy Eights

Group: General Forum Members
Last Login: Today @ 2:08 PM
Points: 8,844, Visits: 9,405
David Portas (5/10/2011)
Belatedly I realised that normalization isn't entirely defeated by Codd tables without keys. Given the definition of JDs already discussed, the Codd table T(a) would satisfy the JD * (a,{}) where {} is a projection on the empty set of attributes. This is a trivial join dependency. But if T doesn't have any keys then this trivial JD must be a JD not implied by keys. So T is not in PJ/NF.

Don't forget that Codd required both that every base table have a primary key and that no attribute included in a primary key permit NULL.
Since there is no key, you are talking about a derived table here, and derived tables are often not in PJ/NF even when NULLs are not allowed - see my post with an example of the restriction operator delivering from a 5NF table (with no nulls permitted) a derived table (also with no nulls permitted) which isn't even in 2NF, let alone in PJ/NF. The presence of NULLs makes no significant difference to questions of normality for derived tables - unless of course we include the requirement for a primary key in the definition of 1NF and don't inculde a requirement that that primary key be meaninful, in which case 1NF is a form which the null-free model can guarantee in derived relatins while the null-allowing model can't; of course if we include a requirement for a meaningful primary key neither model can guarantee it).


Tom
Post #1106578
Posted Tuesday, June 21, 2011 3:34 PM
SSC-Addicted

SSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-AddictedSSC-Addicted

Group: General Forum Members
Last Login: Today @ 4:28 AM
Points: 448, Visits: 3,354
Tom.Thomson (5/10/2011)
Well, presumably one of the applicable values that a-null could be is 0, and it surely is not true that 0/0 delivers 0 (it should deliver something like "error: indeterminate value" or "error: zero-divide" if it's a bit less good at distinguishing between errors);

Yes but that's just a neat way to sidestep the real problem we were talking about. If I'd said z * x = 0 instead of z/x = 0 would you be any more likely to agree that MVL without tautology detection is just an accident waiting to happen?

You have answered my main argument about any hypothetical system which can support both Normalization and nulls at the same time:

it won't be SQL and it won't be RM2. Nor will it be RM-T.

In other words it is none of the sytems that people are likely to be talking about on SSC. If you have your own definition of such a system then please publish it somewhere so that I can understand and scrutinise it properly. The space in this forum is certainly too small for that - after all Codd wrote 500 pages and still didn't manage it! Until you've done that I'm going to remain as sceptical as anyone else with a scientific mind should. Myself and millions of others who know of no such system are going to stick with what is presently known: that normal forms as originally defined have nothing to do with any table with a null in it.

For 5NF and PJ/NF (why list both, when they are the same thing?

According to some sources (e.g. David Maier, Terry Halpin and this) they are not the same thing. I mentioned PJ/NF to make it clear that I was talking about Fagin's original definition and not any other.

Are you claiming for example that the domain consisting of the (fully defined) integers plus "bottom" is not a valid domain?

It's clear to me right from Codd's first papers and I think from everything else I've ever read about the relational model that what RM calls a domain is a set, not a poset. A relational domain as conventionally defined is not the same as what domain theory calls a domain.


David
Post #1129363
Posted Thursday, June 23, 2011 6:00 AM


Hall of Fame

Hall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall of FameHall of Fame

Group: General Forum Members
Last Login: Tuesday, January 28, 2014 8:15 AM
Points: 3,068, Visits: 4,639
fourteen, fourteen pages already on this thread!!!

There is an abundant amount of information on the posts of this thread but I'm affraid most people wouldn't read it from start to end then same queistions, issues, comments and answers can be found once and again.

Don't you think it is time to close this one and start new, more specific threads on data normalization?

Just my two cents.


_____________________________________
Pablo (Paul) Berzukov

Author of Understanding Database Administration available at Amazon and other bookstores.

Disclaimer: Advice is provided to the best of my knowledge but no implicit or explicit warranties are provided. Since the advisor explicitly encourages testing any and all suggestions on a test non-production environment advisor should not held liable or responsible for any actions taken based on the given advice.
Post #1130319
« Prev Topic | Next Topic »

Add to briefcase «««1112131415»»

Permissions Expand / Collapse