Repository: tajo Updated Branches: refs/heads/master 8dad551ec -> 49d592024
TAJO-2104: Implement Identifier which supports quotation information. Closes #988 Project: http://git-wip-us.apache.org/repos/asf/tajo/repo Commit: http://git-wip-us.apache.org/repos/asf/tajo/commit/49d59202 Tree: http://git-wip-us.apache.org/repos/asf/tajo/tree/49d59202 Diff: http://git-wip-us.apache.org/repos/asf/tajo/diff/49d59202 Branch: refs/heads/master Commit: 49d5920242581d86c292dca3f9263bf6d2a607a7 Parents: 8dad551 Author: Hyunsik Choi <[email protected]> Authored: Mon Mar 28 19:51:40 2016 +0900 Committer: Hyunsik Choi <[email protected]> Committed: Mon Mar 28 19:51:40 2016 +0900 ---------------------------------------------------------------------- CHANGES | 3 + .../tajo/schema/ANSISQLIdentifierPolicy.java | 55 ++++++++++++ .../java/org/apache/tajo/schema/Identifier.java | 73 +++++++++++++++ .../apache/tajo/schema/IdentifierPolicy.java | 93 ++++++++++++++++++++ .../tajo/schema/PgSQLIdentifierPolicy.java | 55 ++++++++++++ .../apache/tajo/schema/QualifiedIdentifier.java | 57 ++++++++++++ .../java/org/apache/tajo/schema/Schema.java | 2 +- .../tajo/schema/TajoIdentifierPolicy.java | 29 ++++++ .../schema/TestANSISQLIdentifierPolicy.java | 48 ++++++++++ .../apache/tajo/schema/TestTajoIdentifier.java | 54 ++++++++++++ 10 files changed, 468 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/CHANGES ---------------------------------------------------------------------- diff --git a/CHANGES b/CHANGES index 971d8d8..cefb3df 100644 --- a/CHANGES +++ b/CHANGES @@ -8,6 +8,9 @@ Release 0.12.0 - unreleased IMPROVEMENT + TAJO-2104: Implement Identifier which supports quotation information. + (hyunsik) + TAJO-2099: Implement an Adapter for the legacy Schema. (hyunsik) TAJO-2091: Error or progress update should use stderr instead of stdout. http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/main/java/org/apache/tajo/schema/ANSISQLIdentifierPolicy.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/schema/ANSISQLIdentifierPolicy.java b/tajo-common/src/main/java/org/apache/tajo/schema/ANSISQLIdentifierPolicy.java new file mode 100644 index 0000000..c195bb6 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/schema/ANSISQLIdentifierPolicy.java @@ -0,0 +1,55 @@ +/* + * Lisensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.schema; + +/** + * ANSI SQL Standard Identifier Policy + */ +public class ANSISQLIdentifierPolicy extends IdentifierPolicy { + + @Override + String getName() { + return "ANSI SQL Identifier Policy"; + } + + @Override + public String getIdentifierQuoteString() { + return ANSI_SQL_QUOTE_STRING; + } + + @Override + String getIdentifierSeperator() { + return ANSI_SQL_SEPERATOR_STRING; + } + + @Override + public int getMaxColumnNameLength() { + return MAX_IDENTIFIER_LENGTH; + } + + @Override + IdentifierCase storesUnquotedIdentifierAs() { + return IdentifierCase.UpperCase; + } + + @Override + IdentifierCase storesQuotedIdentifierAs() { + return IdentifierCase.MixedCase; + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/main/java/org/apache/tajo/schema/Identifier.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/schema/Identifier.java b/tajo-common/src/main/java/org/apache/tajo/schema/Identifier.java new file mode 100644 index 0000000..ef4c2bf --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/schema/Identifier.java @@ -0,0 +1,73 @@ +/* + * Lisensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.schema; + +import org.apache.tajo.schema.IdentifierPolicy.IdentifierCase; + +/** + * Identifier Element + */ +public class Identifier { + private String name; + private boolean quoted; + + private Identifier(String name, boolean quoted) { + this.name = name; + this.quoted = quoted; + } + + public static Identifier _(String name) { + return new Identifier(name, false); + } + + public static Identifier _(String name, boolean quoted) { + return new Identifier(name, quoted); + } + + public String displayString(IdentifierPolicy policy) { + StringBuilder sb = new StringBuilder(); + if (quoted) { + appendByCase(sb, policy.storesQuotedIdentifierAs()); + sb.insert(0, policy.getIdentifierQuoteString()); + sb.append(policy.getIdentifierQuoteString()); + } else { + appendByCase(sb, policy.storesUnquotedIdentifierAs()); + } + + return sb.toString(); + } + + private void appendByCase(StringBuilder sb, IdentifierCase c) { + switch (c) { + case LowerCase: + sb.append(name.toLowerCase()); + break; + case UpperCase: + sb.append(name.toUpperCase()); + break; + case MixedCase: + sb.append(name); + break; + } + } + + public String toString() { + return displayString(IdentifierPolicy.DefaultPolicy()); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/main/java/org/apache/tajo/schema/IdentifierPolicy.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/schema/IdentifierPolicy.java b/tajo-common/src/main/java/org/apache/tajo/schema/IdentifierPolicy.java new file mode 100644 index 0000000..56762e7 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/schema/IdentifierPolicy.java @@ -0,0 +1,93 @@ +/* + * Lisensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.schema; + +/** + * Policy to describe how to deal identifiers + */ +public abstract class IdentifierPolicy { + + /** Quote String; e.g., 'abc' */ + public static final String ANSI_SQL_QUOTE_STRING = "'"; + /** Separator; e.g., abc.xyz */ + public static final String ANSI_SQL_SEPERATOR_STRING = "."; + /** Maximum length of identifiers */ + public final static int MAX_IDENTIFIER_LENGTH = 128; + + public enum IdentifierCase { + LowerCase, + UpperCase, + MixedCase + } + + /** + * Policy name + * + * @return Policy name + */ + abstract String getName(); + + /** + * Retrieves the string used to quote SQL identifiers. This method returns a space " " + * if identifier quoting is not supported. + * + * @return the quoting string or a space if quoting is not supported + */ + abstract String getIdentifierQuoteString(); + + /** + * Retrieves the <code>String</code> that this policy uses as the separator between + * identifiers. + * + * @return the separator string + */ + abstract String getIdentifierSeperator(); + + /** + * Retrieves the maximum number of characters this policy allows for a column name. + * + * @return the maximum number of characters allowed for a column name; + * a result of zero means that there is no limit or the limit is not known + */ + abstract int getMaxColumnNameLength(); + + /** + * Retrieves whether this policy treats unquoted SQL identifiers as + * which case and stores them in which case. + * + * @return IdentifierCase + */ + abstract IdentifierCase storesUnquotedIdentifierAs(); + + /** + * Retrieves whether this policy treats quoted SQL identifiers as + * which case and stores them in which case. + * + * @return IdentifierCase + */ + abstract IdentifierCase storesQuotedIdentifierAs(); + + public static final IdentifierPolicy DefaultPolicy() { + return new TajoIdentifierPolicy(); + } + + public static final IdentifierPolicy ANSISQLPolicy() { + return new ANSISQLIdentifierPolicy(); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/main/java/org/apache/tajo/schema/PgSQLIdentifierPolicy.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/schema/PgSQLIdentifierPolicy.java b/tajo-common/src/main/java/org/apache/tajo/schema/PgSQLIdentifierPolicy.java new file mode 100644 index 0000000..0aca2d7 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/schema/PgSQLIdentifierPolicy.java @@ -0,0 +1,55 @@ +/* + * Lisensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.schema; + +/** + * PostgreSQL Identifier Policy + */ +public class PgSQLIdentifierPolicy extends IdentifierPolicy { + + @Override + String getName() { + return "PostgreSQL Identifier Policy"; + } + + @Override + public String getIdentifierQuoteString() { + return ANSI_SQL_QUOTE_STRING; + } + + @Override + String getIdentifierSeperator() { + return ANSI_SQL_SEPERATOR_STRING; + } + + @Override + public int getMaxColumnNameLength() { + return MAX_IDENTIFIER_LENGTH; + } + + @Override + IdentifierCase storesUnquotedIdentifierAs() { + return IdentifierCase.LowerCase; + } + + @Override + IdentifierCase storesQuotedIdentifierAs() { + return IdentifierCase.MixedCase; + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/main/java/org/apache/tajo/schema/QualifiedIdentifier.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/schema/QualifiedIdentifier.java b/tajo-common/src/main/java/org/apache/tajo/schema/QualifiedIdentifier.java new file mode 100644 index 0000000..6f00ee9 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/schema/QualifiedIdentifier.java @@ -0,0 +1,57 @@ +/* + * Lisensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.schema; + +import com.google.common.base.Function; +import com.google.common.collect.ImmutableList; +import org.apache.tajo.util.StringUtils; + +import javax.annotation.Nullable; +import java.util.Collection; + +import static org.apache.tajo.schema.IdentifierPolicy.DefaultPolicy; + +public class QualifiedIdentifier { + private ImmutableList<Identifier> names; + + private QualifiedIdentifier(ImmutableList<Identifier> names) { + this.names = names; + } + + public String displayString(final IdentifierPolicy policy) { + return StringUtils.join(names, policy.getIdentifierSeperator(), new Function<Identifier, String>() { + @Override + public String apply(@Nullable Identifier identifier) { + return identifier.displayString(policy); + } + }); + } + + public String toString() { + return displayString(DefaultPolicy()); + } + + public static QualifiedIdentifier QualifiedIdentifier(Collection<Identifier> names) { + return new QualifiedIdentifier(ImmutableList.copyOf(names)); + } + + public static QualifiedIdentifier QualifiedIdentifier(Identifier...names) { + return new QualifiedIdentifier(ImmutableList.copyOf(names)); + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/main/java/org/apache/tajo/schema/Schema.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/schema/Schema.java b/tajo-common/src/main/java/org/apache/tajo/schema/Schema.java index d505062..332f622 100644 --- a/tajo-common/src/main/java/org/apache/tajo/schema/Schema.java +++ b/tajo-common/src/main/java/org/apache/tajo/schema/Schema.java @@ -52,7 +52,7 @@ public class Schema { } public static NamedStructType Struct(String name, NamedType... namedTypes) { - return new NamedStructType(name, Arrays.asList(namedTypes)); + return Struct(name, Arrays.asList(namedTypes)); } public static NamedStructType Struct(String name, Collection<NamedType> namedTypes) { http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/main/java/org/apache/tajo/schema/TajoIdentifierPolicy.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/main/java/org/apache/tajo/schema/TajoIdentifierPolicy.java b/tajo-common/src/main/java/org/apache/tajo/schema/TajoIdentifierPolicy.java new file mode 100644 index 0000000..f74be90 --- /dev/null +++ b/tajo-common/src/main/java/org/apache/tajo/schema/TajoIdentifierPolicy.java @@ -0,0 +1,29 @@ +/* + * Lisensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.schema; + +/** + * Tajo Identifier Policy + */ +public class TajoIdentifierPolicy extends PgSQLIdentifierPolicy { + @Override + String getName() { + return "Tajo Identifier Policy"; + } +} http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/test/java/org/apache/tajo/schema/TestANSISQLIdentifierPolicy.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/test/java/org/apache/tajo/schema/TestANSISQLIdentifierPolicy.java b/tajo-common/src/test/java/org/apache/tajo/schema/TestANSISQLIdentifierPolicy.java new file mode 100644 index 0000000..9643a89 --- /dev/null +++ b/tajo-common/src/test/java/org/apache/tajo/schema/TestANSISQLIdentifierPolicy.java @@ -0,0 +1,48 @@ +/* + * Lisensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.schema; + +import org.junit.Test; + +import static org.apache.tajo.schema.Identifier._; +import static org.apache.tajo.schema.IdentifierPolicy.ANSISQLPolicy; +import static org.apache.tajo.schema.QualifiedIdentifier.QualifiedIdentifier; +import static org.apache.tajo.schema.TestTajoIdentifier.assertIdentifier; +import static org.apache.tajo.schema.TestTajoIdentifier.assertQualifiedIdentifier; + +public class TestANSISQLIdentifierPolicy { + + @Test + public void displayString() throws Exception { + assertIdentifier(ANSISQLPolicy(), _("xyz"), "XYZ"); + assertIdentifier(ANSISQLPolicy(), _("XYZ"), "XYZ"); + + assertIdentifier(ANSISQLPolicy(), _("xyz", true), "'xyz'"); + assertIdentifier(ANSISQLPolicy(), _("xYz", true), "'xYz'"); + } + + @Test + public void testQualifiedIdentifiers() throws Exception { + assertQualifiedIdentifier(ANSISQLPolicy(), QualifiedIdentifier(_("xyz"), _("opq")), "XYZ.OPQ"); + assertQualifiedIdentifier(ANSISQLPolicy(), QualifiedIdentifier(_("XYZ"), _("opq")), "XYZ.OPQ"); + + assertQualifiedIdentifier(ANSISQLPolicy(), QualifiedIdentifier(_("xyz", true), _("opq", false)), "'xyz'.OPQ"); + assertQualifiedIdentifier(ANSISQLPolicy(), QualifiedIdentifier(_("xYz", true), _("opq", true)), "'xYz'.'opq'"); + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tajo/blob/49d59202/tajo-common/src/test/java/org/apache/tajo/schema/TestTajoIdentifier.java ---------------------------------------------------------------------- diff --git a/tajo-common/src/test/java/org/apache/tajo/schema/TestTajoIdentifier.java b/tajo-common/src/test/java/org/apache/tajo/schema/TestTajoIdentifier.java new file mode 100644 index 0000000..675f631 --- /dev/null +++ b/tajo-common/src/test/java/org/apache/tajo/schema/TestTajoIdentifier.java @@ -0,0 +1,54 @@ +/* + * Lisensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.tajo.schema; + +import org.junit.Test; + +import static org.apache.tajo.schema.Identifier._; +import static org.apache.tajo.schema.IdentifierPolicy.DefaultPolicy; +import static org.apache.tajo.schema.QualifiedIdentifier.QualifiedIdentifier; +import static org.junit.Assert.assertEquals; + +public class TestTajoIdentifier { + @Test + public void testIdentifiers() throws Exception { + assertIdentifier(DefaultPolicy(), _("xyz"), "xyz"); + assertIdentifier(DefaultPolicy(), _("XYZ"), "xyz"); + + assertIdentifier(DefaultPolicy(), _("xyz", true), "'xyz'"); + assertIdentifier(DefaultPolicy(), _("xYz", true), "'xYz'"); + } + + @Test + public void testQualifiedIdentifiers() throws Exception { + assertQualifiedIdentifier(DefaultPolicy(), QualifiedIdentifier(_("xyz"), _("opq")), "xyz.opq"); + assertQualifiedIdentifier(DefaultPolicy(), QualifiedIdentifier(_("XYZ"), _("opq")), "xyz.opq"); + + assertQualifiedIdentifier(DefaultPolicy(), QualifiedIdentifier(_("xyz", true), _("opq", false)), "'xyz'.opq"); + assertQualifiedIdentifier(DefaultPolicy(), QualifiedIdentifier(_("xYz", true), _("opq", true)), "'xYz'.'opq'"); + } + + public static void assertIdentifier(IdentifierPolicy p, Identifier id, String expected) { + assertEquals(expected, id.displayString(p)); + } + + public static void assertQualifiedIdentifier(IdentifierPolicy p, QualifiedIdentifier id, String expected) { + assertEquals(expected, id.displayString(p)); + } +} \ No newline at end of file
