diff --git a/.mvn/extensions.xml b/.mvn/extensions.xml deleted file mode 100644 index dd8999be0..000000000 --- a/.mvn/extensions.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - io.takari.aether - takari-local-repository - 0.11.3 - - diff --git a/.mvn/jvm.config b/.mvn/jvm.config deleted file mode 100644 index 608348df8..000000000 --- a/.mvn/jvm.config +++ /dev/null @@ -1 +0,0 @@ --Xmx8192m diff --git a/.mvn/modernizer/violations.xml b/.mvn/modernizer/violations.xml deleted file mode 100644 index 444193e5a..000000000 --- a/.mvn/modernizer/violations.xml +++ /dev/null @@ -1,159 +0,0 @@ - - - - java/lang/Class.newInstance:()Ljava/lang/Object; - 1.1 - Prefer Class.getConstructor().newInstance() - - - - java/lang/String."<init>":([B)V - 1.1 - Prefer new String(byte[], Charset) - - - - java/lang/String.getBytes:()[B - 1.1 - Prefer String.getBytes(Charset) - - - - java/lang/String.toLowerCase:()Ljava/lang/String; - 1.1 - Prefer String.toLowerCase(java.util.Locale) - - - - java/lang/String.toUpperCase:()Ljava/lang/String; - 1.1 - Prefer String.toUpperCase(java.util.Locale) - - - - - java/io/File.toString:()Ljava/lang/String; - 1.1 - Prefer File.getPath() - - - - com/google/common/primitives/Ints.checkedCast:(J)I - 1.8 - Prefer Math.toIntExact(long) - - - - org/testng/Assert.assertEquals:(Ljava/lang/Iterable;Ljava/lang/Iterable;)V - 1.8 - Use io.trino.testing.assertions.Assert.assertEquals due to TestNG #543 - - - - org/testng/Assert.assertEquals:(Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/String;)V - 1.8 - Use io.trino.testing.assertions.Assert.assertEquals due to TestNG #543 - - - - org/testng/Assert.assertThrows:(Lorg/testng/Assert$ThrowingRunnable;)V - 1.8 - Use AssertJ's assertThatThrownBy, see https://github.com/trinodb/trino/issues/5320 for rationale - - - - org/testng/Assert.assertThrows:(Ljava/lang/Class;Lorg/testng/Assert$ThrowingRunnable;)V - 1.8 - Use AssertJ's assertThatThrownBy, see https://github.com/trinodb/trino/issues/5320 for rationale - - - - org/apache/hadoop/conf/Configuration."<init>":()V - 1.1 - Prefer new Configuration(false) - - - - java/util/TimeZone.getTimeZone:(Ljava/lang/String;)Ljava/util/TimeZone; - 1.8 - Avoid TimeZone.getTimeZone as it returns GMT for a zone not supported by the JVM. Use TimeZone.getTimeZone(ZoneId.of(..)) instead, or TimeZone.getTimeZone(..., false). - - - - org/joda/time/DateTimeZone.toTimeZone:()Ljava/util/TimeZone; - 1.8 - Avoid DateTimeZone.toTimeZone as it returns GMT for a zone not supported by the JVM. Use TimeZone.getTimeZone(ZoneId.of(dtz.getId())) instead. - - - - com/esri/core/geometry/ogc/OGCGeometry.equals:(Lcom/esri/core/geometry/ogc/OGCGeometry;)Z - 1.6 - Prefer OGCGeometry.Equals(OGCGeometry) - - - - com/esri/core/geometry/ogc/OGCGeometry.equals:(Ljava/lang/Object;)Z - 1.6 - Prefer OGCGeometry.Equals(OGCGeometry) - - - - io/airlift/units/DataSize."<init>":(DLio/airlift/units/DataSize$Unit;)V - 1.8 - Use io.airlift.units.DataSize.of(long, DataSize.Unit) - - - - io/airlift/units/DataSize.succinctDataSize:(DLio/airlift/units/DataSize$Unit;)Lio/airlift/units/DataSize; - 1.8 - Use io.airlift.units.DataSize.of(long, DataSize.Unit).succinct() -- Note that succinct conversion only affects toString() results - - - - io/airlift/units/DataSize.getValue:()D - 1.8 - Use io.airlift.units.DataSize.toBytes() and Unit.inBytes() for conversion - - - - io/airlift/units/DataSize.getValue:(Lio/airlift/units/DataSize$Unit;)D - 1.8 - Use io.airlift.units.DataSize.toBytes() and Unit.inBytes() for conversion - - - - io/airlift/units/DataSize.roundTo:(Lio/airlift/units/DataSize$Unit;)J - 1.8 - Method is deprecated for removal - - - - io/airlift/units/DataSize.convertTo:(Lio/airlift/units/DataSize$Unit;)Lio/airlift/units/DataSize; - 1.8 - Use io.airlift.units.DataSize.to(DataSize.Unit) - - - - io/airlift/units/DataSize.convertToMostSuccinctDataSize:()Lio/airlift/units/DataSize; - 1.8 - Use io.airlift.units.DataSize.succinct() - - - - io/airlift/testing/Closeables.closeQuietly:([Ljava/io/Closeable;)V - 1.0 - Use Closeables.closeAll() or Closer. - - - - com/google/inject/util/Modules.combine:(Ljava/lang/Iterable;)Lcom/google/inject/Module; - 1.8 - Use io.airlift.configuration.ConfigurationAwareModule.combine - - - - com/google/inject/util/Modules.combine:([Lcom/google/inject/Module;)Lcom/google/inject/Module; - 1.8 - Use io.airlift.configuration.ConfigurationAwareModule.combine - - diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index c6feb8bb6..000000000 Binary files a/.mvn/wrapper/maven-wrapper.jar and /dev/null differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index d808bf3e0..000000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.8/apache-maven-3.9.8-bin.zip diff --git a/core/wren-core-py/README.md b/core/wren-core-py/README.md index 3329fe32d..57ef83dde 100644 --- a/core/wren-core-py/README.md +++ b/core/wren-core-py/README.md @@ -1,6 +1,6 @@ -# Wren Core in Python +# Wren Core Python binding -Here is a dependency package for Python. It is a wrapper for the Rust package [wren-core](../wren-core). The Rust package is compiled to a Python package and can be used in Python. +This is a python binding for [wren-core](../wren-core). It uses [PyO3](https://github.com/PyO3/pyo3) to build the required wheel for [ibis-server](../ibis-server/). ## Developer Guide @@ -12,7 +12,7 @@ Here is a dependency package for Python. It is a wrapper for the Rust package [w - Install [casey/just](https://github.com/casey/just) ### Test and build - +After install `casey/just`, you can use the following command to build or test: - Execute `just install` to create Python venv and install dependencies. - **Important**: Before testing Python, you need to build the Rust package by running `just develop`. - Use `just test-rs` to test Rust only, and `just test-py` to test Python only. diff --git a/core/wren-core/README.md b/core/wren-core/README.md index e6eb41630..f0394ae0e 100644 --- a/core/wren-core/README.md +++ b/core/wren-core/README.md @@ -1,32 +1,36 @@ # Wren Core Module -This is just a very early version of transforming SQL with DataFusion. The main program is a simple use case demonstrating how to use the mdl library. +The Wren Core module serves as the semantic core of the Wren engine. To understand the concept of the Wren engine, refer to the [Wren engine documentation](https://docs.getwren.ai/oss/engine/concept/what_is_semantics). -There are some modules: +This module is utilized by the API v3 of the ibis-server for SQL planning. Additionally, there is another module for Python bindings, [wren-core-py](../wren-core-py/), which is also used by the [ibis-server](../ibis-server/). -- mdl: The main entry point for using Wren modeling. -- logical_plan: The rewrite rule based on the logical planner of DataFusion. +## How to Test / Build -# How to Test / Build - -- Run Test - Currently, the test cases are placed in `src/mdl/mod.rs` +- **Run Tests**: + - Most unit test cases are located in `src/mdl/mod.rs`. + - SQL end-to-end tests are executed using `sqllogictests`. +You can run all tests with the following command: ``` cargo test ``` -# Coding Style -Please format your code with `rustfmt` and `taplo` before submitting a pull request. +## Coding Style -## Format with rustfmt +Please ensure your code is properly formatted before submitting a pull request. Use `rustfmt` for Rust files and `taplo` for formatting TOML files. + +### Format with rustfmt + +Run the following command to format Rust code: ``` cargo fmt ``` -## Format toml with taplo +### Format TOML with taplo + +Install `taplo-cli` and format TOML files with the following commands: ``` cargo install taplo-cli --locked diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 7e8b42232..000000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM eclipse-temurin:21 -LABEL maintainer="https://www.canner.io/" -WORKDIR /usr/src/app - -RUN \ - apt update && \ - apt -y install curl gpg lsb-release && \ - curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg && \ - echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" | tee /etc/apt/sources.list.d/pgdg.list && \ - apt update && \ - apt -y install postgresql-client-13 - -ARG WREN_VERSION -ENV ENV_WREN_VERSION=${WREN_VERSION} -ENV WREN_JAR=wren-server-${ENV_WREN_VERSION}-executable.jar -COPY ${WREN_JAR} ./ - -COPY entrypoint.sh ./ -RUN chmod +x ./entrypoint.sh - -CMD ./entrypoint.sh ${WREN_JAR} ${MAX_HEAP_SIZE} ${MIN_HEAP_SIZE} diff --git a/docker/build-local.sh b/docker/build-local.sh deleted file mode 100755 index ecd50ef66..000000000 --- a/docker/build-local.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/usr/bin/env bash - -set -euo pipefail - -SOURCE_DIR="../" - -# Retrieve the script directory. -SCRIPT_DIR="${BASH_SOURCE%/*}" -cd ${SCRIPT_DIR} - -# Move to the root directory to run maven for current version. -pushd ${SOURCE_DIR} -WREN_VERSION=$(./mvnw --quiet help:evaluate -Dexpression=project.version -DforceStdout) -popd - -WORK_DIR="$(mktemp -d)" -cp ${SOURCE_DIR}wren-server/target/wren-server-${WREN_VERSION}-executable.jar ${WORK_DIR} -cp ./entrypoint.sh ${WORK_DIR} - -CONTAINER="wren-engine:${WREN_VERSION}" - -docker build ${WORK_DIR} --pull --platform linux/amd64 -f Dockerfile -t ${CONTAINER}-amd64 --build-arg "WREN_VERSION=${WREN_VERSION}" -docker build ${WORK_DIR} --pull --platform linux/arm64 -f Dockerfile -t ${CONTAINER}-arm64 --build-arg "WREN_VERSION=${WREN_VERSION}" - -rm -r ${WORK_DIR} - -docker image inspect -f '🚀 Built {{.RepoTags}} {{.Id}}' ${CONTAINER}-amd64 -docker image inspect -f '🚀 Built {{.RepoTags}} {{.Id}}' ${CONTAINER}-arm64 diff --git a/docker/compose.yaml b/docker/compose.yaml deleted file mode 100644 index bf6dbc3c3..000000000 --- a/docker/compose.yaml +++ /dev/null @@ -1,13 +0,0 @@ -services: - ibis-server: - image: ghcr.io/canner/wren-engine-ibis:latest - ports: - - "8000:8000" - environment: - WREN_ENGINE_ENDPOINT: http://java-engine:8080 - java-engine: - image: ghcr.io/canner/wren-engine:latest - ports: - - "8080:8080" - volumes: - - ./etc:/usr/src/app/etc diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh deleted file mode 100644 index b7ef9e6c6..000000000 --- a/docker/entrypoint.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/bash -export ENV_MAX_HEAP_SIZE=$2 -export ENV_MIN_HEAP_SIZE=$3 - -# Required add-opens=java.nio=ALL-UNNAMED for Apache arrow in the Snowflake -java -Xmx${ENV_MAX_HEAP_SIZE:-"512m"} -Xms${ENV_MIN_HEAP_SIZE:-"64m"} -Dconfig=etc/config.properties \ - --add-opens=java.base/java.nio=ALL-UNNAMED \ - -jar $1 diff --git a/docker/etc/config.properties b/docker/etc/config.properties deleted file mode 100644 index af2777b89..000000000 --- a/docker/etc/config.properties +++ /dev/null @@ -1 +0,0 @@ -node.environment=test diff --git a/mvnw b/mvnw deleted file mode 100755 index 6ecc150ae..000000000 --- a/mvnw +++ /dev/null @@ -1,236 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed 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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Migwn, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - local basedir=$(pwd) - local wdir=$(pwd) - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - wdir=$(cd "$wdir/.."; pwd) - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` -fi - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -# avoid using MAVEN_CMD_LINE_ARGS below since that would loose parameter escaping in $@ -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 42f4b2048..000000000 --- a/pom.xml +++ /dev/null @@ -1,668 +0,0 @@ - - - 4.0.0 - - - io.airlift - airbase - 241 - - - io.wren - wren-root - 0.15.2-SNAPSHOT - pom - - WrenEngine - WrenEngine - - 2022 - - - - Apache License 2.0 - http://www.apache.org/licenses/LICENSE-2.0 - repo - - - - - trino-parser - wren-base - wren-main - wren-server - wren-tests - - - - HEAD - - - - - maven-repo.cannerdata.com - Canner Repository - s3://maven-repo.cannerdata.com/release - - - maven-repo.cannerdata.com - Canner Repository - s3://maven-repo.cannerdata.com/snapshot - - - - - 21 - - ${project.basedir} - true - true - true - false - false - 21.0.1 - 8 - - 4.13.2 - 269 - ${dep.airlift.version} - 1.22 - 1.20.6 - 2.37.0 - ${dep.plugin.surefire.version} - 4.1.45.Final - - - America/Bahia_Banderas - methods - 2 - - 3g - -missing - - - - - - org.jdbi - jdbi3-bom - 3.48.0 - pom - import - - - - org.testcontainers - testcontainers-bom - ${dep.testcontainers.version} - pom - import - - - - com.fasterxml.jackson.core - jackson-annotations - 2.18.3 - - - - com.fasterxml.jackson.core - jackson-databind - 2.18.3 - - - - com.fasterxml.jackson.core - jackson-dataformat-yaml - 2.17.0 - - - - com.fasterxml.jackson.dataformat - jackson-dataformat-yaml - 2.18.3 - - - - com.google.code.findbugs - jsr305 - 3.0.2 - - - - com.google.code.gson - gson - 2.12.1 - - - - com.google.errorprone - error_prone_annotations - ${dep.errorprone.version} - - - - com.google.guava - failureaccess - 1.0.3 - - - - com.google.protobuf - protobuf-java - 4.30.1 - - - - com.hubspot.jinjava - jinjava - 2.7.4 - - - com.google.code.findbugs - annotations - - - - - - com.zaxxer - HikariCP - 6.3.0 - - - org.slf4j - slf4j-api - - - - - - io.airlift - bootstrap - ${dep.airlift.version} - - - - io.airlift - concurrent - ${dep.airlift.version} - - - - io.airlift - configuration - ${dep.airlift.version} - - - - io.airlift - event - ${dep.airlift.version} - - - - io.airlift - http-client - ${dep.airlift.version} - - - - io.airlift - http-server - ${dep.airlift.version} - - - - io.airlift - jaxrs - ${dep.airlift.version} - - - - io.airlift - json - ${dep.airlift.version} - - - - io.airlift - log - ${dep.airlift.version} - - - - io.airlift - log-manager - ${dep.airlift.version} - - - - io.airlift - node - ${dep.airlift.version} - - - - io.airlift - stats - ${dep.airlift.version} - - - - io.airlift - testing - ${dep.airlift.version} - - - - io.airlift - trace-token - ${dep.airlift.version} - - - - io.airlift - units - 1.10 - - - - io.opentelemetry.semconv - opentelemetry-semconv - 1.30.0 - - - - io.wren - trino-parser - ${project.version} - - - - io.wren - wren-base - ${project.version} - - - - io.wren - wren-main - ${project.version} - - - - io.wren - wren-server - ${project.version} - - - - io.wren - wren-tests - ${project.version} - - - - io.wren - wren-validation - ${project.version} - - - - net.bytebuddy - byte-buddy - 1.17.4 - - - - org.antlr - antlr4-runtime - ${dep.antlr.version} - - - - - org.apache.commons - commons-math3 - 3.6.1 - - - - org.apache.httpcomponents - httpclient - 4.5.14 - - - - org.apache.httpcomponents - httpcore - 4.4.16 - - - - org.checkerframework - checker-qual - 3.49.1 - - - - org.duckdb - duckdb_jdbc - 1.2.1 - - - - org.jetbrains - annotations - 26.0.2 - - - - org.jgrapht - jgrapht-core - 1.5.2 - - - - org.postgresql - postgresql - 42.7.5 - - - - org.testcontainers - testcontainers - ${dep.testcontainers.version} - - - org.osgi - org.osgi.core - - - - - - org.threeten - threetenbp - 1.7.1 - - - - - - - - - org.antlr - antlr4-maven-plugin - ${dep.antlr.version} - - true - - - - - antlr4 - - - - - - - org.apache.maven.plugins - maven-shade-plugin - 3.6.0 - - - - org.skife.maven - really-executable-jar-maven-plugin - 2.1.1 - - - - org.apache.maven.plugins - maven-antrun-plugin - 3.1.0 - - - - org.codehaus.mojo - exec-maven-plugin - 3.5.0 - - - - io.airlift.drift - drift-maven-plugin - ${dep.drift.version} - - - - org.gaul - modernizer-maven-plugin - - - ${air.main.basedir}/.mvn/modernizer/violations.xml - - - org/joda/time/.* - - - - com/google/common/collect/Iterables.getOnlyElement:(Ljava/lang/Iterable;)Ljava/lang/Object; - com/google/common/collect/Iterables.getOnlyElement:(Ljava/lang/Iterable;Ljava/lang/Object;)Ljava/lang/Object; - - com/google/common/collect/Iterables.getLast:(Ljava/lang/Iterable;)Ljava/lang/Object; - com/google/common/collect/Iterables.getLast:(Ljava/lang/Iterable;Ljava/lang/Object;)Ljava/lang/Object; - - com/google/common/collect/Iterables.transform:(Ljava/lang/Iterable;Lcom/google/common/base/Function;)Ljava/lang/Iterable; - com/google/common/collect/Lists.transform:(Ljava/util/List;Lcom/google/common/base/Function;)Ljava/util/List; - com/google/common/collect/Iterables.isEmpty:(Ljava/lang/Iterable;)Z - com/google/common/collect/Iterables.concat:(Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/lang/Iterable; - com/google/common/collect/Iterables.concat:(Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/lang/Iterable; - com/google/common/collect/Iterables.concat:(Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;Ljava/lang/Iterable;)Ljava/lang/Iterable; - com/google/common/collect/Iterables.concat:(Ljava/lang/Iterable;)Ljava/lang/Iterable; - com/google/common/collect/Iterables.all:(Ljava/lang/Iterable;Lcom/google/common/base/Predicate;)Z - com/google/common/collect/Iterables.any:(Ljava/lang/Iterable;Lcom/google/common/base/Predicate;)Z - com/google/common/collect/Iterables.skip:(Ljava/lang/Iterable;I)Ljava/lang/Iterable; - com/google/common/collect/Iterables.limit:(Ljava/lang/Iterable;I)Ljava/lang/Iterable; - com/google/common/collect/Iterables.get:(Ljava/lang/Iterable;I)Ljava/lang/Object; - com/google/common/collect/Iterables.getFirst:(Ljava/lang/Iterable;Ljava/lang/Object;)Ljava/lang/Object; - com/google/common/collect/Iterables.getLast:(Ljava/lang/Iterable;)Ljava/lang/Object; - com/google/common/collect/Iterables.cycle:(Ljava/lang/Iterable;)Ljava/lang/Iterable; - com/google/common/collect/Iterables.cycle:([Ljava/lang/Object;)Ljava/lang/Iterable; - - com/google/common/io/BaseEncoding.base64:()Lcom/google/common/io/BaseEncoding; - - - com/google/inject/Provider - - - - - - org.apache.maven.plugins - maven-enforcer-plugin - - - - - - org.codehaus.plexus:plexus-utils - com.google.guava:guava - com.fasterxml.jackson.core:jackson-core - com.google.j2objc:j2objc-annotations - - - - - - org.apache.logging.log4j:log4j-core - - org.yaml:snakeyaml - - javax.inject:javax.inject - - javax.annotation:javax.annotation-api - - - - org.yaml:snakeyaml:2.+ - - - - - project.description - - - - - - org.apache.maven.plugins - maven-release-plugin - - clean verify -DskipTests - - - - - ca.vanzyl.provisio.maven.plugins - provisio-maven-plugin - 1.1.1 - - - - - - - io.trino - trino-maven-plugin - 15 - true - - - - ca.vanzyl.provisio.maven.plugins - provisio-maven-plugin - true - - - - org.apache.maven.plugins - maven-compiler-plugin - - false - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - %1$tY-%1$tm-%1$tdT%1$tH:%1$tM:%1$tS.%1$tL%1$tz %4$s %3$s %5$s%6$s%n - - - @{argLine} - - --add-opens=java.base/java.nio=ALL-UNNAMED - - false - - - **/Test*.java - **/*Test.java - **/Benchmark*.java - - - **/*jmhTest*.java - **/*jmhType*.java - - - - - - - - org.kuali.maven.wagons - maven-s3-wagon - 1.2.1 - - - - - - - errorprone-compiler - - - - org.apache.maven.plugins - maven-compiler-plugin - - - - -XDcompilePolicy=simple - - -Xplugin:ErrorProne - -XepExcludedPaths:.*/target/generated-(|test-)sources/.* - -XepDisableAllChecks - -Xep:ArrayEquals:ERROR - -Xep:ArrayHashCode:ERROR - -Xep:ArrayToString:ERROR - -Xep:ArraysAsListPrimitiveArray:ERROR - -Xep:BadInstanceof:ERROR - -Xep:BadShiftAmount:ERROR - -Xep:BoxedPrimitiveConstructor:ERROR - -Xep:ClassCanBeStatic:ERROR - -Xep:CompareToZero:ERROR - -Xep:ComparingThisWithNull:ERROR - -Xep:EqualsIncompatibleType:ERROR - -Xep:FallThrough:ERROR - -Xep:FormatString:ERROR - -Xep:GetClassOnAnnotation:ERROR - -Xep:GetClassOnClass:ERROR - -Xep:IdentityBinaryExpression:ERROR - -Xep:ImmutableSetForContains:ERROR - -Xep:InconsistentHashCode:ERROR - -Xep:InjectOnConstructorOfAbstractClass:ERROR - -Xep:MissingCasesInEnumSwitch:ERROR - -Xep:MissingOverride:ERROR - -Xep:MisusedWeekYear:ERROR - -Xep:NullOptional:ERROR - -Xep:ObjectToString:ERROR - -Xep:OptionalEquality:ERROR - -Xep:OptionalMapUnusedValue:ERROR - -Xep:PreconditionsInvalidPlaceholder:ERROR - -Xep:ReturnValueIgnored:ERROR - -Xep:StaticQualifiedUsingExpression:ERROR - -Xep:ThrowIfUncheckedKnownChecked:ERROR - -Xep:UnnecessaryCheckNotNull:ERROR - -Xep:UnnecessaryMethodReference:ERROR - -Xep:UnnecessaryOptionalGet:ERROR - -Xep:UnusedVariable:ERROR - -Xep:UseEnumSwitch:ERROR - -Xep:ZoneIdOfZ:ERROR - - - - com.google.errorprone - error_prone_core - ${dep.errorprone.version} - - - - - - - - - diff --git a/trino-parser/pom.xml b/trino-parser/pom.xml deleted file mode 100644 index a2d5cdc46..000000000 --- a/trino-parser/pom.xml +++ /dev/null @@ -1,77 +0,0 @@ - - - 4.0.0 - - - io.wren - wren-root - 0.15.2-SNAPSHOT - ../pom.xml - - - trino-parser - trino-parser - Trino - Parser - - - ${project.parent.basedir} - - - - - - com.google.code.findbugs - jsr305 - true - - - - com.google.guava - guava - - - - io.airlift - slice - - - - org.antlr - antlr4-runtime - - - - - org.assertj - assertj-core - test - - - - org.junit.jupiter - junit-jupiter-api - test - - - - org.junit.jupiter - junit-jupiter-engine - test - - - - org.junit.jupiter - junit-jupiter-params - test - - - - - - - org.antlr - antlr4-maven-plugin - - - - diff --git a/trino-parser/src/main/antlr4/io/trino/sql/parser/SqlBase.g4 b/trino-parser/src/main/antlr4/io/trino/sql/parser/SqlBase.g4 deleted file mode 100644 index 4f98f8398..000000000 --- a/trino-parser/src/main/antlr4/io/trino/sql/parser/SqlBase.g4 +++ /dev/null @@ -1,1129 +0,0 @@ -/* - * Licensed 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. - */ -grammar SqlBase; - -tokens { - DELIMITER -} - -singleStatement - : statement EOF - ; - -standaloneExpression - : expression EOF - ; - -standalonePathSpecification - : pathSpecification EOF - ; - -standaloneType - : type EOF - ; - -standaloneRowPattern - : rowPattern EOF - ; - -statement - : query #statementDefault - | USE schema=identifier #use - | USE catalog=identifier '.' schema=identifier #use - | CREATE SCHEMA (IF NOT EXISTS)? qualifiedName - (AUTHORIZATION principal)? - (WITH properties)? #createSchema - | DROP SCHEMA (IF EXISTS)? qualifiedName (CASCADE | RESTRICT)? #dropSchema - | ALTER SCHEMA qualifiedName RENAME TO identifier #renameSchema - | ALTER SCHEMA qualifiedName SET AUTHORIZATION principal #setSchemaAuthorization - | CREATE TABLE (IF NOT EXISTS)? qualifiedName columnAliases? - (COMMENT string)? - (WITH properties)? AS (query | '('query')') - (WITH (NO)? DATA)? #createTableAsSelect - | CREATE TABLE (IF NOT EXISTS)? qualifiedName - '(' tableElement (',' tableElement)* ')' - (COMMENT string)? - (WITH properties)? #createTable - | DROP TABLE (IF EXISTS)? qualifiedName #dropTable - | INSERT INTO qualifiedName columnAliases? query #insertInto - | DELETE FROM qualifiedName (WHERE booleanExpression)? #delete - | TRUNCATE TABLE qualifiedName #truncateTable - | COMMENT ON TABLE qualifiedName IS (string | NULL) #commentTable - | COMMENT ON COLUMN qualifiedName IS (string | NULL) #commentColumn - | ALTER TABLE (IF EXISTS)? from=qualifiedName - RENAME TO to=qualifiedName #renameTable - | ALTER TABLE (IF EXISTS)? tableName=qualifiedName - ADD COLUMN (IF NOT EXISTS)? column=columnDefinition #addColumn - | ALTER TABLE (IF EXISTS)? tableName=qualifiedName - RENAME COLUMN (IF EXISTS)? from=identifier TO to=identifier #renameColumn - | ALTER TABLE (IF EXISTS)? tableName=qualifiedName - DROP COLUMN (IF EXISTS)? column=qualifiedName #dropColumn - | ALTER TABLE tableName=qualifiedName SET AUTHORIZATION principal #setTableAuthorization - | ALTER TABLE tableName=qualifiedName - SET PROPERTIES propertyAssignments #setTableProperties - | ALTER TABLE tableName=qualifiedName - EXECUTE procedureName=identifier - ('(' (callArgument (',' callArgument)*)? ')')? - (WHERE where=booleanExpression)? #tableExecute - | ANALYZE qualifiedName (WITH properties)? #analyze - | CREATE (OR REPLACE)? MATERIALIZED VIEW - (IF NOT EXISTS)? qualifiedName - (COMMENT string)? - (WITH properties)? AS query #createMaterializedView - | CREATE (OR REPLACE)? VIEW qualifiedName - (COMMENT string)? - (SECURITY (DEFINER | INVOKER))? AS query #createView - | REFRESH MATERIALIZED VIEW qualifiedName #refreshMaterializedView - | DROP MATERIALIZED VIEW (IF EXISTS)? qualifiedName #dropMaterializedView - | ALTER MATERIALIZED VIEW (IF EXISTS)? from=qualifiedName - RENAME TO to=qualifiedName #renameMaterializedView - | ALTER MATERIALIZED VIEW qualifiedName - SET PROPERTIES propertyAssignments #setMaterializedViewProperties - | DROP VIEW (IF EXISTS)? qualifiedName #dropView - | ALTER VIEW from=qualifiedName RENAME TO to=qualifiedName #renameView - | ALTER VIEW from=qualifiedName SET AUTHORIZATION principal #setViewAuthorization - | CALL qualifiedName '(' (callArgument (',' callArgument)*)? ')' #call - | CREATE ROLE name=identifier - (WITH ADMIN grantor)? - (IN catalog=identifier)? #createRole - | DROP ROLE name=identifier (IN catalog=identifier)? #dropRole - | GRANT - roles - TO principal (',' principal)* - (WITH ADMIN OPTION)? - (GRANTED BY grantor)? - (IN catalog=identifier)? #grantRoles - | REVOKE - (ADMIN OPTION FOR)? - roles - FROM principal (',' principal)* - (GRANTED BY grantor)? - (IN catalog=identifier)? #revokeRoles - | SET ROLE (ALL | NONE | role=identifier) - (IN catalog=identifier)? #setRole - | GRANT - (privilege (',' privilege)* | ALL PRIVILEGES) - ON (SCHEMA | TABLE)? qualifiedName - TO grantee=principal - (WITH GRANT OPTION)? #grant - | DENY - (privilege (',' privilege)* | ALL PRIVILEGES) - ON (SCHEMA | TABLE)? qualifiedName - TO grantee=principal #deny - | REVOKE - (GRANT OPTION FOR)? - (privilege (',' privilege)* | ALL PRIVILEGES) - ON (SCHEMA | TABLE)? qualifiedName - FROM grantee=principal #revoke - | SHOW GRANTS (ON TABLE? qualifiedName)? #showGrants - | EXPLAIN ('(' explainOption (',' explainOption)* ')')? statement #explain - | EXPLAIN ANALYZE VERBOSE? statement #explainAnalyze - | SHOW CREATE TABLE qualifiedName #showCreateTable - | SHOW CREATE SCHEMA qualifiedName #showCreateSchema - | SHOW CREATE VIEW qualifiedName #showCreateView - | SHOW CREATE MATERIALIZED VIEW qualifiedName #showCreateMaterializedView - | SHOW TABLES ((FROM | IN) qualifiedName)? - (LIKE pattern=string (ESCAPE escape=string)?)? #showTables - | SHOW SCHEMAS ((FROM | IN) identifier)? - (LIKE pattern=string (ESCAPE escape=string)?)? #showSchemas - | SHOW CATALOGS - (LIKE pattern=string (ESCAPE escape=string)?)? #showCatalogs - | SHOW COLUMNS (FROM | IN) qualifiedName? - (LIKE pattern=string (ESCAPE escape=string)?)? #showColumns - | SHOW STATS FOR qualifiedName #showStats - | SHOW STATS FOR '(' query ')' #showStatsForQuery - | SHOW CURRENT? ROLES ((FROM | IN) identifier)? #showRoles - | SHOW ROLE GRANTS ((FROM | IN) identifier)? #showRoleGrants - | DESCRIBE qualifiedName #showColumns - | DESC qualifiedName #showColumns - | SHOW FUNCTIONS - (LIKE pattern=string (ESCAPE escape=string)?)? #showFunctions - | SHOW SESSION - (LIKE pattern=string (ESCAPE escape=string)?)? #showSession - | SET SESSION qualifiedName EQ expression #setSession - | RESET SESSION qualifiedName #resetSession - | START TRANSACTION (transactionMode (',' transactionMode)*)? #startTransaction - | COMMIT WORK? #commit - | ROLLBACK WORK? #rollback - | PREPARE identifier FROM statement #prepare - | DEALLOCATE PREPARE identifier #deallocate - | EXECUTE identifier (USING expression (',' expression)*)? #execute - | DESCRIBE INPUT identifier #describeInput - | DESCRIBE OUTPUT identifier #describeOutput - | SET PATH pathSpecification #setPath - | SET TIME ZONE (LOCAL | expression) #setTimeZone - | UPDATE qualifiedName - SET updateAssignment (',' updateAssignment)* - (WHERE where=booleanExpression)? #update - | MERGE INTO qualifiedName (AS? identifier)? - USING relation ON expression mergeCase+ #merge - | DECLARE name=identifier - ('BINARY')? ('ASENSITIVE' | 'INSENSITIVE')? (('NO')? 'SCROLL')? - CURSOR ((WITH | WITHOUT) 'HOLD')? FOR body=query #declareCursor // pg syntax - | FETCH row=INTEGER_VALUE (FROM | IN) cursor=identifier #fetchCursor // pg syntax - | IMPERSONATE expression #impersonateUser // added by canner - ; - -query - : with? queryNoWith - ; - -with - : WITH RECURSIVE? namedQuery (',' namedQuery)* - ; - -tableElement - : columnDefinition - | likeClause - ; - -columnDefinition - : identifier type (NOT NULL)? (COMMENT string)? (WITH properties)? - ; - -likeClause - : LIKE qualifiedName (optionType=(INCLUDING | EXCLUDING) PROPERTIES)? - ; - -properties - : '(' propertyAssignments ')' - ; - -propertyAssignments - : property (',' property)* - ; - -property - : identifier EQ propertyValue - ; - -propertyValue - : DEFAULT #defaultPropertyValue - | expression #nonDefaultPropertyValue - ; - -queryNoWith - : queryTerm - (ORDER BY sortItem (',' sortItem)*)? - (((OFFSET offset=rowCount (ROW | ROWS)?)? - ( (LIMIT limit=limitRowCount pgCast?) - | (FETCH (FIRST | NEXT) (fetchFirst=rowCount)? (ROW | ROWS) (ONLY | WITH TIES)) - )?) - | - // for wire protocol to support limit xx offset xx - (LIMIT limit=limitRowCount pgCast?)? - (OFFSET offset=rowCount (ROW | ROWS)?)? - ) - ; - -// for wire protocol to support the syntax (limit xx::pgtype) -pgCast - : (PG_CAST (IDENTIFIER '.')? identifier) - ; - -limitRowCount - : ALL - | rowCount - | string // for pg syntax - ; - -rowCount - : INTEGER_VALUE - | QUESTION_MARK - ; - -queryTerm - : queryPrimary #queryTermDefault - | left=queryTerm operator=INTERSECT setQuantifier? right=queryTerm #setOperation - | left=queryTerm operator=(UNION | EXCEPT) setQuantifier? right=queryTerm #setOperation - ; - -queryPrimary - : querySpecification #queryPrimaryDefault - | TABLE qualifiedName #table - | VALUES expression (',' expression)* #inlineTable - | '(' queryNoWith ')' #subquery - ; - -sortItem - : expression ordering=(ASC | DESC)? (NULLS nullOrdering=(FIRST | LAST))? - ; - -querySpecification - : SELECT setQuantifier? selectItem (',' selectItem)* - (FROM relation (',' relation)*)? - (WHERE where=booleanExpression)? - (GROUP BY groupBy)? - (HAVING having=booleanExpression)? - (WINDOW windowDefinition (',' windowDefinition)*)? - ; - -groupBy - : setQuantifier? groupingElement (',' groupingElement)* - ; - -groupingElement - : groupingSet #singleGroupingSet - | ROLLUP '(' (expression (',' expression)*)? ')' #rollup - | CUBE '(' (expression (',' expression)*)? ')' #cube - | GROUPING SETS '(' groupingSet (',' groupingSet)* ')' #multipleGroupingSets - ; - -groupingSet - : '(' (expression (',' expression)*)? ')' - | expression - ; - -windowDefinition - : name=identifier AS '(' windowSpecification ')' - ; - -windowSpecification - : (existingWindowName=identifier)? - (PARTITION BY partition+=expression (',' partition+=expression)*)? - (ORDER BY sortItem (',' sortItem)*)? - windowFrame? - ; - -namedQuery - : name=identifier (columnAliases)? AS '(' query ')' - ; - -setQuantifier - : DISTINCT - | ALL - ; - -selectItem - : expression (AS? identifier)? #selectSingle - | primaryExpression '.' ASTERISK (AS columnAliases)? #selectAll - | ASTERISK #selectAll - ; - -relation - : left=relation - ( CROSS JOIN right=sampledRelation - | joinType JOIN rightRelation=relation joinCriteria - | NATURAL joinType JOIN right=sampledRelation - ) #joinRelation - | sampledRelation #relationDefault - ; - -joinType - : INNER? - | LEFT OUTER? - | RIGHT OUTER? - | FULL OUTER? - ; - -joinCriteria - : ON booleanExpression - | USING '(' identifier (',' identifier)* ')' - ; - -sampledRelation - : patternRecognition ( - TABLESAMPLE sampleType '(' percentage=expression ')' - )? - ; - -sampleType - : BERNOULLI - | SYSTEM - ; - -listAggOverflowBehavior - : ERROR - | TRUNCATE string? listaggCountIndication - ; - -listaggCountIndication - : WITH COUNT - | WITHOUT COUNT - ; - -patternRecognition - : aliasedRelation ( - MATCH_RECOGNIZE '(' - (PARTITION BY partition+=expression (',' partition+=expression)*)? - (ORDER BY sortItem (',' sortItem)*)? - (MEASURES measureDefinition (',' measureDefinition)*)? - rowsPerMatch? - (AFTER MATCH skipTo)? - (INITIAL | SEEK)? - PATTERN '(' rowPattern ')' - (SUBSET subsetDefinition (',' subsetDefinition)*)? - DEFINE variableDefinition (',' variableDefinition)* - ')' - (AS? identifier columnAliases?)? - )? - ; - -measureDefinition - : expression AS identifier - ; - -rowsPerMatch - : ONE ROW PER MATCH - | ALL ROWS PER MATCH emptyMatchHandling? - ; - -emptyMatchHandling - : SHOW EMPTY MATCHES - | OMIT EMPTY MATCHES - | WITH UNMATCHED ROWS - ; - -skipTo - : 'SKIP' TO NEXT ROW - | 'SKIP' PAST LAST ROW - | 'SKIP' TO FIRST identifier - | 'SKIP' TO LAST identifier - | 'SKIP' TO identifier - ; - -subsetDefinition - : name=identifier EQ '(' union+=identifier (',' union+=identifier)* ')' - ; - -variableDefinition - : identifier AS expression - ; - -aliasedRelation - : relationPrimary (AS? identifier columnAliases?)? - ; - -columnAliases - : '(' identifier (',' identifier)* ')' - ; - -relationPrimary - : qualifiedName queryPeriod? #tableName - | '(' query ')' #subqueryRelation - | UNNEST '(' expression (',' expression)* ')' (WITH ORDINALITY)? #unnest - | (IDENTIFIER '.')? UNNEST '(' expression (',' expression)* ')' (WITH ORDINALITY)? #unnest // pg syntax - | functionExpression #functionRelation // pg syntax - | string #pathRelation // duckdb syntax - | LATERAL '(' query ')' #lateral - | '(' relation ')' #parenthesizedRelation - ; - -expression - : booleanExpression - ; - -booleanExpression - : valueExpression predicate[$valueExpression.ctx]? #predicated - | NOT booleanExpression #logicalNot - | booleanExpression AND booleanExpression #and - | booleanExpression OR booleanExpression #or - ; - -// workaround for https://github.com/antlr/antlr4/issues/780 -predicate[ParserRuleContext value] - // quantified comparison with functiond should be the first because the second rule, comparing with valueExpression, will - // cover the first rule, and then comparisionQuantifier will be recognize as function name. - : comparisonOperator comparisonQuantifier '(' functionExpression ')' #quantifiedComparison // pg syntax - | NOT? (REGEX_MATCH | quotedRegexMatch) ASTERISK? pattern=valueExpression #posixComparison // pg syntax - | OPERATOR '(' (IDENTIFIER '.')? comparisonOperator ')' right=valueExpression #comparison // pg syntax - | comparisonOperator right=valueExpression #comparison - | comparisonOperator comparisonQuantifier '(' query ')' #quantifiedComparison - | NOT? BETWEEN lower=valueExpression AND upper=valueExpression #between - | NOT? IN '(' expression (',' expression)* ')' #inList - | NOT? IN '(' query ')' #inSubquery - | NOT? LIKE pattern=valueExpression (ESCAPE escape=valueExpression)? #like - | IS NOT? NULL #nullPredicate - | IS NOT? DISTINCT FROM right=valueExpression #distinctFrom - ; - -functionExpression - : qualifiedName '(' expression (',' expression)* ')' - ; - -valueExpression - : primaryExpression (collateClause)? #valueExpressionDefault // pg syntax - | primaryExpression #valueExpressionDefault - | valueExpression AT timeZoneSpecifier #atTimeZone - | operator=(MINUS | PLUS) valueExpression #arithmeticUnary - | left=valueExpression operator=(ASTERISK | SLASH | PERCENT) right=valueExpression #arithmeticBinary - | left=valueExpression operator=(PLUS | MINUS) right=valueExpression #arithmeticBinary - | left=valueExpression OPERATOR '(' (IDENTIFIER '.')? operator=(MINUS | PLUS | ASTERISK | SLASH | PERCENT) ')' right=valueExpression #arithmeticBinary // pg syntax - | left=valueExpression CONCAT right=valueExpression #concatenation - ; - -primaryExpression - : NULL #nullLiteral - | interval #intervalLiteral - | identifier string #typeConstructor - | DOUBLE PRECISION string #typeConstructor - // for wireprotocol pg style type constructor - | string PG_CAST (IDENTIFIER '.')? identifier #typeConstructor - | number #numericLiteral - | booleanValue #booleanLiteral - | string #stringLiteral - | BINARY_LITERAL #binaryLiteral - | QUESTION_MARK #parameter - | POSITION '(' valueExpression IN valueExpression ')' #position - | '(' expression (',' expression)+ ')' #rowConstructor - | ROW '(' expression (',' expression)* ')' #rowConstructor - | name=LISTAGG '(' setQuantifier? expression (',' string)? - (ON OVERFLOW listAggOverflowBehavior)? ')' - (WITHIN GROUP '(' ORDER BY sortItem (',' sortItem)* ')') #listagg - | processingMode? qualifiedName '(' (label=identifier '.')? ASTERISK ')' - filter? over? #functionCall - | processingMode? qualifiedName '(' (setQuantifier? expression (',' expression)*)? - (ORDER BY sortItem (',' sortItem)*)? ')' filter? (nullTreatment? over)? #functionCall - | identifier over #measure - | identifier '->' expression #lambda - | '(' (identifier (',' identifier)*)? ')' '->' expression #lambda - | '(' query ')' #subqueryExpression - // This is an extension to ANSI SQL, which considers EXISTS to be a - | EXISTS '(' query ')' #exists - | CASE operand=expression whenClause+ (ELSE elseExpression=expression)? END #simpleCase - | CASE whenClause+ (ELSE elseExpression=expression)? END #searchedCase - | CAST '(' expression AS type ')' #cast - | TRY_CAST '(' expression AS type ')' #cast - | CAST '(' expression AS (IDENTIFIER '.')? type ')' #cast // pg syntax - // for wireprotocol pg style casting - | primaryExpression PG_CAST (IDENTIFIER '.')? type #cast - | ARRAY '[' (expression (',' expression)*)? ']' #arrayConstructor - | '[' (expression (',' expression)*)? ']' #arrayConstructor // duckdb array syntax - | value=primaryExpression '[' index=valueExpression ']' #subscript - | identifier #columnReference - | base=primaryExpression '.' fieldName=identifier #dereference - | name=CURRENT_DATE #specialDateTimeFunction - | name=CURRENT_TIME ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction - | name=CURRENT_TIMESTAMP ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction - | name=LOCALTIME ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction - | name=LOCALTIMESTAMP ('(' precision=INTEGER_VALUE ')')? #specialDateTimeFunction - | name=CURRENT_USER #currentUser - | name=CURRENT_CATALOG #currentCatalog - // To support pg-style current_schema() - | (identifier '.')? name=CURRENT_SCHEMA ('(' ')')? #currentSchema - | name=CURRENT_PATH #currentPath - | SUBSTRING '(' valueExpression FROM valueExpression (FOR valueExpression)? ')' #substring - | NORMALIZE '(' valueExpression (',' normalForm)? ')' #normalize - | EXTRACT '(' identifier FROM valueExpression ')' #extract - | '(' expression ')' #parenthesizedExpression - | GROUPING '(' (qualifiedName (',' qualifiedName)*)? ')' #groupingOperation - ; - -processingMode - : RUNNING - | FINAL - ; - -nullTreatment - : IGNORE NULLS - | RESPECT NULLS - ; - -string - : STRING #basicStringLiteral - | UNICODE_STRING (UESCAPE STRING)? #unicodeStringLiteral - | ESCAPED_STRING #escapedCharsStringLiteral - ; - -timeZoneSpecifier - : TIME ZONE interval #timeZoneInterval - | TIME ZONE string #timeZoneString - ; - -comparisonOperator - : EQ | NEQ | LT | LTE | GT | GTE - ; - -comparisonQuantifier - : ALL | SOME | ANY - ; - -booleanValue - : TRUE | FALSE - ; - -interval - : INTERVAL sign=(PLUS | MINUS)? string from=intervalField (TO to=intervalField)? - ; - -intervalField - : YEAR | MONTH | DAY | HOUR | MINUTE | SECOND - ; - -normalForm - : NFD | NFC | NFKD | NFKC - ; - -type - : ROW '(' rowField (',' rowField)* ')' #rowType - | INTERVAL from=intervalField (TO to=intervalField)? #intervalType - | base=TIMESTAMP ('(' precision = typeParameter ')')? (WITHOUT TIME ZONE)? #dateTimeType - | base=TIMESTAMP ('(' precision = typeParameter ')')? WITH TIME ZONE #dateTimeType - | base=TIME ('(' precision = typeParameter ')')? (WITHOUT TIME ZONE)? #dateTimeType - | base=TIME ('(' precision = typeParameter ')')? WITH TIME ZONE #dateTimeType - | DOUBLE PRECISION #doublePrecisionType - | ARRAY '<' type '>' #legacyArrayType - | MAP '<' keyType=type ',' valueType=type '>' #legacyMapType - | type ARRAY ('[' INTEGER_VALUE ']')? #arrayType - | identifier ('(' typeParameter (',' typeParameter)* ')')? #genericType - ; - -rowField - : type - | identifier type; - -typeParameter - : INTEGER_VALUE | type - ; - -whenClause - : WHEN condition=expression THEN result=expression - ; - -filter - : FILTER '(' WHERE booleanExpression ')' - ; - -mergeCase - : WHEN MATCHED (AND condition=expression)? THEN - UPDATE SET targets+=identifier EQ values+=expression - (',' targets+=identifier EQ values+=expression)* #mergeUpdate - | WHEN MATCHED (AND condition=expression)? THEN DELETE #mergeDelete - | WHEN NOT MATCHED (AND condition=expression)? THEN - INSERT ('(' targets+=identifier (',' targets+=identifier)* ')')? - VALUES '(' values+=expression (',' values+=expression)* ')' #mergeInsert - ; - -over - : OVER (windowName=identifier | '(' windowSpecification ')') - ; - -windowFrame - : (MEASURES measureDefinition (',' measureDefinition)*)? - frameExtent - (AFTER MATCH skipTo)? - (INITIAL | SEEK)? - (PATTERN '(' rowPattern ')')? - (SUBSET subsetDefinition (',' subsetDefinition)*)? - (DEFINE variableDefinition (',' variableDefinition)*)? - ; - -frameExtent - : frameType=RANGE start=frameBound - | frameType=ROWS start=frameBound - | frameType=GROUPS start=frameBound - | frameType=RANGE BETWEEN start=frameBound AND end=frameBound - | frameType=ROWS BETWEEN start=frameBound AND end=frameBound - | frameType=GROUPS BETWEEN start=frameBound AND end=frameBound - ; - -frameBound - : UNBOUNDED boundType=PRECEDING #unboundedFrame - | UNBOUNDED boundType=FOLLOWING #unboundedFrame - | CURRENT ROW #currentRowBound - | expression boundType=(PRECEDING | FOLLOWING) #boundedFrame - ; - -rowPattern - : patternPrimary patternQuantifier? #quantifiedPrimary - | rowPattern rowPattern #patternConcatenation - | rowPattern '|' rowPattern #patternAlternation - ; - -patternPrimary - : identifier #patternVariable - | '(' ')' #emptyPattern - | PERMUTE '(' rowPattern (',' rowPattern)* ')' #patternPermutation - | '(' rowPattern ')' #groupedPattern - | '^' #partitionStartAnchor - | '$' #partitionEndAnchor - | '{-' rowPattern '-}' #excludedPattern - ; - -patternQuantifier - : ASTERISK (reluctant=QUESTION_MARK)? #zeroOrMoreQuantifier - | PLUS (reluctant=QUESTION_MARK)? #oneOrMoreQuantifier - | QUESTION_MARK (reluctant=QUESTION_MARK)? #zeroOrOneQuantifier - | '{' exactly=INTEGER_VALUE '}' (reluctant=QUESTION_MARK)? #rangeQuantifier - | '{' (atLeast=INTEGER_VALUE)? ',' (atMost=INTEGER_VALUE)? '}' (reluctant=QUESTION_MARK)? #rangeQuantifier - ; - -updateAssignment - : identifier EQ expression - ; - -explainOption - : FORMAT value=(TEXT | GRAPHVIZ | JSON) #explainFormat - | TYPE value=(LOGICAL | DISTRIBUTED | VALIDATE | IO) #explainType - ; - -transactionMode - : ISOLATION LEVEL levelOfIsolation #isolationLevel - | READ accessMode=(ONLY | WRITE) #transactionAccessMode - ; - -levelOfIsolation - : READ UNCOMMITTED #readUncommitted - | READ COMMITTED #readCommitted - | REPEATABLE READ #repeatableRead - | SERIALIZABLE #serializable - ; - -callArgument - : expression #positionalArgument - | identifier '=>' expression #namedArgument - ; - -pathElement - : identifier '.' identifier #qualifiedArgument - | identifier #unqualifiedArgument - ; - -pathSpecification - : pathElement (',' pathElement)* - ; - -privilege - : CREATE | SELECT | DELETE | INSERT | UPDATE - ; - -qualifiedName - : identifier ('.' identifier)* - ; - -queryPeriod - : FOR rangeType AS OF end=valueExpression - ; - -rangeType - : TIMESTAMP - | VERSION - ; - -grantor - : principal #specifiedPrincipal - | CURRENT_USER #currentUserGrantor - | CURRENT_ROLE #currentRoleGrantor - ; - -principal - : identifier #unspecifiedPrincipal - | USER identifier #userPrincipal - | ROLE identifier #rolePrincipal - ; - -roles - : identifier (',' identifier)* - ; - -identifier - : IDENTIFIER #unquotedIdentifier - | QUOTED_IDENTIFIER #quotedIdentifier - | nonReserved #unquotedIdentifier - | BACKQUOTED_IDENTIFIER #backQuotedIdentifier - | DIGIT_IDENTIFIER #digitIdentifier - ; - -number - : MINUS? DECIMAL_VALUE #decimalLiteral - | MINUS? DOUBLE_VALUE #doubleLiteral - | MINUS? INTEGER_VALUE #integerLiteral - ; - -quotedRegexMatch - : OPERATOR '(' (IDENTIFIER '.')? REGEX_MATCH ')' - ; - -collateClause - // pg syntax - : COLLATE ((IDENTIFIER | QUOTED_IDENTIFIER) '.')? (IDENTIFIER | QUOTED_IDENTIFIER | DEFAULT) - ; - -nonReserved - // IMPORTANT: this rule must only contain tokens. Nested rules are not supported. See SqlParser.exitNonReserved - : ADD | ADMIN | AFTER | ALL | ANALYZE | ANY | ARRAY | ASC | AT | AUTHORIZATION - | BERNOULLI - | CALL | CASCADE | CATALOGS | COLUMN | COLUMNS | COMMENT | COMMIT | COMMITTED | COUNT | CURRENT | COLLATE | CURSOR - | DATA | DATE | DAY | DEFAULT | DEFINE | DEFINER | DESC | DISTRIBUTED | DOUBLE | DECLARE - | EMPTY | ERROR | EXCLUDING | EXPLAIN | EPOCH - | FETCH | FILTER | FINAL | FIRST | FOLLOWING | FORMAT | FUNCTIONS - | GRANT | DENY | GRANTED | GRANTS | GRAPHVIZ | GROUPS - | HOUR - | IF | IGNORE | INCLUDING | INITIAL | INPUT | INTERVAL | INVOKER | IO | ISOLATION | IMPERSONATE - | JSON - | LAST | LATERAL | LEVEL | LIMIT | LOCAL | LOGICAL - | MAP | MATCH | MATCHED | MATCHES | MATCH_RECOGNIZE | MATERIALIZED | MEASURES | MERGE | MINUTE | MONTH - | NEXT | NFC | NFD | NFKC | NFKD | NO | NONE | NULLIF | NULLS - | OF | OFFSET | OMIT | ONE | ONLY | OPTION | ORDINALITY | OUTPUT | OVER | OVERFLOW | OPERATOR - | PARTITION | PARTITIONS | PAST | PATH | PATTERN | PER | PERMUTE | POSITION | PRECEDING | PRECISION | PRIVILEGES | PROPERTIES - | RANGE | READ | REFRESH | RENAME | REPEATABLE | REPLACE | RESET | RESPECT | RESTRICT | REVOKE | ROLE | ROLES | ROLLBACK | ROW | ROWS | RUNNING - | SCHEMA | SCHEMAS | SECOND | SECURITY | SEEK | SERIALIZABLE | SESSION | SET | SETS - | SHOW | SOME | START | STATS | SUBSET | SUBSTRING | SYSTEM - | TABLES | TABLESAMPLE | TEXT | TIES | TIME | TIMESTAMP | TO | TRANSACTION | TRUNCATE | TRY_CAST | TYPE - | UNBOUNDED | UNCOMMITTED | UNMATCHED | UPDATE | USE | USER | SESSION_USER - | VALIDATE | VERBOSE | VERSION | VIEW - | WINDOW | WITHIN | WITHOUT | WORK | WRITE - | YEAR - | ZONE - ; - -ADD: 'ADD'; -ADMIN: 'ADMIN'; -AFTER: 'AFTER'; -ALL: 'ALL'; -ALTER: 'ALTER'; -ANALYZE: 'ANALYZE'; -AND: 'AND'; -ANY: 'ANY'; -ARRAY: 'ARRAY'; -AS: 'AS'; -ASC: 'ASC'; -AT: 'AT'; -AUTHORIZATION: 'AUTHORIZATION'; -BERNOULLI: 'BERNOULLI'; -BETWEEN: 'BETWEEN'; -BY: 'BY'; -CALL: 'CALL'; -CASCADE: 'CASCADE'; -CASE: 'CASE'; -CAST: 'CAST'; -CATALOGS: 'CATALOGS'; -COLLATE: 'COLLATE'; // pg syntax -COLUMN: 'COLUMN'; -COLUMNS: 'COLUMNS'; -COMMENT: 'COMMENT'; -COMMIT: 'COMMIT'; -COMMITTED: 'COMMITTED'; -CONSTRAINT: 'CONSTRAINT'; -COUNT: 'COUNT'; -CREATE: 'CREATE'; -CROSS: 'CROSS'; -CUBE: 'CUBE'; -CURRENT: 'CURRENT'; -CURRENT_CATALOG: 'CURRENT_CATALOG'; -CURRENT_DATE: 'CURRENT_DATE'; -CURRENT_PATH: 'CURRENT_PATH'; -CURRENT_ROLE: 'CURRENT_ROLE'; -CURRENT_SCHEMA: 'CURRENT_SCHEMA'; -CURRENT_TIME: 'CURRENT_TIME'; -CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP'; -CURRENT_USER: 'CURRENT_USER'; -CURSOR: 'CURSOR'; // pg syntax -DATA: 'DATA'; -DATE: 'DATE'; -DAY: 'DAY'; -DEALLOCATE: 'DEALLOCATE'; -DECLARE: 'DECLARE'; // pg syntax -DEFAULT: 'DEFAULT'; -DEFINER: 'DEFINER'; -DELETE: 'DELETE'; -DENY: 'DENY'; -DESC: 'DESC'; -DESCRIBE: 'DESCRIBE'; -DEFINE: 'DEFINE'; -DISTINCT: 'DISTINCT'; -DISTRIBUTED: 'DISTRIBUTED'; -DOUBLE: 'DOUBLE'; -DROP: 'DROP'; -ELSE: 'ELSE'; -EMPTY: 'EMPTY'; -END: 'END'; -EPOCH: 'EPOCH'; // pg syntax -ERROR: 'ERROR'; -ESCAPE: 'ESCAPE'; -EXCEPT: 'EXCEPT'; -EXCLUDING: 'EXCLUDING'; -EXECUTE: 'EXECUTE'; -EXISTS: 'EXISTS'; -EXPLAIN: 'EXPLAIN'; -EXTRACT: 'EXTRACT'; -FALSE: 'FALSE'; -FETCH: 'FETCH'; -FILTER: 'FILTER'; -FINAL: 'FINAL'; -FIRST: 'FIRST'; -FOLLOWING: 'FOLLOWING'; -FOR: 'FOR'; -FORMAT: 'FORMAT'; -FROM: 'FROM'; -FULL: 'FULL'; -FUNCTIONS: 'FUNCTIONS'; -GRANT: 'GRANT'; -GRANTED: 'GRANTED'; -GRANTS: 'GRANTS'; -GRAPHVIZ: 'GRAPHVIZ'; -GROUP: 'GROUP'; -GROUPING: 'GROUPING'; -GROUPS: 'GROUPS'; -HAVING: 'HAVING'; -HOUR: 'HOUR'; -IF: 'IF'; -IGNORE: 'IGNORE'; -IMPERSONATE: 'IMPERSONATE'; // added by canner -IN: 'IN'; -INCLUDING: 'INCLUDING'; -INITIAL: 'INITIAL'; -INNER: 'INNER'; -INPUT: 'INPUT'; -INSERT: 'INSERT'; -INTERSECT: 'INTERSECT'; -INTERVAL: 'INTERVAL'; -INTO: 'INTO'; -INVOKER: 'INVOKER'; -IO: 'IO'; -IS: 'IS'; -ISOLATION: 'ISOLATION'; -JOIN: 'JOIN'; -JSON: 'JSON'; -LAST: 'LAST'; -LATERAL: 'LATERAL'; -LEFT: 'LEFT'; -LEVEL: 'LEVEL'; -LIKE: 'LIKE' | '~~'; // pg syntax "~~" -LIMIT: 'LIMIT'; -LISTAGG: 'LISTAGG'; -LOCAL: 'LOCAL'; -LOCALTIME: 'LOCALTIME'; -LOCALTIMESTAMP: 'LOCALTIMESTAMP'; -LOGICAL: 'LOGICAL'; -MAP: 'MAP'; -MATCH: 'MATCH'; -MATCHED: 'MATCHED'; -MATCHES: 'MATCHES'; -MATCH_RECOGNIZE: 'MATCH_RECOGNIZE'; -MATERIALIZED: 'MATERIALIZED'; -MEASURES: 'MEASURES'; -MERGE: 'MERGE'; -MINUTE: 'MINUTE'; -MONTH: 'MONTH'; -NATURAL: 'NATURAL'; -NEXT: 'NEXT'; -NFC : 'NFC'; -NFD : 'NFD'; -NFKC : 'NFKC'; -NFKD : 'NFKD'; -NO: 'NO'; -NONE: 'NONE'; -NORMALIZE: 'NORMALIZE'; -NOT: 'NOT' | '!'; // pg syntax "!" -NULL: 'NULL'; -NULLIF: 'NULLIF'; -NULLS: 'NULLS'; -OFFSET: 'OFFSET'; -OMIT: 'OMIT'; -OF: 'OF'; -ON: 'ON'; -ONE: 'ONE'; -ONLY: 'ONLY'; -OPERATOR: 'OPERATOR'; // pg syntax -OPTION: 'OPTION'; -OR: 'OR'; -ORDER: 'ORDER'; -ORDINALITY: 'ORDINALITY'; -OUTER: 'OUTER'; -OUTPUT: 'OUTPUT'; -OVER: 'OVER'; -OVERFLOW: 'OVERFLOW'; -PARTITION: 'PARTITION'; -PARTITIONS: 'PARTITIONS'; -PAST: 'PAST'; -PATH: 'PATH'; -PATTERN: 'PATTERN'; -PER: 'PER'; -PERMUTE: 'PERMUTE'; -POSITION: 'POSITION'; -PRECEDING: 'PRECEDING'; -PRECISION: 'PRECISION'; -PREPARE: 'PREPARE'; -PRIVILEGES: 'PRIVILEGES'; -PROPERTIES: 'PROPERTIES'; -RANGE: 'RANGE'; -READ: 'READ'; -RECURSIVE: 'RECURSIVE'; -REFRESH: 'REFRESH'; -RENAME: 'RENAME'; -REPEATABLE: 'REPEATABLE'; -REPLACE: 'REPLACE'; -RESET: 'RESET'; -RESPECT: 'RESPECT'; -RESTRICT: 'RESTRICT'; -REVOKE: 'REVOKE'; -RIGHT: 'RIGHT'; -ROLE: 'ROLE'; -ROLES: 'ROLES'; -ROLLBACK: 'ROLLBACK'; -ROLLUP: 'ROLLUP'; -ROW: 'ROW'; -ROWS: 'ROWS'; -RUNNING: 'RUNNING'; -SCHEMA: 'SCHEMA'; -SCHEMAS: 'SCHEMAS'; -SECOND: 'SECOND'; -SECURITY: 'SECURITY'; -SEEK: 'SEEK'; -SELECT: 'SELECT'; -SERIALIZABLE: 'SERIALIZABLE'; -SESSION: 'SESSION'; -SESSION_USER: 'SESSION_USER'; -SET: 'SET'; -SETS: 'SETS'; -SHOW: 'SHOW'; -SOME: 'SOME'; -START: 'START'; -STATS: 'STATS'; -SUBSET: 'SUBSET'; -SUBSTRING: 'SUBSTRING'; -SYSTEM: 'SYSTEM'; -TABLE: 'TABLE'; -TABLES: 'TABLES'; -TABLESAMPLE: 'TABLESAMPLE'; -TEXT: 'TEXT'; -THEN: 'THEN'; -TIES: 'TIES'; -TIME: 'TIME'; -TIMESTAMP: 'TIMESTAMP'; -TO: 'TO'; -TRANSACTION: 'TRANSACTION'; -TRUE: 'TRUE'; -TRUNCATE: 'TRUNCATE'; -TRY_CAST: 'TRY_CAST'; -TYPE: 'TYPE'; -UESCAPE: 'UESCAPE'; -UNBOUNDED: 'UNBOUNDED'; -UNCOMMITTED: 'UNCOMMITTED'; -UNION: 'UNION'; -UNMATCHED: 'UNMATCHED'; -UNNEST: 'UNNEST'; -UPDATE: 'UPDATE'; -USE: 'USE'; -USER: 'USER'; -USING: 'USING'; -VALIDATE: 'VALIDATE'; -VALUES: 'VALUES'; -VERBOSE: 'VERBOSE'; -VERSION: 'VERSION'; -VIEW: 'VIEW'; -WHEN: 'WHEN'; -WHERE: 'WHERE'; -WINDOW: 'WINDOW'; -WITH: 'WITH'; -WITHIN: 'WITHIN'; -WITHOUT: 'WITHOUT'; -WORK: 'WORK'; -WRITE: 'WRITE'; -YEAR: 'YEAR'; -ZONE: 'ZONE'; - -EQ: '='; -NEQ: '<>' | '!='; -LT: '<'; -LTE: '<='; -GT: '>'; -GTE: '>='; - -PLUS: '+'; -MINUS: '-'; -ASTERISK: '*'; -SLASH: '/'; -PERCENT: '%'; -CONCAT: '||'; -QUESTION_MARK: '?'; -// for wireprotocol to use POSIX regular expressions -REGEX_MATCH: '~'; - -STRING - : '\'' ( ~'\'' | '\'\'' )* '\'' - ; - -UNICODE_STRING - : 'U&\'' ( ~'\'' | '\'\'' )* '\'' - ; - -// Note: we allow any character inside the binary literal and validate -// its a correct literal when the AST is being constructed. This -// allows us to provide more meaningful error messages to the user -BINARY_LITERAL - : 'X\'' (~'\'')* '\'' - ; - -INTEGER_VALUE - : DIGIT+ - ; - -DECIMAL_VALUE - : DIGIT+ '.' DIGIT* - | '.' DIGIT+ - ; - -DOUBLE_VALUE - : DIGIT+ ('.' DIGIT*)? EXPONENT - | '.' DIGIT+ EXPONENT - ; - -IDENTIFIER - : (LETTER | '_') (LETTER | DIGIT | '_')* - ; - -DIGIT_IDENTIFIER - : DIGIT (LETTER | DIGIT | '_')+ - ; - -QUOTED_IDENTIFIER - : '"' ( ~'"' | '""' )* '"' - ; - -BACKQUOTED_IDENTIFIER - : '`' ( ~'`' | '``' )* '`' - ; - -fragment EXPONENT - : 'E' [+-]? DIGIT+ - ; - -fragment DIGIT - : [0-9] - ; - -fragment LETTER - : [A-Z] - ; - -SIMPLE_COMMENT - : '--' ~[\r\n]* '\r'? '\n'? -> channel(HIDDEN) - ; - -BRACKETED_COMMENT - : '/*' .*? '*/' -> channel(HIDDEN) - ; - -WS - : [ \r\n\t]+ -> channel(HIDDEN) - ; - -// Catch-all for anything we can't recognize. -// We use this to be able to ignore and recover all the text -// when splitting statements with DelimiterLexer -UNRECOGNIZED - : . - ; - -// for wireprotocol to use pg-syle casting. -PG_CAST - : '::' - ; - -// for wireprotocl to use c-style escapes. -ESCAPED_STRING - : 'E' '\'' ( ~'\'' | '\'\'' | '\\\'' )* '\'' - ; diff --git a/trino-parser/src/main/antlr4/io/trino/type/TypeCalculation.g4 b/trino-parser/src/main/antlr4/io/trino/type/TypeCalculation.g4 deleted file mode 100644 index a2d156178..000000000 --- a/trino-parser/src/main/antlr4/io/trino/type/TypeCalculation.g4 +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed 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. - */ -//TODO: consider using the SQL grammar for this -grammar TypeCalculation; - -// workaround for: -// https://github.com/antlr/antlr4/issues/118 -typeCalculation - : expression EOF - ; - -expression - : NULL #nullLiteral - | INTEGER_VALUE #numericLiteral - | binaryFunctionName '(' left=expression ',' right=expression ')' #binaryFunction - | IDENTIFIER #identifier - | '(' expression ')' #parenthesizedExpression - | operator=(MINUS | PLUS) expression #arithmeticUnary - | left=expression operator=(ASTERISK | SLASH) right=expression #arithmeticBinary - | left=expression operator=(PLUS | MINUS) right=expression #arithmeticBinary - ; - -binaryFunctionName - : name=(MAX | MIN) - ; - -PLUS: '+'; -MINUS: '-'; -ASTERISK: '*'; -SLASH: '/'; -NULL: 'NULL'; -MIN: 'MIN'; -MAX: 'MAX'; - -IDENTIFIER - : (LETTER | '_') (LETTER | DIGIT | '_' )* - ; - -INTEGER_VALUE - : DIGIT+ - ; - -fragment DIGIT - : ('0'..'9') - ; - -fragment LETTER - : [A-Za-z] - ; - -WS - : [ \r\n\t]+ -> channel(HIDDEN) - ; diff --git a/trino-parser/src/main/java/io/trino/sql/ExpressionFormatter.java b/trino-parser/src/main/java/io/trino/sql/ExpressionFormatter.java deleted file mode 100644 index 741ce3e5a..000000000 --- a/trino-parser/src/main/java/io/trino/sql/ExpressionFormatter.java +++ /dev/null @@ -1,1212 +0,0 @@ -package io.trino.sql; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import io.trino.sql.SqlFormatter.Dialect; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.AllRows; -import io.trino.sql.tree.ArithmeticBinaryExpression; -import io.trino.sql.tree.ArithmeticUnaryExpression; -import io.trino.sql.tree.ArrayConstructor; -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.AtTimeZone; -import io.trino.sql.tree.BetweenPredicate; -import io.trino.sql.tree.BinaryLiteral; -import io.trino.sql.tree.BindExpression; -import io.trino.sql.tree.BooleanLiteral; -import io.trino.sql.tree.Cast; -import io.trino.sql.tree.CharLiteral; -import io.trino.sql.tree.CoalesceExpression; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.Cube; -import io.trino.sql.tree.CurrentCatalog; -import io.trino.sql.tree.CurrentPath; -import io.trino.sql.tree.CurrentSchema; -import io.trino.sql.tree.CurrentTime; -import io.trino.sql.tree.CurrentUser; -import io.trino.sql.tree.DateTimeDataType; -import io.trino.sql.tree.DecimalLiteral; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.DoubleLiteral; -import io.trino.sql.tree.ExistsPredicate; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Extract; -import io.trino.sql.tree.FieldReference; -import io.trino.sql.tree.Format; -import io.trino.sql.tree.FrameBound; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.GenericDataType; -import io.trino.sql.tree.GenericLiteral; -import io.trino.sql.tree.GroupingElement; -import io.trino.sql.tree.GroupingOperation; -import io.trino.sql.tree.GroupingSets; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.IfExpression; -import io.trino.sql.tree.InListExpression; -import io.trino.sql.tree.InPredicate; -import io.trino.sql.tree.IntervalDayTimeDataType; -import io.trino.sql.tree.IntervalLiteral; -import io.trino.sql.tree.IsNotNullPredicate; -import io.trino.sql.tree.IsNullPredicate; -import io.trino.sql.tree.LabelDereference; -import io.trino.sql.tree.LambdaArgumentDeclaration; -import io.trino.sql.tree.LambdaExpression; -import io.trino.sql.tree.LikePredicate; -import io.trino.sql.tree.LogicalExpression; -import io.trino.sql.tree.LongLiteral; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NotExpression; -import io.trino.sql.tree.NullIfExpression; -import io.trino.sql.tree.NullLiteral; -import io.trino.sql.tree.NumericParameter; -import io.trino.sql.tree.OrderBy; -import io.trino.sql.tree.Parameter; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.QuantifiedComparisonExpression; -import io.trino.sql.tree.Rollup; -import io.trino.sql.tree.Row; -import io.trino.sql.tree.RowDataType; -import io.trino.sql.tree.SearchedCaseExpression; -import io.trino.sql.tree.SimpleCaseExpression; -import io.trino.sql.tree.SimpleGroupBy; -import io.trino.sql.tree.SkipTo; -import io.trino.sql.tree.SortItem; -import io.trino.sql.tree.StringLiteral; -import io.trino.sql.tree.SubqueryExpression; -import io.trino.sql.tree.SubscriptExpression; -import io.trino.sql.tree.SymbolReference; -import io.trino.sql.tree.TimeLiteral; -import io.trino.sql.tree.TimestampLiteral; -import io.trino.sql.tree.TryExpression; -import io.trino.sql.tree.TypeParameter; -import io.trino.sql.tree.WhenClause; -import io.trino.sql.tree.Window; -import io.trino.sql.tree.WindowFrame; -import io.trino.sql.tree.WindowOperation; -import io.trino.sql.tree.WindowReference; -import io.trino.sql.tree.WindowSpecification; - -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; -import java.util.function.Function; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.Iterables.getOnlyElement; -import static io.trino.sql.RowPatternFormatter.formatPattern; -import static io.trino.sql.SqlFormatter.Dialect.BIGQUERY; -import static io.trino.sql.SqlFormatter.Dialect.DEFAULT; -import static io.trino.sql.SqlFormatter.Dialect.DUCKDB; -import static io.trino.sql.SqlFormatter.Dialect.POSTGRES; -import static io.trino.sql.SqlFormatter.formatName; -import static io.trino.sql.SqlFormatter.formatSql; -import static io.trino.sql.tree.ComparisonExpression.Operator.EQUAL; -import static io.trino.sql.tree.QuantifiedComparisonExpression.Quantifier.ANY; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; - -public final class ExpressionFormatter -{ - private static final ThreadLocal doubleFormatter = ThreadLocal.withInitial( - () -> new DecimalFormat("0.###################E0###", new DecimalFormatSymbols(Locale.US))); - - private ExpressionFormatter() {} - - public static String formatExpression(Expression expression, Dialect dialect) - { - return new Formatter(dialect).process(expression, null); - } - - private static String formatIdentifier(String s, Dialect dialect) - { - if (dialect == DEFAULT || dialect == DUCKDB || dialect == POSTGRES) { - return '"' + s.replace("\"", "\"\"") + '"'; - } - else if (dialect == BIGQUERY) { - return '`' + s + '`'; - } - throw new IllegalArgumentException("Unsupported identifier quote: " + dialect); - } - - public static class Formatter - extends AstVisitor - { - private final Dialect dialect; - - private Formatter(Dialect dialect) - { - this.dialect = requireNonNull(dialect, "dialect is null"); - } - - @Override - protected String visitNode(Node node, Void context) - { - throw new UnsupportedOperationException(); - } - - @Override - protected String visitRow(Row node, Void context) - { - return "(" + Joiner.on(", ").join(node.getItems().stream() - .map(child -> process(child, context)) - .collect(toList())) + ")"; - } - - @Override - protected String visitExpression(Expression node, Void context) - { - throw new UnsupportedOperationException(format("not yet implemented: %s.visit%s", getClass().getName(), node.getClass().getSimpleName())); - } - - @Override - protected String visitAtTimeZone(AtTimeZone node, Void context) - { - return new StringBuilder() - .append(process(node.getValue(), context)) - .append(" AT TIME ZONE ") - .append(process(node.getTimeZone(), context)).toString(); - } - - @Override - protected String visitCurrentCatalog(CurrentCatalog node, Void context) - { - return "CURRENT_CATALOG"; - } - - @Override - protected String visitCurrentSchema(CurrentSchema node, Void context) - { - return "CURRENT_SCHEMA"; - } - - @Override - protected String visitCurrentUser(CurrentUser node, Void context) - { - return "CURRENT_USER"; - } - - @Override - protected String visitCurrentPath(CurrentPath node, Void context) - { - return "CURRENT_PATH"; - } - - @Override - protected String visitFormat(Format node, Void context) - { - return "format(" + joinExpressions(node.getArguments()) + ")"; - } - - @Override - protected String visitCurrentTime(CurrentTime node, Void context) - { - StringBuilder builder = new StringBuilder(); - - builder.append(node.getFunction().getName()); - - if (node.getPrecision() != null) { - builder.append('(') - .append(node.getPrecision()) - .append(')'); - } - - return builder.toString(); - } - - @Override - protected String visitExtract(Extract node, Void context) - { - return "EXTRACT(" + node.getField() + " FROM " + process(node.getExpression(), context) + ")"; - } - - @Override - protected String visitBooleanLiteral(BooleanLiteral node, Void context) - { - return String.valueOf(node.getValue()); - } - - @Override - protected String visitStringLiteral(StringLiteral node, Void context) - { - return formatStringLiteral(node.getValue()); - } - - @Override - protected String visitCharLiteral(CharLiteral node, Void context) - { - return "CHAR " + formatStringLiteral(node.getValue()); - } - - @Override - protected String visitBinaryLiteral(BinaryLiteral node, Void context) - { - return "X'" + node.toHexString() + "'"; - } - - @Override - protected String visitParameter(Parameter node, Void context) - { - return "?"; - } - - @Override - protected String visitAllRows(AllRows node, Void context) - { - return "ALL"; - } - - @Override - protected String visitArrayConstructor(ArrayConstructor node, Void context) - { - ImmutableList.Builder valueStrings = ImmutableList.builder(); - for (Expression value : node.getValues()) { - valueStrings.add(formatSql(value, dialect)); - } - return "ARRAY[" + Joiner.on(",").join(valueStrings.build()) + "]"; - } - - @Override - protected String visitSubscriptExpression(SubscriptExpression node, Void context) - { - String subscript; - if (dialect == DEFAULT || dialect == DUCKDB || dialect == POSTGRES) { - subscript = formatSql(node.getIndex(), dialect); - } - else if (dialect == BIGQUERY) { - // BigQuery doesn't support the normal way to access array element like `ARRAY[1,2,3][1]`. - // It should use `ORDINAL` or `OFFSET` operator to handle index value. - // Since pg is 1-based array index, that's why we use `ORDINAL` here. - // https://cloud.google.com/bigquery/docs/reference/standard-sql/arrays#accessing_array_elements - // use `SAFE_ORDINAL` to avoid array out of bounds error since in sql rewrite one-to-many relationship - // could use array index in join condition, sometimes the array column could be null - subscript = "SAFE_ORDINAL(" + formatSql(node.getIndex(), dialect) + ")"; - } - else { - throw new IllegalArgumentException("Unsupported dialect: " + dialect); - } - if (dialect == POSTGRES) { - return "(" + formatSql(node.getBase(), dialect) + ")[" + subscript + "]"; - } - return formatSql(node.getBase(), dialect) + "[" + subscript + "]"; - } - - @Override - protected String visitLongLiteral(LongLiteral node, Void context) - { - return Long.toString(node.getValue()); - } - - @Override - protected String visitDoubleLiteral(DoubleLiteral node, Void context) - { - if (dialect == DUCKDB) { - return String.valueOf(node.getValue()); - } - return doubleFormatter.get().format(node.getValue()); - } - - @Override - protected String visitDecimalLiteral(DecimalLiteral node, Void context) - { - if (dialect == DUCKDB) { - return node.getValue(); - } - // TODO return node value without "DECIMAL '..'" when FeaturesConfig#parseDecimalLiteralsAsDouble switch is removed - return "DECIMAL '" + node.getValue() + "'"; - } - - @Override - protected String visitGenericLiteral(GenericLiteral node, Void context) - { - return node.getType() + " " + formatStringLiteral(node.getValue()); - } - - @Override - protected String visitTimeLiteral(TimeLiteral node, Void context) - { - return "TIME '" + node.getValue() + "'"; - } - - @Override - protected String visitTimestampLiteral(TimestampLiteral node, Void context) - { - return "TIMESTAMP '" + node.getValue() + "'"; - } - - @Override - protected String visitNullLiteral(NullLiteral node, Void context) - { - return "null"; - } - - @Override - protected String visitIntervalLiteral(IntervalLiteral node, Void context) - { - String sign = (node.getSign() == IntervalLiteral.Sign.NEGATIVE) ? "-" : ""; - StringBuilder builder = new StringBuilder(); - if (dialect.equals(BIGQUERY) || dialect.equals(DUCKDB)) { - builder.append("INTERVAL ") - .append("'").append(sign).append(node.getValue()).append("' ") - .append(node.getStartField()); - } - else { - builder.append("INTERVAL ") - .append(sign) - .append(" '").append(node.getValue()).append("' ") - .append(node.getStartField()); - } - - if (node.getEndField().isPresent()) { - builder.append(" TO ").append(node.getEndField().get()); - } - return builder.toString(); - } - - @Override - protected String visitSubqueryExpression(SubqueryExpression node, Void context) - { - return "(" + formatSql(node.getQuery(), dialect) + ")"; - } - - @Override - protected String visitExists(ExistsPredicate node, Void context) - { - return "(EXISTS " + formatSql(node.getSubquery(), dialect) + ")"; - } - - @Override - protected String visitIdentifier(Identifier node, Void context) - { - if (!node.isDelimited()) { - return node.getValue(); - } - else { - return formatIdentifier(node.getValue(), dialect); - } - } - - @Override - protected String visitLambdaArgumentDeclaration(LambdaArgumentDeclaration node, Void context) - { - return formatExpression(node.getName(), dialect); - } - - @Override - protected String visitSymbolReference(SymbolReference node, Void context) - { - return formatIdentifier(node.getName(), dialect); - } - - @Override - protected String visitDereferenceExpression(DereferenceExpression node, Void context) - { - String baseString = process(node.getBase(), context); - return baseString + "." + node.getField().map(this::process).orElse("*"); - } - - @Override - public String visitFieldReference(FieldReference node, Void context) - { - // add colon so this won't parse - return ":input(" + node.getFieldIndex() + ")"; - } - - @Override - protected String visitFunctionCall(FunctionCall node, Void context) - { - if ("LISTAGG".equalsIgnoreCase(node.getName().toString())) { - return visitListagg(node); - } - - // TODO: support slice function in duckdb & postgresql dialect - // https://github.com/Canner/canner-metric-layer/issues/289 - if ("SLICE".equalsIgnoreCase(node.getName().toString()) && dialect.equals(BIGQUERY)) { - return processSliceInBigQuery(node); - } - - // TODO: `GENERATE_TIMESTAMP_ARRAY` is a bigquery function. We may need to consider the SQL dialect when Wren planning. - if ("GENERATE_TIMESTAMP_ARRAY".equalsIgnoreCase(node.getName().toString()) && dialect.equals(DUCKDB)) { - return processGenerateTimestampArrayInDuckDB(node); - } - - if (dialect.equals(BIGQUERY) && "COUNT_IF".equalsIgnoreCase(node.getName().toString())) { - return visitFunctionCall(new FunctionCall( - node.getLocation(), - QualifiedName.of("COUNTIF"), - node.getWindow(), - node.getFilter(), - node.getOrderBy(), - node.isDistinct(), - node.getNullTreatment(), - node.getProcessingMode(), - node.getArguments()), context); - } - - if (dialect.equals(BIGQUERY) && "DATE_DIFF".equalsIgnoreCase(node.getName().toString())) { - return processDateDiffInBigQuery(node, context); - } - - StringBuilder builder = new StringBuilder(); - - if (node.getProcessingMode().isPresent()) { - builder.append(node.getProcessingMode().get().getMode()) - .append(" "); - } - - String arguments = joinExpressions(node.getArguments()); - if (node.getArguments().isEmpty() && "count".equalsIgnoreCase(node.getName().getSuffix())) { - arguments = "*"; - } - if (node.isDistinct()) { - arguments = "DISTINCT " + arguments; - } - - builder.append(formatName(node.getName(), dialect)) - .append('(').append(arguments); - - // BigQuery doesn't allow null element in an array. Add IGNORE NULLS to ignore null element always. - if (dialect.equals(BIGQUERY) && - "ARRAY_AGG".equalsIgnoreCase(node.getName().toString())) { - builder.append(" IGNORE NULLS"); - } - - if (node.getOrderBy().isPresent()) { - builder.append(' ').append(formatOrderBy(node.getOrderBy().get(), dialect)); - } - - builder.append(')'); - - node.getNullTreatment().ifPresent(nullTreatment -> { - switch (nullTreatment) { - case IGNORE: - builder.append(" IGNORE NULLS"); - break; - case RESPECT: - builder.append(" RESPECT NULLS"); - break; - } - }); - - if (!dialect.equals(BIGQUERY) && node.getFilter().isPresent()) { - builder.append(" FILTER ").append(visitFilter(node.getFilter().get(), context)); - } - - if (node.getWindow().isPresent()) { - builder.append(" OVER ").append(formatWindow(node.getWindow().get(), dialect)); - } - - return builder.toString(); - } - - @Override - protected String visitWindowOperation(WindowOperation node, Void context) - { - return process(node.getName(), context) + " OVER " + formatWindow(node.getWindow(), dialect); - } - - @Override - protected String visitLambdaExpression(LambdaExpression node, Void context) - { - StringBuilder builder = new StringBuilder(); - - builder.append('('); - Joiner.on(", ").appendTo(builder, node.getArguments()); - builder.append(") -> "); - builder.append(process(node.getBody(), context)); - return builder.toString(); - } - - @Override - protected String visitBindExpression(BindExpression node, Void context) - { - StringBuilder builder = new StringBuilder(); - - builder.append("\"$INTERNAL$BIND\"("); - for (Expression value : node.getValues()) { - builder.append(process(value, context)) - .append(", "); - } - builder.append(process(node.getFunction(), context)) - .append(")"); - return builder.toString(); - } - - @Override - protected String visitLogicalExpression(LogicalExpression node, Void context) - { - return "(" + - node.getTerms().stream() - .map(term -> process(term, context)) - .collect(Collectors.joining(" " + node.getOperator().toString() + " ")) + - ")"; - } - - @Override - protected String visitNotExpression(NotExpression node, Void context) - { - return "(NOT " + process(node.getValue(), context) + ")"; - } - - @Override - protected String visitComparisonExpression(ComparisonExpression node, Void context) - { - return formatBinaryExpression(node.getOperator().getValue(), node.getLeft(), node.getRight()); - } - - @Override - protected String visitIsNullPredicate(IsNullPredicate node, Void context) - { - return "(" + process(node.getValue(), context) + " IS NULL)"; - } - - @Override - protected String visitIsNotNullPredicate(IsNotNullPredicate node, Void context) - { - return "(" + process(node.getValue(), context) + " IS NOT NULL)"; - } - - @Override - protected String visitNullIfExpression(NullIfExpression node, Void context) - { - return "NULLIF(" + process(node.getFirst(), context) + ", " + process(node.getSecond(), context) + ')'; - } - - @Override - protected String visitIfExpression(IfExpression node, Void context) - { - StringBuilder builder = new StringBuilder(); - builder.append("IF(") - .append(process(node.getCondition(), context)) - .append(", ") - .append(process(node.getTrueValue(), context)); - if (node.getFalseValue().isPresent()) { - builder.append(", ") - .append(process(node.getFalseValue().get(), context)); - } - builder.append(")"); - return builder.toString(); - } - - @Override - protected String visitTryExpression(TryExpression node, Void context) - { - return "TRY(" + process(node.getInnerExpression(), context) + ")"; - } - - @Override - protected String visitCoalesceExpression(CoalesceExpression node, Void context) - { - return "COALESCE(" + joinExpressions(node.getOperands()) + ")"; - } - - @Override - protected String visitArithmeticUnary(ArithmeticUnaryExpression node, Void context) - { - String value = process(node.getValue(), context); - - switch (node.getSign()) { - case MINUS: - // Unary is ambiguous with respect to negative numbers. "-1" parses as a number, but "-(1)" parses as "unaryMinus(number)" - // The parentheses are needed to ensure the parsing roundtrips properly. - return "-(" + value + ")"; - case PLUS: - return "+" + value; - } - throw new UnsupportedOperationException("Unsupported sign: " + node.getSign()); - } - - @Override - protected String visitArithmeticBinary(ArithmeticBinaryExpression node, Void context) - { - return formatBinaryExpression(node.getOperator().getValue(), node.getLeft(), node.getRight()); - } - - @Override - protected String visitLikePredicate(LikePredicate node, Void context) - { - StringBuilder builder = new StringBuilder(); - - builder.append('(') - .append(process(node.getValue(), context)) - .append(" LIKE ") - .append(process(node.getPattern(), context)); - - if (dialect == DEFAULT || dialect == DUCKDB) { - node.getEscape().ifPresent(escape -> builder.append(" ESCAPE ") - .append(process(escape, context))); - } - - builder.append(')'); - - return builder.toString(); - } - - @Override - protected String visitAllColumns(AllColumns node, Void context) - { - StringBuilder builder = new StringBuilder(); - if (node.getTarget().isPresent()) { - builder.append(process(node.getTarget().get(), context)); - builder.append(".*"); - } - else { - builder.append("*"); - } - - if (!node.getAliases().isEmpty()) { - builder.append(" AS ("); - Joiner.on(", ").appendTo(builder, node.getAliases().stream() - .map(alias -> process(alias, context)) - .collect(toList())); - builder.append(")"); - } - - return builder.toString(); - } - - @Override - public String visitCast(Cast node, Void context) - { - return (node.isSafe() ? "TRY_CAST" : "CAST") + - "(" + process(node.getExpression(), context) + " AS " + process(node.getType(), context) + ")"; - } - - @Override - protected String visitSearchedCaseExpression(SearchedCaseExpression node, Void context) - { - ImmutableList.Builder parts = ImmutableList.builder(); - parts.add("CASE"); - for (WhenClause whenClause : node.getWhenClauses()) { - parts.add(process(whenClause, context)); - } - - node.getDefaultValue() - .ifPresent(value -> parts.add("ELSE").add(process(value, context))); - - parts.add("END"); - - return "(" + Joiner.on(' ').join(parts.build()) + ")"; - } - - @Override - protected String visitSimpleCaseExpression(SimpleCaseExpression node, Void context) - { - ImmutableList.Builder parts = ImmutableList.builder(); - - parts.add("CASE") - .add(process(node.getOperand(), context)); - - for (WhenClause whenClause : node.getWhenClauses()) { - parts.add(process(whenClause, context)); - } - - node.getDefaultValue() - .ifPresent(value -> parts.add("ELSE").add(process(value, context))); - - parts.add("END"); - - return "(" + Joiner.on(' ').join(parts.build()) + ")"; - } - - @Override - protected String visitWhenClause(WhenClause node, Void context) - { - return "WHEN " + process(node.getOperand(), context) + " THEN " + process(node.getResult(), context); - } - - @Override - protected String visitBetweenPredicate(BetweenPredicate node, Void context) - { - return "(" + process(node.getValue(), context) + " BETWEEN " + - process(node.getMin(), context) + " AND " + process(node.getMax(), context) + ")"; - } - - @Override - protected String visitInPredicate(InPredicate node, Void context) - { - return "(" + process(node.getValue(), context) + " IN " + process(node.getValueList(), context) + ")"; - } - - @Override - protected String visitInListExpression(InListExpression node, Void context) - { - return "(" + joinExpressions(node.getValues()) + ")"; - } - - private String visitFilter(Expression node, Void context) - { - return "(WHERE " + process(node, context) + ')'; - } - - @Override - protected String visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, Void context) - { - if (dialect.equals(BIGQUERY)) { - // Convert PostgreSQL `= ANY` to BigQuery `IN` - if (node.getQuantifier().equals(ANY) && node.getOperator().equals(EQUAL)) { - return "(" + - process(node.getValue(), context) + - " IN " + - process(node.getSubquery(), context) + - ")"; - } - } - - return new StringBuilder() - .append("(") - .append(process(node.getValue(), context)) - .append(' ') - .append(node.getOperator().getValue()) - .append(' ') - .append(node.getQuantifier().toString()) - .append(' ') - .append(process(node.getSubquery(), context)) - .append(")") - .toString(); - } - - @Override - protected String visitGroupingOperation(GroupingOperation node, Void context) - { - return "GROUPING (" + joinExpressions(node.getGroupingColumns()) + ")"; - } - - @Override - protected String visitRowDataType(RowDataType node, Void context) - { - return node.getFields().stream() - .map(this::process) - .collect(joining(", ", "ROW(", ")")); - } - - @Override - protected String visitRowField(RowDataType.Field node, Void context) - { - StringBuilder result = new StringBuilder(); - - if (node.getName().isPresent()) { - result.append(process(node.getName().get(), context)); - result.append(" "); - } - - result.append(process(node.getType(), context)); - - return result.toString(); - } - - @Override - protected String visitGenericDataType(GenericDataType node, Void context) - { - StringBuilder result = new StringBuilder(); - result.append(node.getName()); - - if (node.getName().getCanonicalValue().equals("ARRAY")) { - switch (dialect) { - case BIGQUERY: - // Format to ARRAY - result.append("<"); - result.append(process(node.getArguments().get(0), context)); - result.append(">"); - return result.toString(); - case POSTGRES: - case DUCKDB: - // Format to BOOLEAN[] - result.delete(0, result.length()); - result.append(process(node.getArguments().get(0), context)); - result.append("[]"); - return result.toString(); - } - } - - if (!node.getArguments().isEmpty()) { - result.append(node.getArguments().stream() - .map(this::process) - .collect(joining(", ", "(", ")"))); - } - - return result.toString(); - } - - @Override - protected String visitTypeParameter(TypeParameter node, Void context) - { - return process(node.getValue(), context); - } - - @Override - protected String visitNumericTypeParameter(NumericParameter node, Void context) - { - return node.getValue(); - } - - @Override - protected String visitIntervalDataType(IntervalDayTimeDataType node, Void context) - { - StringBuilder builder = new StringBuilder(); - - builder.append("INTERVAL "); - builder.append(node.getFrom()); - if (node.getFrom() != node.getTo()) { - builder.append(" TO ") - .append(node.getTo()); - } - - return builder.toString(); - } - - @Override - protected String visitDateTimeType(DateTimeDataType node, Void context) - { - StringBuilder builder = new StringBuilder(); - - builder.append(node.getType().toString().toLowerCase(Locale.ENGLISH)); // TODO: normalize to upper case according to standard SQL semantics - if (node.getPrecision().isPresent()) { - builder.append("(") - .append(node.getPrecision().get()) - .append(")"); - } - - if (node.isWithTimeZone()) { - builder.append(" with time zone"); // TODO: normalize to upper case according to standard SQL semantics - } - - return builder.toString(); - } - - @Override - protected String visitLabelDereference(LabelDereference node, Void context) - { - // format LabelDereference L.x as "LABEL_DEREFERENCE("L", "x")" - // LabelDereference, like SymbolReference, is an IR-type expression. It is never a result of the parser. - // After being formatted this way for serialization, it will be parsed as functionCall - // and swapped back for LabelDereference. - return "LABEL_DEREFERENCE(" + formatIdentifier(node.getLabel(), dialect) + ", " + node.getReference().map(this::process).orElse("*") + ")"; - } - - private String formatBinaryExpression(String operator, Expression left, Expression right) - { - return '(' + process(left, null) + ' ' + operator + ' ' + process(right, null) + ')'; - } - - private String joinExpressions(List expressions) - { - return Joiner.on(", ").join(expressions.stream() - .map((e) -> process(e, null)) - .iterator()); - } - - /** - * Returns the formatted `LISTAGG` function call corresponding to the specified node. - *

- * During the parsing of the syntax tree, the `LISTAGG` expression is synthetically converted - * to a function call. This method formats the specified {@link FunctionCall} node to correspond - * to the standardised syntax of the `LISTAGG` expression. - * - * @param node the `LISTAGG` function call - */ - private String visitListagg(FunctionCall node) - { - StringBuilder builder = new StringBuilder(); - - List arguments = node.getArguments(); - Expression expression = arguments.get(0); - Expression separator = arguments.get(1); - BooleanLiteral overflowError = (BooleanLiteral) arguments.get(2); - Expression overflowFiller = arguments.get(3); - BooleanLiteral showOverflowEntryCount = (BooleanLiteral) arguments.get(4); - - String innerArguments = joinExpressions(ImmutableList.of(expression, separator)); - if (node.isDistinct()) { - innerArguments = "DISTINCT " + innerArguments; - } - - builder.append("LISTAGG") - .append('(').append(innerArguments); - - builder.append(" ON OVERFLOW "); - if (overflowError.getValue()) { - builder.append(" ERROR"); - } - else { - builder.append(" TRUNCATE") - .append(' ') - .append(process(overflowFiller, null)); - if (showOverflowEntryCount.getValue()) { - builder.append(" WITH COUNT"); - } - else { - builder.append(" WITHOUT COUNT"); - } - } - - builder.append(')'); - - if (node.getOrderBy().isPresent()) { - builder.append(" WITHIN GROUP ") - .append('(') - .append(formatOrderBy(node.getOrderBy().get(), dialect)) - .append(')'); - } - - return builder.toString(); - } - - private String processSliceInBigQuery(FunctionCall node) - { - List arguments = node.getArguments(); - Expression expression = arguments.get(0); - LongLiteral start = (LongLiteral) arguments.get(1); - LongLiteral length = (LongLiteral) arguments.get(2); - return format("ARRAY(SELECT p FROM UNNEST(%s) p WITH OFFSET index WHERE index BETWEEN %s AND %s ORDER BY index)", - process(expression), - // bigquery use zero-based indexes - start.getValue() - 1, - start.getValue() - 1 + length.getValue()); - } - - private String processGenerateTimestampArrayInDuckDB(FunctionCall node) - { - List arguments = node.getArguments(); - Expression start = arguments.get(0); - Expression end = arguments.get(1); - return format("GENERATE_SERIES(%s, %s, INTERVAL 1 DAY)", - start, - end); - } - - private String processDateDiffInBigQuery(FunctionCall node, Void context) - { - checkArgument(node.getArguments().size() == 3, "DATE_DIFF function should have 3 arguments"); - List arguments = node.getArguments(); - StringLiteral datePart = (StringLiteral) arguments.get(0); - Expression start = arguments.get(1); - Expression end = arguments.get(2); - // In BigQuery, the formula is `start - end` but it's `end - start` in trino. - return format("TIMESTAMP_DIFF(%s, %s, %s)", - process(end, context), - process(start, context), - datePart.getValue()); - } - } - - static String formatStringLiteral(String s) - { - return "'" + s.replace("'", "''") + "'"; - } - - public static String formatOrderBy(OrderBy orderBy, Dialect dialect) - { - return "ORDER BY " + formatSortItems(orderBy.getSortItems(), dialect); - } - - private static String formatSortItems(List sortItems, Dialect dialect) - { - return Joiner.on(", ").join(sortItems.stream() - .map(sortItemFormatterFunction(dialect)) - .iterator()); - } - - private static String formatWindow(Window window, Dialect dialect) - { - if (window instanceof WindowReference) { - return formatExpression(((WindowReference) window).getName(), dialect); - } - - return formatWindowSpecification((WindowSpecification) window, dialect); - } - - static String formatWindowSpecification(WindowSpecification windowSpecification, Dialect dialect) - { - List parts = new ArrayList<>(); - - if (windowSpecification.getExistingWindowName().isPresent()) { - parts.add(formatExpression(windowSpecification.getExistingWindowName().get(), dialect)); - } - if (!windowSpecification.getPartitionBy().isEmpty()) { - parts.add("PARTITION BY " + windowSpecification.getPartitionBy().stream() - .map(expression -> formatExpression(expression, dialect)) - .collect(joining(", "))); - } - if (windowSpecification.getOrderBy().isPresent()) { - parts.add(formatOrderBy(windowSpecification.getOrderBy().get(), dialect)); - } - if (windowSpecification.getFrame().isPresent()) { - parts.add(formatFrame(windowSpecification.getFrame().get(), dialect)); - } - - return '(' + Joiner.on(' ').join(parts) + ')'; - } - - private static String formatFrame(WindowFrame windowFrame, Dialect dialect) - { - StringBuilder builder = new StringBuilder(); - - if (!windowFrame.getMeasures().isEmpty()) { - builder.append("MEASURES ") - .append(windowFrame.getMeasures().stream() - .map(measure -> formatExpression(measure.getExpression(), dialect) + " AS " + formatExpression(measure.getName(), dialect)) - .collect(joining(", "))) - .append(" "); - } - - builder.append(windowFrame.getType().toString()) - .append(' '); - - if (windowFrame.getEnd().isPresent()) { - builder.append("BETWEEN ") - .append(formatFrameBound(windowFrame.getStart(), dialect)) - .append(" AND ") - .append(formatFrameBound(windowFrame.getEnd().get(), dialect)); - } - else { - builder.append(formatFrameBound(windowFrame.getStart(), dialect)); - } - - windowFrame.getAfterMatchSkipTo().ifPresent(skipTo -> - builder.append(" ") - .append(formatSkipTo(skipTo, dialect))); - windowFrame.getPatternSearchMode().ifPresent(searchMode -> - builder.append(" ") - .append(searchMode.getMode().name())); - windowFrame.getPattern().ifPresent(pattern -> - builder.append(" PATTERN(") - .append(formatPattern(pattern, dialect)) - .append(")")); - if (!windowFrame.getSubsets().isEmpty()) { - builder.append(" SUBSET "); - builder.append(windowFrame.getSubsets().stream() - .map(subset -> formatExpression(subset.getName(), dialect) + " = " + subset.getIdentifiers().stream() - .map(expression -> formatExpression(expression, dialect)).collect(joining(", ", "(", ")"))) - .collect(joining(", "))); - } - if (!windowFrame.getVariableDefinitions().isEmpty()) { - builder.append(" DEFINE "); - builder.append(windowFrame.getVariableDefinitions().stream() - .map(variable -> formatExpression(variable.getName(), dialect) + " AS " + formatExpression(variable.getExpression(), dialect)) - .collect(joining(", "))); - } - - return builder.toString(); - } - - private static String formatFrameBound(FrameBound frameBound, Dialect dialect) - { - switch (frameBound.getType()) { - case UNBOUNDED_PRECEDING: - return "UNBOUNDED PRECEDING"; - case PRECEDING: - return formatExpression(frameBound.getValue().get(), dialect) + " PRECEDING"; - case CURRENT_ROW: - return "CURRENT ROW"; - case FOLLOWING: - return formatExpression(frameBound.getValue().get(), dialect) + " FOLLOWING"; - case UNBOUNDED_FOLLOWING: - return "UNBOUNDED FOLLOWING"; - } - throw new IllegalArgumentException("unhandled type: " + frameBound.getType()); - } - - public static String formatSkipTo(SkipTo skipTo, Dialect dialect) - { - switch (skipTo.getPosition()) { - case PAST_LAST: - return "AFTER MATCH SKIP PAST LAST ROW"; - case NEXT: - return "AFTER MATCH SKIP TO NEXT ROW"; - case LAST: - checkState(skipTo.getIdentifier().isPresent(), "missing identifier in AFTER MATCH SKIP TO LAST"); - return "AFTER MATCH SKIP TO LAST " + formatExpression(skipTo.getIdentifier().get(), dialect); - case FIRST: - checkState(skipTo.getIdentifier().isPresent(), "missing identifier in AFTER MATCH SKIP TO FIRST"); - return "AFTER MATCH SKIP TO FIRST " + formatExpression(skipTo.getIdentifier().get(), dialect); - default: - throw new IllegalStateException("unexpected skipTo: " + skipTo); - } - } - - static String formatGroupBy(List groupingElements, Dialect dialect) - { - ImmutableList.Builder resultStrings = ImmutableList.builder(); - - for (GroupingElement groupingElement : groupingElements) { - String result = ""; - if (groupingElement instanceof SimpleGroupBy) { - List columns = groupingElement.getExpressions(); - if (columns.size() == 1) { - result = formatExpression(getOnlyElement(columns), dialect); - } - else { - result = formatGroupingSet(columns, dialect); - } - } - else if (groupingElement instanceof GroupingSets) { - result = format("GROUPING SETS (%s)", Joiner.on(", ").join( - ((GroupingSets) groupingElement).getSets().stream() - .map(expression -> formatGroupingSet(expression, dialect)) - .iterator())); - } - else if (groupingElement instanceof Cube) { - result = format("CUBE %s", formatGroupingSet(groupingElement.getExpressions(), dialect)); - } - else if (groupingElement instanceof Rollup) { - result = format("ROLLUP %s", formatGroupingSet(groupingElement.getExpressions(), dialect)); - } - resultStrings.add(result); - } - return Joiner.on(", ").join(resultStrings.build()); - } - - private static boolean isAsciiPrintable(int codePoint) - { - return codePoint >= 0x20 && codePoint < 0x7F; - } - - private static String formatGroupingSet(List groupingSet, Dialect dialect) - { - return format("(%s)", Joiner.on(", ").join(groupingSet.stream() - .map(expression -> formatExpression(expression, dialect)) - .iterator())); - } - - private static Function sortItemFormatterFunction(Dialect dialect) - { - return input -> { - StringBuilder builder = new StringBuilder(); - - builder.append(formatExpression(input.getSortKey(), dialect)); - - switch (input.getOrdering()) { - case ASCENDING: - builder.append(" ASC"); - break; - case DESCENDING: - builder.append(" DESC"); - break; - default: - throw new UnsupportedOperationException("unknown ordering: " + input.getOrdering()); - } - - switch (input.getNullOrdering()) { - case FIRST: - builder.append(" NULLS FIRST"); - break; - case LAST: - builder.append(" NULLS LAST"); - break; - case UNDEFINED: - // no op - break; - default: - throw new UnsupportedOperationException("unknown null ordering: " + input.getNullOrdering()); - } - - return builder.toString(); - }; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/QueryUtil.java b/trino-parser/src/main/java/io/trino/sql/QueryUtil.java deleted file mode 100644 index d5faccee9..000000000 --- a/trino-parser/src/main/java/io/trino/sql/QueryUtil.java +++ /dev/null @@ -1,367 +0,0 @@ -package io.trino.sql; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.parser.ParsingOptions; -import io.trino.sql.parser.SqlParser; -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.CoalesceExpression; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.GroupBy; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.Join; -import io.trino.sql.tree.JoinCriteria; -import io.trino.sql.tree.JoinOn; -import io.trino.sql.tree.LogicalExpression; -import io.trino.sql.tree.LongLiteral; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NullLiteral; -import io.trino.sql.tree.Offset; -import io.trino.sql.tree.OrderBy; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.QueryBody; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.Relation; -import io.trino.sql.tree.Row; -import io.trino.sql.tree.SearchedCaseExpression; -import io.trino.sql.tree.Select; -import io.trino.sql.tree.SelectItem; -import io.trino.sql.tree.SingleColumn; -import io.trino.sql.tree.SortItem; -import io.trino.sql.tree.StringLiteral; -import io.trino.sql.tree.SubscriptExpression; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.Unnest; -import io.trino.sql.tree.Values; -import io.trino.sql.tree.WhenClause; -import io.trino.sql.tree.WindowDefinition; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DOUBLE; -import static io.trino.sql.tree.BooleanLiteral.FALSE_LITERAL; -import static io.trino.sql.tree.BooleanLiteral.TRUE_LITERAL; -import static java.util.Arrays.asList; - -public final class QueryUtil -{ - private QueryUtil() {} - - public static Identifier identifier(String name) - { - return new Identifier(name); - } - - public static Identifier quotedIdentifier(String name) - { - return new Identifier(name, true); - } - - public static Expression nameReference(String first, String... rest) - { - return DereferenceExpression.from(QualifiedName.of(first, rest)); - } - - public static SelectItem unaliasedName(String name) - { - return new SingleColumn(identifier(name)); - } - - public static SelectItem aliasedName(String name, String alias) - { - return new SingleColumn(identifier(name), identifier(alias)); - } - - public static SubscriptExpression subscriptExpression(Expression name, String index) - { - return new SubscriptExpression(name, new LongLiteral(index)); - } - - public static Select selectList(Expression... expressions) - { - return selectList(asList(expressions)); - } - - public static Select selectList(List expressions) - { - ImmutableList.Builder items = ImmutableList.builder(); - for (Expression expression : expressions) { - items.add(new SingleColumn(expression)); - } - return new Select(false, items.build()); - } - - public static Select selectListDistinct(List expressions) - { - ImmutableList.Builder items = ImmutableList.builder(); - for (Expression expression : expressions) { - items.add(new SingleColumn(expression)); - } - return new Select(true, items.build()); - } - - public static Select selectList(List expressions, List aliases) - { - ImmutableList.Builder items = ImmutableList.builder(); - for (int i = 0; i < expressions.size(); i++) { - items.add(new SingleColumn(expressions.get(i), identifier(aliases.get(i)))); - } - return new Select(false, items.build()); - } - - public static Select selectList(SelectItem... items) - { - return new Select(false, ImmutableList.copyOf(items)); - } - - public static Select selectAll(List items) - { - return new Select(false, items); - } - - public static Table table(QualifiedName name) - { - return new Table(name); - } - - public static Unnest unnest(Expression... expressions) - { - return new Unnest(asList(expressions), false); - } - - public static Join leftJoin(Relation left, Relation right, JoinCriteria joinCriteria) - { - return new Join(Join.Type.LEFT, left, right, Optional.ofNullable(joinCriteria)); - } - - public static Join crossJoin(Relation left, Relation right) - { - return new Join(Join.Type.CROSS, left, right, Optional.empty()); - } - - public static Join implicitJoin(Relation left, Relation right) - { - return new Join(Join.Type.IMPLICIT, left, right, Optional.empty()); - } - - public static JoinOn joinOn(Expression conditionSql) - { - return new JoinOn(conditionSql); - } - - public static ComparisonExpression getConditionNode(String condition) - { - SqlParser sqlParser = new SqlParser(); - Query statement = (Query) sqlParser.createStatement("SELECT " + condition, new ParsingOptions(AS_DOUBLE)); - return (ComparisonExpression) - ((SingleColumn) ((QuerySpecification) statement.getQueryBody()).getSelect().getSelectItems().get(0)).getExpression(); - } - - public static Relation subquery(Query query) - { - return new TableSubquery(query); - } - - public static SortItem ascending(String name) - { - return new SortItem(identifier(name), SortItem.Ordering.ASCENDING, SortItem.NullOrdering.UNDEFINED); - } - - public static Expression logicalAnd(Expression left, Expression right) - { - return LogicalExpression.and(left, right); - } - - public static Expression equal(Expression left, Expression right) - { - return new ComparisonExpression(ComparisonExpression.Operator.EQUAL, left, right); - } - - public static Expression caseWhen(Expression operand, Expression result) - { - return new SearchedCaseExpression(ImmutableList.of(new WhenClause(operand, result)), Optional.empty()); - } - - public static Expression functionCall(String name, List arguments) - { - return new FunctionCall(QualifiedName.of(name), ImmutableList.copyOf(arguments)); - } - - public static Expression functionCall(String name, Expression... arguments) - { - return new FunctionCall(QualifiedName.of(name), ImmutableList.copyOf(arguments)); - } - - public static Values values(Row... row) - { - return new Values(ImmutableList.copyOf(row)); - } - - public static Row row(Expression... values) - { - return new Row(ImmutableList.copyOf(values)); - } - - public static Relation aliased(Relation relation, String alias) - { - return new AliasedRelation(relation, identifier(alias), null); - } - - public static Relation aliased(Relation relation, String alias, List columnAliases) - { - return new AliasedRelation( - relation, - identifier(alias), - columnAliases.stream() - .map(QueryUtil::identifier) - .collect(Collectors.toList())); - } - - public static SelectItem aliasedNullToEmpty(String column, String alias) - { - return new SingleColumn(new CoalesceExpression(identifier(column), new StringLiteral("")), identifier(alias)); - } - - public static OrderBy ordering(SortItem... items) - { - return new OrderBy(ImmutableList.copyOf(items)); - } - - public static Query simpleQuery(Select select) - { - return query(new QuerySpecification( - select, - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - } - - public static Query simpleQuery(Select select, Relation from) - { - return simpleQuery(select, from, Optional.empty(), Optional.empty()); - } - - public static Query simpleQuery(Select select, Relation from, OrderBy orderBy) - { - return simpleQuery(select, from, Optional.empty(), Optional.of(orderBy)); - } - - public static Query simpleQuery(Select select, Relation from, Expression where) - { - return simpleQuery(select, from, Optional.of(where), Optional.empty()); - } - - public static Query simpleQuery(Select select, Relation from, Expression where, OrderBy orderBy) - { - return simpleQuery(select, from, Optional.of(where), Optional.of(orderBy)); - } - - public static Query simpleQuery(Select select, Relation from, Optional where, Optional orderBy) - { - return simpleQuery(select, from, where, Optional.empty(), Optional.empty(), orderBy, Optional.empty(), Optional.empty()); - } - - public static Query simpleQuery( - Select select, - Relation from, - Optional where, - Optional groupBy, - Optional having, - Optional orderBy, - Optional offset, - Optional limit) - { - return simpleQuery(select, from, where, groupBy, having, ImmutableList.of(), orderBy, offset, limit); - } - - public static Query simpleQuery( - Select select, - Relation from, - Optional where, - Optional groupBy, - Optional having, - List windows, - Optional orderBy, - Optional offset, - Optional limit) - { - return query(new QuerySpecification( - select, - Optional.of(from), - where, - groupBy, - having, - windows, - orderBy, - offset, - limit)); - } - - public static Query singleValueQuery(String columnName, String value) - { - Relation values = values(row(new StringLiteral((value)))); - return simpleQuery( - selectList(new AllColumns()), - aliased(values, "t", ImmutableList.of(columnName))); - } - - public static Query singleValueQuery(String columnName, boolean value) - { - Relation values = values(row(value ? TRUE_LITERAL : FALSE_LITERAL)); - return simpleQuery( - selectList(new AllColumns()), - aliased(values, "t", ImmutableList.of(columnName))); - } - - // TODO pass column types - public static Query emptyQuery(List columns) - { - Select select = selectList(columns.stream() - .map(column -> new SingleColumn(new NullLiteral(), QueryUtil.identifier(column))) - .toArray(SelectItem[]::new)); - Optional where = Optional.of(FALSE_LITERAL); - return query(new QuerySpecification( - select, - Optional.empty(), - where, - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - } - - public static Query query(QueryBody body) - { - return new Query( - Optional.empty(), - body, - Optional.empty(), - Optional.empty(), - Optional.empty()); - } - - public static QualifiedName getQualifiedName(Expression expression) - { - if (expression instanceof DereferenceExpression) { - return DereferenceExpression.getQualifiedName((DereferenceExpression) expression); - } - if (expression instanceof Identifier) { - return QualifiedName.of(ImmutableList.of((Identifier) expression)); - } - return null; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/ReservedIdentifiers.java b/trino-parser/src/main/java/io/trino/sql/ReservedIdentifiers.java deleted file mode 100644 index 6b9145d23..000000000 --- a/trino-parser/src/main/java/io/trino/sql/ReservedIdentifiers.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Licensed 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 io.trino.sql; - -import com.google.common.collect.ImmutableSet; -import io.trino.sql.parser.ParsingException; -import io.trino.sql.parser.ParsingOptions; -import io.trino.sql.parser.SqlBaseLexer; -import io.trino.sql.parser.SqlParser; -import io.trino.sql.tree.Identifier; -import org.antlr.v4.runtime.Vocabulary; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static com.google.common.base.Strings.nullToEmpty; -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static java.lang.String.format; - -public final class ReservedIdentifiers -{ - private static final Pattern IDENTIFIER = Pattern.compile("'([A-Z_]+)'"); - private static final Pattern TABLE_ROW = Pattern.compile("``([A-Z_]+)``.*"); - private static final String TABLE_PREFIX = "============================== "; - - private static final SqlParser PARSER = new SqlParser(); - - private ReservedIdentifiers() {} - - @SuppressWarnings("CallToPrintStackTrace") - public static void main(String[] args) - { - if ((args.length == 2) && args[0].equals("validateDocs")) { - try { - validateDocs(Paths.get(args[1])); - } - catch (Throwable t) { - t.printStackTrace(); - System.exit(100); - } - } - else { - for (String name : reservedIdentifiers()) { - System.out.println(name); - } - } - } - - private static void validateDocs(Path path) - throws IOException - { - System.out.println("Validating " + path); - List lines = Files.readAllLines(path); - - if (lines.stream().filter(s -> s.startsWith(TABLE_PREFIX)).count() != 3) { - throw new RuntimeException("Failed to find exactly one table"); - } - - Iterator iterator = lines.iterator(); - - // find table and skip header - while (!iterator.next().startsWith(TABLE_PREFIX)) { - // skip - } - if (iterator.next().startsWith(TABLE_PREFIX)) { - throw new RuntimeException("Expected to find a header line"); - } - if (!iterator.next().startsWith(TABLE_PREFIX)) { - throw new RuntimeException("Found multiple header lines"); - } - - Set reserved = reservedIdentifiers(); - Set found = new HashSet<>(); - while (true) { - String line = iterator.next(); - if (line.startsWith(TABLE_PREFIX)) { - break; - } - - Matcher matcher = TABLE_ROW.matcher(line); - if (!matcher.matches()) { - throw new RuntimeException("Invalid table line: " + line); - } - String name = matcher.group(1); - - if (!reserved.contains(name)) { - throw new RuntimeException("Documented identifier is not reserved: " + name); - } - if (!found.add(name)) { - throw new RuntimeException("Duplicate documented identifier: " + name); - } - } - - for (String name : reserved) { - if (!found.contains(name)) { - throw new RuntimeException("Reserved identifier is not documented: " + name); - } - } - - System.out.println(format("Validated %s reserved identifiers", reserved.size())); - } - - public static Set reservedIdentifiers() - { - return sqlKeywords().stream() - .filter(ReservedIdentifiers::reserved) - .sorted() - .collect(toImmutableSet()); - } - - public static Set sqlKeywords() - { - ImmutableSet.Builder names = ImmutableSet.builder(); - Vocabulary vocabulary = SqlBaseLexer.VOCABULARY; - for (int i = 0; i <= vocabulary.getMaxTokenType(); i++) { - String name = nullToEmpty(vocabulary.getLiteralName(i)); - Matcher matcher = IDENTIFIER.matcher(name); - if (matcher.matches()) { - names.add(matcher.group(1)); - } - } - return names.build(); - } - - public static boolean reserved(String name) - { - try { - return !(PARSER.createExpression(name, new ParsingOptions()) instanceof Identifier); - } - catch (ParsingException ignored) { - return true; - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/RowPatternFormatter.java b/trino-parser/src/main/java/io/trino/sql/RowPatternFormatter.java deleted file mode 100644 index db27e4ff9..000000000 --- a/trino-parser/src/main/java/io/trino/sql/RowPatternFormatter.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Licensed 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 io.trino.sql; - -import io.trino.sql.SqlFormatter.Dialect; -import io.trino.sql.tree.AnchorPattern; -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.EmptyPattern; -import io.trino.sql.tree.ExcludedPattern; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.OneOrMoreQuantifier; -import io.trino.sql.tree.PatternAlternation; -import io.trino.sql.tree.PatternConcatenation; -import io.trino.sql.tree.PatternPermutation; -import io.trino.sql.tree.PatternVariable; -import io.trino.sql.tree.QuantifiedPattern; -import io.trino.sql.tree.RangeQuantifier; -import io.trino.sql.tree.RowPattern; -import io.trino.sql.tree.ZeroOrMoreQuantifier; -import io.trino.sql.tree.ZeroOrOneQuantifier; - -import static io.trino.sql.ExpressionFormatter.formatExpression; -import static java.lang.String.format; -import static java.util.stream.Collectors.joining; - -public final class RowPatternFormatter -{ - private RowPatternFormatter() {} - - public static String formatPattern(RowPattern pattern, Dialect dialect) - { - return new Formatter(dialect).process(pattern, null); - } - - public static class Formatter - extends AstVisitor - { - private final Dialect dialect; - - public Formatter(Dialect dialect) - { - this.dialect = dialect; - } - - @Override - protected String visitNode(Node node, Void context) - { - throw new UnsupportedOperationException(); - } - - @Override - protected String visitRowPattern(RowPattern node, Void context) - { - throw new UnsupportedOperationException(format("not yet implemented: %s.visit%s", getClass().getName(), node.getClass().getSimpleName())); - } - - @Override - protected String visitPatternAlternation(PatternAlternation node, Void context) - { - return node.getPatterns().stream() - .map(child -> process(child, context)) - .collect(joining(" | ", "(", ")")); - } - - @Override - protected String visitPatternConcatenation(PatternConcatenation node, Void context) - { - return node.getPatterns().stream() - .map(child -> process(child, context)) - .collect(joining(" ", "(", ")")); - } - - @Override - protected String visitQuantifiedPattern(QuantifiedPattern node, Void context) - { - return "(" + process(node.getPattern(), context) + process(node.getPatternQuantifier(), context) + ")"; - } - - @Override - protected String visitPatternVariable(PatternVariable node, Void context) - { - return formatExpression(node.getName(), dialect); - } - - @Override - protected String visitEmptyPattern(EmptyPattern node, Void context) - { - return "()"; - } - - @Override - protected String visitPatternPermutation(PatternPermutation node, Void context) - { - return node.getPatterns().stream() - .map(child -> process(child, context)) - .collect(joining(", ", "PERMUTE(", ")")); - } - - @Override - protected String visitAnchorPattern(AnchorPattern node, Void context) - { - switch (node.getType()) { - case PARTITION_START: - return "^"; - case PARTITION_END: - return "$"; - default: - throw new IllegalStateException("unexpected anchor pattern type: " + node.getType()); - } - } - - @Override - protected String visitExcludedPattern(ExcludedPattern node, Void context) - { - return "{-" + process(node.getPattern(), context) + "-}"; - } - - @Override - protected String visitZeroOrMoreQuantifier(ZeroOrMoreQuantifier node, Void context) - { - String greedy = node.isGreedy() ? "" : "?"; - return "*" + greedy; - } - - @Override - protected String visitOneOrMoreQuantifier(OneOrMoreQuantifier node, Void context) - { - String greedy = node.isGreedy() ? "" : "?"; - return "+" + greedy; - } - - @Override - protected String visitZeroOrOneQuantifier(ZeroOrOneQuantifier node, Void context) - { - String greedy = node.isGreedy() ? "" : "?"; - return "?" + greedy; - } - - @Override - protected String visitRangeQuantifier(RangeQuantifier node, Void context) - { - String greedy = node.isGreedy() ? "" : "?"; - String atLeast = node.getAtLeast().map(expression -> formatExpression(expression, dialect)).orElse(""); - String atMost = node.getAtMost().map(expression -> formatExpression(expression, dialect)).orElse(""); - return "{" + atLeast + "," + atMost + "}" + greedy; - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/SqlFormatter.java b/trino-parser/src/main/java/io/trino/sql/SqlFormatter.java deleted file mode 100644 index eb0845113..000000000 --- a/trino-parser/src/main/java/io/trino/sql/SqlFormatter.java +++ /dev/null @@ -1,1999 +0,0 @@ -/* - * Licensed 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 io.trino.sql; - -import com.google.common.base.Joiner; -import com.google.common.base.Strings; -import io.trino.sql.tree.AddColumn; -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.Analyze; -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.Call; -import io.trino.sql.tree.CallArgument; -import io.trino.sql.tree.ColumnDefinition; -import io.trino.sql.tree.Comment; -import io.trino.sql.tree.Commit; -import io.trino.sql.tree.CreateMaterializedView; -import io.trino.sql.tree.CreateRole; -import io.trino.sql.tree.CreateSchema; -import io.trino.sql.tree.CreateTable; -import io.trino.sql.tree.CreateTableAsSelect; -import io.trino.sql.tree.CreateView; -import io.trino.sql.tree.Deallocate; -import io.trino.sql.tree.Declare; -import io.trino.sql.tree.Delete; -import io.trino.sql.tree.Deny; -import io.trino.sql.tree.DescribeInput; -import io.trino.sql.tree.DescribeOutput; -import io.trino.sql.tree.DropColumn; -import io.trino.sql.tree.DropMaterializedView; -import io.trino.sql.tree.DropRole; -import io.trino.sql.tree.DropSchema; -import io.trino.sql.tree.DropTable; -import io.trino.sql.tree.DropView; -import io.trino.sql.tree.Except; -import io.trino.sql.tree.Execute; -import io.trino.sql.tree.Explain; -import io.trino.sql.tree.ExplainAnalyze; -import io.trino.sql.tree.ExplainFormat; -import io.trino.sql.tree.ExplainOption; -import io.trino.sql.tree.ExplainType; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FetchCursor; -import io.trino.sql.tree.FetchFirst; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.FunctionRelation; -import io.trino.sql.tree.Grant; -import io.trino.sql.tree.GrantRoles; -import io.trino.sql.tree.GrantorSpecification; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.ImpersonateUser; -import io.trino.sql.tree.Insert; -import io.trino.sql.tree.Intersect; -import io.trino.sql.tree.Isolation; -import io.trino.sql.tree.Join; -import io.trino.sql.tree.JoinCriteria; -import io.trino.sql.tree.JoinOn; -import io.trino.sql.tree.JoinUsing; -import io.trino.sql.tree.Lateral; -import io.trino.sql.tree.LikeClause; -import io.trino.sql.tree.Limit; -import io.trino.sql.tree.Merge; -import io.trino.sql.tree.MergeCase; -import io.trino.sql.tree.MergeDelete; -import io.trino.sql.tree.MergeInsert; -import io.trino.sql.tree.MergeUpdate; -import io.trino.sql.tree.NaturalJoin; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.Offset; -import io.trino.sql.tree.OrderBy; -import io.trino.sql.tree.PathRelation; -import io.trino.sql.tree.PatternRecognitionRelation; -import io.trino.sql.tree.Prepare; -import io.trino.sql.tree.PrincipalSpecification; -import io.trino.sql.tree.Property; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.QueryPeriod; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.RefreshMaterializedView; -import io.trino.sql.tree.Relation; -import io.trino.sql.tree.RenameColumn; -import io.trino.sql.tree.RenameMaterializedView; -import io.trino.sql.tree.RenameSchema; -import io.trino.sql.tree.RenameTable; -import io.trino.sql.tree.RenameView; -import io.trino.sql.tree.ResetSession; -import io.trino.sql.tree.Revoke; -import io.trino.sql.tree.RevokeRoles; -import io.trino.sql.tree.Rollback; -import io.trino.sql.tree.Row; -import io.trino.sql.tree.RowPattern; -import io.trino.sql.tree.SampledRelation; -import io.trino.sql.tree.Select; -import io.trino.sql.tree.SelectItem; -import io.trino.sql.tree.SetPath; -import io.trino.sql.tree.SetProperties; -import io.trino.sql.tree.SetRole; -import io.trino.sql.tree.SetSchemaAuthorization; -import io.trino.sql.tree.SetSession; -import io.trino.sql.tree.SetTableAuthorization; -import io.trino.sql.tree.SetTimeZone; -import io.trino.sql.tree.SetViewAuthorization; -import io.trino.sql.tree.ShowCatalogs; -import io.trino.sql.tree.ShowColumns; -import io.trino.sql.tree.ShowCreate; -import io.trino.sql.tree.ShowFunctions; -import io.trino.sql.tree.ShowGrants; -import io.trino.sql.tree.ShowRoleGrants; -import io.trino.sql.tree.ShowRoles; -import io.trino.sql.tree.ShowSchemas; -import io.trino.sql.tree.ShowSession; -import io.trino.sql.tree.ShowStats; -import io.trino.sql.tree.ShowTables; -import io.trino.sql.tree.SingleColumn; -import io.trino.sql.tree.StartTransaction; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableExecute; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.TransactionAccessMode; -import io.trino.sql.tree.TransactionMode; -import io.trino.sql.tree.TruncateTable; -import io.trino.sql.tree.Union; -import io.trino.sql.tree.Unnest; -import io.trino.sql.tree.Update; -import io.trino.sql.tree.UpdateAssignment; -import io.trino.sql.tree.Values; -import io.trino.sql.tree.WithQuery; - -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.Iterables.getOnlyElement; -import static com.google.common.collect.Iterables.transform; -import static io.trino.sql.ExpressionFormatter.formatExpression; -import static io.trino.sql.ExpressionFormatter.formatGroupBy; -import static io.trino.sql.ExpressionFormatter.formatOrderBy; -import static io.trino.sql.ExpressionFormatter.formatSkipTo; -import static io.trino.sql.ExpressionFormatter.formatStringLiteral; -import static io.trino.sql.ExpressionFormatter.formatWindowSpecification; -import static io.trino.sql.RowPatternFormatter.formatPattern; -import static io.trino.sql.SqlFormatter.Dialect.BIGQUERY; -import static io.trino.sql.SqlFormatter.Dialect.DEFAULT; -import static io.trino.sql.SqlFormatter.Dialect.POSTGRES; -import static java.lang.String.format; -import static java.util.stream.Collectors.joining; - -public final class SqlFormatter -{ - private static final String INDENT = " "; - - public enum Dialect - { - DEFAULT, - BIGQUERY, - DUCKDB, - POSTGRES - } - - private SqlFormatter() {} - - public static String formatSql(Node root) - { - return formatSql(root, DEFAULT); - } - - public static String formatSql(Node root, Dialect dialect) - { - StringBuilder builder = new StringBuilder(); - new Formatter(builder, dialect).process(root, 0); - return builder.toString(); - } - - static String formatName(QualifiedName name, Dialect dialect) - { - return name.getOriginalParts().stream() - .map(expression -> formatExpression(expression, dialect)) - .collect(joining(".")); - } - - private static class Formatter - extends AstVisitor - { - private final StringBuilder builder; - private final Dialect dialect; - - public Formatter(StringBuilder builder, Dialect dialect) - { - this.builder = builder; - this.dialect = dialect; - } - - @Override - protected Void visitNode(Node node, Integer indent) - { - throw new UnsupportedOperationException("not yet implemented: " + node); - } - - @Override - protected Void visitExpression(Expression node, Integer indent) - { - checkArgument(indent == 0, "visitExpression should only be called at root"); - builder.append(formatExpression(node, dialect)); - return null; - } - - @Override - protected Void visitRowPattern(RowPattern node, Integer indent) - { - checkArgument(indent == 0, "visitRowPattern should only be called at root"); - builder.append(formatPattern(node, dialect)); - return null; - } - - @Override - protected Void visitFunctionRelation(FunctionRelation node, Integer indent) - { - builder.append(formatName(node.getName(), dialect)) - .append("(") - .append(node.getArguments().stream() - .map(expression -> formatExpression(expression, dialect)) - .collect(joining(", "))) - .append(")"); - return null; - } - - @Override - protected Void visitPathRelation(PathRelation node, Integer context) - { - builder.append(node.getPath()); - return null; - } - - @Override - protected Void visitUnnest(Unnest node, Integer indent) - { - // Postgres doesn't have `generate_array` function and `generate_series` is a table function. - // Use `generate_series` to instead `UNNEST(generate_array(...))` for Postgres. - if (dialect == POSTGRES && - node.getExpressions().size() == 1 && - node.getExpressions().get(0) instanceof FunctionCall && - ((FunctionCall) node.getExpressions().get(0)).getName().equals(QualifiedName.of("generate_array"))) { - builder.append("generate_series(") - .append(((FunctionCall) node.getExpressions().get(0)).getArguments().stream() - .map(expression -> formatExpression(expression, dialect)) - .collect(joining(", "))) - .append(")"); - return null; - } - - builder.append("UNNEST(") - .append(node.getExpressions().stream() - .map(expression -> formatExpression(expression, dialect)) - .collect(joining(", "))) - .append(")"); - if (node.isWithOrdinality()) { - builder.append(" WITH ORDINALITY"); - } - return null; - } - - @Override - protected Void visitLateral(Lateral node, Integer indent) - { - append(indent, "LATERAL ("); - process(node.getQuery(), indent + 1); - append(indent, ")"); - return null; - } - - @Override - protected Void visitPrepare(Prepare node, Integer indent) - { - append(indent, "PREPARE "); - builder.append(node.getName()); - builder.append(" FROM"); - builder.append("\n"); - process(node.getStatement(), indent + 1); - return null; - } - - @Override - protected Void visitDeallocate(Deallocate node, Integer indent) - { - append(indent, "DEALLOCATE PREPARE "); - builder.append(node.getName()); - return null; - } - - // pg syntax - @Override - protected Void visitDeclareCursor(Declare node, Integer ident) - { - append(ident, "DECLARE "); - builder.append(node.getName()); - builder.append(" CURSOR FOR "); - process(node.getBody(), ident + 1); - return null; - } - - // pg syntax - @Override - protected Void visitFetchCursor(FetchCursor node, Integer ident) - { - append(ident, "FETCH ") - .append(node.getRowCount()) - .append(" FROM ") - .append(node.getCursor()); - return null; - } - - @Override - protected Void visitImpersonateUser(ImpersonateUser node, Integer ident) - { - append(ident, "IMPERSONATE ") - .append(node.getExpression()); - return null; - } - - @Override - protected Void visitExecute(Execute node, Integer indent) - { - append(indent, "EXECUTE "); - builder.append(node.getName()); - List parameters = node.getParameters(); - if (!parameters.isEmpty()) { - builder.append(" USING "); - Joiner.on(", ").appendTo(builder, parameters); - } - return null; - } - - @Override - protected Void visitDescribeOutput(DescribeOutput node, Integer indent) - { - append(indent, "DESCRIBE OUTPUT "); - builder.append(node.getName()); - return null; - } - - @Override - protected Void visitDescribeInput(DescribeInput node, Integer indent) - { - append(indent, "DESCRIBE INPUT "); - builder.append(node.getName()); - return null; - } - - @Override - protected Void visitQuery(Query node, Integer indent) - { - node.getWith().ifPresent(with -> { - append(indent, "WITH"); - if (with.isRecursive()) { - builder.append(" RECURSIVE"); - } - builder.append("\n "); - Iterator queries = with.getQueries().iterator(); - while (queries.hasNext()) { - WithQuery query = queries.next(); - append(indent, formatExpression(query.getName(), dialect)); - query.getColumnNames().ifPresent(columnNames -> appendAliasColumns(builder, columnNames, dialect)); - builder.append(" AS "); - process(new TableSubquery(query.getQuery()), indent); - builder.append('\n'); - if (queries.hasNext()) { - builder.append(", "); - } - } - }); - - processRelation(node.getQueryBody(), indent); - node.getOrderBy().ifPresent(orderBy -> process(orderBy, indent)); - if (dialect.equals(BIGQUERY)) { - node.getLimit().ifPresent(limit -> process(limit, indent)); - node.getOffset().ifPresent(offset -> process(offset, indent)); - } - else { - node.getOffset().ifPresent(offset -> process(offset, indent)); - node.getLimit().ifPresent(limit -> process(limit, indent)); - } - return null; - } - - @Override - protected Void visitQuerySpecification(QuerySpecification node, Integer indent) - { - process(node.getSelect(), indent); - - node.getFrom().ifPresent(from -> { - append(indent, "FROM"); - builder.append('\n'); - append(indent, " "); - process(from, indent); - }); - - builder.append('\n'); - - node.getWhere().ifPresent(where -> - append(indent, "WHERE " + formatExpression(where, dialect)).append('\n')); - - node.getGroupBy().ifPresent(groupBy -> - append(indent, "GROUP BY " + (groupBy.isDistinct() ? " DISTINCT " : "") + formatGroupBy(groupBy.getGroupingElements(), dialect)).append('\n')); - - node.getHaving().ifPresent(having -> append(indent, "HAVING " + formatExpression(having, dialect)) - .append('\n')); - - if (!node.getWindows().isEmpty()) { - append(indent, "WINDOW"); - formatDefinitionList(node.getWindows().stream() - .map(definition -> formatExpression(definition.getName(), dialect) + " AS " + formatWindowSpecification(definition.getWindow(), dialect)) - .collect(toImmutableList()), indent + 1); - } - - node.getOrderBy().ifPresent(orderBy -> process(orderBy, indent)); - if (dialect.equals(BIGQUERY)) { - node.getLimit().ifPresent(limit -> process(limit, indent)); - node.getOffset().ifPresent(offset -> process(offset, indent)); - } - else { - node.getOffset().ifPresent(offset -> process(offset, indent)); - node.getLimit().ifPresent(limit -> process(limit, indent)); - } - return null; - } - - @Override - protected Void visitOrderBy(OrderBy node, Integer indent) - { - append(indent, formatOrderBy(node, dialect)) - .append('\n'); - return null; - } - - @Override - protected Void visitOffset(Offset node, Integer indent) - { - append(indent, "OFFSET ") - .append(formatExpression(node.getRowCount(), dialect)) - .append("\n"); - if (!dialect.equals(BIGQUERY)) { - append(indent, "ROWS\n"); - } - return null; - } - - @Override - protected Void visitFetchFirst(FetchFirst node, Integer indent) - { - append(indent, "FETCH FIRST " + node.getRowCount().map(count -> formatExpression(count, dialect) + " ROWS ").orElse("ROW ")) - .append(node.isWithTies() ? "WITH TIES" : "ONLY") - .append('\n'); - return null; - } - - @Override - protected Void visitLimit(Limit node, Integer indent) - { - append(indent, "LIMIT ") - .append(formatExpression(node.getRowCount(), dialect)) - .append('\n'); - return null; - } - - @Override - protected Void visitSelect(Select node, Integer indent) - { - append(indent, "SELECT"); - if (node.isDistinct()) { - builder.append(" DISTINCT"); - } - - if (node.getSelectItems().size() > 1) { - boolean first = true; - for (SelectItem item : node.getSelectItems()) { - builder.append("\n") - .append(indentString(indent)) - .append(first ? " " : ", "); - - process(item, indent); - first = false; - } - } - else { - builder.append(' '); - process(getOnlyElement(node.getSelectItems()), indent); - } - - builder.append('\n'); - - return null; - } - - @Override - protected Void visitSingleColumn(SingleColumn node, Integer indent) - { - builder.append(formatExpression(node.getExpression(), dialect)); - node.getAlias().ifPresent(alias -> builder - .append(' ') - .append(formatExpression(alias, dialect))); - - return null; - } - - @Override - protected Void visitAllColumns(AllColumns node, Integer indent) - { - node.getTarget().ifPresent(value -> builder - .append(formatExpression(value, dialect)) - .append(".")); - builder.append("*"); - - if (!node.getAliases().isEmpty()) { - builder.append(" AS (") - .append(Joiner.on(", ").join(node.getAliases().stream() - .map(expression -> formatExpression(expression, dialect)) - .collect(toImmutableList()))) - .append(")"); - } - - return null; - } - - @Override - protected Void visitTable(Table node, Integer indent) - { - builder.append(formatName(node.getName(), dialect)); - node.getQueryPeriod().ifPresent(queryPeriod -> builder - .append(" " + queryPeriod)); - return null; - } - - @Override - protected Void visitQueryPeriod(QueryPeriod node, Integer indent) - { - builder.append("FOR " + node.getRangeType().name() + " AS OF " + formatExpression(node.getEnd().get(), dialect)); - return null; - } - - @Override - protected Void visitJoin(Join node, Integer indent) - { - JoinCriteria criteria = node.getCriteria().orElse(null); - String type = node.getType().toString(); - if (criteria instanceof NaturalJoin) { - type = "NATURAL " + type; - } - - process(node.getLeft(), indent); - - builder.append('\n'); - if (node.getType() == Join.Type.IMPLICIT) { - append(indent, ", "); - } - else { - append(indent, type).append(" JOIN "); - } - - process(node.getRight(), indent); - - if (node.getType() != Join.Type.CROSS && node.getType() != Join.Type.IMPLICIT) { - if (criteria instanceof JoinUsing) { - JoinUsing using = (JoinUsing) criteria; - builder.append(" USING (") - .append(Joiner.on(", ").join(using.getColumns())) - .append(")"); - } - else if (criteria instanceof JoinOn) { - JoinOn on = (JoinOn) criteria; - builder.append(" ON ") - .append(formatExpression(on.getExpression(), dialect)); - } - else if (!(criteria instanceof NaturalJoin)) { - throw new UnsupportedOperationException("unknown join criteria: " + criteria); - } - } - - return null; - } - - @Override - protected Void visitAliasedRelation(AliasedRelation node, Integer indent) - { - processRelationSuffix(node.getRelation(), indent); - - builder.append(' ') - .append(formatExpression(node.getAlias(), dialect)); - appendAliasColumns(builder, node.getColumnNames(), dialect); - - return null; - } - - @Override - protected Void visitPatternRecognitionRelation(PatternRecognitionRelation node, Integer indent) - { - processRelationSuffix(node.getInput(), indent); - - builder.append(" MATCH_RECOGNIZE (\n"); - if (!node.getPartitionBy().isEmpty()) { - append(indent + 1, "PARTITION BY ") - .append(node.getPartitionBy().stream() - .map(expression -> formatExpression(expression, dialect)) - .collect(joining(", "))) - .append("\n"); - } - node.getOrderBy().ifPresent(orderBy -> process(orderBy, indent + 1)); - - if (!node.getMeasures().isEmpty()) { - append(indent + 1, "MEASURES"); - formatDefinitionList(node.getMeasures().stream() - .map(measure -> formatExpression(measure.getExpression(), dialect) + " AS " + formatExpression(measure.getName(), dialect)) - .collect(toImmutableList()), indent + 2); - } - - node.getRowsPerMatch().ifPresent(rowsPerMatch -> { - String rowsPerMatchDescription; - switch (rowsPerMatch) { - case ONE: - rowsPerMatchDescription = "ONE ROW PER MATCH"; - break; - case ALL_SHOW_EMPTY: - rowsPerMatchDescription = "ALL ROWS PER MATCH SHOW EMPTY MATCHES"; - break; - case ALL_OMIT_EMPTY: - rowsPerMatchDescription = "ALL ROWS PER MATCH OMIT EMPTY MATCHES"; - break; - case ALL_WITH_UNMATCHED: - rowsPerMatchDescription = "ALL ROWS PER MATCH WITH UNMATCHED ROWS"; - break; - default: - // RowsPerMatch of type WINDOW cannot occur in MATCH_RECOGNIZE clause - throw new IllegalStateException("unexpected rowsPerMatch: " + node.getRowsPerMatch().get()); - } - append(indent + 1, rowsPerMatchDescription) - .append("\n"); - }); - - node.getAfterMatchSkipTo().ifPresent(afterMatchSkipTo -> { - String skipTo = formatSkipTo(afterMatchSkipTo, dialect); - append(indent + 1, skipTo) - .append("\n"); - }); - - node.getPatternSearchMode().ifPresent(patternSearchMode -> - append(indent + 1, patternSearchMode.getMode().name()) - .append("\n")); - - append(indent + 1, "PATTERN (") - .append(formatPattern(node.getPattern(), dialect)) - .append(")\n"); - if (!node.getSubsets().isEmpty()) { - append(indent + 1, "SUBSET"); - formatDefinitionList(node.getSubsets().stream() - .map(subset -> formatExpression(subset.getName(), dialect) + " = " + subset.getIdentifiers().stream() - .map(expression -> formatExpression(expression, dialect)).collect(joining(", ", "(", ")"))) - .collect(toImmutableList()), indent + 2); - } - append(indent + 1, "DEFINE"); - formatDefinitionList(node.getVariableDefinitions().stream() - .map(variable -> formatExpression(variable.getName(), dialect) + " AS " + formatExpression(variable.getExpression(), dialect)) - .collect(toImmutableList()), indent + 2); - - builder.append(")"); - - return null; - } - - @Override - protected Void visitSampledRelation(SampledRelation node, Integer indent) - { - processRelationSuffix(node.getRelation(), indent); - - builder.append(" TABLESAMPLE ") - .append(node.getType()) - .append(" (") - .append(node.getSamplePercentage()) - .append(')'); - - return null; - } - - private void processRelationSuffix(Relation relation, Integer indent) - { - if ((relation instanceof AliasedRelation) || (relation instanceof SampledRelation) || (relation instanceof PatternRecognitionRelation) || (relation instanceof Join)) { - builder.append("( "); - process(relation, indent + 1); - append(indent, ")"); - } - else { - process(relation, indent); - } - } - - @Override - protected Void visitValues(Values node, Integer indent) - { - builder.append(" VALUES "); - - boolean first = true; - for (Expression row : node.getRows()) { - builder.append("\n") - .append(indentString(indent)) - .append(first ? " " : ", "); - if (row instanceof Row) { - builder.append(formatExpression(row, dialect)); - } - else { - builder.append("(") - .append(formatExpression(row, dialect)) - .append(")"); - } - first = false; - } - builder.append('\n'); - - return null; - } - - @Override - protected Void visitTableSubquery(TableSubquery node, Integer indent) - { - builder.append('(') - .append('\n'); - - process(node.getQuery(), indent + 1); - - append(indent, ") "); - - return null; - } - - @Override - protected Void visitUnion(Union node, Integer indent) - { - Iterator relations = node.getRelations().iterator(); - - while (relations.hasNext()) { - processRelation(relations.next(), indent); - - if (relations.hasNext()) { - builder.append("UNION "); - if (!node.isDistinct()) { - builder.append("ALL "); - } - } - } - - return null; - } - - @Override - protected Void visitExcept(Except node, Integer indent) - { - processRelation(node.getLeft(), indent); - - builder.append("EXCEPT "); - if (!node.isDistinct()) { - builder.append("ALL "); - } - - processRelation(node.getRight(), indent); - - return null; - } - - @Override - protected Void visitIntersect(Intersect node, Integer indent) - { - Iterator relations = node.getRelations().iterator(); - - while (relations.hasNext()) { - processRelation(relations.next(), indent); - - if (relations.hasNext()) { - builder.append("INTERSECT "); - if (!node.isDistinct()) { - builder.append("ALL "); - } - } - } - - return null; - } - - @Override - protected Void visitMerge(Merge node, Integer indent) - { - builder.append("MERGE INTO ") - .append(node.getTable().getName()); - - node.getTargetAlias().ifPresent(value -> builder - .append(' ') - .append(value)); - builder.append("\n"); - - append(indent + 1, "USING "); - - processRelation(node.getRelation(), indent + 2); - - builder.append("\n"); - append(indent + 1, "ON "); - builder.append(formatExpression(node.getExpression(), dialect)); - - for (MergeCase mergeCase : node.getMergeCases()) { - builder.append("\n"); - process(mergeCase, indent); - } - - return null; - } - - @Override - protected Void visitMergeInsert(MergeInsert node, Integer indent) - { - appendMergeCaseWhen(false, node.getExpression()); - append(indent + 1, "THEN INSERT "); - - if (!node.getColumns().isEmpty()) { - builder.append("("); - Joiner.on(", ").appendTo(builder, node.getColumns()); - builder.append(")"); - } - - builder.append("VALUES ("); - Joiner.on(", ").appendTo(builder, transform(node.getValues(), expression -> formatExpression(expression, dialect))); - builder.append(")"); - - return null; - } - - @Override - protected Void visitMergeUpdate(MergeUpdate node, Integer indent) - { - appendMergeCaseWhen(true, node.getExpression()); - append(indent + 1, "THEN UPDATE SET"); - - boolean first = true; - for (MergeUpdate.Assignment assignment : node.getAssignments()) { - builder.append("\n"); - append(indent + 1, first ? " " : ", "); - builder.append(assignment.getTarget()) - .append(" = ") - .append(formatExpression(assignment.getValue(), dialect)); - first = false; - } - - return null; - } - - @Override - protected Void visitMergeDelete(MergeDelete node, Integer indent) - { - appendMergeCaseWhen(true, node.getExpression()); - append(indent + 1, "THEN DELETE"); - return null; - } - - private void appendMergeCaseWhen(boolean matched, Optional expression) - { - builder.append(matched ? "WHEN MATCHED" : "WHEN NOT MATCHED"); - expression.ifPresent(value -> builder - .append(" AND ") - .append(formatExpression(value, dialect))); - builder.append("\n"); - } - - @Override - protected Void visitCreateView(CreateView node, Integer indent) - { - builder.append("CREATE "); - if (node.isReplace()) { - builder.append("OR REPLACE "); - } - builder.append("VIEW ") - .append(formatName(node.getName(), dialect)); - - node.getComment().ifPresent(comment -> builder - .append(" COMMENT ") - .append(formatStringLiteral(comment))); - - node.getSecurity().ifPresent(security -> builder - .append(" SECURITY ") - .append(security)); - - builder.append(" AS\n"); - - process(node.getQuery(), indent); - - return null; - } - - @Override - protected Void visitRenameView(RenameView node, Integer indent) - { - builder.append("ALTER VIEW ") - .append(node.getSource()) - .append(" RENAME TO ") - .append(node.getTarget()); - - return null; - } - - @Override - protected Void visitRenameMaterializedView(RenameMaterializedView node, Integer indent) - { - builder.append("ALTER MATERIALIZED VIEW "); - if (node.isExists()) { - builder.append("IF EXISTS "); - } - builder.append(node.getSource()) - .append(" RENAME TO ") - .append(node.getTarget()); - - return null; - } - - @Override - protected Void visitSetViewAuthorization(SetViewAuthorization node, Integer indent) - { - builder.append("ALTER VIEW ") - .append(formatName(node.getSource(), dialect)) - .append(" SET AUTHORIZATION ") - .append(formatPrincipal(node.getPrincipal())); - - return null; - } - - @Override - protected Void visitCreateMaterializedView(CreateMaterializedView node, Integer indent) - { - builder.append("CREATE "); - if (node.isReplace()) { - builder.append("OR REPLACE "); - } - builder.append("MATERIALIZED VIEW "); - - if (node.isNotExists()) { - builder.append("IF NOT EXISTS "); - } - - builder.append(formatName(node.getName(), dialect)); - node.getComment().ifPresent(comment -> builder - .append("\nCOMMENT ") - .append(formatStringLiteral(comment))); - builder.append(formatPropertiesMultiLine(node.getProperties())); - builder.append(" AS\n"); - - process(node.getQuery(), indent); - - return null; - } - - @Override - protected Void visitRefreshMaterializedView(RefreshMaterializedView node, Integer indent) - { - builder.append("REFRESH MATERIALIZED VIEW "); - builder.append(formatName(node.getName(), dialect)); - - return null; - } - - @Override - protected Void visitDropMaterializedView(DropMaterializedView node, Integer indent) - { - builder.append("DROP MATERIALIZED VIEW "); - if (node.isExists()) { - builder.append("IF EXISTS "); - } - builder.append(formatName(node.getName(), dialect)); - return null; - } - - @Override - protected Void visitDropView(DropView node, Integer indent) - { - builder.append("DROP VIEW "); - if (node.isExists()) { - builder.append("IF EXISTS "); - } - builder.append(node.getName()); - - return null; - } - - @Override - protected Void visitExplain(Explain node, Integer indent) - { - builder.append("EXPLAIN "); - - List options = new ArrayList<>(); - - for (ExplainOption option : node.getOptions()) { - if (option instanceof ExplainType) { - options.add("TYPE " + ((ExplainType) option).getType()); - } - else if (option instanceof ExplainFormat) { - options.add("FORMAT " + ((ExplainFormat) option).getType()); - } - else { - throw new UnsupportedOperationException("unhandled explain option: " + option); - } - } - - if (!options.isEmpty()) { - builder.append("("); - Joiner.on(", ").appendTo(builder, options); - builder.append(")"); - } - - builder.append("\n"); - - process(node.getStatement(), indent); - - return null; - } - - @Override - protected Void visitExplainAnalyze(ExplainAnalyze node, Integer indent) - { - builder.append("EXPLAIN ANALYZE"); - if (node.isVerbose()) { - builder.append(" VERBOSE"); - } - builder.append("\n"); - - process(node.getStatement(), indent); - - return null; - } - - @Override - protected Void visitShowCatalogs(ShowCatalogs node, Integer indent) - { - builder.append("SHOW CATALOGS"); - - node.getLikePattern().ifPresent(value -> builder - .append(" LIKE ") - .append(formatStringLiteral(value))); - - node.getEscape().ifPresent(value -> builder - .append(" ESCAPE ") - .append(formatStringLiteral(value))); - - return null; - } - - @Override - protected Void visitShowSchemas(ShowSchemas node, Integer indent) - { - builder.append("SHOW SCHEMAS"); - - node.getCatalog().ifPresent(catalog -> builder - .append(" FROM ") - .append(node.getCatalog().get())); - - node.getLikePattern().ifPresent(value -> builder - .append(" LIKE ") - .append(formatStringLiteral(value))); - - node.getEscape().ifPresent(value -> builder - .append(" ESCAPE ") - .append(formatStringLiteral(value))); - - return null; - } - - @Override - protected Void visitShowTables(ShowTables node, Integer indent) - { - builder.append("SHOW TABLES"); - - node.getSchema().ifPresent(value -> builder - .append(" FROM ") - .append(formatName(value, dialect))); - - node.getLikePattern().ifPresent(value -> builder - .append(" LIKE ") - .append(formatStringLiteral(value))); - - node.getEscape().ifPresent(value -> builder - .append(" ESCAPE ") - .append(formatStringLiteral(value))); - - return null; - } - - @Override - protected Void visitShowCreate(ShowCreate node, Integer indent) - { - if (node.getType() == ShowCreate.Type.TABLE) { - builder.append("SHOW CREATE TABLE ") - .append(formatName(node.getName(), dialect)); - } - else if (node.getType() == ShowCreate.Type.VIEW) { - builder.append("SHOW CREATE VIEW ") - .append(formatName(node.getName(), dialect)); - } - else if (node.getType() == ShowCreate.Type.MATERIALIZED_VIEW) { - builder.append("SHOW CREATE MATERIALIZED VIEW ") - .append(formatName(node.getName(), dialect)); - } - return null; - } - - @Override - protected Void visitShowColumns(ShowColumns node, Integer indent) - { - builder.append("SHOW COLUMNS FROM ") - .append(formatName(node.getTable(), dialect)); - - node.getLikePattern().ifPresent(value -> builder - .append(" LIKE ") - .append(formatStringLiteral(value))); - - node.getEscape().ifPresent(value -> builder - .append(" ESCAPE ") - .append(formatStringLiteral(value))); - - return null; - } - - @Override - protected Void visitShowStats(ShowStats node, Integer indent) - { - builder.append("SHOW STATS FOR "); - process(node.getRelation(), 0); - - return null; - } - - @Override - protected Void visitShowFunctions(ShowFunctions node, Integer indent) - { - builder.append("SHOW FUNCTIONS"); - - node.getLikePattern().ifPresent(value -> builder - .append(" LIKE ") - .append(formatStringLiteral(value))); - - node.getEscape().ifPresent(value -> builder - .append(" ESCAPE ") - .append(formatStringLiteral(value))); - - return null; - } - - @Override - protected Void visitShowSession(ShowSession node, Integer indent) - { - builder.append("SHOW SESSION"); - - node.getLikePattern().ifPresent(value -> builder - .append(" LIKE ") - .append(formatStringLiteral(value))); - - node.getEscape().ifPresent(value -> builder - .append(" ESCAPE ") - .append(formatStringLiteral(value))); - - return null; - } - - @Override - protected Void visitDelete(Delete node, Integer indent) - { - builder.append("DELETE FROM ") - .append(formatName(node.getTable().getName(), dialect)); - - node.getWhere().ifPresent(where -> builder - .append(" WHERE ") - .append(formatExpression(where, dialect))); - - return null; - } - - @Override - protected Void visitCreateSchema(CreateSchema node, Integer indent) - { - builder.append("CREATE SCHEMA "); - if (node.isNotExists()) { - builder.append("IF NOT EXISTS "); - } - builder.append(formatName(node.getSchemaName(), dialect)); - node.getPrincipal().ifPresent(principal -> builder - .append("\nAUTHORIZATION ") - .append(formatPrincipal(principal))); - builder.append(formatPropertiesMultiLine(node.getProperties())); - - return null; - } - - @Override - protected Void visitDropSchema(DropSchema node, Integer indent) - { - builder.append("DROP SCHEMA "); - if (node.isExists()) { - builder.append("IF EXISTS "); - } - builder.append(formatName(node.getSchemaName(), dialect)) - .append(" ") - .append(node.isCascade() ? "CASCADE" : "RESTRICT"); - - return null; - } - - @Override - protected Void visitRenameSchema(RenameSchema node, Integer indent) - { - builder.append("ALTER SCHEMA ") - .append(formatName(node.getSource(), dialect)) - .append(" RENAME TO ") - .append(formatExpression(node.getTarget(), dialect)); - - return null; - } - - @Override - protected Void visitSetSchemaAuthorization(SetSchemaAuthorization node, Integer indent) - { - builder.append("ALTER SCHEMA ") - .append(formatName(node.getSource(), dialect)) - .append(" SET AUTHORIZATION ") - .append(formatPrincipal(node.getPrincipal())); - - return null; - } - - @Override - protected Void visitCreateTableAsSelect(CreateTableAsSelect node, Integer indent) - { - builder.append("CREATE TABLE "); - if (node.isNotExists()) { - builder.append("IF NOT EXISTS "); - } - builder.append(formatName(node.getName(), dialect)); - - node.getColumnAliases().ifPresent(columnAliases -> { - String columnList = columnAliases.stream() - .map(alias -> formatExpression(alias, dialect)) - .collect(joining(", ")); - builder.append(format("( %s )", columnList)); - }); - - node.getComment().ifPresent(comment -> builder - .append("\nCOMMENT ") - .append(formatStringLiteral(comment))); - builder.append(formatPropertiesMultiLine(node.getProperties())); - - builder.append(" AS "); - process(node.getQuery(), indent); - - if (!node.isWithData()) { - builder.append(" WITH NO DATA"); - } - - return null; - } - - @Override - protected Void visitCreateTable(CreateTable node, Integer indent) - { - builder.append("CREATE TABLE "); - if (node.isNotExists()) { - builder.append("IF NOT EXISTS "); - } - String tableName = formatName(node.getName(), dialect); - builder.append(tableName).append(" (\n"); - - String elementIndent = indentString(indent + 1); - String columnList = node.getElements().stream() - .map(element -> { - if (element instanceof ColumnDefinition) { - ColumnDefinition column = (ColumnDefinition) element; - return elementIndent + formatColumnDefinition(column); - } - if (element instanceof LikeClause) { - LikeClause likeClause = (LikeClause) element; - StringBuilder builder = new StringBuilder(elementIndent); - builder.append("LIKE ") - .append(formatName(likeClause.getTableName(), dialect)); - - likeClause.getPropertiesOption().ifPresent(propertiesOption -> builder - .append(" ") - .append(propertiesOption.name()) - .append(" PROPERTIES")); - - return builder.toString(); - } - throw new UnsupportedOperationException("unknown table element: " + element); - }) - .collect(joining(",\n")); - builder.append(columnList); - builder.append("\n").append(")"); - - node.getComment().ifPresent(comment -> builder - .append("\nCOMMENT ") - .append(formatStringLiteral(comment))); - - builder.append(formatPropertiesMultiLine(node.getProperties())); - - return null; - } - - private String formatPropertiesMultiLine(List properties) - { - if (properties.isEmpty()) { - return ""; - } - - String propertyList = properties.stream() - .map(element -> INDENT + - formatExpression(element.getName(), dialect) + " = " + - (element.isSetToDefault() ? "DEFAULT" : formatExpression(element.getNonDefaultValue(), dialect))) - .collect(joining(",\n")); - - return "\nWITH (\n" + propertyList + "\n)"; - } - - private String formatPropertiesSingleLine(List properties) - { - if (properties.isEmpty()) { - return ""; - } - - return " WITH ( " + joinProperties(properties) + " )"; - } - - private String formatColumnDefinition(ColumnDefinition column) - { - StringBuilder builder = new StringBuilder() - .append(formatExpression(column.getName(), dialect)) - .append(" ").append(column.getType()); - if (!column.isNullable()) { - builder.append(" NOT NULL"); - } - column.getComment().ifPresent(comment -> builder - .append(" COMMENT ") - .append(formatStringLiteral(comment))); - builder.append(formatPropertiesSingleLine(column.getProperties())); - return builder.toString(); - } - - private static String formatGrantor(GrantorSpecification grantor) - { - GrantorSpecification.Type type = grantor.getType(); - switch (type) { - case CURRENT_ROLE: - case CURRENT_USER: - return type.name(); - case PRINCIPAL: - return formatPrincipal(grantor.getPrincipal().get()); - } - throw new IllegalArgumentException("Unsupported principal type: " + type); - } - - private static String formatPrincipal(PrincipalSpecification principal) - { - PrincipalSpecification.Type type = principal.getType(); - switch (type) { - case UNSPECIFIED: - return principal.getName().toString(); - case USER: - case ROLE: - return format("%s %s", type.name(), principal.getName()); - } - throw new IllegalArgumentException("Unsupported principal type: " + type); - } - - @Override - protected Void visitDropTable(DropTable node, Integer indent) - { - builder.append("DROP TABLE "); - if (node.isExists()) { - builder.append("IF EXISTS "); - } - builder.append(formatName(node.getTableName(), dialect)); - - return null; - } - - @Override - protected Void visitRenameTable(RenameTable node, Integer indent) - { - builder.append("ALTER TABLE "); - if (node.isExists()) { - builder.append("IF EXISTS "); - } - builder.append(node.getSource()) - .append(" RENAME TO ") - .append(node.getTarget()); - - return null; - } - - @Override - protected Void visitSetProperties(SetProperties node, Integer context) - { - SetProperties.Type type = node.getType(); - builder.append("ALTER "); - switch (type) { - case TABLE: - builder.append("TABLE "); - break; - case MATERIALIZED_VIEW: - builder.append("MATERIALIZED VIEW "); - break; - default: - throw new IllegalArgumentException("Unsupported SetProperties.Type: " + type); - } - builder.append(formatName(node.getName(), dialect)) - .append(" SET PROPERTIES ") - .append(joinProperties(node.getProperties())); - - return null; - } - - private String joinProperties(List properties) - { - return properties.stream() - .map(element -> formatExpression(element.getName(), dialect) + " = " + - (element.isSetToDefault() ? "DEFAULT" : formatExpression(element.getNonDefaultValue(), dialect))) - .collect(joining(", ")); - } - - @Override - protected Void visitComment(Comment node, Integer context) - { - String comment = node.getComment() - .map(ExpressionFormatter::formatStringLiteral) - .orElse("NULL"); - - switch (node.getType()) { - case TABLE: - builder.append("COMMENT ON TABLE ") - .append(node.getName()) - .append(" IS ") - .append(comment); - break; - case COLUMN: - builder.append("COMMENT ON COLUMN ") - .append(node.getName()) - .append(" IS ") - .append(comment); - break; - } - - return null; - } - - @Override - protected Void visitRenameColumn(RenameColumn node, Integer indent) - { - builder.append("ALTER TABLE "); - if (node.isTableExists()) { - builder.append("IF EXISTS "); - } - builder.append(node.getTable()) - .append(" RENAME COLUMN "); - if (node.isColumnExists()) { - builder.append("IF EXISTS "); - } - builder.append(node.getSource()) - .append(" TO ") - .append(node.getTarget()); - - return null; - } - - @Override - protected Void visitDropColumn(DropColumn node, Integer indent) - { - builder.append("ALTER TABLE "); - if (node.isTableExists()) { - builder.append("IF EXISTS "); - } - builder.append(formatName(node.getTable(), dialect)) - .append(" DROP COLUMN "); - if (node.isColumnExists()) { - builder.append("IF EXISTS "); - } - builder.append(formatExpression(node.getColumn(), dialect)); - - return null; - } - - @Override - protected Void visitTableExecute(TableExecute node, Integer indent) - { - builder.append("ALTER TABLE "); - builder.append(formatName(node.getTable().getName(), dialect)); - builder.append(" EXECUTE "); - builder.append(formatExpression(node.getProcedureName(), dialect)); - if (!node.getArguments().isEmpty()) { - builder.append("("); - formatCallArguments(indent, node.getArguments()); - builder.append(")"); - } - node.getWhere().ifPresent(where -> builder - .append("\n") - .append(indentString(indent)) - .append("WHERE ") - .append(formatExpression(where, dialect))); - return null; - } - - @Override - protected Void visitAnalyze(Analyze node, Integer indent) - { - builder.append("ANALYZE ") - .append(formatName(node.getTableName(), dialect)); - builder.append(formatPropertiesMultiLine(node.getProperties())); - return null; - } - - @Override - protected Void visitAddColumn(AddColumn node, Integer indent) - { - builder.append("ALTER TABLE "); - if (node.isTableExists()) { - builder.append("IF EXISTS "); - } - builder.append(node.getName()) - .append(" ADD COLUMN "); - if (node.isColumnNotExists()) { - builder.append("IF NOT EXISTS "); - } - builder.append(formatColumnDefinition(node.getColumn())); - - return null; - } - - @Override - protected Void visitSetTableAuthorization(SetTableAuthorization node, Integer indent) - { - builder.append("ALTER TABLE ") - .append(formatName(node.getSource(), dialect)) - .append(" SET AUTHORIZATION ") - .append(formatPrincipal(node.getPrincipal())); - - return null; - } - - @Override - protected Void visitInsert(Insert node, Integer indent) - { - builder.append("INSERT INTO ") - .append(formatName(node.getTarget(), dialect)); - - node.getColumns().ifPresent(columns -> builder - .append(" (") - .append(Joiner.on(", ").join(columns)) - .append(")")); - - builder.append("\n"); - - process(node.getQuery(), indent); - - return null; - } - - @Override - protected Void visitUpdate(Update node, Integer indent) - { - builder.append("UPDATE ") - .append(node.getTable().getName()) - .append(" SET"); - int setCounter = node.getAssignments().size() - 1; - for (UpdateAssignment assignment : node.getAssignments()) { - builder.append("\n") - .append(indentString(indent + 1)) - .append(assignment.getName().getValue()) - .append(" = ") - .append(formatExpression(assignment.getValue(), dialect)); - if (setCounter > 0) { - builder.append(","); - } - setCounter--; - } - node.getWhere().ifPresent(where -> builder - .append("\n") - .append(indentString(indent)) - .append("WHERE ").append(formatExpression(where, dialect))); - return null; - } - - @Override - protected Void visitTruncateTable(TruncateTable node, Integer indent) - { - builder.append("TRUNCATE TABLE "); - builder.append(formatName(node.getTableName(), dialect)); - - return null; - } - - @Override - public Void visitSetSession(SetSession node, Integer indent) - { - builder.append("SET SESSION ") - .append(formatName(node.getName(), dialect)) - .append(" = ") - .append(formatExpression(node.getValue(), dialect)); - - return null; - } - - @Override - public Void visitResetSession(ResetSession node, Integer indent) - { - builder.append("RESET SESSION ") - .append(formatName(node.getName(), dialect)); - - return null; - } - - @Override - protected Void visitCallArgument(CallArgument node, Integer indent) - { - node.getName().ifPresent(name -> builder - .append(name) - .append(" => ")); - builder.append(formatExpression(node.getValue(), dialect)); - - return null; - } - - @Override - protected Void visitCall(Call node, Integer indent) - { - builder.append("CALL ") - .append(node.getName()) - .append("("); - formatCallArguments(indent, node.getArguments()); - builder.append(")"); - - return null; - } - - private void formatCallArguments(Integer indent, List arguments) - { - Iterator iterator = arguments.iterator(); - while (iterator.hasNext()) { - process(iterator.next(), indent); - if (iterator.hasNext()) { - builder.append(", "); - } - } - } - - @Override - protected Void visitRow(Row node, Integer indent) - { - builder.append("ROW("); - boolean firstItem = true; - for (Expression item : node.getItems()) { - if (!firstItem) { - builder.append(", "); - } - process(item, indent); - firstItem = false; - } - builder.append(")"); - return null; - } - - @Override - protected Void visitStartTransaction(StartTransaction node, Integer indent) - { - builder.append("START TRANSACTION"); - - Iterator iterator = node.getTransactionModes().iterator(); - while (iterator.hasNext()) { - builder.append(" "); - process(iterator.next(), indent); - if (iterator.hasNext()) { - builder.append(","); - } - } - return null; - } - - @Override - protected Void visitIsolationLevel(Isolation node, Integer indent) - { - builder.append("ISOLATION LEVEL ").append(node.getLevel().getText()); - return null; - } - - @Override - protected Void visitTransactionAccessMode(TransactionAccessMode node, Integer indent) - { - builder.append(node.isReadOnly() ? "READ ONLY" : "READ WRITE"); - return null; - } - - @Override - protected Void visitCommit(Commit node, Integer indent) - { - builder.append("COMMIT"); - return null; - } - - @Override - protected Void visitRollback(Rollback node, Integer indent) - { - builder.append("ROLLBACK"); - return null; - } - - @Override - protected Void visitCreateRole(CreateRole node, Integer indent) - { - builder.append("CREATE ROLE ").append(node.getName()); - node.getGrantor().ifPresent(grantor -> builder - .append(" WITH ADMIN ") - .append(formatGrantor(grantor))); - node.getCatalog().ifPresent(catalog -> builder - .append(" IN ") - .append(catalog)); - return null; - } - - @Override - protected Void visitDropRole(DropRole node, Integer indent) - { - builder.append("DROP ROLE ").append(node.getName()); - node.getCatalog().ifPresent(catalog -> builder - .append(" IN ") - .append(catalog)); - return null; - } - - @Override - protected Void visitGrantRoles(GrantRoles node, Integer indent) - { - builder.append("GRANT "); - builder.append(node.getRoles().stream() - .map(Identifier::toString) - .collect(joining(", "))); - builder.append(" TO "); - builder.append(node.getGrantees().stream() - .map(Formatter::formatPrincipal) - .collect(joining(", "))); - if (node.isAdminOption()) { - builder.append(" WITH ADMIN OPTION"); - } - node.getGrantor().ifPresent(grantor -> builder - .append(" GRANTED BY ") - .append(formatGrantor(grantor))); - node.getCatalog().ifPresent(catalog -> builder - .append(" IN ") - .append(catalog)); - return null; - } - - @Override - protected Void visitRevokeRoles(RevokeRoles node, Integer indent) - { - builder.append("REVOKE "); - if (node.isAdminOption()) { - builder.append("ADMIN OPTION FOR "); - } - builder.append(node.getRoles().stream() - .map(Identifier::toString) - .collect(joining(", "))); - builder.append(" FROM "); - builder.append(node.getGrantees().stream() - .map(Formatter::formatPrincipal) - .collect(joining(", "))); - node.getGrantor().ifPresent(grantor -> builder - .append(" GRANTED BY ") - .append(formatGrantor(grantor))); - node.getCatalog().ifPresent(catalog -> builder - .append(" IN ") - .append(catalog)); - return null; - } - - @Override - protected Void visitSetRole(SetRole node, Integer indent) - { - builder.append("SET ROLE "); - SetRole.Type type = node.getType(); - switch (type) { - case ALL: - case NONE: - builder.append(type); - break; - case ROLE: - builder.append(node.getRole().get()); - break; - default: - throw new IllegalArgumentException("Unsupported type: " + type); - } - node.getCatalog().ifPresent(catalog -> builder - .append(" IN ") - .append(catalog)); - return null; - } - - @Override - public Void visitGrant(Grant node, Integer indent) - { - builder.append("GRANT "); - - builder.append(node.getPrivileges() - .map(privileges -> String.join(", ", privileges)) - .orElse("ALL PRIVILEGES")); - - builder.append(" ON "); - node.getType().ifPresent(type -> builder - .append(type) - .append(' ')); - builder.append(formatName(node.getName(), dialect)) - .append(" TO ") - .append(formatPrincipal(node.getGrantee())); - if (node.isWithGrantOption()) { - builder.append(" WITH GRANT OPTION"); - } - - return null; - } - - @Override - public Void visitDeny(Deny node, Integer indent) - { - builder.append("DENY "); - - if (node.getPrivileges().isPresent()) { - builder.append(String.join(", ", node.getPrivileges().get())); - } - else { - builder.append("ALL PRIVILEGES"); - } - - builder.append(" ON "); - if (node.getType().isPresent()) { - builder.append(node.getType().get()); - builder.append(" "); - } - builder.append(formatName(node.getName(), dialect)) - .append(" TO ") - .append(formatPrincipal(node.getGrantee())); - - return null; - } - - @Override - public Void visitRevoke(Revoke node, Integer indent) - { - builder.append("REVOKE "); - - if (node.isGrantOptionFor()) { - builder.append("GRANT OPTION FOR "); - } - - builder.append(node.getPrivileges() - .map(privileges -> String.join(", ", privileges)) - .orElse("ALL PRIVILEGES")); - - builder.append(" ON "); - node.getType().ifPresent(type -> builder - .append(type) - .append(' ')); - builder.append(node.getName()) - .append(" FROM ") - .append(formatPrincipal(node.getGrantee())); - - return null; - } - - @Override - public Void visitShowGrants(ShowGrants node, Integer indent) - { - builder.append("SHOW GRANTS "); - - node.getTableName().ifPresent(tableName -> { - builder.append("ON "); - if (node.getTable()) { - builder.append("TABLE "); - } - builder.append(tableName); - }); - - return null; - } - - @Override - protected Void visitShowRoles(ShowRoles node, Integer indent) - { - builder.append("SHOW "); - if (node.isCurrent()) { - builder.append("CURRENT "); - } - builder.append("ROLES"); - node.getCatalog().ifPresent(catalog -> builder - .append(" FROM ") - .append(catalog)); - - return null; - } - - @Override - protected Void visitShowRoleGrants(ShowRoleGrants node, Integer indent) - { - builder.append("SHOW ROLE GRANTS"); - node.getCatalog().ifPresent(catalog -> builder - .append(" FROM ") - .append(catalog)); - return null; - } - - @Override - public Void visitSetPath(SetPath node, Integer indent) - { - builder.append("SET PATH "); - builder.append(Joiner.on(", ").join(node.getPathSpecification().getPath())); - return null; - } - - @Override - public Void visitSetTimeZone(SetTimeZone node, Integer indent) - { - builder.append("SET TIME ZONE "); - builder.append(node.getTimeZone().map(expression -> formatExpression(expression, dialect)).orElse("LOCAL")); - return null; - } - - private void processRelation(Relation relation, Integer indent) - { - // TODO: handle this properly - if (relation instanceof Table) { - builder.append("TABLE ") - .append(((Table) relation).getName()) - .append('\n'); - } - else { - process(relation, indent); - } - } - - private StringBuilder append(int indent, String value) - { - return builder.append(indentString(indent)) - .append(value); - } - - private static String indentString(int indent) - { - return Strings.repeat(INDENT, indent); - } - - private void formatDefinitionList(List elements, int indent) - { - if (elements.size() == 1) { - builder.append(" ") - .append(getOnlyElement(elements)) - .append("\n"); - } - else { - builder.append("\n"); - for (int i = 0; i < elements.size() - 1; i++) { - append(indent, elements.get(i)) - .append(",\n"); - } - append(indent, elements.get(elements.size() - 1)) - .append("\n"); - } - } - } - - private static void appendAliasColumns(StringBuilder builder, List columns, Dialect dialect) - { - if ((columns != null) && (!columns.isEmpty())) { - String formattedColumns = columns.stream() - .map(expression -> formatExpression(expression, dialect)) - .collect(Collectors.joining(", ")); - - builder.append(" (") - .append(formattedColumns) - .append(')'); - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/TreePrinter.java b/trino-parser/src/main/java/io/trino/sql/TreePrinter.java deleted file mode 100644 index 8e55abc80..000000000 --- a/trino-parser/src/main/java/io/trino/sql/TreePrinter.java +++ /dev/null @@ -1,462 +0,0 @@ -package io.trino.sql; - -import com.google.common.base.Joiner; -import com.google.common.base.Strings; -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.ArithmeticBinaryExpression; -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.BinaryLiteral; -import io.trino.sql.tree.BooleanLiteral; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.Cube; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.GroupingElement; -import io.trino.sql.tree.GroupingSets; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.InPredicate; -import io.trino.sql.tree.LikePredicate; -import io.trino.sql.tree.LogicalExpression; -import io.trino.sql.tree.LongLiteral; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.OrderBy; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.Rollup; -import io.trino.sql.tree.Row; -import io.trino.sql.tree.SampledRelation; -import io.trino.sql.tree.Select; -import io.trino.sql.tree.SimpleGroupBy; -import io.trino.sql.tree.SingleColumn; -import io.trino.sql.tree.SortItem; -import io.trino.sql.tree.StringLiteral; -import io.trino.sql.tree.SubqueryExpression; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.Values; -import io.trino.sql.tree.WindowDefinition; -import io.trino.sql.tree.WindowReference; -import io.trino.sql.tree.WindowSpecification; - -import java.io.PrintStream; -import java.util.IdentityHashMap; -import java.util.List; - -public class TreePrinter -{ - private static final String INDENT = " "; - - private final IdentityHashMap resolvedNameReferences; - private final PrintStream out; - - public TreePrinter(IdentityHashMap resolvedNameReferences, PrintStream out) - { - this.resolvedNameReferences = new IdentityHashMap<>(resolvedNameReferences); - this.out = out; - } - - public void print(Node root) - { - AstVisitor printer = new DefaultTraversalVisitor() - { - @Override - protected Void visitNode(Node node, Integer indentLevel) - { - throw new UnsupportedOperationException("not yet implemented: " + node); - } - - @Override - protected Void visitQuery(Query node, Integer indentLevel) - { - print(indentLevel, "Query "); - - indentLevel++; - - print(indentLevel, "QueryBody"); - process(node.getQueryBody(), indentLevel); - if (node.getOrderBy().isPresent()) { - print(indentLevel, "OrderBy"); - process(node.getOrderBy().get(), indentLevel + 1); - } - - if (node.getLimit().isPresent()) { - print(indentLevel, "Limit: " + node.getLimit().get()); - } - - return null; - } - - @Override - protected Void visitQuerySpecification(QuerySpecification node, Integer indentLevel) - { - print(indentLevel, "QuerySpecification "); - - indentLevel++; - - process(node.getSelect(), indentLevel); - - if (node.getFrom().isPresent()) { - print(indentLevel, "From"); - process(node.getFrom().get(), indentLevel + 1); - } - - if (node.getWhere().isPresent()) { - print(indentLevel, "Where"); - process(node.getWhere().get(), indentLevel + 1); - } - - if (node.getGroupBy().isPresent()) { - String distinct = ""; - if (node.getGroupBy().get().isDistinct()) { - distinct = "[DISTINCT]"; - } - print(indentLevel, "GroupBy" + distinct); - for (GroupingElement groupingElement : node.getGroupBy().get().getGroupingElements()) { - print(indentLevel, "SimpleGroupBy"); - if (groupingElement instanceof SimpleGroupBy) { - for (Expression column : groupingElement.getExpressions()) { - process(column, indentLevel + 1); - } - } - else if (groupingElement instanceof GroupingSets) { - print(indentLevel + 1, "GroupingSets"); - for (List set : ((GroupingSets) groupingElement).getSets()) { - print(indentLevel + 2, "GroupingSet["); - for (Expression expression : set) { - process(expression, indentLevel + 3); - } - print(indentLevel + 2, "]"); - } - } - else if (groupingElement instanceof Cube) { - print(indentLevel + 1, "Cube"); - for (Expression column : groupingElement.getExpressions()) { - process(column, indentLevel + 1); - } - } - else if (groupingElement instanceof Rollup) { - print(indentLevel + 1, "Rollup"); - for (Expression column : groupingElement.getExpressions()) { - process(column, indentLevel + 1); - } - } - } - } - - if (node.getHaving().isPresent()) { - print(indentLevel, "Having"); - process(node.getHaving().get(), indentLevel + 1); - } - - if (!node.getWindows().isEmpty()) { - print(indentLevel, "Window"); - for (WindowDefinition windowDefinition : node.getWindows()) { - process(windowDefinition, indentLevel + 1); - } - } - - if (node.getOrderBy().isPresent()) { - print(indentLevel, "OrderBy"); - process(node.getOrderBy().get(), indentLevel + 1); - } - - if (node.getLimit().isPresent()) { - print(indentLevel, "Limit: " + node.getLimit().get()); - } - - return null; - } - - @Override - protected Void visitOrderBy(OrderBy node, Integer indentLevel) - { - for (SortItem sortItem : node.getSortItems()) { - process(sortItem, indentLevel); - } - - return null; - } - - @Override - protected Void visitWindowDefinition(WindowDefinition node, Integer indentLevel) - { - print(indentLevel, "WindowDefinition[" + node.getName() + "]"); - process(node.getWindow(), indentLevel + 1); - - return null; - } - - @Override - protected Void visitWindowReference(WindowReference node, Integer indentLevel) - { - print(indentLevel, "WindowReference[" + node.getName() + "]"); - - return null; - } - - @Override - public Void visitWindowSpecification(WindowSpecification node, Integer indentLevel) - { - if (node.getExistingWindowName().isPresent()) { - print(indentLevel, "ExistingWindowName " + node.getExistingWindowName().get()); - } - - if (!node.getPartitionBy().isEmpty()) { - print(indentLevel, "PartitionBy"); - for (Expression expression : node.getPartitionBy()) { - process(expression, indentLevel + 1); - } - } - - if (node.getOrderBy().isPresent()) { - print(indentLevel, "OrderBy"); - process(node.getOrderBy().get(), indentLevel + 1); - } - - if (node.getFrame().isPresent()) { - print(indentLevel, "Frame"); - process(node.getFrame().get(), indentLevel + 1); - } - - return null; - } - - @Override - protected Void visitSelect(Select node, Integer indentLevel) - { - String distinct = ""; - if (node.isDistinct()) { - distinct = "[DISTINCT]"; - } - print(indentLevel, "Select" + distinct); - - super.visitSelect(node, indentLevel + 1); // visit children - - return null; - } - - @Override - protected Void visitAllColumns(AllColumns node, Integer indent) - { - StringBuilder aliases = new StringBuilder(); - if (!node.getAliases().isEmpty()) { - aliases.append(" [Aliases: "); - Joiner.on(", ").appendTo(aliases, node.getAliases()); - aliases.append("]"); - } - print(indent, "All columns" + aliases.toString()); - - if (node.getTarget().isPresent()) { - super.visitAllColumns(node, indent + 1); // visit child - } - - return null; - } - - @Override - protected Void visitSingleColumn(SingleColumn node, Integer indent) - { - if (node.getAlias().isPresent()) { - print(indent, "Alias: " + node.getAlias().get()); - } - - super.visitSingleColumn(node, indent + 1); // visit children - - return null; - } - - @Override - protected Void visitComparisonExpression(ComparisonExpression node, Integer indentLevel) - { - print(indentLevel, node.getOperator().toString()); - - super.visitComparisonExpression(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitArithmeticBinary(ArithmeticBinaryExpression node, Integer indentLevel) - { - print(indentLevel, node.getOperator().toString()); - - super.visitArithmeticBinary(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitLogicalExpression(LogicalExpression node, Integer indentLevel) - { - print(indentLevel, node.getOperator().toString()); - - super.visitLogicalExpression(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitStringLiteral(StringLiteral node, Integer indentLevel) - { - print(indentLevel, "String[" + node.getValue() + "]"); - return null; - } - - @Override - protected Void visitBinaryLiteral(BinaryLiteral node, Integer indentLevel) - { - print(indentLevel, "Binary[" + node.toHexString() + "]"); - return null; - } - - @Override - protected Void visitBooleanLiteral(BooleanLiteral node, Integer indentLevel) - { - print(indentLevel, "Boolean[" + node.getValue() + "]"); - return null; - } - - @Override - protected Void visitLongLiteral(LongLiteral node, Integer indentLevel) - { - print(indentLevel, "Long[" + node.getValue() + "]"); - return null; - } - - @Override - protected Void visitLikePredicate(LikePredicate node, Integer indentLevel) - { - print(indentLevel, "LIKE"); - - super.visitLikePredicate(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitIdentifier(Identifier node, Integer indentLevel) - { - QualifiedName resolved = resolvedNameReferences.get(node); - String resolvedName = ""; - if (resolved != null) { - resolvedName = "=>" + resolved.toString(); - } - print(indentLevel, "Identifier[" + node.getValue() + resolvedName + "]"); - return null; - } - - @Override - protected Void visitDereferenceExpression(DereferenceExpression node, Integer indentLevel) - { - QualifiedName resolved = resolvedNameReferences.get(node); - String resolvedName = ""; - if (resolved != null) { - resolvedName = "=>" + resolved.toString(); - } - print(indentLevel, "DereferenceExpression[" + node + resolvedName + "]"); - return null; - } - - @Override - protected Void visitFunctionCall(FunctionCall node, Integer indentLevel) - { - String name = Joiner.on('.').join(node.getName().getParts()); - print(indentLevel, "FunctionCall[" + name + "]"); - - super.visitFunctionCall(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitTable(Table node, Integer indentLevel) - { - String name = Joiner.on('.').join(node.getName().getParts()); - print(indentLevel, "Table[" + name + "]"); - - return null; - } - - @Override - protected Void visitValues(Values node, Integer indentLevel) - { - print(indentLevel, "Values"); - - super.visitValues(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitRow(Row node, Integer indentLevel) - { - print(indentLevel, "Row"); - - super.visitRow(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitAliasedRelation(AliasedRelation node, Integer indentLevel) - { - print(indentLevel, "Alias[" + node.getAlias() + "]"); - - super.visitAliasedRelation(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitSampledRelation(SampledRelation node, Integer indentLevel) - { - print(indentLevel, "TABLESAMPLE[" + node.getType() + " (" + node.getSamplePercentage() + ")]"); - - super.visitSampledRelation(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitTableSubquery(TableSubquery node, Integer indentLevel) - { - print(indentLevel, "SubQuery"); - - super.visitTableSubquery(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitInPredicate(InPredicate node, Integer indentLevel) - { - print(indentLevel, "IN"); - - super.visitInPredicate(node, indentLevel + 1); - - return null; - } - - @Override - protected Void visitSubqueryExpression(SubqueryExpression node, Integer indentLevel) - { - print(indentLevel, "SubQuery"); - - super.visitSubqueryExpression(node, indentLevel + 1); - - return null; - } - }; - - printer.process(root, 0); - } - - private void print(Integer indentLevel, String value) - { - out.println(Strings.repeat(INDENT, indentLevel) + value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/AntlrATNCacheFields.java b/trino-parser/src/main/java/io/trino/sql/parser/AntlrATNCacheFields.java deleted file mode 100644 index 5b9a6b443..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/AntlrATNCacheFields.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import org.antlr.v4.runtime.Lexer; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.atn.ATN; -import org.antlr.v4.runtime.atn.LexerATNSimulator; -import org.antlr.v4.runtime.atn.ParserATNSimulator; -import org.antlr.v4.runtime.atn.PredictionContextCache; -import org.antlr.v4.runtime.dfa.DFA; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public final class AntlrATNCacheFields -{ - private final ATN atn; - private final PredictionContextCache predictionContextCache; - private final DFA[] decisionToDFA; - - public AntlrATNCacheFields(ATN atn) - { - this.atn = requireNonNull(atn, "atn is null"); - this.predictionContextCache = new PredictionContextCache(); - this.decisionToDFA = createDecisionToDFA(atn); - } - - @SuppressWarnings("ObjectEquality") - public void configureLexer(Lexer lexer) - { - requireNonNull(lexer, "lexer is null"); - // Intentional identity equals comparison - checkArgument(atn == lexer.getATN(), "Lexer ATN mismatch: expected %s, found %s", atn, lexer.getATN()); - lexer.setInterpreter(new LexerATNSimulator(lexer, atn, decisionToDFA, predictionContextCache)); - } - - @SuppressWarnings("ObjectEquality") - public void configureParser(Parser parser) - { - requireNonNull(parser, "parser is null"); - // Intentional identity equals comparison - checkArgument(atn == parser.getATN(), "Parser ATN mismatch: expected %s, found %s", atn, parser.getATN()); - parser.setInterpreter(new ParserATNSimulator(parser, atn, decisionToDFA, predictionContextCache)); - } - - private static DFA[] createDecisionToDFA(ATN atn) - { - DFA[] decisionToDFA = new DFA[atn.getNumberOfDecisions()]; - for (int i = 0; i < decisionToDFA.length; i++) { - decisionToDFA[i] = new DFA(atn.getDecisionState(i), i); - } - return decisionToDFA; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/AstBuilder.java b/trino-parser/src/main/java/io/trino/sql/parser/AstBuilder.java deleted file mode 100644 index b83443006..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/AstBuilder.java +++ /dev/null @@ -1,3492 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import io.trino.sql.tree.AddColumn; -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.AllRows; -import io.trino.sql.tree.Analyze; -import io.trino.sql.tree.AnchorPattern; -import io.trino.sql.tree.ArithmeticBinaryExpression; -import io.trino.sql.tree.ArithmeticUnaryExpression; -import io.trino.sql.tree.ArrayConstructor; -import io.trino.sql.tree.AtTimeZone; -import io.trino.sql.tree.BetweenPredicate; -import io.trino.sql.tree.BinaryLiteral; -import io.trino.sql.tree.BindExpression; -import io.trino.sql.tree.BooleanLiteral; -import io.trino.sql.tree.Call; -import io.trino.sql.tree.CallArgument; -import io.trino.sql.tree.Cast; -import io.trino.sql.tree.CharLiteral; -import io.trino.sql.tree.CoalesceExpression; -import io.trino.sql.tree.ColumnDefinition; -import io.trino.sql.tree.Comment; -import io.trino.sql.tree.Commit; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.CreateMaterializedView; -import io.trino.sql.tree.CreateRole; -import io.trino.sql.tree.CreateSchema; -import io.trino.sql.tree.CreateTable; -import io.trino.sql.tree.CreateTableAsSelect; -import io.trino.sql.tree.CreateView; -import io.trino.sql.tree.Cube; -import io.trino.sql.tree.CurrentCatalog; -import io.trino.sql.tree.CurrentPath; -import io.trino.sql.tree.CurrentSchema; -import io.trino.sql.tree.CurrentTime; -import io.trino.sql.tree.CurrentUser; -import io.trino.sql.tree.DataType; -import io.trino.sql.tree.DataTypeParameter; -import io.trino.sql.tree.DateTimeDataType; -import io.trino.sql.tree.Deallocate; -import io.trino.sql.tree.DecimalLiteral; -import io.trino.sql.tree.Declare; -import io.trino.sql.tree.Delete; -import io.trino.sql.tree.Deny; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.DescribeInput; -import io.trino.sql.tree.DescribeOutput; -import io.trino.sql.tree.DoubleLiteral; -import io.trino.sql.tree.DropColumn; -import io.trino.sql.tree.DropMaterializedView; -import io.trino.sql.tree.DropRole; -import io.trino.sql.tree.DropSchema; -import io.trino.sql.tree.DropTable; -import io.trino.sql.tree.DropView; -import io.trino.sql.tree.EmptyPattern; -import io.trino.sql.tree.Except; -import io.trino.sql.tree.ExcludedPattern; -import io.trino.sql.tree.Execute; -import io.trino.sql.tree.ExistsPredicate; -import io.trino.sql.tree.Explain; -import io.trino.sql.tree.ExplainAnalyze; -import io.trino.sql.tree.ExplainFormat; -import io.trino.sql.tree.ExplainOption; -import io.trino.sql.tree.ExplainType; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Extract; -import io.trino.sql.tree.FetchCursor; -import io.trino.sql.tree.FetchFirst; -import io.trino.sql.tree.Format; -import io.trino.sql.tree.FrameBound; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.FunctionCall.NullTreatment; -import io.trino.sql.tree.FunctionRelation; -import io.trino.sql.tree.GenericDataType; -import io.trino.sql.tree.GenericLiteral; -import io.trino.sql.tree.Grant; -import io.trino.sql.tree.GrantOnType; -import io.trino.sql.tree.GrantRoles; -import io.trino.sql.tree.GrantorSpecification; -import io.trino.sql.tree.GroupBy; -import io.trino.sql.tree.GroupingElement; -import io.trino.sql.tree.GroupingOperation; -import io.trino.sql.tree.GroupingSets; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.IfExpression; -import io.trino.sql.tree.ImpersonateUser; -import io.trino.sql.tree.InListExpression; -import io.trino.sql.tree.InPredicate; -import io.trino.sql.tree.Insert; -import io.trino.sql.tree.Intersect; -import io.trino.sql.tree.IntervalDayTimeDataType; -import io.trino.sql.tree.IntervalLiteral; -import io.trino.sql.tree.IsNotNullPredicate; -import io.trino.sql.tree.IsNullPredicate; -import io.trino.sql.tree.Isolation; -import io.trino.sql.tree.Join; -import io.trino.sql.tree.JoinCriteria; -import io.trino.sql.tree.JoinOn; -import io.trino.sql.tree.JoinUsing; -import io.trino.sql.tree.LambdaArgumentDeclaration; -import io.trino.sql.tree.LambdaExpression; -import io.trino.sql.tree.Lateral; -import io.trino.sql.tree.LikeClause; -import io.trino.sql.tree.LikePredicate; -import io.trino.sql.tree.Limit; -import io.trino.sql.tree.LogicalExpression; -import io.trino.sql.tree.LongLiteral; -import io.trino.sql.tree.MeasureDefinition; -import io.trino.sql.tree.Merge; -import io.trino.sql.tree.MergeCase; -import io.trino.sql.tree.MergeDelete; -import io.trino.sql.tree.MergeInsert; -import io.trino.sql.tree.MergeUpdate; -import io.trino.sql.tree.NaturalJoin; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NodeLocation; -import io.trino.sql.tree.NotExpression; -import io.trino.sql.tree.NullIfExpression; -import io.trino.sql.tree.NullLiteral; -import io.trino.sql.tree.NumericParameter; -import io.trino.sql.tree.Offset; -import io.trino.sql.tree.OneOrMoreQuantifier; -import io.trino.sql.tree.OrderBy; -import io.trino.sql.tree.Parameter; -import io.trino.sql.tree.PathElement; -import io.trino.sql.tree.PathRelation; -import io.trino.sql.tree.PathSpecification; -import io.trino.sql.tree.PatternAlternation; -import io.trino.sql.tree.PatternConcatenation; -import io.trino.sql.tree.PatternPermutation; -import io.trino.sql.tree.PatternQuantifier; -import io.trino.sql.tree.PatternRecognitionRelation; -import io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch; -import io.trino.sql.tree.PatternSearchMode; -import io.trino.sql.tree.PatternVariable; -import io.trino.sql.tree.Prepare; -import io.trino.sql.tree.PrincipalSpecification; -import io.trino.sql.tree.ProcessingMode; -import io.trino.sql.tree.Property; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.QuantifiedComparisonExpression; -import io.trino.sql.tree.QuantifiedPattern; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.QueryBody; -import io.trino.sql.tree.QueryPeriod; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.RangeQuantifier; -import io.trino.sql.tree.RefreshMaterializedView; -import io.trino.sql.tree.Relation; -import io.trino.sql.tree.RenameColumn; -import io.trino.sql.tree.RenameMaterializedView; -import io.trino.sql.tree.RenameSchema; -import io.trino.sql.tree.RenameTable; -import io.trino.sql.tree.RenameView; -import io.trino.sql.tree.ResetSession; -import io.trino.sql.tree.Revoke; -import io.trino.sql.tree.RevokeRoles; -import io.trino.sql.tree.Rollback; -import io.trino.sql.tree.Rollup; -import io.trino.sql.tree.Row; -import io.trino.sql.tree.RowDataType; -import io.trino.sql.tree.RowPattern; -import io.trino.sql.tree.SampledRelation; -import io.trino.sql.tree.SearchedCaseExpression; -import io.trino.sql.tree.Select; -import io.trino.sql.tree.SelectItem; -import io.trino.sql.tree.SetPath; -import io.trino.sql.tree.SetProperties; -import io.trino.sql.tree.SetRole; -import io.trino.sql.tree.SetSchemaAuthorization; -import io.trino.sql.tree.SetSession; -import io.trino.sql.tree.SetTableAuthorization; -import io.trino.sql.tree.SetTimeZone; -import io.trino.sql.tree.SetViewAuthorization; -import io.trino.sql.tree.ShowCatalogs; -import io.trino.sql.tree.ShowColumns; -import io.trino.sql.tree.ShowCreate; -import io.trino.sql.tree.ShowFunctions; -import io.trino.sql.tree.ShowGrants; -import io.trino.sql.tree.ShowRoleGrants; -import io.trino.sql.tree.ShowRoles; -import io.trino.sql.tree.ShowSchemas; -import io.trino.sql.tree.ShowSession; -import io.trino.sql.tree.ShowStats; -import io.trino.sql.tree.ShowTables; -import io.trino.sql.tree.SimpleCaseExpression; -import io.trino.sql.tree.SimpleGroupBy; -import io.trino.sql.tree.SingleColumn; -import io.trino.sql.tree.SkipTo; -import io.trino.sql.tree.SortItem; -import io.trino.sql.tree.StartTransaction; -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.StringLiteral; -import io.trino.sql.tree.SubqueryExpression; -import io.trino.sql.tree.SubscriptExpression; -import io.trino.sql.tree.SubsetDefinition; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableElement; -import io.trino.sql.tree.TableExecute; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.TimeLiteral; -import io.trino.sql.tree.TimestampLiteral; -import io.trino.sql.tree.TransactionAccessMode; -import io.trino.sql.tree.TransactionMode; -import io.trino.sql.tree.TruncateTable; -import io.trino.sql.tree.TryExpression; -import io.trino.sql.tree.TypeParameter; -import io.trino.sql.tree.Union; -import io.trino.sql.tree.Unnest; -import io.trino.sql.tree.Update; -import io.trino.sql.tree.UpdateAssignment; -import io.trino.sql.tree.Use; -import io.trino.sql.tree.Values; -import io.trino.sql.tree.VariableDefinition; -import io.trino.sql.tree.WhenClause; -import io.trino.sql.tree.Window; -import io.trino.sql.tree.WindowDefinition; -import io.trino.sql.tree.WindowFrame; -import io.trino.sql.tree.WindowOperation; -import io.trino.sql.tree.WindowReference; -import io.trino.sql.tree.WindowSpecification; -import io.trino.sql.tree.With; -import io.trino.sql.tree.WithQuery; -import io.trino.sql.tree.ZeroOrMoreQuantifier; -import io.trino.sql.tree.ZeroOrOneQuantifier; -import io.trino.sql.util.IntervalLiteralUtil; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.tree.ParseTree; -import org.antlr.v4.runtime.tree.TerminalNode; - -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Deque; -import java.util.Iterator; -import java.util.List; -import java.util.Optional; -import java.util.function.Function; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.Iterables.getOnlyElement; -import static io.trino.sql.QueryUtil.functionCall; -import static io.trino.sql.QueryUtil.selectAll; -import static io.trino.sql.QueryUtil.selectList; -import static io.trino.sql.QueryUtil.simpleQuery; -import static io.trino.sql.parser.SqlBaseParser.TIME; -import static io.trino.sql.parser.SqlBaseParser.TIMESTAMP; -import static io.trino.sql.tree.AnchorPattern.Type.PARTITION_END; -import static io.trino.sql.tree.AnchorPattern.Type.PARTITION_START; -import static io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch.ALL_OMIT_EMPTY; -import static io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch.ALL_SHOW_EMPTY; -import static io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch.ALL_WITH_UNMATCHED; -import static io.trino.sql.tree.PatternRecognitionRelation.RowsPerMatch.ONE; -import static io.trino.sql.tree.PatternSearchMode.Mode.INITIAL; -import static io.trino.sql.tree.PatternSearchMode.Mode.SEEK; -import static io.trino.sql.tree.ProcessingMode.Mode.FINAL; -import static io.trino.sql.tree.ProcessingMode.Mode.RUNNING; -import static io.trino.sql.tree.SkipTo.skipPastLastRow; -import static io.trino.sql.tree.SkipTo.skipToFirst; -import static io.trino.sql.tree.SkipTo.skipToLast; -import static io.trino.sql.tree.SkipTo.skipToNextRow; -import static io.trino.sql.util.EscapedCharsUtil.replaceEscapedChars; -import static java.lang.String.format; -import static java.util.Locale.ENGLISH; -import static java.util.Objects.isNull; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toList; - -@VisibleForTesting -public class AstBuilder - extends SqlBaseBaseVisitor -{ - public static final List DUCKDB_TABLE_FUNCTIONS = ImmutableList.of( - "read_csv", - "sniff_csv", - "read_json", - "glob", - "read_parquet", - "parquet_metadata"); - - private int parameterPosition; - private final ParsingOptions parsingOptions; - - AstBuilder(ParsingOptions parsingOptions) - { - this.parsingOptions = requireNonNull(parsingOptions, "parsingOptions is null"); - } - - @Override - public Node visitSingleStatement(SqlBaseParser.SingleStatementContext context) - { - return visit(context.statement()); - } - - @Override - public Node visitStandaloneExpression(SqlBaseParser.StandaloneExpressionContext context) - { - return visit(context.expression()); - } - - @Override - public Node visitStandaloneType(SqlBaseParser.StandaloneTypeContext context) - { - return visit(context.type()); - } - - @Override - public Node visitStandalonePathSpecification(SqlBaseParser.StandalonePathSpecificationContext context) - { - return visit(context.pathSpecification()); - } - - @Override - public Node visitStandaloneRowPattern(SqlBaseParser.StandaloneRowPatternContext context) - { - return visit(context.rowPattern()); - } - - // ******************* statements ********************** - - @Override - public Node visitUse(SqlBaseParser.UseContext context) - { - return new Use( - getLocation(context), - visitIfPresent(context.catalog, Identifier.class), - (Identifier) visit(context.schema)); - } - - @Override - public Node visitCreateSchema(SqlBaseParser.CreateSchemaContext context) - { - Optional principal = Optional.empty(); - if (context.AUTHORIZATION() != null) { - principal = Optional.of(getPrincipalSpecification(context.principal())); - } - - List properties = ImmutableList.of(); - if (context.properties() != null) { - properties = visit(context.properties().propertyAssignments().property(), Property.class); - } - - return new CreateSchema( - getLocation(context), - getQualifiedName(context.qualifiedName()), - context.EXISTS() != null, - properties, - principal); - } - - @Override - public Node visitDropSchema(SqlBaseParser.DropSchemaContext context) - { - return new DropSchema( - getLocation(context), - getQualifiedName(context.qualifiedName()), - context.EXISTS() != null, - context.CASCADE() != null); - } - - @Override - public Node visitRenameSchema(SqlBaseParser.RenameSchemaContext context) - { - return new RenameSchema( - getLocation(context), - getQualifiedName(context.qualifiedName()), - (Identifier) visit(context.identifier())); - } - - @Override - public Node visitSetSchemaAuthorization(SqlBaseParser.SetSchemaAuthorizationContext context) - { - return new SetSchemaAuthorization( - getLocation(context), - getQualifiedName(context.qualifiedName()), - getPrincipalSpecification(context.principal())); - } - - @Override - public Node visitCreateTableAsSelect(SqlBaseParser.CreateTableAsSelectContext context) - { - Optional comment = Optional.empty(); - if (context.COMMENT() != null) { - comment = Optional.of(((StringLiteral) visit(context.string())).getValue()); - } - - Optional> columnAliases = Optional.empty(); - if (context.columnAliases() != null) { - columnAliases = Optional.of(visit(context.columnAliases().identifier(), Identifier.class)); - } - - List properties = ImmutableList.of(); - if (context.properties() != null) { - properties = visit(context.properties().propertyAssignments().property(), Property.class); - } - - return new CreateTableAsSelect( - getLocation(context), - getQualifiedName(context.qualifiedName()), - (Query) visit(context.query()), - context.EXISTS() != null, - properties, - context.NO() == null, - columnAliases, - comment); - } - - @Override - public Node visitCreateTable(SqlBaseParser.CreateTableContext context) - { - Optional comment = Optional.empty(); - if (context.COMMENT() != null) { - comment = Optional.of(((StringLiteral) visit(context.string())).getValue()); - } - List properties = ImmutableList.of(); - if (context.properties() != null) { - properties = visit(context.properties().propertyAssignments().property(), Property.class); - } - return new CreateTable( - getLocation(context), - getQualifiedName(context.qualifiedName()), - visit(context.tableElement(), TableElement.class), - context.EXISTS() != null, - properties, - comment); - } - - @Override - public Node visitCreateMaterializedView(SqlBaseParser.CreateMaterializedViewContext context) - { - Optional comment = Optional.empty(); - if (context.COMMENT() != null) { - comment = Optional.of(((StringLiteral) visit(context.string())).getValue()); - } - - List properties = ImmutableList.of(); - if (context.properties() != null) { - properties = visit(context.properties().propertyAssignments().property(), Property.class); - } - - return new CreateMaterializedView( - Optional.of(getLocation(context)), - getQualifiedName(context.qualifiedName()), - (Query) visit(context.query()), - context.REPLACE() != null, - context.EXISTS() != null, - properties, - comment); - } - - @Override - public Node visitRefreshMaterializedView(SqlBaseParser.RefreshMaterializedViewContext context) - { - return new RefreshMaterializedView( - Optional.of(getLocation(context)), - new Table(getQualifiedName(context.qualifiedName()))); - } - - @Override - public Node visitDropMaterializedView(SqlBaseParser.DropMaterializedViewContext context) - { - return new DropMaterializedView( - getLocation(context), getQualifiedName(context.qualifiedName()), context.EXISTS() != null); - } - - @Override - public Node visitShowCreateTable(SqlBaseParser.ShowCreateTableContext context) - { - return new ShowCreate(getLocation(context), ShowCreate.Type.TABLE, getQualifiedName(context.qualifiedName())); - } - - @Override - public Node visitDropTable(SqlBaseParser.DropTableContext context) - { - return new DropTable(getLocation(context), getQualifiedName(context.qualifiedName()), context.EXISTS() != null); - } - - @Override - public Node visitDropView(SqlBaseParser.DropViewContext context) - { - return new DropView(getLocation(context), getQualifiedName(context.qualifiedName()), context.EXISTS() != null); - } - - @Override - public Node visitInsertInto(SqlBaseParser.InsertIntoContext context) - { - Optional> columnAliases = Optional.empty(); - if (context.columnAliases() != null) { - columnAliases = Optional.of(visit(context.columnAliases().identifier(), Identifier.class)); - } - - return new Insert( - new Table(getQualifiedName(context.qualifiedName())), - columnAliases, - (Query) visit(context.query())); - } - - @Override - public Node visitDelete(SqlBaseParser.DeleteContext context) - { - return new Delete( - getLocation(context), - new Table(getLocation(context), getQualifiedName(context.qualifiedName())), - visitIfPresent(context.booleanExpression(), Expression.class)); - } - - @Override - public Node visitUpdate(SqlBaseParser.UpdateContext context) - { - return new Update( - getLocation(context), - new Table(getLocation(context), getQualifiedName(context.qualifiedName())), - visit(context.updateAssignment(), UpdateAssignment.class), - visitIfPresent(context.booleanExpression(), Expression.class)); - } - - @Override - public Node visitUpdateAssignment(SqlBaseParser.UpdateAssignmentContext context) - { - return new UpdateAssignment((Identifier) visit(context.identifier()), (Expression) visit(context.expression())); - } - - @Override - public Node visitTruncateTable(SqlBaseParser.TruncateTableContext context) - { - return new TruncateTable(getLocation(context), getQualifiedName(context.qualifiedName())); - } - - @Override - public Node visitMerge(SqlBaseParser.MergeContext context) - { - return new Merge( - getLocation(context), - new Table(getLocation(context), getQualifiedName(context.qualifiedName())), - visitIfPresent(context.identifier(), Identifier.class), - (Relation) visit(context.relation()), - (Expression) visit(context.expression()), - visit(context.mergeCase(), MergeCase.class)); - } - - @Override - public Node visitMergeInsert(SqlBaseParser.MergeInsertContext context) - { - return new MergeInsert( - getLocation(context), - visitIfPresent(context.condition, Expression.class), - visitIdentifiers(context.targets), - visit(context.values, Expression.class)); - } - - private List visitIdentifiers(List identifiers) - { - return identifiers.stream() - .map(identifier -> (Identifier) visit(identifier)) - .collect(toImmutableList()); - } - - @Override - public Node visitMergeUpdate(SqlBaseParser.MergeUpdateContext context) - { - ImmutableList.Builder assignments = ImmutableList.builder(); - for (int i = 0; i < context.targets.size(); i++) { - assignments.add(new MergeUpdate.Assignment( - (Identifier) visit(context.targets.get(i)), - (Expression) visit(context.values.get(i)))); - } - - return new MergeUpdate(getLocation(context), visitIfPresent(context.condition, Expression.class), assignments.build()); - } - - @Override - public Node visitMergeDelete(SqlBaseParser.MergeDeleteContext context) - { - return new MergeDelete(getLocation(context), visitIfPresent(context.condition, Expression.class)); - } - - @Override - public Node visitRenameTable(SqlBaseParser.RenameTableContext context) - { - return new RenameTable(getLocation(context), getQualifiedName(context.from), getQualifiedName(context.to), context.EXISTS() != null); - } - - @Override - public Node visitSetTableProperties(SqlBaseParser.SetTablePropertiesContext context) - { - List properties = ImmutableList.of(); - if (context.propertyAssignments() != null) { - properties = visit(context.propertyAssignments().property(), Property.class); - } - - return new SetProperties(getLocation(context), SetProperties.Type.TABLE, getQualifiedName(context.qualifiedName()), properties); - } - - @Override - public Node visitCommentTable(SqlBaseParser.CommentTableContext context) - { - Optional comment = Optional.empty(); - - if (context.string() != null) { - comment = Optional.of(((StringLiteral) visit(context.string())).getValue()); - } - - return new Comment(getLocation(context), Comment.Type.TABLE, getQualifiedName(context.qualifiedName()), comment); - } - - @Override - public Node visitCommentColumn(SqlBaseParser.CommentColumnContext context) - { - Optional comment = Optional.empty(); - - if (context.string() != null) { - comment = Optional.of(((StringLiteral) visit(context.string())).getValue()); - } - - return new Comment(getLocation(context), Comment.Type.COLUMN, getQualifiedName(context.qualifiedName()), comment); - } - - @Override - public Node visitRenameColumn(SqlBaseParser.RenameColumnContext context) - { - return new RenameColumn( - getLocation(context), - getQualifiedName(context.tableName), - (Identifier) visit(context.from), - (Identifier) visit(context.to), - context.EXISTS().stream().anyMatch(node -> node.getSymbol().getTokenIndex() < context.COLUMN().getSymbol().getTokenIndex()), - context.EXISTS().stream().anyMatch(node -> node.getSymbol().getTokenIndex() > context.COLUMN().getSymbol().getTokenIndex())); - } - - @Override - public Node visitAnalyze(SqlBaseParser.AnalyzeContext context) - { - List properties = ImmutableList.of(); - if (context.properties() != null) { - properties = visit(context.properties().propertyAssignments().property(), Property.class); - } - return new Analyze( - getLocation(context), - getQualifiedName(context.qualifiedName()), - properties); - } - - @Override - public Node visitAddColumn(SqlBaseParser.AddColumnContext context) - { - return new AddColumn(getLocation(context), - getQualifiedName(context.qualifiedName()), - (ColumnDefinition) visit(context.columnDefinition()), - context.EXISTS().stream().anyMatch(node -> node.getSymbol().getTokenIndex() < context.COLUMN().getSymbol().getTokenIndex()), - context.EXISTS().stream().anyMatch(node -> node.getSymbol().getTokenIndex() > context.COLUMN().getSymbol().getTokenIndex())); - } - - @Override - public Node visitSetTableAuthorization(SqlBaseParser.SetTableAuthorizationContext context) - { - return new SetTableAuthorization( - getLocation(context), - getQualifiedName(context.qualifiedName()), - getPrincipalSpecification(context.principal())); - } - - @Override - public Node visitDropColumn(SqlBaseParser.DropColumnContext context) - { - return new DropColumn(getLocation(context), - getQualifiedName(context.tableName), - (Identifier) visit(context.column), - context.EXISTS().stream().anyMatch(node -> node.getSymbol().getTokenIndex() < context.COLUMN().getSymbol().getTokenIndex()), - context.EXISTS().stream().anyMatch(node -> node.getSymbol().getTokenIndex() > context.COLUMN().getSymbol().getTokenIndex())); - } - - @Override - public Node visitTableExecute(SqlBaseParser.TableExecuteContext context) - { - List arguments = ImmutableList.of(); - if (context.callArgument() != null) { - arguments = this.visit(context.callArgument(), CallArgument.class); - } - - return new TableExecute( - new Table(getLocation(context), getQualifiedName(context.tableName)), - (Identifier) visit(context.procedureName), - arguments, - visitIfPresent(context.booleanExpression(), Expression.class)); - } - - @Override - public Node visitCreateView(SqlBaseParser.CreateViewContext context) - { - Optional comment = Optional.empty(); - if (context.COMMENT() != null) { - comment = Optional.of(((StringLiteral) visit(context.string())).getValue()); - } - - Optional security = Optional.empty(); - if (context.DEFINER() != null) { - security = Optional.of(CreateView.Security.DEFINER); - } - else if (context.INVOKER() != null) { - security = Optional.of(CreateView.Security.INVOKER); - } - - return new CreateView( - getLocation(context), - getQualifiedName(context.qualifiedName()), - (Query) visit(context.query()), - context.REPLACE() != null, - comment, - security); - } - - @Override - public Node visitRenameView(SqlBaseParser.RenameViewContext context) - { - return new RenameView(getLocation(context), getQualifiedName(context.from), getQualifiedName(context.to)); - } - - @Override - public Node visitRenameMaterializedView(SqlBaseParser.RenameMaterializedViewContext context) - { - return new RenameMaterializedView(getLocation(context), getQualifiedName(context.from), getQualifiedName(context.to), context.EXISTS() != null); - } - - @Override - public Node visitSetViewAuthorization(SqlBaseParser.SetViewAuthorizationContext context) - { - return new SetViewAuthorization( - getLocation(context), - getQualifiedName(context.qualifiedName()), - getPrincipalSpecification(context.principal())); - } - - @Override - public Node visitSetMaterializedViewProperties(SqlBaseParser.SetMaterializedViewPropertiesContext context) - { - return new SetProperties( - getLocation(context), - SetProperties.Type.MATERIALIZED_VIEW, - getQualifiedName(context.qualifiedName()), - visit(context.propertyAssignments().property(), Property.class)); - } - - @Override - public Node visitStartTransaction(SqlBaseParser.StartTransactionContext context) - { - return new StartTransaction(visit(context.transactionMode(), TransactionMode.class)); - } - - @Override - public Node visitCommit(SqlBaseParser.CommitContext context) - { - return new Commit(getLocation(context)); - } - - @Override - public Node visitRollback(SqlBaseParser.RollbackContext context) - { - return new Rollback(getLocation(context)); - } - - @Override - public Node visitTransactionAccessMode(SqlBaseParser.TransactionAccessModeContext context) - { - return new TransactionAccessMode(getLocation(context), context.accessMode.getType() == SqlBaseLexer.ONLY); - } - - @Override - public Node visitIsolationLevel(SqlBaseParser.IsolationLevelContext context) - { - return visit(context.levelOfIsolation()); - } - - @Override - public Node visitReadUncommitted(SqlBaseParser.ReadUncommittedContext context) - { - return new Isolation(getLocation(context), Isolation.Level.READ_UNCOMMITTED); - } - - @Override - public Node visitReadCommitted(SqlBaseParser.ReadCommittedContext context) - { - return new Isolation(getLocation(context), Isolation.Level.READ_COMMITTED); - } - - @Override - public Node visitRepeatableRead(SqlBaseParser.RepeatableReadContext context) - { - return new Isolation(getLocation(context), Isolation.Level.REPEATABLE_READ); - } - - @Override - public Node visitSerializable(SqlBaseParser.SerializableContext context) - { - return new Isolation(getLocation(context), Isolation.Level.SERIALIZABLE); - } - - @Override - public Node visitCall(SqlBaseParser.CallContext context) - { - return new Call( - getLocation(context), - getQualifiedName(context.qualifiedName()), - visit(context.callArgument(), CallArgument.class)); - } - - @Override - public Node visitPrepare(SqlBaseParser.PrepareContext context) - { - return new Prepare( - getLocation(context), - (Identifier) visit(context.identifier()), - (Statement) visit(context.statement())); - } - - @Override - public Node visitDeallocate(SqlBaseParser.DeallocateContext context) - { - return new Deallocate( - getLocation(context), - (Identifier) visit(context.identifier())); - } - - @Override - public Node visitExecute(SqlBaseParser.ExecuteContext context) - { - return new Execute( - getLocation(context), - (Identifier) visit(context.identifier()), - visit(context.expression(), Expression.class)); - } - - @Override - public Node visitDescribeOutput(SqlBaseParser.DescribeOutputContext context) - { - return new DescribeOutput( - getLocation(context), - (Identifier) visit(context.identifier())); - } - - @Override - public Node visitDescribeInput(SqlBaseParser.DescribeInputContext context) - { - return new DescribeInput( - getLocation(context), - (Identifier) visit(context.identifier())); - } - - @Override - public Node visitProperty(SqlBaseParser.PropertyContext context) - { - NodeLocation location = getLocation(context); - Identifier name = (Identifier) visit(context.identifier()); - SqlBaseParser.PropertyValueContext valueContext = context.propertyValue(); - if (valueContext instanceof SqlBaseParser.DefaultPropertyValueContext) { - return new Property(location, name); - } - Expression value = (Expression) visit(((SqlBaseParser.NonDefaultPropertyValueContext) valueContext).expression()); - return new Property(location, name, value); - } - - // pg syntax - @Override - public Node visitDeclareCursor(SqlBaseParser.DeclareCursorContext ctx) - { - NodeLocation location = getLocation(ctx); - Identifier name = (Identifier) visit(ctx.name); - Query body = (Query) visit(ctx.body); - return new Declare(location, name, body); - } - - // pg syntax - @Override - public Node visitFetchCursor(SqlBaseParser.FetchCursorContext ctx) - { - NodeLocation location = getLocation(ctx); - Integer rowCount = Integer.parseInt(ctx.row.getText()); - Identifier cursor = (Identifier) visit(ctx.cursor); - return new FetchCursor(location, rowCount, cursor); - } - - // added by canner - @Override - public Node visitImpersonateUser(SqlBaseParser.ImpersonateUserContext ctx) - { - return new ImpersonateUser(getLocation(ctx), (Expression) visit(ctx.expression())); - } - - // ********************** query expressions ******************** - - @Override - public Node visitQuery(SqlBaseParser.QueryContext context) - { - Query body = (Query) visit(context.queryNoWith()); - - return new Query( - getLocation(context), - visitIfPresent(context.with(), With.class), - body.getQueryBody(), - body.getOrderBy(), - body.getOffset(), - body.getLimit()); - } - - @Override - public Node visitWith(SqlBaseParser.WithContext context) - { - return new With(getLocation(context), context.RECURSIVE() != null, visit(context.namedQuery(), WithQuery.class)); - } - - @Override - public Node visitNamedQuery(SqlBaseParser.NamedQueryContext context) - { - Optional> columns = Optional.empty(); - if (context.columnAliases() != null) { - columns = Optional.of(visit(context.columnAliases().identifier(), Identifier.class)); - } - - return new WithQuery( - getLocation(context), - (Identifier) visit(context.name), - (Query) visit(context.query()), - columns); - } - - @Override - public Node visitQueryNoWith(SqlBaseParser.QueryNoWithContext context) - { - QueryBody term = (QueryBody) visit(context.queryTerm()); - - Optional orderBy = Optional.empty(); - if (context.ORDER() != null) { - orderBy = Optional.of(new OrderBy(getLocation(context.ORDER()), visit(context.sortItem(), SortItem.class))); - } - - Optional offset = Optional.empty(); - if (context.OFFSET() != null) { - Expression rowCount; - if (context.offset.INTEGER_VALUE() != null) { - rowCount = new LongLiteral(getLocation(context.offset.INTEGER_VALUE()), context.offset.getText()); - } - else { - rowCount = new Parameter(getLocation(context.offset.QUESTION_MARK()), parameterPosition); - parameterPosition++; - } - offset = Optional.of(new Offset(Optional.of(getLocation(context.OFFSET())), rowCount)); - } - - Optional limit = Optional.empty(); - if (context.FETCH() != null) { - Optional rowCount = Optional.empty(); - if (context.fetchFirst != null) { - if (context.fetchFirst.INTEGER_VALUE() != null) { - rowCount = Optional.of(new LongLiteral(getLocation(context.fetchFirst.INTEGER_VALUE()), context.fetchFirst.getText())); - } - else { - rowCount = Optional.of(new Parameter(getLocation(context.fetchFirst.QUESTION_MARK()), parameterPosition)); - parameterPosition++; - } - } - limit = Optional.of(new FetchFirst(Optional.of(getLocation(context.FETCH())), rowCount, context.TIES() != null)); - } - else if (context.LIMIT() != null) { - if (context.limit == null) { - throw new IllegalStateException("Missing LIMIT value"); - } - Expression rowCount; - if (context.limit.ALL() != null) { - rowCount = new AllRows(getLocation(context.limit.ALL())); - } - else if (context.limit.string() != null) { - // for pg style limit clause - StringLiteral literal = (StringLiteral) visit(context.limit.string()); - rowCount = new LongLiteral(literal.getLocation().get(), literal.getValue()); - } - else if (context.limit.rowCount().INTEGER_VALUE() != null) { - rowCount = new LongLiteral(getLocation(context.limit.rowCount().INTEGER_VALUE()), context.limit.getText()); - } - else { - rowCount = new Parameter(getLocation(context.limit.rowCount().QUESTION_MARK()), parameterPosition); - parameterPosition++; - } - - limit = Optional.of(new Limit(Optional.of(getLocation(context.LIMIT())), rowCount)); - } - - if (term instanceof QuerySpecification) { - // When we have a simple query specification - // followed by order by, offset, limit or fetch, - // fold the order by, limit, offset or fetch clauses - // into the query specification (analyzer/planner - // expects this structure to resolve references with respect - // to columns defined in the query specification) - QuerySpecification query = (QuerySpecification) term; - - return new Query( - getLocation(context), - Optional.empty(), - new QuerySpecification( - getLocation(context), - query.getSelect(), - query.getFrom(), - query.getWhere(), - query.getGroupBy(), - query.getHaving(), - query.getWindows(), - orderBy, - offset, - limit), - Optional.empty(), - Optional.empty(), - Optional.empty()); - } - - return new Query( - getLocation(context), - Optional.empty(), - term, - orderBy, - offset, - limit); - } - - @Override - public Node visitQuerySpecification(SqlBaseParser.QuerySpecificationContext context) - { - Optional from = Optional.empty(); - List selectItems = visit(context.selectItem(), SelectItem.class); - - List relations = visit(context.relation(), Relation.class); - if (!relations.isEmpty()) { - // synthesize implicit join nodes - Iterator iterator = relations.iterator(); - Relation relation = iterator.next(); - - while (iterator.hasNext()) { - relation = new Join(getLocation(context), Join.Type.IMPLICIT, relation, iterator.next(), Optional.empty()); - } - - from = Optional.of(relation); - } - - return new QuerySpecification( - getLocation(context), - new Select(getLocation(context.SELECT()), isDistinct(context.setQuantifier()), selectItems), - from, - visitIfPresent(context.where, Expression.class), - visitIfPresent(context.groupBy(), GroupBy.class), - visitIfPresent(context.having, Expression.class), - visit(context.windowDefinition(), WindowDefinition.class), - Optional.empty(), - Optional.empty(), - Optional.empty()); - } - - @Override - public Node visitGroupBy(SqlBaseParser.GroupByContext context) - { - return new GroupBy(getLocation(context), isDistinct(context.setQuantifier()), visit(context.groupingElement(), GroupingElement.class)); - } - - @Override - public Node visitSingleGroupingSet(SqlBaseParser.SingleGroupingSetContext context) - { - return new SimpleGroupBy(getLocation(context), visit(context.groupingSet().expression(), Expression.class)); - } - - @Override - public Node visitRollup(SqlBaseParser.RollupContext context) - { - return new Rollup(getLocation(context), visit(context.expression(), Expression.class)); - } - - @Override - public Node visitCube(SqlBaseParser.CubeContext context) - { - return new Cube(getLocation(context), visit(context.expression(), Expression.class)); - } - - @Override - public Node visitMultipleGroupingSets(SqlBaseParser.MultipleGroupingSetsContext context) - { - return new GroupingSets(getLocation(context), context.groupingSet().stream() - .map(groupingSet -> visit(groupingSet.expression(), Expression.class)) - .collect(toList())); - } - - @Override - public Node visitWindowSpecification(SqlBaseParser.WindowSpecificationContext context) - { - Optional orderBy = Optional.empty(); - if (context.ORDER() != null) { - orderBy = Optional.of(new OrderBy(getLocation(context.ORDER()), visit(context.sortItem(), SortItem.class))); - } - - return new WindowSpecification( - getLocation(context), - visitIfPresent(context.existingWindowName, Identifier.class), - visit(context.partition, Expression.class), - orderBy, - visitIfPresent(context.windowFrame(), WindowFrame.class)); - } - - @Override - public Node visitWindowDefinition(SqlBaseParser.WindowDefinitionContext context) - { - return new WindowDefinition( - getLocation(context), - (Identifier) visit(context.name), - (WindowSpecification) visit(context.windowSpecification())); - } - - @Override - public Node visitSetOperation(SqlBaseParser.SetOperationContext context) - { - QueryBody left = (QueryBody) visit(context.left); - QueryBody right = (QueryBody) visit(context.right); - - boolean distinct = context.setQuantifier() == null || context.setQuantifier().DISTINCT() != null; - - switch (context.operator.getType()) { - case SqlBaseLexer.UNION: - return new Union(getLocation(context.UNION()), ImmutableList.of(left, right), distinct); - case SqlBaseLexer.INTERSECT: - return new Intersect(getLocation(context.INTERSECT()), ImmutableList.of(left, right), distinct); - case SqlBaseLexer.EXCEPT: - return new Except(getLocation(context.EXCEPT()), left, right, distinct); - } - - throw new IllegalArgumentException("Unsupported set operation: " + context.operator.getText()); - } - - @Override - public Node visitSelectAll(SqlBaseParser.SelectAllContext context) - { - List aliases = ImmutableList.of(); - if (context.columnAliases() != null) { - aliases = visit(context.columnAliases().identifier(), Identifier.class); - } - - return new AllColumns( - getLocation(context), - visitIfPresent(context.primaryExpression(), Expression.class), - aliases); - } - - @Override - public Node visitSelectSingle(SqlBaseParser.SelectSingleContext context) - { - return new SingleColumn( - getLocation(context), - (Expression) visit(context.expression()), - visitIfPresent(context.identifier(), Identifier.class)); - } - - @Override - public Node visitTable(SqlBaseParser.TableContext context) - { - return new Table(getLocation(context), getQualifiedName(context.qualifiedName())); - } - - @Override - public Node visitSubquery(SqlBaseParser.SubqueryContext context) - { - return new TableSubquery(getLocation(context), (Query) visit(context.queryNoWith())); - } - - @Override - public Node visitInlineTable(SqlBaseParser.InlineTableContext context) - { - return new Values(getLocation(context), visit(context.expression(), Expression.class)); - } - - @Override - public Node visitExplain(SqlBaseParser.ExplainContext context) - { - return new Explain(getLocation(context), (Statement) visit(context.statement()), visit(context.explainOption(), ExplainOption.class)); - } - - @Override - public Node visitExplainAnalyze(SqlBaseParser.ExplainAnalyzeContext context) - { - return new ExplainAnalyze(getLocation(context), context.VERBOSE() != null, (Statement) visit(context.statement())); - } - - @Override - public Node visitExplainFormat(SqlBaseParser.ExplainFormatContext context) - { - switch (context.value.getType()) { - case SqlBaseLexer.GRAPHVIZ: - return new ExplainFormat(getLocation(context), ExplainFormat.Type.GRAPHVIZ); - case SqlBaseLexer.TEXT: - return new ExplainFormat(getLocation(context), ExplainFormat.Type.TEXT); - case SqlBaseLexer.JSON: - return new ExplainFormat(getLocation(context), ExplainFormat.Type.JSON); - } - - throw new IllegalArgumentException("Unsupported EXPLAIN format: " + context.value.getText()); - } - - @Override - public Node visitExplainType(SqlBaseParser.ExplainTypeContext context) - { - switch (context.value.getType()) { - case SqlBaseLexer.LOGICAL: - return new ExplainType(getLocation(context), ExplainType.Type.LOGICAL); - case SqlBaseLexer.DISTRIBUTED: - return new ExplainType(getLocation(context), ExplainType.Type.DISTRIBUTED); - case SqlBaseLexer.VALIDATE: - return new ExplainType(getLocation(context), ExplainType.Type.VALIDATE); - case SqlBaseLexer.IO: - return new ExplainType(getLocation(context), ExplainType.Type.IO); - } - - throw new IllegalArgumentException("Unsupported EXPLAIN type: " + context.value.getText()); - } - - @Override - public Node visitShowTables(SqlBaseParser.ShowTablesContext context) - { - return new ShowTables( - getLocation(context), - Optional.ofNullable(context.qualifiedName()) - .map(this::getQualifiedName), - getTextIfPresent(context.pattern) - .map(AstBuilder::unquote), - getTextIfPresent(context.escape) - .map(AstBuilder::unquote)); - } - - @Override - public Node visitShowSchemas(SqlBaseParser.ShowSchemasContext context) - { - return new ShowSchemas( - getLocation(context), - visitIfPresent(context.identifier(), Identifier.class), - getTextIfPresent(context.pattern) - .map(AstBuilder::unquote), - getTextIfPresent(context.escape) - .map(AstBuilder::unquote)); - } - - @Override - public Node visitShowCatalogs(SqlBaseParser.ShowCatalogsContext context) - { - return new ShowCatalogs(getLocation(context), - getTextIfPresent(context.pattern) - .map(AstBuilder::unquote), - getTextIfPresent(context.escape) - .map(AstBuilder::unquote)); - } - - @Override - public Node visitShowColumns(SqlBaseParser.ShowColumnsContext context) - { - return new ShowColumns( - getLocation(context), - getQualifiedName(context.qualifiedName()), - getTextIfPresent(context.pattern) - .map(AstBuilder::unquote), - getTextIfPresent(context.escape) - .map(AstBuilder::unquote)); - } - - @Override - public Node visitShowStats(SqlBaseParser.ShowStatsContext context) - { - return new ShowStats(Optional.of(getLocation(context)), new Table(getQualifiedName(context.qualifiedName()))); - } - - @Override - public Node visitShowStatsForQuery(SqlBaseParser.ShowStatsForQueryContext context) - { - Query query = (Query) visit(context.query()); - return new ShowStats(Optional.of(getLocation(context)), new TableSubquery(query)); - } - - @Override - public Node visitShowCreateSchema(SqlBaseParser.ShowCreateSchemaContext context) - { - return new ShowCreate(getLocation(context), ShowCreate.Type.SCHEMA, getQualifiedName(context.qualifiedName())); - } - - @Override - public Node visitShowCreateView(SqlBaseParser.ShowCreateViewContext context) - { - return new ShowCreate(getLocation(context), ShowCreate.Type.VIEW, getQualifiedName(context.qualifiedName())); - } - - @Override - public Node visitShowCreateMaterializedView(SqlBaseParser.ShowCreateMaterializedViewContext context) - { - return new ShowCreate(getLocation(context), ShowCreate.Type.MATERIALIZED_VIEW, getQualifiedName(context.qualifiedName())); - } - - @Override - public Node visitShowFunctions(SqlBaseParser.ShowFunctionsContext context) - { - return new ShowFunctions(getLocation(context), - getTextIfPresent(context.pattern) - .map(AstBuilder::unquote), - getTextIfPresent(context.escape) - .map(AstBuilder::unquote)); - } - - @Override - public Node visitShowSession(SqlBaseParser.ShowSessionContext context) - { - return new ShowSession(getLocation(context), - getTextIfPresent(context.pattern) - .map(AstBuilder::unquote), - getTextIfPresent(context.escape) - .map(AstBuilder::unquote)); - } - - @Override - public Node visitSetSession(SqlBaseParser.SetSessionContext context) - { - return new SetSession(getLocation(context), getQualifiedName(context.qualifiedName()), (Expression) visit(context.expression())); - } - - @Override - public Node visitResetSession(SqlBaseParser.ResetSessionContext context) - { - return new ResetSession(getLocation(context), getQualifiedName(context.qualifiedName())); - } - - @Override - public Node visitCreateRole(SqlBaseParser.CreateRoleContext context) - { - return new CreateRole( - getLocation(context), - (Identifier) visit(context.name), - getGrantorSpecificationIfPresent(context.grantor()), - visitIfPresent(context.catalog, Identifier.class)); - } - - @Override - public Node visitDropRole(SqlBaseParser.DropRoleContext context) - { - return new DropRole( - getLocation(context), - (Identifier) visit(context.name), - visitIfPresent(context.catalog, Identifier.class)); - } - - @Override - public Node visitGrantRoles(SqlBaseParser.GrantRolesContext context) - { - return new GrantRoles( - getLocation(context), - ImmutableSet.copyOf(getIdentifiers(context.roles().identifier())), - ImmutableSet.copyOf(getPrincipalSpecifications(context.principal())), - context.OPTION() != null, - getGrantorSpecificationIfPresent(context.grantor()), - visitIfPresent(context.catalog, Identifier.class)); - } - - @Override - public Node visitRevokeRoles(SqlBaseParser.RevokeRolesContext context) - { - return new RevokeRoles( - getLocation(context), - ImmutableSet.copyOf(getIdentifiers(context.roles().identifier())), - ImmutableSet.copyOf(getPrincipalSpecifications(context.principal())), - context.OPTION() != null, - getGrantorSpecificationIfPresent(context.grantor()), - visitIfPresent(context.catalog, Identifier.class)); - } - - @Override - public Node visitSetRole(SqlBaseParser.SetRoleContext context) - { - SetRole.Type type = SetRole.Type.ROLE; - if (context.ALL() != null) { - type = SetRole.Type.ALL; - } - else if (context.NONE() != null) { - type = SetRole.Type.NONE; - } - return new SetRole( - getLocation(context), - type, - getIdentifierIfPresent(context.role), - visitIfPresent(context.catalog, Identifier.class)); - } - - @Override - public Node visitGrant(SqlBaseParser.GrantContext context) - { - Optional> privileges; - if (context.ALL() != null) { - privileges = Optional.empty(); - } - else { - privileges = Optional.of(context.privilege().stream() - .map(SqlBaseParser.PrivilegeContext::getText) - .collect(toList())); - } - - Optional type; - if (context.SCHEMA() != null) { - type = Optional.of(GrantOnType.SCHEMA); - } - else if (context.TABLE() != null) { - type = Optional.of(GrantOnType.TABLE); - } - else { - type = Optional.empty(); - } - - return new Grant( - getLocation(context), - privileges, - type, - getQualifiedName(context.qualifiedName()), - getPrincipalSpecification(context.grantee), - context.OPTION() != null); - } - - @Override - public Node visitDeny(SqlBaseParser.DenyContext context) - { - Optional> privileges; - if (context.ALL() != null) { - privileges = Optional.empty(); - } - else { - privileges = Optional.of(context.privilege().stream() - .map(SqlBaseParser.PrivilegeContext::getText) - .collect(toList())); - } - - Optional type; - if (context.SCHEMA() != null) { - type = Optional.of(GrantOnType.SCHEMA); - } - else if (context.TABLE() != null) { - type = Optional.of(GrantOnType.TABLE); - } - else { - type = Optional.empty(); - } - - return new Deny( - getLocation(context), - privileges, - type, - getQualifiedName(context.qualifiedName()), - getPrincipalSpecification(context.grantee)); - } - - @Override - public Node visitRevoke(SqlBaseParser.RevokeContext context) - { - Optional> privileges; - if (context.ALL() != null) { - privileges = Optional.empty(); - } - else { - privileges = Optional.of(context.privilege().stream() - .map(SqlBaseParser.PrivilegeContext::getText) - .collect(toList())); - } - - Optional type; - if (context.SCHEMA() != null) { - type = Optional.of(GrantOnType.SCHEMA); - } - else if (context.TABLE() != null) { - type = Optional.of(GrantOnType.TABLE); - } - else { - type = Optional.empty(); - } - - return new Revoke( - getLocation(context), - context.OPTION() != null, - privileges, - type, - getQualifiedName(context.qualifiedName()), - getPrincipalSpecification(context.grantee)); - } - - @Override - public Node visitShowGrants(SqlBaseParser.ShowGrantsContext context) - { - Optional tableName = Optional.empty(); - - if (context.qualifiedName() != null) { - tableName = Optional.of(getQualifiedName(context.qualifiedName())); - } - - return new ShowGrants( - getLocation(context), - context.TABLE() != null, - tableName); - } - - @Override - public Node visitShowRoles(SqlBaseParser.ShowRolesContext context) - { - return new ShowRoles( - getLocation(context), - getIdentifierIfPresent(context.identifier()), - context.CURRENT() != null); - } - - @Override - public Node visitShowRoleGrants(SqlBaseParser.ShowRoleGrantsContext context) - { - return new ShowRoleGrants( - getLocation(context), - getIdentifierIfPresent(context.identifier())); - } - - @Override - public Node visitSetPath(SqlBaseParser.SetPathContext context) - { - return new SetPath(getLocation(context), (PathSpecification) visit(context.pathSpecification())); - } - - @Override - public Node visitSetTimeZone(SqlBaseParser.SetTimeZoneContext context) - { - Optional timeZone = Optional.empty(); - if (context.expression() != null) { - timeZone = Optional.of((Expression) visit(context.expression())); - } - return new SetTimeZone(getLocation(context), timeZone); - } - - // ***************** boolean expressions ****************** - - @Override - public Node visitLogicalNot(SqlBaseParser.LogicalNotContext context) - { - return new NotExpression(getLocation(context), (Expression) visit(context.booleanExpression())); - } - - @Override - public Node visitOr(SqlBaseParser.OrContext context) - { - List terms = flatten(context, element -> { - if (element instanceof SqlBaseParser.OrContext) { - SqlBaseParser.OrContext or = (SqlBaseParser.OrContext) element; - return Optional.of(or.booleanExpression()); - } - - return Optional.empty(); - }); - - return new LogicalExpression(getLocation(context), LogicalExpression.Operator.OR, visit(terms, Expression.class)); - } - - @Override - public Node visitAnd(SqlBaseParser.AndContext context) - { - List terms = flatten(context, element -> { - if (element instanceof SqlBaseParser.AndContext) { - SqlBaseParser.AndContext and = (SqlBaseParser.AndContext) element; - return Optional.of(and.booleanExpression()); - } - - return Optional.empty(); - }); - - return new LogicalExpression(getLocation(context), LogicalExpression.Operator.AND, visit(terms, Expression.class)); - } - - private static List flatten(ParserRuleContext root, Function>> extractChildren) - { - List result = new ArrayList<>(); - Deque pending = new ArrayDeque<>(); - pending.push(root); - - while (!pending.isEmpty()) { - ParserRuleContext next = pending.pop(); - - Optional> children = extractChildren.apply(next); - if (!children.isPresent()) { - result.add(next); - } - else { - for (int i = children.get().size() - 1; i >= 0; i--) { - pending.push(children.get().get(i)); - } - } - } - - return result; - } - - // *************** from clause ***************** - - @Override - public Node visitJoinRelation(SqlBaseParser.JoinRelationContext context) - { - Relation left = (Relation) visit(context.left); - Relation right; - - if (context.CROSS() != null) { - right = (Relation) visit(context.right); - return new Join(getLocation(context), Join.Type.CROSS, left, right, Optional.empty()); - } - - JoinCriteria criteria; - if (context.NATURAL() != null) { - right = (Relation) visit(context.right); - criteria = new NaturalJoin(); - } - else { - right = (Relation) visit(context.rightRelation); - if (context.joinCriteria().ON() != null) { - criteria = new JoinOn((Expression) visit(context.joinCriteria().booleanExpression())); - } - else if (context.joinCriteria().USING() != null) { - criteria = new JoinUsing(visit(context.joinCriteria().identifier(), Identifier.class)); - } - else { - throw new IllegalArgumentException("Unsupported join criteria"); - } - } - - Join.Type joinType; - if (context.joinType().LEFT() != null) { - joinType = Join.Type.LEFT; - } - else if (context.joinType().RIGHT() != null) { - joinType = Join.Type.RIGHT; - } - else if (context.joinType().FULL() != null) { - joinType = Join.Type.FULL; - } - else { - joinType = Join.Type.INNER; - } - - return new Join(getLocation(context), joinType, left, right, Optional.of(criteria)); - } - - @Override - public Node visitSampledRelation(SqlBaseParser.SampledRelationContext context) - { - Relation child = (Relation) visit(context.patternRecognition()); - - if (context.TABLESAMPLE() == null) { - return child; - } - - return new SampledRelation( - getLocation(context), - child, - getSamplingMethod((Token) context.sampleType().getChild(0).getPayload()), - (Expression) visit(context.percentage)); - } - - @Override - public Node visitPatternRecognition(SqlBaseParser.PatternRecognitionContext context) - { - Relation child = (Relation) visit(context.aliasedRelation()); - - if (context.MATCH_RECOGNIZE() == null) { - return child; - } - - Optional orderBy = Optional.empty(); - if (context.ORDER() != null) { - orderBy = Optional.of(new OrderBy(getLocation(context.ORDER()), visit(context.sortItem(), SortItem.class))); - } - - Optional searchMode = Optional.empty(); - if (context.INITIAL() != null) { - searchMode = Optional.of(new PatternSearchMode(getLocation(context.INITIAL()), INITIAL)); - } - else if (context.SEEK() != null) { - searchMode = Optional.of(new PatternSearchMode(getLocation(context.SEEK()), SEEK)); - } - - PatternRecognitionRelation relation = new PatternRecognitionRelation( - getLocation(context), - child, - visit(context.partition, Expression.class), - orderBy, - visit(context.measureDefinition(), MeasureDefinition.class), - getRowsPerMatch(context.rowsPerMatch()), - visitIfPresent(context.skipTo(), SkipTo.class), - searchMode, - (RowPattern) visit(context.rowPattern()), - visit(context.subsetDefinition(), SubsetDefinition.class), - visit(context.variableDefinition(), VariableDefinition.class)); - - if (context.identifier() == null) { - return relation; - } - - List aliases = null; - if (context.columnAliases() != null) { - aliases = visit(context.columnAliases().identifier(), Identifier.class); - } - - return new AliasedRelation(getLocation(context), relation, (Identifier) visit(context.identifier()), aliases); - } - - @Override - public Node visitMeasureDefinition(SqlBaseParser.MeasureDefinitionContext context) - { - return new MeasureDefinition(getLocation(context), (Expression) visit(context.expression()), (Identifier) visit(context.identifier())); - } - - private Optional getRowsPerMatch(SqlBaseParser.RowsPerMatchContext context) - { - if (context == null) { - return Optional.empty(); - } - - if (context.ONE() != null) { - return Optional.of(ONE); - } - - if (context.emptyMatchHandling() == null) { - return Optional.of(ALL_SHOW_EMPTY); - } - - if (context.emptyMatchHandling().SHOW() != null) { - return Optional.of(ALL_SHOW_EMPTY); - } - - if (context.emptyMatchHandling().OMIT() != null) { - return Optional.of(ALL_OMIT_EMPTY); - } - - return Optional.of(ALL_WITH_UNMATCHED); - } - - @Override - public Node visitSkipTo(SqlBaseParser.SkipToContext context) - { - if (context.PAST() != null) { - return skipPastLastRow(getLocation(context)); - } - - if (context.NEXT() != null) { - return skipToNextRow(getLocation(context)); - } - - if (context.FIRST() != null) { - return skipToFirst(getLocation(context), (Identifier) visit(context.identifier())); - } - - return skipToLast(getLocation(context), (Identifier) visit(context.identifier())); - } - - @Override - public Node visitSubsetDefinition(SqlBaseParser.SubsetDefinitionContext context) - { - return new SubsetDefinition(getLocation(context), (Identifier) visit(context.name), visit(context.union, Identifier.class)); - } - - @Override - public Node visitVariableDefinition(SqlBaseParser.VariableDefinitionContext context) - { - return new VariableDefinition(getLocation(context), (Identifier) visit(context.identifier()), (Expression) visit(context.expression())); - } - - @Override - public Node visitAliasedRelation(SqlBaseParser.AliasedRelationContext context) - { - Relation child = (Relation) visit(context.relationPrimary()); - - if (context.identifier() == null) { - return child; - } - - List aliases = null; - if (context.columnAliases() != null) { - aliases = visit(context.columnAliases().identifier(), Identifier.class); - } - - return new AliasedRelation(getLocation(context), child, (Identifier) visit(context.identifier()), aliases); - } - - @Override - public Node visitTableName(SqlBaseParser.TableNameContext context) - { - if (context.queryPeriod() != null) { - return new Table(getLocation(context), getQualifiedName(context.qualifiedName()), (QueryPeriod) visit(context.queryPeriod())); - } - return new Table(getLocation(context), getQualifiedName(context.qualifiedName())); - } - - @Override - public Node visitSubqueryRelation(SqlBaseParser.SubqueryRelationContext context) - { - return new TableSubquery(getLocation(context), (Query) visit(context.query())); - } - - @Override - public Node visitUnnest(SqlBaseParser.UnnestContext context) - { - checkPgSchema(context.IDENTIFIER()); // pg syntax - - return new Unnest(getLocation(context), visit(context.expression(), Expression.class), context.ORDINALITY() != null); - } - - /** - * postgre sql syntax - */ - @Override - public Node visitFunctionRelation(SqlBaseParser.FunctionRelationContext context) - { - QualifiedName name = getQualifiedName(context.functionExpression().qualifiedName()); - - // wren function: metric roll_up and duckdb table function - if (name.toString().equalsIgnoreCase("roll_up") || isDuckDBTableFunction(name.toString())) { - List arguments = visit(context.functionExpression().expression(), Expression.class); - return new FunctionRelation(getLocation(context), name, arguments); - } - - for (PgSetReturnFunction pgSetReturnFunction : PgSetReturnFunction.values()) { - if (name.toString().equals(pgSetReturnFunction.getPgFuncName())) { - return new Unnest(ImmutableList.of(functionCall(pgSetReturnFunction.getRemoteFuncName(), visit(context.functionExpression().expression(), Expression.class))), false); - } - } - Query query = simpleQuery(selectList( - ImmutableList.of(functionCall(name.toString(), visit(context.functionExpression().expression(), Expression.class))), - ImmutableList.of(name.toString()))); - return new TableSubquery(getLocation(context), query); - } - - public boolean isDuckDBTableFunction(String functionName) - { - return DUCKDB_TABLE_FUNCTIONS.contains(functionName); - } - - @Override - public Node visitPathRelation(SqlBaseParser.PathRelationContext ctx) - { - return new PathRelation(Optional.of(getLocation(ctx)), ctx.string().getText()); - } - - @Override - public Node visitLateral(SqlBaseParser.LateralContext context) - { - return new Lateral(getLocation(context), (Query) visit(context.query())); - } - - @Override - public Node visitParenthesizedRelation(SqlBaseParser.ParenthesizedRelationContext context) - { - return visit(context.relation()); - } - - // ********************* predicates ******************* - - @Override - public Node visitPredicated(SqlBaseParser.PredicatedContext context) - { - if (context.predicate() != null) { - return visit(context.predicate()); - } - - return visit(context.valueExpression); - } - - @Override - public Node visitComparison(SqlBaseParser.ComparisonContext context) - { - checkPgSchema(context.IDENTIFIER()); // pg syntax - - return new ComparisonExpression( - getLocation(context.comparisonOperator()), - getComparisonOperator(((TerminalNode) context.comparisonOperator().getChild(0)).getSymbol()), - (Expression) visit(context.value), - (Expression) visit(context.right)); - } - - /** - * postgre sql syntax - */ - @Override - public Node visitPosixComparison(SqlBaseParser.PosixComparisonContext context) - { - if (!isNull(context.quotedRegexMatch())) { - checkPgSchema(context.quotedRegexMatch().IDENTIFIER()); - } - - Expression value = (Expression) visit(context.value); - Expression pattern = (Expression) visit(context.pattern); - - List args = (isNull(context.ASTERISK())) ? // if asterisk is null, means case-sensitive. - ImmutableList.of(value, pattern) : - ImmutableList.of(functionCall("lower", value), functionCall("lower", pattern)); - - Expression function = functionCall("regexp_like", args); - return (isNull(context.NOT())) ? function : new NotExpression(getLocation(context), function); - } - - @Override - public Node visitDistinctFrom(SqlBaseParser.DistinctFromContext context) - { - Expression expression = new ComparisonExpression( - getLocation(context), - ComparisonExpression.Operator.IS_DISTINCT_FROM, - (Expression) visit(context.value), - (Expression) visit(context.right)); - - if (context.NOT() != null) { - expression = new NotExpression(getLocation(context), expression); - } - - return expression; - } - - @Override - public Node visitBetween(SqlBaseParser.BetweenContext context) - { - Expression expression = new BetweenPredicate( - getLocation(context), - (Expression) visit(context.value), - (Expression) visit(context.lower), - (Expression) visit(context.upper)); - - if (context.NOT() != null) { - expression = new NotExpression(getLocation(context), expression); - } - - return expression; - } - - @Override - public Node visitNullPredicate(SqlBaseParser.NullPredicateContext context) - { - Expression child = (Expression) visit(context.value); - - if (context.NOT() == null) { - return new IsNullPredicate(getLocation(context), child); - } - - return new IsNotNullPredicate(getLocation(context), child); - } - - @Override - public Node visitLike(SqlBaseParser.LikeContext context) - { - Expression result = new LikePredicate( - getLocation(context), - (Expression) visit(context.value), - (Expression) visit(context.pattern), - visitIfPresent(context.escape, Expression.class)); - - if (context.NOT() != null) { - result = new NotExpression(getLocation(context), result); - } - - return result; - } - - @Override - public Node visitInList(SqlBaseParser.InListContext context) - { - Expression result = new InPredicate( - getLocation(context), - (Expression) visit(context.value), - new InListExpression(getLocation(context), visit(context.expression(), Expression.class))); - - if (context.NOT() != null) { - result = new NotExpression(getLocation(context), result); - } - - return result; - } - - @Override - public Node visitInSubquery(SqlBaseParser.InSubqueryContext context) - { - Expression result = new InPredicate( - getLocation(context), - (Expression) visit(context.value), - new SubqueryExpression(getLocation(context), (Query) visit(context.query()))); - - if (context.NOT() != null) { - result = new NotExpression(getLocation(context), result); - } - - return result; - } - - @Override - public Node visitExists(SqlBaseParser.ExistsContext context) - { - return new ExistsPredicate(getLocation(context), new SubqueryExpression(getLocation(context), (Query) visit(context.query()))); - } - - @Override - public Node visitQuantifiedComparison(SqlBaseParser.QuantifiedComparisonContext context) - { - SqlBaseParser.FunctionExpressionContext functionExpression = context.functionExpression(); - // postgre sql syntax - if (functionExpression != null) { - QualifiedName functionName = getQualifiedName(functionExpression.qualifiedName()); - - Query query = simpleQuery( - selectAll(ImmutableList.of(new AllColumns())), - new Unnest(ImmutableList.of(functionCall(functionName.toString(), visit(functionExpression.expression(), Expression.class))), false)); - - return new QuantifiedComparisonExpression( - getLocation(context.comparisonOperator()), - getComparisonOperator(((TerminalNode) context.comparisonOperator().getChild(0)).getSymbol()), - getComparisonQuantifier(((TerminalNode) context.comparisonQuantifier().getChild(0)).getSymbol()), - (Expression) visit(context.value), - new SubqueryExpression(getLocation(context.functionExpression()), query)); - } - - return new QuantifiedComparisonExpression( - getLocation(context.comparisonOperator()), - getComparisonOperator(((TerminalNode) context.comparisonOperator().getChild(0)).getSymbol()), - getComparisonQuantifier(((TerminalNode) context.comparisonQuantifier().getChild(0)).getSymbol()), - (Expression) visit(context.value), - new SubqueryExpression(getLocation(context.query()), (Query) visit(context.query()))); - } - - // ************** value expressions ************** - - @Override - public Node visitArithmeticUnary(SqlBaseParser.ArithmeticUnaryContext context) - { - Expression child = (Expression) visit(context.valueExpression()); - - switch (context.operator.getType()) { - case SqlBaseLexer.MINUS: - return ArithmeticUnaryExpression.negative(getLocation(context), child); - case SqlBaseLexer.PLUS: - return ArithmeticUnaryExpression.positive(getLocation(context), child); - default: - throw new UnsupportedOperationException("Unsupported sign: " + context.operator.getText()); - } - } - - @Override - public Node visitArithmeticBinary(SqlBaseParser.ArithmeticBinaryContext context) - { - checkPgSchema(context.IDENTIFIER()); // pg syntax - - return new ArithmeticBinaryExpression( - getLocation(context.operator), - getArithmeticBinaryOperator(context.operator), - (Expression) visit(context.left), - (Expression) visit(context.right)); - } - - @Override - public Node visitConcatenation(SqlBaseParser.ConcatenationContext context) - { - return new FunctionCall( - getLocation(context.CONCAT()), - QualifiedName.of("concat"), ImmutableList.of( - (Expression) visit(context.left), - (Expression) visit(context.right))); - } - - @Override - public Node visitAtTimeZone(SqlBaseParser.AtTimeZoneContext context) - { - return new AtTimeZone( - getLocation(context.AT()), - (Expression) visit(context.valueExpression()), - (Expression) visit(context.timeZoneSpecifier())); - } - - @Override - public Node visitTimeZoneInterval(SqlBaseParser.TimeZoneIntervalContext context) - { - return visit(context.interval()); - } - - @Override - public Node visitTimeZoneString(SqlBaseParser.TimeZoneStringContext context) - { - return visit(context.string()); - } - - // ********************* primary expressions ********************** - - @Override - public Node visitParenthesizedExpression(SqlBaseParser.ParenthesizedExpressionContext context) - { - return visit(context.expression()); - } - - @Override - public Node visitRowConstructor(SqlBaseParser.RowConstructorContext context) - { - return new Row(getLocation(context), visit(context.expression(), Expression.class)); - } - - @Override - public Node visitArrayConstructor(SqlBaseParser.ArrayConstructorContext context) - { - return new ArrayConstructor(getLocation(context), visit(context.expression(), Expression.class)); - } - - @Override - public Node visitCast(SqlBaseParser.CastContext context) - { - checkPgSchema(context.IDENTIFIER()); // pg syntax - - boolean isTryCast = context.TRY_CAST() != null; - boolean isPostgreStyle = context.PG_CAST() != null; - if (isPostgreStyle) { - return new Cast(getLocation(context), (Expression) visit(context.primaryExpression()), (DataType) visit(context.type()), isTryCast); - } - return new Cast(getLocation(context), (Expression) visit(context.expression()), (DataType) visit(context.type()), isTryCast); - } - - @Override - public Node visitSpecialDateTimeFunction(SqlBaseParser.SpecialDateTimeFunctionContext context) - { - CurrentTime.Function function = getDateTimeFunctionType(context.name); - - if (context.precision != null) { - return new CurrentTime(getLocation(context), function, Integer.parseInt(context.precision.getText())); - } - - return new CurrentTime(getLocation(context), function); - } - - @Override - public Node visitCurrentCatalog(SqlBaseParser.CurrentCatalogContext context) - { - return new CurrentCatalog(getLocation(context.CURRENT_CATALOG())); - } - - @Override - public Node visitCurrentSchema(SqlBaseParser.CurrentSchemaContext context) - { - return new CurrentSchema(getLocation(context.CURRENT_SCHEMA())); - } - - @Override - public Node visitCurrentUser(SqlBaseParser.CurrentUserContext context) - { - return new CurrentUser(getLocation(context.CURRENT_USER())); - } - - @Override - public Node visitCurrentPath(SqlBaseParser.CurrentPathContext context) - { - return new CurrentPath(getLocation(context.CURRENT_PATH())); - } - - @Override - public Node visitExtract(SqlBaseParser.ExtractContext context) - { - String fieldString = context.identifier().getText(); - Extract.Field field; - try { - field = new Extract.Field(fieldString.toUpperCase(ENGLISH)); - } - catch (IllegalArgumentException e) { - throw parseError("Invalid EXTRACT field: " + fieldString, context); - } - return new Extract(getLocation(context), (Expression) visit(context.valueExpression()), field); - } - - /** - * Returns the corresponding {@link FunctionCall} for the `LISTAGG` primary expression. - *

- * Although the syntax tree should represent the structure of the original parsed query - * as closely as possible and any semantic interpretation should be part of the - * analysis/planning phase, in case of `LISTAGG` aggregation function it is more pragmatic - * now to create a synthetic {@link FunctionCall} expression during the parsing of the syntax tree. - * - * @param context `LISTAGG` expression context - */ - @Override - public Node visitListagg(SqlBaseParser.ListaggContext context) - { - Optional window = Optional.empty(); - OrderBy orderBy = new OrderBy(visit(context.sortItem(), SortItem.class)); - boolean distinct = isDistinct(context.setQuantifier()); - - Expression expression = (Expression) visit(context.expression()); - StringLiteral separator = context.string() == null ? new StringLiteral(getLocation(context), "") : (StringLiteral) (visit(context.string())); - BooleanLiteral overflowError = new BooleanLiteral(getLocation(context), "true"); - StringLiteral overflowFiller = new StringLiteral(getLocation(context), "..."); - BooleanLiteral showOverflowEntryCount = new BooleanLiteral(getLocation(context), "false"); - - SqlBaseParser.ListAggOverflowBehaviorContext overflowBehavior = context.listAggOverflowBehavior(); - if (overflowBehavior != null) { - if (overflowBehavior.ERROR() != null) { - overflowError = new BooleanLiteral(getLocation(context), "true"); - } - else if (overflowBehavior.TRUNCATE() != null) { - overflowError = new BooleanLiteral(getLocation(context), "false"); - if (overflowBehavior.string() != null) { - overflowFiller = (StringLiteral) (visit(overflowBehavior.string())); - } - SqlBaseParser.ListaggCountIndicationContext listaggCountIndicationContext = overflowBehavior.listaggCountIndication(); - if (listaggCountIndicationContext.WITH() != null) { - showOverflowEntryCount = new BooleanLiteral(getLocation(context), "true"); - } - else if (listaggCountIndicationContext.WITHOUT() != null) { - showOverflowEntryCount = new BooleanLiteral(getLocation(context), "false"); - } - } - } - - List arguments = ImmutableList.of(expression, separator, overflowError, overflowFiller, showOverflowEntryCount); - - //TODO model this as a ListAgg node in the AST - return new FunctionCall( - Optional.of(getLocation(context)), - QualifiedName.of("LISTAGG"), - window, - Optional.empty(), - Optional.of(orderBy), - distinct, - Optional.empty(), - Optional.empty(), - arguments); - } - - @Override - public Node visitSubstring(SqlBaseParser.SubstringContext context) - { - return new FunctionCall(getLocation(context), QualifiedName.of("substr"), visit(context.valueExpression(), Expression.class)); - } - - @Override - public Node visitPosition(SqlBaseParser.PositionContext context) - { - List arguments = Lists.reverse(visit(context.valueExpression(), Expression.class)); - return new FunctionCall(getLocation(context), QualifiedName.of("strpos"), arguments); - } - - @Override - public Node visitNormalize(SqlBaseParser.NormalizeContext context) - { - Expression str = (Expression) visit(context.valueExpression()); - String normalForm = Optional.ofNullable(context.normalForm()).map(ParserRuleContext::getText).orElse("NFC"); - return new FunctionCall( - getLocation(context), - QualifiedName.of(ImmutableList.of(new Identifier("normalize", true))), // delimited to avoid ambiguity with NORMALIZE SQL construct - ImmutableList.of(str, new StringLiteral(getLocation(context), normalForm))); - } - - @Override - public Node visitSubscript(SqlBaseParser.SubscriptContext context) - { - return new SubscriptExpression(getLocation(context), (Expression) visit(context.value), (Expression) visit(context.index)); - } - - @Override - public Node visitSubqueryExpression(SqlBaseParser.SubqueryExpressionContext context) - { - return new SubqueryExpression(getLocation(context), (Query) visit(context.query())); - } - - @Override - public Node visitDereference(SqlBaseParser.DereferenceContext context) - { - return new DereferenceExpression( - getLocation(context), - (Expression) visit(context.base), - (Identifier) visit(context.fieldName)); - } - - @Override - public Node visitColumnReference(SqlBaseParser.ColumnReferenceContext context) - { - return visit(context.identifier()); - } - - @Override - public Node visitSimpleCase(SqlBaseParser.SimpleCaseContext context) - { - return new SimpleCaseExpression( - getLocation(context), - (Expression) visit(context.operand), - visit(context.whenClause(), WhenClause.class), - visitIfPresent(context.elseExpression, Expression.class)); - } - - @Override - public Node visitSearchedCase(SqlBaseParser.SearchedCaseContext context) - { - return new SearchedCaseExpression( - getLocation(context), - visit(context.whenClause(), WhenClause.class), - visitIfPresent(context.elseExpression, Expression.class)); - } - - @Override - public Node visitWhenClause(SqlBaseParser.WhenClauseContext context) - { - return new WhenClause(getLocation(context), (Expression) visit(context.condition), (Expression) visit(context.result)); - } - - @Override - public Node visitFunctionCall(SqlBaseParser.FunctionCallContext context) - { - Optional filter = visitIfPresent(context.filter(), Expression.class); - Optional window = visitIfPresent(context.over(), Window.class); - - Optional orderBy = Optional.empty(); - if (context.ORDER() != null) { - orderBy = Optional.of(new OrderBy(visit(context.sortItem(), SortItem.class))); - } - - QualifiedName name = getQualifiedName(context.qualifiedName()); - - boolean distinct = isDistinct(context.setQuantifier()); - - SqlBaseParser.NullTreatmentContext nullTreatment = context.nullTreatment(); - - SqlBaseParser.ProcessingModeContext processingMode = context.processingMode(); - - if (name.toString().equalsIgnoreCase("if")) { - check(context.expression().size() == 2 || context.expression().size() == 3, "Invalid number of arguments for 'if' function", context); - check(!window.isPresent(), "OVER clause not valid for 'if' function", context); - check(!distinct, "DISTINCT not valid for 'if' function", context); - check(nullTreatment == null, "Null treatment clause not valid for 'if' function", context); - check(processingMode == null, "Running or final semantics not valid for 'if' function", context); - check(!filter.isPresent(), "FILTER not valid for 'if' function", context); - - Expression elseExpression = null; - if (context.expression().size() == 3) { - elseExpression = (Expression) visit(context.expression(2)); - } - - return new IfExpression( - getLocation(context), - (Expression) visit(context.expression(0)), - (Expression) visit(context.expression(1)), - elseExpression); - } - - if (name.toString().equalsIgnoreCase("nullif")) { - check(context.expression().size() == 2, "Invalid number of arguments for 'nullif' function", context); - check(!window.isPresent(), "OVER clause not valid for 'nullif' function", context); - check(!distinct, "DISTINCT not valid for 'nullif' function", context); - check(nullTreatment == null, "Null treatment clause not valid for 'nullif' function", context); - check(processingMode == null, "Running or final semantics not valid for 'nullif' function", context); - check(!filter.isPresent(), "FILTER not valid for 'nullif' function", context); - - return new NullIfExpression( - getLocation(context), - (Expression) visit(context.expression(0)), - (Expression) visit(context.expression(1))); - } - - if (name.toString().equalsIgnoreCase("coalesce")) { - check(context.expression().size() >= 2, "The 'coalesce' function must have at least two arguments", context); - check(!window.isPresent(), "OVER clause not valid for 'coalesce' function", context); - check(!distinct, "DISTINCT not valid for 'coalesce' function", context); - check(nullTreatment == null, "Null treatment clause not valid for 'coalesce' function", context); - check(processingMode == null, "Running or final semantics not valid for 'coalesce' function", context); - check(!filter.isPresent(), "FILTER not valid for 'coalesce' function", context); - - return new CoalesceExpression(getLocation(context), visit(context.expression(), Expression.class)); - } - - if (name.toString().equalsIgnoreCase("try")) { - check(context.expression().size() == 1, "The 'try' function must have exactly one argument", context); - check(!window.isPresent(), "OVER clause not valid for 'try' function", context); - check(!distinct, "DISTINCT not valid for 'try' function", context); - check(nullTreatment == null, "Null treatment clause not valid for 'try' function", context); - check(processingMode == null, "Running or final semantics not valid for 'try' function", context); - check(!filter.isPresent(), "FILTER not valid for 'try' function", context); - - return new TryExpression(getLocation(context), (Expression) visit(getOnlyElement(context.expression()))); - } - - if (name.toString().equalsIgnoreCase("format")) { - check(context.expression().size() >= 2, "The 'format' function must have at least two arguments", context); - check(!window.isPresent(), "OVER clause not valid for 'format' function", context); - check(!distinct, "DISTINCT not valid for 'format' function", context); - check(nullTreatment == null, "Null treatment clause not valid for 'format' function", context); - check(processingMode == null, "Running or final semantics not valid for 'format' function", context); - check(!filter.isPresent(), "FILTER not valid for 'format' function", context); - - return new Format(getLocation(context), visit(context.expression(), Expression.class)); - } - - if (name.toString().equalsIgnoreCase("$internal$bind")) { - check(context.expression().size() >= 1, "The '$internal$bind' function must have at least one arguments", context); - check(!window.isPresent(), "OVER clause not valid for '$internal$bind' function", context); - check(!distinct, "DISTINCT not valid for '$internal$bind' function", context); - check(nullTreatment == null, "Null treatment clause not valid for '$internal$bind' function", context); - check(processingMode == null, "Running or final semantics not valid for '$internal$bind' function", context); - check(!filter.isPresent(), "FILTER not valid for '$internal$bind' function", context); - - int numValues = context.expression().size() - 1; - List arguments = context.expression().stream() - .map(this::visit) - .map(Expression.class::cast) - .collect(toImmutableList()); - - return new BindExpression( - getLocation(context), - arguments.subList(0, numValues), - arguments.get(numValues)); - } - - Optional nulls = Optional.empty(); - if (nullTreatment != null) { - if (nullTreatment.IGNORE() != null) { - nulls = Optional.of(NullTreatment.IGNORE); - } - else if (nullTreatment.RESPECT() != null) { - nulls = Optional.of(NullTreatment.RESPECT); - } - } - - Optional mode = Optional.empty(); - if (processingMode != null) { - if (processingMode.RUNNING() != null) { - mode = Optional.of(new ProcessingMode(getLocation(processingMode), RUNNING)); - } - else if (processingMode.FINAL() != null) { - mode = Optional.of(new ProcessingMode(getLocation(processingMode), FINAL)); - } - } - - List arguments = visit(context.expression(), Expression.class); - if (context.label != null) { - arguments = ImmutableList.of(new DereferenceExpression(getLocation(context.label), (Identifier) visit(context.label))); - } - - return new FunctionCall( - Optional.of(getLocation(context)), - name, - window, - filter, - orderBy, - distinct, - nulls, - mode, - arguments); - } - - @Override - public Node visitMeasure(SqlBaseParser.MeasureContext context) - { - return new WindowOperation(getLocation(context), (Identifier) visit(context.identifier()), (Window) visit(context.over())); - } - - @Override - public Node visitLambda(SqlBaseParser.LambdaContext context) - { - List arguments = visit(context.identifier(), Identifier.class).stream() - .map(LambdaArgumentDeclaration::new) - .collect(toList()); - - Expression body = (Expression) visit(context.expression()); - - return new LambdaExpression(getLocation(context), arguments, body); - } - - @Override - public Node visitFilter(SqlBaseParser.FilterContext context) - { - return visit(context.booleanExpression()); - } - - @Override - public Node visitOver(SqlBaseParser.OverContext context) - { - if (context.windowName != null) { - return new WindowReference(getLocation(context), (Identifier) visit(context.windowName)); - } - - return visit(context.windowSpecification()); - } - - @Override - public Node visitColumnDefinition(SqlBaseParser.ColumnDefinitionContext context) - { - Optional comment = Optional.empty(); - if (context.COMMENT() != null) { - comment = Optional.of(((StringLiteral) visit(context.string())).getValue()); - } - - List properties = ImmutableList.of(); - if (context.properties() != null) { - properties = visit(context.properties().propertyAssignments().property(), Property.class); - } - - boolean nullable = context.NOT() == null; - - return new ColumnDefinition( - getLocation(context), - (Identifier) visit(context.identifier()), - (DataType) visit(context.type()), - nullable, - properties, - comment); - } - - @Override - public Node visitLikeClause(SqlBaseParser.LikeClauseContext context) - { - return new LikeClause( - getLocation(context), - getQualifiedName(context.qualifiedName()), - Optional.ofNullable(context.optionType) - .map(AstBuilder::getPropertiesOption)); - } - - @Override - public Node visitSortItem(SqlBaseParser.SortItemContext context) - { - return new SortItem( - getLocation(context), - (Expression) visit(context.expression()), - Optional.ofNullable(context.ordering) - .map(AstBuilder::getOrderingType) - .orElse(SortItem.Ordering.ASCENDING), - Optional.ofNullable(context.nullOrdering) - .map(AstBuilder::getNullOrderingType) - .orElse(SortItem.NullOrdering.UNDEFINED)); - } - - @Override - public Node visitWindowFrame(SqlBaseParser.WindowFrameContext context) - { - Optional searchMode = Optional.empty(); - if (context.INITIAL() != null) { - searchMode = Optional.of(new PatternSearchMode(getLocation(context.INITIAL()), INITIAL)); - } - else if (context.SEEK() != null) { - searchMode = Optional.of(new PatternSearchMode(getLocation(context.SEEK()), SEEK)); - } - - return new WindowFrame( - getLocation(context), - getFrameType(context.frameExtent().frameType), - (FrameBound) visit(context.frameExtent().start), - visitIfPresent(context.frameExtent().end, FrameBound.class), - visit(context.measureDefinition(), MeasureDefinition.class), - visitIfPresent(context.skipTo(), SkipTo.class), - searchMode, - visitIfPresent(context.rowPattern(), RowPattern.class), - visit(context.subsetDefinition(), SubsetDefinition.class), - visit(context.variableDefinition(), VariableDefinition.class)); - } - - @Override - public Node visitUnboundedFrame(SqlBaseParser.UnboundedFrameContext context) - { - return new FrameBound(getLocation(context), getUnboundedFrameBoundType(context.boundType)); - } - - @Override - public Node visitBoundedFrame(SqlBaseParser.BoundedFrameContext context) - { - return new FrameBound(getLocation(context), getBoundedFrameBoundType(context.boundType), (Expression) visit(context.expression())); - } - - @Override - public Node visitCurrentRowBound(SqlBaseParser.CurrentRowBoundContext context) - { - return new FrameBound(getLocation(context), FrameBound.Type.CURRENT_ROW); - } - - @Override - public Node visitGroupingOperation(SqlBaseParser.GroupingOperationContext context) - { - List arguments = context.qualifiedName().stream() - .map(this::getQualifiedName) - .collect(toList()); - - return new GroupingOperation(Optional.of(getLocation(context)), arguments); - } - - @Override - public Node visitUnquotedIdentifier(SqlBaseParser.UnquotedIdentifierContext context) - { - return new Identifier(getLocation(context), context.getText(), false); - } - - @Override - public Node visitQuotedIdentifier(SqlBaseParser.QuotedIdentifierContext context) - { - String token = context.getText(); - String identifier = token.substring(1, token.length() - 1) - .replace("\"\"", "\""); - - return new Identifier(getLocation(context), identifier, true); - } - - @Override - public Node visitPatternAlternation(SqlBaseParser.PatternAlternationContext context) - { - List parts = visit(context.rowPattern(), RowPattern.class); - return new PatternAlternation(getLocation(context), parts); - } - - @Override - public Node visitPatternConcatenation(SqlBaseParser.PatternConcatenationContext context) - { - List parts = visit(context.rowPattern(), RowPattern.class); - return new PatternConcatenation(getLocation(context), parts); - } - - @Override - public Node visitQuantifiedPrimary(SqlBaseParser.QuantifiedPrimaryContext context) - { - RowPattern primary = (RowPattern) visit(context.patternPrimary()); - if (context.patternQuantifier() != null) { - return new QuantifiedPattern(getLocation(context), primary, (PatternQuantifier) visit(context.patternQuantifier())); - } - return primary; - } - - @Override - public Node visitPatternVariable(SqlBaseParser.PatternVariableContext context) - { - return new PatternVariable(getLocation(context), (Identifier) visit(context.identifier())); - } - - @Override - public Node visitEmptyPattern(SqlBaseParser.EmptyPatternContext context) - { - return new EmptyPattern(getLocation(context)); - } - - @Override - public Node visitPatternPermutation(SqlBaseParser.PatternPermutationContext context) - { - return new PatternPermutation(getLocation(context), visit(context.rowPattern(), RowPattern.class)); - } - - @Override - public Node visitGroupedPattern(SqlBaseParser.GroupedPatternContext context) - { - // skip parentheses - return visit(context.rowPattern()); - } - - @Override - public Node visitPartitionStartAnchor(SqlBaseParser.PartitionStartAnchorContext context) - { - return new AnchorPattern(getLocation(context), PARTITION_START); - } - - @Override - public Node visitPartitionEndAnchor(SqlBaseParser.PartitionEndAnchorContext context) - { - return new AnchorPattern(getLocation(context), PARTITION_END); - } - - @Override - public Node visitExcludedPattern(SqlBaseParser.ExcludedPatternContext context) - { - return new ExcludedPattern(getLocation(context), (RowPattern) visit(context.rowPattern())); - } - - @Override - public Node visitZeroOrMoreQuantifier(SqlBaseParser.ZeroOrMoreQuantifierContext context) - { - boolean greedy = context.reluctant == null; - return new ZeroOrMoreQuantifier(getLocation(context), greedy); - } - - @Override - public Node visitOneOrMoreQuantifier(SqlBaseParser.OneOrMoreQuantifierContext context) - { - boolean greedy = context.reluctant == null; - return new OneOrMoreQuantifier(getLocation(context), greedy); - } - - @Override - public Node visitZeroOrOneQuantifier(SqlBaseParser.ZeroOrOneQuantifierContext context) - { - boolean greedy = context.reluctant == null; - return new ZeroOrOneQuantifier(getLocation(context), greedy); - } - - @Override - public Node visitRangeQuantifier(SqlBaseParser.RangeQuantifierContext context) - { - boolean greedy = context.reluctant == null; - - Optional atLeast = Optional.empty(); - Optional atMost = Optional.empty(); - if (context.exactly != null) { - atLeast = Optional.of(new LongLiteral(getLocation(context.exactly), context.exactly.getText())); - atMost = Optional.of(new LongLiteral(getLocation(context.exactly), context.exactly.getText())); - } - if (context.atLeast != null) { - atLeast = Optional.of(new LongLiteral(getLocation(context.atLeast), context.atLeast.getText())); - } - if (context.atMost != null) { - atMost = Optional.of(new LongLiteral(getLocation(context.atMost), context.atMost.getText())); - } - return new RangeQuantifier(getLocation(context), greedy, atLeast, atMost); - } - - // ************** literals ************** - - @Override - public Node visitNullLiteral(SqlBaseParser.NullLiteralContext context) - { - return new NullLiteral(getLocation(context)); - } - - @Override - public Node visitBasicStringLiteral(SqlBaseParser.BasicStringLiteralContext context) - { - return new StringLiteral(getLocation(context), unquote(context.STRING().getText())); - } - - @Override - public Node visitUnicodeStringLiteral(SqlBaseParser.UnicodeStringLiteralContext context) - { - return new StringLiteral(getLocation(context), decodeUnicodeLiteral(context)); - } - - @Override - public Node visitEscapedCharsStringLiteral(SqlBaseParser.EscapedCharsStringLiteralContext ctx) - { - String text = ctx.ESCAPED_STRING().getText(); - return new StringLiteral(getLocation(ctx), replaceEscapedChars(unquote(text.substring(1)))); - } - - @Override - public Node visitBinaryLiteral(SqlBaseParser.BinaryLiteralContext context) - { - String raw = context.BINARY_LITERAL().getText(); - return new BinaryLiteral(getLocation(context), unquote(raw.substring(1))); - } - - @Override - public Node visitTypeConstructor(SqlBaseParser.TypeConstructorContext context) - { - checkPgSchema(context.IDENTIFIER()); // pg syntax - - String value = ((StringLiteral) visit(context.string())).getValue(); - - if (context.DOUBLE() != null) { - // TODO: Temporary hack that should be removed with new planner. - return new GenericLiteral(getLocation(context), "DOUBLE", value); - } - - String type = context.identifier().getText(); - if (type.equalsIgnoreCase("time")) { - return new TimeLiteral(getLocation(context), value); - } - if (type.equalsIgnoreCase("timestamp")) { - return new TimestampLiteral(getLocation(context), value); - } - if (type.equalsIgnoreCase("decimal")) { - return new DecimalLiteral(getLocation(context), value); - } - // bpchar for PostgreSQL wire protocol, handle blank-padding char - if (type.equalsIgnoreCase("char") || type.equalsIgnoreCase("bpchar")) { - return new CharLiteral(getLocation(context), value); - } - // for PostgreSQL wire protocol, handle interval pattern - if (type.equalsIgnoreCase("interval")) { - return IntervalLiteralUtil.parse(getLocation(context), value); - } - // for PostgreSQL wire protocol, handle bytea binary pattern - if (type.equalsIgnoreCase("bytea") && value.startsWith("\\x")) { - return new BinaryLiteral(getLocation(context), value.substring(2)); - } - - return new GenericLiteral(getLocation(context), type, value); - } - - @Override - public Node visitIntegerLiteral(SqlBaseParser.IntegerLiteralContext context) - { - return new LongLiteral(getLocation(context), context.getText()); - } - - @Override - public Node visitDecimalLiteral(SqlBaseParser.DecimalLiteralContext context) - { - switch (parsingOptions.getDecimalLiteralTreatment()) { - case AS_DOUBLE: - return new DoubleLiteral(getLocation(context), context.getText()); - case AS_DECIMAL: - return new DecimalLiteral(getLocation(context), context.getText()); - case REJECT: - throw new ParsingException("Unexpected decimal literal: " + context.getText()); - } - throw new AssertionError("Unreachable"); - } - - @Override - public Node visitDoubleLiteral(SqlBaseParser.DoubleLiteralContext context) - { - return new DoubleLiteral(getLocation(context), context.getText()); - } - - @Override - public Node visitBooleanValue(SqlBaseParser.BooleanValueContext context) - { - return new BooleanLiteral(getLocation(context), context.getText()); - } - - @Override - public Node visitInterval(SqlBaseParser.IntervalContext context) - { - return new IntervalLiteral( - getLocation(context), - ((StringLiteral) visit(context.string())).getValue(), - Optional.ofNullable(context.sign) - .map(AstBuilder::getIntervalSign) - .orElse(IntervalLiteral.Sign.POSITIVE), - getIntervalFieldType((Token) context.from.getChild(0).getPayload()), - Optional.ofNullable(context.to) - .map((x) -> x.getChild(0).getPayload()) - .map(Token.class::cast) - .map(AstBuilder::getIntervalFieldType)); - } - - @Override - public Node visitParameter(SqlBaseParser.ParameterContext context) - { - io.trino.sql.tree.Parameter parameter = new io.trino.sql.tree.Parameter(getLocation(context), parameterPosition); - parameterPosition++; - return parameter; - } - - // ***************** arguments ***************** - - @Override - public Node visitPositionalArgument(SqlBaseParser.PositionalArgumentContext context) - { - return new CallArgument(getLocation(context), (Expression) visit(context.expression())); - } - - @Override - public Node visitNamedArgument(SqlBaseParser.NamedArgumentContext context) - { - return new CallArgument(getLocation(context), (Identifier) visit(context.identifier()), (Expression) visit(context.expression())); - } - - @Override - public Node visitQualifiedArgument(SqlBaseParser.QualifiedArgumentContext context) - { - return new PathElement(getLocation(context), (Identifier) visit(context.identifier(0)), (Identifier) visit(context.identifier(1))); - } - - @Override - public Node visitUnqualifiedArgument(SqlBaseParser.UnqualifiedArgumentContext context) - { - return new PathElement(getLocation(context), (Identifier) visit(context.identifier())); - } - - @Override - public Node visitPathSpecification(SqlBaseParser.PathSpecificationContext context) - { - return new PathSpecification(getLocation(context), visit(context.pathElement(), PathElement.class)); - } - - @Override - public Node visitRowType(SqlBaseParser.RowTypeContext context) - { - List fields = context.rowField().stream() - .map(this::visit) - .map(RowDataType.Field.class::cast) - .collect(toImmutableList()); - - return new RowDataType(getLocation(context), fields); - } - - @Override - public Node visitRowField(SqlBaseParser.RowFieldContext context) - { - return new RowDataType.Field( - getLocation(context), - visitIfPresent(context.identifier(), Identifier.class), - (DataType) visit(context.type())); - } - - @Override - public Node visitGenericType(SqlBaseParser.GenericTypeContext context) - { - List parameters = context.typeParameter().stream() - .map(this::visit) - .map(DataTypeParameter.class::cast) - .collect(toImmutableList()); - - return new GenericDataType(getLocation(context), (Identifier) visit(context.identifier()), parameters); - } - - @Override - public Node visitTypeParameter(SqlBaseParser.TypeParameterContext context) - { - if (context.INTEGER_VALUE() != null) { - return new NumericParameter(getLocation(context), context.getText()); - } - - return new TypeParameter((DataType) visit(context.type())); - } - - @Override - public Node visitIntervalType(SqlBaseParser.IntervalTypeContext context) - { - String from = context.from.getText(); - String to = getTextIfPresent(context.to) - .orElse(from); - - return new IntervalDayTimeDataType( - getLocation(context), - IntervalDayTimeDataType.Field.valueOf(from.toUpperCase(ENGLISH)), - IntervalDayTimeDataType.Field.valueOf(to.toUpperCase(ENGLISH))); - } - - @Override - public Node visitDateTimeType(SqlBaseParser.DateTimeTypeContext context) - { - DateTimeDataType.Type type; - - if (context.base.getType() == TIME) { - type = DateTimeDataType.Type.TIME; - } - else if (context.base.getType() == TIMESTAMP) { - type = DateTimeDataType.Type.TIMESTAMP; - } - else { - throw new ParsingException("Unexpected datetime type: " + context.getText()); - } - - return new DateTimeDataType( - getLocation(context), - type, - context.WITH() != null, - visitIfPresent(context.precision, DataTypeParameter.class)); - } - - @Override - public Node visitDoublePrecisionType(SqlBaseParser.DoublePrecisionTypeContext context) - { - return new GenericDataType( - getLocation(context), - new Identifier(getLocation(context.DOUBLE()), context.DOUBLE().getText(), false), - ImmutableList.of()); - } - - @Override - public Node visitLegacyArrayType(SqlBaseParser.LegacyArrayTypeContext context) - { - return new GenericDataType( - getLocation(context), - new Identifier(getLocation(context.ARRAY()), context.ARRAY().getText(), false), - ImmutableList.of(new TypeParameter((DataType) visit(context.type())))); - } - - @Override - public Node visitLegacyMapType(SqlBaseParser.LegacyMapTypeContext context) - { - return new GenericDataType( - getLocation(context), - new Identifier(getLocation(context.MAP()), context.MAP().getText(), false), - ImmutableList.of( - new TypeParameter((DataType) visit(context.keyType)), - new TypeParameter((DataType) visit(context.valueType)))); - } - - @Override - public Node visitArrayType(SqlBaseParser.ArrayTypeContext context) - { - if (context.INTEGER_VALUE() != null) { - throw new UnsupportedOperationException("Explicit array size not supported"); - } - - return new GenericDataType( - getLocation(context), - new Identifier(getLocation(context.ARRAY()), context.ARRAY().getText(), false), - ImmutableList.of(new TypeParameter((DataType) visit(context.type())))); - } - - @Override - public Node visitQueryPeriod(SqlBaseParser.QueryPeriodContext context) - { - QueryPeriod.RangeType type = getRangeType((Token) context.rangeType().getChild(0).getPayload()); - Expression marker = (Expression) visit(context.valueExpression()); - return new QueryPeriod(getLocation(context), type, marker); - } - - @Override - public Node visitValueExpressionDefault(SqlBaseParser.ValueExpressionDefaultContext context) - { - // This is for pg wire protocol. - // We don't really support collate clause, so we just let it pass and do nothing. - if (context.children.size() == 2 && context.children.get(1) instanceof SqlBaseParser.CollateClauseContext) { - context.children.remove(1); - } - return super.visitValueExpressionDefault(context); - } - - // ***************** helpers ***************** - - @Override - protected Node defaultResult() - { - return null; - } - - @Override - protected Node aggregateResult(Node aggregate, Node nextResult) - { - if (nextResult == null) { - throw new UnsupportedOperationException("not yet implemented"); - } - - if (aggregate == null) { - return nextResult; - } - - throw new UnsupportedOperationException("not yet implemented"); - } - - private enum UnicodeDecodeState - { - EMPTY, - ESCAPED, - UNICODE_SEQUENCE - } - - private enum PgSetReturnFunction - { - // TODO: support other remote database - // https://github.com/Canner/canner-metric-layer/issues/62 - // the array generating function in bigquery call 'generate_array`. - GENERATE_SERIES("generate_series", "generate_array"); - - private final String pgFuncName; - private final String prestoFuncName; - - PgSetReturnFunction(String pgFuncName, String prestoFuncName) - { - this.pgFuncName = pgFuncName; - this.prestoFuncName = prestoFuncName; - } - - public String getPgFuncName() - { - return pgFuncName; - } - - public String getRemoteFuncName() - { - return prestoFuncName; - } - } - - private static String decodeUnicodeLiteral(SqlBaseParser.UnicodeStringLiteralContext context) - { - char escape; - if (context.UESCAPE() != null) { - String escapeString = unquote(context.STRING().getText()); - check(!escapeString.isEmpty(), "Empty Unicode escape character", context); - check(escapeString.length() == 1, "Invalid Unicode escape character: " + escapeString, context); - escape = escapeString.charAt(0); - check(isValidUnicodeEscape(escape), "Invalid Unicode escape character: " + escapeString, context); - } - else { - escape = '\\'; - } - - String rawContent = unquote(context.UNICODE_STRING().getText().substring(2)); - StringBuilder unicodeStringBuilder = new StringBuilder(); - StringBuilder escapedCharacterBuilder = new StringBuilder(); - int charactersNeeded = 0; - UnicodeDecodeState state = UnicodeDecodeState.EMPTY; - for (int i = 0; i < rawContent.length(); i++) { - char ch = rawContent.charAt(i); - switch (state) { - case EMPTY: - if (ch == escape) { - state = UnicodeDecodeState.ESCAPED; - } - else { - unicodeStringBuilder.append(ch); - } - break; - case ESCAPED: - if (ch == escape) { - unicodeStringBuilder.append(escape); - state = UnicodeDecodeState.EMPTY; - } - else if (ch == '+') { - state = UnicodeDecodeState.UNICODE_SEQUENCE; - charactersNeeded = 6; - } - else if (isHexDigit(ch)) { - state = UnicodeDecodeState.UNICODE_SEQUENCE; - charactersNeeded = 4; - escapedCharacterBuilder.append(ch); - } - else { - throw parseError("Invalid hexadecimal digit: " + ch, context); - } - break; - case UNICODE_SEQUENCE: - check(isHexDigit(ch), "Incomplete escape sequence: " + escapedCharacterBuilder.toString(), context); - escapedCharacterBuilder.append(ch); - if (charactersNeeded == escapedCharacterBuilder.length()) { - String currentEscapedCode = escapedCharacterBuilder.toString(); - escapedCharacterBuilder.setLength(0); - int codePoint = Integer.parseInt(currentEscapedCode, 16); - check(Character.isValidCodePoint(codePoint), "Invalid escaped character: " + currentEscapedCode, context); - if (Character.isSupplementaryCodePoint(codePoint)) { - unicodeStringBuilder.appendCodePoint(codePoint); - } - else { - char currentCodePoint = (char) codePoint; - check(!Character.isSurrogate(currentCodePoint), format("Invalid escaped character: %s. Escaped character is a surrogate. Use '\\+123456' instead.", currentEscapedCode), context); - unicodeStringBuilder.append(currentCodePoint); - } - state = UnicodeDecodeState.EMPTY; - charactersNeeded = -1; - } - else { - check(charactersNeeded > escapedCharacterBuilder.length(), "Unexpected escape sequence length: " + escapedCharacterBuilder.length(), context); - } - break; - default: - throw new UnsupportedOperationException(); - } - } - - check(state == UnicodeDecodeState.EMPTY, "Incomplete escape sequence: " + escapedCharacterBuilder.toString(), context); - return unicodeStringBuilder.toString(); - } - - private Optional visitIfPresent(ParserRuleContext context, Class clazz) - { - return Optional.ofNullable(context) - .map(this::visit) - .map(clazz::cast); - } - - private List visit(List contexts, Class clazz) - { - return contexts.stream() - .map(this::visit) - .map(clazz::cast) - .collect(toList()); - } - - private static String unquote(String value) - { - return value.substring(1, value.length() - 1) - .replace("''", "'"); - } - - private static LikeClause.PropertiesOption getPropertiesOption(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.INCLUDING: - return LikeClause.PropertiesOption.INCLUDING; - case SqlBaseLexer.EXCLUDING: - return LikeClause.PropertiesOption.EXCLUDING; - } - throw new IllegalArgumentException("Unsupported LIKE option type: " + token.getText()); - } - - private QualifiedName getQualifiedName(SqlBaseParser.QualifiedNameContext context) - { - return QualifiedName.of(visit(context.identifier(), Identifier.class)); - } - - private static boolean isDistinct(SqlBaseParser.SetQuantifierContext setQuantifier) - { - return setQuantifier != null && setQuantifier.DISTINCT() != null; - } - - private static boolean isHexDigit(char c) - { - return ((c >= '0') && (c <= '9')) || - ((c >= 'A') && (c <= 'F')) || - ((c >= 'a') && (c <= 'f')); - } - - private static boolean isValidUnicodeEscape(char c) - { - return c < 0x7F && c > 0x20 && !isHexDigit(c) && c != '"' && c != '+' && c != '\''; - } - - private static Optional getTextIfPresent(ParserRuleContext context) - { - return Optional.ofNullable(context) - .map(ParseTree::getText); - } - - private Optional getIdentifierIfPresent(ParserRuleContext context) - { - return Optional.ofNullable(context).map(c -> (Identifier) visit(c)); - } - - private static ArithmeticBinaryExpression.Operator getArithmeticBinaryOperator(Token operator) - { - switch (operator.getType()) { - case SqlBaseLexer.PLUS: - return ArithmeticBinaryExpression.Operator.ADD; - case SqlBaseLexer.MINUS: - return ArithmeticBinaryExpression.Operator.SUBTRACT; - case SqlBaseLexer.ASTERISK: - return ArithmeticBinaryExpression.Operator.MULTIPLY; - case SqlBaseLexer.SLASH: - return ArithmeticBinaryExpression.Operator.DIVIDE; - case SqlBaseLexer.PERCENT: - return ArithmeticBinaryExpression.Operator.MODULUS; - } - - throw new UnsupportedOperationException("Unsupported operator: " + operator.getText()); - } - - private static ComparisonExpression.Operator getComparisonOperator(Token symbol) - { - switch (symbol.getType()) { - case SqlBaseLexer.EQ: - return ComparisonExpression.Operator.EQUAL; - case SqlBaseLexer.NEQ: - return ComparisonExpression.Operator.NOT_EQUAL; - case SqlBaseLexer.LT: - return ComparisonExpression.Operator.LESS_THAN; - case SqlBaseLexer.LTE: - return ComparisonExpression.Operator.LESS_THAN_OR_EQUAL; - case SqlBaseLexer.GT: - return ComparisonExpression.Operator.GREATER_THAN; - case SqlBaseLexer.GTE: - return ComparisonExpression.Operator.GREATER_THAN_OR_EQUAL; - } - - throw new IllegalArgumentException("Unsupported operator: " + symbol.getText()); - } - - private static CurrentTime.Function getDateTimeFunctionType(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.CURRENT_DATE: - return CurrentTime.Function.DATE; - case SqlBaseLexer.CURRENT_TIME: - return CurrentTime.Function.TIME; - case SqlBaseLexer.CURRENT_TIMESTAMP: - return CurrentTime.Function.TIMESTAMP; - case SqlBaseLexer.LOCALTIME: - return CurrentTime.Function.LOCALTIME; - case SqlBaseLexer.LOCALTIMESTAMP: - return CurrentTime.Function.LOCALTIMESTAMP; - } - - throw new IllegalArgumentException("Unsupported special function: " + token.getText()); - } - - private static IntervalLiteral.IntervalField getIntervalFieldType(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.YEAR: - return IntervalLiteral.IntervalField.YEAR; - case SqlBaseLexer.MONTH: - return IntervalLiteral.IntervalField.MONTH; - case SqlBaseLexer.DAY: - return IntervalLiteral.IntervalField.DAY; - case SqlBaseLexer.HOUR: - return IntervalLiteral.IntervalField.HOUR; - case SqlBaseLexer.MINUTE: - return IntervalLiteral.IntervalField.MINUTE; - case SqlBaseLexer.SECOND: - return IntervalLiteral.IntervalField.SECOND; - } - - throw new IllegalArgumentException("Unsupported interval field: " + token.getText()); - } - - private static IntervalLiteral.Sign getIntervalSign(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.MINUS: - return IntervalLiteral.Sign.NEGATIVE; - case SqlBaseLexer.PLUS: - return IntervalLiteral.Sign.POSITIVE; - } - - throw new IllegalArgumentException("Unsupported sign: " + token.getText()); - } - - private static WindowFrame.Type getFrameType(Token type) - { - switch (type.getType()) { - case SqlBaseLexer.RANGE: - return WindowFrame.Type.RANGE; - case SqlBaseLexer.ROWS: - return WindowFrame.Type.ROWS; - case SqlBaseLexer.GROUPS: - return WindowFrame.Type.GROUPS; - } - - throw new IllegalArgumentException("Unsupported frame type: " + type.getText()); - } - - private static FrameBound.Type getBoundedFrameBoundType(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.PRECEDING: - return FrameBound.Type.PRECEDING; - case SqlBaseLexer.FOLLOWING: - return FrameBound.Type.FOLLOWING; - } - - throw new IllegalArgumentException("Unsupported bound type: " + token.getText()); - } - - private static FrameBound.Type getUnboundedFrameBoundType(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.PRECEDING: - return FrameBound.Type.UNBOUNDED_PRECEDING; - case SqlBaseLexer.FOLLOWING: - return FrameBound.Type.UNBOUNDED_FOLLOWING; - } - - throw new IllegalArgumentException("Unsupported bound type: " + token.getText()); - } - - private static SampledRelation.Type getSamplingMethod(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.BERNOULLI: - return SampledRelation.Type.BERNOULLI; - case SqlBaseLexer.SYSTEM: - return SampledRelation.Type.SYSTEM; - } - - throw new IllegalArgumentException("Unsupported sampling method: " + token.getText()); - } - - private static SortItem.NullOrdering getNullOrderingType(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.FIRST: - return SortItem.NullOrdering.FIRST; - case SqlBaseLexer.LAST: - return SortItem.NullOrdering.LAST; - } - - throw new IllegalArgumentException("Unsupported ordering: " + token.getText()); - } - - private static SortItem.Ordering getOrderingType(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.ASC: - return SortItem.Ordering.ASCENDING; - case SqlBaseLexer.DESC: - return SortItem.Ordering.DESCENDING; - } - - throw new IllegalArgumentException("Unsupported ordering: " + token.getText()); - } - - private static QuantifiedComparisonExpression.Quantifier getComparisonQuantifier(Token symbol) - { - switch (symbol.getType()) { - case SqlBaseLexer.ALL: - return QuantifiedComparisonExpression.Quantifier.ALL; - case SqlBaseLexer.ANY: - return QuantifiedComparisonExpression.Quantifier.ANY; - case SqlBaseLexer.SOME: - return QuantifiedComparisonExpression.Quantifier.SOME; - } - - throw new IllegalArgumentException("Unsupported quantifier: " + symbol.getText()); - } - - private List getIdentifiers(List identifiers) - { - return identifiers.stream().map(context -> (Identifier) visit(context)).collect(toList()); - } - - private List getPrincipalSpecifications(List principals) - { - return principals.stream().map(this::getPrincipalSpecification).collect(toList()); - } - - private Optional getGrantorSpecificationIfPresent(SqlBaseParser.GrantorContext context) - { - return Optional.ofNullable(context).map(this::getGrantorSpecification); - } - - private GrantorSpecification getGrantorSpecification(SqlBaseParser.GrantorContext context) - { - if (context instanceof SqlBaseParser.SpecifiedPrincipalContext) { - return new GrantorSpecification(GrantorSpecification.Type.PRINCIPAL, Optional.of(getPrincipalSpecification(((SqlBaseParser.SpecifiedPrincipalContext) context).principal()))); - } - else if (context instanceof SqlBaseParser.CurrentUserGrantorContext) { - return new GrantorSpecification(GrantorSpecification.Type.CURRENT_USER, Optional.empty()); - } - else if (context instanceof SqlBaseParser.CurrentRoleGrantorContext) { - return new GrantorSpecification(GrantorSpecification.Type.CURRENT_ROLE, Optional.empty()); - } - else { - throw new IllegalArgumentException("Unsupported grantor: " + context); - } - } - - private PrincipalSpecification getPrincipalSpecification(SqlBaseParser.PrincipalContext context) - { - if (context instanceof SqlBaseParser.UnspecifiedPrincipalContext) { - return new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, (Identifier) visit(((SqlBaseParser.UnspecifiedPrincipalContext) context).identifier())); - } - else if (context instanceof SqlBaseParser.UserPrincipalContext) { - return new PrincipalSpecification(PrincipalSpecification.Type.USER, (Identifier) visit(((SqlBaseParser.UserPrincipalContext) context).identifier())); - } - else if (context instanceof SqlBaseParser.RolePrincipalContext) { - return new PrincipalSpecification(PrincipalSpecification.Type.ROLE, (Identifier) visit(((SqlBaseParser.RolePrincipalContext) context).identifier())); - } - else { - throw new IllegalArgumentException("Unsupported principal: " + context); - } - } - - private static void check(boolean condition, String message, ParserRuleContext context) - { - if (!condition) { - throw parseError(message, context); - } - } - - public static NodeLocation getLocation(TerminalNode terminalNode) - { - requireNonNull(terminalNode, "terminalNode is null"); - return getLocation(terminalNode.getSymbol()); - } - - public static NodeLocation getLocation(ParserRuleContext parserRuleContext) - { - requireNonNull(parserRuleContext, "parserRuleContext is null"); - return getLocation(parserRuleContext.getStart()); - } - - public static NodeLocation getLocation(Token token) - { - requireNonNull(token, "token is null"); - return new NodeLocation(token.getLine(), token.getCharPositionInLine() + 1); - } - - private static ParsingException parseError(String message, ParserRuleContext context) - { - return new ParsingException(message, null, context.getStart().getLine(), context.getStart().getCharPositionInLine() + 1); - } - - private static QueryPeriod.RangeType getRangeType(Token token) - { - switch (token.getType()) { - case SqlBaseLexer.TIMESTAMP: - return QueryPeriod.RangeType.TIMESTAMP; - case SqlBaseLexer.VERSION: - return QueryPeriod.RangeType.VERSION; - } - throw new IllegalArgumentException("Unsupported query period range type: " + token.getText()); - } - - /** - * PostgreSQL syntax - */ - private static void checkPgSchema(TerminalNode identifier) - { - if (isNull(identifier) || identifier.getText().equals("pg_catalog")) { - return; - } - - throw new IllegalArgumentException("Unsupported pg schema"); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/CaseInsensitiveStream.java b/trino-parser/src/main/java/io/trino/sql/parser/CaseInsensitiveStream.java deleted file mode 100644 index 8a0d665dd..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/CaseInsensitiveStream.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.IntStream; -import org.antlr.v4.runtime.misc.Interval; - -public class CaseInsensitiveStream - implements CharStream -{ - private final CharStream stream; - - public CaseInsensitiveStream(CharStream stream) - { - this.stream = stream; - } - - @Override - public String getText(Interval interval) - { - return stream.getText(interval); - } - - @Override - public void consume() - { - stream.consume(); - } - - @Override - public int LA(int i) - { - int result = stream.LA(i); - - switch (result) { - case 0: - case IntStream.EOF: - return result; - default: - return Character.toUpperCase(result); - } - } - - @Override - public int mark() - { - return stream.mark(); - } - - @Override - public void release(int marker) - { - stream.release(marker); - } - - @Override - public int index() - { - return stream.index(); - } - - @Override - public void seek(int index) - { - stream.seek(index); - } - - @Override - public int size() - { - return stream.size(); - } - - @Override - public String getSourceName() - { - return stream.getSourceName(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/DelimiterLexer.java b/trino-parser/src/main/java/io/trino/sql/parser/DelimiterLexer.java deleted file mode 100644 index 20a73c62f..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/DelimiterLexer.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import com.google.common.collect.ImmutableSet; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.IntStream; -import org.antlr.v4.runtime.LexerNoViableAltException; -import org.antlr.v4.runtime.Token; - -import java.util.Set; - -/** - * This is a special-purpose lexer that can identify custom delimiters in addition to every other - * token in the SQL grammar. - *

- * The code in nextToken() is a copy of the implementation in org.antlr.v4.runtime.Lexer, with a - * bit added to match the token before the default behavior is invoked. - */ -class DelimiterLexer - extends SqlBaseLexer -{ - private final Set delimiters; - - public DelimiterLexer(CharStream input, Set delimiters) - { - super(input); - this.delimiters = ImmutableSet.copyOf(delimiters); - } - - @Override - public Token nextToken() - { - if (_input == null) { - throw new IllegalStateException("nextToken requires a non-null input stream."); - } - - // Mark start location in char stream so unbuffered streams are - // guaranteed at least have text of current token - int tokenStartMarker = _input.mark(); - try { - outer: - while (true) { - if (_hitEOF) { - emitEOF(); - return _token; - } - - _token = null; - _channel = Token.DEFAULT_CHANNEL; - _tokenStartCharIndex = _input.index(); - _tokenStartCharPositionInLine = getInterpreter().getCharPositionInLine(); - _tokenStartLine = getInterpreter().getLine(); - _text = null; - do { - _type = Token.INVALID_TYPE; - int ttype = -1; - - // This entire method is copied from org.antlr.v4.runtime.Lexer, with the following bit - // added to match the delimiters before we attempt to match the token - boolean found = false; - for (String terminator : delimiters) { - if (match(terminator)) { - ttype = SqlBaseParser.DELIMITER; - found = true; - break; - } - } - - if (!found) { - try { - ttype = getInterpreter().match(_input, _mode); - } - catch (LexerNoViableAltException e) { - notifyListeners(e); // report error - recover(e); - ttype = SKIP; - } - } - - if (_input.LA(1) == IntStream.EOF) { - _hitEOF = true; - } - if (_type == Token.INVALID_TYPE) { - _type = ttype; - } - if (_type == SKIP) { - continue outer; - } - } - while (_type == MORE); - if (_token == null) { - emit(); - } - return _token; - } - } - finally { - // make sure we release marker after match or - // unbuffered char stream will keep buffering - _input.release(tokenStartMarker); - } - } - - private boolean match(String delimiter) - { - for (int i = 0; i < delimiter.length(); i++) { - if (_input.LA(i + 1) != delimiter.charAt(i)) { - return false; - } - } - _input.seek(_input.index() + delimiter.length()); - return true; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/ErrorHandler.java b/trino-parser/src/main/java/io/trino/sql/parser/ErrorHandler.java deleted file mode 100644 index f11601cc2..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/ErrorHandler.java +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import com.google.common.collect.ImmutableSet; -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.NoViableAltException; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.RuleContext; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenStream; -import org.antlr.v4.runtime.Vocabulary; -import org.antlr.v4.runtime.atn.ATN; -import org.antlr.v4.runtime.atn.ATNState; -import org.antlr.v4.runtime.atn.NotSetTransition; -import org.antlr.v4.runtime.atn.PrecedencePredicateTransition; -import org.antlr.v4.runtime.atn.RuleStartState; -import org.antlr.v4.runtime.atn.RuleStopState; -import org.antlr.v4.runtime.atn.RuleTransition; -import org.antlr.v4.runtime.atn.Transition; -import org.antlr.v4.runtime.atn.WildcardTransition; -import org.antlr.v4.runtime.misc.IntervalSet; - -import java.util.ArrayDeque; -import java.util.Deque; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import static com.google.common.base.MoreObjects.firstNonNull; -import static java.lang.String.format; -import static java.util.logging.Level.SEVERE; -import static org.antlr.v4.runtime.atn.ATNState.RULE_START; - -class ErrorHandler - extends BaseErrorListener -{ - private static final Logger LOG = Logger.getLogger(ErrorHandler.class.getName()); - - private final Map specialRules; - private final Map specialTokens; - private final Set ignoredRules; - - private ErrorHandler(Map specialRules, Map specialTokens, Set ignoredRules) - { - this.specialRules = new HashMap<>(specialRules); - this.specialTokens = specialTokens; - this.ignoredRules = new HashSet<>(ignoredRules); - } - - @Override - public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String message, RecognitionException e) - { - try { - Parser parser = (Parser) recognizer; - - ATN atn = parser.getATN(); - - ATNState currentState; - Token currentToken; - RuleContext context; - - if (e != null) { - currentState = atn.states.get(e.getOffendingState()); - currentToken = e.getOffendingToken(); - context = e.getCtx(); - - if (e instanceof NoViableAltException) { - currentToken = ((NoViableAltException) e).getStartToken(); - } - } - else { - currentState = atn.states.get(parser.getState()); - currentToken = parser.getCurrentToken(); - context = parser.getContext(); - } - - Analyzer analyzer = new Analyzer(parser, specialRules, specialTokens, ignoredRules); - Result result = analyzer.process(currentState, currentToken.getTokenIndex(), context); - - // pick the candidate tokens associated largest token index processed (i.e., the path that consumed the most input) - String expected = result.getExpected().stream() - .sorted() - .collect(Collectors.joining(", ")); - - message = format("mismatched input '%s'. Expecting: %s", parser.getTokenStream().get(result.getErrorTokenIndex()).getText(), expected); - } - catch (Exception exception) { - LOG.log(SEVERE, "Unexpected failure when handling parsing error. This is likely a bug in the implementation", exception); - } - - throw new ParsingException(message, e, line, charPositionInLine + 1); - } - - private static class ParsingState - { - public final ATNState state; - public final int tokenIndex; - public final boolean suppressed; - public final Parser parser; - - public ParsingState(ATNState state, int tokenIndex, boolean suppressed, Parser parser) - { - this.state = state; - this.tokenIndex = tokenIndex; - this.suppressed = suppressed; - this.parser = parser; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ParsingState that = (ParsingState) o; - return tokenIndex == that.tokenIndex && - state.equals(that.state); - } - - @Override - public int hashCode() - { - return Objects.hash(state, tokenIndex); - } - - @Override - public String toString() - { - Token token = parser.getTokenStream().get(tokenIndex); - - String text = firstNonNull(token.getText(), "?"); - if (text != null) { - text = text.replace("\\", "\\\\"); - text = text.replace("\n", "\\n"); - text = text.replace("\r", "\\r"); - text = text.replace("\t", "\\t"); - } - - return format( - "%s%s:%s @ %s:<%s>:%s", - suppressed ? "-" : "+", - parser.getRuleNames()[state.ruleIndex], - state.stateNumber, - tokenIndex, - parser.getVocabulary().getSymbolicName(token.getType()), - text); - } - } - - private static class Analyzer - { - private final Parser parser; - private final ATN atn; - private final Vocabulary vocabulary; - private final Map specialRules; - private final Map specialTokens; - private final Set ignoredRules; - private final TokenStream stream; - - private int furthestTokenIndex = -1; - private final Set candidates = new HashSet<>(); - - private final Map> memo = new HashMap<>(); - - public Analyzer( - Parser parser, - Map specialRules, - Map specialTokens, - Set ignoredRules) - { - this.parser = parser; - this.stream = parser.getTokenStream(); - this.atn = parser.getATN(); - this.vocabulary = parser.getVocabulary(); - this.specialRules = specialRules; - this.specialTokens = specialTokens; - this.ignoredRules = ignoredRules; - } - - public Result process(ATNState currentState, int tokenIndex, RuleContext context) - { - RuleStartState startState = atn.ruleToStartState[currentState.ruleIndex]; - - if (isReachable(currentState, startState)) { - // We've been dropped inside a rule in a state that's reachable via epsilon transitions. This is, - // effectively, equivalent to starting at the beginning (or immediately outside) the rule. - // In that case, backtrack to the beginning to be able to take advantage of logic that remaps - // some rules to well-known names for reporting purposes - currentState = startState; - } - - Set endTokens = process(new ParsingState(currentState, tokenIndex, false, parser), 0); - Set nextTokens = new HashSet<>(); - while (!endTokens.isEmpty() && context.invokingState != -1) { - for (int endToken : endTokens) { - ATNState nextState = ((RuleTransition) atn.states.get(context.invokingState).transition(0)).followState; - nextTokens.addAll(process(new ParsingState(nextState, endToken, false, parser), 0)); - } - context = context.parent; - endTokens = nextTokens; - } - - return new Result(furthestTokenIndex, candidates); - } - - private boolean isReachable(ATNState target, RuleStartState from) - { - Deque activeStates = new ArrayDeque<>(); - activeStates.add(from); - - while (!activeStates.isEmpty()) { - ATNState current = activeStates.pop(); - - if (current.stateNumber == target.stateNumber) { - return true; - } - - for (int i = 0; i < current.getNumberOfTransitions(); i++) { - Transition transition = current.transition(i); - - if (transition.isEpsilon()) { - activeStates.push(transition.target); - } - } - } - - return false; - } - - private Set process(ParsingState start, int precedence) - { - Set result = memo.get(start); - if (result != null) { - return result; - } - - ImmutableSet.Builder endTokens = ImmutableSet.builder(); - - // Simulates the ATN by consuming input tokens and walking transitions. - // The ATN can be in multiple states (similar to an NFA) - Deque activeStates = new ArrayDeque<>(); - activeStates.add(start); - - while (!activeStates.isEmpty()) { - ParsingState current = activeStates.pop(); - - ATNState state = current.state; - int tokenIndex = current.tokenIndex; - boolean suppressed = current.suppressed; - - while (stream.get(tokenIndex).getChannel() == Token.HIDDEN_CHANNEL) { - // Ignore whitespace - tokenIndex++; - } - int currentToken = stream.get(tokenIndex).getType(); - - if (state.getStateType() == RULE_START) { - int rule = state.ruleIndex; - - if (specialRules.containsKey(rule)) { - if (!suppressed) { - record(tokenIndex, specialRules.get(rule)); - } - suppressed = true; - } - else if (ignoredRules.contains(rule)) { - // TODO expand ignored rules like we expand special rules - continue; - } - } - - if (state instanceof RuleStopState) { - endTokens.add(tokenIndex); - continue; - } - - for (int i = 0; i < state.getNumberOfTransitions(); i++) { - Transition transition = state.transition(i); - - if (transition instanceof RuleTransition) { - RuleTransition ruleTransition = (RuleTransition) transition; - for (int endToken : process(new ParsingState(ruleTransition.target, tokenIndex, suppressed, parser), ruleTransition.precedence)) { - activeStates.push(new ParsingState(ruleTransition.followState, endToken, suppressed, parser)); - } - } - else if (transition instanceof PrecedencePredicateTransition) { - if (precedence < ((PrecedencePredicateTransition) transition).precedence) { - activeStates.push(new ParsingState(transition.target, tokenIndex, suppressed, parser)); - } - } - else if (transition.isEpsilon()) { - activeStates.push(new ParsingState(transition.target, tokenIndex, suppressed, parser)); - } - else if (transition instanceof WildcardTransition) { - throw new UnsupportedOperationException("not yet implemented: wildcard transition"); - } - else { - IntervalSet labels = transition.label(); - - if (transition instanceof NotSetTransition) { - labels = labels.complement(IntervalSet.of(Token.MIN_USER_TOKEN_TYPE, atn.maxTokenType)); - } - - // Surprisingly, TokenStream (i.e. BufferedTokenStream) may not have loaded all the tokens from the - // underlying stream. TokenStream.get() does not force tokens to be buffered -- it just returns what's - // in the current buffer, or fail with an IndexOutOfBoundsError. Since Antlr decided the error occurred - // within the current set of buffered tokens, stop when we reach the end of the buffer. - if (labels.contains(currentToken) && tokenIndex < stream.size() - 1) { - activeStates.push(new ParsingState(transition.target, tokenIndex + 1, false, parser)); - } - else { - if (!suppressed) { - record(tokenIndex, getTokenNames(labels)); - } - } - } - } - } - - result = endTokens.build(); - memo.put(start, result); - return result; - } - - private void record(int tokenIndex, String label) - { - record(tokenIndex, ImmutableSet.of(label)); - } - - private void record(int tokenIndex, Set labels) - { - if (tokenIndex >= furthestTokenIndex) { - if (tokenIndex > furthestTokenIndex) { - candidates.clear(); - furthestTokenIndex = tokenIndex; - } - - candidates.addAll(labels); - } - } - - private Set getTokenNames(IntervalSet tokens) - { - Set names = new HashSet<>(); - for (int i = 0; i < tokens.size(); i++) { - int token = tokens.get(i); - if (token == Token.EOF) { - names.add(""); - } - else { - names.add(specialTokens.getOrDefault(token, vocabulary.getDisplayName(token))); - } - } - - return names; - } - } - - public static Builder builder() - { - return new Builder(); - } - - public static class Builder - { - private final Map specialRules = new HashMap<>(); - private final Map specialTokens = new HashMap<>(); - private final Set ignoredRules = new HashSet<>(); - - public Builder specialRule(int ruleId, String name) - { - specialRules.put(ruleId, name); - return this; - } - - public Builder specialToken(int tokenId, String name) - { - specialTokens.put(tokenId, name); - return this; - } - - public Builder ignoredRule(int ruleId) - { - ignoredRules.add(ruleId); - return this; - } - - public ErrorHandler build() - { - return new ErrorHandler(specialRules, specialTokens, ignoredRules); - } - } - - private static class Result - { - private final int errorTokenIndex; - private final Set expected; - - public Result(int errorTokenIndex, Set expected) - { - this.errorTokenIndex = errorTokenIndex; - this.expected = expected; - } - - public int getErrorTokenIndex() - { - return errorTokenIndex; - } - - public Set getExpected() - { - return expected; - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/ParsingException.java b/trino-parser/src/main/java/io/trino/sql/parser/ParsingException.java deleted file mode 100644 index 3882d54f0..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/ParsingException.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import io.trino.sql.tree.NodeLocation; -import org.antlr.v4.runtime.RecognitionException; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.lang.String.format; - -public class ParsingException - extends RuntimeException -{ - private final int line; - private final int column; - - public ParsingException(String message, RecognitionException cause, int line, int column) - { - super(message, cause); - checkArgument(line > 0, "line must be > 0"); - checkArgument(column > 0, "column must be > 0"); - - this.line = line; - this.column = column; - } - - public ParsingException(String message) - { - this(message, null, 1, 1); - } - - public ParsingException(String message, NodeLocation nodeLocation) - { - this(message, null, nodeLocation.getLineNumber(), nodeLocation.getColumnNumber()); - } - - public int getLineNumber() - { - return line; - } - - public int getColumnNumber() - { - return column; - } - - public String getErrorMessage() - { - return super.getMessage(); - } - - @Override - public String getMessage() - { - return format("line %s:%s: %s", getLineNumber(), getColumnNumber(), getErrorMessage()); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/ParsingOptions.java b/trino-parser/src/main/java/io/trino/sql/parser/ParsingOptions.java deleted file mode 100644 index 4f0b203fe..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/ParsingOptions.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import static java.util.Objects.requireNonNull; - -public class ParsingOptions -{ - public enum DecimalLiteralTreatment - { - AS_DOUBLE, - AS_DECIMAL, - REJECT - } - - private final DecimalLiteralTreatment decimalLiteralTreatment; - - public ParsingOptions() - { - this(DecimalLiteralTreatment.REJECT); - } - - public ParsingOptions(DecimalLiteralTreatment decimalLiteralTreatment) - { - this.decimalLiteralTreatment = requireNonNull(decimalLiteralTreatment, "decimalLiteralTreatment is null"); - } - - public DecimalLiteralTreatment getDecimalLiteralTreatment() - { - return decimalLiteralTreatment; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/RefreshableSqlBaseParserInitializer.java b/trino-parser/src/main/java/io/trino/sql/parser/RefreshableSqlBaseParserInitializer.java deleted file mode 100644 index 91a207d15..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/RefreshableSqlBaseParserInitializer.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import javax.annotation.concurrent.ThreadSafe; - -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.BiConsumer; - -@ThreadSafe -public final class RefreshableSqlBaseParserInitializer - implements BiConsumer -{ - private final AtomicReference caches = new AtomicReference<>(); - - public RefreshableSqlBaseParserInitializer() - { - refresh(); - } - - public void refresh() - { - caches.set(new SqlBaseParserAndLexerATNCaches()); - } - - @Override - public void accept(SqlBaseLexer lexer, SqlBaseParser parser) - { - SqlBaseParserAndLexerATNCaches caches = this.caches.get(); - caches.lexer.configureLexer(lexer); - caches.parser.configureParser(parser); - } - - private static final class SqlBaseParserAndLexerATNCaches - { - public final AntlrATNCacheFields lexer = new AntlrATNCacheFields(SqlBaseLexer._ATN); - public final AntlrATNCacheFields parser = new AntlrATNCacheFields(SqlBaseParser._ATN); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/SqlParser.java b/trino-parser/src/main/java/io/trino/sql/parser/SqlParser.java deleted file mode 100644 index 3b8c856de..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/SqlParser.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import io.trino.sql.tree.DataType; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.PathSpecification; -import io.trino.sql.tree.RowPattern; -import io.trino.sql.tree.Statement; -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonToken; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.DefaultErrorStrategy; -import org.antlr.v4.runtime.InputMismatchException; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.Pair; -import org.antlr.v4.runtime.misc.ParseCancellationException; -import org.antlr.v4.runtime.tree.TerminalNode; - -import java.util.Arrays; -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.Function; - -import static java.util.Objects.requireNonNull; - -public class SqlParser -{ - private static final BaseErrorListener LEXER_ERROR_LISTENER = new BaseErrorListener() - { - @Override - public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String message, RecognitionException e) - { - throw new ParsingException(message, e, line, charPositionInLine + 1); - } - }; - private static final BiConsumer DEFAULT_PARSER_INITIALIZER = (SqlBaseLexer lexer, SqlBaseParser parser) -> {}; - - private static final ErrorHandler PARSER_ERROR_HANDLER = ErrorHandler.builder() - .specialRule(SqlBaseParser.RULE_expression, "") - .specialRule(SqlBaseParser.RULE_booleanExpression, "") - .specialRule(SqlBaseParser.RULE_valueExpression, "") - .specialRule(SqlBaseParser.RULE_primaryExpression, "") - .specialRule(SqlBaseParser.RULE_predicate, "") - .specialRule(SqlBaseParser.RULE_identifier, "") - .specialRule(SqlBaseParser.RULE_string, "") - .specialRule(SqlBaseParser.RULE_query, "") - .specialRule(SqlBaseParser.RULE_type, "") - .specialToken(SqlBaseLexer.INTEGER_VALUE, "") - .ignoredRule(SqlBaseParser.RULE_nonReserved) - .build(); - - private final BiConsumer initializer; - - public SqlParser() - { - this(DEFAULT_PARSER_INITIALIZER); - } - - public SqlParser(BiConsumer initializer) - { - this.initializer = requireNonNull(initializer, "initializer is null"); - } - - public Statement createStatement(String sql, ParsingOptions parsingOptions) - { - return (Statement) invokeParser("statement", sql, SqlBaseParser::singleStatement, parsingOptions); - } - - public Expression createExpression(String expression, ParsingOptions parsingOptions) - { - return (Expression) invokeParser("expression", expression, SqlBaseParser::standaloneExpression, parsingOptions); - } - - public DataType createType(String expression) - { - return (DataType) invokeParser("type", expression, SqlBaseParser::standaloneType, new ParsingOptions()); - } - - public PathSpecification createPathSpecification(String expression) - { - return (PathSpecification) invokeParser("path specification", expression, SqlBaseParser::standalonePathSpecification, new ParsingOptions()); - } - - public RowPattern createRowPattern(String pattern) - { - return (RowPattern) invokeParser("row pattern", pattern, SqlBaseParser::standaloneRowPattern, new ParsingOptions()); - } - - private Node invokeParser(String name, String sql, Function parseFunction, ParsingOptions parsingOptions) - { - try { - SqlBaseLexer lexer = new SqlBaseLexer(new CaseInsensitiveStream(CharStreams.fromString(sql))); - CommonTokenStream tokenStream = new CommonTokenStream(lexer); - SqlBaseParser parser = new SqlBaseParser(tokenStream); - initializer.accept(lexer, parser); - - // Override the default error strategy to not attempt inserting or deleting a token. - // Otherwise, it messes up error reporting - parser.setErrorHandler(new DefaultErrorStrategy() - { - @Override - public Token recoverInline(Parser recognizer) - throws RecognitionException - { - if (nextTokensContext == null) { - throw new InputMismatchException(recognizer); - } - else { - throw new InputMismatchException(recognizer, nextTokensState, nextTokensContext); - } - } - }); - - parser.addParseListener(new PostProcessor(Arrays.asList(parser.getRuleNames()), parser)); - - lexer.removeErrorListeners(); - lexer.addErrorListener(LEXER_ERROR_LISTENER); - - parser.removeErrorListeners(); - parser.addErrorListener(PARSER_ERROR_HANDLER); - - ParserRuleContext tree; - try { - // first, try parsing with potentially faster SLL mode - parser.getInterpreter().setPredictionMode(PredictionMode.SLL); - tree = parseFunction.apply(parser); - } - catch (ParseCancellationException ex) { - // if we fail, parse with LL mode - tokenStream.seek(0); // rewind input stream - parser.reset(); - - parser.getInterpreter().setPredictionMode(PredictionMode.LL); - tree = parseFunction.apply(parser); - } - - return new AstBuilder(parsingOptions).visit(tree); - } - catch (StackOverflowError e) { - throw new ParsingException(name + " is too large (stack overflow while parsing)"); - } - } - - private static class PostProcessor - extends SqlBaseBaseListener - { - private final List ruleNames; - private final SqlBaseParser parser; - - public PostProcessor(List ruleNames, SqlBaseParser parser) - { - this.ruleNames = ruleNames; - this.parser = parser; - } - - @Override - public void exitQuotedIdentifier(SqlBaseParser.QuotedIdentifierContext context) - { - Token token = context.QUOTED_IDENTIFIER().getSymbol(); - if (token.getText().length() == 2) { // empty identifier - throw new ParsingException("Zero-length delimited identifier not allowed", null, token.getLine(), token.getCharPositionInLine() + 1); - } - } - - @Override - public void exitBackQuotedIdentifier(SqlBaseParser.BackQuotedIdentifierContext context) - { - Token token = context.BACKQUOTED_IDENTIFIER().getSymbol(); - throw new ParsingException( - "backquoted identifiers are not supported; use double quotes to quote identifiers", - null, - token.getLine(), - token.getCharPositionInLine() + 1); - } - - @Override - public void exitDigitIdentifier(SqlBaseParser.DigitIdentifierContext context) - { - Token token = context.DIGIT_IDENTIFIER().getSymbol(); - throw new ParsingException( - "identifiers must not start with a digit; surround the identifier with double quotes", - null, - token.getLine(), - token.getCharPositionInLine() + 1); - } - - @Override - public void exitNonReserved(SqlBaseParser.NonReservedContext context) - { - // we can't modify the tree during rule enter/exit event handling unless we're dealing with a terminal. - // Otherwise, ANTLR gets confused and fires spurious notifications. - if (!(context.getChild(0) instanceof TerminalNode)) { - int rule = ((ParserRuleContext) context.getChild(0)).getRuleIndex(); - throw new AssertionError("nonReserved can only contain tokens. Found nested rule: " + ruleNames.get(rule)); - } - - // replace nonReserved words with IDENT tokens - context.getParent().removeLastChild(); - - Token token = (Token) context.getChild(0).getPayload(); - Token newToken = new CommonToken( - new Pair<>(token.getTokenSource(), token.getInputStream()), - SqlBaseLexer.IDENTIFIER, - token.getChannel(), - token.getStartIndex(), - token.getStopIndex()); - - context.getParent().addChild(parser.createTerminalNode(context.getParent(), newToken)); - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/parser/StatementSplitter.java b/trino-parser/src/main/java/io/trino/sql/parser/StatementSplitter.java deleted file mode 100644 index 7385a2b2b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/parser/StatementSplitter.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import org.antlr.v4.runtime.CharStream; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.TokenSource; - -import java.util.List; -import java.util.Objects; -import java.util.Set; - -import static java.util.Objects.requireNonNull; - -public class StatementSplitter -{ - private final List completeStatements; - private final String partialStatement; - - public StatementSplitter(String sql) - { - this(sql, ImmutableSet.of(";")); - } - - public StatementSplitter(String sql, Set delimiters) - { - TokenSource tokens = getLexer(sql, delimiters); - ImmutableList.Builder list = ImmutableList.builder(); - StringBuilder sb = new StringBuilder(); - while (true) { - Token token = tokens.nextToken(); - if (token.getType() == Token.EOF) { - break; - } - if (token.getType() == SqlBaseParser.DELIMITER) { - String statement = sb.toString().trim(); - if (!statement.isEmpty()) { - list.add(new Statement(statement, token.getText())); - } - sb = new StringBuilder(); - } - else { - sb.append(token.getText()); - } - } - this.completeStatements = list.build(); - this.partialStatement = sb.toString().trim(); - } - - public List getCompleteStatements() - { - return completeStatements; - } - - public String getPartialStatement() - { - return partialStatement; - } - - public static String squeezeStatement(String sql) - { - TokenSource tokens = getLexer(sql, ImmutableSet.of()); - StringBuilder sb = new StringBuilder(); - while (true) { - Token token = tokens.nextToken(); - if (token.getType() == Token.EOF) { - break; - } - if (token.getType() == SqlBaseLexer.WS) { - sb.append(' '); - } - else { - sb.append(token.getText()); - } - } - return sb.toString().trim(); - } - - public static boolean isEmptyStatement(String sql) - { - TokenSource tokens = getLexer(sql, ImmutableSet.of()); - while (true) { - Token token = tokens.nextToken(); - if (token.getType() == Token.EOF) { - return true; - } - if (token.getChannel() != Token.HIDDEN_CHANNEL) { - return false; - } - } - } - - public static TokenSource getLexer(String sql, Set terminators) - { - requireNonNull(sql, "sql is null"); - CharStream stream = new CaseInsensitiveStream(CharStreams.fromString(sql)); - return new DelimiterLexer(stream, terminators); - } - - public static class Statement - { - private final String statement; - private final String terminator; - - public Statement(String statement, String terminator) - { - this.statement = requireNonNull(statement, "statement is null"); - this.terminator = requireNonNull(terminator, "terminator is null"); - } - - public String statement() - { - return statement; - } - - public String terminator() - { - return terminator; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Statement o = (Statement) obj; - return Objects.equals(statement, o.statement) && - Objects.equals(terminator, o.terminator); - } - - @Override - public int hashCode() - { - return Objects.hash(statement, terminator); - } - - @Override - public String toString() - { - return statement + terminator; - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/testing/TreeAssertions.java b/trino-parser/src/main/java/io/trino/sql/testing/TreeAssertions.java deleted file mode 100644 index f57151532..000000000 --- a/trino-parser/src/main/java/io/trino/sql/testing/TreeAssertions.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed 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 io.trino.sql.testing; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import io.trino.sql.parser.ParsingException; -import io.trino.sql.parser.ParsingOptions; -import io.trino.sql.parser.SqlParser; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.Statement; - -import javax.annotation.Nullable; - -import java.util.List; - -import static io.trino.sql.SqlFormatter.formatSql; -import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DOUBLE; -import static java.lang.String.format; - -public final class TreeAssertions -{ - private TreeAssertions() {} - - public static void assertFormattedSql(SqlParser sqlParser, Node expected) - { - ParsingOptions parsingOptions = new ParsingOptions(AS_DOUBLE /* anything */); - assertFormattedSql(sqlParser, parsingOptions, expected); - } - - public static void assertFormattedSql(SqlParser sqlParser, ParsingOptions parsingOptions, Node expected) - { - String formatted = formatSql(expected); - - // verify round-trip of formatting already-formatted SQL - Statement actual = parseFormatted(sqlParser, parsingOptions, formatted, expected); - assertEquals(formatSql(actual), formatted); - - // compare parsed tree with parsed tree of formatted SQL - if (!actual.equals(expected)) { - // simplify finding the non-equal part of the tree - assertListEquals(linearizeTree(actual), linearizeTree(expected)); - } - assertEquals(actual, expected); - } - - private static Statement parseFormatted(SqlParser sqlParser, ParsingOptions parsingOptions, String sql, Node tree) - { - try { - return sqlParser.createStatement(sql, parsingOptions); - } - catch (ParsingException e) { - String message = format("failed to parse formatted SQL: %s\nerror: %s\ntree: %s", sql, e.getMessage(), tree); - throw new AssertionError(message, e); - } - } - - private static List linearizeTree(Node tree) - { - ImmutableList.Builder nodes = ImmutableList.builder(); - new DefaultTraversalVisitor() - { - @Override - public Void process(Node node, @Nullable Void context) - { - super.process(node, context); - nodes.add(node); - return null; - } - }.process(tree, null); - return nodes.build(); - } - - private static void assertListEquals(List actual, List expected) - { - if (actual.size() != expected.size()) { - throw new AssertionError(format("Lists not equal in size%n%s", formatLists(actual, expected))); - } - if (!actual.equals(expected)) { - throw new AssertionError(format("Lists not equal at index %s%n%s", - differingIndex(actual, expected), formatLists(actual, expected))); - } - } - - private static String formatLists(List actual, List expected) - { - Joiner joiner = Joiner.on("\n "); - return format("Actual [%s]:%n %s%nExpected [%s]:%n %s%n", - actual.size(), joiner.join(actual), - expected.size(), joiner.join(expected)); - } - - private static int differingIndex(List actual, List expected) - { - for (int i = 0; i < actual.size(); i++) { - if (!actual.get(i).equals(expected.get(i))) { - return i; - } - } - return actual.size(); - } - - private static void assertEquals(T actual, T expected) - { - if (!actual.equals(expected)) { - throw new AssertionError(format("expected [%s] but found [%s]", expected, actual)); - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/AddColumn.java b/trino-parser/src/main/java/io/trino/sql/tree/AddColumn.java deleted file mode 100644 index 5ed85a0f0..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/AddColumn.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class AddColumn - extends Statement -{ - private final QualifiedName name; - private final ColumnDefinition column; - private final boolean tableExists; - private final boolean columnNotExists; - - public AddColumn(QualifiedName name, ColumnDefinition column, boolean tableExists, boolean columnNotExists) - { - this(Optional.empty(), name, column, tableExists, columnNotExists); - } - - public AddColumn(NodeLocation location, QualifiedName name, ColumnDefinition column, boolean tableExists, boolean columnNotExists) - { - this(Optional.of(location), name, column, tableExists, columnNotExists); - } - - private AddColumn(Optional location, QualifiedName name, ColumnDefinition column, boolean tableExists, boolean columnNotExists) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.column = requireNonNull(column, "column is null"); - this.tableExists = tableExists; - this.columnNotExists = columnNotExists; - } - - public QualifiedName getName() - { - return name; - } - - public ColumnDefinition getColumn() - { - return column; - } - - public boolean isTableExists() - { - return tableExists; - } - - public boolean isColumnNotExists() - { - return columnNotExists; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitAddColumn(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(column); - } - - @Override - public int hashCode() - { - return Objects.hash(name, column); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - AddColumn o = (AddColumn) obj; - return Objects.equals(name, o.name) && - Objects.equals(column, o.column); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("column", column) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/AliasedRelation.java b/trino-parser/src/main/java/io/trino/sql/tree/AliasedRelation.java deleted file mode 100644 index ab05f2fc0..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/AliasedRelation.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class AliasedRelation - extends Relation -{ - private final Relation relation; - private final Identifier alias; - private final List columnNames; - - public AliasedRelation(Relation relation, Identifier alias, List columnNames) - { - this(Optional.empty(), relation, alias, columnNames); - } - - public AliasedRelation(NodeLocation location, Relation relation, Identifier alias, List columnNames) - { - this(Optional.of(location), relation, alias, columnNames); - } - - private AliasedRelation(Optional location, Relation relation, Identifier alias, List columnNames) - { - super(location); - requireNonNull(relation, "relation is null"); - requireNonNull(alias, "alias is null"); - - this.relation = relation; - this.alias = alias; - this.columnNames = columnNames; - } - - public Relation getRelation() - { - return relation; - } - - public Identifier getAlias() - { - return alias; - } - - public List getColumnNames() - { - return columnNames; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitAliasedRelation(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(relation); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("relation", relation) - .add("alias", alias) - .add("columnNames", columnNames) - .omitNullValues() - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - AliasedRelation that = (AliasedRelation) o; - return Objects.equals(relation, that.relation) && - Objects.equals(alias, that.alias) && - Objects.equals(columnNames, that.columnNames); - } - - @Override - public int hashCode() - { - return Objects.hash(relation, alias, columnNames); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - AliasedRelation otherRelation = (AliasedRelation) other; - return alias.equals(otherRelation.alias) && Objects.equals(columnNames, otherRelation.columnNames); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/AllColumns.java b/trino-parser/src/main/java/io/trino/sql/tree/AllColumns.java deleted file mode 100644 index eeecac138..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/AllColumns.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class AllColumns - extends SelectItem -{ - private final List aliases; - private final Optional target; - - public AllColumns() - { - this(Optional.empty(), Optional.empty(), ImmutableList.of()); - } - - public AllColumns(Expression target) - { - this(Optional.empty(), Optional.of(target), ImmutableList.of()); - } - - public AllColumns(Expression target, List aliases) - { - this(Optional.empty(), Optional.of(target), aliases); - } - - public AllColumns(NodeLocation location, Optional target, List aliases) - { - this(Optional.of(location), target, aliases); - } - - public AllColumns(Optional location, Optional target, List aliases) - { - super(location); - this.aliases = ImmutableList.copyOf(requireNonNull(aliases, "aliases is null")); - this.target = requireNonNull(target, "target is null"); - } - - public List getAliases() - { - return aliases; - } - - public Optional getTarget() - { - return target; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitAllColumns(this, context); - } - - @Override - public List getChildren() - { - return target.map(ImmutableList::of) - .orElse(ImmutableList.of()); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - AllColumns other = (AllColumns) o; - return Objects.equals(aliases, other.aliases) && - Objects.equals(target, other.target); - } - - @Override - public int hashCode() - { - return Objects.hash(aliases, target); - } - - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - - target.ifPresent(value -> builder.append(value).append(".")); - builder.append("*"); - - if (!aliases.isEmpty()) { - builder.append(" ("); - Joiner.on(", ").appendTo(builder, aliases); - builder.append(")"); - } - - return builder.toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return aliases.equals(((AllColumns) other).aliases); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/AllRows.java b/trino-parser/src/main/java/io/trino/sql/tree/AllRows.java deleted file mode 100644 index 4224d067d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/AllRows.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -public class AllRows - extends Expression -{ - public AllRows() - { - this(Optional.empty()); - } - - public AllRows(NodeLocation location) - { - this(Optional.of(location)); - } - - public AllRows(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitAllRows(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - return (o != null) && (getClass() == o.getClass()); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Analyze.java b/trino-parser/src/main/java/io/trino/sql/tree/Analyze.java deleted file mode 100644 index 9a3515235..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Analyze.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Analyze - extends Statement -{ - private final QualifiedName tableName; - private final List properties; - - public Analyze(QualifiedName tableName, List properties) - { - this(Optional.empty(), tableName, properties); - } - - public Analyze(NodeLocation location, QualifiedName tableName, List properties) - { - this(Optional.of(location), tableName, properties); - } - - private Analyze(Optional location, QualifiedName tableName, List properties) - { - super(location); - this.tableName = requireNonNull(tableName, "tableName is null"); - this.properties = ImmutableList.copyOf(requireNonNull(properties, "properties is null")); - } - - public QualifiedName getTableName() - { - return tableName; - } - - public List getProperties() - { - return properties; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitAnalyze(this, context); - } - - @Override - public List getChildren() - { - return properties; - } - - @Override - public int hashCode() - { - return Objects.hash(tableName, properties); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Analyze o = (Analyze) obj; - return Objects.equals(tableName, o.tableName) && - Objects.equals(properties, o.properties); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("tableName", tableName) - .add("properties", properties) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/AnchorPattern.java b/trino-parser/src/main/java/io/trino/sql/tree/AnchorPattern.java deleted file mode 100644 index 9ee05d898..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/AnchorPattern.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class AnchorPattern - extends RowPattern -{ - public enum Type - { - PARTITION_START, - PARTITION_END - } - - private final Type type; - - public AnchorPattern(NodeLocation location, Type type) - { - this(Optional.of(location), type); - } - - private AnchorPattern(Optional location, Type type) - { - super(location); - this.type = requireNonNull(type, "type is null"); - } - - public Type getType() - { - return type; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitAnchorPattern(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - AnchorPattern o = (AnchorPattern) obj; - return Objects.equals(type, o.type); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ArithmeticBinaryExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/ArithmeticBinaryExpression.java deleted file mode 100644 index 1d79d51aa..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ArithmeticBinaryExpression.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -public class ArithmeticBinaryExpression - extends Expression -{ - public enum Operator - { - ADD("+"), - SUBTRACT("-"), - MULTIPLY("*"), - DIVIDE("/"), - MODULUS("%"); - private final String value; - - Operator(String value) - { - this.value = value; - } - - public String getValue() - { - return value; - } - } - - private final Operator operator; - private final Expression left; - private final Expression right; - - public ArithmeticBinaryExpression(Operator operator, Expression left, Expression right) - { - this(Optional.empty(), operator, left, right); - } - - public ArithmeticBinaryExpression(NodeLocation location, Operator operator, Expression left, Expression right) - { - this(Optional.of(location), operator, left, right); - } - - private ArithmeticBinaryExpression(Optional location, Operator operator, Expression left, Expression right) - { - super(location); - this.operator = operator; - this.left = left; - this.right = right; - } - - public Operator getOperator() - { - return operator; - } - - public Expression getLeft() - { - return left; - } - - public Expression getRight() - { - return right; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitArithmeticBinary(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(left, right); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ArithmeticBinaryExpression that = (ArithmeticBinaryExpression) o; - return (operator == that.operator) && - Objects.equals(left, that.left) && - Objects.equals(right, that.right); - } - - @Override - public int hashCode() - { - return Objects.hash(operator, left, right); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return operator == ((ArithmeticBinaryExpression) other).operator; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ArithmeticUnaryExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/ArithmeticUnaryExpression.java deleted file mode 100644 index 39f5e3e71..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ArithmeticUnaryExpression.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class ArithmeticUnaryExpression - extends Expression -{ - public enum Sign - { - PLUS, - MINUS - } - - private final Expression value; - private final Sign sign; - - public ArithmeticUnaryExpression(Sign sign, Expression value) - { - this(Optional.empty(), sign, value); - } - - public ArithmeticUnaryExpression(NodeLocation location, Sign sign, Expression value) - { - this(Optional.of(location), sign, value); - } - - private ArithmeticUnaryExpression(Optional location, Sign sign, Expression value) - { - super(location); - requireNonNull(value, "value is null"); - requireNonNull(sign, "sign is null"); - - this.value = value; - this.sign = sign; - } - - public static ArithmeticUnaryExpression positive(NodeLocation location, Expression value) - { - return new ArithmeticUnaryExpression(Optional.of(location), Sign.PLUS, value); - } - - public static ArithmeticUnaryExpression negative(NodeLocation location, Expression value) - { - return new ArithmeticUnaryExpression(Optional.of(location), Sign.MINUS, value); - } - - public static ArithmeticUnaryExpression positive(Expression value) - { - return new ArithmeticUnaryExpression(Optional.empty(), Sign.PLUS, value); - } - - public static ArithmeticUnaryExpression negative(Expression value) - { - return new ArithmeticUnaryExpression(Optional.empty(), Sign.MINUS, value); - } - - public Expression getValue() - { - return value; - } - - public Sign getSign() - { - return sign; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitArithmeticUnary(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ArithmeticUnaryExpression that = (ArithmeticUnaryExpression) o; - return Objects.equals(value, that.value) && - (sign == that.sign); - } - - @Override - public int hashCode() - { - return Objects.hash(value, sign); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return sign == ((ArithmeticUnaryExpression) other).sign; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ArrayConstructor.java b/trino-parser/src/main/java/io/trino/sql/tree/ArrayConstructor.java deleted file mode 100644 index b23309c54..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ArrayConstructor.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class ArrayConstructor - extends Expression -{ - public static final String ARRAY_CONSTRUCTOR = "ARRAY_CONSTRUCTOR"; - private final List values; - - public ArrayConstructor(List values) - { - this(Optional.empty(), values); - } - - public ArrayConstructor(NodeLocation location, List values) - { - this(Optional.of(location), values); - } - - private ArrayConstructor(Optional location, List values) - { - super(location); - requireNonNull(values, "values is null"); - this.values = ImmutableList.copyOf(values); - } - - public List getValues() - { - return values; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitArrayConstructor(this, context); - } - - @Override - public List getChildren() - { - return values; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ArrayConstructor that = (ArrayConstructor) o; - return Objects.equals(values, that.values); - } - - @Override - public int hashCode() - { - return values.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/AstVisitor.java b/trino-parser/src/main/java/io/trino/sql/tree/AstVisitor.java deleted file mode 100644 index 0b5792011..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/AstVisitor.java +++ /dev/null @@ -1,1112 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import javax.annotation.Nullable; - -public abstract class AstVisitor -{ - public R process(Node node) - { - return process(node, null); - } - - public R process(Node node, @Nullable C context) - { - return node.accept(this, context); - } - - protected R visitNode(Node node, C context) - { - return null; - } - - protected R visitExpression(Expression node, C context) - { - return visitNode(node, context); - } - - protected R visitCurrentTime(CurrentTime node, C context) - { - return visitExpression(node, context); - } - - protected R visitExtract(Extract node, C context) - { - return visitExpression(node, context); - } - - protected R visitArithmeticBinary(ArithmeticBinaryExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitBetweenPredicate(BetweenPredicate node, C context) - { - return visitExpression(node, context); - } - - protected R visitCoalesceExpression(CoalesceExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitComparisonExpression(ComparisonExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitLiteral(Literal node, C context) - { - return visitExpression(node, context); - } - - protected R visitDoubleLiteral(DoubleLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitDecimalLiteral(DecimalLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitStatement(Statement node, C context) - { - return visitNode(node, context); - } - - protected R visitPrepare(Prepare node, C context) - { - return visitStatement(node, context); - } - - protected R visitDeallocate(Deallocate node, C context) - { - return visitStatement(node, context); - } - - protected R visitExecute(Execute node, C context) - { - return visitStatement(node, context); - } - - protected R visitDescribeOutput(DescribeOutput node, C context) - { - return visitStatement(node, context); - } - - protected R visitDescribeInput(DescribeInput node, C context) - { - return visitStatement(node, context); - } - - protected R visitQuery(Query node, C context) - { - return visitStatement(node, context); - } - - protected R visitExplain(Explain node, C context) - { - return visitStatement(node, context); - } - - protected R visitExplainAnalyze(ExplainAnalyze node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowTables(ShowTables node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowSchemas(ShowSchemas node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowCatalogs(ShowCatalogs node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowColumns(ShowColumns node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowStats(ShowStats node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowCreate(ShowCreate node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowFunctions(ShowFunctions node, C context) - { - return visitStatement(node, context); - } - - protected R visitUse(Use node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowSession(ShowSession node, C context) - { - return visitStatement(node, context); - } - - protected R visitSetSession(SetSession node, C context) - { - return visitStatement(node, context); - } - - protected R visitResetSession(ResetSession node, C context) - { - return visitStatement(node, context); - } - - protected R visitGenericLiteral(GenericLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitTimeLiteral(TimeLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitExplainOption(ExplainOption node, C context) - { - return visitNode(node, context); - } - - protected R visitWith(With node, C context) - { - return visitNode(node, context); - } - - protected R visitWithQuery(WithQuery node, C context) - { - return visitNode(node, context); - } - - protected R visitSelect(Select node, C context) - { - return visitNode(node, context); - } - - protected R visitRelation(Relation node, C context) - { - return visitNode(node, context); - } - - protected R visitQueryBody(QueryBody node, C context) - { - return visitRelation(node, context); - } - - protected R visitOrderBy(OrderBy node, C context) - { - return visitNode(node, context); - } - - protected R visitOffset(Offset node, C context) - { - return visitNode(node, context); - } - - protected R visitFetchFirst(FetchFirst node, C context) - { - return visitNode(node, context); - } - - protected R visitLimit(Limit node, C context) - { - return visitNode(node, context); - } - - protected R visitAllRows(AllRows node, C context) - { - return visitExpression(node, context); - } - - protected R visitQuerySpecification(QuerySpecification node, C context) - { - return visitQueryBody(node, context); - } - - protected R visitSetOperation(SetOperation node, C context) - { - return visitQueryBody(node, context); - } - - protected R visitUnion(Union node, C context) - { - return visitSetOperation(node, context); - } - - protected R visitIntersect(Intersect node, C context) - { - return visitSetOperation(node, context); - } - - protected R visitExcept(Except node, C context) - { - return visitSetOperation(node, context); - } - - protected R visitTimestampLiteral(TimestampLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitWhenClause(WhenClause node, C context) - { - return visitExpression(node, context); - } - - protected R visitIntervalLiteral(IntervalLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitInPredicate(InPredicate node, C context) - { - return visitExpression(node, context); - } - - protected R visitFunctionCall(FunctionCall node, C context) - { - return visitExpression(node, context); - } - - protected R visitProcessingMode(ProcessingMode node, C context) - { - return visitNode(node, context); - } - - protected R visitWindowOperation(WindowOperation node, C context) - { - return visitExpression(node, context); - } - - protected R visitLambdaExpression(LambdaExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitSimpleCaseExpression(SimpleCaseExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitStringLiteral(StringLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitCharLiteral(CharLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitBinaryLiteral(BinaryLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitBooleanLiteral(BooleanLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitInListExpression(InListExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitIdentifier(Identifier node, C context) - { - return visitExpression(node, context); - } - - protected R visitDereferenceExpression(DereferenceExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitNullIfExpression(NullIfExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitIfExpression(IfExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitNullLiteral(NullLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitArithmeticUnary(ArithmeticUnaryExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitNotExpression(NotExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitSelectItem(SelectItem node, C context) - { - return visitNode(node, context); - } - - protected R visitSingleColumn(SingleColumn node, C context) - { - return visitSelectItem(node, context); - } - - protected R visitAllColumns(AllColumns node, C context) - { - return visitSelectItem(node, context); - } - - protected R visitSearchedCaseExpression(SearchedCaseExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitLikePredicate(LikePredicate node, C context) - { - return visitExpression(node, context); - } - - protected R visitIsNotNullPredicate(IsNotNullPredicate node, C context) - { - return visitExpression(node, context); - } - - protected R visitIsNullPredicate(IsNullPredicate node, C context) - { - return visitExpression(node, context); - } - - protected R visitArrayConstructor(ArrayConstructor node, C context) - { - return visitExpression(node, context); - } - - protected R visitSubscriptExpression(SubscriptExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitLongLiteral(LongLiteral node, C context) - { - return visitLiteral(node, context); - } - - protected R visitParameter(Parameter node, C context) - { - return visitExpression(node, context); - } - - protected R visitLogicalExpression(LogicalExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitSubqueryExpression(SubqueryExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitSortItem(SortItem node, C context) - { - return visitNode(node, context); - } - - protected R visitTable(Table node, C context) - { - return visitQueryBody(node, context); - } - - protected R visitFunctionRelation(FunctionRelation node, C context) - { - return visitQueryBody(node, context); - } - - protected R visitPathRelation(PathRelation node, C context) - { - return visitQueryBody(node, context); - } - - protected R visitUnnest(Unnest node, C context) - { - return visitRelation(node, context); - } - - protected R visitLateral(Lateral node, C context) - { - return visitRelation(node, context); - } - - protected R visitValues(Values node, C context) - { - return visitQueryBody(node, context); - } - - protected R visitRow(Row node, C context) - { - return visitExpression(node, context); - } - - protected R visitTableSubquery(TableSubquery node, C context) - { - return visitQueryBody(node, context); - } - - protected R visitAliasedRelation(AliasedRelation node, C context) - { - return visitRelation(node, context); - } - - protected R visitSampledRelation(SampledRelation node, C context) - { - return visitRelation(node, context); - } - - protected R visitJoin(Join node, C context) - { - return visitRelation(node, context); - } - - protected R visitExists(ExistsPredicate node, C context) - { - return visitExpression(node, context); - } - - protected R visitTryExpression(TryExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitCast(Cast node, C context) - { - return visitExpression(node, context); - } - - protected R visitFieldReference(FieldReference node, C context) - { - return visitExpression(node, context); - } - - protected R visitWindowReference(WindowReference node, C context) - { - return visitNode(node, context); - } - - protected R visitWindowSpecification(WindowSpecification node, C context) - { - return visitNode(node, context); - } - - protected R visitWindowDefinition(WindowDefinition node, C context) - { - return visitNode(node, context); - } - - protected R visitWindowFrame(WindowFrame node, C context) - { - return visitNode(node, context); - } - - protected R visitFrameBound(FrameBound node, C context) - { - return visitNode(node, context); - } - - protected R visitCallArgument(CallArgument node, C context) - { - return visitNode(node, context); - } - - protected R visitMergeCase(MergeCase node, C context) - { - return visitNode(node, context); - } - - protected R visitMergeInsert(MergeInsert node, C context) - { - return visitMergeCase(node, context); - } - - protected R visitMergeUpdate(MergeUpdate node, C context) - { - return visitMergeCase(node, context); - } - - protected R visitMergeDelete(MergeDelete node, C context) - { - return visitMergeCase(node, context); - } - - protected R visitTableElement(TableElement node, C context) - { - return visitNode(node, context); - } - - protected R visitColumnDefinition(ColumnDefinition node, C context) - { - return visitTableElement(node, context); - } - - protected R visitLikeClause(LikeClause node, C context) - { - return visitTableElement(node, context); - } - - protected R visitCreateSchema(CreateSchema node, C context) - { - return visitStatement(node, context); - } - - protected R visitDropSchema(DropSchema node, C context) - { - return visitStatement(node, context); - } - - protected R visitRenameSchema(RenameSchema node, C context) - { - return visitStatement(node, context); - } - - protected R visitSetSchemaAuthorization(SetSchemaAuthorization node, C context) - { - return visitStatement(node, context); - } - - protected R visitCreateTable(CreateTable node, C context) - { - return visitStatement(node, context); - } - - protected R visitCreateTableAsSelect(CreateTableAsSelect node, C context) - { - return visitStatement(node, context); - } - - protected R visitProperty(Property node, C context) - { - return visitNode(node, context); - } - - protected R visitDropTable(DropTable node, C context) - { - return visitStatement(node, context); - } - - protected R visitRenameTable(RenameTable node, C context) - { - return visitStatement(node, context); - } - - protected R visitRenameView(RenameView node, C context) - { - return visitStatement(node, context); - } - - protected R visitRenameMaterializedView(RenameMaterializedView node, C context) - { - return visitStatement(node, context); - } - - protected R visitSetViewAuthorization(SetViewAuthorization node, C context) - { - return visitStatement(node, context); - } - - protected R visitSetProperties(SetProperties node, C context) - { - return visitStatement(node, context); - } - - protected R visitComment(Comment node, C context) - { - return visitStatement(node, context); - } - - protected R visitRenameColumn(RenameColumn node, C context) - { - return visitStatement(node, context); - } - - protected R visitDropColumn(DropColumn node, C context) - { - return visitStatement(node, context); - } - - protected R visitAddColumn(AddColumn node, C context) - { - return visitStatement(node, context); - } - - protected R visitSetTableAuthorization(SetTableAuthorization node, C context) - { - return visitStatement(node, context); - } - - protected R visitTableExecute(TableExecute node, C context) - { - return visitStatement(node, context); - } - - protected R visitAnalyze(Analyze node, C context) - { - return visitStatement(node, context); - } - - protected R visitCreateView(CreateView node, C context) - { - return visitStatement(node, context); - } - - protected R visitDropView(DropView node, C context) - { - return visitStatement(node, context); - } - - protected R visitInsert(Insert node, C context) - { - return visitStatement(node, context); - } - - protected R visitRefreshMaterializedView(RefreshMaterializedView node, C context) - { - return visitStatement(node, context); - } - - protected R visitCall(Call node, C context) - { - return visitStatement(node, context); - } - - protected R visitDelete(Delete node, C context) - { - return visitStatement(node, context); - } - - protected R visitUpdate(Update node, C context) - { - return visitStatement(node, context); - } - - protected R visitUpdateAssignment(UpdateAssignment node, C context) - { - return visitNode(node, context); - } - - protected R visitTruncateTable(TruncateTable node, C context) - { - return visitStatement(node, context); - } - - protected R visitStartTransaction(StartTransaction node, C context) - { - return visitStatement(node, context); - } - - protected R visitCreateRole(CreateRole node, C context) - { - return visitStatement(node, context); - } - - protected R visitDropRole(DropRole node, C context) - { - return visitStatement(node, context); - } - - protected R visitGrantRoles(GrantRoles node, C context) - { - return visitStatement(node, context); - } - - protected R visitRevokeRoles(RevokeRoles node, C context) - { - return visitStatement(node, context); - } - - protected R visitSetRole(SetRole node, C context) - { - return visitStatement(node, context); - } - - protected R visitGrant(Grant node, C context) - { - return visitStatement(node, context); - } - - protected R visitDeny(Deny node, C context) - { - return visitStatement(node, context); - } - - protected R visitRevoke(Revoke node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowGrants(ShowGrants node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowRoles(ShowRoles node, C context) - { - return visitStatement(node, context); - } - - protected R visitShowRoleGrants(ShowRoleGrants node, C context) - { - return visitStatement(node, context); - } - - protected R visitSetPath(SetPath node, C context) - { - return visitStatement(node, context); - } - - protected R visitPathSpecification(PathSpecification node, C context) - { - return visitNode(node, context); - } - - protected R visitPathElement(PathElement node, C context) - { - return visitNode(node, context); - } - - protected R visitSetTimeZone(SetTimeZone node, C context) - { - return visitStatement(node, context); - } - - protected R visitTransactionMode(TransactionMode node, C context) - { - return visitNode(node, context); - } - - protected R visitIsolationLevel(Isolation node, C context) - { - return visitTransactionMode(node, context); - } - - protected R visitTransactionAccessMode(TransactionAccessMode node, C context) - { - return visitTransactionMode(node, context); - } - - protected R visitCommit(Commit node, C context) - { - return visitStatement(node, context); - } - - protected R visitRollback(Rollback node, C context) - { - return visitStatement(node, context); - } - - protected R visitAtTimeZone(AtTimeZone node, C context) - { - return visitExpression(node, context); - } - - protected R visitGroupBy(GroupBy node, C context) - { - return visitNode(node, context); - } - - protected R visitGroupingElement(GroupingElement node, C context) - { - return visitNode(node, context); - } - - protected R visitCube(Cube node, C context) - { - return visitGroupingElement(node, context); - } - - protected R visitGroupingSets(GroupingSets node, C context) - { - return visitGroupingElement(node, context); - } - - protected R visitRollup(Rollup node, C context) - { - return visitGroupingElement(node, context); - } - - protected R visitSimpleGroupBy(SimpleGroupBy node, C context) - { - return visitGroupingElement(node, context); - } - - protected R visitSymbolReference(SymbolReference node, C context) - { - return visitExpression(node, context); - } - - protected R visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitLambdaArgumentDeclaration(LambdaArgumentDeclaration node, C context) - { - return visitExpression(node, context); - } - - protected R visitBindExpression(BindExpression node, C context) - { - return visitExpression(node, context); - } - - protected R visitGroupingOperation(GroupingOperation node, C context) - { - return visitExpression(node, context); - } - - protected R visitCurrentCatalog(CurrentCatalog node, C context) - { - return visitExpression(node, context); - } - - protected R visitCurrentSchema(CurrentSchema node, C context) - { - return visitExpression(node, context); - } - - protected R visitCurrentUser(CurrentUser node, C context) - { - return visitExpression(node, context); - } - - protected R visitCurrentPath(CurrentPath node, C context) - { - return visitExpression(node, context); - } - - protected R visitFormat(Format node, C context) - { - return visitExpression(node, context); - } - - protected R visitDataType(DataType node, C context) - { - return visitExpression(node, context); - } - - protected R visitRowDataType(RowDataType node, C context) - { - return visitDataType(node, context); - } - - protected R visitGenericDataType(GenericDataType node, C context) - { - return visitDataType(node, context); - } - - protected R visitRowField(RowDataType.Field node, C context) - { - return visitNode(node, context); - } - - protected R visitDataTypeParameter(DataTypeParameter node, C context) - { - return visitNode(node, context); - } - - protected R visitNumericTypeParameter(NumericParameter node, C context) - { - return visitDataTypeParameter(node, context); - } - - protected R visitTypeParameter(TypeParameter node, C context) - { - return visitDataTypeParameter(node, context); - } - - protected R visitIntervalDataType(IntervalDayTimeDataType node, C context) - { - return visitDataType(node, context); - } - - protected R visitDateTimeType(DateTimeDataType node, C context) - { - return visitDataType(node, context); - } - - protected R visitCreateMaterializedView(CreateMaterializedView node, C context) - { - return visitStatement(node, context); - } - - protected R visitDropMaterializedView(DropMaterializedView node, C context) - { - return visitStatement(node, context); - } - - protected R visitMerge(Merge node, C context) - { - return visitStatement(node, context); - } - - protected R visitMeasureDefinition(MeasureDefinition node, C context) - { - return visitNode(node, context); - } - - protected R visitSkipTo(SkipTo node, C context) - { - return visitNode(node, context); - } - - protected R visitPatternSearchMode(PatternSearchMode node, C context) - { - return visitNode(node, context); - } - - protected R visitSubsetDefinition(SubsetDefinition node, C context) - { - return visitNode(node, context); - } - - protected R visitVariableDefinition(VariableDefinition node, C context) - { - return visitNode(node, context); - } - - protected R visitPatternRecognitionRelation(PatternRecognitionRelation node, C context) - { - return visitRelation(node, context); - } - - protected R visitLabelDereference(LabelDereference node, C context) - { - return visitExpression(node, context); - } - - protected R visitRowPattern(RowPattern node, C context) - { - return visitNode(node, context); - } - - protected R visitPatternAlternation(PatternAlternation node, C context) - { - return visitRowPattern(node, context); - } - - protected R visitPatternConcatenation(PatternConcatenation node, C context) - { - return visitRowPattern(node, context); - } - - protected R visitQuantifiedPattern(QuantifiedPattern node, C context) - { - return visitRowPattern(node, context); - } - - protected R visitAnchorPattern(AnchorPattern node, C context) - { - return visitRowPattern(node, context); - } - - protected R visitEmptyPattern(EmptyPattern node, C context) - { - return visitRowPattern(node, context); - } - - protected R visitExcludedPattern(ExcludedPattern node, C context) - { - return visitRowPattern(node, context); - } - - protected R visitPatternPermutation(PatternPermutation node, C context) - { - return visitRowPattern(node, context); - } - - protected R visitPatternVariable(PatternVariable node, C context) - { - return visitRowPattern(node, context); - } - - protected R visitPatternQuantifier(PatternQuantifier node, C context) - { - return visitNode(node, context); - } - - protected R visitZeroOrMoreQuantifier(ZeroOrMoreQuantifier node, C context) - { - return visitPatternQuantifier(node, context); - } - - protected R visitOneOrMoreQuantifier(OneOrMoreQuantifier node, C context) - { - return visitPatternQuantifier(node, context); - } - - protected R visitZeroOrOneQuantifier(ZeroOrOneQuantifier node, C context) - { - return visitPatternQuantifier(node, context); - } - - protected R visitRangeQuantifier(RangeQuantifier node, C context) - { - return visitPatternQuantifier(node, context); - } - - protected R visitQueryPeriod(QueryPeriod node, C context) - { - return visitNode(node, context); - } - - // pg syntax - protected R visitDeclareCursor(Declare node, C context) - { - return visitStatement(node, context); - } - - // pg syntax - protected R visitFetchCursor(FetchCursor node, C context) - { - return visitStatement(node, context); - } - - // added by canner - protected R visitImpersonateUser(ImpersonateUser node, C context) - { - return visitStatement(node, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/AtTimeZone.java b/trino-parser/src/main/java/io/trino/sql/tree/AtTimeZone.java deleted file mode 100644 index 162eb36fd..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/AtTimeZone.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class AtTimeZone - extends Expression -{ - private final Expression value; - private final Expression timeZone; - - public AtTimeZone(Expression value, Expression timeZone) - { - this(Optional.empty(), value, timeZone); - } - - public AtTimeZone(NodeLocation location, Expression value, Expression timeZone) - { - this(Optional.of(location), value, timeZone); - } - - private AtTimeZone(Optional location, Expression value, Expression timeZone) - { - super(location); - checkArgument(timeZone instanceof IntervalLiteral || timeZone instanceof StringLiteral, "timeZone must be IntervalLiteral or StringLiteral"); - this.value = requireNonNull(value, "value is null"); - this.timeZone = requireNonNull(timeZone, "timeZone is null"); - } - - public Expression getValue() - { - return value; - } - - public Expression getTimeZone() - { - return timeZone; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitAtTimeZone(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value, timeZone); - } - - @Override - public int hashCode() - { - return Objects.hash(value, timeZone); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - AtTimeZone atTimeZone = (AtTimeZone) obj; - return Objects.equals(value, atTimeZone.value) && Objects.equals(timeZone, atTimeZone.timeZone); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/BetweenPredicate.java b/trino-parser/src/main/java/io/trino/sql/tree/BetweenPredicate.java deleted file mode 100644 index ebfd53d5a..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/BetweenPredicate.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class BetweenPredicate - extends Expression -{ - private final Expression value; - private final Expression min; - private final Expression max; - - public BetweenPredicate(Expression value, Expression min, Expression max) - { - this(Optional.empty(), value, min, max); - } - - public BetweenPredicate(NodeLocation location, Expression value, Expression min, Expression max) - { - this(Optional.of(location), value, min, max); - } - - private BetweenPredicate(Optional location, Expression value, Expression min, Expression max) - { - super(location); - requireNonNull(value, "value is null"); - requireNonNull(min, "min is null"); - requireNonNull(max, "max is null"); - - this.value = value; - this.min = min; - this.max = max; - } - - public Expression getValue() - { - return value; - } - - public Expression getMin() - { - return min; - } - - public Expression getMax() - { - return max; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitBetweenPredicate(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value, min, max); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - BetweenPredicate that = (BetweenPredicate) o; - return Objects.equals(value, that.value) && - Objects.equals(min, that.min) && - Objects.equals(max, that.max); - } - - @Override - public int hashCode() - { - return Objects.hash(value, min, max); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/BinaryLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/BinaryLiteral.java deleted file mode 100644 index 4cfe14424..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/BinaryLiteral.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.io.BaseEncoding; -import io.airlift.slice.Slice; -import io.airlift.slice.Slices; -import io.trino.sql.parser.ParsingException; - -import java.util.Objects; -import java.util.Optional; -import java.util.regex.Pattern; - -import static java.util.Locale.ENGLISH; -import static java.util.Objects.requireNonNull; - -public class BinaryLiteral - extends Literal -{ - // the grammar could possibly include whitespace in the value it passes to us - private static final Pattern WHITESPACE_PATTERN = Pattern.compile("[ \\r\\n\\t]"); - private static final Pattern NOT_HEX_DIGIT_PATTERN = Pattern.compile(".*[^A-F0-9].*"); - - private final Slice value; - - public BinaryLiteral(String value) - { - this(Optional.empty(), value); - } - - public BinaryLiteral(Optional location, String value) - { - super(location); - requireNonNull(value, "value is null"); - String hexString = WHITESPACE_PATTERN.matcher(value).replaceAll("").toUpperCase(ENGLISH); - if (NOT_HEX_DIGIT_PATTERN.matcher(hexString).matches()) { - throw new ParsingException("Binary literal can only contain hexadecimal digits", location.get()); - } - if (hexString.length() % 2 != 0) { - throw new ParsingException("Binary literal must contain an even number of digits", location.get()); - } - this.value = Slices.wrappedBuffer(BaseEncoding.base16().decode(hexString)); - } - - public BinaryLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - /** - * Return the valued as a hex-formatted string with upper-case characters - */ - public String toHexString() - { - return BaseEncoding.base16().encode(value.getBytes()); - } - - public Slice getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitBinaryLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - BinaryLiteral that = (BinaryLiteral) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return value.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return Objects.equals(value, ((BinaryLiteral) other).value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/BindExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/BindExpression.java deleted file mode 100644 index c3e4d5040..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/BindExpression.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -/** - * "$INTERNAL$BIND"(value, targetFunction) - *

- * When invoked, the returned function inserts the given value as - * the leading argument to the targetFunction. The other arguments are - * passed unchanged. - *

- * Bind is fundamentally first class, just like function applications. - * It requires special treatment from the type system. There is no way - * to write out the type of `bind`. The return type of `bind` is function. - * Its type looks somewhat like: - *

    - *
  • X, (X) -> Y => () -> Y - *
  • X1, (X1, X2) -> Y => (X2) -> Y - *
  • X1, (X1, X2, X3) -> Y => (X2, X3) -> Y - *
  • X1, (X1, X2, X3, X4) -> Y => (X2, X3, X4) -> Y - *
  • ... - *
- *

- * Lambda capturing is implemented through desugaring in Trino. - * This expression facilitates desugaring. - */ -public class BindExpression - extends Expression -{ - private final List values; - // Function expression must be of function type. - // It is not necessarily a lambda. For example, it can be another bind expression. - private final Expression function; - - public BindExpression(List values, Expression function) - { - this(Optional.empty(), values, function); - } - - public BindExpression(NodeLocation location, List values, Expression function) - { - this(Optional.of(location), values, function); - } - - private BindExpression(Optional location, List values, Expression function) - { - super(location); - this.values = requireNonNull(values, "values is null"); - this.function = requireNonNull(function, "function is null"); - } - - public List getValues() - { - return values; - } - - public Expression getFunction() - { - return function; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitBindExpression(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - return nodes.addAll(values) - .add(function) - .build(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - BindExpression that = (BindExpression) o; - return Objects.equals(values, that.values) && - Objects.equals(function, that.function); - } - - @Override - public int hashCode() - { - return Objects.hash(values, function); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/BooleanLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/BooleanLiteral.java deleted file mode 100644 index efaa2f4d7..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/BooleanLiteral.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Locale.ENGLISH; -import static java.util.Objects.requireNonNull; - -public class BooleanLiteral - extends Literal -{ - public static final BooleanLiteral TRUE_LITERAL = new BooleanLiteral(Optional.empty(), "true"); - public static final BooleanLiteral FALSE_LITERAL = new BooleanLiteral(Optional.empty(), "false"); - - private final boolean value; - - public BooleanLiteral(String value) - { - this(Optional.empty(), value); - } - - public BooleanLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - private BooleanLiteral(Optional location, String value) - { - super(location); - requireNonNull(value, "value is null"); - checkArgument(value.toLowerCase(ENGLISH).equals("true") || value.toLowerCase(ENGLISH).equals("false")); - - this.value = value.toLowerCase(ENGLISH).equals("true"); - } - - public boolean getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitBooleanLiteral(this, context); - } - - @Override - public int hashCode() - { - return Objects.hash(value); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - BooleanLiteral other = (BooleanLiteral) obj; - return Objects.equals(this.value, other.value); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return value == ((BooleanLiteral) other).value; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Call.java b/trino-parser/src/main/java/io/trino/sql/tree/Call.java deleted file mode 100644 index 9b09ee40c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Call.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Call - extends Statement -{ - private final QualifiedName name; - private final List arguments; - - public Call(QualifiedName name, List arguments) - { - this(Optional.empty(), name, arguments); - } - - public Call(NodeLocation location, QualifiedName name, List arguments) - { - this(Optional.of(location), name, arguments); - } - - public Call(Optional location, QualifiedName name, List arguments) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.arguments = ImmutableList.copyOf(requireNonNull(arguments, "arguments is null")); - } - - public QualifiedName getName() - { - return name; - } - - public List getArguments() - { - return arguments; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCall(this, context); - } - - @Override - public List getChildren() - { - return arguments; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Call o = (Call) obj; - return Objects.equals(name, o.name) && - Objects.equals(arguments, o.arguments); - } - - @Override - public int hashCode() - { - return Objects.hash(name, arguments); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("arguments", arguments) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CallArgument.java b/trino-parser/src/main/java/io/trino/sql/tree/CallArgument.java deleted file mode 100644 index 85467ad8e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CallArgument.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class CallArgument - extends Node -{ - private final Optional name; - private final Expression value; - - public CallArgument(Expression value) - { - this(Optional.empty(), Optional.empty(), value); - } - - public CallArgument(NodeLocation location, Expression value) - { - this(Optional.of(location), Optional.empty(), value); - } - - public CallArgument(Identifier name, Expression value) - { - this(Optional.empty(), Optional.of(name), value); - } - - public CallArgument(NodeLocation location, Identifier name, Expression value) - { - this(Optional.of(location), Optional.of(name), value); - } - - public CallArgument(Optional location, Optional name, Expression value) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.value = requireNonNull(value, "value is null"); - } - - public Optional getName() - { - return name; - } - - public Expression getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCallArgument(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - CallArgument o = (CallArgument) obj; - return Objects.equals(name, o.name) && - Objects.equals(value, o.value); - } - - @Override - public int hashCode() - { - return Objects.hash(name, value); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name.orElse(null)) - .add("value", value) - .omitNullValues() - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Cast.java b/trino-parser/src/main/java/io/trino/sql/tree/Cast.java deleted file mode 100644 index caa24ac65..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Cast.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public final class Cast - extends Expression -{ - private final Expression expression; - private final DataType type; - private final boolean safe; - private final boolean typeOnly; - - public Cast(Expression expression, DataType type) - { - this(Optional.empty(), expression, type, false, false); - } - - public Cast(Expression expression, DataType type, boolean safe) - { - this(Optional.empty(), expression, type, safe, false); - } - - public Cast(Expression expression, DataType type, boolean safe, boolean typeOnly) - { - this(Optional.empty(), expression, type, safe, typeOnly); - } - - public Cast(NodeLocation location, Expression expression, DataType type) - { - this(Optional.of(location), expression, type, false, false); - } - - public Cast(NodeLocation location, Expression expression, DataType type, boolean safe) - { - this(Optional.of(location), expression, type, safe, false); - } - - public Cast(NodeLocation location, Expression expression, DataType type, boolean safe, boolean typeOnly) - { - this(Optional.of(location), expression, type, safe, typeOnly); - } - - private Cast(Optional location, Expression expression, DataType type, boolean safe, boolean typeOnly) - { - super(location); - requireNonNull(expression, "expression is null"); - - this.expression = expression; - this.type = type; - this.safe = safe; - this.typeOnly = typeOnly; - } - - public Expression getExpression() - { - return expression; - } - - public DataType getType() - { - return type; - } - - public boolean isSafe() - { - return safe; - } - - public boolean isTypeOnly() - { - return typeOnly; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCast(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(expression, type); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Cast cast = (Cast) o; - return safe == cast.safe && - typeOnly == cast.typeOnly && - expression.equals(cast.expression) && - type.equals(cast.type); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, type, safe, typeOnly); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - Cast otherCast = (Cast) other; - return safe == otherCast.safe && - typeOnly == otherCast.typeOnly; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CharLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/CharLiteral.java deleted file mode 100644 index cce465c98..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CharLiteral.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.base.CharMatcher; -import io.airlift.slice.Slice; - -import java.util.Objects; -import java.util.Optional; - -import static io.airlift.slice.Slices.utf8Slice; -import static java.util.Objects.requireNonNull; - -public class CharLiteral - extends Literal -{ - private final String value; - private final Slice slice; - - public CharLiteral(String value) - { - this(Optional.empty(), value); - } - - public CharLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - public CharLiteral(Optional location, String value) - { - super(location); - requireNonNull(value, "value is null"); - this.value = value; - this.slice = utf8Slice(CharMatcher.is(' ').trimTrailingFrom(value)); - } - - public String getValue() - { - return value; - } - - public Slice getSlice() - { - return slice; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCharLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CharLiteral that = (CharLiteral) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return Objects.hash(value); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return Objects.equals(value, ((CharLiteral) other).value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CoalesceExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/CoalesceExpression.java deleted file mode 100644 index ce14f7dc2..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CoalesceExpression.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class CoalesceExpression - extends Expression -{ - private final List operands; - - public CoalesceExpression(Expression first, Expression second, Expression... additional) - { - this(Optional.empty(), ImmutableList.builder() - .add(first, second) - .add(additional) - .build()); - } - - public CoalesceExpression(List operands) - { - this(Optional.empty(), operands); - } - - public CoalesceExpression(NodeLocation location, List operands) - { - this(Optional.of(location), operands); - } - - private CoalesceExpression(Optional location, List operands) - { - super(location); - requireNonNull(operands, "operands is null"); - checkArgument(operands.size() >= 2, "must have at least two operands"); - - this.operands = ImmutableList.copyOf(operands); - } - - public List getOperands() - { - return operands; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCoalesceExpression(this, context); - } - - @Override - public List getChildren() - { - return operands; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - CoalesceExpression that = (CoalesceExpression) o; - return Objects.equals(operands, that.operands); - } - - @Override - public int hashCode() - { - return operands.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ColumnDefinition.java b/trino-parser/src/main/java/io/trino/sql/tree/ColumnDefinition.java deleted file mode 100644 index b96a9e077..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ColumnDefinition.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class ColumnDefinition - extends TableElement -{ - private final Identifier name; - private final DataType type; - private final boolean nullable; - private final List properties; - private final Optional comment; - - public ColumnDefinition(Identifier name, DataType type, boolean nullable, List properties, Optional comment) - { - this(Optional.empty(), name, type, nullable, properties, comment); - } - - public ColumnDefinition(NodeLocation location, Identifier name, DataType type, boolean nullable, List properties, Optional comment) - { - this(Optional.of(location), name, type, nullable, properties, comment); - } - - private ColumnDefinition(Optional location, Identifier name, DataType type, boolean nullable, List properties, Optional comment) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.type = requireNonNull(type, "type is null"); - this.nullable = nullable; - this.properties = requireNonNull(properties, "properties is null"); - this.comment = requireNonNull(comment, "comment is null"); - } - - public Identifier getName() - { - return name; - } - - public DataType getType() - { - return type; - } - - public boolean isNullable() - { - return nullable; - } - - public List getProperties() - { - return properties; - } - - public Optional getComment() - { - return comment; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitColumnDefinition(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - ColumnDefinition o = (ColumnDefinition) obj; - return Objects.equals(this.name, o.name) && - Objects.equals(this.type, o.type) && - this.nullable == o.nullable && - Objects.equals(properties, o.properties) && - Objects.equals(this.comment, o.comment); - } - - @Override - public int hashCode() - { - return Objects.hash(name, type, properties, comment, nullable); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("type", type) - .add("nullable", nullable) - .add("properties", properties) - .add("comment", comment) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Comment.java b/trino-parser/src/main/java/io/trino/sql/tree/Comment.java deleted file mode 100644 index 9b4f8b26b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Comment.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Comment - extends Statement -{ - public enum Type - { - TABLE, COLUMN - } - - private final Type type; - private final QualifiedName name; - private final Optional comment; - - public Comment(Type type, QualifiedName name, Optional comment) - { - this(Optional.empty(), type, name, comment); - } - - public Comment(NodeLocation location, Type type, QualifiedName name, Optional comment) - { - this(Optional.of(location), type, name, comment); - } - - private Comment(Optional location, Type type, QualifiedName name, Optional comment) - { - super(location); - this.type = requireNonNull(type, "type is null"); - this.name = requireNonNull(name, "name is null"); - this.comment = requireNonNull(comment, "comment is null"); - } - - public Type getType() - { - return type; - } - - public QualifiedName getName() - { - return name; - } - - public Optional getComment() - { - return comment; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitComment(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(type, name, comment); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Comment o = (Comment) obj; - return type == o.type && - Objects.equals(name, o.name) && - Objects.equals(comment, o.comment); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("name", name) - .add("comment", comment) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Commit.java b/trino-parser/src/main/java/io/trino/sql/tree/Commit.java deleted file mode 100644 index aea94b97d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Commit.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -public final class Commit - extends Statement -{ - public Commit() - { - this(Optional.empty()); - } - - public Commit(NodeLocation location) - { - this(Optional.of(location)); - } - - private Commit(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCommit(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return true; - } - - @Override - public String toString() - { - return "COMMIT"; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ComparisonExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/ComparisonExpression.java deleted file mode 100644 index 71c59bbc1..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ComparisonExpression.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class ComparisonExpression - extends Expression -{ - private final Operator operator; - private final Expression left; - private final Expression right; - - public ComparisonExpression(Operator operator, Expression left, Expression right) - { - this(Optional.empty(), operator, left, right); - } - - public ComparisonExpression(NodeLocation location, Operator operator, Expression left, Expression right) - { - this(Optional.of(location), operator, left, right); - } - - private ComparisonExpression(Optional location, Operator operator, Expression left, Expression right) - { - super(location); - requireNonNull(operator, "operator is null"); - requireNonNull(left, "left is null"); - requireNonNull(right, "right is null"); - - this.operator = operator; - this.left = left; - this.right = right; - } - - public Operator getOperator() - { - return operator; - } - - public Expression getLeft() - { - return left; - } - - public Expression getRight() - { - return right; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitComparisonExpression(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(left, right); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ComparisonExpression that = (ComparisonExpression) o; - return (operator == that.operator) && - Objects.equals(left, that.left) && - Objects.equals(right, that.right); - } - - @Override - public int hashCode() - { - return Objects.hash(operator, left, right); - } - - public enum Operator - { - EQUAL("="), - NOT_EQUAL("<>"), - LESS_THAN("<"), - LESS_THAN_OR_EQUAL("<="), - GREATER_THAN(">"), - GREATER_THAN_OR_EQUAL(">="), - IS_DISTINCT_FROM("IS DISTINCT FROM"); - - private final String value; - - Operator(String value) - { - this.value = value; - } - - public String getValue() - { - return value; - } - - public Operator flip() - { - switch (this) { - case EQUAL: - return EQUAL; - case NOT_EQUAL: - return NOT_EQUAL; - case LESS_THAN: - return GREATER_THAN; - case LESS_THAN_OR_EQUAL: - return GREATER_THAN_OR_EQUAL; - case GREATER_THAN: - return LESS_THAN; - case GREATER_THAN_OR_EQUAL: - return LESS_THAN_OR_EQUAL; - case IS_DISTINCT_FROM: - return IS_DISTINCT_FROM; - } - throw new IllegalArgumentException("Unsupported comparison: " + this); - } - - public Operator negate() - { - switch (this) { - case EQUAL: - return NOT_EQUAL; - case NOT_EQUAL: - return EQUAL; - case LESS_THAN: - return GREATER_THAN_OR_EQUAL; - case LESS_THAN_OR_EQUAL: - return GREATER_THAN; - case GREATER_THAN: - return LESS_THAN_OR_EQUAL; - case GREATER_THAN_OR_EQUAL: - return LESS_THAN; - case IS_DISTINCT_FROM: - // Cannot negate - break; - } - throw new IllegalArgumentException("Unsupported comparison: " + this); - } - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return operator == ((ComparisonExpression) other).operator; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CreateMaterializedView.java b/trino-parser/src/main/java/io/trino/sql/tree/CreateMaterializedView.java deleted file mode 100644 index 41f5282a4..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CreateMaterializedView.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class CreateMaterializedView - extends Statement -{ - private final QualifiedName name; - private final Query query; - private final boolean replace; - private final boolean notExists; - private final List properties; - private final Optional comment; - - public CreateMaterializedView(Optional location, - QualifiedName name, - Query query, - boolean replace, - boolean notExists, - List properties, - Optional comment) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.query = requireNonNull(query, "query is null"); - this.replace = replace; - this.notExists = notExists; - this.properties = properties; - this.comment = comment; - } - - public QualifiedName getName() - { - return name; - } - - public Query getQuery() - { - return query; - } - - public boolean isReplace() - { - return replace; - } - - public boolean isNotExists() - { - return notExists; - } - - public List getProperties() - { - return properties; - } - - public Optional getComment() - { - return comment; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCreateMaterializedView(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(query); - } - - @Override - public int hashCode() - { - return Objects.hash(name, query, replace, notExists, properties, comment); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - CreateMaterializedView o = (CreateMaterializedView) obj; - return Objects.equals(name, o.name) - && Objects.equals(query, o.query) - && Objects.equals(replace, o.replace) - && Objects.equals(notExists, o.notExists) - && Objects.equals(properties, o.properties) - && Objects.equals(comment, o.comment); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("query", query) - .add("replace", replace) - .add("notExists", notExists) - .add("properties", properties) - .add("comment", comment) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CreateRole.java b/trino-parser/src/main/java/io/trino/sql/tree/CreateRole.java deleted file mode 100644 index 90250b0c3..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CreateRole.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class CreateRole - extends Statement -{ - private final Identifier name; - private final Optional grantor; - private final Optional catalog; - - public CreateRole(Identifier name, Optional grantor, Optional catalog) - { - this(Optional.empty(), name, grantor, catalog); - } - - public CreateRole(NodeLocation location, Identifier name, Optional grantor, Optional catalog) - { - this(Optional.of(location), name, grantor, catalog); - } - - private CreateRole(Optional location, Identifier name, Optional grantor, Optional catalog) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.grantor = requireNonNull(grantor, "grantor is null"); - this.catalog = requireNonNull(catalog, "catalog is null"); - } - - public Identifier getName() - { - return name; - } - - public Optional getGrantor() - { - return grantor; - } - - public Optional getCatalog() - { - return catalog; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CreateRole that = (CreateRole) o; - return Objects.equals(name, that.name) && - Objects.equals(grantor, that.grantor) && - Objects.equals(catalog, that.catalog); - } - - @Override - public int hashCode() - { - return Objects.hash(name, grantor, catalog); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("grantor", grantor) - .add("catalog", catalog) - .toString(); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCreateRole(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CreateSchema.java b/trino-parser/src/main/java/io/trino/sql/tree/CreateSchema.java deleted file mode 100644 index d4f47bd17..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CreateSchema.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class CreateSchema - extends Statement -{ - private final QualifiedName schemaName; - private final boolean notExists; - private final List properties; - private final Optional principal; - - public CreateSchema(QualifiedName schemaName, boolean notExists, List properties) - { - this(Optional.empty(), schemaName, notExists, properties, Optional.empty()); - } - - public CreateSchema(QualifiedName schemaName, boolean notExists, List properties, Optional principal) - { - this(Optional.empty(), schemaName, notExists, properties, principal); - } - - public CreateSchema(NodeLocation location, QualifiedName schemaName, boolean notExists, List properties, Optional principal) - { - this(Optional.of(location), schemaName, notExists, properties, principal); - } - - private CreateSchema(Optional location, QualifiedName schemaName, boolean notExists, List properties, Optional principal) - { - super(location); - this.schemaName = requireNonNull(schemaName, "schemaName is null"); - this.notExists = notExists; - this.properties = ImmutableList.copyOf(requireNonNull(properties, "properties is null")); - this.principal = principal; - } - - public QualifiedName getSchemaName() - { - return schemaName; - } - - public boolean isNotExists() - { - return notExists; - } - - public Optional getPrincipal() - { - return principal; - } - - public List getProperties() - { - return properties; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCreateSchema(this, context); - } - - @Override - public List getChildren() - { - return properties; - } - - @Override - public int hashCode() - { - return Objects.hash(schemaName, notExists, properties); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - CreateSchema o = (CreateSchema) obj; - return Objects.equals(schemaName, o.schemaName) && - Objects.equals(notExists, o.notExists) && - Objects.equals(properties, o.properties); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("schemaName", schemaName) - .add("notExists", notExists) - .add("properties", properties) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CreateTable.java b/trino-parser/src/main/java/io/trino/sql/tree/CreateTable.java deleted file mode 100644 index e288062fb..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CreateTable.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class CreateTable - extends Statement -{ - private final QualifiedName name; - private final List elements; - private final boolean notExists; - private final List properties; - private final Optional comment; - - public CreateTable(QualifiedName name, List elements, boolean notExists, List properties, Optional comment) - { - this(Optional.empty(), name, elements, notExists, properties, comment); - } - - public CreateTable(NodeLocation location, QualifiedName name, List elements, boolean notExists, List properties, Optional comment) - { - this(Optional.of(location), name, elements, notExists, properties, comment); - } - - private CreateTable(Optional location, QualifiedName name, List elements, boolean notExists, List properties, Optional comment) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.elements = ImmutableList.copyOf(requireNonNull(elements, "elements is null")); - this.notExists = notExists; - this.properties = requireNonNull(properties, "properties is null"); - this.comment = requireNonNull(comment, "comment is null"); - } - - public QualifiedName getName() - { - return name; - } - - public List getElements() - { - return elements; - } - - public boolean isNotExists() - { - return notExists; - } - - public List getProperties() - { - return properties; - } - - public Optional getComment() - { - return comment; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCreateTable(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.builder() - .addAll(elements) - .addAll(properties) - .build(); - } - - @Override - public int hashCode() - { - return Objects.hash(name, elements, notExists, properties, comment); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - CreateTable o = (CreateTable) obj; - return Objects.equals(name, o.name) && - Objects.equals(elements, o.elements) && - Objects.equals(notExists, o.notExists) && - Objects.equals(properties, o.properties) && - Objects.equals(comment, o.comment); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("elements", elements) - .add("notExists", notExists) - .add("properties", properties) - .add("comment", comment) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CreateTableAsSelect.java b/trino-parser/src/main/java/io/trino/sql/tree/CreateTableAsSelect.java deleted file mode 100644 index 628c3e4b1..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CreateTableAsSelect.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class CreateTableAsSelect - extends Statement -{ - private final QualifiedName name; - private final Query query; - private final boolean notExists; - private final List properties; - private final boolean withData; - private final Optional> columnAliases; - private final Optional comment; - - public CreateTableAsSelect(QualifiedName name, Query query, boolean notExists, List properties, boolean withData, Optional> columnAliases, Optional comment) - { - this(Optional.empty(), name, query, notExists, properties, withData, columnAliases, comment); - } - - public CreateTableAsSelect(NodeLocation location, QualifiedName name, Query query, boolean notExists, List properties, boolean withData, Optional> columnAliases, Optional comment) - { - this(Optional.of(location), name, query, notExists, properties, withData, columnAliases, comment); - } - - private CreateTableAsSelect(Optional location, QualifiedName name, Query query, boolean notExists, List properties, boolean withData, Optional> columnAliases, Optional comment) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.query = requireNonNull(query, "query is null"); - this.notExists = notExists; - this.properties = ImmutableList.copyOf(requireNonNull(properties, "properties is null")); - this.withData = withData; - this.columnAliases = columnAliases; - this.comment = requireNonNull(comment, "comment is null"); - } - - public QualifiedName getName() - { - return name; - } - - public Query getQuery() - { - return query; - } - - public boolean isNotExists() - { - return notExists; - } - - public List getProperties() - { - return properties; - } - - public boolean isWithData() - { - return withData; - } - - public Optional> getColumnAliases() - { - return columnAliases; - } - - public Optional getComment() - { - return comment; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCreateTableAsSelect(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.builder() - .add(query) - .addAll(properties) - .build(); - } - - @Override - public int hashCode() - { - return Objects.hash(name, query, properties, withData, columnAliases, comment); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - CreateTableAsSelect o = (CreateTableAsSelect) obj; - return Objects.equals(name, o.name) - && Objects.equals(query, o.query) - && Objects.equals(notExists, o.notExists) - && Objects.equals(properties, o.properties) - && Objects.equals(withData, o.withData) - && Objects.equals(columnAliases, o.columnAliases) - && Objects.equals(comment, o.comment); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("query", query) - .add("notExists", notExists) - .add("properties", properties) - .add("withData", withData) - .add("columnAliases", columnAliases) - .add("comment", comment) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CreateView.java b/trino-parser/src/main/java/io/trino/sql/tree/CreateView.java deleted file mode 100644 index d25836b79..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CreateView.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class CreateView - extends Statement -{ - public enum Security - { - INVOKER, DEFINER - } - - private final QualifiedName name; - private final Query query; - private final boolean replace; - private final Optional comment; - private final Optional security; - - public CreateView(QualifiedName name, Query query, boolean replace, Optional comment, Optional security) - { - this(Optional.empty(), name, query, replace, comment, security); - } - - public CreateView(NodeLocation location, QualifiedName name, Query query, boolean replace, Optional comment, Optional security) - { - this(Optional.of(location), name, query, replace, comment, security); - } - - private CreateView(Optional location, QualifiedName name, Query query, boolean replace, Optional comment, Optional security) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.query = requireNonNull(query, "query is null"); - this.replace = replace; - this.comment = requireNonNull(comment, "comment is null"); - this.security = requireNonNull(security, "security is null"); - } - - public QualifiedName getName() - { - return name; - } - - public Query getQuery() - { - return query; - } - - public boolean isReplace() - { - return replace; - } - - public Optional getComment() - { - return comment; - } - - public Optional getSecurity() - { - return security; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCreateView(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(query); - } - - @Override - public int hashCode() - { - return Objects.hash(name, query, replace, security); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - CreateView o = (CreateView) obj; - return Objects.equals(name, o.name) - && Objects.equals(query, o.query) - && Objects.equals(replace, o.replace) - && Objects.equals(comment, o.comment) - && Objects.equals(security, o.security); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("query", query) - .add("replace", replace) - .add("comment", comment) - .add("security", security) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Cube.java b/trino-parser/src/main/java/io/trino/sql/tree/Cube.java deleted file mode 100644 index 2a5b567ec..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Cube.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Cube - extends GroupingElement -{ - private final List columns; - - public Cube(List columns) - { - this(Optional.empty(), columns); - } - - public Cube(NodeLocation location, List columns) - { - this(Optional.of(location), columns); - } - - private Cube(Optional location, List columns) - { - super(location); - this.columns = ImmutableList.copyOf(requireNonNull(columns, "columns is null")); - } - - @Override - public List getExpressions() - { - return columns; - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitCube(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Cube cube = (Cube) o; - return Objects.equals(columns, cube.columns); - } - - @Override - public int hashCode() - { - return Objects.hash(columns); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("columns", columns) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CurrentCatalog.java b/trino-parser/src/main/java/io/trino/sql/tree/CurrentCatalog.java deleted file mode 100644 index 141f0c2aa..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CurrentCatalog.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -public class CurrentCatalog - extends Expression -{ - public CurrentCatalog(NodeLocation location) - { - this(Optional.of(location)); - } - - private CurrentCatalog(Optional location) - { - super(location); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCurrentCatalog(this, context); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return true; - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CurrentPath.java b/trino-parser/src/main/java/io/trino/sql/tree/CurrentPath.java deleted file mode 100644 index 031c2755e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CurrentPath.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -public class CurrentPath - extends Expression -{ - public CurrentPath(NodeLocation location) - { - this(Optional.of(location)); - } - - private CurrentPath(Optional location) - { - super(location); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCurrentPath(this, context); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return true; - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CurrentSchema.java b/trino-parser/src/main/java/io/trino/sql/tree/CurrentSchema.java deleted file mode 100644 index f4aaf5c40..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CurrentSchema.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -public class CurrentSchema - extends Expression -{ - public CurrentSchema(NodeLocation location) - { - this(Optional.of(location)); - } - - private CurrentSchema(Optional location) - { - super(location); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCurrentSchema(this, context); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return true; - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CurrentTime.java b/trino-parser/src/main/java/io/trino/sql/tree/CurrentTime.java deleted file mode 100644 index c111018e2..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CurrentTime.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class CurrentTime - extends Expression -{ - private final Function function; - private final Integer precision; - - public enum Function - { - TIME("current_time"), - DATE("current_date"), - TIMESTAMP("current_timestamp"), - LOCALTIME("localtime"), - LOCALTIMESTAMP("localtimestamp"); - - private final String name; - - Function(String name) - { - this.name = name; - } - - public String getName() - { - return name; - } - } - - public CurrentTime(Function function) - { - this(Optional.empty(), function, null); - } - - public CurrentTime(NodeLocation location, Function function) - { - this(Optional.of(location), function, null); - } - - public CurrentTime(Function function, Integer precision) - { - this(Optional.empty(), function, precision); - } - - public CurrentTime(NodeLocation location, Function function, Integer precision) - { - this(Optional.of(location), function, precision); - } - - private CurrentTime(Optional location, Function function, Integer precision) - { - super(location); - requireNonNull(function, "function is null"); - this.function = function; - this.precision = precision; - } - - public Function getFunction() - { - return function; - } - - public Integer getPrecision() - { - return precision; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCurrentTime(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if ((o == null) || (getClass() != o.getClass())) { - return false; - } - CurrentTime that = (CurrentTime) o; - return (function == that.function) && - Objects.equals(precision, that.precision); - } - - @Override - public int hashCode() - { - return Objects.hash(function, precision); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - CurrentTime otherNode = (CurrentTime) other; - return (function == otherNode.function) && - Objects.equals(precision, otherNode.precision); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/CurrentUser.java b/trino-parser/src/main/java/io/trino/sql/tree/CurrentUser.java deleted file mode 100644 index 4050eab4d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/CurrentUser.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -public class CurrentUser - extends Expression -{ - public CurrentUser() - { - this(Optional.empty()); - } - - public CurrentUser(NodeLocation location) - { - this(Optional.of(location)); - } - - private CurrentUser(Optional location) - { - super(location); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitCurrentUser(this, context); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return true; - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DataType.java b/trino-parser/src/main/java/io/trino/sql/tree/DataType.java deleted file mode 100644 index f0024381f..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DataType.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class DataType - extends Expression -{ - public DataType(Optional location) - { - super(location); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DataTypeParameter.java b/trino-parser/src/main/java/io/trino/sql/tree/DataTypeParameter.java deleted file mode 100644 index 4a4183dc3..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DataTypeParameter.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class DataTypeParameter - extends Node -{ - protected DataTypeParameter(Optional location) - { - super(location); - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitDataTypeParameter(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DateTimeDataType.java b/trino-parser/src/main/java/io/trino/sql/tree/DateTimeDataType.java deleted file mode 100644 index e58eaa10d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DateTimeDataType.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class DateTimeDataType - extends DataType -{ - public enum Type - { - TIMESTAMP, TIME - } - - private final Type type; - private final boolean withTimeZone; - private final Optional precision; - - public DateTimeDataType(NodeLocation location, Type type, boolean withTimeZone, Optional precision) - { - this(Optional.of(location), type, withTimeZone, precision); - } - - public DateTimeDataType(Optional location, Type type, boolean withTimeZone, Optional precision) - { - super(location); - this.type = requireNonNull(type, "type is null"); - this.withTimeZone = withTimeZone; - this.precision = requireNonNull(precision, "precision is null"); - } - - public Type getType() - { - return type; - } - - public boolean isWithTimeZone() - { - return withTimeZone; - } - - public Optional getPrecision() - { - return precision; - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitDateTimeType(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DateTimeDataType that = (DateTimeDataType) o; - return withTimeZone == that.withTimeZone && - type == that.type && - precision.equals(that.precision); - } - - @Override - public int hashCode() - { - return Objects.hash(type, withTimeZone, precision); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - DateTimeDataType otherType = (DateTimeDataType) other; - return type.equals(otherType.type) && - withTimeZone == otherType.withTimeZone && - precision.equals(otherType.precision); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Deallocate.java b/trino-parser/src/main/java/io/trino/sql/tree/Deallocate.java deleted file mode 100644 index 974db8e17..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Deallocate.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Deallocate - extends Statement -{ - private final Identifier name; - - public Deallocate(NodeLocation location, Identifier name) - { - this(Optional.of(location), name); - } - - public Deallocate(Identifier name) - { - this(Optional.empty(), name); - } - - private Deallocate(Optional location, Identifier name) - { - super(location); - this.name = requireNonNull(name, "name is null"); - } - - public Identifier getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDeallocate(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Deallocate o = (Deallocate) obj; - return Objects.equals(name, o.name); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DecimalLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/DecimalLiteral.java deleted file mode 100644 index 9b0d45753..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DecimalLiteral.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class DecimalLiteral - extends Literal -{ - private final String value; - - public DecimalLiteral(String value) - { - this(Optional.empty(), value); - } - - public DecimalLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - public DecimalLiteral(Optional location, String value) - { - super(location); - this.value = requireNonNull(value, "value is null"); - } - - public String getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDecimalLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DecimalLiteral that = (DecimalLiteral) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return Objects.hash(value); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - DecimalLiteral otherLiteral = (DecimalLiteral) other; - return value.equals(otherLiteral.value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Declare.java b/trino-parser/src/main/java/io/trino/sql/tree/Declare.java deleted file mode 100644 index c434bbfa0..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Declare.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) Canner, Inc - All Rights Reserved - * Unauthorized copying of this file, via any medium is strictly prohibited - * Proprietary and confidential - * Written by Canner dev team , Sep 2022 - */ -package io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.SqlFormatter; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Declare - extends Statement -{ - private final Identifier name; - private final Query body; - - public Declare(NodeLocation location, Identifier name, Query body) - { - this(Optional.of(location), name, body); - } - - public Declare(Identifier name, Query body) - { - this(Optional.empty(), name, body); - } - - protected Declare(Optional location, Identifier name, Query body) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.body = requireNonNull(body, "body is null"); - } - - public Identifier getName() - { - return name; - } - - public Query getBody() - { - return body; - } - - public String toStatement() - { - return SqlFormatter.formatSql(body); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDeclareCursor(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(name, body); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Declare o = (Declare) obj; - return Objects.equals(name, o.name) - && Objects.equals(body, o.body); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("body", body) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DefaultExpressionTraversalVisitor.java b/trino-parser/src/main/java/io/trino/sql/tree/DefaultExpressionTraversalVisitor.java deleted file mode 100644 index c0aeb7e0e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DefaultExpressionTraversalVisitor.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -/** - * When walking Expressions, don't traverse into SubqueryExpressions - */ -public abstract class DefaultExpressionTraversalVisitor - extends DefaultTraversalVisitor -{ - @Override - protected Void visitSubqueryExpression(SubqueryExpression node, C context) - { - // Don't traverse into Subqueries within an Expression - return null; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DefaultTraversalVisitor.java b/trino-parser/src/main/java/io/trino/sql/tree/DefaultTraversalVisitor.java deleted file mode 100644 index 61ab4ad87..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DefaultTraversalVisitor.java +++ /dev/null @@ -1,914 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -public abstract class DefaultTraversalVisitor - extends AstVisitor -{ - @Override - protected Void visitExtract(Extract node, C context) - { - process(node.getExpression(), context); - return null; - } - - @Override - protected Void visitCast(Cast node, C context) - { - process(node.getExpression(), context); - return null; - } - - @Override - protected Void visitArithmeticBinary(ArithmeticBinaryExpression node, C context) - { - process(node.getLeft(), context); - process(node.getRight(), context); - - return null; - } - - @Override - protected Void visitBetweenPredicate(BetweenPredicate node, C context) - { - process(node.getValue(), context); - process(node.getMin(), context); - process(node.getMax(), context); - - return null; - } - - @Override - protected Void visitCoalesceExpression(CoalesceExpression node, C context) - { - for (Expression operand : node.getOperands()) { - process(operand, context); - } - - return null; - } - - @Override - protected Void visitAtTimeZone(AtTimeZone node, C context) - { - process(node.getValue(), context); - process(node.getTimeZone(), context); - - return null; - } - - @Override - protected Void visitArrayConstructor(ArrayConstructor node, C context) - { - for (Expression expression : node.getValues()) { - process(expression, context); - } - - return null; - } - - @Override - protected Void visitSubscriptExpression(SubscriptExpression node, C context) - { - process(node.getBase(), context); - process(node.getIndex(), context); - - return null; - } - - @Override - protected Void visitComparisonExpression(ComparisonExpression node, C context) - { - process(node.getLeft(), context); - process(node.getRight(), context); - - return null; - } - - @Override - protected Void visitFormat(Format node, C context) - { - for (Expression argument : node.getArguments()) { - process(argument, context); - } - - return null; - } - - @Override - protected Void visitQuery(Query node, C context) - { - if (node.getWith().isPresent()) { - process(node.getWith().get(), context); - } - process(node.getQueryBody(), context); - if (node.getOrderBy().isPresent()) { - process(node.getOrderBy().get(), context); - } - if (node.getOffset().isPresent()) { - process(node.getOffset().get(), context); - } - if (node.getLimit().isPresent()) { - process(node.getLimit().get(), context); - } - - return null; - } - - @Override - protected Void visitWith(With node, C context) - { - for (WithQuery query : node.getQueries()) { - process(query, context); - } - - return null; - } - - @Override - protected Void visitWithQuery(WithQuery node, C context) - { - process(node.getQuery(), context); - return null; - } - - @Override - protected Void visitSelect(Select node, C context) - { - for (SelectItem item : node.getSelectItems()) { - process(item, context); - } - - return null; - } - - @Override - protected Void visitSingleColumn(SingleColumn node, C context) - { - process(node.getExpression(), context); - - return null; - } - - @Override - protected Void visitAllColumns(AllColumns node, C context) - { - node.getTarget().ifPresent(value -> process(value, context)); - - return null; - } - - @Override - protected Void visitWhenClause(WhenClause node, C context) - { - process(node.getOperand(), context); - process(node.getResult(), context); - - return null; - } - - @Override - protected Void visitInPredicate(InPredicate node, C context) - { - process(node.getValue(), context); - process(node.getValueList(), context); - - return null; - } - - @Override - protected Void visitFunctionCall(FunctionCall node, C context) - { - for (Expression argument : node.getArguments()) { - process(argument, context); - } - - if (node.getOrderBy().isPresent()) { - process(node.getOrderBy().get(), context); - } - - if (node.getWindow().isPresent()) { - process((Node) node.getWindow().get(), context); - } - - if (node.getFilter().isPresent()) { - process(node.getFilter().get(), context); - } - - return null; - } - - @Override - protected Void visitWindowOperation(WindowOperation node, C context) - { - process(node.getName(), context); - process((Node) node.getWindow(), context); - - return null; - } - - @Override - protected Void visitGroupingOperation(GroupingOperation node, C context) - { - for (Expression columnArgument : node.getGroupingColumns()) { - process(columnArgument, context); - } - - return null; - } - - @Override - protected Void visitDereferenceExpression(DereferenceExpression node, C context) - { - process(node.getBase(), context); - return null; - } - - @Override - protected Void visitWindowReference(WindowReference node, C context) - { - process(node.getName(), context); - - return null; - } - - @Override - public Void visitWindowSpecification(WindowSpecification node, C context) - { - if (node.getExistingWindowName().isPresent()) { - process(node.getExistingWindowName().get(), context); - } - - for (Expression expression : node.getPartitionBy()) { - process(expression, context); - } - - if (node.getOrderBy().isPresent()) { - process(node.getOrderBy().get(), context); - } - - if (node.getFrame().isPresent()) { - process(node.getFrame().get(), context); - } - - return null; - } - - @Override - protected Void visitWindowDefinition(WindowDefinition node, C context) - { - process(node.getWindow()); - - return null; - } - - @Override - public Void visitWindowFrame(WindowFrame node, C context) - { - process(node.getStart(), context); - if (node.getEnd().isPresent()) { - process(node.getEnd().get(), context); - } - for (MeasureDefinition measureDefinition : node.getMeasures()) { - process(measureDefinition, context); - } - for (VariableDefinition variableDefinition : node.getVariableDefinitions()) { - process(variableDefinition, context); - } - - return null; - } - - @Override - protected Void visitMeasureDefinition(MeasureDefinition node, C context) - { - process(node.getExpression(), context); - return null; - } - - @Override - protected Void visitVariableDefinition(VariableDefinition node, C context) - { - process(node.getExpression(), context); - return null; - } - - @Override - public Void visitFrameBound(FrameBound node, C context) - { - if (node.getValue().isPresent()) { - process(node.getValue().get(), context); - } - - return null; - } - - @Override - protected Void visitOffset(Offset node, C context) - { - process(node.getRowCount()); - - return null; - } - - @Override - protected Void visitLimit(Limit node, C context) - { - process(node.getRowCount()); - - return null; - } - - @Override - protected Void visitFetchFirst(FetchFirst node, C context) - { - node.getRowCount().ifPresent(this::process); - - return null; - } - - @Override - protected Void visitSimpleCaseExpression(SimpleCaseExpression node, C context) - { - process(node.getOperand(), context); - for (WhenClause clause : node.getWhenClauses()) { - process(clause, context); - } - - node.getDefaultValue() - .ifPresent(value -> process(value, context)); - - return null; - } - - @Override - protected Void visitInListExpression(InListExpression node, C context) - { - for (Expression value : node.getValues()) { - process(value, context); - } - - return null; - } - - @Override - protected Void visitNullIfExpression(NullIfExpression node, C context) - { - process(node.getFirst(), context); - process(node.getSecond(), context); - - return null; - } - - @Override - protected Void visitIfExpression(IfExpression node, C context) - { - process(node.getCondition(), context); - process(node.getTrueValue(), context); - if (node.getFalseValue().isPresent()) { - process(node.getFalseValue().get(), context); - } - - return null; - } - - @Override - protected Void visitTryExpression(TryExpression node, C context) - { - process(node.getInnerExpression(), context); - return null; - } - - @Override - protected Void visitBindExpression(BindExpression node, C context) - { - for (Expression value : node.getValues()) { - process(value, context); - } - process(node.getFunction(), context); - - return null; - } - - @Override - protected Void visitArithmeticUnary(ArithmeticUnaryExpression node, C context) - { - process(node.getValue(), context); - return null; - } - - @Override - protected Void visitNotExpression(NotExpression node, C context) - { - process(node.getValue(), context); - return null; - } - - @Override - protected Void visitSearchedCaseExpression(SearchedCaseExpression node, C context) - { - for (WhenClause clause : node.getWhenClauses()) { - process(clause, context); - } - node.getDefaultValue() - .ifPresent(value -> process(value, context)); - - return null; - } - - @Override - protected Void visitLikePredicate(LikePredicate node, C context) - { - process(node.getValue(), context); - process(node.getPattern(), context); - node.getEscape().ifPresent(value -> process(value, context)); - - return null; - } - - @Override - protected Void visitIsNotNullPredicate(IsNotNullPredicate node, C context) - { - process(node.getValue(), context); - return null; - } - - @Override - protected Void visitIsNullPredicate(IsNullPredicate node, C context) - { - process(node.getValue(), context); - return null; - } - - @Override - protected Void visitLogicalExpression(LogicalExpression node, C context) - { - for (Node child : node.getTerms()) { - process(child, context); - } - - return null; - } - - @Override - protected Void visitSubqueryExpression(SubqueryExpression node, C context) - { - process(node.getQuery(), context); - return null; - } - - @Override - protected Void visitOrderBy(OrderBy node, C context) - { - for (SortItem sortItem : node.getSortItems()) { - process(sortItem, context); - } - return null; - } - - @Override - protected Void visitSortItem(SortItem node, C context) - { - process(node.getSortKey(), context); - return null; - } - - @Override - protected Void visitQuerySpecification(QuerySpecification node, C context) - { - process(node.getSelect(), context); - if (node.getFrom().isPresent()) { - process(node.getFrom().get(), context); - } - if (node.getWhere().isPresent()) { - process(node.getWhere().get(), context); - } - if (node.getGroupBy().isPresent()) { - process(node.getGroupBy().get(), context); - } - if (node.getHaving().isPresent()) { - process(node.getHaving().get(), context); - } - for (WindowDefinition windowDefinition : node.getWindows()) { - process(windowDefinition, context); - } - if (node.getOrderBy().isPresent()) { - process(node.getOrderBy().get(), context); - } - if (node.getOffset().isPresent()) { - process(node.getOffset().get(), context); - } - if (node.getLimit().isPresent()) { - process(node.getLimit().get(), context); - } - return null; - } - - @Override - protected Void visitSetOperation(SetOperation node, C context) - { - for (Relation relation : node.getRelations()) { - process(relation, context); - } - return null; - } - - @Override - protected Void visitValues(Values node, C context) - { - for (Expression row : node.getRows()) { - process(row, context); - } - return null; - } - - @Override - protected Void visitRow(Row node, C context) - { - for (Expression expression : node.getItems()) { - process(expression, context); - } - return null; - } - - @Override - protected Void visitTableSubquery(TableSubquery node, C context) - { - process(node.getQuery(), context); - return null; - } - - @Override - protected Void visitAliasedRelation(AliasedRelation node, C context) - { - process(node.getRelation(), context); - return null; - } - - @Override - protected Void visitSampledRelation(SampledRelation node, C context) - { - process(node.getRelation(), context); - process(node.getSamplePercentage(), context); - return null; - } - - @Override - protected Void visitJoin(Join node, C context) - { - process(node.getLeft(), context); - process(node.getRight(), context); - - node.getCriteria() - .filter(criteria -> criteria instanceof JoinOn) - .ifPresent(criteria -> process(((JoinOn) criteria).getExpression(), context)); - - return null; - } - - @Override - protected Void visitUnnest(Unnest node, C context) - { - for (Expression expression : node.getExpressions()) { - process(expression, context); - } - - return null; - } - - @Override - protected Void visitGroupBy(GroupBy node, C context) - { - for (GroupingElement groupingElement : node.getGroupingElements()) { - process(groupingElement, context); - } - - return null; - } - - @Override - protected Void visitCube(Cube node, C context) - { - return null; - } - - @Override - protected Void visitRollup(Rollup node, C context) - { - return null; - } - - @Override - protected Void visitSimpleGroupBy(SimpleGroupBy node, C context) - { - for (Expression expression : node.getExpressions()) { - process(expression, context); - } - - return null; - } - - @Override - protected Void visitGroupingSets(GroupingSets node, C context) - { - return null; - } - - @Override - protected Void visitInsert(Insert node, C context) - { - process(node.getQuery(), context); - - return null; - } - - @Override - protected Void visitRefreshMaterializedView(RefreshMaterializedView node, C context) - { - return null; - } - - @Override - protected Void visitDelete(Delete node, C context) - { - process(node.getTable(), context); - node.getWhere().ifPresent(where -> process(where, context)); - - return null; - } - - @Override - protected Void visitUpdate(Update node, C context) - { - process(node.getTable(), context); - node.getAssignments().forEach(value -> process(value, context)); - node.getWhere().ifPresent(where -> process(where, context)); - - return null; - } - - @Override - protected Void visitUpdateAssignment(UpdateAssignment node, C context) - { - process(node.getName(), context); - process(node.getValue(), context); - return null; - } - - @Override - protected Void visitMerge(Merge node, C context) - { - process(node.getTable(), context); - node.getTargetAlias().ifPresent(target -> process(target, context)); - process(node.getRelation(), context); - process(node.getExpression(), context); - node.getMergeCases().forEach(mergeCase -> process(mergeCase, context)); - return null; - } - - @Override - protected Void visitMergeInsert(MergeInsert node, C context) - { - node.getExpression().ifPresent(expression -> process(expression, context)); - node.getColumns().forEach(column -> process(column, context)); - node.getValues().forEach(expression -> process(expression, context)); - return null; - } - - @Override - protected Void visitMergeUpdate(MergeUpdate node, C context) - { - node.getExpression().ifPresent(expression -> process(expression, context)); - node.getAssignments().forEach(assignment -> { - process(assignment.getTarget(), context); - process(assignment.getValue(), context); - }); - return null; - } - - @Override - protected Void visitMergeDelete(MergeDelete node, C context) - { - node.getExpression().ifPresent(expression -> process(expression, context)); - return null; - } - - @Override - protected Void visitCreateTableAsSelect(CreateTableAsSelect node, C context) - { - process(node.getQuery(), context); - for (Property property : node.getProperties()) { - process(property, context); - } - - return null; - } - - @Override - protected Void visitProperty(Property node, C context) - { - process(node.getName(), context); - if (!node.isSetToDefault()) { - process(node.getNonDefaultValue(), context); - } - return null; - } - - @Override - protected Void visitAnalyze(Analyze node, C context) - { - for (Property property : node.getProperties()) { - process(property, context); - } - return null; - } - - @Override - protected Void visitCreateView(CreateView node, C context) - { - process(node.getQuery(), context); - - return null; - } - - @Override - protected Void visitSetSession(SetSession node, C context) - { - process(node.getValue(), context); - - return null; - } - - @Override - protected Void visitAddColumn(AddColumn node, C context) - { - process(node.getColumn(), context); - - return null; - } - - @Override - protected Void visitCreateSchema(CreateSchema node, C context) - { - for (Property property : node.getProperties()) { - process(property, context); - } - - return null; - } - - @Override - protected Void visitCreateTable(CreateTable node, C context) - { - for (TableElement tableElement : node.getElements()) { - process(tableElement, context); - } - for (Property property : node.getProperties()) { - process(property, context); - } - - return null; - } - - @Override - protected Void visitStartTransaction(StartTransaction node, C context) - { - for (TransactionMode transactionMode : node.getTransactionModes()) { - process(transactionMode, context); - } - - return null; - } - - @Override - protected Void visitExplain(Explain node, C context) - { - process(node.getStatement(), context); - - for (ExplainOption option : node.getOptions()) { - process(option, context); - } - - return null; - } - - @Override - protected Void visitExplainAnalyze(ExplainAnalyze node, C context) - { - process(node.getStatement(), context); - return null; - } - - @Override - protected Void visitShowStats(ShowStats node, C context) - { - process(node.getRelation(), context); - return null; - } - - @Override - protected Void visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, C context) - { - process(node.getValue(), context); - process(node.getSubquery(), context); - - return null; - } - - @Override - protected Void visitExists(ExistsPredicate node, C context) - { - process(node.getSubquery(), context); - - return null; - } - - @Override - protected Void visitLateral(Lateral node, C context) - { - process(node.getQuery(), context); - - return null; - } - - @Override - protected Void visitLambdaExpression(LambdaExpression node, C context) - { - process(node.getBody(), context); - - return null; - } - - @Override - protected Void visitExcludedPattern(ExcludedPattern node, C context) - { - process(node.getPattern(), context); - - return null; - } - - @Override - protected Void visitPatternAlternation(PatternAlternation node, C context) - { - for (RowPattern rowPattern : node.getPatterns()) { - process(rowPattern, context); - } - - return null; - } - - @Override - protected Void visitPatternConcatenation(PatternConcatenation node, C context) - { - for (RowPattern rowPattern : node.getPatterns()) { - process(rowPattern, context); - } - - return null; - } - - @Override - protected Void visitPatternPermutation(PatternPermutation node, C context) - { - for (RowPattern rowPattern : node.getPatterns()) { - process(rowPattern, context); - } - - return null; - } - - @Override - protected Void visitPatternVariable(PatternVariable node, C context) - { - process(node.getName(), context); - - return null; - } - - @Override - protected Void visitQuantifiedPattern(QuantifiedPattern node, C context) - { - process(node.getPattern(), context); - - return null; - } - - @Override - protected Void visitLabelDereference(LabelDereference node, C context) - { - node.getReference().ifPresent(reference -> process(reference, context)); - - return null; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Delete.java b/trino-parser/src/main/java/io/trino/sql/tree/Delete.java deleted file mode 100644 index cbdbb4841..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Delete.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Delete - extends Statement -{ - private final Table table; - private final Optional where; - - public Delete(Table table, Optional where) - { - this(Optional.empty(), table, where); - } - - public Delete(NodeLocation location, Table table, Optional where) - { - this(Optional.of(location), table, where); - } - - private Delete(Optional location, Table table, Optional where) - { - super(location); - this.table = requireNonNull(table, "table is null"); - this.where = requireNonNull(where, "where is null"); - } - - public Table getTable() - { - return table; - } - - public Optional getWhere() - { - return where; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDelete(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.add(table); - where.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public int hashCode() - { - return Objects.hash(table, where); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Delete o = (Delete) obj; - return Objects.equals(table, o.table) && - Objects.equals(where, o.where); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table.getName()) - .add("where", where) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Deny.java b/trino-parser/src/main/java/io/trino/sql/tree/Deny.java deleted file mode 100644 index d20f035bd..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Deny.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Deny - extends Statement -{ - private final Optional> privileges; // missing means ALL PRIVILEGES - private final Optional type; - private final QualifiedName name; - private final PrincipalSpecification grantee; - - public Deny(Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee) - { - this(Optional.empty(), privileges, type, name, grantee); - } - - public Deny(NodeLocation location, Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee) - { - this(Optional.of(location), privileges, type, name, grantee); - } - - private Deny(Optional location, Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee) - { - super(location); - requireNonNull(privileges, "privileges is null"); - this.privileges = privileges.map(ImmutableList::copyOf); - this.type = requireNonNull(type, "type is null"); - this.name = requireNonNull(name, "name is null"); - this.grantee = requireNonNull(grantee, "grantee is null"); - } - - public Optional> getPrivileges() - { - return privileges; - } - - public Optional getType() - { - return type; - } - - public QualifiedName getName() - { - return name; - } - - public PrincipalSpecification getGrantee() - { - return grantee; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDeny(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(privileges, type, name, grantee); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Deny o = (Deny) obj; - return Objects.equals(privileges, o.privileges) && - Objects.equals(type, o.type) && - Objects.equals(name, o.name) && - Objects.equals(grantee, o.grantee); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("privileges", privileges) - .add("type", type) - .add("name", name) - .add("grantee", grantee) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DereferenceExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/DereferenceExpression.java deleted file mode 100644 index 9e094d9f3..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DereferenceExpression.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class DereferenceExpression - extends Expression -{ - private final Expression base; - private final Optional field; - - public DereferenceExpression(Expression base, Identifier field) - { - this(Optional.empty(), base, Optional.of(field)); - } - - public DereferenceExpression(NodeLocation location, Expression base, Identifier field) - { - this(Optional.of(location), base, Optional.of(field)); - } - - public DereferenceExpression(Identifier label) - { - this(Optional.empty(), label, Optional.empty()); - } - - public DereferenceExpression(NodeLocation location, Identifier label) - { - this(Optional.of(location), label, Optional.empty()); - } - - public DereferenceExpression(Optional location, Expression base, Optional field) - { - super(location); - checkArgument(base != null, "base is null"); - requireNonNull(field, "field is null"); - this.base = base; - this.field = field; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDereferenceExpression(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder children = ImmutableList.builder(); - children.add(base); - field.ifPresent(children::add); - return children.build(); - } - - public Expression getBase() - { - return base; - } - - public Optional getField() - { - return field; - } - - /** - * If this DereferenceExpression looks like a QualifiedName, return QualifiedName. - * Otherwise return null - */ - public static QualifiedName getQualifiedName(DereferenceExpression expression) - { - if (!expression.field.isPresent()) { - return null; - } - - Identifier field = expression.field.get(); - - List parts = null; - if (expression.base instanceof Identifier) { - parts = ImmutableList.of((Identifier) expression.base, field); - } - else if (expression.base instanceof DereferenceExpression) { - QualifiedName baseQualifiedName = getQualifiedName((DereferenceExpression) expression.base); - if (baseQualifiedName != null) { - ImmutableList.Builder builder = ImmutableList.builder(); - builder.addAll(baseQualifiedName.getOriginalParts()); - builder.add(field); - parts = builder.build(); - } - } - - return parts == null ? null : QualifiedName.of(parts); - } - - public static Expression from(QualifiedName name) - { - Expression result = null; - - for (Identifier part : name.getOriginalParts()) { - if (result == null) { - result = part; - } - else { - result = new DereferenceExpression(result, part); - } - } - - return result; - } - - public static boolean isQualifiedAllFieldsReference(Expression expression) - { - return expression instanceof DereferenceExpression && !((DereferenceExpression) expression).field.isPresent(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DereferenceExpression that = (DereferenceExpression) o; - return Objects.equals(base, that.base) && - Objects.equals(field, that.field); - } - - @Override - public int hashCode() - { - return Objects.hash(base, field); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DescribeInput.java b/trino-parser/src/main/java/io/trino/sql/tree/DescribeInput.java deleted file mode 100644 index a5fcbce41..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DescribeInput.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class DescribeInput - extends Statement -{ - private final Identifier name; - - public DescribeInput(NodeLocation location, Identifier name) - { - this(Optional.of(location), name); - } - - public DescribeInput(Identifier name) - { - this(Optional.empty(), name); - } - - private DescribeInput(Optional location, Identifier name) - { - super(location); - this.name = name; - } - - public Identifier getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDescribeInput(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - DescribeInput o = (DescribeInput) obj; - return Objects.equals(name, o.name); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DescribeOutput.java b/trino-parser/src/main/java/io/trino/sql/tree/DescribeOutput.java deleted file mode 100644 index 5447d5902..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DescribeOutput.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class DescribeOutput - extends Statement -{ - private final Identifier name; - - public DescribeOutput(NodeLocation location, Identifier name) - { - this(Optional.of(location), name); - } - - public DescribeOutput(Identifier name) - { - this(Optional.empty(), name); - } - - private DescribeOutput(Optional location, Identifier name) - { - super(location); - this.name = name; - } - - public Identifier getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDescribeOutput(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - DescribeOutput o = (DescribeOutput) obj; - return Objects.equals(name, o.name); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DoubleLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/DoubleLiteral.java deleted file mode 100644 index 5a36af50c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DoubleLiteral.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class DoubleLiteral - extends Literal -{ - private final double value; - - public DoubleLiteral(String value) - { - this(Optional.empty(), value); - } - - public DoubleLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - private DoubleLiteral(Optional location, String value) - { - super(location); - requireNonNull(value, "value is null"); - this.value = Double.parseDouble(value); - } - - public double getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDoubleLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - DoubleLiteral that = (DoubleLiteral) o; - - if (Double.compare(that.value, value) != 0) { - return false; - } - - return true; - } - - @SuppressWarnings("UnaryPlus") - @Override - public int hashCode() - { - long temp = value != +0.0d ? Double.doubleToLongBits(value) : 0L; - return (int) (temp ^ (temp >>> 32)); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return value == ((DoubleLiteral) other).value; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DropColumn.java b/trino-parser/src/main/java/io/trino/sql/tree/DropColumn.java deleted file mode 100644 index 469a85145..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DropColumn.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class DropColumn - extends Statement -{ - private final QualifiedName table; - private final Identifier column; - private final boolean tableExists; - private final boolean columnExists; - - public DropColumn(QualifiedName table, Identifier column, boolean tableExists, boolean columnExists) - { - this(Optional.empty(), table, column, tableExists, columnExists); - } - - public DropColumn(NodeLocation location, QualifiedName table, Identifier column, boolean tableExists, boolean columnExists) - { - this(Optional.of(location), table, column, tableExists, columnExists); - } - - private DropColumn(Optional location, QualifiedName table, Identifier column, boolean tableExists, boolean columnExists) - { - super(location); - this.table = requireNonNull(table, "table is null"); - this.column = requireNonNull(column, "column is null"); - this.tableExists = tableExists; - this.columnExists = columnExists; - } - - public QualifiedName getTable() - { - return table; - } - - public Identifier getColumn() - { - return column; - } - - public boolean isTableExists() - { - return tableExists; - } - - public boolean isColumnExists() - { - return columnExists; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDropColumn(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DropColumn that = (DropColumn) o; - return Objects.equals(table, that.table) && - Objects.equals(column, that.column); - } - - @Override - public int hashCode() - { - return Objects.hash(table, column); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .add("column", column) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DropMaterializedView.java b/trino-parser/src/main/java/io/trino/sql/tree/DropMaterializedView.java deleted file mode 100644 index 9e62b05a8..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DropMaterializedView.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class DropMaterializedView - extends Statement -{ - private final QualifiedName name; - private final boolean exists; - - public DropMaterializedView(QualifiedName name, boolean exists) - { - this(Optional.empty(), name, exists); - } - - public DropMaterializedView(NodeLocation location, QualifiedName name, boolean exists) - { - this(Optional.of(location), name, exists); - } - - private DropMaterializedView(Optional location, QualifiedName name, boolean exists) - { - super(location); - this.name = name; - this.exists = exists; - } - - public QualifiedName getName() - { - return name; - } - - public boolean isExists() - { - return exists; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDropMaterializedView(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(name, exists); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - DropMaterializedView o = (DropMaterializedView) obj; - return Objects.equals(name, o.name) - && (exists == o.exists); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("exists", exists) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DropRole.java b/trino-parser/src/main/java/io/trino/sql/tree/DropRole.java deleted file mode 100644 index 595fb6bee..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DropRole.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class DropRole - extends Statement -{ - private final Identifier name; - private final Optional catalog; - - public DropRole(Identifier name, Optional catalog) - { - this(Optional.empty(), name, catalog); - } - - public DropRole(NodeLocation location, Identifier name, Optional catalog) - { - this(Optional.of(location), name, catalog); - } - - private DropRole(Optional location, Identifier name, Optional catalog) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.catalog = requireNonNull(catalog, "catalog is null"); - } - - public Identifier getName() - { - return name; - } - - public Optional getCatalog() - { - return catalog; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DropRole dropRole = (DropRole) o; - return Objects.equals(name, dropRole.name) && - Objects.equals(catalog, dropRole.catalog); - } - - @Override - public int hashCode() - { - return Objects.hash(name, catalog); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("catalog", catalog) - .toString(); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDropRole(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DropSchema.java b/trino-parser/src/main/java/io/trino/sql/tree/DropSchema.java deleted file mode 100644 index 83d78ba4a..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DropSchema.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class DropSchema - extends Statement -{ - private final QualifiedName schemaName; - private final boolean exists; - private final boolean cascade; - - public DropSchema(QualifiedName schemaName, boolean exists, boolean cascade) - { - this(Optional.empty(), schemaName, exists, cascade); - } - - public DropSchema(NodeLocation location, QualifiedName schemaName, boolean exists, boolean cascade) - { - this(Optional.of(location), schemaName, exists, cascade); - } - - private DropSchema(Optional location, QualifiedName schemaName, boolean exists, boolean cascade) - { - super(location); - this.schemaName = requireNonNull(schemaName, "schemaName is null"); - this.exists = exists; - this.cascade = cascade; - } - - public QualifiedName getSchemaName() - { - return schemaName; - } - - public boolean isExists() - { - return exists; - } - - public boolean isCascade() - { - return cascade; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDropSchema(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - DropSchema o = (DropSchema) obj; - return Objects.equals(schemaName, o.schemaName) && - (exists == o.exists) && - (cascade == o.cascade); - } - - @Override - public int hashCode() - { - return Objects.hash(schemaName, exists); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("schemaName", schemaName) - .add("exists", exists) - .add("cascade", cascade) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DropTable.java b/trino-parser/src/main/java/io/trino/sql/tree/DropTable.java deleted file mode 100644 index a2066d04a..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DropTable.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class DropTable - extends Statement -{ - private final QualifiedName tableName; - private final boolean exists; - - public DropTable(QualifiedName tableName, boolean exists) - { - this(Optional.empty(), tableName, exists); - } - - public DropTable(NodeLocation location, QualifiedName tableName, boolean exists) - { - this(Optional.of(location), tableName, exists); - } - - private DropTable(Optional location, QualifiedName tableName, boolean exists) - { - super(location); - this.tableName = tableName; - this.exists = exists; - } - - public QualifiedName getTableName() - { - return tableName; - } - - public boolean isExists() - { - return exists; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDropTable(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(tableName, exists); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - DropTable o = (DropTable) obj; - return Objects.equals(tableName, o.tableName) - && (exists == o.exists); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("tableName", tableName) - .add("exists", exists) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/DropView.java b/trino-parser/src/main/java/io/trino/sql/tree/DropView.java deleted file mode 100644 index 1d2307d28..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/DropView.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class DropView - extends Statement -{ - private final QualifiedName name; - private final boolean exists; - - public DropView(QualifiedName name, boolean exists) - { - this(Optional.empty(), name, exists); - } - - public DropView(NodeLocation location, QualifiedName name, boolean exists) - { - this(Optional.of(location), name, exists); - } - - private DropView(Optional location, QualifiedName name, boolean exists) - { - super(location); - this.name = name; - this.exists = exists; - } - - public QualifiedName getName() - { - return name; - } - - public boolean isExists() - { - return exists; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitDropView(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(name, exists); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - DropView o = (DropView) obj; - return Objects.equals(name, o.name) - && (exists == o.exists); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("exists", exists) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/EmptyPattern.java b/trino-parser/src/main/java/io/trino/sql/tree/EmptyPattern.java deleted file mode 100644 index ffb6480bd..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/EmptyPattern.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class EmptyPattern - extends RowPattern -{ - public EmptyPattern(NodeLocation location) - { - this(Optional.of(location)); - } - - private EmptyPattern(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitEmptyPattern(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return true; - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public String toString() - { - return toStringHelper(this) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Except.java b/trino-parser/src/main/java/io/trino/sql/tree/Except.java deleted file mode 100644 index 422e78e97..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Except.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Except - extends SetOperation -{ - private final Relation left; - private final Relation right; - - public Except(Relation left, Relation right, boolean distinct) - { - this(Optional.empty(), left, right, distinct); - } - - public Except(NodeLocation location, Relation left, Relation right, boolean distinct) - { - this(Optional.of(location), left, right, distinct); - } - - private Except(Optional location, Relation left, Relation right, boolean distinct) - { - super(location, distinct); - requireNonNull(left, "left is null"); - requireNonNull(right, "right is null"); - - this.left = left; - this.right = right; - } - - public Relation getLeft() - { - return left; - } - - public Relation getRight() - { - return right; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitExcept(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(left, right); - } - - @Override - public List getRelations() - { - return ImmutableList.of(left, right); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("left", left) - .add("right", right) - .add("distinct", isDistinct()) - .toString(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Except o = (Except) obj; - return Objects.equals(left, o.left) && - Objects.equals(right, o.right) && - Objects.equals(isDistinct(), o.isDistinct()); - } - - @Override - public int hashCode() - { - return Objects.hash(left, right, isDistinct()); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return this.isDistinct() == ((Except) other).isDistinct(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ExcludedPattern.java b/trino-parser/src/main/java/io/trino/sql/tree/ExcludedPattern.java deleted file mode 100644 index 33ca22b56..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ExcludedPattern.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ExcludedPattern - extends RowPattern -{ - private final RowPattern pattern; - - public ExcludedPattern(NodeLocation location, RowPattern pattern) - { - this(Optional.of(location), pattern); - } - - private ExcludedPattern(Optional location, RowPattern pattern) - { - super(location); - this.pattern = requireNonNull(pattern, "pattern is null"); - } - - public RowPattern getPattern() - { - return pattern; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitExcludedPattern(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(pattern); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ExcludedPattern o = (ExcludedPattern) obj; - return Objects.equals(pattern, o.pattern); - } - - @Override - public int hashCode() - { - return Objects.hash(pattern); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("pattern", pattern) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Execute.java b/trino-parser/src/main/java/io/trino/sql/tree/Execute.java deleted file mode 100644 index 908f16d7e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Execute.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Execute - extends Statement -{ - private final Identifier name; - private final List parameters; - - public Execute(NodeLocation location, Identifier name, List parameters) - { - this(Optional.of(location), name, parameters); - } - - public Execute(Identifier name, List parameters) - { - this(Optional.empty(), name, parameters); - } - - private Execute(Optional location, Identifier name, List parameters) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.parameters = ImmutableList.copyOf(requireNonNull(parameters, "parameters is null")); - } - - public Identifier getName() - { - return name; - } - - public List getParameters() - { - return parameters; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitExecute(this, context); - } - - @Override - public List getChildren() - { - return parameters; - } - - @Override - public int hashCode() - { - return Objects.hash(name, parameters); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Execute o = (Execute) obj; - return Objects.equals(name, o.name) && - Objects.equals(parameters, o.parameters); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("parameters", parameters) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ExistsPredicate.java b/trino-parser/src/main/java/io/trino/sql/tree/ExistsPredicate.java deleted file mode 100644 index 370ff8603..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ExistsPredicate.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class ExistsPredicate - extends Expression -{ - private final Expression subquery; - - public ExistsPredicate(Expression subquery) - { - this(Optional.empty(), subquery); - } - - public ExistsPredicate(NodeLocation location, Expression subquery) - { - this(Optional.of(location), subquery); - } - - private ExistsPredicate(Optional location, Expression subquery) - { - super(location); - requireNonNull(subquery, "subquery is null"); - this.subquery = subquery; - } - - public Expression getSubquery() - { - return subquery; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitExists(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(subquery); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - ExistsPredicate that = (ExistsPredicate) o; - return Objects.equals(subquery, that.subquery); - } - - @Override - public int hashCode() - { - return subquery.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Explain.java b/trino-parser/src/main/java/io/trino/sql/tree/Explain.java deleted file mode 100644 index d908d089a..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Explain.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Explain - extends Statement -{ - private final Statement statement; - private final List options; - - public Explain(Statement statement, List options) - { - this(Optional.empty(), statement, options); - } - - public Explain(NodeLocation location, Statement statement, List options) - { - this(Optional.of(location), statement, options); - } - - public Explain(Optional location, Statement statement, List options) - { - super(location); - this.statement = requireNonNull(statement, "statement is null"); - this.options = ImmutableList.copyOf(requireNonNull(options, "options is null")); - } - - public Statement getStatement() - { - return statement; - } - - public List getOptions() - { - return options; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitExplain(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.builder() - .add(statement) - .addAll(options) - .build(); - } - - @Override - public int hashCode() - { - return Objects.hash(statement, options); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Explain o = (Explain) obj; - return Objects.equals(statement, o.statement) && - Objects.equals(options, o.options); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("statement", statement) - .add("options", options) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ExplainAnalyze.java b/trino-parser/src/main/java/io/trino/sql/tree/ExplainAnalyze.java deleted file mode 100644 index 099184dbf..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ExplainAnalyze.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class ExplainAnalyze - extends Statement -{ - private final Statement statement; - private final boolean verbose; - - public ExplainAnalyze(Statement statement, boolean verbose) - { - this(Optional.empty(), statement, verbose); - } - - public ExplainAnalyze(NodeLocation location, boolean verbose, Statement statement) - { - this(Optional.of(location), statement, verbose); - } - - public ExplainAnalyze(Optional location, Statement statement, boolean verbose) - { - super(location); - this.statement = requireNonNull(statement, "statement is null"); - this.verbose = verbose; - } - - public Statement getStatement() - { - return statement; - } - - public boolean isVerbose() - { - return verbose; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitExplainAnalyze(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.builder() - .add(statement) - .build(); - } - - @Override - public int hashCode() - { - return Objects.hash(statement, verbose); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ExplainAnalyze o = (ExplainAnalyze) obj; - return Objects.equals(statement, o.statement); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("statement", statement) - .add("verbose", verbose) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ExplainFormat.java b/trino-parser/src/main/java/io/trino/sql/tree/ExplainFormat.java deleted file mode 100644 index 2e9528755..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ExplainFormat.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ExplainFormat - extends ExplainOption -{ - public enum Type - { - TEXT, - GRAPHVIZ, - JSON - } - - private final Type type; - - public ExplainFormat(Type type) - { - this(Optional.empty(), type); - } - - public ExplainFormat(NodeLocation location, Type type) - { - this(Optional.of(location), type); - } - - private ExplainFormat(Optional location, Type type) - { - super(location); - this.type = requireNonNull(type, "type is null"); - } - - public Type getType() - { - return type; - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(type); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ExplainFormat o = (ExplainFormat) obj; - return type == o.type; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ExplainOption.java b/trino-parser/src/main/java/io/trino/sql/tree/ExplainOption.java deleted file mode 100644 index 092e3b0fd..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ExplainOption.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class ExplainOption - extends Node -{ - protected ExplainOption(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitExplainOption(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ExplainType.java b/trino-parser/src/main/java/io/trino/sql/tree/ExplainType.java deleted file mode 100644 index 4f3409f08..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ExplainType.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ExplainType - extends ExplainOption -{ - public enum Type - { - LOGICAL, - DISTRIBUTED, - VALIDATE, - IO - } - - private final Type type; - - public ExplainType(Type type) - { - this(Optional.empty(), type); - } - - public ExplainType(NodeLocation location, Type type) - { - this(Optional.of(location), type); - } - - private ExplainType(Optional location, Type type) - { - super(location); - this.type = requireNonNull(type, "type is null"); - } - - public Type getType() - { - return type; - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(type); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ExplainType o = (ExplainType) obj; - return type == o.type; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Expression.java b/trino-parser/src/main/java/io/trino/sql/tree/Expression.java deleted file mode 100644 index 604c46e06..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Expression.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import io.trino.sql.ExpressionFormatter; - -import java.util.Optional; - -import static io.trino.sql.SqlFormatter.Dialect.DEFAULT; - -public abstract class Expression - extends Node -{ - protected Expression(Optional location) - { - super(location); - } - - /** - * Accessible for {@link AstVisitor}, use {@link AstVisitor#process(Node, Object)} instead. - */ - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitExpression(this, context); - } - - @Override - public final String toString() - { - return ExpressionFormatter.formatExpression(this, DEFAULT); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ExpressionRewriter.java b/trino-parser/src/main/java/io/trino/sql/tree/ExpressionRewriter.java deleted file mode 100644 index 300407746..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ExpressionRewriter.java +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -public class ExpressionRewriter -{ - protected Expression rewriteExpression(Expression node, C context, ExpressionTreeRewriter treeRewriter) - { - return null; - } - - public Expression rewriteRow(Row node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteArithmeticUnary(ArithmeticUnaryExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteArithmeticBinary(ArithmeticBinaryExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteComparisonExpression(ComparisonExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteBetweenPredicate(BetweenPredicate node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteLogicalExpression(LogicalExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteNotExpression(NotExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteIsNullPredicate(IsNullPredicate node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteIsNotNullPredicate(IsNotNullPredicate node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteNullIfExpression(NullIfExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteIfExpression(IfExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteSearchedCaseExpression(SearchedCaseExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteSimpleCaseExpression(SimpleCaseExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteWhenClause(WhenClause node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteCoalesceExpression(CoalesceExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteInListExpression(InListExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteFunctionCall(FunctionCall node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteWindowOperation(WindowOperation node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteLambdaExpression(LambdaExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteBindExpression(BindExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteLikePredicate(LikePredicate node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteInPredicate(InPredicate node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteExists(ExistsPredicate node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteSubqueryExpression(SubqueryExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteLiteral(Literal node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteArrayConstructor(ArrayConstructor node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteSubscriptExpression(SubscriptExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteIdentifier(Identifier node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteDereferenceExpression(DereferenceExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteExtract(Extract node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteCurrentTime(CurrentTime node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteCast(Cast node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteTryExpression(TryExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteAtTimeZone(AtTimeZone node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteCurrentCatalog(CurrentCatalog node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteCurrentSchema(CurrentSchema node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteCurrentUser(CurrentUser node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteCurrentPath(CurrentPath node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteFormat(Format node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteFieldReference(FieldReference node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteSymbolReference(SymbolReference node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteParameter(Parameter node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteQuantifiedComparison(QuantifiedComparisonExpression node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteGroupingOperation(GroupingOperation node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteGenericDataType(GenericDataType node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteRowDataType(RowDataType node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteDateTimeDataType(DateTimeDataType node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteIntervalDayTimeDataType(IntervalDayTimeDataType node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } - - public Expression rewriteLabelDereference(LabelDereference node, C context, ExpressionTreeRewriter treeRewriter) - { - return rewriteExpression(node, context, treeRewriter); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ExpressionTreeRewriter.java b/trino-parser/src/main/java/io/trino/sql/tree/ExpressionTreeRewriter.java deleted file mode 100644 index b183b29af..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ExpressionTreeRewriter.java +++ /dev/null @@ -1,1194 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; - -import java.util.Iterator; -import java.util.List; -import java.util.Optional; - -import static com.google.common.collect.ImmutableList.toImmutableList; - -public final class ExpressionTreeRewriter -{ - private final ExpressionRewriter rewriter; - private final AstVisitor> visitor; - - public static T rewriteWith(ExpressionRewriter rewriter, T node) - { - return new ExpressionTreeRewriter<>(rewriter).rewrite(node, null); - } - - public static T rewriteWith(ExpressionRewriter rewriter, T node, C context) - { - return new ExpressionTreeRewriter<>(rewriter).rewrite(node, context); - } - - public ExpressionTreeRewriter(ExpressionRewriter rewriter) - { - this.rewriter = rewriter; - this.visitor = new RewritingVisitor(); - } - - private List rewrite(List items, Context context) - { - ImmutableList.Builder builder = ImmutableList.builder(); - for (Expression expression : items) { - builder.add(rewrite(expression, context.get())); - } - return builder.build(); - } - - @SuppressWarnings("unchecked") - public T rewrite(T node, C context) - { - return (T) visitor.process(node, new Context<>(context, false)); - } - - /** - * Invoke the default rewrite logic explicitly. Specifically, it skips the invocation of the expression rewriter for the provided node. - */ - @SuppressWarnings("unchecked") - public T defaultRewrite(T node, C context) - { - return (T) visitor.process(node, new Context<>(context, true)); - } - - private class RewritingVisitor - extends AstVisitor> - { - @Override - protected Expression visitExpression(Expression node, Context context) - { - // RewritingVisitor must have explicit support for each expression type, with a dedicated visit method, - // so visitExpression() should never be called. - throw new UnsupportedOperationException("visit() not implemented for " + node.getClass().getName()); - } - - @Override - protected Expression visitRow(Row node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteRow(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - List items = rewrite(node.getItems(), context); - - if (!sameElements(node.getItems(), items)) { - return new Row(items); - } - - return node; - } - - @Override - protected Expression visitArithmeticUnary(ArithmeticUnaryExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteArithmeticUnary(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression child = rewrite(node.getValue(), context.get()); - if (child != node.getValue()) { - return new ArithmeticUnaryExpression(node.getSign(), child); - } - - return node; - } - - @Override - public Expression visitArithmeticBinary(ArithmeticBinaryExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteArithmeticBinary(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression left = rewrite(node.getLeft(), context.get()); - Expression right = rewrite(node.getRight(), context.get()); - - if (left != node.getLeft() || right != node.getRight()) { - return new ArithmeticBinaryExpression(node.getOperator(), left, right); - } - - return node; - } - - @Override - protected Expression visitArrayConstructor(ArrayConstructor node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteArrayConstructor(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - List values = rewrite(node.getValues(), context); - - if (!sameElements(node.getValues(), values)) { - return new ArrayConstructor(values); - } - - return node; - } - - @Override - protected Expression visitAtTimeZone(AtTimeZone node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteAtTimeZone(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression value = rewrite(node.getValue(), context.get()); - Expression timeZone = rewrite(node.getTimeZone(), context.get()); - - if (value != node.getValue() || timeZone != node.getTimeZone()) { - return new AtTimeZone(value, timeZone); - } - - return node; - } - - @Override - protected Expression visitSubscriptExpression(SubscriptExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteSubscriptExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression base = rewrite(node.getBase(), context.get()); - Expression index = rewrite(node.getIndex(), context.get()); - - if (base != node.getBase() || index != node.getIndex()) { - return new SubscriptExpression(base, index); - } - - return node; - } - - @Override - public Expression visitComparisonExpression(ComparisonExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteComparisonExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression left = rewrite(node.getLeft(), context.get()); - Expression right = rewrite(node.getRight(), context.get()); - - if (left != node.getLeft() || right != node.getRight()) { - return new ComparisonExpression(node.getOperator(), left, right); - } - - return node; - } - - @Override - protected Expression visitBetweenPredicate(BetweenPredicate node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteBetweenPredicate(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression value = rewrite(node.getValue(), context.get()); - Expression min = rewrite(node.getMin(), context.get()); - Expression max = rewrite(node.getMax(), context.get()); - - if (value != node.getValue() || min != node.getMin() || max != node.getMax()) { - return new BetweenPredicate(value, min, max); - } - - return node; - } - - @Override - public Expression visitLogicalExpression(LogicalExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteLogicalExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - List terms = rewrite(node.getTerms(), context); - if (!sameElements(node.getTerms(), terms)) { - return new LogicalExpression(node.getOperator(), terms); - } - - return node; - } - - @Override - public Expression visitNotExpression(NotExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteNotExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression value = rewrite(node.getValue(), context.get()); - - if (value != node.getValue()) { - return new NotExpression(value); - } - - return node; - } - - @Override - protected Expression visitIsNullPredicate(IsNullPredicate node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteIsNullPredicate(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression value = rewrite(node.getValue(), context.get()); - - if (value != node.getValue()) { - return new IsNullPredicate(value); - } - - return node; - } - - @Override - protected Expression visitIsNotNullPredicate(IsNotNullPredicate node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteIsNotNullPredicate(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression value = rewrite(node.getValue(), context.get()); - - if (value != node.getValue()) { - return new IsNotNullPredicate(value); - } - - return node; - } - - @Override - protected Expression visitNullIfExpression(NullIfExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteNullIfExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression first = rewrite(node.getFirst(), context.get()); - Expression second = rewrite(node.getSecond(), context.get()); - - if (first != node.getFirst() || second != node.getSecond()) { - return new NullIfExpression(first, second); - } - - return node; - } - - @Override - protected Expression visitIfExpression(IfExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteIfExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression condition = rewrite(node.getCondition(), context.get()); - Expression trueValue = rewrite(node.getTrueValue(), context.get()); - Expression falseValue = null; - if (node.getFalseValue().isPresent()) { - falseValue = rewrite(node.getFalseValue().get(), context.get()); - } - - if ((condition != node.getCondition()) || (trueValue != node.getTrueValue()) || (falseValue != node.getFalseValue().orElse(null))) { - return new IfExpression(condition, trueValue, falseValue); - } - - return node; - } - - @Override - protected Expression visitSearchedCaseExpression(SearchedCaseExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteSearchedCaseExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - ImmutableList.Builder builder = ImmutableList.builder(); - for (WhenClause expression : node.getWhenClauses()) { - builder.add(rewrite(expression, context.get())); - } - - Optional defaultValue = node.getDefaultValue() - .map(value -> rewrite(value, context.get())); - - if (!sameElements(node.getDefaultValue(), defaultValue) || !sameElements(node.getWhenClauses(), builder.build())) { - return new SearchedCaseExpression(builder.build(), defaultValue); - } - - return node; - } - - @Override - protected Expression visitSimpleCaseExpression(SimpleCaseExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteSimpleCaseExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression operand = rewrite(node.getOperand(), context.get()); - - ImmutableList.Builder builder = ImmutableList.builder(); - for (WhenClause expression : node.getWhenClauses()) { - builder.add(rewrite(expression, context.get())); - } - - Optional defaultValue = node.getDefaultValue() - .map(value -> rewrite(value, context.get())); - - if (operand != node.getOperand() || - !sameElements(node.getDefaultValue(), defaultValue) || - !sameElements(node.getWhenClauses(), builder.build())) { - return new SimpleCaseExpression(operand, builder.build(), defaultValue); - } - - return node; - } - - @Override - protected Expression visitWhenClause(WhenClause node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteWhenClause(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression operand = rewrite(node.getOperand(), context.get()); - Expression result = rewrite(node.getResult(), context.get()); - - if (operand != node.getOperand() || result != node.getResult()) { - return new WhenClause(operand, result); - } - return node; - } - - @Override - protected Expression visitCoalesceExpression(CoalesceExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteCoalesceExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - List operands = rewrite(node.getOperands(), context); - - if (!sameElements(node.getOperands(), operands)) { - return new CoalesceExpression(operands); - } - - return node; - } - - @Override - public Expression visitTryExpression(TryExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteTryExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression expression = rewrite(node.getInnerExpression(), context.get()); - - if (node.getInnerExpression() != expression) { - return new TryExpression(expression); - } - - return node; - } - - @Override - public Expression visitFunctionCall(FunctionCall node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteFunctionCall(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Optional filter = node.getFilter(); - if (filter.isPresent()) { - Expression filterExpression = filter.get(); - Expression newFilterExpression = rewrite(filterExpression, context.get()); - filter = Optional.of(newFilterExpression); - } - - Optional window = node.getWindow(); - if (window.isPresent()) { - Window rewrittenWindow = rewriteWindow(window.get(), context); - if (rewrittenWindow != window.get()) { - window = Optional.of(rewrittenWindow); - } - } - - List arguments = rewrite(node.getArguments(), context); - - if (!sameElements(node.getArguments(), arguments) || !sameElements(window, node.getWindow()) - || !sameElements(filter, node.getFilter())) { - return new FunctionCall( - node.getLocation(), - node.getName(), - window, - filter, - node.getOrderBy().map(orderBy -> rewriteOrderBy(orderBy, context)), - node.isDistinct(), - node.getNullTreatment(), - node.getProcessingMode(), - arguments); - } - return node; - } - - // Since OrderBy contains list of SortItems, we want to process each SortItem's key, which is an expression - private OrderBy rewriteOrderBy(OrderBy orderBy, Context context) - { - List rewrittenSortItems = rewriteSortItems(orderBy.getSortItems(), context); - if (sameElements(orderBy.getSortItems(), rewrittenSortItems)) { - return orderBy; - } - - return new OrderBy(rewrittenSortItems); - } - - private List rewriteSortItems(List sortItems, Context context) - { - ImmutableList.Builder rewrittenSortItems = ImmutableList.builder(); - for (SortItem sortItem : sortItems) { - Expression sortKey = rewrite(sortItem.getSortKey(), context.get()); - if (sortItem.getSortKey() != sortKey) { - rewrittenSortItems.add(new SortItem(sortKey, sortItem.getOrdering(), sortItem.getNullOrdering())); - } - else { - rewrittenSortItems.add(sortItem); - } - } - return rewrittenSortItems.build(); - } - - private Window rewriteWindow(Window window, Context context) - { - if (window instanceof WindowReference) { - WindowReference windowReference = (WindowReference) window; - Identifier rewrittenName = rewrite(windowReference.getName(), context.get()); - if (windowReference.getName() != rewrittenName) { - return new WindowReference(rewrittenName); - } - return window; - } - - WindowSpecification windowSpecification = (WindowSpecification) window; - Optional existingWindowName = windowSpecification.getExistingWindowName().map(name -> rewrite(name, context.get())); - - List partitionBy = rewrite(windowSpecification.getPartitionBy(), context); - - Optional orderBy = Optional.empty(); - if (windowSpecification.getOrderBy().isPresent()) { - orderBy = Optional.of(rewriteOrderBy(windowSpecification.getOrderBy().get(), context)); - } - - Optional rewrittenFrame = windowSpecification.getFrame(); - if (rewrittenFrame.isPresent()) { - WindowFrame frame = rewrittenFrame.get(); - - FrameBound start = frame.getStart(); - if (start.getValue().isPresent()) { - Expression value = rewrite(start.getValue().get(), context.get()); - if (value != start.getValue().get()) { - start = new FrameBound(start.getType(), value); - } - } - - Optional rewrittenEnd = frame.getEnd(); - if (rewrittenEnd.isPresent()) { - Optional value = rewrittenEnd.get().getValue(); - if (value.isPresent()) { - Expression rewrittenValue = rewrite(value.get(), context.get()); - if (rewrittenValue != value.get()) { - rewrittenEnd = Optional.of(new FrameBound(rewrittenEnd.get().getType(), rewrittenValue)); - } - } - } - - // Frame properties for row pattern matching are not rewritten. They are planned as parts of - // PatternRecognitionNode, and shouldn't be accessed past the Planner phase. - // There are nested expressions in Measures and VariableDefinitions. They are not rewritten by default. - // Rewriting them requires special handling of DereferenceExpression, aware of pattern labels. - if (!frame.getMeasures().isEmpty() || - frame.getAfterMatchSkipTo().isPresent() || - frame.getPatternSearchMode().isPresent() || - frame.getPattern().isPresent() || - !frame.getSubsets().isEmpty() || - !frame.getVariableDefinitions().isEmpty()) { - throw new UnsupportedOperationException("cannot rewrite pattern recognition clauses in window"); - } - - if ((frame.getStart() != start) || !sameElements(frame.getEnd(), rewrittenEnd)) { - rewrittenFrame = Optional.of(new WindowFrame( - frame.getType(), - start, - rewrittenEnd, - frame.getMeasures(), - frame.getAfterMatchSkipTo(), - frame.getPatternSearchMode(), - frame.getPattern(), - frame.getSubsets(), - frame.getVariableDefinitions())); - } - } - - if (!sameElements(windowSpecification.getExistingWindowName(), existingWindowName) || - !sameElements(windowSpecification.getPartitionBy(), partitionBy) || - !sameElements(windowSpecification.getOrderBy(), orderBy) || - !sameElements(windowSpecification.getFrame(), rewrittenFrame)) { - return new WindowSpecification(existingWindowName, partitionBy, orderBy, rewrittenFrame); - } - return window; - } - - @Override - protected Expression visitWindowOperation(WindowOperation node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteWindowOperation(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Identifier name = rewrite(node.getName(), context.get()); - Window window = rewriteWindow(node.getWindow(), context); - - if (name != node.getName() || window != node.getWindow()) { - return new WindowOperation(name, window); - } - - return node; - } - - @Override - protected Expression visitLambdaExpression(LambdaExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteLambdaExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression body = rewrite(node.getBody(), context.get()); - if (body != node.getBody()) { - return new LambdaExpression(node.getArguments(), body); - } - - return node; - } - - @Override - protected Expression visitBindExpression(BindExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteBindExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - List values = node.getValues().stream() - .map(value -> rewrite(value, context.get())) - .collect(toImmutableList()); - Expression function = rewrite(node.getFunction(), context.get()); - - if (!sameElements(values, node.getValues()) || (function != node.getFunction())) { - return new BindExpression(values, function); - } - return node; - } - - @Override - public Expression visitLikePredicate(LikePredicate node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteLikePredicate(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression value = rewrite(node.getValue(), context.get()); - Expression pattern = rewrite(node.getPattern(), context.get()); - Optional rewrittenEscape = node.getEscape() - .map(escape -> rewrite(escape, context.get())); - - if (value != node.getValue() || pattern != node.getPattern() || !sameElements(node.getEscape(), rewrittenEscape)) { - return new LikePredicate(value, pattern, rewrittenEscape); - } - - return node; - } - - @Override - public Expression visitInPredicate(InPredicate node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteInPredicate(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression value = rewrite(node.getValue(), context.get()); - Expression list = rewrite(node.getValueList(), context.get()); - - if (node.getValue() != value || node.getValueList() != list) { - return new InPredicate(value, list); - } - - return node; - } - - @Override - protected Expression visitInListExpression(InListExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteInListExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - List values = rewrite(node.getValues(), context); - - if (!sameElements(node.getValues(), values)) { - return new InListExpression(values); - } - - return node; - } - - @Override - protected Expression visitExists(ExistsPredicate node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteExists(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression subquery = node.getSubquery(); - subquery = rewrite(subquery, context.get()); - - if (subquery != node.getSubquery()) { - return new ExistsPredicate(subquery); - } - - return node; - } - - @Override - public Expression visitSubqueryExpression(SubqueryExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteSubqueryExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - // No default rewrite for SubqueryExpression since we do not want to traverse subqueries - return node; - } - - @Override - public Expression visitLiteral(Literal node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteLiteral(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - public Expression visitParameter(Parameter node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteParameter(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - public Expression visitIdentifier(Identifier node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteIdentifier(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - public Expression visitDereferenceExpression(DereferenceExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteDereferenceExpression(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression base = rewrite(node.getBase(), context.get()); - if (base != node.getBase()) { - if (node.getField().isPresent()) { - return new DereferenceExpression(base, node.getField().get()); - } - return new DereferenceExpression((Identifier) base); - } - - return node; - } - - @Override - protected Expression visitExtract(Extract node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteExtract(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression expression = rewrite(node.getExpression(), context.get()); - - if (node.getExpression() != expression) { - return new Extract(expression, node.getField()); - } - - return node; - } - - @Override - protected Expression visitCurrentTime(CurrentTime node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteCurrentTime(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - public Expression visitCast(Cast node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteCast(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression expression = rewrite(node.getExpression(), context.get()); - DataType type = rewrite(node.getType(), context.get()); - - if (node.getExpression() != expression || node.getType() != type) { - return new Cast(expression, type, node.isSafe(), node.isTypeOnly()); - } - - return node; - } - - @Override - protected Expression visitRowDataType(RowDataType node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteRowDataType(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - ImmutableList.Builder rewritten = ImmutableList.builder(); - for (RowDataType.Field field : node.getFields()) { - DataType dataType = rewrite(field.getType(), context.get()); - - Optional name = field.getName(); - - if (field.getName().isPresent()) { - Identifier identifier = field.getName().get(); - Identifier rewrittenIdentifier = rewrite(identifier, context.get()); - - if (identifier != rewrittenIdentifier) { - name = Optional.of(rewrittenIdentifier); - } - } - - @SuppressWarnings("OptionalEquality") - boolean nameRewritten = name != field.getName(); - if (dataType != field.getType() || nameRewritten) { - rewritten.add(new RowDataType.Field(field.getLocation(), name, dataType)); - } - else { - rewritten.add(field); - } - } - - List fields = rewritten.build(); - - if (!sameElements(fields, node.getFields())) { - return new RowDataType(node.getLocation(), fields); - } - - return node; - } - - @Override - protected Expression visitGenericDataType(GenericDataType node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteGenericDataType(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Identifier name = rewrite(node.getName(), context.get()); - - ImmutableList.Builder arguments = ImmutableList.builder(); - for (DataTypeParameter argument : node.getArguments()) { - if (argument instanceof NumericParameter) { - arguments.add(argument); - } - else if (argument instanceof TypeParameter) { - TypeParameter parameter = (TypeParameter) argument; - DataType value = (DataType) process(parameter.getValue(), context); - - if (value != parameter.getValue()) { - arguments.add(new TypeParameter(value)); - } - else { - arguments.add(argument); - } - } - } - - List rewrittenArguments = arguments.build(); - - if (name != node.getName() || !sameElements(rewrittenArguments, node.getArguments())) { - return new GenericDataType(node.getLocation(), name, rewrittenArguments); - } - - return node; - } - - @Override - protected Expression visitIntervalDataType(IntervalDayTimeDataType node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteIntervalDayTimeDataType(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitDateTimeType(DateTimeDataType node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteDateTimeDataType(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitFieldReference(FieldReference node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteFieldReference(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitSymbolReference(SymbolReference node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteSymbolReference(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteQuantifiedComparison(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - Expression value = rewrite(node.getValue(), context.get()); - Expression subquery = rewrite(node.getSubquery(), context.get()); - - if (node.getValue() != value || node.getSubquery() != subquery) { - return new QuantifiedComparisonExpression(node.getOperator(), node.getQuantifier(), value, subquery); - } - - return node; - } - - @Override - public Expression visitGroupingOperation(GroupingOperation node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteGroupingOperation(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitCurrentCatalog(CurrentCatalog node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteCurrentCatalog(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitCurrentSchema(CurrentSchema node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteCurrentSchema(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitCurrentUser(CurrentUser node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteCurrentUser(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitCurrentPath(CurrentPath node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteCurrentPath(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - return node; - } - - @Override - protected Expression visitFormat(Format node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteFormat(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - List arguments = rewrite(node.getArguments(), context); - if (!sameElements(node.getArguments(), arguments)) { - return new Format(arguments); - } - - return node; - } - - @Override - protected Expression visitLabelDereference(LabelDereference node, Context context) - { - if (!context.isDefaultRewrite()) { - Expression result = rewriter.rewriteLabelDereference(node, context.get(), ExpressionTreeRewriter.this); - if (result != null) { - return result; - } - } - - if (node.getReference().isPresent()) { - SymbolReference reference = rewrite(node.getReference().get(), context.get()); - if (node.getReference().get() != reference) { - return new LabelDereference(node.getLabel(), reference); - } - } - - return node; - } - } - - public static class Context - { - private final boolean defaultRewrite; - private final C context; - - private Context(C context, boolean defaultRewrite) - { - this.context = context; - this.defaultRewrite = defaultRewrite; - } - - public C get() - { - return context; - } - - public boolean isDefaultRewrite() - { - return defaultRewrite; - } - } - - private static boolean sameElements(Optional a, Optional b) - { - if (!a.isPresent() && !b.isPresent()) { - return true; - } - if (a.isPresent() != b.isPresent()) { - return false; - } - - return a.get() == b.get(); - } - - @SuppressWarnings("ObjectEquality") - private static boolean sameElements(Iterable a, Iterable b) - { - if (Iterables.size(a) != Iterables.size(b)) { - return false; - } - - Iterator first = a.iterator(); - Iterator second = b.iterator(); - - while (first.hasNext() && second.hasNext()) { - if (first.next() != second.next()) { - return false; - } - } - - return true; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Extract.java b/trino-parser/src/main/java/io/trino/sql/tree/Extract.java deleted file mode 100644 index fb189045d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Extract.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import javax.annotation.concurrent.Immutable; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -@Immutable -public class Extract - extends Expression -{ - private final Expression expression; - private final Field field; - - public static class Field - { - private final String name; - - public Field(String name) - { - this.name = name; - } - - public String getName() - { - return name; - } - - @Override - public String toString() - { - return name; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Field that = (Field) o; - return name.equals(that.name); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } - } - - public Extract(Expression expression, Field field) - { - this(Optional.empty(), expression, field); - } - - public Extract(NodeLocation location, Expression expression, Field field) - { - this(Optional.of(location), expression, field); - } - - private Extract(Optional location, Expression expression, Field field) - { - super(location); - requireNonNull(expression, "expression is null"); - requireNonNull(field, "field is null"); - - this.expression = expression; - this.field = field; - } - - public Expression getExpression() - { - return expression; - } - - public Field getField() - { - return field; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitExtract(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(expression); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Extract that = (Extract) o; - return Objects.equals(expression, that.expression) && - Objects.equals(field, that.field); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, field); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - Extract otherExtract = (Extract) other; - return field.equals(otherExtract.field); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/FetchCursor.java b/trino-parser/src/main/java/io/trino/sql/tree/FetchCursor.java deleted file mode 100644 index 850485c91..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/FetchCursor.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) Canner, Inc - All Rights Reserved - * Unauthorized copying of this file, via any medium is strictly prohibited - * Proprietary and confidential - * Written by Canner dev team , Sep 2022 - */ -package io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class FetchCursor - extends Statement -{ - private final Integer rowCount; - private final Identifier cursor; - - public FetchCursor(NodeLocation location, Integer rowCount, Identifier cursor) - { - this(Optional.of(location), rowCount, cursor); - } - - public FetchCursor(Integer rowCount, Identifier cursor) - { - this(Optional.empty(), rowCount, cursor); - } - - protected FetchCursor(Optional location, Integer rowCount, Identifier cursor) - { - super(location); - this.rowCount = requireNonNull(rowCount, "rowCount is null"); - this.cursor = requireNonNull(cursor, "cursor is null"); - } - - public Integer getRowCount() - { - return rowCount; - } - - public Identifier getCursor() - { - return cursor; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitFetchCursor(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(rowCount, cursor); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - FetchCursor o = (FetchCursor) obj; - return Objects.equals(rowCount, o.rowCount) - && Objects.equals(cursor, o.cursor); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("rowCount", rowCount) - .add("cursor", cursor) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/FetchFirst.java b/trino-parser/src/main/java/io/trino/sql/tree/FetchFirst.java deleted file mode 100644 index 04cc140d7..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/FetchFirst.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; - -public class FetchFirst - extends Node -{ - private final Optional rowCount; - private final boolean withTies; - - public FetchFirst(Expression rowCount) - { - this(Optional.empty(), Optional.of(rowCount), false); - } - - public FetchFirst(Expression rowCount, boolean withTies) - { - this(Optional.empty(), Optional.of(rowCount), withTies); - } - - public FetchFirst(Optional rowCount) - { - this(Optional.empty(), rowCount, false); - } - - public FetchFirst(Optional rowCount, boolean withTies) - { - this(Optional.empty(), rowCount, withTies); - } - - public FetchFirst(Optional location, Optional rowCount, boolean withTies) - { - super(location); - rowCount.ifPresent(count -> checkArgument( - count instanceof LongLiteral || count instanceof Parameter, - "unexpected rowCount class: %s", - rowCount.getClass().getSimpleName())); - this.rowCount = rowCount; - this.withTies = withTies; - } - - public Optional getRowCount() - { - return rowCount; - } - - public boolean isWithTies() - { - return withTies; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitFetchFirst(this, context); - } - - @Override - public List getChildren() - { - return rowCount.map(ImmutableList::of).orElse(ImmutableList.of()); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if ((o == null) || (getClass() != o.getClass())) { - return false; - } - FetchFirst that = (FetchFirst) o; - return withTies == that.withTies && - Objects.equals(rowCount, that.rowCount); - } - - @Override - public int hashCode() - { - return Objects.hash(rowCount, withTies); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("rowCount", rowCount.orElse(null)) - .add("withTies", withTies) - .omitNullValues() - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - FetchFirst otherNode = (FetchFirst) other; - - return withTies == otherNode.withTies; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/FieldReference.java b/trino-parser/src/main/java/io/trino/sql/tree/FieldReference.java deleted file mode 100644 index 8cd32b588..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/FieldReference.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; - -public class FieldReference - extends Expression -{ - private final int fieldIndex; - - public FieldReference(int fieldIndex) - { - super(Optional.empty()); - checkArgument(fieldIndex >= 0, "fieldIndex must be >= 0"); - - this.fieldIndex = fieldIndex; - } - - public int getFieldIndex() - { - return fieldIndex; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitFieldReference(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - FieldReference that = (FieldReference) o; - - return fieldIndex == that.fieldIndex; - } - - @Override - public int hashCode() - { - return fieldIndex; - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return fieldIndex == ((FieldReference) other).fieldIndex; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Format.java b/trino-parser/src/main/java/io/trino/sql/tree/Format.java deleted file mode 100644 index 9fe615841..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Format.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class Format - extends Expression -{ - private final List arguments; - - public Format(List arguments) - { - this(Optional.empty(), arguments); - } - - public Format(NodeLocation location, List arguments) - { - this(Optional.of(location), arguments); - } - - private Format(Optional location, List arguments) - { - super(location); - requireNonNull(arguments, "arguments is null"); - checkArgument(arguments.size() >= 2, "must have at least two arguments"); - this.arguments = ImmutableList.copyOf(arguments); - } - - public List getArguments() - { - return arguments; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitFormat(this, context); - } - - @Override - public List getChildren() - { - return arguments; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - - Format o = (Format) obj; - return Objects.equals(arguments, o.arguments); - } - - @Override - public int hashCode() - { - return Objects.hash(arguments); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/FrameBound.java b/trino-parser/src/main/java/io/trino/sql/tree/FrameBound.java deleted file mode 100644 index 3b1aafffe..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/FrameBound.java +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class FrameBound - extends Node -{ - public enum Type - { - UNBOUNDED_PRECEDING, - PRECEDING, - CURRENT_ROW, - FOLLOWING, - UNBOUNDED_FOLLOWING - } - - private final Type type; - private final Optional value; - - public FrameBound(Type type) - { - this(Optional.empty(), type); - } - - public FrameBound(NodeLocation location, Type type) - { - this(Optional.of(location), type); - } - - public FrameBound(Type type, Expression value) - { - this(Optional.empty(), type, value); - } - - private FrameBound(Optional location, Type type) - { - this(location, type, null); - } - - public FrameBound(NodeLocation location, Type type, Expression value) - { - this(Optional.of(location), type, value); - } - - private FrameBound(Optional location, Type type, Expression value) - { - super(location); - this.type = requireNonNull(type, "type is null"); - this.value = Optional.ofNullable(value); - } - - public Type getType() - { - return type; - } - - public Optional getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitFrameBound(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - value.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - FrameBound o = (FrameBound) obj; - return type == o.type && - Objects.equals(value, o.value); - } - - @Override - public int hashCode() - { - return Objects.hash(type, value); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("value", value) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - FrameBound otherNode = (FrameBound) other; - return type == otherNode.type; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/FunctionCall.java b/trino-parser/src/main/java/io/trino/sql/tree/FunctionCall.java deleted file mode 100644 index 4b09cdb10..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/FunctionCall.java +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class FunctionCall - extends Expression -{ - private final QualifiedName name; - private final Optional window; - private final Optional filter; - private final Optional orderBy; - private final boolean distinct; - private final Optional nullTreatment; - private final Optional processingMode; - private final List arguments; - - public FunctionCall(QualifiedName name, List arguments) - { - this(Optional.empty(), name, Optional.empty(), Optional.empty(), Optional.empty(), false, Optional.empty(), Optional.empty(), arguments); - } - - public FunctionCall(NodeLocation location, QualifiedName name, List arguments) - { - this(Optional.of(location), name, Optional.empty(), Optional.empty(), Optional.empty(), false, Optional.empty(), Optional.empty(), arguments); - } - - public FunctionCall( - Optional location, - QualifiedName name, - Optional window, - Optional filter, - Optional orderBy, - boolean distinct, - Optional nullTreatment, - Optional processingMode, - List arguments) - { - super(location); - requireNonNull(name, "name is null"); - requireNonNull(window, "window is null"); - window.ifPresent(node -> checkArgument(node instanceof WindowReference || node instanceof WindowSpecification, "unexpected window: " + node.getClass().getSimpleName())); - requireNonNull(filter, "filter is null"); - requireNonNull(orderBy, "orderBy is null"); - requireNonNull(nullTreatment, "nullTreatment is null"); - requireNonNull(processingMode, "processingMode is null"); - requireNonNull(arguments, "arguments is null"); - - this.name = name; - this.window = window; - this.filter = filter; - this.orderBy = orderBy; - this.distinct = distinct; - this.nullTreatment = nullTreatment; - this.processingMode = processingMode; - this.arguments = arguments; - } - - public QualifiedName getName() - { - return name; - } - - public Optional getWindow() - { - return window; - } - - public Optional getOrderBy() - { - return orderBy; - } - - public boolean isDistinct() - { - return distinct; - } - - public Optional getNullTreatment() - { - return nullTreatment; - } - - public Optional getProcessingMode() - { - return processingMode; - } - - public List getArguments() - { - return arguments; - } - - public Optional getFilter() - { - return filter; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitFunctionCall(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - window.ifPresent(window -> nodes.add((Node) window)); - filter.ifPresent(nodes::add); - orderBy.map(OrderBy::getSortItems).ifPresent(nodes::addAll); - nodes.addAll(arguments); - return nodes.build(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - FunctionCall o = (FunctionCall) obj; - return Objects.equals(name, o.name) && - Objects.equals(window, o.window) && - Objects.equals(filter, o.filter) && - Objects.equals(orderBy, o.orderBy) && - Objects.equals(distinct, o.distinct) && - Objects.equals(nullTreatment, o.nullTreatment) && - Objects.equals(processingMode, o.processingMode) && - Objects.equals(arguments, o.arguments); - } - - @Override - public int hashCode() - { - return Objects.hash(name, distinct, nullTreatment, processingMode, window, filter, orderBy, arguments); - } - - // TODO: make this a proper Tree node so that we can report error - // locations more accurately - public enum NullTreatment - { - IGNORE, RESPECT - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - FunctionCall otherFunction = (FunctionCall) other; - - return name.equals(otherFunction.name) && - distinct == otherFunction.distinct && - nullTreatment.equals(otherFunction.nullTreatment) && - processingMode.equals(otherFunction.processingMode); - } - - public static Builder builder(FunctionCall functionCall) - { - return new Builder() - .location(functionCall.getLocation()) - .name(functionCall.getName()) - .window(functionCall.getWindow()) - .filter(functionCall.getFilter()) - .orderBy(functionCall.getOrderBy()) - .distinct(functionCall.isDistinct()) - .nullTreatment(functionCall.getNullTreatment()) - .processingMode(functionCall.getProcessingMode()) - .arguments(functionCall.getArguments()); - } - - public static class Builder - { - private Optional location = Optional.empty(); - private QualifiedName name; - private Optional window = Optional.empty(); - private Optional filter = Optional.empty(); - private Optional orderBy = Optional.empty(); - private boolean distinct; - private Optional nullTreatment = Optional.empty(); - private Optional processingMode = Optional.empty(); - private List arguments = ImmutableList.of(); - - private Builder() {} - - public Builder location(Optional location) - { - this.location = location; - return this; - } - - public Builder name(QualifiedName name) - { - this.name = name; - return this; - } - - public Builder window(Optional window) - { - this.window = window; - return this; - } - - public Builder filter(Optional filter) - { - this.filter = filter; - return this; - } - - public Builder orderBy(Optional orderBy) - { - this.orderBy = orderBy; - return this; - } - - public Builder distinct(boolean distinct) - { - this.distinct = distinct; - return this; - } - - public Builder nullTreatment(Optional nullTreatment) - { - this.nullTreatment = nullTreatment; - return this; - } - - public Builder processingMode(Optional processingMode) - { - this.processingMode = processingMode; - return this; - } - - public Builder arguments(List arguments) - { - this.arguments = arguments; - return this; - } - - public FunctionCall build() - { - return new FunctionCall(location, name, window, filter, orderBy, distinct, nullTreatment, processingMode, arguments); - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/FunctionRelation.java b/trino-parser/src/main/java/io/trino/sql/tree/FunctionRelation.java deleted file mode 100644 index 038acca4b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/FunctionRelation.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class FunctionRelation - extends QueryBody -{ - private final QualifiedName name; - private final List arguments; - - public FunctionRelation(NodeLocation location, QualifiedName name, List arguments) - { - super(Optional.ofNullable(location)); - this.name = requireNonNull(name, "name is null"); - this.arguments = requireNonNull(arguments, "arguments is null"); - } - - public QualifiedName getName() - { - return name; - } - - public List getArguments() - { - return arguments; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitFunctionRelation(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - FunctionRelation functionRelation = (FunctionRelation) o; - return Objects.equals(name, functionRelation.name) - && Objects.equals(arguments, functionRelation.arguments); - } - - @Override - public int hashCode() - { - return Objects.hash(name, arguments); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("arguments", arguments) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GenericDataType.java b/trino-parser/src/main/java/io/trino/sql/tree/GenericDataType.java deleted file mode 100644 index cefa639e7..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GenericDataType.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class GenericDataType - extends DataType -{ - private final Identifier name; - private final List arguments; - - public GenericDataType(NodeLocation location, Identifier name, List arguments) - { - super(Optional.of(location)); - this.name = requireNonNull(name, "name is null"); - this.arguments = requireNonNull(arguments, "arguments is null"); - } - - public GenericDataType(Optional location, Identifier name, List arguments) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.arguments = requireNonNull(arguments, "arguments is null"); - } - - public Identifier getName() - { - return name; - } - - public List getArguments() - { - return arguments; - } - - @Override - public List getChildren() - { - return ImmutableList.builder() - .add(name) - .addAll(arguments) - .build(); - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitGenericDataType(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GenericDataType that = (GenericDataType) o; - return name.equals(that.name) && - arguments.equals(that.arguments); - } - - @Override - public int hashCode() - { - return Objects.hash(name, arguments); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GenericLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/GenericLiteral.java deleted file mode 100644 index 2737b6769..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GenericLiteral.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import io.trino.sql.parser.ParsingException; - -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public final class GenericLiteral - extends Literal -{ - private final String type; - private final String value; - - public GenericLiteral(String type, String value) - { - this(Optional.empty(), type, value); - } - - public GenericLiteral(NodeLocation location, String type, String value) - { - this(Optional.of(location), type, value); - } - - private GenericLiteral(Optional location, String type, String value) - { - super(location); - requireNonNull(type, "type is null"); - requireNonNull(value, "value is null"); - if (type.equalsIgnoreCase("X")) { - // we explicitly disallow "X" as type name, so if the user arrived here, - // it must be because that he intended to give a binaryLiteral instead, but - // added whitespace between the X and quote - throw new ParsingException("Spaces are not allowed between 'X' and the starting quote of a binary literal", location.get()); - } - this.type = type; - this.value = value; - } - - public String getType() - { - return type; - } - - public String getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitGenericLiteral(this, context); - } - - @Override - public int hashCode() - { - return Objects.hash(value, type); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - - GenericLiteral other = (GenericLiteral) obj; - return Objects.equals(this.value, other.value) && - Objects.equals(this.type, other.type); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - GenericLiteral otherLiteral = (GenericLiteral) other; - - return value.equals(otherLiteral.value) && type.equals(otherLiteral.type); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Grant.java b/trino-parser/src/main/java/io/trino/sql/tree/Grant.java deleted file mode 100644 index f61b29518..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Grant.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Grant - extends Statement -{ - private final Optional> privileges; // missing means ALL PRIVILEGES - private final Optional type; - private final QualifiedName name; - private final PrincipalSpecification grantee; - private final boolean grantOption; - - public Grant(Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee, boolean grantOption) - { - this(Optional.empty(), privileges, type, name, grantee, grantOption); - } - - public Grant(NodeLocation location, Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee, boolean grantOption) - { - this(Optional.of(location), privileges, type, name, grantee, grantOption); - } - - private Grant(Optional location, Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee, boolean grantOption) - { - super(location); - requireNonNull(privileges, "privileges is null"); - this.privileges = privileges.map(ImmutableList::copyOf); - this.type = requireNonNull(type, "type is null"); - this.name = requireNonNull(name, "name is null"); - this.grantee = requireNonNull(grantee, "grantee is null"); - this.grantOption = grantOption; - } - - public Optional> getPrivileges() - { - return privileges; - } - - public Optional getType() - { - return type; - } - - public QualifiedName getName() - { - return name; - } - - public PrincipalSpecification getGrantee() - { - return grantee; - } - - public boolean isWithGrantOption() - { - return grantOption; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitGrant(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(privileges, type, name, grantee, grantOption); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Grant o = (Grant) obj; - return Objects.equals(privileges, o.privileges) && - Objects.equals(type, o.type) && - Objects.equals(name, o.name) && - Objects.equals(grantee, o.grantee) && - Objects.equals(grantOption, o.grantOption); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("privileges", privileges) - .add("type", type) - .add("name", name) - .add("grantee", grantee) - .add("grantOption", grantOption) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GrantOnType.java b/trino-parser/src/main/java/io/trino/sql/tree/GrantOnType.java deleted file mode 100644 index ce852ce50..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GrantOnType.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -public enum GrantOnType -{ - SCHEMA, - TABLE, - /**/; -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GrantRoles.java b/trino-parser/src/main/java/io/trino/sql/tree/GrantRoles.java deleted file mode 100644 index 7057fbb7d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GrantRoles.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class GrantRoles - extends Statement -{ - private final Set roles; - private final Set grantees; - private final boolean adminOption; - private final Optional grantor; - private final Optional catalog; - - public GrantRoles( - NodeLocation location, - Set roles, - Set grantees, - boolean adminOption, - Optional grantor, - Optional catalog) - { - this(Optional.of(location), roles, grantees, adminOption, grantor, catalog); - } - - public GrantRoles( - Set roles, - Set grantees, - boolean adminOption, - Optional grantor, - Optional catalog) - { - this(Optional.empty(), roles, grantees, adminOption, grantor, catalog); - } - - private GrantRoles( - Optional location, - Set roles, - Set grantees, - boolean adminOption, - Optional grantor, - Optional catalog) - { - super(location); - this.roles = ImmutableSet.copyOf(requireNonNull(roles, "roles is null")); - this.grantees = ImmutableSet.copyOf(requireNonNull(grantees, "grantees is null")); - this.adminOption = adminOption; - this.grantor = requireNonNull(grantor, "grantor is null"); - this.catalog = requireNonNull(catalog, "catalog is null"); - } - - public Set getRoles() - { - return roles; - } - - public Set getGrantees() - { - return grantees; - } - - public boolean isAdminOption() - { - return adminOption; - } - - public Optional getGrantor() - { - return grantor; - } - - public Optional getCatalog() - { - return catalog; - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitGrantRoles(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GrantRoles grantRoles = (GrantRoles) o; - return adminOption == grantRoles.adminOption && - Objects.equals(roles, grantRoles.roles) && - Objects.equals(grantees, grantRoles.grantees) && - Objects.equals(grantor, grantRoles.grantor) && - Objects.equals(catalog, grantRoles.catalog); - } - - @Override - public int hashCode() - { - return Objects.hash(roles, grantees, adminOption, grantor, catalog); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("roles", roles) - .add("grantees", grantees) - .add("adminOption", adminOption) - .add("grantor", grantor) - .add("catalog", catalog) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GrantorSpecification.java b/trino-parser/src/main/java/io/trino/sql/tree/GrantorSpecification.java deleted file mode 100644 index 467b3a4e9..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GrantorSpecification.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class GrantorSpecification -{ - public enum Type - { - PRINCIPAL, CURRENT_USER, CURRENT_ROLE - } - - private final Type type; - private final Optional principal; - - public GrantorSpecification(Type type, Optional principal) - { - this.type = requireNonNull(type, "type is null"); - this.principal = requireNonNull(principal, "principal is null"); - } - - public Type getType() - { - return type; - } - - public Optional getPrincipal() - { - return principal; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GrantorSpecification that = (GrantorSpecification) o; - return type == that.type && - Objects.equals(principal, that.principal); - } - - @Override - public int hashCode() - { - return Objects.hash(type, principal); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("principal", principal) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GroupBy.java b/trino-parser/src/main/java/io/trino/sql/tree/GroupBy.java deleted file mode 100644 index 4ba05ddee..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GroupBy.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class GroupBy - extends Node -{ - private final boolean isDistinct; - private final List groupingElements; - - public GroupBy(boolean isDistinct, List groupingElements) - { - this(Optional.empty(), isDistinct, groupingElements); - } - - public GroupBy(NodeLocation location, boolean isDistinct, List groupingElements) - { - this(Optional.of(location), isDistinct, groupingElements); - } - - private GroupBy(Optional location, boolean isDistinct, List groupingElements) - { - super(location); - this.isDistinct = isDistinct; - this.groupingElements = ImmutableList.copyOf(requireNonNull(groupingElements)); - } - - public boolean isDistinct() - { - return isDistinct; - } - - public List getGroupingElements() - { - return groupingElements; - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitGroupBy(this, context); - } - - @Override - public List getChildren() - { - return groupingElements; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GroupBy groupBy = (GroupBy) o; - return isDistinct == groupBy.isDistinct && - Objects.equals(groupingElements, groupBy.groupingElements); - } - - @Override - public int hashCode() - { - return Objects.hash(isDistinct, groupingElements); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("isDistinct", isDistinct) - .add("groupingElements", groupingElements) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return isDistinct == ((GroupBy) other).isDistinct; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GroupingElement.java b/trino-parser/src/main/java/io/trino/sql/tree/GroupingElement.java deleted file mode 100644 index 9864e283e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GroupingElement.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.List; -import java.util.Optional; - -public abstract class GroupingElement - extends Node -{ - protected GroupingElement(Optional location) - { - super(location); - } - - public abstract List getExpressions(); - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitGroupingElement(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GroupingOperation.java b/trino-parser/src/main/java/io/trino/sql/tree/GroupingOperation.java deleted file mode 100644 index f3ecf4b48..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GroupingOperation.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.util.Objects.requireNonNull; - -public class GroupingOperation - extends Expression -{ - private final List groupingColumns; - - public GroupingOperation(Optional location, List groupingColumns) - { - super(location); - requireNonNull(groupingColumns); - checkArgument(!groupingColumns.isEmpty(), "grouping operation columns cannot be empty"); - this.groupingColumns = groupingColumns.stream() - .map(DereferenceExpression::from) - .collect(toImmutableList()); - } - - public List getGroupingColumns() - { - return groupingColumns; - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitGroupingOperation(this, context); - } - - @Override - public List getChildren() - { - return groupingColumns; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GroupingOperation other = (GroupingOperation) o; - return Objects.equals(groupingColumns, other.groupingColumns); - } - - @Override - public int hashCode() - { - return Objects.hash(groupingColumns); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/GroupingSets.java b/trino-parser/src/main/java/io/trino/sql/tree/GroupingSets.java deleted file mode 100644 index 823f28ee5..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/GroupingSets.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.stream.Collectors; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.util.Objects.requireNonNull; - -public final class GroupingSets - extends GroupingElement -{ - private final List> sets; - - public GroupingSets(List> groupingSets) - { - this(Optional.empty(), groupingSets); - } - - public GroupingSets(NodeLocation location, List> sets) - { - this(Optional.of(location), sets); - } - - private GroupingSets(Optional location, List> sets) - { - super(location); - requireNonNull(sets, "sets is null"); - checkArgument(!sets.isEmpty(), "grouping sets cannot be empty"); - this.sets = sets.stream().map(ImmutableList::copyOf).collect(toImmutableList()); - } - - public List> getSets() - { - return sets; - } - - @Override - public List getExpressions() - { - return sets.stream() - .flatMap(List::stream) - .collect(Collectors.toList()); - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitGroupingSets(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GroupingSets groupingSets = (GroupingSets) o; - return Objects.equals(sets, groupingSets.sets); - } - - @Override - public int hashCode() - { - return Objects.hash(sets); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("sets", sets) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - GroupingSets that = (GroupingSets) other; - return Objects.equals(sets, that.sets); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Identifier.java b/trino-parser/src/main/java/io/trino/sql/tree/Identifier.java deleted file mode 100644 index 2f6fa073f..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Identifier.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.base.CharMatcher; -import com.google.common.base.Strings; -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Verify.verify; -import static io.trino.sql.ReservedIdentifiers.reservedIdentifiers; -import static java.util.Locale.ENGLISH; -import static java.util.Objects.requireNonNull; - -public class Identifier - extends Expression -{ - private static final CharMatcher FIRST_CHAR_DISALLOWED_MATCHER = CharMatcher.inRange('0', '9') - .precomputed(); - - private static final CharMatcher ALLOWED_CHARS_MATCHER = CharMatcher.inRange('a', 'z') - .or(CharMatcher.inRange('A', 'Z')) - .or(CharMatcher.is('_')) - .or(CharMatcher.inRange('0', '9')) - .precomputed(); - - private static final Set RESERVED_IDENTIFIERS = reservedIdentifiers(); - - private final String value; - private final boolean delimited; - - public Identifier(NodeLocation location, String value, boolean delimited) - { - this(Optional.of(location), value, delimited); - } - - public Identifier(String value, boolean delimited) - { - this(Optional.empty(), value, delimited); - } - - public Identifier(String value) - { - this(Optional.empty(), value, !isValidIdentifier(value) || RESERVED_IDENTIFIERS.contains(value.toUpperCase(ENGLISH))); - } - - private Identifier(Optional location, String value, boolean delimited) - { - super(location); - this.value = requireNonNull(value, "value is null"); - this.delimited = delimited; - - checkArgument(!value.isEmpty(), "value is empty"); - checkArgument(delimited || isValidIdentifier(value), "value contains illegal characters: %s", value); - // Firstly, check if RESERVED_IDENTIFIERS is null because we are unsure why RESERVED_IDENTIFIERS would be null at times. - checkArgument(delimited || RESERVED_IDENTIFIERS == null || !RESERVED_IDENTIFIERS.contains(value.toUpperCase(ENGLISH)), "value is a reserved identifier: %s", value); - } - - public String getValue() - { - return value; - } - - public boolean isDelimited() - { - return delimited; - } - - public String getCanonicalValue() - { - if (isDelimited()) { - return value; - } - - return value.toUpperCase(ENGLISH); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitIdentifier(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Identifier that = (Identifier) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return value.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - Identifier that = (Identifier) other; - return Objects.equals(value, that.value) && delimited == that.delimited; - } - - private static boolean isValidIdentifier(String value) - { - verify(!Strings.isNullOrEmpty(value), "Identifier cannot be empty or null"); - - if (FIRST_CHAR_DISALLOWED_MATCHER.matches(value.charAt(0))) { - return false; - } - - // We've already checked that first char does not contain digits, - // so to avoid copying we are checking whole string. - return ALLOWED_CHARS_MATCHER.matchesAllOf(value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/IfExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/IfExpression.java deleted file mode 100644 index 5d6e16c8c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/IfExpression.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -/** - * IF(v1,v2[,v3]): CASE WHEN v1 THEN v2 [ELSE v3] END - */ -public class IfExpression - extends Expression -{ - private final Expression condition; - private final Expression trueValue; - private final Optional falseValue; - - public IfExpression(Expression condition, Expression trueValue, Expression falseValue) - { - this(Optional.empty(), condition, trueValue, falseValue); - } - - public IfExpression(NodeLocation location, Expression condition, Expression trueValue, Expression falseValue) - { - this(Optional.of(location), condition, trueValue, falseValue); - } - - private IfExpression(Optional location, Expression condition, Expression trueValue, Expression falseValue) - { - super(location); - this.condition = requireNonNull(condition, "condition is null"); - this.trueValue = requireNonNull(trueValue, "trueValue is null"); - this.falseValue = Optional.ofNullable(falseValue); - } - - public Expression getCondition() - { - return condition; - } - - public Expression getTrueValue() - { - return trueValue; - } - - public Optional getFalseValue() - { - return falseValue; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitIfExpression(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - falseValue.ifPresent(nodes::add); - return nodes.add(condition) - .add(trueValue) - .build(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - IfExpression o = (IfExpression) obj; - return Objects.equals(condition, o.condition) && - Objects.equals(trueValue, o.trueValue) && - Objects.equals(falseValue, o.falseValue); - } - - @Override - public int hashCode() - { - return Objects.hash(condition, trueValue, falseValue); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ImpersonateUser.java b/trino-parser/src/main/java/io/trino/sql/tree/ImpersonateUser.java deleted file mode 100644 index 1aebd11ef..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ImpersonateUser.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) Canner, Inc - All Rights Reserved - * Unauthorized copying of this file, via any medium is strictly prohibited - * Proprietary and confidential - * Written by Canner dev team , Jan 2023 - */ -package io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ImpersonateUser - extends Statement -{ - private final Expression expression; - - public ImpersonateUser(NodeLocation location, Expression expression) - { - this(Optional.of(location), expression); - } - - public ImpersonateUser(Expression expression) - { - this(Optional.empty(), expression); - } - - protected ImpersonateUser(Optional location, Expression expression) - { - super(location); - this.expression = requireNonNull(expression, "expression is null"); - } - - public Expression getExpression() - { - return expression; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitImpersonateUser(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(expression); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ImpersonateUser o = (ImpersonateUser) obj; - return Objects.equals(expression, o.expression); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("expression", expression) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/InListExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/InListExpression.java deleted file mode 100644 index 8344a0602..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/InListExpression.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class InListExpression - extends Expression -{ - private final List values; - - public InListExpression(List values) - { - this(Optional.empty(), values); - } - - public InListExpression(NodeLocation location, List values) - { - this(Optional.of(location), values); - } - - private InListExpression(Optional location, List values) - { - super(location); - requireNonNull(values, "values is null"); - checkArgument(!values.isEmpty(), "values cannot be empty"); - this.values = ImmutableList.copyOf(values); - } - - public List getValues() - { - return values; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitInListExpression(this, context); - } - - @Override - public List getChildren() - { - return values; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - InListExpression that = (InListExpression) o; - return Objects.equals(values, that.values); - } - - @Override - public int hashCode() - { - return values.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/InPredicate.java b/trino-parser/src/main/java/io/trino/sql/tree/InPredicate.java deleted file mode 100644 index 62439dc5b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/InPredicate.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -public class InPredicate - extends Expression -{ - private final Expression value; - private final Expression valueList; - - public InPredicate(Expression value, Expression valueList) - { - this(Optional.empty(), value, valueList); - } - - public InPredicate(NodeLocation location, Expression value, Expression valueList) - { - this(Optional.of(location), value, valueList); - } - - private InPredicate(Optional location, Expression value, Expression valueList) - { - super(location); - this.value = value; - this.valueList = valueList; - } - - public Expression getValue() - { - return value; - } - - public Expression getValueList() - { - return valueList; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitInPredicate(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value, valueList); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - InPredicate that = (InPredicate) o; - return Objects.equals(value, that.value) && - Objects.equals(valueList, that.valueList); - } - - @Override - public int hashCode() - { - return Objects.hash(value, valueList); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Insert.java b/trino-parser/src/main/java/io/trino/sql/tree/Insert.java deleted file mode 100644 index 2058bf243..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Insert.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Insert - extends Statement -{ - private final Table table; - private final Query query; - private final Optional> columns; - - public Insert(Table table, Optional> columns, Query query) - { - this(Optional.empty(), table, columns, query); - } - - private Insert(Optional location, Table table, Optional> columns, Query query) - { - super(location); - this.table = requireNonNull(table, "target is null"); - this.columns = requireNonNull(columns, "columns is null"); - this.query = requireNonNull(query, "query is null"); - } - - public Table getTable() - { - return table; - } - - public QualifiedName getTarget() - { - return table.getName(); - } - - public Optional> getColumns() - { - return columns; - } - - public Query getQuery() - { - return query; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitInsert(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(query); - } - - @Override - public int hashCode() - { - return Objects.hash(table, columns, query); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Insert o = (Insert) obj; - return Objects.equals(table, o.table) && - Objects.equals(columns, o.columns) && - Objects.equals(query, o.query); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .add("columns", columns) - .add("query", query) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Intersect.java b/trino-parser/src/main/java/io/trino/sql/tree/Intersect.java deleted file mode 100644 index 287f6c586..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Intersect.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Intersect - extends SetOperation -{ - private final List relations; - - public Intersect(List relations, boolean distinct) - { - this(Optional.empty(), relations, distinct); - } - - public Intersect(NodeLocation location, List relations, boolean distinct) - { - this(Optional.of(location), relations, distinct); - } - - private Intersect(Optional location, List relations, boolean distinct) - { - super(location, distinct); - requireNonNull(relations, "relations is null"); - - this.relations = ImmutableList.copyOf(relations); - } - - @Override - public List getRelations() - { - return relations; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitIntersect(this, context); - } - - @Override - public List getChildren() - { - return relations; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("relations", relations) - .add("distinct", isDistinct()) - .toString(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Intersect o = (Intersect) obj; - return Objects.equals(relations, o.relations) && - Objects.equals(isDistinct(), o.isDistinct()); - } - - @Override - public int hashCode() - { - return Objects.hash(relations, isDistinct()); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return this.isDistinct() == ((Intersect) other).isDistinct(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/IntervalDayTimeDataType.java b/trino-parser/src/main/java/io/trino/sql/tree/IntervalDayTimeDataType.java deleted file mode 100644 index 58e8da140..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/IntervalDayTimeDataType.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class IntervalDayTimeDataType - extends DataType -{ - public enum Field - { - YEAR, - MONTH, - DAY, - HOUR, - MINUTE, - SECOND, - } - - private final Field from; - private final Field to; - - public IntervalDayTimeDataType(NodeLocation location, Field from, Field to) - { - this(Optional.of(location), from, to); - } - - public IntervalDayTimeDataType(Optional location, Field from, Field to) - { - super(location); - this.from = requireNonNull(from, "from is null"); - this.to = requireNonNull(to, "to is null"); - } - - public Field getFrom() - { - return from; - } - - public Field getTo() - { - return to; - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitIntervalDataType(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - IntervalDayTimeDataType that = (IntervalDayTimeDataType) o; - return from == that.from && - to == that.to; - } - - @Override - public int hashCode() - { - return Objects.hash(from, to); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - IntervalDayTimeDataType otherType = (IntervalDayTimeDataType) other; - return from.equals(otherType.from) && - to == otherType.to; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/IntervalLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/IntervalLiteral.java deleted file mode 100644 index 05f4b07f3..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/IntervalLiteral.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class IntervalLiteral - extends Literal -{ - public enum Sign - { - POSITIVE { - @Override - public int multiplier() - { - return 1; - } - }, - NEGATIVE { - @Override - public int multiplier() - { - return -1; - } - }; - - public abstract int multiplier(); - } - - public enum IntervalField - { - YEAR, MONTH, DAY, HOUR, MINUTE, SECOND - } - - private final String value; - private final Sign sign; - private final IntervalField startField; - private final Optional endField; - - public IntervalLiteral(String value, Sign sign, IntervalField startField) - { - this(Optional.empty(), value, sign, startField, Optional.empty()); - } - - public IntervalLiteral(String value, Sign sign, IntervalField startField, Optional endField) - { - this(Optional.empty(), value, sign, startField, endField); - } - - public IntervalLiteral(NodeLocation location, String value, Sign sign, IntervalField startField, Optional endField) - { - this(Optional.of(location), value, sign, startField, endField); - } - - private IntervalLiteral(Optional location, String value, Sign sign, IntervalField startField, Optional endField) - { - super(location); - requireNonNull(value, "value is null"); - requireNonNull(sign, "sign is null"); - requireNonNull(startField, "startField is null"); - requireNonNull(endField, "endField is null"); - - this.value = value; - this.sign = sign; - this.startField = startField; - this.endField = endField; - } - - public String getValue() - { - return value; - } - - public Sign getSign() - { - return sign; - } - - public IntervalField getStartField() - { - return startField; - } - - public Optional getEndField() - { - return endField; - } - - public boolean isYearToMonth() - { - return startField == IntervalField.YEAR || startField == IntervalField.MONTH; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitIntervalLiteral(this, context); - } - - @Override - public int hashCode() - { - return Objects.hash(value, sign, startField, endField); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - IntervalLiteral other = (IntervalLiteral) obj; - return Objects.equals(this.value, other.value) && - this.sign == other.sign && - this.startField == other.startField && - Objects.equals(this.endField, other.endField); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - IntervalLiteral otherLiteral = (IntervalLiteral) other; - return Objects.equals(this.value, otherLiteral.value) && - this.sign == otherLiteral.sign && - this.startField == otherLiteral.startField && - Objects.equals(this.endField, otherLiteral.endField); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/IsNotNullPredicate.java b/trino-parser/src/main/java/io/trino/sql/tree/IsNotNullPredicate.java deleted file mode 100644 index 3a1b5ef91..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/IsNotNullPredicate.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class IsNotNullPredicate - extends Expression -{ - private final Expression value; - - public IsNotNullPredicate(Expression value) - { - this(Optional.empty(), value); - } - - public IsNotNullPredicate(NodeLocation location, Expression value) - { - this(Optional.of(location), value); - } - - private IsNotNullPredicate(Optional location, Expression value) - { - super(location); - requireNonNull(value, "value is null"); - this.value = value; - } - - public Expression getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitIsNotNullPredicate(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - IsNotNullPredicate that = (IsNotNullPredicate) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return value.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/IsNullPredicate.java b/trino-parser/src/main/java/io/trino/sql/tree/IsNullPredicate.java deleted file mode 100644 index 292436f06..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/IsNullPredicate.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class IsNullPredicate - extends Expression -{ - private final Expression value; - - public IsNullPredicate(Expression value) - { - this(Optional.empty(), value); - } - - public IsNullPredicate(NodeLocation location, Expression value) - { - this(Optional.of(location), value); - } - - private IsNullPredicate(Optional location, Expression value) - { - super(location); - requireNonNull(value, "value is null"); - this.value = value; - } - - public Expression getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitIsNullPredicate(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - IsNullPredicate that = (IsNullPredicate) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return value.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Isolation.java b/trino-parser/src/main/java/io/trino/sql/tree/Isolation.java deleted file mode 100644 index 1f3a43445..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Isolation.java +++ /dev/null @@ -1,110 +0,0 @@ - -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Isolation - extends TransactionMode -{ - public enum Level - { - SERIALIZABLE("SERIALIZABLE"), - REPEATABLE_READ("REPEATABLE READ"), - READ_COMMITTED("READ COMMITTED"), - READ_UNCOMMITTED("READ UNCOMMITTED"); - - private final String text; - - Level(String text) - { - this.text = requireNonNull(text, "text is null"); - } - - public String getText() - { - return text; - } - } - - private final Level level; - - public Isolation(Level level) - { - this(Optional.empty(), level); - } - - public Isolation(NodeLocation location, Level level) - { - this(Optional.of(location), level); - } - - private Isolation(Optional location, Level level) - { - super(location); - this.level = requireNonNull(level, "level is null"); - } - - public Level getLevel() - { - return level; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitIsolationLevel(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(level); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Isolation other = (Isolation) obj; - return this.level == other.level; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("level", level) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Join.java b/trino-parser/src/main/java/io/trino/sql/tree/Join.java deleted file mode 100644 index 1be838e34..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Join.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class Join - extends Relation -{ - public Join(Type type, Relation left, Relation right, Optional criteria) - { - this(Optional.empty(), type, left, right, criteria); - } - - public Join(NodeLocation location, Type type, Relation left, Relation right, Optional criteria) - { - this(Optional.of(location), type, left, right, criteria); - } - - private Join(Optional location, Type type, Relation left, Relation right, Optional criteria) - { - super(location); - requireNonNull(left, "left is null"); - requireNonNull(right, "right is null"); - if ((type == Type.CROSS) || (type == Type.IMPLICIT)) { - checkArgument(!criteria.isPresent(), "%s join cannot have join criteria", type); - } - else { - checkArgument(criteria.isPresent(), "No join criteria specified"); - } - - this.type = type; - this.left = left; - this.right = right; - this.criteria = criteria; - } - - public enum Type - { - CROSS, INNER, LEFT, RIGHT, FULL, IMPLICIT - } - - private final Type type; - private final Relation left; - private final Relation right; - private final Optional criteria; - - public Type getType() - { - return type; - } - - public Relation getLeft() - { - return left; - } - - public Relation getRight() - { - return right; - } - - public Optional getCriteria() - { - return criteria; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitJoin(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.add(left); - nodes.add(right); - criteria.map(JoinCriteria::getNodes) - .ifPresent(nodes::addAll); - return nodes.build(); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("left", left) - .add("right", right) - .add("criteria", criteria) - .omitNullValues() - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if ((o == null) || (getClass() != o.getClass())) { - return false; - } - Join join = (Join) o; - return (type == join.type) && - Objects.equals(left, join.left) && - Objects.equals(right, join.right) && - Objects.equals(criteria, join.criteria); - } - - @Override - public int hashCode() - { - return Objects.hash(type, left, right, criteria); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return type.equals(((Join) other).type); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/JoinCriteria.java b/trino-parser/src/main/java/io/trino/sql/tree/JoinCriteria.java deleted file mode 100644 index 59e4cfa58..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/JoinCriteria.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.List; - -public abstract class JoinCriteria -{ - // Force subclasses to have a proper equals and hashcode implementation - @Override - public abstract boolean equals(Object obj); - - @Override - public abstract int hashCode(); - - @Override - public abstract String toString(); - - public abstract List getNodes(); -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/JoinOn.java b/trino-parser/src/main/java/io/trino/sql/tree/JoinOn.java deleted file mode 100644 index 84c540b96..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/JoinOn.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class JoinOn - extends JoinCriteria -{ - private final Expression expression; - - public JoinOn(Expression expression) - { - this.expression = requireNonNull(expression, "expression is null"); - } - - public Expression getExpression() - { - return expression; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - JoinOn o = (JoinOn) obj; - return Objects.equals(expression, o.expression); - } - - @Override - public int hashCode() - { - return Objects.hash(expression); - } - - @Override - public String toString() - { - return toStringHelper(this) - .addValue(expression) - .toString(); - } - - @Override - public List getNodes() - { - return ImmutableList.of(expression); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/JoinUsing.java b/trino-parser/src/main/java/io/trino/sql/tree/JoinUsing.java deleted file mode 100644 index ed5e5edf4..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/JoinUsing.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class JoinUsing - extends JoinCriteria -{ - private final List columns; - - public JoinUsing(List columns) - { - requireNonNull(columns, "columns is null"); - checkArgument(!columns.isEmpty(), "columns is empty"); - this.columns = ImmutableList.copyOf(columns); - } - - public List getColumns() - { - return columns; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - JoinUsing o = (JoinUsing) obj; - return Objects.equals(columns, o.columns); - } - - @Override - public int hashCode() - { - return Objects.hash(columns); - } - - @Override - public String toString() - { - return toStringHelper(this) - .addValue(columns) - .toString(); - } - - @Override - public List getNodes() - { - return ImmutableList.of(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/LabelDereference.java b/trino-parser/src/main/java/io/trino/sql/tree/LabelDereference.java deleted file mode 100644 index d28f5a14c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/LabelDereference.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -/** - * A temporary IR representation of a label-prefixed column reference - * in the context of row pattern recognition. - *

- * It is created from a DereferenceExpression when the MEASURES or DEFINE - * expressions are rewritten using the TranslationMap: - * A.price -> DereferenceExpression("A", "price") -> LabelDereference("A", price_symbol). - * Next, the LabelDereference is processed by the LogicalIndexExtractor, - * and it is removed from the expression. - *

- * LabelDereference is a synthetic AST node. It had to be introduced in order to carry - * the rewritten symbol (`price_symbol` in the example). The DereferenceExpression - * cannot be used for that purpose, because it only contains identifiers, and a Symbol - * cannot be safely converted to an Identifier. - */ -public class LabelDereference - extends Expression -{ - private final String label; - private final Optional reference; - - public LabelDereference(String label, SymbolReference reference) - { - this(label, Optional.of(requireNonNull(reference, "reference is null"))); - } - - public LabelDereference(String label) - { - this(label, Optional.empty()); - } - - public LabelDereference(String label, Optional reference) - { - super(Optional.empty()); - this.label = requireNonNull(label, "label is null"); - this.reference = requireNonNull(reference, "reference is null"); - } - - public String getLabel() - { - return label; - } - - public Optional getReference() - { - return reference; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLabelDereference(this, context); - } - - @Override - public List getChildren() - { - return reference.>map(ImmutableList::of).orElseGet(ImmutableList::of); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - LabelDereference that = (LabelDereference) o; - return Objects.equals(label, that.label) && - Objects.equals(reference, that.reference); - } - - @Override - public int hashCode() - { - return Objects.hash(label, reference); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return label.equals(((LabelDereference) other).label); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/LambdaArgumentDeclaration.java b/trino-parser/src/main/java/io/trino/sql/tree/LambdaArgumentDeclaration.java deleted file mode 100644 index 78de3b4e8..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/LambdaArgumentDeclaration.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -public class LambdaArgumentDeclaration - extends Expression -{ - private final Identifier name; - - public LambdaArgumentDeclaration(Identifier name) - { - super(Optional.empty()); - this.name = name; - } - - public Identifier getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLambdaArgumentDeclaration(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - LambdaArgumentDeclaration that = (LambdaArgumentDeclaration) o; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return name.equals(((LambdaArgumentDeclaration) other).getName()); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/LambdaExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/LambdaExpression.java deleted file mode 100644 index de06cb405..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/LambdaExpression.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class LambdaExpression - extends Expression -{ - private final List arguments; - private final Expression body; - - public LambdaExpression(List arguments, Expression body) - { - this(Optional.empty(), arguments, body); - } - - public LambdaExpression(NodeLocation location, List arguments, Expression body) - { - this(Optional.of(location), arguments, body); - } - - private LambdaExpression(Optional location, List arguments, Expression body) - { - super(location); - this.arguments = requireNonNull(arguments, "arguments is null"); - this.body = requireNonNull(body, "body is null"); - } - - public List getArguments() - { - return arguments; - } - - public Expression getBody() - { - return body; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLambdaExpression(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.addAll(arguments); - nodes.add(body); - return nodes.build(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - LambdaExpression that = (LambdaExpression) obj; - return Objects.equals(arguments, that.arguments) && - Objects.equals(body, that.body); - } - - @Override - public int hashCode() - { - return Objects.hash(arguments, body); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Lateral.java b/trino-parser/src/main/java/io/trino/sql/tree/Lateral.java deleted file mode 100644 index ddb267e05..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Lateral.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public final class Lateral - extends Relation -{ - private final Query query; - - public Lateral(Query query) - { - this(Optional.empty(), query); - } - - public Lateral(NodeLocation location, Query query) - { - this(Optional.of(location), query); - } - - private Lateral(Optional location, Query query) - { - super(location); - this.query = requireNonNull(query, "query is null"); - } - - public Query getQuery() - { - return query; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLateral(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(query); - } - - @Override - public String toString() - { - return "LATERAL(" + query + ")"; - } - - @Override - public int hashCode() - { - return Objects.hash(query); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Lateral other = (Lateral) obj; - return Objects.equals(this.query, other.query); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/LikeClause.java b/trino-parser/src/main/java/io/trino/sql/tree/LikeClause.java deleted file mode 100644 index 97caf0838..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/LikeClause.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class LikeClause - extends TableElement -{ - private final QualifiedName tableName; - private final Optional propertiesOption; - - public enum PropertiesOption - { - INCLUDING, - EXCLUDING - } - - public LikeClause(QualifiedName tableName, Optional propertiesOption) - { - this(Optional.empty(), tableName, propertiesOption); - } - - public LikeClause(NodeLocation location, QualifiedName tableName, Optional propertiesOption) - { - this(Optional.of(location), tableName, propertiesOption); - } - - private LikeClause(Optional location, QualifiedName tableName, Optional propertiesOption) - { - super(location); - this.tableName = requireNonNull(tableName, "tableName is null"); - this.propertiesOption = requireNonNull(propertiesOption, "propertiesOption is null"); - } - - public QualifiedName getTableName() - { - return tableName; - } - - public Optional getPropertiesOption() - { - return propertiesOption; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLikeClause(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - LikeClause o = (LikeClause) obj; - return Objects.equals(this.tableName, o.tableName) && - Objects.equals(this.propertiesOption, o.propertiesOption); - } - - @Override - public int hashCode() - { - return Objects.hash(tableName, propertiesOption); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("tableName", tableName) - .add("propertiesOption", propertiesOption) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/LikePredicate.java b/trino-parser/src/main/java/io/trino/sql/tree/LikePredicate.java deleted file mode 100644 index 984aa778f..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/LikePredicate.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class LikePredicate - extends Expression -{ - private final Expression value; - private final Expression pattern; - private final Optional escape; - - public LikePredicate(Expression value, Expression pattern, Expression escape) - { - this(Optional.empty(), value, pattern, Optional.of(escape)); - } - - public LikePredicate(NodeLocation location, Expression value, Expression pattern, Optional escape) - { - this(Optional.of(location), value, pattern, escape); - } - - public LikePredicate(Expression value, Expression pattern, Optional escape) - { - this(Optional.empty(), value, pattern, escape); - } - - private LikePredicate(Optional location, Expression value, Expression pattern, Optional escape) - { - super(location); - requireNonNull(value, "value is null"); - requireNonNull(pattern, "pattern is null"); - requireNonNull(escape, "escape is null"); - - this.value = value; - this.pattern = pattern; - this.escape = escape; - } - - public Expression getValue() - { - return value; - } - - public Expression getPattern() - { - return pattern; - } - - public Optional getEscape() - { - return escape; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLikePredicate(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder result = ImmutableList.builder() - .add(value) - .add(pattern); - - escape.ifPresent(result::add); - - return result.build(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - LikePredicate that = (LikePredicate) o; - return Objects.equals(value, that.value) && - Objects.equals(pattern, that.pattern) && - Objects.equals(escape, that.escape); - } - - @Override - public int hashCode() - { - return Objects.hash(value, pattern, escape); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Limit.java b/trino-parser/src/main/java/io/trino/sql/tree/Limit.java deleted file mode 100644 index 2a5762eb6..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Limit.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; - -public class Limit - extends Node -{ - private final Expression rowCount; - - public Limit(Expression rowCount) - { - this(Optional.empty(), rowCount); - } - - public Limit(NodeLocation location, Expression rowCount) - { - this(Optional.of(location), rowCount); - } - - public Limit(Optional location, Expression rowCount) - { - super(location); - checkArgument( - rowCount instanceof AllRows || - rowCount instanceof LongLiteral || - rowCount instanceof Parameter, - "unexpected rowCount class: %s", - rowCount.getClass().getSimpleName()); - this.rowCount = rowCount; - } - - public Expression getRowCount() - { - return rowCount; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLimit(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(rowCount); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Limit o = (Limit) obj; - return Objects.equals(rowCount, o.rowCount); - } - - @Override - public int hashCode() - { - return Objects.hash(rowCount); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("limit", rowCount) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Literal.java b/trino-parser/src/main/java/io/trino/sql/tree/Literal.java deleted file mode 100644 index 8bc8bb963..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Literal.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -public abstract class Literal - extends Expression -{ - protected Literal(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLiteral(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/LogicalExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/LogicalExpression.java deleted file mode 100644 index 344801c4e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/LogicalExpression.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class LogicalExpression - extends Expression -{ - public enum Operator - { - AND, OR; - - public Operator flip() - { - switch (this) { - case AND: - return OR; - case OR: - return AND; - } - throw new IllegalArgumentException("Unsupported logical expression type: " + this); - } - } - - private final Operator operator; - private final List terms; - - public LogicalExpression(Operator operator, List terms) - { - this(Optional.empty(), operator, terms); - } - - public LogicalExpression(NodeLocation location, Operator operator, List terms) - { - this(Optional.of(location), operator, terms); - } - - private LogicalExpression(Optional location, Operator operator, List terms) - { - super(location); - requireNonNull(operator, "operator is null"); - checkArgument(terms.size() >= 2, "Expected at least 2 terms"); - - this.operator = operator; - this.terms = ImmutableList.copyOf(terms); - } - - public Operator getOperator() - { - return operator; - } - - public List getTerms() - { - return terms; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLogicalExpression(this, context); - } - - @Override - public List getChildren() - { - return terms; - } - - public static LogicalExpression and(Expression left, Expression right) - { - return new LogicalExpression(Optional.empty(), Operator.AND, ImmutableList.of(left, right)); - } - - public static LogicalExpression or(Expression left, Expression right) - { - return new LogicalExpression(Optional.empty(), Operator.OR, ImmutableList.of(left, right)); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - LogicalExpression that = (LogicalExpression) o; - return operator == that.operator && Objects.equals(terms, that.terms); - } - - @Override - public int hashCode() - { - return Objects.hash(operator, terms); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return operator == ((LogicalExpression) other).operator; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/LongLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/LongLiteral.java deleted file mode 100644 index 3e434ef07..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/LongLiteral.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import io.trino.sql.parser.ParsingException; - -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class LongLiteral - extends Literal -{ - private final long value; - - public LongLiteral(String value) - { - this(Optional.empty(), value); - } - - public LongLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - private LongLiteral(Optional location, String value) - { - super(location); - requireNonNull(value, "value is null"); - try { - this.value = Long.parseLong(value); - } - catch (NumberFormatException e) { - throw new ParsingException("Invalid numeric literal: " + value); - } - } - - public long getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitLongLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - LongLiteral that = (LongLiteral) o; - - if (value != that.value) { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - return (int) (value ^ (value >>> 32)); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return value == ((LongLiteral) other).value; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/MeasureDefinition.java b/trino-parser/src/main/java/io/trino/sql/tree/MeasureDefinition.java deleted file mode 100644 index 7eae5bbe3..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/MeasureDefinition.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class MeasureDefinition - extends Node -{ - private final Expression expression; - private final Identifier name; - - public MeasureDefinition(Expression expression, Identifier name) - { - this(Optional.empty(), expression, name); - } - - public MeasureDefinition(NodeLocation location, Expression expression, Identifier name) - { - this(Optional.of(location), expression, name); - } - - private MeasureDefinition(Optional location, Expression expression, Identifier name) - { - super(location); - this.expression = requireNonNull(expression, "expression is null"); - this.name = requireNonNull(name, "name is null"); - } - - public Expression getExpression() - { - return expression; - } - - public Identifier getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitMeasureDefinition(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(expression); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("expression", expression) - .add("name", name) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - MeasureDefinition that = (MeasureDefinition) o; - return Objects.equals(expression, that.expression) && - Objects.equals(name, that.name); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, name); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return Objects.equals(name, ((MeasureDefinition) other).name); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Merge.java b/trino-parser/src/main/java/io/trino/sql/tree/Merge.java deleted file mode 100644 index 0b2fb29b0..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Merge.java +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Merge - extends Statement -{ - private final Table table; - private final Optional targetAlias; - private final Relation relation; - private final Expression expression; - private final List mergeCases; - - public Merge( - Table table, - Optional targetAlias, - Relation relation, - Expression expression, - List mergeCases) - - { - this(Optional.empty(), table, targetAlias, relation, expression, mergeCases); - } - - public Merge( - NodeLocation location, - Table table, - Optional targetAlias, - Relation relation, - Expression expression, - List mergeCases) - { - this(Optional.of(location), table, targetAlias, relation, expression, mergeCases); - } - - public Merge( - Optional location, - Table table, - Optional targetAlias, - Relation relation, - Expression expression, - List mergeCases) - { - super(location); - this.table = requireNonNull(table, "table is null"); - this.targetAlias = requireNonNull(targetAlias, "targetAlias is null"); - this.relation = requireNonNull(relation, "relation is null"); - this.expression = requireNonNull(expression, "expression is null"); - this.mergeCases = ImmutableList.copyOf(requireNonNull(mergeCases, "mergeCases is null")); - } - - public Table getTable() - { - return table; - } - - public Optional getTargetAlias() - { - return targetAlias; - } - - public Relation getRelation() - { - return relation; - } - - public Expression getExpression() - { - return expression; - } - - public List getMergeCases() - { - return mergeCases; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitMerge(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder builder = ImmutableList.builder(); - builder.add(table); - builder.add(relation); - builder.add(expression); - builder.addAll(mergeCases); - return builder.build(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Merge merge = (Merge) o; - return Objects.equals(table, merge.table) && - Objects.equals(targetAlias, merge.targetAlias) && - Objects.equals(relation, merge.relation) && - Objects.equals(expression, merge.expression) && - Objects.equals(mergeCases, merge.mergeCases); - } - - @Override - public int hashCode() - { - return Objects.hash(table, targetAlias, relation, expression, mergeCases); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .add("targetAlias", targetAlias.orElse(null)) - .add("relation", relation) - .add("expression", expression) - .add("mergeCases", mergeCases) - .omitNullValues() - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/MergeCase.java b/trino-parser/src/main/java/io/trino/sql/tree/MergeCase.java deleted file mode 100644 index 6d7a5cb02..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/MergeCase.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.List; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public abstract class MergeCase - extends Node -{ - protected final Optional expression; - - protected MergeCase(Optional location, Optional expression) - { - super(location); - this.expression = requireNonNull(expression, "expression is null"); - } - - public Optional getExpression() - { - return expression; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitMergeCase(this, context); - } - - public abstract List getSetColumns(); - - public abstract List getSetExpressions(); -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/MergeDelete.java b/trino-parser/src/main/java/io/trino/sql/tree/MergeDelete.java deleted file mode 100644 index fe094887d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/MergeDelete.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class MergeDelete - extends MergeCase -{ - public MergeDelete(Optional expression) - { - this(Optional.empty(), expression); - } - - public MergeDelete(NodeLocation location, Optional expression) - { - super(Optional.of(location), expression); - } - - public MergeDelete(Optional location, Optional expression) - { - super(location, expression); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitMergeDelete(this, context); - } - - @Override - public List getSetColumns() - { - return ImmutableList.of(); - } - - @Override - public List getSetExpressions() - { - return ImmutableList.of(); - } - - @Override - public List getChildren() - { - return expression.map(ImmutableList::of).orElseGet(ImmutableList::of); - } - - @Override - public int hashCode() - { - return Objects.hash(expression); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - MergeDelete mergeDelete = (MergeDelete) obj; - return Objects.equals(expression, mergeDelete.expression); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("expression", expression.orElse(null)) - .omitNullValues() - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/MergeInsert.java b/trino-parser/src/main/java/io/trino/sql/tree/MergeInsert.java deleted file mode 100644 index 74ccead2c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/MergeInsert.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class MergeInsert - extends MergeCase -{ - private final List columns; - private final List values; - - public MergeInsert(Optional expression, List columns, List values) - { - this(Optional.empty(), expression, columns, values); - } - - public MergeInsert(NodeLocation location, Optional expression, List columns, List values) - { - this(Optional.of(location), expression, columns, values); - } - - public MergeInsert(Optional location, Optional expression, List columns, List values) - { - super(location, expression); - this.columns = ImmutableList.copyOf(requireNonNull(columns, "columns is null")); - this.values = ImmutableList.copyOf(requireNonNull(values, "values is null")); - } - - public List getColumns() - { - return columns; - } - - public List getValues() - { - return values; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitMergeInsert(this, context); - } - - @Override - public List getSetColumns() - { - return columns; - } - - @Override - public List getSetExpressions() - { - return values; - } - - @Override - public List getChildren() - { - ImmutableList.Builder builder = ImmutableList.builder(); - expression.ifPresent(builder::add); - builder.addAll(columns); - builder.addAll(values); - return builder.build(); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, columns, values); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - MergeInsert o = (MergeInsert) obj; - return Objects.equals(expression, o.expression) && - Objects.equals(columns, o.columns) && - Objects.equals(values, o.values); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("expression", expression.orElse(null)) - .add("columns", columns) - .add("values", values) - .omitNullValues() - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/MergeUpdate.java b/trino-parser/src/main/java/io/trino/sql/tree/MergeUpdate.java deleted file mode 100644 index 806b44473..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/MergeUpdate.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.util.Objects.requireNonNull; - -public class MergeUpdate - extends MergeCase -{ - private final List assignments; - - public MergeUpdate(Optional expression, List assignments) - { - this(Optional.empty(), expression, assignments); - } - - public MergeUpdate(NodeLocation location, Optional expression, List assignments) - { - this(Optional.of(location), expression, assignments); - } - - public MergeUpdate(Optional location, Optional expression, List assignments) - { - super(location, expression); - this.assignments = ImmutableList.copyOf(requireNonNull(assignments, "assignments is null")); - } - - public List getAssignments() - { - return assignments; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitMergeUpdate(this, context); - } - - @Override - public List getSetColumns() - { - return assignments.stream() - .map(Assignment::getTarget) - .collect(toImmutableList()); - } - - @Override - public List getSetExpressions() - { - return assignments.stream() - .map(Assignment::getValue) - .collect(toImmutableList()); - } - - @Override - public List getChildren() - { - ImmutableList.Builder builder = ImmutableList.builder(); - expression.ifPresent(builder::add); - assignments.forEach(assignment -> { - builder.add(assignment.getTarget()); - builder.add(assignment.getValue()); - }); - return builder.build(); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, assignments); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - MergeUpdate o = (MergeUpdate) obj; - return Objects.equals(expression, o.expression) && - Objects.equals(assignments, o.assignments); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("expression", expression.orElse(null)) - .add("assignments", assignments) - .omitNullValues() - .toString(); - } - - public static class Assignment - { - private final Identifier target; - private final Expression value; - - public Assignment(Identifier target, Expression value) - { - this.target = requireNonNull(target, "target is null"); - this.value = requireNonNull(value, "value is null"); - } - - public Identifier getTarget() - { - return target; - } - - public Expression getValue() - { - return value; - } - - @Override - public int hashCode() - { - return Objects.hash(target, value); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Assignment o = (Assignment) obj; - return Objects.equals(target, o.target) && - Objects.equals(value, o.value); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("target", target) - .add("value", value) - .toString(); - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/NaturalJoin.java b/trino-parser/src/main/java/io/trino/sql/tree/NaturalJoin.java deleted file mode 100644 index 01b9c5e79..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/NaturalJoin.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class NaturalJoin - extends JoinCriteria -{ - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - return (obj != null) && (getClass() == obj.getClass()); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public String toString() - { - return toStringHelper(this).toString(); - } - - @Override - public List getNodes() - { - return ImmutableList.of(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Node.java b/trino-parser/src/main/java/io/trino/sql/tree/Node.java deleted file mode 100644 index e550c5310..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Node.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.List; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public abstract class Node -{ - private final Optional location; - - protected Node(Optional location) - { - this.location = requireNonNull(location, "location is null"); - } - - /** - * Accessible for {@link AstVisitor}, use {@link AstVisitor#process(Node, Object)} instead. - */ - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitNode(this, context); - } - - public Optional getLocation() - { - return location; - } - - public abstract List getChildren(); - - // Force subclasses to have a proper equals and hashcode implementation - @Override - public abstract int hashCode(); - - @Override - public abstract boolean equals(Object obj); - - @Override - public abstract String toString(); - - /** - * Compare with another node by considering internal state excluding any Node returned by getChildren() - */ - public boolean shallowEquals(Node other) - { - throw new UnsupportedOperationException("not yet implemented: " + getClass().getName()); - } - - static boolean sameClass(Node left, Node right) - { - if (left == right) { - return true; - } - - return left.getClass() == right.getClass(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/NodeLocation.java b/trino-parser/src/main/java/io/trino/sql/tree/NodeLocation.java deleted file mode 100644 index 7666f5b30..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/NodeLocation.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Objects; - -import static com.google.common.base.Preconditions.checkArgument; - -public final class NodeLocation -{ - private final int line; - private final int column; - - public NodeLocation(int line, int column) - { - checkArgument(line >= 1, "line must be at least one, got: %s", line); - checkArgument(column >= 1, "column must be at least one, got: %s", column); - - this.line = line; - this.column = column; - } - - public int getLineNumber() - { - return line; - } - - public int getColumnNumber() - { - return column; - } - - @Override - public String toString() - { - return line + ":" + column; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NodeLocation that = (NodeLocation) o; - return line == that.line && - column == that.column; - } - - @Override - public int hashCode() - { - return Objects.hash(line, column); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/NodeRef.java b/trino-parser/src/main/java/io/trino/sql/tree/NodeRef.java deleted file mode 100644 index 09acebf01..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/NodeRef.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import static java.lang.String.format; -import static java.lang.System.identityHashCode; -import static java.util.Objects.requireNonNull; - -public final class NodeRef -{ - public static NodeRef of(T node) - { - return new NodeRef<>(node); - } - - private final T node; - - private NodeRef(T node) - { - this.node = requireNonNull(node, "node is null"); - } - - public T getNode() - { - return node; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NodeRef other = (NodeRef) o; - return node == other.node; - } - - @Override - public int hashCode() - { - return identityHashCode(node); - } - - @Override - public String toString() - { - return format( - "@%s: %s", - Integer.toHexString(identityHashCode(node)), - node); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/NotExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/NotExpression.java deleted file mode 100644 index 0ceb9a8e8..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/NotExpression.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class NotExpression - extends Expression -{ - private final Expression value; - - public NotExpression(Expression value) - { - this(Optional.empty(), value); - } - - public NotExpression(NodeLocation location, Expression value) - { - this(Optional.of(location), value); - } - - private NotExpression(Optional location, Expression value) - { - super(location); - requireNonNull(value, "value is null"); - this.value = value; - } - - public Expression getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitNotExpression(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - NotExpression that = (NotExpression) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return value.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/NullIfExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/NullIfExpression.java deleted file mode 100644 index 272f2e902..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/NullIfExpression.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -/** - * NULLIF(V1,V2): CASE WHEN V1=V2 THEN NULL ELSE V1 END - */ -public class NullIfExpression - extends Expression -{ - private final Expression first; - private final Expression second; - - public NullIfExpression(Expression first, Expression second) - { - this(Optional.empty(), first, second); - } - - public NullIfExpression(NodeLocation location, Expression first, Expression second) - { - this(Optional.of(location), first, second); - } - - private NullIfExpression(Optional location, Expression first, Expression second) - { - super(location); - this.first = first; - this.second = second; - } - - public Expression getFirst() - { - return first; - } - - public Expression getSecond() - { - return second; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitNullIfExpression(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(first, second); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - NullIfExpression that = (NullIfExpression) o; - return Objects.equals(first, that.first) && - Objects.equals(second, that.second); - } - - @Override - public int hashCode() - { - return Objects.hash(first, second); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/NullLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/NullLiteral.java deleted file mode 100644 index 3186fdc38..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/NullLiteral.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public class NullLiteral - extends Literal -{ - public NullLiteral() - { - super(Optional.empty()); - } - - public NullLiteral(NodeLocation location) - { - super(Optional.of(location)); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitNullLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - return true; - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/NumericParameter.java b/trino-parser/src/main/java/io/trino/sql/tree/NumericParameter.java deleted file mode 100644 index 36cc4a128..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/NumericParameter.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class NumericParameter - extends DataTypeParameter -{ - private final String value; - - public NumericParameter(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - public NumericParameter(Optional location, String value) - { - super(location); - this.value = requireNonNull(value, "value is null"); - } - - public String getValue() - { - return value; - } - - @Override - public String toString() - { - return value; - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitNumericTypeParameter(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NumericParameter that = (NumericParameter) o; - return value.equals(that.value); - } - - @Override - public int hashCode() - { - return Objects.hash(value); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return Objects.equals(value, ((NumericParameter) other).value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Offset.java b/trino-parser/src/main/java/io/trino/sql/tree/Offset.java deleted file mode 100644 index bb8160214..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Offset.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; - -public class Offset - extends Node -{ - private final Expression rowCount; - - public Offset(Expression rowCount) - { - this(Optional.empty(), rowCount); - } - - public Offset(NodeLocation location, Expression rowCount) - { - this(Optional.of(location), rowCount); - } - - public Offset(Optional location, Expression rowCount) - { - super(location); - checkArgument(rowCount instanceof LongLiteral || rowCount instanceof Parameter, - "unexpected rowCount class: %s", - rowCount.getClass().getSimpleName()); - this.rowCount = rowCount; - } - - public Expression getRowCount() - { - return rowCount; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitOffset(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(rowCount); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Offset o = (Offset) obj; - return Objects.equals(rowCount, o.rowCount); - } - - @Override - public int hashCode() - { - return Objects.hash(rowCount); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("rowCount", rowCount) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/OneOrMoreQuantifier.java b/trino-parser/src/main/java/io/trino/sql/tree/OneOrMoreQuantifier.java deleted file mode 100644 index 409a6c53a..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/OneOrMoreQuantifier.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public class OneOrMoreQuantifier - extends PatternQuantifier -{ - public OneOrMoreQuantifier(boolean greedy) - { - this(Optional.empty(), greedy); - } - - public OneOrMoreQuantifier(NodeLocation location, boolean greedy) - { - this(Optional.of(location), greedy); - } - - public OneOrMoreQuantifier(Optional location, boolean greedy) - { - super(location, greedy); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitOneOrMoreQuantifier(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/OrderBy.java b/trino-parser/src/main/java/io/trino/sql/tree/OrderBy.java deleted file mode 100644 index ab8f8acc5..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/OrderBy.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class OrderBy - extends Node -{ - private final List sortItems; - - public OrderBy(List sortItems) - { - this(Optional.empty(), sortItems); - } - - public OrderBy(NodeLocation location, List sortItems) - { - this(Optional.of(location), sortItems); - } - - private OrderBy(Optional location, List sortItems) - { - super(location); - requireNonNull(sortItems, "sortItems is null"); - checkArgument(!sortItems.isEmpty(), "sortItems should not be empty"); - this.sortItems = ImmutableList.copyOf(sortItems); - } - - public List getSortItems() - { - return sortItems; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitOrderBy(this, context); - } - - @Override - public List getChildren() - { - return sortItems; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("sortItems", sortItems) - .toString(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - OrderBy o = (OrderBy) obj; - return Objects.equals(sortItems, o.sortItems); - } - - @Override - public int hashCode() - { - return Objects.hash(sortItems); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Parameter.java b/trino-parser/src/main/java/io/trino/sql/tree/Parameter.java deleted file mode 100644 index b12e31ac7..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Parameter.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -public class Parameter - extends Expression -{ - private final int position; - - public Parameter(int id) - { - this(Optional.empty(), id); - } - - public Parameter(NodeLocation location, int id) - { - this(Optional.of(location), id); - } - - private Parameter(Optional location, int position) - { - super(location); - this.position = position; - } - - public int getPosition() - { - return position; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitParameter(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Parameter that = (Parameter) o; - return Objects.equals(position, that.position); - } - - @Override - public int hashCode() - { - return position; - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return position == ((Parameter) other).position; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PathElement.java b/trino-parser/src/main/java/io/trino/sql/tree/PathElement.java deleted file mode 100644 index 102aa7532..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PathElement.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; - -public final class PathElement - extends Node -{ - private final Optional catalog; - private final Identifier schema; - - public PathElement(NodeLocation location, Identifier schema) - { - this(Optional.of(location), Optional.empty(), schema); - } - - @VisibleForTesting - public PathElement(Optional catalog, Identifier schema) - { - this(Optional.empty(), catalog, schema); - } - - public PathElement(NodeLocation location, Identifier catalog, Identifier schema) - { - this(Optional.of(location), Optional.of(catalog), schema); - } - - private PathElement(Optional location, Optional catalog, Identifier schema) - { - super(location); - this.catalog = requireNonNull(catalog, "catalog is null"); - this.schema = requireNonNull(schema, "schema is null"); - } - - public Optional getCatalog() - { - return catalog; - } - - public Identifier getSchema() - { - return schema; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPathElement(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - PathElement o = (PathElement) obj; - return Objects.equals(schema, o.schema) && - Objects.equals(catalog, o.catalog); - } - - @Override - public int hashCode() - { - return Objects.hash(catalog, schema); - } - - @Override - public String toString() - { - if (catalog.isPresent()) { - return format("%s.%s", catalog.get(), schema); - } - return schema.toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PathRelation.java b/trino-parser/src/main/java/io/trino/sql/tree/PathRelation.java deleted file mode 100644 index 25300a53c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PathRelation.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class PathRelation - extends QueryBody -{ - private final String path; - - public PathRelation(Optional location, String path) - { - super(location); - this.path = path; - } - - @Override - public List getChildren() - { - return List.of(); - } - - public String getPath() - { - return path; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPathRelation(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - PathRelation that = (PathRelation) o; - return Objects.equals(path, that.path); - } - - @Override - public int hashCode() - { - return Objects.hashCode(path); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("path", path) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PathSpecification.java b/trino-parser/src/main/java/io/trino/sql/tree/PathSpecification.java deleted file mode 100644 index a7f6af5aa..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PathSpecification.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public final class PathSpecification - extends Node -{ - private final List path; - - public PathSpecification(NodeLocation location, List path) - { - this(Optional.of(location), path); - } - - @VisibleForTesting - public PathSpecification(Optional location, List path) - { - super(location); - this.path = ImmutableList.copyOf(requireNonNull(path, "path is null")); - } - - public List getPath() - { - return path; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPathSpecification(this, context); - } - - @Override - public List getChildren() - { - return path; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - PathSpecification o = (PathSpecification) obj; - return Objects.equals(path, o.path); - } - - @Override - public int hashCode() - { - return Objects.hash(path); - } - - @Override - public String toString() - { - return Joiner.on(", ").join(path); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PatternAlternation.java b/trino-parser/src/main/java/io/trino/sql/tree/PatternAlternation.java deleted file mode 100644 index 9239d2c66..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PatternAlternation.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class PatternAlternation - extends RowPattern -{ - private final List patterns; - - public PatternAlternation(NodeLocation location, List patterns) - { - this(Optional.of(location), patterns); - } - - private PatternAlternation(Optional location, List patterns) - { - super(location); - this.patterns = requireNonNull(patterns, "patterns is null"); - checkArgument(!patterns.isEmpty(), "patterns list is empty"); - } - - public List getPatterns() - { - return patterns; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPatternAlternation(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.copyOf(patterns); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - PatternAlternation o = (PatternAlternation) obj; - return Objects.equals(patterns, o.patterns); - } - - @Override - public int hashCode() - { - return Objects.hash(patterns); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("patterns", patterns) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PatternConcatenation.java b/trino-parser/src/main/java/io/trino/sql/tree/PatternConcatenation.java deleted file mode 100644 index 0a62a31e5..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PatternConcatenation.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class PatternConcatenation - extends RowPattern -{ - private final List patterns; - - public PatternConcatenation(NodeLocation location, List patterns) - { - this(Optional.of(location), patterns); - } - - private PatternConcatenation(Optional location, List patterns) - { - super(location); - this.patterns = requireNonNull(patterns, "patterns is null"); - checkArgument(!patterns.isEmpty(), "patterns list is empty"); - } - - public List getPatterns() - { - return patterns; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPatternConcatenation(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.copyOf(patterns); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - PatternConcatenation o = (PatternConcatenation) obj; - return Objects.equals(patterns, o.patterns); - } - - @Override - public int hashCode() - { - return Objects.hash(patterns); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("patterns", patterns) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PatternPermutation.java b/trino-parser/src/main/java/io/trino/sql/tree/PatternPermutation.java deleted file mode 100644 index 438ec6dd2..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PatternPermutation.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class PatternPermutation - extends RowPattern -{ - private final List patterns; - - public PatternPermutation(NodeLocation location, List patterns) - { - this(Optional.of(location), patterns); - } - - private PatternPermutation(Optional location, List patterns) - { - super(location); - this.patterns = requireNonNull(patterns, "patterns is null"); - checkArgument(!patterns.isEmpty(), "patterns list is empty"); - } - - public List getPatterns() - { - return patterns; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPatternPermutation(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.copyOf(patterns); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - PatternPermutation o = (PatternPermutation) obj; - return Objects.equals(patterns, o.patterns); - } - - @Override - public int hashCode() - { - return Objects.hash(patterns); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("patterns", patterns) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PatternQuantifier.java b/trino-parser/src/main/java/io/trino/sql/tree/PatternQuantifier.java deleted file mode 100644 index a66e0e9e4..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PatternQuantifier.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public abstract class PatternQuantifier - extends Node -{ - private final boolean greedy; - - protected PatternQuantifier(Optional location, boolean greedy) - { - super(location); - this.greedy = greedy; - } - - public boolean isGreedy() - { - return greedy; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPatternQuantifier(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - PatternQuantifier o = (PatternQuantifier) obj; - return greedy == o.greedy; - } - - @Override - public int hashCode() - { - return Objects.hash(greedy); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - PatternQuantifier otherNode = (PatternQuantifier) other; - return greedy == otherNode.greedy; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("greedy", greedy) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PatternRecognitionRelation.java b/trino-parser/src/main/java/io/trino/sql/tree/PatternRecognitionRelation.java deleted file mode 100644 index 0dc5eb55b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PatternRecognitionRelation.java +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class PatternRecognitionRelation - extends Relation -{ - private final Relation input; - private final List partitionBy; - private final Optional orderBy; - private final List measures; - private final Optional rowsPerMatch; - private final Optional afterMatchSkipTo; - private final Optional patternSearchMode; - private final RowPattern pattern; - private final List subsets; - private final List variableDefinitions; - - public PatternRecognitionRelation( - Relation input, - List partitionBy, - Optional orderBy, - List measures, - Optional rowsPerMatch, - Optional afterMatchSkipTo, - Optional patternSearchMode, - RowPattern pattern, - List subsets, - List variableDefinitions) - { - this(Optional.empty(), input, partitionBy, orderBy, measures, rowsPerMatch, afterMatchSkipTo, patternSearchMode, pattern, subsets, variableDefinitions); - } - - public PatternRecognitionRelation( - NodeLocation location, - Relation input, - List partitionBy, - Optional orderBy, - List measures, - Optional rowsPerMatch, - Optional afterMatchSkipTo, - Optional patternSearchMode, - RowPattern pattern, - List subsets, - List variableDefinitions) - { - this(Optional.of(location), input, partitionBy, orderBy, measures, rowsPerMatch, afterMatchSkipTo, patternSearchMode, pattern, subsets, variableDefinitions); - } - - private PatternRecognitionRelation( - Optional location, - Relation input, - List partitionBy, - Optional orderBy, - List measures, - Optional rowsPerMatch, - Optional afterMatchSkipTo, - Optional patternSearchMode, - RowPattern pattern, - List subsets, - List variableDefinitions) - { - super(location); - this.input = requireNonNull(input, "input is null"); - this.partitionBy = requireNonNull(partitionBy, "partitionBy is null"); - this.orderBy = requireNonNull(orderBy, "orderBy is null"); - this.measures = requireNonNull(measures, "measures is null"); - this.rowsPerMatch = requireNonNull(rowsPerMatch, "rowsPerMatch is null"); - this.afterMatchSkipTo = requireNonNull(afterMatchSkipTo, "afterMatchSkipTo is null"); - this.patternSearchMode = requireNonNull(patternSearchMode, "patternSearchMode is null"); - this.pattern = requireNonNull(pattern, "pattern is null"); - this.subsets = requireNonNull(subsets, "subsets is null"); - requireNonNull(variableDefinitions, "variableDefinitions is null"); - checkArgument(!variableDefinitions.isEmpty(), "variableDefinitions is empty"); - this.variableDefinitions = variableDefinitions; - } - - public Relation getInput() - { - return input; - } - - public List getPartitionBy() - { - return partitionBy; - } - - public Optional getOrderBy() - { - return orderBy; - } - - public List getMeasures() - { - return measures; - } - - public Optional getRowsPerMatch() - { - return rowsPerMatch; - } - - public Optional getAfterMatchSkipTo() - { - return afterMatchSkipTo; - } - - public Optional getPatternSearchMode() - { - return patternSearchMode; - } - - public RowPattern getPattern() - { - return pattern; - } - - public List getSubsets() - { - return subsets; - } - - public List getVariableDefinitions() - { - return variableDefinitions; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPatternRecognitionRelation(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder builder = ImmutableList.builder(); - builder.add(input); - builder.addAll(partitionBy); - orderBy.ifPresent(builder::add); - builder.addAll(measures); - afterMatchSkipTo.ifPresent(builder::add); - builder.add(pattern) - .addAll(subsets) - .addAll(variableDefinitions); - patternSearchMode.ifPresent(builder::add); - - return builder.build(); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("input", input) - .add("partitionBy", partitionBy) - .add("orderBy", orderBy.orElse(null)) - .add("measures", measures) - .add("rowsPerMatch", rowsPerMatch.orElse(null)) - .add("afterMatchSkipTo", afterMatchSkipTo) - .add("patternSearchMode", patternSearchMode.orElse(null)) - .add("pattern", pattern) - .add("subsets", subsets) - .add("variableDefinitions", variableDefinitions) - .omitNullValues() - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - PatternRecognitionRelation that = (PatternRecognitionRelation) o; - return Objects.equals(input, that.input) && - Objects.equals(partitionBy, that.partitionBy) && - Objects.equals(orderBy, that.orderBy) && - Objects.equals(measures, that.measures) && - Objects.equals(rowsPerMatch, that.rowsPerMatch) && - Objects.equals(afterMatchSkipTo, that.afterMatchSkipTo) && - Objects.equals(patternSearchMode, that.patternSearchMode) && - Objects.equals(pattern, that.pattern) && - Objects.equals(subsets, that.subsets) && - Objects.equals(variableDefinitions, that.variableDefinitions); - } - - @Override - public int hashCode() - { - return Objects.hash(input, partitionBy, orderBy, measures, rowsPerMatch, afterMatchSkipTo, patternSearchMode, pattern, subsets, variableDefinitions); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return rowsPerMatch.equals(((PatternRecognitionRelation) other).rowsPerMatch); - } - - public enum RowsPerMatch - { - // ONE option applies to the MATCH_RECOGNIZE clause. This is the default option. - // Output a single summary row for every match, including empty matches. - // In the case of an empty match, output the starting row of the match attempt. - ONE { - @Override - public boolean isOneRow() - { - return true; - } - - @Override - public boolean isEmptyMatches() - { - return true; - } - - @Override - public boolean isUnmatchedRows() - { - return false; - } - }, - - // ALL_SHOW_EMPTY option applies to the MATCH_RECOGNIZE clause. - // Output all rows of every match, including empty matches. - // In the case of an empty match, output the starting row of the match attempt. - // Do not produce output for the rows matched within exclusion `{- ... -}`. - ALL_SHOW_EMPTY { - @Override - public boolean isOneRow() - { - return false; - } - - @Override - public boolean isEmptyMatches() - { - return true; - } - - @Override - public boolean isUnmatchedRows() - { - return false; - } - }, - - // ALL_OMIT_EMPTY option applies to the MATCH_RECOGNIZE clause. - // Output all rows of every non-empty match. - // Do not produce output for the rows matched within exclusion `{- ... -}` - ALL_OMIT_EMPTY { - @Override - public boolean isOneRow() - { - return false; - } - - @Override - public boolean isEmptyMatches() - { - return false; - } - - @Override - public boolean isUnmatchedRows() - { - return false; - } - }, - - // ALL_WITH_UNMATCHED option applies to the MATCH_RECOGNIZE clause. - // Output all rows of every match, including empty matches. - // Produce an additional output row for every unmatched row. - // Pattern exclusions are not allowed with this option. - ALL_WITH_UNMATCHED { - @Override - public boolean isOneRow() - { - return false; - } - - @Override - public boolean isEmptyMatches() - { - return true; - } - - @Override - public boolean isUnmatchedRows() - { - return true; - } - }, - - // WINDOW option applies to pattern recognition within window specification. - // Output one row for every input row: - // - if the row is skipped by some previous match, produce output as for unmatched row - // - if match is found (either empty or non-empty), output a single-row summary - // - if no match is found, produce output as for unmatched row - WINDOW { - @Override - public boolean isOneRow() - { - return true; - } - - @Override - public boolean isEmptyMatches() - { - return true; - } - - @Override - public boolean isUnmatchedRows() - { - return true; - } - }; - - public abstract boolean isOneRow(); - - public abstract boolean isEmptyMatches(); - - public abstract boolean isUnmatchedRows(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PatternSearchMode.java b/trino-parser/src/main/java/io/trino/sql/tree/PatternSearchMode.java deleted file mode 100644 index 8a60ae4ee..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PatternSearchMode.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class PatternSearchMode - extends Node -{ - private final Mode mode; - - public PatternSearchMode(Mode mode) - { - this(Optional.empty(), mode); - } - - public PatternSearchMode(NodeLocation location, Mode mode) - { - this(Optional.of(location), mode); - } - - public PatternSearchMode(Optional location, Mode mode) - { - super(location); - this.mode = requireNonNull(mode, "mode is null"); - } - - public Mode getMode() - { - return mode; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPatternSearchMode(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return mode == ((PatternSearchMode) obj).mode; - } - - @Override - public int hashCode() - { - return Objects.hash(mode); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("mode", mode) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return mode == ((PatternSearchMode) other).mode; - } - - public enum Mode - { - INITIAL, SEEK - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PatternVariable.java b/trino-parser/src/main/java/io/trino/sql/tree/PatternVariable.java deleted file mode 100644 index 7aa932600..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PatternVariable.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class PatternVariable - extends RowPattern -{ - private final Identifier name; - - public PatternVariable(NodeLocation location, Identifier name) - { - this(Optional.of(location), name); - } - - private PatternVariable(Optional location, Identifier name) - { - super(location); - this.name = requireNonNull(name, "name is null"); - } - - public Identifier getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPatternVariable(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(name); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - PatternVariable o = (PatternVariable) obj; - return Objects.equals(name, o.name); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Prepare.java b/trino-parser/src/main/java/io/trino/sql/tree/Prepare.java deleted file mode 100644 index 9709da788..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Prepare.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Prepare - extends Statement -{ - private final Identifier name; - private final Statement statement; - - public Prepare(NodeLocation location, Identifier name, Statement statement) - { - this(Optional.of(location), name, statement); - } - - public Prepare(Identifier name, Statement statement) - { - this(Optional.empty(), name, statement); - } - - private Prepare(Optional location, Identifier name, Statement statement) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.statement = requireNonNull(statement, "statement is null"); - } - - public Identifier getName() - { - return name; - } - - public Statement getStatement() - { - return statement; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitPrepare(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(statement); - } - - @Override - public int hashCode() - { - return Objects.hash(name, statement); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Prepare o = (Prepare) obj; - return Objects.equals(name, o.name) && - Objects.equals(statement, o.statement); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("statement", statement) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/PrincipalSpecification.java b/trino-parser/src/main/java/io/trino/sql/tree/PrincipalSpecification.java deleted file mode 100644 index 2ba18057d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/PrincipalSpecification.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class PrincipalSpecification -{ - public enum Type - { - UNSPECIFIED, USER, ROLE - } - - private final Type type; - private final Identifier name; - - public PrincipalSpecification(Type type, Identifier name) - { - this.type = requireNonNull(type, "type is null"); - this.name = requireNonNull(name, "name is null"); - } - - public Type getType() - { - return type; - } - - public Identifier getName() - { - return name; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PrincipalSpecification that = (PrincipalSpecification) o; - return type == that.type && - Objects.equals(name, that.name); - } - - @Override - public int hashCode() - { - return Objects.hash(type, name); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("name", name) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ProcessingMode.java b/trino-parser/src/main/java/io/trino/sql/tree/ProcessingMode.java deleted file mode 100644 index b569cc723..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ProcessingMode.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class ProcessingMode - extends Node -{ - private final Mode mode; - - public ProcessingMode(NodeLocation location, Mode mode) - { - this(Optional.of(location), mode); - } - - public ProcessingMode(Optional location, Mode mode) - { - super(location); - this.mode = requireNonNull(mode, "mode is null"); - } - - public Mode getMode() - { - return mode; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitProcessingMode(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return mode == ((ProcessingMode) obj).mode; - } - - @Override - public int hashCode() - { - return Objects.hash(mode); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("mode", mode) - .toString(); - } - - public enum Mode - { - RUNNING, FINAL - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Property.java b/trino-parser/src/main/java/io/trino/sql/tree/Property.java deleted file mode 100644 index bde9df4f3..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Property.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkState; -import static java.util.Objects.requireNonNull; - -// TODO: Model DEFAULT as a type of expression to make it easier to do analysis, planning and error reporting in a uniform way -public class Property - extends Node -{ - private final Identifier name; - private final Optional value; // empty iff the value is set to DEFAULT - - /** - * Constructs an instance representing a property whose value is set to DEFAULT - */ - public Property(Identifier name) - { - this(Optional.empty(), name, Optional.empty()); - } - - /** - * Constructs an instance representing a property whose value is set to DEFAULT - */ - public Property(NodeLocation location, Identifier name) - { - this(Optional.of(requireNonNull(location, "location is null")), name, Optional.empty()); - } - - public Property(Identifier name, Expression value) - { - this(Optional.empty(), name, Optional.of(requireNonNull(value, "value is null"))); - } - - public Property(NodeLocation location, Identifier name, Expression value) - { - this( - Optional.of(requireNonNull(location, "location is null")), - name, - Optional.of(requireNonNull(value, "value is null"))); - } - - private Property(Optional location, Identifier name, Optional value) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.value = requireNonNull(value, "value is null"); - } - - public Identifier getName() - { - return name; - } - - public boolean isSetToDefault() - { - return !value.isPresent(); - } - - /** - * Returns the non-default value of the property. This method should be called only if the property is not set to DEFAULT. - */ - public Expression getNonDefaultValue() - { - checkState(!isSetToDefault(), "Cannot get non-default value of property %s since its value is set to DEFAULT", name); - return value.get(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitProperty(this, context); - } - - @Override - public List getChildren() - { - return isSetToDefault() ? ImmutableList.of(name) : ImmutableList.of(name, getNonDefaultValue()); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Property other = (Property) obj; - return Objects.equals(name, other.name) && - Objects.equals(value, other.value); - } - - @Override - public int hashCode() - { - return Objects.hash(name, value); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("value", isSetToDefault() ? "DEFAULT" : getNonDefaultValue()) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/QualifiedName.java b/trino-parser/src/main/java/io/trino/sql/tree/QualifiedName.java deleted file mode 100644 index cea120ef0..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/QualifiedName.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Iterables; -import com.google.common.collect.Lists; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.Iterables.isEmpty; -import static java.util.Objects.requireNonNull; - -public class QualifiedName -{ - private final List parts; - private final List originalParts; - - public static QualifiedName of(String first, String... rest) - { - requireNonNull(first, "first is null"); - return of(ImmutableList.copyOf(Lists.asList(first, rest).stream().map(Identifier::new).collect(Collectors.toList()))); - } - - public static QualifiedName of(List parts) - { - requireNonNull(parts, "parts is null"); - return of(ImmutableList.copyOf(parts.stream().map(Identifier::new).collect(Collectors.toList()))); - } - - public static QualifiedName of(String name) - { - requireNonNull(name, "name is null"); - return of(ImmutableList.of(new Identifier(name))); - } - - public static QualifiedName of(Iterable originalParts) - { - requireNonNull(originalParts, "originalParts is null"); - checkArgument(!isEmpty(originalParts), "originalParts is empty"); - - return new QualifiedName(ImmutableList.copyOf(originalParts)); - } - - private QualifiedName(List originalParts) - { - this.originalParts = originalParts; - this.parts = originalParts.stream().map(Identifier::getValue).collect(toImmutableList()); - } - - public List getParts() - { - return parts; - } - - public List getOriginalParts() - { - return originalParts; - } - - @Override - public String toString() - { - return Joiner.on('.').join(parts); - } - - /** - * For an identifier of the form "a.b.c.d", returns "a.b.c" - * For an identifier of the form "a", returns absent - */ - public Optional getPrefix() - { - if (parts.size() == 1) { - return Optional.empty(); - } - - List subList = originalParts.subList(0, originalParts.size() - 1); - return Optional.of(new QualifiedName(subList)); - } - - public boolean hasSuffix(QualifiedName suffix) - { - if (parts.size() < suffix.getParts().size()) { - return false; - } - - int start = parts.size() - suffix.getParts().size(); - - return parts.subList(start, parts.size()).equals(suffix.getParts()); - } - - public String getSuffix() - { - return Iterables.getLast(parts); - } - - public boolean hasPrefix(QualifiedName prefix) - { - if (parts.size() < prefix.getParts().size()) { - return false; - } - - return parts.subList(0, prefix.getParts().size()).equals(prefix.getParts()); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - return parts.equals(((QualifiedName) o).parts); - } - - @Override - public int hashCode() - { - return parts.hashCode(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/QuantifiedComparisonExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/QuantifiedComparisonExpression.java deleted file mode 100644 index 10ef15623..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/QuantifiedComparisonExpression.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class QuantifiedComparisonExpression - extends Expression -{ - public enum Quantifier - { - ALL, - ANY, - SOME, - } - - private final ComparisonExpression.Operator operator; - private final Quantifier quantifier; - private final Expression value; - private final Expression subquery; - - public QuantifiedComparisonExpression(ComparisonExpression.Operator operator, Quantifier quantifier, Expression value, Expression subquery) - { - this(Optional.empty(), operator, quantifier, value, subquery); - } - - public QuantifiedComparisonExpression(NodeLocation location, ComparisonExpression.Operator operator, Quantifier quantifier, Expression value, Expression subquery) - { - this(Optional.of(location), operator, quantifier, value, subquery); - } - - private QuantifiedComparisonExpression(Optional location, ComparisonExpression.Operator operator, Quantifier quantifier, Expression value, Expression subquery) - { - super(location); - this.operator = requireNonNull(operator, "operator is null"); - this.quantifier = requireNonNull(quantifier, "quantifier is null"); - this.value = requireNonNull(value, "value is null"); - this.subquery = requireNonNull(subquery, "subquery is null"); - } - - public ComparisonExpression.Operator getOperator() - { - return operator; - } - - public Quantifier getQuantifier() - { - return quantifier; - } - - public Expression getValue() - { - return value; - } - - public Expression getSubquery() - { - return subquery; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitQuantifiedComparisonExpression(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value, subquery); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - QuantifiedComparisonExpression that = (QuantifiedComparisonExpression) o; - return operator == that.operator && - quantifier == that.quantifier && - Objects.equals(value, that.value) && - Objects.equals(subquery, that.subquery); - } - - @Override - public int hashCode() - { - return Objects.hash(operator, quantifier, value, subquery); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - QuantifiedComparisonExpression otherNode = (QuantifiedComparisonExpression) other; - return operator == otherNode.operator && quantifier == otherNode.quantifier; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/QuantifiedPattern.java b/trino-parser/src/main/java/io/trino/sql/tree/QuantifiedPattern.java deleted file mode 100644 index c1a4bdd83..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/QuantifiedPattern.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class QuantifiedPattern - extends RowPattern -{ - private final RowPattern pattern; - private final PatternQuantifier patternQuantifier; - - public QuantifiedPattern(NodeLocation location, RowPattern pattern, PatternQuantifier patternQuantifier) - { - this(Optional.of(location), pattern, patternQuantifier); - } - - private QuantifiedPattern(Optional location, RowPattern pattern, PatternQuantifier patternQuantifier) - { - super(location); - this.pattern = requireNonNull(pattern, "pattern is null"); - this.patternQuantifier = requireNonNull(patternQuantifier, "patternQuantifier is null"); - } - - public RowPattern getPattern() - { - return pattern; - } - - public PatternQuantifier getPatternQuantifier() - { - return patternQuantifier; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitQuantifiedPattern(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(pattern, patternQuantifier); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - QuantifiedPattern o = (QuantifiedPattern) obj; - return Objects.equals(pattern, o.pattern) && - Objects.equals(patternQuantifier, o.patternQuantifier); - } - - @Override - public int hashCode() - { - return Objects.hash(pattern, patternQuantifier); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("pattern", pattern) - .add("patternQuantifier", patternQuantifier) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Query.java b/trino-parser/src/main/java/io/trino/sql/tree/Query.java deleted file mode 100644 index 19afd477e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Query.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class Query - extends Statement -{ - private final Optional with; - private final QueryBody queryBody; - private final Optional orderBy; - private final Optional offset; - private final Optional limit; - - public Query( - Optional with, - QueryBody queryBody, - Optional orderBy, - Optional offset, - Optional limit) - { - this(Optional.empty(), with, queryBody, orderBy, offset, limit); - } - - public Query( - NodeLocation location, - Optional with, - QueryBody queryBody, - Optional orderBy, - Optional offset, - Optional limit) - { - this(Optional.of(location), with, queryBody, orderBy, offset, limit); - } - - private Query( - Optional location, - Optional with, - QueryBody queryBody, - Optional orderBy, - Optional offset, - Optional limit) - { - super(location); - requireNonNull(with, "with is null"); - requireNonNull(queryBody, "queryBody is null"); - requireNonNull(orderBy, "orderBy is null"); - requireNonNull(offset, "offset is null"); - requireNonNull(limit, "limit is null"); - checkArgument(!limit.isPresent() || limit.get() instanceof FetchFirst || limit.get() instanceof Limit, "limit must be optional of either FetchFirst or Limit type"); - - this.with = with; - this.queryBody = queryBody; - this.orderBy = orderBy; - this.offset = offset; - this.limit = limit; - } - - public Optional getWith() - { - return with; - } - - public QueryBody getQueryBody() - { - return queryBody; - } - - public Optional getOrderBy() - { - return orderBy; - } - - public Optional getOffset() - { - return offset; - } - - public Optional getLimit() - { - return limit; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitQuery(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - with.ifPresent(nodes::add); - nodes.add(queryBody); - orderBy.ifPresent(nodes::add); - offset.ifPresent(nodes::add); - limit.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("with", with.orElse(null)) - .add("queryBody", queryBody) - .add("orderBy", orderBy) - .add("offset", offset.orElse(null)) - .add("limit", limit.orElse(null)) - .omitNullValues() - .toString(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Query o = (Query) obj; - return Objects.equals(with, o.with) && - Objects.equals(queryBody, o.queryBody) && - Objects.equals(orderBy, o.orderBy) && - Objects.equals(offset, o.offset) && - Objects.equals(limit, o.limit); - } - - @Override - public int hashCode() - { - return Objects.hash(with, queryBody, orderBy, offset, limit); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/QueryBody.java b/trino-parser/src/main/java/io/trino/sql/tree/QueryBody.java deleted file mode 100644 index 40d372690..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/QueryBody.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class QueryBody - extends Relation -{ - protected QueryBody(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitQueryBody(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/QueryPeriod.java b/trino-parser/src/main/java/io/trino/sql/tree/QueryPeriod.java deleted file mode 100644 index 29584cb7e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/QueryPeriod.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class QueryPeriod - extends Node -{ - private final Optional start; - private final Optional end; - private final RangeType rangeType; - - public enum RangeType - { - TIMESTAMP, - VERSION - } - - public QueryPeriod(NodeLocation location, RangeType rangeType, Expression end) - { - this(location, rangeType, Optional.empty(), Optional.of(end)); - } - - private QueryPeriod(NodeLocation location, RangeType rangeType, Optional start, Optional end) - { - super(Optional.of(location)); - this.rangeType = requireNonNull(rangeType, "rangeType is null"); - this.start = start; - this.end = end; - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - if (start.isPresent()) { - nodes.add(start.get()); - } - if (end.isPresent()) { - nodes.add(end.get()); - } - return nodes.build(); - } - - public Optional getStart() - { - return start; - } - - public Optional getEnd() - { - return end; - } - - public RangeType getRangeType() - { - return rangeType; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitQueryPeriod(this, context); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - QueryPeriod o = (QueryPeriod) obj; - return Objects.equals(rangeType, o.rangeType) && - Objects.equals(start, o.start) && - Objects.equals(end, o.end); - } - - @Override - public int hashCode() - { - return Objects.hash(rangeType, start, end); - } - - @Override - public String toString() - { - return "FOR " + rangeType.toString() + " AS OF " + end.get().toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/QuerySpecification.java b/trino-parser/src/main/java/io/trino/sql/tree/QuerySpecification.java deleted file mode 100644 index 539a4f18c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/QuerySpecification.java +++ /dev/null @@ -1,222 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class QuerySpecification - extends QueryBody -{ - private final Select select; - private final Optional from; - private final Optional where; - private final Optional groupBy; - private final Optional having; - private final List windows; - private final Optional orderBy; - private final Optional offset; - private final Optional limit; - - public QuerySpecification( - Select select, - Optional from, - Optional where, - Optional groupBy, - Optional having, - List windows, - Optional orderBy, - Optional offset, - Optional limit) - { - this(Optional.empty(), select, from, where, groupBy, having, windows, orderBy, offset, limit); - } - - public QuerySpecification( - NodeLocation location, - Select select, - Optional from, - Optional where, - Optional groupBy, - Optional having, - List windows, - Optional orderBy, - Optional offset, - Optional limit) - { - this(Optional.of(location), select, from, where, groupBy, having, windows, orderBy, offset, limit); - } - - private QuerySpecification( - Optional location, - Select select, - Optional from, - Optional where, - Optional groupBy, - Optional having, - List windows, - Optional orderBy, - Optional offset, - Optional limit) - { - super(location); - requireNonNull(select, "select is null"); - requireNonNull(from, "from is null"); - requireNonNull(where, "where is null"); - requireNonNull(groupBy, "groupBy is null"); - requireNonNull(having, "having is null"); - requireNonNull(windows, "windows is null"); - requireNonNull(orderBy, "orderBy is null"); - requireNonNull(offset, "offset is null"); - requireNonNull(limit, "limit is null"); - checkArgument( - !limit.isPresent() - || limit.get() instanceof FetchFirst - || limit.get() instanceof Limit, - "limit must be optional of either FetchFirst or Limit type"); - - this.select = select; - this.from = from; - this.where = where; - this.groupBy = groupBy; - this.having = having; - this.windows = windows; - this.orderBy = orderBy; - this.offset = offset; - this.limit = limit; - } - - public Select getSelect() - { - return select; - } - - public Optional getFrom() - { - return from; - } - - public Optional getWhere() - { - return where; - } - - public Optional getGroupBy() - { - return groupBy; - } - - public Optional getHaving() - { - return having; - } - - public List getWindows() - { - return windows; - } - - public Optional getOrderBy() - { - return orderBy; - } - - public Optional getOffset() - { - return offset; - } - - public Optional getLimit() - { - return limit; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitQuerySpecification(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.add(select); - from.ifPresent(nodes::add); - where.ifPresent(nodes::add); - groupBy.ifPresent(nodes::add); - having.ifPresent(nodes::add); - nodes.addAll(windows); - orderBy.ifPresent(nodes::add); - offset.ifPresent(nodes::add); - limit.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("select", select) - .add("from", from) - .add("where", where.orElse(null)) - .add("groupBy", groupBy) - .add("having", having.orElse(null)) - .add("windows", windows.isEmpty() ? null : windows) - .add("orderBy", orderBy) - .add("offset", offset.orElse(null)) - .add("limit", limit.orElse(null)) - .toString(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - QuerySpecification o = (QuerySpecification) obj; - return Objects.equals(select, o.select) && - Objects.equals(from, o.from) && - Objects.equals(where, o.where) && - Objects.equals(groupBy, o.groupBy) && - Objects.equals(having, o.having) && - Objects.equals(windows, o.windows) && - Objects.equals(orderBy, o.orderBy) && - Objects.equals(offset, o.offset) && - Objects.equals(limit, o.limit); - } - - @Override - public int hashCode() - { - return Objects.hash(select, from, where, groupBy, having, windows, orderBy, offset, limit); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RangeQuantifier.java b/trino-parser/src/main/java/io/trino/sql/tree/RangeQuantifier.java deleted file mode 100644 index 402acf513..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RangeQuantifier.java +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class RangeQuantifier - extends PatternQuantifier -{ - private final Optional atLeast; - private final Optional atMost; - - public RangeQuantifier(boolean greedy, Optional atLeast, Optional atMost) - { - this(Optional.empty(), greedy, atLeast, atMost); - } - - public RangeQuantifier(NodeLocation location, boolean greedy, Optional atLeast, Optional atMost) - { - this(Optional.of(location), greedy, atLeast, atMost); - } - - private RangeQuantifier(Optional location, boolean greedy, Optional atLeast, Optional atMost) - { - super(location, greedy); - this.atLeast = requireNonNull(atLeast, "atLeast is null"); - this.atMost = requireNonNull(atMost, "atMost is null"); - } - - public Optional getAtLeast() - { - return atLeast; - } - - public Optional getAtMost() - { - return atMost; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRangeQuantifier(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder children = ImmutableList.builder(); - atLeast.ifPresent(children::add); - atMost.ifPresent(children::add); - return children.build(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - RangeQuantifier o = (RangeQuantifier) obj; - return isGreedy() == o.isGreedy() && - Objects.equals(atLeast, o.atLeast) && - Objects.equals(atMost, o.atMost); - } - - @Override - public int hashCode() - { - return Objects.hash(isGreedy(), atLeast, atMost); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("atLeast", atLeast) - .add("atMost", atMost) - .add("greedy", isGreedy()) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RefreshMaterializedView.java b/trino-parser/src/main/java/io/trino/sql/tree/RefreshMaterializedView.java deleted file mode 100644 index eccc11e2d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RefreshMaterializedView.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class RefreshMaterializedView - extends Statement -{ - private final Table table; - - public RefreshMaterializedView(Optional location, Table table) - { - super(location); - this.table = requireNonNull(table, "name is null"); - } - - public Table getTable() - { - return table; - } - - public QualifiedName getName() - { - return table.getName(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRefreshMaterializedView(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(table); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - RefreshMaterializedView o = (RefreshMaterializedView) obj; - return Objects.equals(table, o.table); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Relation.java b/trino-parser/src/main/java/io/trino/sql/tree/Relation.java deleted file mode 100644 index 91c2bf8fa..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Relation.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class Relation - extends Node -{ - protected Relation(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRelation(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RenameColumn.java b/trino-parser/src/main/java/io/trino/sql/tree/RenameColumn.java deleted file mode 100644 index 02f2baf3d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RenameColumn.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class RenameColumn - extends Statement -{ - private final QualifiedName table; - private final Identifier source; - private final Identifier target; - private final boolean tableExists; - private final boolean columnExists; - - public RenameColumn(QualifiedName table, Identifier source, Identifier target, boolean tableExists, boolean columnExists) - { - this(Optional.empty(), table, source, target, tableExists, columnExists); - } - - public RenameColumn(NodeLocation location, QualifiedName table, Identifier source, Identifier target, boolean tableExists, boolean columnExists) - { - this(Optional.of(location), table, source, target, tableExists, columnExists); - } - - private RenameColumn(Optional location, QualifiedName table, Identifier source, Identifier target, boolean tableExists, boolean columnExists) - { - super(location); - this.table = requireNonNull(table, "table is null"); - this.source = requireNonNull(source, "source is null"); - this.target = requireNonNull(target, "target is null"); - this.tableExists = tableExists; - this.columnExists = columnExists; - } - - public QualifiedName getTable() - { - return table; - } - - public Identifier getSource() - { - return source; - } - - public Identifier getTarget() - { - return target; - } - - public boolean isTableExists() - { - return tableExists; - } - - public boolean isColumnExists() - { - return columnExists; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRenameColumn(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RenameColumn that = (RenameColumn) o; - return Objects.equals(table, that.table) && - Objects.equals(source, that.source) && - Objects.equals(target, that.target); - } - - @Override - public int hashCode() - { - return Objects.hash(table, source, target); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .add("source", source) - .add("target", target) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RenameMaterializedView.java b/trino-parser/src/main/java/io/trino/sql/tree/RenameMaterializedView.java deleted file mode 100644 index ef9c05992..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RenameMaterializedView.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class RenameMaterializedView - extends Statement -{ - private final QualifiedName source; - private final QualifiedName target; - private final boolean exists; - - public RenameMaterializedView(QualifiedName source, QualifiedName target, boolean exists) - { - this(Optional.empty(), source, target, exists); - } - - public RenameMaterializedView(NodeLocation location, QualifiedName source, QualifiedName target, boolean exists) - { - this(Optional.of(location), source, target, exists); - } - - private RenameMaterializedView(Optional location, QualifiedName source, QualifiedName target, boolean exists) - { - super(location); - this.source = requireNonNull(source, "source name is null"); - this.target = requireNonNull(target, "target name is null"); - this.exists = exists; - } - - public QualifiedName getSource() - { - return source; - } - - public QualifiedName getTarget() - { - return target; - } - - public boolean isExists() - { - return exists; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRenameMaterializedView(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(source, target, exists); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - RenameMaterializedView o = (RenameMaterializedView) obj; - return Objects.equals(source, o.source) && - Objects.equals(target, o.target) && - Objects.equals(exists, o.exists); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("source", source) - .add("target", target) - .add("exists", exists) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RenameSchema.java b/trino-parser/src/main/java/io/trino/sql/tree/RenameSchema.java deleted file mode 100644 index 3b0d79ea7..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RenameSchema.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class RenameSchema - extends Statement -{ - private final QualifiedName source; - private final Identifier target; - - public RenameSchema(QualifiedName source, Identifier target) - { - this(Optional.empty(), source, target); - } - - public RenameSchema(NodeLocation location, QualifiedName source, Identifier target) - { - this(Optional.of(location), source, target); - } - - private RenameSchema(Optional location, QualifiedName source, Identifier target) - { - super(location); - this.source = requireNonNull(source, "source is null"); - this.target = requireNonNull(target, "target is null"); - } - - public QualifiedName getSource() - { - return source; - } - - public Identifier getTarget() - { - return target; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRenameSchema(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(source, target); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - RenameSchema o = (RenameSchema) obj; - return Objects.equals(source, o.source) && - Objects.equals(target, o.target); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("source", source) - .add("target", target) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RenameTable.java b/trino-parser/src/main/java/io/trino/sql/tree/RenameTable.java deleted file mode 100644 index 005424530..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RenameTable.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class RenameTable - extends Statement -{ - private final QualifiedName source; - private final QualifiedName target; - private final boolean exists; - - public RenameTable(QualifiedName source, QualifiedName target, boolean exists) - { - this(Optional.empty(), source, target, exists); - } - - public RenameTable(NodeLocation location, QualifiedName source, QualifiedName target, boolean exists) - { - this(Optional.of(location), source, target, exists); - } - - private RenameTable(Optional location, QualifiedName source, QualifiedName target, boolean exists) - { - super(location); - this.source = requireNonNull(source, "source name is null"); - this.target = requireNonNull(target, "target name is null"); - this.exists = exists; - } - - public QualifiedName getSource() - { - return source; - } - - public QualifiedName getTarget() - { - return target; - } - - public boolean isExists() - { - return exists; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRenameTable(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(source, target); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - RenameTable o = (RenameTable) obj; - return Objects.equals(source, o.source) && - Objects.equals(target, o.target); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("source", source) - .add("target", target) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RenameView.java b/trino-parser/src/main/java/io/trino/sql/tree/RenameView.java deleted file mode 100644 index 3e8e81af8..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RenameView.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class RenameView - extends Statement -{ - private final QualifiedName source; - private final QualifiedName target; - - public RenameView(QualifiedName source, QualifiedName target) - { - this(Optional.empty(), source, target); - } - - public RenameView(NodeLocation location, QualifiedName source, QualifiedName target) - { - this(Optional.of(location), source, target); - } - - private RenameView(Optional location, QualifiedName source, QualifiedName target) - { - super(location); - this.source = requireNonNull(source, "source name is null"); - this.target = requireNonNull(target, "target name is null"); - } - - public QualifiedName getSource() - { - return source; - } - - public QualifiedName getTarget() - { - return target; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRenameView(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(source, target); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - RenameView o = (RenameView) obj; - return Objects.equals(source, o.source) && - Objects.equals(target, o.target); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("source", source) - .add("target", target) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ResetSession.java b/trino-parser/src/main/java/io/trino/sql/tree/ResetSession.java deleted file mode 100644 index 6da3ec797..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ResetSession.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class ResetSession - extends Statement -{ - private final QualifiedName name; - - public ResetSession(QualifiedName name) - { - this(Optional.empty(), name); - } - - public ResetSession(NodeLocation location, QualifiedName name) - { - this(Optional.of(location), name); - } - - private ResetSession(Optional location, QualifiedName name) - { - super(location); - this.name = name; - } - - public QualifiedName getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitResetSession(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ResetSession o = (ResetSession) obj; - return Objects.equals(name, o.name); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Revoke.java b/trino-parser/src/main/java/io/trino/sql/tree/Revoke.java deleted file mode 100644 index f66652424..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Revoke.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Revoke - extends Statement -{ - private final boolean grantOptionFor; - private final Optional> privileges; // missing means ALL PRIVILEGES - private final Optional type; - private final QualifiedName name; - private final PrincipalSpecification grantee; - - public Revoke(boolean grantOptionFor, Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee) - { - this(Optional.empty(), grantOptionFor, privileges, type, name, grantee); - } - - public Revoke(NodeLocation location, boolean grantOptionFor, Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee) - { - this(Optional.of(location), grantOptionFor, privileges, type, name, grantee); - } - - private Revoke(Optional location, boolean grantOptionFor, Optional> privileges, Optional type, QualifiedName name, PrincipalSpecification grantee) - { - super(location); - this.grantOptionFor = grantOptionFor; - requireNonNull(privileges, "privileges is null"); - this.privileges = privileges.map(ImmutableList::copyOf); - this.type = requireNonNull(type, "type is null"); - this.name = requireNonNull(name, "name is null"); - this.grantee = requireNonNull(grantee, "grantee is null"); - } - - public boolean isGrantOptionFor() - { - return grantOptionFor; - } - - public Optional> getPrivileges() - { - return privileges; - } - - public Optional getType() - { - return type; - } - - public QualifiedName getName() - { - return name; - } - - public PrincipalSpecification getGrantee() - { - return grantee; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRevoke(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(grantOptionFor, privileges, type, name, grantee); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Revoke o = (Revoke) obj; - return Objects.equals(grantOptionFor, o.grantOptionFor) && - Objects.equals(privileges, o.privileges) && - Objects.equals(type, o.type) && - Objects.equals(name, o.name) && - Objects.equals(grantee, o.grantee); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("grantOptionFor", grantOptionFor) - .add("privileges", privileges) - .add("type", type) - .add("name", name) - .add("grantee", grantee) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RevokeRoles.java b/trino-parser/src/main/java/io/trino/sql/tree/RevokeRoles.java deleted file mode 100644 index 321b35c45..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RevokeRoles.java +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class RevokeRoles - extends Statement -{ - private final Set roles; - private final Set grantees; - private final boolean adminOption; - private final Optional grantor; - private final Optional catalog; - - public RevokeRoles( - NodeLocation location, - Set roles, - Set grantees, - boolean adminOption, - Optional grantor, - Optional catalog) - { - this(Optional.of(location), roles, grantees, adminOption, grantor, catalog); - } - - public RevokeRoles( - Set roles, - Set grantees, - boolean adminOption, - Optional grantor, - Optional catalog) - { - this(Optional.empty(), roles, grantees, adminOption, grantor, catalog); - } - - private RevokeRoles( - Optional location, - Set roles, - Set grantees, - boolean adminOption, - Optional grantor, - Optional catalog) - { - super(location); - this.roles = ImmutableSet.copyOf(requireNonNull(roles, "roles is null")); - this.grantees = ImmutableSet.copyOf(requireNonNull(grantees, "grantees is null")); - this.adminOption = adminOption; - this.grantor = requireNonNull(grantor, "grantor is null"); - this.catalog = requireNonNull(catalog, "catalog is null"); - } - - public Set getRoles() - { - return roles; - } - - public Set getGrantees() - { - return grantees; - } - - public boolean isAdminOption() - { - return adminOption; - } - - public Optional getGrantor() - { - return grantor; - } - - public Optional getCatalog() - { - return catalog; - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRevokeRoles(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RevokeRoles that = (RevokeRoles) o; - return adminOption == that.adminOption && - Objects.equals(roles, that.roles) && - Objects.equals(grantees, that.grantees) && - Objects.equals(grantor, that.grantor) && - Objects.equals(catalog, that.catalog); - } - - @Override - public int hashCode() - { - return Objects.hash(roles, grantees, adminOption, grantor, catalog); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("roles", roles) - .add("grantees", grantees) - .add("adminOption", adminOption) - .add("grantor", grantor) - .add("catalog", catalog) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Rollback.java b/trino-parser/src/main/java/io/trino/sql/tree/Rollback.java deleted file mode 100644 index 071e5a957..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Rollback.java +++ /dev/null @@ -1,75 +0,0 @@ - -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Optional; - -public final class Rollback - extends Statement -{ - public Rollback() - { - this(Optional.empty()); - } - - public Rollback(NodeLocation location) - { - this(Optional.of(location)); - } - - private Rollback(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRollback(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return getClass().hashCode(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - return true; - } - - @Override - public String toString() - { - return "ROLLBACK"; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Rollup.java b/trino-parser/src/main/java/io/trino/sql/tree/Rollup.java deleted file mode 100644 index aa079d17c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Rollup.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Rollup - extends GroupingElement -{ - private final List columns; - - public Rollup(List columns) - { - this(Optional.empty(), columns); - } - - public Rollup(NodeLocation location, List columns) - { - this(Optional.of(location), columns); - } - - private Rollup(Optional location, List columns) - { - super(location); - this.columns = ImmutableList.copyOf(requireNonNull(columns, "columns is null")); - } - - @Override - public List getExpressions() - { - return columns; - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitRollup(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Rollup rollup = (Rollup) o; - return Objects.equals(columns, rollup.columns); - } - - @Override - public int hashCode() - { - return Objects.hash(columns); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("columns", columns) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Row.java b/trino-parser/src/main/java/io/trino/sql/tree/Row.java deleted file mode 100644 index b55d0b575..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Row.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public final class Row - extends Expression -{ - private final List items; - - public Row(List items) - { - this(Optional.empty(), items); - } - - public Row(NodeLocation location, List items) - { - this(Optional.of(location), items); - } - - private Row(Optional location, List items) - { - super(location); - requireNonNull(items, "items is null"); - this.items = ImmutableList.copyOf(items); - } - - public List getItems() - { - return items; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRow(this, context); - } - - @Override - public List getChildren() - { - return items; - } - - @Override - public int hashCode() - { - return Objects.hash(items); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Row other = (Row) obj; - return Objects.equals(this.items, other.items); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RowDataType.java b/trino-parser/src/main/java/io/trino/sql/tree/RowDataType.java deleted file mode 100644 index f78d9a12c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RowDataType.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class RowDataType - extends DataType -{ - private final List fields; - - public RowDataType(NodeLocation location, List fields) - { - super(Optional.of(location)); - this.fields = ImmutableList.copyOf(fields); - } - - public RowDataType(Optional location, List fields) - { - super(location); - this.fields = ImmutableList.copyOf(fields); - } - - public List getFields() - { - return fields; - } - - @Override - public List getChildren() - { - return fields; - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitRowDataType(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RowDataType that = (RowDataType) o; - return fields.equals(that.fields); - } - - @Override - public int hashCode() - { - return Objects.hash(fields); - } - - public static class Field - extends Node - { - private final Optional name; - private final DataType type; - - public Field(NodeLocation location, Optional name, DataType type) - { - super(Optional.of(location)); - - this.name = requireNonNull(name, "name is null"); - this.type = requireNonNull(type, "type is null"); - } - - public Field(Optional location, Optional name, DataType type) - { - super(location); - - this.name = requireNonNull(name, "name is null"); - this.type = requireNonNull(type, "type is null"); - } - - public Optional getName() - { - return name; - } - - public DataType getType() - { - return type; - } - - @Override - public List getChildren() - { - ImmutableList.Builder children = ImmutableList.builder(); - name.ifPresent(children::add); - children.add(type); - - return children.build(); - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitRowField(this, context); - } - - @Override - public String toString() - { - StringBuilder builder = new StringBuilder(); - if (name.isPresent()) { - builder.append(name.get()); - builder.append(" "); - } - builder.append(type); - - return builder.toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Field field = (Field) o; - return name.equals(field.name) && - type.equals(field.type); - } - - @Override - public int hashCode() - { - return Objects.hash(name, type); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/RowPattern.java b/trino-parser/src/main/java/io/trino/sql/tree/RowPattern.java deleted file mode 100644 index dc7833d1b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/RowPattern.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class RowPattern - extends Node -{ - protected RowPattern(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitRowPattern(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SampledRelation.java b/trino-parser/src/main/java/io/trino/sql/tree/SampledRelation.java deleted file mode 100644 index e52948027..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SampledRelation.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class SampledRelation - extends Relation -{ - public enum Type - { - BERNOULLI, - SYSTEM - } - - private final Relation relation; - private final Type type; - private final Expression samplePercentage; - - public SampledRelation(Relation relation, Type type, Expression samplePercentage) - { - this(Optional.empty(), relation, type, samplePercentage); - } - - public SampledRelation(NodeLocation location, Relation relation, Type type, Expression samplePercentage) - { - this(Optional.of(location), relation, type, samplePercentage); - } - - private SampledRelation(Optional location, Relation relation, Type type, Expression samplePercentage) - { - super(location); - this.relation = requireNonNull(relation, "relation is null"); - this.type = requireNonNull(type, "type is null"); - this.samplePercentage = requireNonNull(samplePercentage, "samplePercentage is null"); - } - - public Relation getRelation() - { - return relation; - } - - public Type getType() - { - return type; - } - - public Expression getSamplePercentage() - { - return samplePercentage; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSampledRelation(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(relation, samplePercentage); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("relation", relation) - .add("type", type) - .add("samplePercentage", samplePercentage) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SampledRelation that = (SampledRelation) o; - return Objects.equals(relation, that.relation) && - type == that.type && - Objects.equals(samplePercentage, that.samplePercentage); - } - - @Override - public int hashCode() - { - return Objects.hash(relation, type, samplePercentage); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - SampledRelation otherRelation = (SampledRelation) other; - return type == otherRelation.type && Objects.equals(samplePercentage, otherRelation.samplePercentage); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SearchedCaseExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/SearchedCaseExpression.java deleted file mode 100644 index 5147869a4..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SearchedCaseExpression.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class SearchedCaseExpression - extends Expression -{ - private final List whenClauses; - private final Optional defaultValue; - - public SearchedCaseExpression(List whenClauses, Optional defaultValue) - { - this(Optional.empty(), whenClauses, defaultValue); - } - - public SearchedCaseExpression(NodeLocation location, List whenClauses, Optional defaultValue) - { - this(Optional.of(location), whenClauses, defaultValue); - } - - private SearchedCaseExpression(Optional location, List whenClauses, Optional defaultValue) - { - super(location); - requireNonNull(whenClauses, "whenClauses is null"); - requireNonNull(defaultValue, "defaultValue is null"); - this.whenClauses = ImmutableList.copyOf(whenClauses); - this.defaultValue = defaultValue; - } - - public List getWhenClauses() - { - return whenClauses; - } - - public Optional getDefaultValue() - { - return defaultValue; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSearchedCaseExpression(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.addAll(whenClauses); - defaultValue.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SearchedCaseExpression that = (SearchedCaseExpression) o; - return Objects.equals(whenClauses, that.whenClauses) && - Objects.equals(defaultValue, that.defaultValue); - } - - @Override - public int hashCode() - { - return Objects.hash(whenClauses, defaultValue); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Select.java b/trino-parser/src/main/java/io/trino/sql/tree/Select.java deleted file mode 100644 index be69e8476..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Select.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Select - extends Node -{ - private final boolean distinct; - private final List selectItems; - - public Select(boolean distinct, List selectItems) - { - this(Optional.empty(), distinct, selectItems); - } - - public Select(NodeLocation location, boolean distinct, List selectItems) - { - this(Optional.of(location), distinct, selectItems); - } - - private Select(Optional location, boolean distinct, List selectItems) - { - super(location); - this.distinct = distinct; - this.selectItems = ImmutableList.copyOf(requireNonNull(selectItems, "selectItems")); - } - - public boolean isDistinct() - { - return distinct; - } - - public List getSelectItems() - { - return selectItems; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSelect(this, context); - } - - @Override - public List getChildren() - { - return selectItems; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("distinct", distinct) - .add("selectItems", selectItems) - .omitNullValues() - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Select select = (Select) o; - return (distinct == select.distinct) && - Objects.equals(selectItems, select.selectItems); - } - - @Override - public int hashCode() - { - return Objects.hash(distinct, selectItems); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return distinct == ((Select) other).distinct; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SelectItem.java b/trino-parser/src/main/java/io/trino/sql/tree/SelectItem.java deleted file mode 100644 index eb803ecc5..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SelectItem.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class SelectItem - extends Node -{ - protected SelectItem(Optional location) - { - super(location); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetAuthorizationStatement.java b/trino-parser/src/main/java/io/trino/sql/tree/SetAuthorizationStatement.java deleted file mode 100644 index 075474b8b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetAuthorizationStatement.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public abstract class SetAuthorizationStatement - extends Statement -{ - private final QualifiedName source; - private final PrincipalSpecification principal; - - public SetAuthorizationStatement(QualifiedName source, PrincipalSpecification principal) - { - super(Optional.empty()); - this.source = requireNonNull(source, "source is null"); - this.principal = requireNonNull(principal, "principal is null"); - } - - public SetAuthorizationStatement(NodeLocation location, QualifiedName source, PrincipalSpecification principal) - { - super(Optional.of(location)); - this.source = requireNonNull(source, "source is null"); - this.principal = requireNonNull(principal, "principal is null"); - } - - public QualifiedName getSource() - { - return source; - } - - public PrincipalSpecification getPrincipal() - { - return principal; - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(source, principal); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - SetAuthorizationStatement o = (SetAuthorizationStatement) obj; - return Objects.equals(source, o.source) && - Objects.equals(principal, o.principal); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("source", source) - .add("principal", principal) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetOperation.java b/trino-parser/src/main/java/io/trino/sql/tree/SetOperation.java deleted file mode 100644 index ccf2382dc..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetOperation.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.List; -import java.util.Optional; - -public abstract class SetOperation - extends QueryBody -{ - private final boolean distinct; - - protected SetOperation(Optional location, boolean distinct) - { - super(location); - this.distinct = distinct; - } - - public boolean isDistinct() - { - return distinct; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetOperation(this, context); - } - - public abstract List getRelations(); -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetPath.java b/trino-parser/src/main/java/io/trino/sql/tree/SetPath.java deleted file mode 100644 index ebbb55d81..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetPath.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class SetPath - extends Statement -{ - private final PathSpecification pathSpecification; - - public SetPath(PathSpecification pathSpecification) - { - this(Optional.empty(), pathSpecification); - } - - public SetPath(NodeLocation location, PathSpecification pathSpecification) - { - this(Optional.of(location), pathSpecification); - } - - private SetPath(Optional location, PathSpecification pathSpecification) - { - super(location); - this.pathSpecification = requireNonNull(pathSpecification, "pathSpecification is null"); - } - - public PathSpecification getPathSpecification() - { - return pathSpecification; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetPath(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(pathSpecification); - } - - @Override - public int hashCode() - { - return Objects.hash(pathSpecification); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - SetPath o = (SetPath) obj; - return Objects.equals(pathSpecification, o.pathSpecification); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("pathSpecification", pathSpecification) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetProperties.java b/trino-parser/src/main/java/io/trino/sql/tree/SetProperties.java deleted file mode 100644 index f5f1578f6..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetProperties.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class SetProperties - extends Statement -{ - public enum Type - { - TABLE, MATERIALIZED_VIEW - } - - private final Type type; - private final QualifiedName name; - private final List properties; - - public SetProperties(Type type, QualifiedName name, List properties) - { - this(Optional.empty(), type, name, properties); - } - - public SetProperties(NodeLocation location, Type type, QualifiedName name, List properties) - { - this(Optional.of(location), type, name, properties); - } - - private SetProperties(Optional location, Type type, QualifiedName name, List properties) - { - super(location); - this.type = requireNonNull(type, "type is null"); - this.name = requireNonNull(name, "name is null"); - this.properties = ImmutableList.copyOf(requireNonNull(properties, "properties is null")); - } - - public Type getType() - { - return type; - } - - public QualifiedName getName() - { - return name; - } - - public List getProperties() - { - return properties; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetProperties(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(type, name, properties); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - SetProperties o = (SetProperties) obj; - return type == o.type && - Objects.equals(name, o.name) && - Objects.equals(properties, o.properties); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("name", name) - .add("properties", properties) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetRole.java b/trino-parser/src/main/java/io/trino/sql/tree/SetRole.java deleted file mode 100644 index e295b634f..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetRole.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class SetRole - extends Statement -{ - public enum Type - { - ROLE, ALL, NONE - } - - private final Type type; - private final Optional role; - private final Optional catalog; - - public SetRole(Type type, Optional role, Optional catalog) - { - this(Optional.empty(), type, role, catalog); - } - - public SetRole(NodeLocation location, Type type, Optional role, Optional catalog) - { - this(Optional.of(location), type, role, catalog); - } - - private SetRole(Optional location, Type type, Optional role, Optional catalog) - { - super(location); - this.type = requireNonNull(type, "type is null"); - this.role = requireNonNull(role, "role is null"); - this.catalog = requireNonNull(catalog, "catalog is null"); - } - - public Type getType() - { - return type; - } - - public Optional getRole() - { - return role; - } - - public Optional getCatalog() - { - return catalog; - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetRole(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SetRole setRole = (SetRole) o; - return type == setRole.type && - Objects.equals(role, setRole.role) && - Objects.equals(catalog, setRole.catalog); - } - - @Override - public int hashCode() - { - return Objects.hash(type, role, catalog); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("role", role) - .add("catalog", catalog) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetSchemaAuthorization.java b/trino-parser/src/main/java/io/trino/sql/tree/SetSchemaAuthorization.java deleted file mode 100644 index cdd04d460..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetSchemaAuthorization.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -public final class SetSchemaAuthorization - extends SetAuthorizationStatement -{ - public SetSchemaAuthorization(QualifiedName source, PrincipalSpecification principal) - { - super(source, principal); - } - - public SetSchemaAuthorization(NodeLocation location, QualifiedName source, PrincipalSpecification principal) - { - super(location, source, principal); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetSchemaAuthorization(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetSession.java b/trino-parser/src/main/java/io/trino/sql/tree/SetSession.java deleted file mode 100644 index 526aeb088..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetSession.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class SetSession - extends Statement -{ - private final QualifiedName name; - private final Expression value; - - public SetSession(QualifiedName name, Expression value) - { - this(Optional.empty(), name, value); - } - - public SetSession(NodeLocation location, QualifiedName name, Expression value) - { - this(Optional.of(location), name, value); - } - - private SetSession(Optional location, QualifiedName name, Expression value) - { - super(location); - this.name = name; - this.value = value; - } - - public QualifiedName getName() - { - return name; - } - - public Expression getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetSession(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(value); - } - - @Override - public int hashCode() - { - return Objects.hash(name, value); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - SetSession o = (SetSession) obj; - return Objects.equals(name, o.name) - && Objects.equals(value, o.value); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("value", value) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetTableAuthorization.java b/trino-parser/src/main/java/io/trino/sql/tree/SetTableAuthorization.java deleted file mode 100644 index 3b1253f45..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetTableAuthorization.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -public final class SetTableAuthorization - extends SetAuthorizationStatement -{ - public SetTableAuthorization(QualifiedName source, PrincipalSpecification principal) - { - super(source, principal); - } - - public SetTableAuthorization(NodeLocation location, QualifiedName source, PrincipalSpecification principal) - { - super(location, source, principal); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetTableAuthorization(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetTimeZone.java b/trino-parser/src/main/java/io/trino/sql/tree/SetTimeZone.java deleted file mode 100644 index 881ce9e3f..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetTimeZone.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class SetTimeZone - extends Statement -{ - private final Optional timeZone; - - public SetTimeZone(NodeLocation location, Optional timeZone) - { - super(Optional.of(location)); - requireNonNull(timeZone, "timeZone is null"); - this.timeZone = timeZone; - } - - public Optional getTimeZone() - { - return timeZone; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetTimeZone(this, context); - } - - @Override - public List getChildren() - { - return timeZone.isPresent() ? ImmutableList.of(timeZone.get()) : ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SetTimeZone that = (SetTimeZone) o; - return Objects.equals(timeZone, that.timeZone); - } - - @Override - public int hashCode() - { - return Objects.hash(timeZone); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("timeZone", timeZone.isPresent() ? timeZone : "LOCAL") - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SetViewAuthorization.java b/trino-parser/src/main/java/io/trino/sql/tree/SetViewAuthorization.java deleted file mode 100644 index f9986fd6c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SetViewAuthorization.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -public final class SetViewAuthorization - extends SetAuthorizationStatement -{ - public SetViewAuthorization(QualifiedName source, PrincipalSpecification principal) - { - super(source, principal); - } - - public SetViewAuthorization(NodeLocation location, QualifiedName source, PrincipalSpecification principal) - { - super(location, source, principal); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSetViewAuthorization(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowCatalogs.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowCatalogs.java deleted file mode 100644 index 13f4ea647..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowCatalogs.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class ShowCatalogs - extends Statement -{ - private final Optional likePattern; - private final Optional escape; - - public ShowCatalogs(Optional likePattern, Optional escape) - { - this(Optional.empty(), likePattern, escape); - } - - public ShowCatalogs(NodeLocation location, Optional likePattern, Optional escape) - { - this(Optional.of(location), likePattern, escape); - } - - public ShowCatalogs(Optional location, Optional likePattern, Optional escape) - { - super(location); - this.likePattern = requireNonNull(likePattern, "likePattern is null"); - this.escape = requireNonNull(escape, "escape is null"); - } - - public Optional getLikePattern() - { - return likePattern; - } - - public Optional getEscape() - { - return escape; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowCatalogs(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(likePattern, escape); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowCatalogs o = (ShowCatalogs) obj; - return Objects.equals(likePattern, o.likePattern) && - Objects.equals(escape, o.escape); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("likePattern", likePattern) - .add("escape", escape) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowColumns.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowColumns.java deleted file mode 100644 index fff4ce28b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowColumns.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowColumns - extends Statement -{ - private final QualifiedName table; - private final Optional likePattern; - private final Optional escape; - - public ShowColumns(QualifiedName table, Optional likePattern, Optional escape) - { - this(Optional.empty(), table, likePattern, escape); - } - - public ShowColumns(NodeLocation location, QualifiedName table, Optional likePattern, Optional escape) - { - this(Optional.of(location), table, likePattern, escape); - } - - private ShowColumns(Optional location, QualifiedName table, Optional likePattern, Optional escape) - { - super(location); - this.table = requireNonNull(table, "table is null"); - this.likePattern = requireNonNull(likePattern, "likePattern is null"); - this.escape = requireNonNull(escape, "escape is null"); - } - - public QualifiedName getTable() - { - return table; - } - - public Optional getLikePattern() - { - return likePattern; - } - - public Optional getEscape() - { - return escape; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowColumns(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(table, likePattern, escape); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowColumns o = (ShowColumns) obj; - return Objects.equals(table, o.table) && - Objects.equals(likePattern, o.likePattern) && - Objects.equals(escape, o.escape); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .add("likePattern", likePattern) - .add("escape", escape) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowCreate.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowCreate.java deleted file mode 100644 index 1ef133cac..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowCreate.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowCreate - extends Statement -{ - public enum Type - { - TABLE, - VIEW, - SCHEMA, - MATERIALIZED_VIEW, - /**/; - } - - private final Type type; - private final QualifiedName name; - - public ShowCreate(Type type, QualifiedName name) - { - this(Optional.empty(), type, name); - } - - public ShowCreate(NodeLocation location, Type type, QualifiedName name) - { - this(Optional.of(location), type, name); - } - - private ShowCreate(Optional location, Type type, QualifiedName name) - { - super(location); - this.type = requireNonNull(type, "type is null"); - this.name = requireNonNull(name, "name is null"); - } - - public QualifiedName getName() - { - return name; - } - - public Type getType() - { - return type; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowCreate(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(type, name); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowCreate o = (ShowCreate) obj; - return Objects.equals(name, o.name) && type == o.type; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("name", name) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowFunctions.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowFunctions.java deleted file mode 100644 index 0bab2d011..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowFunctions.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowFunctions - extends Statement -{ - private final Optional likePattern; - private final Optional escape; - - public ShowFunctions(Optional likePattern, Optional escape) - { - this(Optional.empty(), likePattern, escape); - } - - public ShowFunctions(NodeLocation location, Optional likePattern, Optional escape) - { - this(Optional.of(location), likePattern, escape); - } - - private ShowFunctions(Optional location, Optional likePattern, Optional escape) - { - super(location); - this.likePattern = requireNonNull(likePattern, "likePattern is null"); - this.escape = requireNonNull(escape, "escape is null"); - } - - public Optional getLikePattern() - { - return likePattern; - } - - public Optional getEscape() - { - return escape; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowFunctions(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(likePattern, escape); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowFunctions o = (ShowFunctions) obj; - return Objects.equals(likePattern, o.likePattern) && - Objects.equals(escape, o.escape); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("likePattern", likePattern) - .add("escape", escape) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowGrants.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowGrants.java deleted file mode 100644 index 8b32b7824..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowGrants.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowGrants - extends Statement -{ - private final boolean table; - private final Optional tableName; - - public ShowGrants(boolean table, Optional tableName) - { - this(Optional.empty(), table, tableName); - } - - public ShowGrants(NodeLocation location, boolean table, Optional tableName) - { - this(Optional.of(location), table, tableName); - } - - public ShowGrants(Optional location, boolean table, Optional tableName) - { - super(location); - requireNonNull(tableName, "tableName is null"); - - this.table = table; - this.tableName = tableName; - } - - public boolean getTable() - { - return table; - } - - public Optional getTableName() - { - return tableName; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowGrants(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(table, tableName); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowGrants o = (ShowGrants) obj; - return Objects.equals(table, o.table) && - Objects.equals(tableName, o.tableName); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .add("tableName", tableName) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowRoleGrants.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowRoleGrants.java deleted file mode 100644 index a90107a42..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowRoleGrants.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowRoleGrants - extends Statement -{ - private final Optional catalog; - - public ShowRoleGrants(Optional catalog) - { - this(Optional.empty(), catalog); - } - - public ShowRoleGrants(NodeLocation location, Optional catalog) - { - this(Optional.of(location), catalog); - } - - public ShowRoleGrants(Optional location, Optional catalog) - { - super(location); - this.catalog = requireNonNull(catalog, "catalog is null"); - } - - public Optional getCatalog() - { - return catalog; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowRoleGrants(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(catalog); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowRoleGrants o = (ShowRoleGrants) obj; - return Objects.equals(catalog, o.catalog); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("catalog", catalog) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowRoles.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowRoles.java deleted file mode 100644 index 768a3d369..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowRoles.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowRoles - extends Statement -{ - private final Optional catalog; - private final boolean current; - - public ShowRoles(Optional catalog, boolean current) - { - this(Optional.empty(), catalog, current); - } - - public ShowRoles(NodeLocation location, Optional catalog, boolean current) - { - this(Optional.of(location), catalog, current); - } - - public ShowRoles(Optional location, Optional catalog, boolean current) - { - super(location); - this.catalog = requireNonNull(catalog, "catalog is null"); - this.current = current; - } - - public Optional getCatalog() - { - return catalog; - } - - public boolean isCurrent() - { - return current; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowRoles(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(catalog, current); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowRoles o = (ShowRoles) obj; - return Objects.equals(catalog, o.catalog) && - current == o.current; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("catalog", catalog) - .add("current", current) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowSchemas.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowSchemas.java deleted file mode 100644 index 1be931b76..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowSchemas.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowSchemas - extends Statement -{ - private final Optional catalog; - private final Optional likePattern; - private final Optional escape; - - public ShowSchemas(Optional catalog, Optional likePattern, Optional escape) - { - this(Optional.empty(), catalog, likePattern, escape); - } - - public ShowSchemas(NodeLocation location, Optional catalog, Optional likePattern, Optional escape) - { - this(Optional.of(location), catalog, likePattern, escape); - } - - private ShowSchemas(Optional location, Optional catalog, Optional likePattern, Optional escape) - { - super(location); - this.catalog = requireNonNull(catalog, "catalog is null"); - this.likePattern = requireNonNull(likePattern, "likePattern is null"); - this.escape = requireNonNull(escape, "escape is null"); - } - - public Optional getCatalog() - { - return catalog; - } - - public Optional getLikePattern() - { - return likePattern; - } - - public Optional getEscape() - { - return escape; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowSchemas(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(catalog, likePattern, escape); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowSchemas o = (ShowSchemas) obj; - return Objects.equals(catalog, o.catalog) && - Objects.equals(likePattern, o.likePattern) && - Objects.equals(escape, o.escape); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("catalog", catalog) - .add("likePattern", likePattern) - .add("escape", escape) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowSession.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowSession.java deleted file mode 100644 index 373054f5d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowSession.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowSession - extends Statement -{ - private final Optional likePattern; - private final Optional escape; - - public ShowSession(Optional likePattern, Optional escape) - { - this(Optional.empty(), likePattern, escape); - } - - public ShowSession(NodeLocation location, Optional likePattern, Optional escape) - { - this(Optional.of(location), likePattern, escape); - } - - private ShowSession(Optional location, Optional likePattern, Optional escape) - { - super(location); - this.likePattern = requireNonNull(likePattern, "likePattern is null"); - this.escape = requireNonNull(escape, "escape is null"); - } - - public Optional getLikePattern() - { - return likePattern; - } - - public Optional getEscape() - { - return escape; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowSession(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(likePattern, escape); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowSession o = (ShowSession) obj; - return Objects.equals(likePattern, o.likePattern) && - Objects.equals(escape, o.escape); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("likePattern", likePattern) - .add("escape", escape) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowStats.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowStats.java deleted file mode 100644 index dcf7bacd7..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowStats.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class ShowStats - extends Statement -{ - private final Relation relation; - - @VisibleForTesting - public ShowStats(Relation relation) - { - this(Optional.empty(), relation); - } - - public ShowStats(Optional location, Relation relation) - { - super(location); - this.relation = relation; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowStats(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(relation); - } - - @Override - public int hashCode() - { - return Objects.hash(relation); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowStats o = (ShowStats) obj; - return Objects.equals(relation, o.relation); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("query", relation) - .toString(); - } - - public Relation getRelation() - { - return relation; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ShowTables.java b/trino-parser/src/main/java/io/trino/sql/tree/ShowTables.java deleted file mode 100644 index faa2bf65b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ShowTables.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ShowTables - extends Statement -{ - private final Optional schema; - private final Optional likePattern; - private final Optional escape; - - public ShowTables(Optional schema, Optional likePattern, Optional escape) - { - this(Optional.empty(), schema, likePattern, escape); - } - - public ShowTables(NodeLocation location, Optional schema, Optional likePattern, Optional escape) - { - this(Optional.of(location), schema, likePattern, escape); - } - - private ShowTables(Optional location, Optional schema, Optional likePattern, Optional escape) - { - super(location); - requireNonNull(schema, "schema is null"); - requireNonNull(likePattern, "likePattern is null"); - requireNonNull(escape, "escape is null"); - - this.schema = schema; - this.likePattern = likePattern; - this.escape = escape; - } - - public Optional getSchema() - { - return schema; - } - - public Optional getLikePattern() - { - return likePattern; - } - - public Optional getEscape() - { - return escape; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitShowTables(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(schema, likePattern, escape); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - ShowTables o = (ShowTables) obj; - return Objects.equals(schema, o.schema) && - Objects.equals(likePattern, o.likePattern) && - Objects.equals(escape, o.escape); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("schema", schema) - .add("likePattern", likePattern) - .add("escape", escape) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SimpleCaseExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/SimpleCaseExpression.java deleted file mode 100644 index d2b633269..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SimpleCaseExpression.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class SimpleCaseExpression - extends Expression -{ - private final Expression operand; - private final List whenClauses; - private final Optional defaultValue; - - public SimpleCaseExpression(Expression operand, List whenClauses, Optional defaultValue) - { - this(Optional.empty(), operand, whenClauses, defaultValue); - } - - public SimpleCaseExpression(NodeLocation location, Expression operand, List whenClauses, Optional defaultValue) - { - this(Optional.of(location), operand, whenClauses, defaultValue); - } - - private SimpleCaseExpression(Optional location, Expression operand, List whenClauses, Optional defaultValue) - { - super(location); - requireNonNull(operand, "operand is null"); - requireNonNull(whenClauses, "whenClauses is null"); - - this.operand = operand; - this.whenClauses = ImmutableList.copyOf(whenClauses); - this.defaultValue = defaultValue; - } - - public Expression getOperand() - { - return operand; - } - - public List getWhenClauses() - { - return whenClauses; - } - - public Optional getDefaultValue() - { - return defaultValue; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSimpleCaseExpression(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.add(operand); - nodes.addAll(whenClauses); - defaultValue.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SimpleCaseExpression that = (SimpleCaseExpression) o; - return Objects.equals(operand, that.operand) && - Objects.equals(whenClauses, that.whenClauses) && - Objects.equals(defaultValue, that.defaultValue); - } - - @Override - public int hashCode() - { - return Objects.hash(operand, whenClauses, defaultValue); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SimpleGroupBy.java b/trino-parser/src/main/java/io/trino/sql/tree/SimpleGroupBy.java deleted file mode 100644 index 027d42a62..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SimpleGroupBy.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class SimpleGroupBy - extends GroupingElement -{ - private final List columns; - - public SimpleGroupBy(List simpleGroupByExpressions) - { - this(Optional.empty(), simpleGroupByExpressions); - } - - public SimpleGroupBy(NodeLocation location, List simpleGroupByExpressions) - { - this(Optional.of(location), simpleGroupByExpressions); - } - - private SimpleGroupBy(Optional location, List simpleGroupByExpressions) - { - super(location); - this.columns = ImmutableList.copyOf(requireNonNull(simpleGroupByExpressions, "simpleGroupByExpressions is null")); - } - - @Override - public List getExpressions() - { - return columns; - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitSimpleGroupBy(this, context); - } - - @Override - public List getChildren() - { - return columns; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SimpleGroupBy that = (SimpleGroupBy) o; - return Objects.equals(columns, that.columns); - } - - @Override - public int hashCode() - { - return Objects.hash(columns); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("columns", columns) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SingleColumn.java b/trino-parser/src/main/java/io/trino/sql/tree/SingleColumn.java deleted file mode 100644 index e167aed8d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SingleColumn.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class SingleColumn - extends SelectItem -{ - private final Optional alias; - private final Expression expression; - - public SingleColumn(Expression expression) - { - this(Optional.empty(), expression, Optional.empty()); - } - - public SingleColumn(Expression expression, Optional alias) - { - this(Optional.empty(), expression, alias); - } - - public SingleColumn(Expression expression, Identifier alias) - { - this(Optional.empty(), expression, Optional.of(alias)); - } - - public SingleColumn(NodeLocation location, Expression expression, Optional alias) - { - this(Optional.of(location), expression, alias); - } - - private SingleColumn(Optional location, Expression expression, Optional alias) - { - super(location); - requireNonNull(expression, "expression is null"); - requireNonNull(alias, "alias is null"); - - this.expression = expression; - this.alias = alias; - } - - public Optional getAlias() - { - return alias; - } - - public Expression getExpression() - { - return expression; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - SingleColumn other = (SingleColumn) obj; - return Objects.equals(this.alias, other.alias) && Objects.equals(this.expression, other.expression); - } - - @Override - public int hashCode() - { - return Objects.hash(alias, expression); - } - - @Override - public String toString() - { - if (alias.isPresent()) { - return expression.toString() + " " + alias.get(); - } - - return expression.toString(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSingleColumn(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(expression); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return alias.equals(((SingleColumn) other).alias); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SkipTo.java b/trino-parser/src/main/java/io/trino/sql/tree/SkipTo.java deleted file mode 100644 index 4b4e8c2bd..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SkipTo.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static io.trino.sql.tree.SkipTo.Position.FIRST; -import static io.trino.sql.tree.SkipTo.Position.LAST; -import static io.trino.sql.tree.SkipTo.Position.NEXT; -import static io.trino.sql.tree.SkipTo.Position.PAST_LAST; -import static java.util.Objects.requireNonNull; - -public class SkipTo - extends Node -{ - private final Position position; - private final Optional identifier; - - public enum Position - { - PAST_LAST, - NEXT, - FIRST, - LAST - } - - // default - public static SkipTo skipPastLastRow() - { - return skipPastLastRow(Optional.empty()); - } - - public static SkipTo skipPastLastRow(NodeLocation location) - { - return skipPastLastRow(Optional.of(location)); - } - - private static SkipTo skipPastLastRow(Optional location) - { - return new SkipTo(location, PAST_LAST, Optional.empty()); - } - - public static SkipTo skipToNextRow() - { - return skipToNextRow(Optional.empty()); - } - - public static SkipTo skipToNextRow(NodeLocation location) - { - return skipToNextRow(Optional.of(location)); - } - - private static SkipTo skipToNextRow(Optional location) - { - return new SkipTo(location, NEXT, Optional.empty()); - } - - public static SkipTo skipToFirst(Identifier identifier) - { - return skipToFirst(Optional.empty(), identifier); - } - - public static SkipTo skipToFirst(NodeLocation location, Identifier identifier) - { - return skipToFirst(Optional.of(location), identifier); - } - - private static SkipTo skipToFirst(Optional location, Identifier identifier) - { - return new SkipTo(location, FIRST, Optional.of(identifier)); - } - - public static SkipTo skipToLast(Identifier identifier) - { - return skipToLast(Optional.empty(), identifier); - } - - public static SkipTo skipToLast(NodeLocation location, Identifier identifier) - { - return skipToLast(Optional.of(location), identifier); - } - - private static SkipTo skipToLast(Optional location, Identifier identifier) - { - return new SkipTo(location, LAST, Optional.of(identifier)); - } - - private SkipTo(Optional location, Position position, Optional identifier) - { - super(location); - requireNonNull(position, "position is null"); - requireNonNull(identifier, "identifier is null"); - checkArgument(identifier.isPresent() || (position == PAST_LAST || position == NEXT), "missing identifier in SKIP TO " + position.name()); - checkArgument(!identifier.isPresent() || (position == FIRST || position == LAST), "unexpected identifier in SKIP TO " + position.name()); - this.position = position; - this.identifier = identifier; - } - - public Position getPosition() - { - return position; - } - - public Optional getIdentifier() - { - return identifier; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSkipTo(this, context); - } - - @Override - public List getChildren() - { - return identifier.map(ImmutableList::of).orElse(ImmutableList.of()); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("position", position) - .add("identifier", identifier.orElse(null)) - .omitNullValues() - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SkipTo that = (SkipTo) o; - return Objects.equals(position, that.position) && - Objects.equals(identifier, that.identifier); - } - - @Override - public int hashCode() - { - return Objects.hash(position, identifier); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return position == ((SkipTo) other).position; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SortItem.java b/trino-parser/src/main/java/io/trino/sql/tree/SortItem.java deleted file mode 100644 index fe7f2174a..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SortItem.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class SortItem - extends Node -{ - public enum Ordering - { - ASCENDING, DESCENDING - } - - public enum NullOrdering - { - FIRST, LAST, UNDEFINED - } - - private final Expression sortKey; - private final Ordering ordering; - private final NullOrdering nullOrdering; - - public SortItem(Expression sortKey, Ordering ordering, NullOrdering nullOrdering) - { - this(Optional.empty(), sortKey, ordering, nullOrdering); - } - - public SortItem(NodeLocation location, Expression sortKey, Ordering ordering, NullOrdering nullOrdering) - { - this(Optional.of(location), sortKey, ordering, nullOrdering); - } - - private SortItem(Optional location, Expression sortKey, Ordering ordering, NullOrdering nullOrdering) - { - super(location); - this.ordering = ordering; - this.sortKey = sortKey; - this.nullOrdering = nullOrdering; - } - - public Expression getSortKey() - { - return sortKey; - } - - public Ordering getOrdering() - { - return ordering; - } - - public NullOrdering getNullOrdering() - { - return nullOrdering; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSortItem(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(sortKey); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("sortKey", sortKey) - .add("ordering", ordering) - .add("nullOrdering", nullOrdering) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SortItem sortItem = (SortItem) o; - return Objects.equals(sortKey, sortItem.sortKey) && - (ordering == sortItem.ordering) && - (nullOrdering == sortItem.nullOrdering); - } - - @Override - public int hashCode() - { - return Objects.hash(sortKey, ordering, nullOrdering); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - SortItem otherItem = (SortItem) other; - return ordering == otherItem.ordering && nullOrdering == otherItem.nullOrdering; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/StackableAstVisitor.java b/trino-parser/src/main/java/io/trino/sql/tree/StackableAstVisitor.java deleted file mode 100644 index fc93f299c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/StackableAstVisitor.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.LinkedList; -import java.util.Optional; - -public class StackableAstVisitor - extends AstVisitor> -{ - @Override - public R process(Node node, StackableAstVisitorContext context) - { - context.push(node); - try { - return node.accept(this, context); - } - finally { - context.pop(); - } - } - - public static class StackableAstVisitorContext - { - private final LinkedList stack = new LinkedList<>(); - private final C context; - - public StackableAstVisitorContext(C context) - { - this.context = context; - } - - public C getContext() - { - return context; - } - - private void pop() - { - stack.pop(); - } - - void push(Node node) - { - stack.push(node); - } - - public Optional getPreviousNode() - { - if (stack.size() > 1) { - return Optional.of(stack.get(1)); - } - return Optional.empty(); - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/StartTransaction.java b/trino-parser/src/main/java/io/trino/sql/tree/StartTransaction.java deleted file mode 100644 index a6ab06685..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/StartTransaction.java +++ /dev/null @@ -1,90 +0,0 @@ - -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class StartTransaction - extends Statement -{ - private final List transactionModes; - - public StartTransaction(List transactionModes) - { - this(Optional.empty(), transactionModes); - } - - public StartTransaction(NodeLocation location, List transactionModes) - { - this(Optional.of(location), transactionModes); - } - - private StartTransaction(Optional location, List transactionModes) - { - super(location); - this.transactionModes = ImmutableList.copyOf(requireNonNull(transactionModes, "transactionModes is null")); - } - - public List getTransactionModes() - { - return transactionModes; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitStartTransaction(this, context); - } - - @Override - public List getChildren() - { - return transactionModes; - } - - @Override - public int hashCode() - { - return Objects.hash(transactionModes); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - StartTransaction other = (StartTransaction) obj; - return Objects.equals(this.transactionModes, other.transactionModes); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("transactionModes", transactionModes) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Statement.java b/trino-parser/src/main/java/io/trino/sql/tree/Statement.java deleted file mode 100644 index 1d085c7e9..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Statement.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class Statement - extends Node -{ - protected Statement(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitStatement(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/StringLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/StringLiteral.java deleted file mode 100644 index 89405b387..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/StringLiteral.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import io.airlift.slice.Slice; - -import java.util.Objects; -import java.util.Optional; - -import static io.airlift.slice.Slices.utf8Slice; -import static java.util.Objects.requireNonNull; - -public class StringLiteral - extends Literal -{ - private final String value; - private final Slice slice; - - public StringLiteral(String value) - { - this(Optional.empty(), value); - } - - public StringLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - private StringLiteral(Optional location, String value) - { - super(location); - requireNonNull(value, "value is null"); - this.value = value; - this.slice = utf8Slice(value); - } - - public String getValue() - { - return value; - } - - public Slice getSlice() - { - return slice; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitStringLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - StringLiteral that = (StringLiteral) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return value.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return Objects.equals(value, ((StringLiteral) other).value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SubqueryExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/SubqueryExpression.java deleted file mode 100644 index c2962a006..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SubqueryExpression.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -public class SubqueryExpression - extends Expression -{ - private final Query query; - - public SubqueryExpression(Query query) - { - this(Optional.empty(), query); - } - - public SubqueryExpression(NodeLocation location, Query query) - { - this(Optional.of(location), query); - } - - private SubqueryExpression(Optional location, Query query) - { - super(location); - this.query = query; - } - - public Query getQuery() - { - return query; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSubqueryExpression(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(query); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SubqueryExpression that = (SubqueryExpression) o; - return Objects.equals(query, that.query); - } - - @Override - public int hashCode() - { - return query.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SubscriptExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/SubscriptExpression.java deleted file mode 100644 index 350efe6f9..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SubscriptExpression.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class SubscriptExpression - extends Expression -{ - private final Expression base; - private final Expression index; - - public SubscriptExpression(Expression base, Expression index) - { - this(Optional.empty(), base, index); - } - - public SubscriptExpression(NodeLocation location, Expression base, Expression index) - { - this(Optional.of(location), base, index); - } - - public SubscriptExpression(Optional location, Expression base, Expression index) - { - super(location); - this.base = requireNonNull(base, "base is null"); - this.index = requireNonNull(index, "index is null"); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSubscriptExpression(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(base, index); - } - - public Expression getBase() - { - return base; - } - - public Expression getIndex() - { - return index; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SubscriptExpression that = (SubscriptExpression) o; - - return Objects.equals(this.base, that.base) && Objects.equals(this.index, that.index); - } - - @Override - public int hashCode() - { - return Objects.hash(base, index); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SubsetDefinition.java b/trino-parser/src/main/java/io/trino/sql/tree/SubsetDefinition.java deleted file mode 100644 index bd2474124..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SubsetDefinition.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class SubsetDefinition - extends Node -{ - private final Identifier name; - private final List identifiers; - - public SubsetDefinition(Identifier name, List identifiers) - { - this(Optional.empty(), name, identifiers); - } - - public SubsetDefinition(NodeLocation location, Identifier name, List identifiers) - { - this(Optional.of(location), name, identifiers); - } - - private SubsetDefinition(Optional location, Identifier name, List identifiers) - { - super(location); - this.name = requireNonNull(name, "name is null"); - requireNonNull(identifiers, "identifiers is null"); - checkArgument(!identifiers.isEmpty(), "identifiers is empty"); - this.identifiers = identifiers; - } - - public Identifier getName() - { - return name; - } - - public List getIdentifiers() - { - return identifiers; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSubsetDefinition(this, context); - } - - @Override - public List getChildren() - { - return identifiers; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("identifiers", identifiers) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - SubsetDefinition that = (SubsetDefinition) o; - return Objects.equals(name, that.name) && - Objects.equals(identifiers, that.identifiers); - } - - @Override - public int hashCode() - { - return Objects.hash(name, identifiers); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return Objects.equals(name, ((SubsetDefinition) other).name); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/SymbolReference.java b/trino-parser/src/main/java/io/trino/sql/tree/SymbolReference.java deleted file mode 100644 index ab585d3dc..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/SymbolReference.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -public class SymbolReference - extends Expression -{ - private final String name; - - public SymbolReference(String name) - { - super(Optional.empty()); - this.name = name; - } - - public String getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitSymbolReference(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - SymbolReference that = (SymbolReference) o; - return Objects.equals(name, that.name); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Table.java b/trino-parser/src/main/java/io/trino/sql/tree/Table.java deleted file mode 100644 index e2047714f..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Table.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class Table - extends QueryBody -{ - private final QualifiedName name; - private final Optional queryPeriod; - - public Table(QualifiedName name) - { - this(Optional.empty(), name, Optional.empty()); - } - - public Table(NodeLocation location, QualifiedName name) - { - this(Optional.of(location), name, Optional.empty()); - } - - public Table(NodeLocation location, QualifiedName name, QueryPeriod queryPeriod) - { - this(Optional.of(location), name, Optional.of(queryPeriod)); - } - - // For CannerflowSqlRewrite - public Table(Optional location, QualifiedName name, QueryPeriod queryPeriod) - { - this(location, name, Optional.ofNullable(queryPeriod)); - } - - private Table(Optional location, QualifiedName name, Optional queryPeriod) - { - super(location); - this.name = name; - this.queryPeriod = queryPeriod; - } - - public QualifiedName getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTable(this, context); - } - - @Override - public List getChildren() - { - if (queryPeriod.isPresent()) { - return ImmutableList.of(queryPeriod.get()); - } - return ImmutableList.of(); - } - - @Override - public String toString() - { - return toStringHelper(this) - .addValue(name) - .addValue(queryPeriod) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Table table = (Table) o; - return Objects.equals(name, table.name) && - Objects.equals(queryPeriod, table.getQueryPeriod()); - } - - @Override - public int hashCode() - { - return Objects.hash(name, queryPeriod); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - Table otherTable = (Table) other; - return name.equals(otherTable.name); - } - - public Optional getQueryPeriod() - { - return queryPeriod; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TableElement.java b/trino-parser/src/main/java/io/trino/sql/tree/TableElement.java deleted file mode 100644 index 48c7320aa..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TableElement.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class TableElement - extends Node -{ - public TableElement(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTableElement(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TableExecute.java b/trino-parser/src/main/java/io/trino/sql/tree/TableExecute.java deleted file mode 100644 index 4fa64f96d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TableExecute.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class TableExecute - extends Statement -{ - private final Table table; - private final Identifier procedureName; - private final List arguments; - private final Optional where; - - public TableExecute( - Table table, - Identifier procedureName, - List properties, - Optional where) - { - this(Optional.empty(), table, procedureName, properties, where); - } - - public TableExecute( - NodeLocation location, - Table table, - Identifier procedureName, - List arguments, - Optional where) - { - this(Optional.of(location), table, procedureName, arguments, where); - } - - private TableExecute( - Optional location, - Table table, - Identifier procedureName, - List arguments, - Optional where) - { - super(location); - this.table = requireNonNull(table, "table is null"); - this.procedureName = requireNonNull(procedureName, "procedureName is null"); - this.arguments = requireNonNull(arguments, "arguments is null"); - this.where = requireNonNull(where, "where is null"); - } - - public Table getTable() - { - return table; - } - - public Identifier getProcedureName() - { - return procedureName; - } - - public List getArguments() - { - return arguments; - } - - public Optional getWhere() - { - return where; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTableExecute(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.addAll(arguments); - where.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public int hashCode() - { - return Objects.hash(table, procedureName, arguments, where); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TableExecute that = (TableExecute) o; - return Objects.equals(table, that.table) && - Objects.equals(procedureName, that.procedureName) && - Objects.equals(arguments, that.arguments) && - Objects.equals(where, that.where); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .add("procedureNaem", procedureName) - .add("arguments", arguments) - .add("where", where) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TableSubquery.java b/trino-parser/src/main/java/io/trino/sql/tree/TableSubquery.java deleted file mode 100644 index 3deeb2ac8..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TableSubquery.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class TableSubquery - extends QueryBody -{ - private final Query query; - - public TableSubquery(Query query) - { - this(Optional.empty(), query); - } - - public TableSubquery(NodeLocation location, Query query) - { - this(Optional.of(location), query); - } - - private TableSubquery(Optional location, Query query) - { - super(location); - this.query = query; - } - - public Query getQuery() - { - return query; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTableSubquery(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(query); - } - - @Override - public String toString() - { - return toStringHelper(this) - .addValue(query) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - TableSubquery tableSubquery = (TableSubquery) o; - return Objects.equals(query, tableSubquery.query); - } - - @Override - public int hashCode() - { - return query.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TimeLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/TimeLiteral.java deleted file mode 100644 index 01f83186c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TimeLiteral.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class TimeLiteral - extends Literal -{ - private final String value; - - public TimeLiteral(String value) - { - this(Optional.empty(), value); - } - - public TimeLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - private TimeLiteral(Optional location, String value) - { - super(location); - requireNonNull(value, "value is null"); - this.value = value; - } - - public String getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTimeLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - TimeLiteral that = (TimeLiteral) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return value.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - TimeLiteral otherLiteral = (TimeLiteral) other; - return Objects.equals(this.value, otherLiteral.value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TimestampLiteral.java b/trino-parser/src/main/java/io/trino/sql/tree/TimestampLiteral.java deleted file mode 100644 index b4c44f869..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TimestampLiteral.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class TimestampLiteral - extends Literal -{ - private final String value; - - public TimestampLiteral(String value) - { - this(Optional.empty(), value); - } - - public TimestampLiteral(NodeLocation location, String value) - { - this(Optional.of(location), value); - } - - private TimestampLiteral(Optional location, String value) - { - super(location); - requireNonNull(value, "value is null"); - - this.value = value; - } - - public String getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTimestampLiteral(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - TimestampLiteral that = (TimestampLiteral) o; - return Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return value.hashCode(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - TimestampLiteral otherLiteral = (TimestampLiteral) other; - return value.equals(otherLiteral.value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TransactionAccessMode.java b/trino-parser/src/main/java/io/trino/sql/tree/TransactionAccessMode.java deleted file mode 100644 index 86fbb1da7..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TransactionAccessMode.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public final class TransactionAccessMode - extends TransactionMode -{ - private final boolean readOnly; - - public TransactionAccessMode(boolean readOnly) - { - this(Optional.empty(), readOnly); - } - - public TransactionAccessMode(NodeLocation location, boolean readOnly) - { - this(Optional.of(location), readOnly); - } - - private TransactionAccessMode(Optional location, boolean readOnly) - { - super(location); - this.readOnly = readOnly; - } - - public boolean isReadOnly() - { - return readOnly; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTransactionAccessMode(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(readOnly); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - TransactionAccessMode other = (TransactionAccessMode) obj; - return this.readOnly == other.readOnly; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("readOnly", readOnly) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TransactionMode.java b/trino-parser/src/main/java/io/trino/sql/tree/TransactionMode.java deleted file mode 100644 index 87c8145d0..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TransactionMode.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public abstract class TransactionMode - extends Node -{ - public TransactionMode(Optional location) - { - super(location); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTransactionMode(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TruncateTable.java b/trino-parser/src/main/java/io/trino/sql/tree/TruncateTable.java deleted file mode 100644 index 56c3886ad..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TruncateTable.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class TruncateTable - extends Statement -{ - private final QualifiedName tableName; - - public TruncateTable(QualifiedName tableName) - { - this(Optional.empty(), tableName); - } - - public TruncateTable(NodeLocation location, QualifiedName tableName) - { - this(Optional.of(location), tableName); - } - - private TruncateTable(Optional location, QualifiedName tableName) - { - super(location); - this.tableName = tableName; - } - - public QualifiedName getTableName() - { - return tableName; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTruncateTable(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(tableName); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - TruncateTable o = (TruncateTable) obj; - return Objects.equals(tableName, o.tableName); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("tableName", tableName) - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TryExpression.java b/trino-parser/src/main/java/io/trino/sql/tree/TryExpression.java deleted file mode 100644 index dbe44784b..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TryExpression.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class TryExpression - extends Expression -{ - private final Expression innerExpression; - - public TryExpression(Expression innerExpression) - { - this(Optional.empty(), innerExpression); - } - - public TryExpression(NodeLocation location, Expression innerExpression) - { - this(Optional.of(location), innerExpression); - } - - private TryExpression(Optional location, Expression innerExpression) - { - super(location); - this.innerExpression = requireNonNull(innerExpression, "innerExpression is null"); - } - - public Expression getInnerExpression() - { - return innerExpression; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitTryExpression(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(innerExpression); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - TryExpression o = (TryExpression) obj; - return Objects.equals(innerExpression, o.innerExpression); - } - - @Override - public int hashCode() - { - return Objects.hash(innerExpression); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/TypeParameter.java b/trino-parser/src/main/java/io/trino/sql/tree/TypeParameter.java deleted file mode 100644 index a72a3f782..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/TypeParameter.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class TypeParameter - extends DataTypeParameter -{ - private final DataType type; - - public TypeParameter(DataType type) - { - super(Optional.empty()); - this.type = requireNonNull(type, "type is null"); - } - - public DataType getValue() - { - return type; - } - - @Override - public String toString() - { - return type.toString(); - } - - @Override - public List getChildren() - { - return ImmutableList.of(type); - } - - @Override - protected R accept(AstVisitor visitor, C context) - { - return visitor.visitTypeParameter(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TypeParameter that = (TypeParameter) o; - return type.equals(that.type); - } - - @Override - public int hashCode() - { - return Objects.hash(type); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Union.java b/trino-parser/src/main/java/io/trino/sql/tree/Union.java deleted file mode 100644 index 3925c507c..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Union.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Union - extends SetOperation -{ - private final List relations; - - public Union(List relations, boolean distinct) - { - this(Optional.empty(), relations, distinct); - } - - public Union(NodeLocation location, List relations, boolean distinct) - { - this(Optional.of(location), relations, distinct); - } - - private Union(Optional location, List relations, boolean distinct) - { - super(location, distinct); - requireNonNull(relations, "relations is null"); - - this.relations = ImmutableList.copyOf(relations); - } - - @Override - public List getRelations() - { - return relations; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitUnion(this, context); - } - - @Override - public List getChildren() - { - return relations; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("relations", relations) - .add("distinct", isDistinct()) - .toString(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - Union o = (Union) obj; - return Objects.equals(relations, o.relations) && - Objects.equals(isDistinct(), o.isDistinct()); - } - - @Override - public int hashCode() - { - return Objects.hash(relations, isDistinct()); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return this.isDistinct() == ((Union) other).isDistinct(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Unnest.java b/trino-parser/src/main/java/io/trino/sql/tree/Unnest.java deleted file mode 100644 index 713d2d9d4..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Unnest.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Unnest - extends Relation -{ - private final List expressions; - private final boolean withOrdinality; - - public Unnest(List expressions, boolean withOrdinality) - { - this(Optional.empty(), expressions, withOrdinality); - } - - public Unnest(NodeLocation location, List expressions, boolean withOrdinality) - { - this(Optional.of(location), expressions, withOrdinality); - } - - private Unnest(Optional location, List expressions, boolean withOrdinality) - { - super(location); - requireNonNull(expressions, "expressions is null"); - this.expressions = ImmutableList.copyOf(expressions); - this.withOrdinality = withOrdinality; - } - - public List getExpressions() - { - return expressions; - } - - public boolean isWithOrdinality() - { - return withOrdinality; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitUnnest(this, context); - } - - @Override - public List getChildren() - { - return expressions; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("expressions", expressions) - .add("withOrdinality", withOrdinality) - .toString(); - } - - @Override - public int hashCode() - { - return Objects.hash(expressions, withOrdinality); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Unnest other = (Unnest) obj; - return Objects.equals(expressions, other.expressions) && withOrdinality == other.withOrdinality; - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - Unnest otherNode = (Unnest) other; - return withOrdinality == otherNode.withOrdinality; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Update.java b/trino-parser/src/main/java/io/trino/sql/tree/Update.java deleted file mode 100644 index 6a717427a..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Update.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class Update - extends Statement -{ - private final Table table; - private final List assignments; - private final Optional where; - - public Update(Table table, List assignments, Optional where) - { - this(Optional.empty(), table, assignments, where); - } - - public Update(NodeLocation location, Table table, List assignments, Optional where) - { - this(Optional.of(location), table, assignments, where); - } - - private Update(Optional location, Table table, List assignments, Optional where) - { - super(location); - this.table = requireNonNull(table, "table is null"); - this.assignments = requireNonNull(assignments, "assignments is null"); - this.where = requireNonNull(where, "where is null"); - } - - public Table getTable() - { - return table; - } - - public List getAssignments() - { - return assignments; - } - - public Optional getWhere() - { - return where; - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.addAll(assignments); - where.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitUpdate(this, context); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Update update = (Update) o; - return table.equals(update.table) && - assignments.equals(update.assignments) && - where.equals(update.where); - } - - @Override - public int hashCode() - { - return Objects.hash(table, assignments, where); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("table", table) - .add("assignments", assignments) - .add("where", where.orElse(null)) - .omitNullValues() - .toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/UpdateAssignment.java b/trino-parser/src/main/java/io/trino/sql/tree/UpdateAssignment.java deleted file mode 100644 index 49c102615..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/UpdateAssignment.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; - -public class UpdateAssignment - extends Node -{ - private final Identifier name; - private final Expression value; - - public UpdateAssignment(Identifier name, Expression value) - { - this(Optional.empty(), name, value); - } - - public UpdateAssignment(NodeLocation location, Identifier name, Expression value) - { - this(Optional.of(location), name, value); - } - - private UpdateAssignment(Optional location, Identifier name, Expression value) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.value = requireNonNull(value, "value is null"); - } - - public Identifier getName() - { - return name; - } - - public Expression getValue() - { - return value; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitUpdateAssignment(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(name, value); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - UpdateAssignment other = (UpdateAssignment) obj; - return Objects.equals(name, other.name) && - Objects.equals(value, other.value); - } - - @Override - public int hashCode() - { - return Objects.hash(name, value); - } - - @Override - public String toString() - { - return format("%s = %s", name, value); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Use.java b/trino-parser/src/main/java/io/trino/sql/tree/Use.java deleted file mode 100644 index efad1b64d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Use.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public final class Use - extends Statement -{ - private final Optional catalog; - private final Identifier schema; - - public Use(Optional catalog, Identifier schema) - { - this(Optional.empty(), catalog, schema); - } - - public Use(NodeLocation location, Optional catalog, Identifier schema) - { - this(Optional.of(location), catalog, schema); - } - - private Use(Optional location, Optional catalog, Identifier schema) - { - super(location); - requireNonNull(catalog, "catalog is null"); - requireNonNull(schema, "schema is null"); - this.catalog = catalog; - this.schema = schema; - } - - public Optional getCatalog() - { - return catalog; - } - - public Identifier getSchema() - { - return schema; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitUse(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(); - } - - @Override - public int hashCode() - { - return Objects.hash(catalog, schema); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Use use = (Use) o; - - if (!catalog.equals(use.catalog)) { - return false; - } - if (!schema.equals(use.schema)) { - return false; - } - - return true; - } - - @Override - public String toString() - { - return toStringHelper(this).toString(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Values.java b/trino-parser/src/main/java/io/trino/sql/tree/Values.java deleted file mode 100644 index 460159b5e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Values.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public final class Values - extends QueryBody -{ - private final List rows; - - public Values(List rows) - { - this(Optional.empty(), rows); - } - - public Values(NodeLocation location, List rows) - { - this(Optional.of(location), rows); - } - - private Values(Optional location, List rows) - { - super(location); - requireNonNull(rows, "rows is null"); - this.rows = ImmutableList.copyOf(rows); - } - - public List getRows() - { - return rows; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitValues(this, context); - } - - @Override - public List getChildren() - { - return rows; - } - - @Override - public String toString() - { - return "(" + Joiner.on(", ").join(rows) + ")"; - } - - @Override - public int hashCode() - { - return Objects.hash(rows); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Values other = (Values) obj; - return Objects.equals(this.rows, other.rows); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/VariableDefinition.java b/trino-parser/src/main/java/io/trino/sql/tree/VariableDefinition.java deleted file mode 100644 index 9c79ce1cd..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/VariableDefinition.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class VariableDefinition - extends Node -{ - private final Identifier name; - private final Expression expression; - - public VariableDefinition(Identifier name, Expression expression) - { - this(Optional.empty(), name, expression); - } - - public VariableDefinition(NodeLocation location, Identifier name, Expression expression) - { - this(Optional.of(location), name, expression); - } - - private VariableDefinition(Optional location, Identifier name, Expression expression) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.expression = requireNonNull(expression, "expression is null"); - } - - public Identifier getName() - { - return name; - } - - public Expression getExpression() - { - return expression; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitVariableDefinition(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(expression); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("expression", expression) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - VariableDefinition that = (VariableDefinition) o; - return Objects.equals(name, that.name) && - Objects.equals(expression, that.expression); - } - - @Override - public int hashCode() - { - return Objects.hash(name, expression); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return Objects.equals(name, ((VariableDefinition) other).name); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/WhenClause.java b/trino-parser/src/main/java/io/trino/sql/tree/WhenClause.java deleted file mode 100644 index 535ecf3cc..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/WhenClause.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -public class WhenClause - extends Expression -{ - private final Expression operand; - private final Expression result; - - public WhenClause(Expression operand, Expression result) - { - this(Optional.empty(), operand, result); - } - - public WhenClause(NodeLocation location, Expression operand, Expression result) - { - this(Optional.of(location), operand, result); - } - - private WhenClause(Optional location, Expression operand, Expression result) - { - super(location); - this.operand = operand; - this.result = result; - } - - public Expression getOperand() - { - return operand; - } - - public Expression getResult() - { - return result; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitWhenClause(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(operand, result); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - WhenClause that = (WhenClause) o; - return Objects.equals(operand, that.operand) && - Objects.equals(result, that.result); - } - - @Override - public int hashCode() - { - return Objects.hash(operand, result); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/Window.java b/trino-parser/src/main/java/io/trino/sql/tree/Window.java deleted file mode 100644 index 46c7ccc85..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/Window.java +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -public interface Window -{ -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/WindowDefinition.java b/trino-parser/src/main/java/io/trino/sql/tree/WindowDefinition.java deleted file mode 100644 index 0821d9dc5..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/WindowDefinition.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class WindowDefinition - extends Node -{ - private final Identifier name; - private final WindowSpecification window; - - public WindowDefinition(Identifier name, WindowSpecification window) - { - this(Optional.empty(), name, window); - } - - public WindowDefinition(NodeLocation location, Identifier name, WindowSpecification window) - { - this(Optional.of(location), name, window); - } - - private WindowDefinition(Optional location, Identifier name, WindowSpecification window) - { - super(location); - this.name = requireNonNull(name, "name is null"); - this.window = requireNonNull(window, "window is null"); - } - - public Identifier getName() - { - return name; - } - - public WindowSpecification getWindow() - { - return window; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitWindowDefinition(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(window); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - WindowDefinition o = (WindowDefinition) obj; - return Objects.equals(name, o.name) && Objects.equals(window, o.window); - } - - @Override - public int hashCode() - { - return Objects.hash(name, window); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("window", window) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - return name.equals(((WindowDefinition) other).name); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/WindowFrame.java b/trino-parser/src/main/java/io/trino/sql/tree/WindowFrame.java deleted file mode 100644 index 8cea1ac23..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/WindowFrame.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class WindowFrame - extends Node -{ - public enum Type - { - RANGE, ROWS, GROUPS - } - - private final Type type; - private final FrameBound start; - private final Optional end; - private final List measures; - private final Optional afterMatchSkipTo; - private final Optional patternSearchMode; - private final Optional pattern; - private final List subsets; - private final List variableDefinitions; - - public WindowFrame( - Type type, - FrameBound start, - Optional end, - List measures, - Optional afterMatchSkipTo, - Optional patternSearchMode, - Optional pattern, - List subsets, - List variableDefinitions) - { - this(Optional.empty(), type, start, end, measures, afterMatchSkipTo, patternSearchMode, pattern, subsets, variableDefinitions); - } - - public WindowFrame( - NodeLocation location, - Type type, - FrameBound start, - Optional end, - List measures, - Optional afterMatchSkipTo, - Optional patternSearchMode, - Optional pattern, - List subsets, - List variableDefinitions) - { - this(Optional.of(location), type, start, end, measures, afterMatchSkipTo, patternSearchMode, pattern, subsets, variableDefinitions); - } - - private WindowFrame( - Optional location, - Type type, - FrameBound start, - Optional end, - List measures, - Optional afterMatchSkipTo, - Optional patternSearchMode, - Optional pattern, - List subsets, - List variableDefinitions) - { - super(location); - this.type = requireNonNull(type, "type is null"); - this.start = requireNonNull(start, "start is null"); - this.end = requireNonNull(end, "end is null"); - this.measures = requireNonNull(measures, "measures is null"); - this.afterMatchSkipTo = requireNonNull(afterMatchSkipTo, "afterMatchSkipTo is null"); - this.patternSearchMode = requireNonNull(patternSearchMode, "patternSearchMode is null"); - this.pattern = requireNonNull(pattern, "pattern is null"); - this.subsets = requireNonNull(subsets, "subsets is null"); - this.variableDefinitions = requireNonNull(variableDefinitions, "variableDefinitions is null"); - } - - public Type getType() - { - return type; - } - - public FrameBound getStart() - { - return start; - } - - public Optional getEnd() - { - return end; - } - - public List getMeasures() - { - return measures; - } - - public Optional getAfterMatchSkipTo() - { - return afterMatchSkipTo; - } - - public Optional getPatternSearchMode() - { - return patternSearchMode; - } - - public Optional getPattern() - { - return pattern; - } - - public List getSubsets() - { - return subsets; - } - - public List getVariableDefinitions() - { - return variableDefinitions; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitWindowFrame(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - nodes.add(start); - end.ifPresent(nodes::add); - nodes.addAll(measures); - afterMatchSkipTo.ifPresent(nodes::add); - patternSearchMode.ifPresent(nodes::add); - pattern.ifPresent(nodes::add); - nodes.addAll(subsets); - nodes.addAll(variableDefinitions); - return nodes.build(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - WindowFrame o = (WindowFrame) obj; - return type == o.type && - Objects.equals(start, o.start) && - Objects.equals(end, o.end) && - Objects.equals(measures, o.measures) && - Objects.equals(afterMatchSkipTo, o.afterMatchSkipTo) && - Objects.equals(patternSearchMode, o.patternSearchMode) && - Objects.equals(pattern, o.pattern) && - Objects.equals(subsets, o.subsets) && - Objects.equals(variableDefinitions, o.variableDefinitions); - } - - @Override - public int hashCode() - { - return Objects.hash(type, start, end, measures, afterMatchSkipTo, patternSearchMode, pattern, subsets, variableDefinitions); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("type", type) - .add("start", start) - .add("end", end) - .add("measures", measures) - .add("afterMatchSkipTo", afterMatchSkipTo) - .add("patternSearchMode", patternSearchMode) - .add("pattern", pattern) - .add("subsets", subsets) - .add("variableDefinitions", variableDefinitions) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - WindowFrame otherNode = (WindowFrame) other; - return type == otherNode.type; - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/WindowOperation.java b/trino-parser/src/main/java/io/trino/sql/tree/WindowOperation.java deleted file mode 100644 index 3ee1abc88..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/WindowOperation.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -/** - * Represents a call over a window: - *

- *     classifier OVER (...)
- * 
- * There are two types of window calls supported in Trino: - * - function calls - * - row pattern measures - * This class captures row pattern measures only. A function call over a window - * is represented as `FunctionCall` having a `Window` member. - * // TODO refactor `FunctionCall` so that it does not contain `Window`, and instead represent a windowed function call as `WindowOperation` - */ -public class WindowOperation - extends Expression -{ - private final Identifier name; - private final Window window; - - public WindowOperation(Identifier name, Window window) - { - this(Optional.empty(), name, window); - } - - public WindowOperation(NodeLocation location, Identifier name, Window window) - { - this(Optional.of(location), name, window); - } - - private WindowOperation(Optional location, Identifier name, Window window) - { - super(location); - requireNonNull(name, "name is null"); - requireNonNull(window, "window is null"); - checkArgument(window instanceof WindowReference || window instanceof WindowSpecification, "unexpected window: " + window.getClass().getSimpleName()); - - this.name = name; - this.window = window; - } - - public Identifier getName() - { - return name; - } - - public Window getWindow() - { - return window; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitWindowOperation(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(name, (Node) window); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - WindowOperation o = (WindowOperation) obj; - return Objects.equals(name, o.name) && - Objects.equals(window, o.window); - } - - @Override - public int hashCode() - { - return Objects.hash(name, window); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/WindowReference.java b/trino-parser/src/main/java/io/trino/sql/tree/WindowReference.java deleted file mode 100644 index bf15a90e4..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/WindowReference.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class WindowReference - extends Node - implements Window -{ - private final Identifier name; - - public WindowReference(Identifier name) - { - this(Optional.empty(), name); - } - - public WindowReference(NodeLocation location, Identifier name) - { - this(Optional.of(location), name); - } - - private WindowReference(Optional location, Identifier name) - { - super(location); - this.name = requireNonNull(name, "name is null"); - } - - public Identifier getName() - { - return name; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitWindowReference(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(name); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - WindowReference o = (WindowReference) obj; - return Objects.equals(name, o.name); - } - - @Override - public int hashCode() - { - return Objects.hash(name); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/WindowSpecification.java b/trino-parser/src/main/java/io/trino/sql/tree/WindowSpecification.java deleted file mode 100644 index e32bdc8b8..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/WindowSpecification.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class WindowSpecification - extends Node - implements Window -{ - private final Optional existingWindowName; - private final List partitionBy; - private final Optional orderBy; - private final Optional frame; - - public WindowSpecification(Optional existingWindowName, List partitionBy, Optional orderBy, Optional frame) - { - this(Optional.empty(), existingWindowName, partitionBy, orderBy, frame); - } - - public WindowSpecification(NodeLocation location, Optional existingWindowName, List partitionBy, Optional orderBy, Optional frame) - { - this(Optional.of(location), existingWindowName, partitionBy, orderBy, frame); - } - - private WindowSpecification(Optional location, Optional existingWindowName, List partitionBy, Optional orderBy, Optional frame) - { - super(location); - this.existingWindowName = requireNonNull(existingWindowName, "existingWindowName is null"); - this.partitionBy = requireNonNull(partitionBy, "partitionBy is null"); - this.orderBy = requireNonNull(orderBy, "orderBy is null"); - this.frame = requireNonNull(frame, "frame is null"); - } - - public Optional getExistingWindowName() - { - return existingWindowName; - } - - public List getPartitionBy() - { - return partitionBy; - } - - public Optional getOrderBy() - { - return orderBy; - } - - public Optional getFrame() - { - return frame; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitWindowSpecification(this, context); - } - - @Override - public List getChildren() - { - ImmutableList.Builder nodes = ImmutableList.builder(); - existingWindowName.ifPresent(nodes::add); - nodes.addAll(partitionBy); - orderBy.ifPresent(nodes::add); - frame.ifPresent(nodes::add); - return nodes.build(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - WindowSpecification o = (WindowSpecification) obj; - return Objects.equals(existingWindowName, o.existingWindowName) && - Objects.equals(partitionBy, o.partitionBy) && - Objects.equals(orderBy, o.orderBy) && - Objects.equals(frame, o.frame); - } - - @Override - public int hashCode() - { - return Objects.hash(existingWindowName, partitionBy, orderBy, frame); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("existingWindowName", existingWindowName) - .add("partitionBy", partitionBy) - .add("orderBy", orderBy) - .add("frame", frame) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/With.java b/trino-parser/src/main/java/io/trino/sql/tree/With.java deleted file mode 100644 index 08d0af98f..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/With.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class With - extends Node -{ - private final boolean recursive; - private final List queries; - - public With(boolean recursive, List queries) - { - this(Optional.empty(), recursive, queries); - } - - public With(NodeLocation location, boolean recursive, List queries) - { - this(Optional.of(location), recursive, queries); - } - - private With(Optional location, boolean recursive, List queries) - { - super(location); - requireNonNull(queries, "queries is null"); - checkArgument(!queries.isEmpty(), "queries is empty"); - - this.recursive = recursive; - this.queries = ImmutableList.copyOf(queries); - } - - public boolean isRecursive() - { - return recursive; - } - - public List getQueries() - { - return queries; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitWith(this, context); - } - - @Override - public List getChildren() - { - return queries; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - With o = (With) obj; - return Objects.equals(recursive, o.recursive) && - Objects.equals(queries, o.queries); - } - - @Override - public int hashCode() - { - return Objects.hash(recursive, queries); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("recursive", recursive) - .add("queries", queries) - .toString(); - } - - @Override - public boolean shallowEquals(Node other) - { - return sameClass(this, other); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/WithQuery.java b/trino-parser/src/main/java/io/trino/sql/tree/WithQuery.java deleted file mode 100644 index 7818c5daa..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/WithQuery.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class WithQuery - extends Node -{ - private final Identifier name; - private final Query query; - private final Optional> columnNames; - - public WithQuery(Identifier name, Query query, Optional> columnNames) - { - this(Optional.empty(), name, query, columnNames); - } - - public WithQuery(NodeLocation location, Identifier name, Query query, Optional> columnNames) - { - this(Optional.of(location), name, query, columnNames); - } - - private WithQuery(Optional location, Identifier name, Query query, Optional> columnNames) - { - super(location); - this.name = name; - this.query = requireNonNull(query, "query is null"); - this.columnNames = requireNonNull(columnNames, "columnNames is null"); - } - - public Identifier getName() - { - return name; - } - - public Query getQuery() - { - return query; - } - - public Optional> getColumnNames() - { - return columnNames; - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitWithQuery(this, context); - } - - @Override - public List getChildren() - { - return ImmutableList.of(query); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("query", query) - .add("columnNames", columnNames) - .omitNullValues() - .toString(); - } - - @Override - public int hashCode() - { - return Objects.hash(name, query, columnNames); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if ((obj == null) || (getClass() != obj.getClass())) { - return false; - } - WithQuery o = (WithQuery) obj; - return Objects.equals(name, o.name) && - Objects.equals(query, o.query) && - Objects.equals(columnNames, o.columnNames); - } - - @Override - public boolean shallowEquals(Node other) - { - if (!sameClass(this, other)) { - return false; - } - - WithQuery otherRelation = (WithQuery) other; - return name.equals(otherRelation.name) && Objects.equals(columnNames, otherRelation.columnNames); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ZeroOrMoreQuantifier.java b/trino-parser/src/main/java/io/trino/sql/tree/ZeroOrMoreQuantifier.java deleted file mode 100644 index 46f378d17..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ZeroOrMoreQuantifier.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public class ZeroOrMoreQuantifier - extends PatternQuantifier -{ - public ZeroOrMoreQuantifier(boolean greedy) - { - this(Optional.empty(), greedy); - } - - public ZeroOrMoreQuantifier(NodeLocation location, boolean greedy) - { - this(Optional.of(location), greedy); - } - - public ZeroOrMoreQuantifier(Optional location, boolean greedy) - { - super(location, greedy); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitZeroOrMoreQuantifier(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/tree/ZeroOrOneQuantifier.java b/trino-parser/src/main/java/io/trino/sql/tree/ZeroOrOneQuantifier.java deleted file mode 100644 index 551645adf..000000000 --- a/trino-parser/src/main/java/io/trino/sql/tree/ZeroOrOneQuantifier.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import java.util.Optional; - -public class ZeroOrOneQuantifier - extends PatternQuantifier -{ - public ZeroOrOneQuantifier(boolean greedy) - { - this(Optional.empty(), greedy); - } - - public ZeroOrOneQuantifier(NodeLocation location, boolean greedy) - { - this(Optional.of(location), greedy); - } - - public ZeroOrOneQuantifier(Optional location, boolean greedy) - { - super(location, greedy); - } - - @Override - public R accept(AstVisitor visitor, C context) - { - return visitor.visitZeroOrOneQuantifier(this, context); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/util/AstUtils.java b/trino-parser/src/main/java/io/trino/sql/util/AstUtils.java deleted file mode 100644 index c69823519..000000000 --- a/trino-parser/src/main/java/io/trino/sql/util/AstUtils.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed 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 io.trino.sql.util; - -import com.google.common.graph.SuccessorsFunction; -import com.google.common.graph.Traverser; -import io.trino.sql.tree.Node; - -import java.util.List; -import java.util.OptionalInt; -import java.util.function.BiFunction; -import java.util.function.Function; -import java.util.stream.Stream; - -import static com.google.common.collect.Streams.stream; -import static java.util.Objects.requireNonNull; - -public final class AstUtils -{ - public static Stream preOrder(Node node) - { - return stream( - Traverser.forTree((SuccessorsFunction) Node::getChildren) - .depthFirstPreOrder(requireNonNull(node, "node is null"))); - } - - /** - *

Compares two AST trees recursively by applying the provided comparator to each pair of nodes.

- * - *

The comparator can perform a hybrid shallow/deep comparison. If it returns true or false, the - * nodes and any subtrees are considered equal or different, respectively. If it returns null, - * the nodes are considered shallowly-equal and their children will be compared recursively.

- */ - public static boolean treeEqual(Node left, Node right, BiFunction subtreeComparator) - { - Boolean equal = subtreeComparator.apply(left, right); - - if (equal != null) { - return equal; - } - - List leftChildren = left.getChildren(); - List rightChildren = right.getChildren(); - - if (leftChildren.size() != rightChildren.size()) { - return false; - } - - for (int i = 0; i < leftChildren.size(); i++) { - if (!treeEqual(leftChildren.get(i), rightChildren.get(i), subtreeComparator)) { - return false; - } - } - - return true; - } - - /** - *

Computes a hash of the given AST by applying the provided subtree hasher at each level.

- * - *

If the hasher returns a non-empty {@link OptionalInt}, the value is treated as the hash for - * the subtree at that node. Otherwise, the hashes of its children are computed and combined.

- */ - public static int treeHash(Node node, Function subtreeHasher) - { - OptionalInt hash = subtreeHasher.apply(node); - - if (hash.isPresent()) { - return hash.getAsInt(); - } - - List children = node.getChildren(); - - int result = node.getClass().hashCode(); - for (Node element : children) { - result = 31 * result + treeHash(element, subtreeHasher); - } - - return result; - } - - private AstUtils() {} -} diff --git a/trino-parser/src/main/java/io/trino/sql/util/EscapedChars.java b/trino-parser/src/main/java/io/trino/sql/util/EscapedChars.java deleted file mode 100644 index f36ae791d..000000000 --- a/trino-parser/src/main/java/io/trino/sql/util/EscapedChars.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (C) Canner, Inc - All Rights Reserved - * Unauthorized copying of this file, via any medium is strictly prohibited - * Proprietary and confidential - * Written by Canner dev team contact@canner.io, Nov 2021 - */ - -package io.trino.sql.util; - -public class EscapedChars -{ - private final String value; - private final StringBuilder builder; - private final int length; - private int index; - - public static EscapedChars of(String value) - { - return new EscapedChars(value); - } - - private EscapedChars(String value) - { - this.value = value; - this.length = value.length(); - this.builder = new StringBuilder(value.length()); - } - - public boolean hasNext() - { - return index < length; - } - - public char getCurrent() - { - return value.charAt(index); - } - - public char getNext() - { - return value.charAt(index + 1); - } - - public StringBuilder getBuilder() - { - return builder; - } - - public String getValue() - { - return value; - } - - public int getLength() - { - return length; - } - - public int getIndex() - { - return index; - } - - public void setIndex(int index) - { - this.index = index; - } - - public void incrementIndex() - { - index++; - } - - @Override - public String toString() - { - return getBuilder().toString(); - } - - public void appendAndIncrement(char c) - { - builder.append(c); - this.incrementIndex(); - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/util/EscapedCharsUtil.java b/trino-parser/src/main/java/io/trino/sql/util/EscapedCharsUtil.java deleted file mode 100644 index 48ba74658..000000000 --- a/trino-parser/src/main/java/io/trino/sql/util/EscapedCharsUtil.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright (C) Canner, Inc - All Rights Reserved - * Unauthorized copying of this file, via any medium is strictly prohibited - * Proprietary and confidential - * Written by Canner dev team contact@canner.io, Nov 2021 - */ - -package io.trino.sql.util; - -import java.util.function.Consumer; -import java.util.function.Predicate; - -/** - * Handle string with C-Style escapes. For more information, refer to - * https://www.postgresql.org/docs/13/sql-syntax-lexical.html#SQL-SYNTAX-CONSTANTS - */ -public final class EscapedCharsUtil -{ - private static final String ESCAPED_UNICODE_ERROR = "Invalid Unicode escape (must be \\uXXXX or \\UXXXXXXXX (X = 0–9, A–F))"; - - private EscapedCharsUtil() {} - - public static String replaceEscapedChars(String input) - { - if (input.length() <= 1) { - return input; - } - - EscapedChars chars = EscapedChars.of(input); - - while (chars.hasNext()) { - char current = chars.getCurrent(); - if (current == '\\' && chars.getIndex() + 1 < chars.getLength()) { - Handlers.get(chars.getNext()).accept(chars); - } - else { - chars.getBuilder().append(current); - } - chars.incrementIndex(); - } - return chars.toString(); - } - - public static boolean isOctalDigit(char ch) - { - return ch >= '0' && ch <= '7'; - } - - public static boolean isHexDigit(char ch) - { - return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f'); - } - - public static int calculateIndexInSequence(CharSequence seq, - int beginIndex, - int maxCharsToMatch, - Predicate predicate) - { - int index = beginIndex; - int end = Math.min(seq.length(), beginIndex + maxCharsToMatch); - while (index < end && predicate.test(seq.charAt(index))) { - index++; - } - return index; - } - - public static void handleUnicode(EscapedChars chars) - { - // handle unicode case, e.g. \u1000, \U00001000 - int charsToConsume = (chars.getNext() == 'u') ? 4 : 8; - if (chars.getIndex() + 1 + charsToConsume >= chars.getLength()) { - throw new IllegalArgumentException(ESCAPED_UNICODE_ERROR); - } - int endIndex = calculateIndexInSequence(chars.getValue(), - chars.getIndex() + 2, - charsToConsume, - EscapedCharsUtil::isHexDigit); - if (endIndex != chars.getIndex() + 2 + charsToConsume) { - throw new IllegalArgumentException(ESCAPED_UNICODE_ERROR); - } - // skip the backslash and the unicode prefix here, e.g. "\u1000" get string "1000" - String substring = chars.getValue().substring(chars.getIndex() + 2, endIndex); - chars.getBuilder().appendCodePoint(Integer.parseInt(substring, 16)); - chars.setIndex(endIndex - 1); // skip already consumed chars - } - - public static void handleHex(EscapedChars chars) - { - StringBuilder builder = chars.getBuilder(); - - // handle hex byte case - up to 2 chars for hex value - int endIndex = calculateIndexInSequence(chars.getValue(), - chars.getIndex() + 2, - 2, - EscapedCharsUtil::isHexDigit); - if (endIndex > chars.getIndex() + 2) { - // skip the backslash and the hexadecimal prefix here, e.g. "\xAA" get string "AA" - String substring = chars.getValue().substring(chars.getIndex() + 2, endIndex); - builder.appendCodePoint(Integer.parseInt(substring, 16)); - chars.setIndex(endIndex - 1); // skip already consumed chars - } - else { - // hex sequence unmatched - output original char - builder.append(chars.getNext()); - chars.incrementIndex(); - } - } - - public static void handleOctal(EscapedChars chars) - { - // handle octal case - up to 3 chars - int endIndex = calculateIndexInSequence(chars.getValue(), - chars.getIndex() + 2, - 2, // first char is already "consumed" - EscapedCharsUtil::isOctalDigit); - // skip the backslash here, e.g. "\100" get string "100" - String substring = chars.getValue().substring(chars.getIndex() + 1, endIndex); - chars.getBuilder().appendCodePoint(Integer.parseInt(substring, 8)); - chars.setIndex(endIndex - 1); // skip already consumed chars - } - - private enum Handlers - { - BACKSPACE(chars -> chars.appendAndIncrement('\b')), - FORM_FEED(chars -> chars.appendAndIncrement('\f')), - NEWLINE(chars -> chars.appendAndIncrement('\n')), - CARRIAGE_RETURN(chars -> chars.appendAndIncrement('\r')), - TAB(chars -> chars.appendAndIncrement('\t')), - OCTAL_BYTE_VALUE(EscapedCharsUtil::handleOctal), - HEXADECIMAL_BYTE_VALUE(EscapedCharsUtil::handleHex), - HEXADECIMAL_UNICODE_CHARACTER_VALUE(EscapedCharsUtil::handleUnicode), - BACK_SLASH(chars -> chars.appendAndIncrement(chars.getNext())), - DEFAULT(chars -> chars.appendAndIncrement(chars.getNext())); - - private final Consumer handler; - - Handlers(Consumer handler) - { - this.handler = handler; - } - - public static Consumer get(char ch) - { - switch (ch) { - case 'b': - return BACKSPACE.handler; - case 'f': - return FORM_FEED.handler; - case 'n': - return NEWLINE.handler; - case 'r': - return CARRIAGE_RETURN.handler; - case 't': - return TAB.handler; - case '\\': - return BACK_SLASH.handler; - case 'u': - case 'U': - return HEXADECIMAL_UNICODE_CHARACTER_VALUE.handler; - case 'x': - return HEXADECIMAL_BYTE_VALUE.handler; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - return OCTAL_BYTE_VALUE.handler; - } - // non-valid escaped char sequence - return DEFAULT.handler; - } - } -} diff --git a/trino-parser/src/main/java/io/trino/sql/util/IntervalLiteralUtil.java b/trino-parser/src/main/java/io/trino/sql/util/IntervalLiteralUtil.java deleted file mode 100644 index b0dc4ee6e..000000000 --- a/trino-parser/src/main/java/io/trino/sql/util/IntervalLiteralUtil.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) Canner, Inc - All Rights Reserved - * Unauthorized copying of this file, via any medium is strictly prohibited - * Proprietary and confidential - * Written by Canner dev team contact@canner.io, Feb 2022 - */ - -package io.trino.sql.util; - -import io.trino.sql.tree.IntervalLiteral; -import io.trino.sql.tree.NodeLocation; - -import java.util.Locale; -import java.util.Optional; - -import static io.trino.sql.tree.IntervalLiteral.Sign.NEGATIVE; -import static io.trino.sql.tree.IntervalLiteral.Sign.POSITIVE; - -public final class IntervalLiteralUtil -{ - private IntervalLiteralUtil() {} - - /** - * we use this method to parse PostgreSQL style interval string to IntervalLiteral. - *

- * e.g. - * when client sends a query like - * select CAST((CAST(now() AS timestamp) + (INTERVAL '-30 day')) AS date); - * will get the same result as - * select CAST((CAST(now() AS timestamp) + (INTERVAL - '30' day)) AS date); - */ - public static IntervalLiteral parse(NodeLocation location, String text) - { - String[] strings = text.split(" "); - String value = strings[0].replaceFirst("[-+]", ""); - IntervalLiteral.Sign sign = (strings[0].startsWith("-")) ? NEGATIVE : POSITIVE; - if (strings[1].equalsIgnoreCase("week")) { - return new IntervalLiteral(location, Long.toString(Long.parseLong(value) * 7), sign, IntervalLiteral.IntervalField.DAY, Optional.empty()); - } - IntervalLiteral.IntervalField field = IntervalLiteral.IntervalField.valueOf(strings[1].toUpperCase(Locale.ROOT)); - - return new IntervalLiteral(location, value, sign, field, Optional.empty()); - } -} diff --git a/trino-parser/src/main/java/io/trino/type/TypeCalculation.java b/trino-parser/src/main/java/io/trino/type/TypeCalculation.java deleted file mode 100644 index 7a6fc7a4b..000000000 --- a/trino-parser/src/main/java/io/trino/type/TypeCalculation.java +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Licensed 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 io.trino.type; - -import io.trino.sql.parser.CaseInsensitiveStream; -import io.trino.sql.parser.ParsingException; -import io.trino.type.TypeCalculationParser.ArithmeticBinaryContext; -import io.trino.type.TypeCalculationParser.ArithmeticUnaryContext; -import io.trino.type.TypeCalculationParser.BinaryFunctionContext; -import io.trino.type.TypeCalculationParser.IdentifierContext; -import io.trino.type.TypeCalculationParser.NullLiteralContext; -import io.trino.type.TypeCalculationParser.NumericLiteralContext; -import io.trino.type.TypeCalculationParser.ParenthesizedExpressionContext; -import io.trino.type.TypeCalculationParser.TypeCalculationContext; -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.ParseCancellationException; - -import java.math.BigInteger; -import java.util.Map; - -import static com.google.common.base.Preconditions.checkState; -import static io.trino.type.TypeCalculationParser.ASTERISK; -import static io.trino.type.TypeCalculationParser.MAX; -import static io.trino.type.TypeCalculationParser.MIN; -import static io.trino.type.TypeCalculationParser.MINUS; -import static io.trino.type.TypeCalculationParser.PLUS; -import static io.trino.type.TypeCalculationParser.SLASH; -import static java.util.Objects.requireNonNull; - -public final class TypeCalculation -{ - private static final BaseErrorListener ERROR_LISTENER = new BaseErrorListener() - { - @Override - public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String message, RecognitionException e) - { - throw new ParsingException(message, e, line, charPositionInLine + 1); - } - }; - - private TypeCalculation() {} - - public static Long calculateLiteralValue( - String calculation, - Map inputs) - { - try { - ParserRuleContext tree = parseTypeCalculation(calculation); - CalculateTypeVisitor visitor = new CalculateTypeVisitor(inputs); - BigInteger result = visitor.visit(tree); - return result.longValueExact(); - } - catch (StackOverflowError e) { - throw new ParsingException("Type calculation is too large (stack overflow while parsing)"); - } - } - - private static ParserRuleContext parseTypeCalculation(String calculation) - { - TypeCalculationLexer lexer = new TypeCalculationLexer(new CaseInsensitiveStream(CharStreams.fromString(calculation))); - CommonTokenStream tokenStream = new CommonTokenStream(lexer); - TypeCalculationParser parser = new TypeCalculationParser(tokenStream); - - lexer.removeErrorListeners(); - lexer.addErrorListener(ERROR_LISTENER); - - parser.removeErrorListeners(); - parser.addErrorListener(ERROR_LISTENER); - - ParserRuleContext tree; - try { - // first, try parsing with potentially faster SLL mode - parser.getInterpreter().setPredictionMode(PredictionMode.SLL); - tree = parser.typeCalculation(); - } - catch (ParseCancellationException ex) { - // if we fail, parse with LL mode - tokenStream.seek(0); // rewind input stream - parser.reset(); - - parser.getInterpreter().setPredictionMode(PredictionMode.LL); - tree = parser.typeCalculation(); - } - return tree; - } - - private static class IsSimpleExpressionVisitor - extends TypeCalculationBaseVisitor - { - @Override - public Boolean visitArithmeticBinary(ArithmeticBinaryContext ctx) - { - return false; - } - - @Override - public Boolean visitArithmeticUnary(ArithmeticUnaryContext ctx) - { - return false; - } - - @Override - protected Boolean defaultResult() - { - return true; - } - - @Override - protected Boolean aggregateResult(Boolean aggregate, Boolean nextResult) - { - return aggregate && nextResult; - } - } - - private static class CalculateTypeVisitor - extends TypeCalculationBaseVisitor - { - private final Map inputs; - - public CalculateTypeVisitor(Map inputs) - { - this.inputs = requireNonNull(inputs); - } - - @Override - public BigInteger visitTypeCalculation(TypeCalculationContext ctx) - { - return visit(ctx.expression()); - } - - @Override - public BigInteger visitArithmeticBinary(ArithmeticBinaryContext ctx) - { - BigInteger left = visit(ctx.left); - BigInteger right = visit(ctx.right); - switch (ctx.operator.getType()) { - case PLUS: - return left.add(right); - case MINUS: - return left.subtract(right); - case ASTERISK: - return left.multiply(right); - case SLASH: - return left.divide(right); - default: - throw new IllegalStateException("Unsupported binary operator " + ctx.operator.getText()); - } - } - - @Override - public BigInteger visitArithmeticUnary(ArithmeticUnaryContext ctx) - { - BigInteger value = visit(ctx.expression()); - switch (ctx.operator.getType()) { - case PLUS: - return value; - case MINUS: - return value.negate(); - default: - throw new IllegalStateException("Unsupported unary operator " + ctx.operator.getText()); - } - } - - @Override - public BigInteger visitBinaryFunction(BinaryFunctionContext ctx) - { - BigInteger left = visit(ctx.left); - BigInteger right = visit(ctx.right); - switch (ctx.binaryFunctionName().name.getType()) { - case MIN: - return left.min(right); - case MAX: - return left.max(right); - default: - throw new IllegalArgumentException("Unsupported binary function " + ctx.binaryFunctionName().getText()); - } - } - - @Override - public BigInteger visitNumericLiteral(NumericLiteralContext ctx) - { - return new BigInteger(ctx.INTEGER_VALUE().getText()); - } - - @Override - public BigInteger visitNullLiteral(NullLiteralContext ctx) - { - return BigInteger.ZERO; - } - - @Override - public BigInteger visitIdentifier(IdentifierContext ctx) - { - String identifier = ctx.getText(); - Long value = inputs.get(identifier); - checkState(value != null, "value for variable '%s' is not specified in the inputs", identifier); - return BigInteger.valueOf(value); - } - - @Override - public BigInteger visitParenthesizedExpression(ParenthesizedExpressionContext ctx) - { - return visit(ctx.expression()); - } - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/TestSqlFormatter.java b/trino-parser/src/test/java/io/trino/sql/TestSqlFormatter.java deleted file mode 100644 index f8b549a45..000000000 --- a/trino-parser/src/test/java/io/trino/sql/TestSqlFormatter.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Licensed 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 io.trino.sql; - -import io.trino.sql.parser.ParsingOptions; -import io.trino.sql.parser.SqlParser; -import org.junit.jupiter.api.Test; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class TestSqlFormatter -{ - private static final SqlParser SQL_PARSER = new SqlParser(); - - @Test - public void testFormatJoin() - { - String sql = "SELECT * FROM a JOIN b ON a.x = b.y"; - String formattedSql = SqlFormatter.formatSql(SQL_PARSER.createStatement(sql, new ParsingOptions())); - assertEquals(""" - SELECT * - FROM - a - INNER JOIN b ON (a.x = b.y) - """, formattedSql); - - sql = "SELECT * FROM a JOIN b ON a.x = b.y JOIN c ON a.x = c.z"; - formattedSql = SqlFormatter.formatSql(SQL_PARSER.createStatement(sql, new ParsingOptions())); - assertEquals(""" - SELECT * - FROM - a - INNER JOIN b ON (a.x = b.y) - INNER JOIN c ON (a.x = c.z) - """, formattedSql); - } - - @Test - public void testFormatAliasJoin() - { - String sql = "SELECT * FROM (a JOIN b ON a.x = b.y) t1"; - String formattedSql = SqlFormatter.formatSql(SQL_PARSER.createStatement(sql, new ParsingOptions())); - assertEquals(""" - SELECT * - FROM - ( a - INNER JOIN b ON (a.x = b.y)) t1 - """, formattedSql); - sql = "SELECT * FROM ((a JOIN b ON a.x = b.y) t1 join c on t1.x = c.y)"; - formattedSql = SqlFormatter.formatSql(SQL_PARSER.createStatement(sql, new ParsingOptions())); - assertEquals(""" - SELECT * - FROM - ( a - INNER JOIN b ON (a.x = b.y)) t1 - INNER JOIN c ON (t1.x = c.y) - """, formattedSql); - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/parser/ParserAssert.java b/trino-parser/src/test/java/io/trino/sql/parser/ParserAssert.java deleted file mode 100644 index 12438ed13..000000000 --- a/trino-parser/src/test/java/io/trino/sql/parser/ParserAssert.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import io.trino.sql.SqlFormatter; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.RowPattern; -import io.trino.sql.tree.Statement; -import org.assertj.core.api.AssertProvider; -import org.assertj.core.api.RecursiveComparisonAssert; -import org.assertj.core.api.ThrowableAssertAlternative; -import org.assertj.core.api.recursive.comparison.RecursiveComparisonConfiguration; -import org.assertj.core.presentation.StandardRepresentation; - -import java.util.function.Function; - -import static io.trino.sql.SqlFormatter.formatSql; -import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DECIMAL; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -public class ParserAssert - extends RecursiveComparisonAssert -{ - private static final StandardRepresentation NODE_REPRESENTATION = new StandardRepresentation() - { - @Override - public String toStringOf(Object object) - { - if (object instanceof Statement || object instanceof Expression || object instanceof RowPattern) { - return SqlFormatter.formatSql((Node) object); - } - return super.toStringOf(object); - } - }; - - public static AssertProvider type(String sql) - { - return createAssertion(new SqlParser()::createType, sql); - } - - public static AssertProvider expression(String sql) - { - return createAssertion(ParserAssert::createExpression, sql); - } - - public static AssertProvider statement(String sql) - { - return createAssertion(ParserAssert::createStatement, sql); - } - - public static AssertProvider rowPattern(String sql) - { - return createAssertion(new SqlParser()::createRowPattern, sql); - } - - private static Expression createExpression(String expression) - { - return new SqlParser().createExpression(expression, new ParsingOptions(AS_DECIMAL)); - } - - private static Statement createStatement(String statement) - { - return new SqlParser().createStatement(statement, new ParsingOptions(AS_DECIMAL)); - } - - public static ThrowableAssertAlternative assertExpressionIsInvalid(String sql) - { - return assertThatExceptionOfType(ParsingException.class) - .as("expression: %s", sql) - .isThrownBy(() -> createExpression(sql)); - } - - public static ThrowableAssertAlternative assertStatementIsInvalid(String sql) - { - return assertThatExceptionOfType(ParsingException.class) - .as("statement: %s", sql) - .isThrownBy(() -> createStatement(sql)); - } - - private ParserAssert(Node actual, RecursiveComparisonConfiguration recursiveComparisonConfiguration) - { - super(actual, recursiveComparisonConfiguration); - } - - public ParserAssert ignoringLocation() - { - return ignoringFieldsMatchingRegexes("(.*\\.)?location"); - } - - private static AssertProvider createAssertion(Function parser, String sql) - { - return () -> new ParserAssert(parser.apply(sql), newRecursiveComparisonConfig()) - .withRepresentation(NODE_REPRESENTATION) - .satisfies(parsed -> new ParserAssert(parser.apply(formatSql((Node) parsed)), newRecursiveComparisonConfig()) - .describedAs("Validate SQL->AST->SQL roundtrip") - .withRepresentation(NODE_REPRESENTATION) - .ignoringLocation() - .isEqualTo(parser.apply(sql))); - } - - private static RecursiveComparisonConfiguration newRecursiveComparisonConfig() - { - RecursiveComparisonConfiguration config = new RecursiveComparisonConfiguration(); - config.ignoreAllOverriddenEquals(); - config.strictTypeChecking(true); - return config; - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/parser/TestParsingException.java b/trino-parser/src/test/java/io/trino/sql/parser/TestParsingException.java deleted file mode 100644 index 1b04aab23..000000000 --- a/trino-parser/src/test/java/io/trino/sql/parser/TestParsingException.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import io.trino.sql.tree.NodeLocation; -import org.junit.jupiter.api.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TestParsingException -{ - @Test - public void test() - { - ParsingException exception = new ParsingException("the message", new NodeLocation(5, 13)); - - assertThat(exception) - .hasMessage("line 5:13: the message"); - - assertThat(exception.getLineNumber()) - .isEqualTo(5); - - assertThat(exception.getColumnNumber()) - .isEqualTo(13); - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/parser/TestSqlParser.java b/trino-parser/src/test/java/io/trino/sql/parser/TestSqlParser.java deleted file mode 100644 index c596517a8..000000000 --- a/trino-parser/src/test/java/io/trino/sql/parser/TestSqlParser.java +++ /dev/null @@ -1,3913 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import com.google.common.base.Splitter; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Lists; -import io.trino.sql.tree.AddColumn; -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.AllRows; -import io.trino.sql.tree.Analyze; -import io.trino.sql.tree.AnchorPattern; -import io.trino.sql.tree.ArithmeticBinaryExpression; -import io.trino.sql.tree.ArrayConstructor; -import io.trino.sql.tree.AtTimeZone; -import io.trino.sql.tree.BetweenPredicate; -import io.trino.sql.tree.BinaryLiteral; -import io.trino.sql.tree.BooleanLiteral; -import io.trino.sql.tree.Call; -import io.trino.sql.tree.CallArgument; -import io.trino.sql.tree.Cast; -import io.trino.sql.tree.CharLiteral; -import io.trino.sql.tree.CoalesceExpression; -import io.trino.sql.tree.ColumnDefinition; -import io.trino.sql.tree.Comment; -import io.trino.sql.tree.Commit; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.CreateMaterializedView; -import io.trino.sql.tree.CreateRole; -import io.trino.sql.tree.CreateSchema; -import io.trino.sql.tree.CreateTable; -import io.trino.sql.tree.CreateTableAsSelect; -import io.trino.sql.tree.CreateView; -import io.trino.sql.tree.Cube; -import io.trino.sql.tree.CurrentTime; -import io.trino.sql.tree.Deallocate; -import io.trino.sql.tree.DecimalLiteral; -import io.trino.sql.tree.Delete; -import io.trino.sql.tree.Deny; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.DescribeInput; -import io.trino.sql.tree.DescribeOutput; -import io.trino.sql.tree.DoubleLiteral; -import io.trino.sql.tree.DropColumn; -import io.trino.sql.tree.DropMaterializedView; -import io.trino.sql.tree.DropRole; -import io.trino.sql.tree.DropSchema; -import io.trino.sql.tree.DropTable; -import io.trino.sql.tree.DropView; -import io.trino.sql.tree.EmptyPattern; -import io.trino.sql.tree.Execute; -import io.trino.sql.tree.ExistsPredicate; -import io.trino.sql.tree.Explain; -import io.trino.sql.tree.ExplainAnalyze; -import io.trino.sql.tree.ExplainFormat; -import io.trino.sql.tree.ExplainType; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FetchFirst; -import io.trino.sql.tree.Format; -import io.trino.sql.tree.FrameBound; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.FunctionCall.NullTreatment; -import io.trino.sql.tree.FunctionRelation; -import io.trino.sql.tree.GenericLiteral; -import io.trino.sql.tree.Grant; -import io.trino.sql.tree.GrantOnType; -import io.trino.sql.tree.GrantRoles; -import io.trino.sql.tree.GrantorSpecification; -import io.trino.sql.tree.GroupBy; -import io.trino.sql.tree.GroupingOperation; -import io.trino.sql.tree.GroupingSets; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.IfExpression; -import io.trino.sql.tree.Insert; -import io.trino.sql.tree.Intersect; -import io.trino.sql.tree.IntervalLiteral; -import io.trino.sql.tree.IntervalLiteral.IntervalField; -import io.trino.sql.tree.IntervalLiteral.Sign; -import io.trino.sql.tree.IsNullPredicate; -import io.trino.sql.tree.Isolation; -import io.trino.sql.tree.Join; -import io.trino.sql.tree.JoinOn; -import io.trino.sql.tree.LambdaArgumentDeclaration; -import io.trino.sql.tree.LambdaExpression; -import io.trino.sql.tree.Lateral; -import io.trino.sql.tree.LikeClause; -import io.trino.sql.tree.Limit; -import io.trino.sql.tree.LogicalExpression; -import io.trino.sql.tree.LongLiteral; -import io.trino.sql.tree.MeasureDefinition; -import io.trino.sql.tree.Merge; -import io.trino.sql.tree.MergeDelete; -import io.trino.sql.tree.MergeInsert; -import io.trino.sql.tree.MergeUpdate; -import io.trino.sql.tree.NaturalJoin; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NodeLocation; -import io.trino.sql.tree.NotExpression; -import io.trino.sql.tree.NullIfExpression; -import io.trino.sql.tree.NullLiteral; -import io.trino.sql.tree.Offset; -import io.trino.sql.tree.OneOrMoreQuantifier; -import io.trino.sql.tree.OrderBy; -import io.trino.sql.tree.Parameter; -import io.trino.sql.tree.PathElement; -import io.trino.sql.tree.PathSpecification; -import io.trino.sql.tree.PatternAlternation; -import io.trino.sql.tree.PatternConcatenation; -import io.trino.sql.tree.PatternSearchMode; -import io.trino.sql.tree.PatternVariable; -import io.trino.sql.tree.Prepare; -import io.trino.sql.tree.PrincipalSpecification; -import io.trino.sql.tree.ProcessingMode; -import io.trino.sql.tree.Property; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.QuantifiedComparisonExpression; -import io.trino.sql.tree.QuantifiedPattern; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.QueryPeriod; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.RangeQuantifier; -import io.trino.sql.tree.RefreshMaterializedView; -import io.trino.sql.tree.RenameColumn; -import io.trino.sql.tree.RenameMaterializedView; -import io.trino.sql.tree.RenameSchema; -import io.trino.sql.tree.RenameTable; -import io.trino.sql.tree.RenameView; -import io.trino.sql.tree.ResetSession; -import io.trino.sql.tree.Revoke; -import io.trino.sql.tree.RevokeRoles; -import io.trino.sql.tree.Rollback; -import io.trino.sql.tree.Rollup; -import io.trino.sql.tree.Row; -import io.trino.sql.tree.SearchedCaseExpression; -import io.trino.sql.tree.Select; -import io.trino.sql.tree.SelectItem; -import io.trino.sql.tree.SetPath; -import io.trino.sql.tree.SetProperties; -import io.trino.sql.tree.SetRole; -import io.trino.sql.tree.SetSession; -import io.trino.sql.tree.SetTableAuthorization; -import io.trino.sql.tree.SetTimeZone; -import io.trino.sql.tree.SetViewAuthorization; -import io.trino.sql.tree.ShowCatalogs; -import io.trino.sql.tree.ShowColumns; -import io.trino.sql.tree.ShowFunctions; -import io.trino.sql.tree.ShowGrants; -import io.trino.sql.tree.ShowRoleGrants; -import io.trino.sql.tree.ShowRoles; -import io.trino.sql.tree.ShowSchemas; -import io.trino.sql.tree.ShowSession; -import io.trino.sql.tree.ShowStats; -import io.trino.sql.tree.ShowTables; -import io.trino.sql.tree.SimpleCaseExpression; -import io.trino.sql.tree.SimpleGroupBy; -import io.trino.sql.tree.SingleColumn; -import io.trino.sql.tree.SortItem; -import io.trino.sql.tree.StartTransaction; -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.StringLiteral; -import io.trino.sql.tree.SubqueryExpression; -import io.trino.sql.tree.SubscriptExpression; -import io.trino.sql.tree.SubsetDefinition; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableExecute; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.TimeLiteral; -import io.trino.sql.tree.TimestampLiteral; -import io.trino.sql.tree.TransactionAccessMode; -import io.trino.sql.tree.TruncateTable; -import io.trino.sql.tree.Union; -import io.trino.sql.tree.Unnest; -import io.trino.sql.tree.Update; -import io.trino.sql.tree.UpdateAssignment; -import io.trino.sql.tree.Values; -import io.trino.sql.tree.VariableDefinition; -import io.trino.sql.tree.WhenClause; -import io.trino.sql.tree.WindowDefinition; -import io.trino.sql.tree.WindowFrame; -import io.trino.sql.tree.WindowOperation; -import io.trino.sql.tree.WindowReference; -import io.trino.sql.tree.WindowSpecification; -import io.trino.sql.tree.With; -import io.trino.sql.tree.WithQuery; -import io.trino.sql.tree.ZeroOrMoreQuantifier; -import io.trino.sql.tree.ZeroOrOneQuantifier; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static io.trino.sql.QueryUtil.aliased; -import static io.trino.sql.QueryUtil.ascending; -import static io.trino.sql.QueryUtil.equal; -import static io.trino.sql.QueryUtil.identifier; -import static io.trino.sql.QueryUtil.nameReference; -import static io.trino.sql.QueryUtil.ordering; -import static io.trino.sql.QueryUtil.query; -import static io.trino.sql.QueryUtil.quotedIdentifier; -import static io.trino.sql.QueryUtil.row; -import static io.trino.sql.QueryUtil.selectList; -import static io.trino.sql.QueryUtil.simpleQuery; -import static io.trino.sql.QueryUtil.subquery; -import static io.trino.sql.QueryUtil.table; -import static io.trino.sql.QueryUtil.values; -import static io.trino.sql.SqlFormatter.formatSql; -import static io.trino.sql.parser.ParserAssert.assertExpressionIsInvalid; -import static io.trino.sql.parser.ParserAssert.assertStatementIsInvalid; -import static io.trino.sql.parser.ParserAssert.expression; -import static io.trino.sql.parser.ParserAssert.rowPattern; -import static io.trino.sql.parser.ParserAssert.statement; -import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DECIMAL; -import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.REJECT; -import static io.trino.sql.parser.TreeNodes.columnDefinition; -import static io.trino.sql.parser.TreeNodes.dateTimeType; -import static io.trino.sql.parser.TreeNodes.field; -import static io.trino.sql.parser.TreeNodes.location; -import static io.trino.sql.parser.TreeNodes.property; -import static io.trino.sql.parser.TreeNodes.qualifiedName; -import static io.trino.sql.parser.TreeNodes.rowType; -import static io.trino.sql.parser.TreeNodes.simpleType; -import static io.trino.sql.testing.TreeAssertions.assertFormattedSql; -import static io.trino.sql.tree.ArithmeticUnaryExpression.negative; -import static io.trino.sql.tree.ArithmeticUnaryExpression.positive; -import static io.trino.sql.tree.ComparisonExpression.Operator.EQUAL; -import static io.trino.sql.tree.DateTimeDataType.Type.TIMESTAMP; -import static io.trino.sql.tree.FrameBound.Type.CURRENT_ROW; -import static io.trino.sql.tree.FrameBound.Type.FOLLOWING; -import static io.trino.sql.tree.PatternSearchMode.Mode.SEEK; -import static io.trino.sql.tree.ProcessingMode.Mode.FINAL; -import static io.trino.sql.tree.ProcessingMode.Mode.RUNNING; -import static io.trino.sql.tree.SetProperties.Type.MATERIALIZED_VIEW; -import static io.trino.sql.tree.SkipTo.skipToNextRow; -import static io.trino.sql.tree.SortItem.NullOrdering.UNDEFINED; -import static io.trino.sql.tree.SortItem.Ordering.ASCENDING; -import static io.trino.sql.tree.SortItem.Ordering.DESCENDING; -import static io.trino.sql.tree.WindowFrame.Type.ROWS; -import static java.lang.String.format; -import static java.util.Collections.emptyList; -import static java.util.Objects.requireNonNull; -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; - -public class TestSqlParser -{ - private static final SqlParser SQL_PARSER = new SqlParser(); - - @Test - public void testPosition() - { - assertThat(expression("position('a' in 'b')")) - .isEqualTo(new FunctionCall(location(1, 1), QualifiedName.of("strpos"), ImmutableList.of( - new StringLiteral(location(1, 17), "b"), - new StringLiteral(location(1, 10), "a")))); - - assertThat(expression("position('a' in ('b'))")) - .isEqualTo(new FunctionCall(location(1, 1), QualifiedName.of("strpos"), ImmutableList.of( - new StringLiteral(location(1, 18), "b"), - new StringLiteral(location(1, 10), "a")))); - } - - @Test - public void testPossibleExponentialBacktracking() - { - createExpression("(((((((((((((((((((((((((((true)))))))))))))))))))))))))))"); - } - - @Test - @Timeout(value = 2, unit = SECONDS) - public void testPotentialUnboundedLookahead() - { - createExpression("(\n" + - " 1 * -1 +\n" + - " 1 * -2 +\n" + - " 1 * -3 +\n" + - " 1 * -4 +\n" + - " 1 * -5 +\n" + - " 1 * -6 +\n" + - " 1 * -7 +\n" + - " 1 * -8 +\n" + - " 1 * -9 +\n" + - " 1 * -10 +\n" + - " 1 * -11 +\n" + - " 1 * -12 \n" + - ")\n"); - } - - @Test - public void testQualifiedName() - { - assertThat(QualifiedName.of("a", "b", "c", "d").toString()) - .isEqualTo("a.b.c.d"); - assertThat(QualifiedName.of("A", "b", "C", "d").toString()) - .isEqualTo("A.b.C.d"); - assertTrue(QualifiedName.of("a", "b", "c", "d").hasSuffix(QualifiedName.of("b", "c", "d"))); - assertTrue(QualifiedName.of("a", "b", "c", "d").hasSuffix(QualifiedName.of("a", "b", "c", "d"))); - assertFalse(QualifiedName.of("a", "b", "c", "d").hasSuffix(QualifiedName.of("a", "c", "d"))); - assertFalse(QualifiedName.of("a", "b", "c", "d").hasSuffix(QualifiedName.of("z", "a", "b", "c", "d"))); - assertThat(QualifiedName.of("a", "b", "c", "d")) - .isEqualTo(QualifiedName.of("a", "b", "c", "d")); - } - - @Test - public void testGenericLiteral() - { - assertGenericLiteral("VARCHAR"); - assertGenericLiteral("BIGINT"); - assertGenericLiteral("DOUBLE"); - assertGenericLiteral("BOOLEAN"); - assertGenericLiteral("DATE"); - assertGenericLiteral("foo"); - } - - @Test - public void testBinaryLiteral() - { - assertExpression("x' '", new BinaryLiteral("")); - assertExpression("x''", new BinaryLiteral("")); - assertExpression("X'abcdef1234567890ABCDEF'", new BinaryLiteral("abcdef1234567890ABCDEF")); - - // forms such as "X 'a b' " may look like BinaryLiteral - // but they do not pass the syntax rule for BinaryLiteral - // but instead conform to TypeConstructor, which generates a GenericLiteral expression - assertInvalidExpression("X 'a b'", "Spaces are not allowed.*"); - assertInvalidExpression("X'a b c'", "Binary literal must contain an even number of digits.*"); - assertInvalidExpression("X'a z'", "Binary literal can only contain hexadecimal digits.*"); - } - - public static void assertGenericLiteral(String type) - { - assertExpression(type + " 'abc'", new GenericLiteral(type, "abc")); - } - - @Test - public void testLiterals() - { - assertExpression("TIME 'abc'", new TimeLiteral("abc")); - assertExpression("TIMESTAMP 'abc'", new TimestampLiteral("abc")); - assertExpression("INTERVAL '33' day", new IntervalLiteral("33", Sign.POSITIVE, IntervalField.DAY, Optional.empty())); - assertExpression("INTERVAL '33' day to second", new IntervalLiteral("33", Sign.POSITIVE, IntervalField.DAY, Optional.of(IntervalField.SECOND))); - assertExpression("CHAR 'abc'", new CharLiteral("abc")); - } - - @Test - public void testNumbers() - { - assertExpression("9223372036854775807", new LongLiteral("9223372036854775807")); - assertInvalidExpression("9223372036854775808", "Invalid numeric literal: 9223372036854775808"); - - assertExpression("-9223372036854775808", new LongLiteral("-9223372036854775808")); - assertInvalidExpression("-9223372036854775809", "Invalid numeric literal: -9223372036854775809"); - - assertExpression("1E5", new DoubleLiteral("1E5")); - assertExpression("1E-5", new DoubleLiteral("1E-5")); - assertExpression(".1E5", new DoubleLiteral(".1E5")); - assertExpression(".1E-5", new DoubleLiteral(".1E-5")); - assertExpression("1.1E5", new DoubleLiteral("1.1E5")); - assertExpression("1.1E-5", new DoubleLiteral("1.1E-5")); - - assertExpression("-1E5", new DoubleLiteral("-1E5")); - assertExpression("-1E-5", new DoubleLiteral("-1E-5")); - assertExpression("-.1E5", new DoubleLiteral("-.1E5")); - assertExpression("-.1E-5", new DoubleLiteral("-.1E-5")); - assertExpression("-1.1E5", new DoubleLiteral("-1.1E5")); - assertExpression("-1.1E-5", new DoubleLiteral("-1.1E-5")); - - assertExpression(".1", new DecimalLiteral(".1")); - assertExpression("1.2", new DecimalLiteral("1.2")); - assertExpression("-1.2", new DecimalLiteral("-1.2")); - } - - @Test - public void testArrayConstructor() - { - assertExpression("ARRAY []", new ArrayConstructor(ImmutableList.of())); - assertExpression("ARRAY [1, 2]", new ArrayConstructor(ImmutableList.of(new LongLiteral("1"), new LongLiteral("2")))); - assertExpression("ARRAY [1e0, 2.5e0]", new ArrayConstructor(ImmutableList.of(new DoubleLiteral("1.0"), new DoubleLiteral("2.5")))); - assertExpression("ARRAY ['hi']", new ArrayConstructor(ImmutableList.of(new StringLiteral("hi")))); - assertExpression("ARRAY ['hi', 'hello']", new ArrayConstructor(ImmutableList.of(new StringLiteral("hi"), new StringLiteral("hello")))); - } - - @Test - public void testArraySubscript() - { - assertExpression("ARRAY [1, 2][1]", new SubscriptExpression( - new ArrayConstructor(ImmutableList.of(new LongLiteral("1"), new LongLiteral("2"))), - new LongLiteral("1"))); - - assertExpression("CASE WHEN TRUE THEN ARRAY[1,2] END[1]", new SubscriptExpression( - new SearchedCaseExpression( - ImmutableList.of( - new WhenClause( - new BooleanLiteral("true"), - new ArrayConstructor(ImmutableList.of(new LongLiteral("1"), new LongLiteral("2"))))), - Optional.empty()), - new LongLiteral("1"))); - } - - @Test - public void testRowSubscript() - { - assertExpression("ROW (1, 'a', true)[1]", new SubscriptExpression( - new Row(ImmutableList.of(new LongLiteral("1"), new StringLiteral("a"), new BooleanLiteral("true"))), - new LongLiteral("1"))); - } - - @Test - public void testAllColumns() - { - assertStatement("SELECT * FROM t", simpleQuery( - new Select( - false, - ImmutableList.of( - new AllColumns( - Optional.empty(), - Optional.empty(), - ImmutableList.of()))), - table(QualifiedName.of("t")))); - - assertStatement("SELECT r.* FROM t", simpleQuery( - new Select( - false, - ImmutableList.of( - new AllColumns( - Optional.empty(), - Optional.of(new Identifier("r")), - ImmutableList.of()))), - table(QualifiedName.of("t")))); - - assertStatement("SELECT ROW (1, 'a', true).*", simpleQuery( - new Select( - false, - ImmutableList.of( - new AllColumns( - Optional.empty(), - Optional.of(new Row(ImmutableList.of(new LongLiteral("1"), new StringLiteral("a"), new BooleanLiteral("true")))), - ImmutableList.of()))))); - - assertStatement("SELECT ROW (1, 'a', true).* AS (f1, f2, f3)", simpleQuery( - new Select( - false, - ImmutableList.of( - new AllColumns( - Optional.empty(), - Optional.of(new Row(ImmutableList.of(new LongLiteral("1"), new StringLiteral("a"), new BooleanLiteral("true")))), - ImmutableList.of(new Identifier("f1"), new Identifier("f2"), new Identifier("f3"))))))); - } - - @Test - public void testDouble() - { - assertExpression("123E7", new DoubleLiteral("123E7")); - assertExpression("123.E7", new DoubleLiteral("123E7")); - assertExpression("123.0E7", new DoubleLiteral("123E7")); - assertExpression("123E+7", new DoubleLiteral("123E7")); - assertExpression("123E-7", new DoubleLiteral("123E-7")); - - assertExpression("123.456E7", new DoubleLiteral("123.456E7")); - assertExpression("123.456E+7", new DoubleLiteral("123.456E7")); - assertExpression("123.456E-7", new DoubleLiteral("123.456E-7")); - - assertExpression(".4E42", new DoubleLiteral(".4E42")); - assertExpression(".4E+42", new DoubleLiteral(".4E42")); - assertExpression(".4E-42", new DoubleLiteral(".4E-42")); - } - - @Test - public void testArithmeticUnary() - { - assertExpression("9", new LongLiteral("9")); - - assertExpression("+9", positive(new LongLiteral("9"))); - assertExpression("+ 9", positive(new LongLiteral("9"))); - - assertExpression("++9", positive(positive(new LongLiteral("9")))); - assertExpression("+ +9", positive(positive(new LongLiteral("9")))); - assertExpression("+ + 9", positive(positive(new LongLiteral("9")))); - - assertExpression("+++9", positive(positive(positive(new LongLiteral("9"))))); - assertExpression("+ + +9", positive(positive(positive(new LongLiteral("9"))))); - assertExpression("+ + + 9", positive(positive(positive(new LongLiteral("9"))))); - - assertExpression("-9", new LongLiteral("-9")); - assertExpression("- 9", new LongLiteral("-9")); - - assertExpression("- + 9", negative(positive(new LongLiteral("9")))); - assertExpression("-+9", negative(positive(new LongLiteral("9")))); - - assertExpression("+ - + 9", positive(negative(positive(new LongLiteral("9"))))); - assertExpression("+-+9", positive(negative(positive(new LongLiteral("9"))))); - - assertExpression("- -9", negative(new LongLiteral("-9"))); - assertExpression("- - 9", negative(new LongLiteral("-9"))); - - assertExpression("- + - + 9", negative(positive(negative(positive(new LongLiteral("9")))))); - assertExpression("-+-+9", negative(positive(negative(positive(new LongLiteral("9")))))); - - assertExpression("+ - + - + 9", positive(negative(positive(negative(positive(new LongLiteral("9"))))))); - assertExpression("+-+-+9", positive(negative(positive(negative(positive(new LongLiteral("9"))))))); - - assertExpression("- - -9", negative(negative(new LongLiteral("-9")))); - assertExpression("- - - 9", negative(negative(new LongLiteral("-9")))); - } - - @Test - public void testCoalesce() - { - assertInvalidExpression("coalesce()", "The 'coalesce' function must have at least two arguments"); - assertInvalidExpression("coalesce(5)", "The 'coalesce' function must have at least two arguments"); - assertInvalidExpression("coalesce(1, 2) filter (where true)", "FILTER not valid for 'coalesce' function"); - assertInvalidExpression("coalesce(1, 2) OVER ()", "OVER clause not valid for 'coalesce' function"); - assertExpression("coalesce(13, 42)", new CoalesceExpression(new LongLiteral("13"), new LongLiteral("42"))); - assertExpression("coalesce(6, 7, 8)", new CoalesceExpression(new LongLiteral("6"), new LongLiteral("7"), new LongLiteral("8"))); - assertExpression("coalesce(13, null)", new CoalesceExpression(new LongLiteral("13"), new NullLiteral())); - assertExpression("coalesce(null, 13)", new CoalesceExpression(new NullLiteral(), new LongLiteral("13"))); - assertExpression("coalesce(null, null)", new CoalesceExpression(new NullLiteral(), new NullLiteral())); - } - - @Test - public void testIf() - { - assertExpression("if(true, 1, 0)", new IfExpression(new BooleanLiteral("true"), new LongLiteral("1"), new LongLiteral("0"))); - assertExpression("if(true, 3, null)", new IfExpression(new BooleanLiteral("true"), new LongLiteral("3"), new NullLiteral())); - assertExpression("if(false, null, 4)", new IfExpression(new BooleanLiteral("false"), new NullLiteral(), new LongLiteral("4"))); - assertExpression("if(false, null, null)", new IfExpression(new BooleanLiteral("false"), new NullLiteral(), new NullLiteral())); - assertExpression("if(true, 3)", new IfExpression(new BooleanLiteral("true"), new LongLiteral("3"), null)); - assertInvalidExpression("IF(true)", "Invalid number of arguments for 'if' function"); - assertInvalidExpression("IF(true, 1, 0) FILTER (WHERE true)", "FILTER not valid for 'if' function"); - assertInvalidExpression("IF(true, 1, 0) OVER()", "OVER clause not valid for 'if' function"); - } - - @Test - public void testNullIf() - { - assertExpression("nullif(42, 87)", new NullIfExpression(new LongLiteral("42"), new LongLiteral("87"))); - assertExpression("nullif(42, null)", new NullIfExpression(new LongLiteral("42"), new NullLiteral())); - assertExpression("nullif(null, null)", new NullIfExpression(new NullLiteral(), new NullLiteral())); - assertInvalidExpression("nullif(1)", "Invalid number of arguments for 'nullif' function"); - assertInvalidExpression("nullif(1, 2, 3)", "Invalid number of arguments for 'nullif' function"); - assertInvalidExpression("nullif(42, 87) filter (where true)", "FILTER not valid for 'nullif' function"); - assertInvalidExpression("nullif(42, 87) OVER ()", "OVER clause not valid for 'nullif' function"); - } - - @Test - public void testDoubleInQuery() - { - assertStatement("SELECT 123.456E7 FROM DUAL", - simpleQuery( - selectList(new DoubleLiteral("123.456E7")), - table(QualifiedName.of("DUAL")))); - } - - @Test - public void testIntersect() - { - assertStatement("SELECT 123 INTERSECT DISTINCT SELECT 123 INTERSECT ALL SELECT 123", - query(new Intersect( - ImmutableList.of( - new Intersect(ImmutableList.of(createSelect123(), createSelect123()), true), - createSelect123()), - false))); - } - - @Test - public void testUnion() - { - assertStatement("SELECT 123 UNION DISTINCT SELECT 123 UNION ALL SELECT 123", - query(new Union( - ImmutableList.of( - new Union(ImmutableList.of(createSelect123(), createSelect123()), true), - createSelect123()), - false))); - } - - private static QuerySpecification createSelect123() - { - return new QuerySpecification( - selectList(new LongLiteral("123")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.empty(), - Optional.empty()); - } - - @Test - public void testReservedWordIdentifier() - { - assertStatement("SELECT id FROM public.orders", - simpleQuery( - selectList(identifier("id")), - new Table(QualifiedName.of("public", "orders")))); - - assertStatement("SELECT id FROM \"public\".\"order\"", - simpleQuery( - selectList(identifier("id")), - new Table(QualifiedName.of(ImmutableList.of( - new Identifier("public", true), - new Identifier("order", true)))))); - - assertStatement("SELECT id FROM \"public\".\"order\"\"2\"", - simpleQuery( - selectList(identifier("id")), - new Table(QualifiedName.of(ImmutableList.of( - new Identifier("public", true), - new Identifier("order\"2", true)))))); - } - - @Test - public void testBetween() - { - assertExpression("1 BETWEEN 2 AND 3", new BetweenPredicate(new LongLiteral("1"), new LongLiteral("2"), new LongLiteral("3"))); - assertExpression("1 NOT BETWEEN 2 AND 3", new NotExpression(new BetweenPredicate(new LongLiteral("1"), new LongLiteral("2"), new LongLiteral("3")))); - } - - @Test - public void testSelectWithLimit() - { - assertStatement("SELECT * FROM table1 LIMIT 2", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Limit(new LongLiteral("2"))))); - - assertStatement("SELECT * FROM table1 LIMIT ALL", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Limit(new AllRows())))); - - Query valuesQuery = query(values( - row(new LongLiteral("1"), new StringLiteral("1")), - row(new LongLiteral("2"), new StringLiteral("2")))); - - assertStatement("SELECT * FROM (VALUES (1, '1'), (2, '2')) LIMIT ALL", - simpleQuery(selectList(new AllColumns()), - subquery(valuesQuery), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Limit(new AllRows())))); - } - - @Test - public void testValues() - { - Query valuesQuery = query(values( - row(new StringLiteral("a"), new LongLiteral("1"), new DoubleLiteral("2.2")), - row(new StringLiteral("b"), new LongLiteral("2"), new DoubleLiteral("3.3")))); - - assertStatement("VALUES ('a', 1, 2.2e0), ('b', 2, 3.3e0)", valuesQuery); - - assertStatement("SELECT * FROM (VALUES ('a', 1, 2.2e0), ('b', 2, 3.3e0))", - simpleQuery( - selectList(new AllColumns()), - subquery(valuesQuery))); - } - - @Test - public void testRowPattern() - { - assertThat(rowPattern("(A B)* | CC+? DD?? E | (F | G)")) - .isEqualTo( - new PatternAlternation( - location(1, 1), - ImmutableList.of( - new PatternAlternation( - location(1, 1), - ImmutableList.of( - new QuantifiedPattern( - location(1, 1), - new PatternConcatenation( - location(1, 2), - ImmutableList.of( - new PatternVariable(location(1, 2), new Identifier(location(1, 2), "A", false)), - new PatternVariable(location(1, 4), new Identifier(location(1, 4), "B", false)))), - new ZeroOrMoreQuantifier(location(1, 6), true)), - new PatternConcatenation( - location(1, 10), - ImmutableList.of( - new PatternConcatenation( - location(1, 10), - ImmutableList.of( - new QuantifiedPattern(location(1, 10), new PatternVariable(location(1, 10), new Identifier(location(1, 10), "CC", false)), new OneOrMoreQuantifier(location(1, 12), false)), - new QuantifiedPattern(location(1, 15), new PatternVariable(location(1, 15), new Identifier(location(1, 15), "DD", false)), new ZeroOrOneQuantifier(location(1, 17), false)))), - new PatternVariable(location(1, 20), new Identifier(location(1, 20), "E", false)))))), - new PatternAlternation( - location(1, 25), - ImmutableList.of( - new PatternVariable(location(1, 25), new Identifier(location(1, 25), "F", false)), - new PatternVariable(location(1, 29), new Identifier(location(1, 29), "G", false))))))); - - assertThat(rowPattern("A | B | C D E F")) - .isEqualTo( - new PatternAlternation( - location(1, 1), - ImmutableList.of( - new PatternAlternation( - location(1, 1), - ImmutableList.of( - new PatternVariable(location(1, 1), new Identifier(location(1, 1), "A", false)), - new PatternVariable(location(1, 5), new Identifier(location(1, 5), "B", false)))), - new PatternConcatenation( - location(1, 9), - ImmutableList.of( - new PatternConcatenation( - location(1, 9), - ImmutableList.of( - new PatternConcatenation( - location(1, 9), - ImmutableList.of( - new PatternVariable(location(1, 9), new Identifier(location(1, 9), "C", false)), - new PatternVariable(location(1, 11), new Identifier(location(1, 11), "D", false)))), - new PatternVariable(location(1, 13), new Identifier(location(1, 13), "E", false)))), - new PatternVariable(location(1, 15), new Identifier(location(1, 15), "F", false))))))); - - assertThatThrownBy(() -> SQL_PARSER.createRowPattern("A!")) - .isInstanceOf(ParsingException.class) - .hasMessageMatching("line 1:2: mismatched input '!'.*"); - - assertThatThrownBy(() -> SQL_PARSER.createRowPattern("A**")) - .isInstanceOf(ParsingException.class) - .hasMessageMatching("line 1:3: mismatched input '*'.*"); - - assertThat(rowPattern("A??")) - .isEqualTo(new QuantifiedPattern( - location(1, 1), - new PatternVariable(location(1, 1), new Identifier(location(1, 1), "A", false)), - new ZeroOrOneQuantifier(location(1, 2), false))); - - assertThat(rowPattern("^$")) - .isEqualTo(new PatternConcatenation( - location(1, 1), - ImmutableList.of( - new AnchorPattern(location(1, 1), AnchorPattern.Type.PARTITION_START), - new AnchorPattern(location(1, 2), AnchorPattern.Type.PARTITION_END)))); - - assertThat(rowPattern("()")) - .isEqualTo(new EmptyPattern(location(1, 1))); - - assertThat(rowPattern("A{3}")) - .isEqualTo(new QuantifiedPattern( - location(1, 1), - new PatternVariable(location(1, 1), new Identifier(location(1, 1), "A", false)), - new RangeQuantifier(location(1, 2), true, Optional.of(new LongLiteral(location(1, 3), "3")), Optional.of(new LongLiteral(location(1, 3), "3"))))); - - assertThat(rowPattern("A{3,}")) - .isEqualTo(new QuantifiedPattern( - location(1, 1), - new PatternVariable(location(1, 1), new Identifier(location(1, 1), "A", false)), - new RangeQuantifier(location(1, 2), true, Optional.of(new LongLiteral(location(1, 3), "3")), Optional.empty()))); - - assertThat(rowPattern("A{,3}")) - .isEqualTo(new QuantifiedPattern( - location(1, 1), - new PatternVariable(location(1, 1), new Identifier(location(1, 1), "A", false)), - new RangeQuantifier(location(1, 2), true, Optional.empty(), Optional.of(new LongLiteral(location(1, 4), "3"))))); - - assertThat(rowPattern("A{3,4}")) - .isEqualTo(new QuantifiedPattern( - location(1, 1), - new PatternVariable(location(1, 1), new Identifier(location(1, 1), "A", false)), - new RangeQuantifier(location(1, 2), true, Optional.of(new LongLiteral(location(1, 3), "3")), Optional.of(new LongLiteral(location(1, 5), "4"))))); - } - - @Test - public void testPrecedenceAndAssociativity() - { - assertThat(expression("1 AND 2 AND 3 AND 4")) - .isEqualTo(new LogicalExpression( - location(1, 1), - LogicalExpression.Operator.AND, - ImmutableList.of( - new LongLiteral(location(1, 1), "1"), - new LongLiteral(location(1, 7), "2"), - new LongLiteral(location(1, 13), "3"), - new LongLiteral(location(1, 19), "4")))); - - assertThat(expression("1 OR 2 OR 3 OR 4")) - .isEqualTo(new LogicalExpression( - location(1, 1), - LogicalExpression.Operator.OR, - ImmutableList.of( - new LongLiteral(location(1, 1), "1"), - new LongLiteral(location(1, 6), "2"), - new LongLiteral(location(1, 11), "3"), - new LongLiteral(location(1, 16), "4")))); - - assertThat(expression("1 AND 2 AND 3 OR 4 AND 5 AND 6 OR 7 AND 8 AND 9")) - .isEqualTo(new LogicalExpression( - location(1, 1), - LogicalExpression.Operator.OR, - ImmutableList.of( - new LogicalExpression( - location(1, 1), - LogicalExpression.Operator.AND, - ImmutableList.of( - new LongLiteral(location(1, 1), "1"), - new LongLiteral(location(1, 7), "2"), - new LongLiteral(location(1, 13), "3"))), - new LogicalExpression( - location(1, 18), - LogicalExpression.Operator.AND, - ImmutableList.of( - new LongLiteral(location(1, 18), "4"), - new LongLiteral(location(1, 24), "5"), - new LongLiteral(location(1, 30), "6"))), - new LogicalExpression( - location(1, 35), - LogicalExpression.Operator.AND, - ImmutableList.of( - new LongLiteral(location(1, 35), "7"), - new LongLiteral(location(1, 41), "8"), - new LongLiteral(location(1, 47), "9")))))); - - assertExpression("1 AND 2 OR 3", LogicalExpression.or( - LogicalExpression.and( - new LongLiteral("1"), - new LongLiteral("2")), - new LongLiteral("3"))); - - assertExpression("1 OR 2 AND 3", LogicalExpression.or( - new LongLiteral("1"), - LogicalExpression.and( - new LongLiteral("2"), - new LongLiteral("3")))); - - assertExpression("NOT 1 AND 2", LogicalExpression.and( - new NotExpression(new LongLiteral("1")), - new LongLiteral("2"))); - - assertExpression("NOT 1 OR 2", LogicalExpression.or( - new NotExpression(new LongLiteral("1")), - new LongLiteral("2"))); - - assertExpression("-1 + 2", new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Operator.ADD, - new LongLiteral("-1"), - new LongLiteral("2"))); - - assertExpression("1 - 2 - 3", new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Operator.SUBTRACT, - new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Operator.SUBTRACT, - new LongLiteral("1"), - new LongLiteral("2")), - new LongLiteral("3"))); - - assertExpression("1 / 2 / 3", new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Operator.DIVIDE, - new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Operator.DIVIDE, - new LongLiteral("1"), - new LongLiteral("2")), - new LongLiteral("3"))); - - assertExpression("1 + 2 * 3", new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Operator.ADD, - new LongLiteral("1"), - new ArithmeticBinaryExpression(ArithmeticBinaryExpression.Operator.MULTIPLY, - new LongLiteral("2"), - new LongLiteral("3")))); - } - - @Test - public void testInterval() - { - assertExpression("INTERVAL '123' YEAR", new IntervalLiteral("123", Sign.POSITIVE, IntervalField.YEAR)); - assertExpression("INTERVAL '123-3' YEAR TO MONTH", new IntervalLiteral("123-3", Sign.POSITIVE, IntervalField.YEAR, Optional.of(IntervalField.MONTH))); - assertExpression("INTERVAL '123' MONTH", new IntervalLiteral("123", Sign.POSITIVE, IntervalField.MONTH)); - assertExpression("INTERVAL '123' DAY", new IntervalLiteral("123", Sign.POSITIVE, IntervalField.DAY)); - assertExpression("INTERVAL '123 23:58:53.456' DAY TO SECOND", new IntervalLiteral("123 23:58:53.456", Sign.POSITIVE, IntervalField.DAY, Optional.of(IntervalField.SECOND))); - assertExpression("INTERVAL '123' HOUR", new IntervalLiteral("123", Sign.POSITIVE, IntervalField.HOUR)); - assertExpression("INTERVAL '23:59' HOUR TO MINUTE", new IntervalLiteral("23:59", Sign.POSITIVE, IntervalField.HOUR, Optional.of(IntervalField.MINUTE))); - assertExpression("INTERVAL '123' MINUTE", new IntervalLiteral("123", Sign.POSITIVE, IntervalField.MINUTE)); - assertExpression("INTERVAL '123' SECOND", new IntervalLiteral("123", Sign.POSITIVE, IntervalField.SECOND)); - } - - @Test - public void testDecimal() - { - assertExpression("DECIMAL '12.34'", new DecimalLiteral("12.34")); - assertExpression("DECIMAL '12.'", new DecimalLiteral("12.")); - assertExpression("DECIMAL '12'", new DecimalLiteral("12")); - assertExpression("DECIMAL '.34'", new DecimalLiteral(".34")); - assertExpression("DECIMAL '+12.34'", new DecimalLiteral("+12.34")); - assertExpression("DECIMAL '+12'", new DecimalLiteral("+12")); - assertExpression("DECIMAL '-12.34'", new DecimalLiteral("-12.34")); - assertExpression("DECIMAL '-12'", new DecimalLiteral("-12")); - assertExpression("DECIMAL '+.34'", new DecimalLiteral("+.34")); - assertExpression("DECIMAL '-.34'", new DecimalLiteral("-.34")); - - assertExpression("123.", new DecimalLiteral("123.")); - assertExpression("123.0", new DecimalLiteral("123.0")); - assertExpression(".5", new DecimalLiteral(".5")); - assertExpression("123.5", new DecimalLiteral("123.5")); - - assertInvalidDecimalExpression("123.", "Unexpected decimal literal: 123."); - assertInvalidDecimalExpression("123.0", "Unexpected decimal literal: 123.0"); - assertInvalidDecimalExpression(".5", "Unexpected decimal literal: .5"); - assertInvalidDecimalExpression("123.5", "Unexpected decimal literal: 123.5"); - } - - private static void assertInvalidDecimalExpression(String sql, String message) - { - assertThatThrownBy(() -> SQL_PARSER.createExpression(sql, new ParsingOptions(REJECT))) - .isInstanceOfSatisfying(ParsingException.class, e -> - assertThat(e.getErrorMessage()).isEqualTo(message)); - } - - @Test - public void testTime() - { - assertExpression("TIME '03:04:05'", new TimeLiteral("03:04:05")); - } - - @Test - public void testCurrentTimestamp() - { - assertExpression("CURRENT_TIMESTAMP", new CurrentTime(CurrentTime.Function.TIMESTAMP)); - } - - @Test - public void testFormat() - { - assertExpression("format('%s', 'abc')", new Format(ImmutableList.of(new StringLiteral("%s"), new StringLiteral("abc")))); - assertExpression("format('%d %s', 123, 'x')", new Format(ImmutableList.of(new StringLiteral("%d %s"), new LongLiteral("123"), new StringLiteral("x")))); - - assertInvalidExpression("format()", "The 'format' function must have at least two arguments"); - assertInvalidExpression("format('%s')", "The 'format' function must have at least two arguments"); - } - - @Test - public void testCase() - { - assertExpression( - "CASE 1 IS NULL WHEN true THEN 2 ELSE 3 END", - new SimpleCaseExpression( - new IsNullPredicate(new LongLiteral("1")), - ImmutableList.of( - new WhenClause( - new BooleanLiteral("true"), - new LongLiteral("2"))), - Optional.of(new LongLiteral("3")))); - } - - @Test - public void testSearchedCase() - { - assertExpression( - "CASE WHEN a > 3 THEN 23 WHEN b = a THEN 33 END", - new SearchedCaseExpression( - ImmutableList.of( - new WhenClause( - new ComparisonExpression(ComparisonExpression.Operator.GREATER_THAN, new Identifier("a"), new LongLiteral("3")), - new LongLiteral("23")), - new WhenClause( - new ComparisonExpression(ComparisonExpression.Operator.EQUAL, new Identifier("b"), new Identifier("a")), - new LongLiteral("33"))), - Optional.empty())); - } - - @Test - public void testSetSession() - { - assertStatement("SET SESSION foo = 'bar'", new SetSession(QualifiedName.of("foo"), new StringLiteral("bar"))); - assertStatement("SET SESSION foo.bar = 'baz'", new SetSession(QualifiedName.of("foo", "bar"), new StringLiteral("baz"))); - assertStatement("SET SESSION foo.bar.boo = 'baz'", new SetSession(QualifiedName.of("foo", "bar", "boo"), new StringLiteral("baz"))); - - assertStatement("SET SESSION foo.bar = 'ban' || 'ana'", new SetSession( - QualifiedName.of("foo", "bar"), - new FunctionCall(QualifiedName.of("concat"), ImmutableList.of( - new StringLiteral("ban"), - new StringLiteral("ana"))))); - } - - @Test - public void testResetSession() - { - assertStatement("RESET SESSION foo.bar", new ResetSession(QualifiedName.of("foo", "bar"))); - assertStatement("RESET SESSION foo", new ResetSession(QualifiedName.of("foo"))); - } - - @Test - public void testSessionIdentifiers() - { - assertStatement("SET SESSION \"foo-bar\".baz = 'x'", - new SetSession(QualifiedName.of("foo-bar", "baz"), new StringLiteral("x"))); - assertStatementIsInvalid("SET SESSION foo-bar.name = 'value'") - .withMessage("line 1:16: mismatched input '-'. Expecting: '.', '='"); - - assertStatement("RESET SESSION \"foo-bar\".baz", - new ResetSession(QualifiedName.of("foo-bar", "baz"))); - assertStatementIsInvalid("RESET SESSION foo-bar.name") - .withMessage("line 1:18: mismatched input '-'. Expecting: '.', "); - } - - @Test - public void testShowSession() - { - assertStatement("SHOW SESSION", new ShowSession(Optional.empty(), Optional.empty())); - assertStatement("SHOW SESSION LIKE '%'", new ShowSession(Optional.of("%"), Optional.empty())); - assertStatement("SHOW SESSION LIKE '%' ESCAPE '$'", new ShowSession(Optional.of("%"), Optional.of("$"))); - } - - @Test - public void testShowCatalogs() - { - assertStatement("SHOW CATALOGS", new ShowCatalogs(Optional.empty(), Optional.empty())); - assertStatement("SHOW CATALOGS LIKE '%'", new ShowCatalogs(Optional.of("%"), Optional.empty())); - assertStatement("SHOW CATALOGS LIKE '%$_%' ESCAPE '$'", new ShowCatalogs(Optional.of("%$_%"), Optional.of("$"))); - } - - @Test - public void testShowSchemas() - { - assertStatement("SHOW SCHEMAS", new ShowSchemas(Optional.empty(), Optional.empty(), Optional.empty())); - assertStatement("SHOW SCHEMAS FROM foo", new ShowSchemas(Optional.of(identifier("foo")), Optional.empty(), Optional.empty())); - assertStatement("SHOW SCHEMAS IN foo LIKE '%'", new ShowSchemas(Optional.of(identifier("foo")), Optional.of("%"), Optional.empty())); - assertStatement("SHOW SCHEMAS IN foo LIKE '%$_%' ESCAPE '$'", new ShowSchemas(Optional.of(identifier("foo")), Optional.of("%$_%"), Optional.of("$"))); - } - - @Test - public void testShowTables() - { - assertStatement("SHOW TABLES", new ShowTables(Optional.empty(), Optional.empty(), Optional.empty())); - assertStatement("SHOW TABLES FROM a", new ShowTables(Optional.of(QualifiedName.of("a")), Optional.empty(), Optional.empty())); - assertStatement("SHOW TABLES FROM \"awesome schema\"", new ShowTables(Optional.of(QualifiedName.of("awesome schema")), Optional.empty(), Optional.empty())); - assertStatement("SHOW TABLES IN a LIKE '%$_%' ESCAPE '$'", new ShowTables(Optional.of(QualifiedName.of("a")), Optional.of("%$_%"), Optional.of("$"))); - } - - @Test - public void testShowColumns() - { - assertStatement("SHOW COLUMNS FROM a", new ShowColumns(QualifiedName.of("a"), Optional.empty(), Optional.empty())); - assertStatement("SHOW COLUMNS FROM a.b", new ShowColumns(QualifiedName.of("a", "b"), Optional.empty(), Optional.empty())); - assertStatement("SHOW COLUMNS FROM \"awesome table\"", new ShowColumns(QualifiedName.of("awesome table"), Optional.empty(), Optional.empty())); - assertStatement("SHOW COLUMNS FROM \"awesome schema\".\"awesome table\"", new ShowColumns(QualifiedName.of("awesome schema", "awesome table"), Optional.empty(), Optional.empty())); - assertStatement("SHOW COLUMNS FROM a.b LIKE '%$_%' ESCAPE '$'", new ShowColumns(QualifiedName.of("a", "b"), Optional.of("%$_%"), Optional.of("$"))); - - assertStatementIsInvalid("SHOW COLUMNS FROM a.b LIKE null") - .withMessage("line 1:28: mismatched input 'null'. Expecting: "); - - assertStatementIsInvalid("SHOW COLUMNS FROM a.b LIKE 'a' ESCAPE null'") - .withMessage("line 1:39: mismatched input 'null'. Expecting: "); - } - - @Test - public void testShowFunctions() - { - assertStatement("SHOW FUNCTIONS", new ShowFunctions(Optional.empty(), Optional.empty())); - assertStatement("SHOW FUNCTIONS LIKE '%'", new ShowFunctions(Optional.of("%"), Optional.empty())); - assertStatement("SHOW FUNCTIONS LIKE '%' ESCAPE '$'", new ShowFunctions(Optional.of("%"), Optional.of("$"))); - } - - @Test - public void testSubstringBuiltInFunction() - { - String givenString = "ABCDEF"; - assertStatement(format("SELECT substring('%s' FROM 2)", givenString), - simpleQuery(selectList( - new FunctionCall(QualifiedName.of("substr"), Lists.newArrayList(new StringLiteral(givenString), new LongLiteral("2")))))); - - assertStatement(format("SELECT substring('%s' FROM 2 FOR 3)", givenString), - simpleQuery(selectList( - new FunctionCall(QualifiedName.of("substr"), Lists.newArrayList(new StringLiteral(givenString), new LongLiteral("2"), new LongLiteral("3")))))); - } - - @Test - public void testSubstringRegisteredFunction() - { - String givenString = "ABCDEF"; - assertStatement(format("SELECT substring('%s', 2)", givenString), - simpleQuery(selectList( - new FunctionCall(QualifiedName.of("substring"), Lists.newArrayList(new StringLiteral(givenString), new LongLiteral("2")))))); - - assertStatement(format("SELECT substring('%s', 2, 3)", givenString), - simpleQuery(selectList( - new FunctionCall(QualifiedName.of("substring"), Lists.newArrayList(new StringLiteral(givenString), new LongLiteral("2"), new LongLiteral("3")))))); - } - - @Test - public void testSelectWithRowType() - { - assertStatement("SELECT col1.f1, col2, col3.f1.f2.f3 FROM table1", - simpleQuery( - selectList( - new DereferenceExpression(new Identifier("col1"), identifier("f1")), - new Identifier("col2"), - new DereferenceExpression( - new DereferenceExpression(new DereferenceExpression(new Identifier("col3"), identifier("f1")), identifier("f2")), identifier("f3"))), - new Table(QualifiedName.of("table1")))); - - assertStatement("SELECT col1.f1[0], col2, col3[2].f2.f3, col4[4] FROM table1", - simpleQuery( - selectList( - new SubscriptExpression(new DereferenceExpression(new Identifier("col1"), identifier("f1")), new LongLiteral("0")), - new Identifier("col2"), - new DereferenceExpression(new DereferenceExpression(new SubscriptExpression(new Identifier("col3"), new LongLiteral("2")), identifier("f2")), identifier("f3")), - new SubscriptExpression(new Identifier("col4"), new LongLiteral("4"))), - new Table(QualifiedName.of("table1")))); - - assertStatement("SELECT CAST(ROW(11, 12) AS ROW(COL0 INTEGER, COL1 INTEGER)).col0", - simpleQuery( - selectList( - new DereferenceExpression( - new Cast( - new Row(Lists.newArrayList(new LongLiteral("11"), new LongLiteral("12"))), - rowType(location(1, 26), - field(location(1, 30), "COL0", simpleType(location(1, 35), "INTEGER")), - field(location(1, 44), "COL1", simpleType(location(1, 49), "INTEGER")))), - identifier("col0"))))); - } - - @Test - public void testSelectWithOrderBy() - { - assertStatement("SELECT * FROM table1 ORDER BY a", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - ordering(ascending("a")))); - } - - @Test - public void testSelectWithOffset() - { - assertStatement("SELECT * FROM table1 OFFSET 2 ROWS", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Offset(new LongLiteral("2"))), - Optional.empty())); - - assertStatement("SELECT * FROM table1 OFFSET 2", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Offset(new LongLiteral("2"))), - Optional.empty())); - - Query valuesQuery = query(values( - row(new LongLiteral("1"), new StringLiteral("1")), - row(new LongLiteral("2"), new StringLiteral("2")))); - - assertStatement("SELECT * FROM (VALUES (1, '1'), (2, '2')) OFFSET 2 ROWS", - simpleQuery(selectList(new AllColumns()), - subquery(valuesQuery), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Offset(new LongLiteral("2"))), - Optional.empty())); - - assertStatement("SELECT * FROM (VALUES (1, '1'), (2, '2')) OFFSET 2", - simpleQuery(selectList(new AllColumns()), - subquery(valuesQuery), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Offset(new LongLiteral("2"))), - Optional.empty())); - } - - @Test - public void testSelectWithFetch() - { - assertStatement("SELECT * FROM table1 FETCH FIRST 2 ROWS ONLY", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new FetchFirst(new LongLiteral("2"))))); - - assertStatement("SELECT * FROM table1 FETCH NEXT ROW ONLY", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new FetchFirst(Optional.empty())))); - - Query valuesQuery = query(values( - row(new LongLiteral("1"), new StringLiteral("1")), - row(new LongLiteral("2"), new StringLiteral("2")))); - - assertStatement("SELECT * FROM (VALUES (1, '1'), (2, '2')) FETCH FIRST ROW ONLY", - simpleQuery( - selectList(new AllColumns()), - subquery(valuesQuery), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new FetchFirst(Optional.empty())))); - - assertStatement("SELECT * FROM (VALUES (1, '1'), (2, '2')) FETCH FIRST ROW WITH TIES", - simpleQuery( - selectList(new AllColumns()), - subquery(valuesQuery), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new FetchFirst(Optional.empty(), true)))); - - assertStatement("SELECT * FROM table1 FETCH FIRST 2 ROWS WITH TIES", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new FetchFirst(new LongLiteral("2"), true)))); - - assertStatement("SELECT * FROM table1 FETCH NEXT ROW WITH TIES", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new FetchFirst(Optional.empty(), true)))); - } - - @Test - public void testSelectWithGroupBy() - { - assertStatement("SELECT * FROM table1 GROUP BY a", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.of(new GroupBy(false, ImmutableList.of(new SimpleGroupBy(ImmutableList.of(new Identifier("a")))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - - assertStatement("SELECT * FROM table1 GROUP BY a, b", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.of(new GroupBy(false, ImmutableList.of( - new SimpleGroupBy(ImmutableList.of(new Identifier("a"))), - new SimpleGroupBy(ImmutableList.of(new Identifier("b")))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - - assertStatement("SELECT * FROM table1 GROUP BY ()", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.of(new GroupBy(false, ImmutableList.of(new SimpleGroupBy(ImmutableList.of())))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - - assertStatement("SELECT * FROM table1 GROUP BY GROUPING SETS (a)", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.of(new GroupBy(false, ImmutableList.of(new GroupingSets( - ImmutableList.of( - ImmutableList.of(new Identifier("a"))))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - - assertStatement("SELECT a, b, GROUPING(a, b) FROM table1 GROUP BY GROUPING SETS ((a), (b))", - simpleQuery( - selectList( - DereferenceExpression.from(QualifiedName.of("a")), - DereferenceExpression.from(QualifiedName.of("b")), - new GroupingOperation( - Optional.empty(), - ImmutableList.of(QualifiedName.of("a"), QualifiedName.of("b")))), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.of(new GroupBy(false, ImmutableList.of(new GroupingSets( - ImmutableList.of( - ImmutableList.of(new Identifier("a")), - ImmutableList.of(new Identifier("b"))))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - - assertStatement("SELECT * FROM table1 GROUP BY ALL GROUPING SETS ((a, b), (a), ()), CUBE (c), ROLLUP (d)", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.of(new GroupBy(false, ImmutableList.of( - new GroupingSets( - ImmutableList.of( - ImmutableList.of(new Identifier("a"), new Identifier("b")), - ImmutableList.of(new Identifier("a")), - ImmutableList.of())), - new Cube(ImmutableList.of(new Identifier("c"))), - new Rollup(ImmutableList.of(new Identifier("d")))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - - assertStatement("SELECT * FROM table1 GROUP BY DISTINCT GROUPING SETS ((a, b), (a), ()), CUBE (c), ROLLUP (d)", - simpleQuery( - selectList(new AllColumns()), - new Table(QualifiedName.of("table1")), - Optional.empty(), - Optional.of(new GroupBy(true, ImmutableList.of( - new GroupingSets( - ImmutableList.of( - ImmutableList.of(new Identifier("a"), new Identifier("b")), - ImmutableList.of(new Identifier("a")), - ImmutableList.of())), - new Cube(ImmutableList.of(new Identifier("c"))), - new Rollup(ImmutableList.of(new Identifier("d")))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty())); - } - - @Test - public void testCreateSchema() - { - assertStatement("CREATE SCHEMA test", - new CreateSchema(QualifiedName.of("test"), false, ImmutableList.of())); - - assertStatement("CREATE SCHEMA IF NOT EXISTS test", - new CreateSchema(QualifiedName.of("test"), true, ImmutableList.of())); - - assertStatement("CREATE SCHEMA test WITH (a = 'apple', b = 123)", - new CreateSchema( - QualifiedName.of("test"), - false, - ImmutableList.of( - new Property(new Identifier("a"), new StringLiteral("apple")), - new Property(new Identifier("b"), new LongLiteral("123"))))); - - assertStatement("CREATE SCHEMA \"some name that contains space\"", - new CreateSchema(QualifiedName.of("some name that contains space"), false, ImmutableList.of())); - } - - @Test - public void testDropSchema() - { - assertStatement("DROP SCHEMA test", - new DropSchema(QualifiedName.of("test"), false, false)); - - assertStatement("DROP SCHEMA test CASCADE", - new DropSchema(QualifiedName.of("test"), false, true)); - - assertStatement("DROP SCHEMA IF EXISTS test", - new DropSchema(QualifiedName.of("test"), true, false)); - - assertStatement("DROP SCHEMA IF EXISTS test RESTRICT", - new DropSchema(QualifiedName.of("test"), true, false)); - - assertStatement("DROP SCHEMA \"some schema that contains space\"", - new DropSchema(QualifiedName.of("some schema that contains space"), false, false)); - } - - @Test - public void testRenameSchema() - { - assertStatement("ALTER SCHEMA foo RENAME TO bar", - new RenameSchema(QualifiedName.of("foo"), identifier("bar"))); - - assertStatement("ALTER SCHEMA foo.bar RENAME TO baz", - new RenameSchema(QualifiedName.of("foo", "bar"), identifier("baz"))); - - assertStatement("ALTER SCHEMA \"awesome schema\".\"awesome table\" RENAME TO \"even more awesome table\"", - new RenameSchema(QualifiedName.of("awesome schema", "awesome table"), quotedIdentifier("even more awesome table"))); - } - - @Test - public void testUnicodeString() - { - assertExpression("U&''", new StringLiteral("")); - assertExpression("U&'' UESCAPE ')'", new StringLiteral("")); - assertExpression("U&'hello\\6d4B\\8Bd5\\+10FFFFworld\\7F16\\7801'", new StringLiteral("hello\u6d4B\u8Bd5\uDBFF\uDFFFworld\u7F16\u7801")); - assertExpression("U&'\u6d4B\u8Bd5ABC\\6d4B\\8Bd5'", new StringLiteral("\u6d4B\u8Bd5ABC\u6d4B\u8Bd5")); - assertExpression("u&'\u6d4B\u8Bd5ABC\\6d4B\\8Bd5'", new StringLiteral("\u6d4B\u8Bd5ABC\u6d4B\u8Bd5")); - assertExpression("u&'\u6d4B\u8Bd5ABC\\\\'", new StringLiteral("\u6d4B\u8Bd5ABC\\")); - assertExpression("u&'\u6d4B\u8Bd5ABC###8Bd5' UESCAPE '#'", new StringLiteral("\u6d4B\u8Bd5ABC#\u8Bd5")); - assertExpression("u&'\u6d4B\u8Bd5''A''B''C##''''#8Bd5' UESCAPE '#'", new StringLiteral("\u6d4B\u8Bd5\'A\'B\'C#\'\'\u8Bd5")); - assertInvalidExpression("U& '\u6d4B\u8Bd5ABC\\\\'", ".*mismatched input.*"); - assertInvalidExpression("u&'\u6d4B\u8Bd5ABC\\'", "Incomplete escape sequence: "); - assertInvalidExpression("u&'\u6d4B\u8Bd5ABC\\+'", "Incomplete escape sequence: "); - assertInvalidExpression("U&'hello\\6dB\\8Bd5'", "Incomplete escape sequence: 6dB.*"); - assertInvalidExpression("U&'hello\\6D4B\\8Bd'", "Incomplete escape sequence: 8Bd"); - assertInvalidExpression("U&'hello\\K6B\\8Bd5'", "Invalid hexadecimal digit: K"); - assertInvalidExpression("U&'hello\\+FFFFFD\\8Bd5'", "Invalid escaped character: FFFFFD"); - assertInvalidExpression("U&'hello\\DBFF'", "Invalid escaped character: DBFF\\. Escaped character is a surrogate\\. Use \'\\\\\\+123456\' instead\\."); - assertInvalidExpression("U&'hello\\+00DBFF'", "Invalid escaped character: 00DBFF\\. Escaped character is a surrogate\\. Use \'\\\\\\+123456\' instead\\."); - assertInvalidExpression("U&'hello\\8Bd5' UESCAPE '%%'", "Invalid Unicode escape character: %%"); - assertInvalidExpression("U&'hello\\8Bd5' UESCAPE '\uDBFF'", "Invalid Unicode escape character: \uDBFF"); - assertInvalidExpression("U&'hello\\8Bd5' UESCAPE '\n'", "Invalid Unicode escape character: \n"); - assertInvalidExpression("U&'hello\\8Bd5' UESCAPE ''''", "Invalid Unicode escape character: \'"); - assertInvalidExpression("U&'hello\\8Bd5' UESCAPE ' '", "Invalid Unicode escape character: "); - assertInvalidExpression("U&'hello\\8Bd5' UESCAPE ''", "Empty Unicode escape character"); - assertInvalidExpression("U&'hello\\8Bd5' UESCAPE '1'", "Invalid Unicode escape character: 1"); - assertInvalidExpression("U&'hello\\8Bd5' UESCAPE '+'", "Invalid Unicode escape character: \\+"); - assertExpression("U&'hello!6d4B!8Bd5!+10FFFFworld!7F16!7801' UESCAPE '!'", new StringLiteral("hello\u6d4B\u8Bd5\uDBFF\uDFFFworld\u7F16\u7801")); - assertExpression("U&'\u6d4B\u8Bd5ABC!6d4B!8Bd5' UESCAPE '!'", new StringLiteral("\u6d4B\u8Bd5ABC\u6d4B\u8Bd5")); - assertExpression("U&'hello\\6d4B\\8Bd5\\+10FFFFworld\\7F16\\7801' UESCAPE '!'", - new StringLiteral("hello\\6d4B\\8Bd5\\+10FFFFworld\\7F16\\7801")); - } - - @Test - public void testCreateTable() - { - assertThat(statement("CREATE TABLE foo (a VARCHAR, b BIGINT COMMENT 'hello world', c IPADDRESS)")) - .isEqualTo(new CreateTable( - location(1, 1), - qualifiedName(location(1, 14), "foo"), - ImmutableList.of( - columnDefinition(location(1, 19), "a", simpleType(location(1, 21), "VARCHAR")), - columnDefinition(location(1, 30), "b", simpleType(location(1, 32), "BIGINT"), true, "hello world"), - columnDefinition(location(1, 62), "c", simpleType(location(1, 64), "IPADDRESS"))), - false, - ImmutableList.of(), - Optional.empty())); - - assertThat(statement("CREATE TABLE IF NOT EXISTS bar (c TIMESTAMP)")) - .isEqualTo(new CreateTable( - location(1, 1), - qualifiedName(location(1, 28), "bar"), - ImmutableList.of( - columnDefinition(location(1, 33), "c", dateTimeType(location(1, 35), TIMESTAMP, false), true)), - true, - ImmutableList.of(), - Optional.empty())); - - assertThat(statement("CREATE TABLE IF NOT EXISTS bar (c VARCHAR WITH (nullable = true, compression = 'LZ4'))")) - .describedAs("CREATE TABLE with column properties") - .isEqualTo( - new CreateTable( - location(1, 1), - qualifiedName(location(1, 28), "bar"), - ImmutableList.of( - columnDefinition( - location(1, 33), - "c", - simpleType(location(1, 35), "VARCHAR"), - true, - ImmutableList.of( - property(location(1, 49), "nullable", new BooleanLiteral(location(1, 60), "true")), - property(location(1, 66), "compression", new StringLiteral(location(1, 80), "LZ4"))))), - true, - ImmutableList.of(), - Optional.empty())); - - // with LIKE - assertStatement("CREATE TABLE IF NOT EXISTS bar (LIKE like_table)", - new CreateTable(QualifiedName.of("bar"), - ImmutableList.of( - new LikeClause(QualifiedName.of("like_table"), - Optional.empty())), - true, - ImmutableList.of(), - Optional.empty())); - - assertThat(statement("CREATE TABLE IF NOT EXISTS bar (c VARCHAR, LIKE like_table)")) - .ignoringLocation() - .isEqualTo(new CreateTable(QualifiedName.of("bar"), - ImmutableList.of( - new ColumnDefinition(identifier("c"), simpleType(location(1, 35), "VARCHAR"), true, emptyList(), Optional.empty()), - new LikeClause(QualifiedName.of("like_table"), - Optional.empty())), - true, - ImmutableList.of(), - Optional.empty())); - - assertThat(statement("CREATE TABLE IF NOT EXISTS bar (c VARCHAR, LIKE like_table, d BIGINT)")) - .ignoringLocation() - .isEqualTo(new CreateTable(QualifiedName.of("bar"), - ImmutableList.of( - new ColumnDefinition(identifier("c"), simpleType(location(1, 35), "VARCHAR"), true, emptyList(), Optional.empty()), - new LikeClause(QualifiedName.of("like_table"), - Optional.empty()), - new ColumnDefinition(identifier("d"), simpleType(location(1, 63), "BIGINT"), true, emptyList(), Optional.empty())), - true, - ImmutableList.of(), - Optional.empty())); - - assertStatement("CREATE TABLE IF NOT EXISTS bar (LIKE like_table INCLUDING PROPERTIES)", - new CreateTable(QualifiedName.of("bar"), - ImmutableList.of( - new LikeClause(QualifiedName.of("like_table"), - Optional.of(LikeClause.PropertiesOption.INCLUDING))), - true, - ImmutableList.of(), - Optional.empty())); - - assertThat(statement("CREATE TABLE IF NOT EXISTS bar (c VARCHAR, LIKE like_table EXCLUDING PROPERTIES)")) - .ignoringLocation() - .isEqualTo(new CreateTable(QualifiedName.of("bar"), - ImmutableList.of( - new ColumnDefinition(identifier("c"), simpleType(location(1, 35), "VARCHAR"), true, emptyList(), Optional.empty()), - new LikeClause(QualifiedName.of("like_table"), - Optional.of(LikeClause.PropertiesOption.EXCLUDING))), - true, - ImmutableList.of(), - Optional.empty())); - - assertThat(statement("CREATE TABLE IF NOT EXISTS bar (c VARCHAR, LIKE like_table EXCLUDING PROPERTIES) COMMENT 'test'")) - .ignoringLocation() - .isEqualTo(new CreateTable(QualifiedName.of("bar"), - ImmutableList.of( - new ColumnDefinition(identifier("c"), simpleType(location(1, 35), "VARCHAR"), true, emptyList(), Optional.empty()), - new LikeClause(QualifiedName.of("like_table"), - Optional.of(LikeClause.PropertiesOption.EXCLUDING))), - true, - ImmutableList.of(), - Optional.of("test"))); - } - - @Test - public void testCreateTableWithNotNull() - { - assertThat(statement( - "CREATE TABLE foo (" + - "a VARCHAR NOT NULL COMMENT 'column a', " + - "b BIGINT COMMENT 'hello world', " + - "c IPADDRESS, " + - "d INTEGER NOT NULL)")) - .ignoringLocation() - .isEqualTo(new CreateTable( - QualifiedName.of("foo"), - ImmutableList.of( - new ColumnDefinition(identifier("a"), simpleType(location(1, 20), "VARCHAR"), false, emptyList(), Optional.of("column a")), - new ColumnDefinition(identifier("b"), simpleType(location(1, 59), "BIGINT"), true, emptyList(), Optional.of("hello world")), - new ColumnDefinition(identifier("c"), simpleType(location(1, 91), "IPADDRESS"), true, emptyList(), Optional.empty()), - new ColumnDefinition(identifier("d"), simpleType(location(1, 104), "INTEGER"), false, emptyList(), Optional.empty())), - false, - ImmutableList.of(), - Optional.empty())); - } - - @Test - public void testCreateTableAsSelect() - { - Query query = simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))); - Query querySelectColumn = simpleQuery(selectList(new Identifier("a")), table(QualifiedName.of("t"))); - Query querySelectColumns = simpleQuery(selectList(new Identifier("a"), new Identifier("b")), table(QualifiedName.of("t"))); - QualifiedName table = QualifiedName.of("foo"); - - assertStatement("CREATE TABLE foo AS SELECT * FROM t", - new CreateTableAsSelect(table, query, false, ImmutableList.of(), true, Optional.empty(), Optional.empty())); - assertStatement("CREATE TABLE foo(x) AS SELECT a FROM t", - new CreateTableAsSelect(table, querySelectColumn, false, ImmutableList.of(), true, Optional.of(ImmutableList.of(new Identifier("x"))), Optional.empty())); - assertStatement("CREATE TABLE foo(x,y) AS SELECT a,b FROM t", - new CreateTableAsSelect(table, querySelectColumns, false, ImmutableList.of(), true, Optional.of(ImmutableList.of(new Identifier("x"), new Identifier("y"))), Optional.empty())); - - assertStatement("CREATE TABLE IF NOT EXISTS foo AS SELECT * FROM t", - new CreateTableAsSelect(table, query, true, ImmutableList.of(), true, Optional.empty(), Optional.empty())); - assertStatement("CREATE TABLE IF NOT EXISTS foo(x) AS SELECT a FROM t", - new CreateTableAsSelect(table, querySelectColumn, true, ImmutableList.of(), true, Optional.of(ImmutableList.of(new Identifier("x"))), Optional.empty())); - assertStatement("CREATE TABLE IF NOT EXISTS foo(x,y) AS SELECT a,b FROM t", - new CreateTableAsSelect(table, querySelectColumns, true, ImmutableList.of(), true, Optional.of(ImmutableList.of(new Identifier("x"), new Identifier("y"))), Optional.empty())); - - assertStatement("CREATE TABLE foo AS SELECT * FROM t WITH NO DATA", - new CreateTableAsSelect(table, query, false, ImmutableList.of(), false, Optional.empty(), Optional.empty())); - assertStatement("CREATE TABLE foo(x) AS SELECT a FROM t WITH NO DATA", - new CreateTableAsSelect(table, querySelectColumn, false, ImmutableList.of(), false, Optional.of(ImmutableList.of(new Identifier("x"))), Optional.empty())); - assertStatement("CREATE TABLE foo(x,y) AS SELECT a,b FROM t WITH NO DATA", - new CreateTableAsSelect(table, querySelectColumns, false, ImmutableList.of(), false, Optional.of(ImmutableList.of(new Identifier("x"), new Identifier("y"))), Optional.empty())); - - List properties = ImmutableList.of( - new Property(new Identifier("string"), new StringLiteral("bar")), - new Property(new Identifier("long"), new LongLiteral("42")), - new Property( - new Identifier("computed"), - new FunctionCall(QualifiedName.of("concat"), ImmutableList.of(new StringLiteral("ban"), new StringLiteral("ana")))), - new Property(new Identifier("a"), new ArrayConstructor(ImmutableList.of(new StringLiteral("v1"), new StringLiteral("v2"))))); - - assertStatement("CREATE TABLE foo " + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT * FROM t", - new CreateTableAsSelect(table, query, false, properties, true, Optional.empty(), Optional.empty())); - assertStatement("CREATE TABLE foo(x) " + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT a FROM t", - new CreateTableAsSelect(table, querySelectColumn, false, properties, true, Optional.of(ImmutableList.of(new Identifier("x"))), Optional.empty())); - assertStatement("CREATE TABLE foo(x,y) " + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT a,b FROM t", - new CreateTableAsSelect(table, querySelectColumns, false, properties, true, Optional.of(ImmutableList.of(new Identifier("x"), new Identifier("y"))), Optional.empty())); - - assertStatement("CREATE TABLE foo " + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT * FROM t " + - "WITH NO DATA", - new CreateTableAsSelect(table, query, false, properties, false, Optional.empty(), Optional.empty())); - assertStatement("CREATE TABLE foo(x) " + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT a FROM t " + - "WITH NO DATA", - new CreateTableAsSelect(table, querySelectColumn, false, properties, false, Optional.of(ImmutableList.of(new Identifier("x"))), Optional.empty())); - assertStatement("CREATE TABLE foo(x,y) " + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT a,b FROM t " + - "WITH NO DATA", - new CreateTableAsSelect(table, querySelectColumns, false, properties, false, Optional.of(ImmutableList.of(new Identifier("x"), new Identifier("y"))), Optional.empty())); - - assertStatement("CREATE TABLE foo COMMENT 'test'" + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT * FROM t " + - "WITH NO DATA", - new CreateTableAsSelect(table, query, false, properties, false, Optional.empty(), Optional.of("test"))); - assertStatement("CREATE TABLE foo(x) COMMENT 'test'" + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT a FROM t " + - "WITH NO DATA", - new CreateTableAsSelect(table, querySelectColumn, false, properties, false, Optional.of(ImmutableList.of(new Identifier("x"))), Optional.of("test"))); - assertStatement("CREATE TABLE foo(x,y) COMMENT 'test'" + - "WITH ( string = 'bar', long = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT a,b FROM t " + - "WITH NO DATA", - new CreateTableAsSelect(table, querySelectColumns, false, properties, false, Optional.of(ImmutableList.of(new Identifier("x"), new Identifier("y"))), Optional.of("test"))); - assertStatement("CREATE TABLE foo(x,y) COMMENT 'test'" + - "WITH ( \"string\" = 'bar', \"long\" = 42, computed = 'ban' || 'ana', a = ARRAY[ 'v1', 'v2' ] ) " + - "AS " + - "SELECT a,b FROM t " + - "WITH NO DATA", - new CreateTableAsSelect(table, querySelectColumns, false, properties, false, Optional.of(ImmutableList.of(new Identifier("x"), new Identifier("y"))), Optional.of("test"))); - } - - @Test - public void testCreateTableAsWith() - { - String queryParenthesizedWith = "CREATE TABLE foo " + - "AS " + - "( WITH t(x) AS (VALUES 1) " + - "TABLE t ) " + - "WITH NO DATA"; - String queryUnparenthesizedWith = "CREATE TABLE foo " + - "AS " + - "WITH t(x) AS (VALUES 1) " + - "TABLE t " + - "WITH NO DATA"; - String queryParenthesizedWithHasAlias = "CREATE TABLE foo(a) " + - "AS " + - "( WITH t(x) AS (VALUES 1) " + - "TABLE t ) " + - "WITH NO DATA"; - String queryUnparenthesizedWithHasAlias = "CREATE TABLE foo(a) " + - "AS " + - "WITH t(x) AS (VALUES 1) " + - "TABLE t " + - "WITH NO DATA"; - - QualifiedName table = QualifiedName.of("foo"); - - Query query = new Query( - Optional.of(new With(false, ImmutableList.of( - new WithQuery( - identifier("t"), - query(new Values(ImmutableList.of(new LongLiteral("1")))), - Optional.of(ImmutableList.of(identifier("x"))))))), - new Table(QualifiedName.of("t")), - Optional.empty(), - Optional.empty(), - Optional.empty()); - assertStatement(queryParenthesizedWith, new CreateTableAsSelect(table, query, false, ImmutableList.of(), false, Optional.empty(), Optional.empty())); - assertStatement(queryUnparenthesizedWith, new CreateTableAsSelect(table, query, false, ImmutableList.of(), false, Optional.empty(), Optional.empty())); - assertStatement(queryParenthesizedWithHasAlias, new CreateTableAsSelect(table, query, false, ImmutableList.of(), false, Optional.of(ImmutableList.of(new Identifier("a"))), Optional.empty())); - assertStatement(queryUnparenthesizedWithHasAlias, new CreateTableAsSelect(table, query, false, ImmutableList.of(), false, Optional.of(ImmutableList.of(new Identifier("a"))), Optional.empty())); - } - - @Test - public void testDropTable() - { - assertStatement("DROP TABLE a", new DropTable(QualifiedName.of("a"), false)); - assertStatement("DROP TABLE a.b", new DropTable(QualifiedName.of("a", "b"), false)); - assertStatement("DROP TABLE a.b.c", new DropTable(QualifiedName.of("a", "b", "c"), false)); - assertStatement("DROP TABLE a.\"b/y\".c", new DropTable(QualifiedName.of("a", "b/y", "c"), false)); - - assertStatement("DROP TABLE IF EXISTS a", new DropTable(QualifiedName.of("a"), true)); - assertStatement("DROP TABLE IF EXISTS a.b", new DropTable(QualifiedName.of("a", "b"), true)); - assertStatement("DROP TABLE IF EXISTS a.b.c", new DropTable(QualifiedName.of("a", "b", "c"), true)); - assertStatement("DROP TABLE IF EXISTS a.\"b/y\".c", new DropTable(QualifiedName.of("a", "b/y", "c"), true)); - } - - @Test - public void testTruncateTable() - throws Exception - { - assertStatement("TRUNCATE TABLE a", new TruncateTable(QualifiedName.of("a"))); - assertStatement("TRUNCATE TABLE a.b", new TruncateTable(QualifiedName.of("a", "b"))); - assertStatement("TRUNCATE TABLE a.b.c", new TruncateTable(QualifiedName.of("a", "b", "c"))); - } - - @Test - public void testDropView() - { - assertStatement("DROP VIEW a", new DropView(QualifiedName.of("a"), false)); - assertStatement("DROP VIEW a.b", new DropView(QualifiedName.of("a", "b"), false)); - assertStatement("DROP VIEW a.b.c", new DropView(QualifiedName.of("a", "b", "c"), false)); - - assertStatement("DROP VIEW IF EXISTS a", new DropView(QualifiedName.of("a"), true)); - assertStatement("DROP VIEW IF EXISTS a.b", new DropView(QualifiedName.of("a", "b"), true)); - assertStatement("DROP VIEW IF EXISTS a.b.c", new DropView(QualifiedName.of("a", "b", "c"), true)); - } - - @Test - public void testInsertInto() - { - Table table = new Table(QualifiedName.of("a", "b/c", "d")); - Query query = simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))); - - assertStatement("INSERT INTO a.\"b/c\".d SELECT * FROM t", - new Insert(table, Optional.empty(), query)); - - assertStatement("INSERT INTO a.\"b/c\".d (c1, c2) SELECT * FROM t", - new Insert(table, Optional.of(ImmutableList.of(identifier("c1"), identifier("c2"))), query)); - } - - @Test - public void testDelete() - { - assertStatement("DELETE FROM t", new Delete(table(QualifiedName.of("t")), Optional.empty())); - assertStatement("DELETE FROM \"awesome table\"", new Delete(table(QualifiedName.of("awesome table")), Optional.empty())); - - assertStatement("DELETE FROM t WHERE a = b", new Delete(table(QualifiedName.of("t")), Optional.of( - new ComparisonExpression(ComparisonExpression.Operator.EQUAL, - new Identifier("a"), - new Identifier("b"))))); - } - - @Test - public void testMerge() - { - assertStatement("" + - "MERGE INTO inventory AS i " + - " USING changes AS c " + - " ON i.part = c.part " + - "WHEN MATCHED AND c.action = 'mod' " + - " THEN UPDATE SET " + - " qty = qty + c.qty " + - " , ts = CURRENT_TIMESTAMP " + - "WHEN MATCHED AND c.action = 'del' " + - " THEN DELETE " + - "WHEN NOT MATCHED AND c.action = 'new' " + - " THEN INSERT (part, qty) VALUES (c.part, c.qty)", - new Merge( - table(QualifiedName.of("inventory")), - Optional.of(new Identifier("i")), - aliased(table(QualifiedName.of("changes")), "c"), - equal(nameReference("i", "part"), nameReference("c", "part")), - ImmutableList.of( - new MergeUpdate( - Optional.of(equal(nameReference("c", "action"), new StringLiteral("mod"))), - ImmutableList.of( - new MergeUpdate.Assignment(new Identifier("qty"), new ArithmeticBinaryExpression( - ArithmeticBinaryExpression.Operator.ADD, - nameReference("qty"), - nameReference("c", "qty"))), - new MergeUpdate.Assignment(new Identifier("ts"), new CurrentTime(CurrentTime.Function.TIMESTAMP)))), - new MergeDelete( - Optional.of(equal(nameReference("c", "action"), new StringLiteral("del")))), - new MergeInsert( - Optional.of(equal(nameReference("c", "action"), new StringLiteral("new"))), - ImmutableList.of(new Identifier("part"), new Identifier("qty")), - ImmutableList.of(nameReference("c", "part"), nameReference("c", "qty")))))); - } - - @Test - public void testRenameTable() - { - assertStatement("ALTER TABLE a RENAME TO b", new RenameTable(QualifiedName.of("a"), QualifiedName.of("b"), false)); - assertStatement("ALTER TABLE IF EXISTS a RENAME TO b", new RenameTable(QualifiedName.of("a"), QualifiedName.of("b"), true)); - } - - @Test - public void testSetTableProperties() - { - assertStatement("ALTER TABLE a SET PROPERTIES foo='bar'", new SetProperties(SetProperties.Type.TABLE, QualifiedName.of("a"), ImmutableList.of(new Property(new Identifier("foo"), new StringLiteral("bar"))))); - assertStatement("ALTER TABLE a SET PROPERTIES foo=true", new SetProperties(SetProperties.Type.TABLE, QualifiedName.of("a"), ImmutableList.of(new Property(new Identifier("foo"), new BooleanLiteral("true"))))); - assertStatement("ALTER TABLE a SET PROPERTIES foo=123", new SetProperties(SetProperties.Type.TABLE, QualifiedName.of("a"), ImmutableList.of(new Property(new Identifier("foo"), new LongLiteral("123"))))); - assertStatement("ALTER TABLE a SET PROPERTIES foo=123, bar=456", new SetProperties(SetProperties.Type.TABLE, QualifiedName.of("a"), ImmutableList.of(new Property(new Identifier("foo"), new LongLiteral("123")), new Property(new Identifier("bar"), new LongLiteral("456"))))); - assertStatement("ALTER TABLE a SET PROPERTIES \" s p a c e \"='bar'", new SetProperties(SetProperties.Type.TABLE, QualifiedName.of("a"), ImmutableList.of(new Property(new Identifier(" s p a c e "), new StringLiteral("bar"))))); - assertStatement("ALTER TABLE a SET PROPERTIES foo=123, bar=DEFAULT", new SetProperties(SetProperties.Type.TABLE, QualifiedName.of("a"), ImmutableList.of(new Property(new Identifier("foo"), new LongLiteral("123")), new Property(new Identifier("bar"))))); - - assertStatementIsInvalid("ALTER TABLE a SET PROPERTIES") - .withMessage("line 1:29: mismatched input ''. Expecting: "); - assertStatementIsInvalid("ALTER TABLE a SET PROPERTIES ()") - .withMessage("line 1:30: mismatched input '('. Expecting: "); - assertStatementIsInvalid("ALTER TABLE a SET PROPERTIES (foo='bar')") - .withMessage("line 1:30: mismatched input '('. Expecting: "); - } - - @Test - public void testCommentTable() - { - assertStatement("COMMENT ON TABLE a IS 'test'", new Comment(Comment.Type.TABLE, QualifiedName.of("a"), Optional.of("test"))); - assertStatement("COMMENT ON TABLE a IS ''", new Comment(Comment.Type.TABLE, QualifiedName.of("a"), Optional.of(""))); - assertStatement("COMMENT ON TABLE a IS NULL", new Comment(Comment.Type.TABLE, QualifiedName.of("a"), Optional.empty())); - } - - @Test - public void testCommentColumn() - { - assertStatement("COMMENT ON COLUMN a.b IS 'test'", new Comment(Comment.Type.COLUMN, QualifiedName.of("a", "b"), Optional.of("test"))); - assertStatement("COMMENT ON COLUMN a.b IS ''", new Comment(Comment.Type.COLUMN, QualifiedName.of("a", "b"), Optional.of(""))); - assertStatement("COMMENT ON COLUMN a.b IS NULL", new Comment(Comment.Type.COLUMN, QualifiedName.of("a", "b"), Optional.empty())); - - assertStatement("COMMENT ON COLUMN a IS 'test'", new Comment(Comment.Type.COLUMN, QualifiedName.of("a"), Optional.of("test"))); - assertStatement("COMMENT ON COLUMN a.b.c IS 'test'", new Comment(Comment.Type.COLUMN, QualifiedName.of("a", "b", "c"), Optional.of("test"))); - assertStatement("COMMENT ON COLUMN a.b.c.d IS 'test'", new Comment(Comment.Type.COLUMN, QualifiedName.of("a", "b", "c", "d"), Optional.of("test"))); - } - - @Test - public void testRenameColumn() - { - assertStatement("ALTER TABLE foo.t RENAME COLUMN a TO b", new RenameColumn(QualifiedName.of("foo", "t"), identifier("a"), identifier("b"), false, false)); - assertStatement("ALTER TABLE IF EXISTS foo.t RENAME COLUMN a TO b", new RenameColumn(QualifiedName.of("foo", "t"), identifier("a"), identifier("b"), true, false)); - assertStatement("ALTER TABLE foo.t RENAME COLUMN IF EXISTS a TO b", new RenameColumn(QualifiedName.of("foo", "t"), identifier("a"), identifier("b"), false, true)); - assertStatement("ALTER TABLE IF EXISTS foo.t RENAME COLUMN IF EXISTS a TO b", new RenameColumn(QualifiedName.of("foo", "t"), identifier("a"), identifier("b"), true, true)); - } - - @Test - public void testRenameView() - { - assertStatement("ALTER VIEW a RENAME TO b", new RenameView(QualifiedName.of("a"), QualifiedName.of("b"))); - } - - @Test - public void testAlterViewSetAuthorization() - { - assertStatement( - "ALTER VIEW foo.bar.baz SET AUTHORIZATION qux", - new SetViewAuthorization(QualifiedName.of("foo", "bar", "baz"), new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("qux")))); - assertStatement( - "ALTER VIEW foo.bar.baz SET AUTHORIZATION USER qux", - new SetViewAuthorization(QualifiedName.of("foo", "bar", "baz"), new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("qux")))); - assertStatement( - "ALTER VIEW foo.bar.baz SET AUTHORIZATION ROLE qux", - new SetViewAuthorization(QualifiedName.of("foo", "bar", "baz"), new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("qux")))); - } - - @Test - public void testTableExecute() - { - Table table = new Table(QualifiedName.of("foo")); - Identifier procedure = new Identifier("bar"); - - assertStatement("ALTER TABLE foo EXECUTE bar", new TableExecute(table, procedure, ImmutableList.of(), Optional.empty())); - assertStatement( - "ALTER TABLE foo EXECUTE bar(bah => 1, wuh => 'clap') WHERE age > 17", - new TableExecute( - table, - procedure, - ImmutableList.of( - new CallArgument(identifier("bah"), new LongLiteral("1")), - new CallArgument(identifier("wuh"), new StringLiteral("clap"))), - Optional.of( - new ComparisonExpression(ComparisonExpression.Operator.GREATER_THAN, - new Identifier("age"), - new LongLiteral("17"))))); - - assertStatement( - "ALTER TABLE foo EXECUTE bar(1, 'clap') WHERE age > 17", - new TableExecute( - table, - procedure, - ImmutableList.of( - new CallArgument(new LongLiteral("1")), - new CallArgument(new StringLiteral("clap"))), - Optional.of( - new ComparisonExpression(ComparisonExpression.Operator.GREATER_THAN, - new Identifier("age"), - new LongLiteral("17"))))); - } - - @Test - public void testAnalyze() - { - QualifiedName table = QualifiedName.of("foo"); - assertStatement("ANALYZE foo", new Analyze(table, ImmutableList.of())); - - assertStatement("ANALYZE foo WITH ( \"string\" = 'bar', \"long\" = 42, computed = concat('ban', 'ana'), a = ARRAY[ 'v1', 'v2' ] )", - new Analyze(table, ImmutableList.of( - new Property(new Identifier("string"), new StringLiteral("bar")), - new Property(new Identifier("long"), new LongLiteral("42")), - new Property( - new Identifier("computed"), - new FunctionCall(QualifiedName.of("concat"), ImmutableList.of(new StringLiteral("ban"), new StringLiteral("ana")))), - new Property(new Identifier("a"), new ArrayConstructor(ImmutableList.of(new StringLiteral("v1"), new StringLiteral("v2"))))))); - - assertStatement("EXPLAIN ANALYZE foo", new Explain(new Analyze(table, ImmutableList.of()), ImmutableList.of())); - assertStatement("EXPLAIN ANALYZE ANALYZE foo", new ExplainAnalyze(new Analyze(table, ImmutableList.of()), false)); - } - - @Test - public void testAddColumn() - { - assertThat(statement("ALTER TABLE foo.t ADD COLUMN c bigint")) - .ignoringLocation() - .isEqualTo(new AddColumn( - QualifiedName.of("foo", "t"), - new ColumnDefinition(identifier("c"), simpleType(location(1, 31), "bigint"), true, emptyList(), Optional.empty()), false, false)); - - assertThat(statement("ALTER TABLE foo.t ADD COLUMN d double NOT NULL")) - .ignoringLocation() - .isEqualTo(new AddColumn( - QualifiedName.of("foo", "t"), - new ColumnDefinition(identifier("d"), simpleType(location(1, 31), "double"), false, emptyList(), Optional.empty()), false, false)); - - assertThat(statement("ALTER TABLE IF EXISTS foo.t ADD COLUMN d double NOT NULL")) - .ignoringLocation() - .isEqualTo(new AddColumn( - QualifiedName.of("foo", "t"), - new ColumnDefinition(identifier("d"), simpleType(location(1, 31), "double"), false, emptyList(), Optional.empty()), true, false)); - - assertThat(statement("ALTER TABLE foo.t ADD COLUMN IF NOT EXISTS d double NOT NULL")) - .ignoringLocation() - .isEqualTo(new AddColumn( - QualifiedName.of("foo", "t"), - new ColumnDefinition(identifier("d"), simpleType(location(1, 31), "double"), false, emptyList(), Optional.empty()), false, true)); - - assertThat(statement("ALTER TABLE IF EXISTS foo.t ADD COLUMN IF NOT EXISTS d double NOT NULL")) - .ignoringLocation() - .isEqualTo(new AddColumn( - QualifiedName.of("foo", "t"), - new ColumnDefinition(identifier("d"), simpleType(location(1, 31), "double"), false, emptyList(), Optional.empty()), true, true)); - } - - @Test - public void testDropColumn() - { - assertStatement("ALTER TABLE foo.t DROP COLUMN c", new DropColumn(QualifiedName.of("foo", "t"), identifier("c"), false, false)); - assertStatement("ALTER TABLE \"t x\" DROP COLUMN \"c d\"", new DropColumn(QualifiedName.of("t x"), quotedIdentifier("c d"), false, false)); - assertStatement("ALTER TABLE IF EXISTS foo.t DROP COLUMN c", new DropColumn(QualifiedName.of("foo", "t"), identifier("c"), true, false)); - assertStatement("ALTER TABLE foo.t DROP COLUMN IF EXISTS c", new DropColumn(QualifiedName.of("foo", "t"), identifier("c"), false, true)); - assertStatement("ALTER TABLE IF EXISTS foo.t DROP COLUMN IF EXISTS c", new DropColumn(QualifiedName.of("foo", "t"), identifier("c"), true, true)); - } - - @Test - public void testAlterTableSetAuthorization() - { - assertStatement( - "ALTER TABLE foo.bar.baz SET AUTHORIZATION qux", - new SetTableAuthorization(QualifiedName.of("foo", "bar", "baz"), new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("qux")))); - assertStatement( - "ALTER TABLE foo.bar.baz SET AUTHORIZATION USER qux", - new SetTableAuthorization(QualifiedName.of("foo", "bar", "baz"), new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("qux")))); - assertStatement( - "ALTER TABLE foo.bar.baz SET AUTHORIZATION ROLE qux", - new SetTableAuthorization(QualifiedName.of("foo", "bar", "baz"), new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("qux")))); - } - - @Test - public void testCreateView() - { - Query query = simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))); - - assertStatement("CREATE VIEW a AS SELECT * FROM t", new CreateView(QualifiedName.of("a"), query, false, Optional.empty(), Optional.empty())); - assertStatement("CREATE OR REPLACE VIEW a AS SELECT * FROM t", new CreateView(QualifiedName.of("a"), query, true, Optional.empty(), Optional.empty())); - - assertStatement("CREATE VIEW a SECURITY DEFINER AS SELECT * FROM t", new CreateView(QualifiedName.of("a"), query, false, Optional.empty(), Optional.of(CreateView.Security.DEFINER))); - assertStatement("CREATE VIEW a SECURITY INVOKER AS SELECT * FROM t", new CreateView(QualifiedName.of("a"), query, false, Optional.empty(), Optional.of(CreateView.Security.INVOKER))); - - assertStatement("CREATE VIEW a COMMENT 'comment' SECURITY DEFINER AS SELECT * FROM t", new CreateView(QualifiedName.of("a"), query, false, Optional.of("comment"), Optional.of(CreateView.Security.DEFINER))); - assertStatement("CREATE VIEW a COMMENT '' SECURITY INVOKER AS SELECT * FROM t", new CreateView(QualifiedName.of("a"), query, false, Optional.of(""), Optional.of(CreateView.Security.INVOKER))); - - assertStatement("CREATE VIEW a COMMENT 'comment' AS SELECT * FROM t", new CreateView(QualifiedName.of("a"), query, false, Optional.of("comment"), Optional.empty())); - assertStatement("CREATE VIEW a COMMENT '' AS SELECT * FROM t", new CreateView(QualifiedName.of("a"), query, false, Optional.of(""), Optional.empty())); - - assertStatement("CREATE VIEW bar.foo AS SELECT * FROM t", new CreateView(QualifiedName.of("bar", "foo"), query, false, Optional.empty(), Optional.empty())); - assertStatement("CREATE VIEW \"awesome view\" AS SELECT * FROM t", new CreateView(QualifiedName.of("awesome view"), query, false, Optional.empty(), Optional.empty())); - assertStatement("CREATE VIEW \"awesome schema\".\"awesome view\" AS SELECT * FROM t", new CreateView(QualifiedName.of("awesome schema", "awesome view"), query, false, Optional.empty(), Optional.empty())); - } - - @Test - public void testGrant() - { - assertStatement("GRANT INSERT, DELETE ON t TO u", - new Grant( - Optional.of(ImmutableList.of("INSERT", "DELETE")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("u")), - false)); - assertStatement("GRANT UPDATE ON t TO u", - new Grant( - Optional.of(ImmutableList.of("UPDATE")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("u")), - false)); - assertStatement("GRANT SELECT ON t TO ROLE PUBLIC WITH GRANT OPTION", - new Grant( - Optional.of(ImmutableList.of("SELECT")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("PUBLIC")), - true)); - assertStatement("GRANT ALL PRIVILEGES ON TABLE t TO USER u", - new Grant( - Optional.empty(), - Optional.of(GrantOnType.TABLE), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("u")), - false)); - assertStatement("GRANT DELETE ON \"t\" TO ROLE \"public\" WITH GRANT OPTION", - new Grant( - Optional.of(ImmutableList.of("DELETE")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("public")), - true)); - assertStatement("GRANT SELECT ON SCHEMA s TO USER u", - new Grant( - Optional.of(ImmutableList.of("SELECT")), - Optional.of(GrantOnType.SCHEMA), - QualifiedName.of("s"), - new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("u")), - false)); - } - - @Test - public void testDeny() - { - assertStatement("DENY INSERT, DELETE ON t TO u", - new Deny( - Optional.of(ImmutableList.of("INSERT", "DELETE")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("u")))); - assertStatement("DENY UPDATE ON t TO u", - new Deny( - Optional.of(ImmutableList.of("UPDATE")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("u")))); - assertStatement("DENY ALL PRIVILEGES ON TABLE t TO USER u", - new Deny( - Optional.empty(), - Optional.of(GrantOnType.TABLE), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("u")))); - assertStatement("DENY SELECT ON SCHEMA s TO USER u", - new Deny( - Optional.of(ImmutableList.of("SELECT")), - Optional.of(GrantOnType.SCHEMA), - QualifiedName.of("s"), - new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("u")))); - } - - @Test - public void testRevoke() - { - assertStatement("REVOKE INSERT, DELETE ON t FROM u", - new Revoke( - false, - Optional.of(ImmutableList.of("INSERT", "DELETE")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("u")))); - assertStatement("REVOKE UPDATE ON t FROM u", - new Revoke( - false, - Optional.of(ImmutableList.of("UPDATE")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("u")))); - assertStatement("REVOKE GRANT OPTION FOR SELECT ON t FROM ROLE PUBLIC", - new Revoke( - true, - Optional.of(ImmutableList.of("SELECT")), - Optional.empty(), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("PUBLIC")))); - assertStatement("REVOKE ALL PRIVILEGES ON TABLE t FROM USER u", - new Revoke( - false, - Optional.empty(), - Optional.of(GrantOnType.TABLE), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("u")))); - assertStatement("REVOKE DELETE ON TABLE \"t\" FROM \"u\"", - new Revoke( - false, - Optional.of(ImmutableList.of("DELETE")), - Optional.of(GrantOnType.TABLE), - QualifiedName.of("t"), - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("u")))); - assertStatement("REVOKE SELECT ON SCHEMA s FROM USER u", - new Revoke( - false, - Optional.of(ImmutableList.of("SELECT")), - Optional.of(GrantOnType.SCHEMA), - QualifiedName.of("s"), - new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("u")))); - } - - @Test - public void testShowGrants() - { - assertStatement("SHOW GRANTS ON TABLE t", - new ShowGrants(true, Optional.of(QualifiedName.of("t")))); - assertStatement("SHOW GRANTS ON t", - new ShowGrants(false, Optional.of(QualifiedName.of("t")))); - assertStatement("SHOW GRANTS", - new ShowGrants(false, Optional.empty())); - } - - @Test - public void testShowRoles() - { - assertStatement("SHOW ROLES", - new ShowRoles(Optional.empty(), false)); - assertStatement("SHOW ROLES FROM foo", - new ShowRoles(Optional.of(new Identifier("foo")), false)); - assertStatement("SHOW ROLES IN foo", - new ShowRoles(Optional.of(new Identifier("foo")), false)); - - assertStatement("SHOW CURRENT ROLES", - new ShowRoles(Optional.empty(), true)); - assertStatement("SHOW CURRENT ROLES FROM foo", - new ShowRoles(Optional.of(new Identifier("foo")), true)); - assertStatement("SHOW CURRENT ROLES IN foo", - new ShowRoles(Optional.of(new Identifier("foo")), true)); - } - - @Test - public void testShowRoleGrants() - { - assertStatement("SHOW ROLE GRANTS", - new ShowRoleGrants(Optional.empty(), Optional.empty())); - assertStatement("SHOW ROLE GRANTS FROM catalog", - new ShowRoleGrants(Optional.of(new Identifier("catalog")))); - } - - @Test - public void testSetPath() - { - assertStatement("SET PATH iLikeToEat.apples, andBananas", - new SetPath(new PathSpecification(Optional.empty(), ImmutableList.of( - new PathElement(Optional.of(new Identifier("iLikeToEat")), new Identifier("apples")), - new PathElement(Optional.empty(), new Identifier("andBananas")))))); - - assertStatement("SET PATH \"schemas,with\".\"grammar.in\", \"their!names\"", - new SetPath(new PathSpecification(Optional.empty(), ImmutableList.of( - new PathElement(Optional.of(new Identifier("schemas,with")), new Identifier("grammar.in")), - new PathElement(Optional.empty(), new Identifier("their!names")))))); - - assertThatThrownBy(() -> assertStatement("SET PATH one.too.many, qualifiers", - new SetPath(new PathSpecification(Optional.empty(), ImmutableList.of( - new PathElement(Optional.empty(), new Identifier("dummyValue"))))))) - .isInstanceOf(ParsingException.class) - .hasMessage("line 1:17: mismatched input '.'. Expecting: ',', "); - - assertThatThrownBy(() -> SQL_PARSER.createStatement("SET PATH ", new ParsingOptions())) - .isInstanceOf(ParsingException.class) - .hasMessage("line 1:10: mismatched input ''. Expecting: "); - } - - @Test - public void testSetTimeZone() - { - assertThat(statement("SET TIME ZONE LOCAL")) - .isEqualTo( - new SetTimeZone( - location(1, 1), - Optional.empty())); - assertThat(statement("SET TIME ZONE 'America/Los_Angeles'")) - .isEqualTo( - new SetTimeZone( - location(1, 1), - Optional.of(new StringLiteral( - location(1, 15), - "America/Los_Angeles")))); - assertThat(statement("SET TIME ZONE concat_ws('/', 'America', 'Los_Angeles')")) - .isEqualTo( - new SetTimeZone( - location(1, 1), - Optional.of(new FunctionCall( - location(1, 15), - QualifiedName.of(ImmutableList.of(new Identifier(location(1, 15), "concat_ws", false))), - ImmutableList.of( - new StringLiteral( - location(1, 25), - "/"), - new StringLiteral( - location(1, 30), - "America"), - new StringLiteral( - location(1, 41), - "Los_Angeles")))))); - assertThat(statement("SET TIME ZONE '-08:00'")) - .isEqualTo( - new SetTimeZone( - location(1, 1), - Optional.of(new StringLiteral( - location(1, 15), - "-08:00")))); - assertThat(statement("SET TIME ZONE INTERVAL '10' HOUR")) - .isEqualTo( - new SetTimeZone( - location(1, 1), - Optional.of(new IntervalLiteral( - location(1, 15), - "10", Sign.POSITIVE, IntervalField.HOUR, Optional.empty())))); - assertThat(statement("SET TIME ZONE INTERVAL -'08:00' HOUR TO MINUTE")) - .isEqualTo( - new SetTimeZone( - location(1, 1), - Optional.of(new IntervalLiteral( - location(1, 15), "08:00", Sign.NEGATIVE, IntervalField.HOUR, Optional.of(IntervalField.MINUTE))))); - } - - @Test - public void testWith() - { - assertStatement("WITH a (t, u) AS (SELECT * FROM x), b AS (SELECT * FROM y) TABLE z", - new Query( - Optional.of(new With(false, ImmutableList.of( - new WithQuery( - identifier("a"), - simpleQuery( - selectList(new AllColumns()), - table(QualifiedName.of("x"))), - Optional.of(ImmutableList.of(identifier("t"), identifier("u")))), - new WithQuery( - identifier("b"), - simpleQuery( - selectList(new AllColumns()), - table(QualifiedName.of("y"))), - Optional.empty())))), - new Table(QualifiedName.of("z")), - Optional.empty(), - Optional.empty(), - Optional.empty())); - - assertStatement("WITH RECURSIVE a AS (SELECT * FROM x) TABLE y", - new Query( - Optional.of(new With(true, ImmutableList.of( - new WithQuery( - identifier("a"), - simpleQuery(selectList(new AllColumns()), - table(QualifiedName.of("x"))), - Optional.empty())))), - new Table(QualifiedName.of("y")), - Optional.empty(), - Optional.empty(), - Optional.empty())); - } - - @Test - public void testImplicitJoin() - { - assertStatement("SELECT * FROM a, b", - simpleQuery( - selectList(new AllColumns()), - new Join(Join.Type.IMPLICIT, - new Table(QualifiedName.of("a")), - new Table(QualifiedName.of("b")), - Optional.empty()))); - } - - @Test - public void testExplain() - { - assertStatement("EXPLAIN SELECT * FROM t", - new Explain(simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), ImmutableList.of())); - assertStatement("EXPLAIN (TYPE LOGICAL) SELECT * FROM t", - new Explain( - simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), - ImmutableList.of(new ExplainType(ExplainType.Type.LOGICAL)))); - assertStatement("EXPLAIN (TYPE LOGICAL, FORMAT TEXT) SELECT * FROM t", - new Explain( - simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), - ImmutableList.of( - new ExplainType(ExplainType.Type.LOGICAL), - new ExplainFormat(ExplainFormat.Type.TEXT)))); - - assertStatementIsInvalid("EXPLAIN VERBOSE SELECT * FROM t") - .withMessageStartingWith("line 1:9: mismatched input 'VERBOSE'. Expecting: '(', 'ALTER', 'ANALYZE', 'CALL',"); - - assertStatementIsInvalid("EXPLAIN VERBOSE (type LOGICAL) SELECT * FROM t") - .withMessageStartingWith("line 1:9: mismatched input 'VERBOSE'. Expecting: '(', 'ALTER', 'ANALYZE', 'CALL',"); - } - - @Test - public void testExplainAnalyze() - { - assertStatement("EXPLAIN ANALYZE SELECT * FROM t", - new ExplainAnalyze(simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), false)); - - assertStatement("EXPLAIN ANALYZE VERBOSE SELECT * FROM t", - new ExplainAnalyze(simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))), true)); - - assertStatementIsInvalid("EXPLAIN ANALYZE (type DISTRIBUTED) SELECT * FROM t") - .withMessage("line 1:18: mismatched input 'type'. Expecting: '(', 'SELECT', 'TABLE', 'VALUES'"); - - assertStatementIsInvalid("EXPLAIN ANALYZE VERBOSE (type DISTRIBUTED) SELECT * FROM t") - .withMessage("line 1:26: mismatched input 'type'. Expecting: '(', 'SELECT', 'TABLE', 'VALUES'"); - } - - @Test - public void testJoinPrecedence() - { - assertStatement("SELECT * FROM a CROSS JOIN b LEFT JOIN c ON true", - simpleQuery( - selectList(new AllColumns()), - new Join( - Join.Type.LEFT, - new Join( - Join.Type.CROSS, - new Table(QualifiedName.of("a")), - new Table(QualifiedName.of("b")), - Optional.empty()), - new Table(QualifiedName.of("c")), - Optional.of(new JoinOn(BooleanLiteral.TRUE_LITERAL))))); - assertStatement("SELECT * FROM a CROSS JOIN b NATURAL JOIN c CROSS JOIN d NATURAL JOIN e", - simpleQuery( - selectList(new AllColumns()), - new Join( - Join.Type.INNER, - new Join( - Join.Type.CROSS, - new Join( - Join.Type.INNER, - new Join( - Join.Type.CROSS, - new Table(QualifiedName.of("a")), - new Table(QualifiedName.of("b")), - Optional.empty()), - new Table(QualifiedName.of("c")), - Optional.of(new NaturalJoin())), - new Table(QualifiedName.of("d")), - Optional.empty()), - new Table(QualifiedName.of("e")), - Optional.of(new NaturalJoin())))); - } - - @Test - public void testUnnest() - { - assertStatement("SELECT * FROM t CROSS JOIN UNNEST(a)", - simpleQuery( - selectList(new AllColumns()), - new Join( - Join.Type.CROSS, - new Table(QualifiedName.of("t")), - new Unnest(ImmutableList.of(new Identifier("a")), false), - Optional.empty()))); - assertStatement("SELECT * FROM t CROSS JOIN UNNEST(a, b) WITH ORDINALITY", - simpleQuery( - selectList(new AllColumns()), - new Join( - Join.Type.CROSS, - new Table(QualifiedName.of("t")), - new Unnest(ImmutableList.of(new Identifier("a"), new Identifier("b")), true), - Optional.empty()))); - assertStatement("SELECT * FROM t FULL JOIN UNNEST(a) AS tmp (c) ON true", - simpleQuery( - selectList(new AllColumns()), - new Join( - Join.Type.FULL, - new Table(QualifiedName.of("t")), - new AliasedRelation(new Unnest(ImmutableList.of(new Identifier("a")), false), new Identifier("tmp"), ImmutableList.of(new Identifier("c"))), - Optional.of(new JoinOn(BooleanLiteral.TRUE_LITERAL))))); - } - - @Test - public void testLateral() - { - Lateral lateralRelation = new Lateral( - query(new Values(ImmutableList.of(new LongLiteral("1"))))); - - assertStatement("SELECT * FROM t, LATERAL (VALUES 1) a(x)", - simpleQuery( - selectList(new AllColumns()), - new Join( - Join.Type.IMPLICIT, - new Table(QualifiedName.of("t")), - new AliasedRelation(lateralRelation, identifier("a"), ImmutableList.of(identifier("x"))), - Optional.empty()))); - - assertStatement("SELECT * FROM t CROSS JOIN LATERAL (VALUES 1) ", - simpleQuery( - selectList(new AllColumns()), - new Join( - Join.Type.CROSS, - new Table(QualifiedName.of("t")), - lateralRelation, - Optional.empty()))); - - assertStatement("SELECT * FROM t FULL JOIN LATERAL (VALUES 1) ON true", - simpleQuery( - selectList(new AllColumns()), - new Join( - Join.Type.FULL, - new Table(QualifiedName.of("t")), - lateralRelation, - Optional.of(new JoinOn(BooleanLiteral.TRUE_LITERAL))))); - } - - @Test - public void testStartTransaction() - { - assertStatement("START TRANSACTION", - new StartTransaction(ImmutableList.of())); - assertStatement("START TRANSACTION ISOLATION LEVEL READ UNCOMMITTED", - new StartTransaction(ImmutableList.of( - new Isolation(Isolation.Level.READ_UNCOMMITTED)))); - assertStatement("START TRANSACTION ISOLATION LEVEL READ COMMITTED", - new StartTransaction(ImmutableList.of( - new Isolation(Isolation.Level.READ_COMMITTED)))); - assertStatement("START TRANSACTION ISOLATION LEVEL REPEATABLE READ", - new StartTransaction(ImmutableList.of( - new Isolation(Isolation.Level.REPEATABLE_READ)))); - assertStatement("START TRANSACTION ISOLATION LEVEL SERIALIZABLE", - new StartTransaction(ImmutableList.of( - new Isolation(Isolation.Level.SERIALIZABLE)))); - assertStatement("START TRANSACTION READ ONLY", - new StartTransaction(ImmutableList.of( - new TransactionAccessMode(true)))); - assertStatement("START TRANSACTION READ WRITE", - new StartTransaction(ImmutableList.of( - new TransactionAccessMode(false)))); - assertStatement("START TRANSACTION ISOLATION LEVEL READ COMMITTED, READ ONLY", - new StartTransaction(ImmutableList.of( - new Isolation(Isolation.Level.READ_COMMITTED), - new TransactionAccessMode(true)))); - assertStatement("START TRANSACTION READ ONLY, ISOLATION LEVEL READ COMMITTED", - new StartTransaction(ImmutableList.of( - new TransactionAccessMode(true), - new Isolation(Isolation.Level.READ_COMMITTED)))); - assertStatement("START TRANSACTION READ WRITE, ISOLATION LEVEL SERIALIZABLE", - new StartTransaction(ImmutableList.of( - new TransactionAccessMode(false), - new Isolation(Isolation.Level.SERIALIZABLE)))); - } - - @Test - public void testCommit() - { - assertStatement("COMMIT", new Commit()); - assertStatement("COMMIT WORK", new Commit()); - } - - @Test - public void testRollback() - { - assertStatement("ROLLBACK", new Rollback()); - assertStatement("ROLLBACK WORK", new Rollback()); - } - - @Test - public void testAtTimeZone() - { - assertStatement("SELECT timestamp '2012-10-31 01:00 UTC' AT TIME ZONE 'America/Los_Angeles'", - simpleQuery(selectList( - new AtTimeZone(new TimestampLiteral("2012-10-31 01:00 UTC"), new StringLiteral("America/Los_Angeles"))))); - } - - @Test - public void testLambda() - { - assertExpression("() -> x", - new LambdaExpression( - ImmutableList.of(), - new Identifier("x"))); - assertExpression("x -> sin(x)", - new LambdaExpression( - ImmutableList.of(new LambdaArgumentDeclaration(identifier("x"))), - new FunctionCall(QualifiedName.of("sin"), ImmutableList.of(new Identifier("x"))))); - assertExpression("(x, y) -> mod(x, y)", - new LambdaExpression( - ImmutableList.of(new LambdaArgumentDeclaration(identifier("x")), new LambdaArgumentDeclaration(identifier("y"))), - new FunctionCall( - QualifiedName.of("mod"), - ImmutableList.of(new Identifier("x"), new Identifier("y"))))); - } - - @Test - public void testNonReserved() - { - assertStatement("SELECT zone FROM t", - simpleQuery( - selectList(new Identifier("zone")), - table(QualifiedName.of("t")))); - assertStatement("SELECT INCLUDING, EXCLUDING, PROPERTIES FROM t", - simpleQuery( - selectList( - new Identifier("INCLUDING"), - new Identifier("EXCLUDING"), - new Identifier("PROPERTIES")), - table(QualifiedName.of("t")))); - assertStatement("SELECT ALL, SOME, ANY FROM t", - simpleQuery( - selectList( - new Identifier("ALL"), - new Identifier("SOME"), - new Identifier("ANY")), - table(QualifiedName.of("t")))); - - assertExpression("stats", new Identifier("stats")); - assertExpression("nfd", new Identifier("nfd")); - assertExpression("nfc", new Identifier("nfc")); - assertExpression("nfkd", new Identifier("nfkd")); - assertExpression("nfkc", new Identifier("nfkc")); - } - - @Test - public void testBinaryLiteralToHex() - { - // note that toHexString() always outputs in upper case - assertThat(new BinaryLiteral("ab 01").toHexString()) - .isEqualTo("AB01"); - } - - @Test - public void testCall() - { - assertStatement("CALL foo()", new Call(QualifiedName.of("foo"), ImmutableList.of())); - assertStatement("CALL foo(123, a => 1, b => 'go', 456)", new Call(QualifiedName.of("foo"), ImmutableList.of( - new CallArgument(new LongLiteral("123")), - new CallArgument(identifier("a"), new LongLiteral("1")), - new CallArgument(identifier("b"), new StringLiteral("go")), - new CallArgument(new LongLiteral("456"))))); - } - - @Test - public void testPrepare() - { - assertStatement("PREPARE myquery FROM select * from foo", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new AllColumns()), - table(QualifiedName.of("foo"))))); - } - - @Test - public void testPrepareWithParameters() - { - assertStatement("PREPARE myquery FROM SELECT ?, ? FROM foo", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new Parameter(0), new Parameter(1)), - table(QualifiedName.of("foo"))))); - - assertStatement("PREPARE myquery FROM SELECT * FROM foo LIMIT ?", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new AllColumns()), - table(QualifiedName.of("foo")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Limit(new Parameter(0)))))); - - assertStatement("PREPARE myquery FROM SELECT ?, ? FROM foo LIMIT ?", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new Parameter(0), new Parameter(1)), - table(QualifiedName.of("foo")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Limit(new Parameter(2)))))); - - assertStatement("PREPARE myquery FROM SELECT ? FROM foo FETCH FIRST ? ROWS ONLY", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new Parameter(0)), - table(QualifiedName.of("foo")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new FetchFirst(new Parameter(1)))))); - - assertStatement("PREPARE myquery FROM SELECT ?, ? FROM foo FETCH NEXT ? ROWS WITH TIES", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new Parameter(0), new Parameter(1)), - table(QualifiedName.of("foo")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new FetchFirst(new Parameter(2), true))))); - - assertStatement("PREPARE myquery FROM SELECT ?, ? FROM foo OFFSET ? ROWS", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new Parameter(0), new Parameter(1)), - table(QualifiedName.of("foo")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Offset(new Parameter(2))), - Optional.empty()))); - - assertStatement("PREPARE myquery FROM SELECT ? FROM foo OFFSET ? ROWS LIMIT ?", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new Parameter(0)), - table(QualifiedName.of("foo")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Offset(new Parameter(1))), - Optional.of(new Limit(new Parameter(2)))))); - - assertStatement("PREPARE myquery FROM SELECT ? FROM foo OFFSET ? ROWS FETCH FIRST ? ROWS WITH TIES", - new Prepare(identifier("myquery"), simpleQuery( - selectList(new Parameter(0)), - table(QualifiedName.of("foo")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.of(new Offset(new Parameter(1))), - Optional.of(new FetchFirst(new Parameter(2), true))))); - } - - @Test - public void testDeallocatePrepare() - { - assertStatement("DEALLOCATE PREPARE myquery", new Deallocate(identifier("myquery"))); - } - - @Test - public void testExecute() - { - assertStatement("EXECUTE myquery", new Execute(identifier("myquery"), emptyList())); - } - - @Test - public void testExecuteWithUsing() - { - assertStatement("EXECUTE myquery USING 1, 'abc', ARRAY ['hello']", - new Execute(identifier("myquery"), ImmutableList.of(new LongLiteral("1"), new StringLiteral("abc"), new ArrayConstructor(ImmutableList.of(new StringLiteral("hello")))))); - } - - @Test - public void testExists() - { - assertStatement("SELECT EXISTS(SELECT 1)", simpleQuery(selectList(exists(simpleQuery(selectList(new LongLiteral("1"))))))); - - assertStatement( - "SELECT EXISTS(SELECT 1) = EXISTS(SELECT 2)", - simpleQuery( - selectList(new ComparisonExpression( - ComparisonExpression.Operator.EQUAL, - exists(simpleQuery(selectList(new LongLiteral("1")))), - exists(simpleQuery(selectList(new LongLiteral("2")))))))); - - assertStatement( - "SELECT NOT EXISTS(SELECT 1) = EXISTS(SELECT 2)", - simpleQuery( - selectList( - new NotExpression( - new ComparisonExpression( - ComparisonExpression.Operator.EQUAL, - exists(simpleQuery(selectList(new LongLiteral("1")))), - exists(simpleQuery(selectList(new LongLiteral("2"))))))))); - - assertStatement( - "SELECT (NOT EXISTS(SELECT 1)) = EXISTS(SELECT 2)", - simpleQuery( - selectList( - new ComparisonExpression( - ComparisonExpression.Operator.EQUAL, - new NotExpression(exists(simpleQuery(selectList(new LongLiteral("1"))))), - exists(simpleQuery(selectList(new LongLiteral("2")))))))); - } - - private static ExistsPredicate exists(Query query) - { - return new ExistsPredicate(new SubqueryExpression(query)); - } - - @Test - public void testShowStats() - { - String[] tableNames = {"t", "s.t", "c.s.t"}; - - for (String fullName : tableNames) { - QualifiedName qualifiedName = makeQualifiedName(fullName); - assertStatement(format("SHOW STATS FOR %s", qualifiedName), new ShowStats(new Table(qualifiedName))); - } - } - - @Test - public void testShowStatsForQuery() - { - String[] tableNames = {"t", "s.t", "c.s.t"}; - - for (String fullName : tableNames) { - QualifiedName qualifiedName = makeQualifiedName(fullName); - - // Simple SELECT - assertStatement(format("SHOW STATS FOR (SELECT * FROM %s)", qualifiedName), - createShowStats(qualifiedName, ImmutableList.of(new AllColumns()), Optional.empty())); - - // SELECT with predicate - assertStatement(format("SHOW STATS FOR (SELECT * FROM %s WHERE field > 0)", qualifiedName), - createShowStats(qualifiedName, - ImmutableList.of(new AllColumns()), - Optional.of( - new ComparisonExpression(ComparisonExpression.Operator.GREATER_THAN, - new Identifier("field"), - new LongLiteral("0"))))); - - // SELECT with more complex predicate - assertStatement(format("SHOW STATS FOR (SELECT * FROM %s WHERE field > 0 or field < 0)", qualifiedName), - createShowStats(qualifiedName, - ImmutableList.of(new AllColumns()), - Optional.of( - LogicalExpression.or( - new ComparisonExpression(ComparisonExpression.Operator.GREATER_THAN, - new Identifier("field"), - new LongLiteral("0")), - new ComparisonExpression(ComparisonExpression.Operator.LESS_THAN, - new Identifier("field"), - new LongLiteral("0")))))); - } - - // SELECT with LIMIT - assertThat(statement("SHOW STATS FOR (SELECT * FROM t LIMIT 10)")) - .isEqualTo( - new ShowStats( - Optional.of(location(1, 1)), - new TableSubquery( - new Query( - location(1, 17), - Optional.empty(), - new QuerySpecification( - location(1, 17), - new Select( - location(1, 17), - false, - ImmutableList.of(new AllColumns(location(1, 24), Optional.empty(), ImmutableList.of()))), - Optional.of(new Table( - location(1, 31), - QualifiedName.of(ImmutableList.of(new Identifier(location(1, 31), "t", false))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.empty(), - Optional.of(new Limit(location(1, 33), new LongLiteral(location(1, 39), "10")))), - Optional.empty(), - Optional.empty(), - Optional.empty())))); - - // SELECT with ORDER BY ... LIMIT - assertThat(statement("SHOW STATS FOR (SELECT * FROM t ORDER BY field LIMIT 10)")) - .isEqualTo( - new ShowStats( - Optional.of(location(1, 1)), - new TableSubquery( - new Query( - location(1, 17), - Optional.empty(), - new QuerySpecification( - location(1, 17), - new Select( - location(1, 17), - false, - ImmutableList.of(new AllColumns(location(1, 24), Optional.empty(), ImmutableList.of()))), - Optional.of(new Table( - location(1, 31), - QualifiedName.of(ImmutableList.of(new Identifier(location(1, 31), "t", false))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.of(new OrderBy(location(1, 33), ImmutableList.of( - new SortItem(location(1, 42), new Identifier(location(1, 42), "field", false), ASCENDING, UNDEFINED)))), - Optional.empty(), - Optional.of(new Limit(location(1, 48), new LongLiteral(location(1, 54), "10")))), - Optional.empty(), - Optional.empty(), - Optional.empty())))); - - // SELECT with WITH - assertThat(statement("SHOW STATS FOR (\n" + - " WITH t AS (SELECT 1 )\n" + - " SELECT * FROM t)")) - .isEqualTo( - new ShowStats( - Optional.of(location(1, 1)), - new TableSubquery( - new Query( - location(2, 4), - Optional.of( - new With( - location(2, 4), - false, - ImmutableList.of( - new WithQuery( - location(2, 9), - new Identifier(location(2, 9), "t", false), - new Query( - location(2, 15), - Optional.empty(), - new QuerySpecification( - location(2, 15), - new Select( - location(2, 15), - false, - ImmutableList.of( - new SingleColumn( - location(2, 22), - new LongLiteral(location(2, 22), "1"), - Optional.empty()))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.empty(), - Optional.empty()), - Optional.empty(), - Optional.empty(), - Optional.empty()), - Optional.empty())))), - new QuerySpecification( - location(3, 4), - new Select( - location(3, 4), - false, - ImmutableList.of(new AllColumns(location(3, 11), Optional.empty(), ImmutableList.of()))), - Optional.of(new Table( - location(3, 18), - QualifiedName.of(ImmutableList.of(new Identifier(location(3, 18), "t", false))))), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.empty(), - Optional.empty()), - Optional.empty(), - Optional.empty(), - Optional.empty())))); - } - - private static ShowStats createShowStats(QualifiedName name, List selects, Optional where) - { - return new ShowStats( - new TableSubquery(simpleQuery(new Select(false, selects), - new Table(name), - where, - Optional.empty()))); - } - - @Test - public void testDescribeOutput() - { - assertStatement("DESCRIBE OUTPUT myquery", new DescribeOutput(identifier("myquery"))); - } - - @Test - public void testDescribeInput() - { - assertStatement("DESCRIBE INPUT myquery", new DescribeInput(identifier("myquery"))); - } - - @Test - public void testAggregationFilter() - { - assertStatement("SELECT SUM(x) FILTER (WHERE x > 4)", - simpleQuery(selectList( - new FunctionCall( - Optional.empty(), - QualifiedName.of("SUM"), - Optional.empty(), - Optional.of(new ComparisonExpression( - ComparisonExpression.Operator.GREATER_THAN, - new Identifier("x"), - new LongLiteral("4"))), - Optional.empty(), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of(new Identifier("x")))))); - } - - @Test - public void testQuantifiedComparison() - { - assertExpression("col1 < ANY (SELECT col2 FROM table1)", - new QuantifiedComparisonExpression( - ComparisonExpression.Operator.LESS_THAN, - QuantifiedComparisonExpression.Quantifier.ANY, - identifier("col1"), - new SubqueryExpression(simpleQuery(selectList(new SingleColumn(identifier("col2"))), table(QualifiedName.of("table1")))))); - assertExpression("col1 = ALL (VALUES ROW(1), ROW(2))", - new QuantifiedComparisonExpression( - ComparisonExpression.Operator.EQUAL, - QuantifiedComparisonExpression.Quantifier.ALL, - identifier("col1"), - new SubqueryExpression(query(values(row(new LongLiteral("1")), row(new LongLiteral("2"))))))); - assertExpression("col1 >= SOME (SELECT 10)", - new QuantifiedComparisonExpression( - ComparisonExpression.Operator.GREATER_THAN_OR_EQUAL, - QuantifiedComparisonExpression.Quantifier.SOME, - identifier("col1"), - new SubqueryExpression(simpleQuery(selectList(new LongLiteral("10")))))); - } - - @Test - public void testAggregationWithOrderBy() - { - assertExpression("array_agg(x ORDER BY x DESC)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("array_agg"), - Optional.empty(), - Optional.empty(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(identifier("x"), DESCENDING, UNDEFINED)))), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of(identifier("x")))); - assertStatement("SELECT array_agg(x ORDER BY t.y) FROM t", - simpleQuery( - selectList(new FunctionCall( - Optional.empty(), - QualifiedName.of("array_agg"), - Optional.empty(), - Optional.empty(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new DereferenceExpression(new Identifier("t"), identifier("y")), ASCENDING, UNDEFINED)))), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of(new Identifier("x")))), - table(QualifiedName.of("t")))); - } - - @Test - public void testCreateRole() - { - assertStatement("CREATE ROLE role", new CreateRole(new Identifier("role"), Optional.empty(), Optional.empty())); - assertStatement("CREATE ROLE role1 WITH ADMIN admin", - new CreateRole( - new Identifier("role1"), - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("admin"))))), - Optional.empty())); - assertStatement("CREATE ROLE \"role\" WITH ADMIN \"admin\"", - new CreateRole( - new Identifier("role"), - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("admin"))))), - Optional.empty())); - assertStatement("CREATE ROLE \"ro le\" WITH ADMIN \"ad min\"", - new CreateRole( - new Identifier("ro le"), - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("ad min"))))), - Optional.empty())); - assertStatement("CREATE ROLE \"!@#$%^&*'\" WITH ADMIN \"ад\"\"мін\"", - new CreateRole( - new Identifier("!@#$%^&*'"), - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("ад\"мін"))))), - Optional.empty())); - assertStatement("CREATE ROLE role2 WITH ADMIN USER admin1", - new CreateRole( - new Identifier("role2"), - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("admin1"))))), - Optional.empty())); - assertStatement("CREATE ROLE role2 WITH ADMIN ROLE role1", - new CreateRole( - new Identifier("role2"), - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("role1"))))), - Optional.empty())); - assertStatement("CREATE ROLE role2 WITH ADMIN CURRENT_USER", - new CreateRole( - new Identifier("role2"), - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.CURRENT_USER, - Optional.empty())), - Optional.empty())); - assertStatement("CREATE ROLE role2 WITH ADMIN CURRENT_ROLE", - new CreateRole( - new Identifier("role2"), - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.CURRENT_ROLE, - Optional.empty())), - Optional.empty())); - assertStatement("CREATE ROLE role IN my_catalog", - new CreateRole( - new Identifier("role"), - Optional.empty(), - Optional.of(new Identifier("my_catalog")))); - } - - @Test - public void testDropRole() - { - assertStatement("DROP ROLE role", new DropRole(new Identifier("role"), Optional.empty())); - assertStatement("DROP ROLE \"role\"", new DropRole(new Identifier("role"), Optional.empty())); - assertStatement("DROP ROLE \"ro le\"", new DropRole(new Identifier("ro le"), Optional.empty())); - assertStatement("DROP ROLE \"!@#$%^&*'ад\"\"мін\"", new DropRole(new Identifier("!@#$%^&*'ад\"мін"), Optional.empty())); - assertStatement("DROP ROLE role IN my_catalog", new DropRole(new Identifier("role"), Optional.of(new Identifier("my_catalog")))); - } - - @Test - public void testGrantRoles() - { - assertStatement("GRANT role1 TO user1", - new GrantRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("user1"))), - false, - Optional.empty(), - Optional.empty())); - assertStatement("GRANT role1, role2, role3 TO user1, USER user2, ROLE role4 WITH ADMIN OPTION", - new GrantRoles( - ImmutableSet.of(new Identifier("role1"), new Identifier("role2"), new Identifier("role3")), - ImmutableSet.of( - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("user1")), - new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("user2")), - new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("role4"))), - true, - Optional.empty(), - Optional.empty())); - assertStatement("GRANT role1 TO user1 WITH ADMIN OPTION GRANTED BY admin", - new GrantRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("user1"))), - true, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("admin"))))), - Optional.empty())); - assertStatement("GRANT role1 TO USER user1 WITH ADMIN OPTION GRANTED BY USER admin", - new GrantRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("user1"))), - true, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("admin"))))), - Optional.empty())); - assertStatement("GRANT role1 TO ROLE role2 WITH ADMIN OPTION GRANTED BY ROLE admin", - new GrantRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("role2"))), - true, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("admin"))))), - Optional.empty())); - assertStatement("GRANT role1 TO ROLE role2 GRANTED BY ROLE admin", - new GrantRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("role2"))), - false, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("admin"))))), - Optional.empty())); - assertStatement("GRANT \"role1\" TO ROLE \"role2\" GRANTED BY ROLE \"admin\"", - new GrantRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("role2"))), - false, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("admin"))))), - Optional.empty())); - assertStatement("GRANT role1 TO user1 IN my_catalog", - new GrantRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("user1"))), - false, - Optional.empty(), - Optional.of(new Identifier("my_catalog")))); - } - - @Test - public void testRevokeRoles() - { - assertStatement("REVOKE role1 FROM user1", - new RevokeRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("user1"))), - false, - Optional.empty(), - Optional.empty())); - assertStatement("REVOKE ADMIN OPTION FOR role1, role2, role3 FROM user1, USER user2, ROLE role4", - new RevokeRoles( - ImmutableSet.of(new Identifier("role1"), new Identifier("role2"), new Identifier("role3")), - ImmutableSet.of( - new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("user1")), - new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("user2")), - new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("role4"))), - true, - Optional.empty(), - Optional.empty())); - assertStatement("REVOKE ADMIN OPTION FOR role1 FROM user1 GRANTED BY admin", - new RevokeRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("user1"))), - true, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("admin"))))), - Optional.empty())); - assertStatement("REVOKE ADMIN OPTION FOR role1 FROM USER user1 GRANTED BY USER admin", - new RevokeRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("user1"))), - true, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.USER, new Identifier("admin"))))), - Optional.empty())); - assertStatement("REVOKE role1 FROM ROLE role2 GRANTED BY ROLE admin", - new RevokeRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("role2"))), - false, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("admin"))))), - Optional.empty())); - assertStatement("REVOKE \"role1\" FROM ROLE \"role2\" GRANTED BY ROLE \"admin\"", - new RevokeRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("role2"))), - false, - Optional.of(new GrantorSpecification( - GrantorSpecification.Type.PRINCIPAL, - Optional.of(new PrincipalSpecification(PrincipalSpecification.Type.ROLE, new Identifier("admin"))))), - Optional.empty())); - assertStatement("REVOKE role1 FROM user1 IN my_catalog", - new RevokeRoles( - ImmutableSet.of(new Identifier("role1")), - ImmutableSet.of(new PrincipalSpecification(PrincipalSpecification.Type.UNSPECIFIED, new Identifier("user1"))), - false, - Optional.empty(), - Optional.of(new Identifier("my_catalog")))); - } - - @Test - public void testSetRole() - { - assertStatement("SET ROLE ALL", new SetRole(SetRole.Type.ALL, Optional.empty(), Optional.empty())); - assertStatement("SET ROLE NONE", new SetRole(SetRole.Type.NONE, Optional.empty(), Optional.empty())); - assertStatement("SET ROLE role", new SetRole(SetRole.Type.ROLE, Optional.of(new Identifier("role")), Optional.empty())); - assertStatement("SET ROLE \"role\"", new SetRole(SetRole.Type.ROLE, Optional.of(new Identifier("role")), Optional.empty())); - assertStatement("SET ROLE role IN my_catalog", new SetRole(SetRole.Type.ROLE, Optional.of(new Identifier("role")), Optional.of(new Identifier("my_catalog")))); - } - - @Test - public void testCreateMaterializedView() - { - Query query = simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("t"))); - - Optional location = Optional.empty(); - - assertStatement("CREATE MATERIALIZED VIEW a AS SELECT * FROM t", new CreateMaterializedView(location, - QualifiedName.of("a"), query, false, false, new ArrayList<>(), Optional.empty())); - - Query query2 = simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("catalog2", "schema2", "tab"))); - assertStatement("CREATE OR REPLACE MATERIALIZED VIEW catalog.schema.matview COMMENT 'A simple materialized view'" + - " AS SELECT * FROM catalog2.schema2.tab", - new CreateMaterializedView(location, QualifiedName.of("catalog", "schema", "matview"), query2, - true, false, new ArrayList<>(), Optional.of("A simple materialized view"))); - - assertStatement("CREATE OR REPLACE MATERIALIZED VIEW catalog.schema.matview COMMENT 'A simple materialized view'" + - " AS SELECT * FROM catalog2.schema2.tab", - new CreateMaterializedView(location, QualifiedName.of("catalog", "schema", "matview"), query2, - true, false, new ArrayList<>(), Optional.of("A simple materialized view"))); - - List properties = ImmutableList.of(new Property(new Identifier("partitioned_by"), - new ArrayConstructor(ImmutableList.of(new StringLiteral("dateint"))))); - - assertStatement("CREATE OR REPLACE MATERIALIZED VIEW catalog.schema.matview COMMENT 'A simple materialized view'" + - "WITH (partitioned_by = ARRAY ['dateint'])" + - " AS SELECT * FROM catalog2.schema2.tab", - new CreateMaterializedView(location, QualifiedName.of("catalog", "schema", "matview"), query2, - true, false, properties, Optional.of("A simple materialized view"))); - - Query query3 = new Query(Optional.of(new With(false, ImmutableList.of( - new WithQuery(identifier("a"), simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("x"))), Optional.of(ImmutableList.of(identifier("t"), identifier("u")))), - new WithQuery(identifier("b"), simpleQuery(selectList(new AllColumns()), table(QualifiedName.of("a"))), Optional.empty())))), - new Table(QualifiedName.of("b")), - Optional.empty(), - Optional.empty(), - Optional.empty()); - - assertStatement("CREATE OR REPLACE MATERIALIZED VIEW catalog.schema.matview COMMENT 'A partitioned materialized view' " + - "WITH (partitioned_by = ARRAY ['dateint'])" + - " AS WITH a (t, u) AS (SELECT * FROM x), b AS (SELECT * FROM a) TABLE b", - new CreateMaterializedView(location, QualifiedName.of("catalog", "schema", "matview"), query3, - true, false, properties, Optional.of("A partitioned materialized view"))); - } - - @Test - public void testRefreshMaterializedView() - { - assertStatement("REFRESH MATERIALIZED VIEW test", - new RefreshMaterializedView(Optional.empty(), new Table(QualifiedName.of("test")))); - - assertStatement("REFRESH MATERIALIZED VIEW \"some name that contains space\"", - new RefreshMaterializedView(Optional.empty(), new Table(QualifiedName.of("some name that contains space")))); - } - - @Test - public void testDropMaterializedView() - { - assertStatement("DROP MATERIALIZED VIEW a", new DropMaterializedView(QualifiedName.of("a"), false)); - assertStatement("DROP MATERIALIZED VIEW a.b", new DropMaterializedView(QualifiedName.of("a", "b"), false)); - assertStatement("DROP MATERIALIZED VIEW a.b.c", new DropMaterializedView(QualifiedName.of("a", "b", "c"), false)); - - assertStatement("DROP MATERIALIZED VIEW IF EXISTS a", new DropMaterializedView(QualifiedName.of("a"), true)); - assertStatement("DROP MATERIALIZED VIEW IF EXISTS a.b", new DropMaterializedView(QualifiedName.of("a", "b"), true)); - assertStatement("DROP MATERIALIZED VIEW IF EXISTS a.b.c", new DropMaterializedView(QualifiedName.of("a", "b", "c"), true)); - } - - @Test - public void testRenameMaterializedView() - { - assertStatement("ALTER MATERIALIZED VIEW a RENAME TO b", new RenameMaterializedView(QualifiedName.of("a"), QualifiedName.of("b"), false)); - assertStatement("ALTER MATERIALIZED VIEW IF EXISTS a RENAME TO b", new RenameMaterializedView(QualifiedName.of("a"), QualifiedName.of("b"), true)); - } - - @Test - public void testSetMaterializedViewProperties() - { - assertStatement( - "ALTER MATERIALIZED VIEW a SET PROPERTIES foo='bar'", - new SetProperties( - MATERIALIZED_VIEW, - QualifiedName.of("a"), - ImmutableList.of(new Property(new Identifier("foo"), new StringLiteral("bar"))))); - assertStatement( - "ALTER MATERIALIZED VIEW a SET PROPERTIES foo=true", - new SetProperties( - MATERIALIZED_VIEW, - QualifiedName.of("a"), - ImmutableList.of(new Property(new Identifier("foo"), new BooleanLiteral("true"))))); - assertStatement( - "ALTER MATERIALIZED VIEW a SET PROPERTIES foo=123", - new SetProperties( - MATERIALIZED_VIEW, - QualifiedName.of("a"), - ImmutableList.of(new Property(new Identifier("foo"), new LongLiteral("123"))))); - assertStatement( - "ALTER MATERIALIZED VIEW a SET PROPERTIES foo=123, bar=456", - new SetProperties( - MATERIALIZED_VIEW, - QualifiedName.of("a"), - ImmutableList.of( - new Property(new Identifier("foo"), new LongLiteral("123")), - new Property(new Identifier("bar"), new LongLiteral("456"))))); - assertStatement( - "ALTER MATERIALIZED VIEW a SET PROPERTIES \" s p a c e \"='bar'", - new SetProperties( - MATERIALIZED_VIEW, - QualifiedName.of("a"), - ImmutableList.of(new Property(new Identifier(" s p a c e "), new StringLiteral("bar"))))); - assertStatement( - "ALTER MATERIALIZED VIEW a SET PROPERTIES foo=123, bar=DEFAULT", - new SetProperties( - MATERIALIZED_VIEW, - QualifiedName.of("a"), - ImmutableList.of( - new Property(new Identifier("foo"), new LongLiteral("123")), - new Property(new Identifier("bar"))))); - - assertStatementIsInvalid("ALTER MATERIALIZED VIEW a SET PROPERTIES") - .withMessage("line 1:41: mismatched input ''. Expecting: "); - assertStatementIsInvalid("ALTER MATERIALIZED VIEW a SET PROPERTIES ()") - .withMessage("line 1:42: mismatched input '('. Expecting: "); - assertStatementIsInvalid("ALTER MATERIALIZED VIEW a SET PROPERTIES (foo='bar')") - .withMessage("line 1:42: mismatched input '('. Expecting: "); - } - - @Test - public void testNullTreatment() - { - assertExpression("lead(x, 1) ignore nulls over()", - new FunctionCall( - Optional.empty(), - QualifiedName.of("lead"), - Optional.of(new WindowSpecification(Optional.empty(), ImmutableList.of(), Optional.empty(), Optional.empty())), - Optional.empty(), - Optional.empty(), - false, - Optional.of(NullTreatment.IGNORE), - Optional.empty(), - ImmutableList.of(new Identifier("x"), new LongLiteral("1")))); - assertExpression("lead(x, 1) respect nulls over()", - new FunctionCall( - Optional.empty(), - QualifiedName.of("lead"), - Optional.of(new WindowSpecification(Optional.empty(), ImmutableList.of(), Optional.empty(), Optional.empty())), - Optional.empty(), - Optional.empty(), - false, - Optional.of(NullTreatment.RESPECT), - Optional.empty(), - ImmutableList.of(new Identifier("x"), new LongLiteral("1")))); - } - - @Test - public void testProcessingMode() - { - assertExpression("RUNNING LAST(x, 1)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("LAST"), - Optional.empty(), - Optional.empty(), - Optional.empty(), - false, - Optional.empty(), - Optional.of(new ProcessingMode(Optional.empty(), RUNNING)), - ImmutableList.of(new Identifier("x"), new LongLiteral("1")))); - assertExpression("FINAL FIRST(x, 1)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("FIRST"), - Optional.empty(), - Optional.empty(), - Optional.empty(), - false, - Optional.empty(), - Optional.of(new ProcessingMode(Optional.empty(), FINAL)), - ImmutableList.of(new Identifier("x"), new LongLiteral("1")))); - } - - @Test - public void testWindowSpecification() - { - assertExpression("rank() OVER someWindow", - new FunctionCall( - Optional.empty(), - QualifiedName.of("rank"), - Optional.of(new WindowReference(new Identifier("someWindow"))), - Optional.empty(), - Optional.empty(), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of())); - - assertExpression("rank() OVER (someWindow PARTITION BY x ORDER BY y ROWS CURRENT ROW)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("rank"), - Optional.of(new WindowSpecification( - Optional.of(new Identifier("someWindow")), - ImmutableList.of(new Identifier("x")), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("y"), ASCENDING, UNDEFINED)))), - Optional.of(new WindowFrame(ROWS, new FrameBound(CURRENT_ROW), Optional.empty(), ImmutableList.of(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableList.of(), ImmutableList.of())))), - Optional.empty(), - Optional.empty(), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of())); - - assertExpression("rank() OVER (PARTITION BY x ORDER BY y ROWS CURRENT ROW)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("rank"), - Optional.of(new WindowSpecification( - Optional.empty(), - ImmutableList.of(new Identifier("x")), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("y"), ASCENDING, UNDEFINED)))), - Optional.of(new WindowFrame(ROWS, new FrameBound(CURRENT_ROW), Optional.empty(), ImmutableList.of(), Optional.empty(), Optional.empty(), Optional.empty(), ImmutableList.of(), ImmutableList.of())))), - Optional.empty(), - Optional.empty(), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of())); - } - - @Test - public void testWindowClause() - { - assertStatement("SELECT * FROM T WINDOW someWindow AS (PARTITION BY a), otherWindow AS (someWindow ORDER BY b)", - simpleQuery( - selectList(new AllColumns()), - new Table(makeQualifiedName("T")), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of( - new WindowDefinition( - new Identifier("someWindow"), - new WindowSpecification( - Optional.empty(), - ImmutableList.of(new Identifier("a")), - Optional.empty(), - Optional.empty())), - new WindowDefinition( - new Identifier("otherWindow"), - new WindowSpecification( - Optional.of(new Identifier("someWindow")), - ImmutableList.of(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("b"), ASCENDING, UNDEFINED)))), - Optional.empty()))), - Optional.empty(), - Optional.empty(), - Optional.empty())); - } - - @Test - public void testWindowFrameWithPatternRecognition() - { - assertThat(expression("rank() OVER (" + - " PARTITION BY x " + - " ORDER BY y " + - " MEASURES " + - " MATCH_NUMBER() AS match_no, " + - " LAST(A.z) AS last_z " + - " ROWS BETWEEN CURRENT ROW AND 5 FOLLOWING " + - " AFTER MATCH SKIP TO NEXT ROW " + - " SEEK " + - " PATTERN (A B C) " + - " SUBSET U = (A, B) " + - " DEFINE " + - " B AS false, " + - " C AS CLASSIFIER(U) = 'B' " + - " )")) - .isEqualTo(new FunctionCall( - Optional.of(location(1, 1)), - QualifiedName.of(ImmutableList.of(new Identifier(location(1, 1), "rank", false))), - Optional.of(new WindowSpecification( - location(1, 41), - Optional.empty(), - ImmutableList.of(new Identifier(location(1, 54), "x", false)), - Optional.of(new OrderBy( - location(1, 83), - ImmutableList.of(new SortItem(location(1, 92), new Identifier(location(1, 92), "y", false), ASCENDING, UNDEFINED)))), - Optional.of(new WindowFrame( - location(1, 121), - ROWS, - new FrameBound(location(1, 280), CURRENT_ROW), - Optional.of(new FrameBound(location(1, 296), FOLLOWING, new LongLiteral(location(1, 296), "5"))), - ImmutableList.of( - new MeasureDefinition( - location(1, 161), - new FunctionCall( - location(1, 161), - QualifiedName.of(ImmutableList.of(new Identifier(location(1, 161), "MATCH_NUMBER", false))), - ImmutableList.of()), - new Identifier(location(1, 179), "match_no", false)), - new MeasureDefinition( - location(1, 220), - new FunctionCall( - location(1, 220), - QualifiedName.of(ImmutableList.of(new Identifier(location(1, 220), "LAST", false))), - ImmutableList.of(new DereferenceExpression( - location(1, 225), - new Identifier(location(1, 225), "A", false), - new Identifier(location(1, 227), "z", false)))), - new Identifier(location(1, 233), "last_z", false))), - Optional.of(skipToNextRow(location(1, 347))), - Optional.of(new PatternSearchMode(location(1, 391), SEEK)), - Optional.of(new PatternConcatenation( - location(1, 432), - ImmutableList.of( - new PatternConcatenation( - location(1, 432), - ImmutableList.of( - new PatternVariable(location(1, 432), new Identifier(location(1, 432), "A", false)), - new PatternVariable(location(1, 434), new Identifier(location(1, 434), "B", false)))), - new PatternVariable(location(1, 436), new Identifier(location(1, 436), "C", false))))), - ImmutableList.of(new SubsetDefinition( - location(1, 473), - new Identifier(location(1, 473), "U", false), - ImmutableList.of(new Identifier(location(1, 478), "A", false), new Identifier(location(1, 481), "B", false)))), - ImmutableList.of( - new VariableDefinition( - location(1, 549), - new Identifier(location(1, 549), "B", false), - new BooleanLiteral(location(1, 554), "false")), - new VariableDefinition( - location(1, 592), - new Identifier(location(1, 592), "C", false), - new ComparisonExpression( - location(1, 611), - EQUAL, - new FunctionCall( - location(1, 597), - QualifiedName.of(ImmutableList.of(new Identifier(location(1, 597), "CLASSIFIER", false))), - ImmutableList.of(new Identifier(location(1, 608), "U", false))), - new StringLiteral(location(1, 613), "B")))))))), - Optional.empty(), - Optional.empty(), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of())); - } - - @Test - public void testMeasureOverWindow() - { - assertThat(expression("last_z OVER (" + - " MEASURES z AS last_z " + - " ROWS CURRENT ROW " + - " PATTERN (A) " + - " DEFINE a AS true " + - " )")) - .isEqualTo(new WindowOperation( - location(1, 1), - new Identifier(location(1, 1), "last_z", false), - new WindowSpecification( - location(1, 41), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.of(new WindowFrame( - location(1, 41), - ROWS, - new FrameBound(location(1, 94), CURRENT_ROW), - Optional.empty(), - ImmutableList.of(new MeasureDefinition( - location(1, 50), - new Identifier(location(1, 50), "z", false), - new Identifier(location(1, 55), "last_z", false))), - Optional.empty(), - Optional.empty(), - Optional.of(new PatternVariable(location(1, 142), new Identifier(location(1, 142), "A", false))), - ImmutableList.of(), - ImmutableList.of(new VariableDefinition( - location(1, 179), - new Identifier(location(1, 179), "a", false), - new BooleanLiteral(location(1, 184), "true")))))))); - } - - @Test - public void testAllRowsReference() - { - assertThatThrownBy(() -> SQL_PARSER.createStatement("SELECT 1 + A.*", new ParsingOptions(REJECT))) - .isInstanceOf(ParsingException.class) - .hasMessageMatching("line 1:13: mismatched input '.'.*"); - - assertThat(statement("SELECT A.*")) - .ignoringLocation() - .isEqualTo(simpleQuery(new Select(false, ImmutableList.of(new AllColumns(new Identifier("A"), ImmutableList.of()))))); - } - - @Test - public void testUpdate() - { - assertStatement("" + - "UPDATE foo_table\n" + - " SET bar = 23, baz = 3.1415E0, bletch = 'barf'\n" + - "WHERE (nothing = 'fun')", - new Update( - new NodeLocation(1, 1), - table(QualifiedName.of("foo_table")), - ImmutableList.of( - new UpdateAssignment(new Identifier("bar"), new LongLiteral("23")), - new UpdateAssignment(new Identifier("baz"), new DoubleLiteral("3.1415")), - new UpdateAssignment(new Identifier("bletch"), new StringLiteral("barf"))), - Optional.of(new ComparisonExpression(ComparisonExpression.Operator.EQUAL, new Identifier("nothing"), new StringLiteral("fun"))))); - } - - @Test - public void testWherelessUpdate() - { - assertStatement("" + - "UPDATE foo_table\n" + - " SET bar = 23", - new Update( - new NodeLocation(1, 1), - table(QualifiedName.of("foo_table")), - ImmutableList.of( - new UpdateAssignment(new Identifier("bar"), new LongLiteral("23"))), - Optional.empty())); - } - - @Test - public void testQueryPeriod() - { - Expression rangeValue = new TimestampLiteral(location(1, 37), "2021-03-01 00:00:01"); - QueryPeriod queryPeriod = new QueryPeriod(location(1, 17), QueryPeriod.RangeType.TIMESTAMP, rangeValue); - Table table = new Table(location(1, 15), qualifiedName(location(1, 15), "t"), queryPeriod); - assertThat(statement("SELECT * FROM t FOR TIMESTAMP AS OF TIMESTAMP '2021-03-01 00:00:01'")) - .isEqualTo( - new Query( - location(1, 1), - Optional.empty(), - new QuerySpecification( - location(1, 1), - new Select( - location(1, 1), - false, - ImmutableList.of( - new AllColumns( - location(1, 8), - Optional.empty(), - ImmutableList.of()))), - Optional.of(table), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.empty(), - Optional.empty()), - Optional.empty(), - Optional.empty(), - Optional.empty())); - - rangeValue = new StringLiteral(location(1, 35), "version1"); - queryPeriod = new QueryPeriod(new NodeLocation(1, 17), QueryPeriod.RangeType.VERSION, rangeValue); - table = new Table(location(1, 15), qualifiedName(location(1, 15), "t"), queryPeriod); - assertThat(statement("SELECT * FROM t FOR VERSION AS OF 'version1'")) - .isEqualTo( - new Query( - location(1, 1), - Optional.empty(), - new QuerySpecification( - location(1, 1), - new Select( - location(1, 1), - false, - ImmutableList.of( - new AllColumns( - location(1, 8), - Optional.empty(), - ImmutableList.of()))), - Optional.of(table), - Optional.empty(), - Optional.empty(), - Optional.empty(), - ImmutableList.of(), - Optional.empty(), - Optional.empty(), - Optional.empty()), - Optional.empty(), - Optional.empty(), - Optional.empty())); - } - - @Test - public void testListagg() - { - assertExpression("LISTAGG(x) WITHIN GROUP (ORDER BY x)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("LISTAGG"), - Optional.empty(), - Optional.empty(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("x", false), ASCENDING, UNDEFINED)))), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of( - identifier("x"), - new StringLiteral(""), - new BooleanLiteral("true"), - new StringLiteral("..."), - new BooleanLiteral("false")))); - - assertExpression("LISTAGG( DISTINCT x) WITHIN GROUP (ORDER BY x)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("LISTAGG"), - Optional.empty(), - Optional.empty(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("x", false), ASCENDING, UNDEFINED)))), - true, - Optional.empty(), - Optional.empty(), - ImmutableList.of( - identifier("x"), - new StringLiteral(""), - new BooleanLiteral("true"), - new StringLiteral("..."), - new BooleanLiteral("false")))); - - assertExpression("LISTAGG(x, ',') WITHIN GROUP (ORDER BY y)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("LISTAGG"), - Optional.empty(), - Optional.empty(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("y", false), ASCENDING, UNDEFINED)))), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of( - identifier("x"), - new StringLiteral(","), - new BooleanLiteral("true"), - new StringLiteral("..."), - new BooleanLiteral("false")))); - - assertExpression("LISTAGG(x, ',' ON OVERFLOW ERROR) WITHIN GROUP (ORDER BY x)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("LISTAGG"), - Optional.empty(), - Optional.empty(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("x", false), ASCENDING, UNDEFINED)))), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of( - identifier("x"), - new StringLiteral(","), - new BooleanLiteral("true"), - new StringLiteral("..."), - new BooleanLiteral("false")))); - - assertExpression("LISTAGG(x, ',' ON OVERFLOW TRUNCATE WITH COUNT) WITHIN GROUP (ORDER BY x)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("LISTAGG"), - Optional.empty(), - Optional.empty(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("x", false), ASCENDING, UNDEFINED)))), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of( - identifier("x"), - new StringLiteral(","), - new BooleanLiteral("false"), - new StringLiteral("..."), - new BooleanLiteral("true")))); - - assertExpression("LISTAGG(x, ',' ON OVERFLOW TRUNCATE 'HIDDEN' WITHOUT COUNT) WITHIN GROUP (ORDER BY x)", - new FunctionCall( - Optional.empty(), - QualifiedName.of("LISTAGG"), - Optional.empty(), - Optional.empty(), - Optional.of(new OrderBy(ImmutableList.of(new SortItem(new Identifier("x", false), ASCENDING, UNDEFINED)))), - false, - Optional.empty(), - Optional.empty(), - ImmutableList.of( - identifier("x"), - new StringLiteral(","), - new BooleanLiteral("false"), - new StringLiteral("HIDDEN"), - new BooleanLiteral("false")))); - } - - @Test - public void testFunctionRelation() - { - assertStatement("SELECT * FROM ROLL_UP(wren.test.metric, col, day)", - simpleQuery( - new Select( - false, - ImmutableList.of( - new AllColumns( - Optional.empty(), - Optional.empty(), - ImmutableList.of()))), - new FunctionRelation( - null, - QualifiedName.of("ROLL_UP"), - ImmutableList.of( - DereferenceExpression.from(QualifiedName.of("wren", "test", "metric")), - new Identifier("col"), - new Identifier("day"))))); - } - - private static QualifiedName makeQualifiedName(String tableName) - { - List parts = Splitter.on('.').splitToList(tableName).stream() - .map(Identifier::new) - .collect(toImmutableList()); - return QualifiedName.of(parts); - } - - /** - * @deprecated use {@link ParserAssert#statement(String)} instead - */ - @Deprecated - private static void assertStatement(String query, Statement expected) - { - assertParsed(query, expected, SQL_PARSER.createStatement(query, new ParsingOptions())); - assertFormattedSql(SQL_PARSER, expected); - } - - /** - * @deprecated use {@link ParserAssert#expression(String)} instead - */ - @Deprecated - private static void assertExpression(String expression, Expression expected) - { - requireNonNull(expression, "expression is null"); - requireNonNull(expected, "expected is null"); - assertParsed(expression, expected, SQL_PARSER.createExpression(expression, new ParsingOptions(AS_DECIMAL))); - } - - private static void assertParsed(String input, Node expected, Node parsed) - { - if (!parsed.equals(expected)) { - fail(format("expected\n\n%s\n\nto parse as\n\n%s\n\nbut was\n\n%s\n", - indent(input), - indent(formatSql(expected)), - indent(formatSql(parsed)))); - } - } - - private static void assertInvalidExpression(String expression, String expectedErrorMessageRegex) - { - assertExpressionIsInvalid(expression) - .withMessageMatching("line \\d+:\\d+: " + expectedErrorMessageRegex); - } - - private static String indent(String value) - { - String indent = " "; - return indent + value.trim().replaceAll("\n", "\n" + indent); - } - - private static Expression createExpression(String expression) - { - return SQL_PARSER.createExpression(expression, new ParsingOptions()); - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/parser/TestSqlParserErrorHandling.java b/trino-parser/src/test/java/io/trino/sql/parser/TestSqlParserErrorHandling.java deleted file mode 100644 index 7f1c8fe1d..000000000 --- a/trino-parser/src/test/java/io/trino/sql/parser/TestSqlParserErrorHandling.java +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.Timeout; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; - -import java.util.stream.Stream; - -import static java.util.concurrent.TimeUnit.SECONDS; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class TestSqlParserErrorHandling -{ - private static final SqlParser SQL_PARSER = new SqlParser(); - private static final ParsingOptions PARSING_OPTIONS = new ParsingOptions(); - - private static Stream expressions() - { - return Stream.of( - Arguments.of("", "line 1:1: mismatched input ''. Expecting: "), - // Canner: sc-9618 Fix the error message - Arguments.of("1 + 1 x", "line 1:7: mismatched input 'x'. Expecting: '%', '*', '+', '-', '.', '/', '::', 'AND', 'AT', 'COLLATE', 'OPERATOR', 'OR', '[', '||', , ")); - } - - private static Stream statements() - { - return Stream.of( - Arguments.of("", - "line 1:1: mismatched input ''. Expecting: 'ALTER', 'ANALYZE', 'CALL', 'COMMENT', 'COMMIT', 'CREATE', 'DEALLOCATE', 'DECLARE', 'DELETE', 'DENY', 'DESC', 'DESCRIBE', 'DROP', 'EXECUTE', 'EXPLAIN', 'FETCH', 'GRANT', 'IMPERSONATE', " + - "'INSERT', 'MERGE', 'PREPARE', 'REFRESH', 'RESET', 'REVOKE', 'ROLLBACK', 'SET', 'SHOW', 'START', 'TRUNCATE', 'UPDATE', 'USE', "), - Arguments.of("@select", - "line 1:1: mismatched input '@'. Expecting: 'ALTER', 'ANALYZE', 'CALL', 'COMMENT', 'COMMIT', 'CREATE', 'DEALLOCATE', 'DECLARE', 'DELETE', 'DENY', 'DESC', 'DESCRIBE', 'DROP', 'EXECUTE', 'EXPLAIN', 'FETCH', 'GRANT', 'IMPERSONATE', " + - "'INSERT', 'MERGE', 'PREPARE', 'REFRESH', 'RESET', 'REVOKE', 'ROLLBACK', 'SET', 'SHOW', 'START', 'TRUNCATE', 'UPDATE', 'USE', "), - Arguments.of("select * from foo where @what", - "line 1:25: mismatched input '@'. Expecting: "), - // Canner: sc-9618 Fix the error message - Arguments.of("select * from 'oops", - "line 1:15: mismatched input '''. Expecting: '(', 'LATERAL', 'UNNEST', , , IDENTIFIER"), - Arguments.of("select *\nfrom x\nfrom", - "line 3:1: mismatched input 'from'. Expecting: ',', '.', 'AS', 'CROSS', 'EXCEPT', 'FETCH', 'FOR', 'FULL', 'GROUP', 'HAVING', 'INNER', 'INTERSECT', 'JOIN', 'LEFT', " + - "'LIMIT', 'MATCH_RECOGNIZE', 'NATURAL', 'OFFSET', 'ORDER', 'RIGHT', 'TABLESAMPLE', 'UNION', 'WHERE', 'WINDOW', , "), - Arguments.of("select *\nfrom x\nwhere from", - "line 3:7: mismatched input 'from'. Expecting: "), - Arguments.of("select ", - "line 1:8: mismatched input ''. Expecting: '*', 'ALL', 'DISTINCT', "), - // Canner: sc-9618 Fix the error message - Arguments.of("select * from", - "line 1:14: mismatched input ''. Expecting: '(', 'LATERAL', 'UNNEST', , , IDENTIFIER"), - // Canner: sc-9618 Fix the error message - Arguments.of("select * from ", - "line 1:16: mismatched input ''. Expecting: '(', 'LATERAL', 'UNNEST', , , IDENTIFIER"), - Arguments.of("select * from `foo`", - "line 1:15: backquoted identifiers are not supported; use double quotes to quote identifiers"), - Arguments.of("select * from foo `bar`", - "line 1:19: backquoted identifiers are not supported; use double quotes to quote identifiers"), - Arguments.of("select 1x from dual", - "line 1:8: identifiers must not start with a digit; surround the identifier with double quotes"), - // Canner: sc-9618 Fix the error message - Arguments.of("select fuu from dual order by fuu order by fuu", - "line 1:35: mismatched input 'order'. Expecting: '%', '*', '+', ',', '-', '.', '/', '::', 'AND', 'ASC', 'AT', 'COLLATE', 'DESC', 'FETCH', 'LIMIT', 'NULLS', 'OFFSET', 'OPERATOR', 'OR', '[', '||', , "), - Arguments.of("select fuu from dual limit 10 order by fuu", - "line 1:31: mismatched input 'order'. Expecting: '::', "), - Arguments.of("select CAST(12223222232535343423232435343 AS BIGINT)", - "line 1:1: Invalid numeric literal: 12223222232535343423232435343"), - Arguments.of("select CAST(-12223222232535343423232435343 AS BIGINT)", - "line 1:1: Invalid numeric literal: -12223222232535343423232435343"), - // Canner: sc-9618 Fix the error message - Arguments.of("select foo.!", - "line 1:12: mismatched input '!'. Expecting: '*', 'CURRENT_SCHEMA', "), - Arguments.of("select foo(,1)", - "line 1:12: mismatched input ','. Expecting: ')', '*', 'ALL', 'DISTINCT', 'ORDER', "), - Arguments.of("select foo ( ,1)", - "line 1:14: mismatched input ','. Expecting: ')', '*', 'ALL', 'DISTINCT', 'ORDER', "), - Arguments.of("select foo(DISTINCT)", - "line 1:20: mismatched input ')'. Expecting: "), - Arguments.of("select foo(DISTINCT ,1)", - "line 1:21: mismatched input ','. Expecting: "), - Arguments.of("CREATE )", - "line 1:8: mismatched input ')'. Expecting: 'MATERIALIZED', 'OR', 'ROLE', 'SCHEMA', 'TABLE', 'VIEW'"), - Arguments.of("CREATE TABLE ) AS (VALUES 1)", - "line 1:14: mismatched input ')'. Expecting: 'IF', "), - Arguments.of("CREATE TABLE foo ", - "line 1:18: mismatched input ''. Expecting: '(', '.', 'AS', 'COMMENT', 'WITH'"), - // Canner: sc-9618 Fix the error message - Arguments.of("CREATE TABLE foo () AS (VALUES 1)", - "line 1:19: mismatched input ')'. Expecting: , LIKE"), - // Canner: sc-9618 Fix the error message - Arguments.of("CREATE TABLE foo (*) AS (VALUES 1)", - "line 1:19: mismatched input '*'. Expecting: , LIKE"), - Arguments.of("SELECT grouping(a+2) FROM (VALUES (1)) AS t (a) GROUP BY a+2", - "line 1:18: mismatched input '+'. Expecting: ')', ',', '.'"), - Arguments.of("SELECT x() over (ROWS select) FROM t", - "line 1:23: mismatched input 'select'. Expecting: 'BETWEEN', 'CURRENT', 'UNBOUNDED', "), - Arguments.of("SELECT X() OVER (ROWS UNBOUNDED) FROM T", - "line 1:32: mismatched input ')'. Expecting: 'FOLLOWING', 'PRECEDING'"), - Arguments.of("SELECT a FROM x ORDER BY (SELECT b FROM t WHERE ", - "line 1:49: mismatched input ''. Expecting: "), - Arguments.of("SELECT a FROM a AS x TABLESAMPLE x ", - "line 1:34: mismatched input 'x'. Expecting: 'BERNOULLI', 'SYSTEM'"), - Arguments.of("SELECT a AS z FROM t GROUP BY CUBE (a), ", - "line 1:41: mismatched input ''. Expecting: '(', 'CUBE', 'GROUPING', 'ROLLUP', "), - Arguments.of("SELECT a AS z FROM t WHERE x = 1 + ", - "line 1:36: mismatched input ''. Expecting: "), - // Canner: sc-9618 Fix the error message - Arguments.of("SELECT a AS z FROM t WHERE a. ", - "line 1:29: mismatched input '.'. Expecting: '%', '*', '+', '-', '/', 'AND', 'AT', 'COLLATE', 'EXCEPT', 'FETCH', 'GROUP', 'HAVING', 'INTERSECT', 'LIMIT', 'OFFSET', 'OPERATOR', 'OR', 'ORDER', 'UNION', 'WINDOW', '||', , "), - Arguments.of("CREATE TABLE t (x bigint) COMMENT ", - "line 1:35: mismatched input ''. Expecting: "), - // Canner: sc-9618 Fix the error message - Arguments.of("SELECT * FROM ( ", - "line 1:17: mismatched input ''. Expecting: '(', 'LATERAL', 'UNNEST', , , , IDENTIFIER"), - // Canner: sc-9618 Fix the error message - Arguments.of("SELECT CAST(a AS )", - "line 1:18: mismatched input ')'. Expecting: , IDENTIFIER"), - Arguments.of("SELECT CAST(a AS decimal()", - "line 1:26: mismatched input ')'. Expecting: , "), - Arguments.of("SELECT foo(*) filter (", - "line 1:23: mismatched input ''. Expecting: 'WHERE'"), - Arguments.of("SELECT * FROM t t x", - "line 1:19: mismatched input 'x'. Expecting: '(', ',', 'CROSS', 'EXCEPT', 'FETCH', 'FULL', 'GROUP', 'HAVING', 'INNER', 'INTERSECT', 'JOIN', 'LEFT', 'LIMIT', " + - "'MATCH_RECOGNIZE', 'NATURAL', 'OFFSET', 'ORDER', 'RIGHT', 'TABLESAMPLE', 'UNION', 'WHERE', 'WINDOW', "), - Arguments.of("SELECT * FROM t WHERE EXISTS (", - "line 1:31: mismatched input ''. Expecting: "), - Arguments.of("SELECT \"\" FROM t", - "line 1:8: Zero-length delimited identifier not allowed"), - Arguments.of("SELECT a FROM \"\"", - "line 1:15: Zero-length delimited identifier not allowed"), - Arguments.of("SELECT a FROM \"\".t", - "line 1:15: Zero-length delimited identifier not allowed"), - Arguments.of("SELECT a FROM \"\".s.t", - "line 1:15: Zero-length delimited identifier not allowed"), - // Canner: sc-9618 Fix the error message - Arguments.of("WITH t AS (SELECT 1 SELECT t.* FROM t", - "line 1:21: mismatched input 'SELECT'. Expecting: '%', '(', ')', '*', '+', ',', '-', '.', '/', '::', 'AND', 'AS', 'AT', 'COLLATE', 'EXCEPT', 'FETCH', 'FROM', " + - "'GROUP', 'HAVING', 'INTERSECT', 'LIMIT', 'OFFSET', 'OPERATOR', 'OR', 'ORDER', 'SELECT', 'TABLE', 'UNION', 'VALUES', " + - "'WHERE', 'WINDOW', '[', '||', , , "), - Arguments.of("SHOW CATALOGS LIKE '%$_%' ESCAPE", - "line 1:33: mismatched input ''. Expecting: "), - Arguments.of("SHOW SCHEMAS IN foo LIKE '%$_%' ESCAPE", - "line 1:39: mismatched input ''. Expecting: "), - Arguments.of("SHOW FUNCTIONS LIKE '%$_%' ESCAPE", - "line 1:34: mismatched input ''. Expecting: "), - Arguments.of("SHOW SESSION LIKE '%$_%' ESCAPE", - "line 1:32: mismatched input ''. Expecting: "), - Arguments.of("SHOW CATALOGS LIKE '%$_%' ESCAPE", - "line 1:33: mismatched input ''. Expecting: "), - Arguments.of("SHOW SCHEMAS IN foo LIKE '%$_%' ESCAPE", - "line 1:39: mismatched input ''. Expecting: "), - Arguments.of("SHOW FUNCTIONS LIKE '%$_%' ESCAPE", - "line 1:34: mismatched input ''. Expecting: "), - Arguments.of("SHOW SESSION LIKE '%$_%' ESCAPE", - "line 1:32: mismatched input ''. Expecting: "), - Arguments.of("SELECT * FROM t FOR TIMESTAMP ", - "line 1:31: mismatched input ''. Expecting: 'AS'"), - Arguments.of("SELECT * FROM t FOR TIMESTAMP AS OF TIMESTAMP WHERE", - "line 1:52: mismatched input ''. Expecting: "), - Arguments.of("SELECT * FROM t FOR VERSION AS OF TIMESTAMP WHERE", - "line 1:50: mismatched input ''. Expecting: ")); - } - - @Test - @Timeout(value = 1, unit = SECONDS) - public void testPossibleExponentialBacktracking() - { - testStatement("SELECT CASE WHEN " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9 * " + - "1 * 2 * 3 * 4 * 5 * 6 * 7 * 8 * 9", - // Canner: sc-9618 Fix the error message - "line 1:375: mismatched input ''. Expecting: '%', '*', '+', '-', '/', 'AT', 'OPERATOR', 'THEN', '||'"); - } - - @Test - public void testPossibleExponentialBacktracking2() - { - testStatement("SELECT id FROM t WHERE\n" + - "(f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "OR (f()\n" + - "GROUP BY id", - // Canner: sc-9618 Fix the error message - "line 24:1: mismatched input 'GROUP'. Expecting: ')', ',', '.', '::', 'FILTER', 'IGNORE', 'OVER', 'RESPECT', '['"); - } - - @ParameterizedTest - @MethodSource("statements") - public void testStatement(String sql, String error) - { - assertThatThrownBy(() -> SQL_PARSER.createStatement(sql, PARSING_OPTIONS)) - .isInstanceOf(ParsingException.class) - .hasMessage(error); - } - - @ParameterizedTest - @MethodSource("expressions") - public void testExpression(String sql, String error) - { - assertThatThrownBy(() -> SQL_PARSER.createExpression(sql, PARSING_OPTIONS)) - .isInstanceOf(ParsingException.class) - .hasMessage(error); - } - - @Test - public void testParsingExceptionPositionInfo() - { - assertThatThrownBy(() -> SQL_PARSER.createStatement("select *\nfrom x\nwhere from", PARSING_OPTIONS)) - .isInstanceOfSatisfying(ParsingException.class, e -> { - assertTrue(e.getMessage().startsWith("line 3:7: mismatched input 'from'")); - assertTrue(e.getErrorMessage().startsWith("mismatched input 'from'")); - assertEquals(3, e.getLineNumber()); - assertEquals(7, e.getColumnNumber()); - }); - } - - @Test - public void testStackOverflowExpression() - { - assertThatThrownBy( - () -> { - for (int size = 3000; size <= 100_000; size *= 2) { - String expression = "x = y"; - for (int i = 1; i < size; i++) { - expression = "(" + expression + ") OR x = y"; - } - SQL_PARSER.createExpression(expression, new ParsingOptions()); - } - }) - .hasMessageContaining("line 1:1: expression is too large (stack overflow while parsing)"); - } - - @Test - public void testStackOverflowStatement() - { - assertThatThrownBy( - () -> { - for (int size = 6000; size <= 100_000; size *= 2) { - String expression = "x = y"; - for (int i = 1; i < size; i++) { - expression = "(" + expression + ") OR x = y"; - } - SQL_PARSER.createStatement("SELECT " + expression, PARSING_OPTIONS); - } - }) - .hasMessageContaining("line 1:1: statement is too large (stack overflow while parsing)"); - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/parser/TestStatementBuilder.java b/trino-parser/src/test/java/io/trino/sql/parser/TestStatementBuilder.java deleted file mode 100644 index fec0906f6..000000000 --- a/trino-parser/src/test/java/io/trino/sql/parser/TestStatementBuilder.java +++ /dev/null @@ -1,448 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import com.google.common.io.Resources; -import io.trino.sql.SqlFormatter; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Statement; -import org.junit.jupiter.api.Test; - -import java.io.IOException; -import java.io.UncheckedIOException; - -import static com.google.common.base.Strings.repeat; -import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DOUBLE; -import static io.trino.sql.testing.TreeAssertions.assertFormattedSql; -import static java.lang.String.format; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; - -public class TestStatementBuilder -{ - private static final SqlParser SQL_PARSER = new SqlParser(); - - @Test - public void testPreparedGrantWithQuotes() - { - printStatement("prepare p from grant select on table hive.test.\"case\" to role test"); - printStatement("prepare p from grant select on hive.test.\"case\" to role test"); - printStatement("prepare p from grant select on table hive.test.\"case\" to role \"case\""); - } - - @Test - public void testStatementBuilder() - { - printStatement("select * from foo"); - printStatement("explain select * from foo"); - printStatement("explain (type distributed, format graphviz) select * from foo"); - - printStatement("select * from foo /* end */"); - printStatement("/* start */ select * from foo"); - printStatement("/* start */ select * /* middle */ from foo /* end */"); - printStatement("-- start\nselect * -- junk\n-- hi\nfrom foo -- done"); - - printStatement("select * from foo a (x, y, z)"); - - printStatement("select *, 123, * from foo"); - - printStatement("select show from foo"); - printStatement("select extract(day from x), extract(dow from x) from y"); - - printStatement("select 1 + 13 || '15' from foo"); - - printStatement("select x is distinct from y from foo where a is not distinct from b"); - - printStatement("select x[1] from my_table"); - printStatement("select x[1][2] from my_table"); - printStatement("select x[cast(10 * sin(x) as bigint)] from my_table"); - - printStatement("select * from (select * from (select * from t) x) y"); - printStatement("select * from (select * from (table t) x) y"); - - printStatement("select * from t x tablesample system (10)"); - printStatement("select * from (t x tablesample system (10)) y"); - printStatement("select * from (t tablesample system (10)) tablesample system (10)"); - printStatement("select * from (t x tablesample system (10)) y tablesample system (10)"); - - printStatement("select * from (((select q)))"); - printStatement("select * from (select q) x"); - printStatement("select * from ((select q) x) y"); - printStatement("select * from (((select q) x) y) z"); - - printStatement("select * from unnest(t.my_array)"); - printStatement("select * from unnest(array[1, 2, 3])"); - printStatement("select x from unnest(array[1, 2, 3]) t(x)"); - printStatement("select * from users cross join unnest(friends)"); - printStatement("select id, friend from users cross join unnest(friends) t(friend)"); - printStatement("select * from unnest(t.my_array) with ordinality"); - printStatement("select * from unnest(array[1, 2, 3]) with ordinality"); - printStatement("select x from unnest(array[1, 2, 3]) with ordinality t(x)"); - printStatement("select * from users cross join unnest(friends) with ordinality"); - printStatement("select id, friend from users cross join unnest(friends) with ordinality t(friend)"); - - printStatement("select count(*) x from src group by k, v"); - printStatement("select count(*) x from src group by cube (k, v)"); - printStatement("select count(*) x from src group by rollup (k, v)"); - printStatement("select count(*) x from src group by grouping sets ((k, v))"); - printStatement("select count(*) x from src group by grouping sets ((k, v), (v))"); - printStatement("select count(*) x from src group by grouping sets (k, v, k)"); - - printStatement("select count(*) filter (where x > 4) y from t"); - printStatement("select sum(x) filter (where x > 4) y from t"); - printStatement("select sum(x) filter (where x > 4) y, sum(x) filter (where x < 2) z from t"); - printStatement("select sum(distinct x) filter (where x > 4) y, sum(x) filter (where x < 2) z from t"); - printStatement("select sum(x) filter (where x > 4) over (partition by y) z from t"); - - printStatement("" + - "select depname, empno, salary\n" + - ", count(*) over ()\n" + - ", avg(salary) over (partition by depname)\n" + - ", rank() over (partition by depname order by salary desc)\n" + - ", sum(salary) over (order by salary rows unbounded preceding)\n" + - ", sum(salary) over (partition by depname order by salary rows between current row and 3 following)\n" + - ", sum(salary) over (partition by depname order by salary rows between current row and empno following)\n" + - ", sum(salary) over (partition by depname range unbounded preceding)\n" + - ", sum(salary) over (rows between 2 preceding and unbounded following)\n" + - "from emp"); - - printStatement("" + - "with a (id) as (with x as (select 123 from z) select * from x) " + - " , b (id) as (select 999 from z) " + - "select * from a join b using (id)"); - - printStatement("with recursive t as (select * from x) select * from t"); - - printStatement("select * from information_schema.tables"); - - printStatement("show catalogs"); - - printStatement("show schemas"); - printStatement("show schemas from sys"); - - printStatement("show tables"); - printStatement("show tables from information_schema"); - printStatement("show tables like '%'"); - printStatement("show tables from information_schema like '%'"); - - printStatement("show functions"); - - printStatement("select cast('123' as bigint), try_cast('foo' as bigint)"); - - printStatement("select * from a.b.c"); - printStatement("select * from a.b.c.e.f.g"); - - printStatement("select \"TOTALPRICE\" \"my price\" from \"$MY\"\"ORDERS\""); - - printStatement("select * from foo tablesample system (10+1)"); - printStatement("select * from foo tablesample system (10) join bar tablesample bernoulli (30) on a.id = b.id"); - printStatement("select * from foo tablesample system (10) join bar tablesample bernoulli (30) on not(a.id > b.id)"); - - printStatement("create table foo as (select * from abc)"); - printStatement("create table if not exists foo as (select * from abc)"); - printStatement("create table foo with (a = 'apple', b = 'banana') as select * from abc"); - printStatement("create table foo comment 'test' with (a = 'apple') as select * from abc"); - printStatement("create table foo as select * from abc WITH NO DATA"); - - printStatement("create table foo as (with t(x) as (values 1) select x from t)"); - printStatement("create table if not exists foo as (with t(x) as (values 1) select x from t)"); - printStatement("create table foo as (with t(x) as (values 1) select x from t) WITH DATA"); - printStatement("create table if not exists foo as (with t(x) as (values 1) select x from t) WITH DATA"); - printStatement("create table foo as (with t(x) as (values 1) select x from t) WITH NO DATA"); - printStatement("create table if not exists foo as (with t(x) as (values 1) select x from t) WITH NO DATA"); - - printStatement("create table foo(a) as (with t(x) as (values 1) select x from t)"); - printStatement("create table if not exists foo(a) as (with t(x) as (values 1) select x from t)"); - printStatement("create table foo(a) as (with t(x) as (values 1) select x from t) WITH DATA"); - printStatement("create table if not exists foo(a) as (with t(x) as (values 1) select x from t) WITH DATA"); - printStatement("create table foo(a) as (with t(x) as (values 1) select x from t) WITH NO DATA"); - printStatement("create table if not exists foo(a) as (with t(x) as (values 1) select x from t) WITH NO DATA"); - printStatement("drop table foo"); - - printStatement("insert into foo select * from abc"); - - printStatement("delete from foo"); - printStatement("delete from foo where a = b"); - - printStatement("truncate table foo"); - - printStatement("values ('a', 1, 2.2), ('b', 2, 3.3)"); - - printStatement("table foo"); - printStatement("table foo order by x limit 10"); - printStatement("(table foo)"); - printStatement("(table foo) limit 10"); - printStatement("(table foo limit 5) limit 10"); - - printStatement("select * from a limit all"); - printStatement("select * from a order by x limit all"); - - printStatement("select * from a union select * from b"); - printStatement("table a union all table b"); - printStatement("(table foo) union select * from foo union (table foo order by x)"); - - printStatement("table a union table b intersect table c"); - printStatement("(table a union table b) intersect table c"); - printStatement("table a union table b except table c intersect table d"); - printStatement("(table a union table b except table c) intersect table d"); - printStatement("((table a union table b) except table c) intersect table d"); - printStatement("(table a union (table b except table c)) intersect table d"); - printStatement("table a intersect table b union table c"); - printStatement("table a intersect (table b union table c)"); - - printStatement("alter table foo rename to bar"); - printStatement("alter table a.b.c rename to d.e.f"); - - printStatement("alter table a.b.c rename column x to y"); - - printStatement("alter table foo set properties a='1'"); - printStatement("alter table a.b.c set properties a=true, b=123, c='x'"); - printStatement("alter table a.b.c set properties a=DEFAULT, b=123"); - - printStatement("alter table a.b.c add column x bigint"); - - printStatement("alter table a.b.c add column x bigint comment 'large x'"); - printStatement("alter table a.b.c add column x bigint with (weight = 2)"); - printStatement("alter table a.b.c add column x bigint comment 'xtra' with (compression = 'LZ4', special = true)"); - - printStatement("alter table a.b.c drop column x"); - - printStatement("alter materialized view foo set properties a='1'"); - printStatement("alter materialized view a.b.c set properties a=true, b=123, c='x'"); - printStatement("alter materialized view a.b.c set properties a=default, b=123"); - - printStatement("create schema test"); - printStatement("create schema test authorization alice"); - printStatement("create schema test authorization alice with ( location = 'xyz' )"); - printStatement("create schema test authorization user alice"); - printStatement("create schema test authorization user alice with ( location = 'xyz' )"); - printStatement("create schema test authorization role public"); - printStatement("create schema test authorization role public with ( location = 'xyz' )"); - printStatement("create schema if not exists test"); - printStatement("create schema test with (a = 'apple', b = 123)"); - - printStatement("drop schema test"); - printStatement("drop schema test cascade"); - printStatement("drop schema if exists test"); - printStatement("drop schema if exists test restrict"); - - printStatement("alter schema foo rename to bar"); - printStatement("alter schema foo.bar rename to baz"); - - printStatement("alter schema foo set authorization alice"); - printStatement("alter schema foo.bar set authorization USER alice"); - printStatement("alter schema foo.bar set authorization ROLE public"); - - printStatement("create table test (a boolean, b bigint, c double, d varchar, e timestamp)"); - printStatement("create table test (a boolean, b bigint comment 'test')"); - printStatement("create table if not exists baz (a timestamp, b varchar)"); - printStatement("create table test (a boolean, b bigint) with (a = 'apple', b = 'banana')"); - printStatement("create table test (a boolean, b bigint) comment 'test' with (a = 'apple')"); - printStatement("create table test (a boolean with (a = 'apple', b = 'banana'), b bigint comment 'bla' with (c = 'cherry')) comment 'test' with (a = 'apple')"); - printStatement("comment on table test is 'test'"); - printStatement("comment on column test.a is 'test'"); - printStatement("drop table test"); - - printStatement("alter table foo set authorization alice"); - printStatement("alter table foo.bar set authorization USER alice"); - printStatement("alter table foo.bar.baz set authorization ROLE public"); - - printStatement("create view foo as with a as (select 123) select * from a"); - printStatement("create or replace view foo as select 123 from t"); - - printStatement("drop view foo"); - printStatement("alter view foo set authorization alice"); - printStatement("alter view foo.bar set authorization USER alice"); - printStatement("alter view foo.bar.baz set authorization ROLE public"); - - printStatement("insert into t select * from t"); - printStatement("insert into t (c1, c2) select * from t"); - - printStatement("start transaction"); - printStatement("start transaction isolation level read uncommitted"); - printStatement("start transaction isolation level read committed"); - printStatement("start transaction isolation level repeatable read"); - printStatement("start transaction isolation level serializable"); - printStatement("start transaction read only"); - printStatement("start transaction read write"); - printStatement("start transaction isolation level read committed, read only"); - printStatement("start transaction read only, isolation level read committed"); - printStatement("start transaction read write, isolation level serializable"); - printStatement("commit"); - printStatement("commit work"); - printStatement("rollback"); - printStatement("rollback work"); - - printStatement("call foo()"); - printStatement("call foo(123, a => 1, b => 'go', 456)"); - - printStatement("grant select on foo to alice with grant option"); - printStatement("grant all privileges on foo to alice"); - printStatement("grant delete, select on foo to role public"); - printStatement("deny select on foo to alice"); - printStatement("deny all privileges on foo to alice"); - printStatement("deny delete, select on foo to role public"); - printStatement("deny select on schema foo to alice"); - printStatement("deny all privileges on schema foo to alice"); - printStatement("deny delete, select on schema foo to role public"); - printStatement("revoke grant option for select on foo from alice"); - printStatement("revoke all privileges on foo from alice"); - printStatement("revoke insert, delete on foo from role public"); - printStatement("show grants on table t"); - printStatement("show grants on t"); - printStatement("show grants"); - printStatement("show roles"); - printStatement("show roles from foo"); - printStatement("show current roles"); - printStatement("show current roles from foo"); - printStatement("show role grants"); - printStatement("show role grants from foo"); - - printStatement("prepare p from select * from (select * from T) \"A B\""); - - printStatement("SELECT * FROM table1 WHERE a >= ALL (VALUES 2, 3, 4)"); - printStatement("SELECT * FROM table1 WHERE a <> ANY (SELECT 2, 3, 4)"); - printStatement("SELECT * FROM table1 WHERE a = SOME (SELECT id FROM table2)"); - - printStatement("" + - "merge into inventory as i\n" + - "using changes as c\n" + - "on i.part = c.part\n" + - "when matched and c.action = 'mod' then\n" + - "update set qty = qty + c.qty\n" + - "when matched and c.action = 'del' then delete\n" + - "when not matched and c.action = 'new' then\n" + - "insert (part, qty) values (c.part, c.qty)"); - } - - @Test - public void testStringFormatter() - { - assertSqlFormatter("U&'hello\\6d4B\\8Bd5\\+10FFFFworld\\7F16\\7801'", - "'hello测试\uDBFF\uDFFFworld编码'"); - assertSqlFormatter("'hello world'", "'hello world'"); - assertSqlFormatter("U&'!+10FFFF!6d4B!8Bd5ABC!6d4B!8Bd5' UESCAPE '!'", "'\uDBFF\uDFFF测试ABC测试'"); - assertSqlFormatter("U&'\\+10FFFF\\6D4B\\8BD5\\0041\\0042\\0043\\6D4B\\8BD5'", "'\uDBFF\uDFFF测试ABC测试'"); - assertSqlFormatter("U&'\\\\abc\\6D4B'''", "'\\abc测'''"); - assertSqlFormatter("'攻殻機動隊'", "'攻殻機動隊'"); - assertSqlFormatter("'😂'", "'😂'"); - assertSqlFormatter("'시험'", "'시험'"); - } - - @Test - public void testStatementBuilderTpch() - { - printTpchQuery(1, 3); - printTpchQuery(2, 33, "part type like", "region name"); - printTpchQuery(3, "market segment", "2013-03-05"); - printTpchQuery(4, "2013-03-05"); - printTpchQuery(5, "region name", "2013-03-05"); - printTpchQuery(6, "2013-03-05", 33, 44); - printTpchQuery(7, "nation name 1", "nation name 2"); - printTpchQuery(8, "nation name", "region name", "part type"); - printTpchQuery(9, "part name like"); - printTpchQuery(10, "2013-03-05"); - printTpchQuery(11, "nation name", 33); - printTpchQuery(12, "ship mode 1", "ship mode 2", "2013-03-05"); - printTpchQuery(13, "comment like 1", "comment like 2"); - printTpchQuery(14, "2013-03-05"); - // query 15: views not supported - printTpchQuery(16, "part brand", "part type like", 3, 4, 5, 6, 7, 8, 9, 10); - printTpchQuery(17, "part brand", "part container"); - printTpchQuery(18, 33); - printTpchQuery(19, "part brand 1", "part brand 2", "part brand 3", 11, 22, 33); - printTpchQuery(20, "part name like", "2013-03-05", "nation name"); - printTpchQuery(21, "nation name"); - printTpchQuery(22, - "phone 1", - "phone 2", - "phone 3", - "phone 4", - "phone 5", - "phone 6", - "phone 7"); - } - - private static void printStatement(String sql) - { - println(sql.trim()); - println(""); - - ParsingOptions parsingOptions = new ParsingOptions(AS_DOUBLE /* anything */); - Statement statement = SQL_PARSER.createStatement(sql, parsingOptions); - println(statement.toString()); - println(""); - - println(SqlFormatter.formatSql(statement)); - println(""); - assertFormattedSql(SQL_PARSER, statement); - - println(repeat("=", 60)); - println(""); - } - - private static void assertSqlFormatter(String expression, String formatted) - { - Expression originalExpression = SQL_PARSER.createExpression(expression, new ParsingOptions()); - String real = SqlFormatter.formatSql(originalExpression); - assertEquals(formatted, real); - } - - private static void println(String s) - { - if (Boolean.parseBoolean(System.getProperty("printParse"))) { - System.out.println(s); - } - } - - private static String getTpchQuery(int q) - { - return readResource("tpch/queries/" + q + ".sql"); - } - - private static void printTpchQuery(int query, Object... values) - { - String sql = getTpchQuery(query); - - for (int i = values.length - 1; i >= 0; i--) { - sql = sql.replaceAll(format(":%s", i + 1), String.valueOf(values[i])); - } - - assertFalse(sql.matches("(?s).*:[0-9].*"), "Not all bind parameters were replaced: " + sql); - - sql = fixTpchQuery(sql); - printStatement(sql); - } - - private static String readResource(String name) - { - try { - return Resources.toString(Resources.getResource(name), UTF_8); - } - catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - private static String fixTpchQuery(String s) - { - s = s.replaceFirst("(?m);$", ""); - s = s.replaceAll("(?m)^:[xo]$", ""); - s = s.replaceAll("(?m)^:n -1$", ""); - s = s.replaceAll("(?m)^:n ([0-9]+)$", "LIMIT $1"); - s = s.replace("day (3)", "day"); // for query 1 - return s; - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/parser/TestStatementSplitter.java b/trino-parser/src/test/java/io/trino/sql/parser/TestStatementSplitter.java deleted file mode 100644 index 9b0d47106..000000000 --- a/trino-parser/src/test/java/io/trino/sql/parser/TestStatementSplitter.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import org.junit.jupiter.api.Test; - -import java.util.List; - -import static com.google.common.base.Preconditions.checkArgument; -import static io.trino.sql.parser.StatementSplitter.Statement; -import static io.trino.sql.parser.StatementSplitter.isEmptyStatement; -import static io.trino.sql.parser.StatementSplitter.squeezeStatement; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -public class TestStatementSplitter -{ - @Test - public void testSplitterIncomplete() - { - StatementSplitter splitter = new StatementSplitter(" select * FROM foo "); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals("select * FROM foo", splitter.getPartialStatement()); - } - - @Test - public void testSplitterEmptyInput() - { - StatementSplitter splitter = new StatementSplitter(""); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals("", splitter.getPartialStatement()); - } - - @Test - public void testSplitterEmptyStatements() - { - StatementSplitter splitter = new StatementSplitter(";;;"); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals("", splitter.getPartialStatement()); - } - - @Test - public void testSplitterSingle() - { - StatementSplitter splitter = new StatementSplitter("select * from foo;"); - assertEquals(statements("select * from foo", ";"), splitter.getCompleteStatements()); - assertEquals("", splitter.getPartialStatement()); - } - - @Test - public void testSplitterMultiple() - { - StatementSplitter splitter = new StatementSplitter(" select * from foo ; select * from t; select * from "); - assertEquals(statements("select * from foo", ";", "select * from t", ";"), splitter.getCompleteStatements()); - assertEquals("select * from", splitter.getPartialStatement()); - } - - @Test - public void testSplitterMultipleWithEmpty() - { - StatementSplitter splitter = new StatementSplitter("; select * from foo ; select * from t;;;select * from "); - assertEquals(statements("select * from foo", ";", "select * from t", ";"), splitter.getCompleteStatements()); - assertEquals("select * from", splitter.getPartialStatement()); - } - - @Test - public void testSplitterCustomDelimiters() - { - String sql = "// select * from foo // select * from t;//select * from "; - StatementSplitter splitter = new StatementSplitter(sql, ImmutableSet.of(";", "//")); - assertEquals(statements("select * from foo", "//", "select * from t", ";"), splitter.getCompleteStatements()); - assertEquals("select * from", splitter.getPartialStatement()); - } - - @Test - public void testSplitterErrorBeforeComplete() - { - StatementSplitter splitter = new StatementSplitter(" select * from z# oops ; select "); - assertEquals(statements("select * from z# oops", ";"), splitter.getCompleteStatements()); - assertEquals("select", splitter.getPartialStatement()); - } - - @Test - public void testSplitterErrorAfterComplete() - { - StatementSplitter splitter = new StatementSplitter("select * from foo; select z# oops "); - assertEquals(statements("select * from foo", ";"), splitter.getCompleteStatements()); - assertEquals("select z# oops", splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithQuotedString() - { - String sql = "select 'foo bar' x from dual"; - StatementSplitter splitter = new StatementSplitter(sql); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals(sql, splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithIncompleteQuotedString() - { - String sql = "select 'foo', 'bar"; - StatementSplitter splitter = new StatementSplitter(sql); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals(sql, splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithEscapedSingleQuote() - { - String sql = "select 'hello''world' from dual"; - StatementSplitter splitter = new StatementSplitter(sql + ";"); - assertEquals(statements(sql, ";"), splitter.getCompleteStatements()); - assertEquals("", splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithQuotedIdentifier() - { - String sql = "select \"0\"\"bar\" from dual"; - StatementSplitter splitter = new StatementSplitter(sql + ";"); - assertEquals(statements(sql, ";"), splitter.getCompleteStatements()); - assertEquals("", splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithBackquote() - { - String sql = "select ` f``o o ` from dual"; - StatementSplitter splitter = new StatementSplitter(sql); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals(sql, splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithDigitIdentifier() - { - String sql = "select 1x from dual"; - StatementSplitter splitter = new StatementSplitter(sql); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals(sql, splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithSingleLineComment() - { - StatementSplitter splitter = new StatementSplitter("--empty\n;-- start\nselect * -- junk\n-- hi\nfrom foo; -- done"); - assertEquals(statements("--empty", ";", "-- start\nselect * -- junk\n-- hi\nfrom foo", ";"), splitter.getCompleteStatements()); - assertEquals("-- done", splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithMultiLineComment() - { - StatementSplitter splitter = new StatementSplitter("/* empty */;/* start */ select * /* middle */ from foo; /* end */"); - assertEquals(statements("/* empty */", ";", "/* start */ select * /* middle */ from foo", ";"), splitter.getCompleteStatements()); - assertEquals("/* end */", splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithSingleLineCommentPartial() - { - String sql = "-- start\nselect * -- junk\n-- hi\nfrom foo -- done"; - StatementSplitter splitter = new StatementSplitter(sql); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals(sql, splitter.getPartialStatement()); - } - - @Test - public void testSplitterWithMultiLineCommentPartial() - { - String sql = "/* start */ select * /* middle */ from foo /* end */"; - StatementSplitter splitter = new StatementSplitter(sql); - assertEquals(ImmutableList.of(), splitter.getCompleteStatements()); - assertEquals(sql, splitter.getPartialStatement()); - } - - @Test - public void testIsEmptyStatement() - { - assertTrue(isEmptyStatement("")); - assertTrue(isEmptyStatement(" ")); - assertTrue(isEmptyStatement("\t\n ")); - assertTrue(isEmptyStatement("--foo\n --what")); - assertTrue(isEmptyStatement("/* oops */")); - assertFalse(isEmptyStatement("x")); - assertFalse(isEmptyStatement("select")); - assertFalse(isEmptyStatement("123")); - assertFalse(isEmptyStatement("z#oops")); - } - - @Test - public void testSqueezeStatement() - { - String sql = "select * from\n foo\n order by x ; "; - assertEquals("select * from foo order by x ;", squeezeStatement(sql)); - } - - @Test - public void testSqueezeStatementWithIncompleteQuotedString() - { - String sql = "select * from\n foo\n where x = 'oops"; - assertEquals("select * from foo where x = 'oops", squeezeStatement(sql)); - } - - @Test - public void testSqueezeStatementWithBackquote() - { - String sql = "select ` f``o o`` ` from dual"; - assertEquals("select ` f``o o`` ` from dual", squeezeStatement(sql)); - } - - @Test - public void testSqueezeStatementAlternateDelimiter() - { - String sql = "select * from\n foo\n order by x // "; - assertEquals("select * from foo order by x //", squeezeStatement(sql)); - } - - @Test - public void testSqueezeStatementError() - { - String sql = "select * from z#oops"; - assertEquals("select * from z#oops", squeezeStatement(sql)); - } - - private static List statements(String... args) - { - checkArgument(args.length % 2 == 0, "arguments not paired"); - ImmutableList.Builder list = ImmutableList.builder(); - for (int i = 0; i < args.length; i += 2) { - list.add(new Statement(args[i], args[i + 1])); - } - return list.build(); - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/parser/TestTypeParser.java b/trino-parser/src/test/java/io/trino/sql/parser/TestTypeParser.java deleted file mode 100644 index 0511a28d6..000000000 --- a/trino-parser/src/test/java/io/trino/sql/parser/TestTypeParser.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import org.junit.jupiter.api.Test; - -import static io.trino.sql.parser.ParserAssert.type; -import static io.trino.sql.parser.TreeNodes.dateTimeType; -import static io.trino.sql.parser.TreeNodes.field; -import static io.trino.sql.parser.TreeNodes.identifier; -import static io.trino.sql.parser.TreeNodes.intervalType; -import static io.trino.sql.parser.TreeNodes.location; -import static io.trino.sql.parser.TreeNodes.parameter; -import static io.trino.sql.parser.TreeNodes.parametricType; -import static io.trino.sql.parser.TreeNodes.rowType; -import static io.trino.sql.parser.TreeNodes.simpleType; -import static io.trino.sql.tree.DateTimeDataType.Type.TIME; -import static io.trino.sql.tree.DateTimeDataType.Type.TIMESTAMP; -import static io.trino.sql.tree.IntervalDayTimeDataType.Field.DAY; -import static io.trino.sql.tree.IntervalDayTimeDataType.Field.MONTH; -import static io.trino.sql.tree.IntervalDayTimeDataType.Field.SECOND; -import static io.trino.sql.tree.IntervalDayTimeDataType.Field.YEAR; -import static org.assertj.core.api.Assertions.assertThat; - -public class TestTypeParser -{ - @Test - public void testCaseVariants() - { - assertThat(type("varchar")) - .isEqualTo(simpleType(location(1, 1), "varchar")); - - assertThat(type("VARCHAR")) - .isEqualTo(simpleType(location(1, 1), "VARCHAR")); - - assertThat(type("Varchar")) - .isEqualTo(simpleType(location(1, 1), "Varchar")); - - assertThat(type("ARRAY(bigint)")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 1), "ARRAY"), - parameter(simpleType(location(1, 7), "bigint")))); - - assertThat(type("Array(Bigint)")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 1), "Array"), - parameter(simpleType(location(1, 7), "Bigint")))); - - assertThat(type("array(bigint)")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 1), "array"), - parameter(simpleType(location(1, 7), "bigint")))); - } - - @Test - public void testDoublePrecisionVariants() - { - assertThat(type("DOUBLE PRECISION")) - .isEqualTo(simpleType(location(1, 1), "DOUBLE")); - - assertThat(type("DOUBLE PRECISION")) - .isEqualTo(simpleType(location(1, 1), "DOUBLE")); - - assertThat(type("double precision")) - .isEqualTo(simpleType(location(1, 1), "double")); - - assertThat(type("ROW(DOUBLE PRECISION)")) - .isEqualTo(rowType( - location(1, 1), - field(location(1, 5), simpleType(location(1, 5), "DOUBLE")))); - } - - @Test - public void testSimpleTypes() - { - assertThat(type("VARCHAR")) - .isEqualTo(simpleType(location(1, 1), "VARCHAR")); - - assertThat(type("BIGINT")) - .isEqualTo(simpleType(location(1, 1), "BIGINT")); - - assertThat(type("DOUBLE")) - .isEqualTo(simpleType(location(1, 1), "DOUBLE")); - - assertThat(type("BOOLEAN")) - .isEqualTo(simpleType(location(1, 1), "BOOLEAN")); - } - - @Test - public void testDayTimeTypes() - { - assertThat(type("TIMESTAMP")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, false)); - - assertThat(type("TIMESTAMP WITHOUT TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, false)); - - assertThat(type("TIMESTAMP WITH TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, true)); - - assertThat(type("TIMESTAMP(3)")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, false, parameter(location(1, 11), "3"))); - - assertThat(type("TIMESTAMP(3) WITHOUT TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, false, parameter(location(1, 11), "3"))); - - assertThat(type("TIMESTAMP(3) WITH TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, true, parameter(location(1, 11), "3"))); - - assertThat(type("TIMESTAMP(p)")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, false, parameter(simpleType(location(1, 11), "p")))); - - assertThat(type("TIMESTAMP(p) WITHOUT TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, false, parameter(simpleType(location(1, 11), "p")))); - - assertThat(type("TIMESTAMP(p) WITH TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIMESTAMP, true, parameter(simpleType(location(1, 11), "p")))); - - assertThat(type("TIME")) - .isEqualTo(dateTimeType(location(1, 1), TIME, false)); - - assertThat(type("TIME WITHOUT TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIME, false)); - - assertThat(type("TIME WITH TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIME, true)); - - assertThat(type("TIME(3)")) - .isEqualTo(dateTimeType(location(1, 1), TIME, false, parameter(location(1, 6), "3"))); - - assertThat(type("TIME(3) WITHOUT TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIME, false, parameter(location(1, 6), "3"))); - - assertThat(type("TIME(3) WITH TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIME, true, parameter(location(1, 6), "3"))); - - assertThat(type("TIME(p)")) - .isEqualTo(dateTimeType(location(1, 1), TIME, false, parameter(simpleType(location(1, 6), "p")))); - - assertThat(type("TIME(p) WITHOUT TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIME, false, parameter(simpleType(location(1, 6), "p")))); - - assertThat(type("TIME(p) WITH TIME ZONE")) - .isEqualTo(dateTimeType(location(1, 1), TIME, true, parameter(simpleType(location(1, 6), "p")))); - } - - @Test - public void testIntervalTypes() - { - assertThat(type("INTERVAL YEAR TO DAY")) - .isEqualTo(intervalType(location(1, 1), YEAR, DAY)); - - assertThat(type("INTERVAL YEAR TO MONTH")) - .isEqualTo(intervalType(location(1, 1), YEAR, MONTH)); - - assertThat(type("INTERVAL SECOND")) - .isEqualTo(intervalType(location(1, 1), SECOND, SECOND)); - } - - @Test - public void testParametricTypes() - { - assertThat(type("ARRAY(TINYINT)")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 1), "ARRAY"), - parameter(simpleType(location(1, 7), "TINYINT")))); - - assertThat(type("ARRAY ( TINYINT ) ")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 1), "ARRAY"), - parameter(simpleType(location(1, 9), "TINYINT")))); - - assertThat(type("MAP(BIGINT, SMALLINT)")) - .isEqualTo(parametricType( - location(1, 1), - "MAP", - parameter(simpleType(location(1, 5), "BIGINT")), - parameter(simpleType(location(1, 13), "SMALLINT")))); - } - - @Test - public void testArray() - { - assertThat(type("foo(42, 55) ARRAY")) - .isEqualTo(parametricType(location(1, 1), - identifier(location(1, 13), "ARRAY"), - parameter(parametricType(location(1, 1), "foo", - parameter(location(1, 5), "42"), - parameter(location(1, 9), "55"))))); - - assertThat(type("VARCHAR(7) ARRAY")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 12), "ARRAY"), - parameter(parametricType( - location(1, 1), - identifier(location(1, 1), "VARCHAR"), - parameter(location(1, 9), "7"))))); - - assertThat(type("VARCHAR(7) ARRAY array")) - .isEqualTo( - parametricType( - location(1, 1), - identifier(location(1, 18), "array"), - parameter( - parametricType( - location(1, 1), - identifier(location(1, 12), "ARRAY"), - parameter(parametricType( - location(1, 1), - identifier(location(1, 1), "VARCHAR"), - parameter(location(1, 9), "7"))))))); - } - - @Test - public void testRowType() - { - assertThat(type("ROW(a BIGINT, b VARCHAR)")) - .isEqualTo(rowType( - location(1, 1), - field(location(1, 5), "a", simpleType(location(1, 7), "BIGINT")), - field(location(1, 15), "b", simpleType(location(1, 17), "VARCHAR")))); - - assertThat(type("ROW(a BIGINT,b VARCHAR)")) - .describedAs("No space after comma") - .isEqualTo(rowType( - location(1, 1), - field(location(1, 5), "a", simpleType(location(1, 7), "BIGINT")), - field(location(1, 14), "b", simpleType(location(1, 16), "VARCHAR")))); - - assertThat(type("ROW(\"a\" BIGINT, \"b\" VARCHAR)")) - .isEqualTo(rowType( - location(1, 1), - field(location(1, 5), "a", true, simpleType(location(1, 9), "BIGINT")), - field(location(1, 17), "b", true, simpleType(location(1, 21), "VARCHAR")))); - } - - @Test - public void testComplexTypes() - { - assertThat(type("ROW(x BIGINT, y DOUBLE PRECISION, z ROW(m array,n map))")) - .isEqualTo(rowType( - location(1, 1), - field(location(1, 5), "x", simpleType(location(1, 7), "BIGINT")), - field(location(1, 15), "y", simpleType(location(1, 17), "DOUBLE")), - field(location(1, 35), "z", rowType( - location(1, 37), - field(location(1, 41), "m", parametricType( - location(1, 43), - "array", - parameter(simpleType(location(1, 49), "bigint")))), - field(location(1, 57), "n", parametricType( - location(1, 59), - "map", - parameter(simpleType(location(1, 63), "double")), - parameter(simpleType(location(1, 70), "varchar")))))))); - } - - @Test - public void testLegacyTypes() - { - assertThat(type("ARRAY")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 1), "ARRAY"), - parameter(simpleType(location(1, 7), "BIGINT")))); - - assertThat(type("ARRAY < BIGINT > ")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 1), "ARRAY"), - parameter(simpleType(location(1, 9), "BIGINT")))); - - assertThat(type("ARRAY>")) - .isEqualTo(parametricType(location(1, 1), "ARRAY", parameter( - parametricType( - location(1, 7), - "ARRAY", - parameter(simpleType(location(1, 13), "BIGINT")))))); - - assertThat(type("ARRAY>")) - .isEqualTo(parametricType( - location(1, 1), - "ARRAY", - parameter(parametricType( - location(1, 7), - "array", - parameter(parametricType( - location(1, 13), - "varchar", - parameter(location(1, 21), "42"))))))); - - assertThat(type("ARRAY")) - .isEqualTo(parametricType(location(1, 1), "ARRAY", parameter( - parametricType( - location(1, 7), - "varchar", - parameter(location(1, 15), "42"))))); - - assertThat(type("MAP")) - .isEqualTo(parametricType( - location(1, 1), - "MAP", - parameter(simpleType(location(1, 5), "BIGINT")), - parameter(simpleType(location(1, 13), "VARCHAR")))); - - assertThat(type("MAP ARRAY")) - .isEqualTo(parametricType( - location(1, 1), - identifier(location(1, 22), "ARRAY"), - parameter( - parametricType( - location(1, 1), - "MAP", - parameter(simpleType(location(1, 5), "BIGINT")), - parameter(simpleType(location(1, 13), "VARCHAR")))))); - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/parser/TreeNodes.java b/trino-parser/src/test/java/io/trino/sql/parser/TreeNodes.java deleted file mode 100644 index 9fd928568..000000000 --- a/trino-parser/src/test/java/io/trino/sql/parser/TreeNodes.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed 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 io.trino.sql.parser; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.tree.ColumnDefinition; -import io.trino.sql.tree.DataType; -import io.trino.sql.tree.DataTypeParameter; -import io.trino.sql.tree.DateTimeDataType; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.GenericDataType; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.IntervalDayTimeDataType; -import io.trino.sql.tree.NodeLocation; -import io.trino.sql.tree.NumericParameter; -import io.trino.sql.tree.Property; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.RowDataType; -import io.trino.sql.tree.TypeParameter; - -import java.util.Arrays; -import java.util.List; -import java.util.Optional; - -import static java.util.Collections.emptyList; - -class TreeNodes -{ - private TreeNodes() {} - - public static NodeLocation location(int line, int column) - { - return new NodeLocation(line, column); - } - - public static Identifier identifier(NodeLocation location, String name) - { - return new Identifier(location, name, false); - } - - public static DataType simpleType(NodeLocation location, String identifier) - { - return new GenericDataType(location, new Identifier(location, identifier, false), ImmutableList.of()); - } - - public static IntervalDayTimeDataType intervalType(NodeLocation location, IntervalDayTimeDataType.Field from, IntervalDayTimeDataType.Field to) - { - return new IntervalDayTimeDataType(location, from, to); - } - - public static DateTimeDataType dateTimeType(NodeLocation location, DateTimeDataType.Type kind, boolean withTimeZone) - { - return new DateTimeDataType(location, kind, withTimeZone, Optional.empty()); - } - - public static DateTimeDataType dateTimeType(NodeLocation location, DateTimeDataType.Type kind, boolean withTimeZone, DataTypeParameter precision) - { - return new DateTimeDataType(location, kind, withTimeZone, Optional.of(precision)); - } - - public static RowDataType rowType(NodeLocation location, RowDataType.Field... fields) - { - return new RowDataType(location, Arrays.asList(fields)); - } - - public static RowDataType.Field field(NodeLocation location, String name, DataType type) - { - return field(location, name, false, type); - } - - public static RowDataType.Field field(NodeLocation location, DataType type) - { - return new RowDataType.Field(location, Optional.empty(), type); - } - - public static RowDataType.Field field(NodeLocation location, String name, boolean delimited, DataType type) - { - return new RowDataType.Field( - location, - Optional.of(new Identifier(location, name, delimited)), - type); - } - - public static GenericDataType parametricType(NodeLocation location, String name, DataTypeParameter... parameters) - { - return new GenericDataType( - location, - new Identifier(location, name, false), - Arrays.asList(parameters)); - } - - public static GenericDataType parametricType(NodeLocation location, Identifier name, DataTypeParameter... parameters) - { - return new GenericDataType(location, name, Arrays.asList(parameters)); - } - - public static TypeParameter parameter(DataType type) - { - return new TypeParameter(type); - } - - public static NumericParameter parameter(NodeLocation location, String value) - { - return new NumericParameter(location, value); - } - - public static ColumnDefinition columnDefinition(NodeLocation location, String name, DataType type) - { - return new ColumnDefinition(location, identifier(location, name), type, true, emptyList(), Optional.empty()); - } - - public static ColumnDefinition columnDefinition(NodeLocation location, String name, DataType type, boolean nullable) - { - return new ColumnDefinition(location, identifier(location, name), type, nullable, emptyList(), Optional.empty()); - } - - public static ColumnDefinition columnDefinition(NodeLocation location, String name, DataType type, boolean nullable, String comment) - { - return new ColumnDefinition(location, identifier(location, name), type, nullable, emptyList(), Optional.of(comment)); - } - - public static ColumnDefinition columnDefinition(NodeLocation location, String name, DataType type, boolean nullable, List properties) - { - return new ColumnDefinition(location, identifier(location, name), type, nullable, properties, Optional.empty()); - } - - public static Property property(NodeLocation location, String name, Expression value) - { - return new Property(location, identifier(location, name), value); - } - - public static QualifiedName qualifiedName(NodeLocation location, String part) - { - return QualifiedName.of(ImmutableList.of(identifier(location, part))); - } -} diff --git a/trino-parser/src/test/java/io/trino/sql/tree/TestLikePredicate.java b/trino-parser/src/test/java/io/trino/sql/tree/TestLikePredicate.java deleted file mode 100644 index 472bc90d9..000000000 --- a/trino-parser/src/test/java/io/trino/sql/tree/TestLikePredicate.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Licensed 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 io.trino.sql.tree; - -import com.google.common.collect.ImmutableList; -import org.junit.jupiter.api.Test; - -import java.util.Optional; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class TestLikePredicate -{ - @Test - public void testGetChildren() - { - StringLiteral value = new StringLiteral("a"); - StringLiteral pattern = new StringLiteral("b"); - StringLiteral escape = new StringLiteral("c"); - - assertEquals(ImmutableList.of(value, pattern, escape), new LikePredicate(value, pattern, escape).getChildren()); - assertEquals(ImmutableList.of(value, pattern), new LikePredicate(value, pattern, Optional.empty()).getChildren()); - } -} diff --git a/trino-parser/src/test/java/io/trino/type/TestTypeCalculation.java b/trino-parser/src/test/java/io/trino/type/TestTypeCalculation.java deleted file mode 100644 index 3bd8df1e8..000000000 --- a/trino-parser/src/test/java/io/trino/type/TestTypeCalculation.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed 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 io.trino.type; - -import com.google.common.collect.ImmutableMap; -import org.junit.jupiter.api.Test; - -import static io.trino.type.TypeCalculation.calculateLiteralValue; -import static org.junit.jupiter.api.Assertions.assertEquals; - -public class TestTypeCalculation -{ - @Test - public void testBasicUsage() - { - assertEquals(Long.valueOf(42), calculateLiteralValue("42", ImmutableMap.of())); - assertEquals(Long.valueOf(0), calculateLiteralValue("NULL", ImmutableMap.of())); - assertEquals(Long.valueOf(0), calculateLiteralValue("null", ImmutableMap.of())); - assertEquals(Long.valueOf(42), calculateLiteralValue("x", ImmutableMap.of("x", 42L))); - assertEquals(Long.valueOf(42), calculateLiteralValue("(42)", ImmutableMap.of())); - assertEquals(Long.valueOf(0), calculateLiteralValue("(NULL)", ImmutableMap.of())); - assertEquals(Long.valueOf(42), calculateLiteralValue("(x)", ImmutableMap.of("x", 42L))); - - assertEquals(Long.valueOf(42 + 55), calculateLiteralValue("42 + 55", ImmutableMap.of())); - assertEquals(Long.valueOf(42 - 55), calculateLiteralValue("42 - 55", ImmutableMap.of())); - assertEquals(Long.valueOf(42 * 55), calculateLiteralValue("42 * 55", ImmutableMap.of())); - assertEquals(Long.valueOf(42 / 6), calculateLiteralValue("42 / 6", ImmutableMap.of())); - - assertEquals(Long.valueOf(42 + 55 * 6), calculateLiteralValue("42 + 55 * 6", ImmutableMap.of())); - assertEquals(Long.valueOf((42 + 55) * 6), calculateLiteralValue("(42 + 55) * 6", ImmutableMap.of())); - - assertEquals(Long.valueOf(2), calculateLiteralValue("min(10,2)", ImmutableMap.of())); - assertEquals(Long.valueOf(10), calculateLiteralValue("min(10,2*10)", ImmutableMap.of())); - assertEquals(Long.valueOf(20), calculateLiteralValue("max(10,2*10)", ImmutableMap.of())); - assertEquals(Long.valueOf(10), calculateLiteralValue("max(10,2)", ImmutableMap.of())); - - assertEquals(Long.valueOf(42 + 55), calculateLiteralValue("x + y", ImmutableMap.of("x", 42L, "y", 55L))); - } -} diff --git a/trino-parser/src/test/resources/tpch/queries/1.sql b/trino-parser/src/test/resources/tpch/queries/1.sql deleted file mode 100644 index d03095997..000000000 --- a/trino-parser/src/test/resources/tpch/queries/1.sql +++ /dev/null @@ -1,28 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Pricing Summary Report Query (Q1) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - l_returnflag, - l_linestatus, - sum(l_quantity) as sum_qty, - sum(l_extendedprice) as sum_base_price, - sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, - sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, - avg(l_quantity) as avg_qty, - avg(l_extendedprice) as avg_price, - avg(l_discount) as avg_disc, - count(*) as count_order -from - lineitem -where - l_shipdate <= date '1998-12-01' - interval ':1' day (3) -group by - l_returnflag, - l_linestatus -order by - l_returnflag, - l_linestatus; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/10.sql b/trino-parser/src/test/resources/tpch/queries/10.sql deleted file mode 100644 index aa52f8ea2..000000000 --- a/trino-parser/src/test/resources/tpch/queries/10.sql +++ /dev/null @@ -1,38 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Returned Item Reporting Query (Q10) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - c_custkey, - c_name, - sum(l_extendedprice * (1 - l_discount)) as revenue, - c_acctbal, - n_name, - c_address, - c_phone, - c_comment -from - customer, - orders, - lineitem, - nation -where - c_custkey = o_custkey - and l_orderkey = o_orderkey - and o_orderdate >= date ':1' - and o_orderdate < date ':1' + interval '3' month - and l_returnflag = 'R' - and c_nationkey = n_nationkey -group by - c_custkey, - c_name, - c_acctbal, - c_phone, - n_name, - c_address, - c_comment -order by - revenue desc; -:n 20 diff --git a/trino-parser/src/test/resources/tpch/queries/11.sql b/trino-parser/src/test/resources/tpch/queries/11.sql deleted file mode 100644 index 8d8b74459..000000000 --- a/trino-parser/src/test/resources/tpch/queries/11.sql +++ /dev/null @@ -1,34 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Important Stock Identification Query (Q11) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - ps_partkey, - sum(ps_supplycost * ps_availqty) as value -from - partsupp, - supplier, - nation -where - ps_suppkey = s_suppkey - and s_nationkey = n_nationkey - and n_name = ':1' -group by - ps_partkey having - sum(ps_supplycost * ps_availqty) > ( - select - sum(ps_supplycost * ps_availqty) * :2 - from - partsupp, - supplier, - nation - where - ps_suppkey = s_suppkey - and s_nationkey = n_nationkey - and n_name = ':1' - ) -order by - value desc; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/12.sql b/trino-parser/src/test/resources/tpch/queries/12.sql deleted file mode 100644 index 2cc7a0f80..000000000 --- a/trino-parser/src/test/resources/tpch/queries/12.sql +++ /dev/null @@ -1,35 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Shipping Modes and Order Priority Query (Q12) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - l_shipmode, - sum(case - when o_orderpriority = '1-URGENT' - or o_orderpriority = '2-HIGH' - then 1 - else 0 - end) as high_line_count, - sum(case - when o_orderpriority <> '1-URGENT' - and o_orderpriority <> '2-HIGH' - then 1 - else 0 - end) as low_line_count -from - orders, - lineitem -where - o_orderkey = l_orderkey - and l_shipmode in (':1', ':2') - and l_commitdate < l_receiptdate - and l_shipdate < l_commitdate - and l_receiptdate >= date ':3' - and l_receiptdate < date ':3' + interval '1' year -group by - l_shipmode -order by - l_shipmode; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/13.sql b/trino-parser/src/test/resources/tpch/queries/13.sql deleted file mode 100644 index 20dd693ec..000000000 --- a/trino-parser/src/test/resources/tpch/queries/13.sql +++ /dev/null @@ -1,27 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Customer Distribution Query (Q13) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - c_count, - count(*) as custdist -from - ( - select - c_custkey, - count(o_orderkey) - from - customer left outer join orders on - c_custkey = o_custkey - and o_comment not like '%:1%:2%' - group by - c_custkey - ) as c_orders (c_custkey, c_count) -group by - c_count -order by - custdist desc, - c_count desc; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/14.sql b/trino-parser/src/test/resources/tpch/queries/14.sql deleted file mode 100644 index 27c5b4793..000000000 --- a/trino-parser/src/test/resources/tpch/queries/14.sql +++ /dev/null @@ -1,20 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Promotion Effect Query (Q14) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - 100.00 * sum(case - when p_type like 'PROMO%' - then l_extendedprice * (1 - l_discount) - else 0 - end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue -from - lineitem, - part -where - l_partkey = p_partkey - and l_shipdate >= date ':1' - and l_shipdate < date ':1' + interval '1' month; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/15.sql b/trino-parser/src/test/resources/tpch/queries/15.sql deleted file mode 100644 index 77fe2a400..000000000 --- a/trino-parser/src/test/resources/tpch/queries/15.sql +++ /dev/null @@ -1,40 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Top Supplier Query (Q15) --- Functional Query Definition --- Approved February 1998 -:x -create view revenue:s (supplier_no, total_revenue) as - select - l_suppkey, - sum(l_extendedprice * (1 - l_discount)) - from - lineitem - where - l_shipdate >= date ':1' - and l_shipdate < date ':1' + interval '3' month - group by - l_suppkey; - -:o -select - s_suppkey, - s_name, - s_address, - s_phone, - total_revenue -from - supplier, - revenue:s -where - s_suppkey = supplier_no - and total_revenue = ( - select - max(total_revenue) - from - revenue:s - ) -order by - s_suppkey; - -drop view revenue:s; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/16.sql b/trino-parser/src/test/resources/tpch/queries/16.sql deleted file mode 100644 index f07a96575..000000000 --- a/trino-parser/src/test/resources/tpch/queries/16.sql +++ /dev/null @@ -1,37 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Parts/Supplier Relationship Query (Q16) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - p_brand, - p_type, - p_size, - count(distinct ps_suppkey) as supplier_cnt -from - partsupp, - part -where - p_partkey = ps_partkey - and p_brand <> ':1' - and p_type not like ':2%' - and p_size in (:3, :4, :5, :6, :7, :8, :9, :10) - and ps_suppkey not in ( - select - s_suppkey - from - supplier - where - s_comment like '%Customer%Complaints%' - ) -group by - p_brand, - p_type, - p_size -order by - supplier_cnt desc, - p_brand, - p_type, - p_size; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/17.sql b/trino-parser/src/test/resources/tpch/queries/17.sql deleted file mode 100644 index bca3f1bb4..000000000 --- a/trino-parser/src/test/resources/tpch/queries/17.sql +++ /dev/null @@ -1,24 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Small-Quantity-Order Revenue Query (Q17) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - sum(l_extendedprice) / 7.0 as avg_yearly -from - lineitem, - part -where - p_partkey = l_partkey - and p_brand = ':1' - and p_container = ':2' - and l_quantity < ( - select - 0.2 * avg(l_quantity) - from - lineitem - where - l_partkey = p_partkey - ); -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/18.sql b/trino-parser/src/test/resources/tpch/queries/18.sql deleted file mode 100644 index 3f7e12568..000000000 --- a/trino-parser/src/test/resources/tpch/queries/18.sql +++ /dev/null @@ -1,39 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Large Volume Customer Query (Q18) --- Function Query Definition --- Approved February 1998 -:x -:o -select - c_name, - c_custkey, - o_orderkey, - o_orderdate, - o_totalprice, - sum(l_quantity) -from - customer, - orders, - lineitem -where - o_orderkey in ( - select - l_orderkey - from - lineitem - group by - l_orderkey having - sum(l_quantity) > :1 - ) - and c_custkey = o_custkey - and o_orderkey = l_orderkey -group by - c_name, - c_custkey, - o_orderkey, - o_orderdate, - o_totalprice -order by - o_totalprice desc, - o_orderdate; -:n 100 diff --git a/trino-parser/src/test/resources/tpch/queries/19.sql b/trino-parser/src/test/resources/tpch/queries/19.sql deleted file mode 100644 index a9c6e5d54..000000000 --- a/trino-parser/src/test/resources/tpch/queries/19.sql +++ /dev/null @@ -1,42 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Discounted Revenue Query (Q19) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - sum(l_extendedprice* (1 - l_discount)) as revenue -from - lineitem, - part -where - ( - p_partkey = l_partkey - and p_brand = ':1' - and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') - and l_quantity >= :4 and l_quantity <= :4 + 10 - and p_size between 1 and 5 - and l_shipmode in ('AIR', 'AIR REG') - and l_shipinstruct = 'DELIVER IN PERSON' - ) - or - ( - p_partkey = l_partkey - and p_brand = ':2' - and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') - and l_quantity >= :5 and l_quantity <= :5 + 10 - and p_size between 1 and 10 - and l_shipmode in ('AIR', 'AIR REG') - and l_shipinstruct = 'DELIVER IN PERSON' - ) - or - ( - p_partkey = l_partkey - and p_brand = ':3' - and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') - and l_quantity >= :6 and l_quantity <= :6 + 10 - and p_size between 1 and 15 - and l_shipmode in ('AIR', 'AIR REG') - and l_shipinstruct = 'DELIVER IN PERSON' - ); -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/2.sql b/trino-parser/src/test/resources/tpch/queries/2.sql deleted file mode 100644 index 2c941f5a7..000000000 --- a/trino-parser/src/test/resources/tpch/queries/2.sql +++ /dev/null @@ -1,50 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Minimum Cost Supplier Query (Q2) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - s_acctbal, - s_name, - n_name, - p_partkey, - p_mfgr, - s_address, - s_phone, - s_comment -from - part, - supplier, - partsupp, - nation, - region -where - p_partkey = ps_partkey - and s_suppkey = ps_suppkey - and p_size = :1 - and p_type like '%:2' - and s_nationkey = n_nationkey - and n_regionkey = r_regionkey - and r_name = ':3' - and ps_supplycost = ( - select - min(ps_supplycost) - from - partsupp, - supplier, - nation, - region - where - p_partkey = ps_partkey - and s_suppkey = ps_suppkey - and s_nationkey = n_nationkey - and n_regionkey = r_regionkey - and r_name = ':3' - ) -order by - s_acctbal desc, - n_name, - s_name, - p_partkey; -:n 100 diff --git a/trino-parser/src/test/resources/tpch/queries/20.sql b/trino-parser/src/test/resources/tpch/queries/20.sql deleted file mode 100644 index 23cecc763..000000000 --- a/trino-parser/src/test/resources/tpch/queries/20.sql +++ /dev/null @@ -1,44 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Potential Part Promotion Query (Q20) --- Function Query Definition --- Approved February 1998 -:x -:o -select - s_name, - s_address -from - supplier, - nation -where - s_suppkey in ( - select - ps_suppkey - from - partsupp - where - ps_partkey in ( - select - p_partkey - from - part - where - p_name like ':1%' - ) - and ps_availqty > ( - select - 0.5 * sum(l_quantity) - from - lineitem - where - l_partkey = ps_partkey - and l_suppkey = ps_suppkey - and l_shipdate >= date ':2' - and l_shipdate < date ':2' + interval '1' year - ) - ) - and s_nationkey = n_nationkey - and n_name = ':3' -order by - s_name; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/21.sql b/trino-parser/src/test/resources/tpch/queries/21.sql deleted file mode 100644 index 380bcfd81..000000000 --- a/trino-parser/src/test/resources/tpch/queries/21.sql +++ /dev/null @@ -1,46 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Suppliers Who Kept Orders Waiting Query (Q21) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - s_name, - count(*) as numwait -from - supplier, - lineitem l1, - orders, - nation -where - s_suppkey = l1.l_suppkey - and o_orderkey = l1.l_orderkey - and o_orderstatus = 'F' - and l1.l_receiptdate > l1.l_commitdate - and exists ( - select - * - from - lineitem l2 - where - l2.l_orderkey = l1.l_orderkey - and l2.l_suppkey <> l1.l_suppkey - ) - and not exists ( - select - * - from - lineitem l3 - where - l3.l_orderkey = l1.l_orderkey - and l3.l_suppkey <> l1.l_suppkey - and l3.l_receiptdate > l3.l_commitdate - ) - and s_nationkey = n_nationkey - and n_name = ':1' -group by - s_name -order by - numwait desc, - s_name; -:n 100 diff --git a/trino-parser/src/test/resources/tpch/queries/22.sql b/trino-parser/src/test/resources/tpch/queries/22.sql deleted file mode 100644 index 3cf5b615e..000000000 --- a/trino-parser/src/test/resources/tpch/queries/22.sql +++ /dev/null @@ -1,44 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Global Sales Opportunity Query (Q22) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - cntrycode, - count(*) as numcust, - sum(c_acctbal) as totacctbal -from - ( - select - substring(c_phone from 1 for 2) as cntrycode, - c_acctbal - from - customer - where - substring(c_phone from 1 for 2) in - (':1', ':2', ':3', ':4', ':5', ':6', ':7') - and c_acctbal > ( - select - avg(c_acctbal) - from - customer - where - c_acctbal > 0.00 - and substring(c_phone from 1 for 2) in - (':1', ':2', ':3', ':4', ':5', ':6', ':7') - ) - and not exists ( - select - * - from - orders - where - o_custkey = c_custkey - ) - ) as custsale -group by - cntrycode -order by - cntrycode; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/3.sql b/trino-parser/src/test/resources/tpch/queries/3.sql deleted file mode 100644 index 7c388289d..000000000 --- a/trino-parser/src/test/resources/tpch/queries/3.sql +++ /dev/null @@ -1,29 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Shipping Priority Query (Q3) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - l_orderkey, - sum(l_extendedprice * (1 - l_discount)) as revenue, - o_orderdate, - o_shippriority -from - customer, - orders, - lineitem -where - c_mktsegment = ':1' - and c_custkey = o_custkey - and l_orderkey = o_orderkey - and o_orderdate < date ':2' - and l_shipdate > date ':2' -group by - l_orderkey, - o_orderdate, - o_shippriority -order by - revenue desc, - o_orderdate; -:n 10 diff --git a/trino-parser/src/test/resources/tpch/queries/4.sql b/trino-parser/src/test/resources/tpch/queries/4.sql deleted file mode 100644 index 8a99c8d41..000000000 --- a/trino-parser/src/test/resources/tpch/queries/4.sql +++ /dev/null @@ -1,28 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Order Priority Checking Query (Q4) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - o_orderpriority, - count(*) as order_count -from - orders -where - o_orderdate >= date ':1' - and o_orderdate < date ':1' + interval '3' month - and exists ( - select - * - from - lineitem - where - l_orderkey = o_orderkey - and l_commitdate < l_receiptdate - ) -group by - o_orderpriority -order by - o_orderpriority; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/5.sql b/trino-parser/src/test/resources/tpch/queries/5.sql deleted file mode 100644 index 499a735fa..000000000 --- a/trino-parser/src/test/resources/tpch/queries/5.sql +++ /dev/null @@ -1,31 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Local Supplier Volume Query (Q5) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - n_name, - sum(l_extendedprice * (1 - l_discount)) as revenue -from - customer, - orders, - lineitem, - supplier, - nation, - region -where - c_custkey = o_custkey - and l_orderkey = o_orderkey - and l_suppkey = s_suppkey - and c_nationkey = s_nationkey - and s_nationkey = n_nationkey - and n_regionkey = r_regionkey - and r_name = ':1' - and o_orderdate >= date ':2' - and o_orderdate < date ':2' + interval '1' year -group by - n_name -order by - revenue desc; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/6.sql b/trino-parser/src/test/resources/tpch/queries/6.sql deleted file mode 100644 index 8698a28a4..000000000 --- a/trino-parser/src/test/resources/tpch/queries/6.sql +++ /dev/null @@ -1,16 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Forecasting Revenue Change Query (Q6) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - sum(l_extendedprice * l_discount) as revenue -from - lineitem -where - l_shipdate >= date ':1' - and l_shipdate < date ':1' + interval '1' year - and l_discount between :2 - 0.01 and :2 + 0.01 - and l_quantity < :3; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/7.sql b/trino-parser/src/test/resources/tpch/queries/7.sql deleted file mode 100644 index d1a4441b5..000000000 --- a/trino-parser/src/test/resources/tpch/queries/7.sql +++ /dev/null @@ -1,46 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Volume Shipping Query (Q7) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - supp_nation, - cust_nation, - l_year, - sum(volume) as revenue -from - ( - select - n1.n_name as supp_nation, - n2.n_name as cust_nation, - extract(year from l_shipdate) as l_year, - l_extendedprice * (1 - l_discount) as volume - from - supplier, - lineitem, - orders, - customer, - nation n1, - nation n2 - where - s_suppkey = l_suppkey - and o_orderkey = l_orderkey - and c_custkey = o_custkey - and s_nationkey = n1.n_nationkey - and c_nationkey = n2.n_nationkey - and ( - (n1.n_name = ':1' and n2.n_name = ':2') - or (n1.n_name = ':2' and n2.n_name = ':1') - ) - and l_shipdate between date '1995-01-01' and date '1996-12-31' - ) as shipping -group by - supp_nation, - cust_nation, - l_year -order by - supp_nation, - cust_nation, - l_year; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/8.sql b/trino-parser/src/test/resources/tpch/queries/8.sql deleted file mode 100644 index 677e06f2c..000000000 --- a/trino-parser/src/test/resources/tpch/queries/8.sql +++ /dev/null @@ -1,44 +0,0 @@ --- $ID$ --- TPC-H/TPC-R National Market Share Query (Q8) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - o_year, - sum(case - when nation = ':1' then volume - else 0 - end) / sum(volume) as mkt_share -from - ( - select - extract(year from o_orderdate) as o_year, - l_extendedprice * (1 - l_discount) as volume, - n2.n_name as nation - from - part, - supplier, - lineitem, - orders, - customer, - nation n1, - nation n2, - region - where - p_partkey = l_partkey - and s_suppkey = l_suppkey - and l_orderkey = o_orderkey - and o_custkey = c_custkey - and c_nationkey = n1.n_nationkey - and n1.n_regionkey = r_regionkey - and r_name = ':2' - and s_nationkey = n2.n_nationkey - and o_orderdate between date '1995-01-01' and date '1996-12-31' - and p_type = ':3' - ) as all_nations -group by - o_year -order by - o_year; -:n -1 diff --git a/trino-parser/src/test/resources/tpch/queries/9.sql b/trino-parser/src/test/resources/tpch/queries/9.sql deleted file mode 100644 index 1d6351173..000000000 --- a/trino-parser/src/test/resources/tpch/queries/9.sql +++ /dev/null @@ -1,39 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Product Type Profit Measure Query (Q9) --- Functional Query Definition --- Approved February 1998 -:x -:o -select - nation, - o_year, - sum(amount) as sum_profit -from - ( - select - n_name as nation, - extract(year from o_orderdate) as o_year, - l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount - from - part, - supplier, - lineitem, - partsupp, - orders, - nation - where - s_suppkey = l_suppkey - and ps_suppkey = l_suppkey - and ps_partkey = l_partkey - and p_partkey = l_partkey - and o_orderkey = l_orderkey - and s_nationkey = n_nationkey - and p_name like '%:1%' - ) as profit -group by - nation, - o_year -order by - nation, - o_year desc; -:n -1 diff --git a/wren-base/pom.xml b/wren-base/pom.xml deleted file mode 100644 index 1d9b07134..000000000 --- a/wren-base/pom.xml +++ /dev/null @@ -1,192 +0,0 @@ - - - - 4.0.0 - - - io.wren - wren-root - 0.15.2-SNAPSHOT - ../pom.xml - - - wren-base - wren-base - WrenEngine - Base - - - ${project.parent.basedir} - - - - - com.fasterxml.jackson.core - jackson-annotations - - - - com.fasterxml.jackson.core - jackson-core - - - - com.fasterxml.jackson.core - jackson-databind - - - - com.google.code.findbugs - jsr305 - true - - - - com.google.inject - guice - - - - com.hubspot.jinjava - jinjava - - - - com.zaxxer - HikariCP - - - org.slf4j - slf4j-api - - - - - - io.airlift - configuration - - - - io.airlift - json - - - - io.airlift - log - - - - io.airlift - units - - - - io.wren - trino-parser - - - - jakarta.validation - jakarta.validation-api - - - - org.antlr - antlr4-runtime - - - - org.duckdb - duckdb_jdbc - - - - org.jgrapht - jgrapht-core - - - - org.postgresql - postgresql - - - - com.google.guava - guava - provided - - - - - io.airlift - testing - test - - - - org.assertj - assertj-core - test - - - - org.jetbrains - annotations - test - - - - org.junit.jupiter - junit-jupiter-engine - test - - - - org.openjdk.jmh - jmh-core - test - - - - org.openjdk.jmh - jmh-generator-annprocess - test - - - - org.testng - testng - test - - - - - - - org.antlr - antlr4-maven-plugin - ${dep.antlr.version} - - - - antlr4 - - - - - - - diff --git a/wren-base/src/main/antlr4/io/wren/base/macro/ParameterListBase.g4 b/wren-base/src/main/antlr4/io/wren/base/macro/ParameterListBase.g4 deleted file mode 100644 index 82b82ef48..000000000 --- a/wren-base/src/main/antlr4/io/wren/base/macro/ParameterListBase.g4 +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed 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. - */ - -grammar ParameterListBase; - -parameterList - : '(' (parameter (',' parameter)*)? ')' - ; - -parameter - : paraName ':' typeName - ; - -typeName - : ID - ; - -paraName - : ID - ; - -ID : [a-zA-Z_][a-zA-Z0-9_]*; - - -fragment WhiteSpace - : '\u0020' - | '\u0009' - | '\u000D' - | '\u000A' - ; - - -WS - : WhiteSpace+ -> skip - ; \ No newline at end of file diff --git a/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgArray.g4 b/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgArray.g4 deleted file mode 100644 index 9578b3c9f..000000000 --- a/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgArray.g4 +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to Crate.io GmbH ("Crate") under one or more contributor - * license agreements. See the NOTICE file distributed with this work for - * additional information regarding copyright ownership. Crate 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. - * - * However, if you have executed another commercial license agreement - * with Crate these terms will supersede the license and you may use the - * software solely pursuant to the terms of the relevant commercial agreement. - */ - -grammar PgArray; - -/** -The grammar is used to parse PG array text -representations. E.g.: - - numeric PG arrays: - {10, NULL, NULL, 20, 30} - {"10", NULL, NULL, "20", "30"} - - multi-dimentsional PG arrays: - {{"10", "20"}, {"30", NULL, "40"}} - - json PG arrays: - {"{\"x\": 10}", "{\"y\": 20}"} - {\"{\\\"x\\\": 10}\", \"{\\\"y\\\": 20}\"} -*/ - -array - : '{' item (',' item)* '}' - | '{' '}' - ; - -item - : string - | array - ; - -string - : QUOTED_STRING #quotedString - | NULL #null - | UNQUOTED_STRING #unquotedString - ; - - -NULL - : [nN] [uU] [lL] [lL] - ; - - -QUOTED_STRING - : '"' (ESC | ~["\\])* '"' - ; - -UNQUOTED_STRING - : CHAR+ (' ')* CHAR+ - | CHAR+ - ; - -fragment CHAR - : ~[,"\\{} \t\n\r] - ; - -fragment ESC - : '\\' (["\\/bfnrt] | UNICODE) - ; - -fragment UNICODE - : 'u' HEX HEX HEX HEX - ; - -fragment HEX - : [0-9a-fA-F] - ; - -WS: [ \t\n\r]+ -> skip; diff --git a/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgDateTimeFormat.g4 b/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgDateTimeFormat.g4 deleted file mode 100644 index 3c8fb3abc..000000000 --- a/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgDateTimeFormat.g4 +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Licensed 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. - */ - -grammar PgDateTimeFormat; - -format - : symbol (symbol)* - ; - -symbol - : separator - | pattern - ; - -pattern - : HOUR #hourLiteral - | MINUTE #minuteLiteral - | SECOND #secondLiteral - | MILLISECOND #milliSecondLiteral - | YEAR #yearLiteral - | MONTH #monthLiteral - | DAY #dayLiteral - | WEEK #weekLiteral - | TIME_ZONE #timeZoneLiteral - | AM #meridiemMarkerLiteral - | PM #meridiemMarkerLiteral - | BC #eraDesignatorLiteral - | AD #eraDesignatorLiteral - ; - -separator - : SEPARATOR - ; - -HOUR: ('HH' | 'hh') ('12' | '24')?; -MINUTE: 'MI' | 'mi'; -SECOND: 'SS' | 'ss'; -MILLISECOND: 'MS' | 'ms' | 'FF3' | 'ff3'; -YEAR: 'YYYY' | 'yyyy' | 'YYY' | 'yyy' | 'YY' | 'yy' | 'Y' | 'y'; -MONTH: 'MM' | 'mm' | 'Month' | 'Mon'; -DAY: 'DDD' | 'ddd' | 'DD' | 'dd' | 'D' | 'd' | 'Day' | 'Dy'; -WEEK: 'WW' | 'ww'; -TIME_ZONE: 'TZ'; -AM: 'AM' | 'am'; -PM: 'PM' | 'pm'; -BC: 'BC' | 'bc'; -AD: 'AD' | 'ad'; - -SEPARATOR: [ _/:\-\\.]; diff --git a/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgNumericFormat.g4 b/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgNumericFormat.g4 deleted file mode 100644 index 253a436fe..000000000 --- a/wren-base/src/main/antlr4/io/wren/base/type/parser/antlr/v4/PgNumericFormat.g4 +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed 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. - */ - -grammar PgNumericFormat; - -format - : pattern (pattern)* - ; - -pattern - : DIGIT_CAN_DROP #digitPattern - | DIGIT_CAN_NOT_DROP #digitPattern - | DECIMAL_POINT #decimalPointPattern - | DECIMAL_POINT_LOCALE #decimalPointPattern - | GROUP_SEPARATOR #groupSeparatorPattern - | GROUP_SEPARATOR_LOCALE #groupSeparatorPattern - | CURRENCY_SYMBOL #currencySymbolPattern - | EXPONENT #exponentPattern - | nonReserved #nonReservedPattern - ; - -nonReserved - : PR - | SHIFT_DIGIT - | ORDINAL - | ROMAN - | PLUS - | MINUS - | SIGN - | SIGN_ANCHOR_LOCALE - | FM - ; - -DIGIT_CAN_DROP: '9'; -DIGIT_CAN_NOT_DROP: '0'; -DECIMAL_POINT: '.'; -GROUP_SEPARATOR: ','; -PR: 'PR'; -SIGN_ANCHOR_LOCALE: 'S'; -CURRENCY_SYMBOL: 'L'; -DECIMAL_POINT_LOCALE: 'D'; -GROUP_SEPARATOR_LOCALE: 'G'; -MINUS: 'MI'; -PLUS: 'PL'; -SIGN: 'SG'; -ROMAN: 'RN'; -ORDINAL: 'TH' | 'th'; -SHIFT_DIGIT: 'V'; -EXPONENT: 'EEEE'; -FM: 'FM'; diff --git a/wren-base/src/main/java/io/wren/base/AnalyzedMDL.java b/wren-base/src/main/java/io/wren/base/AnalyzedMDL.java deleted file mode 100644 index fd00393d0..000000000 --- a/wren-base/src/main/java/io/wren/base/AnalyzedMDL.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import io.wren.base.sqlrewrite.WrenDataLineage; - -import javax.annotation.Nullable; - -import static java.util.Objects.requireNonNull; - -public class AnalyzedMDL -{ - private final WrenMDL wrenMDL; - private final WrenDataLineage wrenDataLineage; - private final String version; - - public AnalyzedMDL(WrenMDL wrenMDL, @Nullable String version) - { - this.wrenMDL = requireNonNull(wrenMDL); - this.wrenDataLineage = WrenDataLineage.analyze(wrenMDL); - this.version = version; - } - - public AnalyzedMDL(WrenMDL wrenMDL, WrenDataLineage wrenDataLineage, @Nullable String version) - { - this.wrenMDL = requireNonNull(wrenMDL); - this.wrenDataLineage = requireNonNull(wrenDataLineage); - this.version = version; - } - - public WrenMDL getWrenMDL() - { - return wrenMDL; - } - - public WrenDataLineage getWrenDataLineage() - { - return wrenDataLineage; - } - - @Nullable - public String getVersion() - { - return version; - } -} diff --git a/wren-base/src/main/java/io/wren/base/CatalogSchemaTableName.java b/wren-base/src/main/java/io/wren/base/CatalogSchemaTableName.java deleted file mode 100644 index 50d4bdbcb..000000000 --- a/wren-base/src/main/java/io/wren/base/CatalogSchemaTableName.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.metadata.SchemaTableName; - -import java.util.Objects; - -import static io.wren.base.metadata.SchemaUtil.checkNotEmpty; -import static java.util.Objects.requireNonNull; - -public final class CatalogSchemaTableName -{ - public static CatalogSchemaTableName catalogSchemaTableName(String catalogName, String schemaName, String tableName) - { - return new CatalogSchemaTableName(catalogName, new SchemaTableName(schemaName, tableName)); - } - - private final String catalogName; - private final SchemaTableName schemaTableName; - - @JsonCreator - public CatalogSchemaTableName( - @JsonProperty("catalog") String catalogName, - @JsonProperty("schemaTable") SchemaTableName schemaTableName) - { - this.catalogName = checkNotEmpty(catalogName, "catalogName"); - this.schemaTableName = requireNonNull(schemaTableName, "schemaTableName is null"); - } - - public CatalogSchemaTableName(String catalogName, String schemaName, String tableName) - { - this(catalogName, new SchemaTableName(schemaName, tableName)); - } - - @JsonProperty("catalog") - public String getCatalogName() - { - return catalogName; - } - - @JsonProperty("schemaTable") - public SchemaTableName getSchemaTableName() - { - return schemaTableName; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CatalogSchemaTableName that = (CatalogSchemaTableName) o; - return Objects.equals(catalogName, that.catalogName) && - Objects.equals(schemaTableName, that.schemaTableName); - } - - @Override - public int hashCode() - { - return Objects.hash(catalogName, schemaTableName); - } - - @Override - public String toString() - { - return catalogName + '.' + schemaTableName.toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/Column.java b/wren-base/src/main/java/io/wren/base/Column.java deleted file mode 100644 index f70b29588..000000000 --- a/wren-base/src/main/java/io/wren/base/Column.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Locale; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public final class Column -{ - public static Column column(String name, String type) - { - return new Column(name, type); - } - - private final String name; - private final String type; - - @JsonCreator - public Column( - @JsonProperty("name") String name, - @JsonProperty("type") String type) - { - this.name = name; - this.type = type.toUpperCase(Locale.ROOT); - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getType() - { - return type; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Column column = (Column) o; - return Objects.equals(name, column.name) && - Objects.equals(type, column.type); - } - - @Override - public int hashCode() - { - return Objects.hash(name, type); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("type", type) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/ConnectorRecordIterator.java b/wren-base/src/main/java/io/wren/base/ConnectorRecordIterator.java deleted file mode 100644 index deca1a7f6..000000000 --- a/wren-base/src/main/java/io/wren/base/ConnectorRecordIterator.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import java.util.Iterator; -import java.util.List; - -public interface ConnectorRecordIterator - extends Iterator, AutoCloseable -{ - List getColumns(); -} diff --git a/wren-base/src/main/java/io/wren/base/ErrorCode.java b/wren-base/src/main/java/io/wren/base/ErrorCode.java deleted file mode 100644 index 2effc034e..000000000 --- a/wren-base/src/main/java/io/wren/base/ErrorCode.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; - -import static java.util.Objects.requireNonNull; - -public final class ErrorCode -{ - private final int code; - private final String name; - private final ErrorType type; - - @JsonCreator - public ErrorCode( - @JsonProperty("code") int code, - @JsonProperty("name") String name, - @JsonProperty("type") ErrorType type) - { - if (code < 0) { - throw new IllegalArgumentException("code is negative"); - } - this.code = code; - this.name = requireNonNull(name, "name is null"); - this.type = requireNonNull(type, "type is null"); - } - - @JsonProperty - public int getCode() - { - return code; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public ErrorType getType() - { - return type; - } - - @Override - public String toString() - { - return name + ":" + code; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - - ErrorCode that = (ErrorCode) obj; - return Objects.equals(this.code, that.code); - } - - @Override - public int hashCode() - { - return Objects.hash(code); - } -} diff --git a/wren-base/src/main/java/io/wren/base/ErrorCodeSupplier.java b/wren-base/src/main/java/io/wren/base/ErrorCodeSupplier.java deleted file mode 100644 index 65e64061a..000000000 --- a/wren-base/src/main/java/io/wren/base/ErrorCodeSupplier.java +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -public interface ErrorCodeSupplier -{ - ErrorCode toErrorCode(); -} diff --git a/wren-base/src/main/java/io/wren/base/ErrorType.java b/wren-base/src/main/java/io/wren/base/ErrorType.java deleted file mode 100644 index 88c5e7d94..000000000 --- a/wren-base/src/main/java/io/wren/base/ErrorType.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -public enum ErrorType -{ - USER_ERROR, - INTERNAL_ERROR, - INSUFFICIENT_RESOURCES, - EXTERNAL -} diff --git a/wren-base/src/main/java/io/wren/base/Location.java b/wren-base/src/main/java/io/wren/base/Location.java deleted file mode 100644 index 9d5f6e03d..000000000 --- a/wren-base/src/main/java/io/wren/base/Location.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -public final class Location -{ - private final int lineNumber; - private final int columnNumber; - - public Location(int lineNumber, int columnNumber) - { - if (lineNumber < 1) { - throw new IllegalArgumentException("lineNumber must be at least one"); - } - - if (columnNumber < 1) { - throw new IllegalArgumentException("columnNumber must be at least one"); - } - - this.lineNumber = lineNumber; - this.columnNumber = columnNumber; - } - - public int getLineNumber() - { - return lineNumber; - } - - public int getColumnNumber() - { - return columnNumber; - } - - @Override - public String toString() - { - return lineNumber + ":" + columnNumber; - } -} diff --git a/wren-base/src/main/java/io/wren/base/Parameter.java b/wren-base/src/main/java/io/wren/base/Parameter.java deleted file mode 100644 index 9dc1b8238..000000000 --- a/wren-base/src/main/java/io/wren/base/Parameter.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import java.util.Objects; - -public class Parameter -{ - private final String type; - private final Object value; - - public Parameter(String type, Object value) - { - this.type = type; - this.value = value; - } - - public String getType() - { - return type; - } - - public Object getValue() - { - return value; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Parameter parameter = (Parameter) o; - return Objects.equals(type, parameter.type) && - Objects.equals(value, parameter.value); - } - - @Override - public int hashCode() - { - return Objects.hash(type, value); - } -} diff --git a/wren-base/src/main/java/io/wren/base/SessionContext.java b/wren-base/src/main/java/io/wren/base/SessionContext.java deleted file mode 100644 index 6825020b1..000000000 --- a/wren-base/src/main/java/io/wren/base/SessionContext.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import java.util.Optional; - -public final class SessionContext -{ - public static Builder builder() - { - return new Builder(); - } - - private final String catalog; - private final String schema; - private final boolean enableDynamicField; - - private SessionContext(String catalog, String schema, boolean enableDynamicField) - { - this.catalog = catalog; - this.schema = schema; - this.enableDynamicField = enableDynamicField; - } - - public Optional getCatalog() - { - return Optional.ofNullable(catalog); - } - - public Optional getSchema() - { - return Optional.ofNullable(schema); - } - - public boolean isEnableDynamicField() - { - return enableDynamicField; - } - - public static class Builder - { - private String catalog; - private String schema; - private boolean enableDynamic; - - public Builder setCatalog(String catalog) - { - this.catalog = catalog; - return this; - } - - public Builder setSchema(String schema) - { - this.schema = schema; - return this; - } - - public Builder setEnableDynamic(boolean enableDynamic) - { - this.enableDynamic = enableDynamic; - return this; - } - - public SessionContext build() - { - return new SessionContext(catalog, schema, enableDynamic); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/Utils.java b/wren-base/src/main/java/io/wren/base/Utils.java deleted file mode 100644 index a87b0ce37..000000000 --- a/wren-base/src/main/java/io/wren/base/Utils.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import java.security.SecureRandom; -import java.util.Arrays; -import java.util.Objects; - -import static java.lang.Character.MAX_RADIX; -import static java.lang.Math.abs; -import static java.lang.Math.min; - -public class Utils -{ - private Utils() {} - - private static final SecureRandom random = new SecureRandom(); - private static final int RANDOM_SUFFIX_LENGTH = 10; - - public static void checkArgument(boolean expression, String errorMessagePattern, Object... errorMessageArgs) - { - if (!expression) { - throw new IllegalArgumentException(String.format(errorMessagePattern, errorMessageArgs)); - } - } - - public static String requireNonNullEmpty(String value, String errorMessage) - { - checkArgument(value != null && !value.isEmpty(), errorMessage); - return value; - } - - public static String randomIntString() - { - String randomSuffix = Long.toString(abs(random.nextLong()), MAX_RADIX); - return randomSuffix.substring(0, min(RANDOM_SUFFIX_LENGTH, randomSuffix.length())); - } - - public static T firstNonNull(T... objects) - { - return Arrays.stream(objects).filter(Objects::nonNull).findFirst().orElse(null); - } -} diff --git a/wren-base/src/main/java/io/wren/base/WrenException.java b/wren-base/src/main/java/io/wren/base/WrenException.java deleted file mode 100644 index 639090894..000000000 --- a/wren-base/src/main/java/io/wren/base/WrenException.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import java.util.Optional; - -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; - -public class WrenException - extends RuntimeException -{ - private final ErrorCode errorCode; - private final Optional location; - - public WrenException(ErrorCodeSupplier errorCode, String message) - { - this(errorCode, message, null); - } - - public WrenException(ErrorCodeSupplier errorCode, Throwable throwable) - { - this(errorCode, null, throwable); - } - - public WrenException(ErrorCodeSupplier errorCode, String message, Throwable cause) - { - this(errorCode, Optional.empty(), message, cause); - } - - public WrenException(ErrorCodeSupplier errorCodeSupplier, Optional location, String message, Throwable cause) - { - super(message, cause); - this.errorCode = errorCodeSupplier.toErrorCode(); - this.location = requireNonNull(location, "location is null"); - } - - public ErrorCode getErrorCode() - { - return errorCode; - } - - public Optional getLocation() - { - return location; - } - - @Override - public String getMessage() - { - String message = getRawMessage(); - if (location.isPresent()) { - message = format("line %s:%s: %s", location.get().getLineNumber(), location.get().getColumnNumber(), message); - } - return message; - } - - public String getRawMessage() - { - String message = super.getMessage(); - if (message == null && getCause() != null) { - message = getCause().getMessage(); - } - if (message == null) { - message = errorCode.getName(); - } - return message; - } -} diff --git a/wren-base/src/main/java/io/wren/base/WrenMDL.java b/wren-base/src/main/java/io/wren/base/WrenMDL.java deleted file mode 100644 index 0f0a80968..000000000 --- a/wren-base/src/main/java/io/wren/base/WrenMDL.java +++ /dev/null @@ -1,325 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.google.common.collect.ImmutableMap; -import com.hubspot.jinjava.Jinjava; -import io.wren.base.dto.CacheInfo; -import io.wren.base.dto.Column; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.DateSpine; -import io.wren.base.dto.EnumDefinition; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationable; -import io.wren.base.dto.Relationship; -import io.wren.base.dto.View; -import io.wren.base.jinjava.JinjavaExpressionProcessor; -import io.wren.base.jinjava.JinjavaUtils; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Stream; - -import static com.fasterxml.jackson.databind.DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.ImmutableMap.toImmutableMap; -import static io.wren.base.macro.Parameter.TYPE.MACRO; -import static java.util.Objects.requireNonNull; -import static java.util.function.UnaryOperator.identity; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; - -public class WrenMDL -{ - public static final WrenMDL EMPTY = WrenMDL.fromManifest(Manifest.builder().setCatalog("default").setSchema("default").build()); - private static final ObjectMapper MAPPER = new ObjectMapper().disable(FAIL_ON_UNKNOWN_PROPERTIES); - private static final Jinjava JINJAVA = new Jinjava(); - - private final String catalog; - private final String schema; - private final Manifest manifest; - private final Map models; - private final Map metrics; - private final Map cumulativeMetrics; - private final Map relationships; - - public static WrenMDL fromJson(String manifest) - throws JsonProcessingException - { - return new WrenMDL(MAPPER.readValue(manifest, Manifest.class)); - } - - public static WrenMDL fromManifest(Manifest manifest) - { - return new WrenMDL(manifest); - } - - private WrenMDL(Manifest manifest) - { - requireNonNull(manifest, "manifest is null"); - this.manifest = renderManifest(manifest); - this.catalog = manifest.getCatalog(); - this.schema = manifest.getSchema(); - this.models = listModels().stream().collect(toImmutableMap(Model::getName, identity())); - this.metrics = listMetrics().stream().collect(toImmutableMap(Metric::getName, identity())); - this.cumulativeMetrics = listCumulativeMetrics().stream().collect(toImmutableMap(CumulativeMetric::getName, identity())); - this.relationships = listRelationships().stream().collect(toImmutableMap(Relationship::getName, identity())); - } - - private Manifest renderManifest(Manifest original) - { - String macroTags = original.getMacros().stream() - .filter(macro -> macro.getParameters().stream().noneMatch(parameter -> parameter.getType() == MACRO)) - .map(JinjavaUtils::getMacroTag).collect(joining("\n")); - List renderedModels = original.getModels().stream().map(model -> { - List processed = model.getColumns().stream().map(column -> renderExpression(column, macroTags, original)).collect(toList()); - return new Model( - model.getName(), - model.getRefSql(), - model.getBaseObject(), - model.getTableReference(), - processed, - model.getPrimaryKey(), - model.isCached(), - model.getRefreshTime()); - }).collect(toList()); - - List renderedMetrics = original.getMetrics().stream().map(metric -> - new Metric(metric.getName(), - metric.getBaseObject(), - metric.getDimension().stream().map(column -> renderExpression(column, macroTags, original)).collect(toList()), - metric.getMeasure().stream().map(column -> renderExpression(column, macroTags, original)).collect(toList()), - metric.getTimeGrain(), - metric.isCached(), - metric.getRefreshTime()) - ).collect(toList()); - - return Manifest.builder(original) - .setModels(renderedModels) - .setMetrics(renderedMetrics) - .build(); - } - - private io.wren.base.dto.Column renderExpression(io.wren.base.dto.Column original, String macroTags, Manifest unProcessedManifest) - { - if (original.getExpression().isEmpty()) { - return original; - } - - String withTag = macroTags + JinjavaExpressionProcessor.process(original.getSqlExpression(), unProcessedManifest.getMacros()); - String expression = JINJAVA.render(withTag, ImmutableMap.of()); - return new io.wren.base.dto.Column(original.getName(), - original.getType(), - original.getRelationship().orElse(null), - original.isCalculated(), - original.isNotNull(), - expression); - } - - public String getCatalog() - { - return catalog; - } - - public String getSchema() - { - return schema; - } - - public Manifest getManifest() - { - return manifest; - } - - public List listModels() - { - return manifest.getModels(); - } - - public Optional getModel(String name) - { - return Optional.ofNullable(models.get(name)); - } - - public List listRelationships() - { - return manifest.getRelationships(); - } - - public Optional getRelationship(String name) - { - return Optional.ofNullable(relationships.get(name)); - } - - public List listEnums() - { - return manifest.getEnumDefinitions(); - } - - public Optional getEnum(String name) - { - return manifest.getEnumDefinitions().stream() - .filter(enumField -> enumField.getName().equals(name)) - .findAny(); - } - - public List listMetrics() - { - return manifest.getMetrics(); - } - - public List listCached() - { - return Stream.concat(manifest.getMetrics().stream(), manifest.getModels().stream()) - .filter(CacheInfo::isCached) - .collect(toImmutableList()); - } - - public Optional getCacheInfo(CatalogSchemaTableName name) - { - if (catalog.equals(name.getCatalogName()) && schema.equals(name.getSchemaTableName().getSchemaName())) { - return listCached().stream() - .filter(cacheInfo -> cacheInfo.getName().equals(name.getSchemaTableName().getTableName())) - .findAny(); - } - return Optional.empty(); - } - - public Optional getMetric(String name) - { - return Optional.ofNullable(metrics.get(name)); - } - - public Optional getMetric(CatalogSchemaTableName name) - { - if (catalog.equals(name.getCatalogName()) && schema.equals(name.getSchemaTableName().getSchemaName())) { - return getMetric(name.getSchemaTableName().getTableName()); - } - return Optional.empty(); - } - - public List listCumulativeMetrics() - { - return manifest.getCumulativeMetrics(); - } - - public Optional getCumulativeMetric(String name) - { - return Optional.ofNullable(cumulativeMetrics.get(name)); - } - - public Optional getCumulativeMetric(CatalogSchemaTableName name) - { - if (catalog.equals(name.getCatalogName()) && schema.equals(name.getSchemaTableName().getSchemaName())) { - return getCumulativeMetric(name.getSchemaTableName().getTableName()); - } - return Optional.empty(); - } - - public Optional getView(String name) - { - return manifest.getViews().stream() - .filter(view -> view.getName().equals(name)) - .findAny(); - } - - public Optional getView(CatalogSchemaTableName name) - { - if (catalog.equals(name.getCatalogName()) && schema.equals(name.getSchemaTableName().getSchemaName())) { - return getView(name.getSchemaTableName().getTableName()); - } - return Optional.empty(); - } - - public List listViews() - { - return manifest.getViews(); - } - - public static Optional getRelationshipColumn(Model model, String name) - { - return getColumn(model, name) - .filter(column -> column.getRelationship().isPresent()); - } - - private static Optional getColumn(Model model, String name) - { - requireNonNull(model); - requireNonNull(name); - return model.getColumns().stream() - .filter(column -> column.getName().equals(name)) - .findAny(); - } - - public Optional getColumnType(String objectName, String columnName) - { - if (!isObjectExist(objectName)) { - throw new IllegalArgumentException("Dataset " + objectName + " not found"); - } - if (getModel(objectName).isPresent()) { - return getModel(objectName).get().getColumns().stream() - .filter(column -> columnName.equals(column.getName())) - .map(io.wren.base.dto.Column::getType) - .findAny(); - } - else if (getMetric(objectName).isPresent()) { - return getMetric(objectName).get().getColumns().stream() - .filter(column -> columnName.equals(column.getName())) - .map(Column::getType) - .findAny(); - } - else if (getCumulativeMetric(objectName).isPresent()) { - CumulativeMetric cumulativeMetric = getCumulativeMetric(objectName).get(); - if (cumulativeMetric.getMeasure().getName().equals(columnName)) { - return Optional.of(cumulativeMetric.getMeasure().getType()); - } - if (cumulativeMetric.getWindow().getName().equals(columnName)) { - return getColumnType(cumulativeMetric.getBaseObject(), cumulativeMetric.getWindow().getRefColumn()); - } - } - else if (getView(objectName).isPresent()) { - return Optional.empty(); - } - throw new IllegalArgumentException("Dataset " + objectName + " is not a model, metric, cumulative metric or view"); - } - - public DateSpine getDateSpine() - { - return manifest.getDateSpine(); - } - - public boolean isObjectExist(String name) - { - if (name == null) { - return false; - } - return getModel(name).isPresent() - || getMetric(name).isPresent() - || getCumulativeMetric(name).isPresent() - || getView(name).isPresent(); - } - - public Optional getRelationable(String name) - { - return getModel(name) - .map(model -> (Relationable) model) - .or(() -> getMetric(name).map(metric -> (Relationable) metric)); - } -} diff --git a/wren-base/src/main/java/io/wren/base/WrenTypes.java b/wren-base/src/main/java/io/wren/base/WrenTypes.java deleted file mode 100644 index 0f4b44f7f..000000000 --- a/wren-base/src/main/java/io/wren/base/WrenTypes.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed 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 io.wren.base; - -public final class WrenTypes -{ - public static final String BIGINT = "bigint"; - public static final String INTEGER = "integer"; - public static final String SMALLINT = "smallint"; - public static final String TINYINT = "tinyint"; - public static final String BOOLEAN = "boolean"; - public static final String DATE = "date"; - public static final String DECIMAL = "decimal"; - public static final String REAL = "real"; - public static final String DOUBLE = "double"; - public static final String HYPER_LOG_LOG = "HyperLogLog"; - public static final String QDIGEST = "qdigest"; - public static final String TDIGEST = "tdigest"; - public static final String P4_HYPER_LOG_LOG = "P4HyperLogLog"; - public static final String INTERVAL_DAY_TO_SECOND = "interval day to second"; - public static final String INTERVAL_YEAR_TO_MONTH = "interval year to month"; - public static final String TIMESTAMP = "timestamp"; - public static final String TIMESTAMP_WITH_TIME_ZONE = "timestamp with time zone"; - public static final String TIME = "time"; - public static final String TIME_WITH_TIME_ZONE = "time with time zone"; - public static final String BYTEA = "bytea"; - public static final String VARCHAR = "varchar"; - public static final String CHAR = "char"; - public static final String ROW = "row"; - public static final String TEXT = "text"; - public static final String NAME = "name"; - public static final String ARRAY = "array"; - public static final String MAP = "map"; - public static final String JSON = "json"; - public static final String IPADDRESS = "ipaddress"; - public static final String GEOMETRY = "Geometry"; - public static final String BING_TILE = "BingTile"; - public static final String UUID = "uuid"; - - private WrenTypes() {} -} diff --git a/wren-base/src/main/java/io/wren/base/client/AutoCloseableIterator.java b/wren-base/src/main/java/io/wren/base/client/AutoCloseableIterator.java deleted file mode 100644 index 5128493a7..000000000 --- a/wren-base/src/main/java/io/wren/base/client/AutoCloseableIterator.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed 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 io.wren.base.client; - -import java.util.Iterator; - -public interface AutoCloseableIterator - extends Iterator, AutoCloseable -{ -} diff --git a/wren-base/src/main/java/io/wren/base/client/Client.java b/wren-base/src/main/java/io/wren/base/client/Client.java deleted file mode 100644 index f2fcaaf82..000000000 --- a/wren-base/src/main/java/io/wren/base/client/Client.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed 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 io.wren.base.client; - -import io.wren.base.Column; -import io.wren.base.Parameter; - -import java.sql.Connection; -import java.sql.SQLException; -import java.util.List; - -import static java.util.Collections.emptyList; - -public interface Client -{ - default AutoCloseableIterator query(String sql) - { - return query(sql, emptyList()); - } - - AutoCloseableIterator query(String sql, List parameters); - - void executeDDL(String sql); - - List describe(String sql, List parameters); - - List listTables(); - - Connection createConnection() - throws SQLException; - - void close(); -} diff --git a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBConfig.java b/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBConfig.java deleted file mode 100644 index 3c4ddd4a6..000000000 --- a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBConfig.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Licensed 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. - */ - -/* - * Licensed 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 io.wren.base.client.duckdb; - -import io.airlift.configuration.Config; -import io.airlift.units.DataSize; - -public class DuckDBConfig -{ - public static final String DUCKDB_MEMORY_LIMIT = "duckdb.memory-limit"; - public static final String DUCKDB_HOME_DIRECTORY = "duckdb.home-directory"; - public static final String DUCKDB_TEMP_DIRECTORY = "duckdb.temp-directory"; - public static final String DUCKDB_MAX_CONCURRENT_TASKS = "duckdb.max-concurrent-tasks"; - public static final String DUCKDB_MAX_CACHE_QUERY_TIMEOUT = "duckdb.max-cache-query-timeout"; - public static final String DUCKDB_CACHE_TASK_RETRY_DELAY = "duckdb.cache-task-retry-delay"; - - private DataSize memoryLimit = DataSize.of(Runtime.getRuntime().maxMemory() / 2, DataSize.Unit.BYTE); - private String homeDirectory; - private String tempDirectory = "/tmp/duck"; - private int maxConcurrentTasks = 10; - private long maxCacheQueryTimeout = 20; - private long cacheTaskRetryDelay = 60; - - public DataSize getMemoryLimit() - { - return memoryLimit; - } - - @Config(DUCKDB_MEMORY_LIMIT) - public void setMemoryLimit(DataSize memoryLimit) - { - this.memoryLimit = memoryLimit; - } - - public String getHomeDirectory() - { - return homeDirectory; - } - - @Config(DUCKDB_HOME_DIRECTORY) - public void setHomeDirectory(String homeDirectory) - { - this.homeDirectory = homeDirectory; - } - - public String getTempDirectory() - { - return tempDirectory; - } - - @Config(DUCKDB_TEMP_DIRECTORY) - public void setTempDirectory(String tempDirectory) - { - this.tempDirectory = tempDirectory; - } - - public int getMaxConcurrentTasks() - { - return maxConcurrentTasks; - } - - @Config(DUCKDB_MAX_CONCURRENT_TASKS) - public void setMaxConcurrentTasks(int maxConcurrentTasks) - { - this.maxConcurrentTasks = maxConcurrentTasks; - } - - public long getMaxCacheQueryTimeout() - { - return maxCacheQueryTimeout; - } - - @Config(DUCKDB_MAX_CACHE_QUERY_TIMEOUT) - public void setMaxCacheQueryTimeout(long maxCacheQueryTimeout) - { - this.maxCacheQueryTimeout = maxCacheQueryTimeout; - } - - public long getCacheTaskRetryDelay() - { - return cacheTaskRetryDelay; - } - - @Config(DUCKDB_CACHE_TASK_RETRY_DELAY) - public void setCacheTaskRetryDelay(long cacheTaskRetryDelay) - { - this.cacheTaskRetryDelay = cacheTaskRetryDelay; - } -} diff --git a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBConnectorConfig.java b/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBConnectorConfig.java deleted file mode 100644 index ccf8cb632..000000000 --- a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBConnectorConfig.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed 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 io.wren.base.client.duckdb; - -import io.airlift.configuration.Config; - -public class DuckDBConnectorConfig -{ - public static final String DUCKDB_CONNECTOR_INIT_SQL_PATH = "duckdb.connector.init-sql-path"; - public static final String DUCKDB_CONNECTOR_SESSION_SQL_PATH = "duckdb.connector.session-sql-path"; - - private String initSQLPath = "etc/duckdb/init.sql"; - private String sessionSQLPath = "etc/duckdb/session.sql"; - - @Config(DUCKDB_CONNECTOR_INIT_SQL_PATH) - public void setInitSQLPath(String initSQLPath) - { - this.initSQLPath = initSQLPath; - } - - @Config(DUCKDB_CONNECTOR_SESSION_SQL_PATH) - public void setSessionSQLPath(String sessionSQLPath) - { - this.sessionSQLPath = sessionSQLPath; - } - - public String getInitSQLPath() - { - return initSQLPath; - } - - public String getSessionSQLPath() - { - return sessionSQLPath; - } -} diff --git a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBDataSource.java b/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBDataSource.java deleted file mode 100644 index 002171ab0..000000000 --- a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBDataSource.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed 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 io.wren.base.client.duckdb; - -import org.duckdb.DuckDBConnection; -import org.postgresql.ds.common.BaseDataSource; - -import javax.sql.DataSource; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.io.Serializable; -import java.sql.Connection; -import java.sql.SQLException; - -public class DuckDBDataSource - extends BaseDataSource - implements DataSource, Serializable -{ - private final DuckDBConnection duckDBConnection; - - public DuckDBDataSource( - DuckDBConnection duckDBConnection) - { - this.duckDBConnection = duckDBConnection; - } - - @Override - public String getDescription() - { - return "Non-Pooling DataSource from DuckDB"; - } - - /** - * Get a connection from the DuckDB instance and init some local variables. - */ - @Override - public Connection getConnection() - throws SQLException - { - // Refer to the official doc, if we want to create multiple read-write connections, - // to the same database in-memory database instance, we can use the custom `duplicate()` method. - // https://duckdb.org/docs/api/java - return duckDBConnection.duplicate(); - } - - @Override - public boolean isWrapperFor(Class iface) - { - return iface.isAssignableFrom(getClass()); - } - - @Override - public T unwrap(Class iface) - throws SQLException - { - if (iface.isAssignableFrom(getClass())) { - return iface.cast(this); - } - throw new SQLException("Cannot unwrap to " + iface.getName()); - } - - private void writeObject(ObjectOutputStream out) - throws IOException - { - writeBaseObject(out); - } - - private void readObject(ObjectInputStream in) - throws IOException, ClassNotFoundException - { - readBaseObject(in); - } -} diff --git a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBSettingSQL.java b/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBSettingSQL.java deleted file mode 100644 index af6dc6b6e..000000000 --- a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckDBSettingSQL.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Licensed 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. - */ - -/* - * - * * Licensed 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 io.wren.base.client.duckdb; - -public class DuckDBSettingSQL -{ - private String initSQL; - private String sessionSQL; - - public String getInitSQL() - { - return initSQL; - } - - public void setInitSQL(String initSQL) - { - this.initSQL = initSQL; - } - - public String getSessionSQL() - { - return sessionSQL; - } - - public void setSessionSQL(String sessionSQL) - { - this.sessionSQL = sessionSQL; - } -} diff --git a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckdbClient.java b/wren-base/src/main/java/io/wren/base/client/duckdb/DuckdbClient.java deleted file mode 100644 index d49777128..000000000 --- a/wren-base/src/main/java/io/wren/base/client/duckdb/DuckdbClient.java +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Licensed 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 io.wren.base.client.duckdb; - -import com.google.common.collect.ImmutableList; -import com.zaxxer.hikari.HikariConfig; -import com.zaxxer.hikari.HikariDataSource; -import io.airlift.log.Logger; -import io.airlift.units.DataSize; -import io.wren.base.Column; -import io.wren.base.Parameter; -import io.wren.base.WrenException; -import io.wren.base.client.AutoCloseableIterator; -import io.wren.base.client.Client; -import io.wren.base.client.jdbc.JdbcRecordIterator; -import io.wren.base.metadata.StandardErrorCode; -import org.duckdb.DuckDBConnection; - -import javax.annotation.Nullable; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -import static java.lang.String.format; - -public final class DuckdbClient - implements Client -{ - private static final Logger LOG = Logger.get(DuckdbClient.class); - private final DuckDBConfig duckDBConfig; - private final DuckDBSettingSQL duckDBSettingSQL; - private DuckDBConnection duckDBConnection; - private HikariDataSource connectionPool; - - public DuckdbClient( - DuckDBConfig duckDBConfig, - @Nullable DuckDBSettingSQL duckDBSettingSQL) - { - this.duckDBConfig = duckDBConfig; - this.duckDBSettingSQL = duckDBSettingSQL; - init(); - } - - public static Builder builder() - { - return new Builder(); - } - - private void init() - { - try { - // The instance will be cleared after the process end. We don't need to - // close this connection - Class.forName("org.duckdb.DuckDBDriver"); - duckDBConnection = (DuckDBConnection) DriverManager.getConnection("jdbc:duckdb:"); - initPool(); - if (duckDBSettingSQL != null) { - if (duckDBSettingSQL.getInitSQL() != null) { - LOG.info("Initialize by init SQL"); // Not print the SQL to avoid leaking sensitive information - executeDDL(duckDBSettingSQL.getInitSQL()); - } - } - else { - DataSize memoryLimit = duckDBConfig.getMemoryLimit(); - executeDDL(format("SET memory_limit='%s'", memoryLimit.toBytesValueString())); - LOG.info("Set memory limit to %s", memoryLimit.toBytesValueString()); - executeDDL(format("SET temp_directory='%s'", duckDBConfig.getTempDirectory())); - LOG.info("Set temp directory to %s", duckDBConfig.getTempDirectory()); - } - } - catch (SQLException | ClassNotFoundException e) { - throw new RuntimeException(e); - } - } - - public synchronized void initPool() - { - connectionPool = new HikariDataSource(getHikariConfig(duckDBConfig, duckDBConnection, duckDBSettingSQL)); - } - - private static HikariConfig getHikariConfig( - DuckDBConfig duckDBConfig, - DuckDBConnection duckDBConnection, - DuckDBSettingSQL duckDBSettingSQL) - { - DuckDBDataSource dataSource = new DuckDBDataSource(duckDBConnection); - HikariConfig config = new HikariConfig(); - config.setDataSource(dataSource); - config.setPoolName("DUCKDB_POOL"); - config.setConnectionTimeout(60000); - config.setMinimumIdle(duckDBConfig.getMaxConcurrentTasks()); - config.setMaximumPoolSize(duckDBConfig.getMaxConcurrentTasks()); - String initSql = buildConnectionInitSql(duckDBSettingSQL, duckDBConfig); - config.setConnectionInitSql(initSql); - return config; - } - - private static String buildConnectionInitSql(DuckDBSettingSQL duckDBSettingSQL, DuckDBConfig duckDBConfig) - { - List sql = new ArrayList<>(); - // Both of them should be true in default, however they're some issue in v0.10.3. - // see https://github.com/duckdb/duckdb-java/issues/18 - sql.add("SET autoload_known_extensions = true"); - sql.add("SET autoinstall_known_extensions = true"); - if (duckDBSettingSQL != null) { - if (duckDBSettingSQL.getSessionSQL() != null) { - LOG.info("Append session SQL to connection init SQL"); // Not print the SQL to avoid leaking sensitive information - sql.add(duckDBSettingSQL.getSessionSQL()); - } - } - else { - sql.add("SET search_path = 'main'"); - sql.add(format("SET home_directory='%s'", duckDBConfig.getHomeDirectory())); - } - return String.join(";", sql); - } - - @Override - public AutoCloseableIterator query(String sql) - { - try { - return JdbcRecordIterator.of(this, sql); - } - catch (SQLException e) { - throw new RuntimeException(e); - } - } - - @Override - public AutoCloseableIterator query(String sql, List parameters) - { - try { - return JdbcRecordIterator.of(this, sql, parameters); - } - catch (Exception e) { - LOG.error(e, "Error executing DDL"); - throw new WrenException(StandardErrorCode.GENERIC_USER_ERROR, e); - } - } - - /** - * Describe the output of a query. DuckDB won't support to describe a sql with parameters in the select items. - * So we ignore the parameters here. - */ - @Override - public List describe(String sql, List ignored) - { - try (Connection connection = createConnection()) { - PreparedStatement preparedStatement = connection.prepareStatement(sql); - ResultSetMetaData metaData = preparedStatement.getMetaData(); - int columnCount = metaData.getColumnCount(); - - ImmutableList.Builder builder = ImmutableList.builder(); - for (int i = 1; i <= columnCount; i++) { - builder.add(new Column(metaData.getColumnName(i), metaData.getColumnTypeName(i))); - } - return builder.build(); - } - catch (Exception e) { - LOG.error(e, "Error executing DDL: %s", sql); - throw new WrenException(StandardErrorCode.GENERIC_USER_ERROR, e); - } - } - - @Override - public void executeDDL(String sql) - { - try (Connection connection = createConnection()) { - Statement statement = connection.createStatement(); - statement.execute(sql); - } - catch (SQLException se) { - LOG.error("Failed SQL: %s", sql); - throw new RuntimeException(se); - } - } - - // for canner use - public void executeDDL(String sql, List parameters) - { - try (Connection connection = createConnection(); - PreparedStatement statement = connection.prepareStatement(sql)) { - for (int i = 0; i < parameters.size(); i++) { - statement.setObject(i + 1, parameters.get(i)); - } - statement.execute(); - } - catch (SQLException se) { - throw new RuntimeException(se); - } - } - - @Override - public List listTables() - { - try (Connection connection = createConnection(); - ResultSet resultSet = connection.getMetaData().getTables(null, null, null, null)) { - List names = new ArrayList<>(); - while (resultSet.next()) { - String tableName = resultSet.getString(3); - names.add(tableName); - } - return names; - } - catch (SQLException se) { - throw new RuntimeException(se); - } - } - - @Override - public Connection createConnection() - throws SQLException - { - return connectionPool.getConnection(); - } - - @Override - public void close() - { - try { - connectionPool.close(); - duckDBConnection.close(); - } - catch (SQLException e) { - throw new RuntimeException(e); - } - } - - public synchronized void closeAndInitPool() - { - connectionPool.close(); - initPool(); - } - - public static class Builder - { - private DuckDBConfig duckDBConfig; - private DuckDBSettingSQL duckDBSettingSQL; - - public Builder setDuckDBConfig(DuckDBConfig duckDBConfig) - { - this.duckDBConfig = duckDBConfig; - return this; - } - - public Builder setDuckDBSettingSQL(DuckDBSettingSQL duckDBSettingSQL) - { - this.duckDBSettingSQL = duckDBSettingSQL; - return this; - } - - public DuckdbClient build() - { - return new DuckdbClient(duckDBConfig, duckDBSettingSQL); - } - - public Optional buildSafely() - { - try { - return Optional.of(build()); - } - catch (Exception e) { - LOG.error(e, "Failed to build DuckdbClient"); - return Optional.empty(); - } - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/client/duckdb/FileUtil.java b/wren-base/src/main/java/io/wren/base/client/duckdb/FileUtil.java deleted file mode 100644 index 704f1cf86..000000000 --- a/wren-base/src/main/java/io/wren/base/client/duckdb/FileUtil.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Licensed 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 io.wren.base.client.duckdb; - -import java.io.IOException; -import java.io.UncheckedIOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -import static java.nio.file.StandardOpenOption.APPEND; - -public class FileUtil -{ - public static final String ARCHIVED = "archived"; - - private FileUtil() {} - - public static void createDir(Path path) - { - try { - Files.createDirectories(path); - } - catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static void createFile(Path path, String content) - { - try { - Path dir = path.getParent(); - if (!Files.exists(dir)) { - createDir(dir); - } - Path actualPath = Files.createFile(path); - Files.writeString(actualPath, content); - } - catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static void appendToFile(Path path, String content) - { - try { - if (!Files.exists(path)) { - createFile(path, content); - } - else { - Files.writeString(path, System.lineSeparator() + content, APPEND); - } - } - catch (IOException e) { - throw new UncheckedIOException(e); - } - } - - public static void archiveFile(Path path) - { - try { - if (!Files.exists(path)) { - return; - } - Path archiveDir = path.getParent().resolve(ARCHIVED); - if (!Files.exists(archiveDir)) { - createDir(archiveDir); - } - String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmssnnnn")); - Files.move(path, archiveDir.resolve(path.getFileName() + "." + timestamp)); - } - catch (IOException e) { - throw new UncheckedIOException(e); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/client/jdbc/BaseJdbcRecordIterator.java b/wren-base/src/main/java/io/wren/base/client/jdbc/BaseJdbcRecordIterator.java deleted file mode 100644 index 1a13fd61e..000000000 --- a/wren-base/src/main/java/io/wren/base/client/jdbc/BaseJdbcRecordIterator.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Licensed 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 io.wren.base.client.jdbc; - -import io.wren.base.Parameter; -import io.wren.base.client.AutoCloseableIterator; -import io.wren.base.client.Client; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.List; -import java.util.NoSuchElementException; - -import static com.google.common.util.concurrent.MoreExecutors.directExecutor; -import static java.util.Objects.requireNonNull; - -public abstract class BaseJdbcRecordIterator - implements AutoCloseableIterator -{ - private final Connection connection; - protected final PreparedStatement statement; - protected final ResultSet resultSet; - private final ResultSetMetaData resultSetMetaData; - protected final int columnCount; - - private boolean hasNext; - - public BaseJdbcRecordIterator(Client client, String sql, List parameters) - throws SQLException - { - requireNonNull(client, "client is null"); - connection = client.createConnection(); - try { - statement = connection.prepareStatement(sql); - setParameter(parameters); - resultSet = statement.executeQuery(); - - this.resultSetMetaData = resultSet.getMetaData(); - this.columnCount = resultSetMetaData.getColumnCount(); - - hasNext = resultSet.next(); - } - catch (SQLException e) { - connection.close(); - throw e; - } - } - - protected void setParameter(List parameters) - throws SQLException - { - for (int i = 0; i < parameters.size(); i++) { - statement.setObject(i + 1, parameters.get(i).getValue()); - } - } - - @Override - public boolean hasNext() - { - return hasNext; - } - - @Override - public T next() - { - if (!hasNext) { - throw new NoSuchElementException(); - } - T currentResult; - try { - currentResult = getCurrentRecord(); - // move to next row - hasNext = resultSet.next(); - } - catch (SQLException e) { - throw new RuntimeException(e); - } - return currentResult; - } - - @Override - public void close() - throws Exception - { - // use try with resources to close everything properly - try (Connection connection = this.connection; - Statement statement = this.statement; - ResultSet resultSet = this.resultSet) { - if (statement != null) { - try { - // Trying to cancel running statement as close() may not do it - statement.cancel(); - } - catch (SQLException ignored) { - // statement already closed or cancel is not supported - } - } - if (connection != null && resultSet != null) { - if (!resultSet.isAfterLast()) { - connection.abort(directExecutor()); - } - } - } - catch (SQLException | RuntimeException e) { - // ignore exception from close - } - } - - public ResultSetMetaData getResultSetMetaData() - { - return resultSetMetaData; - } - - public abstract T getCurrentRecord() - throws SQLException; -} diff --git a/wren-base/src/main/java/io/wren/base/client/jdbc/JdbcRecordIterator.java b/wren-base/src/main/java/io/wren/base/client/jdbc/JdbcRecordIterator.java deleted file mode 100644 index 1d98ab785..000000000 --- a/wren-base/src/main/java/io/wren/base/client/jdbc/JdbcRecordIterator.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed 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 io.wren.base.client.jdbc; - -import io.wren.base.Parameter; -import io.wren.base.client.Client; - -import java.sql.Blob; -import java.sql.SQLException; -import java.sql.Types; -import java.util.ArrayList; -import java.util.List; - -import static java.util.Collections.emptyList; - -public class JdbcRecordIterator - extends BaseJdbcRecordIterator -{ - public static JdbcRecordIterator of(Client client, String sql) - - throws SQLException - { - return of(client, sql, emptyList()); - } - - public static JdbcRecordIterator of(Client client, String sql, List parameters) - throws SQLException - { - return new JdbcRecordIterator(client, sql, parameters); - } - - private JdbcRecordIterator(Client client, String sql, List parameters) - throws SQLException - { - super(client, sql, parameters); - } - - @Override - public Object[] getCurrentRecord() - throws SQLException - { - List builder = new ArrayList<>(columnCount); - for (int i = 1; i <= columnCount; i++) { - if (resultSet.getMetaData().getColumnType(i) == Types.BLOB) { - Blob blob = resultSet.getBlob(i); - builder.add(blob == null ? null : blob.getBytes(1, (int) blob.length())); - } - else if (resultSet.getMetaData().getColumnType(i) == Types.SMALLINT) { - short value = resultSet.getShort(i); - builder.add(resultSet.wasNull() ? null : value); - } - else { - builder.add(resultSet.getObject(i)); - } - } - return builder.toArray(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/config/BigQueryConfig.java b/wren-base/src/main/java/io/wren/base/config/BigQueryConfig.java deleted file mode 100644 index 0be3a5357..000000000 --- a/wren-base/src/main/java/io/wren/base/config/BigQueryConfig.java +++ /dev/null @@ -1,120 +0,0 @@ -/* - * Licensed 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 io.wren.base.config; - -import io.airlift.configuration.Config; -import io.airlift.configuration.ConfigDescription; -import io.airlift.configuration.ConfigSecuritySensitive; -import jakarta.validation.constraints.NotNull; - -import java.util.Optional; - -@Deprecated -public class BigQueryConfig -{ - public static final String BIGQUERY_CRENDITALS_KEY = "bigquery.credentials-key"; - public static final String BIGQUERY_CRENDITALS_FILE = "bigquery.credentials-file"; - public static final String BIGQUERY_PROJECT_ID = "bigquery.project-id"; - public static final String BIGQUERY_LOCATION = "bigquery.location"; - public static final String BIGQUERY_BUCKET_NAME = "bigquery.bucket-name"; - public static final String BIGQUERY_METADATA_SCHEMA_PREFIX = "bigquery.metadata.schema.prefix"; - private Optional credentialsKey = Optional.empty(); - private Optional credentialsFile = Optional.empty(); - private Optional projectId = Optional.empty(); - - private Optional location = Optional.empty(); - - private Optional bucketName = Optional.empty(); - private String metadataSchemaPrefix = ""; - - public Optional getCredentialsKey() - { - return credentialsKey; - } - - @Config(BIGQUERY_CRENDITALS_KEY) - @ConfigDescription("The base64 encoded credentials key") - @ConfigSecuritySensitive - public BigQueryConfig setCredentialsKey(String credentialsKey) - { - this.credentialsKey = Optional.ofNullable(credentialsKey); - return this; - } - - public Optional getCredentialsFile() - { - return credentialsFile; - } - - @Config(BIGQUERY_CRENDITALS_FILE) - @ConfigDescription("The path to the JSON credentials file") - public BigQueryConfig setCredentialsFile(String credentialsFile) - { - this.credentialsFile = Optional.ofNullable(credentialsFile); - return this; - } - - public Optional getProjectId() - { - return projectId; - } - - @Config(BIGQUERY_PROJECT_ID) - @ConfigDescription("The Google Cloud Project ID where the data reside") - public BigQueryConfig setProjectId(String projectId) - { - this.projectId = Optional.ofNullable(projectId); - return this; - } - - public Optional getLocation() - { - return location; - } - - @Config(BIGQUERY_LOCATION) - @ConfigDescription("The Google Cloud Project ID where the data reside") - public BigQueryConfig setLocation(String location) - { - this.location = Optional.ofNullable(location); - return this; - } - - public Optional getBucketName() - { - return bucketName; - } - - @Config(BIGQUERY_BUCKET_NAME) - @ConfigDescription("The Google Cloud bucket name used to temporarily store the metric cached results") - public BigQueryConfig setBucketName(String bucketName) - { - this.bucketName = Optional.ofNullable(bucketName); - return this; - } - - @NotNull - public String getMetadataSchemaPrefix() - { - return metadataSchemaPrefix; - } - - @Config(BIGQUERY_METADATA_SCHEMA_PREFIX) - @ConfigDescription("Wren needs to create two schemas in BigQuery: wren_temp, pg_catalog. This is a config to add a prefix to the names of these two schemas if it's set.") - public BigQueryConfig setMetadataSchemaPrefix(String metadataSchemaPrefix) - { - this.metadataSchemaPrefix = metadataSchemaPrefix; - return this; - } -} diff --git a/wren-base/src/main/java/io/wren/base/config/ConfigManager.java b/wren-base/src/main/java/io/wren/base/config/ConfigManager.java deleted file mode 100644 index 9376ff8da..000000000 --- a/wren-base/src/main/java/io/wren/base/config/ConfigManager.java +++ /dev/null @@ -1,338 +0,0 @@ -/* - * Licensed 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 io.wren.base.config; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.inject.Inject; -import io.airlift.log.Logger; -import io.airlift.units.DataSize; -import io.wren.base.WrenException; -import io.wren.base.client.duckdb.DuckDBConfig; -import io.wren.base.client.duckdb.DuckDBConnectorConfig; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; -import java.util.Properties; -import java.util.Set; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.airlift.configuration.ConfigurationLoader.loadPropertiesFrom; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_CACHE_TASK_RETRY_DELAY; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_HOME_DIRECTORY; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_MAX_CACHE_QUERY_TIMEOUT; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_MAX_CONCURRENT_TASKS; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_MEMORY_LIMIT; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_TEMP_DIRECTORY; -import static io.wren.base.client.duckdb.DuckDBConnectorConfig.DUCKDB_CONNECTOR_INIT_SQL_PATH; -import static io.wren.base.client.duckdb.DuckDBConnectorConfig.DUCKDB_CONNECTOR_SESSION_SQL_PATH; -import static io.wren.base.client.duckdb.FileUtil.ARCHIVED; -import static io.wren.base.metadata.StandardErrorCode.NOT_FOUND; -import static java.lang.String.format; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toMap; - -public class ConfigManager -{ - private static final Logger LOG = Logger.get(ConfigManager.class); - private Optional wrenConfig; - private Optional duckDBConfig; - private Optional duckDBConnectorConfig; - - private final Map configs = new HashMap<>(); - // All configs set by user and config files. It's used to sync with config file. - private Properties setConfigs = new Properties(); - private final String configFile = System.getProperty("config"); - private final Set requiredReload = new HashSet<>(); - private final Set staticConfigs = new HashSet<>(); - - @Inject - public ConfigManager( - WrenConfig wrenConfig, - DuckDBConfig duckDBConfig, - DuckDBConnectorConfig duckDBConnectorConfig) - { - this.wrenConfig = Optional.of(wrenConfig); - this.duckDBConfig = Optional.of(duckDBConfig); - this.duckDBConnectorConfig = Optional.of(duckDBConnectorConfig); - - initConfig( - wrenConfig, - duckDBConfig, - duckDBConnectorConfig); - - try { - setConfigs.putAll(loadPropertiesFrom(configFile)); - } - catch (IOException e) { - throw new WrenException(NOT_FOUND, "Config file not found"); - } - } - - private void initConfig( - WrenConfig wrenConfig, - DuckDBConfig duckDBConfig, - DuckDBConnectorConfig duckDBConnectorConfig) - { - initConfig(WrenConfig.WREN_DIRECTORY, wrenConfig.getWrenMDLDirectory().getPath(), false, true); - initConfig(WrenConfig.WREN_DATASOURCE_TYPE, Optional.ofNullable(wrenConfig.getDataSourceType()).map(Enum::name).orElse(null), true, false); - initConfig(WrenConfig.WREN_ENABLE_DYNAMIC_FIELDS, Boolean.toString(wrenConfig.getEnableDynamicFields()), false, false); - initConfig(DUCKDB_MEMORY_LIMIT, duckDBConfig.getMemoryLimit().toString(), true, false); - initConfig(DUCKDB_HOME_DIRECTORY, duckDBConfig.getHomeDirectory(), true, false); - initConfig(DUCKDB_TEMP_DIRECTORY, duckDBConfig.getTempDirectory(), true, false); - initConfig(DUCKDB_MAX_CONCURRENT_TASKS, Integer.toString(duckDBConfig.getMaxConcurrentTasks()), false, true); - initConfig(DUCKDB_MAX_CACHE_QUERY_TIMEOUT, Long.toString(duckDBConfig.getMaxCacheQueryTimeout()), false, true); - initConfig(DUCKDB_CACHE_TASK_RETRY_DELAY, Long.toString(duckDBConfig.getCacheTaskRetryDelay()), false, true); - initConfig(DUCKDB_CONNECTOR_INIT_SQL_PATH, duckDBConnectorConfig.getInitSQLPath(), false, false); - initConfig(DUCKDB_CONNECTOR_SESSION_SQL_PATH, duckDBConnectorConfig.getSessionSQLPath(), false, false); - } - - private void initConfig(String key, String value, boolean requiredReload, boolean isStatic) - { - configs.put(key, value); - - if (requiredReload) { - this.requiredReload.add(key); - } - - if (isStatic) { - staticConfigs.add(key); - } - } - - public T getConfig(Class config) - { - if (config == WrenConfig.class) { - return (T) wrenConfig.orElseGet(() -> { - WrenConfig result = getWrenConfig(); - wrenConfig = Optional.of(result); - return result; - }); - } - if (config == DuckDBConfig.class) { - return (T) duckDBConfig.orElseGet(() -> { - DuckDBConfig result = getDuckDBConfig(); - duckDBConfig = Optional.of(result); - return result; - }); - } - if (config == DuckDBConnectorConfig.class) { - return (T) duckDBConnectorConfig.orElseGet(() -> { - DuckDBConnectorConfig result = getDuckDBConnectorConfig(); - duckDBConnectorConfig = Optional.of(result); - return result; - }); - } - throw new RuntimeException("Unknown config class: " + config.getName()); - } - - private WrenConfig getWrenConfig() - { - WrenConfig result = new WrenConfig(); - Optional.ofNullable(configs.get(WrenConfig.WREN_DIRECTORY)) - .ifPresent(directory -> result.setWrenMDLDirectory(Paths.get(directory).toFile())); - result.setDataSourceType(WrenConfig.DataSourceType.valueOf(configs.get(WrenConfig.WREN_DATASOURCE_TYPE).toUpperCase(Locale.ROOT))); - result.setEnableDynamicFields(Boolean.parseBoolean(configs.get(WrenConfig.WREN_ENABLE_DYNAMIC_FIELDS))); - return result; - } - - private DuckDBConfig getDuckDBConfig() - { - DuckDBConfig result = new DuckDBConfig(); - result.setMemoryLimit(DataSize.valueOf(configs.get(DUCKDB_MEMORY_LIMIT))); - result.setHomeDirectory(configs.get(DUCKDB_HOME_DIRECTORY)); - result.setTempDirectory(configs.get(DUCKDB_TEMP_DIRECTORY)); - result.setMaxConcurrentTasks(Integer.parseInt(configs.get(DUCKDB_MAX_CONCURRENT_TASKS))); - result.setMaxCacheQueryTimeout(Integer.parseInt(configs.get(DUCKDB_MAX_CACHE_QUERY_TIMEOUT))); - result.setCacheTaskRetryDelay(Integer.parseInt(configs.get(DUCKDB_CACHE_TASK_RETRY_DELAY))); - return result; - } - - private DuckDBConnectorConfig getDuckDBConnectorConfig() - { - DuckDBConnectorConfig result = new DuckDBConnectorConfig(); - result.setInitSQLPath(configs.get(DUCKDB_CONNECTOR_INIT_SQL_PATH)); - result.setSessionSQLPath(configs.get(DUCKDB_CONNECTOR_SESSION_SQL_PATH)); - return result; - } - - public synchronized boolean setConfigs(List configEntries, boolean reset) - { - if (reset) { - reset(); - } - - Map update = configEntries.stream() - .map(entry -> Map.entry(entry.getName(), entry.getValue())) - .collect(toMap(Map.Entry::getKey, entry -> entry.getValue().trim())); - update.forEach(this::setConfigInternal); - boolean needReload = false; - for (ConfigEntry configEntry : configEntries) { - needReload |= setConfigInternal(configEntry.getName(), configEntry.getValue()); - } - resetCache(); - syncFile(update); - return needReload; - } - - private boolean setConfigInternal(String key, String value) - { - // ignore all static config changes - if (staticConfigs.contains(key)) { - return false; - } - - // Only allow set the config that already exists. - if (configs.containsKey(key)) { - configs.put(key, value); - } - else { - throw new WrenException(NOT_FOUND, "Config not found: " + key); - } - - return requiredReload.contains(key); - } - - private void resetCache() - { - wrenConfig = Optional.empty(); - duckDBConfig = Optional.empty(); - duckDBConnectorConfig = Optional.empty(); - } - - private void reset() - { - configs.clear(); - setConfigs.clear(); - initConfig( - new WrenConfig(), - new DuckDBConfig(), - new DuckDBConnectorConfig()); - } - - private void syncFile(Map updated) - { - try { - archiveConfigs(); - setConfigs.putAll(updated); - setConfigs.store(Files.newBufferedWriter(Paths.get(configFile)), "sync with file"); - LOG.info("Syncing config file: " + configFile); - } - catch (IOException e) { - throw new WrenException(NOT_FOUND, format("Config file %s not found", configFile), e); - } - } - - private void archiveConfigs() - throws IOException - { - Path home = Paths.get(configFile).toFile().getParentFile().toPath(); - File archived = home.resolve(ARCHIVED).toFile(); - if (!archived.exists()) { - if (!archived.mkdir()) { - throw new IOException("Cannot create archive folder"); - } - } - File archivedFile = Paths.get(configFile).toFile(); - Files.copy(archivedFile.toPath(), - archived.toPath().resolve(archivedFile.getName() + "." + LocalDateTime.now().format(DateTimeFormatter.ofPattern("uuuuMMddHHmmssnnnn")))); - LOG.info("Archiving config file: " + archived); - } - - public List getConfigs() - { - return configs.entrySet().stream().map(entry -> new ConfigEntry(entry.getKey(), entry.getValue())).collect(toList()); - } - - public ConfigEntry getConfig(String key) - { - if (configs.containsKey(key)) { - return new ConfigEntry(key, configs.get(key)); - } - throw new WrenException(NOT_FOUND, "Config not found: " + key); - } - - public static class ConfigEntry - { - public static ConfigEntry configEntry(String name, String value) - { - return new ConfigEntry(name, value); - } - - private final String name; - private final String value; - - @JsonCreator - public ConfigEntry( - @JsonProperty("name") String name, - @JsonProperty("value") String value) - { - this.name = name; - this.value = value == null || value.isEmpty() ? null : value; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getValue() - { - return value; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ConfigEntry that = (ConfigEntry) o; - return Objects.equals(name, that.name) && Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return Objects.hash(name, value); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("value", value) - .toString(); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/config/DuckdbS3StyleStorageConfig.java b/wren-base/src/main/java/io/wren/base/config/DuckdbS3StyleStorageConfig.java deleted file mode 100644 index e4b2bb2d2..000000000 --- a/wren-base/src/main/java/io/wren/base/config/DuckdbS3StyleStorageConfig.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Licensed 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 io.wren.base.config; - -import io.airlift.configuration.Config; -import io.airlift.configuration.ConfigDescription; -import io.airlift.configuration.ConfigSecuritySensitive; - -import java.util.Optional; - -@Deprecated -public class DuckdbS3StyleStorageConfig -{ - public static final String DUCKDB_STORAGE_ENDPOINT = "duckdb.storage.endpoint"; - public static final String DUCKDB_STORAGE_ACCESS_KEY = "duckdb.storage.access-key"; - public static final String DUCKDB_STORAGE_SECRET_KEY = "duckdb.storage.secret-key"; - public static final String DUCKDB_STORAGE_REGION = "duckdb.storage.region"; - public static final String DUCKDB_STORAGE_URL_STYLE = "duckdb.storage.url-style"; - - // https://duckdb.org/docs/guides/import/s3_import.html - private String endpoint = "storage.googleapis.com"; - private Optional accessKey = Optional.empty(); - private Optional secretKey = Optional.empty(); - private Optional region = Optional.empty(); - private String urlStyle = "path"; - - @Config(DUCKDB_STORAGE_ENDPOINT) - @ConfigDescription("The storage endpoint; default is storage.googleapis.com") - public DuckdbS3StyleStorageConfig setEndpoint(String endpoint) - { - this.endpoint = endpoint; - return this; - } - - public String getEndpoint() - { - return endpoint; - } - - @Config(DUCKDB_STORAGE_ACCESS_KEY) - @ConfigDescription("The storage access key") - @ConfigSecuritySensitive - public DuckdbS3StyleStorageConfig setAccessKey(String accessKey) - { - this.accessKey = Optional.of(accessKey); - return this; - } - - public Optional getAccessKey() - { - return accessKey; - } - - @Config(DUCKDB_STORAGE_SECRET_KEY) - @ConfigDescription("The storage secret key") - @ConfigSecuritySensitive - public DuckdbS3StyleStorageConfig setSecretKey(String secretKey) - { - this.secretKey = Optional.of(secretKey); - return this; - } - - public Optional getSecretKey() - { - return secretKey; - } - - @Config(DUCKDB_STORAGE_REGION) - @ConfigDescription("The storage region") - public DuckdbS3StyleStorageConfig setRegion(String region) - { - this.region = Optional.of(region); - return this; - } - - public Optional getRegion() - { - return region; - } - - @Config(DUCKDB_STORAGE_URL_STYLE) - @ConfigDescription("The storage url style; default is path") - public DuckdbS3StyleStorageConfig setUrlStyle(String urlStyle) - { - this.urlStyle = urlStyle; - return this; - } - - public String getUrlStyle() - { - return urlStyle; - } -} diff --git a/wren-base/src/main/java/io/wren/base/config/PostgresConfig.java b/wren-base/src/main/java/io/wren/base/config/PostgresConfig.java deleted file mode 100644 index 43f2a3197..000000000 --- a/wren-base/src/main/java/io/wren/base/config/PostgresConfig.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed 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 io.wren.base.config; - -import io.airlift.configuration.Config; - -@Deprecated -public class PostgresConfig -{ - public static final String POSTGRES_JDBC_URL = "postgres.jdbc.url"; - public static final String POSTGRES_USER = "postgres.user"; - public static final String POSTGRES_PASSWORD = "postgres.password"; - private String jdbcUrl; - private String user; - private String password; - - public String getJdbcUrl() - { - return jdbcUrl; - } - - @Config(POSTGRES_JDBC_URL) - public PostgresConfig setJdbcUrl(String jdbcUrl) - { - this.jdbcUrl = jdbcUrl; - return this; - } - - public String getUser() - { - return user; - } - - @Config(POSTGRES_USER) - public PostgresConfig setUser(String user) - { - this.user = user; - return this; - } - - public String getPassword() - { - return password; - } - - @Config(POSTGRES_PASSWORD) - public PostgresConfig setPassword(String password) - { - this.password = password; - return this; - } -} diff --git a/wren-base/src/main/java/io/wren/base/config/PostgresWireProtocolConfig.java b/wren-base/src/main/java/io/wren/base/config/PostgresWireProtocolConfig.java deleted file mode 100644 index e18a8ec79..000000000 --- a/wren-base/src/main/java/io/wren/base/config/PostgresWireProtocolConfig.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Licensed 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 io.wren.base.config; - -import io.airlift.configuration.Config; -import jakarta.validation.constraints.NotNull; - -import java.io.File; -import java.nio.file.Paths; - -@Deprecated -public class PostgresWireProtocolConfig -{ - public static final String PG_WIRE_PROTOCOL_ENABLED = "pg-wire-protocol.enabled"; - public static final String PG_WIRE_PROTOCOL_SSL_ENABLED = "pg-wire-protocol.ssl.enabled"; - public static final String PG_WIRE_PROTOCOL_NETTY_THREAD_COUNT = "pg-wire-protocol.netty.thread.count"; - public static final String PG_WIRE_PROTOCOL_AUTH_FILE = "pg-wire-protocol.auth.file"; - public static final String PG_WIRE_PROTOCOL_PORT = "pg-wire-protocol.port"; - - private String port = "7432"; - private boolean sslEnable; - private int nettyThreadCount; - private File authFile = Paths.get("etc/accounts").toFile(); - private boolean pgWireProtocolEnabled; - - @NotNull - public String getPort() - { - return port; - } - - @Config(PG_WIRE_PROTOCOL_PORT) - public PostgresWireProtocolConfig setPort(String port) - { - this.port = port; - return this; - } - - @NotNull - public boolean isSslEnable() - { - return sslEnable; - } - - @Config(PG_WIRE_PROTOCOL_SSL_ENABLED) - public PostgresWireProtocolConfig setSslEnable(boolean sslEnable) - { - this.sslEnable = sslEnable; - return this; - } - - @NotNull - public int getNettyThreadCount() - { - return nettyThreadCount; - } - - @Config(PG_WIRE_PROTOCOL_NETTY_THREAD_COUNT) - public PostgresWireProtocolConfig setNettyThreadCount(int nettyThreadCount) - { - this.nettyThreadCount = nettyThreadCount; - return this; - } - - public File getAuthFile() - { - return authFile; - } - - @Config(PG_WIRE_PROTOCOL_AUTH_FILE) - public PostgresWireProtocolConfig setAuthFile(File authFile) - { - this.authFile = authFile; - return this; - } - - @Config(PG_WIRE_PROTOCOL_ENABLED) - public void setPgWireProtocolEnabled(boolean pgWireProtocolEnabled) - { - this.pgWireProtocolEnabled = pgWireProtocolEnabled; - } - - public boolean isPgWireProtocolEnabled() - { - return pgWireProtocolEnabled; - } -} diff --git a/wren-base/src/main/java/io/wren/base/config/SQLGlotConfig.java b/wren-base/src/main/java/io/wren/base/config/SQLGlotConfig.java deleted file mode 100644 index c603b89ae..000000000 --- a/wren-base/src/main/java/io/wren/base/config/SQLGlotConfig.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed 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. - */ - -/* - * Licensed 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 io.wren.base.config; - -import io.airlift.configuration.Config; - -import java.io.IOException; -import java.net.ServerSocket; -import java.util.Optional; - -import static java.lang.System.getenv; - -@Deprecated -public class SQLGlotConfig -{ - public static final String SQLGLOT_PORT = "sqlglot.port"; - - private int port = Optional.ofNullable(getenv("SQLGLOT_PORT")) - .map(Integer::parseInt) - .orElse(8000); - - public int getPort() - { - return port; - } - - @Config(SQLGLOT_PORT) - public void setPort(int port) - { - this.port = port; - } - - public static SQLGlotConfig createConfigWithFreePort() - { - SQLGlotConfig config = new SQLGlotConfig(); - config.setPort(findFreePort()); - return config; - } - - private static int findFreePort() - { - try (ServerSocket serverSocket = new ServerSocket(0)) { - return serverSocket.getLocalPort(); - } - catch (IOException e) { - throw new AssertionError(e); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/config/SnowflakeConfig.java b/wren-base/src/main/java/io/wren/base/config/SnowflakeConfig.java deleted file mode 100644 index 8f0c280fd..000000000 --- a/wren-base/src/main/java/io/wren/base/config/SnowflakeConfig.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Licensed 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 io.wren.base.config; - -import io.airlift.configuration.Config; - -import java.util.Optional; - -@Deprecated -public class SnowflakeConfig -{ - public static final String SNOWFLAKE_JDBC_URL = "snowflake.jdbc.url"; - public static final String SNOWFLAKE_USER = "snowflake.user"; - public static final String SNOWFLAKE_PASSWORD = "snowflake.password"; - public static final String SNOWFLAKE_ROLE = "snowflake.role"; - public static final String SNOWFLAKE_WAREHOUSE = "snowflake.warehouse"; - public static final String SNOWFLAKE_DATABASE = "snowflake.database"; - public static final String SNOWFLAKE_SCHEMA = "snowflake.schema"; - - private String jdbcUrl; - private String user; - private String password; - private String role; - private String warehouse; - private String database; - private String schema; - - public String getJdbcUrl() - { - return jdbcUrl; - } - - @Config(SNOWFLAKE_JDBC_URL) - public SnowflakeConfig setJdbcUrl(String jdbcUrl) - { - this.jdbcUrl = jdbcUrl; - return this; - } - - public String getUser() - { - return user; - } - - @Config(SNOWFLAKE_USER) - public SnowflakeConfig setUser(String user) - { - this.user = user; - return this; - } - - public String getPassword() - { - return password; - } - - @Config(SNOWFLAKE_PASSWORD) - public SnowflakeConfig setPassword(String password) - { - this.password = password; - return this; - } - - public Optional getRole() - { - return Optional.ofNullable(role); - } - - @Config(SNOWFLAKE_ROLE) - public SnowflakeConfig setRole(String role) - { - this.role = role; - return this; - } - - public Optional getWarehouse() - { - return Optional.ofNullable(warehouse); - } - - @Config(SNOWFLAKE_WAREHOUSE) - public SnowflakeConfig setWarehouse(String warehouse) - { - this.warehouse = warehouse; - return this; - } - - public Optional getDatabase() - { - return Optional.ofNullable(database); - } - - @Config(SNOWFLAKE_DATABASE) - public SnowflakeConfig setDatabase(String database) - { - this.database = database; - return this; - } - - public Optional getSchema() - { - return Optional.ofNullable(schema); - } - - @Config(SNOWFLAKE_SCHEMA) - public SnowflakeConfig setSchema(String schema) - { - this.schema = schema; - return this; - } -} diff --git a/wren-base/src/main/java/io/wren/base/config/WrenConfig.java b/wren-base/src/main/java/io/wren/base/config/WrenConfig.java deleted file mode 100644 index 14e66079a..000000000 --- a/wren-base/src/main/java/io/wren/base/config/WrenConfig.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed 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 io.wren.base.config; - -import io.airlift.configuration.Config; -import jakarta.validation.constraints.NotNull; - -import java.io.File; -import java.nio.file.Paths; - -public class WrenConfig -{ - public static final String WREN_DIRECTORY = "wren.directory"; - public static final String WREN_DATASOURCE_TYPE = "wren.datasource.type"; - public static final String WREN_ENABLE_DYNAMIC_FIELDS = "wren.experimental-enable-dynamic-fields"; - - public enum DataSourceType - { - @Deprecated - BIGQUERY, - @Deprecated - POSTGRES, - DUCKDB, - @Deprecated - SNOWFLAKE - } - - private File wrenMDLDirectory = Paths.get("etc/mdl").toFile(); - private DataSourceType dataSourceType = DataSourceType.DUCKDB; - private boolean enableDynamicFields = true; - - @NotNull - public File getWrenMDLDirectory() - { - return wrenMDLDirectory; - } - - @Config(WREN_DIRECTORY) - public WrenConfig setWrenMDLDirectory(File wrenMDLDirectory) - { - this.wrenMDLDirectory = wrenMDLDirectory; - return this; - } - - public DataSourceType getDataSourceType() - { - return dataSourceType; - } - - @Config(WREN_DATASOURCE_TYPE) - public WrenConfig setDataSourceType(DataSourceType dataSourceType) - { - this.dataSourceType = dataSourceType; - return this; - } - - public boolean getEnableDynamicFields() - { - return enableDynamicFields; - } - - @Config(WREN_ENABLE_DYNAMIC_FIELDS) - public WrenConfig setEnableDynamicFields(boolean enableDynamicFields) - { - this.enableDynamicFields = enableDynamicFields; - return this; - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/CacheInfo.java b/wren-base/src/main/java/io/wren/base/dto/CacheInfo.java deleted file mode 100644 index eb967076c..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/CacheInfo.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import io.airlift.units.Duration; - -import static java.util.concurrent.TimeUnit.MINUTES; - -public interface CacheInfo -{ - Duration defaultRefreshTime = new Duration(30, MINUTES); - - String getName(); - - boolean isCached(); - - Duration getRefreshTime(); -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Column.java b/wren-base/src/main/java/io/wren/base/dto/Column.java deleted file mode 100644 index 7b8fb2e5d..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Column.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; - -public class Column -{ - private final String name; - private final String type; - - private final boolean notNull; - private final String relationship; - private final String expression; - private final boolean isCalculated; - - public static Column column(String name, String type, String relationship, boolean notNull) - { - return new Column(name, type, relationship, false, notNull, null); - } - - public static Column column(String name, String type, String relationship, boolean notNull, String expression) - { - return new Column(name, type, relationship, false, notNull, expression); - } - - public static Column relationshipColumn(String name, String type, String relationship) - { - return new Column(name, type, relationship, false, false, null); - } - - public static Column calculatedColumn(String name, String type, String expression) - { - return new Column(name, type, null, true, false, expression); - } - - @JsonCreator - public Column( - @JsonProperty("name") String name, - @JsonProperty("type") String type, - @JsonProperty("relationship") String relationship, - @JsonProperty("isCalculated") boolean isCalculated, - @JsonProperty("notNull") boolean notNull, - @JsonProperty("expression") String expression) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.type = requireNonNullEmpty(type, "type is null or empty"); - this.relationship = relationship; - this.isCalculated = isCalculated; - this.notNull = notNull; - this.expression = expression == null || expression.isEmpty() ? null : expression; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getType() - { - return type; - } - - @JsonProperty - public Optional getRelationship() - { - return Optional.ofNullable(relationship); - } - - @JsonProperty - public boolean isNotNull() - { - return notNull; - } - - @JsonProperty - public Optional getExpression() - { - return Optional.ofNullable(expression); - } - - @JsonProperty("isCalculated") - public boolean isCalculated() - { - return isCalculated; - } - - public String getSqlExpression() - { - return getExpression().orElse(quote(name)); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Column that = (Column) obj; - return notNull == that.notNull && - isCalculated == that.isCalculated && - Objects.equals(name, that.name) && - Objects.equals(type, that.type) && - Objects.equals(relationship, that.relationship) && - Objects.equals(expression, that.expression); - } - - @Override - public int hashCode() - { - return Objects.hash(name, type, isCalculated, notNull, relationship, expression); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("type", type) - .add("notNull", notNull) - .add("isCalculated", isCalculated) - .add("relationship", relationship) - .add("expression", expression) - .toString(); - } - - private static String quote(String name) - { - return String.format("\"%s\"", name); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/CumulativeMetric.java b/wren-base/src/main/java/io/wren/base/dto/CumulativeMetric.java deleted file mode 100644 index df82707f0..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/CumulativeMetric.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.airlift.units.Duration; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; -import static java.util.Objects.requireNonNull; - -public class CumulativeMetric - implements CacheInfo -{ - public static CumulativeMetric cumulativeMetric( - String name, - String baseObject, - Measure measure, - Window window) - { - return new CumulativeMetric(name, baseObject, measure, window, false, null); - } - - private final String name; - private final String baseObject; - private final Measure measure; - private final Window window; - private final boolean cached; - private final Duration refreshTime; - - @JsonCreator - public CumulativeMetric( - @JsonProperty("name") String name, - @JsonProperty("baseObject") String baseObject, - @JsonProperty("measure") Measure measure, - @JsonProperty("window") Window window, - @JsonProperty("cached") boolean cached, - @JsonProperty("refreshTime") Duration refreshTime) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.baseObject = requireNonNullEmpty(baseObject, "baseObject is null or empty"); - this.measure = requireNonNull(measure, "measure is null"); - this.window = requireNonNull(window, "window is null"); - this.cached = cached; - this.refreshTime = refreshTime; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getBaseObject() - { - return baseObject; - } - - @JsonProperty - public Measure getMeasure() - { - return measure; - } - - @JsonProperty - public Window getWindow() - { - return window; - } - - @JsonProperty - public boolean isCached() - { - return cached; - } - - @JsonProperty - public Duration getRefreshTime() - { - return refreshTime; - } - - @Override - public int hashCode() - { - return Objects.hash(name, baseObject, measure, window, cached, refreshTime); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - CumulativeMetric that = (CumulativeMetric) o; - return cached == that.cached && - Objects.equals(name, that.name) && - Objects.equals(baseObject, that.baseObject) && - Objects.equals(measure, that.measure) && - Objects.equals(window, that.window) && - Objects.equals(refreshTime, that.refreshTime); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("baseObject", baseObject) - .add("measure", measure) - .add("window", window) - .add("cached", cached) - .add("refreshTime", refreshTime) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/DateSpine.java b/wren-base/src/main/java/io/wren/base/dto/DateSpine.java deleted file mode 100644 index 256d17fb0..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/DateSpine.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; -import static java.util.Objects.requireNonNull; - -public class DateSpine -{ - public static final DateSpine DEFAULT = new DateSpine(TimeUnit.DAY, "1970-01-01", "2077-12-31"); - - private final TimeUnit unit; - private final String start; - private final String end; - - @JsonCreator - public DateSpine( - @JsonProperty("unit") TimeUnit unit, - @JsonProperty("start") String start, - @JsonProperty("end") String end) - { - this.unit = requireNonNull(unit, "unit is null"); - this.start = requireNonNullEmpty(start, "start is null or empty"); - this.end = requireNonNullEmpty(end, "end is null or empty"); - } - - @JsonProperty - public TimeUnit getUnit() - { - return unit; - } - - @JsonProperty - public String getStart() - { - return start; - } - - @JsonProperty - public String getEnd() - { - return end; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("unit", unit) - .add("start", start) - .add("end", end) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - DateSpine dateSpine = (DateSpine) o; - return unit == dateSpine.unit && - Objects.equals(start, dateSpine.start) && - Objects.equals(end, dateSpine.end); - } - - @Override - public int hashCode() - { - return Objects.hash(unit, start, end); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/EnumDefinition.java b/wren-base/src/main/java/io/wren/base/dto/EnumDefinition.java deleted file mode 100644 index 507ee5e81..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/EnumDefinition.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; -import static java.util.Objects.requireNonNull; - -public class EnumDefinition -{ - public static EnumDefinition enumDefinition(String name, List values) - { - return new EnumDefinition(name, values); - } - - private final String name; - private final List values; - - @JsonCreator - public EnumDefinition( - @JsonProperty("name") String name, - @JsonProperty("values") List values) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.values = requireNonNull(values); - } - - @JsonProperty - public List getValues() - { - return values; - } - - @JsonProperty - public String getName() - { - return name; - } - - public Optional valueOf(String enumValueName) - { - return values.stream() - .filter(candidate -> candidate.getName().equals(enumValueName)) - .findAny(); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - EnumDefinition that = (EnumDefinition) obj; - return Objects.equals(name, that.name) && - Objects.equals(values, that.values); - } - - @Override - public int hashCode() - { - return Objects.hash( - name, - values); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("values", values) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/EnumValue.java b/wren-base/src/main/java/io/wren/base/dto/EnumValue.java deleted file mode 100644 index cb79a0f69..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/EnumValue.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; - -public class EnumValue -{ - public static EnumValue enumValue(String name) - { - return enumValue(name, null); - } - - public static EnumValue enumValue(String name, String value) - { - return new EnumValue(name, value); - } - - private final String name; - private final String value; - - @JsonCreator - public EnumValue( - @JsonProperty("name") String name, - @JsonProperty("value") String value) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.value = value; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getValue() - { - return Optional.ofNullable(value).orElse(name); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - EnumValue enumValue = (EnumValue) o; - return Objects.equals(name, enumValue.name) && - Objects.equals(value, enumValue.value); - } - - @Override - public int hashCode() - { - return Objects.hash(name, value); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("value", value) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/JoinType.java b/wren-base/src/main/java/io/wren/base/dto/JoinType.java deleted file mode 100644 index 0a2b813dd..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/JoinType.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import static io.wren.base.dto.JoinType.GenericJoinType.TO_MANY; -import static io.wren.base.dto.JoinType.GenericJoinType.TO_ONE; -import static java.util.Objects.requireNonNull; - -public enum JoinType -{ - MANY_TO_MANY(TO_MANY), - ONE_TO_ONE(TO_ONE), - MANY_TO_ONE(TO_ONE), - ONE_TO_MANY(TO_MANY); - - public enum GenericJoinType - { - TO_ONE, - TO_MANY, - } - - private final GenericJoinType type; - - JoinType(GenericJoinType type) - { - this.type = requireNonNull(type); - } - - public static JoinType reverse(JoinType joinType) - { - return switch (joinType) { - case ONE_TO_ONE -> ONE_TO_ONE; - case ONE_TO_MANY -> MANY_TO_ONE; - case MANY_TO_ONE -> ONE_TO_MANY; - case MANY_TO_MANY -> MANY_TO_MANY; - }; - } - - public GenericJoinType getType() - { - return type; - } - - public boolean isToOne() - { - return type == TO_ONE; - } - - public boolean isToMany() - { - return type == TO_MANY; - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Macro.java b/wren-base/src/main/java/io/wren/base/dto/Macro.java deleted file mode 100644 index 884eadacc..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Macro.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.macro.Parameter; -import io.wren.base.macro.ParameterListParser; - -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.checkArgument; -import static io.wren.base.Utils.requireNonNullEmpty; -import static java.lang.String.format; - -public class Macro -{ - public static Macro macro(String name, String definition) - { - return new Macro(name, definition); - } - - private final String name; - private final String definition; - private final List parameters; - private final String body; - - @JsonCreator - public Macro( - @JsonProperty("name") String name, - @JsonProperty("definition") String definition) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.definition = requireNonNullEmpty(definition, "definition is null or empty"); - String[] split = definition.split("=>", 2); - checkArgument(split.length == 2, format("definition is invalid: %s", definition)); - String paramString = split[0].trim(); - String body = split[1].trim(); - this.parameters = new ParameterListParser().parse(paramString); - this.body = body; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getDefinition() - { - return definition; - } - - public List getParameters() - { - return parameters; - } - - public String getBody() - { - return body; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Macro macro = (Macro) o; - return Objects.equals(name, macro.name) && - Objects.equals(parameters, macro.parameters) && - Objects.equals(body, macro.body); - } - - @Override - public int hashCode() - { - return Objects.hash(name, parameters, body); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("parameters", parameters) - .add("body", body) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Manifest.java b/wren-base/src/main/java/io/wren/base/dto/Manifest.java deleted file mode 100644 index aeedc5e6a..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Manifest.java +++ /dev/null @@ -1,300 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.airlift.json.JsonCodec; - -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; -import static io.wren.base.dto.DateSpine.DEFAULT; - -public class Manifest -{ - public static final JsonCodec MANIFEST_JSON_CODEC = JsonCodec.jsonCodec(Manifest.class); - private final String catalog; - private final String schema; - private final DateSpine dateSpine; - private final List models; - private final List relationships; - private final List enumDefinitions; - private final List metrics; - private final List cumulativeMetrics; - - private final List views; - private final List macros; - - public static Builder builder() - { - return new Builder(); - } - - public static Builder builder(Manifest manifest) - { - return new Builder(manifest); - } - - @JsonCreator - public Manifest( - @JsonProperty("catalog") String catalog, - @JsonProperty("schema") String schema, - @JsonProperty("models") List models, - @JsonProperty("relationships") List relationships, - @JsonProperty("enumDefinitions") List enumDefinitions, - @JsonProperty("metrics") List metrics, - @JsonProperty("cumulativeMetrics") List cumulativeMetrics, - @JsonProperty("views") List views, - @JsonProperty("macros") List macros, - @JsonProperty("dateSpine") DateSpine dateSpine) - { - this.catalog = requireNonNullEmpty(catalog, "catalog is null or empty"); - this.schema = requireNonNullEmpty(schema, "schema is null or empty"); - this.models = models == null ? List.of() : models; - this.relationships = relationships == null ? List.of() : relationships; - this.enumDefinitions = enumDefinitions == null ? List.of() : enumDefinitions; - this.metrics = metrics == null ? List.of() : metrics; - this.cumulativeMetrics = cumulativeMetrics == null ? List.of() : cumulativeMetrics; - this.views = views == null ? List.of() : views; - this.macros = macros == null ? List.of() : macros; - this.dateSpine = dateSpine == null ? DEFAULT : dateSpine; - } - - @JsonProperty - public String getCatalog() - { - return catalog; - } - - @JsonProperty - public String getSchema() - { - return schema; - } - - @JsonProperty - public DateSpine getDateSpine() - { - return dateSpine; - } - - @JsonProperty - public List getModels() - { - return models; - } - - @JsonProperty - public List getRelationships() - { - return relationships; - } - - @JsonProperty - public List getEnumDefinitions() - { - return enumDefinitions; - } - - @JsonProperty - public List getMetrics() - { - return metrics; - } - - @JsonProperty - public List getCumulativeMetrics() - { - return cumulativeMetrics; - } - - @JsonProperty - public List getViews() - { - return views; - } - - @JsonProperty - public List getMacros() - { - return macros; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - Manifest manifest = (Manifest) o; - return Objects.equals(catalog, manifest.catalog) && - Objects.equals(schema, manifest.schema) && - Objects.equals(models, manifest.models) && - Objects.equals(relationships, manifest.relationships) && - Objects.equals(enumDefinitions, manifest.enumDefinitions) && - Objects.equals(metrics, manifest.metrics) && - Objects.equals(cumulativeMetrics, manifest.cumulativeMetrics) && - Objects.equals(views, manifest.views) && - Objects.equals(macros, manifest.macros) && - Objects.equals(dateSpine, manifest.dateSpine); - } - - @Override - public int hashCode() - { - return Objects.hash( - catalog, - schema, - models, - relationships, - enumDefinitions, - metrics, - cumulativeMetrics, - views, - macros, - dateSpine); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("catalog", catalog) - .add("schema", schema) - .add("models", models) - .add("relationships", relationships) - .add("enumDefinitions", enumDefinitions) - .add("metrics", metrics) - .add("cumulativeMetrics", cumulativeMetrics) - .add("views", views) - .add("macros", macros) - .add("dateSpine", dateSpine) - .toString(); - } - - public static class Builder - { - private String catalog; - private String schema; - private List models; - private List relationships; - private List enumDefinitions; - private List metrics; - private List cumulativeMetrics; - - private List views; - private List macros; - private DateSpine dateSpine; - - private Builder() {} - - private Builder(Manifest manifest) - { - this.catalog = manifest.catalog; - this.schema = manifest.schema; - this.models = manifest.models; - this.relationships = manifest.relationships; - this.enumDefinitions = manifest.enumDefinitions; - this.metrics = manifest.metrics; - this.cumulativeMetrics = manifest.cumulativeMetrics; - this.views = manifest.views; - this.macros = manifest.macros; - this.dateSpine = manifest.dateSpine; - } - - public Builder setCatalog(String catalog) - { - this.catalog = catalog; - return this; - } - - public Builder setSchema(String schema) - { - this.schema = schema; - return this; - } - - public Builder setModels(List models) - { - this.models = models; - return this; - } - - public Builder setRelationships(List relationships) - { - this.relationships = relationships; - return this; - } - - public Builder setEnumDefinitions(List enumDefinitions) - { - this.enumDefinitions = enumDefinitions; - return this; - } - - public Builder setMetrics(List metrics) - { - this.metrics = metrics; - return this; - } - - public Builder setCumulativeMetrics(List cumulativeMetrics) - { - this.cumulativeMetrics = cumulativeMetrics; - return this; - } - - public Builder setViews(List views) - { - this.views = views; - return this; - } - - public Builder setMacros(List macros) - { - this.macros = macros; - return this; - } - - public Builder setDateSpine(DateSpine dateSpine) - { - this.dateSpine = dateSpine; - return this; - } - - public Manifest build() - { - return new Manifest( - catalog, - schema, - models, - relationships, - enumDefinitions, - metrics, - cumulativeMetrics, - views, - macros, - dateSpine); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Measure.java b/wren-base/src/main/java/io/wren/base/dto/Measure.java deleted file mode 100644 index f89a6fbcc..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Measure.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; - -public class Measure -{ - public static Measure measure(String name, String type, String operator, String refColumn) - { - return new Measure(name, type, operator, refColumn); - } - - private final String name; - private final String type; - private final String operator; - private final String refColumn; - - @JsonCreator - public Measure( - @JsonProperty("name") String name, - @JsonProperty("type") String type, - @JsonProperty("operator") String operator, - @JsonProperty("refColumn") String refColumn) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.type = requireNonNullEmpty(type, "type is null or empty"); - this.operator = requireNonNullEmpty(operator, "operator is null or empty"); - this.refColumn = requireNonNullEmpty(refColumn, "refColumn is null or empty"); - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getType() - { - return type; - } - - @JsonProperty - public String getOperator() - { - return operator; - } - - @JsonProperty - public String getRefColumn() - { - return refColumn; - } - - public Column toColumn() - { - return new Column(name, type, null, false, false, refColumn); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Measure measure = (Measure) o; - return Objects.equals(name, measure.name) && - Objects.equals(type, measure.type) && - Objects.equals(operator, measure.operator) && - Objects.equals(refColumn, measure.refColumn); - } - - @Override - public int hashCode() - { - return Objects.hash(name, type, operator, refColumn); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("type", type) - .add("operator", operator) - .add("refColumn", refColumn) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Metric.java b/wren-base/src/main/java/io/wren/base/dto/Metric.java deleted file mode 100644 index 38ab9475b..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Metric.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.collect.ImmutableList; -import io.airlift.units.Duration; - -import java.util.List; -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.checkArgument; -import static io.wren.base.Utils.requireNonNullEmpty; -import static java.util.Objects.requireNonNull; - -public class Metric - implements CacheInfo, Relationable -{ - private final String name; - private final String baseObject; - private final List dimension; - private final List measure; - private final List timeGrain; - private final boolean cached; - private final Duration refreshTime; - - public static Metric metric(String name, String baseObject, List dimension, List measure) - { - return metric(name, baseObject, dimension, measure, List.of(), false); - } - - public static Metric metric(String name, String baseObject, List dimension, List measure, List timeGrain) - { - return metric(name, baseObject, dimension, measure, timeGrain, false); - } - - public static Metric metric(String name, String baseObject, List dimension, List measure, List timeGrain, boolean cached) - { - return new Metric(name, baseObject, dimension, measure, timeGrain, cached, null); - } - - @JsonCreator - public Metric( - @JsonProperty("name") String name, - @JsonProperty("baseObject") String baseObject, - @JsonProperty("dimension") List dimension, - @JsonProperty("measure") List measure, - @JsonProperty("timeGrain") List timeGrain, - @JsonProperty("cached") boolean cached, - @JsonProperty("refreshTime") Duration refreshTime) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.baseObject = requireNonNullEmpty(baseObject, "baseObject is null or empty"); - this.dimension = requireNonNull(dimension, "dimension is null"); - this.measure = requireNonNull(measure, "measure is null"); - this.cached = cached; - checkArgument(!measure.isEmpty(), "the number of measures should be one at least"); - this.timeGrain = timeGrain == null ? ImmutableList.of() : timeGrain; - this.refreshTime = refreshTime == null ? defaultRefreshTime : refreshTime; - } - - @Override - @JsonProperty - public String getName() - { - return name; - } - - @Override - @JsonProperty - public String getBaseObject() - { - return baseObject; - } - - @JsonProperty - public List getDimension() - { - return dimension; - } - - @JsonProperty - public List getMeasure() - { - return measure; - } - - @JsonProperty - public List getTimeGrain() - { - return timeGrain; - } - - public Optional getTimeGrain(String timeGrainName) - { - return timeGrain.stream() - .filter(timeGrain -> timeGrain.getName().equals(timeGrainName)) - .findFirst(); - } - - @Override - public List getColumns() - { - return ImmutableList.builder().addAll(dimension).addAll(measure).build(); - } - - @Override - @JsonProperty - public boolean isCached() - { - return cached; - } - - @Override - @JsonProperty - public Duration getRefreshTime() - { - return refreshTime; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Metric that = (Metric) obj; - return cached == that.cached && - Objects.equals(name, that.name) && - Objects.equals(baseObject, that.baseObject) && - Objects.equals(dimension, that.dimension) && - Objects.equals(measure, that.measure) && - Objects.equals(timeGrain, that.timeGrain) && - Objects.equals(refreshTime, that.refreshTime); - } - - @Override - public int hashCode() - { - return Objects.hash( - name, - baseObject, - dimension, - measure, - timeGrain, - cached, - refreshTime); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("baseObject", baseObject) - .add("dimension", dimension) - .add("measure", measure) - .add("timeGrain", timeGrain) - .add("cached", cached) - .add("refreshTime", refreshTime) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Model.java b/wren-base/src/main/java/io/wren/base/dto/Model.java deleted file mode 100644 index 23dab92c4..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Model.java +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.airlift.units.Duration; - -import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.checkArgument; -import static io.wren.base.Utils.requireNonNullEmpty; - -public class Model - implements CacheInfo, Relationable -{ - private final String name; - private final String refSql; - private final String baseObject; - private final TableReference tableReference; - private final List columns; - private final String primaryKey; - private final boolean cached; - private final Duration refreshTime; - - public static Model model(String name, String refSql, List columns) - { - return model(name, refSql, columns, null); - } - - public static Model model(String name, String refSql, List columns, boolean cached) - { - return new Model(name, refSql, null, null, columns, null, cached, null); - } - - public static Model model(String name, String refSql, List columns, String primaryKey) - { - return new Model(name, refSql, null, null, columns, primaryKey, false, null); - } - - public static Model onBaseObject(String name, String baseObject, List columns, String primaryKey) - { - return new Model(name, null, baseObject, null, columns, primaryKey, false, null); - } - - public static Model onTableReference(String name, TableReference tableReference, List columns, String primaryKey) - { - return new Model(name, null, null, tableReference, columns, primaryKey, false, null); - } - - @JsonCreator - public Model( - @JsonProperty("name") String name, - @JsonProperty("refSql") String refSql, - @JsonProperty("baseObject") String baseObject, - @JsonProperty("tableReference") TableReference tableReference, - @JsonProperty("columns") List columns, - @JsonProperty("primaryKey") String primaryKey, - @JsonProperty("cached") boolean cached, - @JsonProperty("refreshTime") Duration refreshTime) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - checkArgument(Stream.of(refSql, baseObject, tableReference).filter(Model::isNonNullOrNonEmpty).count() == 1, - "either none or more than one of (refSql, baseObject, tableReference) are set"); - this.refSql = refSql; - this.baseObject = baseObject; - this.tableReference = tableReference; - this.columns = columns == null ? List.of() : columns; - this.primaryKey = primaryKey; - this.cached = cached; - this.refreshTime = refreshTime == null ? defaultRefreshTime : refreshTime; - } - - private static boolean isNonNullOrNonEmpty(Object value) - { - if (value == null) { - return false; - } - if (value instanceof String) { - return !((String) value).isEmpty(); - } - return true; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getRefSql() - { - return refSql; - } - - @JsonProperty - @Override - public String getBaseObject() - { - return baseObject; - } - - @JsonProperty - public TableReference getTableReference() - { - return tableReference; - } - - @Override - @JsonProperty - public List getColumns() - { - return columns; - } - - @JsonProperty - public String getPrimaryKey() - { - return primaryKey; - } - - @Override - @JsonProperty - public boolean isCached() - { - return cached; - } - - @Override - @JsonProperty - public Duration getRefreshTime() - { - return refreshTime; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Model that = (Model) obj; - return cached == that.cached && - Objects.equals(name, that.name) && - Objects.equals(refSql, that.refSql) && - Objects.equals(baseObject, that.baseObject) && - Objects.equals(tableReference, that.tableReference) && - Objects.equals(columns, that.columns) && - Objects.equals(primaryKey, that.primaryKey) && - Objects.equals(refreshTime, that.refreshTime); - } - - @Override - public int hashCode() - { - return Objects.hash(name, refSql, baseObject, tableReference, columns, primaryKey); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("refSql", refSql) - .add("baseObject", baseObject) - .add("tableReference", tableReference) - .add("columns", columns) - .add("cached", cached) - .add("refreshTime", refreshTime) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Relationable.java b/wren-base/src/main/java/io/wren/base/dto/Relationable.java deleted file mode 100644 index f09866b24..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Relationable.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import java.util.List; - -public interface Relationable -{ - String getName(); - - List getColumns(); - - String getBaseObject(); -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Relationship.java b/wren-base/src/main/java/io/wren/base/dto/Relationship.java deleted file mode 100644 index 5d5fcea14..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Relationship.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.collect.Lists; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.ExpressionRewriter; -import io.trino.sql.tree.ExpressionTreeRewriter; -import io.trino.sql.tree.Identifier; - -import java.util.Arrays; -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.checkArgument; -import static io.wren.base.Utils.requireNonNullEmpty; -import static io.wren.base.sqlrewrite.Utils.parseExpression; -import static java.util.Objects.requireNonNull; - -public class Relationship -{ - private final String name; - private final List models; - private final JoinType joinType; - private final String condition; - private final Expression qualifiedCondition; - - // for debugging internally - private final boolean isReverse; - private final List manySideSortKeys; - - public static Relationship relationship(String name, List models, JoinType joinType, String condition) - { - return relationship(name, models, joinType, condition, null); - } - - public static Relationship relationship(String name, List models, JoinType joinType, String condition, List manySideSortKeys) - { - return new Relationship(name, models, joinType, condition, manySideSortKeys); - } - - public static Relationship reverse(Relationship relationship) - { - return new Relationship( - relationship.name, - Lists.reverse(relationship.getModels()), - JoinType.reverse(relationship.joinType), - relationship.getCondition(), - true, - relationship.getManySideSortKeys()); - } - - @JsonCreator - public Relationship( - @JsonProperty("name") String name, - @JsonProperty("models") List models, - @JsonProperty("joinType") JoinType joinType, - @JsonProperty("condition") String condition, - @JsonProperty("manySideSortKeys") List manySideSortKeys) - { - this(name, models, joinType, condition, false, manySideSortKeys); - } - - public Relationship( - String name, - List models, - JoinType joinType, - String condition, - boolean isReverse, - List manySideSortKeys) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - checkArgument(models != null && models.size() >= 2, "relationship should contain at least 2 models"); - this.models = models; - this.joinType = requireNonNull(joinType, "joinType is null"); - this.condition = requireNonNullEmpty(condition, "condition is null or empty"); - this.qualifiedCondition = qualifiedCondition(condition); - this.isReverse = isReverse; - this.manySideSortKeys = manySideSortKeys == null ? List.of() : manySideSortKeys; - } - - private Expression qualifiedCondition(String condition) - { - Expression parsed = parseExpression(condition); - return ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<>() - { - @Override - public Expression rewriteDereferenceExpression(DereferenceExpression node, Void context, ExpressionTreeRewriter treeRewriter) - { - return new DereferenceExpression( - node.getLocation(), - treeRewriter.rewrite(node.getBase(), context), - node.getField().map(field -> treeRewriter.rewrite(field, context))); - } - - @Override - public Expression rewriteIdentifier(Identifier node, Void context, ExpressionTreeRewriter treeRewriter) - { - if (node.isDelimited()) { - return node; - } - if (node.getLocation().isPresent()) { - return new Identifier(node.getLocation().get(), node.getValue(), true); - } - return new Identifier(node.getValue(), true); - } - }, parsed); - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public List getModels() - { - return models; - } - - @JsonProperty - public JoinType getJoinType() - { - return joinType; - } - - @JsonProperty - public String getCondition() - { - return condition; - } - - public Expression getQualifiedCondition() - { - return qualifiedCondition; - } - - @JsonProperty - public List getManySideSortKeys() - { - return manySideSortKeys; - } - - public boolean isReverse() - { - return isReverse; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - Relationship that = (Relationship) obj; - return Objects.equals(name, that.name) && - Objects.equals(models, that.models) && - joinType == that.joinType && - Objects.equals(condition, that.condition) && - isReverse == that.isReverse && - Objects.equals(manySideSortKeys, that.manySideSortKeys); - } - - @Override - public int hashCode() - { - return Objects.hash(name, models, joinType, condition, isReverse, manySideSortKeys); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("models", models) - .add("joinType", joinType) - .add("condition", condition) - .add("isReverse", isReverse) - .add("manySideSortKeys", manySideSortKeys) - .toString(); - } - - public static class SortKey - { - public enum Ordering - { - ASC, - DESC; - - public static Ordering get(String value) - { - return Arrays.stream(values()) - .filter(v -> v.toString().equalsIgnoreCase(value)) - .findAny() - .orElseThrow(() -> new IllegalArgumentException("Unsupported ordering")); - } - } - - private final String name; - private final boolean isDescending; - - @JsonCreator - public SortKey( - @JsonProperty("name") String name, - @JsonProperty("ordering") Ordering ordering) - { - this.name = requireNonNull(name, "name is null"); - this.isDescending = ordering == Ordering.DESC; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public boolean isDescending() - { - return isDescending; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - SortKey sortKey = (SortKey) obj; - return Objects.equals(name, sortKey.name) - && isDescending == sortKey.isDescending; - } - - @Override - public int hashCode() - { - return Objects.hash(name, isDescending); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("isDescending", isDescending) - .toString(); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/TableReference.java b/wren-base/src/main/java/io/wren/base/dto/TableReference.java deleted file mode 100644 index 1acb31935..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/TableReference.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.Utils; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.lang.String.format; - -public class TableReference -{ - public static TableReference tableReference(String catalog, String schema, String table) - { - return new TableReference(catalog, schema, table); - } - - private final String catalog; - private final String schema; - private final String table; - - @JsonCreator - public TableReference( - @JsonProperty("catalog") String catalog, - @JsonProperty("schema") String schema, - @JsonProperty("table") String table) - { - this.catalog = catalog; - this.schema = schema; - this.table = Utils.requireNonNullEmpty(table, "table should not be empty"); - } - - @JsonProperty - public String getCatalog() - { - return catalog; - } - - @JsonProperty - public String getSchema() - { - return schema; - } - - @JsonProperty - public String getTable() - { - return table; - } - - public String toQualifiedName() - { - if (isNullOrEmpty(catalog)) { - if (isNullOrEmpty(schema)) { - return format("\"%s\"", table); - } - return format("\"%s\".\"%s\"", schema, table); - } - return format("\"%s\".\"%s\".\"%s\"", catalog, schema, table); - } - - private boolean isNullOrEmpty(String str) - { - return str == null || str.isEmpty(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - TableReference that = (TableReference) o; - return Objects.equals(catalog, that.catalog) && Objects.equals(schema, that.schema) && Objects.equals(table, that.table); - } - - @Override - public int hashCode() - { - return Objects.hash(catalog, schema, table); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("catalog", catalog) - .add("schema", schema) - .add("table", table) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/TimeGrain.java b/wren-base/src/main/java/io/wren/base/dto/TimeGrain.java deleted file mode 100644 index 3e5c0c3a2..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/TimeGrain.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; - -public class TimeGrain -{ - private final String name; - - private final String refColumn; - private final List timeUnits; - - public static TimeGrain timeGrain(String name, String refColumn, List timeUnits) - { - return new TimeGrain(name, refColumn, timeUnits); - } - - @JsonCreator - public TimeGrain( - @JsonProperty("name") String name, - @JsonProperty("refColumn") String refColumn, - @JsonProperty("dateParts") List timeUnits) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.refColumn = requireNonNullEmpty(refColumn, "refColumn is null or empty"); - this.timeUnits = timeUnits == null ? List.of() : timeUnits; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getRefColumn() - { - return refColumn; - } - - @JsonProperty - public List getDateParts() - { - return timeUnits; - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - TimeGrain that = (TimeGrain) obj; - return Objects.equals(name, that.name) && - Objects.equals(refColumn, that.refColumn) && - Objects.equals(timeUnits, that.timeUnits); - } - - @Override - public int hashCode() - { - return Objects.hash(name, refColumn, timeUnits); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("refColumn", refColumn) - .add("timeUnits", timeUnits) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/TimeUnit.java b/wren-base/src/main/java/io/wren/base/dto/TimeUnit.java deleted file mode 100644 index ee2a6c581..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/TimeUnit.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import static java.util.Locale.ENGLISH; - -public enum TimeUnit -{ - YEAR("INTERVAL '1 YEAR'"), - QUARTER("INTERVAL '3 MONTH'"), - MONTH("INTERVAL '1 MONTH'"), - WEEK("INTERVAL '7 DAY'"), - DAY("INTERVAL '1 DAY'"), - HOUR("INTERVAL '1 HOUR'"), - MINUTE("INTERVAL '1 MINUTE'"), - SECOND("INTERVAL '1 SECOND'"); - - private final String intervalExpression; - - TimeUnit(String intervalExpression) - { - this.intervalExpression = intervalExpression; - } - - public String getIntervalExpression() - { - return intervalExpression; - } - - public static TimeUnit timeUnit(String name) - { - return valueOf(name.toUpperCase(ENGLISH)); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/View.java b/wren-base/src/main/java/io/wren/base/dto/View.java deleted file mode 100644 index 833e81186..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/View.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Map; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; - -public class View -{ - private final String name; - private final String statement; - - public static View view(String name, String statement) - { - return new View(name, statement, null); - } - - @JsonCreator - public View( - @JsonProperty("name") String name, - @JsonProperty("statement") String statement, - @JsonProperty("properties") Map properties) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.statement = requireNonNullEmpty(statement, "statement is null or empty"); - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getStatement() - { - return statement; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - View view = (View) o; - return Objects.equals(name, view.name) && - Objects.equals(statement, view.statement); - } - - @Override - public int hashCode() - { - return Objects.hash( - name, - statement); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("statement", statement) - .toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/dto/Window.java b/wren-base/src/main/java/io/wren/base/dto/Window.java deleted file mode 100644 index 38f4faea3..000000000 --- a/wren-base/src/main/java/io/wren/base/dto/Window.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.WrenTypes; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static io.wren.base.Utils.requireNonNullEmpty; -import static java.util.Objects.requireNonNull; - -public class Window -{ - private final String name; - - private final String refColumn; - - private final TimeUnit timeUnit; - - private final String start; - private final String end; - - public static Window window(String name, String refColumn, TimeUnit timeUnit, String start, String end) - { - return new Window(name, refColumn, timeUnit, start, end); - } - - @JsonCreator - public Window( - @JsonProperty("name") String name, - @JsonProperty("refColumn") String refColumn, - @JsonProperty("timeUnit") TimeUnit timeUnit, - @JsonProperty("start") String start, - @JsonProperty("end") String end) - { - this.name = requireNonNullEmpty(name, "name is null or empty"); - this.refColumn = requireNonNullEmpty(refColumn, "refColumn is null or empty"); - this.timeUnit = requireNonNull(timeUnit, "timeUnit is null or empty"); - this.start = requireNonNullEmpty(start, "start is null or empty"); - this.end = requireNonNullEmpty(end, "end is null or empty"); - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public String getRefColumn() - { - return refColumn; - } - - @JsonProperty - public TimeUnit getTimeUnit() - { - return timeUnit; - } - - @JsonProperty - public String getStart() - { - return start; - } - - @JsonProperty - public String getEnd() - { - return end; - } - - public Column toColumn() - { - return new Column(name, WrenTypes.TIMESTAMP, null, false, false, refColumn); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("name", name) - .add("refColumn", refColumn) - .add("timeUnit", timeUnit) - .add("start", start) - .add("end", end) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - - Window window = (Window) o; - return Objects.equals(name, window.name) && - Objects.equals(refColumn, window.refColumn) && - timeUnit == window.timeUnit && - Objects.equals(start, window.start) && - Objects.equals(end, window.end); - } - - @Override - public int hashCode() - { - return Objects.hash(name, refColumn, timeUnit, start, end); - } -} diff --git a/wren-base/src/main/java/io/wren/base/jinjava/JinjavaExpressionProcessor.java b/wren-base/src/main/java/io/wren/base/jinjava/JinjavaExpressionProcessor.java deleted file mode 100644 index 007de880a..000000000 --- a/wren-base/src/main/java/io/wren/base/jinjava/JinjavaExpressionProcessor.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Licensed 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 io.wren.base.jinjava; - -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.ExpressionRewriter; -import io.trino.sql.tree.ExpressionTreeRewriter; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.QualifiedName; -import io.wren.base.WrenException; -import io.wren.base.dto.Macro; -import io.wren.base.macro.Parameter; - -import java.util.List; -import java.util.Optional; - -import static io.trino.sql.SqlFormatter.formatSql; -import static io.wren.base.metadata.StandardErrorCode.SYNTAX_ERROR; -import static io.wren.base.sqlrewrite.Utils.parseExpression; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toList; - -/** - * Process passing jinjava macro as an argument to another jinjava macro - */ -public class JinjavaExpressionProcessor -{ - public static String process(String source, List macros) - { - return new JinjavaExpressionProcessor(source, null, macros).processInternal(); - } - - static String process(String source, CallerInfo caller, List macros) - { - return new JinjavaExpressionProcessor(source, caller, macros).processInternal(); - } - - private final String source; - private final StringBuilder resultBuffer; - - private final List macros; - - private final Optional callerInfo; - private StringBuilder expressionBuffer; - private boolean inQuoted; - private boolean inDoubleQuoted; - private boolean inExpression; - - public JinjavaExpressionProcessor(String source, CallerInfo callerInfo, List macros) - { - this.source = requireNonNull(source, "source is null"); - this.callerInfo = Optional.ofNullable(callerInfo); - this.macros = macros == null ? List.of() : macros; - this.resultBuffer = new StringBuilder(source.length()); - this.expressionBuffer = new StringBuilder(); - } - - private String processInternal() - { - for (int i = 0; i < source.length(); i++) { - char c = source.charAt(i); - if (c == '{') { - if (i + 1 < source.length() && source.charAt(i + 1) == '{') { - i++; - if (inQuoted || inDoubleQuoted) { - resultBuffer.append(c); - } - else if (inExpression) { - throw new WrenException(SYNTAX_ERROR, format("Generating macro failed: Nested expression is not supported for macro: %s", source)); - } - else { - inExpression = true; - } - } - else { - resultBuffer.append(c); - } - } - else if (c == '}') { - if (i + 1 < source.length() && source.charAt(i + 1) == '}') { - i++; - if (inQuoted || inDoubleQuoted) { - resultBuffer.append(c); - } - else if (!inExpression) { - throw new WrenException(SYNTAX_ERROR, format("Generating macro failed: Unmatched }} in %s", source)); - } - else { - inExpression = false; - resultBuffer.append(processExpression(expressionBuffer.toString())); - expressionBuffer = new StringBuilder(); - } - } - else { - resultBuffer.append(c); - } - } - else if (c == '\'') { - if (inDoubleQuoted) { - if (inExpression) { - expressionBuffer.append(c); - } - else { - resultBuffer.append(c); - } - } - else if (inExpression) { - inQuoted = !inQuoted; - expressionBuffer.append(c); - } - else { - inQuoted = !inQuoted; - resultBuffer.append(c); - } - } - else if (c == '"') { - if (inQuoted) { - if (inExpression) { - expressionBuffer.append(c); - } - else { - resultBuffer.append(c); - } - } - else if (inExpression) { - inDoubleQuoted = !inDoubleQuoted; - expressionBuffer.append(c); - } - else { - inDoubleQuoted = !inDoubleQuoted; - resultBuffer.append(c); - } - } - else if (inExpression) { - expressionBuffer.append(c); - } - else { - resultBuffer.append(c); - } - } - return resultBuffer.toString(); - } - - private String processExpression(String expression) - { - Expression macroExpression = parseExpression(expression); - return Optional.ofNullable(new Processor(macros, callerInfo).process(macroExpression, null)) - .orElseThrow(() -> new WrenException(SYNTAX_ERROR, format("Failed to apply macro to %s in %s", expression, source))); - } - - static class Processor - extends AstVisitor - { - private final List macros; - private Optional callerInfo = Optional.empty(); - - public Processor(List macros, Optional callerInfo) - { - this.macros = macros; - this.callerInfo = callerInfo; - } - - @Override - protected String visitIdentifier(Identifier node, Void context) - { - return format("{{ %s }}", formatSql(node)); - } - - @Override - protected String visitFunctionCall(FunctionCall node, Void context) - { - String functionName = node.getName().toString(); - List arguments = node.getArguments(); - Optional callee = macros.stream() - .filter(m -> m.getName().equals(functionName)) - .filter(m -> m.getParameters().stream().anyMatch(p -> p.getType() == Parameter.TYPE.MACRO)) - .findAny(); - if (callee.isPresent()) { - return JinjavaExpressionProcessor.process( - callee.get().getBody(), - new CallerInfo(callee.get(), arguments), - macros); - } - - if (callerInfo.isPresent()) { - Macro caller = callerInfo.get().getCaller(); - Expression processed = ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<>() - { - @Override - public Expression rewriteFunctionCall(FunctionCall node, Void context, ExpressionTreeRewriter treeRewriter) - { - Optional matched = caller.getParameters().stream() - .filter(p -> p.getName().equals(node.getName().toString()) && p.getType() == Parameter.TYPE.MACRO) - .findAny(); - if (matched.isEmpty()) { - return treeRewriter.defaultRewrite(node, context); - } - int index = caller.getParameters().indexOf(matched.get()); - if (node.getLocation().isPresent()) { - return treeRewriter.defaultRewrite(new FunctionCall( - node.getLocation().get(), - QualifiedName.of(callerInfo.get().getArguments().get(index).toString()), - node.getArguments().stream() - .map(expression -> treeRewriter.defaultRewrite(expression, context)) - .collect(toList())), - context); - } - return treeRewriter.defaultRewrite( - new FunctionCall(QualifiedName.of(callerInfo.get().getArguments().get(index).toString()), node.getArguments().stream() - .map(expression -> treeRewriter.defaultRewrite(expression, context)) - .collect(toList())), - context); - } - - @Override - public Expression rewriteIdentifier(Identifier node, Void context, ExpressionTreeRewriter treeRewriter) - { - Optional matched = caller.getParameters().stream() - .filter(p -> p.getName().equals(node.getValue()) && p.getType() == Parameter.TYPE.EXPRESSION) - .findAny(); - if (matched.isEmpty()) { - return treeRewriter.defaultRewrite(node, context); - } - - int index = caller.getParameters().indexOf(matched.get()); - Expression newValue = callerInfo.get().getArguments().get(index); - - if (node.getLocation().isPresent()) { - return treeRewriter.defaultRewrite( - newValue, - context); - } - return treeRewriter.defaultRewrite( - newValue, - context); - } - }, node); - return format("{{ %s }}", formatSql(processed)); - } - return format("{{ %s }}", formatSql(node)); - } - } - - static class CallerInfo - { - private final Macro caller; - private final List arguments; - - public CallerInfo(Macro caller, List arguments) - { - this.caller = caller; - this.arguments = arguments; - } - - public Macro getCaller() - { - return caller; - } - - public List getArguments() - { - return arguments; - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/jinjava/JinjavaUtils.java b/wren-base/src/main/java/io/wren/base/jinjava/JinjavaUtils.java deleted file mode 100644 index 98f3cdc63..000000000 --- a/wren-base/src/main/java/io/wren/base/jinjava/JinjavaUtils.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Licensed 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 io.wren.base.jinjava; - -import io.wren.base.dto.Macro; -import io.wren.base.macro.Parameter; - -import static java.lang.String.format; -import static java.util.stream.Collectors.joining; - -public class JinjavaUtils -{ - private JinjavaUtils() {} - - public static String getMacroTag(Macro macro) - { - StringBuilder builder = new StringBuilder(); - String paramString = macro.getParameters().stream().map(Parameter::getName).collect(joining(",")); - builder.append(format("{%% macro %s(%s) -%%}", macro.getName(), paramString)); - builder.append(macro.getBody()); - builder.append("{%- endmacro -%}"); - return builder.toString(); - } -} diff --git a/wren-base/src/main/java/io/wren/base/macro/Parameter.java b/wren-base/src/main/java/io/wren/base/macro/Parameter.java deleted file mode 100644 index e4b3e00a2..000000000 --- a/wren-base/src/main/java/io/wren/base/macro/Parameter.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed 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 io.wren.base.macro; - -import java.util.Objects; - -public class Parameter -{ - public static Parameter expressionType(String name) - { - return new Parameter(name, TYPE.EXPRESSION); - } - - public static Parameter macroType(String name) - { - return new Parameter(name, TYPE.MACRO); - } - - public enum TYPE - { - MACRO, - EXPRESSION - } - - private final String name; - private final TYPE type; - - public Parameter(String name, TYPE type) - { - this.name = name; - this.type = type; - } - - public String getName() - { - return name; - } - - public TYPE getType() - { - return type; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Parameter parameter = (Parameter) o; - return Objects.equals(name, parameter.name) && type == parameter.type; - } - - @Override - public int hashCode() - { - return Objects.hash(name, type); - } - - @Override - public String toString() - { - return "Parameter{" + - "name='" + name + '\'' + - ", type=" + type + - '}'; - } -} diff --git a/wren-base/src/main/java/io/wren/base/macro/ParameterCollector.java b/wren-base/src/main/java/io/wren/base/macro/ParameterCollector.java deleted file mode 100644 index a2ac7c7d7..000000000 --- a/wren-base/src/main/java/io/wren/base/macro/ParameterCollector.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Licensed 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 io.wren.base.macro; - -import org.antlr.v4.runtime.ParserRuleContext; - -import java.util.ArrayList; -import java.util.List; - -import static java.util.Locale.ENGLISH; - -public class ParameterCollector - extends ParameterListBaseBaseVisitor -{ - private final List parameters = new ArrayList<>(); - - public List collect(ParserRuleContext context) - { - visit(context); - return parameters; - } - - @Override - public Void visitParameter(ParameterListBaseParser.ParameterContext ctx) - { - parameters.add(new Parameter(ctx.paraName().getText(), - Parameter.TYPE.valueOf(ctx.typeName().getText().toUpperCase(ENGLISH)))); - return null; - } -} diff --git a/wren-base/src/main/java/io/wren/base/macro/ParameterListParser.java b/wren-base/src/main/java/io/wren/base/macro/ParameterListParser.java deleted file mode 100644 index b3f8a5265..000000000 --- a/wren-base/src/main/java/io/wren/base/macro/ParameterListParser.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Licensed 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 io.wren.base.macro; - -import org.antlr.v4.runtime.BaseErrorListener; -import org.antlr.v4.runtime.CharStreams; -import org.antlr.v4.runtime.CommonTokenStream; -import org.antlr.v4.runtime.DefaultErrorStrategy; -import org.antlr.v4.runtime.InputMismatchException; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.ParserRuleContext; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.Token; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.misc.ParseCancellationException; - -import java.util.List; -import java.util.function.BiConsumer; -import java.util.function.Function; - -import static java.lang.String.format; -import static java.util.Locale.ENGLISH; -import static java.util.Objects.requireNonNull; - -public class ParameterListParser -{ - private static final BaseErrorListener LEXER_ERROR_LISTENER = new BaseErrorListener() - { - @Override - public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String message, RecognitionException e) - { - throw new ParsingException(message, e, line, charPositionInLine + 1); - } - }; - private static final BiConsumer DEFAULT_PARSER_INITIALIZER = (ParameterListBaseLexer lexer, ParameterListBaseParser parser) -> {}; - - private final BiConsumer initializer; - - public ParameterListParser() - { - this(DEFAULT_PARSER_INITIALIZER); - } - - public ParameterListParser(BiConsumer initializer) - { - this.initializer = requireNonNull(initializer, "initializer is null"); - } - - public List parse(String listString) - { - return parse(listString, ParameterListBaseParser::parameterList); - } - - private List parse(String listString, Function parseFunction) - { - try { - ParameterListBaseLexer lexer = new ParameterListBaseLexer(CharStreams.fromString(listString)); - CommonTokenStream tokenStream = new CommonTokenStream(lexer); - ParameterListBaseParser parser = new ParameterListBaseParser(tokenStream); - initializer.accept(lexer, parser); - - // Override the default error strategy to not attempt inserting or deleting a token. - // Otherwise, it messes up error reporting - parser.setErrorHandler(new DefaultErrorStrategy() - { - @Override - public Token recoverInline(Parser recognizer) - throws RecognitionException - { - if (nextTokensContext == null) { - throw new InputMismatchException(recognizer); - } - else { - throw new InputMismatchException(recognizer, nextTokensState, nextTokensContext); - } - } - }); - - parser.addParseListener(new PostProcessor()); - - lexer.removeErrorListeners(); - lexer.addErrorListener(LEXER_ERROR_LISTENER); - - ParserRuleContext tree; - try { - // first, try parsing with potentially faster SLL mode - parser.getInterpreter().setPredictionMode(PredictionMode.SLL); - tree = parseFunction.apply(parser); - } - catch (ParseCancellationException ex) { - // if we fail, parse with LL mode - tokenStream.seek(0); // rewind input stream - parser.reset(); - - parser.getInterpreter().setPredictionMode(PredictionMode.LL); - tree = parseFunction.apply(parser); - } - - return new ParameterCollector().collect(tree); - } - catch (StackOverflowError e) { - throw new RuntimeException("ParameterList is too large (stack overflow while parsing)"); - } - } - - private static class PostProcessor - extends ParameterListBaseBaseListener - { - @Override - public void exitParameter(ParameterListBaseParser.ParameterContext ctx) - { - if (ctx.paraName() == null) { - throw new ParsingException(format("parse parameter failed: %s", ctx.getText()), ctx.getStart().getLine(), ctx.getStart().getCharPositionInLine()); - } - - if (ctx.typeName() == null) { - throw new ParsingException(format("typeName is null: %s", ctx.getText()), - ctx.paraName().getStart().getLine(), ctx.paraName().getStart().getCharPositionInLine() + 1); - } - - try { - Parameter.TYPE.valueOf(ctx.typeName().getText().toUpperCase(ENGLISH)); - } - catch (IllegalArgumentException e) { - throw new ParsingException(format("typeName is invalid: %s", ctx.getText()), - ctx.typeName().getStart().getLine(), ctx.typeName().getStart().getCharPositionInLine() + 1); - } - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/macro/ParsingException.java b/wren-base/src/main/java/io/wren/base/macro/ParsingException.java deleted file mode 100644 index b03c7019e..000000000 --- a/wren-base/src/main/java/io/wren/base/macro/ParsingException.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed 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 io.wren.base.macro; - -import org.antlr.v4.runtime.RecognitionException; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.lang.String.format; - -public class ParsingException - extends RuntimeException -{ - private final int line; - private final int column; - - public ParsingException(String message, RecognitionException cause, int line, int column) - { - super(message, cause); - checkArgument(line > 0, "line must be > 0"); - checkArgument(column > 0, "column must be > 0"); - - this.line = line; - this.column = column; - } - - public ParsingException(String message, int line, int column) - { - super(message); - checkArgument(line > 0, "line must be > 0"); - checkArgument(column > 0, "column must be > 0"); - - this.line = line; - this.column = column; - } - - public int getLineNumber() - { - return line; - } - - public int getColumnNumber() - { - return column; - } - - public String getErrorMessage() - { - return super.getMessage(); - } - - @Override - public String getMessage() - { - return format("line %s:%s: %s", getLineNumber(), getColumnNumber(), getErrorMessage()); - } -} diff --git a/wren-base/src/main/java/io/wren/base/metadata/CatalogName.java b/wren-base/src/main/java/io/wren/base/metadata/CatalogName.java deleted file mode 100644 index c6cb17f7b..000000000 --- a/wren-base/src/main/java/io/wren/base/metadata/CatalogName.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed 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 io.wren.base.metadata; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonValue; - -import java.util.Objects; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public final class CatalogName -{ - private static final String INFORMATION_SCHEMA_CONNECTOR_PREFIX = "$info_schema@"; - private static final String SYSTEM_TABLES_CONNECTOR_PREFIX = "$system@"; - - private final String catalogName; - - @JsonCreator - public CatalogName(String catalogName) - { - this.catalogName = requireNonNull(catalogName, "catalogName is null"); - checkArgument(!catalogName.isEmpty(), "catalogName is empty"); - } - - public String getCatalogName() - { - return catalogName; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - CatalogName that = (CatalogName) o; - return Objects.equals(catalogName, that.catalogName); - } - - @Override - public int hashCode() - { - return Objects.hash(catalogName); - } - - @JsonValue - @Override - public String toString() - { - return catalogName; - } - - public static boolean isInternalSystemConnector(CatalogName catalogName) - { - return catalogName.getCatalogName().startsWith(SYSTEM_TABLES_CONNECTOR_PREFIX) || - catalogName.getCatalogName().startsWith(INFORMATION_SCHEMA_CONNECTOR_PREFIX); - } - - public static CatalogName createInformationSchemaCatalogName(CatalogName catalogName) - { - return new CatalogName(INFORMATION_SCHEMA_CONNECTOR_PREFIX + catalogName.getCatalogName()); - } - - public static CatalogName createSystemTablesCatalogName(CatalogName catalogName) - { - return new CatalogName(SYSTEM_TABLES_CONNECTOR_PREFIX + catalogName.getCatalogName()); - } -} diff --git a/wren-base/src/main/java/io/wren/base/metadata/SchemaTableName.java b/wren-base/src/main/java/io/wren/base/metadata/SchemaTableName.java deleted file mode 100644 index 27d34876f..000000000 --- a/wren-base/src/main/java/io/wren/base/metadata/SchemaTableName.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Licensed 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 io.wren.base.metadata; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; - -import static io.wren.base.metadata.SchemaUtil.checkNotEmpty; - -public final class SchemaTableName -{ - private final String schemaName; - private final String tableName; - - @JsonCreator - public SchemaTableName(@JsonProperty("schema") String schemaName, @JsonProperty("table") String tableName) - { - this.schemaName = checkNotEmpty(schemaName, "schemaName"); - this.tableName = checkNotEmpty(tableName, "tableName"); - } - - @JsonProperty("schema") - public String getSchemaName() - { - return schemaName; - } - - @JsonProperty("table") - public String getTableName() - { - return tableName; - } - - @Override - public int hashCode() - { - return Objects.hash(schemaName, tableName); - } - - @Override - public boolean equals(Object obj) - { - if (this == obj) { - return true; - } - if (obj == null || getClass() != obj.getClass()) { - return false; - } - SchemaTableName other = (SchemaTableName) obj; - return Objects.equals(this.schemaName, other.schemaName) && - Objects.equals(this.tableName, other.tableName); - } - - @Override - public String toString() - { - return schemaName + '.' + tableName; - } -} diff --git a/wren-base/src/main/java/io/wren/base/metadata/SchemaUtil.java b/wren-base/src/main/java/io/wren/base/metadata/SchemaUtil.java deleted file mode 100644 index 6e84f17ad..000000000 --- a/wren-base/src/main/java/io/wren/base/metadata/SchemaUtil.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.wren.base.metadata; - -public final class SchemaUtil -{ - private SchemaUtil() {} - - public static String checkNotEmpty(String value, String name) - { - if (value == null) { - throw new NullPointerException(name + " is null"); - } - if (value.isEmpty()) { - throw new IllegalArgumentException(name + " is empty"); - } - return value; - } -} diff --git a/wren-base/src/main/java/io/wren/base/metadata/StandardErrorCode.java b/wren-base/src/main/java/io/wren/base/metadata/StandardErrorCode.java deleted file mode 100644 index cd94cac53..000000000 --- a/wren-base/src/main/java/io/wren/base/metadata/StandardErrorCode.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Licensed 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 io.wren.base.metadata; - -import io.wren.base.ErrorCode; -import io.wren.base.ErrorCodeSupplier; -import io.wren.base.ErrorType; - -public enum StandardErrorCode - implements ErrorCodeSupplier -{ - GENERIC_USER_ERROR(0, ErrorType.USER_ERROR), - SYNTAX_ERROR(1, ErrorType.USER_ERROR), - ABANDONED_QUERY(2, ErrorType.USER_ERROR), - USER_CANCELED(3, ErrorType.USER_ERROR), - PERMISSION_DENIED(4, ErrorType.USER_ERROR), - NOT_FOUND(5, ErrorType.USER_ERROR), - FUNCTION_NOT_FOUND(6, ErrorType.USER_ERROR), - INVALID_FUNCTION_ARGUMENT(7, ErrorType.USER_ERROR), // caught by TRY - DIVISION_BY_ZERO(8, ErrorType.USER_ERROR), // caught by TRY - INVALID_CAST_ARGUMENT(9, ErrorType.USER_ERROR), // caught by TRY - OPERATOR_NOT_FOUND(10, ErrorType.USER_ERROR), - INVALID_VIEW(11, ErrorType.USER_ERROR), - ALREADY_EXISTS(12, ErrorType.USER_ERROR), - NOT_SUPPORTED(13, ErrorType.USER_ERROR), - INVALID_SESSION_PROPERTY(14, ErrorType.USER_ERROR), - INVALID_WINDOW_FRAME(15, ErrorType.USER_ERROR), - CONSTRAINT_VIOLATION(16, ErrorType.USER_ERROR), - TRANSACTION_CONFLICT(17, ErrorType.USER_ERROR), - INVALID_TABLE_PROPERTY(18, ErrorType.USER_ERROR), - NUMERIC_VALUE_OUT_OF_RANGE(19, ErrorType.USER_ERROR), // caught by TRY - UNKNOWN_TRANSACTION(20, ErrorType.USER_ERROR), - NOT_IN_TRANSACTION(21, ErrorType.USER_ERROR), - TRANSACTION_ALREADY_ABORTED(22, ErrorType.USER_ERROR), - READ_ONLY_VIOLATION(23, ErrorType.USER_ERROR), - MULTI_CATALOG_WRITE_CONFLICT(24, ErrorType.USER_ERROR), - AUTOCOMMIT_WRITE_CONFLICT(25, ErrorType.USER_ERROR), - UNSUPPORTED_ISOLATION_LEVEL(26, ErrorType.USER_ERROR), - INCOMPATIBLE_CLIENT(27, ErrorType.USER_ERROR), - SUBQUERY_MULTIPLE_ROWS(28, ErrorType.USER_ERROR), - PROCEDURE_NOT_FOUND(29, ErrorType.USER_ERROR), - INVALID_PROCEDURE_ARGUMENT(30, ErrorType.USER_ERROR), - QUERY_REJECTED(31, ErrorType.USER_ERROR), - AMBIGUOUS_FUNCTION_CALL(32, ErrorType.USER_ERROR), - INVALID_SCHEMA_PROPERTY(33, ErrorType.USER_ERROR), - SCHEMA_NOT_EMPTY(34, ErrorType.USER_ERROR), - QUERY_TEXT_TOO_LARGE(35, ErrorType.USER_ERROR), - UNSUPPORTED_SUBQUERY(36, ErrorType.USER_ERROR), - EXCEEDED_FUNCTION_MEMORY_LIMIT(37, ErrorType.USER_ERROR), - ADMINISTRATIVELY_KILLED(38, ErrorType.USER_ERROR), - INVALID_COLUMN_PROPERTY(39, ErrorType.USER_ERROR), - QUERY_HAS_TOO_MANY_STAGES(40, ErrorType.USER_ERROR), - INVALID_SPATIAL_PARTITIONING(41, ErrorType.USER_ERROR), - INVALID_ANALYZE_PROPERTY(42, ErrorType.USER_ERROR), - TYPE_NOT_FOUND(43, ErrorType.USER_ERROR), - CATALOG_NOT_FOUND(44, ErrorType.USER_ERROR), - SCHEMA_NOT_FOUND(45, ErrorType.USER_ERROR), - TABLE_NOT_FOUND(46, ErrorType.USER_ERROR), - COLUMN_NOT_FOUND(47, ErrorType.USER_ERROR), - ROLE_NOT_FOUND(48, ErrorType.USER_ERROR), - SCHEMA_ALREADY_EXISTS(49, ErrorType.USER_ERROR), - TABLE_ALREADY_EXISTS(50, ErrorType.USER_ERROR), - COLUMN_ALREADY_EXISTS(51, ErrorType.USER_ERROR), - ROLE_ALREADY_EXISTS(52, ErrorType.USER_ERROR), - DUPLICATE_NAMED_QUERY(53, ErrorType.USER_ERROR), - DUPLICATE_COLUMN_NAME(54, ErrorType.USER_ERROR), - MISSING_COLUMN_NAME(55, ErrorType.USER_ERROR), - MISSING_CATALOG_NAME(56, ErrorType.USER_ERROR), - MISSING_SCHEMA_NAME(57, ErrorType.USER_ERROR), - TYPE_MISMATCH(58, ErrorType.USER_ERROR), - INVALID_LITERAL(59, ErrorType.USER_ERROR), - COLUMN_TYPE_UNKNOWN(60, ErrorType.USER_ERROR), - MISMATCHED_COLUMN_ALIASES(61, ErrorType.USER_ERROR), - AMBIGUOUS_NAME(62, ErrorType.USER_ERROR), - INVALID_COLUMN_REFERENCE(63, ErrorType.USER_ERROR), - MISSING_GROUP_BY(64, ErrorType.USER_ERROR), - MISSING_ORDER_BY(65, ErrorType.USER_ERROR), - MISSING_OVER(66, ErrorType.USER_ERROR), - NESTED_AGGREGATION(67, ErrorType.USER_ERROR), - NESTED_WINDOW(68, ErrorType.USER_ERROR), - EXPRESSION_NOT_IN_DISTINCT(69, ErrorType.USER_ERROR), - TOO_MANY_GROUPING_SETS(70, ErrorType.USER_ERROR), - FUNCTION_NOT_WINDOW(71, ErrorType.USER_ERROR), - FUNCTION_NOT_AGGREGATE(72, ErrorType.USER_ERROR), - EXPRESSION_NOT_AGGREGATE(73, ErrorType.USER_ERROR), - EXPRESSION_NOT_SCALAR(74, ErrorType.USER_ERROR), - EXPRESSION_NOT_CONSTANT(75, ErrorType.USER_ERROR), - INVALID_ARGUMENTS(76, ErrorType.USER_ERROR), - TOO_MANY_ARGUMENTS(77, ErrorType.USER_ERROR), - INVALID_PRIVILEGE(78, ErrorType.USER_ERROR), - DUPLICATE_PROPERTY(79, ErrorType.USER_ERROR), - INVALID_PARAMETER_USAGE(80, ErrorType.USER_ERROR), - VIEW_IS_STALE(81, ErrorType.USER_ERROR), - VIEW_IS_RECURSIVE(82, ErrorType.USER_ERROR), - NULL_TREATMENT_NOT_ALLOWED(83, ErrorType.USER_ERROR), - INVALID_ROW_FILTER(84, ErrorType.USER_ERROR), - INVALID_COLUMN_MASK(85, ErrorType.USER_ERROR), - MISSING_TABLE(86, ErrorType.USER_ERROR), - INVALID_RECURSIVE_REFERENCE(87, ErrorType.USER_ERROR), - MISSING_COLUMN_ALIASES(88, ErrorType.USER_ERROR), - NESTED_RECURSIVE(89, ErrorType.USER_ERROR), - INVALID_LIMIT_CLAUSE(90, ErrorType.USER_ERROR), - INVALID_ORDER_BY(91, ErrorType.USER_ERROR), - DUPLICATE_WINDOW_NAME(92, ErrorType.USER_ERROR), - INVALID_WINDOW_REFERENCE(93, ErrorType.USER_ERROR), - INVALID_PARTITION_BY(94, ErrorType.USER_ERROR), - - GENERIC_INTERNAL_ERROR(65536, ErrorType.INTERNAL_ERROR), - TOO_MANY_REQUESTS_FAILED(65537, ErrorType.INTERNAL_ERROR), - PAGE_TOO_LARGE(65538, ErrorType.INTERNAL_ERROR), - PAGE_TRANSPORT_ERROR(65539, ErrorType.INTERNAL_ERROR), - PAGE_TRANSPORT_TIMEOUT(65540, ErrorType.INTERNAL_ERROR), - NO_NODES_AVAILABLE(65541, ErrorType.INTERNAL_ERROR), - REMOTE_TASK_ERROR(65542, ErrorType.INTERNAL_ERROR), - COMPILER_ERROR(65543, ErrorType.INTERNAL_ERROR), - REMOTE_TASK_MISMATCH(65544, ErrorType.INTERNAL_ERROR), - SERVER_SHUTTING_DOWN(65545, ErrorType.INTERNAL_ERROR), - FUNCTION_IMPLEMENTATION_MISSING(65546, ErrorType.INTERNAL_ERROR), - REMOTE_BUFFER_CLOSE_FAILED(65547, ErrorType.INTERNAL_ERROR), - SERVER_STARTING_UP(65548, ErrorType.INTERNAL_ERROR), - FUNCTION_IMPLEMENTATION_ERROR(65549, ErrorType.INTERNAL_ERROR), - INVALID_PROCEDURE_DEFINITION(65550, ErrorType.INTERNAL_ERROR), - PROCEDURE_CALL_FAILED(65551, ErrorType.INTERNAL_ERROR), - AMBIGUOUS_FUNCTION_IMPLEMENTATION(65552, ErrorType.INTERNAL_ERROR), - ABANDONED_TASK(65553, ErrorType.INTERNAL_ERROR), - CORRUPT_SERIALIZED_IDENTITY(65554, ErrorType.INTERNAL_ERROR), - CORRUPT_PAGE(65555, ErrorType.INTERNAL_ERROR), - OPTIMIZER_TIMEOUT(65556, ErrorType.INTERNAL_ERROR), - OUT_OF_SPILL_SPACE(65557, ErrorType.INTERNAL_ERROR), - REMOTE_HOST_GONE(65558, ErrorType.INTERNAL_ERROR), - CONFIGURATION_INVALID(65559, ErrorType.INTERNAL_ERROR), - CONFIGURATION_UNAVAILABLE(65560, ErrorType.INTERNAL_ERROR), - INVALID_RESOURCE_GROUP(65561, ErrorType.INTERNAL_ERROR), - SERIALIZATION_ERROR(65562, ErrorType.INTERNAL_ERROR), - - GENERIC_INSUFFICIENT_RESOURCES(131072, ErrorType.INSUFFICIENT_RESOURCES), - EXCEEDED_GLOBAL_MEMORY_LIMIT(131073, ErrorType.INSUFFICIENT_RESOURCES), - QUERY_QUEUE_FULL(131074, ErrorType.INSUFFICIENT_RESOURCES), - EXCEEDED_TIME_LIMIT(131075, ErrorType.INSUFFICIENT_RESOURCES), - CLUSTER_OUT_OF_MEMORY(131076, ErrorType.INSUFFICIENT_RESOURCES), - EXCEEDED_CPU_LIMIT(131077, ErrorType.INSUFFICIENT_RESOURCES), - EXCEEDED_SPILL_LIMIT(131078, ErrorType.INSUFFICIENT_RESOURCES), - EXCEEDED_LOCAL_MEMORY_LIMIT(131079, ErrorType.INSUFFICIENT_RESOURCES), - ADMINISTRATIVELY_PREEMPTED(131080, ErrorType.INSUFFICIENT_RESOURCES), - EXCEEDED_SCAN_LIMIT(131081, ErrorType.INSUFFICIENT_RESOURCES), - - /**/; - - // Connectors can use error codes starting at the range 0x0100_0000 - // See https://github.com/trinodb/trino/wiki/Error-Codes - - private final ErrorCode errorCode; - - StandardErrorCode(int code, ErrorType type) - { - errorCode = new ErrorCode(code, name(), type); - } - - @Override - public ErrorCode toErrorCode() - { - return errorCode; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sql/SqlConverter.java b/wren-base/src/main/java/io/wren/base/sql/SqlConverter.java deleted file mode 100644 index 8afafb9e2..000000000 --- a/wren-base/src/main/java/io/wren/base/sql/SqlConverter.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed 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 io.wren.base.sql; - -import io.wren.base.SessionContext; - -public interface SqlConverter -{ - String convert(String sql, SessionContext sessionContext); -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/BaseRewriter.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/BaseRewriter.java deleted file mode 100644 index ddbfff935..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/BaseRewriter.java +++ /dev/null @@ -1,650 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.ArithmeticBinaryExpression; -import io.trino.sql.tree.ArithmeticUnaryExpression; -import io.trino.sql.tree.ArrayConstructor; -import io.trino.sql.tree.BetweenPredicate; -import io.trino.sql.tree.BinaryLiteral; -import io.trino.sql.tree.BindExpression; -import io.trino.sql.tree.BooleanLiteral; -import io.trino.sql.tree.Cast; -import io.trino.sql.tree.CharLiteral; -import io.trino.sql.tree.CoalesceExpression; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.DataType; -import io.trino.sql.tree.DataTypeParameter; -import io.trino.sql.tree.DateTimeDataType; -import io.trino.sql.tree.DecimalLiteral; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.DoubleLiteral; -import io.trino.sql.tree.ExistsPredicate; -import io.trino.sql.tree.FieldReference; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.GenericDataType; -import io.trino.sql.tree.GenericLiteral; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.IfExpression; -import io.trino.sql.tree.InListExpression; -import io.trino.sql.tree.InPredicate; -import io.trino.sql.tree.IntervalDayTimeDataType; -import io.trino.sql.tree.IntervalLiteral; -import io.trino.sql.tree.IsNotNullPredicate; -import io.trino.sql.tree.IsNullPredicate; -import io.trino.sql.tree.LambdaArgumentDeclaration; -import io.trino.sql.tree.LambdaExpression; -import io.trino.sql.tree.LikePredicate; -import io.trino.sql.tree.Literal; -import io.trino.sql.tree.LogicalExpression; -import io.trino.sql.tree.LongLiteral; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NotExpression; -import io.trino.sql.tree.NullIfExpression; -import io.trino.sql.tree.NullLiteral; -import io.trino.sql.tree.NumericParameter; -import io.trino.sql.tree.Parameter; -import io.trino.sql.tree.QuantifiedComparisonExpression; -import io.trino.sql.tree.Row; -import io.trino.sql.tree.RowDataType; -import io.trino.sql.tree.SearchedCaseExpression; -import io.trino.sql.tree.SimpleCaseExpression; -import io.trino.sql.tree.StringLiteral; -import io.trino.sql.tree.SubqueryExpression; -import io.trino.sql.tree.SubscriptExpression; -import io.trino.sql.tree.TimeLiteral; -import io.trino.sql.tree.TimestampLiteral; -import io.trino.sql.tree.TryExpression; -import io.trino.sql.tree.TypeParameter; -import io.trino.sql.tree.WhenClause; -import io.trino.sql.tree.Window; -import io.trino.sql.tree.WindowReference; -import io.trino.sql.tree.WindowSpecification; - -import java.util.List; -import java.util.Optional; - -import static java.util.stream.Collectors.toList; - -public class BaseRewriter - extends BaseTreeRewriter -{ - @Override - protected Node visitCoalesceExpression(CoalesceExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new CoalesceExpression( - node.getLocation().get(), - visitNodes(node.getOperands(), context)); - } - return new CoalesceExpression(visitNodes(node.getOperands(), context)); - } - - @Override - protected Node visitLiteral(Literal node, T context) - { - return super.visitLiteral(node, context); - } - - @Override - protected Node visitDoubleLiteral(DoubleLiteral node, T context) - { - return super.visitDoubleLiteral(node, context); - } - - @Override - protected Node visitDecimalLiteral(DecimalLiteral node, T context) - { - return super.visitDecimalLiteral(node, context); - } - - @Override - protected Node visitGenericLiteral(GenericLiteral node, T context) - { - return super.visitGenericLiteral(node, context); - } - - @Override - protected Node visitTimeLiteral(TimeLiteral node, T context) - { - return super.visitTimeLiteral(node, context); - } - - @Override - protected Node visitTimestampLiteral(TimestampLiteral node, T context) - { - return super.visitTimestampLiteral(node, context); - } - - @Override - protected Node visitWhenClause(WhenClause node, T context) - { - if (node.getLocation().isPresent()) { - return new WhenClause( - node.getLocation().get(), - visitAndCast(node.getOperand(), context), - visitAndCast(node.getResult(), context)); - } - return new WhenClause( - visitAndCast(node.getOperand(), context), - visitAndCast(node.getResult(), context)); - } - - @Override - protected Node visitIntervalLiteral(IntervalLiteral node, T context) - { - return super.visitIntervalLiteral(node, context); - } - - @Override - protected Node visitLambdaExpression(LambdaExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new LambdaExpression( - node.getLocation().get(), - node.getArguments(), - visitAndCast(node.getBody(), context)); - } - return new LambdaExpression( - node.getArguments(), - visitAndCast(node.getBody(), context)); - } - - @Override - protected Node visitSimpleCaseExpression(SimpleCaseExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new SimpleCaseExpression( - node.getLocation().get(), - visitAndCast(node.getOperand(), context), - visitNodes(node.getWhenClauses(), context), - node.getDefaultValue().map(expression -> visitAndCast(expression, context))); - } - return new SimpleCaseExpression( - visitAndCast(node.getOperand(), context), - visitNodes(node.getWhenClauses(), context), - node.getDefaultValue().map(expression -> visitAndCast(expression, context))); - } - - @Override - protected Node visitStringLiteral(StringLiteral node, T context) - { - return super.visitStringLiteral(node, context); - } - - @Override - protected Node visitCharLiteral(CharLiteral node, T context) - { - return super.visitCharLiteral(node, context); - } - - @Override - protected Node visitBinaryLiteral(BinaryLiteral node, T context) - { - return super.visitBinaryLiteral(node, context); - } - - @Override - protected Node visitBooleanLiteral(BooleanLiteral node, T context) - { - return super.visitBooleanLiteral(node, context); - } - - @Override - protected Node visitInListExpression(InListExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new InListExpression( - node.getLocation().get(), - visitNodes(node.getValues(), context)); - } - return new InListExpression(visitNodes(node.getValues(), context)); - } - - @Override - protected Node visitIdentifier(Identifier node, T context) - { - return super.visitIdentifier(node, context); - } - - @Override - protected Node visitNullIfExpression(NullIfExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new NullIfExpression( - node.getLocation().get(), - visitAndCast(node.getFirst(), context), - visitAndCast(node.getSecond(), context)); - } - return new NullIfExpression( - visitAndCast(node.getFirst(), context), - visitAndCast(node.getSecond(), context)); - } - - @Override - protected Node visitIfExpression(IfExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new IfExpression( - node.getLocation().get(), - visitAndCast(node.getCondition(), context), - visitAndCast(node.getTrueValue(), context), - node.getFalseValue().map(expression -> visitAndCast(expression, context)).orElse(null)); - } - return new IfExpression( - visitAndCast(node.getCondition(), context), - visitAndCast(node.getTrueValue(), context), - node.getFalseValue().map(expression -> visitAndCast(expression, context)).orElse(null)); - } - - @Override - protected Node visitNullLiteral(NullLiteral node, T context) - { - return super.visitNullLiteral(node, context); - } - - @Override - protected Node visitArithmeticUnary(ArithmeticUnaryExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new ArithmeticUnaryExpression( - node.getLocation().get(), - node.getSign(), - visitAndCast(node.getValue(), context)); - } - return new ArithmeticUnaryExpression(node.getSign(), visitAndCast(node.getValue(), context)); - } - - @Override - protected Node visitSearchedCaseExpression(SearchedCaseExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new SearchedCaseExpression( - node.getLocation().get(), - visitNodes(node.getWhenClauses(), context), - node.getDefaultValue().map(expression -> visitAndCast(expression, context))); - } - return new SearchedCaseExpression( - visitNodes(node.getWhenClauses(), context), - node.getDefaultValue().map(expression -> visitAndCast(expression, context))); - } - - @Override - protected Node visitLikePredicate(LikePredicate node, T context) - { - if (node.getLocation().isPresent()) { - return new LikePredicate( - node.getLocation().get(), - visitAndCast(node.getValue(), context), - visitAndCast(node.getPattern(), context), - node.getEscape().map(expression -> visitAndCast(expression, context))); - } - return new LikePredicate( - visitAndCast(node.getValue(), context), - visitAndCast(node.getPattern(), context), - node.getEscape().map(expression -> visitAndCast(expression, context))); - } - - @Override - protected Node visitIsNotNullPredicate(IsNotNullPredicate node, T context) - { - if (node.getLocation().isPresent()) { - return new IsNotNullPredicate( - node.getLocation().get(), - visitAndCast(node.getValue(), context)); - } - return new IsNotNullPredicate(visitAndCast(node.getValue(), context)); - } - - @Override - protected Node visitIsNullPredicate(IsNullPredicate node, T context) - { - if (node.getLocation().isPresent()) { - return new IsNullPredicate( - node.getLocation().get(), - visitAndCast(node.getValue(), context)); - } - return new IsNullPredicate(visitAndCast(node.getValue(), context)); - } - - @Override - protected Node visitArrayConstructor(ArrayConstructor node, T context) - { - if (node.getLocation().isPresent()) { - return new ArrayConstructor( - node.getLocation().get(), - visitNodes(node.getValues(), context)); - } - return new ArrayConstructor(visitNodes(node.getValues(), context)); - } - - @Override - protected Node visitLogicalExpression(LogicalExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new LogicalExpression( - node.getLocation().get(), - node.getOperator(), - visitNodes(node.getTerms(), context)); - } - return new LogicalExpression( - node.getOperator(), - visitNodes(node.getTerms(), context)); - } - - @Override - protected Node visitSubscriptExpression(SubscriptExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new SubscriptExpression( - node.getLocation().get(), - visitAndCast(node.getBase(), context), - visitAndCast(node.getIndex(), context)); - } - return new SubscriptExpression(visitAndCast(node.getBase(), context), visitAndCast(node.getIndex(), context)); - } - - @Override - protected Node visitLongLiteral(LongLiteral node, T context) - { - return super.visitLongLiteral(node, context); - } - - @Override - protected Node visitParameter(Parameter node, T context) - { - return super.visitParameter(node, context); - } - - @Override - protected Node visitRow(Row node, T context) - { - if (node.getLocation().isPresent()) { - return new Row( - node.getLocation().get(), - visitNodes(node.getItems(), context)); - } - return new Row(visitNodes(node.getItems(), context)); - } - - @Override - protected Node visitTryExpression(TryExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new TryExpression( - node.getLocation().get(), - visitAndCast(node.getInnerExpression(), context)); - } - return new TryExpression(visitAndCast(node.getInnerExpression(), context)); - } - - @Override - protected Node visitCast(Cast node, T context) - { - if (node.getLocation().isPresent()) { - return new Cast( - node.getLocation().get(), - visitAndCast(node.getExpression(), context), - visitAndCast(node.getType(), context), - node.isSafe(), - node.isTypeOnly()); - } - return new Cast( - visitAndCast(node.getExpression(), context), - visitAndCast(node.getType(), context), - node.isSafe(), - node.isTypeOnly()); - } - - @Override - protected Node visitFieldReference(FieldReference node, T context) - { - return super.visitFieldReference(node, context); - } - - @Override - protected Node visitQuantifiedComparisonExpression(QuantifiedComparisonExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new QuantifiedComparisonExpression( - node.getLocation().get(), - node.getOperator(), - node.getQuantifier(), - visitAndCast(node.getValue(), context), - visitAndCast(node.getSubquery(), context)); - } - return new QuantifiedComparisonExpression( - node.getOperator(), - node.getQuantifier(), - visitAndCast(node.getValue(), context), - visitAndCast(node.getSubquery(), context)); - } - - @Override - protected Node visitLambdaArgumentDeclaration(LambdaArgumentDeclaration node, T context) - { - return super.visitLambdaArgumentDeclaration(node, context); - } - - @Override - protected Node visitBindExpression(BindExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new BindExpression( - node.getLocation().get(), - visitNodes(node.getValues(), context), - visitAndCast(node.getFunction(), context)); - } - return new BindExpression(visitNodes(node.getValues(), context), visitAndCast(node.getFunction(), context)); - } - - @Override - protected Node visitDataType(DataType node, T context) - { - return super.visitDataType(node, context); - } - - @Override - protected Node visitRowDataType(RowDataType node, T context) - { - return super.visitRowDataType(node, context); - } - - @Override - protected Node visitGenericDataType(GenericDataType node, T context) - { - return super.visitGenericDataType(node, context); - } - - @Override - protected Node visitRowField(RowDataType.Field node, T context) - { - return super.visitRowField(node, context); - } - - @Override - protected Node visitDataTypeParameter(DataTypeParameter node, T context) - { - return super.visitDataTypeParameter(node, context); - } - - @Override - protected Node visitNumericTypeParameter(NumericParameter node, T context) - { - return super.visitNumericTypeParameter(node, context); - } - - @Override - protected Node visitTypeParameter(TypeParameter node, T context) - { - return super.visitTypeParameter(node, context); - } - - @Override - protected Node visitIntervalDataType(IntervalDayTimeDataType node, T context) - { - return super.visitIntervalDataType(node, context); - } - - @Override - protected Node visitDateTimeType(DateTimeDataType node, T context) - { - return super.visitDateTimeType(node, context); - } - - @Override - protected Node visitInPredicate(InPredicate node, T context) - { - if (node.getLocation().isPresent()) { - return new InPredicate( - node.getLocation().get(), - visitAndCast(node.getValue(), context), - visitAndCast(node.getValueList(), context)); - } - return new InPredicate( - visitAndCast(node.getValue(), context), - visitAndCast(node.getValueList(), context)); - } - - @Override - protected Node visitComparisonExpression(ComparisonExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new ComparisonExpression( - node.getLocation().get(), - node.getOperator(), - visitAndCast(node.getLeft(), context), - visitAndCast(node.getRight(), context)); - } - return new ComparisonExpression( - node.getOperator(), - visitAndCast(node.getLeft(), context), - visitAndCast(node.getRight(), context)); - } - - @Override - protected Node visitExists(ExistsPredicate node, T context) - { - if (node.getLocation().isPresent()) { - return new ExistsPredicate( - node.getLocation().get(), - visitAndCast(node.getSubquery(), context)); - } - return new ExistsPredicate(visitAndCast(node.getSubquery(), context)); - } - - @Override - protected Node visitNotExpression(NotExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new NotExpression( - node.getLocation().get(), - visitAndCast(node.getValue(), context)); - } - return new NotExpression(visitAndCast(node.getValue(), context)); - } - - @Override - protected Node visitArithmeticBinary(ArithmeticBinaryExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new ArithmeticBinaryExpression( - node.getLocation().get(), - node.getOperator(), - visitAndCast(node.getLeft(), context), - visitAndCast(node.getRight(), context)); - } - return new ArithmeticBinaryExpression( - node.getOperator(), - visitAndCast(node.getLeft(), context), - visitAndCast(node.getRight(), context)); - } - - @Override - protected Node visitBetweenPredicate(BetweenPredicate node, T context) - { - if (node.getLocation().isPresent()) { - return new BetweenPredicate( - node.getLocation().get(), - visitAndCast(node.getValue(), context), - visitAndCast(node.getMin(), context), - visitAndCast(node.getMax(), context)); - } - return new BetweenPredicate( - visitAndCast(node.getValue(), context), - visitAndCast(node.getMin(), context), - visitAndCast(node.getMax(), context)); - } - - @Override - protected Node visitFunctionCall(FunctionCall node, T context) - { - return new FunctionCall( - node.getLocation(), - node.getName(), - node.getWindow().map(expression -> visitAndCast(expression, context)), - node.getFilter().map(expression -> visitAndCast(expression, context)), - node.getOrderBy().map(expression -> visitAndCast(expression, context)), - node.isDistinct(), - node.getNullTreatment(), - Optional.empty(), - visitNodes(node.getArguments(), context)); - } - - @Override - protected Node visitSubqueryExpression(SubqueryExpression node, T context) - { - if (node.getLocation().isPresent()) { - return new SubqueryExpression( - node.getLocation().get(), - visitAndCast(node.getQuery(), context)); - } - return new SubqueryExpression(visitAndCast(node.getQuery(), context)); - } - - @Override - protected Node visitDereferenceExpression(DereferenceExpression node, T context) - { - return new DereferenceExpression( - node.getLocation(), - visitAndCast(node.getBase(), context), - node.getField()); - } - - protected S visitAndCast(S node, T context) - { - return (S) process(node, context); - } - - protected S visitAndCast(S window, T context) - { - Node node = null; - if (window instanceof WindowSpecification) { - node = (WindowSpecification) window; - } - else if (window instanceof WindowReference) { - node = (WindowReference) window; - } - return (S) process(node, context); - } - - @SuppressWarnings("unchecked") - protected List visitNodes(List nodes, T context) - { - return nodes.stream() - .map(node -> (S) process(node, context)) - .collect(toList()); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/BaseTreeRewriter.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/BaseTreeRewriter.java deleted file mode 100644 index 6e677cb94..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/BaseTreeRewriter.java +++ /dev/null @@ -1,1197 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.AddColumn; -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.Analyze; -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.AtTimeZone; -import io.trino.sql.tree.Call; -import io.trino.sql.tree.CallArgument; -import io.trino.sql.tree.ColumnDefinition; -import io.trino.sql.tree.Comment; -import io.trino.sql.tree.Commit; -import io.trino.sql.tree.CreateRole; -import io.trino.sql.tree.CreateSchema; -import io.trino.sql.tree.CreateTable; -import io.trino.sql.tree.CreateTableAsSelect; -import io.trino.sql.tree.CreateView; -import io.trino.sql.tree.Cube; -import io.trino.sql.tree.CurrentPath; -import io.trino.sql.tree.CurrentTime; -import io.trino.sql.tree.CurrentUser; -import io.trino.sql.tree.Deallocate; -import io.trino.sql.tree.Delete; -import io.trino.sql.tree.DescribeInput; -import io.trino.sql.tree.DescribeOutput; -import io.trino.sql.tree.DropColumn; -import io.trino.sql.tree.DropRole; -import io.trino.sql.tree.DropSchema; -import io.trino.sql.tree.DropTable; -import io.trino.sql.tree.DropView; -import io.trino.sql.tree.Except; -import io.trino.sql.tree.Execute; -import io.trino.sql.tree.Explain; -import io.trino.sql.tree.ExplainOption; -import io.trino.sql.tree.Extract; -import io.trino.sql.tree.FetchFirst; -import io.trino.sql.tree.Format; -import io.trino.sql.tree.FrameBound; -import io.trino.sql.tree.FunctionRelation; -import io.trino.sql.tree.GenericLiteral; -import io.trino.sql.tree.Grant; -import io.trino.sql.tree.GrantRoles; -import io.trino.sql.tree.GroupBy; -import io.trino.sql.tree.GroupingElement; -import io.trino.sql.tree.GroupingOperation; -import io.trino.sql.tree.GroupingSets; -import io.trino.sql.tree.Insert; -import io.trino.sql.tree.Intersect; -import io.trino.sql.tree.Isolation; -import io.trino.sql.tree.Join; -import io.trino.sql.tree.JoinCriteria; -import io.trino.sql.tree.JoinOn; -import io.trino.sql.tree.Lateral; -import io.trino.sql.tree.LikeClause; -import io.trino.sql.tree.Limit; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.Offset; -import io.trino.sql.tree.OrderBy; -import io.trino.sql.tree.PathElement; -import io.trino.sql.tree.PathSpecification; -import io.trino.sql.tree.Prepare; -import io.trino.sql.tree.Property; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.QueryBody; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.Relation; -import io.trino.sql.tree.RenameColumn; -import io.trino.sql.tree.RenameSchema; -import io.trino.sql.tree.RenameTable; -import io.trino.sql.tree.ResetSession; -import io.trino.sql.tree.Revoke; -import io.trino.sql.tree.RevokeRoles; -import io.trino.sql.tree.Rollback; -import io.trino.sql.tree.Rollup; -import io.trino.sql.tree.SampledRelation; -import io.trino.sql.tree.Select; -import io.trino.sql.tree.SelectItem; -import io.trino.sql.tree.SetOperation; -import io.trino.sql.tree.SetPath; -import io.trino.sql.tree.SetRole; -import io.trino.sql.tree.SetSession; -import io.trino.sql.tree.ShowCatalogs; -import io.trino.sql.tree.ShowColumns; -import io.trino.sql.tree.ShowCreate; -import io.trino.sql.tree.ShowFunctions; -import io.trino.sql.tree.ShowGrants; -import io.trino.sql.tree.ShowRoleGrants; -import io.trino.sql.tree.ShowRoles; -import io.trino.sql.tree.ShowSchemas; -import io.trino.sql.tree.ShowSession; -import io.trino.sql.tree.ShowStats; -import io.trino.sql.tree.ShowTables; -import io.trino.sql.tree.SimpleGroupBy; -import io.trino.sql.tree.SingleColumn; -import io.trino.sql.tree.SortItem; -import io.trino.sql.tree.StartTransaction; -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.SymbolReference; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableElement; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.TimeLiteral; -import io.trino.sql.tree.TransactionAccessMode; -import io.trino.sql.tree.TransactionMode; -import io.trino.sql.tree.Union; -import io.trino.sql.tree.Unnest; -import io.trino.sql.tree.Use; -import io.trino.sql.tree.Values; -import io.trino.sql.tree.Window; -import io.trino.sql.tree.WindowFrame; -import io.trino.sql.tree.WindowReference; -import io.trino.sql.tree.WindowSpecification; -import io.trino.sql.tree.With; -import io.trino.sql.tree.WithQuery; - -import java.util.List; -import java.util.Optional; - -import static java.util.stream.Collectors.toList; - -/** - * Base class for tree rewriter. It will traverse all query nodes excludes all expressions, literals and data type parameters. - */ -public class BaseTreeRewriter - extends AstVisitor -{ - @Override - protected Node visitNode(Node node, T context) - { - return node; - } - - @Override - protected Node visitCreateTableAsSelect(CreateTableAsSelect node, T context) - { - if (node.getLocation().isPresent()) { - return new CreateTableAsSelect( - node.getLocation().get(), - node.getName(), - visitAndCast(node.getQuery(), context), - node.isNotExists(), - node.getProperties(), - node.isWithData(), - node.getColumnAliases(), - node.getComment()); - } - return new CreateTableAsSelect( - node.getName(), - visitAndCast(node.getQuery(), context), - node.isNotExists(), - node.getProperties(), - node.isWithData(), - node.getColumnAliases(), - node.getComment()); - } - - @Override - protected Node visitQuery(Query node, T context) - { - if (node.getLocation().isPresent()) { - return new Query( - node.getLocation().get(), - node.getWith().map(expression -> visitAndCast(expression, context)), - visitAndCast(node.getQueryBody(), context), - node.getOrderBy().map(expression -> visitAndCast(expression, context)), - node.getOffset(), - node.getLimit()); - } - return new Query( - node.getWith().map(expression -> visitAndCast(expression, context)), - visitAndCast(node.getQueryBody(), context), - node.getOrderBy().map(expression -> visitAndCast(expression, context)), - node.getOffset(), - node.getLimit()); - } - - @Override - protected Node visitCurrentTime(CurrentTime node, T context) - { - return super.visitCurrentTime(node, context); - } - - @Override - protected Node visitExtract(Extract node, T context) - { - if (node.getLocation().isPresent()) { - new Extract( - node.getLocation().get(), - visitAndCast(node.getExpression(), context), - node.getField()); - } - return new Extract(visitAndCast(node.getExpression(), context), node.getField()); - } - - @Override - protected Node visitStatement(Statement node, T context) - { - return super.visitStatement(node, context); - } - - @Override - protected Node visitPrepare(Prepare node, T context) - { - if (node.getLocation().isPresent()) { - return new Prepare( - node.getLocation().get(), - node.getName(), - visitAndCast(node.getStatement(), context)); - } - return new Prepare( - node.getName(), - visitAndCast(node.getStatement(), context)); - } - - @Override - protected Node visitDeallocate(Deallocate node, T context) - { - return super.visitDeallocate(node, context); - } - - @Override - protected Node visitExecute(Execute node, T context) - { - if (node.getLocation().isPresent()) { - return new Execute( - node.getLocation().get(), - node.getName(), - visitNodes(node.getParameters(), context)); - } - return new Execute(node.getName(), visitNodes(node.getParameters(), context)); - } - - @Override - protected Node visitDescribeOutput(DescribeOutput node, T context) - { - return super.visitDescribeOutput(node, context); - } - - @Override - protected Node visitDescribeInput(DescribeInput node, T context) - { - return super.visitDescribeInput(node, context); - } - - @Override - protected Node visitExplain(Explain node, T context) - { - if (node.getLocation().isPresent()) { - return new Explain( - node.getLocation().get(), - visitAndCast(node.getStatement(), context), - node.getOptions()); - } - return new Explain( - visitAndCast(node.getStatement(), context), - node.getOptions()); - } - - @Override - protected Node visitShowTables(ShowTables node, T context) - { - if (node.getLocation().isPresent()) { - return new ShowTables( - node.getLocation().get(), - node.getSchema(), - node.getLikePattern(), - node.getEscape()); - } - return new ShowTables( - node.getSchema(), - node.getLikePattern(), - node.getEscape()); - } - - @Override - protected Node visitShowSchemas(ShowSchemas node, T context) - { - if (node.getLocation().isPresent()) { - return new ShowSchemas( - node.getLocation().get(), - node.getCatalog(), - node.getLikePattern(), - node.getEscape()); - } - return new ShowSchemas( - node.getCatalog(), - node.getLikePattern(), - node.getEscape()); - } - - @Override - protected Node visitShowCatalogs(ShowCatalogs node, T context) - { - return super.visitShowCatalogs(node, context); - } - - @Override - protected Node visitShowStats(ShowStats node, T context) - { - if (node.getLocation().isPresent()) { - return new ShowStats( - node.getLocation(), - visitAndCast(node.getRelation(), context)); - } - return new ShowStats(visitAndCast(node.getRelation(), context)); - } - - @Override - protected Node visitShowCreate(ShowCreate node, T context) - { - if (node.getType() == ShowCreate.Type.TABLE) { - Table table = (Table) visitTable(new Table(node.getName()), context); - if (node.getLocation().isPresent()) { - return new ShowCreate( - node.getLocation().get(), - node.getType(), - table.getName()); - } - return new ShowCreate( - node.getType(), - table.getName()); - } - return super.visitShowCreate(node, context); - } - - @Override - protected Node visitShowFunctions(ShowFunctions node, T context) - { - return super.visitShowFunctions(node, context); - } - - @Override - protected Node visitUse(Use node, T context) - { - return super.visitUse(node, context); - } - - @Override - protected Node visitShowSession(ShowSession node, T context) - { - return super.visitShowSession(node, context); - } - - @Override - protected Node visitSetSession(SetSession node, T context) - { - return super.visitSetSession(node, context); - } - - @Override - protected Node visitResetSession(ResetSession node, T context) - { - return super.visitResetSession(node, context); - } - - @Override - protected Node visitGenericLiteral(GenericLiteral node, T context) - { - return super.visitGenericLiteral(node, context); - } - - @Override - protected Node visitTimeLiteral(TimeLiteral node, T context) - { - return super.visitTimeLiteral(node, context); - } - - @Override - protected Node visitExplainOption(ExplainOption node, T context) - { - return super.visitExplainOption(node, context); - } - - @Override - protected Node visitRelation(Relation node, T context) - { - return super.visitRelation(node, context); - } - - @Override - protected Node visitQueryBody(QueryBody node, T context) - { - return super.visitQueryBody(node, context); - } - - @Override - protected Node visitOffset(Offset node, T context) - { - return super.visitOffset(node, context); - } - - @Override - protected Node visitFetchFirst(FetchFirst node, T context) - { - return super.visitFetchFirst(node, context); - } - - @Override - protected Node visitLimit(Limit node, T context) - { - return super.visitLimit(node, context); - } - - @Override - protected Node visitSetOperation(SetOperation node, T context) - { - return super.visitSetOperation(node, context); - } - - @Override - protected Node visitIntersect(Intersect node, T context) - { - if (node.getLocation().isPresent()) { - return new Intersect( - node.getLocation().get(), - visitNodes(node.getRelations(), context), - node.isDistinct()); - } - return new Intersect(visitNodes(node.getRelations(), context), node.isDistinct()); - } - - @Override - protected Node visitExcept(Except node, T context) - { - if (node.getLocation().isPresent()) { - return new Except( - node.getLocation().get(), - visitAndCast(node.getLeft(), context), - visitAndCast(node.getRight(), context), - node.isDistinct()); - } - return new Except( - visitAndCast(node.getLeft(), context), - visitAndCast(node.getRight(), context), - node.isDistinct()); - } - - @Override - protected Node visitSelectItem(SelectItem node, T context) - { - return super.visitSelectItem(node, context); - } - - @Override - protected Node visitAllColumns(AllColumns node, T context) - { - return super.visitAllColumns(node, context); - } - - @Override - protected Node visitUnnest(Unnest node, T context) - { - if (node.getLocation().isPresent()) { - return new Unnest( - node.getLocation().get(), - visitNodes(node.getExpressions(), context), - node.isWithOrdinality()); - } - return new Unnest(visitNodes(node.getExpressions(), context), node.isWithOrdinality()); - } - - @Override - protected Node visitFunctionRelation(FunctionRelation node, T context) - { - return new FunctionRelation( - node.getLocation().orElse(null), - node.getName(), - node.getArguments()); - } - - @Override - protected Node visitLateral(Lateral node, T context) - { - if (node.getLocation().isPresent()) { - return new Lateral( - node.getLocation().get(), - visitAndCast(node.getQuery(), context)); - } - return new Lateral(visitAndCast(node.getQuery(), context)); - } - - @Override - protected Node visitValues(Values node, T context) - { - if (node.getLocation().isPresent()) { - return new Values( - node.getLocation().get(), - visitNodes(node.getRows(), context)); - } - return new Values(visitNodes(node.getRows(), context)); - } - - @Override - protected Node visitSampledRelation(SampledRelation node, T context) - { - if (node.getLocation().isPresent()) { - return new SampledRelation( - node.getLocation().get(), - visitAndCast(node.getRelation(), context), - node.getType(), - visitAndCast(node.getSamplePercentage(), context)); - } - return new SampledRelation( - visitAndCast(node.getRelation(), context), - node.getType(), - visitAndCast(node.getSamplePercentage(), context)); - } - - @Override - protected Node visitWindowSpecification(WindowSpecification node, T context) - { - if (node.getLocation().isPresent()) { - return new WindowSpecification( - node.getLocation().get(), - node.getExistingWindowName(), - visitNodes(node.getPartitionBy(), context), - node.getOrderBy(), - node.getFrame().map(expression -> visitAndCast(expression, context))); - } - return new WindowSpecification( - node.getExistingWindowName(), - visitNodes(node.getPartitionBy(), context), - node.getOrderBy(), - node.getFrame().map(expression -> visitAndCast(expression, context))); - } - - @Override - protected Node visitWindowFrame(WindowFrame node, T context) - { - if (node.getLocation().isPresent()) { - return new WindowFrame( - node.getLocation().get(), - node.getType(), - visitAndCast(node.getStart(), context), - node.getEnd().map(expression -> visitAndCast(expression, context)), - node.getMeasures(), - node.getAfterMatchSkipTo(), - node.getPatternSearchMode(), - node.getPattern(), - node.getSubsets(), - node.getVariableDefinitions()); - } - return new WindowFrame( - node.getType(), - visitAndCast(node.getStart(), context), - node.getEnd().map(expression -> visitAndCast(expression, context)), - node.getMeasures(), - node.getAfterMatchSkipTo(), - node.getPatternSearchMode(), - node.getPattern(), - node.getSubsets(), - node.getVariableDefinitions()); - } - - @Override - protected Node visitFrameBound(FrameBound node, T context) - { - if (node.getLocation().isPresent()) { - return new FrameBound( - node.getLocation().get(), - node.getType(), - node.getValue().map(expression -> visitAndCast(expression, context)).orElse(null)); - } - return new FrameBound( - node.getType(), - node.getValue().map(expression -> visitAndCast(expression, context)).orElse(null)); - } - - @Override - protected Node visitCallArgument(CallArgument node, T context) - { - return new CallArgument( - node.getLocation(), - node.getName(), - visitAndCast(node.getValue(), context)); - } - - @Override - protected Node visitTableElement(TableElement node, T context) - { - return super.visitTableElement(node, context); - } - - @Override - protected Node visitColumnDefinition(ColumnDefinition node, T context) - { - return super.visitColumnDefinition(node, context); - } - - @Override - protected Node visitLikeClause(LikeClause node, T context) - { - return super.visitLikeClause(node, context); - } - - @Override - protected Node visitCreateSchema(CreateSchema node, T context) - { - return super.visitCreateSchema(node, context); - } - - @Override - protected Node visitDropSchema(DropSchema node, T context) - { - return super.visitDropSchema(node, context); - } - - @Override - protected Node visitRenameSchema(RenameSchema node, T context) - { - return super.visitRenameSchema(node, context); - } - - @Override - protected Node visitCreateTable(CreateTable node, T context) - { - return super.visitCreateTable(node, context); - } - - @Override - protected Node visitProperty(Property node, T context) - { - return super.visitProperty(node, context); - } - - @Override - protected Node visitDropTable(DropTable node, T context) - { - return super.visitDropTable(node, context); - } - - @Override - protected Node visitRenameTable(RenameTable node, T context) - { - return super.visitRenameTable(node, context); - } - - @Override - protected Node visitComment(Comment node, T context) - { - return super.visitComment(node, context); - } - - @Override - protected Node visitRenameColumn(RenameColumn node, T context) - { - return super.visitRenameColumn(node, context); - } - - @Override - protected Node visitDropColumn(DropColumn node, T context) - { - return super.visitDropColumn(node, context); - } - - @Override - protected Node visitAddColumn(AddColumn node, T context) - { - return super.visitAddColumn(node, context); - } - - @Override - protected Node visitAnalyze(Analyze node, T context) - { - return super.visitAnalyze(node, context); - } - - @Override - protected Node visitCreateView(CreateView node, T context) - { - if (node.getLocation().isPresent()) { - return new CreateView( - node.getLocation().get(), - node.getName(), - visitAndCast(node.getQuery(), context), - node.isReplace(), - node.getComment(), - node.getSecurity()); - } - return new CreateView( - node.getName(), - visitAndCast(node.getQuery(), context), - node.isReplace(), - node.getComment(), - node.getSecurity()); - } - - @Override - protected Node visitDropView(DropView node, T context) - { - return super.visitDropView(node, context); - } - - @Override - protected Node visitInsert(Insert node, T context) - { - return super.visitInsert(node, context); - } - - @Override - protected Node visitCall(Call node, T context) - { - if (node.getLocation().isPresent()) { - return new Call( - node.getLocation().get(), - node.getName(), - visitNodes(node.getArguments(), context)); - } - return new Call(node.getName(), visitNodes(node.getArguments(), context)); - } - - @Override - protected Node visitDelete(Delete node, T context) - { - if (node.getLocation().isPresent()) { - return new Delete( - node.getLocation().get(), - visitAndCast(node.getTable(), context), - node.getWhere().map(expression -> visitAndCast(expression, context))); - } - return new Delete( - visitAndCast(node.getTable(), context), - node.getWhere().map(expression -> visitAndCast(expression, context))); - } - - @Override - protected Node visitStartTransaction(StartTransaction node, T context) - { - return super.visitStartTransaction(node, context); - } - - @Override - protected Node visitCreateRole(CreateRole node, T context) - { - return super.visitCreateRole(node, context); - } - - @Override - protected Node visitDropRole(DropRole node, T context) - { - return super.visitDropRole(node, context); - } - - @Override - protected Node visitGrantRoles(GrantRoles node, T context) - { - return super.visitGrantRoles(node, context); - } - - @Override - protected Node visitRevokeRoles(RevokeRoles node, T context) - { - return super.visitRevokeRoles(node, context); - } - - @Override - protected Node visitSetRole(SetRole node, T context) - { - return super.visitSetRole(node, context); - } - - @Override - protected Node visitGrant(Grant node, T context) - { - return super.visitGrant(node, context); - } - - @Override - protected Node visitRevoke(Revoke node, T context) - { - return super.visitRevoke(node, context); - } - - @Override - protected Node visitShowGrants(ShowGrants node, T context) - { - return super.visitShowGrants(node, context); - } - - @Override - protected Node visitShowRoles(ShowRoles node, T context) - { - return super.visitShowRoles(node, context); - } - - @Override - protected Node visitShowRoleGrants(ShowRoleGrants node, T context) - { - return super.visitShowRoleGrants(node, context); - } - - @Override - protected Node visitSetPath(SetPath node, T context) - { - return super.visitSetPath(node, context); - } - - @Override - protected Node visitPathSpecification(PathSpecification node, T context) - { - return super.visitPathSpecification(node, context); - } - - @Override - protected Node visitPathElement(PathElement node, T context) - { - return super.visitPathElement(node, context); - } - - @Override - protected Node visitTransactionMode(TransactionMode node, T context) - { - return super.visitTransactionMode(node, context); - } - - @Override - protected Node visitIsolationLevel(Isolation node, T context) - { - return super.visitIsolationLevel(node, context); - } - - @Override - protected Node visitTransactionAccessMode(TransactionAccessMode node, T context) - { - return super.visitTransactionAccessMode(node, context); - } - - @Override - protected Node visitCommit(Commit node, T context) - { - return super.visitCommit(node, context); - } - - @Override - protected Node visitRollback(Rollback node, T context) - { - return super.visitRollback(node, context); - } - - @Override - protected Node visitAtTimeZone(AtTimeZone node, T context) - { - return super.visitAtTimeZone(node, context); - } - - @Override - protected Node visitGroupingElement(GroupingElement node, T context) - { - return super.visitGroupingElement(node, context); - } - - @Override - protected Node visitSymbolReference(SymbolReference node, T context) - { - return super.visitSymbolReference(node, context); - } - - @Override - protected Node visitGroupingOperation(GroupingOperation node, T context) - { - return super.visitGroupingOperation(node, context); - } - - @Override - protected Node visitCurrentUser(CurrentUser node, T context) - { - return super.visitCurrentUser(node, context); - } - - @Override - protected Node visitCurrentPath(CurrentPath node, T context) - { - return super.visitCurrentPath(node, context); - } - - @Override - protected Node visitFormat(Format node, T context) - { - if (node.getLocation().isPresent()) { - return new Format( - node.getLocation().get(), - visitNodes(node.getArguments(), context)); - } - return new Format(visitNodes(node.getArguments(), context)); - } - - @Override - protected Node visitQuerySpecification(QuerySpecification node, T context) - { - // Relations should be visited first for alias. - Optional from = node.getFrom().map(expression -> visitAndCast(expression, context)); - - if (node.getLocation().isPresent()) { - return new QuerySpecification( - node.getLocation().get(), - visitAndCast(node.getSelect(), context), - from, - node.getWhere().map(expression -> visitAndCast(expression, context)), - node.getGroupBy().map(expression -> visitAndCast(expression, context)), - node.getHaving().map(expression -> visitAndCast(expression, context)), - visitNodes(node.getWindows(), context), - node.getOrderBy().map(expression -> visitAndCast(expression, context)), - node.getOffset(), - node.getLimit()); - } - return new QuerySpecification( - visitAndCast(node.getSelect(), context), - from, - node.getWhere().map(expression -> visitAndCast(expression, context)), - node.getGroupBy().map(expression -> visitAndCast(expression, context)), - node.getHaving().map(expression -> visitAndCast(expression, context)), - visitNodes(node.getWindows(), context), - node.getOrderBy().map(expression -> visitAndCast(expression, context)), - node.getOffset(), - node.getLimit()); - } - - @Override - protected Node visitShowColumns(ShowColumns node, T context) - { - Table table = (Table) visitTable(new Table(node.getTable()), context); - if (node.getLocation().isPresent()) { - return new ShowColumns( - node.getLocation().get(), - table.getName(), - Optional.empty(), - Optional.empty()); - } - return new ShowColumns(table.getName(), Optional.empty(), Optional.empty()); - } - - @Override - protected Node visitJoin(Join node, T context) - { - if (node.getLocation().isPresent()) { - return new Join( - node.getLocation().get(), - node.getType(), - visitAndCast(node.getLeft(), context), - visitAndCast(node.getRight(), context), - node.getCriteria().map(joinCriteria -> visitJoinCriteria(joinCriteria, context))); - } - return new Join( - node.getType(), - visitAndCast(node.getLeft(), context), - visitAndCast(node.getRight(), context), - node.getCriteria().map(joinCriteria -> visitJoinCriteria(joinCriteria, context))); - } - - protected JoinCriteria visitJoinCriteria(JoinCriteria joinCriteria, T context) - { - if (joinCriteria instanceof JoinOn) { - JoinOn joinOn = (JoinOn) joinCriteria; - return new JoinOn(visitAndCast(joinOn.getExpression(), context)); - } - - return joinCriteria; - } - - @Override - protected Node visitAliasedRelation(AliasedRelation node, T context) - { - if (node.getLocation().isPresent()) { - return new AliasedRelation( - node.getLocation().get(), - visitAndCast(node.getRelation(), context), - node.getAlias(), - node.getColumnNames()); - } - return new AliasedRelation( - visitAndCast(node.getRelation(), context), - node.getAlias(), - node.getColumnNames()); - } - - @Override - protected Node visitTableSubquery(TableSubquery node, T context) - { - if (node.getLocation().isPresent()) { - return new TableSubquery( - node.getLocation().get(), - visitAndCast(node.getQuery(), context)); - } - return new TableSubquery(visitAndCast(node.getQuery(), context)); - } - - @Override - protected Node visitWith(With node, T context) - { - if (node.getLocation().isPresent()) { - return new With( - node.getLocation().get(), - node.isRecursive(), - visitNodes(node.getQueries(), context)); - } - return new With( - node.isRecursive(), - visitNodes(node.getQueries(), context)); - } - - @Override - protected Node visitWithQuery(WithQuery node, T context) - { - if (node.getLocation().isPresent()) { - return new WithQuery( - node.getLocation().get(), - node.getName(), - visitAndCast(node.getQuery(), context), - node.getColumnNames()); - } - return new WithQuery( - node.getName(), - visitAndCast(node.getQuery(), context), - node.getColumnNames()); - } - - @Override - protected Node visitUnion(Union node, T context) - { - if (node.getLocation().isPresent()) { - return new Union( - node.getLocation().get(), - visitNodes(node.getRelations(), context), - node.isDistinct()); - } - return new Union( - visitNodes(node.getRelations(), context), - node.isDistinct()); - } - - @Override - protected Node visitSelect(Select node, T context) - { - if (node.getLocation().isPresent()) { - return new Select( - node.getLocation().get(), - node.isDistinct(), - visitNodes(node.getSelectItems(), context)); - } - return new Select( - node.isDistinct(), - visitNodes(node.getSelectItems(), context)); - } - - @Override - protected Node visitGroupBy(GroupBy node, T context) - { - if (node.getLocation().isPresent()) { - return new GroupBy( - node.getLocation().get(), - node.isDistinct(), - visitNodes(node.getGroupingElements(), context)); - } - return new GroupBy(node.isDistinct(), visitNodes(node.getGroupingElements(), context)); - } - - @Override - protected Node visitCube(Cube node, T context) - { - if (node.getLocation().isPresent()) { - return new Cube( - node.getLocation().get(), - visitNodes(node.getExpressions(), context)); - } - return new Cube(visitNodes(node.getExpressions(), context)); - } - - @Override - protected Node visitGroupingSets(GroupingSets node, T context) - { - if (node.getLocation().isPresent()) { - return new GroupingSets( - node.getLocation().get(), - node.getSets().stream() - .map(expressions -> visitNodes(expressions, context)) - .collect(toList())); - } - return new GroupingSets( - node.getSets().stream() - .map(expressions -> visitNodes(expressions, context)) - .collect(toList())); - } - - @Override - protected Node visitSimpleGroupBy(SimpleGroupBy node, T context) - { - if (node.getLocation().isPresent()) { - return new SimpleGroupBy( - node.getLocation().get(), - visitNodes(node.getExpressions(), context)); - } - return new SimpleGroupBy(visitNodes(node.getExpressions(), context)); - } - - @Override - protected Node visitRollup(Rollup node, T context) - { - if (node.getLocation().isPresent()) { - return new Rollup( - node.getLocation().get(), - visitNodes(node.getExpressions(), context)); - } - return new Rollup(visitNodes(node.getExpressions(), context)); - } - - @Override - protected Node visitOrderBy(OrderBy node, T context) - { - if (node.getLocation().isPresent()) { - return new OrderBy( - node.getLocation().get(), - visitNodes(node.getSortItems(), context)); - } - return new OrderBy(visitNodes(node.getSortItems(), context)); - } - - @Override - protected Node visitSortItem(SortItem node, T context) - { - if (node.getLocation().isPresent()) { - return new SortItem( - node.getLocation().get(), - visitAndCast(node.getSortKey(), context), - node.getOrdering(), - node.getNullOrdering()); - } - return new SortItem( - visitAndCast(node.getSortKey(), context), - node.getOrdering(), - node.getNullOrdering()); - } - - @Override - protected Node visitSingleColumn(SingleColumn node, T context) - { - if (node.getLocation().isPresent()) { - return new SingleColumn( - node.getLocation().get(), - visitAndCast(node.getExpression(), context), - node.getAlias()); - } - return new SingleColumn( - visitAndCast(node.getExpression(), context), - node.getAlias()); - } - - @Override - protected Node visitTable(Table node, T context) - { - if (node.getLocation().isPresent()) { - return new Table( - node.getLocation().get(), - node.getName()); - } - return new Table(node.getName()); - } - - protected S visitAndCast(S node, T context) - { - return (S) process(node, context); - } - - protected S visitAndCast(S window, T context) - { - Node node = null; - if (window instanceof WindowSpecification) { - node = (WindowSpecification) window; - } - else if (window instanceof WindowReference) { - node = (WindowReference) window; - } - return (S) process(node, context); - } - - @SuppressWarnings("unchecked") - protected List visitNodes(List nodes, T context) - { - return nodes.stream() - .map(node -> (S) process(node, context)) - .collect(toList()); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/CumulativeMetricInfo.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/CumulativeMetricInfo.java deleted file mode 100644 index 4e6091ebe..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/CumulativeMetricInfo.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Query; -import io.wren.base.WrenMDL; -import io.wren.base.dto.CumulativeMetric; - -import java.util.Set; - -import static java.util.Objects.requireNonNull; - -public class CumulativeMetricInfo - implements QueryDescriptor -{ - private final String name; - private final Set requiredObjects; - private final Query query; - - public static CumulativeMetricInfo get(CumulativeMetric metric, WrenMDL mdl) - { - return new CumulativeMetricInfo( - metric.getName(), - Set.of(metric.getBaseObject(), DateSpineInfo.NAME), - Utils.parseCumulativeMetricSql(metric, mdl)); - } - - private CumulativeMetricInfo(String name, Set requiredObjects, Query query) - { - this.name = requireNonNull(name); - this.requiredObjects = requireNonNull(requiredObjects); - this.query = requireNonNull(query); - } - - @Override - public String getName() - { - return name; - } - - @Override - public Set getRequiredObjects() - { - return requiredObjects; - } - - @Override - public Query getQuery() - { - return query; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/DateSpineInfo.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/DateSpineInfo.java deleted file mode 100644 index 89ebb081e..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/DateSpineInfo.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Query; -import io.wren.base.dto.DateSpine; - -import java.util.Set; - -import static io.wren.base.sqlrewrite.Utils.createDateSpineQuery; -import static java.util.Objects.requireNonNull; - -public class DateSpineInfo - implements QueryDescriptor -{ - public static final String NAME = "date_spine"; - - private final Query query; - - public static DateSpineInfo get(DateSpine dateSpine) - { - return new DateSpineInfo(dateSpine); - } - - private DateSpineInfo(DateSpine dateSpine) - { - this.query = createDateSpineQuery(requireNonNull(dateSpine)); - } - - @Override - public String getName() - { - return NAME; - } - - @Override - public Set getRequiredObjects() - { - return Set.of(); - } - - @Override - public Query getQuery() - { - return query; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/DummyInfo.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/DummyInfo.java deleted file mode 100644 index 19c2d082f..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/DummyInfo.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Query; - -import java.util.Set; - -import static java.util.Objects.requireNonNull; - -public class DummyInfo - implements QueryDescriptor -{ - private final String name; - - public DummyInfo(String name) - { - this.name = requireNonNull(name, "name is null"); - } - - @Override - public String getName() - { - return name; - } - - @Override - public Set getRequiredObjects() - { - return Set.of(); - } - - @Override - public Query getQuery() - { - return Utils.parseQuery("select 1"); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/EnumRewrite.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/EnumRewrite.java deleted file mode 100644 index a51a153a8..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/EnumRewrite.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.StringLiteral; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.dto.EnumDefinition; -import io.wren.base.dto.EnumValue; -import io.wren.base.sqlrewrite.analyzer.Analysis; - -import java.util.Optional; - -import static java.lang.String.format; - -public class EnumRewrite - implements WrenRule -{ - public static final EnumRewrite ENUM_REWRITE = new EnumRewrite(); - - private EnumRewrite() {} - - @Override - public Statement apply(Statement root, SessionContext sessionContext, AnalyzedMDL analyzedMDL) - { - return apply(root, sessionContext, null, analyzedMDL); - } - - @Override - public Statement apply(Statement root, SessionContext sessionContext, Analysis analysis, AnalyzedMDL analyzedMDL) - { - return (Statement) new Rewriter(analyzedMDL.getWrenMDL()).process(root); - } - - private static class Rewriter - extends BaseRewriter - { - private final WrenMDL wrenMDL; - - Rewriter(WrenMDL wrenMDL) - { - this.wrenMDL = wrenMDL; - } - - @Override - protected Node visitDereferenceExpression(DereferenceExpression node, Void context) - { - Expression newNode = rewriteEnumIfNeed(node); - if (newNode != node) { - return newNode; - } - return new DereferenceExpression(node.getLocation(), (Expression) process(node.getBase()), node.getField()); - } - - private Expression rewriteEnumIfNeed(DereferenceExpression node) - { - QualifiedName qualifiedName = DereferenceExpression.getQualifiedName(node); - if (qualifiedName == null || qualifiedName.getOriginalParts().size() != 2) { - return node; - } - - String enumName = qualifiedName.getOriginalParts().get(0).getValue(); - Optional enumDefinitionOptional = wrenMDL.getEnum(enumName); - if (enumDefinitionOptional.isEmpty()) { - return node; - } - - return enumDefinitionOptional.get().valueOf(qualifiedName.getOriginalParts().get(1).getValue()) - .map(EnumValue::getValue) - .map(StringLiteral::new) - .orElseThrow(() -> new IllegalArgumentException(format("Enum value '%s' not found in enum '%s'", qualifiedName.getParts().get(1), qualifiedName.getParts().get(0)))); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/GenerateViewRewrite.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/GenerateViewRewrite.java deleted file mode 100644 index f118378c0..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/GenerateViewRewrite.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.WithQuery; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.Utils; -import io.wren.base.sqlrewrite.analyzer.Analysis; -import io.wren.base.sqlrewrite.analyzer.StatementAnalyzer; -import org.jgrapht.graph.DirectedAcyclicGraph; -import org.jgrapht.graph.GraphCycleProhibitedException; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static io.wren.base.sqlrewrite.WithRewriter.getWithQuery; -import static java.util.stream.Collectors.toSet; - -public class GenerateViewRewrite - implements WrenRule -{ - public static final GenerateViewRewrite GENERATE_VIEW_REWRITE = new GenerateViewRewrite(); - - @Override - public Statement apply(Statement root, SessionContext sessionContext, AnalyzedMDL analyzedMDL) - { - Analysis analysis = new Analysis(root); - StatementAnalyzer.analyze(analysis, root, sessionContext, analyzedMDL.getWrenMDL()); - return apply(root, sessionContext, analysis, analyzedMDL); - } - - @Override - public Statement apply(Statement root, SessionContext sessionContext, Analysis analysis, AnalyzedMDL analyzedMDL) - { - Set viewDescriptors = analysis.getViews().stream().map(view -> ViewInfo.get(view, analyzedMDL, sessionContext)).collect(toSet()); - DirectedAcyclicGraph graph = new DirectedAcyclicGraph<>(Object.class); - Set requiredQueryDescriptors = new HashSet<>(); - viewDescriptors.forEach(viewDescriptor -> addSqlDescriptorToGraph(viewDescriptor, graph, analyzedMDL, requiredQueryDescriptors, sessionContext)); - - Map descriptorMap = new HashMap<>(); - viewDescriptors.forEach(queryDescriptor -> descriptorMap.put(queryDescriptor.getName(), queryDescriptor)); - requiredQueryDescriptors.forEach(queryDescriptor -> descriptorMap.put(queryDescriptor.getName(), queryDescriptor)); - - List withQueries = new ArrayList<>(); - graph.iterator().forEachRemaining(objectName -> { - QueryDescriptor queryDescriptor = descriptorMap.get(objectName); - Utils.checkArgument(queryDescriptor != null, objectName + " not found in query descriptors"); - withQueries.add(getWithQuery(queryDescriptor)); - }); - - return (Statement) new WithRewriter(withQueries).process(root); - } - - private static void addSqlDescriptorToGraph( - QueryDescriptor queryDescriptor, - DirectedAcyclicGraph graph, - AnalyzedMDL analyzedMDL, - Set queryDescriptors, - SessionContext sessionContext) - { - // add vertex - graph.addVertex(queryDescriptor.getName()); - Set requiredViews = queryDescriptor.getRequiredObjects().stream() - .filter(name -> analyzedMDL.getWrenMDL().getView(name).isPresent()).collect(toSet()); - requiredViews.forEach(graph::addVertex); - - //add edge - try { - requiredViews.forEach(name -> - graph.addEdge(name, queryDescriptor.getName())); - } - catch (GraphCycleProhibitedException ex) { - throw new IllegalArgumentException("found cycle in view", ex); - } - catch (IllegalArgumentException ex) { - throw new IllegalArgumentException("found issue in view", ex); - } - - // add required view to graph - requiredViews.forEach(name -> { - ViewInfo descriptor = (ViewInfo) QueryDescriptor.of(name, analyzedMDL, sessionContext); - queryDescriptors.add(descriptor); - addSqlDescriptorToGraph(descriptor, graph, analyzedMDL, queryDescriptors, sessionContext); - }); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/MetricRollupRewrite.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/MetricRollupRewrite.java deleted file mode 100644 index b0ade9150..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/MetricRollupRewrite.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.FunctionRelation; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NodeRef; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.TableSubquery; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.sqlrewrite.analyzer.Analysis; -import io.wren.base.sqlrewrite.analyzer.MetricRollupInfo; -import io.wren.base.sqlrewrite.analyzer.StatementAnalyzer; - -import java.util.List; - -import static io.wren.base.sqlrewrite.Utils.parseMetricRollupSql; - -public class MetricRollupRewrite - implements WrenRule -{ - public static final MetricRollupRewrite METRIC_ROLLUP_REWRITE = new MetricRollupRewrite(); - - @Override - public Statement apply(Statement root, SessionContext sessionContext, AnalyzedMDL analyzedMDL) - { - Analysis analysis = new Analysis(root); - StatementAnalyzer.analyze(analysis, root, sessionContext, analyzedMDL.getWrenMDL()); - return apply(root, sessionContext, analysis, analyzedMDL); - } - - @Override - public Statement apply(Statement root, SessionContext sessionContext, Analysis analysis, AnalyzedMDL analyzedMDL) - { - return (Statement) new Rewriter(analysis).process(root); - } - - private static class Rewriter - extends BaseRewriter - { - private final Analysis analysis; - - Rewriter(Analysis analysis) - { - this.analysis = analysis; - } - - @Override - protected Node visitFunctionRelation(FunctionRelation node, Void context) - { - if (analysis.getMetricRollups().containsKey(NodeRef.of(node))) { - MetricRollupInfo info = analysis.getMetricRollups().get(NodeRef.of(node)); - Query query = parseMetricRollupSql(info); - return new AliasedRelation(new TableSubquery(query), new Identifier(info.getMetric().getName()), List.of()); - } - // this should not happen, every MetricRollup node should be captured and syntax checked in StatementAnalyzer - throw new IllegalArgumentException("MetricRollup node is not replaced"); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/MetricSqlRender.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/MetricSqlRender.java deleted file mode 100644 index 735ddf5b7..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/MetricSqlRender.java +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.base.Joiner; -import com.google.common.collect.ImmutableList; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.ExpressionRewriter; -import io.trino.sql.tree.ExpressionTreeRewriter; -import io.trino.sql.tree.Identifier; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationable; -import io.wren.base.dto.Relationship; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipAnalyzer; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipInfo; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; -import java.util.stream.IntStream; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static io.trino.sql.SqlFormatter.formatSql; -import static io.wren.base.sqlrewrite.Utils.parseExpression; -import static io.wren.base.sqlrewrite.Utils.parseQuery; -import static java.lang.String.format; -import static java.lang.String.join; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; -import static java.util.stream.Collectors.toSet; - -public class MetricSqlRender - extends RelationableSqlRender -{ - private final Set requiredDims; - private final Set requiredMeasures; - - public MetricSqlRender(Metric metric, WrenMDL mdl) - { - super(metric, mdl); - this.requiredDims = metric.getDimension().stream().map(Column::getName).collect(toImmutableSet()); - this.requiredMeasures = metric.getMeasure().stream().map(Column::getName).collect(toImmutableSet()); - } - - public MetricSqlRender(Metric metric, WrenMDL mdl, Set requiredFields) - { - super(metric, mdl); - requireNonNull(requiredFields); - this.requiredDims = metric.getDimension().stream() - .map(Column::getName) - .filter(requiredFields::contains) - .collect(toImmutableSet()); - this.requiredMeasures = metric.getMeasure().stream() - .map(Column::getName) - .filter(requiredFields::contains) - .collect(toImmutableSet()); - } - - @Override - protected String initRefSql(Relationable relationable) - { - return "SELECT * FROM \"" + relationable.getBaseObject() + "\""; - } - - @Override - public RelationInfo render() - { - Optional metricBaseModel = mdl.getModel(relationable.getBaseObject()); - // metric on model - if (metricBaseModel.isPresent()) { - return render(metricBaseModel.orElseThrow(() -> new IllegalArgumentException("model not found"))); - } - // metric on metric - Optional metricBaseMetric = mdl.getMetric(relationable.getBaseObject()); - if (metricBaseMetric.isPresent()) { - return renderBasedOnMetric(metricBaseMetric.orElseThrow(() -> new IllegalArgumentException("metric not found")).getName()); - } - // metric on cumulative metric - Optional metricBaseCumulativeMetric = mdl.getCumulativeMetric(relationable.getBaseObject()); - if (metricBaseCumulativeMetric.isPresent()) { - return renderBasedOnMetric(metricBaseCumulativeMetric.orElseThrow(() -> new IllegalArgumentException("metric not found")).getName()); - } - throw new IllegalArgumentException("invalid metric, cannot render metric sql"); - } - - private RelationInfo renderBasedOnMetric(String metricName) - { - Metric metric = (Metric) relationable; - List selectItems = metric.getColumns().stream() - .filter(column -> isRequiredColumn(column.getName())) - .map(column -> format("%s AS \"%s\"", column.getSqlExpression(), column.getName())) - .collect(toList()); - addCountAllIfNeeded(); - String sql = getQuerySql(Joiner.on(", ").join(selectItems), metricName); - return new RelationInfo( - relationable, - Set.of(metricName), - parseQuery(sql)); - } - - @Override - protected String getQuerySql(String selectItemsSql, String tableJoinsSql) - { - if (requiredDims.isEmpty()) { - return format("SELECT %s FROM %s", selectItemsSql, tableJoinsSql); - } - String groupByItems = IntStream.rangeClosed(1, requiredDims.size()).mapToObj(String::valueOf).collect(joining(",")); - return format("SELECT %s FROM %s GROUP BY %s", selectItemsSql, tableJoinsSql, groupByItems); - } - - @Override - protected String getModelSubQuerySelectItemsExpression(Map columnWithoutRelationships) - { - // TODO: consider column projection - return "*"; - } - - @Override - protected String getSelectItemsExpression(Column column, Optional relationableBase) - { - Metric metric = (Metric) relationable; - boolean isMeasure = metric.getMeasure().stream().anyMatch(measure -> measure.getName().equals(column.getName())); - Model baseModel = mdl.getModel(metric.getBaseObject()).orElseThrow(() -> new IllegalArgumentException(format("cannot find model %s", metric.getBaseObject()))); - Expression expression = parseExpression(column.getSqlExpression()); - Set relationshipInfos = ExpressionRelationshipAnalyzer.getRelationships(expression, mdl, baseModel).stream().collect(toImmutableSet()); - - if (!relationshipInfos.isEmpty() && relationableBase.isPresent()) { - Expression newExpression = (Expression) RelationshipRewriter.relationshipAware(relationshipInfos, relationableBase.get(), expression); - return format("%s AS \"%s\"", newExpression, column.getName()); - } - - if (isMeasure) { - return format("%s AS \"%s\"", - awareModel(column.getExpression().orElseThrow(() -> new IllegalArgumentException("measure column must have expression")), baseModel), column.getName()); - } - - return format("%s AS \"%s\"", awareModel(column.getSqlExpression(), baseModel), column.getName()); - } - - private String awareModel(String expression, Model baseModel) - { - return formatSql(awareModel(parseExpression(expression), baseModel)); - } - - private Expression awareModel(Expression expression, Model baseModel) - { - return ExpressionTreeRewriter.rewriteWith(new ExpressionRewriter<>() - { - @Override - public Expression rewriteIdentifier(Identifier node, Void context, ExpressionTreeRewriter treeRewriter) - { - if (baseModel.getColumns().stream().anyMatch(c -> c.getName().equalsIgnoreCase(node.getValue()))) { - return new DereferenceExpression(new Identifier(baseModel.getName(), true), new Identifier(node.getValue(), true)); - } - return node; - } - }, expression); - } - - @Override - protected void collectRelationship(Column column, Model baseModel) - { - if (!isRequiredColumn(column.getName())) { - return; - } - Expression expression = parseExpression(column.getSqlExpression()); - Set relationshipInfos = ExpressionRelationshipAnalyzer.getRelationships(expression, mdl, baseModel); - if (!relationshipInfos.isEmpty()) { - calculatedRequiredRelationshipInfos.add(new CalculatedFieldRelationshipInfo(column, relationshipInfos)); - // collect all required models in relationships - requiredObjects.addAll( - relationshipInfos.stream() - .map(ExpressionRelationshipInfo::getRelationships) - .flatMap(List::stream) - .map(Relationship::getModels) - .flatMap(List::stream) - .filter(modelName -> !modelName.equals(baseModel.getName())) - .collect(toSet())); - - // output from column use relationship will use another subquery which use column name from model as alias name - selectItems.add(getSelectItemsExpression(column, Optional.of(getRelationableAlias(baseModel.getName())))); - } - else { - selectItems.add(getSelectItemsExpression(column, Optional.empty())); - calculatedScopeSelectItems.put(column.getName(), column.getSqlExpression()); - } - } - - @Override - protected List getCalculatedSubQuery(Model baseModel, List relationshipInfos) - { - if (relationshipInfos.isEmpty()) { - return ImmutableList.of(); - } - - String requiredExpressions = relationshipInfos.stream() - .map(CalculatedFieldRelationshipInfo::getExpressionRelationshipInfo) - .flatMap(Set::stream) - .map(RelationshipRewriter::toDereferenceExpression) - .map(Expression::toString) - .distinct() - .collect(joining(", ")); - - List requiredRelationships = relationshipInfos.stream() - .map(CalculatedFieldRelationshipInfo::getExpressionRelationshipInfo) - .flatMap(Set::stream) - .map(ExpressionRelationshipInfo::getRelationships) - .flatMap(List::stream) - .distinct() - .collect(toImmutableList()); - String tableJoins = format("\"%s\"\n%s", - baseModel.getName(), - requiredRelationships.stream() - .map(relationship -> format("LEFT JOIN \"%s\" ON %s\n", relationship.getModels().get(1), relationship.getQualifiedCondition())) - .collect(joining())); - - Function tableJoinCondition = - (name) -> format("\"%s\".\"%s\" = \"%s\".\"%s\"", baseModel.getName(), baseModel.getPrimaryKey(), name, baseModel.getPrimaryKey()); - return ImmutableList.of( - new SubQueryJoinInfo( - format("SELECT \"%s\".\"%s\", %s FROM (%s)", - baseModel.getName(), - baseModel.getPrimaryKey(), - requiredExpressions, - tableJoins), - getRelationableAlias(baseModel.getName()), - tableJoinCondition.apply(getRelationableAlias(baseModel.getName())))); - } - - private RelationInfo render(Model baseModel) - { - requireNonNull(baseModel, "baseModel is null"); - relationable.getColumns().stream() - .filter(column -> column.getRelationship().isEmpty() && column.getExpression().isEmpty()) - .filter(column -> isRequiredColumn(column.getName())) - .forEach(column -> selectItems.add(getSelectItemsExpression(column, Optional.empty()))); - relationable.getColumns().stream() - .filter(column -> column.getRelationship().isEmpty() && column.getExpression().isPresent()) - .forEach(column -> collectRelationship(column, baseModel)); - addCountAllIfNeeded(); - - String modelSubQuerySelectItemsExpression = getModelSubQuerySelectItemsExpression(calculatedScopeSelectItems); - - String modelSubQuery = format("(SELECT %s FROM (%s) AS \"%s\") AS \"%s\"", - modelSubQuerySelectItemsExpression, - refSql, - baseModel.getName(), - baseModel.getName()); - - StringBuilder tableJoinsSql = new StringBuilder(modelSubQuery); - if (!calculatedRequiredRelationshipInfos.isEmpty()) { - tableJoinsSql.append( - getCalculatedSubQuery(baseModel, calculatedRequiredRelationshipInfos).stream() - .map(info -> format("\nLEFT JOIN (%s) AS \"%s\" ON %s", info.getSql(), info.getSubqueryAlias(), info.getJoinCriteria())) - .collect(joining(""))); - } - tableJoinsSql.append("\n"); - - return new RelationInfo( - relationable, - requiredObjects, - parseQuery(getQuerySql(join(", ", selectItems), tableJoinsSql.toString()))); - } - - private boolean isRequiredColumn(String name) - { - return requiredDims.contains(name) || requiredMeasures.contains(name); - } - - // dynamic metric may not contain measure, while metric will use group by clause, so we still need at least one aggregate function - // in metric CTE, that's why added a filler column count(*) here - private void addCountAllIfNeeded() - { - if (requiredMeasures.isEmpty()) { - selectItems.add("COUNT(*) AS _count_filler"); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/ModelSqlRender.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/ModelSqlRender.java deleted file mode 100644 index f9ffc6e4a..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/ModelSqlRender.java +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.tree.Expression; -import io.wren.base.Utils; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationable; -import io.wren.base.dto.Relationship; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipAnalyzer; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipInfo; - -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Function; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static io.wren.base.sqlrewrite.Utils.parseExpression; -import static io.wren.base.sqlrewrite.Utils.parseQuery; -import static java.lang.String.format; -import static java.lang.String.join; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toSet; - -public class ModelSqlRender - extends RelationableSqlRender -{ - private final Set requiredFields; - - public ModelSqlRender(Relationable relationable, WrenMDL mdl, Set requiredFields) - { - super(relationable, mdl); - this.requiredFields = requireNonNull(requiredFields); - } - - public ModelSqlRender(Relationable relationable, WrenMDL mdl) - { - super(relationable, mdl); - this.requiredFields = relationable.getColumns().stream().map(Column::getName).collect(toImmutableSet()); - } - - @Override - protected String initRefSql(Relationable relationable) - { - Utils.checkArgument(relationable instanceof Model, "relationable must be model"); - Model model = (Model) relationable; - if (model.getRefSql() != null) { - return "(" + model.getRefSql() + ")"; - } - else if (model.getBaseObject() != null) { - return "(SELECT * FROM \"" + model.getBaseObject() + "\")"; - } - else if (model.getTableReference() != null) { - return model.getTableReference().toQualifiedName(); - } - else { - throw new IllegalArgumentException("cannot get reference sql from model"); - } - } - - @Override - public RelationInfo render() - { - requireNonNull(relationable, "model is null"); - if (relationable.getColumns().isEmpty()) { - return new RelationInfo(relationable, Set.of(), parseQuery(refSql)); - } - - return render((Model) relationable); - } - - @Override - protected String getQuerySql(String selectItemsSql, String tableJoinsSql) - { - return format("SELECT %s FROM %s", selectItemsSql, tableJoinsSql); - } - - @Override - protected String getModelSubQuerySelectItemsExpression(Map columnWithoutRelationships) - { - return columnWithoutRelationships.entrySet().stream() - .map(e -> format("%s AS \"%s\"", e.getValue(), e.getKey())) - .collect(joining(", ")); - } - - @Override - protected String getSelectItemsExpression(Column column, Optional relationalBase) - { - if (relationalBase.isPresent()) { - return format("\"%s\".\"%s\" AS \"%s\"", relationalBase.get(), column.getName(), column.getName()); - } - return format("\"%s\".\"%s\" AS \"%s\"", relationable.getName(), column.getName(), column.getName()); - } - - @Override - protected void collectRelationship(Column column, Model baseModel) - { - Expression expression = parseExpression(column.getSqlExpression()); - Set relationshipInfos = ExpressionRelationshipAnalyzer.getRelationships(expression, mdl, baseModel); - if (column.isCalculated()) { - if (!relationshipInfos.isEmpty()) { - if (!requiredFields.contains(column.getName())) { - return; - } - CalculatedFieldRelationshipInfo calculatedFieldRelationshipInfo = new CalculatedFieldRelationshipInfo(column, relationshipInfos); - calculatedRequiredRelationshipInfos.add(calculatedFieldRelationshipInfo); - // Collect all required models in relationships - requiredObjects.addAll(relationshipInfos.stream() - .map(ExpressionRelationshipInfo::getRelationships) - .flatMap(List::stream) - .map(Relationship::getModels) - .flatMap(List::stream) - .filter(modelName -> !modelName.equals(baseModel.getName())) - .collect(toSet())); - - // Add select items based on the type of column - if (calculatedFieldRelationshipInfo.isAggregated()) { - selectItems.add(getSelectItemsExpression(column, Optional.of(calculatedFieldRelationshipInfo.getAlias()))); - } - else { - selectItems.add(getSelectItemsExpression(column, Optional.of(getRelationableAlias(baseModel.getName())))); - } - } - else { - // calculated field without relationship - selectItems.add(getSelectItemsExpression(column, Optional.empty())); - calculatedScopeSelectItems.put(column.getName(), column.getSqlExpression()); - } - } - else { - // normal column got from base model sql - selectItems.add(getSelectItemsExpression(column, Optional.empty())); - calculatedScopeSelectItems.put(column.getName(), format("\"%s\".\"%s\"", baseModel.getName(), column.getName())); - } - } - - @Override - protected List getCalculatedSubQuery(Model baseModel, List relationshipInfos) - { - ImmutableList.Builder queries = ImmutableList.builder(); - queries.addAll(getToOneRelationshipsQuery(baseModel, relationshipInfos)); - queries.addAll(getToManyRelationshipsQuery(baseModel, relationshipInfos)); - return queries.build(); - } - - // only accept to-one relationship(s) in this method - private List getToOneRelationshipsQuery(Model baseModel, Collection relationshipInfos) - { - Set toOneRelationships = relationshipInfos.stream() - .filter(relationshipInfo -> !relationshipInfo.isAggregated()) - .collect(toImmutableSet()); - - if (toOneRelationships.isEmpty()) { - return ImmutableList.of(); - } - - String requiredExpressions = toOneRelationships.stream() - .map(info -> format("%s AS \"%s\"", - RelationshipRewriter.rewrite( - info.getExpressionRelationshipInfo(), - parseExpression(info.getColumn().getExpression().orElseThrow())) - .toString(), - info.getAlias())) - .collect(joining(", ")); - - List requiredRelationships = toOneRelationships.stream() - .map(CalculatedFieldRelationshipInfo::getExpressionRelationshipInfo) - .flatMap(Set::stream) - .map(ExpressionRelationshipInfo::getRelationships) - .flatMap(List::stream) - .distinct() - .collect(toImmutableList()); - String tableJoins = format("(%s) AS \"%s\" %s", - getBaseModelSql(baseModel), - baseModel.getName(), - requiredRelationships.stream() - .map(relationship -> format(" LEFT JOIN \"%s\" ON %s", relationship.getModels().get(1), relationship.getQualifiedCondition())) - .collect(joining())); - - Function tableJoinCondition = - (name) -> format("\"%s\".\"%s\" = \"%s\".\"%s\"", baseModel.getName(), baseModel.getPrimaryKey(), name, baseModel.getPrimaryKey()); - return ImmutableList.of( - new SubQueryJoinInfo( - format("SELECT \"%s\".\"%s\", %s FROM (%s)", - baseModel.getName(), - baseModel.getPrimaryKey(), - requiredExpressions, - tableJoins), - getRelationableAlias(baseModel.getName()), - tableJoinCondition.apply(getRelationableAlias(baseModel.getName())))); - } - - private RelationInfo render(Model baseModel) - { - requireNonNull(baseModel, "baseModel is null"); - relationable.getColumns().stream() - .filter(column -> column.getRelationship().isEmpty() && column.getExpression().isEmpty()) - .forEach(column -> { - // normal column got from base model sql - selectItems.add(getSelectItemsExpression(column, Optional.empty())); - calculatedScopeSelectItems.put(column.getName(), format("\"%s\".\"%s\"", baseModel.getName(), column.getName())); - }); - - baseModel.getColumns().stream() - .filter(column -> column.getRelationship().isEmpty() && column.getExpression().isPresent()) - .forEach(column -> collectRelationship(column, baseModel)); - String baseModelSql = getBaseModelSql(baseModel); - String calculatedFieldsWithoutRelationship = getModelSubQuerySelectItemsExpression(calculatedScopeSelectItems); - String calculatedSubQuery = format(""" - (SELECT %s FROM (%s) AS "%s") AS "%s" - """, - calculatedFieldsWithoutRelationship, - baseModelSql, - baseModel.getName(), - baseModel.getName()); - - StringBuilder tableJoinsSql = new StringBuilder(calculatedSubQuery); - if (!calculatedRequiredRelationshipInfos.isEmpty()) { - tableJoinsSql.append( - getCalculatedSubQuery(baseModel, calculatedRequiredRelationshipInfos).stream() - .map(info -> format("LEFT JOIN (%s) AS \"%s\" ON %s", info.getSql(), info.getSubqueryAlias(), info.getJoinCriteria())) - .collect(joining(""))); - } - tableJoinsSql.append("\n"); - - return new RelationInfo( - baseModel, - requiredObjects, - parseQuery(getQuerySql(join(", ", selectItems), tableJoinsSql.toString()))); - } - - // accept to-one relationship(s) and at least one to-many relationship in this method, and use group by model primary key - // to aggregate the query result as to-many relationship could lead to duplicate rows. Here we didn't check if there - // is an aggregation function or not, we should add aggregation function in expression to avoid sql syntax error. - private List getToManyRelationshipsQuery(Model baseModel, Collection relationshipInfos) - { - return relationshipInfos.stream() - .filter(CalculatedFieldRelationshipInfo::isAggregated) - .map(relationshipInfo -> { - String requiredExpressions = format("%s AS \"%s\"", - RelationshipRewriter.rewrite(relationshipInfo.getExpressionRelationshipInfo(), parseExpression(relationshipInfo.getColumn().getSqlExpression())), - relationshipInfo.getAlias()); - - String tableJoins = format("(%s) AS \"%s\" %s", - getBaseModelSql(baseModel), - baseModel.getName(), - relationshipInfo.getExpressionRelationshipInfo().stream() - .map(ExpressionRelationshipInfo::getRelationships) - .flatMap(List::stream) - .distinct() - .map(relationship -> format(" LEFT JOIN \"%s\" ON %s", relationship.getModels().get(1), relationship.getQualifiedCondition())) - .collect(joining())); - - Utils.checkArgument(baseModel.getPrimaryKey() != null, "primary key in model %s contains relationship shouldn't be null", baseModel.getName()); - Function tableJoinCondition = - (name) -> format("\"%s\".\"%s\" = \"%s\".\"%s\"", baseModel.getName(), baseModel.getPrimaryKey(), name, baseModel.getPrimaryKey()); - return new SubQueryJoinInfo( - format("SELECT %s, %s FROM (%s) GROUP BY 1", - format("\"%s\".\"%s\"", baseModel.getName(), baseModel.getPrimaryKey()), - requiredExpressions, - tableJoins), - relationshipInfo.getAlias(), - tableJoinCondition.apply(relationshipInfo.getAlias())); - }) - .collect(toImmutableList()); - } - - private String getBaseModelSql(Model model) - { - String selectItems = model.getColumns().stream() - .filter(column -> !column.isCalculated()) - .filter(column -> column.getRelationship().isEmpty()) - .map(column -> format("%s AS \"%s\"", column.getSqlExpression(), column.getName())) - .collect(joining(", ")); - return format("SELECT %s FROM %s AS \"%s\"", selectItems, refSql, model.getName()); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/QueryDescriptor.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/QueryDescriptor.java deleted file mode 100644 index 7b83c883c..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/QueryDescriptor.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Query; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.View; - -import java.util.Optional; -import java.util.Set; - -public interface QueryDescriptor -{ - String getName(); - - Set getRequiredObjects(); - - Query getQuery(); - - static QueryDescriptor of(String name, AnalyzedMDL analyzedMDL, SessionContext sessionContext) - { - WrenMDL mdl = analyzedMDL.getWrenMDL(); - Optional model = mdl.getModel(name); - if (model.isPresent()) { - return RelationInfo.get(model.get(), mdl); - } - Optional metric = mdl.getMetric(name); - if (metric.isPresent()) { - return RelationInfo.get(metric.get(), mdl); - } - Optional cumulativeMetric = mdl.getCumulativeMetric(name); - if (cumulativeMetric.isPresent()) { - return CumulativeMetricInfo.get(cumulativeMetric.get(), mdl); - } - Optional view = mdl.getView(name); - if (view.isPresent()) { - return ViewInfo.get(view.get(), analyzedMDL, sessionContext); - } - if (name.equals(DateSpineInfo.NAME)) { - return DateSpineInfo.get(mdl.getDateSpine()); - } - throw new IllegalArgumentException(name + " not found in wren mdl"); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationInfo.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationInfo.java deleted file mode 100644 index f22d773d5..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationInfo.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Query; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationable; - -import java.util.Objects; -import java.util.Set; - -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; - -public class RelationInfo - implements QueryDescriptor -{ - private final Relationable relationable; - private final Set requiredObjects; - private final Query query; - - public static RelationInfo get(Relationable relationable, WrenMDL mdl, Set requiredFields) - { - if (relationable instanceof Model) { - return new ModelSqlRender(relationable, mdl, requiredFields).render(); - } - else if (relationable instanceof Metric) { - return new MetricSqlRender((Metric) relationable, mdl, requiredFields).render(); - } - else { - throw new IllegalArgumentException(format("cannot get relation info from relationable %s", relationable)); - } - } - - public static RelationInfo get(Relationable relationable, WrenMDL mdl) - { - if (relationable instanceof Model) { - return new ModelSqlRender(relationable, mdl).render(); - } - else if (relationable instanceof Metric) { - return new MetricSqlRender((Metric) relationable, mdl).render(); - } - else { - throw new IllegalArgumentException(format("cannot get relation info from relationable %s", relationable)); - } - } - - RelationInfo( - Relationable relationable, - Set requiredModels, - Query query) - { - this.relationable = requireNonNull(relationable); - this.requiredObjects = requireNonNull(requiredModels); - this.query = requireNonNull(query); - } - - public Set getRequiredObjects() - { - return requiredObjects; - } - - public Query getQuery() - { - return query; - } - - @Override - public int hashCode() - { - return Objects.hash(relationable, requiredObjects, query); - } - - @Override - public String getName() - { - return relationable.getName(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RelationInfo relationInfo = (RelationInfo) o; - return Objects.equals(relationable, relationInfo.relationable) - && Objects.equals(requiredObjects, relationInfo.requiredObjects) - && Objects.equals(query, relationInfo.query); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationableSqlRender.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationableSqlRender.java deleted file mode 100644 index ee26b8e9d..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationableSqlRender.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationable; -import io.wren.base.dto.Relationship; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipInfo; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import static java.util.Objects.requireNonNull; - -// TODO: Turn this into interface -public abstract class RelationableSqlRender -{ - protected final Relationable relationable; - protected final WrenMDL mdl; - protected final String refSql; - // collect dependent models - protected final Set requiredObjects; - // key is alias_name.column_name, value is column name, this map is used to compose select items in model sql - protected final List selectItems = new ArrayList<>(); - // calculatedRequiredRelationshipInfos collects all join condition needed in model calculated field and the original column name. - // It is used to compose join conditions in model sql. - protected final List calculatedRequiredRelationshipInfos = new ArrayList<>(); - // key is column name in model, value is column expression, this map store columns not use relationships - protected final Map calculatedScopeSelectItems = new LinkedHashMap<>(); - - public RelationableSqlRender(Relationable relationable, WrenMDL mdl) - { - this.relationable = requireNonNull(relationable); - this.mdl = requireNonNull(mdl); - this.refSql = initRefSql(relationable); - this.requiredObjects = new HashSet<>(); - if (relationable.getBaseObject() != null) { - requiredObjects.add(relationable.getBaseObject()); - } - } - - protected abstract String initRefSql(Relationable relationable); - - protected abstract RelationInfo render(); - - protected static String getRelationableAlias(String baseModelName) - { - return baseModelName + "_relationsub"; - } - - protected abstract List getCalculatedSubQuery(Model baseModel, List calculatedFieldRelationshipInfo); - - protected abstract void collectRelationship(Column column, Model baseModel); - - protected abstract String getQuerySql(String selectItemsSql, String tableJoinsSql); - - protected abstract String getModelSubQuerySelectItemsExpression(Map columnWithoutRelationships); - - protected abstract String getSelectItemsExpression(Column column, Optional relationalBase); - - public static class CalculatedFieldRelationshipInfo - { - private final Column column; - private final Set expressionRelationshipInfo; - private final boolean isAggregated; - - public CalculatedFieldRelationshipInfo(Column column, Set expressionRelationshipInfo) - { - this.column = requireNonNull(column); - this.expressionRelationshipInfo = requireNonNull(expressionRelationshipInfo); - this.isAggregated = expressionRelationshipInfo.stream() - .map(ExpressionRelationshipInfo::getRelationships) - .flatMap(List::stream) - .map(Relationship::getJoinType) - .anyMatch(JoinType::isToMany); - } - - public String getAlias() - { - return column.getName(); - } - - public Column getColumn() - { - return column; - } - - public Set getExpressionRelationshipInfo() - { - return expressionRelationshipInfo; - } - - public boolean isAggregated() - { - return isAggregated; - } - } - - public static class SubQueryJoinInfo - { - private final String sql; - private final String subqueryAlias; - private final String joinCriteria; - - public SubQueryJoinInfo(String sql, String subqueryAlias, String joinCriteria) - { - this.sql = sql; - this.subqueryAlias = subqueryAlias; - this.joinCriteria = joinCriteria; - } - - public String getSql() - { - return sql; - } - - public String getSubqueryAlias() - { - return subqueryAlias; - } - - public String getJoinCriteria() - { - return joinCriteria; - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationshipRewriter.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationshipRewriter.java deleted file mode 100644 index 53331abab..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/RelationshipRewriter.java +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.QualifiedName; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipInfo; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static io.trino.sql.tree.DereferenceExpression.getQualifiedName; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toUnmodifiableMap; - -public class RelationshipRewriter - extends BaseRewriter -{ - private final Map replacements; - - public static Node rewrite(Set relationshipInfos, Expression expression) - { - requireNonNull(relationshipInfos); - HashMap replacements = new HashMap<>(); - relationshipInfos.forEach(info -> replacements.put(info.getQualifiedName(), toDereferenceExpression(info))); - return new RelationshipRewriter(replacements) - .process(expression); - } - - public static Node relationshipAware(Set relationshipInfos, String relationshipPrefix, Expression expression) - { - requireNonNull(relationshipInfos); - return new RelationshipRewriter(relationshipInfos.stream() - .collect(toUnmodifiableMap(ExpressionRelationshipInfo::getQualifiedName, info -> getRelationshipResultAsDereferenceExpression(info, relationshipPrefix)))) - .process(expression); - } - - public RelationshipRewriter(Map replacements) - { - this.replacements = requireNonNull(replacements); - } - - @Override - protected Node visitDereferenceExpression(DereferenceExpression node, Void ignored) - { - if (node.getField().isPresent()) { - QualifiedName qualifiedName = getQualifiedName(node); - if (qualifiedName != null) { - return replacements.get(qualifiedName) == null ? node : replacements.get(qualifiedName); - } - } - return node; - } - - protected static DereferenceExpression toDereferenceExpression(ExpressionRelationshipInfo expressionRelationshipInfo) - { - String base = expressionRelationshipInfo.getRelationships().get(expressionRelationshipInfo.getRelationships().size() - 1).getModels().get(1); - List parts = new ArrayList<>(); - parts.add(new Identifier(base, true)); - expressionRelationshipInfo.getRemainingParts().stream() - .map(part -> new Identifier(part, true)) - .forEach(parts::add); - return (DereferenceExpression) DereferenceExpression.from(QualifiedName.of(parts)); - } - - protected static DereferenceExpression getRelationshipResultAsDereferenceExpression(ExpressionRelationshipInfo expressionRelationshipInfo, String relationablePrefix) - { - // The relationshipFieldName is the name of the relationship field in the relationship model with `relationablePrefix`. - List parts = new ArrayList<>(); - parts.add(new Identifier(relationablePrefix, true)); - expressionRelationshipInfo.getRemainingParts().stream() - .map(part -> new Identifier(part, true)) - .forEach(parts::add); - return (DereferenceExpression) DereferenceExpression.from(QualifiedName.of(parts)); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/Utils.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/Utils.java deleted file mode 100644 index c61348d48..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/Utils.java +++ /dev/null @@ -1,334 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; -import io.trino.sql.parser.ParsingOptions; -import io.trino.sql.parser.SqlParser; -import io.trino.sql.tree.DataType; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.Relation; -import io.trino.sql.tree.Statement; -import io.wren.base.CatalogSchemaTableName; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.DateSpine; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.sqlrewrite.analyzer.Field; -import io.wren.base.sqlrewrite.analyzer.MetricRollupInfo; -import io.wren.base.sqlrewrite.analyzer.RelationType; -import io.wren.base.sqlrewrite.analyzer.Scope; -import io.wren.base.sqlrewrite.analyzer.ScopeAnalysis; -import io.wren.base.sqlrewrite.analyzer.ScopeAnalyzer; - -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.stream.IntStream; -import java.util.stream.Stream; - -import static io.trino.sql.parser.ParsingOptions.DecimalLiteralTreatment.AS_DOUBLE; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.joining; -import static java.util.stream.Collectors.toList; - -public final class Utils -{ - public static final SqlParser SQL_PARSER = new SqlParser(); - private static final ParsingOptions PARSING_OPTIONS = new ParsingOptions(AS_DOUBLE); - - private Utils() {} - - public static Statement parseSql(String sql) - { - return SQL_PARSER.createStatement(sql, PARSING_OPTIONS); - } - - public static Query parseView(String sql) - { - return (Query) parseSql(sql); - } - - public static Expression parseExpression(String expression) - { - try { - return SQL_PARSER.createExpression(expression, PARSING_OPTIONS); - } - catch (Exception e) { - throw new RuntimeException(format("Failed to parse expression: %s", expression), e); - } - } - - public static DataType parseType(String type) - { - try { - return SQL_PARSER.createType(type); - } - catch (Exception e) { - throw new RuntimeException(format("Failed to parse type: %s", type), e); - } - } - - public static Query parseQuery(String sql) - { - try { - Statement statement = parseSql(sql); - if (statement instanceof Query) { - return (Query) statement; - } - } - catch (Exception e) { - throw new RuntimeException(format("Failed to parse query: %s", sql), e); - } - throw new IllegalArgumentException("model sql is not a query"); - } - - public static Query parseMetricRollupSql(MetricRollupInfo metricRollupInfo) - { - String sql = getMetricRollupSql(metricRollupInfo); - try { - Statement statement = parseSql(sql); - if (statement instanceof Query) { - return (Query) statement; - } - } - catch (Exception e) { - throw new RuntimeException(format("Failed to parse metric rollup sql: %s", metricRollupInfo), e); - } - throw new IllegalArgumentException(String.format("metric %s is not a query, sql %s", metricRollupInfo.getMetric().getName(), sql)); - } - - public static Query parseCumulativeMetricSql(CumulativeMetric cumulativeMetric, WrenMDL wrenMDL) - { - String sql = getCumulativeMetricSql(cumulativeMetric, wrenMDL); - try { - Statement statement = parseSql(sql); - if (statement instanceof Query) { - return (Query) statement; - } - } - catch (Exception e) { - throw new RuntimeException(format("Failed to parse cumulative metric sql: %s", cumulativeMetric), e); - } - throw new IllegalArgumentException(format("metric %s is not a query, sql %s", cumulativeMetric.getName(), sql)); - } - - private static String getCumulativeMetricSql(CumulativeMetric cumulativeMetric, WrenMDL wrenMDL) - { - requireNonNull(cumulativeMetric, "cumulativeMetric is null"); - - String windowType = getWindowType(cumulativeMetric, wrenMDL) - .orElseThrow(() -> new NoSuchElementException("window type not found in " + cumulativeMetric.getBaseObject())); - - String pattern = - "select \n" + - " metric_time as %s,\n" + - " %s(distinct measure_field) as %s\n" + - "from \n" + - " (\n" + - " select \n" + - " date_trunc('%s', d.metric_time) as metric_time,\n" + - " measure_field\n" + - " from \n" + - " (%s) d \n" + - " left join (\n" + - " select \n" + - " measure_field,\n" + - " metric_time\n" + - " from (%s) sub1\n" + - " where \n" + - " metric_time >= cast('%s' as %s) \n" + - " and metric_time <= cast('%s' as %s)\n" + - " ) sub2 on (\n" + - " sub2.metric_time <= d.metric_time \n" + - " and sub2.metric_time > %s\n" + - " )\n" + - " where \n" + - " d.metric_time >= cast('%s' as %s) \n" + - " and d.metric_time <= cast('%s' as %s) \n" + - " ) sub3 \n" + - "group by 1\n" + - "order by 1\n"; - - String castingDateSpine = format("select cast(metric_time as %s) as metric_time from \"%s\"", windowType, DateSpineInfo.NAME); - String windowRange = format("d.metric_time - %s", cumulativeMetric.getWindow().getTimeUnit().getIntervalExpression()); - String selectFromModel = format("select %s as measure_field, %s as metric_time from %s", - cumulativeMetric.getMeasure().getRefColumn(), - cumulativeMetric.getWindow().getRefColumn(), - cumulativeMetric.getBaseObject()); - - return format(pattern, - cumulativeMetric.getWindow().getName(), - cumulativeMetric.getMeasure().getOperator(), - cumulativeMetric.getMeasure().getName(), - cumulativeMetric.getWindow().getTimeUnit().name(), - castingDateSpine, - selectFromModel, - cumulativeMetric.getWindow().getStart(), - windowType, - cumulativeMetric.getWindow().getEnd(), - windowType, - windowRange, - cumulativeMetric.getWindow().getStart(), - windowType, - cumulativeMetric.getWindow().getEnd(), - windowType); - } - - private static Optional getWindowType(CumulativeMetric cumulativeMetric, WrenMDL wrenMDL) - { - Optional baseModel = wrenMDL.getModel(cumulativeMetric.getBaseObject()); - if (baseModel.isPresent()) { - return baseModel.get().getColumns().stream() - .filter(column -> column.getName().equals(cumulativeMetric.getWindow().getRefColumn())) - .map(Column::getType) - .findAny(); - } - - Optional baseMetric = wrenMDL.getMetric(cumulativeMetric.getBaseObject()); - if (baseMetric.isPresent()) { - return baseMetric.get().getColumns().stream() - .filter(column -> column.getName().equals(cumulativeMetric.getWindow().getRefColumn())) - .map(Column::getType) - .findAny(); - } - - Optional baseCumulativeMetric = wrenMDL.getCumulativeMetric(cumulativeMetric.getBaseObject()); - if (baseCumulativeMetric.isPresent()) { - if (baseCumulativeMetric.get().getWindow().getName().equals(cumulativeMetric.getWindow().getRefColumn())) { - // TODO: potential stackoverflow issue since base object might use child object and - // this recursive call happen before cyclic DAG check in WrenSqlRewrite - return getWindowType(baseCumulativeMetric.get(), wrenMDL); - } - else { - throw new IllegalArgumentException("CumulativeMetric measure cannot be window as it is not date/timestamp type"); - } - } - - return Optional.empty(); - } - - private static String getMetricRollupSql(MetricRollupInfo metricRollupInfo) - { - requireNonNull(metricRollupInfo, "metricRollupInfo is null"); - - Metric metric = metricRollupInfo.getMetric(); - String timeGrain = String.format("DATE_TRUNC('%s', %s) \"%s\"", - metricRollupInfo.getDatePart(), - metricRollupInfo.getTimeGrain().getRefColumn(), - metricRollupInfo.getTimeGrain().getName()); - - List selectItems = - ImmutableList.builder() - .add(timeGrain) - .addAll( - Stream.concat(metric.getDimension().stream(), metric.getMeasure().stream()) - .map(column -> format("%s AS \"%s\"", column.getSqlExpression(), column.getName())) - .collect(toList())) - .build(); - - String groupByColumnOrdinals = - IntStream.rangeClosed(1, selectItems.size() - metric.getMeasure().size()) - .mapToObj(String::valueOf) - .collect(joining(",")); - - return format("SELECT %s FROM \"%s\" GROUP BY %s", - String.join(",", selectItems), - metric.getBaseObject(), - groupByColumnOrdinals); - } - - public static CatalogSchemaTableName toCatalogSchemaTableName(SessionContext sessionContext, QualifiedName name) - { - requireNonNull(sessionContext, "sessionContext is null"); - requireNonNull(name, "name is null"); - if (name.getParts().size() > 3) { - throw new IllegalArgumentException(format("Too many dots in table name: %s", name)); - } - - List parts = Lists.reverse(name.getParts()); - String objectName = parts.get(0); - String schemaName = (parts.size() > 1) ? parts.get(1) : sessionContext.getSchema().orElseThrow(() -> - new IllegalArgumentException("Schema must be specified when session schema is not set")); - String catalogName = (parts.size() > 2) ? parts.get(2) : sessionContext.getCatalog().orElseThrow(() -> - new IllegalArgumentException("Catalog must be specified when session catalog is not set")); - - return new CatalogSchemaTableName(catalogName, schemaName, objectName); - } - - public static QualifiedName toQualifiedName(CatalogSchemaTableName name) - { - requireNonNull(name, "name is null"); - return QualifiedName.of(name.getCatalogName(), name.getSchemaTableName().getSchemaName(), name.getSchemaTableName().getTableName()); - } - - // TODO: handle wren view scope https://github.com/Canner/wren/issues/338 - public static Scope analyzeFrom(WrenMDL wrenMDL, SessionContext sessionContext, Relation node, Optional context) - { - ScopeAnalysis analysis = ScopeAnalyzer.analyze(wrenMDL, node, sessionContext); - List usedWrenObjects = analysis.getUsedWrenObjects(); - ImmutableList.Builder fields = ImmutableList.builder(); - wrenMDL.listModels().stream() - .filter(model -> usedWrenObjects.stream().anyMatch(relation -> relation.getName().equals(model.getName()))) - .forEach(model -> - model.getColumns().forEach(column -> fields.add(toField(wrenMDL, model.getName(), column, usedWrenObjects)))); - - wrenMDL.listMetrics().stream() - .filter(metric -> usedWrenObjects.stream().anyMatch(relation -> relation.getName().equals(metric.getName()))) - .forEach(metric -> { - metric.getDimension().forEach(column -> fields.add(toField(wrenMDL, metric.getName(), column, usedWrenObjects))); - metric.getMeasure().forEach(column -> fields.add(toField(wrenMDL, metric.getName(), column, usedWrenObjects))); - }); - - return Scope.builder() - .parent(context) - .relationType(new RelationType(fields.build())) - .build(); - } - - private static Field toField(WrenMDL wrenMDL, String modelName, Column column, List usedWrenObjects) - { - ScopeAnalysis.Relation relation = usedWrenObjects.stream() - .filter(r -> r.getName().equals(modelName)) - .findFirst() - .orElseThrow(() -> new IllegalArgumentException("Model not found: " + modelName)); - - return Field.builder() - .tableName(new CatalogSchemaTableName(wrenMDL.getCatalog(), wrenMDL.getSchema(), modelName)) - .columnName(column.getName()) - .name(column.getName()) - .relationAlias(relation.getAlias().map(QualifiedName::of).orElse(null)) - .sourceModelName(modelName) - .build(); - } - - public static Query createDateSpineQuery(DateSpine dateSpine) - { - // TODO: `GENERATE_TIMESTAMP_ARRAY` is a bigquery function. We may need to consider the SQL dialect when Wren planning. - String sql = format("SELECT * FROM UNNEST(GENERATE_TIMESTAMP_ARRAY(TIMESTAMP '%s', TIMESTAMP '%s', %s)) t(metric_time)", dateSpine.getStart(), dateSpine.getEnd(), dateSpine.getUnit().getIntervalExpression()); - Statement statement = parseSql(sql); - if (statement instanceof Query) { - return (Query) statement; - } - throw new IllegalArgumentException(format("Failed to parse date spine query: %s", sql)); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/ViewInfo.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/ViewInfo.java deleted file mode 100644 index e504d64bb..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/ViewInfo.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Query; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.dto.View; -import io.wren.base.sqlrewrite.analyzer.Analysis; -import io.wren.base.sqlrewrite.analyzer.StatementAnalyzer; - -import java.util.Set; - -import static io.wren.base.sqlrewrite.Utils.parseView; -import static java.util.Objects.requireNonNull; - -public class ViewInfo - implements QueryDescriptor -{ - private final String name; - private final Set requiredObjects; - private final Query query; - - public static ViewInfo get(View view, AnalyzedMDL analyzedMDL, SessionContext sessionContext) - { - Query query = parseView(view.getStatement()); - Analysis analysis = new Analysis(query); - StatementAnalyzer.analyze(analysis, query, sessionContext, analyzedMDL.getWrenMDL()); - // sql in view can use metric rollup syntax - query = (Query) MetricRollupRewrite.METRIC_ROLLUP_REWRITE.apply(query, sessionContext, analysis, analyzedMDL); - return new ViewInfo(view.getName(), analysis.getWrenObjectNames(), query); - } - - private ViewInfo(String name, Set requiredObjects, Query query) - { - this.name = requireNonNull(name); - this.requiredObjects = requireNonNull(requiredObjects); - this.query = requireNonNull(query); - } - - @Override - public String getName() - { - return name; - } - - @Override - public Set getRequiredObjects() - { - return requiredObjects; - } - - @Override - public Query getQuery() - { - return query; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/WithRewriter.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/WithRewriter.java deleted file mode 100644 index bff5ff1ef..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/WithRewriter.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.With; -import io.trino.sql.tree.WithQuery; - -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; - -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toUnmodifiableList; - -public class WithRewriter - extends BaseRewriter -{ - private final List withQueries; - - public WithRewriter(List withQueries) - { - this.withQueries = requireNonNull(withQueries, "withQueries is null"); - } - - @Override - protected Node visitQuery(Query node, Void context) - { - return new Query( - node.getWith() - .map(with -> new With( - with.isRecursive(), - // model queries must come first since with-queries may use models - // and tables in with query should all be in order. - Stream.concat(withQueries.stream(), with.getQueries().stream()) - .collect(toUnmodifiableList()))) - .or(() -> withQueries.isEmpty() ? Optional.empty() : Optional.of(new With(false, withQueries))), - node.getQueryBody(), - node.getOrderBy(), - node.getOffset(), - node.getLimit()); - } - - public static WithQuery getWithQuery(QueryDescriptor queryDescriptor) - { - return new WithQuery(new Identifier(queryDescriptor.getName(), true), queryDescriptor.getQuery(), Optional.empty()); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenDataLineage.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenDataLineage.java deleted file mode 100644 index cf85acf26..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenDataLineage.java +++ /dev/null @@ -1,527 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.annotations.VisibleForTesting; -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.SetMultimap; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.QualifiedName; -import io.wren.base.Utils; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipAnalyzer; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipInfo; -import io.wren.base.sqlrewrite.analyzer.RelationshipColumnInfo; -import org.jgrapht.graph.DirectedAcyclicGraph; -import org.jgrapht.graph.GraphCycleProhibitedException; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static io.trino.sql.tree.DereferenceExpression.getQualifiedName; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.groupingBy; -import static java.util.stream.Collectors.mapping; -import static java.util.stream.Collectors.toSet; - -// TODO: take care view -public class WrenDataLineage -{ - public static final WrenDataLineage EMPTY = new WrenDataLineage(WrenMDL.EMPTY); - private final WrenMDL mdl; - // key: column name, value: source columns name. format in QualifiedName is modelName.columnName - private final Map> sourceColumnsMap; - private final Map> requiredFields; - - public static WrenDataLineage analyze(WrenMDL mdl) - { - return new WrenDataLineage(mdl); - } - - private WrenDataLineage(WrenMDL mdl) - { - this.mdl = requireNonNull(mdl); - this.sourceColumnsMap = collectSourceColumns(); - this.requiredFields = collectRequiredFieldsByColumn(); - } - - /** - * Retrieve source columns used in the given column. Note that this won't delve deep into the root - * but will only return the columns utilized directly in the specified column. - * - * @param columnName QualifiedName that should only have two elements, first element is table name, second element is column name. - * @return a map of source columns which map key is table name, and map value is column names. - */ - public Map> getSourceColumns(QualifiedName columnName) - { - return Optional.ofNullable(sourceColumnsMap.get(columnName)) - .orElseGet(ImmutableSet::of) - .stream() - .collect(groupingBy(WrenDataLineage::getTable, mapping(WrenDataLineage::getColumn, toSet()))); - } - - @VisibleForTesting - LinkedHashMap> getRequiredFields(QualifiedName columnName) - { - return getRequiredFields(ImmutableList.of(columnName)); - } - - /** - * Retrieve tables in the order of CTE generation and their respective required columns for the given column. - * - * @param columnNames list of QualifiedName, the qualified name should only have two elements, first element is table name, second element is column name. - * @return {@code LinkedHashMap>} which key is table name, value is a set of column names. - * The order of the entry is the order of CTE generation. That's why use LinkedHashMap. - */ - public LinkedHashMap> getRequiredFields(List columnNames) - { - // make sure there is no model dependency cycle in given columnNames. - DirectedAcyclicGraph graph = new DirectedAcyclicGraph<>(Object.class); - Map vertexes = new HashMap<>(); - requiredFields.entrySet().stream() - .filter(e -> columnNames.contains(e.getKey())) - .forEach(e -> { - List nodes = ImmutableList.copyOf(e.getValue()); - for (int i = 1; i < nodes.size(); i++) { - String from = nodes.get(i - 1).getName(); - String to = nodes.get(i).getName(); - Vertex vertexFrom = vertexes.computeIfAbsent(from, (ignored) -> new Vertex(from)); - Vertex vertexTo = vertexes.computeIfAbsent(to, (ignored) -> new Vertex(to)); - graph.addVertex(vertexFrom); - graph.addVertex(vertexTo); - try { - graph.addEdge(vertexFrom, vertexTo); - } - catch (GraphCycleProhibitedException ex) { - throw new IllegalArgumentException("found cycle in " + e.getKey()); - } - vertexFrom.columnNames.addAll(nodes.get(i - 1).getColumnNames()); - vertexTo.columnNames.addAll(nodes.get(i).getColumnNames()); - } - }); - - LinkedHashMap> result = new LinkedHashMap<>(); - graph.iterator().forEachRemaining(vertex -> result.put(vertex.getName(), vertex.getColumnNames())); - // add back column names to requiredFields - columnNames.forEach(fullColumnName -> { - Set names = Optional.ofNullable(result.get(getTable(fullColumnName))).orElseGet(HashSet::new); - names.add(getColumn(fullColumnName)); - result.put(getTable(fullColumnName), names); - }); - return result; - } - - private Map> collectSourceColumns() - { - Map> sourceColumnsMap = new HashMap<>(); - for (Model model : mdl.listModels()) { - for (Column column : model.getColumns()) { - SetMultimap sourceColumns = getSourceColumns(mdl, model, column); - sourceColumnsMap.put( - QualifiedName.of(model.getName(), column.getName()), - // TODO: maybe we can make getSourceColumns return Set - sourceColumns.asMap().entrySet().stream() - .map(e -> - e.getValue().stream() - .map(name -> QualifiedName.of(e.getKey(), name)) - .collect(toImmutableSet())) - .flatMap(Set::stream) - .collect(toImmutableSet())); - } - } - for (Metric metric : mdl.listMetrics()) { - for (Column column : metric.getColumns()) { - SetMultimap sourceColumns = getSourceColumns(mdl, metric, column); - sourceColumnsMap.put( - QualifiedName.of(metric.getName(), column.getName()), - // TODO: maybe we can make getSourceColumns return Set - sourceColumns.asMap().entrySet().stream() - .map(e -> - e.getValue().stream() - .map(name -> QualifiedName.of(e.getKey(), name)) - .collect(toImmutableSet())) - .flatMap(Set::stream) - .collect(toImmutableSet())); - } - } - for (CumulativeMetric cumulativeMetric : mdl.listCumulativeMetrics()) { - Utils.checkArgument(mdl.isObjectExist(cumulativeMetric.getBaseObject()), "cumulative metric base object %s not exist", cumulativeMetric.getBaseObject()); - // handle measure - sourceColumnsMap.put( - QualifiedName.of(cumulativeMetric.getName(), cumulativeMetric.getMeasure().getName()), - ImmutableSet.of(QualifiedName.of(cumulativeMetric.getBaseObject(), cumulativeMetric.getMeasure().getRefColumn()))); - // handle window - sourceColumnsMap.put( - QualifiedName.of(cumulativeMetric.getName(), cumulativeMetric.getWindow().getName()), - ImmutableSet.of(QualifiedName.of(cumulativeMetric.getBaseObject(), cumulativeMetric.getWindow().getRefColumn()))); - } - return sourceColumnsMap; - } - - private Map> collectRequiredFieldsByColumn() - { - Map> columnLineages = new HashMap<>(); - sourceColumnsMap.forEach(((column, sourceColumns) -> { - DirectedAcyclicGraph graph = new DirectedAcyclicGraph<>(Object.class); - Map vertexes = new HashMap<>(); - collectRequiredFields(column, graph, vertexes); - columnLineages.put(column, ImmutableList.copyOf(graph.iterator())); - })); - - return columnLineages; - } - - private void collectRequiredFields( - QualifiedName qualifiedName, - DirectedAcyclicGraph graph, - Map vertexes) - { - if (!sourceColumnsMap.containsKey(qualifiedName)) { - return; - } - - String targetTable = getTable(qualifiedName); - String targetColumn = getColumn(qualifiedName); - Set sourceColumns = sourceColumnsMap.get(qualifiedName); - Vertex targetVertex = vertexes.computeIfAbsent(targetTable, (ignored) -> new Vertex(targetTable)); - graph.addVertex(targetVertex); - // sometimes we can't analyze lineage from column expression e.g. count(*), while the column itself may depend on another object (e.g. metric/model...) - // so we still need detect baseObject here. - if (sourceColumns.isEmpty()) { - String baseObject = getBaseObject(mdl, targetTable); - if (mdl.isObjectExist(baseObject)) { - Vertex sourceVertex = vertexes.computeIfAbsent(baseObject, (ignored) -> new Vertex(baseObject)); - graph.addVertex(sourceVertex); - try { - graph.addEdge(sourceVertex, targetVertex); - } - catch (GraphCycleProhibitedException ex) { - throw new IllegalArgumentException(format("found cycle: %s column: %s", targetTable, targetColumn)); - } - } - } - sourceColumns.forEach(fullSourceColumnName -> { - String sourceTableName = getTable(fullSourceColumnName); - String sourceColumnName = getColumn(fullSourceColumnName); - Vertex sourceVertex = vertexes.computeIfAbsent(sourceTableName, (ignored) -> new Vertex(sourceTableName)); - graph.addVertex(sourceVertex); - if (!skipAddEdge(fullSourceColumnName, qualifiedName)) { - try { - graph.addEdge(sourceVertex, targetVertex); - } - catch (GraphCycleProhibitedException ex) { - throw new IllegalArgumentException(format("found cycle: %s column: %s", targetTable, targetColumn)); - } - } - sourceVertex.columnNames.add(sourceColumnName); - // recursively create column lineage - collectRequiredFields(fullSourceColumnName, graph, vertexes); - }); - } - - private boolean skipAddEdge(QualifiedName sourceColumn, QualifiedName targetColumn) - { - // calculated field could be dependent on non-calculated field in the same model - return getTable(sourceColumn).equals(getTable(targetColumn)) - && isCalculated(targetColumn) - && !isCalculated(sourceColumn); - } - - private boolean isCalculated(QualifiedName fullColumnName) - { - return mdl.getModel(getTable(fullColumnName)) - .map(Model::getColumns) - .orElseGet(ImmutableList::of) - .stream() - .filter(column -> column.getName().equals(getColumn(fullColumnName))) - .anyMatch(Column::isCalculated); - } - - public static class Vertex - { - private final String name; - private final Set columnNames; - - public Vertex(String name) - { - this(name, new HashSet<>()); - } - - @VisibleForTesting - public Vertex(String name, Set columnNames) - { - this.name = requireNonNull(name); - this.columnNames = requireNonNull(columnNames); - } - - public String getName() - { - return name; - } - - public Set getColumnNames() - { - return columnNames; - } - } - - /** - * Collect the required source columns in given expression. Note that this method will only trace - * the columns currently utilized in the expression, without further tracking to identify the columns required - * behind those used in the expression. - * - * @param mdl WrenMDL - * @param model the model that column expression belongs to. - * @param column column to analyze source columns. - * @return A SetMultimap which key is model name and value is a set of column names. - */ - private static SetMultimap getSourceColumns(WrenMDL mdl, Model model, Column column) - { - Expression expression; - // TODO: current column expression allow not empty (i.e. its expression is the same as column name) - // we should not directly use dto object, instead, we should convert them into another object. and fill the expression in every column. - expression = io.wren.base.sqlrewrite.Utils.parseExpression(column.getSqlExpression()); - Analyzer analyzer = new Analyzer(mdl, model, column); - analyzer.process(expression); - return analyzer.getSourceColumns(); - } - - private static SetMultimap getSourceColumns(WrenMDL mdl, Metric metric, Column column) - { - Expression expression; - // TODO: current column expression allow not empty (i.e. its expression is the same as column name) - // we should not directly use dto object, instead, we should convert them into another object. and fill the expression in every column. - expression = io.wren.base.sqlrewrite.Utils.parseExpression(column.getSqlExpression()); - MetricAnalyzer analyzer = new MetricAnalyzer(mdl, metric, column); - analyzer.process(expression); - return analyzer.getSourceColumns(); - } - - private static class MetricAnalyzer - extends DefaultTraversalVisitor - { - private final WrenMDL mdl; - private final Metric metric; - private final SetMultimap sourceColumns = HashMultimap.create(); - - private MetricAnalyzer(WrenMDL mdl, Metric metric, Column column) - { - this.mdl = requireNonNull(mdl); - this.metric = requireNonNull(metric); - } - - @Override - protected Void visitDereferenceExpression(DereferenceExpression node, Void ignored) - { - QualifiedName qualifiedName = getQualifiedName(node); - if (qualifiedName == null) { - return null; - } - Optional parentModel = mdl.getModel(metric.getBaseObject()); - if (parentModel.isPresent()) { - Optional relationshipInfo = ExpressionRelationshipAnalyzer.createRelationshipInfo(qualifiedName, parentModel.get(), mdl).stream() - .filter(info -> info.getRelationships().size() > 0) - .filter(info -> info.getRemainingParts().size() > 0) - .findAny(); - relationshipInfo.ifPresent(info -> { - // collect relationship columns - for (RelationshipColumnInfo rsInfo : info.getRelationshipColumnInfos()) { - sourceColumns.put(rsInfo.getModel().getName(), rsInfo.getColumn().getName()); - } - // collect last relationship output column - Relationship relationship = info.getRelationshipColumnInfos().get(info.getRelationshipColumnInfos().size() - 1).getNormalizedRelationship(); - String columnName = info.getRemainingParts().get(info.getRemainingParts().size() - 1); - String modelName = relationship.getModels().get(1); - sourceColumns.put(modelName, columnName); - }); - } - return null; - } - - @Override - protected Void visitIdentifier(Identifier node, Void ignored) - { - // TODO: exclude sql reserved words - if (isColumnExist(mdl, metric.getBaseObject(), node.getValue())) { - sourceColumns.put(metric.getBaseObject(), node.getValue()); - } - return null; - } - - public SetMultimap getSourceColumns() - { - return sourceColumns; - } - } - - private static class Analyzer - extends DefaultTraversalVisitor - { - private final WrenMDL mdl; - private final Model model; - private final Column column; - private final SetMultimap sourceColumns = HashMultimap.create(); - - private Analyzer(WrenMDL mdl, Model model, Column column) - { - this.mdl = requireNonNull(mdl); - this.model = requireNonNull(model); - this.column = requireNonNull(column); - } - - @Override - protected Void visitDereferenceExpression(DereferenceExpression node, Void ignored) - { - QualifiedName qualifiedName = getQualifiedName(node); - if (qualifiedName == null) { - return null; - } - if (column.isCalculated()) { - Optional relationshipInfo = ExpressionRelationshipAnalyzer.createRelationshipInfo(qualifiedName, model, mdl).stream() - .filter(info -> info.getRelationships().size() > 0) - .filter(info -> info.getRemainingParts().size() > 0) - .findAny(); - relationshipInfo.ifPresent(info -> { - // collect relationship columns - for (RelationshipColumnInfo rsInfo : info.getRelationshipColumnInfos()) { - sourceColumns.put(rsInfo.getModel().getName(), rsInfo.getColumn().getName()); - } - // collect last relationship output column - Relationship relationship = info.getRelationshipColumnInfos().get(info.getRelationshipColumnInfos().size() - 1).getNormalizedRelationship(); - String columnName = info.getRemainingParts().get(info.getRemainingParts().size() - 1); - String modelName = relationship.getModels().get(1); - sourceColumns.put(modelName, columnName); - }); - } - return null; - } - - @Override - protected Void visitIdentifier(Identifier node, Void ignored) - { - // TODO: exclude sql reserved words - // if a column is calculated, it could only use non calculated columns defined in the current model. - if (column.isCalculated()) { - model.getColumns().stream() - .filter(column -> !column.isCalculated()) - .filter(column -> node.getValue().equals(column.getName())) - .findAny() - .ifPresent(column -> sourceColumns.put(model.getName(), node.getValue())); - } - // handle non-calculated column - else { - if (model.getBaseObject() == null) { - return null; - } - if (isColumnExist(mdl, model.getBaseObject(), node.getValue())) { - sourceColumns.put(model.getBaseObject(), node.getValue()); - } - } - return null; - } - - public SetMultimap getSourceColumns() - { - return sourceColumns; - } - } - - public static Optional getJoinKey(Expression expression, String modelName) - { - JoinKey joinKey = new JoinKey(); - joinKey.process(expression); - return Optional.ofNullable(joinKey.getJoinKeys().get(modelName)); - } - - private static class JoinKey - extends DefaultTraversalVisitor - { - private final Map joinKeys = new HashMap<>(); - - @Override - protected Void visitDereferenceExpression(DereferenceExpression node, Void context) - { - QualifiedName qualifiedName = DereferenceExpression.getQualifiedName(node); - if (qualifiedName != null && qualifiedName.getParts().size() == 2) { - joinKeys.put(qualifiedName.getParts().get(0), qualifiedName.getParts().get(1)); - } - return null; - } - - public Map getJoinKeys() - { - return joinKeys; - } - } - - public static String getTable(QualifiedName qualifiedName) - { - return qualifiedName.getParts().get(0); - } - - public static String getColumn(QualifiedName qualifiedName) - { - return qualifiedName.getParts().get(1); - } - - private static boolean isColumnExist(WrenMDL mdl, String objectName, String columnName) - { - if (mdl.getModel(objectName).isPresent()) { - return mdl.getModel(objectName).get().getColumns().stream() - .anyMatch(column -> columnName.equals(column.getName())); - } - else if (mdl.getMetric(objectName).isPresent()) { - return mdl.getMetric(objectName).get().getColumns().stream() - .anyMatch(column -> columnName.equals(column.getName())); - } - else if (mdl.getCumulativeMetric(objectName).isPresent()) { - CumulativeMetric cumulativeMetric = mdl.getCumulativeMetric(objectName).get(); - return cumulativeMetric.getMeasure().getName().equals(columnName) - || cumulativeMetric.getWindow().getName().equals(columnName); - } - return false; - } - - private static String getBaseObject(WrenMDL mdl, String objectName) - { - if (mdl.getModel(objectName).isPresent()) { - return mdl.getModel(objectName).get().getBaseObject(); - } - else if (mdl.getMetric(objectName).isPresent()) { - return mdl.getMetric(objectName).get().getBaseObject(); - } - else if (mdl.getCumulativeMetric(objectName).isPresent()) { - return mdl.getCumulativeMetric(objectName).get().getBaseObject(); - } - return null; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenPlanner.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenPlanner.java deleted file mode 100644 index d6072d9ca..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenPlanner.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.SqlFormatter; -import io.trino.sql.parser.SqlParser; -import io.trino.sql.tree.Statement; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; - -import java.util.List; - -import static io.wren.base.sqlrewrite.EnumRewrite.ENUM_REWRITE; -import static io.wren.base.sqlrewrite.MetricRollupRewrite.METRIC_ROLLUP_REWRITE; -import static io.wren.base.sqlrewrite.Utils.parseSql; -import static io.wren.base.sqlrewrite.WrenSqlRewrite.WREN_SQL_REWRITE; - -public class WrenPlanner -{ - public static final List ALL_RULES = List.of( - GenerateViewRewrite.GENERATE_VIEW_REWRITE, - METRIC_ROLLUP_REWRITE, - WREN_SQL_REWRITE, - ENUM_REWRITE); - private static final SqlParser SQL_PARSER = new SqlParser(); - - private WrenPlanner() {} - - public static String rewrite(String sql, SessionContext sessionContext, AnalyzedMDL analyzedMDL) - { - return rewrite(sql, sessionContext, analyzedMDL, ALL_RULES); - } - - public static String rewrite(String sql, SessionContext sessionContext, AnalyzedMDL analyzedMDL, List rules) - { - Statement statement = parseSql(sql); - for (WrenRule rule : rules) { - // we will replace or rewrite sql node in sql rewrite, to avoid rewrite rules affect each other, format and parse sql before each rewrite - statement = rule.apply(parseSql(SqlFormatter.formatSql(statement)), sessionContext, analyzedMDL); - } - return SqlFormatter.formatSql(statement); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenRule.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenRule.java deleted file mode 100644 index 604c9b675..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenRule.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Statement; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.sqlrewrite.analyzer.Analysis; - -public interface WrenRule -{ - Statement apply(Statement root, SessionContext sessionContext, AnalyzedMDL analyzedMDL); - - Statement apply(Statement root, SessionContext sessionContext, Analysis analysis, AnalyzedMDL analyzedMDL); -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenSqlRewrite.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenSqlRewrite.java deleted file mode 100644 index a98b5def9..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/WrenSqlRewrite.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Iterables; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.WithQuery; -import io.wren.base.AnalyzedMDL; -import io.wren.base.CatalogSchemaTableName; -import io.wren.base.SessionContext; -import io.wren.base.Utils; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationable; -import io.wren.base.sqlrewrite.analyzer.Analysis; -import io.wren.base.sqlrewrite.analyzer.Scope; -import io.wren.base.sqlrewrite.analyzer.StatementAnalyzer; -import org.jgrapht.graph.DirectedAcyclicGraph; -import org.jgrapht.graph.GraphCycleProhibitedException; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import static com.google.common.base.Strings.nullToEmpty; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static io.wren.base.sqlrewrite.Utils.toCatalogSchemaTableName; -import static java.lang.String.format; -import static java.util.stream.Collectors.toMap; -import static java.util.stream.Collectors.toSet; - -public class WrenSqlRewrite - implements WrenRule -{ - public static final WrenSqlRewrite WREN_SQL_REWRITE = new WrenSqlRewrite(); - - private WrenSqlRewrite() {} - - private static LinkedHashMap> getTableRequiredFields(WrenDataLineage dataLineage, Analysis analysis) - { - List collectedColumns = analysis.getCollectedColumns().asMap().entrySet().stream() - .map(e -> - e.getValue().stream() - .map(columnName -> QualifiedName.of(e.getKey().getSchemaTableName().getTableName(), columnName)) - .collect(toImmutableList())) - .flatMap(List::stream) - .collect(toImmutableList()); - - return dataLineage.getRequiredFields(collectedColumns); - } - - @Override - public Statement apply(Statement root, SessionContext sessionContext, AnalyzedMDL analyzedMDL) - { - Analysis analysis = new Analysis(root); - StatementAnalyzer.analyze(analysis, root, sessionContext, analyzedMDL.getWrenMDL()); - return apply(root, sessionContext, analysis, analyzedMDL); - } - - @Override - public Statement apply(Statement root, SessionContext sessionContext, Analysis analysis, AnalyzedMDL analyzedMDL) - { - WrenMDL wrenMDL = analyzedMDL.getWrenMDL(); - Set allDescriptors; - // TODO: Currently DynamicCalculatedField is a experimental feature, and buggy. After all issues are solved, - // we should always enable this setting. - if (sessionContext.isEnableDynamicField()) { - Set visitedTables = analysis.getTables().stream().filter(table -> wrenMDL.getView(table).isEmpty()).collect(toSet()); - LinkedHashMap> tableRequiredFields = getTableRequiredFields(analyzedMDL.getWrenDataLineage(), analysis).entrySet().stream() - .filter(e -> wrenMDL.getView(e.getKey()).isEmpty()) - .collect(toMap(Map.Entry::getKey, Map.Entry::getValue, (a, b) -> a, LinkedHashMap::new)); - - // Some node be applied `count(*)` which won't be collected but its source is required. - analysis.getRequiredSourceNodes().forEach(node -> { - Scope scope = analysis.getScope(node); - if (tryGetTableName(node).flatMap(name -> scope.getNamedQuery(name.toString())).isEmpty()) { - String tableName = analysis.getSourceNodeNames(node).map(QualifiedName::toString) - .orElseThrow(() -> new IllegalArgumentException(format("source node name not found: %s", node))); - if (!tableRequiredFields.containsKey(tableName)) { - Relationable relationable = wrenMDL.getRelationable(tableName) - .orElseThrow(() -> new IllegalArgumentException(format("dataset not found: %s", tableName))); - tableRequiredFields.put(tableName, relationable.getColumns().stream().filter(column -> !column.isCalculated()).map(Column::getName).collect(toImmutableSet())); - } - } - }); - - ImmutableList.Builder descriptorsBuilder = ImmutableList.builder(); - tableRequiredFields.forEach((name, value) -> { - addDescriptor(name, value, wrenMDL, descriptorsBuilder); - visitedTables.remove(toCatalogSchemaTableName(sessionContext, QualifiedName.of(name))); - }); - - List withQueries = new ArrayList<>(); - // add date spine if needed - if (tableRequiredFields.keySet().stream() - .map(wrenMDL::getCumulativeMetric) - .anyMatch(Optional::isPresent)) { - withQueries.add(WithRewriter.getWithQuery(DateSpineInfo.get(wrenMDL.getDateSpine()))); - } - descriptorsBuilder.build().forEach(queryDescriptor -> withQueries.add(WithRewriter.getWithQuery(queryDescriptor))); - - // If a selected table lacks any required fields, create a dummy with query for it. - visitedTables.stream().filter(table -> wrenMDL.isObjectExist(table.getSchemaTableName().getTableName())) - .forEach(dummy -> withQueries.add(WithRewriter.getWithQuery(new DummyInfo(dummy.getSchemaTableName().getTableName())))); - - Node rewriteWith = new WithRewriter(withQueries).process(root); - return (Statement) new Rewriter(wrenMDL, analysis).process(rewriteWith); - } - else { - Set modelDescriptors = analysis.getModels().stream().map(model -> RelationInfo.get(model, wrenMDL)).collect(toSet()); - Set metricDescriptors = analysis.getMetrics().stream().map(metric -> RelationInfo.get(metric, wrenMDL)).collect(toSet()); - Set cumulativeMetricDescriptors = analysis.getCumulativeMetrics().stream().map(metric -> CumulativeMetricInfo.get(metric, wrenMDL)).collect(toSet()); - allDescriptors = ImmutableSet.builder() - .addAll(modelDescriptors) - .addAll(metricDescriptors) - .addAll(cumulativeMetricDescriptors) - .build(); - return apply(root, sessionContext, analysis, analyzedMDL, allDescriptors); - } - } - - private Optional tryGetTableName(Node node) - { - if (node instanceof Table) { - return Optional.of(((Table) node).getName()); - } - return Optional.empty(); - } - - private void addDescriptor(String name, Set requiredFields, WrenMDL wrenMDL, ImmutableList.Builder descriptorsBuilder) - { - if (wrenMDL.getModel(name).isPresent()) { - Model model = wrenMDL.getModel(name).get(); - descriptorsBuilder.add(RelationInfo.get(model, wrenMDL, requiredFields)); - } - else if (wrenMDL.getMetric(name).isPresent()) { - Metric metric = wrenMDL.getMetric(name).get(); - descriptorsBuilder.add(RelationInfo.get(metric, wrenMDL, requiredFields)); - } - else if (wrenMDL.getCumulativeMetric(name).isPresent()) { - CumulativeMetric cumulativeMetric = wrenMDL.getCumulativeMetric(name).get(); - descriptorsBuilder.add(CumulativeMetricInfo.get(cumulativeMetric, wrenMDL)); - } - // If the table is not found in mdl, it could be a remote table or a CTE. - } - - private void addDescriptor(String name, WrenMDL wrenMDL, ImmutableList.Builder descriptorsBuilder) - { - if (wrenMDL.getModel(name).isPresent()) { - Model model = wrenMDL.getModel(name).get(); - descriptorsBuilder.add(RelationInfo.get(model, wrenMDL)); - } - else if (wrenMDL.getMetric(name).isPresent()) { - Metric metric = wrenMDL.getMetric(name).get(); - descriptorsBuilder.add(RelationInfo.get(metric, wrenMDL)); - } - else if (wrenMDL.getCumulativeMetric(name).isPresent()) { - CumulativeMetric cumulativeMetric = wrenMDL.getCumulativeMetric(name).get(); - descriptorsBuilder.add(CumulativeMetricInfo.get(cumulativeMetric, wrenMDL)); - } - // If the table is not found in mdl, it could be a remote table or a CTE. - } - - private Statement apply( - Statement root, - SessionContext sessionContext, - Analysis analysis, - AnalyzedMDL analyzedMDL, - Set allDescriptors) - { - DirectedAcyclicGraph graph = new DirectedAcyclicGraph<>(Object.class); - Set requiredQueryDescriptors = new HashSet<>(); - // add to graph - allDescriptors.forEach(queryDescriptor -> addSqlDescriptorToGraph(queryDescriptor, graph, analyzedMDL, requiredQueryDescriptors, sessionContext)); - - Map descriptorMap = new HashMap<>(); - allDescriptors.forEach(queryDescriptor -> descriptorMap.put(queryDescriptor.getName(), queryDescriptor)); - requiredQueryDescriptors.forEach(queryDescriptor -> descriptorMap.put(queryDescriptor.getName(), queryDescriptor)); - - List withQueries = new ArrayList<>(); - graph.iterator().forEachRemaining(objectName -> { - QueryDescriptor queryDescriptor = descriptorMap.get(objectName); - Utils.checkArgument(queryDescriptor != null, objectName + " not found in query descriptors"); - withQueries.add(WithRewriter.getWithQuery(queryDescriptor)); - }); - - Node rewriteWith = new WithRewriter(withQueries).process(root); - return (Statement) new Rewriter(analyzedMDL.getWrenMDL(), analysis).process(rewriteWith); - } - - private static void addSqlDescriptorToGraph( - QueryDescriptor queryDescriptor, - DirectedAcyclicGraph graph, - AnalyzedMDL analyzedMDL, - Set queryDescriptors, - SessionContext sessionContext) - { - // add vertex - graph.addVertex(queryDescriptor.getName()); - queryDescriptor.getRequiredObjects().forEach(graph::addVertex); - - //add edge - try { - queryDescriptor.getRequiredObjects().forEach(modelName -> - graph.addEdge(modelName, queryDescriptor.getName())); - } - catch (GraphCycleProhibitedException ex) { - throw new IllegalArgumentException("found cycle in models", ex); - } - - // add required models to graph - for (String objectName : queryDescriptor.getRequiredObjects()) { - QueryDescriptor descriptor = QueryDescriptor.of(objectName, analyzedMDL, sessionContext); - queryDescriptors.add(descriptor); - addSqlDescriptorToGraph(descriptor, graph, analyzedMDL, queryDescriptors, sessionContext); - } - } - - private static class Rewriter - extends BaseRewriter - { - private final WrenMDL wrenMDL; - private final Analysis analysis; - - Rewriter(WrenMDL wrenMDL, Analysis analysis) - { - this.analysis = analysis; - this.wrenMDL = wrenMDL; - } - - @Override - protected Node visitTable(Table node, Void context) - { - Node result = node; - if (analysis.getSourceNodeNames(node).isPresent()) { - result = applyModelRule(node); - } - return result; - } - - // remove catalog schema from expression if exist since all tables are in with cte - @Override - protected Node visitDereferenceExpression(DereferenceExpression dereferenceExpression, Void context) - { - QualifiedName qualifiedName = DereferenceExpression.getQualifiedName(dereferenceExpression); - if (qualifiedName != null && !nullToEmpty(wrenMDL.getCatalog()).isEmpty() && !nullToEmpty(wrenMDL.getSchema()).isEmpty()) { - if (qualifiedName.hasPrefix(QualifiedName.of(wrenMDL.getCatalog(), wrenMDL.getSchema()))) { - return DereferenceExpression.from( - QualifiedName.of(qualifiedName.getOriginalParts().subList(2, qualifiedName.getOriginalParts().size()))); - } - if (qualifiedName.hasPrefix(QualifiedName.of(wrenMDL.getSchema()))) { - return DereferenceExpression.from( - QualifiedName.of(qualifiedName.getOriginalParts().subList(1, qualifiedName.getOriginalParts().size()))); - } - } - return dereferenceExpression; - } - - // the model is added in with query, and the catalog and schema should be removed - private Node applyModelRule(Table table) - { - return new Table(QualifiedName.of(ImmutableList.of(Iterables.getLast(table.getName().getOriginalParts())))); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Analysis.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Analysis.java deleted file mode 100644 index 684ddc5f1..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Analysis.java +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableSet; -import com.google.common.collect.Multimap; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FunctionRelation; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NodeRef; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Statement; -import io.wren.base.CatalogSchemaTableName; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; -import io.wren.base.dto.View; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; - -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toSet; - -public class Analysis -{ - private final Statement root; - private final Map, Scope> scopes = new LinkedHashMap<>(); - - private final Set tables = new HashSet<>(); - private final Set relationships = new HashSet<>(); - private final Set models = new HashSet<>(); - private final Set metrics = new HashSet<>(); - private final Map, MetricRollupInfo> metricRollups = new HashMap<>(); - - private final Set cumulativeMetrics = new HashSet<>(); - private final Set views = new HashSet<>(); - private final Multimap collectedColumns = HashMultimap.create(); - private final Map, Field> referenceFields = new HashMap<>(); - - private final Set requiredSourceNodes = new HashSet<>(); - - private final Map, QualifiedName> sourceNodeNames = new HashMap<>(); - private final Map, Node> typeCoercionMap = new HashMap<>(); - - public Analysis(Statement statement) - { - this.root = requireNonNull(statement, "statement is null"); - } - - public Statement getRoot() - { - return root; - } - - void addTable(CatalogSchemaTableName tableName) - { - tables.add(tableName); - } - - public Set getTables() - { - return Set.copyOf(tables); - } - - public Set getRelationships() - { - return relationships; - } - - void addModels(Set models) - { - this.models.addAll(models); - } - - public Set getModels() - { - return models; - } - - void addMetrics(Set metrics) - { - this.metrics.addAll(metrics); - } - - public Set getMetrics() - { - return metrics; - } - - void addMetricRollups(NodeRef metricRollupNodeRef, MetricRollupInfo metricRollupInfo) - { - metricRollups.put(metricRollupNodeRef, metricRollupInfo); - } - - public Map, MetricRollupInfo> getMetricRollups() - { - return metricRollups; - } - - void addCumulativeMetrics(Set cumulativeMetrics) - { - this.cumulativeMetrics.addAll(cumulativeMetrics); - } - - public Set getCumulativeMetrics() - { - return cumulativeMetrics; - } - - public Set getViews() - { - return views; - } - - void addViews(Set views) - { - this.views.addAll(views); - } - - public Set getWrenObjectNames() - { - return ImmutableSet.builder() - .addAll(getModels().stream().map(Model::getName).collect(toSet())) - .addAll(getMetrics().stream().map(Metric::getName).collect(toSet())) - .addAll(getCumulativeMetrics().stream().map(CumulativeMetric::getName).collect(toSet())) - .addAll(getViews().stream().map(View::getName).collect(toSet())) - .build(); - } - - void addCollectedColumns(List fields) - { - fields.forEach(field -> collectedColumns.put(field.getTableName(), field.getColumnName())); - } - - public Multimap getCollectedColumns() - { - return collectedColumns; - } - - public void addReferenceFields(Map, Field> referenceFields) - { - this.referenceFields.putAll(referenceFields); - } - - public Map, Field> getReferenceFields() - { - return referenceFields; - } - - void addTypeCoercion(NodeRef nodeRef, Node node) - { - typeCoercionMap.put(nodeRef, node); - } - - public Map, Node> getTypeCoercionMap() - { - return typeCoercionMap; - } - - public Scope getScope(Node node) - { - return tryGetScope(node).orElseThrow(() -> new IllegalArgumentException(format("Analysis does not contain information for node: %s", node))); - } - - public Optional tryGetScope(Node node) - { - NodeRef key = NodeRef.of(node); - if (scopes.containsKey(key)) { - return Optional.of(scopes.get(key)); - } - - return Optional.empty(); - } - - public Scope getRootScope() - { - return getScope(root); - } - - public void setScope(Node node, Scope scope) - { - scopes.put(NodeRef.of(node), scope); - } - - public Map, Scope> getScopes() - { - return scopes; - } - - public Set getRequiredSourceNodes() - { - return requiredSourceNodes; - } - - public void addRequiredSourceNode(Node node) - { - requiredSourceNodes.add(node); - } - - public Optional getSourceNodeNames(Node node) - { - return Optional.ofNullable(sourceNodeNames.get(NodeRef.of(node))); - } - - public void addSourceNodeName(NodeRef nodeRef, QualifiedName name) - { - sourceNodeNames.put(nodeRef, name); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/CacheAnalysis.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/CacheAnalysis.java deleted file mode 100644 index bae0f23f2..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/CacheAnalysis.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.wren.base.CatalogSchemaTableName; - -import java.util.HashSet; -import java.util.Set; - -public class CacheAnalysis -{ - private final Set tables = new HashSet<>(); - private final Set cachedTables = new HashSet<>(); - - public void addTable(CatalogSchemaTableName tableName) - { - tables.add(tableName); - } - - public void addCachedTables(CatalogSchemaTableName cachedTables) - { - this.cachedTables.add(cachedTables); - } - - public boolean onlyCachedTables() - { - return cachedTables.size() > 0 && tables.equals(cachedTables); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionAnalysis.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionAnalysis.java deleted file mode 100644 index 08e9135bb..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionAnalysis.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.NodeRef; - -import java.util.List; -import java.util.Map; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.util.Objects.requireNonNull; - -public class ExpressionAnalysis -{ - private final List collectedFields; - private final Map, Field> referencedFields; - private final List predicates; - // For `count(*)` expression, we should generate the specific CTE for it. - private final boolean requireRelation; - - public ExpressionAnalysis(Map, Field> referenceFields, List predicates, boolean requireRelation) - { - this.referencedFields = requireNonNull(referenceFields); - this.collectedFields = referenceFields.values().stream().collect(toImmutableList()); - this.predicates = requireNonNull(predicates); - this.requireRelation = requireRelation; - } - - public List getCollectedFields() - { - return collectedFields; - } - - public Map, Field> getReferencedFields() - { - return referencedFields; - } - - public List getPredicates() - { - return predicates; - } - - public boolean isRequireRelation() - { - return requireRelation; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionAnalyzer.java deleted file mode 100644 index 62231e705..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionAnalyzer.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FrameBound; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.NodeRef; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.SubqueryExpression; -import io.trino.sql.tree.SubscriptExpression; -import io.trino.sql.tree.Window; -import io.trino.sql.tree.WindowOperation; -import io.trino.sql.tree.WindowSpecification; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class ExpressionAnalyzer -{ - private ExpressionAnalyzer() {} - - public static ExpressionAnalysis analyze(Scope scope, Expression expression, SessionContext sessionContext, WrenMDL wrenMDL, Analysis analysis) - { - ExpressionVisitor visitor = new ExpressionVisitor(scope, sessionContext, wrenMDL, analysis); - visitor.process(expression); - - return new ExpressionAnalysis(visitor.getReferenceFields(), visitor.getPredicates(), visitor.isRequireRelation()); - } - - private static class ExpressionVisitor - extends DefaultTraversalVisitor - { - private final Scope scope; - private final WrenMDL wrenMDL; - private final SessionContext sessionContext; - private final Analysis analysis; - private final Map, Field> referenceFields = new HashMap<>(); - private final List predicates = new ArrayList<>(); - private boolean requireRelation; - - public ExpressionVisitor( - Scope scope, - SessionContext sessionContext, - WrenMDL wrenMDL, - Analysis analysis) - { - this.scope = requireNonNull(scope, "scope is null"); - this.sessionContext = requireNonNull(sessionContext, "sessionContext is null"); - this.wrenMDL = requireNonNull(wrenMDL, "wrenMDL is null"); - this.analysis = requireNonNull(analysis, "analysis is null"); - } - - @Override - protected Void visitDereferenceExpression(DereferenceExpression node, Void context) - { - QualifiedName qualifiedName = getQualifiedName(node); - if (qualifiedName != null) { - scope.resolveAnyField(qualifiedName) - .ifPresent(field -> referenceFields.put(NodeRef.of(node), field)); - } - else { - // The base could be SubscriptExpression, so we need to process it - process(node.getBase()); - } - - return null; - } - - @Override - protected Void visitIdentifier(Identifier node, Void context) - { - QualifiedName qualifiedName = QualifiedName.of(ImmutableList.of(node)); - scope.resolveAnyField(qualifiedName) - .ifPresent(field -> referenceFields.put(NodeRef.of(node), field)); - return null; - } - - @Override - protected Void visitSubscriptExpression(SubscriptExpression node, Void context) - { - QualifiedName qualifiedName = getQualifiedName(node.getBase()); - scope.resolveAnyField(qualifiedName) - .ifPresent(field -> referenceFields.put(NodeRef.of(node), field)); - return null; - } - - @Override - protected Void visitComparisonExpression(ComparisonExpression node, Void context) - { - process(node.getLeft()); - process(node.getRight()); - predicates.add(node); - return null; - } - - @Override - protected Void visitFunctionCall(FunctionCall node, Void context) - { - if (node.getName().getSuffix().equalsIgnoreCase("count") && node.getArguments().isEmpty()) { - requireRelation = true; - return null; - } - node.getArguments().forEach(this::process); - node.getWindow().ifPresent(this::analyzeWindow); - node.getFilter().ifPresent(this::process); - node.getOrderBy().ifPresent(orderBy -> orderBy.getSortItems().forEach(sortItem -> process(sortItem.getSortKey()))); - return null; - } - - @Override - protected Void visitSubqueryExpression(SubqueryExpression node, Void context) - { - StatementAnalyzer.analyze(analysis, node.getQuery(), sessionContext, wrenMDL, Optional.of(scope)); - return null; - } - - @Override - protected Void visitWindowOperation(WindowOperation node, Void context) - { - analyzeWindow(node.getWindow()); - return null; - } - - private void analyzeWindow(Window window) - { - if (window instanceof WindowSpecification windowSpecification) { - windowSpecification.getPartitionBy().forEach(this::process); - windowSpecification.getOrderBy().ifPresent(orderBy -> orderBy.getSortItems().forEach(sortItem -> process(sortItem.getSortKey()))); - windowSpecification.getFrame().ifPresent(frame -> { - frame.getStart().getValue().ifPresent(this::process); - frame.getEnd().flatMap(FrameBound::getValue).ifPresent(this::process); - }); - } - } - - public Map, Field> getReferenceFields() - { - return referenceFields; - } - - public List getPredicates() - { - return predicates; - } - - public boolean isRequireRelation() - { - return requireRelation; - } - } - - private static QualifiedName getQualifiedName(Expression expression) - { - return switch (expression) { - case DereferenceExpression dereferenceExpression -> DereferenceExpression.getQualifiedName(dereferenceExpression); - case Identifier identifier -> QualifiedName.of(ImmutableList.of(identifier)); - default -> null; - }; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionRelationshipAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionRelationshipAnalyzer.java deleted file mode 100644 index 22ca6392f..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionRelationshipAnalyzer.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import com.google.common.collect.ImmutableSet; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.QualifiedName; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.NoSuchElementException; -import java.util.Optional; -import java.util.Set; - -import static com.google.common.base.Preconditions.checkArgument; -import static io.trino.sql.tree.DereferenceExpression.getQualifiedName; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; - -public class ExpressionRelationshipAnalyzer -{ - private ExpressionRelationshipAnalyzer() {} - - /** - * Collect to-1 relationships in model field expression, will throw error if to-N relationship(s) exist in expression. - * - * @param expression model field expression - * @param mdl wren mdl - * @param model the model that expression belongs to - * @return ExpressionRelationshipInfo - */ - public static Set getToOneRelationships(Expression expression, WrenMDL mdl, Model model) - { - RelationshipCollector collector = new RelationshipCollector(mdl, model, false); - collector.process(expression); - return collector.getExpressionRelationshipInfo(); - } - - /** - * Collect relationships (to-1 and to-N) in model field expression. - * - * @param expression model field expression - * @param mdl wren mdl - * @param model the model that expression belongs to - * @return ExpressionRelationshipInfo - */ - public static Set getRelationships(Expression expression, WrenMDL mdl, Model model) - { - RelationshipCollector collector = new RelationshipCollector(mdl, model, true); - collector.process(expression); - return collector.getExpressionRelationshipInfo(); - } - - private static class RelationshipCollector - extends DefaultTraversalVisitor - { - private final WrenMDL wrenMDL; - private final Model model; - private final boolean allowToManyRelationship; - private final Set relationships = new HashSet<>(); - - public RelationshipCollector(WrenMDL wrenMDL, Model model, boolean allowToManyRelationship) - { - this.wrenMDL = requireNonNull(wrenMDL); - this.model = requireNonNull(model); - this.allowToManyRelationship = allowToManyRelationship; - } - - public Set getExpressionRelationshipInfo() - { - return ImmutableSet.copyOf(relationships); - } - - @Override - protected Void visitDereferenceExpression(DereferenceExpression node, Void ignored) - { - if (node.getField().isPresent()) { - QualifiedName qualifiedName = getQualifiedName(node); - if (qualifiedName != null) { - Optional expressionRelationshipInfo = createRelationshipInfo(qualifiedName, model, wrenMDL); - if (expressionRelationshipInfo.isPresent()) { - if (!allowToManyRelationship) { - validateToOne(expressionRelationshipInfo.get()); - } - relationships.add(expressionRelationshipInfo.get()); - } - } - } - return null; - } - } - - public static Optional createRelationshipInfo(QualifiedName qualifiedName, Model model, WrenMDL mdl) - { - List relationshipColumnInfos = new ArrayList<>(); - Model current = model; - Relationship baseModelRelationship = null; - - for (int i = 0; i < qualifiedName.getParts().size(); i++) { - String columnName = qualifiedName.getParts().get(i); - Optional relationshipColumnOpt = WrenMDL.getRelationshipColumn(current, columnName); - - if (relationshipColumnOpt.isEmpty()) { - if (i == 0) { - return Optional.empty(); - } - return buildExpressionRelationshipInfo(qualifiedName, relationshipColumnInfos, baseModelRelationship, i); - } - - Column relationshipColumn = relationshipColumnOpt.get(); - Relationship relationship = getRelationshipFromMDL(relationshipColumn, mdl); - relationshipColumnInfos.add(new RelationshipColumnInfo(current, relationshipColumn, relationship)); - if (current == model) { - baseModelRelationship = relationship; - } - - current = getNextModel(relationshipColumn, mdl); - checkForCycle(current, model); - } - - return Optional.empty(); - } - - private static Relationship getRelationshipFromMDL(Column relationshipColumn, WrenMDL mdl) - { - String relationshipName = relationshipColumn.getRelationship().get(); - return mdl.getRelationship(relationshipName) - .orElseThrow(() -> new NoSuchElementException(format("relationship %s not found", relationshipName))); - } - - private static Model getNextModel(Column relationshipColumn, WrenMDL mdl) - { - return mdl.getModel(relationshipColumn.getType()) - .orElseThrow(() -> new NoSuchElementException(format("model %s not found", relationshipColumn.getType()))); - } - - private static void checkForCycle(Model current, Model model) - { - checkArgument(current != model, "found cycle in expression"); - } - - private static Optional buildExpressionRelationshipInfo( - QualifiedName qualifiedName, - List relationshipColumnInfos, - Relationship baseModelRelationship, - int index) - { - return Optional.of(new ExpressionRelationshipInfo( - qualifiedName, - qualifiedName.getParts().subList(0, index), - qualifiedName.getParts().subList(index, qualifiedName.getParts().size()), - relationshipColumnInfos, - baseModelRelationship)); - } - - private static void validateToOne(ExpressionRelationshipInfo expressionRelationshipInfo) - { - for (Relationship relationship : expressionRelationshipInfo.getRelationships()) { - checkArgument(relationship.getJoinType().isToOne(), "expr in model only accept to-one relation"); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionRelationshipInfo.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionRelationshipInfo.java deleted file mode 100644 index 82fc72b4d..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ExpressionRelationshipInfo.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.trino.sql.tree.QualifiedName; -import io.wren.base.Utils; -import io.wren.base.dto.Relationship; - -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static java.util.Objects.requireNonNull; - -public class ExpressionRelationshipInfo -{ - private final QualifiedName qualifiedName; - // for debug usage - private final List relationshipParts; - private final List remainingParts; - private final List relationships; - private final Relationship baseModelRelationship; - private final List relationshipColumnInfos; - - public ExpressionRelationshipInfo( - QualifiedName qualifiedName, - List relationshipParts, - List remainingParts, - List relationshipColumnInfos, - Relationship baseModelRelationship) - { - this.qualifiedName = requireNonNull(qualifiedName); - this.relationshipParts = requireNonNull(relationshipParts); - this.remainingParts = requireNonNull(remainingParts); - this.baseModelRelationship = requireNonNull(baseModelRelationship); - this.relationshipColumnInfos = requireNonNull(relationshipColumnInfos); - this.relationships = relationshipColumnInfos.stream().map(RelationshipColumnInfo::getNormalizedRelationship).collect(toImmutableList()); - Utils.checkArgument(relationshipParts.size() + remainingParts.size() == qualifiedName.getParts().size(), "mismatch part size"); - } - - public QualifiedName getQualifiedName() - { - return qualifiedName; - } - - public List getRemainingParts() - { - return remainingParts; - } - - public List getRelationships() - { - return relationships; - } - - public List getRelationshipColumnInfos() - { - return relationshipColumnInfos; - } - - public Relationship getBaseModelRelationship() - { - return baseModelRelationship; - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("qualifiedName", qualifiedName) - .add("relationshipParts", relationshipParts) - .add("remainingParts", remainingParts) - .add("relationships", relationships) - .add("baseModelRelationship", baseModelRelationship) - .toString(); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ExpressionRelationshipInfo that = (ExpressionRelationshipInfo) o; - return Objects.equals(qualifiedName, that.qualifiedName) && - Objects.equals(relationshipParts, that.relationshipParts) && - Objects.equals(remainingParts, that.remainingParts) && - Objects.equals(relationships, that.relationships) && - Objects.equals(baseModelRelationship, that.baseModelRelationship); - } - - @Override - public int hashCode() - { - return Objects.hash( - qualifiedName, - relationshipParts, - remainingParts, - relationships, - baseModelRelationship); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Field.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Field.java deleted file mode 100644 index cf5f4804c..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Field.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.trino.sql.tree.QualifiedName; -import io.wren.base.CatalogSchemaTableName; -import io.wren.base.dto.Column; -import io.wren.base.sqlrewrite.Utils; - -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -/** - * Inspired by io.trino.sql.analyzer.Field - */ -public class Field -{ - // TODO: go check if relationAlias should be optional - // e.g. select table.col_1 from select * from table; => is this legal ? this is false - private final Optional relationAlias; - private final CatalogSchemaTableName tableName; - // the name of the column in the table - private final String columnName; - // the name of the dataset where the column comes from - private final Optional sourceDatasetName; - // the name of the column in the dataset where the column comes from - private final Optional sourceColumn; - // the name of the column in the query (If the column is aliased, this is the alias, otherwise it's the column name) - private final Optional name; - - private Field( - QualifiedName relationAlias, - CatalogSchemaTableName tableName, - String columnName, - String name, - String sourceDatasetName, - Column sourceColumn) - { - this.relationAlias = Optional.ofNullable(relationAlias); - this.tableName = requireNonNull(tableName, "modelName is null"); - this.columnName = requireNonNull(columnName, "columnName is null"); - this.name = Optional.ofNullable(name); - this.sourceDatasetName = Optional.ofNullable(sourceDatasetName); - this.sourceColumn = Optional.ofNullable(sourceColumn); - } - - public Optional getRelationAlias() - { - return relationAlias; - } - - public CatalogSchemaTableName getTableName() - { - return tableName; - } - - public String getColumnName() - { - return columnName; - } - - public Optional getName() - { - return name; - } - - public Optional getSourceDatasetName() - { - return sourceDatasetName; - } - - public Optional getSourceColumn() - { - return sourceColumn; - } - - public boolean matchesPrefix(Optional prefix) - { - return prefix.isEmpty() || relationAlias.orElse(Utils.toQualifiedName(tableName)).hasSuffix(prefix.get()); - } - - /* - Namespaces can have names such as "x", "x.y" or "" if there's no name - Name to resolve can have names like "a", "x.a", "x.y.a" - - namespace name possible match - "" "a" y - "x" "a" y - "x.y" "a" y - - "" "x.a" n - "x" "x.a" y - "x.y" "x.a" n - - "" "x.y.a" n - "x" "x.y.a" n - "x.y" "x.y.a" n - - "" "y.a" n - "x" "y.a" n - "x.y" "y.a" y - */ - public boolean canResolve(QualifiedName name) - { - if (name == null || this.name.isEmpty()) { - return false; - } - - // TODO: need to know whether the qualified name and the name of this field were quoted - return (matchesPrefix(name.getPrefix()) && this.name.get().equalsIgnoreCase(name.getSuffix())) || - name.getPrefix().map(p -> p.toString().equals(columnName)).orElse(false); // support struct type - } - - @Override - public String toString() - { - return "Field{" + - "relationAlias=" + relationAlias + - ", tableName=" + tableName + - ", columnName='" + columnName + '\'' + - ", name=" + name + - ", sourceDatasetName=" + sourceDatasetName + - ", sourceColumn=" + sourceColumn + - '}'; - } - - public static Builder builder() - { - return new Builder(); - } - - public static class Builder - { - private QualifiedName relationAlias; - private CatalogSchemaTableName tableName; - private String columnName; - private String name; - private String sourceModelName; - private Column sourceColumn; - - public Builder() {} - - public Builder like(Field field) - { - this.relationAlias = field.relationAlias.orElse(null); - this.tableName = field.tableName; - this.columnName = field.columnName; - this.name = field.name.orElse(null); - this.sourceModelName = field.sourceDatasetName.orElse(null); - this.sourceColumn = field.sourceColumn.orElse(null); - return this; - } - - public Builder relationAlias(QualifiedName relationAlias) - { - this.relationAlias = relationAlias; - return this; - } - - public Builder tableName(CatalogSchemaTableName tableName) - { - this.tableName = tableName; - return this; - } - - public Builder columnName(String columnName) - { - this.columnName = columnName; - return this; - } - - public Builder name(String name) - { - this.name = name; - return this; - } - - public Builder sourceModelName(String sourceModelName) - { - this.sourceModelName = sourceModelName; - return this; - } - - public Builder sourceColumn(Column sourceColumn) - { - this.sourceColumn = sourceColumn; - return this; - } - - public Field build() - { - return new Field(relationAlias, tableName, columnName, name, sourceModelName, sourceColumn); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/MetricRollupInfo.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/MetricRollupInfo.java deleted file mode 100644 index d12dcd954..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/MetricRollupInfo.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.wren.base.dto.Metric; -import io.wren.base.dto.TimeGrain; -import io.wren.base.dto.TimeUnit; - -import static java.util.Objects.requireNonNull; - -public class MetricRollupInfo -{ - private final Metric metric; - private final TimeGrain timeGrain; - private final TimeUnit timeUnit; - - public MetricRollupInfo(Metric metric, TimeGrain timeGrain, TimeUnit timeUnit) - { - this.metric = requireNonNull(metric, "metric is null"); - this.timeGrain = requireNonNull(timeGrain, "timeGrain is null"); - this.timeUnit = requireNonNull(timeUnit, "datePart is null"); - } - - public Metric getMetric() - { - return metric; - } - - public TimeGrain getTimeGrain() - { - return timeGrain; - } - - public TimeUnit getDatePart() - { - return timeUnit; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationId.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationId.java deleted file mode 100644 index cd1bd195f..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationId.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NodeRef; - -import java.util.Objects; -import java.util.Optional; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.lang.String.format; -import static java.lang.System.identityHashCode; - -public class RelationId -{ - /** - * Creates {@link RelationId} equal to any {@link RelationId} created from exactly the same source. - */ - public static RelationId of(Node sourceNode) - { - return new RelationId(Optional.of(NodeRef.of(sourceNode))); - } - - /** - * Creates {@link RelationId} equal only to itself - */ - public static RelationId anonymous() - { - return new RelationId(Optional.empty()); - } - - private final Optional> sourceNode; - - private RelationId(Optional> sourceNode) - { - this.sourceNode = sourceNode; - } - - public boolean isAnonymous() - { - return sourceNode.isEmpty(); - } - - public Optional getSourceNode() - { - return sourceNode.map(NodeRef::getNode); - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - RelationId that = (RelationId) o; - return sourceNode.isPresent() && that.sourceNode.isPresent() && sourceNode.equals(that.sourceNode); - } - - @Override - public int hashCode() - { - return Objects.hash(sourceNode); - } - - @Override - public String toString() - { - if (isAnonymous()) { - return toStringHelper(this) - .addValue("anonymous") - .addValue(format("x%08x", identityHashCode(this))) - .toString(); - } - else { - return toStringHelper(this) - .addValue(sourceNode.get().getClass().getSimpleName()) - .addValue(format("x%08x", identityHashCode(sourceNode.get()))) - .toString(); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationType.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationType.java deleted file mode 100644 index 1602f0c3f..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationType.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.tree.QualifiedName; - -import java.util.List; -import java.util.Optional; - -import static com.google.common.collect.ImmutableList.toImmutableList; - -public class RelationType -{ - private final List fields; - - public RelationType() - { - this.fields = ImmutableList.of(); - } - - public RelationType(List fields) - { - this.fields = ImmutableList.copyOf(fields); - } - - public List getFields() - { - return fields; - } - - /** - * get the columns matching the specified name - */ - public List resolveFields(QualifiedName name) - { - return fields.stream() - .filter(input -> input.getSourceColumn().stream().anyMatch(column -> column.getRelationship().isEmpty())) - .filter(input -> input.canResolve(name)) - .collect(toImmutableList()); - } - - public Optional resolveAnyField(QualifiedName name) - { - return fields.stream() - .filter(input -> input.getSourceColumn().stream().anyMatch(column -> column.getRelationship().isEmpty())) - .filter(input -> input.canResolve(name)) - .findAny(); - } - - /** - * Creates a new tuple descriptor containing all fields from this tuple descriptor - * and all fields from the specified tuple descriptor. - */ - public RelationType joinWith(RelationType other) - { - List fields = ImmutableList.builder() - .addAll(this.fields) - .addAll(other.fields) - .build(); - - return new RelationType(fields); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationshipColumnInfo.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationshipColumnInfo.java deleted file mode 100644 index 2960f69f5..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/RelationshipColumnInfo.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.wren.base.dto.Column; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; - -import static java.util.Objects.requireNonNull; - -public class RelationshipColumnInfo -{ - private final Column column; - private final Relationship normalizedRelationship; - private final Model model; - - /** - * relationship column info - * - * @param model the model that relationship column belongs to - * @param column the column that indicate to the relationship column - * @param relationship the relationship defined in the column - */ - public RelationshipColumnInfo(Model model, Column column, Relationship relationship) - { - this.model = requireNonNull(model); - this.column = requireNonNull(column); - // reverse the models order in relationship if needed - this.normalizedRelationship = reverseIfNeeded(relationship, column.getType()); - } - - public Column getColumn() - { - return column; - } - - public Model getModel() - { - return model; - } - - public Relationship getNormalizedRelationship() - { - return normalizedRelationship; - } - - private static Relationship reverseIfNeeded(Relationship relationship, String firstModelName) - { - if (relationship.getModels().get(1).equals(firstModelName)) { - return relationship; - } - return Relationship.reverse(relationship); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Scope.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Scope.java deleted file mode 100644 index 9cadfe71c..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/Scope.java +++ /dev/null @@ -1,163 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.WithQuery; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import static com.google.common.base.Preconditions.checkArgument; -import static java.util.Objects.requireNonNull; - -public class Scope -{ - private final Optional parent; - private final RelationId relationId; - private final RelationType relationType; - private final boolean isDataSourceScope; - private final Map namedQueries; - - private Scope( - Scope parent, - RelationId relationId, - RelationType relationType, - boolean isDataSourceScope, - Map namedQueries) - { - this.parent = Optional.ofNullable(parent); - this.relationId = requireNonNull(relationId, "relationId is null"); - this.relationType = requireNonNull(relationType, "relationType is null"); - this.isDataSourceScope = isDataSourceScope; - this.namedQueries = requireNonNull(namedQueries, "namedQueries is null"); - } - - public Optional getParent() - { - return parent; - } - - public RelationType getRelationType() - { - return relationType; - } - - public RelationId getRelationId() - { - return relationId; - } - - public boolean isDataSourceScope() - { - return isDataSourceScope; - } - - public Optional getNamedQuery(String name) - { - if (namedQueries.containsKey(name)) { - return Optional.of(namedQueries.get(name)); - } - - if (parent.isPresent()) { - return parent.get().getNamedQuery(name); - } - - return Optional.empty(); - } - - /** - * get the columns matching the specified name in the current scope and all parent scopes - */ - public List resolveFields(QualifiedName name) - { - List fields = new ArrayList<>(relationType.resolveFields(name)); - parent.ifPresent(scope -> fields.addAll(scope.resolveFields(name))); - return ImmutableList.copyOf(fields); - } - - /** - * get the columns matching the specified name in the current scope and all parent scopes - */ - public Optional resolveAnyField(QualifiedName name) - { - return relationType.resolveAnyField(name).or(() -> { - if (parent.isPresent()) { - return parent.get().resolveAnyField(name); - } - return Optional.empty(); - }); - } - - public static Builder builder() - { - return new Builder(); - } - - public static final class Builder - { - private Optional parent = Optional.empty(); - private RelationId relationId = RelationId.anonymous(); - private RelationType relationType = new RelationType(); - private boolean isDataSourceScope; - private final Map namedQueries = new HashMap<>(); - - public Builder relationType(RelationType relationType) - { - this.relationType = relationType; - return this; - } - - public Builder relationId(RelationId relationId) - { - this.relationId = relationId; - return this; - } - - public Builder parent(Optional parent) - { - checkArgument(this.parent.isEmpty(), "parent is already set"); - this.parent = requireNonNull(parent, "parent is null"); - return this; - } - - public Builder isDataSourceScope(boolean isDataSourceScope) - { - this.isDataSourceScope = isDataSourceScope; - return this; - } - - public Builder namedQuery(String name, WithQuery withQuery) - { - checkArgument(!containsNamedQuery(name), "Query '%s' is already added", name); - namedQueries.put(name, withQuery); - return this; - } - - public boolean containsNamedQuery(String name) - { - return namedQueries.containsKey(name); - } - - public Scope build() - { - return new Scope(parent.orElse(null), relationId, relationType, isDataSourceScope, namedQueries); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ScopeAnalysis.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ScopeAnalysis.java deleted file mode 100644 index d0f0ba7cc..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ScopeAnalysis.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NodeRef; -import io.trino.sql.tree.Table; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; - -import static java.util.Objects.requireNonNull; - -public class ScopeAnalysis -{ - private final List usedWrenObjects = new ArrayList<>(); - private final Map, String> aliasedMap = new HashMap<>(); - - public void addUsedWrenObject(Table model) - { - usedWrenObjects.add(new Relation(model.getName().getSuffix(), aliasedMap.get(NodeRef.of(model)))); - } - - public List getUsedWrenObjects() - { - return List.copyOf(usedWrenObjects); - } - - public void addAliasedNode(Node node, String alias) - { - aliasedMap.put(NodeRef.of(node), alias); - } - - public static class Relation - { - private final String name; - private final String alias; - - public Relation(String name, String alias) - { - this.name = requireNonNull(name, "name is null"); - this.alias = alias; - } - - public String getName() - { - return name; - } - - public Optional getAlias() - { - return Optional.ofNullable(alias); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ScopeAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ScopeAnalyzer.java deleted file mode 100644 index 1c617a92c..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/ScopeAnalyzer.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableSubquery; -import io.wren.base.CatalogSchemaTableName; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.sqlrewrite.Utils; - -public class ScopeAnalyzer -{ - private ScopeAnalyzer() {} - - public static ScopeAnalysis analyze(WrenMDL wrenMDL, Node node, SessionContext sessionContext) - { - ScopeAnalysis analysis = new ScopeAnalysis(); - Visitor visitor = new Visitor(wrenMDL, analysis, sessionContext); - visitor.process(node, null); - return analysis; - } - - static class Visitor - extends DefaultTraversalVisitor - { - private final WrenMDL wrenMDL; - private final ScopeAnalysis analysis; - private final SessionContext sessionContext; - - public Visitor(WrenMDL wrenMDL, ScopeAnalysis analysis, SessionContext sessionContext) - { - this.wrenMDL = wrenMDL; - this.analysis = analysis; - this.sessionContext = sessionContext; - } - - @Override - protected Void visitTable(Table node, Void context) - { - if (isBelongToWren(node.getName())) { - analysis.addUsedWrenObject(node); - } - return null; - } - - @Override - protected Void visitTableSubquery(TableSubquery node, Void context) - { - return null; - } - - @Override - protected Void visitAliasedRelation(AliasedRelation node, Void context) - { - analysis.addAliasedNode(node.getRelation(), node.getAlias().getValue()); - return super.visitAliasedRelation(node, context); - } - - private boolean isBelongToWren(QualifiedName wrenObjectName) - { - CatalogSchemaTableName catalogSchemaTableName = Utils.toCatalogSchemaTableName(sessionContext, wrenObjectName); - String tableName = catalogSchemaTableName.getSchemaTableName().getTableName(); - return catalogSchemaTableName.getCatalogName().equals(wrenMDL.getCatalog()) - && catalogSchemaTableName.getSchemaTableName().getSchemaName().equals(wrenMDL.getSchema()) - && (wrenMDL.listModels().stream().anyMatch(model -> model.getName().equals(tableName)) - || wrenMDL.listMetrics().stream().anyMatch(metric -> metric.getName().equals(tableName))); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/SemanticExceptions.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/SemanticExceptions.java deleted file mode 100644 index aa00a1c5b..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/SemanticExceptions.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.trino.sql.tree.Node; -import io.wren.base.ErrorCodeSupplier; -import io.wren.base.Location; -import io.wren.base.WrenException; - -import java.util.Optional; - -import static java.lang.String.format; - -public final class SemanticExceptions -{ - private SemanticExceptions() {} - - public static WrenException semanticException(ErrorCodeSupplier code, Node node, String format, Object... args) - { - return semanticException(code, node, null, format, args); - } - - public static WrenException semanticException(ErrorCodeSupplier code, Node node, Throwable cause, String format, Object... args) - { - throw new WrenException(code, extractLocation(node), format(format, args), cause); - } - - public static Optional extractLocation(Node node) - { - return node.getLocation() - .map(location -> new Location(location.getLineNumber(), location.getColumnNumber())); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/StatementAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/StatementAnalyzer.java deleted file mode 100644 index bc36d4599..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/StatementAnalyzer.java +++ /dev/null @@ -1,656 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.QueryUtil; -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FrameBound; -import io.trino.sql.tree.FunctionRelation; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.Join; -import io.trino.sql.tree.JoinCriteria; -import io.trino.sql.tree.JoinOn; -import io.trino.sql.tree.JoinUsing; -import io.trino.sql.tree.Lateral; -import io.trino.sql.tree.LongLiteral; -import io.trino.sql.tree.NaturalJoin; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NodeRef; -import io.trino.sql.tree.PathRelation; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.Query; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.Relation; -import io.trino.sql.tree.SelectItem; -import io.trino.sql.tree.SetOperation; -import io.trino.sql.tree.SingleColumn; -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.Unnest; -import io.trino.sql.tree.Values; -import io.trino.sql.tree.WindowSpecification; -import io.trino.sql.tree.With; -import io.trino.sql.tree.WithQuery; -import io.wren.base.CatalogSchemaTableName; -import io.wren.base.SessionContext; -import io.wren.base.Utils; -import io.wren.base.WrenMDL; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.TimeUnit; -import io.wren.base.dto.View; - -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Stream; - -import static com.google.common.base.Preconditions.checkState; -import static com.google.common.collect.ImmutableList.toImmutableList; -import static io.trino.sql.QueryUtil.getQualifiedName; -import static io.trino.sql.parser.AstBuilder.DUCKDB_TABLE_FUNCTIONS; -import static io.wren.base.sqlrewrite.Utils.toCatalogSchemaTableName; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toUnmodifiableSet; - -/** - * Inspired by io.trino.sql.analyzer.StatementAnalyzer - */ -public final class StatementAnalyzer -{ - private StatementAnalyzer() {} - - public static Scope analyze(Analysis analysis, Statement statement, SessionContext sessionContext, WrenMDL wrenMDL) - { - return analyze(analysis, statement, sessionContext, wrenMDL, Optional.empty()); - } - - public static Scope analyze(Analysis analysis, Statement statement, SessionContext sessionContext, WrenMDL wrenMDL, Optional scope) - { - Scope queryScope = new Visitor(sessionContext, analysis, wrenMDL).process(statement, scope); - // add models directly used in sql query - analysis.addModels( - wrenMDL.listModels().stream() - .filter(model -> analysis.getTables().stream() - .filter(table -> table.getCatalogName().equals(wrenMDL.getCatalog())) - .filter(table -> table.getSchemaTableName().getSchemaName().equals(wrenMDL.getSchema())) - .anyMatch(table -> table.getSchemaTableName().getTableName().equals(model.getName()))) - .collect(toUnmodifiableSet())); - - Set metrics = analysis.getTables().stream() - .map(wrenMDL::getMetric) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(toUnmodifiableSet()); - - Set metricInMetricRollups = analysis.getMetricRollups().values().stream() - .map(MetricRollupInfo::getMetric) - .collect(toUnmodifiableSet()); - - // TODO: remove this check - Utils.checkArgument(metrics.stream().noneMatch(metricInMetricRollups::contains), "duplicate metrics in metrics and metric rollups"); - analysis.addMetrics(metrics); - - Set cumulativeMetrics = analysis.getTables().stream() - .map(wrenMDL::getCumulativeMetric) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(toUnmodifiableSet()); - analysis.addCumulativeMetrics(cumulativeMetrics); - - Set views = analysis.getTables().stream() - .map(wrenMDL::getView) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(toUnmodifiableSet()); - - analysis.addViews(views); - return queryScope; - } - - private static class Visitor - extends AstVisitor> - { - private final SessionContext sessionContext; - private final Analysis analysis; - private final WrenMDL wrenMDL; - - public Visitor( - SessionContext sessionContext, - Analysis analysis, - WrenMDL wrenMDL) - { - this.sessionContext = requireNonNull(sessionContext, "sessionContext is null"); - this.analysis = requireNonNull(analysis, "analysis is null"); - this.wrenMDL = requireNonNull(wrenMDL, "wrenMDL is null"); - } - - public Scope process(Node node) - { - return process(node, Optional.empty()); - } - - @Override - protected Scope visitNode(Node node, Optional context) - { - throw new IllegalStateException("Unsupported node type: " + node.getClass().getName()); - } - - @Override - protected Scope visitTable(Table node, Optional scope) - { - if (node.getName().getPrefix().isEmpty() && scope.isPresent()) { - // is this a reference to a WITH query? - Optional withQuery = scope.get().getNamedQuery(node.getName().getSuffix()); - if (withQuery.isPresent()) { - // currently we only care about the table that is actually a model instead of a alias table that use cte table - // return empty scope here. - Optional withScope = analysis.tryGetScope(withQuery.get().getQuery()); - Scope outputScope = createScopeForCommonTableExpression(node, withQuery.get(), withScope); - analysis.setScope(node, outputScope); - return outputScope; - } - } - - CatalogSchemaTableName tableName = toCatalogSchemaTableName(sessionContext, node.getName()); - analysis.addTable(tableName); - Scope outputScope; - if (tableName.getCatalogName().equals(wrenMDL.getCatalog()) && tableName.getSchemaTableName().getSchemaName().equals(wrenMDL.getSchema())) { - analysis.addSourceNodeName(NodeRef.of(node), QualifiedName.of(tableName.getSchemaTableName().getTableName())); - List fields = collectFieldFromMDL(tableName); - - // if catalog and schema matches, but table name doesn't match any model, we assume it's a remote data source table - if (fields.isEmpty()) { - outputScope = Scope.builder() - .parent(scope) - .isDataSourceScope(true) - .build(); - } - else { - outputScope = Scope.builder() - .parent(scope) - .relationId(RelationId.of(node)) - .relationType(new RelationType(fields)) - .build(); - } - } - else { - outputScope = Scope.builder() - .parent(scope) - .relationId(RelationId.of(node)) - .relationType(new RelationType()) - .build(); - } - analysis.setScope(node, outputScope); - return outputScope; - } - - private Scope createScopeForCommonTableExpression(Table table, WithQuery withQuery, Optional scope) - { - Query query = withQuery.getQuery(); - Optional queryScope = analysis.tryGetScope(query); - List fields; - Optional> columnNames = withQuery.getColumnNames(); - if (columnNames.isPresent()) { - List aliasNames = columnNames.get(); - AtomicInteger i = new AtomicInteger(); - List scopedFields = createScopeForQuery(query, table.getName(), queryScope); - Utils.checkArgument(aliasNames.size() == scopedFields.size(), "Column alias count does not match query column count"); - fields = scopedFields.stream() - .map(field -> Field.builder() - .like(field) - .name(aliasNames.get(i.getAndIncrement()).getValue()) - .build()) - .collect(toImmutableList()); - } - else { - fields = createScopeForQuery(query, table.getName(), queryScope); - } - return createAndAssignScope(table, scope, new RelationType(fields)); - } - - private List createScopeForQuery(Query query, QualifiedName scopeName, Optional scope) - { - ImmutableList.Builder fields = ImmutableList.builder(); - if (query.getQueryBody() instanceof QuerySpecification) { - QuerySpecification body = (QuerySpecification) query.getQueryBody(); - for (SelectItem selectItem : body.getSelect().getSelectItems()) { - if (selectItem instanceof AllColumns) { - scope.ifPresent(s -> s.getRelationType().getFields() - .forEach(f -> fields.add(Field.builder() - .columnName(f.getColumnName()) - .name(f.getName().orElse(f.getColumnName())) - .tableName(toCatalogSchemaTableName(sessionContext, scopeName)) - .sourceModelName(f.getSourceDatasetName().orElse(null)) - .sourceColumn(f.getSourceColumn().orElse(null)) - .build()))); - } - else { - SingleColumn singleColumn = (SingleColumn) selectItem; - String name = singleColumn.getAlias().map(Identifier::getValue) - .or(() -> Optional.ofNullable(QueryUtil.getQualifiedName(singleColumn.getExpression())).map(QualifiedName::getSuffix)) - .orElse(singleColumn.getExpression().toString()); - if (scope.isPresent()) { - Optional fieldOptional = scope.get().resolveAnyField(QueryUtil.getQualifiedName(singleColumn.getExpression())); - if (fieldOptional.isPresent()) { - Field f = fieldOptional.get(); - fields.add(Field.builder() - .columnName(name) - .name(name) - .tableName(toCatalogSchemaTableName(sessionContext, scopeName)) - .sourceModelName(f.getSourceDatasetName().orElse(null)) - .sourceColumn(f.getSourceColumn().orElse(null)) - .build()); - continue; - } - } - fields.add(Field.builder() - .columnName(name) - .name(name) - .tableName(toCatalogSchemaTableName(sessionContext, scopeName)) - .build()); - } - } - } - return fields.build(); - } - - private List collectFieldFromMDL(CatalogSchemaTableName tableName) - { - if (wrenMDL.getModel(tableName.getSchemaTableName().getTableName()).isPresent()) { - return wrenMDL.getModel(tableName.getSchemaTableName().getTableName()) - .map(Model::getColumns) - .orElseGet(ImmutableList::of) - .stream() - .map(column -> Field.builder() - .tableName(tableName) - .columnName(column.getName()) - .name(column.getName()) - .sourceModelName(tableName.getSchemaTableName().getTableName()) - .sourceColumn(column) - .build()) - .collect(toImmutableList()); - } - else if (wrenMDL.getMetric(tableName.getSchemaTableName().getTableName()).isPresent()) { - return wrenMDL.getMetric(tableName.getSchemaTableName().getTableName()) - .map(Metric::getColumns) - .orElseGet(ImmutableList::of) - .stream() - .map(column -> Field.builder() - .tableName(tableName) - .columnName(column.getName()) - .name(column.getName()) - .sourceModelName(tableName.getSchemaTableName().getTableName()) - .sourceColumn(column) - .build()) - .collect(toImmutableList()); - } - else if (wrenMDL.getCumulativeMetric(tableName.getSchemaTableName().getTableName()).isPresent()) { - CumulativeMetric cumulativeMetric = wrenMDL.getCumulativeMetric(tableName.getSchemaTableName().getTableName()).get(); - return ImmutableList.of( - Field.builder() - .tableName(tableName) - .columnName(cumulativeMetric.getWindow().getName()) - .name(cumulativeMetric.getWindow().getName()) - .sourceModelName(tableName.getSchemaTableName().getTableName()) - .sourceColumn(cumulativeMetric.getWindow().toColumn()) - .build(), - Field.builder() - .tableName(tableName) - .columnName(cumulativeMetric.getMeasure().getName()) - .name(cumulativeMetric.getMeasure().getName()) - .sourceModelName(tableName.getSchemaTableName().getTableName()) - .sourceColumn(cumulativeMetric.getMeasure().toColumn()) - .build()); - } - return ImmutableList.of(); - } - - @Override - protected Scope visitQuery(Query node, Optional scope) - { - Optional withScope = analyzeWith(node, scope); - Scope queryBodyScope = process(node.getQueryBody(), withScope); - return createAndAssignScope(node, scope, queryBodyScope); - } - - @Override - protected Scope visitQuerySpecification(QuerySpecification node, Optional scope) - { - Scope sourceScope = analyzeFrom(node, scope); - analyzeSelect(node, sourceScope); - node.getWhere().ifPresent(where -> analyzeWhere(where, sourceScope)); - node.getHaving().ifPresent(having -> analyzeExpression(having, sourceScope)); - node.getWindows().forEach(window -> analyzeWindowSpecification(window.getWindow(), sourceScope)); - node.getGroupBy().ifPresent(groupBy -> groupBy.getGroupingElements().forEach(groupingElement -> { - groupingElement.getExpressions().forEach(expression -> analyzeExpression(expression, sourceScope)); - })); - node.getOrderBy().ifPresent(orderBy -> orderBy.getSortItems() - .forEach(item -> { - if (!(item.getSortKey() instanceof LongLiteral)) { - analyzeExpression(item.getSortKey(), sourceScope); - } - })); - return createAndAssignScope(node, scope, sourceScope); - } - - private void analyzeSelect(QuerySpecification node, Scope scope) - { - ImmutableList.Builder outputExpressions = ImmutableList.builder(); - for (SelectItem item : node.getSelect().getSelectItems()) { - if (item instanceof AllColumns) { - analyzeSelectAllColumns((AllColumns) item, scope, outputExpressions); - } - else if (item instanceof SingleColumn) { - analyzeSelectSingleColumn((SingleColumn) item, scope, outputExpressions); - } - else { - throw new IllegalArgumentException("Unsupported SelectItem type: " + item.getClass().getName()); - } - } - outputExpressions.build(); - } - - private void analyzeSelectAllColumns(AllColumns allColumns, Scope scope, ImmutableList.Builder outputExpressions) - { - List fields = scope.getRelationType().getFields(); - Stream collectedColumns = fields.stream().filter(f -> f.getSourceColumn().map(c -> !c.isCalculated()).orElse(true)); - Stream outputExpressionStream = fields.stream(); - - if (allColumns.getTarget().isPresent()) { - QualifiedName target = QualifiedName.of(((Identifier) allColumns.getTarget().get()).getValue()); - collectedColumns = collectedColumns - .filter(field -> - field.getRelationAlias().map(ra -> ra.equals(target)).orElse(false) - || field.getTableName().getSchemaTableName().getTableName().equals(target.getParts().getFirst())); - outputExpressionStream = outputExpressionStream - .filter(field -> field.getRelationAlias().map(ra -> ra.equals(target)).orElse(false)); - } - - analysis.addCollectedColumns(collectedColumns.collect(toImmutableList())); - outputExpressionStream - .map(field -> - field.getRelationAlias().map(DereferenceExpression::from) - .orElse(DereferenceExpression.from(QualifiedName.of(field.getTableName().getSchemaTableName().getTableName(), field.getColumnName())))) - .forEach(outputExpressions::add); - } - - private void analyzeSelectSingleColumn(SingleColumn singleColumn, Scope scope, ImmutableList.Builder outputExpressions) - { - outputExpressions.add(singleColumn.getAlias().map(name -> (Expression) name).orElse(singleColumn.getExpression())); - ExpressionAnalysis expressionAnalysis = analyzeExpression(singleColumn.getExpression(), scope); - - if (expressionAnalysis.isRequireRelation()) { - Node source = scope.getRelationId().getSourceNode() - .orElseThrow(() -> new IllegalArgumentException("count(*) should have a followed source")); - - // collect only the source node that is a table for generating the required column for models - DefaultTraversalVisitor visitor = new DefaultTraversalVisitor<>() - { - @Override - protected Void visitTable(Table node, Scope scope) - { - if (scope.getNamedQuery(node.getName().getSuffix()).isEmpty()) { - analysis.addRequiredSourceNode(node); - } - return null; - } - }; - visitor.process(source, scope); - } - } - - private Scope analyzeFrom(QuerySpecification node, Optional scope) - { - if (node.getFrom().isPresent()) { - return process(node.getFrom().get(), scope); - } - return Scope.builder().parent(scope).build(); - } - - private void analyzeWhere(Expression node, Scope scope) - { - analyzeExpression(node, scope); - } - - private void analyzeWindowSpecification(WindowSpecification windowSpecification, Scope scope) - { - windowSpecification.getExistingWindowName().ifPresent(name -> analyzeExpression(name, scope)); - windowSpecification.getPartitionBy().forEach(expression -> analyzeExpression(expression, scope)); - windowSpecification.getOrderBy().ifPresent(orderBy -> orderBy.getSortItems().forEach(item -> analyzeExpression(item.getSortKey(), scope))); - windowSpecification.getFrame().ifPresent(frame -> { - frame.getStart().getValue().ifPresent(start -> analyzeExpression(start, scope)); - frame.getEnd().flatMap(FrameBound::getValue).ifPresent(end -> analyzeExpression(end, scope)); - }); - } - - @Override - protected Scope visitValues(Values node, Optional scope) - { - // TODO: output scope here isn't right - return Scope.builder().parent(scope).build(); - } - - @Override - protected Scope visitUnnest(Unnest node, Optional scope) - { - scope.ifPresent(s -> node.getExpressions().forEach(e -> analyzeExpression(e, s))); - // TODO: output scope here isn't right - return Scope.builder().parent(scope).build(); - } - - @Override - protected Scope visitFunctionRelation(FunctionRelation node, Optional scope) - { - if (node.getName().toString().equalsIgnoreCase("roll_up")) { - List arguments = node.getArguments(); - Utils.checkArgument(arguments.size() == 3, "rollup function should have 3 arguments"); - - QualifiedName tableName = getQualifiedName(arguments.get(0)); - Utils.checkArgument(tableName != null, "'%s' cannot be resolved", arguments.get(0)); - Utils.checkArgument(arguments.get(1) instanceof Identifier, "'%s' cannot be resolved", arguments.get(1)); - Utils.checkArgument(arguments.get(2) instanceof Identifier, "'%s' cannot be resolved", arguments.get(2)); - - CatalogSchemaTableName catalogSchemaTableName = toCatalogSchemaTableName(sessionContext, tableName); - Metric metric = wrenMDL.getMetric(catalogSchemaTableName).orElseThrow(() -> new IllegalArgumentException("Metric not found: " + catalogSchemaTableName)); - String timeColumn = ((Identifier) arguments.get(1)).getValue(); - - analysis.addMetricRollups( - NodeRef.of(node), - new MetricRollupInfo( - metric, - metric.getTimeGrain(timeColumn).orElseThrow(() -> new IllegalArgumentException("Time column not found in metric: " + timeColumn)), - TimeUnit.timeUnit(((Identifier) arguments.get(2)).getValue()))); - // currently we don't care about metric rollup output scope - return Scope.builder().parent(scope).build(); - } - else if (DUCKDB_TABLE_FUNCTIONS.contains(node.getName().toString())) { - return Scope.builder().parent(scope).build(); - } - else { - throw new IllegalArgumentException("FunctionRelation not supported: " + node.getName()); - } - } - - @Override - protected Scope visitPathRelation(PathRelation node, Optional context) - { - return Scope.builder().parent(context).build(); - } - - @Override - protected Scope visitSetOperation(SetOperation node, Optional scope) - { - checkState(node.getRelations().size() >= 2); - List relationTypes = node.getRelations().stream() - .map(relation -> process(relation, scope).getRelationType()).collect(toImmutableList()); - List outputFields = relationTypes.get(0).getFields(); - - return createAndAssignScope(node, scope, new RelationType(outputFields)); - } - - @Override - protected Scope visitJoin(Join node, Optional scope) - { - Scope leftScope = process(node.getLeft(), scope); - Scope rightScope; - if (isUnnestOrLateral(node.getRight())) { - rightScope = process(node.getRight(), Optional.of(leftScope)); - } - else { - rightScope = process(node.getRight(), scope); - } - RelationType relationType = leftScope.getRelationType().joinWith(rightScope.getRelationType()); - Scope outputScope = createAndAssignScope(node, scope, relationType); - - JoinCriteria criteria = node.getCriteria().orElse(null); - - switch (criteria) { - case JoinOn joinOn: - Expression expression = joinOn.getExpression(); - analyzeExpression(expression, outputScope); - break; - case JoinUsing joinUsing: - joinUsing.getColumns().forEach(column -> analyzeExpression(column, outputScope)); - break; - case NaturalJoin ignored: - break; - case null: - break; - default: - throw new IllegalStateException("Unexpected value: " + criteria); - } - - // TODO: output scope here isn't right - return createAndAssignScope(node, scope, relationType); - } - - protected boolean isUnnestOrLateral(Relation relation) - { - return switch (relation) { - case Unnest ignored -> true; - case Lateral ignored -> true; - case AliasedRelation aliasedRelation -> isUnnestOrLateral(aliasedRelation.getRelation()); - default -> false; - }; - } - - @Override - protected Scope visitLateral(Lateral node, Optional scope) - { - return process(node.getQuery(), scope); - } - - @Override - protected Scope visitAliasedRelation(AliasedRelation relation, Optional scope) - { - Scope relationScope = process(relation.getRelation(), scope); - relationScope.getRelationId().getSourceNode().flatMap(analysis::getSourceNodeNames) - .ifPresent(names -> analysis.addSourceNodeName(NodeRef.of(relation), names)); - List fields = relationScope.getRelationType().getFields(); - // if scope is a data source scope, we should get the fields from MDL - if (relationScope.isDataSourceScope()) { - CatalogSchemaTableName tableName = toCatalogSchemaTableName(sessionContext, QualifiedName.of(relation.getAlias().getValue())); - fields = collectFieldFromMDL(tableName); - } - - List fieldsWithRelationAlias = fields.stream() - .map(field -> Field.builder() - .like(field) - .relationAlias(QualifiedName.of(relation.getAlias().getValue())) - .build()) - .collect(toImmutableList()); - - return createAndAssignScope(relation, scope, new RelationType(fieldsWithRelationAlias)); - } - - @Override - protected Scope visitTableSubquery(TableSubquery node, Optional scope) - { - return Optional.ofNullable(analyze(analysis, node.getQuery(), sessionContext, wrenMDL, scope)) - .map(value -> createAndAssignScope(node, scope, value)) - .orElseGet(() -> Scope.builder().parent(scope).build()); - } - - // TODO: will recursive query mess up anything here? - private Optional analyzeWith(Query node, Optional scope) - { - if (node.getWith().isEmpty()) { - return scope.map(s -> Scope.builder().parent(Optional.of(s)).build()); - } - - With with = node.getWith().get(); - Scope.Builder withScopeBuilder = Scope.builder().parent(scope); - - for (WithQuery withQuery : with.getQueries()) { - String name = withQuery.getName().getValue(); - if (withScopeBuilder.containsNamedQuery(name)) { - throw new IllegalArgumentException(format("WITH query name '%s' specified more than once", name)); - } - Scope withQueryScope = process(withQuery.getQuery(), withScopeBuilder.build()); - analysis.setScope(withQuery.getQuery(), withQueryScope); - withScopeBuilder.namedQuery(name, withQuery); - } - - return Optional.of(withScopeBuilder.build()); - } - - private Scope process(Node node, Scope scope) - { - return process(node, Optional.of(scope)); - } - - private Scope createAndAssignScope(Node node, Optional parentScope, RelationType relationType) - { - Scope newScope = Scope.builder() - .parent(parentScope) - .relationId(RelationId.of(node)) - .relationType(relationType) - .build(); - analysis.setScope(node, newScope); - return newScope; - } - - private Scope createAndAssignScope(Node node, Optional parentScope, Scope scope) - { - Scope newScope = Scope.builder() - .parent(parentScope) - .isDataSourceScope(scope.isDataSourceScope()) - .relationId(RelationId.of(node)) - .relationType(scope.getRelationType()) - .build(); - analysis.setScope(node, newScope); - return newScope; - } - - private ExpressionAnalysis analyzeExpression(Expression expression, Scope scope) - { - ExpressionAnalysis expressionAnalysis = ExpressionAnalyzer.analyze(scope, expression, sessionContext, wrenMDL, analysis); - analysis.addCollectedColumns(expressionAnalysis.getCollectedFields()); - analysis.addReferenceFields(expressionAnalysis.getReferencedFields()); - return expressionAnalysis; - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionExpressionAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionExpressionAnalyzer.java deleted file mode 100644 index a2b40d4ef..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionExpressionAnalyzer.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import io.trino.sql.tree.ArithmeticBinaryExpression; -import io.trino.sql.tree.ArithmeticUnaryExpression; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FunctionCall; - -import java.util.Map; - -public class DecisionExpressionAnalyzer -{ - public static final DecisionExpressionAnalysis DEFAULT_ANALYSIS = new DecisionExpressionAnalysis(false, false); - public static final String INCLUDE_FUNCTION_CALL = "includeFunctionCall"; - public static final String INCLUDE_MATHEMATICAL_OPERATION = "includeMathematicalOperation"; - - private DecisionExpressionAnalyzer() {} - - public static DecisionExpressionAnalysis analyze(Expression expression) - { - Visitor visitor = new Visitor(); - visitor.process(expression, null); - return new DecisionExpressionAnalysis(visitor.includeFunctionCall, visitor.includeMathematicalOperation); - } - - static class Visitor - extends DefaultTraversalVisitor - { - private boolean includeFunctionCall; - private boolean includeMathematicalOperation; - - @Override - protected Void visitFunctionCall(FunctionCall node, Void context) - { - includeFunctionCall = true; - return super.visitFunctionCall(node, context); - } - - @Override - protected Void visitArithmeticBinary(ArithmeticBinaryExpression node, Void context) - { - includeMathematicalOperation = true; - return super.visitArithmeticBinary(node, context); - } - - @Override - protected Void visitArithmeticUnary(ArithmeticUnaryExpression node, Void context) - { - includeMathematicalOperation = true; - return super.visitArithmeticUnary(node, context); - } - - @Override - protected Void visitComparisonExpression(ComparisonExpression node, Void context) - { - includeMathematicalOperation = true; - return super.visitComparisonExpression(node, context); - } - } - - public record DecisionExpressionAnalysis(boolean includeFunctionCall, boolean includeMathematicalOperation) - { - public Map toMap() - { - return Map.of(INCLUDE_FUNCTION_CALL, String.valueOf(includeFunctionCall), INCLUDE_MATHEMATICAL_OPERATION, String.valueOf(includeMathematicalOperation)); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionPointAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionPointAnalyzer.java deleted file mode 100644 index 464bfe184..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionPointAnalyzer.java +++ /dev/null @@ -1,232 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.SqlFormatter; -import io.trino.sql.tree.AllColumns; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.GroupBy; -import io.trino.sql.tree.GroupingElement; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.LongLiteral; -import io.trino.sql.tree.OrderBy; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.SingleColumn; -import io.trino.sql.tree.Statement; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.With; -import io.wren.base.CatalogSchemaTableName; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.sqlrewrite.analyzer.Analysis; -import io.wren.base.sqlrewrite.analyzer.Field; -import io.wren.base.sqlrewrite.analyzer.StatementAnalyzer; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import static io.trino.sql.ExpressionFormatter.formatExpression; -import static io.wren.base.sqlrewrite.Utils.toCatalogSchemaTableName; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.DecisionExpressionAnalyzer.DEFAULT_ANALYSIS; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.DecisionPointContext.isSubqueryOrCte; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.DecisionPointContext.withSubqueryOrCte; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.QueryAnalysis.ColumnAnalysis; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; - -public class DecisionPointAnalyzer -{ - private DecisionPointAnalyzer() {} - - public static List analyze(Statement query, SessionContext sessionContext, WrenMDL mdl) - { - Analysis analysis = new Analysis(query); - StatementAnalyzer.analyze(analysis, query, sessionContext, mdl); - Visitor visitor = new Visitor(analysis, sessionContext, mdl); - visitor.process(query); - return visitor.queries; - } - - static class Visitor - extends DefaultTraversalVisitor - { - private final Analysis analysis; - private final SessionContext sessionContext; - private final WrenMDL mdl; - private final List queries = new ArrayList<>(); - - public Visitor(Analysis analysis, SessionContext sessionContext, WrenMDL mdl) - { - this.analysis = requireNonNull(analysis, "analysis is null"); - this.sessionContext = requireNonNull(sessionContext, "sessionContext is null"); - this.mdl = requireNonNull(mdl, "mdl is null"); - } - - @Override - protected Void visitWith(With node, DecisionPointContext decisionPointContext) - { - return super.visitWith(node, withSubqueryOrCte(decisionPointContext, true)); - } - - @Override - protected Void visitTableSubquery(TableSubquery node, DecisionPointContext decisionPointContext) - { - return super.visitTableSubquery(node, withSubqueryOrCte(decisionPointContext, true)); - } - - @Override - protected Void visitQuerySpecification(QuerySpecification node, DecisionPointContext decisionPointContext) - { - QueryAnalysis.Builder builder = QueryAnalysis.builder(); - DecisionPointContext selfDecisionPointContext = new DecisionPointContext(builder, analysis.getScope(node), isSubqueryOrCte(decisionPointContext)); - process(node.getSelect(), selfDecisionPointContext); - node.getFrom().ifPresent(from -> builder.setRelation(RelationAnalyzer.analyze(from, sessionContext, mdl, analysis))); - node.getWhere().ifPresent(where -> builder.setFilter(FilterAnalyzer.analyze(where, selfDecisionPointContext.getScope()))); - - if (node.getGroupBy().isPresent()) { - process(node.getGroupBy().get(), selfDecisionPointContext); - } - - if (node.getOrderBy().isPresent()) { - process(node.getOrderBy().get(), selfDecisionPointContext); - } - builder.setSubqueryOrCte(isSubqueryOrCte(decisionPointContext)); - queries.add(builder.build()); - return null; - } - - @Override - protected Void visitAllColumns(AllColumns node, DecisionPointContext decisionPointContext) - { - List scopedFields = decisionPointContext.getScope().getRelationType().getFields(); - if (node.getTarget().isPresent()) { - String target = formatExpression(node.getTarget().get(), SqlFormatter.Dialect.DEFAULT); - CatalogSchemaTableName catalogSchemaTableName = toCatalogSchemaTableName(sessionContext, QualifiedName.of(List.of(target.split("\\.")))); - if (scopedFields.isEmpty()) { - // relation scope can't be analyzed, so we can't determine the fields. It may be a remote table. - decisionPointContext.getBuilder().addSelectItem(new ColumnAnalysis( - Optional.empty(), - format("%s.*", target), - DEFAULT_ANALYSIS.toMap(), - node.getLocation().orElse(null), - List.of())); - } - else { - scopedFields.stream() - .filter(field -> field.getRelationAlias().filter(alias -> alias.toString().equals(target)).isPresent() || field.getTableName().equals(catalogSchemaTableName)) - .filter(field -> field.getSourceColumn().stream().anyMatch(column -> !column.isCalculated() && column.getRelationship().isEmpty())) - .forEach(field -> { - decisionPointContext.getBuilder().addSelectItem(new ColumnAnalysis( - Optional.empty(), - field.getName().orElse(field.getColumnName()), - DEFAULT_ANALYSIS.toMap(), - node.getLocation().orElse(null), - List.of(new ExprSource( - field.getName().orElse(field.getColumnName()), - field.getTableName().getSchemaTableName().getTableName(), - field.getSourceColumn().map(Column::getName).orElse(null), - node.getLocation().orElse(null))))); - }); - } - } - else { - if (scopedFields.isEmpty()) { - // relation scope can't be analyzed, so we can't determine the fields. It may be a remote table. - decisionPointContext.getBuilder().addSelectItem(new ColumnAnalysis( - Optional.empty(), - "*", - DEFAULT_ANALYSIS.toMap(), - node.getLocation().orElse(null), - List.of())); - } - else { - scopedFields.stream() - .filter(field -> field.getSourceColumn().stream().anyMatch(column -> !column.isCalculated() && column.getRelationship().isEmpty())) - .forEach(field -> { - decisionPointContext.getBuilder().addSelectItem(new ColumnAnalysis( - Optional.empty(), - field.getName().orElse(field.getColumnName()), - DEFAULT_ANALYSIS.toMap(), - node.getLocation().orElse(null), - List.of(new ExprSource( - field.getName().orElse(field.getColumnName()), - field.getTableName().getSchemaTableName().getTableName(), - field.getSourceColumn().map(Column::getName).orElse(null), - node.getLocation().orElse(null))))); - }); - } - } - return null; - } - - @Override - protected Void visitSingleColumn(SingleColumn node, DecisionPointContext decisionPointContext) - { - DecisionExpressionAnalyzer.DecisionExpressionAnalysis expressionAnalysis = DecisionExpressionAnalyzer.analyze(node.getExpression()); - String expression = formatExpression(node.getExpression(), SqlFormatter.Dialect.DEFAULT); - Set exprSources = RelationAnalyzer.ExpressionSourceAnalyzer.analyze(node.getExpression(), decisionPointContext.getScope()); - decisionPointContext.getBuilder().addSelectItem(new ColumnAnalysis( - node.getAlias().map(Identifier::getValue), - expression, - expressionAnalysis.toMap(), - node.getLocation().orElse(null), - List.copyOf(exprSources))); - return null; - } - - @Override - protected Void visitGroupBy(GroupBy node, DecisionPointContext decisionPointContext) - { - ImmutableList.Builder> groups = ImmutableList.builder(); - for (GroupingElement groupingElement : node.getGroupingElements()) { - ImmutableList.Builder keys = ImmutableList.builder(); - for (Expression expression : groupingElement.getExpressions()) { - if (expression instanceof LongLiteral) { - QueryAnalysis.ColumnAnalysis field = decisionPointContext.getBuilder().getSelectItems().get((int) ((LongLiteral) expression).getValue() - 1); - keys.add(new QueryAnalysis.GroupByKey(field.getAliasName().orElse(field.getExpression()), expression.getLocation().orElse(null), field.getExprSources())); - } - else { - List exprSources = List.copyOf(RelationAnalyzer.ExpressionSourceAnalyzer.analyze(expression, decisionPointContext.getScope())); - keys.add(new QueryAnalysis.GroupByKey(formatExpression(expression, SqlFormatter.Dialect.DEFAULT), expression.getLocation().orElse(null), exprSources)); - } - } - groups.add(keys.build()); - } - decisionPointContext.getBuilder().setGroupByKeys(groups.build()); - return null; - } - - @Override - protected Void visitOrderBy(OrderBy node, DecisionPointContext decisionPointContext) - { - decisionPointContext.getBuilder().setSortings( - node.getSortItems().stream().map(sortItem -> { - if (sortItem.getSortKey() instanceof LongLiteral) { - QueryAnalysis.ColumnAnalysis field = decisionPointContext.getBuilder().getSelectItems().get((int) ((LongLiteral) sortItem.getSortKey()).getValue() - 1); - return new QueryAnalysis.SortItemAnalysis(field.getAliasName().orElse(field.getExpression()), sortItem.getOrdering(), sortItem.getLocation().orElse(null), field.getExprSources()); - } - List exprSources = List.copyOf(RelationAnalyzer.ExpressionSourceAnalyzer.analyze(sortItem.getSortKey(), decisionPointContext.getScope())); - return new QueryAnalysis.SortItemAnalysis(formatExpression(sortItem.getSortKey(), SqlFormatter.Dialect.DEFAULT), sortItem.getOrdering(), sortItem.getLocation().orElse(null), exprSources); - }).toList()); - return null; - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionPointContext.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionPointContext.java deleted file mode 100644 index f721af3ef..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/DecisionPointContext.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import io.wren.base.sqlrewrite.analyzer.Scope; - -import java.util.Optional; - -public class DecisionPointContext -{ - private final QueryAnalysis.Builder builder; - private final Scope scope; - private final boolean isSubqueryOrCte; - - public static DecisionPointContext withSubqueryOrCte(DecisionPointContext decisionPointContext, boolean isSubqueryOrCte) - { - return Optional.ofNullable(decisionPointContext) - .map(c -> new DecisionPointContext(c.builder, c.scope, isSubqueryOrCte)) - .orElse(new DecisionPointContext(null, null, isSubqueryOrCte)); - } - - /** - * Because the context could be null, use this method to get the value of isSubqueryOrCte safely. - */ - public static boolean isSubqueryOrCte(DecisionPointContext decisionPointContext) - { - return Optional.ofNullable(decisionPointContext).map(c -> c.isSubqueryOrCte).orElse(false); - } - - public DecisionPointContext(QueryAnalysis.Builder builder, Scope scope, boolean isSubqueryOrCte) - { - this.builder = builder; - this.scope = scope; - this.isSubqueryOrCte = isSubqueryOrCte; - } - - public QueryAnalysis.Builder getBuilder() - { - return builder; - } - - public Scope getScope() - { - return scope; - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/ExprSource.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/ExprSource.java deleted file mode 100644 index 1bfed7724..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/ExprSource.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import io.trino.sql.tree.NodeLocation; - -import java.util.Objects; - -public record ExprSource(String expression, String sourceDataset, String sourceColumn, NodeLocation nodeLocation) -{ - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - - if (o == null || getClass() != o.getClass()) { - return false; - } - - ExprSource that = (ExprSource) o; - return Objects.equals(expression, that.expression) && - Objects.equals(sourceDataset, that.sourceDataset) - && Objects.equals(sourceColumn, that.sourceColumn) - && Objects.equals(nodeLocation, that.nodeLocation); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, sourceDataset, sourceColumn, nodeLocation); - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/ExpressionLocationAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/ExpressionLocationAnalyzer.java deleted file mode 100644 index 5c5948503..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/ExpressionLocationAnalyzer.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import io.trino.sql.tree.ArithmeticBinaryExpression; -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.DefaultTraversalVisitor; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.NodeLocation; - -import java.util.Optional; - -/** - * Try to find the most left-side location of an expression. - * For example, the binary expression "a + b" will return the location of "a". - * The comparison expression "a = b" will return the location of "a". - * The location of the expression itself will be returned if it is not a binary or comparison expression. - */ -public class ExpressionLocationAnalyzer -{ - private ExpressionLocationAnalyzer() {} - - public static Optional analyze(Node node) - { - Visitor visitor = new Visitor(); - visitor.process(node, null); - return visitor.nodeLocation; - } - - static class Visitor - extends DefaultTraversalVisitor - { - private Optional nodeLocation = Optional.empty(); - - @Override - protected Void visitExpression(Expression node, Void context) - { - nodeLocation = node.getLocation(); - return null; - } - - @Override - protected Void visitComparisonExpression(ComparisonExpression node, Void context) - { - nodeLocation = node.getLeft().getLocation(); - return null; - } - - @Override - protected Void visitArithmeticBinary(ArithmeticBinaryExpression node, Void context) - { - nodeLocation = node.getLeft().getLocation(); - return null; - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/FilterAnalysis.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/FilterAnalysis.java deleted file mode 100644 index 092af82b0..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/FilterAnalysis.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import io.trino.sql.tree.NodeLocation; - -import java.util.List; - -import static java.util.Objects.requireNonNull; - -public abstract class FilterAnalysis -{ - public static FilterAnalysis and(FilterAnalysis left, FilterAnalysis right, NodeLocation nodeLocation) - { - return new LogicalAnalysis(Type.AND, left, right, nodeLocation); - } - - public static FilterAnalysis or(FilterAnalysis left, FilterAnalysis right, NodeLocation nodeLocation) - { - return new LogicalAnalysis(Type.OR, left, right, nodeLocation); - } - - public static FilterAnalysis expression(String node, NodeLocation nodeLocation, List exprSources) - { - return new ExpressionAnalysis(node, nodeLocation, exprSources); - } - - public enum Type - { - AND, - OR, - EXPR - } - - private final Type type; - private final NodeLocation nodeLocation; - - public FilterAnalysis(Type type, NodeLocation nodeLocation) - { - this.type = requireNonNull(type, "type is null"); - this.nodeLocation = nodeLocation; - } - - public Type getType() - { - return type; - } - - public NodeLocation getNodeLocation() - { - return nodeLocation; - } - - public static class LogicalAnalysis - extends FilterAnalysis - { - private final FilterAnalysis left; - private final FilterAnalysis right; - - public LogicalAnalysis(Type type, FilterAnalysis left, FilterAnalysis right, NodeLocation nodeLocation) - { - super(type, nodeLocation); - this.left = requireNonNull(left, "left is null"); - this.right = requireNonNull(right, "right is null"); - } - - public FilterAnalysis getLeft() - { - return left; - } - - public FilterAnalysis getRight() - { - return right; - } - } - - public static class ExpressionAnalysis - extends FilterAnalysis - { - private final String node; - private final List exprSources; - - public ExpressionAnalysis(String node, NodeLocation nodeLocation, List exprSources) - { - super(Type.EXPR, nodeLocation); - this.node = requireNonNull(node, "node is null"); - this.exprSources = exprSources == null ? List.of() : List.copyOf(exprSources); - } - - public String getNode() - { - return node; - } - - public List getExprSources() - { - return exprSources; - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/FilterAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/FilterAnalyzer.java deleted file mode 100644 index f91adfc4d..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/FilterAnalyzer.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import io.trino.sql.ExpressionFormatter; -import io.trino.sql.SqlFormatter; -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.LogicalExpression; -import io.trino.sql.tree.Node; -import io.wren.base.sqlrewrite.analyzer.Scope; - -import java.util.List; - -/** - * Only extract the top level logical expression. If a logical expression is contained by other expression, it will be treated as a single expression. - */ -public class FilterAnalyzer -{ - private FilterAnalyzer() {} - - public static FilterAnalysis analyze(Expression expression, Scope scope) - { - return new Visitor(scope).process(expression, null); - } - - static class Visitor - extends AstVisitor - { - private final Scope scope; - - private Visitor(Scope scope) - { - this.scope = scope; - } - - @Override - protected FilterAnalysis visitExpression(Expression node, Node context) - { - if (node instanceof LogicalExpression) { - return process(node, context); - } - List exprSources = List.copyOf(RelationAnalyzer.ExpressionSourceAnalyzer.analyze(node, scope)); - return FilterAnalysis.expression(ExpressionFormatter.formatExpression(node, SqlFormatter.Dialect.DEFAULT), node.getLocation().orElse(null), exprSources); - } - - @Override - protected FilterAnalysis visitLogicalExpression(LogicalExpression node, Node parent) - { - if (parent == null || parent instanceof LogicalExpression) { - if (node.getOperator().equals(LogicalExpression.Operator.AND)) { - return FilterAnalysis.and(process(node.getChildren().get(0), node), process(node.getChildren().get(1), node), node.getLocation().orElse(null)); - } - if (node.getOperator().equals(LogicalExpression.Operator.OR)) { - return FilterAnalysis.or(process(node.getChildren().get(0), node), process(node.getChildren().get(1), node), node.getLocation().orElse(null)); - } - } - List exprSources = List.copyOf(RelationAnalyzer.ExpressionSourceAnalyzer.analyze(node, scope)); - return FilterAnalysis.expression(ExpressionFormatter.formatExpression(node, SqlFormatter.Dialect.DEFAULT), node.getLocation().orElse(null), exprSources); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/QueryAnalysis.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/QueryAnalysis.java deleted file mode 100644 index f5b9efc2f..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/QueryAnalysis.java +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import io.trino.sql.tree.NodeLocation; -import io.trino.sql.tree.SortItem; - -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -public class QueryAnalysis -{ - public static Builder builder() - { - return new Builder(); - } - - private final List selectItems; - private final RelationAnalysis relation; - private final FilterAnalysis filter; - private final List> groupByKeys; - private final List sortings; - private final boolean isSubqueryOrCte; - - public QueryAnalysis( - List selectItems, - RelationAnalysis relation, - FilterAnalysis filter, - List> groupByKeys, - List sortings, - boolean isSubqueryOrCte) - { - this.selectItems = selectItems == null ? List.of() : List.copyOf(selectItems); - this.relation = relation; - this.filter = filter; - this.groupByKeys = groupByKeys == null ? List.of() : List.copyOf(groupByKeys); - this.sortings = sortings == null ? List.of() : List.copyOf(sortings); - this.isSubqueryOrCte = isSubqueryOrCte; - } - - public List getSelectItems() - { - return selectItems; - } - - public RelationAnalysis getRelation() - { - return relation; - } - - public FilterAnalysis getFilter() - { - return filter; - } - - public List> getGroupByKeys() - { - return groupByKeys; - } - - public List getSortings() - { - return sortings; - } - - public boolean isSubqueryOrCte() - { - return isSubqueryOrCte; - } - - public static class ColumnAnalysis - { - private final Optional aliasName; - private final String expression; - private final Map properties; - private final NodeLocation nodeLocation; - private final List exprSources; - - public ColumnAnalysis(Optional aliasName, String expression, Map properties, NodeLocation nodeLocation, List exprSources) - { - this.aliasName = aliasName; - this.expression = expression; - this.properties = properties; - this.nodeLocation = nodeLocation; - this.exprSources = exprSources == null ? List.of() : List.copyOf(exprSources); - } - - public Optional getAliasName() - { - return aliasName; - } - - public String getExpression() - { - return expression; - } - - public Map getProperties() - { - return properties; - } - - public NodeLocation getNodeLocation() - { - return nodeLocation; - } - - public List getExprSources() - { - return exprSources; - } - } - - public static class SortItemAnalysis - { - private final String expression; - private final SortItem.Ordering ordering; - private final NodeLocation nodeLocation; - private final List exprSources; - - public SortItemAnalysis(String expression, SortItem.Ordering ordering, NodeLocation nodeLocation, List exprSources) - { - this.expression = expression; - this.ordering = ordering; - this.nodeLocation = nodeLocation; - this.exprSources = exprSources == null ? List.of() : List.copyOf(exprSources); - } - - public String getExpression() - { - return expression; - } - - public SortItem.Ordering getOrdering() - { - return ordering; - } - - public NodeLocation getNodeLocation() - { - return nodeLocation; - } - - public List getExprSources() - { - return exprSources; - } - } - - public static class GroupByKey - { - private final String expression; - private final NodeLocation nodeLocation; - private final List exprSources; - - public GroupByKey(String expression, NodeLocation nodeLocation, List exprSources) - { - this.expression = expression; - this.nodeLocation = nodeLocation; - this.exprSources = exprSources == null ? List.of() : List.copyOf(exprSources); - } - - public String getExpression() - { - return expression; - } - - public NodeLocation getNodeLocation() - { - return nodeLocation; - } - - public List getExprSources() - { - return exprSources; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GroupByKey that = (GroupByKey) o; - return Objects.equals(expression, that.expression) && - Objects.equals(nodeLocation, that.nodeLocation) && - Objects.equals(exprSources, that.exprSources); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, nodeLocation, exprSources); - } - - @Override - public String toString() - { - return "GroupByKey{" + - "expression='" + expression + '\'' + - ", nodeLocation=" + nodeLocation + - ", exprSources=" + exprSources + - '}'; - } - } - - public static class Builder - { - private final List selectItems = new ArrayList<>(); - private RelationAnalysis relation; - private FilterAnalysis filter; - private List> groupByKeys; - private List sortings; - private boolean isSubqueryOrCte; - - public static Builder from(QueryAnalysis queryAnalysis) - { - Builder builder = new Builder(); - builder.selectItems.addAll(queryAnalysis.selectItems); - builder.relation = queryAnalysis.relation; - builder.filter = queryAnalysis.filter; - builder.groupByKeys = queryAnalysis.groupByKeys; - builder.sortings = queryAnalysis.sortings; - builder.isSubqueryOrCte = queryAnalysis.isSubqueryOrCte; - return builder; - } - - public Builder addSelectItem(ColumnAnalysis selectItem) - { - selectItems.add(selectItem); - return this; - } - - public Builder setRelation(RelationAnalysis relation) - { - this.relation = relation; - return this; - } - - public Builder setFilter(FilterAnalysis filter) - { - this.filter = filter; - return this; - } - - public Builder setGroupByKeys(List> groupByKeys) - { - this.groupByKeys = groupByKeys; - return this; - } - - public Builder setSortings(List sortings) - { - this.sortings = sortings; - return this; - } - - public Builder setSubqueryOrCte(boolean subqueryOrCte) - { - isSubqueryOrCte = subqueryOrCte; - return this; - } - - public List getSelectItems() - { - return selectItems; - } - - public QueryAnalysis build() - { - return new QueryAnalysis(selectItems, relation, filter, groupByKeys, sortings, isSubqueryOrCte); - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/RelationAnalysis.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/RelationAnalysis.java deleted file mode 100644 index 503e46381..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/RelationAnalysis.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import io.trino.sql.tree.NodeLocation; - -import java.util.List; -import java.util.Objects; - -import static io.wren.base.Utils.checkArgument; -import static java.util.Objects.requireNonNull; - -public abstract class RelationAnalysis -{ - static JoinRelation join(Type type, String alias, RelationAnalysis left, RelationAnalysis right, JoinCriteria criteria, List exprSources, NodeLocation nodeLocation) - { - checkArgument(type != Type.TABLE && type != Type.SUBQUERY, "type should be a join type"); - return new JoinRelation(type, alias, left, right, criteria, exprSources, nodeLocation); - } - - static TableRelation table(String tableName, String alias, NodeLocation nodeLocation) - { - return new TableRelation(tableName, alias, nodeLocation); - } - - static SubqueryRelation subquery(String alias, List body, NodeLocation nodeLocation) - { - return new SubqueryRelation(alias, body, nodeLocation); - } - - public enum Type - { - TABLE, - SUBQUERY, - INNER_JOIN, - LEFT_JOIN, - RIGHT_JOIN, - FULL_JOIN, - CROSS_JOIN, - IMPLICIT_JOIN, - } - - private final Type type; - private final String alias; - private final NodeLocation nodeLocation; - - public RelationAnalysis(Type type, String alias, NodeLocation nodeLocation) - { - this.type = requireNonNull(type, "type is null"); - this.alias = alias; - this.nodeLocation = nodeLocation; - } - - public Type getType() - { - return type; - } - - public String getAlias() - { - return alias; - } - - public NodeLocation getNodeLocation() - { - return nodeLocation; - } - - public static class JoinRelation - extends RelationAnalysis - { - private final RelationAnalysis left; - private final RelationAnalysis right; - private final JoinCriteria criteria; - private final List exprSources; - - public JoinRelation(Type type, String alias, RelationAnalysis left, RelationAnalysis right, JoinCriteria criteria, List exprSources, NodeLocation nodeLocation) - { - super(type, alias, nodeLocation); - this.left = requireNonNull(left, "left is null"); - this.right = requireNonNull(right, "right is null"); - this.criteria = criteria; - this.exprSources = exprSources == null ? List.of() : exprSources; - } - - public RelationAnalysis getLeft() - { - return left; - } - - public RelationAnalysis getRight() - { - return right; - } - - public JoinCriteria getCriteria() - { - return criteria; - } - - public List getExprSources() - { - return exprSources; - } - } - - public static class JoinCriteria - { - public static JoinCriteria joinCriteria(String expression, NodeLocation nodeLocation) - { - return new JoinCriteria(expression, nodeLocation); - } - - private final String expression; - private final NodeLocation nodeLocation; - - public JoinCriteria(String expression, NodeLocation nodeLocation) - { - this.expression = expression; - this.nodeLocation = nodeLocation; - } - - public String getExpression() - { - return expression; - } - - public NodeLocation getNodeLocation() - { - return nodeLocation; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - JoinCriteria that = (JoinCriteria) o; - return Objects.equals(expression, that.expression) && - Objects.equals(nodeLocation, that.nodeLocation); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, nodeLocation); - } - - @Override - public String toString() - { - return "JoinCriteria{" + - "expression='" + expression + '\'' + - ", nodeLocation=" + nodeLocation + - '}'; - } - } - - public static class TableRelation - extends RelationAnalysis - { - private final String tableName; - - public TableRelation(String tableName, String alias, NodeLocation nodeLocation) - { - super(Type.TABLE, alias, nodeLocation); - this.tableName = requireNonNull(tableName, "tableName is null"); - } - - public String getTableName() - { - return tableName; - } - } - - public static class SubqueryRelation - extends RelationAnalysis - { - private final List body; - - public SubqueryRelation(String alias, List body, NodeLocation nodeLocation) - { - super(Type.SUBQUERY, alias, nodeLocation); - this.body = requireNonNull(body, "body is null"); - } - - public List getBody() - { - return body; - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/RelationAnalyzer.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/RelationAnalyzer.java deleted file mode 100644 index 4c634c090..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/decisionpoint/RelationAnalyzer.java +++ /dev/null @@ -1,279 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.decisionpoint; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableSet; -import io.trino.sql.tree.AliasedRelation; -import io.trino.sql.tree.AstVisitor; -import io.trino.sql.tree.DefaultExpressionTraversalVisitor; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FunctionRelation; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.Join; -import io.trino.sql.tree.JoinCriteria; -import io.trino.sql.tree.JoinOn; -import io.trino.sql.tree.JoinUsing; -import io.trino.sql.tree.Lateral; -import io.trino.sql.tree.NaturalJoin; -import io.trino.sql.tree.NodeLocation; -import io.trino.sql.tree.PatternRecognitionRelation; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.QuerySpecification; -import io.trino.sql.tree.Relation; -import io.trino.sql.tree.SampledRelation; -import io.trino.sql.tree.SetOperation; -import io.trino.sql.tree.Table; -import io.trino.sql.tree.TableSubquery; -import io.trino.sql.tree.Unnest; -import io.trino.sql.tree.Values; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Column; -import io.wren.base.sqlrewrite.analyzer.Analysis; -import io.wren.base.sqlrewrite.analyzer.Scope; - -import java.util.HashSet; -import java.util.List; -import java.util.Optional; -import java.util.Set; - -import static io.trino.sql.tree.DereferenceExpression.getQualifiedName; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.RelationAnalysis.JoinCriteria.joinCriteria; -import static java.lang.String.format; -import static java.util.stream.Collectors.joining; - -public class RelationAnalyzer -{ - private RelationAnalyzer() {} - - public static RelationAnalysis analyze(Relation relation, SessionContext sessionContext, WrenMDL wrenMDL, Analysis analysis) - { - return new Visitor(sessionContext, wrenMDL, analysis).process(relation, null); - } - - static class Visitor - extends AstVisitor - { - private final SessionContext sessionContext; - private final WrenMDL wrenMDL; - private final Analysis analysis; - - public Visitor(SessionContext sessionContext, WrenMDL wrenMDL, Analysis analysis) - { - this.sessionContext = sessionContext; - this.wrenMDL = wrenMDL; - this.analysis = analysis; - } - - @Override - protected RelationAnalysis visitTable(Table node, Void context) - { - return new RelationAnalysis.TableRelation(node.getName().toString(), null, node.getLocation().orElse(null)); - } - - @Override - protected RelationAnalysis visitSetOperation(SetOperation node, Void context) - { - // TODO: implement this - // except, intersect, union - throw new UnsupportedOperationException("Analyze Set operation is not supported yet"); - } - - @Override - protected RelationAnalysis visitValues(Values node, Void context) - { - // TODO: implement this - throw new UnsupportedOperationException("Analyze Values is not supported yet"); - } - - @Override - protected RelationAnalysis visitFunctionRelation(FunctionRelation node, Void context) - { - // TODO: implement this - throw new UnsupportedOperationException("Analyze FunctionRelation is not supported yet"); - } - - @Override - protected RelationAnalysis visitTableSubquery(TableSubquery node, Void context) - { - List analyses = DecisionPointAnalyzer.analyze(node.getQuery(), sessionContext, wrenMDL) - .stream().map(analysis -> QueryAnalysis.Builder.from(analysis).setSubqueryOrCte(true).build()) - .toList(); - return new RelationAnalysis.SubqueryRelation(null, analyses, node.getLocation().orElse(null)); - } - - @Override - protected RelationAnalysis visitQuerySpecification(QuerySpecification node, Void context) - { - // TODO: implement this - return super.visitQuerySpecification(node, context); - } - - @Override - protected RelationAnalysis visitJoin(Join node, Void context) - { - RelationAnalysis left = process(node.getLeft(), context); - RelationAnalysis right = process(node.getRight(), context); - - Scope scope = analysis.getScope(node); - List exprSources = node.getCriteria().map(criteria -> analyzeCriteria(criteria, scope)) - .orElse(null); - Optional criteriaLocation = node.getCriteria().flatMap(this::findLocation); - return new RelationAnalysis.JoinRelation( - RelationAnalysis.Type.valueOf(format("%s_JOIN", node.getType())), - null, left, right, joinCriteria(node.getCriteria().map(this::formatCriteria).orElse(null), criteriaLocation.orElse(null)), - exprSources, - node.getLocation().orElse(null)); - } - - private String formatCriteria(JoinCriteria criteria) - { - StringBuilder builder = new StringBuilder(); - switch (criteria) { - case JoinOn joinOn: - builder.append("ON "); - builder.append(joinOn.getExpression()); - break; - case JoinUsing joinUsing: - builder.append("USING ("); - builder.append(joinUsing.getColumns().stream().map(Identifier::getValue).collect(joining(", "))); - builder.append(")"); - break; - case NaturalJoin ignored: - return null; - default: - throw new IllegalArgumentException("Unsupported join criteria: " + criteria); - } - return builder.toString(); - } - - private Optional findLocation(JoinCriteria criteria) - { - return switch (criteria) { - case JoinOn joinOn -> joinOn.getNodes().stream().findAny().flatMap(ExpressionLocationAnalyzer::analyze); - case JoinUsing joinUsing -> joinUsing.getColumns().stream().findAny().flatMap(ExpressionLocationAnalyzer::analyze); - case NaturalJoin ignored -> Optional.empty(); - default -> throw new IllegalArgumentException("Unsupported join criteria: " + criteria); - }; - } - - private List analyzeCriteria(JoinCriteria criteria, Scope scope) - { - Set exprSources = new HashSet<>(); - switch (criteria) { - case JoinOn joinOn: - exprSources.addAll(ExpressionSourceAnalyzer.analyze(joinOn.getExpression(), scope)); - break; - case JoinUsing joinUsing: - joinUsing.getColumns().forEach(column -> exprSources.addAll(ExpressionSourceAnalyzer.analyze(column, scope))); - break; - case NaturalJoin ignored: - break; - default: - throw new IllegalArgumentException("Unsupported join criteria: " + criteria); - } - return ImmutableList.copyOf(exprSources); - } - - @Override - protected RelationAnalysis visitAliasedRelation(AliasedRelation node, Void context) - { - RelationAnalysis relationAnalysis = process(node.getRelation(), context); - - return switch (relationAnalysis) { - case RelationAnalysis.TableRelation tableRelation -> RelationAnalysis.table(tableRelation.getTableName(), node.getAlias().getValue(), node.getLocation().orElse(null)); - case RelationAnalysis.JoinRelation joinRelation -> - RelationAnalysis.join( - joinRelation.getType(), - node.getAlias().getValue(), - joinRelation.getLeft(), - joinRelation.getRight(), - joinRelation.getCriteria(), - joinRelation.getExprSources(), - node.getLocation().orElse(null)); - case RelationAnalysis.SubqueryRelation subqueryRelation -> RelationAnalysis.subquery(node.getAlias().getValue(), subqueryRelation.getBody(), node.getLocation().orElse(null)); - default -> throw new IllegalStateException("Unexpected value: " + relationAnalysis); - }; - } - - @Override - protected RelationAnalysis visitSampledRelation(SampledRelation node, Void context) - { - // TODO: implement this - throw new UnsupportedOperationException("Analyze SampledRelation is not supported yet"); - } - - @Override - protected RelationAnalysis visitPatternRecognitionRelation(PatternRecognitionRelation node, Void context) - { - // TODO: implement this - throw new UnsupportedOperationException("Analyze PatternRecognitionRelation is not supported yet"); - } - - @Override - protected RelationAnalysis visitUnnest(Unnest node, Void context) - { - // TODO: implement this - throw new UnsupportedOperationException("Analyze Unnest is not supported yet"); - } - - @Override - protected RelationAnalysis visitLateral(Lateral node, Void context) - { - // TODO: implement this - throw new UnsupportedOperationException("Analyze Lateral is not supported yet"); - } - } - - static class ExpressionSourceAnalyzer - extends DefaultExpressionTraversalVisitor - { - static Set analyze(Expression expression, Scope scope) - { - ExpressionSourceAnalyzer analyzer = new ExpressionSourceAnalyzer(scope); - analyzer.process(expression, null); - return ImmutableSet.copyOf(analyzer.exprSources); - } - - private final Scope scope; - private final Set exprSources = new HashSet<>(); - - public ExpressionSourceAnalyzer(Scope scope) - { - this.scope = scope; - } - - @Override - protected Void visitIdentifier(Identifier node, Void context) - { - scope.resolveFields(QualifiedName.of(node.getValue())) - .stream().filter(field -> field.getSourceDatasetName().isPresent()) - .forEach(field -> exprSources.add(new ExprSource(node.getValue(), field.getSourceDatasetName().get(), field.getSourceColumn().map(Column::getName).orElse(null), node.getLocation().orElse(null)))); - return null; - } - - @Override - protected Void visitDereferenceExpression(DereferenceExpression node, Void context) - { - Optional.ofNullable(getQualifiedName(node)).ifPresent(qualifiedName -> - scope.resolveFields(qualifiedName) - .stream().filter(field -> field.getSourceDatasetName().isPresent()) - .forEach(field -> exprSources.add(new ExprSource(qualifiedName.toString(), field.getSourceDatasetName().get(), field.getSourceColumn().map(Column::getName).orElse(null), node.getLocation().orElse(null))))); - return null; - } - } -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/matcher/Matcher.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/matcher/Matcher.java deleted file mode 100644 index c86680924..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/matcher/Matcher.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.matcher; - -import io.trino.sql.tree.Node; - -public interface Matcher -{ - boolean shapeMatches(Node node); -} diff --git a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/matcher/PredicateMatcher.java b/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/matcher/PredicateMatcher.java deleted file mode 100644 index d63b10466..000000000 --- a/wren-base/src/main/java/io/wren/base/sqlrewrite/analyzer/matcher/PredicateMatcher.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer.matcher; - -import io.trino.sql.tree.ComparisonExpression; -import io.trino.sql.tree.DereferenceExpression; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.Identifier; -import io.trino.sql.tree.Literal; -import io.trino.sql.tree.Node; - -public class PredicateMatcher - implements Matcher -{ - public static final PredicateMatcher PREDICATE_MATCHER = new PredicateMatcher(); - - private PredicateMatcher() {} - - @Override - public boolean shapeMatches(Node node) - { - if (!(node instanceof ComparisonExpression)) { - return false; - } - - Expression left = ((ComparisonExpression) node).getLeft(); - Expression right = ((ComparisonExpression) node).getRight(); - - return (left instanceof DereferenceExpression || left instanceof Identifier) && - (right instanceof Literal || right instanceof DereferenceExpression || right instanceof Identifier); - } -} diff --git a/wren-base/src/test/java/io/wren/base/dto/TestMacro.java b/wren-base/src/test/java/io/wren/base/dto/TestMacro.java deleted file mode 100644 index 1a29a3655..000000000 --- a/wren-base/src/test/java/io/wren/base/dto/TestMacro.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.macro.ParsingException; -import org.testng.annotations.Test; - -import java.util.List; -import java.util.Optional; - -import static io.wren.base.macro.Parameter.expressionType; -import static io.wren.base.macro.Parameter.macroType; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestMacro -{ - @Test - public void testParseParameter() - { - Macro singleParameter = Macro.macro("test", "(a: Expression) => a + 1"); - assertThat(singleParameter.getParameters()).isEqualTo(List.of(expressionType("a"))); - - Macro multipleParameters = Macro.macro("test", "(a: Expression, b: Macro) => a + b"); - assertThat(multipleParameters.getParameters()).isEqualTo(List.of(expressionType("a"), macroType("b"))); - - Macro noParameter = Macro.macro("test", "() => 1"); - assertThat(noParameter.getParameters()).isEqualTo(List.of()); - } - - @Test - public void testErrorHandle() - { - assertThatThrownBy(() -> Macro.macro("test", "xxxxx")) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("definition is invalid"); - - assertThatThrownBy(() -> Macro.macro("test", "(xxxxx) => a + b")) - .isInstanceOf(ParsingException.class) - .hasMessageContaining("typeName is null"); - - assertThatThrownBy(() -> Macro.macro("test", "(a: Expression, xxxxx) => a + b")) - .isInstanceOf(ParsingException.class) - .hasMessageContaining("typeName is null"); - - assertThatThrownBy(() -> Macro.macro("test", "(a: Expression, b: UnDefined) => a + b")) - .isInstanceOf(ParsingException.class) - .hasMessageContaining("typeName is invalid: b:UnDefined"); - } - - @Test - public void testOneParameterCall() - { - Manifest manifest = Manifest.builder() - .setCatalog("test") - .setSchema("test") - .setModels(List.of( - Model.model("Customer", - "select * from main.customer", - List.of( - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("normal_call", WrenTypes.INTEGER, null, true, "addOne(custkey)"), - Column.column("custkey_addOne", WrenTypes.INTEGER, null, true, "{{addOne('custkey')}}"), - Column.column("custkey_callAddOne", WrenTypes.INTEGER, null, true, "{{callAddOne('custkey')}}"), - Column.column("custkey_pass1Macro", WrenTypes.INTEGER, null, true, "{{pass1Macro('custkey', addOne)}}"), - Column.column("custkey_pass2Macro", WrenTypes.INTEGER, null, true, "{{pass2Macro('custkey', addOne, addTwo)}}"), - Column.column("custkey_sum_addOne", WrenTypes.INTEGER, null, true, "{{addOne('sum(custkey)')}}"), - Column.column("name", WrenTypes.VARCHAR, null, true)), - "pk"))) - .setMacros(List.of( - Macro.macro("addOne", "(text: Expression) => {{ text }} + 1"), - Macro.macro("addTwo", "(text: Expression) => {{ text }} + 2"), - Macro.macro("callAddOne", "(text: Expression) => {{addOne(text)}}"), - Macro.macro("pass1Macro", "(text: Expression, rule: Macro) => {{rule(text)}}"), - Macro.macro("pass2Macro", "(text: Expression, rule1: Macro, rule2: Macro) => {{ rule1(text) }} + {{ rule2(text)}}"))) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - Optional modelOptional = mdl.getModel("Customer"); - assertThat(modelOptional).isPresent(); - assertThat(modelOptional.get().getColumns().get(1).getExpression().get()).isEqualTo("addOne(custkey)"); - assertThat(modelOptional.get().getColumns().get(2).getExpression().get()).isEqualTo("custkey + 1"); - assertThat(modelOptional.get().getColumns().get(3).getExpression().get()).isEqualTo("custkey + 1"); - assertThat(modelOptional.get().getColumns().get(4).getExpression().get()).isEqualTo("custkey + 1"); - assertThat(modelOptional.get().getColumns().get(5).getExpression().get()).isEqualTo("custkey + 1 + custkey + 2"); - assertThat(modelOptional.get().getColumns().get(6).getExpression().get()).isEqualTo("sum(custkey) + 1"); - } - - @Test - public void testTwoParameterCall() - { - Manifest manifest = Manifest.builder() - .setCatalog("test") - .setSchema("test") - .setModels(List.of( - Model.model("Customer", - "select * from main.customer", - List.of( - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("custkey_concat_name", WrenTypes.INTEGER, null, true, "{{concat('custkey', 'name')}}"), - Column.column("custkey_callAddOne", WrenTypes.INTEGER, null, true, "{{addPrefixOne('custkey')}}"), - Column.column("custkey_pass1Macro", WrenTypes.INTEGER, null, true, "{{pass1Macro('custkey', 'name', concat)}}")), - "pk"))) - .setMacros(List.of( - Macro.macro("concat", "(text: Expression, text2: Expression) => {{ text }} || {{ text2 }}"), - Macro.macro("addPrefixOne", "(text: Expression) => {{concat(\"'1'\", text)}}"), - Macro.macro("pass1Macro", "(text: Expression, text2: Expression, cf: Macro) => {{cf(text, text2)}}"))) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - Optional modelOptional = mdl.getModel("Customer"); - assertThat(modelOptional).isPresent(); - assertThat(modelOptional.get().getColumns().get(2).getExpression().get()).isEqualTo("custkey || name"); - assertThat(modelOptional.get().getColumns().get(3).getExpression().get()).isEqualTo("'1' || custkey"); - assertThat(modelOptional.get().getColumns().get(4).getExpression().get()).isEqualTo("custkey || name"); - } - - @Test - public void testZeroParameterCall() - { - Manifest manifest = Manifest.builder() - .setCatalog("test") - .setSchema("test") - .setModels(List.of( - Model.model("Customer", - "select * from main.customer", - List.of( - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("standardTime", WrenTypes.INTEGER, null, true, "{{standardTime()}}"), - Column.column("callStandardTime", WrenTypes.INTEGER, null, true, "{{callStandardTime()}}"), - Column.column("passStandardTime", WrenTypes.INTEGER, null, true, "{{passStandardTime(standardTime)}}")), - "pk"))) - .setMacros(List.of( - Macro.macro("standardTime", "() => standardTime"), - Macro.macro("callStandardTime", "() => {{callStandardTime()}}"), - Macro.macro("passStandardTime", "(cf: Macro) => {{cf()}}"))) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - Optional modelOptional = mdl.getModel("Customer"); - assertThat(modelOptional).isPresent(); - assertThat(modelOptional.get().getColumns().get(2).getExpression().get()).isEqualTo("standardTime"); - assertThat(modelOptional.get().getColumns().get(2).getExpression().get()).isEqualTo("standardTime"); - assertThat(modelOptional.get().getColumns().get(2).getExpression().get()).isEqualTo("standardTime"); - } -} diff --git a/wren-base/src/test/java/io/wren/base/dto/TestManifestSerDe.java b/wren-base/src/test/java/io/wren/base/dto/TestManifestSerDe.java deleted file mode 100644 index 05cd8a185..000000000 --- a/wren-base/src/test/java/io/wren/base/dto/TestManifestSerDe.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import com.google.common.collect.ImmutableMap; -import io.airlift.json.JsonCodec; -import io.wren.base.WrenTypes; -import org.testng.annotations.Test; - -import java.util.List; -import java.util.Map; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestManifestSerDe -{ - private static final JsonCodec> STRING_TO_STRING_MAP_CODEC = JsonCodec.mapJsonCodec(String.class, Object.class); - - @Test - public void testSerDeRoundTrip() - { - Manifest original = createManifest(); - String json = Manifest.MANIFEST_JSON_CODEC.toJson(original); - Manifest copy = Manifest.MANIFEST_JSON_CODEC.fromJson(json); - assertThat(original).isEqualTo(copy); - } - - private static Manifest createManifest() - { - return Manifest.builder() - .setCatalog("test-catalog") - .setSchema("test-schema") - .setModels(List.of( - new Model("OrdersModel", - "select * from orders", - null, - null, - List.of( - new Column("orderkey", "integer", null, false, true, null), - new Column("custkey", "integer", null, false, true, null), - new Column("orderstatus", "string", null, false, true, null), - new Column("totalprice", "double", null, false, true, null), - new Column("orderdate", "date", null, false, true, null), - new Column("orderpriority", "string", null, false, true, null), - new Column("clerk", "string", null, false, true, null), - new Column("shippriority", "integer", null, false, true, null), - new Column("comment", "string", null, false, true, null), - new Column("customer", "CustomerModel", "OrdersCustomer", false, true, null)), - "orderkey", - false, - null), - new Model("LineitemModel", - "select * from lineitem", - null, - null, - List.of( - new Column("orderkey", "integer", null, false, true, null), - new Column("linenumber", "integer", null, false, true, null), - new Column("extendedprice", "integer", null, false, true, null)), - null, - false, - null), - new Model("CustomerModel", - null, - null, - new TableReference("test-catalog", "test-schema", "customer"), - List.of( - new Column("custkey", "integer", null, false, true, null), - new Column("name", "string", null, false, true, null), - new Column("address", "string", null, false, true, null), - new Column("nationkey", "integer", null, false, true, null), - new Column("phone", "string", null, false, true, null), - new Column("acctbal", "double", null, false, true, null), - new Column("mktsegment", "string", null, false, true, null), - new Column("comment", "string", null, false, true, null), - new Column("orders", "OrdersModel", "OrdersCustomer", false, true, null), - // calculated field - new Column("orders_totalprice", WrenTypes.VARCHAR, null, true, false, "SUM(orders.totalprice)")), - "custkey", - false, - null))) - .setRelationships(List.of( - new Relationship("OrdersCustomer", - List.of("OrdersModel", "CustomerModel"), - JoinType.MANY_TO_ONE, - "OrdersModel.custkey = CustomerModel.custkey", - List.of(new Relationship.SortKey("orderkey", Relationship.SortKey.Ordering.ASC))))) - .setEnumDefinitions(List.of( - new EnumDefinition("OrderStatus", List.of( - new EnumValue("PENDING", "pending"), - new EnumValue("PROCESSING", "processing"), - new EnumValue("SHIPPED", "shipped"), - new EnumValue("COMPLETE", "complete"))))) - .setMetrics(List.of( - new Metric("Revenue", - "OrdersModel", - List.of(new Column("orderkey", "string", null, false, true, null)), - List.of(new Column("total", "integer", null, false, true, null)), - List.of(new TimeGrain("orderdate", "orderdate", List.of(TimeUnit.DAY, TimeUnit.MONTH))), - true, - null))) - .setViews(List.of( - new View("useMetric", - "select * from Revenue", - ImmutableMap.of("description", "the view for the revenue metric")))) - .setCumulativeMetrics(List.of( - new CumulativeMetric("DailyRevenue", - "Orders", - new Measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - new Window("orderdate", "orderdate", TimeUnit.DAY, "1994-01-01", "1994-12-31"), - false, - null), - new CumulativeMetric("WeeklyRevenue", - "Orders", - new Measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - new Window("orderdate", "orderdate", TimeUnit.WEEK, "1994-01-01", "1994-12-31"), - false, - null))) - .setDateSpine(new DateSpine(TimeUnit.DAY, "1970-01-01", "2077-12-31")) - .setMacros(List.of(new Macro("test", "(a: Expression) => a + 1"))) - .build(); - } - - @Test - public void testEmptyHandle() - { - assertThatThrownBy(() -> { - Map json = Map.of("catalog", "", "schema", "test"); - Manifest.MANIFEST_JSON_CODEC.fromJson(STRING_TO_STRING_MAP_CODEC.toJson(json)); - }).cause().hasMessageFindingMatch("catalog is null or empty"); - - assertThatThrownBy(() -> { - Map json = Map.of("catalog", "test", "schema", ""); - Manifest.MANIFEST_JSON_CODEC.fromJson(STRING_TO_STRING_MAP_CODEC.toJson(json)); - }).cause().hasMessageFindingMatch("schema is null or empty"); - - assertThatThrownBy(() -> { - Map json = Map.of("catalog", "test", "schema", "test", "models", List.of(Map.of("name", ""))); - Manifest.MANIFEST_JSON_CODEC.fromJson(STRING_TO_STRING_MAP_CODEC.toJson(json)); - }).cause().hasMessageFindingMatch("name is null or empty"); - - assertThatThrownBy(() -> { - Map json = Map.of("catalog", "test", "schema", "test", "models", - List.of(Map.of("name", "test", "columns", List.of(Map.of("name", ""))))); - Manifest.MANIFEST_JSON_CODEC.fromJson(STRING_TO_STRING_MAP_CODEC.toJson(json)); - }).cause().hasMessageFindingMatch("name is null or empty"); - - assertThatThrownBy(() -> { - Map json = Map.of("catalog", "test", "schema", "test", "models", - List.of(Map.of("name", "test", "columns", List.of(Map.of("name", "test", "type", ""))))); - Manifest.MANIFEST_JSON_CODEC.fromJson(STRING_TO_STRING_MAP_CODEC.toJson(json)); - }).cause().hasMessageFindingMatch("type is null or empty"); - - assertThatThrownBy(() -> { - Map json = Map.of("catalog", "test", "schema", "test", "relationships", - List.of(Map.of("name", ""))); - Manifest.MANIFEST_JSON_CODEC.fromJson(STRING_TO_STRING_MAP_CODEC.toJson(json)); - }).cause().hasMessageFindingMatch("name is null or empty"); - } -} diff --git a/wren-base/src/test/java/io/wren/base/dto/TestRelationship.java b/wren-base/src/test/java/io/wren/base/dto/TestRelationship.java deleted file mode 100644 index d4a4e1d69..000000000 --- a/wren-base/src/test/java/io/wren/base/dto/TestRelationship.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed 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 io.wren.base.dto; - -import org.assertj.core.api.Assertions; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.trino.sql.SqlFormatter.formatSql; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestRelationship -{ - @Test - public void testOrdering() - { - Assertions.assertThat(Relationship.SortKey.Ordering.get("asc")).isEqualTo(Relationship.SortKey.Ordering.ASC); - Assertions.assertThat(Relationship.SortKey.Ordering.get("ASC")).isEqualTo(Relationship.SortKey.Ordering.ASC); - Assertions.assertThat(Relationship.SortKey.Ordering.get("aSC")).isEqualTo(Relationship.SortKey.Ordering.ASC); - Assertions.assertThat(Relationship.SortKey.Ordering.get("DESC")).isEqualTo(Relationship.SortKey.Ordering.DESC); - assertThatThrownBy(() -> Relationship.SortKey.Ordering.get("foo")).hasMessage("Unsupported ordering"); - } - - @Test - public void testQualifiedCondition() - { - String expected = "(\"A\".\"c1\" = \"B\".\"c1\")"; - Relationship relationship = Relationship.relationship("name", List.of("A", "B"), JoinType.ONE_TO_ONE, "A.c1 = B.c1"); - assertThat(formatSql(relationship.getQualifiedCondition())).isEqualTo(expected); - relationship = Relationship.relationship("name", List.of("A", "B"), JoinType.ONE_TO_ONE, "\"A\".c1 = \"B\".c1"); - assertThat(formatSql(relationship.getQualifiedCondition())).isEqualTo(expected); - relationship = Relationship.relationship("name", List.of("A", "B"), JoinType.ONE_TO_ONE, "A.\"c1\" = B.\"c1\""); - assertThat(formatSql(relationship.getQualifiedCondition())).isEqualTo(expected); - } -} diff --git a/wren-base/src/test/java/io/wren/base/jinjava/TestJinjavaExpressionProcessor.java b/wren-base/src/test/java/io/wren/base/jinjava/TestJinjavaExpressionProcessor.java deleted file mode 100644 index a6e8dcd90..000000000 --- a/wren-base/src/test/java/io/wren/base/jinjava/TestJinjavaExpressionProcessor.java +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Licensed 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 io.wren.base.jinjava; - -import io.wren.base.dto.Macro; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.util.List; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TestJinjavaExpressionProcessor -{ - List macros = List.of( - Macro.macro("standardTime", "() => standardTime"), - Macro.macro("callStandardTime", "() => {{ standardTime() }}"), - Macro.macro("passMacroWithoutParam", "(rule: Macro) => {{ rule() }}"), - Macro.macro("addOne", "(a: Expression) => {{ a }} + 1"), - Macro.macro("addTwo", "(a: Expression) => {{ a }} + 2"), - Macro.macro("callAddOne", "(a: Expression) => {{ addOne(a) }} + 3"), - Macro.macro("passMacro", "(a: Expression, f: Macro) => {{ f(a) }} + 4"), - Macro.macro("pass2Macro", "(a: Expression, f1: Macro, f2: Macro) => {{ f1(a) }} + {{ f2(a) }} + 5"), - Macro.macro("pass3Macro", "(a: Expression, b: Expression, f1: Macro, f2: Macro) => {{ f1(a) }} + {{ f2(b) }} + 6"), - Macro.macro("pass4Macro", "(a: Expression, b: Expression, f1: Macro, f2: Macro) => {{ f1(a) }} + {{ f2(b)}}")); - - @DataProvider - public Object[][] macroCall() - { - return new Object[][] { - {"{{ addOne(1) }}", "{{ addOne(1) }}"}, - {"{{ addOne('sum(id)') }}", "{{ addOne('sum(id)') }}"}, - {"{{ callAddOne(1) }}", "{{ callAddOne(1) }}"}, - {"{{ passMacro(1, addOne) }}", "{{ addOne(1) }} + 4"}, - {"{{ pass2Macro(1, addOne, addTwo) }}", "{{ addOne(1) }} + {{ addTwo(1) }} + 5"}, - {"{{ pass3Macro(1, 2, addOne, addTwo) }}", "{{ addOne(1) }} + {{ addTwo(2) }} + 6"}, - {"{{ pass4Macro(1, 2, addOne, addTwo) }}", "{{ addOne(1) }} + {{ addTwo(2) }}"}, - // TODO: trim the redundant space character - {"{{ passMacro(1, addOne) }} + {{ passMacro(2, addTwo) }}", "{{ addOne(1) }} + 4 + {{ addTwo(2) }} + 4"}, - {"{{ passMacro(1, addOne) }} + {{ addOne(1) }}", "{{ addOne(1) }} + 4 + {{ addOne(1) }}"}, - {"{{ standardTime() }}", "{{ standardTime() }}"}, - {"{{ callStandardTime() }}", "{{ callStandardTime() }}"}, - {"{{ passMacroWithoutParam(standardTime) }}", "{{ standardTime() }}"}, - }; - // TODO: unsupported cases: A jinjava expression includes multiple macro calls - // {"{{ passMacro(1, addOne) + addOne(1) }}", "{{addOne(1)}} + 4 + {{addOne(1)}}"} - // {"{{ passMacro(1, addOne) + passMacro(2, addTwo) }}", "{{addOne(1)}} + 4 + {{addTwo(2)}} + 4"} - } - - @Test(dataProvider = "macroCall") - public void testProcessExpression(String expression, String expected) - { - assertThat(JinjavaExpressionProcessor.process(expression, macros).trim()).isEqualTo(expected); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/AbstractTestFramework.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/AbstractTestFramework.java deleted file mode 100644 index ccd8ac98a..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/AbstractTestFramework.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.collect.ImmutableList; -import io.wren.base.SessionContext; -import io.wren.base.client.AutoCloseableIterator; -import io.wren.base.client.duckdb.DuckDBConfig; -import io.wren.base.client.duckdb.DuckDBSettingSQL; -import io.wren.base.client.duckdb.DuckdbClient; -import io.wren.base.dto.Column; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Model; -import org.intellij.lang.annotations.Language; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; - -import java.util.Arrays; -import java.util.List; - -import static io.trino.sql.SqlFormatter.Dialect.DUCKDB; -import static io.trino.sql.SqlFormatter.formatSql; -import static io.wren.base.sqlrewrite.Utils.parseSql; - -public abstract class AbstractTestFramework -{ - public static final SessionContext DEFAULT_SESSION_CONTEXT = - SessionContext.builder().setCatalog("wren").setSchema("test").build(); - private DuckdbClient duckdbClient; - - public static Manifest.Builder withDefaultCatalogSchema() - { - return Manifest.builder() - .setCatalog(DEFAULT_SESSION_CONTEXT.getCatalog().orElseThrow()) - .setSchema(DEFAULT_SESSION_CONTEXT.getSchema().orElseThrow()); - } - - public static Model addColumnsToModel(Model model, Column... columns) - { - return new Model( - model.getName(), - model.getRefSql(), - model.getBaseObject(), - model.getTableReference(), - ImmutableList.builder() - .addAll(model.getColumns()) - .add(columns) - .build(), - model.getPrimaryKey(), - model.isCached(), - model.getRefreshTime()); - } - - @BeforeClass - public void init() - { - duckdbClient = new DuckdbClient(new DuckDBConfig(), new DuckDBSettingSQL()); - prepareData(); - } - - @AfterClass(alwaysRun = true) - public final void close() - { - cleanup(); - duckdbClient.close(); - } - - protected void prepareData() {} - - protected void cleanup() {} - - protected List> query(@Language("SQL") String sql) - { - sql = formatSql(parseSql(sql), DUCKDB); - try (AutoCloseableIterator iterator = duckdbClient.query(sql)) { - ImmutableList.Builder> builder = ImmutableList.builder(); - while (iterator.hasNext()) { - builder.add(Arrays.asList(iterator.next())); - } - return builder.build(); - } - catch (Exception e) { - throw new RuntimeException("Failed SQL: " + sql, e); - } - } - - protected void exec(@Language("SQL") String sql) - { - duckdbClient.executeDDL(sql); - } - - protected static Manifest.Builder copyOf(Manifest manifest) - { - return Manifest.builder() - .setCatalog(manifest.getCatalog()) - .setSchema(manifest.getSchema()) - .setModels(manifest.getModels()) - .setRelationships(manifest.getRelationships()) - .setMetrics(manifest.getMetrics()) - .setCumulativeMetrics(manifest.getCumulativeMetrics()) - .setViews(manifest.getViews()) - .setEnumDefinitions(manifest.getEnumDefinitions()); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/AbstractTestModel.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/AbstractTestModel.java deleted file mode 100644 index 9aacb64cf..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/AbstractTestModel.java +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.collect.ImmutableList; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; -import io.wren.base.dto.TableReference; -import org.intellij.lang.annotations.Language; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.wren.base.sqlrewrite.WrenSqlRewrite.WREN_SQL_REWRITE; -import static java.util.Objects.requireNonNull; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public abstract class AbstractTestModel - extends AbstractTestFramework -{ - protected Model customer; - protected Model orders; - protected Model lineitem; - - protected final List customerColumns; - protected final List ordersColumns; - protected final List lineitemColumns; - protected final Relationship ordersCustomer; - protected final Relationship ordersLineitem; - - public AbstractTestModel() - { - customerColumns = List.of( - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("address", WrenTypes.VARCHAR, null, true), - Column.column("nationkey", WrenTypes.INTEGER, null, true), - Column.column("phone", WrenTypes.VARCHAR, null, true), - Column.column("acctbal", WrenTypes.INTEGER, null, true), - Column.column("mktsegment", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true)); - ordersColumns = List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.VARCHAR, null, true), - Column.column("totalprice", WrenTypes.INTEGER, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true), - Column.column("orderpriority", WrenTypes.VARCHAR, null, true), - Column.column("clerk", WrenTypes.VARCHAR, null, true), - Column.column("shippriority", WrenTypes.INTEGER, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.column("lineitem", "Lineitem", "OrdersLineitem", true)); - lineitemColumns = List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("partkey", WrenTypes.INTEGER, null, true), - Column.column("suppkey", WrenTypes.INTEGER, null, true), - Column.column("linenumber", WrenTypes.INTEGER, null, true), - Column.column("quantity", WrenTypes.INTEGER, null, true), - Column.column("extendedprice", WrenTypes.INTEGER, null, true), - Column.column("discount", WrenTypes.INTEGER, null, true), - Column.column("tax", WrenTypes.INTEGER, null, true), - Column.column("returnflag", WrenTypes.VARCHAR, null, true), - Column.column("linestatus", WrenTypes.VARCHAR, null, true), - Column.column("shipdate", WrenTypes.DATE, null, true), - Column.column("commitdate", WrenTypes.DATE, null, true), - Column.column("receiptdate", WrenTypes.DATE, null, true), - Column.column("shipinstruct", WrenTypes.VARCHAR, null, true), - Column.column("shipmode", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.column("orderkey_linenumber", WrenTypes.VARCHAR, null, true, "concat(orderkey, '-', linenumber)")); - ordersCustomer = Relationship.relationship("OrdersCustomer", List.of("Orders", "Customer"), JoinType.MANY_TO_ONE, "Orders.custkey = Customer.custkey"); - ordersLineitem = Relationship.relationship("OrdersLineitem", List.of("Orders", "Lineitem"), JoinType.ONE_TO_MANY, "Orders.orderkey = Lineitem.orderkey"); - } - - @Override - protected void prepareData() - { - String orders = requireNonNull(getClass().getClassLoader().getResource("tiny-orders.parquet")).getPath(); - exec("create table orders as select * from '" + orders + "'"); - String customer = requireNonNull(getClass().getClassLoader().getResource("tiny-customer.parquet")).getPath(); - exec("create table customer as select * from '" + customer + "'"); - String lineitem = requireNonNull(getClass().getClassLoader().getResource("tiny-lineitem.parquet")).getPath(); - exec("create table lineitem as select * from '" + lineitem + "'"); - } - - @Test - public void testToManyCalculated() - { - // TODO: add this to test case, currently this won't work - // caluclatedColumn("col_3", BIGINT, "concat(address, sum(orders.lineitem.discount * orders.lineitem.extendedprice))"); - - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true), - Column.calculatedColumn("totalprice", WrenTypes.BIGINT, "sum(orders.totalprice)"), - Column.calculatedColumn("buy_item_count", WrenTypes.BIGINT, "count(distinct orders.lineitem.orderkey_linenumber)"), - Column.calculatedColumn("lineitem_totalprice", WrenTypes.BIGINT, "sum(orders.lineitem.discount * orders.lineitem.extendedprice)"), - Column.calculatedColumn("test_col", WrenTypes.BIGINT, "sum(orders.lineitem.discount * nationkey)")); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(newCustomer, orders, lineitem)) - .setRelationships(List.of(ordersCustomer, ordersLineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - - assertQuery(mdl, - "SELECT totalprice FROM Customer WHERE custkey = 370", - "SELECT sum(totalprice) FROM customer c LEFT JOIN orders o ON c.custkey = o.custkey WHERE c.custkey = 370"); - assertQuery(mdl, - "SELECT custkey, buy_item_count FROM Customer WHERE custkey = 370", - "SELECT c.custkey, count(*) FROM customer c " + - "LEFT JOIN orders o ON c.custkey = o.custkey " + - "LEFT JOIN lineitem l ON o.orderkey = l.orderkey " + - "WHERE c.custkey = 370 " + - "GROUP BY 1"); - assertQuery(mdl, - "SELECT custkey, lineitem_totalprice FROM Customer WHERE custkey = 370", - "SELECT c.custkey, sum(l.extendedprice * l.discount) FROM customer c " + - "LEFT JOIN orders o ON c.custkey = o.custkey " + - "LEFT JOIN lineitem l ON o.orderkey = l.orderkey " + - "WHERE c.custkey = 370 " + - "GROUP BY 1"); - - assertQuery(mdl, - "SELECT custkey, test_col FROM Customer WHERE custkey = 370", - "SELECT c.custkey, sum(l.discount * c.nationkey) FROM customer c " + - "LEFT JOIN orders o ON c.custkey = o.custkey " + - "LEFT JOIN lineitem l ON o.orderkey = l.orderkey " + - "WHERE c.custkey = 370 " + - "GROUP BY 1"); - } - - @Test - public void testToOneCalculated() - { - Model newLineitem = addColumnsToModel( - lineitem, - Column.column("orders", "Orders", "OrdersLineitem", true), - Column.calculatedColumn("col_1", WrenTypes.BIGINT, "orders.totalprice + orders.totalprice"), - Column.calculatedColumn("col_2", WrenTypes.BIGINT, "concat(orders.orderkey, '#', orders.customer.custkey)")); - Model newOrders = addColumnsToModel( - orders, - Column.column("customer", "Customer", "OrdersCustomer", true)); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(customer, newOrders, newLineitem)) - .setRelationships(List.of(ordersCustomer, ordersLineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - - assertQuery(mdl, - "SELECT col_1 FROM Lineitem WHERE orderkey = 44995", - "SELECT (totalprice + totalprice) AS col_1\n" + - "FROM lineitem l\n" + - "LEFT JOIN orders o ON l.orderkey = o.orderkey\n" + - "WHERE l.orderkey = 44995"); - assertQuery(mdl, - "SELECT col_1 FROM Lineitem WHERE orderkey = 44995", - "SELECT (totalprice + totalprice) AS col_1\n" + - "FROM lineitem l\n" + - "LEFT JOIN orders o ON l.orderkey = o.orderkey\n" + - "WHERE l.orderkey = 44995"); - assertQuery(mdl, - "SELECT col_2 FROM Lineitem WHERE orderkey = 44995", - "SELECT concat(l.orderkey, '#', c.custkey) AS col_2\n" + - "FROM lineitem l\n" + - "LEFT JOIN orders o ON l.orderkey = o.orderkey\n" + - "LEFT JOIN customer c ON o.custkey = c.custkey\n" + - "WHERE l.orderkey = 44995"); - - assertQuery(mdl, "SELECT count(*) FROM Lineitem", "SELECT count(*) FROM lineitem"); - assertQuery(mdl, "SELECT count(*) FROM Lineitem WHERE orderkey = 44995", - "SELECT count(*) FROM lineitem WHERE orderkey = 44995"); - assertQuery(mdl, "SELECT count(*) FROM Lineitem l WHERE l.orderkey = 44995", - "SELECT count(*) FROM lineitem l WHERE l.orderkey = 44995"); - - assertQuery(mdl, "SELECT col_1 FROM Lineitem ORDER BY col_2", "SELECT (totalprice + totalprice) AS col_1\n" + - "FROM lineitem l\n" + - "LEFT JOIN orders o ON l.orderkey = o.orderkey\n" + - "LEFT JOIN customer c ON o.custkey = c.custkey\n" + - "ORDER BY concat(l.orderkey, '#', c.custkey)"); - assertQuery(mdl, "SELECT count(*) FROM Lineitem group by col_1, col_2 order by 1", "SELECT count(*)\n" + - "FROM lineitem l\n" + - "LEFT JOIN orders o ON l.orderkey = o.orderkey\n" + - "LEFT JOIN customer c ON o.custkey = c.custkey\n" + - "GROUP BY (totalprice + totalprice), concat(l.orderkey, '#', c.custkey)\n" + - "ORDER BY 1"); - assertQuery(mdl, "SELECT rank() over (order by col_1) FROM Lineitem", - "SELECT rank() OVER (ORDER BY (totalprice + totalprice))\n" + - "FROM lineitem l\n" + - "LEFT JOIN orders o ON l.orderkey = o.orderkey"); - assertQuery(mdl, "SELECT count(f1) FROM (SELECT lag(extendedprice) over (partition by col_2) as f1 FROM Lineitem)", - "SELECT count(f1) FROM (SELECT lag(extendedprice) OVER (PARTITION BY concat(l.orderkey, '#', c.custkey)) as f1\n" + - "FROM lineitem l\n" + - "LEFT JOIN orders o ON l.orderkey = o.orderkey\n" + - "LEFT JOIN customer c ON o.custkey = c.custkey)"); - } - - @Test - public void testModelWithCycle() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true), - Column.calculatedColumn("total_price", WrenTypes.BIGINT, "sum(orders.totalprice)")); - Model newOrders = addColumnsToModel( - orders, - Column.column("customer", "Customer", "OrdersCustomer", true), - Column.calculatedColumn("customer_name", WrenTypes.BIGINT, "customer.name")); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(newCustomer, newOrders)) - .setRelationships(List.of(ordersCustomer, ordersLineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - - assertThatCode(() -> query(rewrite("SELECT * FROM Orders", mdl, true))) - .doesNotThrowAnyException(); - assertThatCode(() -> query(rewrite("SELECT customer_name FROM Orders WHERE orderkey = 44995", mdl, true))) - .doesNotThrowAnyException(); - assertThatCode(() -> query(rewrite("SELECT total_price FROM Customer", mdl, true))) - .doesNotThrowAnyException(); - assertThatCode(() -> query(rewrite("SELECT total_price FROM Customer c LEFT JOIN Orders o ON c.custkey = o.custkey", mdl, true))) - .doesNotThrowAnyException(); - assertThatCode(() -> query(rewrite("SELECT o.custkey, total_price FROM Customer c LEFT JOIN Orders o ON c.custkey = o.custkey", mdl, true))) - .doesNotThrowAnyException(); - assertThatCode(() -> query(rewrite("SELECT customer_name, total_price FROM Customer c LEFT JOIN Orders o ON c.custkey = o.custkey", mdl, true))) - .hasMessageMatching("found cycle in .*"); - } - - @Test - public void testModelOnModel() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true), - Column.calculatedColumn("totalprice", WrenTypes.BIGINT, "sum(orders.totalprice)")); - Model onCustomer = Model.onBaseObject( - "OnCustomer", - "Customer", - ImmutableList.of( - Column.column("mom_custkey", "VARCHAR", null, true, "custkey"), - Column.column("mom_totalprice", "VARCHAR", null, true, "totalprice")), - "mom_custkey"); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(newCustomer, onCustomer, orders)) - .setRelationships(List.of(ordersCustomer)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - - assertQuery(mdl, "SELECT mom_custkey, mom_totalprice FROM OnCustomer WHERE mom_custkey = 370", - "SELECT c.custkey, sum(o.totalprice) FROM customer c\n" + - "LEFT JOIN orders o ON c.custkey = o.custkey\n" + - "WHERE c.custkey = 370\n" + - "GROUP BY 1"); - - assertThatCode(() -> query(rewrite("SELECT 1 FROM OnCustomer", mdl, true))) - .doesNotThrowAnyException(); - } - - @Test - public void testCalculatedUseAnotherCalculated() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true), - Column.calculatedColumn("total_price", WrenTypes.BIGINT, "sum(orders.totalprice)")); - Model newOrders = addColumnsToModel( - orders, - Column.column("customer", "Customer", "OrdersCustomer", true), - Column.column("lineitem", "Lineitem", "OrdersLineitem", true), - Column.calculatedColumn("customer_name", WrenTypes.BIGINT, "customer.name"), - Column.calculatedColumn("extended_price", WrenTypes.BIGINT, "sum(lineitem.extendedprice)")); - Model newLineitem = addColumnsToModel( - lineitem, - Column.column("orders", "Orders", "OrdersLineitem", true), - Column.calculatedColumn("test_column", WrenTypes.BIGINT, "orders.customer.total_price + extendedprice")); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(newCustomer, newOrders, newLineitem)) - .setRelationships(List.of(ordersCustomer, ordersLineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - - assertThatCode(() -> query(rewrite("SELECT test_column FROM Lineitem", mdl, true))) - .doesNotThrowAnyException(); - } - - @Test - public void testSelectEmpty() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true), - Column.calculatedColumn("total_price", WrenTypes.BIGINT, "sum(orders.totalprice)")); - Model newOrders = addColumnsToModel( - orders, - Column.column("customer", "Customer", "OrdersCustomer", true), - Column.column("lineitem", "Lineitem", "OrdersLineitem", true), - Column.calculatedColumn("customer_name", WrenTypes.BIGINT, "customer.name"), - Column.calculatedColumn("extended_price", WrenTypes.BIGINT, "sum(lineitem.extendedprice)")); - Model newLineitem = addColumnsToModel( - lineitem, - Column.column("orders", "Orders", "OrdersLineitem", true), - Column.calculatedColumn("test_column", WrenTypes.BIGINT, "orders.customer.total_price + extendedprice")); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(newCustomer, newOrders, newLineitem)) - .setRelationships(List.of(ordersCustomer, ordersLineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - - assertThatCode(() -> query(rewrite("SELECT true \"_\" FROM Lineitem", mdl, true))) - .doesNotThrowAnyException(); - - assertThatCode(() -> query(rewrite("SELECT true \"_\" FROM Lineitem, Orders", mdl, true))) - .doesNotThrowAnyException(); - - assertThatCode(() -> query(rewrite("SELECT orderkey FROM Lineitem, Orders", mdl, true))) - .doesNotThrowAnyException(); - } - - @Test - public void testCustomCTE() - { - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(customer, orders, lineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - assertThatCode(() -> query(rewrite("WITH cte AS (SELECT * FROM Orders) SELECT * FROM cte", mdl, true))) - .doesNotThrowAnyException(); - assertThatCode(() -> query(rewrite("WITH cte AS (SELECT * FROM Orders) SELECT * FROM cte", mdl, false))) - .doesNotThrowAnyException(); - - assertThatCode(() -> query(rewrite("WITH cte AS (SELECT * FROM Orders), cte2 as (SELECT * FROM cte) SELECT * FROM cte2", mdl, true))) - .doesNotThrowAnyException(); - assertThatCode(() -> query(rewrite("WITH cte AS (SELECT * FROM Orders), cte2 as (SELECT * FROM cte) SELECT * FROM cte2", mdl, false))) - .doesNotThrowAnyException(); - } - - @Test - public void testSelectNotFound() - { - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(customer)) - .setRelationships(List.of(ordersCustomer, ordersLineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - assertThatThrownBy(() -> query(rewrite("SELECT * FROM notfound", mdl, true))) - .hasMessageFindingMatch(".*notfound.*"); - } - - @Test - public void testBuildModelFailed() - { - assertThatThrownBy(() -> buildFailedModel("select * from main.orders", "Orders", TableReference.tableReference("memory", "main", "orders"))) - .hasMessageContaining("either none or more than one of (refSql, baseObject, tableReference) are set"); - assertThatThrownBy(() -> buildFailedModel(null, "Orders", TableReference.tableReference("memory", "main", "orders"))) - .hasMessageContaining("either none or more than one of (refSql, baseObject, tableReference) are set"); - assertThatThrownBy(() -> buildFailedModel("select * from main.orders", null, TableReference.tableReference("memory", "main", "orders"))) - .hasMessageContaining("either none or more than one of (refSql, baseObject, tableReference) are set"); - assertThatThrownBy(() -> buildFailedModel("select * from main.orders", "Orders", null)) - .hasMessageContaining("either none or more than one of (refSql, baseObject, tableReference) are set"); - assertThatThrownBy(() -> buildFailedModel(null, null, null)) - .hasMessageContaining("either none or more than one of (refSql, baseObject, tableReference) are set"); - } - - private void buildFailedModel(String refSql, String baseObject, TableReference tableReference) - { - new Model("failed", refSql, baseObject, tableReference, null, null, false, null); - } - - private void assertQuery(WrenMDL mdl, @Language("SQL") String wrenSql, @Language("SQL") String duckDBSql) - { - assertThat(query(rewrite(wrenSql, mdl, true))).isEqualTo(query(duckDBSql)); - assertThat(query(rewrite(wrenSql, mdl, false))).isEqualTo(query(duckDBSql)); - } - - private String rewrite(String sql, WrenMDL wrenMDL, boolean enableDynamicField) - { - SessionContext sessionContext = SessionContext.builder() - .setCatalog("wren") - .setSchema("test") - .setEnableDynamic(enableDynamicField) - .build(); - return WrenPlanner.rewrite(sql, sessionContext, new AnalyzedMDL(wrenMDL, null), List.of(WREN_SQL_REWRITE)); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestAllRulesRewrite.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestAllRulesRewrite.java deleted file mode 100644 index f9d44b350..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestAllRulesRewrite.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Statement; -import io.wren.base.AnalyzedMDL; -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.EnumDefinition; -import io.wren.base.dto.EnumValue; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; -import io.wren.base.dto.View; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.trino.sql.SqlFormatter.formatSql; -import static io.wren.base.sqlrewrite.Utils.parseSql; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestAllRulesRewrite - extends AbstractTestFramework -{ - private final WrenMDL wrenMDL; - - public TestAllRulesRewrite() - { - wrenMDL = WrenMDL.fromManifest(withDefaultCatalogSchema() - .setModels(List.of( - Model.model("Album", - "select * from (values (1, 'Gusare', 1, 2560, 'I', 'IN_STOCK'), " + - "(2, 'HisoHiso Banashi', 1, 1500, 'O', 'OUT_OF_STOCK'), " + - "(3, 'Dakara boku wa ongaku o yameta', 2, 2553, 'I', 'IN_STOCK')) " + - "Album(id, name, bandId, price, status, statusA)", - List.of( - Column.column("id", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.relationshipColumn("band", "Band", "AlbumBand"), - Column.column("price", WrenTypes.INTEGER, null, true), - Column.column("bandId", WrenTypes.INTEGER, null, true), - Column.calculatedColumn("bandName", WrenTypes.VARCHAR, "band.name"), - Column.column("status", "Inventory", null, true), - Column.column("statusA", "InventoryA", null, true), - Column.relationshipColumn("orders", "Order", "AlbumOrder")), - "id"), - Model.model("Band", - "select * from (values (1, 'ZUTOMAYO'), " + - "(2, 'Yorushika')) " + - "Band(id, name)", - List.of( - Column.column("id", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.relationshipColumn("albums", "Album", "AlbumBand")), - "id"), - Model.model("Order", "select * from (values (1, 1), (2, 1), (3, 2), (4, 3)) Orders(orderkey, albumId)", - List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("albumId", WrenTypes.INTEGER, null, true)), - "orderkey"))) - .setRelationships(List.of( - Relationship.relationship("AlbumBand", List.of("Album", "Band"), JoinType.MANY_TO_ONE, "Album.bandId = Band.id"), - Relationship.relationship("AlbumOrder", List.of("Album", "Order"), JoinType.ONE_TO_MANY, - // It's hard to quote the reserve word in the user-defined join condition. - // We should ask users to quote the identifier by themselves if it's a reserve word. - "Album.id = \"Order\".albumId"))) - .setMetrics(List.of( - Metric.metric( - "Collection", - "Album", - List.of(Column.column("band", WrenTypes.VARCHAR, null, true, "bandName")), - List.of(Column.column("price", WrenTypes.INTEGER, null, true, "sum(Album.price)")), - List.of()), - Metric.metric( - "CollectionA", - "Album", - // TODO: we don't support to output a relationship column in a metric. - // It just can be a group by key but can't be accessed with other relationship operation. e.g. `band.name`. - List.of(Column.column("band", WrenTypes.VARCHAR, null, true, null)), - List.of(Column.column("price", WrenTypes.INTEGER, null, true, "sum(Album.price)")), - List.of()))) - .setEnumDefinitions(List.of( - EnumDefinition.enumDefinition("Inventory", List.of(EnumValue.enumValue("IN_STOCK", "I"), EnumValue.enumValue("OUT_OF_STOCK", "O"))), - EnumDefinition.enumDefinition("InventoryA", List.of(EnumValue.enumValue("IN_STOCK"), EnumValue.enumValue("OUT_OF_STOCK"))))) - .setViews(List.of( - View.view("UseModel", "select * from Album"), - View.view("useMetric", "select band, price from Collection"))) - .build()); - } - - @DataProvider - public Object[][] wrenUsedCases() - { - return new Object[][] { - {"select name, price from Album", - "values('Gusare', 2560), ('HisoHiso Banashi', 1500), ('Dakara boku wa ongaku o yameta', 2553)"}, - {"SELECT name, price FROM wren.test.Album", - "values('Gusare', 2560), ('HisoHiso Banashi', 1500), ('Dakara boku wa ongaku o yameta', 2553)"}, - {"select band, cast(price as integer) from useMetric order by band", "values ('Yorushika', 2553), ('ZUTOMAYO', 4060)"}, - {"select * from \"Order\"", "values (1, 1), (2, 1), (3, 2), (4, 3)"}, - {"select name, price from Album where id in (select albumId from \"Order\")", - "values('Gusare', 2560), ('HisoHiso Banashi', 1500), ('Dakara boku wa ongaku o yameta', 2553)"}, - {"select name, price from Album where id not in (select albumId from \"Order\")", - "values(1, 1) limit 0"}, - {"select * from (select name ,price from Album where bandId = 1 union select name, price from Album where bandId = 2) order by price", - "values('HisoHiso Banashi', 1500), ('Dakara boku wa ongaku o yameta', 2553), ('Gusare', 2560)"}, - {"select * from (select name ,price from Album where bandId = 1 except select name, price from Album where bandId = 2) order by price", - "values('HisoHiso Banashi', 1500), ('Gusare', 2560)"}, - {"select * from (select name ,price from Album where bandId = 1 intersect select name, price from Album where bandId = 2) order by price", - "values(1, 1) limit 0"} - }; - } - - @Test(dataProvider = "wrenUsedCases") - public void testWrenRewrite(String original, String expected) - { - String actualSql = rewrite(original); - assertQuery(actualSql, expected); - } - - private void assertQuery(String actual, String expected) - { - assertThat(query(actual)).isEqualTo(query(expected)); - } - - @DataProvider - public Object[][] noRewriteCase() - { - return new Object[][] { - {"select 1, 2, 3"}, - {"select id, name from normalTable"}, - {"with normalCte as (select id, name from normalTable) select id, name from normalCte"}, - {"SELECT Album.id FROM catalog.schema.Album"}, - }; - } - - @Test(dataProvider = "noRewriteCase") - public void testWrenNoRewrite(String original) - { - Statement expectedState = parseSql(original); - assertThat(rewrite(original)).isEqualTo(formatSql(expectedState)); - } - - // TODO: The scope of QuerySpecification is wrong. Enable it after fixing the scope. - @Test(enabled = false) - public void testSetOperationColumnNoMatch() - { - assertThatThrownBy(() -> rewrite("select name, price from Album union select price from Album")) - .hasMessageFindingMatch("query has different number of fields: expected 2, found 1"); - } - - private String rewrite(String sql) - { - return WrenPlanner.rewrite(sql, DEFAULT_SESSION_CONTEXT, new AnalyzedMDL(wrenMDL, null)); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestCumulativeMetric.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestCumulativeMetric.java deleted file mode 100644 index dd1060f07..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestCumulativeMetric.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.collect.ImmutableList; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.DateSpine; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Measure; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.TimeUnit; -import io.wren.base.dto.Window; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.wren.base.sqlrewrite.WrenSqlRewrite.WREN_SQL_REWRITE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestCumulativeMetric - extends AbstractTestFramework -{ - private final Manifest manifest; - private final WrenMDL wrenMDL; - - public TestCumulativeMetric() - { - manifest = withDefaultCatalogSchema() - .setModels(List.of( - Model.model("Orders", - "select * from main.orders", - List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.VARCHAR, null, true), - Column.column("totalprice", WrenTypes.INTEGER, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true), - Column.column("orderpriority", WrenTypes.VARCHAR, null, true), - Column.column("clerk", WrenTypes.VARCHAR, null, true), - Column.column("shippriority", WrenTypes.INTEGER, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true))))) - .setCumulativeMetrics(List.of( - CumulativeMetric.cumulativeMetric("DailyRevenue", - "Orders", Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderdate", "orderdate", TimeUnit.DAY, "1994-01-01", "1994-12-31")), - CumulativeMetric.cumulativeMetric("WeeklyRevenue", - "Orders", Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderdate", "orderdate", TimeUnit.WEEK, "1994-01-01", "1994-12-31")), - CumulativeMetric.cumulativeMetric("MonthlyRevenue", - "Orders", Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderdate", "orderdate", TimeUnit.MONTH, "1994-01-01", "1994-12-31")), - CumulativeMetric.cumulativeMetric("QuarterlyRevenue", - "Orders", Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderdate", "orderdate", TimeUnit.QUARTER, "1994-01-01", "1995-12-31")), - CumulativeMetric.cumulativeMetric("YearlyRevenue", - "Orders", Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderdate", "orderdate", TimeUnit.YEAR, "1994-01-01", "1998-12-31")))) - .setDateSpine(new DateSpine(TimeUnit.DAY, "1970-01-01", "2077-12-31")) - .build(); - wrenMDL = WrenMDL.fromManifest(manifest); - } - - @Override - protected void prepareData() - { - String orders = getClass().getClassLoader().getResource("tiny-orders.parquet").getPath(); - exec("create table orders as select * from '" + orders + "'"); - } - - @Test - public void testCumulativeMetric() - { - List.of(true, false).forEach(enableDynamic -> { - assertThat(query(rewrite("select * from DailyRevenue", wrenMDL, enableDynamic)).size()).isEqualTo(365); - assertThat(query(rewrite("select * from WeeklyRevenue", wrenMDL, enableDynamic)).size()).isEqualTo(53); - assertThat(query(rewrite("select * from MonthlyRevenue", wrenMDL, enableDynamic)).size()).isEqualTo(12); - assertThat(query(rewrite("select * from QuarterlyRevenue", wrenMDL, enableDynamic)).size()).isEqualTo(8); - assertThat(query(rewrite("select * from YearlyRevenue", wrenMDL, enableDynamic)).size()).isEqualTo(5); - }); - - List.of(true, false).forEach(enableDynamic -> { - assertThatCode(() -> query(rewrite("SELECT 1 FROM DailyRevenue", wrenMDL, true))) - .doesNotThrowAnyException(); - }); - } - - @Test - public void testModelOnCumulativeMetric() - { - List models = ImmutableList.builder() - .addAll(manifest.getModels()) - .add(Model.onBaseObject( - "testModelOnCumulativeMetric", - "WeeklyRevenue", - List.of( - Column.column("totalprice", WrenTypes.INTEGER, null, false), - Column.column("orderdate", "DATE", null, false)), - "orderdate")) - .build(); - WrenMDL mdl = WrenMDL.fromManifest( - copyOf(manifest) - .setModels(models) - .build()); - - List.of(true, false).forEach(enableDynamic -> { - List> result = query(rewrite("select * from testModelOnCumulativeMetric", mdl, enableDynamic)); - assertThat(result.get(0).size()).isEqualTo(2); - assertThat(result.size()).isEqualTo(53); - }); - - List.of(true, false).forEach(enableDynamic -> { - assertThatCode(() -> query(rewrite("SELECT 1 FROM testModelOnCumulativeMetric", mdl, true))) - .doesNotThrowAnyException(); - }); - } - - @Test - public void testMetricOnCumulativeMetric() - { - List metrics = ImmutableList.builder() - .addAll(manifest.getMetrics()) - .add(Metric.metric( - "testMetricOnCumulativeMetric", - "DailyRevenue", - List.of(Column.column("ordermonth", "DATE", null, false, "date_trunc('month', orderdate)")), - List.of(Column.column("totalprice", WrenTypes.INTEGER, null, false, "sum(totalprice)")), - List.of())) - .build(); - WrenMDL mdl = WrenMDL.fromManifest( - copyOf(manifest) - .setMetrics(metrics) - .build()); - - List.of(true, false).forEach(enableDynamic -> { - List> result = query(rewrite("SELECT * FROM testMetricOnCumulativeMetric ORDER BY ordermonth", mdl, enableDynamic)); - assertThat(result.get(0).size()).isEqualTo(2); - assertThat(result.size()).isEqualTo(12); - }); - - List.of(true, false).forEach(enableDynamic -> { - assertThatCode(() -> query(rewrite("SELECT 1 FROM testMetricOnCumulativeMetric", mdl, true))) - .doesNotThrowAnyException(); - }); - } - - @Test - public void testCumulativeMetricOnCumulativeMetric() - { - List cumulativeMetrics = ImmutableList.builder() - .addAll(manifest.getCumulativeMetrics()) - .add(CumulativeMetric.cumulativeMetric("testCumulativeMetricOnCumulativeMetric", - "YearlyRevenue", Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderyear", "orderdate", TimeUnit.YEAR, "1994-01-01", "1998-12-31"))) - .build(); - WrenMDL mdl = WrenMDL.fromManifest( - copyOf(manifest) - .setCumulativeMetrics(cumulativeMetrics) - .build()); - - List.of(true, false).forEach(enableDynamic -> { - List> result = query(rewrite("SELECT * FROM testCumulativeMetricOnCumulativeMetric ORDER BY orderyear", mdl, enableDynamic)); - assertThat(result.get(0).size()).isEqualTo(2); - assertThat(result.size()).isEqualTo(5); - }); - - List.of(true, false).forEach(enableDynamic -> { - assertThatCode(() -> query(rewrite("SELECT 1 FROM testCumulativeMetricOnCumulativeMetric", mdl, true))) - .doesNotThrowAnyException(); - }); - } - - @Test - public void testInvalidCumulativeMetricOnCumulativeMetric() - { - List cumulativeMetrics = ImmutableList.builder() - .addAll(manifest.getCumulativeMetrics()) - .add(CumulativeMetric.cumulativeMetric("testInvalidCumulativeMetricOnCumulativeMetric", - "YearlyRevenue", Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - // window refColumn is a measure that belongs to cumulative metric - Window.window("foo", "totalprice", TimeUnit.YEAR, "1994-01-01", "1998-12-31"))) - .build(); - WrenMDL mdl = WrenMDL.fromManifest( - copyOf(manifest) - .setCumulativeMetrics(cumulativeMetrics) - .build()); - - List.of(true, false).forEach(enableDynamic -> { - assertThatThrownBy(() -> rewrite("SELECT * FROM testInvalidCumulativeMetricOnCumulativeMetric", mdl, enableDynamic)) - .hasMessage("CumulativeMetric measure cannot be window as it is not date/timestamp type"); - }); - } - - @Test - public void testCumulativeMetricOnMetric() - { - List metrics = ImmutableList.of( - Metric.metric("RevenueByOrderdate", "Orders", - List.of(Column.column("orderdate", WrenTypes.DATE, null, true, "orderdate")), - List.of(Column.column("totalprice", WrenTypes.INTEGER, null, true, "sum(totalprice)")), - List.of())); - List cumulativeMetrics = ImmutableList.builder() - .addAll(manifest.getCumulativeMetrics()) - .add(CumulativeMetric.cumulativeMetric("testCumulativeMetricOnMetric", - "RevenueByOrderdate", Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderyear", "orderdate", TimeUnit.YEAR, "1994-01-01", "1998-12-31"))) - .build(); - WrenMDL mdl = WrenMDL.fromManifest( - copyOf(manifest) - .setMetrics(metrics) - .setCumulativeMetrics(cumulativeMetrics) - .build()); - - List.of(true, false).forEach(enableDynamic -> { - List> result = query(rewrite("SELECT * FROM testCumulativeMetricOnMetric ORDER BY orderyear", mdl, enableDynamic)); - assertThat(result.get(0).size()).isEqualTo(2); - assertThat(result.size()).isEqualTo(5); - }); - - List.of(true, false).forEach(enableDynamic -> { - assertThatCode(() -> query(rewrite("SELECT 1 FROM testCumulativeMetricOnMetric", mdl, true))) - .doesNotThrowAnyException(); - }); - } - - private String rewrite(String sql, WrenMDL wrenMDL, boolean enableDynamic) - { - SessionContext sessionContext = SessionContext.builder() - .setCatalog("wren") - .setSchema("test") - .setEnableDynamic(enableDynamic) - .build(); - return WrenPlanner.rewrite(sql, sessionContext, new AnalyzedMDL(wrenMDL, null), List.of(WREN_SQL_REWRITE)); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestEnumRewrite.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestEnumRewrite.java deleted file mode 100644 index 08b390945..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestEnumRewrite.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.parser.ParsingOptions; -import io.trino.sql.parser.SqlParser; -import io.trino.sql.tree.Statement; -import io.wren.base.AnalyzedMDL; -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.EnumDefinition; -import io.wren.base.dto.EnumValue; -import io.wren.base.dto.Model; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.wren.base.sqlrewrite.EnumRewrite.ENUM_REWRITE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestEnumRewrite - extends AbstractTestFramework -{ - private final WrenMDL wrenMDL; - - private static final SqlParser SQL_PARSER = new SqlParser(); - - public TestEnumRewrite() - { - this.wrenMDL = WrenMDL.fromManifest(withDefaultCatalogSchema() - .setModels(List.of( - Model.model("People", - "select * from (values (1, 'user1', 'MALE', 'tw'), (2, 'user2', 'FEMALE', 'jp'), (3, 'user3', 'MALE', 'us')) People(userId, name)", - List.of( - Column.column("userId", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("sex", "Sex", null, true), - Column.column("country", "Country", null, true)), - "userId"))) - .setEnumDefinitions(List.of( - EnumDefinition.enumDefinition("Sex", List.of(EnumValue.enumValue("MALE"), EnumValue.enumValue("FEMALE"))), - EnumDefinition.enumDefinition("Country", List.of(EnumValue.enumValue("TAIWAN", "tw"), EnumValue.enumValue("JAPAN", "jp"), EnumValue.enumValue("USA", "us"))))) - .build()); - } - - @Test - public void testBasic() - { - assertThat(rewrite("select Sex.MALE")).isEqualTo(parse("select 'MALE'")); - assertThat(rewrite("select Country.TAIWAN")).isEqualTo(parse("select 'tw'")); - assertThat(rewrite("select sex = Sex.MALE from People")).isEqualTo(rewrite("select sex = 'MALE' from People")); - assertThat(rewrite("select country = Country.JAPAN from People")).isEqualTo(rewrite("select country = 'jp' from People")); - assertThat(rewrite("select * from People WHERE sex = Sex.MALE")).isEqualTo(rewrite("select * from People WHERE sex = 'MALE'")); - } - - @Test - public void testNoRewrite() - { - assertNoRewrite("select MALE"); - assertNoRewrite("select country.TAIWAN"); - } - - @Test - public void testInvalidEnum() - { - assertThatThrownBy(() -> rewrite("select Country.China")) - .hasMessage("Enum value 'China' not found in enum 'Country'"); - assertThatThrownBy(() -> rewrite("select Country.taiwan")) - .hasMessage("Enum value 'taiwan' not found in enum 'Country'"); - assertThatThrownBy(() -> rewrite("select Country.tw")) - .hasMessage("Enum value 'tw' not found in enum 'Country'"); - } - - private void assertNoRewrite(String sql) - { - assertThat(rewrite(sql)).isEqualTo(parse(sql)); - } - - private Statement rewrite(String sql) - { - return ENUM_REWRITE.apply(parse(sql), DEFAULT_SESSION_CONTEXT, new AnalyzedMDL(wrenMDL, null)); - } - - private Statement parse(String sql) - { - return SQL_PARSER.createStatement(sql, new ParsingOptions()); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestExpressionRelationshipRewriter.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestExpressionRelationshipRewriter.java deleted file mode 100644 index b3b38cc39..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestExpressionRelationshipRewriter.java +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.QualifiedName; -import io.wren.base.WrenMDL; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipAnalyzer; -import io.wren.base.sqlrewrite.analyzer.ExpressionRelationshipInfo; -import io.wren.base.sqlrewrite.analyzer.RelationshipColumnInfo; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; -import java.util.Set; - -import static com.google.common.collect.ImmutableList.toImmutableList; -import static com.google.common.collect.ImmutableSet.toImmutableSet; -import static io.wren.base.sqlrewrite.Utils.parseExpression; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestExpressionRelationshipRewriter -{ - private WrenMDL mdl; - private Model orders; - private Model nation; - private Relationship ordersCustomer; - private Relationship customerNation; - - @BeforeClass - public void init() - throws IOException - { - mdl = WrenMDL.fromJson(Files.readString(Path.of(getClass().getClassLoader().getResource("tpch_mdl.json").getPath()))); - orders = mdl.getModel("Orders").orElseThrow(); - nation = mdl.getModel("Nation").orElseThrow(); - ordersCustomer = mdl.getRelationship("OrdersCustomer").orElseThrow(); - customerNation = mdl.getRelationship("CustomerNation").orElseThrow(); - } - - @DataProvider - public Object[][] rewriteTests() - { - return new Object[][] { - {"customer.custkey", "\"Customer\".\"custkey\"", List.of(ordersCustomer)}, - {"customer.custkey + customer.custkey", "(\"Customer\".\"custkey\" + \"Customer\".\"custkey\")", List.of(ordersCustomer)}, - {"customer.nation.name", "\"Nation\".\"name\"", List.of(ordersCustomer, customerNation)}, - {"customer.nation.nationkey + 1", "(\"Nation\".\"nationkey\" + 1)", List.of(ordersCustomer, customerNation)}, - {"concat('#', customer.nation.name)", "concat('#', \"Nation\".\"name\")", List.of(ordersCustomer, customerNation)}, - {"concat(customer.name, '#', customer.nation.name)", "concat(\"Customer\".\"name\", '#', \"Nation\".\"name\")", - List.of(ordersCustomer, customerNation, ordersCustomer)}, - }; - } - - @Test(dataProvider = "rewriteTests") - public void testGetToOneRelationshipsRewrite(String actual, String expected, List relationships) - { - Expression expression = parseExpression(actual); - Set expressionRelationshipInfos = ExpressionRelationshipAnalyzer.getToOneRelationships(expression, mdl, orders); - assertThat(expressionRelationshipInfos.stream().map(ExpressionRelationshipInfo::getRelationships).flatMap(List::stream).collect(toImmutableList())) - .containsExactlyInAnyOrderElementsOf(relationships); - assertThat(RelationshipRewriter.rewrite(expressionRelationshipInfos, expression).toString()).isEqualTo(expected); - } - - @DataProvider - public Object[][] testGetRelationshipsRewrite() - { - return new Object[][] { - {"customer.custkey", "\"Customer\".\"custkey\"", List.of(Relationship.reverse(customerNation))}, - {"customer.custkey + customer.custkey", "(\"Customer\".\"custkey\" + \"Customer\".\"custkey\")", List.of(Relationship.reverse(customerNation))}, - {"customer.orders.totalprice", "\"Orders\".\"totalprice\"", List.of(Relationship.reverse(customerNation), Relationship.reverse(ordersCustomer))}, - {"customer.orders.totalprice + 1", "(\"Orders\".\"totalprice\" + 1)", List.of(Relationship.reverse(customerNation), Relationship.reverse(ordersCustomer))}, - {"sum(customer.custkey, customer.orders.orderkey)", "sum(\"Customer\".\"custkey\", \"Orders\".\"orderkey\")", - List.of(Relationship.reverse(customerNation), Relationship.reverse(customerNation), Relationship.reverse(ordersCustomer))}, - }; - } - - @Test(dataProvider = "testGetRelationshipsRewrite") - public void testGetRelationshipsRewrite(String actual, String expected, List relationships) - { - Expression expression = parseExpression(actual); - Set expressionRelationshipInfos = ExpressionRelationshipAnalyzer.getRelationships(expression, mdl, nation); - assertThat(expressionRelationshipInfos.stream().map(ExpressionRelationshipInfo::getRelationships).flatMap(List::stream).collect(toImmutableList())) - .containsExactlyInAnyOrderElementsOf(relationships); - assertThat(RelationshipRewriter.rewrite(expressionRelationshipInfos, expression).toString()).isEqualTo(expected); - } - - @Test - public void testInvalidGetToOneRelationships() - { - assertThatThrownBy(() -> ExpressionRelationshipAnalyzer.getToOneRelationships(parseExpression("customer.custkey"), mdl, nation)) - .hasMessage("expr in model only accept to-one relation"); - assertThatThrownBy(() -> ExpressionRelationshipAnalyzer.getToOneRelationships(parseExpression("customer.nation.customer.custkey"), mdl, orders)) - .hasMessage("expr in model only accept to-one relation"); - } - - @Test - public void testNoRelationshipFound() - { - // won't collect relationship if direct access relationship column - assertThat(ExpressionRelationshipAnalyzer.getToOneRelationships(parseExpression("customer"), mdl, nation)).isEmpty(); - assertThat(ExpressionRelationshipAnalyzer.getToOneRelationships(parseExpression("customer.nation"), mdl, orders)).isEmpty(); - // won't collect relationship if column not found in model - assertThat(ExpressionRelationshipAnalyzer.getToOneRelationships(parseExpression("foo"), mdl, orders)).isEmpty(); - // won't collect relationship since "Orders" is not a column in orders model - assertThat(ExpressionRelationshipAnalyzer.getToOneRelationships(parseExpression("Orders.customer.custkey"), mdl, orders)).isEmpty(); - } - - @Test - public void testCycle() - { - assertThatThrownBy(() -> ExpressionRelationshipAnalyzer.getToOneRelationships(parseExpression("region.nation"), mdl, nation)) - .hasMessage("found cycle in expression"); - } - - @Test - public void testMetricMeasureRelationship() - { - Set infos = ExpressionRelationshipAnalyzer.getRelationships(parseExpression("sum(customer.name)"), mdl, orders).stream().collect(toImmutableSet()); - - ExpressionRelationshipInfo expected = new ExpressionRelationshipInfo( - QualifiedName.of("customer", "name"), - List.of("customer"), - List.of("name"), - List.of(new RelationshipColumnInfo( - orders, - orders.getColumns().stream().filter(c -> c.getName().equals("customer")).findAny().orElseThrow(), - ordersCustomer)), - ordersCustomer); - assertThat(infos).containsExactlyInAnyOrder(expected); - - assertThat(RelationshipRewriter.relationshipAware(infos, "count_of_customer", parseExpression("sum(customer.name)")).toString()) - .isEqualTo("sum(\"count_of_customer\".\"name\")"); - - infos = ExpressionRelationshipAnalyzer.getRelationships(parseExpression("sum(customer.name) + sum(customer.name)"), mdl, orders).stream().collect(toImmutableSet()); - assertThat(infos).containsExactlyInAnyOrder(expected); - assertThat(RelationshipRewriter.relationshipAware(infos, "count_of_customer", parseExpression("sum(customer.name)")).toString()) - .isEqualTo("sum(\"count_of_customer\".\"name\")"); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestMetric.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestMetric.java deleted file mode 100644 index b8304f8e1..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestMetric.java +++ /dev/null @@ -1,432 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.collect.ImmutableList; -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; -import io.wren.base.dto.TimeGrain; -import io.wren.base.dto.TimeUnit; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.wren.base.dto.TableReference.tableReference; -import static io.wren.base.sqlrewrite.WrenSqlRewrite.WREN_SQL_REWRITE; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; -import static org.assertj.core.api.Assertions.assertThatNoException; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestMetric - extends AbstractTestFramework -{ - private final Manifest manifest; - private final WrenMDL wrenMDL; - - public TestMetric() - { - manifest = withDefaultCatalogSchema() - .setModels(List.of( - Model.onTableReference("Orders", - tableReference("memory", "main", "orders"), - List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.VARCHAR, null, true), - Column.column("totalprice", WrenTypes.INTEGER, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true), - Column.column("orderpriority", WrenTypes.VARCHAR, null, true), - Column.column("clerk", WrenTypes.VARCHAR, null, true), - Column.column("shippriority", WrenTypes.INTEGER, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.calculatedColumn("customer_name", WrenTypes.VARCHAR, "customer.name"), - Column.calculatedColumn("cumstomer_address", WrenTypes.VARCHAR, "customer.address"), - Column.column("customer", "Customer", "OrdersCustomer", true), - Column.column("lineitem", "Lineitem", "OrdersLineitem", true)), - "orderkey"), - Model.model("Customer", - "select * from main.customer", - List.of( - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("address", WrenTypes.VARCHAR, null, true), - Column.column("nationkey", WrenTypes.INTEGER, null, true), - Column.column("phone", WrenTypes.VARCHAR, null, true), - Column.column("acctbal", WrenTypes.INTEGER, null, true), - Column.column("mktsegment", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.column("orders", "Orders", "OrdersCustomer", true)), - "custkey"), - Model.model("Lineitem", - "select * from main.lineitem", - List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("partkey", WrenTypes.INTEGER, null, true), - Column.column("suppkey", WrenTypes.INTEGER, null, true), - Column.column("linenumber", WrenTypes.INTEGER, null, true), - Column.column("quantity", WrenTypes.INTEGER, null, true), - Column.column("extendedprice", WrenTypes.INTEGER, null, true), - Column.column("discount", WrenTypes.INTEGER, null, true), - Column.column("tax", WrenTypes.INTEGER, null, true), - Column.column("returnflag", WrenTypes.VARCHAR, null, true), - Column.column("linestatus", WrenTypes.VARCHAR, null, true), - Column.column("shipdate", WrenTypes.DATE, null, true), - Column.column("commitdate", WrenTypes.DATE, null, true), - Column.column("receiptdate", WrenTypes.DATE, null, true), - Column.column("shipinstruct", WrenTypes.VARCHAR, null, true), - Column.column("shipmode", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.column("orderkey_linenumber", WrenTypes.VARCHAR, null, true, "concat(orderkey, '-', linenumber)"), - Column.column("order_record", "Orders", "OrdersLineitem", true)), - "orderkey_linenumber"))) - .setRelationships(List.of( - Relationship.relationship("OrdersCustomer", List.of("Orders", "Customer"), JoinType.MANY_TO_ONE, "Orders.custkey = Customer.custkey"), - Relationship.relationship("OrdersLineitem", List.of("Orders", "Lineitem"), JoinType.ONE_TO_MANY, "Orders.orderkey = Lineitem.orderkey"))) - .setMetrics(List.of( - Metric.metric("TotalpriceByCustomer", "Customer", - List.of( - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true, "orders.orderdate")), - List.of( - Column.column("totalprice", WrenTypes.INTEGER, null, true, "sum(orders.totalprice)")), - List.of( - TimeGrain.timeGrain("orderdata", "orderdate", List.of(TimeUnit.DAY, TimeUnit.MONTH, TimeUnit.YEAR)))), - Metric.metric("TotalpriceByCustomerYear", "Customer", - List.of( - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true, "date_trunc('YEAR', orders.orderdate)")), - List.of( - Column.column("totalprice", WrenTypes.INTEGER, null, true, "sum(orders.totalprice)")), - List.of( - TimeGrain.timeGrain("orderdata", "orderdate", List.of(TimeUnit.DAY, TimeUnit.MONTH, TimeUnit.YEAR)))), - Metric.metric("TotalpriceByCustomerBaseOrders", "Orders", - List.of( - Column.column("name", WrenTypes.VARCHAR, null, true, "customer.name"), - Column.column("orderdate", WrenTypes.DATE, null, true)), - List.of( - Column.column("totalprice", WrenTypes.INTEGER, null, true, "sum(totalprice)")), - List.of( - TimeGrain.timeGrain("orderdata", "orderdate", List.of(TimeUnit.DAY, TimeUnit.MONTH, TimeUnit.YEAR)))), - Metric.metric("TotalpriceByCustomerBaseOrdersYear", "Orders", - List.of( - Column.column("name", WrenTypes.VARCHAR, null, true, "customer.name"), - Column.column("orderdate", WrenTypes.DATE, null, true, "date_trunc('YEAR', orderdate)")), - List.of( - Column.column("totalprice", WrenTypes.INTEGER, null, true, "sum(totalprice)")), - List.of()), - Metric.metric("NumberCustomerByDate", "Orders", - List.of(Column.column("orderdate", WrenTypes.DATE, null, true)), - List.of(Column.column("count_of_customer", WrenTypes.INTEGER, null, true, "count(distinct customer.name)")), - List.of()), - Metric.metric("SumExtendedPriceByCustomer", "Customer", - List.of(Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true, "orders.orderdate")), - List.of(Column.column("sum_extendprice", WrenTypes.INTEGER, null, true, "sum(orders.lineitem.extendedprice)")), - List.of()), - Metric.metric("SumExtendedPriceByCustomerBaseLineitem", "Lineitem", - List.of(Column.column("name", WrenTypes.VARCHAR, null, true, "order_record.customer.name"), - Column.column("orderdate", WrenTypes.DATE, null, true, "order_record.orderdate")), - List.of(Column.column("sum_extendprice", WrenTypes.INTEGER, null, true, "sum(extendedprice)")), - List.of()), - Metric.metric("RevenueByCustomer", "Customer", - List.of(Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true, "orders.orderdate")), - List.of(Column.column("revenue", WrenTypes.INTEGER, null, true, "sum(orders.lineitem.extendedprice * (1 - orders.lineitem.discount))")), - List.of()), - Metric.metric("RevenueByCustomerBaseLineitem", "Lineitem", - List.of(Column.column("name", WrenTypes.VARCHAR, null, true, "order_record.customer.name"), - Column.column("orderdate", WrenTypes.DATE, null, true, "order_record.orderdate")), - List.of(Column.column("revenue", WrenTypes.INTEGER, null, true, "sum(extendedprice * (1 - discount))")), - List.of()), - Metric.metric("SumExtendedpriceAddTotalpriceByCustomerBaseOrders", "Orders", - List.of(Column.column("name", WrenTypes.VARCHAR, null, true, "customer.name"), - Column.column("orderdate", WrenTypes.DATE, null, true, "orderdate")), - List.of(Column.column("extAddTotalprice", WrenTypes.INTEGER, null, true, "sum(totalprice + lineitem.extendedprice)")), - List.of()), - Metric.metric("SumExtendedpriceAddTotalpriceByCustomerBaseLineitem", "Lineitem", - List.of(Column.column("name", WrenTypes.VARCHAR, null, true, "order_record.customer.name"), - Column.column("orderdate", WrenTypes.DATE, null, true, "order_record.orderdate")), - List.of(Column.column("extAddTotalprice", WrenTypes.INTEGER, null, true, "sum(order_record.totalprice + extendedprice)")), - List.of()), - Metric.metric("CountOrderkey", "Orders", - List.of(Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true)), - List.of(Column.column("count", WrenTypes.INTEGER, null, true, "count(orderkey)")), - List.of()), - Metric.metric("CountOrders", "Orders", - List.of(Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.VARCHAR, null, true)), - List.of(Column.column("count", WrenTypes.INTEGER, null, true, "count(*)")), - List.of()), - Metric.metric("CountOrders2", "CountOrders", - List.of(Column.column("orderstatus", WrenTypes.VARCHAR, null, true)), - List.of(Column.column("sum_count", WrenTypes.INTEGER, null, true, "sum(count)")), - List.of()))) - .build(); - wrenMDL = WrenMDL.fromManifest(manifest); - } - - @Override - protected void prepareData() - { - String orders = getClass().getClassLoader().getResource("tiny-orders.parquet").getPath(); - exec("create table orders as select * from '" + orders + "'"); - String customer = getClass().getClassLoader().getResource("tiny-customer.parquet").getPath(); - exec("create table customer as select * from '" + customer + "'"); - String lineitem = getClass().getClassLoader().getResource("tiny-lineitem.parquet").getPath(); - exec("create table lineitem as select * from '" + lineitem + "'"); - } - - @Test - public void testMetricUseToOneRelationship() - { - List> result = query(rewrite("select * from TotalpriceByCustomerBaseOrders", true)); - assertThat(result.get(0).size()).isEqualTo(3); - assertThat(result.size()).isEqualTo(14958); - - assertThatNoException() - .isThrownBy(() -> query(rewrite("select name, orderdate, totalprice from TotalpriceByCustomerBaseOrders"))); - - List> measureRelationship = query(rewrite("select * from NumberCustomerByDate")); - assertThat(measureRelationship.get(0).size()).isEqualTo(2); - assertThat(measureRelationship.size()).isEqualTo(2401); - } - - @Test - public void testMetricUseToManyRelationship() - { - List> result = query(rewrite("select * from TotalpriceByCustomer")); - assertThat(result.get(0).size()).isEqualTo(3); - assertThat(result.size()).isEqualTo(15458); - - assertThat(query(rewrite("SELECT totalprice FROM TotalpriceByCustomer " + - "WHERE \"name\" = 'Customer#000000392' and orderdate = DATE '1996-01-10'")).get(0).get(0)) - .isEqualTo(query(rewrite("SELECT totalprice FROM TotalpriceByCustomerBaseOrders " + - "WHERE \"name\" = 'Customer#000000392' and orderdate = DATE '1996-01-10'")).get(0).get(0)); - } - - @Test - public void testMetricUseThreeLevelRelationship() - { - List> result = query(rewrite("select * from SumExtendedPriceByCustomer")); - assertThat(result.get(0).size()).isEqualTo(3); - assertThat(result.size()).isEqualTo(15458); - - assertThat(query(rewrite("SELECT sum_extendprice FROM SumExtendedPriceByCustomer " + - "WHERE \"name\" = 'Customer#000000392' and orderdate = DATE '1996-01-10'")).get(0).get(0)) - .isEqualTo(query(rewrite("SELECT sum_extendprice FROM SumExtendedPriceByCustomerBaseLineitem " + - "WHERE \"name\" = 'Customer#000000392' and orderdate = DATE '1996-01-10'")).get(0).get(0)); - } - - @Test - public void testMultipleRelationshipFieldInExpression() - { - List> result = query(rewrite("select * from RevenueByCustomer")); - assertThat(result.get(0).size()).isEqualTo(3); - assertThat(result.size()).isEqualTo(15458); - - assertThat(query(rewrite("SELECT revenue FROM RevenueByCustomer " + - "WHERE \"name\" = 'Customer#000000392' and orderdate = DATE '1996-01-10'")).get(0).get(0)) - .isEqualTo(query(rewrite("SELECT revenue FROM RevenueByCustomerBaseLineitem " + - "WHERE \"name\" = 'Customer#000000392' and orderdate = DATE '1996-01-10'")).get(0).get(0)); - } - - @Test - public void testExpressionIncludeRelationshipAndNonRelatinonship() - { - assertThat(query(rewrite("SELECT extAddTotalprice FROM SumExtendedpriceAddTotalpriceByCustomerBaseOrders " + - "WHERE \"name\" = 'Customer#000000392' and orderdate = DATE '1996-01-10'")).get(0).get(0)) - .isEqualTo(query(rewrite("SELECT extAddTotalprice FROM SumExtendedpriceAddTotalpriceByCustomerBaseLineitem " + - "WHERE \"name\" = 'Customer#000000392' and orderdate = DATE '1996-01-10'")).get(0).get(0)); - } - - @Test - public void testSelectEmptyWithDynamic() - { - assertThatCode(() -> query(rewrite("select 1 from TotalpriceByCustomerBaseOrders", true))) - .doesNotThrowAnyException(); - } - - @Test - public void testModelOnMetric() - { - List models = ImmutableList.builder() - .addAll(manifest.getModels()) - .add(Model.onBaseObject( - "testModelOnMetric", - "TotalpriceByCustomerBaseOrders", - List.of( - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("revenue", WrenTypes.INTEGER, null, true, "totalprice")), - "name")) - .build(); - WrenMDL mdl = WrenMDL.fromManifest( - copyOf(manifest) - .setModels(models) - .build()); - - List> result = query(rewrite("select * from testModelOnMetric", mdl)); - assertThat(result.get(0).size()).isEqualTo(2); - assertThat(result.size()).isEqualTo(14958); - - assertThatCode(() -> query(rewrite("select 1 from testModelOnMetric", mdl, true))) - .doesNotThrowAnyException(); - } - - @Test - public void testMetricOnMetric() - { - List metrics = ImmutableList.builder() - .addAll(manifest.getMetrics()) - .add(Metric.metric( - "testMetricOnMetric", - "TotalpriceByCustomerBaseOrders", - List.of(Column.column("orderyear", WrenTypes.VARCHAR, null, true, "DATE_TRUNC('YEAR', orderdate)")), - List.of(Column.column("revenue", WrenTypes.INTEGER, null, true, "sum(totalprice)")), - List.of())) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(copyOf(manifest).setMetrics(metrics).build()); - - List> result = query(rewrite("SELECT * FROM testMetricOnMetric ORDER BY orderyear", mdl)); - assertThat(result.get(0).size()).isEqualTo(2); - assertThat(result.size()).isEqualTo(7); - - assertThatCode(() -> query(rewrite("select 1 from testMetricOnMetric", mdl, true))) - .doesNotThrowAnyException(); - } - - @Test - public void testAggregatePrimaryKey() - { - List> result = query(rewrite("select * from CountOrderkey limit 10")); - assertThat(result.get(0).size()).isEqualTo(3); - assertThat(result.size()).isEqualTo(10); - } - - @Test - public void testDynamicMetricOnModel() - { - // select all in CountOrders - assertThat(query(rewrite("SELECT * FROM CountOrders WHERE custkey = 370", true))) - .isEqualTo(query("SELECT custkey, orderstatus, count(*) FROM orders WHERE custkey = 370 GROUP BY 1, 2")); - assertThat(query(rewrite("SELECT * FROM CountOrders WHERE custkey = 370", true))) - .isEqualTo(query(rewrite("SELECT * FROM CountOrders WHERE custkey = 370", false))); - - // select dim in CountOrders - assertThat(query(rewrite("SELECT custkey FROM CountOrders WHERE custkey = 370", true))) - .isEqualTo(query("WITH output AS (SELECT custkey, count(*) FROM orders WHERE custkey = 370 GROUP BY 1) SELECT custkey FROM output")); - - // select measure in CountOrders - assertThat(query(rewrite("SELECT count FROM CountOrders WHERE custkey = 370", true))) - .isEqualTo(query("WITH output AS (SELECT custkey, count(*) AS count FROM orders WHERE custkey = 370 GROUP BY 1) SELECT count FROM output")); - - // select dim custkey and measure count in CountOrders - assertThat(query(rewrite("SELECT custkey, count FROM CountOrders WHERE custkey = 370", true))) - .isEqualTo(query("SELECT custkey, count(*) FROM orders WHERE custkey = 370 GROUP BY 1")); - - // select only measure will use all dimension - assertThat(query(rewrite("SELECT count FROM CountOrders ORDER BY 1", true))) - .isEqualTo(query("WITH output AS (SELECT count(*) AS count FROM orders) SELECT count FROM output ORDER BY 1")); - - // apply count(*) on metric - assertThat(query(rewrite("SELECT count(*) FROM CountOrders ORDER BY 1", true))) - .isEqualTo(query("WITH output AS (SELECT custkey, orderstatus, count(*) AS count FROM orders GROUP BY 1, 2) SELECT count(*) FROM output")); - - // apply count(custkey) on metric - assertThat(query(rewrite("SELECT count(custkey) FROM CountOrders ORDER BY 1", true))) - .isEqualTo(query("WITH output AS (SELECT custkey, count(*) FROM orders GROUP BY 1) SELECT count(custkey) FROM output")); - - assertThatThrownBy(() -> query(rewrite("SELECT count(custkey) FROM notfound ORDER BY 1", true))) - .rootCause() - .hasMessageMatching(".*Table with name notfound does not exist(.|\\n)*"); - } - - @Test - public void testDynamicMetricOnMetric() - { - // select all in CountOrders2 - assertThat(query(rewrite("SELECT * FROM CountOrders2 WHERE orderstatus = 'F'", true))) - .isEqualTo(query("SELECT orderstatus, CAST(count(*) AS HUGEINT) FROM orders WHERE orderstatus = 'F' GROUP BY 1")); - assertThat(query(rewrite("SELECT * FROM CountOrders2 WHERE orderstatus = 'F'", true))) - .isEqualTo(query(rewrite("SELECT * FROM CountOrders2 WHERE orderstatus = 'F'", false))); - - // select dim in CountOrders2 - assertThat(query(rewrite("SELECT orderstatus FROM CountOrders2 WHERE orderstatus = 'F'", true))) - .isEqualTo(query("WITH output AS (SELECT orderstatus, CAST(count(*) AS HUGEINT) FROM orders WHERE orderstatus = 'F' GROUP BY 1)\n" + - "SELECT orderstatus FROM output")); - - // select measure in CountOrders2 - assertThat(query(rewrite("SELECT sum_count FROM CountOrders2 WHERE orderstatus = 'F'", true))) - .isEqualTo(query("WITH output AS (SELECT orderstatus, CAST(count(*) AS HUGEINT) AS sum_count FROM orders WHERE orderstatus = 'F' GROUP BY 1)\n" + - "SELECT sum_count FROM output")); - } - - @Test - public void testInvokeFunctionInDimension() - { - assertThat(query(rewrite("SELECT name, orderdate, totalprice FROM TotalpriceByCustomerYear WHERE name = 'Customer#000001276' ORDER BY 1, 2", true))) - .isEqualTo(query(""" - SELECT name, date_trunc('YEAR', orderdate), sum(totalprice) - FROM orders JOIN customer ON orders.custkey = customer.custkey - WHERE name = 'Customer#000001276' - GROUP BY 1, 2 - ORDER BY 1, 2 - """)); - assertThat(query(rewrite("SELECT name, orderdate, totalprice FROM TotalpriceByCustomerBaseOrdersYear WHERE name = 'Customer#000001276' ORDER BY 1, 2", true))) - .isEqualTo(query(""" - SELECT name, date_trunc('YEAR', orderdate), sum(totalprice) - FROM orders JOIN customer ON orders.custkey = customer.custkey - WHERE name = 'Customer#000001276' - GROUP BY 1, 2 - ORDER BY 1, 2 - """)); - } - - private String rewrite(String sql) - { - return rewrite(sql, wrenMDL); - } - - private String rewrite(String sql, boolean enableDynamicField) - { - return rewrite(sql, wrenMDL, enableDynamicField); - } - - private String rewrite(String sql, WrenMDL wrenMDL) - { - return WrenPlanner.rewrite(sql, DEFAULT_SESSION_CONTEXT, new AnalyzedMDL(wrenMDL, null), List.of(WREN_SQL_REWRITE)); - } - - private String rewrite(String sql, WrenMDL wrenMDL, boolean enableDynamicField) - { - SessionContext sessionContext = SessionContext.builder() - .setCatalog("wren") - .setSchema("test") - .setEnableDynamic(enableDynamicField) - .build(); - String result = WrenPlanner.rewrite(sql, sessionContext, new AnalyzedMDL(wrenMDL, null), List.of(WREN_SQL_REWRITE)); - System.out.println(result); - return result; - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestModelRefSql.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestModelRefSql.java deleted file mode 100644 index 84873309b..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestModelRefSql.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import static io.wren.base.dto.Model.model; - -public class TestModelRefSql - extends AbstractTestModel -{ - public TestModelRefSql() - { - super(); - orders = model("Orders", "select * from main.orders", ordersColumns, "orderkey"); - lineitem = model("Lineitem", "select * from main.lineitem", lineitemColumns, "orderkey_linenumber"); - customer = model("Customer", "select * from main.customer", customerColumns, "custkey"); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestModelTableReference.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestModelTableReference.java deleted file mode 100644 index da52fd03c..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestModelTableReference.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.wren.base.dto.Model; -import io.wren.base.dto.TableReference; - -public class TestModelTableReference - extends AbstractTestModel -{ - public TestModelTableReference() - { - super(); - orders = Model.onTableReference("Orders", TableReference.tableReference("memory", "main", "orders"), ordersColumns, "orderkey"); - lineitem = Model.onTableReference("Lineitem", TableReference.tableReference("memory", "main", "lineitem"), lineitemColumns, "orderkey_linenumber"); - customer = Model.onTableReference("Customer", TableReference.tableReference("memory", "main", "customer"), customerColumns, "custkey"); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestView.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestView.java deleted file mode 100644 index fc1f51a73..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestView.java +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import io.wren.base.AnalyzedMDL; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.View; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.wren.base.sqlrewrite.GenerateViewRewrite.GENERATE_VIEW_REWRITE; -import static io.wren.base.sqlrewrite.WrenSqlRewrite.WREN_SQL_REWRITE; -import static java.util.Objects.requireNonNull; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestView - extends AbstractTestFramework -{ - private final Model orders; - - public TestView() - { - orders = Model.model("Orders", - "select * from main.orders", - List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.VARCHAR, null, true), - Column.column("totalprice", WrenTypes.INTEGER, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true), - Column.column("orderpriority", WrenTypes.VARCHAR, null, true), - Column.column("clerk", WrenTypes.VARCHAR, null, true), - Column.column("shippriority", WrenTypes.INTEGER, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.column("lineitem", "Lineitem", "OrdersLineitem", true)), - "orderkey"); - } - - @Override - protected void prepareData() - { - String orders = requireNonNull(getClass().getClassLoader().getResource("tiny-orders.parquet")).getPath(); - exec("create table orders as select * from '" + orders + "'"); - } - - @Test - public void testView() - { - WrenMDL mdl = WrenMDL.fromManifest(withDefaultCatalogSchema() - .setModels(List.of(orders)) - .setMetrics(List.of( - Metric.metric("CountOrders", "Orders", - List.of(Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.DATE, null, true)), - List.of(Column.column("count", WrenTypes.INTEGER, null, true, "count(*)")), - List.of()))) - .setViews(List.of( - View.view("view1", "select * from CountOrders"), - View.view("view2", "select * from view1"), - View.view("oneDimCount", "select custkey from CountOrders"), - View.view("oneDimCount2", "select * from oneDimCount"), - View.view("cteInView", "with cte as (select * from CountOrders) select * from cte"))) - .build()); - - List.of(true, false).forEach(enableDynamicFields -> { - assertThat(query(rewrite("SELECT custkey, count FROM view1 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey, count FROM CountOrders WHERE custkey = 370", mdl, false))); - assertThat(query(rewrite("SELECT custkey, count FROM view2 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey, count FROM CountOrders WHERE custkey = 370", mdl, false))); - - assertThat(query(rewrite("SELECT * FROM view1 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT * FROM CountOrders WHERE custkey = 370", mdl, false))); - assertThat(query(rewrite("SELECT * FROM view2 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT * FROM CountOrders WHERE custkey = 370", mdl, false))); - - assertThat(query(rewrite("SELECT * FROM oneDimCount WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM CountOrders WHERE custkey = 370", mdl, enableDynamicFields))); - assertThat(query(rewrite("SELECT custkey FROM oneDimCount WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM CountOrders WHERE custkey = 370", mdl, enableDynamicFields))); - - assertThat(query(rewrite("SELECT * FROM oneDimCount2 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM CountOrders WHERE custkey = 370", mdl, enableDynamicFields))); - assertThat(query(rewrite("SELECT custkey FROM oneDimCount2 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM CountOrders WHERE custkey = 370", mdl, enableDynamicFields))); - - assertThat(query(rewrite("SELECT custkey, count FROM cteInView WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey, count FROM CountOrders WHERE custkey = 370", mdl, false))); - }); - } - - @Test - public void testViewWithoutOrder() - { - WrenMDL mdl = WrenMDL.fromManifest(withDefaultCatalogSchema() - .setModels(List.of(orders)) - .setViews(List.of( - View.view("view2", "select * from view1"), - View.view("view3", "select * from view1"), - View.view("view4", "select * from view2"), - View.view("view1", "select * from Orders"))) - .build()); - List.of(true, false).forEach(enableDynamicFields -> { - assertThat(query(rewrite("SELECT custkey FROM view1 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM Orders WHERE custkey = 370", mdl, false))); - assertThat(query(rewrite("SELECT custkey FROM view2 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM Orders WHERE custkey = 370", mdl, false))); - assertThat(query(rewrite("SELECT custkey FROM view3 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM Orders WHERE custkey = 370", mdl, false))); - assertThat(query(rewrite("SELECT custkey FROM view4 WHERE custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM Orders WHERE custkey = 370", mdl, false))); - assertThat(query(rewrite("SELECT v2.custkey FROM view2 v2 JOIN view4 v4 ON v2.orderkey = v4.orderkey WHERE v2.custkey = 370", mdl, enableDynamicFields))) - .isEqualTo(query(rewrite("SELECT custkey FROM Orders WHERE custkey = 370", mdl, false))); - }); - } - - @Test - public void testCycleDependencyView() - { - WrenMDL mdl = WrenMDL.fromManifest(withDefaultCatalogSchema() - .setModels(List.of(orders)) - .setViews(List.of( - View.view("view2", "select * from view1"), - View.view("view1", "select * from view2"), - View.view("view3", "select * from view3"))) - .build()); - - assertThatThrownBy(() -> query(rewrite("select * from view1", mdl, false))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("found cycle in view"); - - assertThatThrownBy(() -> query(rewrite("select * from view3", mdl, false))) - .isInstanceOf(IllegalArgumentException.class) - .hasMessageContaining("found issue in view") - .getCause() - .hasMessageContaining("loops not allowed"); - } - - @Test - public void testCustomCTE() - { - WrenMDL mdl = WrenMDL.fromManifest(withDefaultCatalogSchema() - .setModels(List.of(orders)) - .setViews(List.of( - View.view("view1", "select * from orders"), - View.view("view2", "with cte as (select * from view1) select * from cte"))) - .build()); - assertThat(query(rewrite("WITH cte AS (SELECT * FROM view1) SELECT * FROM cte", mdl, false))) - .isEqualTo(query(rewrite("SELECT * FROM orders", mdl, false))); - assertThat(query(rewrite("WITH cte AS (SELECT * FROM view1) SELECT * FROM cte", mdl, true))) - .isEqualTo(query(rewrite("SELECT * FROM orders", mdl, false))); - assertThat(query(rewrite("WITH cte as (SELECT * FROM view2) SELECT * FROM cte", mdl, false))) - .isEqualTo(query(rewrite("SELECT * FROM orders", mdl, false))); - assertThat(query(rewrite("WITH cte as (SELECT * FROM view2) SELECT * FROM cte", mdl, true))) - .isEqualTo(query(rewrite("SELECT * FROM orders", mdl, false))); - } - - private String rewrite(String sql, WrenMDL wrenMDL, boolean enableDynamicField) - { - SessionContext sessionContext = SessionContext.builder() - .setCatalog("wren") - .setSchema("test") - .setEnableDynamic(enableDynamicField) - .build(); - return WrenPlanner.rewrite(sql, sessionContext, new AnalyzedMDL(wrenMDL, null), List.of(GENERATE_VIEW_REWRITE, WREN_SQL_REWRITE)); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestWrenDataLineage.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/TestWrenDataLineage.java deleted file mode 100644 index 67a8d7d68..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/TestWrenDataLineage.java +++ /dev/null @@ -1,539 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite; - -import com.google.common.collect.ImmutableList; -import io.trino.sql.tree.QualifiedName; -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.CumulativeMetric; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Measure; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.dto.Relationship; -import io.wren.base.dto.TimeUnit; -import io.wren.base.dto.Window; -import org.testng.annotations.Test; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import static io.wren.base.sqlrewrite.AbstractTestFramework.addColumnsToModel; -import static io.wren.base.sqlrewrite.AbstractTestFramework.withDefaultCatalogSchema; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestWrenDataLineage -{ - private final Model customer; - private final Model orders; - private final Model lineitem; - private final Relationship ordersCustomer; - private final Relationship ordersLineitem; - - public TestWrenDataLineage() - { - customer = Model.model("Customer", - "select * from main.customer", - List.of( - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("address", WrenTypes.VARCHAR, null, true), - Column.column("nationkey", WrenTypes.INTEGER, null, true), - Column.column("phone", WrenTypes.VARCHAR, null, true), - Column.column("acctbal", WrenTypes.INTEGER, null, true), - Column.column("mktsegment", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true)), - "custkey"); - orders = Model.model("Orders", - "select * from main.orders", - List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.VARCHAR, null, true), - Column.column("totalprice", WrenTypes.INTEGER, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true), - Column.column("orderpriority", WrenTypes.VARCHAR, null, true), - Column.column("clerk", WrenTypes.VARCHAR, null, true), - Column.column("shippriority", WrenTypes.INTEGER, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.column("lineitem", "Lineitem", "OrdersLineitem", true)), - "orderkey"); - lineitem = Model.model("Lineitem", - "select * from main.lineitem", - List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("partkey", WrenTypes.INTEGER, null, true), - Column.column("suppkey", WrenTypes.INTEGER, null, true), - Column.column("linenumber", WrenTypes.INTEGER, null, true), - Column.column("quantity", WrenTypes.INTEGER, null, true), - Column.column("extendedprice", WrenTypes.INTEGER, null, true), - Column.column("discount", WrenTypes.INTEGER, null, true), - Column.column("tax", WrenTypes.INTEGER, null, true), - Column.column("returnflag", WrenTypes.VARCHAR, null, true), - Column.column("linestatus", WrenTypes.VARCHAR, null, true), - Column.column("shipdate", WrenTypes.DATE, null, true), - Column.column("commitdate", WrenTypes.DATE, null, true), - Column.column("receiptdate", WrenTypes.DATE, null, true), - Column.column("shipinstruct", WrenTypes.VARCHAR, null, true), - Column.column("shipmode", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.column("orderkey_linenumber", WrenTypes.VARCHAR, null, true, "concat(orderkey, '-', linenumber)")), - "orderkey_linenumber"); - ordersCustomer = Relationship.relationship("OrdersCustomer", List.of("Orders", "Customer"), JoinType.MANY_TO_ONE, "Orders.custkey = Customer.custkey"); - ordersLineitem = Relationship.relationship("OrdersLineitem", List.of("Orders", "Lineitem"), JoinType.ONE_TO_MANY, "Orders.orderkey = Lineitem.orderkey"); - } - - @Test - public void testAnalyze() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true), - Column.calculatedColumn("total_price", WrenTypes.BIGINT, "sum(orders.totalprice)"), - Column.calculatedColumn("discount_extended_price", WrenTypes.BIGINT, "sum(orders.lineitem.discount + orders.extended_price)"), - Column.calculatedColumn("lineitem_price", WrenTypes.BIGINT, "sum(orders.lineitem.discount * orders.lineitem.extendedprice)")); - Model newOrders = addColumnsToModel( - orders, - Column.column("customer", "Customer", "OrdersCustomer", true), - Column.column("lineitem", "Lineitem", "OrdersLineitem", true), - Column.calculatedColumn("customer_name", WrenTypes.BIGINT, "customer.name"), - Column.calculatedColumn("extended_price", WrenTypes.BIGINT, "sum(lineitem.extendedprice)"), - Column.calculatedColumn("extended_price_2", WrenTypes.BIGINT, "sum(lineitem.extendedprice + totalprice)")); - Model newLineitem = addColumnsToModel( - lineitem, - Column.column("orders", "Orders", "OrdersLineitem", true), - Column.calculatedColumn("test_column", WrenTypes.BIGINT, "orders.customer.total_price + extendedprice")); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(newCustomer, newOrders, newLineitem)) - .setRelationships(List.of(ordersCustomer, ordersLineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - LinkedHashMap> actual; - LinkedHashMap> expected; - actual = dataLineage.getRequiredFields(QualifiedName.of("Customer", "total_price")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice")); - expected.put("Customer", Set.of("orders", "total_price")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(QualifiedName.of("Orders", "customer_name")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("customer_name", "customer")); - expected.put("Customer", Set.of("name")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(QualifiedName.of("Customer", "discount_extended_price")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("extended_price", "lineitem")); - expected.put("Lineitem", Set.of("discount", "extendedprice")); - expected.put("Customer", Set.of("orders", "discount_extended_price")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields( - ImmutableList.of( - QualifiedName.of("Customer", "total_price"), - QualifiedName.of("Customer", "discount_extended_price"))); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("extended_price", "lineitem", "totalprice")); - expected.put("Lineitem", Set.of("discount", "extendedprice")); - expected.put("Customer", Set.of("orders", "total_price", "discount_extended_price")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields( - ImmutableList.of( - QualifiedName.of("Customer", "total_price"), - QualifiedName.of("Orders", "extended_price"))); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("lineitem", "totalprice", "extended_price")); - expected.put("Lineitem", Set.of("extendedprice")); - expected.put("Customer", Set.of("orders", "total_price")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(QualifiedName.of("Customer", "lineitem_price")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("lineitem")); - expected.put("Lineitem", Set.of("extendedprice", "discount")); - expected.put("Customer", Set.of("orders", "lineitem_price")); - assertThat(actual).isEqualTo(expected); - - // assert cycle - assertThatThrownBy( - () -> dataLineage.getRequiredFields( - ImmutableList.of(QualifiedName.of("Customer", "total_price"), QualifiedName.of("Orders", "customer_name")))) - .hasMessage("found cycle in Customer.total_price"); - - actual = dataLineage.getRequiredFields(QualifiedName.of("Orders", "extended_price_2")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("lineitem", "totalprice", "extended_price_2")); - expected.put("Lineitem", Set.of("extendedprice")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(QualifiedName.of("Lineitem", "test_column")); - expected = new LinkedHashMap<>(); - expected.put("Customer", Set.of("orders", "total_price")); - expected.put("Orders", Set.of("customer", "totalprice")); - expected.put("Lineitem", Set.of("extendedprice", "orders", "test_column")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testAnalyzeModelOnModel() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true), - Column.calculatedColumn("total_price", WrenTypes.BIGINT, "sum(orders.totalprice)")); - Model onCustomer = Model.onBaseObject( - "OnCustomer", - "Customer", - ImmutableList.of( - Column.column("mom_name", "VARCHAR", null, true, "name"), - Column.column("mom_custkey", "VARCHAR", null, true, "custkey"), - Column.column("mom_totalprice", "VARCHAR", null, true, "total_price")), - "mom_custkey"); - Model newOrders = addColumnsToModel( - orders, - Column.column("on_customer", "OnCustomer", "OrdersOnCustomer", true), - Column.calculatedColumn("customer_name", WrenTypes.BIGINT, "on_customer.mom_name")); - Relationship ordersOnCustomer = Relationship.relationship("OrdersOnCustomer", List.of("Orders", "OnCustomer"), JoinType.MANY_TO_ONE, "Orders.custkey = OnCustomer.mom_custkey"); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(newOrders, newCustomer, onCustomer)) - .setRelationships(List.of(ordersOnCustomer, ordersCustomer)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - - LinkedHashMap> actual; - LinkedHashMap> expected; - - actual = dataLineage.getRequiredFields(QualifiedName.of("OnCustomer", "mom_totalprice")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice")); - expected.put("Customer", Set.of("orders", "total_price")); - expected.put("OnCustomer", Set.of("mom_totalprice")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(QualifiedName.of("Orders", "customer_name")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("on_customer", "customer_name")); - expected.put("Customer", Set.of("name")); - expected.put("OnCustomer", Set.of("mom_name")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testAnalyzeMetricOnModel() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true)); - Metric customerSpending = Metric.metric("CustomerSpending", "Customer", - List.of(Column.column("name", WrenTypes.VARCHAR, null, true)), - List.of(Column.column("spending", WrenTypes.BIGINT, null, true, "sum(orders.totalprice)"), - Column.column("count", WrenTypes.BIGINT, null, true, "count(*)"))); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(orders, newCustomer)) - .setMetrics(List.of(customerSpending)) - .setRelationships(List.of(ordersCustomer)) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - LinkedHashMap> actual; - LinkedHashMap> expected; - actual = dataLineage.getRequiredFields(QualifiedName.of("CustomerSpending", "name")); - expected = new LinkedHashMap<>(); - expected.put("Customer", Set.of("name")); - expected.put("CustomerSpending", Set.of("name")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(QualifiedName.of("CustomerSpending", "count")); - expected = new LinkedHashMap<>(); - expected.put("Customer", Set.of()); - expected.put("CustomerSpending", Set.of("count")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(QualifiedName.of("CustomerSpending", "spending")); - expected = new LinkedHashMap<>(); - expected.put("Customer", Set.of("orders")); - expected.put("Orders", Set.of("totalprice")); - expected.put("CustomerSpending", Set.of("spending")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(List.of(QualifiedName.of("CustomerSpending", "name"), QualifiedName.of("CustomerSpending", "spending"))); - expected = new LinkedHashMap<>(); - expected.put("Customer", Set.of("orders", "name")); - expected.put("Orders", Set.of("totalprice")); - expected.put("CustomerSpending", Set.of("name", "spending")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testAnalyzeMetricOnMetric() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true)); - Metric customerSpending = Metric.metric("CustomerSpending", "Customer", - List.of(Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("address", WrenTypes.VARCHAR, null, true)), - List.of(Column.column("spending", WrenTypes.BIGINT, null, true, "sum(orders.totalprice)"))); - Metric derived = Metric.metric("Derived", "CustomerSpending", - List.of(Column.column("address", WrenTypes.VARCHAR, null, true)), - List.of(Column.column("spending", WrenTypes.BIGINT, null, true, "sum(spending)"))); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(orders, newCustomer)) - .setMetrics(List.of(customerSpending, derived)) - .setRelationships(List.of(ordersCustomer)) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - LinkedHashMap> actual; - LinkedHashMap> expected; - actual = dataLineage.getRequiredFields(QualifiedName.of("Derived", "address")); - expected = new LinkedHashMap<>(); - expected.put("Customer", Set.of("address")); - expected.put("CustomerSpending", Set.of("address")); - expected.put("Derived", Set.of("address")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(QualifiedName.of("Derived", "spending")); - expected = new LinkedHashMap<>(); - expected.put("Customer", Set.of("orders")); - expected.put("Orders", Set.of("totalprice")); - expected.put("CustomerSpending", Set.of("spending")); - expected.put("Derived", Set.of("spending")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(List.of(QualifiedName.of("Derived", "address"), QualifiedName.of("Derived", "spending"))); - expected = new LinkedHashMap<>(); - expected.put("Customer", Set.of("orders", "address")); - expected.put("Orders", Set.of("totalprice")); - expected.put("CustomerSpending", Set.of("address", "spending")); - expected.put("Derived", Set.of("address", "spending")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testAnalyzeCumulativeMetricOnModel() - { - CumulativeMetric dailyRevenue = CumulativeMetric.cumulativeMetric("DailyRevenue", "Orders", - Measure.measure("c_totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("c_orderdate", "orderdate", TimeUnit.DAY, "1994-01-01", "1994-12-31")); - - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(orders)) - .setCumulativeMetrics(List.of(dailyRevenue)) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - LinkedHashMap> actual; - LinkedHashMap> expected; - - actual = dataLineage.getRequiredFields(QualifiedName.of("DailyRevenue", "c_totalprice")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice")); - expected.put("DailyRevenue", Set.of("c_totalprice")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(List.of(QualifiedName.of("DailyRevenue", "c_totalprice"), QualifiedName.of("DailyRevenue", "c_orderdate"))); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice", "orderdate")); - expected.put("DailyRevenue", Set.of("c_totalprice", "c_orderdate")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testAnalyzeCumulativeMetricOnMetric() - { - Metric totalpriceByDate = Metric.metric("TotalpriceByDate", "Orders", - List.of(Column.column("orderdate", WrenTypes.DATE, null, true)), - List.of(Column.column("totalprice", WrenTypes.INTEGER, null, true, "sum(totalprice)"))); - CumulativeMetric dailyRevenue = CumulativeMetric.cumulativeMetric("DailyRevenue", "TotalpriceByDate", - Measure.measure("c_totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("c_orderdate", "orderdate", TimeUnit.DAY, "1994-01-01", "1994-12-31")); - - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(orders)) - .setMetrics(List.of(totalpriceByDate)) - .setCumulativeMetrics(List.of(dailyRevenue)) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - LinkedHashMap> actual; - LinkedHashMap> expected; - - actual = dataLineage.getRequiredFields(QualifiedName.of("DailyRevenue", "c_totalprice")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice")); - expected.put("TotalpriceByDate", Set.of("totalprice")); - expected.put("DailyRevenue", Set.of("c_totalprice")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(List.of(QualifiedName.of("DailyRevenue", "c_totalprice"), QualifiedName.of("DailyRevenue", "c_orderdate"))); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice", "orderdate")); - expected.put("TotalpriceByDate", Set.of("totalprice", "orderdate")); - expected.put("DailyRevenue", Set.of("c_totalprice", "c_orderdate")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testAnalyzeCumulativeMetricOnCumulativeMetric() - { - CumulativeMetric dailyRevenue = CumulativeMetric.cumulativeMetric("DailyRevenue", "Orders", - Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderdate", "orderdate", TimeUnit.DAY, "1994-01-01", "1994-12-31")); - CumulativeMetric dailyRevenue2 = CumulativeMetric.cumulativeMetric("DailyRevenue2", "DailyRevenue", - Measure.measure("c_totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("c_orderdate", "orderdate", TimeUnit.DAY, "1994-01-01", "1994-12-31")); - - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(orders)) - .setCumulativeMetrics(List.of(dailyRevenue, dailyRevenue2)) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - LinkedHashMap> actual; - LinkedHashMap> expected; - - actual = dataLineage.getRequiredFields(QualifiedName.of("DailyRevenue2", "c_totalprice")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice")); - expected.put("DailyRevenue", Set.of("totalprice")); - expected.put("DailyRevenue2", Set.of("c_totalprice")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(List.of(QualifiedName.of("DailyRevenue2", "c_totalprice"), QualifiedName.of("DailyRevenue2", "c_orderdate"))); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice", "orderdate")); - expected.put("DailyRevenue", Set.of("totalprice", "orderdate")); - expected.put("DailyRevenue2", Set.of("c_totalprice", "c_orderdate")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testAnalyzeModelOnCumulativeMetric() - { - CumulativeMetric dailyRevenue = CumulativeMetric.cumulativeMetric("DailyRevenue", "Orders", - Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderdate", "orderdate", TimeUnit.DAY, "1994-01-01", "1994-12-31")); - Model onDailyRevenue = Model.onBaseObject("OnDailyRevenue", "DailyRevenue", - ImmutableList.of( - Column.column("c_totalprice", WrenTypes.INTEGER, null, true, "totalprice"), - Column.column("c_orderdate", WrenTypes.DATE, null, true, "orderdate")), - "orderdate"); - - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(onDailyRevenue, orders)) - .setCumulativeMetrics(List.of(dailyRevenue)) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - LinkedHashMap> actual; - LinkedHashMap> expected; - - actual = dataLineage.getRequiredFields(QualifiedName.of("OnDailyRevenue", "c_totalprice")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice")); - expected.put("DailyRevenue", Set.of("totalprice")); - expected.put("OnDailyRevenue", Set.of("c_totalprice")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(List.of(QualifiedName.of("OnDailyRevenue", "c_totalprice"), QualifiedName.of("OnDailyRevenue", "c_orderdate"))); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice", "orderdate")); - expected.put("DailyRevenue", Set.of("totalprice", "orderdate")); - expected.put("OnDailyRevenue", Set.of("c_totalprice", "c_orderdate")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testAnalyzeMetricOnCumulativeMetric() - { - CumulativeMetric dailyRevenue = CumulativeMetric.cumulativeMetric("DailyRevenue", "Orders", - Measure.measure("totalprice", WrenTypes.INTEGER, "sum", "totalprice"), - Window.window("orderdate", "orderdate", TimeUnit.DAY, "1994-01-01", "1994-12-31")); - Metric onDailyRevenue = Metric.metric("OnDailyRevenue", "DailyRevenue", - ImmutableList.of(Column.column("c_orderdate", WrenTypes.DATE, null, true, "orderdate")), - ImmutableList.of(Column.column("c_totalprice", WrenTypes.INTEGER, null, true, "sum(totalprice)"))); - - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(orders)) - .setMetrics(List.of(onDailyRevenue)) - .setCumulativeMetrics(List.of(dailyRevenue)) - .build(); - - WrenMDL mdl = WrenMDL.fromManifest(manifest); - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - LinkedHashMap> actual; - LinkedHashMap> expected; - - actual = dataLineage.getRequiredFields(QualifiedName.of("OnDailyRevenue", "c_totalprice")); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice")); - expected.put("DailyRevenue", Set.of("totalprice")); - expected.put("OnDailyRevenue", Set.of("c_totalprice")); - assertThat(actual).isEqualTo(expected); - - actual = dataLineage.getRequiredFields(List.of(QualifiedName.of("OnDailyRevenue", "c_totalprice"), QualifiedName.of("OnDailyRevenue", "c_orderdate"))); - expected = new LinkedHashMap<>(); - expected.put("Orders", Set.of("totalprice", "orderdate")); - expected.put("DailyRevenue", Set.of("totalprice", "orderdate")); - expected.put("OnDailyRevenue", Set.of("c_totalprice", "c_orderdate")); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testGetSourceColumns() - { - Model newCustomer = addColumnsToModel( - customer, - Column.column("orders", "Orders", "OrdersCustomer", true), - Column.calculatedColumn("discount_extended_price", WrenTypes.BIGINT, "sum(orders.lineitem.discount + orders.lineitem.extendedprice)")); - Manifest manifest = withDefaultCatalogSchema() - .setModels(List.of(newCustomer, orders, lineitem)) - .setRelationships(List.of(ordersCustomer, ordersLineitem)) - .build(); - WrenMDL mdl = WrenMDL.fromManifest(manifest); - - WrenDataLineage dataLineage = WrenDataLineage.analyze(mdl); - Map> actual; - Map> expected; - actual = dataLineage.getSourceColumns(QualifiedName.of("Customer", "discount_extended_price")); - expected = new HashMap<>(); - expected.put("Customer", Set.of("orders")); - expected.put("Orders", Set.of("lineitem")); - expected.put("Lineitem", Set.of("extendedprice", "discount")); - assertThat(actual).isEqualTo(expected); - - // assert not exist - assertThat(dataLineage.getSourceColumns(QualifiedName.of("foo", "bar")).size()).isEqualTo(0); - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/analyzer/TestDecisionPointAnalyzer.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/analyzer/TestDecisionPointAnalyzer.java deleted file mode 100644 index 8aabd66e6..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/analyzer/TestDecisionPointAnalyzer.java +++ /dev/null @@ -1,772 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import io.trino.sql.tree.NodeLocation; -import io.trino.sql.tree.SortItem; -import io.trino.sql.tree.Statement; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Relationship; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.DecisionPointAnalyzer; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.ExprSource; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.FilterAnalysis; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.FilterAnalysis.ExpressionAnalysis; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.FilterAnalysis.LogicalAnalysis; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.QueryAnalysis; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.RelationAnalysis; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.RelationAnalysis.JoinRelation; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.RelationAnalysis.SubqueryRelation; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.RelationAnalysis.TableRelation; -import org.testng.annotations.Test; - -import java.util.List; -import java.util.Set; - -import static io.wren.base.dto.Model.onTableReference; -import static io.wren.base.dto.TableReference.tableReference; -import static io.wren.base.sqlrewrite.Utils.parseSql; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.DecisionExpressionAnalyzer.INCLUDE_FUNCTION_CALL; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.DecisionExpressionAnalyzer.INCLUDE_MATHEMATICAL_OPERATION; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.QueryAnalysis.GroupByKey; -import static io.wren.base.sqlrewrite.analyzer.decisionpoint.RelationAnalysis.JoinCriteria.joinCriteria; -import static org.assertj.core.api.Assertions.assertThat; - -public class TestDecisionPointAnalyzer -{ - private static final SessionContext DEFAULT_SESSION_CONTEXT = - SessionContext.builder().setCatalog("test").setSchema("test").build(); - private WrenMDL mdl; - - public TestDecisionPointAnalyzer() - { - List customerColumns = List.of( - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("address", WrenTypes.VARCHAR, null, true), - Column.column("nationkey", WrenTypes.INTEGER, null, true), - Column.column("phone", WrenTypes.VARCHAR, null, true), - Column.column("acctbal", WrenTypes.INTEGER, null, true), - Column.column("mktsegment", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true)); - List ordersColumns = List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.VARCHAR, null, true), - Column.column("totalprice", WrenTypes.INTEGER, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true), - Column.column("orderpriority", WrenTypes.VARCHAR, null, true), - Column.column("clerk", WrenTypes.VARCHAR, null, true), - Column.column("shippriority", WrenTypes.INTEGER, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true), - Column.column("customer", "customer", "CustomerOrders", false), - Column.calculatedColumn("customer_name", WrenTypes.VARCHAR, "customer.name")); - List lineitemColumns = List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("partkey", WrenTypes.INTEGER, null, true), - Column.column("suppkey", WrenTypes.INTEGER, null, true), - Column.column("linenumber", WrenTypes.INTEGER, null, true), - Column.column("quantity", WrenTypes.INTEGER, null, true), - Column.column("extendedprice", WrenTypes.INTEGER, null, true), - Column.column("discount", WrenTypes.INTEGER, null, true), - Column.column("tax", WrenTypes.INTEGER, null, true), - Column.column("returnflag", WrenTypes.VARCHAR, null, true), - Column.column("linestatus", WrenTypes.VARCHAR, null, true), - Column.column("shipdate", WrenTypes.DATE, null, true), - Column.column("commitdate", WrenTypes.DATE, null, true), - Column.column("receiptdate", WrenTypes.DATE, null, true), - Column.column("shipinstruct", WrenTypes.VARCHAR, null, true), - Column.column("shipmode", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true)); - - mdl = WrenMDL.fromManifest(Manifest.builder() - .setCatalog(DEFAULT_SESSION_CONTEXT.getCatalog().orElseThrow()) - .setSchema(DEFAULT_SESSION_CONTEXT.getSchema().orElseThrow()) - .setModels(List.of(onTableReference("customer", tableReference(null, "main", "customer"), customerColumns, "custkey"), - onTableReference("orders", tableReference(null, "main", "orders"), ordersColumns, "orderkey"), - onTableReference("lineitem", tableReference(null, "main", "lineitem"), lineitemColumns, null))) - .setRelationships(List.of(Relationship.relationship("CustomerOrders", List.of("customer", "orders"), JoinType.ONE_TO_MANY, "customer.custkey = orders.custkey"))) - .build()); - } - - @Test - public void testSelectItem() - { - Statement statement = parseSql("SELECT custkey, name FROM customer"); - List result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(2); - assertThat(result.get(0).getSelectItems().get(0).getExpression()).isEqualTo("custkey"); - assertThat(result.get(0).getSelectItems().get(0).getExprSources()).isEqualTo(List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 8)))); - assertThat(result.get(0).getSelectItems().get(0).getNodeLocation()).isEqualTo(new NodeLocation(1, 8)); - assertThat(result.get(0).getSelectItems().get(1).getExpression()).isEqualTo("name"); - assertThat(result.get(0).getSelectItems().get(1).getExprSources()).isEqualTo(List.of(new ExprSource("name", "customer", "name", new NodeLocation(1, 17)))); - assertThat(result.get(0).getSelectItems().get(1).getNodeLocation()).isEqualTo(new NodeLocation(1, 17)); - - statement = parseSql("SELECT * FROM customer"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(8); - assertThat(result.get(0).getSelectItems().get(0).getNodeLocation()).isEqualTo(new NodeLocation(1, 8)); - assertThat(result.get(0).getSelectItems().get(1).getNodeLocation()).isEqualTo(new NodeLocation(1, 8)); - - statement = parseSql("SELECT * FROM customer, orders"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(17); - - statement = parseSql("SELECT customer.*, orderkey FROM customer JOIN orders ON customer.custkey = orders.custkey"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(9); - assertThat(result.get(0).getSelectItems().get(0).getNodeLocation()).isEqualTo(new NodeLocation(1, 8)); - assertThat(result.get(0).getSelectItems().stream() - .filter(item -> item.getExpression().equals("orderkey")).findAny().orElseThrow(() -> new AssertionError("orderkey not found")).getNodeLocation()) - .isEqualTo(new NodeLocation(1, 20)); - - statement = parseSql("SELECT c.*, orderkey FROM customer c JOIN orders o ON c.custkey = o.custkey"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(9); - - statement = parseSql("SELECT custkey, date_trunc('MONTH', orderdate), custkey + orderkey, mod(custkey + 1, 10) FROM orders"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(4); - assertThat(result.get(0).getSelectItems().get(0).getExpression()).isEqualTo("custkey"); - assertThat(result.get(0).getSelectItems().get(0).getProperties().get(INCLUDE_FUNCTION_CALL)).isEqualTo("false"); - assertThat(result.get(0).getSelectItems().get(0).getProperties().get(INCLUDE_MATHEMATICAL_OPERATION)).isEqualTo("false"); - assertThat(result.get(0).getSelectItems().get(0).getNodeLocation()).isEqualTo(new NodeLocation(1, 8)); - assertThat(result.get(0).getSelectItems().get(1).getExpression()).isEqualTo("date_trunc('MONTH', orderdate)"); - assertThat(result.get(0).getSelectItems().get(1).getExprSources()).isEqualTo(List.of(new ExprSource("orderdate", "orders", "orderdate", new NodeLocation(1, 37)))); - assertThat(result.get(0).getSelectItems().get(1).getProperties().get(INCLUDE_FUNCTION_CALL)).isEqualTo("true"); - assertThat(result.get(0).getSelectItems().get(1).getProperties().get(INCLUDE_MATHEMATICAL_OPERATION)).isEqualTo("false"); - assertThat(result.get(0).getSelectItems().get(1).getNodeLocation()).isEqualTo(new NodeLocation(1, 17)); - assertThat(result.get(0).getSelectItems().get(2).getExpression()).isEqualTo("(custkey + orderkey)"); - assertThat(result.get(0).getSelectItems().get(2).getExprSources()) - .isEqualTo(List.of(new ExprSource("orderkey", "orders", "orderkey", new NodeLocation(1, 59)), - new ExprSource("custkey", "orders", "custkey", new NodeLocation(1, 49)))); - assertThat(result.get(0).getSelectItems().get(2).getProperties().get(INCLUDE_FUNCTION_CALL)).isEqualTo("false"); - assertThat(result.get(0).getSelectItems().get(2).getProperties().get(INCLUDE_MATHEMATICAL_OPERATION)).isEqualTo("true"); - assertThat(result.get(0).getSelectItems().get(2).getNodeLocation()).isEqualTo(new NodeLocation(1, 49)); - assertThat(result.get(0).getSelectItems().get(3).getExpression()).isEqualTo("mod((custkey + 1), 10)"); - assertThat(result.get(0).getSelectItems().get(3).getProperties().get(INCLUDE_FUNCTION_CALL)).isEqualTo("true"); - assertThat(result.get(0).getSelectItems().get(3).getProperties().get(INCLUDE_MATHEMATICAL_OPERATION)).isEqualTo("true"); - assertThat(result.get(0).getSelectItems().get(3).getNodeLocation()).isEqualTo(new NodeLocation(1, 70)); - - statement = parseSql("SELECT custkey ckey, orderkey okey FROM customer"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(2); - assertThat(result.get(0).getSelectItems().get(0).getExpression()).isEqualTo("custkey"); - assertThat(result.get(0).getSelectItems().get(0).getAliasName().get()).isEqualTo("ckey"); - assertThat(result.get(0).getSelectItems().get(1).getExpression()).isEqualTo("orderkey"); - assertThat(result.get(0).getSelectItems().get(1).getAliasName().get()).isEqualTo("okey"); - - statement = parseSql("SELECT * FROM remote_customer"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().get(0).getExpression()).isEqualTo("*"); - - statement = parseSql("SELECT c.* FROM remote_customer c"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().get(0).getExpression()).isEqualTo("c.*"); - - statement = parseSql("SELECT customer_name FROM orders"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().get(0).getExpression()).isEqualTo("customer_name"); - assertThat(result.get(0).getSelectItems().get(0).getExprSources()).isEqualTo(List.of(new ExprSource("customer_name", "orders", "customer_name", new NodeLocation(1, 8)))); - - statement = parseSql("SELECT customer FROM orders"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(1); - assertThat(result.get(0).getSelectItems().get(0).getExpression()).isEqualTo("customer"); - assertThat(result.get(0).getSelectItems().get(0).getExprSources()).isEqualTo(List.of()); - } - - @Test - public void testRelation() - { - Statement statement = parseSql("SELECT * FROM customer, orders"); - List result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.IMPLICIT_JOIN); - assertThat(result.get(0).getRelation().getNodeLocation()).isEqualTo(new NodeLocation(1, 1)); - if (result.get(0).getRelation() instanceof JoinRelation) { - JoinRelation joinRelation = (JoinRelation) result.get(0).getRelation(); - assertThat(joinRelation.getLeft().getAlias()).isNull(); - assertThat(joinRelation.getLeft().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(joinRelation.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 15)); - assertThat(((TableRelation) joinRelation.getLeft()).getTableName()).isEqualTo("customer"); - assertThat(joinRelation.getRight().getAlias()).isNull(); - assertThat(joinRelation.getRight().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(joinRelation.getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 25)); - assertThat(((TableRelation) joinRelation.getRight()).getTableName()).isEqualTo("orders"); - assertThat(joinRelation.getExprSources()).isEmpty(); - } - else { - throw new AssertionError("wrong type"); - } - - statement = parseSql("SELECT * FROM customer JOIN orders ON customer.custkey = orders.custkey"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.INNER_JOIN); - assertThat(result.get(0).getRelation().getNodeLocation()).isEqualTo(new NodeLocation(1, 15)); - if (result.get(0).getRelation() instanceof JoinRelation) { - JoinRelation joinRelation = (JoinRelation) result.get(0).getRelation(); - assertThat(joinRelation.getLeft().getAlias()).isNull(); - assertThat(joinRelation.getLeft().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(joinRelation.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 15)); - assertThat(((TableRelation) joinRelation.getLeft()).getTableName()).isEqualTo("customer"); - assertThat(joinRelation.getRight().getAlias()).isNull(); - assertThat(joinRelation.getRight().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(joinRelation.getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 29)); - assertThat(((TableRelation) joinRelation.getRight()).getTableName()).isEqualTo("orders"); - assertThat(joinRelation.getCriteria()).isEqualTo(joinCriteria("ON (customer.custkey = orders.custkey)", new NodeLocation(1, 39))); - assertThat(joinRelation.getExprSources().get(0).nodeLocation()).isEqualTo(new NodeLocation(1, 58)); - assertThat(joinRelation.getExprSources().get(1).nodeLocation()).isEqualTo(new NodeLocation(1, 39)); - } - else { - throw new AssertionError("wrong type"); - } - - statement = parseSql("SELECT * FROM (customer JOIN orders ON customer.custkey = orders.custkey) join_relation"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getAlias()).isEqualTo("join_relation"); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.INNER_JOIN); - assertThat(result.get(0).getRelation().getNodeLocation()).isEqualTo(new NodeLocation(1, 15)); - if (result.get(0).getRelation() instanceof JoinRelation) { - JoinRelation joinRelation = (JoinRelation) result.get(0).getRelation(); - assertThat(joinRelation.getLeft().getAlias()).isNull(); - assertThat(joinRelation.getLeft().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(joinRelation.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 16)); - assertThat(((TableRelation) joinRelation.getLeft()).getTableName()).isEqualTo("customer"); - assertThat(joinRelation.getRight().getAlias()).isNull(); - assertThat(joinRelation.getRight().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(joinRelation.getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 30)); - assertThat(((TableRelation) joinRelation.getRight()).getTableName()).isEqualTo("orders"); - assertThat(joinRelation.getCriteria()).isEqualTo(joinCriteria("ON (customer.custkey = orders.custkey)", new NodeLocation(1, 40))); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("customer.custkey", "customer", "custkey", new NodeLocation(1, 40)), - new ExprSource("orders.custkey", "orders", "custkey", new NodeLocation(1, 59)))); - } - else { - throw new AssertionError("wrong type"); - } - - statement = parseSql("SELECT * FROM (customer c JOIN orders o ON c.custkey = o.custkey) join_relation"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - if (result.get(0).getRelation() instanceof JoinRelation) { - JoinRelation joinRelation = (JoinRelation) result.get(0).getRelation(); - assertThat(joinRelation.getNodeLocation()).isEqualTo(new NodeLocation(1, 15)); - assertThat(joinRelation.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 16)); - assertThat(joinRelation.getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 32)); - assertThat(joinRelation.getExprSources().size()).isEqualTo(2); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("c.custkey", "customer", "custkey", new NodeLocation(1, 44)), - new ExprSource("o.custkey", "orders", "custkey", new NodeLocation(1, 56)))); - } - else { - throw new AssertionError("wrong type"); - } - - statement = parseSql("SELECT * FROM customer JOIN orders ON customer.custkey = orders.custkey LEFT JOIN lineitem ON orders.orderkey = lineitem.orderkey"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.LEFT_JOIN); - assertThat(result.get(0).getRelation().getNodeLocation()).isEqualTo(new NodeLocation(1, 15)); - if (result.get(0).getRelation() instanceof JoinRelation) { - JoinRelation joinRelation = (JoinRelation) result.get(0).getRelation(); - assertThat(joinRelation.getLeft().getAlias()).isNull(); - assertThat(joinRelation.getLeft().getType()).isEqualTo(RelationAnalysis.Type.INNER_JOIN); - assertThat(joinRelation.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 15)); - assertThat(((JoinRelation) joinRelation.getLeft()).getLeft().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(((JoinRelation) joinRelation.getLeft()).getRight().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(((JoinRelation) joinRelation.getLeft()).getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 15)); - assertThat(((JoinRelation) joinRelation.getLeft()).getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 29)); - assertThat(joinRelation.getRight().getAlias()).isNull(); - assertThat(joinRelation.getRight().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(joinRelation.getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 83)); - assertThat(((TableRelation) joinRelation.getRight()).getTableName()).isEqualTo("lineitem"); - assertThat(joinRelation.getCriteria()).isEqualTo(joinCriteria("ON (orders.orderkey = lineitem.orderkey)", new NodeLocation(1, 95))); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("lineitem.orderkey", "lineitem", "orderkey", new NodeLocation(1, 113)), - new ExprSource("orders.orderkey", "orders", "orderkey", new NodeLocation(1, 95)))); - } - else { - throw new AssertionError("wrong type"); - } - - statement = parseSql("SELECT * FROM customer JOIN orders USING (custkey)"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.INNER_JOIN); - if (result.get(0).getRelation() instanceof JoinRelation) { - JoinRelation joinRelation = (JoinRelation) result.get(0).getRelation(); - assertThat(joinRelation.getLeft().getAlias()).isNull(); - assertThat(joinRelation.getLeft().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(((TableRelation) joinRelation.getLeft()).getTableName()).isEqualTo("customer"); - assertThat(joinRelation.getRight().getAlias()).isNull(); - assertThat(joinRelation.getRight().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(((TableRelation) joinRelation.getRight()).getTableName()).isEqualTo("orders"); - assertThat(joinRelation.getCriteria()).isEqualTo(joinCriteria("USING (custkey)", new NodeLocation(1, 43))); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 43)), - new ExprSource("custkey", "orders", "custkey", new NodeLocation(1, 43)))); - } - else { - throw new AssertionError("wrong type"); - } - - statement = parseSql("SELECT * FROM customer JOIN customer USING (custkey, name)"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.INNER_JOIN); - if (result.get(0).getRelation() instanceof JoinRelation) { - JoinRelation joinRelation = (JoinRelation) result.get(0).getRelation(); - assertThat(joinRelation.getLeft().getAlias()).isNull(); - assertThat(joinRelation.getLeft().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(((TableRelation) joinRelation.getLeft()).getTableName()).isEqualTo("customer"); - assertThat(joinRelation.getRight().getAlias()).isNull(); - assertThat(joinRelation.getRight().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(((TableRelation) joinRelation.getRight()).getTableName()).isEqualTo("customer"); - assertThat(joinRelation.getCriteria()).isEqualTo(joinCriteria("USING (custkey, name)", new NodeLocation(1, 45))); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 45)), - new ExprSource("name", "customer", "name", new NodeLocation(1, 54)))); - } - else { - throw new AssertionError("wrong type"); - } - - statement = parseSql("SELECT * FROM (customer JOIN (SELECT 1 as custkey, 'xxx' as name) orders(custkey, name) ON customer.custkey = orders.custkey) join_relation"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getAlias()).isEqualTo("join_relation"); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.INNER_JOIN); - if (result.get(0).getRelation() instanceof JoinRelation) { - JoinRelation joinRelation = (JoinRelation) result.get(0).getRelation(); - assertThat(joinRelation.getLeft().getAlias()).isNull(); - assertThat(joinRelation.getLeft().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(joinRelation.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 16)); - assertThat(((TableRelation) joinRelation.getLeft()).getTableName()).isEqualTo("customer"); - assertThat(joinRelation.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 16)); - assertThat(joinRelation.getRight().getAlias()).isEqualTo("orders"); - assertThat(joinRelation.getRight().getType()).isEqualTo(RelationAnalysis.Type.SUBQUERY); - assertThat(joinRelation.getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 30)); - assertThat(((SubqueryRelation) joinRelation.getRight()).getBody().size()).isEqualTo(1); - assertThat(joinRelation.getCriteria()).isEqualTo(joinCriteria("ON (customer.custkey = orders.custkey)", new NodeLocation(1, 92))); - assertThat(joinRelation.getExprSources().size()).isEqualTo(1); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("customer.custkey", "customer", "custkey", new NodeLocation(1, 92)))); - } - else { - throw new AssertionError("wrong type"); - } - } - - @Test - public void testFilter() - { - Statement statement = parseSql("SELECT * FROM customer WHERE custkey = 1"); - List result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getFilter().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(result.get(0).getFilter().getNodeLocation()).isEqualTo(new NodeLocation(1, 38)); - if (result.get(0).getFilter() instanceof ExpressionAnalysis) { - ExpressionAnalysis expressionAnalysis = (ExpressionAnalysis) result.get(0).getFilter(); - assertThat(expressionAnalysis.getNode()).isEqualTo("(custkey = 1)"); - assertThat(expressionAnalysis.getExprSources()).isEqualTo(List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 30)))); - } - else { - throw new AssertionError("wrong type"); - } - - statement = parseSql("SELECT * FROM customer WHERE custkey = 1 AND name = 'test'"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getFilter().getType()).isEqualTo(FilterAnalysis.Type.AND); - assertThat(result.get(0).getFilter().getNodeLocation()).isEqualTo(new NodeLocation(1, 30)); - if (result.get(0).getFilter() instanceof LogicalAnalysis) { - LogicalAnalysis logicalAnalysis = (LogicalAnalysis) result.get(0).getFilter(); - assertThat(logicalAnalysis.getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) logicalAnalysis.getLeft()).getNode()).isEqualTo("(custkey = 1)"); - assertThat(((ExpressionAnalysis) logicalAnalysis.getLeft()).getExprSources()).isEqualTo(List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 30)))); - assertThat(logicalAnalysis.getRight().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) logicalAnalysis.getRight()).getNode()).isEqualTo("(name = 'test')"); - } - - statement = parseSql("SELECT * FROM customer WHERE custkey = 1 OR name = 'test'"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getFilter().getType()).isEqualTo(FilterAnalysis.Type.OR); - if (result.get(0).getFilter() instanceof LogicalAnalysis) { - LogicalAnalysis logicalAnalysis = (LogicalAnalysis) result.get(0).getFilter(); - assertThat(logicalAnalysis.getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) logicalAnalysis.getLeft()).getNode()).isEqualTo("(custkey = 1)"); - assertThat(logicalAnalysis.getRight().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) logicalAnalysis.getRight()).getNode()).isEqualTo("(name = 'test')"); - } - - statement = parseSql("SELECT * FROM customer WHERE custkey = 1 OR (name = 'test' AND address = 'test')"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getFilter().getType()).isEqualTo(FilterAnalysis.Type.OR); - assertThat(result.get(0).getFilter().getNodeLocation()).isEqualTo(new NodeLocation(1, 30)); - if (result.get(0).getFilter() instanceof LogicalAnalysis) { - LogicalAnalysis logicalAnalysis = (LogicalAnalysis) result.get(0).getFilter(); - assertThat(logicalAnalysis.getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(logicalAnalysis.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 38)); - assertThat(((ExpressionAnalysis) logicalAnalysis.getLeft()).getNode()).isEqualTo("(custkey = 1)"); - assertThat(logicalAnalysis.getRight().getType()).isEqualTo(FilterAnalysis.Type.AND); - assertThat(logicalAnalysis.getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 46)); - if (logicalAnalysis.getRight() instanceof LogicalAnalysis) { - LogicalAnalysis andLogicalAnalysis = (LogicalAnalysis) logicalAnalysis.getRight(); - assertThat(andLogicalAnalysis.getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(andLogicalAnalysis.getLeft().getNodeLocation()).isEqualTo(new NodeLocation(1, 51)); - assertThat(((ExpressionAnalysis) andLogicalAnalysis.getLeft()).getNode()).isEqualTo("(name = 'test')"); - assertThat(andLogicalAnalysis.getRight().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(andLogicalAnalysis.getRight().getNodeLocation()).isEqualTo(new NodeLocation(1, 72)); - assertThat(((ExpressionAnalysis) andLogicalAnalysis.getRight()).getNode()).isEqualTo("(address = 'test')"); - } - } - - statement = parseSql("SELECT * FROM customer WHERE custkey = 1 OR name = 'test' AND address = 'test'"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getFilter().getType()).isEqualTo(FilterAnalysis.Type.OR); - if (result.get(0).getFilter() instanceof LogicalAnalysis) { - LogicalAnalysis logicalAnalysis = (LogicalAnalysis) result.get(0).getFilter(); - assertThat(logicalAnalysis.getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) logicalAnalysis.getLeft()).getNode()).isEqualTo("(custkey = 1)"); - assertThat(logicalAnalysis.getRight().getType()).isEqualTo(FilterAnalysis.Type.AND); - if (logicalAnalysis.getRight() instanceof LogicalAnalysis) { - LogicalAnalysis andLogicalAnalysis = (LogicalAnalysis) logicalAnalysis.getRight(); - assertThat(andLogicalAnalysis.getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) andLogicalAnalysis.getLeft()).getNode()).isEqualTo("(name = 'test')"); - assertThat(andLogicalAnalysis.getRight().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) andLogicalAnalysis.getRight()).getNode()).isEqualTo("(address = 'test')"); - } - } - - statement = parseSql("SELECT * FROM customer WHERE custkey = 1 OR name = 'test' AND if(nationkey = 1 OR nationkey = 2, true, false)"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getFilter().getType()).isEqualTo(FilterAnalysis.Type.OR); - if (result.get(0).getFilter() instanceof LogicalAnalysis) { - LogicalAnalysis logicalAnalysis = (LogicalAnalysis) result.get(0).getFilter(); - assertThat(logicalAnalysis.getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) logicalAnalysis.getLeft()).getNode()).isEqualTo("(custkey = 1)"); - assertThat(logicalAnalysis.getRight().getType()).isEqualTo(FilterAnalysis.Type.AND); - if (logicalAnalysis.getRight() instanceof LogicalAnalysis) { - LogicalAnalysis andLogicalAnalysis = (LogicalAnalysis) logicalAnalysis.getRight(); - assertThat(andLogicalAnalysis.getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) andLogicalAnalysis.getLeft()).getNode()).isEqualTo("(name = 'test')"); - assertThat(andLogicalAnalysis.getRight().getType()).isEqualTo(FilterAnalysis.Type.EXPR); - assertThat(((ExpressionAnalysis) andLogicalAnalysis.getRight()).getNode()).isEqualTo("IF(((nationkey = 1) OR (nationkey = 2)), true, false)"); - assertThat(((ExpressionAnalysis) andLogicalAnalysis.getRight()).getExprSources()).isEqualTo(List.of(new ExprSource("nationkey", "customer", "nationkey", new NodeLocation(1, 83)), - new ExprSource("nationkey", "customer", "nationkey", new NodeLocation(1, 66)))); - } - } - } - - @Test - public void testGroupBy() - { - Statement statement = parseSql("SELECT custkey, count(*) FROM customer GROUP BY custkey"); - List result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo( - new GroupByKey("custkey", - new NodeLocation(1, 49), - List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 49))))); - - statement = parseSql("SELECT c.custkey, count(*) FROM customer c GROUP BY c.custkey"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo( - new GroupByKey("c.custkey", - new NodeLocation(1, 53), - List.of(new ExprSource("c.custkey", "customer", "custkey", new NodeLocation(1, 53))))); - - statement = parseSql("SELECT custkey, count(*) FROM customer GROUP BY custkey, name"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(2); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo( - new GroupByKey("custkey", - new NodeLocation(1, 49), - List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 49))))); - assertThat(result.get(0).getGroupByKeys().get(1).get(0)).isEqualTo( - new GroupByKey("name", - new NodeLocation(1, 58), - List.of(new ExprSource("name", "customer", "name", new NodeLocation(1, 58))))); - - statement = parseSql("SELECT custkey, count(*) FROM customer GROUP BY (custkey, name), nationkey"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(2); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo( - new GroupByKey("custkey", - new NodeLocation(1, 50), - List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 50))))); - assertThat(result.get(0).getGroupByKeys().get(0).get(1)).isEqualTo( - new GroupByKey("name", - new NodeLocation(1, 59), - List.of(new ExprSource("name", "customer", "name", new NodeLocation(1, 59))))); - assertThat(result.get(0).getGroupByKeys().get(1).get(0)).isEqualTo( - new GroupByKey("nationkey", - new NodeLocation(1, 66), - List.of(new ExprSource("nationkey", "customer", "nationkey", new NodeLocation(1, 66))))); - - statement = parseSql("SELECT custkey, count(*) FROM customer GROUP BY 1"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo( - new GroupByKey("custkey", - // provide the location of the source node if it's an index - new NodeLocation(1, 49), - List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 8))))); - - statement = parseSql("SELECT c.custkey, count(*) FROM customer c GROUP BY 1"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(0).size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo( - new GroupByKey("c.custkey", - new NodeLocation(1, 53), - List.of(new ExprSource("c.custkey", "customer", "custkey", new NodeLocation(1, 8))))); - - statement = parseSql("SELECT custkey, count(*), name FROM customer GROUP BY 1, 3, nationkey"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(3); - assertThat(result.get(0).getGroupByKeys().get(0).size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(1).size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(2).size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo( - new GroupByKey("custkey", new NodeLocation(1, 55), List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 8))))); - assertThat(result.get(0).getGroupByKeys().get(1).get(0)).isEqualTo( - new GroupByKey("name", - new NodeLocation(1, 58), - List.of(new ExprSource("name", "customer", "name", new NodeLocation(1, 27))))); - assertThat(result.get(0).getGroupByKeys().get(2).get(0)).isEqualTo( - new GroupByKey("nationkey", - new NodeLocation(1, 61), - List.of(new ExprSource("nationkey", "customer", "nationkey", new NodeLocation(1, 61))))); - } - - @Test - public void testSorting() - { - Statement statement = parseSql("SELECT custkey, name FROM customer ORDER BY custkey"); - List result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSortings().size()).isEqualTo(1); - assertThat(result.get(0).getSortings().get(0).getExpression()).isEqualTo("custkey"); - assertThat(result.get(0).getSortings().get(0).getOrdering()).isEqualTo(SortItem.Ordering.ASCENDING); - assertThat(result.get(0).getSortings().get(0).getExprSources()).isEqualTo(List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 45)))); - assertThat(result.get(0).getSortings().get(0).getNodeLocation()).isEqualTo(new NodeLocation(1, 45)); - - statement = parseSql("SELECT custkey, name FROM customer ORDER BY custkey ASC, name DESC"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSortings().size()).isEqualTo(2); - assertThat(result.get(0).getSortings().get(0).getExpression()).isEqualTo("custkey"); - assertThat(result.get(0).getSortings().get(0).getOrdering()).isEqualTo(SortItem.Ordering.ASCENDING); - assertThat(result.get(0).getSortings().get(0).getNodeLocation()).isEqualTo(new NodeLocation(1, 45)); - assertThat(result.get(0).getSortings().get(1).getExpression()).isEqualTo("name"); - assertThat(result.get(0).getSortings().get(1).getOrdering()).isEqualTo(SortItem.Ordering.DESCENDING); - assertThat(result.get(0).getSortings().get(1).getNodeLocation()).isEqualTo(new NodeLocation(1, 58)); - - statement = parseSql("SELECT custkey, name FROM customer ORDER BY 1 ASC, 2 DESC"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSortings().size()).isEqualTo(2); - assertThat(result.get(0).getSortings().get(0).getExpression()).isEqualTo("custkey"); - assertThat(result.get(0).getSortings().get(0).getOrdering()).isEqualTo(SortItem.Ordering.ASCENDING); - assertThat(result.get(0).getSortings().get(0).getExprSources()).isEqualTo(List.of(new ExprSource("custkey", "customer", "custkey", new NodeLocation(1, 8)))); - assertThat(result.get(0).getSortings().get(0).getNodeLocation()).isEqualTo(new NodeLocation(1, 45)); - assertThat(result.get(0).getSortings().get(1).getExpression()).isEqualTo("name"); - assertThat(result.get(0).getSortings().get(1).getOrdering()).isEqualTo(SortItem.Ordering.DESCENDING); - assertThat(result.get(0).getSortings().get(1).getExprSources()).isEqualTo(List.of(new ExprSource("name", "customer", "name", new NodeLocation(1, 17)))); - assertThat(result.get(0).getSortings().get(1).getNodeLocation()).isEqualTo(new NodeLocation(1, 52)); - } - - @Test - public void testMultipleQuery() - { - Statement statement = parseSql("WITH t1 as (SELECT * FROM customer) SELECT * FROM t1"); - List result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(2); - assertThat(result.stream().filter(QueryAnalysis::isSubqueryOrCte).toList().size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(8); - if (result.get(0).getRelation() instanceof TableRelation tableRelation) { - assertThat(tableRelation.getTableName()).isEqualTo("customer"); - } - - assertThat(result.get(1).getRelation().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(result.get(1).getRelation().getAlias()).isNull(); - assertThat(result.get(1).getSelectItems().size()).isEqualTo(8); - if (result.get(1).getRelation() instanceof TableRelation tableRelation) { - assertThat(tableRelation.getTableName()).isEqualTo("t1"); - } - - statement = parseSql(""" - WITH t1 as (SELECT custkey, name FROM customer), t2 as (SELECT orderkey, custkey FROM orders) - SELECT * FROM t1 JOIN t2 ON t1.custkey = t2.custkey - """); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(3); - assertThat(result.stream().filter(QueryAnalysis::isSubqueryOrCte).toList().size()).isEqualTo(2); - QueryAnalysis mainBody = result.stream().filter(q -> !q.isSubqueryOrCte()).findFirst().get(); - mainBody.getRelation().getType().equals(RelationAnalysis.Type.INNER_JOIN); - if (mainBody.getRelation() instanceof JoinRelation joinRelation) { - assertThat(joinRelation.getExprSources().size()).isEqualTo(2); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("t1.custkey", "customer", "custkey", new NodeLocation(2, 29)), - new ExprSource("t2.custkey", "orders", "custkey", new NodeLocation(2, 42)))); - } - - statement = parseSql(""" - WITH t1 as (SELECT * FROM customer), t2 as (SELECT * FROM orders) - SELECT * FROM t1 JOIN t2 ON t1.custkey = t2.custkey - """); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(3); - assertThat(result.stream().filter(QueryAnalysis::isSubqueryOrCte).toList().size()).isEqualTo(2); - mainBody = result.stream().filter(q -> !q.isSubqueryOrCte()).findFirst().get(); - mainBody.getRelation().getType().equals(RelationAnalysis.Type.INNER_JOIN); - if (mainBody.getRelation() instanceof JoinRelation joinRelation) { - assertThat(joinRelation.getExprSources().size()).isEqualTo(2); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("t1.custkey", "customer", "custkey", new NodeLocation(2, 29)), - new ExprSource("t2.custkey", "orders", "custkey", new NodeLocation(2, 42)))); - } - - statement = parseSql(""" - WITH "t1" as (SELECT "custkey", "name" FROM "customer"), t2 as (SELECT "orderkey", "custkey" FROM "orders") - SELECT * FROM "t1" JOIN "t2" ON "t1"."custkey" = "t2"."custkey" - """); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(3); - assertThat(result.stream().filter(QueryAnalysis::isSubqueryOrCte).toList().size()).isEqualTo(2); - mainBody = result.stream().filter(q -> !q.isSubqueryOrCte()).findFirst().get(); - mainBody.getRelation().getType().equals(RelationAnalysis.Type.INNER_JOIN); - if (mainBody.getRelation() instanceof JoinRelation joinRelation) { - assertThat(joinRelation.getExprSources().size()).isEqualTo(2); - assertThat(Set.copyOf(joinRelation.getExprSources())).isEqualTo(Set.of( - new ExprSource("t1.custkey", "customer", "custkey", new NodeLocation(2, 33)), - new ExprSource("t2.custkey", "orders", "custkey", new NodeLocation(2, 50)))); - } - - statement = parseSql(""" - WITH t1 as (SELECT customer.custkey FROM customer), - t2 as (SELECT t1.custkey FROM t1) - SELECT t2.custkey FROM t2 - """); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(3); - QueryAnalysis queryAnalysis = result.get(2); - assertThat(queryAnalysis.getSelectItems().get(0).getExprSources().size()).isEqualTo(1); - - statement = parseSql(""" - WITH t1 as (SELECT customer.custkey FROM customer), - t2 as (SELECT t1.custkey as custkey_alias FROM t1) - SELECT custkey_alias FROM t2 - """); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(3); - queryAnalysis = result.get(2); - assertThat(queryAnalysis.getSelectItems().get(0).getExprSources().size()).isEqualTo(1); - - statement = parseSql(""" - WITH t1 as (SELECT customer.custkey FROM customer), - t2 as (SELECT * FROM t1) - SELECT custkey FROM t2 - """); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(3); - queryAnalysis = result.get(2); - assertThat(queryAnalysis.getSelectItems().get(0).getExprSources().size()).isEqualTo(1); - - statement = parseSql(""" - WITH t1 as (SELECT customer.custkey FROM customer), - t2 as (SELECT * FROM t1) - SELECT custkey FROM t2 - """); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(3); - queryAnalysis = result.get(2); - assertThat(queryAnalysis.getSelectItems().get(0).getExprSources().size()).isEqualTo(1); - - - // we only analyze the top-level expression - statement = parseSql(""" - WITH t1 as (SELECT customer.custkey FROM customer), - t2 as (SELECT (t1.custkey + 1) as custkey_plus FROM t1) - SELECT custkey_plus FROM t2 - """); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(3); - queryAnalysis = result.get(2); - assertThat(queryAnalysis.getSelectItems().get(0).getExprSources().size()).isEqualTo(0); - } - - @Test - public void testSubQuery() - { - Statement statement = parseSql("SELECT * FROM (SELECT * FROM customer) t1"); - List result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.SUBQUERY); - assertThat(result.get(0).getRelation().getAlias()).isEqualTo("t1"); - - statement = parseSql("SELECT * FROM (WITH t1 AS (SELECT * FROM customer) SELECT * FROM t1) t2"); - result = DecisionPointAnalyzer.analyze(statement, DEFAULT_SESSION_CONTEXT, mdl); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.SUBQUERY); - assertThat(result.get(0).getRelation().getAlias()).isEqualTo("t2"); - if (result.get(0).getRelation() instanceof SubqueryRelation subQueryRelation) { - assertThat(subQueryRelation.getBody().size()).isEqualTo(2); - assertThat(subQueryRelation.getBody().get(0).isSubqueryOrCte()).isTrue(); - assertThat(subQueryRelation.getBody().get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - assertThat(subQueryRelation.getBody().get(1).getRelation().getType()).isEqualTo(RelationAnalysis.Type.TABLE); - } - } -} diff --git a/wren-base/src/test/java/io/wren/base/sqlrewrite/analyzer/TestStatementAnalyzer.java b/wren-base/src/test/java/io/wren/base/sqlrewrite/analyzer/TestStatementAnalyzer.java deleted file mode 100644 index c71b323f8..000000000 --- a/wren-base/src/test/java/io/wren/base/sqlrewrite/analyzer/TestStatementAnalyzer.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Licensed 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 io.wren.base.sqlrewrite.analyzer; - -import com.google.common.collect.HashMultimap; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Multimap; -import io.trino.sql.tree.Statement; -import io.wren.base.CatalogSchemaTableName; -import io.wren.base.SessionContext; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Metric; -import io.wren.base.dto.Model; -import io.wren.base.sqlrewrite.AbstractTestFramework; -import org.assertj.core.api.Assertions; -import org.testng.annotations.Test; - -import java.util.List; -import java.util.Optional; -import java.util.function.Function; - -import static io.wren.base.CatalogSchemaTableName.catalogSchemaTableName; -import static io.wren.base.WrenMDL.EMPTY; -import static io.wren.base.WrenMDL.fromManifest; -import static io.wren.base.dto.Column.calculatedColumn; -import static io.wren.base.dto.Column.column; -import static io.wren.base.dto.Column.relationshipColumn; -import static io.wren.base.dto.Model.model; -import static io.wren.base.dto.Relationship.relationship; -import static io.wren.base.sqlrewrite.Utils.parseSql; -import static io.wren.base.sqlrewrite.analyzer.StatementAnalyzer.analyze; -import static org.assertj.core.api.Assertions.assertThat; - -public class TestStatementAnalyzer - extends AbstractTestFramework -{ - private static final SessionContext DEFAULT_SESSION_CONTEXT = - SessionContext.builder().setCatalog("test").setSchema("test").build(); - - @Test - public void testValues() - { - SessionContext sessionContext = SessionContext.builder().build(); - Statement statement = parseSql("VALUES(1, 'a')"); - Analysis analysis = new Analysis(statement); - analyze(analysis, statement, sessionContext, EMPTY); - - statement = parseSql("SELECT * FROM (VALUES(1, 'a'))"); - analysis = new Analysis(statement); - analyze(analysis, statement, sessionContext, EMPTY); - } - - @Test - public void testGetTableWithoutWithTable() - { - SessionContext sessionContext = SessionContext.builder().setCatalog("test").setSchema("test").build(); - Statement statement = parseSql("WITH a AS (SELECT * FROM People) SELECT * FROM a"); - Analysis analysis = new Analysis(statement); - analyze(analysis, - statement, - sessionContext, - EMPTY); - - assertThat(analysis.getTables()).containsExactly(new CatalogSchemaTableName("test", "test", "People")); - } - - @Test - public void testCollectedColumns() - { - Manifest manifest = Manifest.builder() - .setCatalog("test") - .setSchema("test") - .setModels(ImmutableList.of( - Model.model("table_1", "SELECT * FROM foo", ImmutableList.of(varcharColumn("c1"), varcharColumn("c2"))), - Model.model("table_2", "SELECT * FROM bar", ImmutableList.of(varcharColumn("c1"), varcharColumn("c2"))))) - .build(); - - Multimap expected; - expected = HashMultimap.create(); - expected.putAll(catalogSchemaTableName("test", "test", "table_1"), ImmutableList.of("c1", "c2")); - assertThat(analyzeSql("SELECT * FROM table_1", manifest).getCollectedColumns()).isEqualTo(expected); - - expected = HashMultimap.create(); - expected.putAll(catalogSchemaTableName("test", "test", "table_1"), ImmutableList.of("c1")); - assertThat(analyzeSql("SELECT c1 FROM table_1", manifest).getCollectedColumns()).isEqualTo(expected); - - expected = HashMultimap.create(); - expected.putAll(catalogSchemaTableName("test", "test", "table_1"), ImmutableList.of("c1")); - assertThat(analyzeSql("SELECT c1, c1 FROM table_1", manifest).getCollectedColumns()).isEqualTo(expected); - - expected = HashMultimap.create(); - expected.putAll(catalogSchemaTableName("test", "test", "table_1"), ImmutableList.of("c1")); - assertThat(analyzeSql("SELECT t1.c1 FROM table_1 t1", manifest).getCollectedColumns()).isEqualTo(expected); - - expected = HashMultimap.create(); - expected.putAll(catalogSchemaTableName("test", "test", "table_1"), ImmutableList.of("c1", "c2")); - expected.putAll(catalogSchemaTableName("test", "test", "table_2"), ImmutableList.of("c1", "c2")); - assertThat(analyzeSql("SELECT t1.c1, t2.c1, t2.c2 FROM table_1 t1 JOIN table_2 t2 ON t1.c2 = t2.c1", manifest).getCollectedColumns()).isEqualTo(expected); - - expected = HashMultimap.create(); - expected.putAll(catalogSchemaTableName("test", "test", "table_1"), ImmutableList.of("c1", "c2")); - assertThat(analyzeSql("SELECT t1.c1 FROM table_1 t1 WHERE t1.c2 = 'wah'", manifest).getCollectedColumns()).isEqualTo(expected); - } - - private Analysis analyzeSql(String sql, Manifest manifest) - { - Statement statement = parseSql(sql); - Analysis analysis = new Analysis(statement); - analyze( - analysis, - statement, - DEFAULT_SESSION_CONTEXT, - fromManifest(manifest)); - return analysis; - } - - @Test - public void testScope() - { - SessionContext sessionContext = SessionContext.builder().setCatalog("test").setSchema("test").build(); - Manifest manifest = Manifest.builder() - .setCatalog("test") - .setSchema("test") - .setModels(ImmutableList.of( - Model.model("table_1", "SELECT * FROM foo", ImmutableList.of(varcharColumn("c1"), varcharColumn("c2"))), - Model.model("table_2", "SELECT * FROM bar", ImmutableList.of(varcharColumn("c1"), varcharColumn("c2"))), - Model.model("table_3", "SELECT * FROM foo", ImmutableList.of(varcharColumn("c1"), integerColumn("c2"))))) - .setMetrics(ImmutableList.of( - Metric.metric("metric_1", "table_3", - ImmutableList.of(varcharColumn("c1")), - ImmutableList.of(Column.column("max_c2", WrenTypes.INTEGER, null, false, "max(c2)"))))) - .build(); - - Function analyzeSql = (sql) -> { - Statement statement = parseSql(sql); - Analysis analysis = new Analysis(statement); - return analyze( - analysis, - statement, - sessionContext, - fromManifest(manifest)); - }; - - Optional scope = Optional.ofNullable(analyzeSql.apply("SELECT * FROM table_1")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(2); - assertThat(scope.get().getRelationType().getFields().get(0).getName().get()).isEqualTo("c1"); - assertThat(scope.get().getRelationType().getFields().get(1).getName().get()).isEqualTo("c2"); - - scope = Optional.ofNullable(analyzeSql.apply("SELECT * FROM table_2")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(2); - assertThat(scope.get().getRelationType().getFields().get(0).getName().get()).isEqualTo("c1"); - assertThat(scope.get().getRelationType().getFields().get(1).getName().get()).isEqualTo("c2"); - - scope = Optional.ofNullable(analyzeSql.apply("SELECT * FROM test.test.foo")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(0); - assertThat(scope.get().isDataSourceScope()).isTrue(); - - scope = Optional.ofNullable(analyzeSql.apply("SELECT * FROM test.foo")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(0); - assertThat(scope.get().isDataSourceScope()).isTrue(); - - scope = Optional.ofNullable(analyzeSql.apply("SELECT * FROM foo")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(0); - assertThat(scope.get().isDataSourceScope()).isTrue(); - - scope = Optional.ofNullable(analyzeSql.apply("SELECT * FROM (select * from test.test.foo) table_1")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(2); - assertThat(scope.get().getRelationType().getFields().get(0).getName().get()).isEqualTo("c1"); - assertThat(scope.get().getRelationType().getFields().get(1).getName().get()).isEqualTo("c2"); - - scope = Optional.ofNullable(analyzeSql.apply("WITH t1 as (SELECT * FROM (select * from test.test.foo) table_1) select * from t1")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(2); - assertThat(scope.get().getRelationType().getFields().get(0).getName().get()).isEqualTo("c1"); - assertThat(scope.get().getRelationType().getFields().get(1).getName().get()).isEqualTo("c2"); - - scope = Optional.ofNullable(analyzeSql.apply("SELECT * FROM table_3")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(2); - assertThat(scope.get().getRelationType().getFields().get(0).getName().get()).isEqualTo("c1"); - assertThat(scope.get().getRelationType().getFields().get(1).getName().get()).isEqualTo("c2"); - - scope = Optional.ofNullable(analyzeSql.apply("WITH table_1 as (SELECT * FROM foo), table_3 as (SELECT c1, max(c2) max_c2 FROM table_1) SELECT * FROM table_3")); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(2); - assertThat(scope.get().getRelationType().getFields().get(0).getName().get()).isEqualTo("c1"); - assertThat(scope.get().getRelationType().getFields().get(1).getName().get()).isEqualTo("max_c2"); - - scope = Optional.ofNullable(analyzeSql.apply(""" - WITH t1 as (SELECT "c1", "c2" FROM (select * from test.test.foo) table_1) select * from t1 - """)); - Assertions.assertThat(scope).isPresent(); - assertThat(scope.get().getRelationType().getFields()).hasSize(2); - assertThat(scope.get().getRelationType().getFields().get(0).getName().get()).isEqualTo("c1"); - assertThat(scope.get().getRelationType().getFields().get(1).getName().get()).isEqualTo("c2"); - } - - @Test - public void testScopeWithRelationship() - { - SessionContext sessionContext = SessionContext.builder().setCatalog("test").setSchema("test").build(); - Manifest manifest = Manifest.builder() - .setCatalog("test") - .setSchema("test") - .setModels(ImmutableList.of( - Model.model("table_1", "SELECT * FROM foo", ImmutableList.of( - varcharColumn("c1"), varcharColumn("c2"), relationshipColumn("table_2", "table_2", "relationship_1_2"))), - Model.model("table_2", "SELECT * FROM bar", ImmutableList.of(varcharColumn("c1"), varcharColumn("c2"))))) - .setRelationships(ImmutableList.of( - relationship("relationship_1_2", List.of("table_1", "table_2"), JoinType.ONE_TO_ONE, "table_1.c1 = table_2.c1"))) - .build(); - - Statement statement = parseSql("SELECT table_2.c2 FROM table_1 JOIN table_2 ON table_1.c1 = table_2.c1"); - Analysis analysis = new Analysis(statement); - analyze(analysis, statement, sessionContext, fromManifest(manifest)); - assertThat(analysis.getCollectedColumns().get(catalogSchemaTableName("test", "test", "table_1"))).containsExactly("c1"); - assertThat(analysis.getCollectedColumns().get(catalogSchemaTableName("test", "test", "table_2"))).containsExactly("c1", "c2"); - } - - @Test - public void testTargetDotAll() - { - Manifest manifest = Manifest.builder() - .setCatalog("test") - .setSchema("test") - .setModels(List.of( - model("Orders", "SELECT * FROM tpch.orders", - List.of(column("orderkey", "integer", null, false, "o_orderkey"), - column("custkey", "integer", null, false, "o_custkey"), - column("customer", "Customer", "CustomerOrders", false), - calculatedColumn("customer_name", "varchar", "customer.name")), - "orderkey"), - model("Customer", "SELECT * FROM tpch.customer", - List.of(column("custkey", "integer", null, false, "c_custkey"), - column("name", "varchar", null, false, "c_name"))))) - .setRelationships(List.of(relationship("CustomerOrders", List.of("Customer", "Orders"), JoinType.ONE_TO_MANY, "Customer.custkey = Orders.custkey"))) - .build(); - List testSqls = ImmutableList.of( - "SELECT Orders.* FROM Orders", - "SELECT o.* FROM Orders AS o", - "SELECT o.* FROM Orders AS o JOIN Customer AS c ON o.custkey = c.custkey"); - for (String sql : testSqls) { - Statement statement = parseSql(sql); - Analysis analysis = new Analysis(statement); - analyze(analysis, statement, DEFAULT_SESSION_CONTEXT, fromManifest(manifest)); - assertThat(analysis.getCollectedColumns().get(catalogSchemaTableName("test", "test", "Orders"))).containsExactly("custkey", "orderkey", "customer"); - } - } - - private static Column varcharColumn(String name) - { - return Column.column(name, "VARCHAR", null, false, null); - } - - private static Column integerColumn(String name) - { - return Column.column(name, "INTEGER", null, false, null); - } -} diff --git a/wren-base/src/test/resources/tiny-customer.parquet b/wren-base/src/test/resources/tiny-customer.parquet deleted file mode 100644 index 60ea10e7d..000000000 Binary files a/wren-base/src/test/resources/tiny-customer.parquet and /dev/null differ diff --git a/wren-base/src/test/resources/tiny-lineitem.parquet b/wren-base/src/test/resources/tiny-lineitem.parquet deleted file mode 100644 index 705cba41e..000000000 Binary files a/wren-base/src/test/resources/tiny-lineitem.parquet and /dev/null differ diff --git a/wren-base/src/test/resources/tiny-orders.parquet b/wren-base/src/test/resources/tiny-orders.parquet deleted file mode 100644 index c0e93fa94..000000000 Binary files a/wren-base/src/test/resources/tiny-orders.parquet and /dev/null differ diff --git a/wren-base/src/test/resources/tpch_mdl.json b/wren-base/src/test/resources/tpch_mdl.json deleted file mode 100644 index a2a4c925e..000000000 --- a/wren-base/src/test/resources/tpch_mdl.json +++ /dev/null @@ -1,367 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "Orders", - "refSql": "select * from wrenai.tpch_tiny.orders", - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "int4" - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "int4" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "OrderStatus" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float8" - }, - { - "name": "customer", - "type": "Customer", - "relationship": "OrdersCustomer" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - }, - { - "name": "lineitems", - "type": "Lineitem", - "relationship": "OrdersLineitem" - } - ], - "primaryKey": "orderkey" - }, - { - "name": "Customer", - "refSql": "select * from wrenai.tpch_tiny.customer", - "columns": [ - { - "name": "custkey", - "expression": "c_custkey", - "type": "int4" - }, - { - "name": "nationkey", - "expression": "c_nationkey", - "type": "integer" - }, - { - "name": "name", - "expression": "c_name", - "type": "varchar" - }, - { - "name": "orders", - "type": "Orders", - "relationship": "OrdersCustomer" - }, - { - "name": "nation", - "type": "Nation", - "relationship": "CustomerNation" - } - ], - "primaryKey": "custkey" - }, - { - "name": "Lineitem", - "refSql": "select * from wrenai.tpch_tiny.lineitem", - "columns": [ - { - "name": "orderkey", - "expression": "l_orderkey", - "type": "int4" - }, - { - "name": "partkey", - "expression": "l_partkey", - "type": "int4" - }, - { - "name": "linenumber", - "expression": "l_linenumber", - "type": "int4" - }, - { - "name": "extendedprice", - "expression": "l_extendedprice", - "type": "float8" - }, - { - "name": "discount", - "expression": "l_discount", - "type": "float8" - }, - { - "name": "shipdate", - "expression": "l_shipdate", - "type": "date" - }, - { - "name": "order", - "type": "int4", - "expression": "1" - }, - { - "name": "part", - "type": "Part", - "relationship": "LineitemPart" - }, - { - "name": "orderkey_linenumber", - "type": "varchar", - "expression": "concat(l_orderkey, l_linenumber)" - } - ], - "primaryKey": "orderkey_linenumber" - }, - { - "name": "Part", - "refSql": "select * from wrenai.tpch_tiny.part", - "columns": [ - { - "name": "partkey", - "expression": "p_partkey", - "type": "int4" - }, - { - "name": "name", - "expression": "p_name", - "type": "varchar" - } - ], - "primaryKey": "partkey" - }, - { - "name": "Nation", - "refSql": "select * from wrenai.tpch_tiny.nation", - "columns": [ - { - "name": "nationkey", - "expression": "n_nationkey", - "type": "int4" - }, - { - "name": "name", - "expression": "n_name", - "type": "varchar" - }, - { - "name": "regionkey", - "expression": "n_regionkey", - "type": "int4" - }, - { - "name": "comment", - "expression": "n_comment", - "type": "varchar" - }, - { - "name": "region", - "type": "Region", - "relationship": "NationRegion" - }, - { - "name": "customer", - "type": "Customer", - "relationship": "CustomerNation" - }, - { - "name": "supplier", - "type": "Supplier", - "relationship": "NationSupplier" - } - ], - "primaryKey": "nationkey" - }, - { - "name": "Region", - "refSql": "select * from wrenai.tpch_tiny.region", - "columns": [ - { - "name": "regionkey", - "expression": "r_regionkey", - "type": "integer" - }, - { - "name": "name", - "expression": "r_name", - "type": "varchar" - }, - { - "name": "comment", - "expression": "r_comment", - "type": "varchar" - }, - { - "name": "nation", - "type": "Nation", - "relationship": "NationRegion" - } - ], - "primaryKey": "regionkey" - } - ], - "relationships": [ - { - "name": "OrdersCustomer", - "models": [ - "Orders", - "Customer" - ], - "joinType": "MANY_TO_ONE", - "condition": "Orders.custkey = Customer.custkey" - }, - { - "name": "OrdersLineitem", - "models": [ - "Orders", - "Lineitem" - ], - "joinType": "ONE_TO_MANY", - "condition": "Orders.orderkey = Lineitem.orderkey" - }, - { - "name": "LineitemPart", - "models": [ - "Lineitem", - "Part" - ], - "joinType": "MANY_TO_ONE", - "condition": "Lineitem.partkey = Part.partkey" - }, - { - "name": "CustomerNation", - "models": [ - "Customer", - "Nation" - ], - "joinType": "MANY_TO_ONE", - "condition": "Customer.nationkey = Nation.nationkey" - }, - { - "name": "NationRegion", - "models": [ - "Nation", - "Region" - ], - "joinType": "MANY_TO_ONE", - "condition": "Nation.regionkey = Region.regionkey" - } - ], - "metrics": [ - { - "name": "Revenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey", - "type": "int4" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "name": "NumberCustomerByDate", - "baseObject": "Orders", - "dimension": [ - { - "name": "orderdate", - "type": "date" - } - ], - "measure": [ - { - "name": "count_of_customer", - "type": "int4", - "expression": "count(distinct customer.name)" - } - ], - "timeGrain": [] - } - ], - "cumulativeMetrics": [ - { - "name": "WeeklyRevenue", - "baseObject": "Orders", - "measure": { - "name": "totalprice", - "type": "int4", - "operator": "sum", - "refColumn": "totalprice" - }, - "window": { - "name": "orderdate", - "refColumn": "orderdate", - "timeUnit": "WEEK", - "start": "1993-01-01", - "end": "1993-12-31" - }, - "cached": false, - "refreshTime": "30m" - } - ], - "enumDefinitions": [ - { - "name": "Status", - "values": [ - { - "name": "F" - }, - { - "name": "O" - }, - { - "name": "P" - } - ] - } - ], - "views": [ - { - "name": "useModel", - "statement": "select * from Orders" - }, - { - "name": "useMetric", - "statement": "select * from Revenue" - }, - { - "name": "useMetricRollUp", - "statement": "select * from roll_up(Revenue, orderdate, YEAR)" - }, - { - "name": "useUseMetric", - "statement": "select * from useMetric" - } - ] -} \ No newline at end of file diff --git a/wren-main/pom.xml b/wren-main/pom.xml deleted file mode 100644 index aeb68bc0a..000000000 --- a/wren-main/pom.xml +++ /dev/null @@ -1,105 +0,0 @@ - - - 4.0.0 - - - io.wren - wren-root - 0.15.2-SNAPSHOT - ../pom.xml - - - wren-main - wren-main - WrenEngine - Main - - - ${project.parent.basedir} - io.wren.\$internal - - - - - com.fasterxml.jackson.core - jackson-annotations - - - - com.google.code.findbugs - jsr305 - - - - com.google.guava - guava - - - - com.google.inject - guice - - - io.airlift - bootstrap - - - - io.airlift - configuration - - - - io.airlift - log - - - - io.airlift - units - - - - io.wren - trino-parser - - - - io.wren - wren-base - - - - jakarta.ws.rs - jakarta.ws.rs-api - - - - org.duckdb - duckdb_jdbc - - - - org.jetbrains - annotations - provided - - - - org.slf4j - slf4j-api - runtime - - - - org.assertj - assertj-core - test - - - - org.testng - testng - test - - - diff --git a/wren-main/src/main/java/io/wren/main/PreviewService.java b/wren-main/src/main/java/io/wren/main/PreviewService.java deleted file mode 100644 index d36083236..000000000 --- a/wren-main/src/main/java/io/wren/main/PreviewService.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Licensed 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 io.wren.main; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.Streams; -import com.google.inject.Inject; -import io.airlift.log.Logger; -import io.wren.base.AnalyzedMDL; -import io.wren.base.Column; -import io.wren.base.ConnectorRecordIterator; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.client.duckdb.DuckDBConfig; -import io.wren.base.config.ConfigManager; -import io.wren.base.config.WrenConfig; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Model; -import io.wren.base.sql.SqlConverter; -import io.wren.base.sqlrewrite.WrenPlanner; -import io.wren.main.metadata.Metadata; -import io.wren.main.web.dto.QueryResultDto; - -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -import static io.wren.base.dto.Column.calculatedColumn; -import static io.wren.base.dto.Column.column; -import static io.wren.base.dto.Column.relationshipColumn; -import static io.wren.base.dto.Model.model; -import static io.wren.base.dto.Relationship.relationship; -import static io.wren.base.dto.TableReference.tableReference; -import static io.wren.base.dto.View.view; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toList; - -public class PreviewService -{ - private static final Logger LOG = Logger.get(PreviewService.class); - private final Metadata metadata; - - private final SqlConverter sqlConverter; - private final ConfigManager configManager; - private final ExecutorService connectionPool; - - private boolean isWarmed; - - @Inject - public PreviewService( - Metadata metadata, - SqlConverter sqlConverter, - ConfigManager configManager) - { - this.metadata = requireNonNull(metadata, "metadata is null"); - this.sqlConverter = requireNonNull(sqlConverter, "sqlConverter is null"); - this.configManager = requireNonNull(configManager, "configManager is null"); - DuckDBConfig config = configManager.getConfig(DuckDBConfig.class); - this.connectionPool = Executors.newFixedThreadPool(config.getMaxConcurrentTasks()); - } - - public CompletableFuture preview(WrenMDL mdl, String sql, long limit) - { - return CompletableFuture.supplyAsync(() -> { - WrenConfig config = configManager.getConfig(WrenConfig.class); - SessionContext sessionContext = SessionContext.builder() - .setCatalog(mdl.getCatalog()) - .setSchema(mdl.getSchema()) - .setEnableDynamic(config.getEnableDynamicFields()) - .build(); - - String planned = WrenPlanner.rewrite(sql, sessionContext, new AnalyzedMDL(mdl, null)); - String converted = sqlConverter.convert(planned, sessionContext); - try (ConnectorRecordIterator iter = metadata.directQuery(converted, List.of())) { - return new QueryResultDto( - iter.getColumns(), - Streams.stream(iter).limit(limit).collect(toList())); - } - catch (Exception e) { - throw new RuntimeException(e); - } - }, connectionPool); - } - - public CompletableFuture dryPlan(WrenMDL mdl, String sql, boolean isModelingOnly) - { - return CompletableFuture.supplyAsync(() -> { - WrenConfig config = configManager.getConfig(WrenConfig.class); - SessionContext sessionContext = SessionContext.builder() - .setCatalog(mdl.getCatalog()) - .setSchema(mdl.getSchema()) - .setEnableDynamic(config.getEnableDynamicFields()) - .build(); - - String planned = WrenPlanner.rewrite(sql, sessionContext, new AnalyzedMDL(mdl, null)); - if (isModelingOnly) { - LOG.info("Planned SQL: %s", planned); - return planned; - } - return sqlConverter.convert(planned, sessionContext); - }, connectionPool); - } - - public CompletableFuture> dryRun(WrenMDL mdl, String sql) - { - return CompletableFuture.supplyAsync(() -> { - WrenConfig config = configManager.getConfig(WrenConfig.class); - SessionContext sessionContext = SessionContext.builder() - .setCatalog(mdl.getCatalog()) - .setSchema(mdl.getSchema()) - .setEnableDynamic(config.getEnableDynamicFields()) - .build(); - - String planned = WrenPlanner.rewrite(sql, sessionContext, new AnalyzedMDL(mdl, null)); - String converted = sqlConverter.convert(planned, sessionContext); - return metadata.describeQuery(converted, List.of()); - }, connectionPool); - } - - public boolean isWarmed() - { - return isWarmed; - } - - public void warmUp() - { - WrenMDL mdl = WrenMDL.fromManifest( - Manifest.builder() - .setCatalog("default") - .setSchema("default") - .setModels(ImmutableList.of( - model("Orders", "SELECT * FROM tpch.tiny.orders", - ImmutableList.of( - column("orderkey", "decimal", null, false), - column("custkey", "decimal", null, false), - relationshipColumn("customer", "Customer", "OrdersCustomer"), - calculatedColumn("double_key", "decimal", "orderkey * 2"), - calculatedColumn("customer_key", "decimal", "customer.custkey"))), - Model.onTableReference("Customer", - tableReference("tpch", "tiny", "customer"), - ImmutableList.of( - column("custkey", "decimal", null, false)), - null))) - .setRelationships(ImmutableList.of( - relationship("OrdersCustomer", - ImmutableList.of("Orders", "Customer"), - JoinType.MANY_TO_ONE, - "Orders.custkey = Customer.custkey"))) - .setViews(ImmutableList.of(view("customer_view", "SELECT * FROM Customer"))) - .build()); - dryPlan(mdl, "SELECT orderkey, double_key, customer_key FROM Orders", true) - .thenRun(() -> { - isWarmed = true; - LOG.info("Warm up done"); - }) - .join(); - } -} diff --git a/wren-main/src/main/java/io/wren/main/ValidationService.java b/wren-main/src/main/java/io/wren/main/ValidationService.java deleted file mode 100644 index b5b4d8b8f..000000000 --- a/wren-main/src/main/java/io/wren/main/ValidationService.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed 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 io.wren.main; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Inject; -import io.wren.base.AnalyzedMDL; -import io.wren.base.WrenException; -import io.wren.base.sql.SqlConverter; -import io.wren.main.metadata.Metadata; -import io.wren.main.validation.ColumnIsValid; -import io.wren.main.validation.ValidationResult; -import io.wren.main.validation.ValidationRule; - -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executors; - -import static io.wren.base.metadata.StandardErrorCode.NOT_FOUND; -import static io.wren.main.validation.ColumnIsValid.COLUMN_IS_VALID; -import static java.util.Objects.requireNonNull; - -public class ValidationService -{ - private final Map validationRules; - - @Inject - public ValidationService( - Metadata metadata, - SqlConverter sqlConverter) - { - requireNonNull(metadata, "metadata is null"); - requireNonNull(sqlConverter, "sqlConverter is null"); - this.validationRules = ImmutableMap.builder() - .put(COLUMN_IS_VALID, new ColumnIsValid(metadata, sqlConverter)) - .build(); - } - - public CompletableFuture> validate(String ruleName, Map parameters, AnalyzedMDL analyzedMDL) - { - return CompletableFuture.supplyAsync(() -> Optional.ofNullable(validationRules.get(ruleName)) - .orElseThrow(() -> new WrenException(NOT_FOUND, "Validation rule not found: " + ruleName)) - .validate(analyzedMDL, parameters) - .stream().map(CompletableFuture::join) - .toList(), Executors.newVirtualThreadPerTaskExecutor()); - } -} diff --git a/wren-main/src/main/java/io/wren/main/WrenModule.java b/wren-main/src/main/java/io/wren/main/WrenModule.java deleted file mode 100644 index c2a2a03a8..000000000 --- a/wren-main/src/main/java/io/wren/main/WrenModule.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed 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 io.wren.main; - -import com.google.inject.Binder; -import io.airlift.configuration.AbstractConfigurationAwareModule; -import io.wren.base.config.WrenConfig; - -import static io.airlift.configuration.ConfigBinder.configBinder; - -public class WrenModule - extends AbstractConfigurationAwareModule -{ - @Override - protected void setup(Binder binder) - { - configBinder(binder).bindConfig(WrenConfig.class); - } -} diff --git a/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckDBMetadata.java b/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckDBMetadata.java deleted file mode 100644 index f203d1209..000000000 --- a/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckDBMetadata.java +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Licensed 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 io.wren.main.connector.duckdb; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Inject; -import io.airlift.log.Logger; -import io.wren.base.Column; -import io.wren.base.ConnectorRecordIterator; -import io.wren.base.Parameter; -import io.wren.base.WrenException; -import io.wren.base.client.duckdb.DuckDBConfig; -import io.wren.base.client.duckdb.DuckDBConnectorConfig; -import io.wren.base.client.duckdb.DuckDBSettingSQL; -import io.wren.base.client.duckdb.DuckdbClient; -import io.wren.base.config.ConfigManager; -import io.wren.base.config.WrenConfig; -import io.wren.main.metadata.Metadata; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.NoSuchFileException; -import java.nio.file.Path; -import java.sql.Date; -import java.time.LocalDate; -import java.util.List; -import java.util.Map; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; - -import static io.wren.base.metadata.StandardErrorCode.GENERIC_INTERNAL_ERROR; -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toList; - -public class DuckDBMetadata - implements Metadata -{ - public static final Map PG_TO_DUCKDB_FUNCTION_NAME_MAPPINGS = initPgNameToDuckDBFunctions(); - private static final Logger LOG = Logger.get(DuckDBMetadata.class); - private final ConfigManager configManager; - private DuckdbClient duckdbClient; - private final AtomicReference duckDBSettingSQL = new AtomicReference<>(new DuckDBSettingSQL()); - - @Inject - public DuckDBMetadata( - ConfigManager configManager) - { - this.configManager = requireNonNull(configManager, "configManager is null"); - if (configManager.getConfig(WrenConfig.class).getDataSourceType().equals(WrenConfig.DataSourceType.DUCKDB)) { - initDuckDBSettingSQLIfNeed(); - this.duckdbClient = buildDuckDBClientSafely(); - } - } - - @Override - public void directDDL(String sql) - { - duckdbClient.executeDDL(sql); - } - - @Override - public ConnectorRecordIterator directQuery(String sql, List parameters) - { - try { - return DuckdbRecordIterator.of(duckdbClient, sql, convertParameters(parameters)); - } - catch (Exception e) { - throw new WrenException(GENERIC_INTERNAL_ERROR, e); - } - } - - @Override - public List describeQuery(String sql, List parameters) - { - return duckdbClient.describe(sql, convertParameters(parameters)).stream() - .map(columnMetadata -> new Column(columnMetadata.getName(), columnMetadata.getType())) - .collect(toList()); - } - - @Override - public void reload() - { - close(); - this.duckdbClient = buildDuckDBClient(); - } - - @Override - public void close() - { - if (duckdbClient != null) { - duckdbClient.close(); - } - } - - public DuckdbClient getClient() - { - return duckdbClient; - } - - private DuckdbClient buildDuckDBClient() - { - return DuckdbClient.builder() - .setDuckDBConfig(configManager.getConfig(DuckDBConfig.class)) - .setDuckDBSettingSQL(duckDBSettingSQL.get()) - .build(); - } - - private DuckdbClient buildDuckDBClientSafely() - { - DuckdbClient.Builder builder = DuckdbClient.builder() - .setDuckDBConfig(configManager.getConfig(DuckDBConfig.class)) - .setDuckDBSettingSQL(duckDBSettingSQL.get()); - return builder.buildSafely().orElse(builder.setDuckDBSettingSQL(null).build()); - } - - /** - * @return mapping table for pg function which can be replaced by duckdb function. - */ - private static Map initPgNameToDuckDBFunctions() - { - return ImmutableMap.builder() - .put("generate_array", "generate_series") - .build(); - } - - private void initDuckDBSettingSQLIfNeed() - { - setSQLFromFile(getInitSQLPath(), this::setInitSQL); - setSQLFromFile(getSessionSQLPath(), this::setSessionSQL); - } - - private void setSQLFromFile(Path filePath, Consumer setter) - { - if (filePath != null) { - try { - setter.accept(Files.readString(filePath)); - } - catch (NoSuchFileException e) { - // Do nothing - } - catch (IOException e) { - LOG.error(e, "Failed to read SQL from %s", filePath); - } - } - } - - public static List convertParameters(List parameters) - { - return parameters.stream().map(DuckDBMetadata::convertParameter).collect(toList()); - } - - private static Parameter convertParameter(Parameter parameter) - { - String type = parameter.getType(); - Object value = parameter.getValue(); - if (type.equals("DATE") && value instanceof LocalDate) { - value = Date.valueOf((LocalDate) value); - } - return new Parameter(type, value); - } - - public String getInitSQL() - { - return duckDBSettingSQL.get().getInitSQL(); - } - - public void setInitSQL(String initSQL) - { - duckDBSettingSQL.get().setInitSQL(initSQL); - } - - public void appendInitSQL(String sql) - { - duckDBSettingSQL.updateAndGet(settingSQL -> { - String initSQL = settingSQL.getInitSQL(); - if (initSQL == null) { - settingSQL.setInitSQL(sql); - } - else { - settingSQL.setInitSQL(initSQL + "\n" + sql); - } - return settingSQL; - }); - } - - public Path getInitSQLPath() - { - return Path.of(configManager.getConfig(DuckDBConnectorConfig.class).getInitSQLPath()); - } - - public String getSessionSQL() - { - return duckDBSettingSQL.get().getSessionSQL(); - } - - public void setSessionSQL(String sessionSQL) - { - duckDBSettingSQL.get().setSessionSQL(sessionSQL); - } - - public void appendSessionSQL(String sql) - { - duckDBSettingSQL.updateAndGet(settingSQL -> { - String sessionSQL = settingSQL.getSessionSQL(); - if (sessionSQL == null) { - settingSQL.setSessionSQL(sql); - } - else { - settingSQL.setSessionSQL(sessionSQL + "\n" + sql); - } - return settingSQL; - }); - } - - public Path getSessionSQLPath() - { - return Path.of(configManager.getConfig(DuckDBConnectorConfig.class).getSessionSQLPath()); - } -} diff --git a/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckDBSqlConverter.java b/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckDBSqlConverter.java deleted file mode 100644 index 643d172a2..000000000 --- a/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckDBSqlConverter.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Licensed 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 io.wren.main.connector.duckdb; - -import com.google.common.collect.ImmutableList; -import com.google.inject.Inject; -import io.airlift.log.Logger; -import io.trino.sql.tree.Node; -import io.wren.base.SessionContext; -import io.wren.base.sql.SqlConverter; -import io.wren.main.metadata.Metadata; -import io.wren.main.sql.SqlRewrite; -import io.wren.main.sql.duckdb.RewriteArray; -import io.wren.main.sql.duckdb.RewriteFunction; -import org.intellij.lang.annotations.Language; - -import java.util.List; - -import static io.trino.sql.SqlFormatter.Dialect.DUCKDB; -import static io.trino.sql.SqlFormatter.formatSql; -import static io.wren.base.sqlrewrite.Utils.parseSql; -import static java.util.Objects.requireNonNull; - -public class DuckDBSqlConverter - implements SqlConverter -{ - private static final Logger LOG = Logger.get(DuckDBSqlConverter.class); - - private final Metadata metadata; - - @Inject - public DuckDBSqlConverter(Metadata metadata) - { - this.metadata = requireNonNull(metadata, "metadata is null"); - } - - @Override - public String convert(@Language("sql") String sql, SessionContext sessionContext) - { - Node rewrittenNode = parseSql(sql); - - List sqlRewrites = ImmutableList.of( - // DuckDB doesn't support `ARRAY[1,2,3][1]` but `array_value(1,2,3])[1]` is supported - RewriteArray.INSTANCE, - RewriteFunction.INSTANCE); - - LOG.info("[Input sql]: %s", sql); - - for (SqlRewrite rewrite : sqlRewrites) { - if (LOG.isDebugEnabled()) { - LOG.debug("Before %s: %s", rewrite.getClass().getSimpleName(), formatSql(rewrittenNode)); - } - rewrittenNode = rewrite.rewrite(rewrittenNode, metadata); - if (LOG.isDebugEnabled()) { - LOG.debug("After %s: %s", rewrite.getClass().getSimpleName(), formatSql(rewrittenNode)); - } - } - String dialectSql = formatSql(rewrittenNode, DUCKDB); - LOG.info("[Dialect sql]: %s", dialectSql); - return dialectSql; - } -} diff --git a/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckdbRecordIterator.java b/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckdbRecordIterator.java deleted file mode 100644 index 8c6acb203..000000000 --- a/wren-main/src/main/java/io/wren/main/connector/duckdb/DuckdbRecordIterator.java +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Licensed 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 io.wren.main.connector.duckdb; - -import com.google.common.collect.ImmutableList; -import io.wren.base.Column; -import io.wren.base.ConnectorRecordIterator; -import io.wren.base.Parameter; -import io.wren.base.client.AutoCloseableIterator; -import io.wren.base.client.Client; -import io.wren.base.client.jdbc.JdbcRecordIterator; -import org.duckdb.DuckDBArray; -import org.duckdb.DuckDBResultSet; - -import java.sql.ResultSetMetaData; -import java.sql.SQLException; -import java.sql.Timestamp; -import java.util.Arrays; -import java.util.List; -import java.util.stream.IntStream; - -import static java.util.Objects.requireNonNull; -import static java.util.stream.Collectors.toList; - -public class DuckdbRecordIterator - implements ConnectorRecordIterator -{ - private final List columns; - private final AutoCloseableIterator recordIterator; - - public static DuckdbRecordIterator of(Client client, String sql, List parameters) - throws SQLException - { - return new DuckdbRecordIterator(client, sql, parameters); - } - - private DuckdbRecordIterator(Client client, String sql, List parameters) - throws SQLException - { - requireNonNull(client, "client is null"); - requireNonNull(sql, "sql is null"); - requireNonNull(parameters, "parameters is null"); - JdbcRecordIterator jdbcRecordIterator = JdbcRecordIterator.of(client, sql, parameters); - this.recordIterator = jdbcRecordIterator; - - ResultSetMetaData resultSetMetaData = jdbcRecordIterator.getResultSetMetaData(); - ImmutableList.Builder columnBuilder = ImmutableList.builder(); - for (int i = 1; i <= resultSetMetaData.getColumnCount(); i++) { - columnBuilder.add(new Column(resultSetMetaData.getColumnName(i), resultSetMetaData.getColumnTypeName(i))); - } - this.columns = columnBuilder.build(); - } - - @Override - public List getColumns() - { - return columns; - } - - @Override - public void close() - throws Exception - { - recordIterator.close(); - } - - @Override - public boolean hasNext() - { - return recordIterator.hasNext(); - } - - @Override - public Object[] next() - { - Object[] record = recordIterator.next(); - return IntStream.range(0, record.length) - .mapToObj(index -> convertValue(columns.get(index).getType(), record[index])) - .toArray(); - } - - private Object convertValue(String type, Object value) - { - try { - if (value == null) { - return null; - } - if (type.endsWith("[]")) { - if (value instanceof DuckDBArray array) { - return Arrays.stream((Object[]) array.getArray()) - .map(innerVal -> convertValue(type.substring(0, type.length() - 2), innerVal)) - .collect(toList()); - } - return Arrays.stream((Object[]) value) - .map(innerVal -> convertValue(type.substring(0, type.length() - 2), innerVal)) - .collect(toList()); - } - switch (type) { - case "TIMESTAMP": - return ((Timestamp) value).toLocalDateTime(); - case "BLOB": - if (value instanceof DuckDBResultSet.DuckDBBlobResult) { - DuckDBResultSet.DuckDBBlobResult blob = (DuckDBResultSet.DuckDBBlobResult) value; - return blob.getBytes(1, (int) blob.length()); - } - case "JSON": - return value.toString(); - } - return value; - } - catch (Exception e) { - throw new IllegalArgumentException("Unsupported value: " + value, e); - } - } -} diff --git a/wren-main/src/main/java/io/wren/main/metadata/Metadata.java b/wren-main/src/main/java/io/wren/main/metadata/Metadata.java deleted file mode 100644 index bdc0e09d7..000000000 --- a/wren-main/src/main/java/io/wren/main/metadata/Metadata.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Licensed 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 io.wren.main.metadata; - -import io.wren.base.Column; -import io.wren.base.ConnectorRecordIterator; -import io.wren.base.Parameter; - -import java.util.List; - -public interface Metadata -{ - void directDDL(String sql); - - ConnectorRecordIterator directQuery(String sql, List parameters); - - List describeQuery(String sql, List parameters); - - void reload(); - - void close(); -} diff --git a/wren-main/src/main/java/io/wren/main/metadata/MetadataManager.java b/wren-main/src/main/java/io/wren/main/metadata/MetadataManager.java deleted file mode 100644 index 3f4ca2053..000000000 --- a/wren-main/src/main/java/io/wren/main/metadata/MetadataManager.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed 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 io.wren.main.metadata; - -import com.google.inject.Inject; -import io.wren.base.Column; -import io.wren.base.ConnectorRecordIterator; -import io.wren.base.Parameter; -import io.wren.base.config.ConfigManager; -import io.wren.base.config.WrenConfig; -import io.wren.main.connector.duckdb.DuckDBMetadata; - -import java.util.List; - -import static java.util.Objects.requireNonNull; - -public final class MetadataManager - implements Metadata -{ - private final DuckDBMetadata duckDBMetadata; - - private WrenConfig.DataSourceType dataSourceType; - private Metadata delegate; - - @Inject - public MetadataManager( - ConfigManager configManager, - DuckDBMetadata duckDBMetadata) - { - this.duckDBMetadata = requireNonNull(duckDBMetadata, "duckDBMetadata is null"); - this.dataSourceType = requireNonNull(configManager.getConfig(WrenConfig.class).getDataSourceType(), "dataSourceType is null"); - changeDelegate(dataSourceType); - } - - private synchronized void changeDelegate(WrenConfig.DataSourceType dataSourceType) - { - switch (dataSourceType) { - case DUCKDB: - delegate = duckDBMetadata; - break; - default: - throw new UnsupportedOperationException("Unsupported data source type: " + dataSourceType); - } - } - - @Override - public void directDDL(String sql) - { - delegate.directDDL(sql); - } - - @Override - public ConnectorRecordIterator directQuery(String sql, List parameters) - { - return delegate.directQuery(sql, parameters); - } - - @Override - public List describeQuery(String sql, List parameters) - { - return delegate.describeQuery(sql, parameters); - } - - @Override - public void reload() - { - delegate.reload(); - } - - @Override - public void close() - { - delegate.close(); - } -} diff --git a/wren-main/src/main/java/io/wren/main/server/Server.java b/wren-main/src/main/java/io/wren/main/server/Server.java deleted file mode 100644 index 464102b6d..000000000 --- a/wren-main/src/main/java/io/wren/main/server/Server.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.wren.main.server; - -import com.google.common.base.StandardSystemProperty; -import com.google.common.collect.ImmutableList; -import com.google.inject.Injector; -import com.google.inject.Module; -import io.airlift.bootstrap.ApplicationConfigurationException; -import io.airlift.bootstrap.Bootstrap; -import io.airlift.log.Logger; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static java.lang.String.format; -import static java.nio.file.LinkOption.NOFOLLOW_LINKS; - -public class Server -{ - public final void start() - { - doStart(); - } - - private void doStart() - { - Logger log = Logger.get(Server.class); - log.info("Java version: %s", StandardSystemProperty.JAVA_VERSION.value()); - - ImmutableList.Builder modules = ImmutableList.builder(); - modules.add(); - modules.addAll(getAdditionalModules()); - Bootstrap app = new Bootstrap(modules.build()); - - try { - Injector injector = app.initialize(); - - configure(injector); - - log.info("======== SERVER STARTED ========"); - } - catch (ApplicationConfigurationException e) { - StringBuilder message = new StringBuilder(); - message.append("Configuration is invalid\n"); - message.append("==========\n"); - addMessages(message, "Errors", ImmutableList.copyOf(e.getErrors())); - addMessages(message, "Warnings", ImmutableList.copyOf(e.getWarnings())); - message.append("\n"); - message.append("=========="); - log.error(message.toString()); - System.exit(1); - } - catch (Throwable e) { - log.error(e); - System.exit(1); - } - } - - protected Iterable getAdditionalModules() - { - return ImmutableList.of(); - } - - protected void configure(Injector injector) {} - - private static void addMessages(StringBuilder output, String type, List messages) - { - if (messages.isEmpty()) { - return; - } - output.append("\n").append(type).append(":\n\n"); - for (int index = 0; index < messages.size(); index++) { - output.append(format("%s) %s\n", index + 1, messages.get(index))); - } - } - - private static void logLocation(Logger log, String name, Path path) - { - if (!Files.exists(path, NOFOLLOW_LINKS)) { - log.info("%s: [does not exist]", name); - return; - } - try { - path = path.toAbsolutePath().toRealPath(); - } - catch (IOException e) { - log.info("%s: [not accessible]", name); - return; - } - log.info("%s: %s", name, path); - } -} diff --git a/wren-main/src/main/java/io/wren/main/sql/SqlConverterManager.java b/wren-main/src/main/java/io/wren/main/sql/SqlConverterManager.java deleted file mode 100644 index 4bf2cd55c..000000000 --- a/wren-main/src/main/java/io/wren/main/sql/SqlConverterManager.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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 io.wren.main.sql; - -import com.google.inject.Inject; -import io.wren.base.SessionContext; -import io.wren.base.config.ConfigManager; -import io.wren.base.config.WrenConfig; -import io.wren.base.sql.SqlConverter; -import io.wren.main.connector.duckdb.DuckDBSqlConverter; - -import static java.util.Objects.requireNonNull; - -public final class SqlConverterManager - implements SqlConverter -{ - private final DuckDBSqlConverter duckDBSqlConverter; - private final ConfigManager configManager; - private WrenConfig.DataSourceType dataSourceType; - private SqlConverter delegate; - - @Inject - public SqlConverterManager( - ConfigManager configManager, - DuckDBSqlConverter duckDBSqlConverter) - { - this.configManager = requireNonNull(configManager, "configManager is null"); - this.duckDBSqlConverter = requireNonNull(duckDBSqlConverter, "duckDBSqlConverter is null"); - this.dataSourceType = requireNonNull(configManager.getConfig(WrenConfig.class).getDataSourceType(), "dataSourceType is null"); - changeDelegate(dataSourceType); - } - - private void changeDelegate(WrenConfig.DataSourceType dataSourceType) - { - switch (dataSourceType) { - case DUCKDB: - delegate = duckDBSqlConverter; - break; - default: - throw new UnsupportedOperationException("Unsupported data source type: " + dataSourceType); - } - } - - public void reload() - { - if (dataSourceType != configManager.getConfig(WrenConfig.class).getDataSourceType()) { - dataSourceType = configManager.getConfig(WrenConfig.class).getDataSourceType(); - changeDelegate(dataSourceType); - } - } - - @Override - public String convert(String sql, SessionContext sessionContext) - { - return delegate.convert(sql, sessionContext); - } -} diff --git a/wren-main/src/main/java/io/wren/main/sql/SqlRewrite.java b/wren-main/src/main/java/io/wren/main/sql/SqlRewrite.java deleted file mode 100644 index ccd136ec8..000000000 --- a/wren-main/src/main/java/io/wren/main/sql/SqlRewrite.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Licensed 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 io.wren.main.sql; - -import io.trino.sql.tree.Node; -import io.wren.main.metadata.Metadata; - -public interface SqlRewrite -{ - Node rewrite(Node node, Metadata metadata); -} diff --git a/wren-main/src/main/java/io/wren/main/sql/duckdb/RewriteArray.java b/wren-main/src/main/java/io/wren/main/sql/duckdb/RewriteArray.java deleted file mode 100644 index 5c7db89a2..000000000 --- a/wren-main/src/main/java/io/wren/main/sql/duckdb/RewriteArray.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed 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 io.wren.main.sql.duckdb; - -import io.trino.sql.tree.ArrayConstructor; -import io.trino.sql.tree.Expression; -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.QualifiedName; -import io.trino.sql.tree.SubscriptExpression; -import io.wren.base.sqlrewrite.BaseRewriter; -import io.wren.main.metadata.Metadata; -import io.wren.main.sql.SqlRewrite; - -public class RewriteArray - implements SqlRewrite -{ - public static final RewriteArray INSTANCE = new RewriteArray(); - - private RewriteArray() {} - - @Override - public Node rewrite(Node node, Metadata metadata) - { - return new RewriteArrayRewriter().process(node, null); - } - - private static class RewriteArrayRewriter - extends BaseRewriter - { - @Override - protected Node visitSubscriptExpression(SubscriptExpression node, Void context) - { - Expression base = node.getBase(); - if (base instanceof ArrayConstructor) { - base = convertToArrayValue((ArrayConstructor) base); - } - if (node.getLocation().isPresent()) { - return new SubscriptExpression( - node.getLocation().get(), - visitAndCast(base, context), - visitAndCast(node.getIndex(), context)); - } - return new SubscriptExpression(visitAndCast(base, context), visitAndCast(node.getIndex(), context)); - } - - private Expression convertToArrayValue(ArrayConstructor node) - { - if (node.getLocation().isPresent()) { - return new FunctionCall( - node.getLocation().get(), - QualifiedName.of("array_value"), - node.getValues()); - } - return new FunctionCall( - QualifiedName.of("array_value"), - node.getValues()); - } - } -} diff --git a/wren-main/src/main/java/io/wren/main/sql/duckdb/RewriteFunction.java b/wren-main/src/main/java/io/wren/main/sql/duckdb/RewriteFunction.java deleted file mode 100644 index 5e557e924..000000000 --- a/wren-main/src/main/java/io/wren/main/sql/duckdb/RewriteFunction.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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 io.wren.main.sql.duckdb; - -import io.trino.sql.tree.FunctionCall; -import io.trino.sql.tree.Node; -import io.trino.sql.tree.QualifiedName; -import io.wren.base.sqlrewrite.BaseRewriter; -import io.wren.main.metadata.Metadata; -import io.wren.main.sql.SqlRewrite; - -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import static io.wren.main.connector.duckdb.DuckDBMetadata.PG_TO_DUCKDB_FUNCTION_NAME_MAPPINGS; -import static java.util.Locale.ENGLISH; - -public class RewriteFunction - implements SqlRewrite -{ - public static final RewriteFunction INSTANCE = new RewriteFunction(); - - private RewriteFunction() {} - - @Override - public Node rewrite(Node node, Metadata metadata) - { - return new RewriteFunctionRewriter().process(node, null); - } - - private static class RewriteFunctionRewriter - extends BaseRewriter - { - @Override - protected Node visitFunctionCall(FunctionCall node, Void context) - { - QualifiedName functionName = resolveFunction(node.getName().toString()); - - FunctionCall newFunctionNode = FunctionCall.builder(node) - .name(functionName) - .build(); - - return super.visitFunctionCall(newFunctionNode, context); - } - - private QualifiedName resolveFunction(String functionName) - { - List funcNameLowerCase = Arrays.stream(functionName.toLowerCase(ENGLISH).split("\\.")).collect(Collectors.toList()); - QualifiedName qualifiedName = QualifiedName.of(funcNameLowerCase); - if (PG_TO_DUCKDB_FUNCTION_NAME_MAPPINGS.containsKey(qualifiedName.getSuffix())) { - return QualifiedName.of(PG_TO_DUCKDB_FUNCTION_NAME_MAPPINGS.get(qualifiedName.getSuffix())); - } - return qualifiedName; - } - } -} diff --git a/wren-main/src/main/java/io/wren/main/validation/ColumnIsValid.java b/wren-main/src/main/java/io/wren/main/validation/ColumnIsValid.java deleted file mode 100644 index cbe2ebb6d..000000000 --- a/wren-main/src/main/java/io/wren/main/validation/ColumnIsValid.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Licensed 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 io.wren.main.validation; - -import io.airlift.units.Duration; -import io.wren.base.AnalyzedMDL; -import io.wren.base.ConnectorRecordIterator; -import io.wren.base.SessionContext; -import io.wren.base.sql.SqlConverter; -import io.wren.base.sqlrewrite.WrenPlanner; -import io.wren.main.metadata.Metadata; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executors; - -import static io.wren.main.validation.ValidationResult.formatRuleWithIdentifier; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static java.util.concurrent.TimeUnit.MILLISECONDS; - -public class ColumnIsValid - implements ValidationRule -{ - public static final String COLUMN_IS_VALID = "column_is_valid"; - private static final String MODEL_NAME = "modelName"; - private static final String COLUMN_NAME = "columnName"; - - public static Map parameters(String model, String column) - { - Map map = new HashMap<>(); - map.put(MODEL_NAME, model); - map.put(COLUMN_NAME, column); - return map; - } - - private final Metadata metadata; - private final SqlConverter sqlConverter; - - public ColumnIsValid(Metadata metadata, SqlConverter sqlConverter) - { - this.metadata = requireNonNull(metadata, "metadata is null"); - this.sqlConverter = requireNonNull(sqlConverter, "sqlConverter is null"); - } - - @Override - public String getRuleName() - { - return COLUMN_IS_VALID; - } - - @Override - public List> validate(AnalyzedMDL analyzedMDL, Map parameters) - { - return List.of(CompletableFuture.supplyAsync(() -> { - long start = System.currentTimeMillis(); - Optional modelName = getModelName(parameters); - Optional columnName = getColumnName(parameters); - - if (modelName.isEmpty() || modelName.get().isEmpty()) { - return ValidationResult.error(getRuleName(), Duration.succinctDuration(System.currentTimeMillis() - start, MILLISECONDS), "Model name is required"); - } - - if (columnName.isEmpty() || columnName.get().isEmpty()) { - return ValidationResult.error(formatRuleWithIdentifier(getRuleName(), modelName.get()), - Duration.succinctDuration(System.currentTimeMillis() - start, MILLISECONDS), "Column name is required"); - } - - try { - String sql = format(""" - SELECT "%s" FROM "%s" LIMIT 1""", columnName.get(), modelName.get()); - SessionContext sessionContext = SessionContext.builder() - .setCatalog(analyzedMDL.getWrenMDL().getCatalog()) - .setSchema(analyzedMDL.getWrenMDL().getSchema()) - .setEnableDynamic(true) - .build(); - String planned = WrenPlanner.rewrite(sql, sessionContext, analyzedMDL); - String converted = sqlConverter.convert(planned, sessionContext); - try (ConnectorRecordIterator recordIterator = metadata.directQuery(converted, List.of())) { - Object[] ignored = recordIterator.next(); - long duration = System.currentTimeMillis() - start; - return ValidationResult.pass(formatRuleWithIdentifier(getRuleName(), modelName.get(), columnName.get()), - Duration.succinctDuration(duration, MILLISECONDS)); - } - } - catch (Exception e) { - long duration = System.currentTimeMillis() - start; - return ValidationResult.fail(formatRuleWithIdentifier(getRuleName(), modelName.get(), columnName.get()), Duration.succinctDuration(duration, MILLISECONDS), e.getMessage()); - } - }, Executors.newVirtualThreadPerTaskExecutor())); - } - - private Optional getColumnName(Map parameters) - { - return Optional.ofNullable(parameters.get(COLUMN_NAME)).map(Object::toString); - } - - private Optional getModelName(Map parameters) - { - return Optional.ofNullable(parameters.get(MODEL_NAME)).map(Object::toString); - } -} diff --git a/wren-main/src/main/java/io/wren/main/validation/ValidationResult.java b/wren-main/src/main/java/io/wren/main/validation/ValidationResult.java deleted file mode 100644 index 26a0e9614..000000000 --- a/wren-main/src/main/java/io/wren/main/validation/ValidationResult.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Licensed 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 io.wren.main.validation; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.airlift.units.Duration; - -import javax.annotation.Nullable; - -import static java.lang.String.format; - -public class ValidationResult -{ - public static ValidationResult pass(String name, Duration duration) - { - return new ValidationResult(name, Status.PASS, duration, null); - } - - public static ValidationResult error(String name, Duration duration, String message) - { - return new ValidationResult(name, Status.ERROR, duration, message); - } - - public static ValidationResult fail(String name, Duration duration, String message) - { - return new ValidationResult(name, Status.FAIL, duration, message); - } - - public static ValidationResult warn(String name, Duration duration, String message) - { - return new ValidationResult(name, Status.WARN, duration, message); - } - - public enum Status - { - PASS, - WARN, - ERROR, - FAIL, - SKIP - } - - private final String name; - private final Status status; - private final Duration duration; - private final String message; - - @JsonCreator - public ValidationResult( - @JsonProperty("name") String name, - @JsonProperty("status") Status status, - @JsonProperty("duration") Duration duration, - @JsonProperty("message") @Nullable String message) - { - this.name = name; - this.status = status; - this.duration = duration; - this.message = message; - } - - @JsonProperty - public String getName() - { - return name; - } - - public static String formatRuleWithIdentifier(String ruleName, String modelName, String identifier) - { - return format("%s:%s:%s", ruleName, modelName, identifier); - } - - public static String formatRuleWithIdentifier(String ruleName, String modelName) - { - return format("%s:%s", ruleName, modelName); - } - - @JsonProperty - public Status getStatus() - { - return status; - } - - @JsonProperty - public Duration getDuration() - { - return duration; - } - - @JsonProperty - @Nullable - public String getMessage() - { - return message; - } -} diff --git a/wren-main/src/main/java/io/wren/main/validation/ValidationRule.java b/wren-main/src/main/java/io/wren/main/validation/ValidationRule.java deleted file mode 100644 index 1971b2949..000000000 --- a/wren-main/src/main/java/io/wren/main/validation/ValidationRule.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Licensed 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 io.wren.main.validation; - -import io.wren.base.AnalyzedMDL; - -import java.util.List; -import java.util.Map; -import java.util.concurrent.CompletableFuture; - -public interface ValidationRule -{ - String getRuleName(); - - List> validate(AnalyzedMDL analyzedMDL, Map parameters); -} diff --git a/wren-main/src/main/java/io/wren/main/web/AnalysisResource.java b/wren-main/src/main/java/io/wren/main/web/AnalysisResource.java deleted file mode 100644 index 0508d53b6..000000000 --- a/wren-main/src/main/java/io/wren/main/web/AnalysisResource.java +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Licensed 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 io.wren.main.web; - -import com.google.inject.Inject; -import io.trino.sql.tree.NodeLocation; -import io.trino.sql.tree.Statement; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.DecisionPointAnalyzer; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.ExprSource; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.FilterAnalysis; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.QueryAnalysis; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.RelationAnalysis; -import io.wren.main.web.dto.NodeLocationDto; -import io.wren.main.web.dto.QueryAnalysisDto; -import io.wren.main.web.dto.QueryAnalysisDto.ColumnAnalysisDto; -import io.wren.main.web.dto.QueryAnalysisDto.FilterAnalysisDto; -import io.wren.main.web.dto.QueryAnalysisDto.RelationAnalysisDto; -import io.wren.main.web.dto.QueryAnalysisDto.SortItemAnalysisDto; -import io.wren.main.web.dto.SqlAnalysisInputDto; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.container.Suspended; - -import java.util.concurrent.CompletableFuture; - -import static io.wren.base.sqlrewrite.Utils.parseSql; -import static io.wren.main.web.WrenExceptionMapper.bindAsyncResponse; -import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; - -@Deprecated -@Path("/v1/analysis") -public class AnalysisResource -{ - @Inject - public AnalysisResource() - { - } - - @GET - @Path("/sql") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public void getSqlAnalysis( - SqlAnalysisInputDto inputDto, - @Suspended AsyncResponse asyncResponse) - { - if (inputDto.getManifest() == null) { - asyncResponse.resume(new IllegalArgumentException("Manifest is required")); - } - CompletableFuture - .supplyAsync(() -> { - WrenMDL mdl = WrenMDL.fromManifest(inputDto.getManifest()); - Statement statement = parseSql(inputDto.getSql()); - return DecisionPointAnalyzer.analyze( - statement, - SessionContext.builder().setCatalog(mdl.getCatalog()).setSchema(mdl.getSchema()).build(), - mdl).stream().map(AnalysisResource::toQueryAnalysisDto).toList(); - }).whenComplete(bindAsyncResponse(asyncResponse)); - } - - static QueryAnalysisDto toQueryAnalysisDto(QueryAnalysis queryAnalysis) - { - return new QueryAnalysisDto( - queryAnalysis.getSelectItems().stream().map(AnalysisResource::toColumnAnalysisDto).toList(), - toRelationAnalysisDto(queryAnalysis.getRelation()), - toFilterAnalysisDto(queryAnalysis.getFilter()), - queryAnalysis.getGroupByKeys().stream().map(groupByKeys -> groupByKeys.stream().map(AnalysisResource::toGroupByKeyDto).toList()).toList(), - queryAnalysis.getSortings().stream().map(AnalysisResource::toSortItemAnalysisDto).toList(), - queryAnalysis.isSubqueryOrCte()); - } - - private static ColumnAnalysisDto toColumnAnalysisDto(QueryAnalysis.ColumnAnalysis columnAnalysis) - { - return new ColumnAnalysisDto(columnAnalysis.getAliasName(), - columnAnalysis.getExpression(), columnAnalysis.getProperties(), - toNodeLocationDto(columnAnalysis.getNodeLocation()), - columnAnalysis.getExprSources().stream().map(AnalysisResource::toExprSourceDto).toList()); - } - - private static FilterAnalysisDto toFilterAnalysisDto(FilterAnalysis filterAnalysis) - { - return switch (filterAnalysis) { - case FilterAnalysis.ExpressionAnalysis exprAnalysis -> new FilterAnalysisDto( - exprAnalysis.getType().name(), - null, - null, - exprAnalysis.getNode(), - toNodeLocationDto(exprAnalysis.getNodeLocation()), - exprAnalysis.getExprSources().stream().map(AnalysisResource::toExprSourceDto).toList()); - case FilterAnalysis.LogicalAnalysis logicalAnalysis -> - new FilterAnalysisDto( - logicalAnalysis.getType().name(), - toFilterAnalysisDto(logicalAnalysis.getLeft()), - toFilterAnalysisDto(logicalAnalysis.getRight()), - null, - toNodeLocationDto(logicalAnalysis.getNodeLocation()), - null); - case null -> null; - default -> throw new IllegalArgumentException("Unsupported filter analysis: " + filterAnalysis); - }; - } - - private static RelationAnalysisDto toRelationAnalysisDto(RelationAnalysis relationAnalysis) - { - return switch (relationAnalysis) { - case RelationAnalysis.TableRelation tableRelation -> - new RelationAnalysisDto(tableRelation.getType().name(), - tableRelation.getAlias(), - null, - null, - null, - tableRelation.getTableName(), - null, - null, - toNodeLocationDto(tableRelation.getNodeLocation())); - case RelationAnalysis.JoinRelation joinRelation -> new RelationAnalysisDto( - joinRelation.getType().name(), - joinRelation.getAlias(), - toRelationAnalysisDto(joinRelation.getLeft()), - toRelationAnalysisDto(joinRelation.getRight()), - joinCriteriaDto(joinRelation.getCriteria()), - null, - null, - joinRelation.getExprSources().stream().map(AnalysisResource::toExprSourceDto).toList(), - toNodeLocationDto(joinRelation.getNodeLocation())); - case RelationAnalysis.SubqueryRelation subqueryRelation -> new RelationAnalysisDto( - subqueryRelation.getType().name(), - subqueryRelation.getAlias(), - null, - null, - null, - null, - subqueryRelation.getBody().stream().map(AnalysisResource::toQueryAnalysisDto).toList(), - null, - toNodeLocationDto(subqueryRelation.getNodeLocation())); - case null -> null; - default -> throw new IllegalArgumentException("Unsupported relation analysis: " + relationAnalysis); - }; - } - - private static SortItemAnalysisDto toSortItemAnalysisDto(QueryAnalysis.SortItemAnalysis sortItemAnalysis) - { - return new SortItemAnalysisDto(sortItemAnalysis.getExpression(), - sortItemAnalysis.getOrdering().name(), - toNodeLocationDto(sortItemAnalysis.getNodeLocation()), - sortItemAnalysis.getExprSources().stream().map(AnalysisResource::toExprSourceDto).toList()); - } - - private static QueryAnalysisDto.ExprSourceDto toExprSourceDto(ExprSource exprSource) - { - return new QueryAnalysisDto.ExprSourceDto(exprSource.expression(), exprSource.sourceDataset(), exprSource.sourceColumn(), toNodeLocationDto(exprSource.nodeLocation())); - } - - private static QueryAnalysisDto.GroupByKeyDto toGroupByKeyDto(QueryAnalysis.GroupByKey groupByKey) - { - return new QueryAnalysisDto.GroupByKeyDto(groupByKey.getExpression(), - toNodeLocationDto(groupByKey.getNodeLocation()), - groupByKey.getExprSources().stream().map(AnalysisResource::toExprSourceDto).toList()); - } - - private static QueryAnalysisDto.JoinCriteriaDto joinCriteriaDto(RelationAnalysis.JoinCriteria joinCriteria) - { - return new QueryAnalysisDto.JoinCriteriaDto(joinCriteria.getExpression(), toNodeLocationDto(joinCriteria.getNodeLocation())); - } - - private static NodeLocationDto toNodeLocationDto(NodeLocation nodeLocation) - { - return new NodeLocationDto(nodeLocation.getLineNumber(), nodeLocation.getColumnNumber()); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/AnalysisResourceV2.java b/wren-main/src/main/java/io/wren/main/web/AnalysisResourceV2.java deleted file mode 100644 index c53ef3391..000000000 --- a/wren-main/src/main/java/io/wren/main/web/AnalysisResourceV2.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.wren.main.web; - -import com.google.inject.Inject; -import io.trino.sql.tree.Statement; -import io.wren.base.SessionContext; -import io.wren.base.WrenMDL; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.DecisionPointAnalyzer; -import io.wren.main.web.dto.SqlAnalysisInputBatchDto; -import io.wren.main.web.dto.SqlAnalysisInputDtoV2; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.container.Suspended; - -import java.io.IOException; -import java.util.Base64; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -import static io.wren.base.sqlrewrite.Utils.parseSql; -import static io.wren.main.web.WrenExceptionMapper.bindAsyncResponse; -import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; -import static java.nio.charset.StandardCharsets.UTF_8; - -@Path("/v2/analysis") -public class AnalysisResourceV2 -{ - @Inject - public AnalysisResourceV2() {} - - @GET - @Path("/sql") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public void getSqlAnalysis( - SqlAnalysisInputDtoV2 inputDto, - @Suspended AsyncResponse asyncResponse) - { - CompletableFuture - .supplyAsync(() -> - Optional.ofNullable(inputDto.getManifestStr()) - .orElseThrow(() -> new IllegalArgumentException("Manifest is required"))) - .thenApply(manifestStr -> { - try { - return WrenMDL.fromJson(new String(Base64.getDecoder().decode(manifestStr), UTF_8)); - } - catch (IOException e) { - throw new RuntimeException(e); - } - }) - .thenApply(mdl -> { - Statement statement = parseSql(inputDto.getSql()); - return DecisionPointAnalyzer.analyze( - statement, - SessionContext.builder().setCatalog(mdl.getCatalog()).setSchema(mdl.getSchema()).build(), - mdl).stream().map(AnalysisResource::toQueryAnalysisDto).toList(); - }) - .whenComplete(bindAsyncResponse(asyncResponse)); - } - - @GET - @Path("/sqls") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public void getSqlAnalysisBatch( - SqlAnalysisInputBatchDto inputBatchDto, - @Suspended AsyncResponse asyncResponse) - { - CompletableFuture - .supplyAsync(() -> - Optional.ofNullable(inputBatchDto.getManifestStr()) - .orElseThrow(() -> new IllegalArgumentException("Manifest is required"))) - .thenApply(manifestStr -> { - try { - return WrenMDL.fromJson(new String(Base64.getDecoder().decode(manifestStr), UTF_8)); - } - catch (IOException e) { - throw new RuntimeException(e); - } - }) - .thenApply(mdl -> - inputBatchDto.getSqls().stream().map(sql -> { - Statement statement = parseSql(sql); - return DecisionPointAnalyzer.analyze( - statement, - SessionContext.builder().setCatalog(mdl.getCatalog()).setSchema(mdl.getSchema()).build(), - mdl).stream().map(AnalysisResource::toQueryAnalysisDto).toList(); - }).toList()) - .whenComplete(bindAsyncResponse(asyncResponse)); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/ConfigResource.java b/wren-main/src/main/java/io/wren/main/web/ConfigResource.java deleted file mode 100644 index ced038416..000000000 --- a/wren-main/src/main/java/io/wren/main/web/ConfigResource.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed 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 io.wren.main.web; - -import com.google.inject.Inject; -import io.wren.base.config.ConfigManager; -import io.wren.base.sql.SqlConverter; -import io.wren.main.metadata.Metadata; -import io.wren.main.sql.SqlConverterManager; -import jakarta.ws.rs.DELETE; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.PATCH; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.container.Suspended; - -import java.util.List; -import java.util.concurrent.CompletableFuture; - -import static java.util.Objects.requireNonNull; - -@Path("/v1/config") -public class ConfigResource -{ - private final ConfigManager configManager; - private final SqlConverterManager sqlConverter; - - @Inject - public ConfigResource( - ConfigManager configManager, - Metadata metadata, - SqlConverter sqlConverter) - - { - this.configManager = requireNonNull(configManager, "configManager is null"); - this.sqlConverter = (SqlConverterManager) requireNonNull(sqlConverter, "sqlConverter is null"); - } - - @GET - @Produces("application/json") - public void getConfigs(@Suspended AsyncResponse asyncResponse) - { - CompletableFuture - .supplyAsync(configManager::getConfigs) - .whenComplete(WrenExceptionMapper.bindAsyncResponse(asyncResponse)); - } - - @GET - @Path("/{configName}") - @Produces("application/json") - public void getOneConfig( - @PathParam("configName") String configName, - @Suspended AsyncResponse asyncResponse) - { - CompletableFuture - .supplyAsync(() -> configManager.getConfig(configName)) - .whenComplete(WrenExceptionMapper.bindAsyncResponse(asyncResponse)); - } - - @DELETE - @Produces("application/json") - public void resetToDefaultConfig(@Suspended AsyncResponse asyncResponse) - { - CompletableFuture - .runAsync(() -> configManager.setConfigs(List.of(), true)) - .whenComplete(WrenExceptionMapper.bindAsyncResponse(asyncResponse)); - } - - @PATCH - @Produces("application/json") - public void patchConfig( - List configEntries, - @Suspended AsyncResponse asyncResponse) - { - CompletableFuture - .runAsync(() -> { - if (configManager.setConfigs(configEntries, false)) { - reloadConfig(); - } - }) - .whenComplete(WrenExceptionMapper.bindAsyncResponse(asyncResponse)); - } - - private void reloadConfig() - { - sqlConverter.reload(); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/DuckDBResource.java b/wren-main/src/main/java/io/wren/main/web/DuckDBResource.java deleted file mode 100644 index c5fe80198..000000000 --- a/wren-main/src/main/java/io/wren/main/web/DuckDBResource.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Licensed 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 io.wren.main.web; - -import com.google.common.collect.ImmutableList; -import com.google.inject.Inject; -import io.wren.base.ConnectorRecordIterator; -import io.wren.base.WrenException; -import io.wren.base.client.duckdb.FileUtil; -import io.wren.main.connector.duckdb.DuckDBMetadata; -import io.wren.main.web.dto.QueryResultDto; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.PATCH; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.PUT; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.container.Suspended; - -import static io.wren.base.metadata.StandardErrorCode.GENERIC_USER_ERROR; -import static io.wren.main.web.WrenExceptionMapper.bindAsyncResponse; -import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; -import static java.util.Objects.requireNonNull; -import static java.util.concurrent.CompletableFuture.runAsync; -import static java.util.concurrent.CompletableFuture.supplyAsync; - -@Path("/v1/data-source/duckdb") -public class DuckDBResource -{ - private final DuckDBMetadata metadata; - - @Inject - public DuckDBResource( - DuckDBMetadata metadata) - { - this.metadata = requireNonNull(metadata, "metadata is null"); - } - - @POST - @Path("/query") - @Produces(APPLICATION_JSON) - public void query( - String statement, - @Suspended AsyncResponse asyncResponse) - throws Exception - { - supplyAsync(() -> { - try (ConnectorRecordIterator iterator = metadata.directQuery(statement, ImmutableList.of())) { - ImmutableList.Builder data = ImmutableList.builder(); - while (iterator.hasNext()) { - data.add(iterator.next()); - } - return new QueryResultDto(iterator.getColumns(), data.build()); - } - catch (WrenException e) { - // Sending DDL via executeQuery() still work. Should catch exception to make sense. - if (e.getMessage().contains("executeQuery() can only be used with queries that return a ResultSet")) { - return new QueryResultDto(ImmutableList.of(), ImmutableList.of()); - } - throw e; - } - catch (Exception e) { - throw new WrenException(GENERIC_USER_ERROR, e); - } - }).whenComplete(bindAsyncResponse(asyncResponse)); - } - - @GET - @Path("/settings/init-sql") - public void getInitSQL(@Suspended AsyncResponse asyncResponse) - { - supplyAsync(metadata::getInitSQL) - .whenComplete(bindAsyncResponse(asyncResponse)); - } - - @PUT - @Path("/settings/init-sql") - public void setInitSQL( - String sql, - @Suspended AsyncResponse asyncResponse) - { - runAsync(() -> { - String initSQL = metadata.getInitSQL(); - metadata.setInitSQL(sql); - try { - metadata.reload(); - } - catch (Exception e) { - metadata.setInitSQL(initSQL); - throw e; - } - java.nio.file.Path initSQLPath = metadata.getInitSQLPath(); - FileUtil.archiveFile(initSQLPath); - FileUtil.createFile(initSQLPath, sql); - }).whenComplete(bindAsyncResponse(asyncResponse)); - } - - @PATCH - @Path("/settings/init-sql") - public void appendToInitSQL( - String sql, - @Suspended AsyncResponse asyncResponse) - { - runAsync(() -> { - metadata.directDDL(sql); - metadata.appendInitSQL(sql); - FileUtil.appendToFile(metadata.getInitSQLPath(), sql); - }).whenComplete(bindAsyncResponse(asyncResponse)); - } - - @GET - @Path("/settings/session-sql") - public void getSessionSQL(@Suspended AsyncResponse asyncResponse) - { - supplyAsync(metadata::getSessionSQL) - .whenComplete(bindAsyncResponse(asyncResponse)); - } - - @PUT - @Path("/settings/session-sql") - public void setSessionSQL( - String sql, - @Suspended AsyncResponse asyncResponse) - { - runAsync(() -> { - metadata.setSessionSQL(sql); - metadata.getClient().closeAndInitPool(); - java.nio.file.Path sessionSQLPath = metadata.getSessionSQLPath(); - FileUtil.archiveFile(sessionSQLPath); - FileUtil.createFile(sessionSQLPath, sql); - }).whenComplete(bindAsyncResponse(asyncResponse)); - } - - @PATCH - @Path("/settings/session-sql") - public void appendToSessionSQL( - String sql, - @Suspended AsyncResponse asyncResponse) - { - runAsync(() -> { - String sessionSQL = metadata.getSessionSQL(); - metadata.appendSessionSQL(sql); - try { - metadata.getClient().closeAndInitPool(); - } - catch (Exception e) { - metadata.setSessionSQL(sessionSQL); - metadata.getClient().initPool(); - throw e; - } - FileUtil.appendToFile(metadata.getSessionSQLPath(), sql); - }).whenComplete(bindAsyncResponse(asyncResponse)); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/MDLResource.java b/wren-main/src/main/java/io/wren/main/web/MDLResource.java deleted file mode 100644 index 9d360a3da..000000000 --- a/wren-main/src/main/java/io/wren/main/web/MDLResource.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Licensed 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 io.wren.main.web; - -import com.google.inject.Inject; -import io.wren.base.AnalyzedMDL; -import io.wren.base.WrenMDL; -import io.wren.main.PreviewService; -import io.wren.main.ValidationService; -import io.wren.main.web.dto.DryPlanDto; -import io.wren.main.web.dto.PreviewDto; -import io.wren.main.web.dto.ValidateDto; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.POST; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.PathParam; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.container.Suspended; - -import java.util.Map; -import java.util.Optional; - -import static io.wren.main.web.WrenExceptionMapper.bindAsyncResponse; -import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; -import static java.util.Objects.requireNonNull; - -@Path("/v1/mdl") -public class MDLResource -{ - private final PreviewService previewService; - private final ValidationService validationService; - - @Inject - public MDLResource( - PreviewService previewService, - ValidationService validationService) - { - this.previewService = requireNonNull(previewService, "previewService is null"); - this.validationService = requireNonNull(validationService, "validationService is null"); - } - - @GET - @Path("/preview") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public void preview( - PreviewDto previewDto, - @Suspended AsyncResponse asyncResponse) - { - if (previewDto.getManifest() == null) { - asyncResponse.resume(new IllegalArgumentException("Manifest is required")); - } - previewService.preview( - WrenMDL.fromManifest(previewDto.getManifest()), - previewDto.getSql(), - Optional.ofNullable(previewDto.getLimit()).orElse(100L)) - .whenComplete(bindAsyncResponse(asyncResponse)); - } - - @GET - @Path("/dry-plan") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public void dryPlan( - DryPlanDto dryPlanDto, - @Suspended AsyncResponse asyncResponse) - { - if (dryPlanDto.getManifest() == null) { - asyncResponse.resume(new IllegalArgumentException("Manifest is required")); - } - previewService.dryPlan(WrenMDL.fromManifest(dryPlanDto.getManifest()), dryPlanDto.getSql(), dryPlanDto.isModelingOnly()) - .whenComplete(bindAsyncResponse(asyncResponse)); - } - - @GET - @Path("/dry-run") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public void dryRun( - PreviewDto previewDto, - @Suspended AsyncResponse asyncResponse) - { - if (previewDto.getManifest() == null) { - asyncResponse.resume(new IllegalArgumentException("Manifest is required")); - } - previewService.dryRun(WrenMDL.fromManifest(previewDto.getManifest()), previewDto.getSql()) - .whenComplete(bindAsyncResponse(asyncResponse)); - } - - @POST - @Path("/validate/{ruleName}") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public void validate( - @PathParam("ruleName") String ruleName, - ValidateDto validateDto, - @Suspended AsyncResponse asyncResponse) - { - if (validateDto == null || validateDto.getManifest() == null) { - asyncResponse.resume(new IllegalArgumentException("Manifest is required")); - } - else { - Map parameters = Map.of(); - parameters = validateDto.getParameters() != null ? validateDto.getParameters() : parameters; - AnalyzedMDL analyzedMDL = new AnalyzedMDL(WrenMDL.fromManifest(validateDto.getManifest()), null); - validationService.validate(ruleName, parameters, analyzedMDL) - .whenComplete(bindAsyncResponse(asyncResponse)); - } - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/MDLResourceV2.java b/wren-main/src/main/java/io/wren/main/web/MDLResourceV2.java deleted file mode 100644 index 0e02a6328..000000000 --- a/wren-main/src/main/java/io/wren/main/web/MDLResourceV2.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed 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 io.wren.main.web; - -import com.google.inject.Inject; -import io.wren.base.WrenMDL; -import io.wren.main.PreviewService; -import io.wren.main.web.dto.DryPlanDtoV2; -import jakarta.ws.rs.Consumes; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.container.Suspended; - -import java.io.IOException; -import java.util.Base64; -import java.util.Optional; -import java.util.concurrent.CompletableFuture; - -import static io.wren.main.web.WrenExceptionMapper.bindAsyncResponse; -import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Objects.requireNonNull; - -@Path("/v2/mdl") -public class MDLResourceV2 -{ - private final PreviewService previewService; - - @Inject - public MDLResourceV2(PreviewService previewService) - { - this.previewService = requireNonNull(previewService, "previewService is null"); - } - - @GET - @Path("/dry-plan") - @Consumes(APPLICATION_JSON) - @Produces(APPLICATION_JSON) - public void dryPlan( - DryPlanDtoV2 dryPlanDto, - @Suspended AsyncResponse asyncResponse) - { - CompletableFuture - .supplyAsync(() -> - Optional.ofNullable(dryPlanDto.getManifestStr()) - .orElseThrow(() -> new IllegalArgumentException("Manifest is required"))) - .thenApply(manifestStr -> { - try { - return WrenMDL.fromJson(new String(Base64.getDecoder().decode(manifestStr), UTF_8)); - } - catch (IOException e) { - throw new RuntimeException(e); - } - }) - .thenCompose(mdl -> previewService.dryPlan(mdl, dryPlanDto.getSql(), true)) - .whenComplete(bindAsyncResponse(asyncResponse)); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/SystemResource.java b/wren-main/src/main/java/io/wren/main/web/SystemResource.java deleted file mode 100644 index 1920eadc9..000000000 --- a/wren-main/src/main/java/io/wren/main/web/SystemResource.java +++ /dev/null @@ -1,33 +0,0 @@ -package io.wren.main.web; - -import com.google.inject.Inject; -import io.wren.main.PreviewService; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.container.Suspended; -import jakarta.ws.rs.core.Response; - -@Path("/v2") -public class SystemResource -{ - private final PreviewService previewService; - - @Inject - public SystemResource(PreviewService previewService) - { - this.previewService = previewService; - } - - @GET - @Path("/health") - public void health(@Suspended AsyncResponse asyncResponse) - { - if (previewService.isWarmed()) { - asyncResponse.resume(Response.ok().build()); - } - else { - asyncResponse.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE).build()); - } - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/WrenExceptionMapper.java b/wren-main/src/main/java/io/wren/main/web/WrenExceptionMapper.java deleted file mode 100644 index 6c58d4230..000000000 --- a/wren-main/src/main/java/io/wren/main/web/WrenExceptionMapper.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Licensed 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 io.wren.main.web; - -import io.airlift.log.Logger; -import io.wren.base.WrenException; -import io.wren.main.web.dto.ErrorMessageDto; -import jakarta.ws.rs.container.AsyncResponse; -import jakarta.ws.rs.core.Response; -import jakarta.ws.rs.ext.ExceptionMapper; - -import java.util.concurrent.CompletionException; -import java.util.concurrent.ExecutionException; -import java.util.function.BiConsumer; - -import static io.wren.base.metadata.StandardErrorCode.GENERIC_INTERNAL_ERROR; -import static io.wren.base.metadata.StandardErrorCode.NOT_FOUND; -import static jakarta.ws.rs.core.MediaType.APPLICATION_JSON; -import static jakarta.ws.rs.core.Response.Status.BAD_REQUEST; -import static jakarta.ws.rs.core.Response.Status.INTERNAL_SERVER_ERROR; -import static java.lang.String.format; - -public final class WrenExceptionMapper - implements ExceptionMapper -{ - private static final Logger LOG = Logger.get(WrenExceptionMapper.class); - - public static BiConsumer bindAsyncResponse(AsyncResponse asyncResponse) - { - return (response, throwable) -> { - if (throwable != null) { - asyncResponse.resume(throwable); - } - else if (response instanceof Response) { - asyncResponse.resume(response); - } - else { - asyncResponse.resume(Response.ok(response).build()); - } - }; - } - - @Override - public Response toResponse(Throwable throwable) - { - LOG.warn(throwable, format("Exception, type: %s, message: %s", throwable.getClass(), throwable.getMessage())); - if (throwable instanceof WrenException) { - return failure((WrenException) throwable); - } - else if ((throwable instanceof ExecutionException || throwable instanceof CompletionException) - && throwable.getCause() instanceof WrenException) { - return failure((WrenException) throwable.getCause()); - } - else { - return Response - .status(INTERNAL_SERVER_ERROR) - .type(APPLICATION_JSON) - .entity(new ErrorMessageDto(GENERIC_INTERNAL_ERROR.name(), throwable.getMessage())) - .build(); - } - } - - private static Response failure(WrenException exception) - { - switch (exception.getErrorCode().getType()) { - case USER_ERROR: - if (exception.getErrorCode().equals(NOT_FOUND.toErrorCode())) { - return Response - .status(Response.Status.NOT_FOUND) - .type(APPLICATION_JSON) - .entity(createErrorMessageDto(exception)) - .build(); - } - return Response - .status(BAD_REQUEST) - .type(APPLICATION_JSON) - .entity(createErrorMessageDto(exception)) - .build(); - case EXTERNAL: - case INTERNAL_ERROR: - case INSUFFICIENT_RESOURCES: - default: - return Response - .status(INTERNAL_SERVER_ERROR) - .type(APPLICATION_JSON) - .entity(createErrorMessageDto(exception)) - .build(); - } - } - - private static ErrorMessageDto createErrorMessageDto(WrenException e) - { - return new ErrorMessageDto(e.getErrorCode().getName(), e.getMessage()); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/CheckOutputDto.java b/wren-main/src/main/java/io/wren/main/web/dto/CheckOutputDto.java deleted file mode 100644 index f487ccc04..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/CheckOutputDto.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Licensed 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. - */ - -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class CheckOutputDto -{ - public static CheckOutputDto ready(String version) - { - return new CheckOutputDto(Status.READY, version); - } - - public static CheckOutputDto prepare(String version) - { - return new CheckOutputDto(Status.PREPARING, version); - } - - public enum Status - { - READY, - PREPARING - } - - private final Status status; - private final String version; - - @JsonCreator - public CheckOutputDto( - @JsonProperty("systemStatus") Status status, - @JsonProperty("version") String version) - { - this.status = status; - this.version = version; - } - - @JsonProperty - public Status getStatus() - { - return status; - } - - @JsonProperty - public String getVersion() - { - return version; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/ColumnLineageInputDto.java b/wren-main/src/main/java/io/wren/main/web/dto/ColumnLineageInputDto.java deleted file mode 100644 index de264de17..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/ColumnLineageInputDto.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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. - */ - -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.dto.Manifest; - -public class ColumnLineageInputDto -{ - private final Manifest manifest; - private final String modelName; - private final String columnName; - - @JsonCreator - public ColumnLineageInputDto( - @JsonProperty("manifest") Manifest manifest, - @JsonProperty("modelName") String modelName, - @JsonProperty("columnName") String columnName) - { - this.manifest = manifest; - this.modelName = modelName; - this.columnName = columnName; - } - - @JsonProperty - public Manifest getManifest() - { - return manifest; - } - - @JsonProperty - public String getModelName() - { - return modelName; - } - - @JsonProperty - public String getColumnName() - { - return columnName; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/ColumnPredicateDto.java b/wren-main/src/main/java/io/wren/main/web/dto/ColumnPredicateDto.java deleted file mode 100644 index 1d95cf769..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/ColumnPredicateDto.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class ColumnPredicateDto -{ - private final String columnName; - private final List predicates; - - @JsonCreator - public ColumnPredicateDto( - @JsonProperty("columnName") String columnName, - @JsonProperty("predicates") List predicates) - { - this.columnName = requireNonNull(columnName); - this.predicates = requireNonNull(predicates); - } - - @JsonProperty - public String getColumnName() - { - return columnName; - } - - @JsonProperty - public List getPredicates() - { - return predicates; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ColumnPredicateDto that = (ColumnPredicateDto) o; - return Objects.equals(columnName, that.columnName) && Objects.equals(predicates, that.predicates); - } - - @Override - public int hashCode() - { - return Objects.hash(columnName, predicates); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("columnName", columnName) - .add("predicates", predicates) - .toString(); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/DeployInputDto.java b/wren-main/src/main/java/io/wren/main/web/dto/DeployInputDto.java deleted file mode 100644 index 997fd48ff..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/DeployInputDto.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.dto.Manifest; - -public class DeployInputDto -{ - private final Manifest manifest; - private final String version; - - @JsonCreator - public DeployInputDto( - @JsonProperty("manifest") Manifest manifest, - @JsonProperty("version") String version) - { - this.manifest = manifest; - this.version = version; - } - - @JsonProperty - public Manifest getManifest() - { - return manifest; - } - - @JsonProperty - public String getVersion() - { - return version; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/DryPlanDto.java b/wren-main/src/main/java/io/wren/main/web/dto/DryPlanDto.java deleted file mode 100644 index ac7f9174a..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/DryPlanDto.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.dto.Manifest; - -public class DryPlanDto -{ - private final Manifest manifest; - private final String sql; - private final boolean isModelingOnly; - - @JsonCreator - public DryPlanDto( - @JsonProperty("manifest") Manifest manifest, - @JsonProperty("sql") String sql, - @JsonProperty("modelingOnly") boolean modelingOnly) - { - this.manifest = manifest; - this.sql = sql; - this.isModelingOnly = modelingOnly; - } - - @JsonProperty - public Manifest getManifest() - { - return manifest; - } - - @JsonProperty - public String getSql() - { - return sql; - } - - @JsonProperty - public boolean isModelingOnly() - { - return isModelingOnly; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/DryPlanDtoV2.java b/wren-main/src/main/java/io/wren/main/web/dto/DryPlanDtoV2.java deleted file mode 100644 index 771c85a4a..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/DryPlanDtoV2.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class DryPlanDtoV2 -{ - private final String manifestStr; - private final String sql; - - @JsonCreator - public DryPlanDtoV2( - @JsonProperty("manifestStr") String manifestStr, - @JsonProperty("sql") String sql) - { - this.manifestStr = manifestStr; - this.sql = sql; - } - - @JsonProperty - public String getManifestStr() - { - return manifestStr; - } - - @JsonProperty - public String getSql() - { - return sql; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/DuckDBSettingsDto.java b/wren-main/src/main/java/io/wren/main/web/dto/DuckDBSettingsDto.java deleted file mode 100644 index 90de9acaa..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/DuckDBSettingsDto.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class DuckDBSettingsDto -{ - private String initSQL; - - private String sessionSQL; - - @JsonProperty - public String getInitSQL() - { - return initSQL; - } - - public void setInitSQL(String initSQL) - { - this.initSQL = initSQL; - } - - @JsonProperty - public String getSessionSQL() - { - return sessionSQL; - } - - public void setSessionSQL(String sessionSQL) - { - this.sessionSQL = sessionSQL; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/ErrorMessageDto.java b/wren-main/src/main/java/io/wren/main/web/dto/ErrorMessageDto.java deleted file mode 100644 index 377d0ff7a..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/ErrorMessageDto.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; - -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ErrorMessageDto -{ - private String code; - private String message; - - @JsonCreator - public ErrorMessageDto(@JsonProperty("code") String code, @JsonProperty("message") String message) - { - this.code = code; - this.message = message; - } - - @JsonProperty - public String getCode() - { - return code; - } - - public void setCode(String code) - { - this.code = code; - } - - @JsonProperty - public String getMessage() - { - return message; - } - - public void setMessage(String message) - { - this.message = message; - } - - @Override - public boolean equals(Object that) - { - if (this == that) { - return true; - } - if (that == null || getClass() != that.getClass()) { - return false; - } - ErrorMessageDto errorMessageDto = (ErrorMessageDto) that; - return Objects.equals(code, errorMessageDto.code) && - Objects.equals(message, errorMessageDto.message); - } - - @Override - public int hashCode() - { - return Objects.hash(code, message); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("code", code) - .add("message", message) - .toString(); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/LineageResult.java b/wren-main/src/main/java/io/wren/main/web/dto/LineageResult.java deleted file mode 100644 index 1dccaa801..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/LineageResult.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Licensed 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. - */ - -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.google.common.collect.ImmutableMap; - -import java.util.List; -import java.util.Map; -import java.util.Objects; - -public class LineageResult -{ - public static LineageResult lineageResult(String datasetName, List columns) - { - return new LineageResult(datasetName, columns); - } - - public static Column columnWithType(String name, String type) - { - return new Column(name, ImmutableMap.of("type", type)); - } - - private final String datasetName; - private final List columns; - - @JsonCreator - public LineageResult( - @JsonProperty("datasetName") String datasetName, - @JsonProperty("columns") List columns) - { - this.datasetName = datasetName; - this.columns = columns; - } - - @JsonProperty - public String getDatasetName() - { - return datasetName; - } - - @JsonProperty - public List getColumns() - { - return columns; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - LineageResult that = (LineageResult) o; - return Objects.equals(datasetName, that.datasetName) && Objects.equals(columns, that.columns); - } - - @Override - public int hashCode() - { - return Objects.hash(datasetName, columns); - } - - @Override - public String toString() - { - return "LineageResult{" + - "datasetName='" + datasetName + '\'' + - ", columns=" + columns + - '}'; - } - - public static class Column - { - private final String name; - private final Map properties; - - @JsonCreator - public Column( - @JsonProperty("name") String name, - @JsonProperty("properties") Map properties) - { - this.name = name; - this.properties = properties; - } - - @JsonProperty - public String getName() - { - return name; - } - - @JsonProperty - public Map getProperties() - { - return properties; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - Column column = (Column) o; - return Objects.equals(name, column.name) && Objects.equals(properties, column.properties); - } - - @Override - public int hashCode() - { - return Objects.hash(name, properties); - } - - @Override - public String toString() - { - return "Column{" + - "name='" + name + '\'' + - ", properties=" + properties + - '}'; - } - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/NodeLocationDto.java b/wren-main/src/main/java/io/wren/main/web/dto/NodeLocationDto.java deleted file mode 100644 index d84faf306..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/NodeLocationDto.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; - -public class NodeLocationDto -{ - public static NodeLocationDto nodeLocationDto(int line, int column) - { - return new NodeLocationDto(line, column); - } - - private final int line; - private final int column; - - @JsonCreator - public NodeLocationDto( - @JsonProperty int line, - @JsonProperty int column) - { - this.line = line; - this.column = column; - } - - @JsonProperty - public int getLine() - { - return line; - } - - @JsonProperty - public int getColumn() - { - return column; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - NodeLocationDto that = (NodeLocationDto) o; - return line == that.line && column == that.column; - } - - @Override - public int hashCode() - { - return Objects.hash(line, column); - } - - @Override - public String toString() - { - return "NodeLocationDto{" + - "line=" + line + - ", column=" + column + - '}'; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/PredicateDto.java b/wren-main/src/main/java/io/wren/main/web/dto/PredicateDto.java deleted file mode 100644 index 1ee82896d..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/PredicateDto.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; -import static java.util.Objects.requireNonNull; - -public class PredicateDto -{ - private final String operator; - private final String value; - - @JsonCreator - public PredicateDto( - @JsonProperty("operator") String operator, - @JsonProperty("value") String value) - { - this.operator = requireNonNull(operator); - this.value = requireNonNull(value); - } - - @JsonProperty - public String getOperator() - { - return operator; - } - - @JsonProperty - public String getValue() - { - return value; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - PredicateDto that = (PredicateDto) o; - return Objects.equals(operator, that.operator) && Objects.equals(value, that.value); - } - - @Override - public int hashCode() - { - return Objects.hash(operator, value); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("operator", operator) - .add("value", value) - .toString(); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/PreviewDto.java b/wren-main/src/main/java/io/wren/main/web/dto/PreviewDto.java deleted file mode 100644 index 259897e4b..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/PreviewDto.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed 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. - */ - -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.dto.Manifest; - -public class PreviewDto -{ - private final Manifest manifest; - private final String sql; - private final Long limit; - - @JsonCreator - public PreviewDto( - @JsonProperty("manifest") Manifest manifest, - @JsonProperty("sql") String sql, - @JsonProperty("limit") Long limit) - { - this.manifest = manifest; - this.sql = sql; - this.limit = limit; - } - - @JsonProperty - public Manifest getManifest() - { - return manifest; - } - - @JsonProperty - public String getSql() - { - return sql; - } - - @JsonProperty - public Long getLimit() - { - return limit; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/QueryAnalysisDto.java b/wren-main/src/main/java/io/wren/main/web/dto/QueryAnalysisDto.java deleted file mode 100644 index b1837106a..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/QueryAnalysisDto.java +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.Optional; - -@JsonInclude(JsonInclude.Include.NON_NULL) -public class QueryAnalysisDto -{ - private List selectItems; - private RelationAnalysisDto relation; - private FilterAnalysisDto filter; - private List> groupByKeys; - private List sortings; - private boolean isSubqueryOrCte; - - @JsonCreator - public QueryAnalysisDto( - List selectItems, - RelationAnalysisDto relation, - FilterAnalysisDto filter, - List> groupByKeys, - List sortings, - boolean isSubqueryOrCte) - { - this.selectItems = selectItems; - this.relation = relation; - this.filter = filter; - this.groupByKeys = groupByKeys; - this.sortings = sortings; - this.isSubqueryOrCte = isSubqueryOrCte; - } - - @JsonProperty - public List getSelectItems() - { - return selectItems; - } - - @JsonProperty - public RelationAnalysisDto getRelation() - { - return relation; - } - - @JsonProperty - public FilterAnalysisDto getFilter() - { - return filter; - } - - @JsonProperty - public List> getGroupByKeys() - { - return groupByKeys; - } - - @JsonProperty - public List getSortings() - { - return sortings; - } - - @JsonProperty("isSubqueryOrCte") - public boolean isSubqueryOrCte() - { - return isSubqueryOrCte; - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class ColumnAnalysisDto - { - private Optional alias; - private String expression; - private Map properties; - private NodeLocationDto nodeLocation; - private List exprSources; - - @JsonCreator - public ColumnAnalysisDto(Optional alias, String expression, Map properties, NodeLocationDto nodeLocation, List exprSources) - { - this.alias = alias; - this.expression = expression; - this.properties = properties; - this.nodeLocation = nodeLocation; - this.exprSources = exprSources; - } - - @JsonProperty - public String getExpression() - { - return expression; - } - - @JsonProperty - public Optional getAlias() - { - return alias; - } - - @JsonProperty - public Map getProperties() - { - return properties; - } - - @JsonProperty - public NodeLocationDto getNodeLocation() - { - return nodeLocation; - } - - @JsonProperty - public List getExprSources() - { - return exprSources; - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class RelationAnalysisDto - { - private String type; - private String alias; - private RelationAnalysisDto left; - private RelationAnalysisDto right; - private JoinCriteriaDto criteria; - private String tableName; - private List body; - private List exprSources; - private NodeLocationDto nodeLocation; - - @JsonCreator - public RelationAnalysisDto( - String type, - String alias, - RelationAnalysisDto left, - RelationAnalysisDto right, - JoinCriteriaDto criteria, - String tableName, - List body, - List exprSources, - NodeLocationDto nodeLocation) - { - this.type = type; - this.alias = alias; - this.left = left; - this.right = right; - this.criteria = criteria; - this.tableName = tableName; - this.body = body; - this.exprSources = exprSources; - this.nodeLocation = nodeLocation; - } - - @JsonProperty - public String getType() - { - return type; - } - - @JsonProperty - public String getAlias() - { - return alias; - } - - @JsonProperty - public RelationAnalysisDto getLeft() - { - return left; - } - - @JsonProperty - public RelationAnalysisDto getRight() - { - return right; - } - - @JsonProperty - public JoinCriteriaDto getCriteria() - { - return criteria; - } - - @JsonProperty - public String getTableName() - { - return tableName; - } - - @JsonProperty - public List getBody() - { - return body; - } - - @JsonProperty - public List getExprSources() - { - return exprSources; - } - - @JsonProperty - public NodeLocationDto getNodeLocation() - { - return nodeLocation; - } - } - - public static class JoinCriteriaDto - { - private String expression; - private NodeLocationDto nodeLocation; - - @JsonCreator - public JoinCriteriaDto(String expression, NodeLocationDto nodeLocation) - { - this.expression = expression; - this.nodeLocation = nodeLocation; - } - - @JsonProperty - public String getExpression() - { - return expression; - } - - @JsonProperty - public NodeLocationDto getNodeLocation() - { - return nodeLocation; - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class FilterAnalysisDto - { - private String type; - private FilterAnalysisDto left; - private FilterAnalysisDto right; - private String node; - private NodeLocationDto nodeLocation; - private List exprSources; - - @JsonCreator - public FilterAnalysisDto(String type, FilterAnalysisDto left, FilterAnalysisDto right, String node, NodeLocationDto nodeLocation, List exprSources) - { - this.type = type; - this.left = left; - this.right = right; - this.node = node; - this.nodeLocation = nodeLocation; - this.exprSources = exprSources; - } - - @JsonProperty - public String getType() - { - return type; - } - - @JsonProperty - public FilterAnalysisDto getLeft() - { - return left; - } - - @JsonProperty - public FilterAnalysisDto getRight() - { - return right; - } - - @JsonProperty - public String getNode() - { - return node; - } - - @JsonProperty - public NodeLocationDto getNodeLocation() - { - return nodeLocation; - } - - @JsonProperty - public List getExprSources() - { - return exprSources; - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class SortItemAnalysisDto - { - private String expression; - private String ordering; - private NodeLocationDto nodeLocation; - private List exprSources; - - @JsonCreator - public SortItemAnalysisDto(String expression, String ordering, NodeLocationDto nodeLocation, List exprSources) - { - this.expression = expression; - this.ordering = ordering; - this.nodeLocation = nodeLocation; - this.exprSources = exprSources; - } - - @JsonProperty - public String getExpression() - { - return expression; - } - - @JsonProperty - public String getOrdering() - { - return ordering; - } - - @JsonProperty - public NodeLocationDto getNodeLocation() - { - return nodeLocation; - } - - @JsonProperty - public List getExprSources() - { - return exprSources; - } - } - - public static class ExprSourceDto - { - private String expression; - private String sourceDataset; - private String sourceColumn; - private NodeLocationDto nodeLocation; - - @JsonCreator - public ExprSourceDto(String expression, String sourceDataset, String sourceColumn, NodeLocationDto nodeLocation) - { - this.expression = expression; - this.sourceDataset = sourceDataset; - this.sourceColumn = sourceColumn; - this.nodeLocation = nodeLocation; - } - - @JsonProperty - public String getExpression() - { - return expression; - } - - @JsonProperty - public String getSourceDataset() - { - return sourceDataset; - } - - @JsonProperty - public String getSourceColumn() - { - return sourceColumn; - } - - @JsonProperty - public NodeLocationDto getNodeLocation() - { - return nodeLocation; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - ExprSourceDto that = (ExprSourceDto) o; - return Objects.equals(expression, that.expression) && - Objects.equals(sourceDataset, that.sourceDataset) && - Objects.equals(sourceColumn, that.sourceColumn) && - Objects.equals(nodeLocation, that.nodeLocation); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, sourceDataset, sourceColumn, nodeLocation); - } - - @Override - public String toString() - { - return "ExprSourceDto{" + - "expression='" + expression + '\'' + - ", sourceDataset='" + sourceDataset + '\'' + - ", sourceColumn='" + sourceColumn + '\'' + - ", nodeLocation=" + nodeLocation + - '}'; - } - } - - @JsonInclude(JsonInclude.Include.NON_NULL) - public static class GroupByKeyDto - { - private String expression; - private NodeLocationDto nodeLocation; - private List exprSources; - - @JsonCreator - public GroupByKeyDto(String expression, NodeLocationDto nodeLocation, List exprSources) - { - this.expression = expression; - this.nodeLocation = nodeLocation; - this.exprSources = exprSources; - } - - @JsonProperty - public String getExpression() - { - return expression; - } - - @JsonProperty - public NodeLocationDto getNodeLocation() - { - return nodeLocation; - } - - @JsonProperty - public List getExprSources() - { - return exprSources; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - GroupByKeyDto that = (GroupByKeyDto) o; - return Objects.equals(expression, that.expression) && - Objects.equals(nodeLocation, that.nodeLocation) - && Objects.equals(exprSources, that.exprSources); - } - - @Override - public int hashCode() - { - return Objects.hash(expression, nodeLocation, exprSources); - } - - @Override - public String toString() - { - return "GroupByKeyDto{" + - "expression='" + expression + '\'' + - ", nodeLocation=" + nodeLocation + - ", exprSources=" + exprSources + - '}'; - } - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/QueryResultDto.java b/wren-main/src/main/java/io/wren/main/web/dto/QueryResultDto.java deleted file mode 100644 index 91dd12176..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/QueryResultDto.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.Column; - -import java.util.List; -import java.util.Objects; - -import static com.google.common.base.MoreObjects.toStringHelper; - -public class QueryResultDto -{ - private final List columns; - private final List data; - - @JsonCreator - public QueryResultDto( - @JsonProperty("columns") List columns, - @JsonProperty("data") List data) - { - this.columns = columns; - this.data = data; - } - - @JsonProperty - public List getColumns() - { - return columns; - } - - @JsonProperty - public List getData() - { - return data; - } - - @Override - public boolean equals(Object o) - { - if (this == o) { - return true; - } - if (o == null || getClass() != o.getClass()) { - return false; - } - QueryResultDto that = (QueryResultDto) o; - return Objects.equals(columns, that.columns) && Objects.equals(data, that.data); - } - - @Override - public int hashCode() - { - return Objects.hash(columns, data); - } - - @Override - public String toString() - { - return toStringHelper(this) - .add("columns", columns) - .add("data", data) - .toString(); - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputBatchDto.java b/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputBatchDto.java deleted file mode 100644 index 41ab8d879..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputBatchDto.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.util.List; - -public class SqlAnalysisInputBatchDto -{ - private final String manifestStr; - private final List sqls; - - @JsonCreator - public SqlAnalysisInputBatchDto(String manifestStr, List sqls) - { - this.manifestStr = manifestStr; - this.sqls = sqls == null ? List.of() : sqls; - } - - @JsonProperty - public String getManifestStr() - { - return manifestStr; - } - - @JsonProperty - public List getSqls() - { - return sqls; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputDto.java b/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputDto.java deleted file mode 100644 index bfe39c57f..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputDto.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.dto.Manifest; - -public class SqlAnalysisInputDto -{ - private final Manifest manifest; - private final String sql; - - @JsonCreator - public SqlAnalysisInputDto( - @JsonProperty("manifest") Manifest manifest, - @JsonProperty("sql") String sql) - { - this.manifest = manifest; - this.sql = sql; - } - - @JsonProperty - public Manifest getManifest() - { - return manifest; - } - - @JsonProperty - public String getSql() - { - return sql; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputDtoV2.java b/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputDtoV2.java deleted file mode 100644 index ea5591e18..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/SqlAnalysisInputDtoV2.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; - -public class SqlAnalysisInputDtoV2 -{ - private final String manifestStr; - private final String sql; - - @JsonCreator - public SqlAnalysisInputDtoV2( - @JsonProperty("manifestStr") String manifestStr, - @JsonProperty("sql") String sql) - { - this.manifestStr = manifestStr; - this.sql = sql; - } - - @JsonProperty - public String getManifestStr() - { - return manifestStr; - } - - @JsonProperty - public String getSql() - { - return sql; - } -} diff --git a/wren-main/src/main/java/io/wren/main/web/dto/ValidateDto.java b/wren-main/src/main/java/io/wren/main/web/dto/ValidateDto.java deleted file mode 100644 index 895baaa49..000000000 --- a/wren-main/src/main/java/io/wren/main/web/dto/ValidateDto.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Licensed 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 io.wren.main.web.dto; - -import com.fasterxml.jackson.annotation.JsonCreator; -import com.fasterxml.jackson.annotation.JsonProperty; -import io.wren.base.dto.Manifest; - -import java.util.Map; - -public class ValidateDto -{ - private final Manifest manifest; - private final Map parameters; - - @JsonCreator - public ValidateDto( - @JsonProperty("manifest") Manifest manifest, - @JsonProperty("parameters") Map parameters) - { - this.manifest = manifest; - this.parameters = parameters; - } - - @JsonProperty - public Manifest getManifest() - { - return manifest; - } - - @JsonProperty - public Map getParameters() - { - return parameters; - } -} diff --git a/wren-server/pom.xml b/wren-server/pom.xml deleted file mode 100644 index d7f19e1fa..000000000 --- a/wren-server/pom.xml +++ /dev/null @@ -1,118 +0,0 @@ - - - 4.0.0 - - - io.wren - wren-root - 0.15.2-SNAPSHOT - ../pom.xml - - - wren-server - wren-server - WrenEngine - Server - - - ${project.parent.basedir} - io.wren.server.WrenServer - - - - - - com.google.guava - guava - - - - com.google.inject - guice - - - io.airlift - configuration - - - - io.airlift - event - - - - io.airlift - http-server - - - - io.airlift - jaxrs - - - - io.airlift - json - - - - io.airlift - node - - - - io.wren - wren-base - - - - io.wren - wren-main - - - - - - exec-jar - - - - org.apache.maven.plugins - maven-shade-plugin - - - - shade - - package - - false - true - executable - - - - *:* - - META-INF/*.SF - META-INF/*.DSA - META-INF/*.RSA - META-INF/MANIFEST.MF - - - - - - - ${main-class} - - - - - - - - - - - - diff --git a/wren-server/src/main/java/io/wren/server/WrenServer.java b/wren-server/src/main/java/io/wren/server/WrenServer.java deleted file mode 100644 index cad29bb94..000000000 --- a/wren-server/src/main/java/io/wren/server/WrenServer.java +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Licensed 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 io.wren.server; - -import com.google.common.collect.ImmutableList; -import com.google.inject.Injector; -import com.google.inject.Module; -import io.airlift.event.client.EventModule; -import io.airlift.http.server.HttpServerModule; -import io.airlift.jaxrs.JaxrsModule; -import io.airlift.json.JsonModule; -import io.airlift.node.NodeModule; -import io.wren.main.PreviewService; -import io.wren.main.WrenModule; -import io.wren.main.server.Server; -import io.wren.server.module.DuckDBConnectorModule; -import io.wren.server.module.MainModule; -import io.wren.server.module.WebModule; - -public class WrenServer - extends Server -{ - public static void main(String[] args) - { - new WrenServer().start(); - } - - @Override - protected Iterable getAdditionalModules() - { - return ImmutableList.of( - new NodeModule(), - new HttpServerModule(), - new JsonModule(), - new JaxrsModule(), - new EventModule(), - new MainModule(), - new DuckDBConnectorModule(), - new WrenModule(), - new WebModule()); - } - - @Override - protected void configure(Injector injector) - { - warmUp(injector); - } - - private void warmUp(Injector injector) - { - injector.getInstance(PreviewService.class).warmUp(); - } -} diff --git a/wren-server/src/main/java/io/wren/server/module/DuckDBConnectorModule.java b/wren-server/src/main/java/io/wren/server/module/DuckDBConnectorModule.java deleted file mode 100644 index 78af41088..000000000 --- a/wren-server/src/main/java/io/wren/server/module/DuckDBConnectorModule.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Licensed 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 io.wren.server.module; - -import com.google.inject.Binder; -import com.google.inject.Scopes; -import io.airlift.configuration.AbstractConfigurationAwareModule; -import io.wren.base.client.duckdb.DuckDBConfig; -import io.wren.base.client.duckdb.DuckDBConnectorConfig; -import io.wren.main.connector.duckdb.DuckDBMetadata; -import io.wren.main.connector.duckdb.DuckDBSqlConverter; - -import static io.airlift.configuration.ConfigBinder.configBinder; - -public class DuckDBConnectorModule - extends AbstractConfigurationAwareModule -{ - @Override - protected void setup(Binder binder) - { - configBinder(binder).bindConfig(DuckDBConnectorConfig.class); - configBinder(binder).bindConfig(DuckDBConfig.class); - binder.bind(DuckDBSqlConverter.class).in(Scopes.SINGLETON); - binder.bind(DuckDBMetadata.class).in(Scopes.SINGLETON); - } -} diff --git a/wren-server/src/main/java/io/wren/server/module/MainModule.java b/wren-server/src/main/java/io/wren/server/module/MainModule.java deleted file mode 100644 index 986c076ed..000000000 --- a/wren-server/src/main/java/io/wren/server/module/MainModule.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Licensed 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 io.wren.server.module; - -import com.google.inject.Binder; -import com.google.inject.Scopes; -import io.airlift.configuration.AbstractConfigurationAwareModule; -import io.wren.base.config.BigQueryConfig; -import io.wren.base.config.ConfigManager; -import io.wren.base.config.DuckdbS3StyleStorageConfig; -import io.wren.base.config.PostgresConfig; -import io.wren.base.config.PostgresWireProtocolConfig; -import io.wren.base.config.SQLGlotConfig; -import io.wren.base.config.SnowflakeConfig; -import io.wren.base.sql.SqlConverter; -import io.wren.main.metadata.Metadata; -import io.wren.main.metadata.MetadataManager; -import io.wren.main.sql.SqlConverterManager; - -import static io.airlift.configuration.ConfigBinder.configBinder; - -public class MainModule - extends AbstractConfigurationAwareModule - -{ - @Override - protected void setup(Binder binder) - { - // backwards compatibility - configBinder(binder).bindConfig(BigQueryConfig.class); - configBinder(binder).bindConfig(PostgresConfig.class); - configBinder(binder).bindConfig(DuckdbS3StyleStorageConfig.class); - configBinder(binder).bindConfig(PostgresWireProtocolConfig.class); - configBinder(binder).bindConfig(SnowflakeConfig.class); - configBinder(binder).bindConfig(SQLGlotConfig.class); - - binder.bind(Metadata.class).to(MetadataManager.class).in(Scopes.SINGLETON); - binder.bind(SqlConverter.class).to(SqlConverterManager.class).in(Scopes.SINGLETON); - binder.bind(ConfigManager.class).in(Scopes.SINGLETON); - } -} diff --git a/wren-server/src/main/java/io/wren/server/module/WebModule.java b/wren-server/src/main/java/io/wren/server/module/WebModule.java deleted file mode 100644 index 9de6bf2a2..000000000 --- a/wren-server/src/main/java/io/wren/server/module/WebModule.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Licensed 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 io.wren.server.module; - -import com.google.inject.Binder; -import com.google.inject.Scopes; -import io.airlift.configuration.AbstractConfigurationAwareModule; -import io.wren.main.PreviewService; -import io.wren.main.ValidationService; -import io.wren.main.web.AnalysisResource; -import io.wren.main.web.AnalysisResourceV2; -import io.wren.main.web.ConfigResource; -import io.wren.main.web.DuckDBResource; -import io.wren.main.web.MDLResource; -import io.wren.main.web.MDLResourceV2; -import io.wren.main.web.SystemResource; -import io.wren.main.web.WrenExceptionMapper; - -import static io.airlift.jaxrs.JaxrsBinder.jaxrsBinder; - -public class WebModule - extends AbstractConfigurationAwareModule -{ - @Override - protected void setup(Binder binder) - { - jaxrsBinder(binder).bind(MDLResource.class); - jaxrsBinder(binder).bind(MDLResourceV2.class); - jaxrsBinder(binder).bind(AnalysisResource.class); - jaxrsBinder(binder).bind(AnalysisResourceV2.class); - jaxrsBinder(binder).bind(ConfigResource.class); - jaxrsBinder(binder).bind(DuckDBResource.class); - jaxrsBinder(binder).bind(SystemResource.class); - jaxrsBinder(binder).bindInstance(new WrenExceptionMapper()); - binder.bind(PreviewService.class).in(Scopes.SINGLETON); - binder.bind(ValidationService.class).in(Scopes.SINGLETON); - } -} diff --git a/wren-tests/pom.xml b/wren-tests/pom.xml deleted file mode 100644 index e71a4184d..000000000 --- a/wren-tests/pom.xml +++ /dev/null @@ -1,180 +0,0 @@ - - - - 4.0.0 - - - io.wren - wren-root - 0.15.2-SNAPSHOT - ../pom.xml - - - wren-tests - wren-tests - WrenEngine - Tests - - ${project.parent.basedir} - - - - - com.google.inject - guice - - - - io.airlift - bootstrap - - - - io.airlift - event - - - - io.airlift - http-client - - - - io.airlift - http-server - - - - io.airlift - jaxrs - - - - io.airlift - json - - - - io.airlift - node - - - - io.airlift - units - - - - io.wren - trino-parser - - - - io.wren - wren-base - - - - io.wren - wren-main - - - - io.wren - wren-server - - - - jakarta.ws.rs - jakarta.ws.rs-api - - - - org.assertj - assertj-core - - - - org.jetbrains - annotations - - - - com.google.guava - guava - provided - - - - org.duckdb - duckdb_jdbc - provided - - - - org.junit.jupiter - junit-jupiter-engine - test - - - - org.testcontainers - postgresql - test - - - - org.testng - testng - test - - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 3.8.1 - - ${air.check.skip-dependency} - ${air.check.fail-dependency} - true - - true - - - - org.ow2.asm - asm - ${dep.asm.version} - - - - - default - - analyze-only - analyze-duplicate - - process-test-classes - - - - - - - - diff --git a/wren-tests/src/main/java/io/wren/testing/TestingWrenServer.java b/wren-tests/src/main/java/io/wren/testing/TestingWrenServer.java deleted file mode 100644 index eeeb9072d..000000000 --- a/wren-tests/src/main/java/io/wren/testing/TestingWrenServer.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import com.google.common.collect.ImmutableList; -import com.google.common.io.Closer; -import com.google.inject.Injector; -import com.google.inject.Key; -import com.google.inject.Module; -import io.airlift.bootstrap.Bootstrap; -import io.airlift.bootstrap.LifeCycleManager; -import io.airlift.event.client.EventModule; -import io.airlift.http.server.testing.TestingHttpServer; -import io.airlift.http.server.testing.TestingHttpServerModule; -import io.airlift.jaxrs.JaxrsModule; -import io.airlift.json.JsonModule; -import io.airlift.node.NodeModule; -import io.wren.main.WrenModule; -import io.wren.main.connector.duckdb.DuckDBMetadata; -import io.wren.server.module.DuckDBConnectorModule; -import io.wren.server.module.MainModule; -import io.wren.server.module.WebModule; - -import java.io.Closeable; -import java.io.IOException; -import java.net.ServerSocket; -import java.net.URI; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; - -public class TestingWrenServer - implements Closeable -{ - private static final String HTTP_SERVER_PORT = "http-server.http.port"; - private static final String NODE_ENVIRONMENT = "node.environment"; - private final Injector injector; - private final Closer closer = Closer.create(); - - public static Builder builder() - { - return new Builder(); - } - - private TestingWrenServer(Map requiredConfigs) - throws IOException - { - Map requiredConfigProps = new HashMap<>(); - requiredConfigProps.put(HTTP_SERVER_PORT, String.valueOf(randomPort())); - requiredConfigProps.put(NODE_ENVIRONMENT, "test"); - - requiredConfigProps.putAll(requiredConfigs); - - Bootstrap app = new Bootstrap(ImmutableList.of( - new TestingHttpServerModule(), - new NodeModule(), - new JsonModule(), - new JaxrsModule(), - new EventModule(), - new MainModule(), - new DuckDBConnectorModule(), - new WrenModule(), - new WebModule())); - - injector = app - .doNotInitializeLogging() - .setRequiredConfigurationProperties(requiredConfigProps) - .quiet() - .initialize(); - - closer.register(() -> injector.getInstance(Key.get(DuckDBMetadata.class)).close()); - closer.register(() -> injector.getInstance(LifeCycleManager.class).stop()); - } - - public URI getHttpServerBasedUrl() - { - return injector.getInstance(TestingHttpServer.class).getBaseUrl(); - } - - public T getInstance(Key key) - { - return injector.getInstance(key); - } - - @Override - public void close() - throws IOException - { - closer.close(); - } - - private static int randomPort() - throws IOException - { - // ServerSocket(0) results in availability of a free random port - try (ServerSocket serverSocket = new ServerSocket(0)) { - return serverSocket.getLocalPort(); - } - } - - public static class Builder - { - private Map configs = new HashMap<>(); - - public Builder setRequireConfig(String key, String value) - { - this.configs.put(key, value); - return this; - } - - public Builder setRequiredConfigs(Map configs) - { - this.configs = configs; - return this; - } - - public TestingWrenServer build() - { - try { - Path config = Files.createTempDirectory("config").resolve("config.properties"); - System.setProperty("config", config.toString()); - Properties properties = new Properties(); - properties.putAll(configs); - properties.store(Files.newBufferedWriter(config), "TestingWrenServer"); - return new TestingWrenServer(configs); - } - catch (IOException ex) { - throw new RuntimeException(ex); - } - } - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/AbstractFunctionTest.java b/wren-tests/src/test/java/io/wren/testing/AbstractFunctionTest.java deleted file mode 100644 index 1a29469be..000000000 --- a/wren-tests/src/test/java/io/wren/testing/AbstractFunctionTest.java +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import io.wren.base.dto.Manifest; -import io.wren.main.web.dto.PreviewDto; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import static org.assertj.core.api.Assertions.assertThatNoException; - -/** - * Test for the list of Trino functions - */ - -public abstract class AbstractFunctionTest - extends RequireWrenServer -{ - @DataProvider - public Object[][] dateTimeFunction() - { - return new Object[][] { - {"SELECT current_date"}, - // {"SELECT current_time",}, - {"SELECT current_timestamp"}, - // {"SELECT localtime",}, - // {"SELECT localtimestamp"}, - // {"SELECT current_timezone"}, - // {"SELECT date('2020-05-01')"}, - // {"SELECT date_add('second', 86, TIMESTAMP '2020-03-01 00:00:00')"}, - // {"SELECT date_diff('second', TIMESTAMP '2020-03-01 00:00:00', TIMESTAMP '2020-03-02 00:00:00')"}, - // {"SELECT date_format(TIMESTAMP '2022-10-20 05:10:00', '%m-%d-%Y %H')"}, - // {"SELECT date_parse('2022/10/20/05', '%Y/%m/%d/%H')"}, - {"SELECT date_trunc('MONTH' , DATE '2022-10-20')"}, - {"SELECT date_trunc('DAY' , TIMESTAMP '2022-10-20 00:00:00')"}, - // {"SELECT from_iso8601_date('2020-05-11')"}, - // {"SELECT from_iso8601_timestamp('2020-05-11')"}, - // {"SELECT from_unixtime_nanos(100)"}, - // {"SELECT from_unixtime(123456)"}, - // {"SELECT from_unixtime(123456, 'UTC')"}, - // {"SELECT now()"}, - // {"SELECT to_iso8601(TIMESTAMP '2022-11-01 09:08:07.321')"}, - // {"SELECT to_milliseconds(INTERVAL '1' month)"}, - // {"SELECT to_unixtime(TIMESTAMP '2022-11-01 09:08:07.321')"}, - }; - } - - @Test(dataProvider = "dateTimeFunction") - public void testDateTimeFunction(String sql) - { - assertThatNoException().isThrownBy(() -> execute(sql)); - } - - @DataProvider - public Object[][] aggregationFunction() - { - return new Object[][] { - // {"select any_value(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select approx_distinct(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select approx_most_frequent(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select approx_percentile(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select arbitrary(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - {"select array_agg(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - {"select avg(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select bitwise_and_agg(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select bitwise_or_agg(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select bool_and(c1) from (values (true, false), (true, true)) t(c1, c2)"}, - {"select bool_or(c1) from (values (true, false), (true, true)) t(c1, c2)"}, - // {"select checksum(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select corr(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - {"select count(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select count_if(c1 > 1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select count_if(c1 > 1) filter (where c1 > 1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select covar_pop(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select covar_samp(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select every(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select geometric_mean(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select histogram(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select kurtosis(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // map_agg - // map_union - {"select max(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select max_by(c1, c2) from (values (1,2), (2,3)) t(c1, c2)"}, - {"select min(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - // {"select min_by(c1, c2) from (values (1,2), (2,3)) t(c1, c2)"}, - {"select sum(c1) from (values (1,2), (2,3)) t(c1, c2)"}, - }; - } - - @Test(dataProvider = "aggregationFunction") - public void testAggregationFunction(String sql) - { - assertThatNoException().isThrownBy(() -> execute(sql)); - } - - @DataProvider - public Object[][] mathFunction() - { - return new Object[][] { - {"select greatest(1, 2)"}, - {"select least(1, 2)"}, - {"select abs(-1)"}, - {"select acos(0.5)"}, - {"select asin(0.5)"}, - {"select atan(0.5)"}, - {"select atan2(0.5, 0.5)"}, - // {"select beta_cdf(1, 5, 1)"}, - {"select cbrt(8)"}, - {"select ceil(1.5)"}, - {"select cos(0.5)"}, - // {"select cosh(0.5)"}, - // {"SELECT cosine_similarity(MAP(ARRAY['a'], ARRAY[1.0]), MAP(ARRAY['a'], ARRAY[2.0]))"}, - // {"select degrees(0.5)"}, - // {"select e()"}, - {"select exp(0.5)"}, - {"select floor(1.5)"}, - // {"select from_base('123', 10)"}, - // {"select infinity()"}, - // inverse_veta_cdf - // inverse_normal_cdf - // {"select is_finite(1)"}, - // {"select is_nan(1)"}, - {"select ln(0.5)"}, - {"select log(2, 8)"}, - // {"select log10(100)"}, - {"select mod(5, 2)"}, - // {"select nan()"}, - // normal_cdf - // {"select pi()"}, - {"select power(2, 3)"}, - // {"select radians(0.5)"}, - {"select round(1.5)"}, - {"select sign(-1)"}, - {"select sin(0.5)"}, - // {"select sinh(0.5)"}, - {"select sqrt(4)"}, - {"select tan(0.5)"}, - // {"select tanh(0.5)"}, - // {"select to_base(123, 10)"}, - // {"select truncate(1.5)"}, - // {"select width_bucket(1.5, 1, 2, 3)"}, - // {"select wilson_interval_lower(1, 2, 1)"}, - // {"select wilson_interval_upper(1, 2, 1)"}, - }; - } - - @Test(dataProvider = "mathFunction") - public void testMathFunction(String sql) - { - assertThatNoException().isThrownBy(() -> execute(sql)); - } - - @DataProvider - public Object[][] stringFunction() - { - return new Object[][] { - {"select chr(1)"}, - // {"select codepoint('123')"}, - {"select concat('123', 'abc')"}, - // {"select concat_ws(',', '123', 'abc')"}, - {"select format('%s %s', '123', 'abc')"}, - // {"select from_utf8('MTIz')"}, - // {"select hamming_distance('123', 'abc')"}, - {"select length('MTIz')"}, - // {"select levenshtein_distance('123,'abc')"}, - {"select lower('MTIz')"}, - {"select length('MTIz')"}, - {"select lpad('MTIz', 5, ' ')"}, - {"select ltrim('MTIz')"}, - // {"select luhn_check('79927398713')"}, - // {"select normalize('79927398713')"}, - {"select position('123' in '123456')"}, - // {"select replace('1', '123')"}, - {"select replace('1', '123', '2')"}, - {"select reverse('MTIz')"}, - {"select rpad('MTIz', 5, ' ')"}, - {"select rtrim('MTIz')"}, - // {"select soundex('abc')"}, - // {"select split('abc', 'b')"}, - // {"select split_part('abc', 'b', 1)"}, - // split_to_multimap - {"select strpos('abc', 'b')"}, - {"select substr('abc', 1, 2)"}, - {"select substring('abc', 1, 2)"}, - // {"select to_utf8('MTIz')"}, - {"select translate('abc', 'b', 'd')"}, - {"select trim('abc')"}, - {"select upper('abc')"}, - // {"select split_to_multimap('abc')"}, - }; - } - - @Test(dataProvider = "stringFunction") - public void testStringFunction(String sql) - { - assertThatNoException().isThrownBy(() -> execute(sql)); - } - - @DataProvider - public Object[][] operators() - { - return new Object[][] { - {"select 1 + 1"}, - {"select 1 - 1"}, - {"select 2 * 2"}, - {"select 4 / 2"}, - // {"select 11 % 10"}, - // {"select a1[1] from (values (array[1,2,3])) t(a1)"}, - // {"select a1 || a1 from (values (array[1,2,3])) t(a1)"}, - {"select '123' || '456'"}, - {"select 2 < 2"}, - {"select 2 > 2"}, - {"select 2 >= 2"}, - {"select 2 <= 2"}, - {"select 2 = 2"}, - {"select 2 <> 2"}, - {"select 2 != 2"}, - }; - } - - @Test(dataProvider = "operators") - public void testOperators(String sql) - { - assertThatNoException().isThrownBy(() -> execute(sql)); - } - - protected void execute(String sql) - { - preview(new PreviewDto(Manifest.builder().setCatalog("wrenai").setSchema("public").build(), sql, 100L)); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/AbstractSqlConverterTest.java b/wren-tests/src/test/java/io/wren/testing/AbstractSqlConverterTest.java deleted file mode 100644 index 12d54a46e..000000000 --- a/wren-tests/src/test/java/io/wren/testing/AbstractSqlConverterTest.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import java.nio.file.Files; -import java.nio.file.Path; - -public abstract class AbstractSqlConverterTest -{ - protected void prepareConfig() - throws Exception - { - Path config = Files.createTempDirectory("mock").resolve("config.properties"); - Files.writeString(config, "node.environment=test"); - System.setProperty("config", config.toString()); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/AbstractTestFramework.java b/wren-tests/src/test/java/io/wren/testing/AbstractTestFramework.java deleted file mode 100644 index 7e0cf9ac6..000000000 --- a/wren-tests/src/test/java/io/wren/testing/AbstractTestFramework.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Licensed 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. - */ - -/* - * Licensed 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 io.wren.testing; - -import io.wren.base.SessionContext; -import io.wren.base.dto.Manifest; -import io.wren.main.web.dto.PreviewDto; -import io.wren.main.web.dto.QueryResultDto; -import org.intellij.lang.annotations.Language; - -public abstract class AbstractTestFramework - extends RequireWrenServer -{ - public static final SessionContext DEFAULT_SESSION_CONTEXT = - SessionContext.builder().setCatalog("wren").setSchema("test").build(); - - public static Manifest.Builder withDefaultCatalogSchema() - { - return Manifest.builder() - .setCatalog(DEFAULT_SESSION_CONTEXT.getCatalog().orElseThrow()) - .setSchema(DEFAULT_SESSION_CONTEXT.getSchema().orElseThrow()); - } - - @Override - protected void prepare() - { - initDuckDB(); - } - - protected QueryResultDto query(Manifest manifest, @Language("SQL") String sql) - { - PreviewDto previewDto = new PreviewDto(manifest, sql, 100L); - return preview(previewDto); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/RequireWrenServer.java b/wren-tests/src/test/java/io/wren/testing/RequireWrenServer.java deleted file mode 100644 index c65208b5f..000000000 --- a/wren-tests/src/test/java/io/wren/testing/RequireWrenServer.java +++ /dev/null @@ -1,420 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import com.google.common.io.Closer; -import com.google.common.io.Resources; -import com.google.inject.Key; -import io.airlift.http.client.HttpClient; -import io.airlift.http.client.HttpClientConfig; -import io.airlift.http.client.Request; -import io.airlift.http.client.ResponseHandler; -import io.airlift.http.client.StringResponseHandler; -import io.airlift.http.client.jetty.JettyHttpClient; -import io.airlift.json.JsonCodec; -import io.airlift.units.Duration; -import io.wren.base.config.ConfigManager; -import io.wren.base.dto.Column; -import io.wren.base.dto.Manifest; -import io.wren.main.connector.duckdb.DuckDBMetadata; -import io.wren.main.validation.ValidationResult; -import io.wren.main.web.dto.DryPlanDto; -import io.wren.main.web.dto.DryPlanDtoV2; -import io.wren.main.web.dto.ErrorMessageDto; -import io.wren.main.web.dto.PreviewDto; -import io.wren.main.web.dto.QueryAnalysisDto; -import io.wren.main.web.dto.QueryResultDto; -import io.wren.main.web.dto.SqlAnalysisInputBatchDto; -import io.wren.main.web.dto.SqlAnalysisInputDto; -import io.wren.main.web.dto.ValidateDto; -import jakarta.ws.rs.WebApplicationException; -import jakarta.ws.rs.core.MediaType; -import jakarta.ws.rs.core.Response; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; - -import java.io.IOException; -import java.util.List; - -import static com.google.common.net.HttpHeaders.CONTENT_TYPE; -import static io.airlift.http.client.JsonBodyGenerator.jsonBodyGenerator; -import static io.airlift.http.client.Request.Builder.prepareDelete; -import static io.airlift.http.client.Request.Builder.prepareGet; -import static io.airlift.http.client.Request.Builder.preparePatch; -import static io.airlift.http.client.Request.Builder.preparePost; -import static io.airlift.http.client.Request.Builder.preparePut; -import static io.airlift.http.client.StaticBodyGenerator.createStaticBodyGenerator; -import static io.airlift.http.client.StringResponseHandler.createStringResponseHandler; -import static io.airlift.json.JsonCodec.jsonCodec; -import static io.airlift.json.JsonCodec.listJsonCodec; -import static java.lang.String.format; -import static java.nio.charset.StandardCharsets.UTF_8; -import static java.util.Objects.requireNonNull; -import static java.util.concurrent.TimeUnit.SECONDS; - -public abstract class RequireWrenServer -{ - protected TestingWrenServer wrenServer; - protected Closer closer = Closer.create(); - protected HttpClient client; - - private static final JsonCodec ERROR_CODEC = jsonCodec(ErrorMessageDto.class); - public static final JsonCodec MANIFEST_JSON_CODEC = jsonCodec(Manifest.class); - private static final JsonCodec PREVIEW_DTO_CODEC = jsonCodec(PreviewDto.class); - private static final JsonCodec SQL_ANALYSIS_INPUT_DTO_CODEC = jsonCodec(SqlAnalysisInputDto.class); - private static final JsonCodec CONFIG_ENTRY_JSON_CODEC = jsonCodec(ConfigManager.ConfigEntry.class); - private static final JsonCodec> CONFIG_ENTRY_LIST_CODEC = listJsonCodec(ConfigManager.ConfigEntry.class); - private static final JsonCodec QUERY_RESULT_DTO_CODEC = jsonCodec(QueryResultDto.class); - private static final JsonCodec> COLUMN_LIST_CODEC = listJsonCodec(Column.class); - private static final JsonCodec DRY_PLAN_DTO_CODEC = jsonCodec(DryPlanDto.class); - private static final JsonCodec DRY_PLAN_DTO_V2_CODEC = jsonCodec(DryPlanDtoV2.class); - private static final JsonCodec> VALIDATION_RESULT_LIST_CODEC = listJsonCodec(ValidationResult.class); - private static final JsonCodec VALIDATE_DTO_CODEC = jsonCodec(ValidateDto.class); - private static final JsonCodec> QUERY_ANALYSIS_DTO_LIST_CODEC = listJsonCodec(QueryAnalysisDto.class); - private static final JsonCodec SQL_ANALYSIS_INPUT_BATCH_DTO_CODEC = jsonCodec(SqlAnalysisInputBatchDto.class); - private static final JsonCodec>> QUERY_ANALYSIS_DTO_LIST_LIST_CODEC = listJsonCodec(listJsonCodec(QueryAnalysisDto.class)); - - public RequireWrenServer() {} - - @BeforeClass - public void init() - throws Exception - { - this.wrenServer = createWrenServer(); - this.client = closer.register(createHttpClient()); - closer.register(wrenServer); - prepare(); - } - - protected static JettyHttpClient createHttpClient() - { - return new JettyHttpClient(new HttpClientConfig().setIdleTimeout(new Duration(20, SECONDS))); - } - - protected abstract TestingWrenServer createWrenServer() - throws Exception; - - protected void initDuckDB() - { - ClassLoader classLoader = getClass().getClassLoader(); - String initSQL; - try { - initSQL = Resources.toString(requireNonNull(classLoader.getResource("duckdb/init.sql")).toURI().toURL(), UTF_8); - } - catch (Exception e) { - throw new RuntimeException(e); - } - initSQL = initSQL.replaceAll("basePath", requireNonNull(classLoader.getResource("tpch/data")).getPath()); - DuckDBMetadata metadata = wrenServer.getInstance(Key.get(DuckDBMetadata.class)); - metadata.setInitSQL(initSQL); - metadata.reload(); - } - - protected TestingWrenServer server() - { - return wrenServer; - } - - protected void prepare() {} - - public T getInstance(Key key) - { - return wrenServer.getInstance(key); - } - - @AfterClass(alwaysRun = true) - public void close() - throws IOException - { - cleanup(); - closer.close(); - } - - protected void cleanup() {} - - public T executeHttpRequest(Request request, ResponseHandler responseHandler) - throws E - { - return client.execute(request, responseHandler); - } - - protected QueryResultDto preview(PreviewDto previewDto) - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/mdl/preview")) - .setHeader(CONTENT_TYPE, "application/json") - .setBodyGenerator(jsonBodyGenerator(PREVIEW_DTO_CODEC, previewDto)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return QUERY_RESULT_DTO_CODEC.fromJson(response.getBody()); - } - - protected List dryRun(PreviewDto previewDto) - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/mdl/dry-run")) - .setHeader(CONTENT_TYPE, "application/json") - .setBodyGenerator(jsonBodyGenerator(PREVIEW_DTO_CODEC, previewDto)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return COLUMN_LIST_CODEC.fromJson(response.getBody()); - } - - protected String dryPlan(DryPlanDto dryPlanDto) - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/mdl/dry-plan")) - .setHeader(CONTENT_TYPE, "application/json") - .setBodyGenerator(jsonBodyGenerator(DRY_PLAN_DTO_CODEC, dryPlanDto)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return response.getBody(); - } - - protected String dryPlanV2(DryPlanDtoV2 dryPlanDto) - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v2/mdl/dry-plan")) - .setHeader(CONTENT_TYPE, "application/json") - .setBodyGenerator(jsonBodyGenerator(DRY_PLAN_DTO_V2_CODEC, dryPlanDto)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return response.getBody(); - } - - protected List getSqlAnalysis(SqlAnalysisInputDto inputDto) - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/analysis/sql")) - .setHeader(CONTENT_TYPE, "application/json") - .setBodyGenerator(jsonBodyGenerator(SQL_ANALYSIS_INPUT_DTO_CODEC, inputDto)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return QUERY_ANALYSIS_DTO_LIST_CODEC.fromJson(response.getBody()); - } - - protected List> getSqlAnalysisBatch(SqlAnalysisInputBatchDto inputBatchDto) - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v2/analysis/sqls")) - .setHeader(CONTENT_TYPE, "application/json") - .setBodyGenerator(jsonBodyGenerator(SQL_ANALYSIS_INPUT_BATCH_DTO_CODEC, inputBatchDto)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return QUERY_ANALYSIS_DTO_LIST_LIST_CODEC.fromJson(response.getBody()); - } - - protected List getConfigs() - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/config")) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return CONFIG_ENTRY_LIST_CODEC.fromJson(response.getBody()); - } - - protected ConfigManager.ConfigEntry getConfig(String configName) - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve(format("/v1/config/%s", configName))) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return CONFIG_ENTRY_JSON_CODEC.fromJson(response.getBody()); - } - - protected void resetConfig() - { - Request request = prepareDelete() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/config")) - .setHeader(CONTENT_TYPE, "application/json") - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - } - - protected void patchConfig(List configEntries) - { - Request request = preparePatch() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/config")) - .setHeader(CONTENT_TYPE, "application/json") - .setBodyGenerator(jsonBodyGenerator(CONFIG_ENTRY_LIST_CODEC, configEntries)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - } - - protected QueryResultDto queryDuckDB(String statement) - { - Request request = preparePost() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/data-source/duckdb/query")) - .setBodyGenerator(createStaticBodyGenerator(statement, UTF_8)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return QUERY_RESULT_DTO_CODEC.fromJson(response.getBody()); - } - - protected String getDuckDBInitSQL() - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/data-source/duckdb/settings/init-sql")) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return response.getBody(); - } - - protected void setDuckDBInitSQL(String statement) - { - Request request = preparePut() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/data-source/duckdb/settings/init-sql")) - .setBodyGenerator(createStaticBodyGenerator(statement, UTF_8)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - } - - protected void appendToDuckDBInitSQL(String statement) - { - Request request = preparePatch() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/data-source/duckdb/settings/init-sql")) - .setBodyGenerator(createStaticBodyGenerator(statement, UTF_8)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - } - - protected String getDuckDBSessionSQL() - { - Request request = prepareGet() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/data-source/duckdb/settings/session-sql")) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return response.getBody(); - } - - protected void setDuckDBSessionSQL(String statement) - { - Request request = preparePut() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/data-source/duckdb/settings/session-sql")) - .setBodyGenerator(createStaticBodyGenerator(statement, UTF_8)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - } - - protected void appendToDuckDBSessionSQL(String statement) - { - Request request = preparePatch() - .setUri(server().getHttpServerBasedUrl().resolve("/v1/data-source/duckdb/settings/session-sql")) - .setBodyGenerator(createStaticBodyGenerator(statement, UTF_8)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - } - - protected List validate(String ruleName, ValidateDto validateDto) - { - Request request = preparePost() - .setUri(server().getHttpServerBasedUrl().resolve(format("/v1/mdl/validate/%s", ruleName))) - .setHeader(CONTENT_TYPE, "application/json") - .setBodyGenerator(jsonBodyGenerator(VALIDATE_DTO_CODEC, validateDto)) - .build(); - - StringResponseHandler.StringResponse response = executeHttpRequest(request, createStringResponseHandler()); - if (response.getStatusCode() != 200) { - getWebApplicationException(response); - } - return VALIDATION_RESULT_LIST_CODEC.fromJson(response.getBody()); - } - - public static void getWebApplicationException(StringResponseHandler.StringResponse response) - { - String body = response.getBody(); - ErrorMessageDto errorMessageDto; - try { - errorMessageDto = ERROR_CODEC.fromJson(body); - } - catch (IllegalArgumentException e) { - throw new IllegalArgumentException(format("Illegal response body '%s' with status code %d", body, response.getStatusCode()), e); - } - - throw new WebApplicationException( - Response.status(response.getStatusCode()) - .type(MediaType.APPLICATION_JSON_TYPE) - .entity(errorMessageDto) - .build()); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/TestAnalysisResource.java b/wren-tests/src/test/java/io/wren/testing/TestAnalysisResource.java deleted file mode 100644 index c6c880a85..000000000 --- a/wren-tests/src/test/java/io/wren/testing/TestAnalysisResource.java +++ /dev/null @@ -1,233 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import com.google.common.collect.ImmutableMap; -import io.trino.sql.tree.SortItem; -import io.wren.base.WrenTypes; -import io.wren.base.dto.Column; -import io.wren.base.dto.Manifest; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.FilterAnalysis; -import io.wren.base.sqlrewrite.analyzer.decisionpoint.RelationAnalysis; -import io.wren.main.web.dto.QueryAnalysisDto; -import io.wren.main.web.dto.SqlAnalysisInputBatchDto; -import io.wren.main.web.dto.SqlAnalysisInputDto; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Base64; -import java.util.List; -import java.util.Set; - -import static io.wren.base.dto.Model.onTableReference; -import static io.wren.base.dto.TableReference.tableReference; -import static io.wren.main.web.dto.NodeLocationDto.nodeLocationDto; -import static io.wren.testing.AbstractTestFramework.DEFAULT_SESSION_CONTEXT; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; - -public class TestAnalysisResource - extends RequireWrenServer -{ - private Manifest manifest; - - @Override - protected TestingWrenServer createWrenServer() - { - initData(); - - Path mdlDir; - try { - mdlDir = Files.createTempDirectory("wrenmdls"); - Path wrenMDLFilePath = mdlDir.resolve("wrenmdl.json"); - Files.write(wrenMDLFilePath, MANIFEST_JSON_CODEC.toJsonBytes(manifest)); - } - catch (IOException ex) { - throw new RuntimeException(ex); - } - - ImmutableMap.Builder properties = ImmutableMap.builder() - .put("wren.directory", mdlDir.toAbsolutePath().toString()) - .put("wren.datasource.type", "duckdb"); - - return TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - } - - private void initData() - { - List customerColumns = List.of( - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("name", WrenTypes.VARCHAR, null, true), - Column.column("address", WrenTypes.VARCHAR, null, true), - Column.column("nationkey", WrenTypes.INTEGER, null, true), - Column.column("phone", WrenTypes.VARCHAR, null, true), - Column.column("acctbal", WrenTypes.INTEGER, null, true), - Column.column("mktsegment", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true)); - List ordersColumns = List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("custkey", WrenTypes.INTEGER, null, true), - Column.column("orderstatus", WrenTypes.VARCHAR, null, true), - Column.column("totalprice", WrenTypes.INTEGER, null, true), - Column.column("orderdate", WrenTypes.DATE, null, true), - Column.column("orderpriority", WrenTypes.VARCHAR, null, true), - Column.column("clerk", WrenTypes.VARCHAR, null, true), - Column.column("shippriority", WrenTypes.INTEGER, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true)); - List lineitemColumns = List.of( - Column.column("orderkey", WrenTypes.INTEGER, null, true), - Column.column("partkey", WrenTypes.INTEGER, null, true), - Column.column("suppkey", WrenTypes.INTEGER, null, true), - Column.column("linenumber", WrenTypes.INTEGER, null, true), - Column.column("quantity", WrenTypes.INTEGER, null, true), - Column.column("extendedprice", WrenTypes.INTEGER, null, true), - Column.column("discount", WrenTypes.INTEGER, null, true), - Column.column("tax", WrenTypes.INTEGER, null, true), - Column.column("returnflag", WrenTypes.VARCHAR, null, true), - Column.column("linestatus", WrenTypes.VARCHAR, null, true), - Column.column("shipdate", WrenTypes.DATE, null, true), - Column.column("commitdate", WrenTypes.DATE, null, true), - Column.column("receiptdate", WrenTypes.DATE, null, true), - Column.column("shipinstruct", WrenTypes.VARCHAR, null, true), - Column.column("shipmode", WrenTypes.VARCHAR, null, true), - Column.column("comment", WrenTypes.VARCHAR, null, true)); - - manifest = Manifest.builder() - .setCatalog(DEFAULT_SESSION_CONTEXT.getCatalog().orElseThrow()) - .setSchema(DEFAULT_SESSION_CONTEXT.getSchema().orElseThrow()) - .setModels(List.of(onTableReference("customer", tableReference(null, "main", "customer"), customerColumns, "custkey"), - onTableReference("orders", tableReference(null, "main", "orders"), ordersColumns, "orderkey"), - onTableReference("lineitem", tableReference(null, "main", "lineitem"), lineitemColumns, null))) - .build(); - } - - @Test - public void testBasic() - { - List result = getSqlAnalysis(new SqlAnalysisInputDto(manifest, "select * from customer")); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.TABLE.name()); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(8); - // all of select item match the star symbol position - assertThat(result.get(0).getSelectItems().get(0).getNodeLocation()).isEqualTo(nodeLocationDto(1, 8)); - assertThat(result.get(0).getSelectItems().get(0).getExprSources()) - .isEqualTo(List.of(new QueryAnalysisDto.ExprSourceDto("custkey", "customer", "custkey", nodeLocationDto(1, 8)))); - assertThat(result.get(0).getSelectItems().get(1).getNodeLocation()).isEqualTo(nodeLocationDto(1, 8)); - assertThat(result.get(0).getRelation().getTableName()).isEqualTo("customer"); - assertThat(result.get(0).getRelation().getNodeLocation()).isEqualTo(nodeLocationDto(1, 15)); - - result = getSqlAnalysis(new SqlAnalysisInputDto(manifest, "select custkey, count(*) from customer group by 1")); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.TABLE.name()); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(2); - assertThat(result.get(0).getSelectItems().get(0).getNodeLocation()).isEqualTo(nodeLocationDto(1, 8)); - assertThat(result.get(0).getSelectItems().get(1).getNodeLocation()).isEqualTo(nodeLocationDto(1, 17)); - assertThat(result.get(0).getRelation().getTableName()).isEqualTo("customer"); - assertThat(result.get(0).getRelation().getNodeLocation()).isEqualTo(nodeLocationDto(1, 31)); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo( - new QueryAnalysisDto.GroupByKeyDto("custkey", - nodeLocationDto(1, 49), - List.of(new QueryAnalysisDto.ExprSourceDto("custkey", "customer", "custkey", nodeLocationDto(1, 8))))); - - result = getSqlAnalysis(new SqlAnalysisInputDto(manifest, "select * from customer c join orders o on c.custkey = o.custkey")); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.INNER_JOIN.name()); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getRelation().getTableName()).isNull(); - assertThat(result.get(0).getRelation().getNodeLocation()).isEqualTo(nodeLocationDto(1, 15)); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(17); - assertThat(result.get(0).getRelation().getLeft().getType()).isEqualTo(RelationAnalysis.Type.TABLE.name()); - assertThat(result.get(0).getRelation().getLeft().getNodeLocation()).isEqualTo(nodeLocationDto(1, 15)); - assertThat(result.get(0).getRelation().getRight().getType()).isEqualTo(RelationAnalysis.Type.TABLE.name()); - assertThat(result.get(0).getRelation().getRight().getNodeLocation()).isEqualTo(nodeLocationDto(1, 31)); - assertThat(result.get(0).getRelation().getCriteria().getExpression()).isEqualTo("ON (c.custkey = o.custkey)"); - assertThat(result.get(0).getRelation().getCriteria().getNodeLocation()).isEqualTo(nodeLocationDto(1, 43)); - assertThat(Set.copyOf(result.get(0).getRelation().getExprSources())) - .isEqualTo(Set.of(new QueryAnalysisDto.ExprSourceDto("c.custkey", "customer", "custkey", nodeLocationDto(1, 43)), - new QueryAnalysisDto.ExprSourceDto("o.custkey", "orders", "custkey", nodeLocationDto(1, 55)))); - - result = getSqlAnalysis(new SqlAnalysisInputDto(manifest, "SELECT * FROM customer WHERE custkey = 1 OR (name = 'test' AND address = 'test')")); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getRelation().getType()).isEqualTo(RelationAnalysis.Type.TABLE.name()); - assertThat(result.get(0).getRelation().getAlias()).isNull(); - assertThat(result.get(0).getSelectItems().size()).isEqualTo(8); - assertThat(result.get(0).getRelation().getTableName()).isEqualTo("customer"); - - assertThat(result.get(0).getFilter().getType()).isEqualTo(FilterAnalysis.Type.OR.name()); - assertThat(result.get(0).getFilter().getLeft().getType()).isEqualTo(FilterAnalysis.Type.EXPR.name()); - assertThat(assertThat(result.get(0).getFilter().getLeft().getExprSources()) - .isEqualTo(List.of(new QueryAnalysisDto.ExprSourceDto("custkey", "customer", "custkey", nodeLocationDto(1, 30))))); - assertThat(result.get(0).getFilter().getRight().getType()).isEqualTo(FilterAnalysis.Type.AND.name()); - - result = getSqlAnalysis(new SqlAnalysisInputDto(manifest, "SELECT custkey, count(*), name FROM customer GROUP BY 1, 3, nationkey")); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getGroupByKeys().size()).isEqualTo(3); - assertThat(result.get(0).getGroupByKeys().get(0).get(0)).isEqualTo(new QueryAnalysisDto.GroupByKeyDto("custkey", - nodeLocationDto(1, 55), - List.of(new QueryAnalysisDto.ExprSourceDto("custkey", "customer", "custkey", nodeLocationDto(1, 8))))); - assertThat(result.get(0).getGroupByKeys().get(1).get(0)).isEqualTo(new QueryAnalysisDto.GroupByKeyDto("name", - nodeLocationDto(1, 58), - List.of(new QueryAnalysisDto.ExprSourceDto("name", "customer", "name", nodeLocationDto(1, 27))))); - assertThat(result.get(0).getGroupByKeys().get(2).get(0)).isEqualTo(new QueryAnalysisDto.GroupByKeyDto("nationkey", - nodeLocationDto(1, 61), - List.of(new QueryAnalysisDto.ExprSourceDto("nationkey", "customer", "nationkey", nodeLocationDto(1, 61))))); - - result = getSqlAnalysis(new SqlAnalysisInputDto(manifest, "SELECT custkey, name FROM customer ORDER BY 1 ASC, 2 DESC")); - assertThat(result.size()).isEqualTo(1); - assertThat(result.get(0).getSortings().size()).isEqualTo(2); - assertThat(result.get(0).getSortings().get(0).getExpression()).isEqualTo("custkey"); - assertThat(result.get(0).getSortings().get(0).getOrdering()).isEqualTo(SortItem.Ordering.ASCENDING.name()); - assertThat(result.get(0).getSortings().get(0).getExprSources()).isEqualTo(List.of(new QueryAnalysisDto.ExprSourceDto("custkey", "customer", "custkey", nodeLocationDto(1, 8)))); - assertThat(result.get(0).getSortings().get(0).getNodeLocation()).isEqualTo(nodeLocationDto(1, 45)); - assertThat(result.get(0).getSortings().get(1).getExpression()).isEqualTo("name"); - assertThat(result.get(0).getSortings().get(1).getOrdering()).isEqualTo(SortItem.Ordering.DESCENDING.name()); - assertThat(result.get(0).getSortings().get(1).getNodeLocation()).isEqualTo(nodeLocationDto(1, 52)); - } - - @Test - public void testBatchAnalysis() - { - SqlAnalysisInputBatchDto inputBatchDto = new SqlAnalysisInputBatchDto( - base64Encode(toJson(manifest)), - List.of("select * from customer", - "select custkey, count(*) from customer group by 1", - "with t1 as (select * from customer) select * from t1", - "select * from orders where orderstatus = 'O' union select * from orders where orderstatus = 'F'")); - - List> results = getSqlAnalysisBatch(inputBatchDto); - assertThat(results.size()).isEqualTo(4); - assertThat(results.get(0).size()).isEqualTo(1); - assertThat(results.get(1).size()).isEqualTo(1); - assertThat(results.get(2).size()).isEqualTo(2); - assertThat(results.get(3).size()).isEqualTo(2); - } - - private String toJson(Manifest manifest) - { - return MANIFEST_JSON_CODEC.toJson(manifest); - } - - private String base64Encode(String str) - { - return Base64.getEncoder().encodeToString(str.getBytes(UTF_8)); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/TestBackwardSupportConfig.java b/wren-tests/src/test/java/io/wren/testing/TestBackwardSupportConfig.java deleted file mode 100644 index ebe619bae..000000000 --- a/wren-tests/src/test/java/io/wren/testing/TestBackwardSupportConfig.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import com.google.common.collect.ImmutableMap; -import io.wren.base.dto.Manifest; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static io.wren.base.config.BigQueryConfig.BIGQUERY_BUCKET_NAME; -import static io.wren.base.config.BigQueryConfig.BIGQUERY_CRENDITALS_FILE; -import static io.wren.base.config.BigQueryConfig.BIGQUERY_CRENDITALS_KEY; -import static io.wren.base.config.BigQueryConfig.BIGQUERY_LOCATION; -import static io.wren.base.config.BigQueryConfig.BIGQUERY_METADATA_SCHEMA_PREFIX; -import static io.wren.base.config.BigQueryConfig.BIGQUERY_PROJECT_ID; -import static io.wren.base.config.ConfigManager.ConfigEntry.configEntry; -import static io.wren.base.config.DuckdbS3StyleStorageConfig.DUCKDB_STORAGE_ACCESS_KEY; -import static io.wren.base.config.DuckdbS3StyleStorageConfig.DUCKDB_STORAGE_ENDPOINT; -import static io.wren.base.config.DuckdbS3StyleStorageConfig.DUCKDB_STORAGE_REGION; -import static io.wren.base.config.DuckdbS3StyleStorageConfig.DUCKDB_STORAGE_SECRET_KEY; -import static io.wren.base.config.DuckdbS3StyleStorageConfig.DUCKDB_STORAGE_URL_STYLE; -import static io.wren.base.config.PostgresConfig.POSTGRES_JDBC_URL; -import static io.wren.base.config.PostgresConfig.POSTGRES_PASSWORD; -import static io.wren.base.config.PostgresConfig.POSTGRES_USER; -import static io.wren.base.config.PostgresWireProtocolConfig.PG_WIRE_PROTOCOL_AUTH_FILE; -import static io.wren.base.config.PostgresWireProtocolConfig.PG_WIRE_PROTOCOL_ENABLED; -import static io.wren.base.config.PostgresWireProtocolConfig.PG_WIRE_PROTOCOL_NETTY_THREAD_COUNT; -import static io.wren.base.config.PostgresWireProtocolConfig.PG_WIRE_PROTOCOL_PORT; -import static io.wren.base.config.PostgresWireProtocolConfig.PG_WIRE_PROTOCOL_SSL_ENABLED; -import static io.wren.base.config.SQLGlotConfig.SQLGLOT_PORT; -import static io.wren.base.config.SnowflakeConfig.SNOWFLAKE_DATABASE; -import static io.wren.base.config.SnowflakeConfig.SNOWFLAKE_JDBC_URL; -import static io.wren.base.config.SnowflakeConfig.SNOWFLAKE_PASSWORD; -import static io.wren.base.config.SnowflakeConfig.SNOWFLAKE_ROLE; -import static io.wren.base.config.SnowflakeConfig.SNOWFLAKE_SCHEMA; -import static io.wren.base.config.SnowflakeConfig.SNOWFLAKE_USER; -import static io.wren.base.config.SnowflakeConfig.SNOWFLAKE_WAREHOUSE; -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static io.wren.base.config.WrenConfig.WREN_DIRECTORY; -import static io.wren.testing.AbstractTestFramework.withDefaultCatalogSchema; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -public class TestBackwardSupportConfig - extends RequireWrenServer -{ - private Path mdlDir; - - @Override - protected TestingWrenServer createWrenServer() - { - Manifest manifest = withDefaultCatalogSchema() - .build(); - - try { - mdlDir = Files.createTempDirectory("wrenmdls"); - Path wrenMDLFilePath = mdlDir.resolve("wrenmdl.json"); - Files.write(wrenMDLFilePath, MANIFEST_JSON_CODEC.toJsonBytes(manifest)); - } - catch (IOException ex) { - throw new RuntimeException(ex); - } - - ImmutableMap.Builder properties = ImmutableMap.builder() - .put(WREN_DIRECTORY, mdlDir.toAbsolutePath().toString()) - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()) - // backward support cases - .put(DUCKDB_STORAGE_ENDPOINT, "http://localhost:9000") - .put(DUCKDB_STORAGE_ACCESS_KEY, "minioadmin") - .put(DUCKDB_STORAGE_SECRET_KEY, "minioadmin") - .put(DUCKDB_STORAGE_REGION, "us-east-1") - .put(DUCKDB_STORAGE_URL_STYLE, "path") - .put(SQLGLOT_PORT, "8000") - .put(BIGQUERY_CRENDITALS_KEY, "http://localhost:9000") - .put(BIGQUERY_CRENDITALS_FILE, "minioadmin") - .put(BIGQUERY_PROJECT_ID, "us-east-1") - .put(BIGQUERY_LOCATION, "path") - .put(BIGQUERY_BUCKET_NAME, "8000") - .put(BIGQUERY_METADATA_SCHEMA_PREFIX, "http://localhost:9000") - .put(POSTGRES_JDBC_URL, "minioadmin") - .put(POSTGRES_USER, "minioadmin") - .put(POSTGRES_PASSWORD, "us-east-1") - .put(PG_WIRE_PROTOCOL_ENABLED, "false") - .put(PG_WIRE_PROTOCOL_SSL_ENABLED, "false") - .put(PG_WIRE_PROTOCOL_NETTY_THREAD_COUNT, "4") - .put(PG_WIRE_PROTOCOL_AUTH_FILE, "minioadmin") - .put(PG_WIRE_PROTOCOL_PORT, "8080") - .put(SNOWFLAKE_JDBC_URL, "minioadmin") - .put(SNOWFLAKE_USER, "minioadmin") - .put(SNOWFLAKE_PASSWORD, "minioadmin") - .put(SNOWFLAKE_ROLE, "minioadmin") - .put(SNOWFLAKE_WAREHOUSE, "minioadmin") - .put(SNOWFLAKE_DATABASE, "minioadmin") - .put(SNOWFLAKE_SCHEMA, "minioadmin"); - - return TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - } - - @Test - public void testGetConfigs() - { - assertThat(getConfigs().size()).isGreaterThan(2); - assertThat(getConfig(WREN_DIRECTORY)).isEqualTo(configEntry(WREN_DIRECTORY, mdlDir.toAbsolutePath().toString())); - assertThat(getConfig(WREN_DATASOURCE_TYPE)).isEqualTo(configEntry(WREN_DATASOURCE_TYPE, DUCKDB.name())); - - assertThatThrownBy(() -> getConfig("notfound")) - .hasMessageFindingMatch(".*404 Not Found.*"); - assertThatThrownBy(() -> getConfig(null)) - .hasMessageFindingMatch(".*404 Not Found.*"); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/TestConfigResource.java b/wren-tests/src/test/java/io/wren/testing/TestConfigResource.java deleted file mode 100644 index fa97cd182..000000000 --- a/wren-tests/src/test/java/io/wren/testing/TestConfigResource.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Key; -import io.wren.base.client.duckdb.DuckDBConfig; -import io.wren.base.config.ConfigManager; -import io.wren.base.config.WrenConfig; -import io.wren.base.dto.Manifest; -import org.testng.annotations.Test; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_CACHE_TASK_RETRY_DELAY; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_MAX_CACHE_QUERY_TIMEOUT; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_MAX_CONCURRENT_TASKS; -import static io.wren.base.client.duckdb.DuckDBConfig.DUCKDB_MEMORY_LIMIT; -import static io.wren.base.config.ConfigManager.ConfigEntry.configEntry; -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static io.wren.base.config.WrenConfig.WREN_DIRECTORY; -import static io.wren.testing.AbstractTestFramework.withDefaultCatalogSchema; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -/** - * Every test will affect each other, so we need to run them in single thread. - */ -@Test(singleThreaded = true) -public class TestConfigResource - extends RequireWrenServer -{ - private Path mdlDir; - - @Override - protected TestingWrenServer createWrenServer() - { - Manifest manifest = withDefaultCatalogSchema() - .build(); - - try { - mdlDir = Files.createTempDirectory("wrenmdls"); - Path wrenMDLFilePath = mdlDir.resolve("wrenmdl.json"); - Files.write(wrenMDLFilePath, MANIFEST_JSON_CODEC.toJsonBytes(manifest)); - } - catch (IOException ex) { - throw new RuntimeException(ex); - } - - ImmutableMap.Builder properties = ImmutableMap.builder() - .put(WREN_DIRECTORY, mdlDir.toAbsolutePath().toString()) - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()); - - return TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - } - - @Test - public void testGetConfigs() - { - assertThat(getConfigs().size()).isGreaterThan(2); - assertThat(getConfig(WREN_DIRECTORY)).isEqualTo(configEntry(WREN_DIRECTORY, mdlDir.toAbsolutePath().toString())); - assertThat(getConfig(WREN_DATASOURCE_TYPE)).isEqualTo(configEntry(WREN_DATASOURCE_TYPE, DUCKDB.name())); - - assertThatThrownBy(() -> getConfig("notfound")) - .hasMessageFindingMatch(".*404 Not Found.*"); - assertThatThrownBy(() -> getConfig(null)) - .hasMessageFindingMatch(".*404 Not Found.*"); - } - - @Test - public void testuUpdateConfigs() - { - patchConfig(List.of(configEntry(DUCKDB_MEMORY_LIMIT, "2GB"))); - assertThat(getConfig(WREN_DATASOURCE_TYPE)).isEqualTo(configEntry(WREN_DATASOURCE_TYPE, DUCKDB.name())); - assertThat(getConfig(WREN_DIRECTORY)).isEqualTo(configEntry(WREN_DIRECTORY, mdlDir.toAbsolutePath().toString())); - assertThat(getConfig(DUCKDB_MEMORY_LIMIT)).isEqualTo(configEntry(DUCKDB_MEMORY_LIMIT, "2GB")); - - resetConfig(); - DuckDBConfig duckDBConfig = new DuckDBConfig(); - WrenConfig wrenConfig = new WrenConfig(); - assertThat(getConfig(WREN_DATASOURCE_TYPE)).isEqualTo(configEntry(WREN_DATASOURCE_TYPE, wrenConfig.getDataSourceType().name())); - assertThat(getConfig(WREN_DIRECTORY)).isEqualTo(configEntry(WREN_DIRECTORY, wrenConfig.getWrenMDLDirectory().getPath())); - assertThat(getConfig(DUCKDB_MEMORY_LIMIT)).isEqualTo(configEntry(DUCKDB_MEMORY_LIMIT, duckDBConfig.getMemoryLimit().toString())); - } - - @Test - public void testDataSourceTypeCaseInsensitive() - { - patchConfig(List.of(configEntry(WREN_DATASOURCE_TYPE, "DuCkDb"))); - assertThat(getConfig(WREN_DATASOURCE_TYPE)).isEqualTo(configEntry(WREN_DATASOURCE_TYPE, "DuCkDb")); - WrenConfig wrenConfig = server().getInstance(Key.get(ConfigManager.class)).getConfig(WrenConfig.class); - assertThat(wrenConfig.getDataSourceType()).isEqualTo(DUCKDB); - patchConfig(List.of(configEntry(WREN_DATASOURCE_TYPE, DUCKDB.name()))); - assertThat(getConfig(WREN_DATASOURCE_TYPE)).isEqualTo(configEntry(WREN_DATASOURCE_TYPE, DUCKDB.name())); - } - - @Test - public void testStaticConfigWontBeChanged() - { - patchConfig(List.of( - configEntry(WREN_DIRECTORY, "fake"), - configEntry(DUCKDB_MAX_CONCURRENT_TASKS, "100"), - configEntry(DUCKDB_MAX_CACHE_QUERY_TIMEOUT, "1000"), - configEntry(DUCKDB_CACHE_TASK_RETRY_DELAY, "1000"))); - - DuckDBConfig duckDBConfig = new DuckDBConfig(); - assertThat(getConfig(WREN_DIRECTORY)).isEqualTo(configEntry(WREN_DIRECTORY, mdlDir.toAbsolutePath().toString())); - assertThat(getConfig(DUCKDB_MAX_CONCURRENT_TASKS)).isEqualTo(configEntry(DUCKDB_MAX_CONCURRENT_TASKS, String.valueOf(duckDBConfig.getMaxConcurrentTasks()))); - assertThat(getConfig(DUCKDB_MAX_CACHE_QUERY_TIMEOUT)).isEqualTo(configEntry(DUCKDB_MAX_CACHE_QUERY_TIMEOUT, String.valueOf(duckDBConfig.getMaxCacheQueryTimeout()))); - assertThat(getConfig(DUCKDB_CACHE_TASK_RETRY_DELAY)).isEqualTo(configEntry(DUCKDB_CACHE_TASK_RETRY_DELAY, String.valueOf(duckDBConfig.getCacheTaskRetryDelay()))); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/TestDuckDBResource.java b/wren-tests/src/test/java/io/wren/testing/TestDuckDBResource.java deleted file mode 100644 index cb0c60d21..000000000 --- a/wren-tests/src/test/java/io/wren/testing/TestDuckDBResource.java +++ /dev/null @@ -1,244 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import com.google.common.collect.ImmutableMap; -import com.google.inject.Key; -import io.wren.base.dto.Manifest; -import io.wren.main.connector.duckdb.DuckDBMetadata; -import io.wren.main.web.dto.QueryResultDto; -import org.testng.annotations.AfterMethod; -import org.testng.annotations.Test; - -import java.io.File; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import static io.wren.base.client.duckdb.DuckDBConnectorConfig.DUCKDB_CONNECTOR_INIT_SQL_PATH; -import static io.wren.base.client.duckdb.DuckDBConnectorConfig.DUCKDB_CONNECTOR_SESSION_SQL_PATH; -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.dto.Manifest.MANIFEST_JSON_CODEC; -import static io.wren.testing.WebApplicationExceptionAssert.assertWebApplicationException; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatCode; - -@Test(singleThreaded = true) -public class TestDuckDBResource - extends RequireWrenServer -{ - private static final String INIT_SQL_1 = "CREATE TABLE customer (custkey integer, name varchar(25), address varchar(40));"; - private static final String INIT_SQL_2 = "CREATE TABLE orders (orderkey integer, custkey integer);"; - private static final String SHOW_TABLES_SQL = "SHOW TABLES;"; - private static final String SESSION_SQL_1 = "SET s3_region = 'us-east-2';"; - private static final String SESSION_SQL_2 = "SET temp_directory = '.tmp';"; - private static final String INVALID_SQL = "xxx"; - - private Path settingDir; - - @Override - protected TestingWrenServer createWrenServer() - { - try { - Path mdlDir = Files.createTempDirectory("wren-mdl"); - Path wrenMDLFilePath = mdlDir.resolve("duckdb_mdl.json"); - Manifest initial = Manifest.builder() - .setCatalog("memory") - .setSchema("tpch") - .build(); - Files.write(wrenMDLFilePath, MANIFEST_JSON_CODEC.toJsonBytes(initial)); - - settingDir = Files.createTempDirectory("duckdb-setting"); - - ImmutableMap.Builder properties = ImmutableMap.builder() - .put("wren.datasource.type", DUCKDB.name()) - .put("wren.directory", mdlDir.toAbsolutePath().toString()) - .put(DUCKDB_CONNECTOR_INIT_SQL_PATH, settingDir.resolve("init.sql").toAbsolutePath().toString()) - .put(DUCKDB_CONNECTOR_SESSION_SQL_PATH, settingDir.resolve("session.sql").toAbsolutePath().toString()); - - return TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - } - catch (IOException ex) { - throw new RuntimeException(ex); - } - } - - @AfterMethod - public void cleanTempDir() - throws IOException - { - Files.walk(settingDir) - .map(Path::toFile) - .forEach(File::delete); - DuckDBMetadata metadata = getInstance(Key.get(DuckDBMetadata.class)); - metadata.setInitSQL(null); - metadata.setSessionSQL(null); - metadata.reload(); - } - - @Test - public void testInitSQLWithInvalidSQL() - { - assertWebApplicationException(() -> setDuckDBInitSQL(INVALID_SQL)) - .hasErrorMessageMatches(".*Parser Error: syntax error at or near \"xxx\""); - } - - @Test - public void testInitSQL() - { - assertThatCode(() -> setDuckDBInitSQL(INIT_SQL_1)).doesNotThrowAnyException(); - assertThat(getDuckDBInitSQL()).isEqualTo(INIT_SQL_1); - assertThat(queryDuckDB(SHOW_TABLES_SQL)) - .extracting(QueryResultDto::getData) - .isNotNull() - .asList().element(0) - .isEqualTo(new String[] {"customer"}); - - assertThatCode(() -> appendToDuckDBInitSQL(INIT_SQL_2)).doesNotThrowAnyException(); - assertThat(getDuckDBInitSQL()).isEqualTo(INIT_SQL_1 + "\n" + INIT_SQL_2); - assertThat(queryDuckDB(SHOW_TABLES_SQL)) - .extracting(QueryResultDto::getData) - .isNotNull() - .asList() - .satisfies(data -> { - assertThat(data).element(0).isEqualTo(new String[] {"customer"}); - assertThat(data).element(1).isEqualTo(new String[] {"orders"}); - }); - - assertThatCode(() -> setDuckDBInitSQL(INIT_SQL_1)).doesNotThrowAnyException(); - assertThat(getDuckDBInitSQL()).isEqualTo(INIT_SQL_1); - assertThat(queryDuckDB(SHOW_TABLES_SQL)) - .extracting(QueryResultDto::getData) - .isNotNull() - .asList().element(0) - .isEqualTo(new String[] {"customer"}); - } - - @Test - public void testAppendInitSQLBeforeSet() - { - assertThatCode(() -> appendToDuckDBInitSQL(INIT_SQL_1)).doesNotThrowAnyException(); - assertThat(getDuckDBInitSQL()).isEqualTo(INIT_SQL_1); - } - - @Test - public void testSessionSQLWithInvalidSQL() - { - assertWebApplicationException(() -> setDuckDBSessionSQL(INVALID_SQL)) - .hasErrorMessageMatches(".*Parser Error: syntax error at or near \"xxx\""); - } - - @Test - public void testAppendInvalidSessionSQLAndItWillRollback() - { - assertThatCode(() -> appendToDuckDBSessionSQL(SESSION_SQL_1)).doesNotThrowAnyException(); - assertWebApplicationException(() -> appendToDuckDBSessionSQL(INVALID_SQL)) - .hasErrorMessageMatches(".*Parser Error: syntax error at or near \"xxx\""); - assertThat(getDuckDBSessionSQL()).isEqualTo(SESSION_SQL_1); - } - - @Test - public void testSessionSQL() - { - assertThatCode(() -> setDuckDBSessionSQL(SESSION_SQL_1)).doesNotThrowAnyException(); - assertThat(getDuckDBSessionSQL()).isEqualTo(SESSION_SQL_1); - assertThat(queryDuckDB("SELECT current_setting('s3_region') AS s3_region;")) - .extracting(QueryResultDto::getData) - .isNotNull() - .asList().element(0) - .isEqualTo(new String[] {"us-east-2"}); - - assertThatCode(() -> appendToDuckDBSessionSQL(SESSION_SQL_2)).doesNotThrowAnyException(); - assertThat(getDuckDBSessionSQL()).isEqualTo(SESSION_SQL_1 + "\n" + SESSION_SQL_2); - assertThat(queryDuckDB("SELECT current_setting('s3_region') AS s3_region, current_setting('temp_directory') AS temp_directory;")) - .extracting(QueryResultDto::getData) - .isNotNull() - .asList().element(0) - .isEqualTo(new String[] {"us-east-2", ".tmp"}); - } - - @Test - public void testSessionSQLEffectAllConnection() - throws ExecutionException, InterruptedException - { - assertThatCode(() -> setDuckDBSessionSQL(SESSION_SQL_1)).doesNotThrowAnyException(); - assertThat(getDuckDBSessionSQL()).isEqualTo(SESSION_SQL_1); - - ExecutorService executorService = Executors.newFixedThreadPool(10); - - List> futures = new ArrayList<>(); - for (int i = 0; i < 10; i++) { - futures.add(executorService.submit(() -> queryDuckDB("SELECT current_setting('s3_region') AS s3_region;"))); - } - - for (Future future : futures) { - assertThat(future.get()) - .extracting(QueryResultDto::getData) - .isNotNull() - .asList().element(0) - .isEqualTo(new String[] {"us-east-2"}); - } - } - - @Test - public void testAppendSessionSQLBeforeSet() - { - assertThatCode(() -> appendToDuckDBSessionSQL(SESSION_SQL_1)).doesNotThrowAnyException(); - assertThat(getDuckDBSessionSQL()).isEqualTo(SESSION_SQL_1); - } - - @Test - public void testQueryWithInvalidSQL() - { - assertWebApplicationException(() -> queryDuckDB(INVALID_SQL)) - .hasErrorMessageMatches(".*Parser Error: syntax error at or near \"xxx\""); - } - - @Test - public void testQuery() - { - assertThatCode(() -> setDuckDBInitSQL(INIT_SQL_1)).doesNotThrowAnyException(); - - assertThat(queryDuckDB(SHOW_TABLES_SQL)) - .extracting(QueryResultDto::getData) - .isNotNull() - .asList().element(0) - .isEqualTo(new String[] {"customer"}); - } - - @Test(description = "We don't promote sending DDL via query API, but we don't have sql parser to validate the syntax.") - public void testInsert() - { - assertThat(queryDuckDB(SHOW_TABLES_SQL)) - .extracting(QueryResultDto::getData) - .asList().isEmpty(); - - assertThatCode(() -> queryDuckDB(INIT_SQL_1)).doesNotThrowAnyException(); - - assertThat(queryDuckDB(SHOW_TABLES_SQL)) - .extracting(QueryResultDto::getData) - .isNotNull() - .asList().element(0) - .isEqualTo(new String[] {"customer"}); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/TestMDLResource.java b/wren-tests/src/test/java/io/wren/testing/TestMDLResource.java deleted file mode 100644 index 71c02fb7d..000000000 --- a/wren-tests/src/test/java/io/wren/testing/TestMDLResource.java +++ /dev/null @@ -1,322 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import com.google.common.collect.ImmutableMap; -import io.wren.base.dto.Column; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Manifest; -import io.wren.main.validation.ColumnIsValid; -import io.wren.main.validation.ValidationResult; -import io.wren.main.web.dto.DryPlanDto; -import io.wren.main.web.dto.PreviewDto; -import io.wren.main.web.dto.QueryResultDto; -import io.wren.main.web.dto.ValidateDto; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static io.wren.base.config.WrenConfig.WREN_ENABLE_DYNAMIC_FIELDS; -import static io.wren.base.dto.Column.calculatedColumn; -import static io.wren.base.dto.Column.column; -import static io.wren.base.dto.Model.model; -import static io.wren.base.dto.Relationship.relationship; -import static io.wren.main.validation.ColumnIsValid.COLUMN_IS_VALID; -import static io.wren.testing.WebApplicationExceptionAssert.assertWebApplicationException; -import static org.assertj.core.api.Assertions.assertThat; - -public class TestMDLResource - extends RequireWrenServer -{ - private Manifest manifest = Manifest.builder() - .setCatalog("wrenai") - .setSchema("tpch") - .setModels(List.of( - model("Orders", "SELECT * FROM tpch.orders", List.of(column("orderkey", "integer", null, false, "o_orderkey"))))) - .build(); - - @Override - protected TestingWrenServer createWrenServer() - throws Exception - { - ImmutableMap.Builder properties = ImmutableMap.builder() - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()) - .put(WREN_ENABLE_DYNAMIC_FIELDS, "true"); - - return TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - } - - @Override - protected void prepare() - { - initDuckDB(); - } - - @Test - public void testPreview() - { - Manifest previewManifest = Manifest.builder() - .setCatalog("wrenai") - .setSchema("tpch") - .setModels(List.of( - model("Customer", "SELECT * FROM tpch.customer", - List.of(column("custkey", "integer", null, false, "c_custkey"))))) - .build(); - - PreviewDto testDefaultDto = new PreviewDto(previewManifest, "select custkey from Customer", null); - QueryResultDto testDefault = preview(testDefaultDto); - assertThat(testDefault.getData().size()).isEqualTo(100); - assertThat(testDefault.getColumns().size()).isEqualTo(1); - assertThat(testDefault.getColumns().get(0).getName()).isEqualTo("custkey"); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("INTEGER"); - - PreviewDto testDefaultDto1 = new PreviewDto(previewManifest, "select custkey from Customer limit 200", null); - QueryResultDto preview1 = preview(testDefaultDto1); - assertThat(preview1.getData().size()).isEqualTo(100); - assertThat(preview1.getColumns().size()).isEqualTo(1); - - PreviewDto testDefaultDto2 = new PreviewDto(previewManifest, "select custkey from Customer limit 200", 150L); - QueryResultDto preview2 = preview(testDefaultDto2); - assertThat(preview2.getData().size()).isEqualTo(150); - assertThat(preview2.getColumns().size()).isEqualTo(1); - - assertWebApplicationException(() -> preview(new PreviewDto(previewManifest, "select orderkey from Orders limit 100", null))) - .hasErrorMessageMatches(".*Orders does not exist.*\n.*\n.*\n.*"); - } - - @Test - public void testDryRunAndDryPlan() - { - Manifest previewManifest = Manifest.builder() - .setCatalog("wrenai") - .setSchema("tpch") - .setModels(List.of( - model("Customer", "SELECT * FROM tpch.customer", - List.of(column("custkey", "integer", null, false, "c_custkey"), - column("name", "varchar", null, false, "c_name"))), - model("Orders", "SELECT * FROM tpch.orders", - List.of(column("orderkey", "integer", null, false, "o_orderkey"), - column("custkey", "integer", null, false, "o_custkey"), - column("customer", "Customer", "CustomerOrders", false), - calculatedColumn("customer_name", "varchar", "customer.name")), - "orderkey"))) - .setRelationships(List.of(relationship("CustomerOrders", List.of("Customer", "Orders"), JoinType.ONE_TO_MANY, "Customer.custkey = Orders.custkey"))) - .build(); - - PreviewDto testDefaultDto1 = new PreviewDto(previewManifest, "select orderkey from Orders limit 200", null); - List dryRun = dryRun(testDefaultDto1); - assertThat(dryRun.size()).isEqualTo(1); - assertThat(dryRun.get(0).getName()).isEqualTo("orderkey"); - - DryPlanDto dryPlanDto = new DryPlanDto(previewManifest, "select orderkey from Orders limit 200", false); - String dryPlan = dryPlan(dryPlanDto); - assertThat(dryPlan).isEqualTo(""" - WITH - "Orders" AS ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - ) "Orders" - )\s - SELECT orderkey - FROM - Orders - LIMIT 200 - """); - - dryPlanDto = new DryPlanDto(previewManifest, "select orderkey from Orders limit 200", true); - dryPlan = dryPlan(dryPlanDto); - assertThat(dryPlan).isEqualTo(""" - WITH - "Orders" AS ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - ) "Orders" - )\s - SELECT orderkey - FROM - Orders - LIMIT 200 - """); - - dryPlanDto = new DryPlanDto(previewManifest, "select customer_name from Orders limit 200", false); - dryPlan = dryPlan(dryPlanDto); - assertThat(dryPlan).isEqualTo(""" - WITH - "Customer" AS ( - SELECT - "Customer"."custkey" "custkey" - , "Customer"."name" "name" - FROM - ( - SELECT - "Customer"."custkey" "custkey" - , "Customer"."name" "name" - FROM - ( - SELECT - c_custkey "custkey" - , c_name "name" - FROM - ( - SELECT * - FROM - tpch.customer - ) "Customer" - ) "Customer" - ) "Customer" - )\s - , "Orders" AS ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - , "Orders_relationsub"."customer_name" "customer_name" - FROM - ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - ) "Orders" - LEFT JOIN ( - SELECT - "Orders"."orderkey" - , "Customer"."name" "customer_name" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - LEFT JOIN "Customer" ON ("Customer"."custkey" = "Orders"."custkey") - ) "Orders_relationsub" ON ("Orders"."orderkey" = "Orders_relationsub"."orderkey") - )\s - SELECT customer_name - FROM - Orders - LIMIT 200 - """); - } - - @Test - public void testValidation() - { - List validations = validate(COLUMN_IS_VALID, new ValidateDto(manifest, ColumnIsValid.parameters("Orders", "orderkey"))); - assertThat(validations.size()).isEqualTo(1); - assertThat(validations.getFirst().getName()).isEqualTo("column_is_valid:Orders:orderkey"); - assertThat(validations.getFirst().getStatus()).isEqualTo(ValidationResult.Status.PASS); - - validations = validate(COLUMN_IS_VALID, new ValidateDto(manifest, ColumnIsValid.parameters("Orders", "notfound"))); - assertThat(validations.size()).isEqualTo(1); - assertThat(validations.getFirst().getName()).isEqualTo("column_is_valid:Orders:notfound"); - assertThat(validations.getFirst().getStatus()).isEqualTo(ValidationResult.Status.FAIL); - assertThat(validations.getFirst().getMessage()).isNotEmpty(); - - validations = validate(COLUMN_IS_VALID, new ValidateDto(manifest, ColumnIsValid.parameters(null, "orderkey"))); - assertThat(validations.size()).isEqualTo(1); - assertThat(validations.getFirst().getName()).isEqualTo("column_is_valid"); - assertThat(validations.getFirst().getStatus()).isEqualTo(ValidationResult.Status.ERROR); - assertThat(validations.getFirst().getMessage()).isEqualTo("Model name is required"); - - validations = validate(COLUMN_IS_VALID, new ValidateDto(manifest, ColumnIsValid.parameters("", "orderkey"))); - assertThat(validations.size()).isEqualTo(1); - assertThat(validations.getFirst().getName()).isEqualTo("column_is_valid"); - assertThat(validations.getFirst().getStatus()).isEqualTo(ValidationResult.Status.ERROR); - assertThat(validations.getFirst().getMessage()).isEqualTo("Model name is required"); - - validations = validate(COLUMN_IS_VALID, new ValidateDto(manifest, ColumnIsValid.parameters("Orders", null))); - assertThat(validations.size()).isEqualTo(1); - assertThat(validations.getFirst().getName()).isEqualTo("column_is_valid:Orders"); - assertThat(validations.getFirst().getStatus()).isEqualTo(ValidationResult.Status.ERROR); - assertThat(validations.getFirst().getMessage()).isEqualTo("Column name is required"); - - validations = validate(COLUMN_IS_VALID, new ValidateDto(manifest, ColumnIsValid.parameters("Orders", ""))); - assertThat(validations.size()).isEqualTo(1); - assertThat(validations.getFirst().getName()).isEqualTo("column_is_valid:Orders"); - assertThat(validations.getFirst().getStatus()).isEqualTo(ValidationResult.Status.ERROR); - assertThat(validations.getFirst().getMessage()).isEqualTo("Column name is required"); - - validations = validate(COLUMN_IS_VALID, new ValidateDto(manifest, ColumnIsValid.parameters(null, null))); - assertThat(validations.size()).isEqualTo(1); - assertThat(validations.getFirst().getName()).isEqualTo("column_is_valid"); - assertThat(validations.getFirst().getStatus()).isEqualTo(ValidationResult.Status.ERROR); - assertThat(validations.getFirst().getMessage()).isEqualTo("Model name is required"); - - validations = validate(COLUMN_IS_VALID, new ValidateDto(manifest, null)); - assertThat(validations.size()).isEqualTo(1); - assertThat(validations.getFirst().getName()).isEqualTo("column_is_valid"); - assertThat(validations.getFirst().getStatus()).isEqualTo(ValidationResult.Status.ERROR); - assertThat(validations.getFirst().getMessage()).isEqualTo("Model name is required"); - - assertWebApplicationException(() -> validate(COLUMN_IS_VALID, null)) - .hasErrorMessageMatches(".*Manifest is required.*"); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/TestMDLResourceV2.java b/wren-tests/src/test/java/io/wren/testing/TestMDLResourceV2.java deleted file mode 100644 index 5378ab94b..000000000 --- a/wren-tests/src/test/java/io/wren/testing/TestMDLResourceV2.java +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import com.google.common.collect.ImmutableMap; -import io.airlift.json.JsonCodec; -import io.wren.base.dto.JoinType; -import io.wren.base.dto.Manifest; -import io.wren.main.web.dto.DryPlanDtoV2; -import org.testng.annotations.Test; - -import java.nio.file.Files; -import java.util.Base64; -import java.util.List; - -import static io.airlift.json.JsonCodec.jsonCodec; -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static io.wren.base.config.WrenConfig.WREN_DIRECTORY; -import static io.wren.base.config.WrenConfig.WREN_ENABLE_DYNAMIC_FIELDS; -import static io.wren.base.dto.Column.calculatedColumn; -import static io.wren.base.dto.Column.column; -import static io.wren.base.dto.Model.model; -import static io.wren.base.dto.Relationship.relationship; -import static java.nio.charset.StandardCharsets.UTF_8; -import static org.assertj.core.api.Assertions.assertThat; - -public class TestMDLResourceV2 - extends RequireWrenServer -{ - private static final JsonCodec MANIFEST_JSON_CODEC = jsonCodec(Manifest.class); - - @Override - protected TestingWrenServer createWrenServer() - throws Exception - { - ImmutableMap.Builder properties = ImmutableMap.builder() - .put(WREN_DIRECTORY, Files.createTempDirectory("mdl").toAbsolutePath().toString()) - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()) - .put(WREN_ENABLE_DYNAMIC_FIELDS, "true"); - TestingWrenServer testing = TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - return testing; - } - - @Override - protected void prepare() - { - initDuckDB(); - } - - @Test - public void testDryPlan() - { - Manifest manifest = Manifest.builder() - .setCatalog("wrenai") - .setSchema("tpch") - .setModels(List.of( - model("Customer", "SELECT * FROM tpch.customer", - List.of(column("custkey", "integer", null, false, "c_custkey"), - column("name", "varchar", null, false, "c_name"))), - model("Orders", "SELECT * FROM tpch.orders", - List.of(column("orderkey", "integer", null, false, "o_orderkey"), - column("custkey", "integer", null, false, "o_custkey"), - column("customer", "Customer", "CustomerOrders", false), - calculatedColumn("customer_name", "varchar", "customer.name")), - "orderkey"))) - .setRelationships(List.of(relationship("CustomerOrders", List.of("Customer", "Orders"), JoinType.ONE_TO_MANY, "Customer.custkey = Orders.custkey"))) - .build(); - - String manifestStr = base64Encode(toJson(manifest)); - - DryPlanDtoV2 dryPlanDto = new DryPlanDtoV2(manifestStr, "select orderkey from Orders limit 200"); - String dryPlan = dryPlanV2(dryPlanDto); - assertThat(dryPlan).isEqualTo(""" - WITH - "Orders" AS ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - ) "Orders" - )\s - SELECT orderkey - FROM - Orders - LIMIT 200 - """); - - dryPlanDto = new DryPlanDtoV2(manifestStr, "select customer_name from Orders limit 200"); - dryPlan = dryPlanV2(dryPlanDto); - assertThat(dryPlan).isEqualTo(""" - WITH - "Customer" AS ( - SELECT - "Customer"."custkey" "custkey" - , "Customer"."name" "name" - FROM - ( - SELECT - "Customer"."custkey" "custkey" - , "Customer"."name" "name" - FROM - ( - SELECT - c_custkey "custkey" - , c_name "name" - FROM - ( - SELECT * - FROM - tpch.customer - ) "Customer" - ) "Customer" - ) "Customer" - )\s - , "Orders" AS ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - , "Orders_relationsub"."customer_name" "customer_name" - FROM - ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - ) "Orders" - LEFT JOIN ( - SELECT - "Orders"."orderkey" - , "Customer"."name" "customer_name" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - LEFT JOIN "Customer" ON ("Customer"."custkey" = "Orders"."custkey") - ) "Orders_relationsub" ON ("Orders"."orderkey" = "Orders_relationsub"."orderkey") - )\s - SELECT customer_name - FROM - Orders - LIMIT 200 - """); - } - - @Test - public void testSetManyToMany() - { - Manifest manifest = Manifest.builder() - .setCatalog("wrenai") - .setSchema("tpch") - .setModels(List.of( - model("Customer", "SELECT * FROM tpch.customer", - List.of(column("custkey", "integer", null, false, "c_custkey"), - column("name", "varchar", null, false, "c_name"))), - model("Orders", "SELECT * FROM tpch.orders", - List.of(column("orderkey", "integer", null, false, "o_orderkey"), - column("custkey", "integer", null, false, "o_custkey"), - column("customer", "Customer", "CustomerOrders", false), - calculatedColumn("customer_name", "varchar", "customer.name")), - "orderkey"))) - .setRelationships(List.of(relationship("CustomerOrders", List.of("Customer", "Orders"), JoinType.MANY_TO_MANY, "Customer.custkey = Orders.custkey"))) - .build(); - - String manifestStr = base64Encode(toJson(manifest)); - DryPlanDtoV2 dryPlanDto = new DryPlanDtoV2(manifestStr, "select orderkey from Orders limit 200"); - String dryPlan = dryPlanV2(dryPlanDto); - assertThat(dryPlan).isEqualTo(""" - WITH - "Orders" AS ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - ) "Orders" - )\s - SELECT orderkey - FROM - Orders - LIMIT 200 - """); - - } - - @Test - public void testPlanCountWithClause() - { - Manifest manifest = Manifest.builder() - .setCatalog("wrenai") - .setSchema("tpch") - .setModels(List.of( - model("Customer", "SELECT * FROM tpch.customer", - List.of(column("custkey", "integer", null, false, "c_custkey"), - column("name", "varchar", null, false, "c_name"))), - model("Orders", "SELECT * FROM tpch.orders", - List.of(column("orderkey", "integer", null, false, "o_orderkey"), - column("custkey", "integer", null, false, "o_custkey"), - column("customer", "Customer", "CustomerOrders", false), - calculatedColumn("customer_name", "varchar", "customer.name")), - "orderkey"))) - .setRelationships(List.of(relationship("CustomerOrders", List.of("Customer", "Orders"), JoinType.MANY_TO_MANY, "Customer.custkey = Orders.custkey"))) - .build(); - String manifestStr = base64Encode(toJson(manifest)); - DryPlanDtoV2 dryPlanDto = new DryPlanDtoV2(manifestStr, "select count(*) from (with orders_custkey as (select custkey from \"Orders\") select * from orders_custkey) "); - String dryPlan = dryPlanV2(dryPlanDto); - assertThat(dryPlan).isEqualTo(""" - WITH - "Orders" AS ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - "Orders"."orderkey" "orderkey" - , "Orders"."custkey" "custkey" - FROM - ( - SELECT - o_orderkey "orderkey" - , o_custkey "custkey" - FROM - ( - SELECT * - FROM - tpch.orders - ) "Orders" - ) "Orders" - ) "Orders" - )\s - SELECT count(*) - FROM - ( - WITH - orders_custkey AS ( - SELECT custkey - FROM - "Orders" - )\s - SELECT * - FROM - orders_custkey - ) t - """); - } - - private String toJson(Manifest manifest) - { - return MANIFEST_JSON_CODEC.toJson(manifest); - } - - private String base64Encode(String str) - { - return Base64.getEncoder().encodeToString(str.getBytes(UTF_8)); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/WebApplicationExceptionAssert.java b/wren-tests/src/test/java/io/wren/testing/WebApplicationExceptionAssert.java deleted file mode 100644 index 9c667f44e..000000000 --- a/wren-tests/src/test/java/io/wren/testing/WebApplicationExceptionAssert.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Licensed 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 io.wren.testing; - -import io.wren.base.metadata.StandardErrorCode; -import io.wren.main.web.dto.ErrorMessageDto; -import jakarta.ws.rs.WebApplicationException; -import org.assertj.core.api.AbstractThrowableAssert; -import org.assertj.core.api.ThrowableAssert; -import org.intellij.lang.annotations.Language; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.catchThrowable; -import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown; - -public final class WebApplicationExceptionAssert - extends AbstractThrowableAssert -{ - public static WebApplicationExceptionAssert assertWebApplicationException(ThrowableAssert.ThrowingCallable throwingCallable) - { - Throwable throwable = catchThrowable(throwingCallable); - if (throwable == null) { - failBecauseExceptionWasNotThrown(WebApplicationException.class); - } - assertThat(throwable).isInstanceOf(WebApplicationException.class); - return new WebApplicationExceptionAssert((WebApplicationException) throwable); - } - - private WebApplicationExceptionAssert(WebApplicationException actual) - { - super(actual, WebApplicationExceptionAssert.class); - } - - public WebApplicationExceptionAssert hasHTTPStatus(int code) - { - try { - assertThat(actual.getResponse().getStatus()).isEqualTo(code); - } - catch (AssertionError e) { - e.addSuppressed(actual); - throw e; - } - return myself; - } - - public WebApplicationExceptionAssert hasErrorCode(StandardErrorCode errorCode) - { - try { - Object responseEntity = actual.getResponse().getEntity(); - assertThat(responseEntity).isInstanceOf(ErrorMessageDto.class); - assertThat(((ErrorMessageDto) responseEntity).getCode()).isEqualTo(errorCode.name()); - } - catch (AssertionError e) { - e.addSuppressed(actual); - throw e; - } - return myself; - } - - public WebApplicationExceptionAssert hasErrorMessageMatches(@Language("RegExp") String regex) - { - try { - Object responseEntity = actual.getResponse().getEntity(); - assertThat(responseEntity).isInstanceOf(ErrorMessageDto.class); - assertThat(((ErrorMessageDto) responseEntity).getMessage()).matches(regex); - } - catch (AssertionError e) { - e.addSuppressed(actual); - throw e; - } - return myself; - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/duckdb/TestDuckDBSqlConverter.java b/wren-tests/src/test/java/io/wren/testing/duckdb/TestDuckDBSqlConverter.java deleted file mode 100644 index 2785ab0cc..000000000 --- a/wren-tests/src/test/java/io/wren/testing/duckdb/TestDuckDBSqlConverter.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Licensed 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 io.wren.testing.duckdb; - -import io.wren.base.SessionContext; -import io.wren.base.client.duckdb.DuckDBConfig; -import io.wren.base.client.duckdb.DuckDBConnectorConfig; -import io.wren.base.config.ConfigManager; -import io.wren.base.config.WrenConfig; -import io.wren.main.connector.duckdb.DuckDBMetadata; -import io.wren.main.connector.duckdb.DuckDBSqlConverter; -import io.wren.testing.AbstractSqlConverterTest; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -public class TestDuckDBSqlConverter - extends AbstractSqlConverterTest -{ - private static final SessionContext DEFAULT_SESSION_CONTEXT = SessionContext.builder() - .setCatalog("memory") - .setSchema("tpch") - .build(); - - private DuckDBSqlConverter sqlConverter; - - @BeforeClass - public void setup() - throws Exception - { - prepareConfig(); - - ConfigManager configManager = new ConfigManager( - new WrenConfig(), - new DuckDBConfig(), - new DuckDBConnectorConfig()); - - DuckDBMetadata metadata = new DuckDBMetadata(configManager); - - sqlConverter = new DuckDBSqlConverter(metadata); - } - - @Test - public void testArray() - { - assertConvert("SELECT ARRAY[1,2,3][1]", "SELECT array_value(1, 2, 3)[1]" + "\n\n"); - } - - @Test - public void testFunction() - { - assertConvert("SELECT generate_array(1, 10)", "SELECT generate_series(1, 10)" + "\n\n"); - } - - @Test - public void testValues() - { - assertConvert("SELECT * FROM (values (ARRAY[1,2,3]))", """ - SELECT * - FROM - ( - VALUES\s - (ARRAY[1,2,3]) - )\s - """); - - assertConvert("SELECT * FROM (values (1))", """ - SELECT * - FROM - ( - VALUES\s - (1) - )\s - """); - assertConvert("SELECT * FROM (values (1, 2, ARRAY[1,2,3]))", """ - SELECT * - FROM - ( - VALUES\s - (1, 2, ARRAY[1,2,3]) - )\s - """); - } - - private void assertConvert(String from, String to) - { - assertThat(sqlConverter.convert(from, DEFAULT_SESSION_CONTEXT)).isEqualTo(to); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/duckdb/TestDynamicFields.java b/wren-tests/src/test/java/io/wren/testing/duckdb/TestDynamicFields.java deleted file mode 100644 index 448c820ff..000000000 --- a/wren-tests/src/test/java/io/wren/testing/duckdb/TestDynamicFields.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Licensed 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 io.wren.testing.duckdb; - -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import io.wren.base.Column; -import io.wren.base.dto.Manifest; -import io.wren.main.web.dto.QueryResultDto; -import io.wren.testing.AbstractTestFramework; -import io.wren.testing.TestingWrenServer; -import org.testng.annotations.Test; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static io.wren.base.Column.column; -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static io.wren.base.config.WrenConfig.WREN_ENABLE_DYNAMIC_FIELDS; -import static org.assertj.core.api.Assertions.assertThat; - -public class TestDynamicFields - extends AbstractTestFramework -{ - private Manifest manifest; - - @Override - protected TestingWrenServer createWrenServer() - { - ImmutableMap.Builder properties = ImmutableMap.builder() - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()) - .put(WREN_ENABLE_DYNAMIC_FIELDS, "true"); - - try { - manifest = MANIFEST_JSON_CODEC.fromJson(Files.readString(Path.of(getClass().getClassLoader().getResource("tpch_mdl.json").getPath()))); - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - - return TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - } - - @Test - public void testDynamicMetric() - { - // select one dimension and measure - QueryResultDto actual = query(manifest, "SELECT customer, totalprice FROM CustomerDailyRevenue WHERE customer = 'Customer#000000048'"); - QueryResultDto expected = query(manifest, "SELECT c.name as customer, SUM(o.totalprice) as totalprice FROM Orders o LEFT JOIN Customer c ON o.custkey = c.custkey\n" + - "WHERE c.name = 'Customer#000000048' GROUP BY 1"); - - assertThat(actual).isEqualTo(expected); - - // select two dimensions and measure - actual = query(manifest, "SELECT customer, date, totalprice FROM CustomerDailyRevenue WHERE customer = 'Customer#000000048' ORDER BY 1, 2"); - expected = query(manifest, "SELECT c.name as customer, o.orderdate as date, SUM(o.totalprice) as totalprice FROM Orders o LEFT JOIN Customer c ON o.custkey = c.custkey\n" + - "WHERE c.name = 'Customer#000000048' GROUP BY 1, 2 ORDER BY 1, 2"); - assertThat(actual).isEqualTo(expected); - } - - @Test - public void testTargetDotAllWillNotIncludeCalculatedField() - { - // Show that there is a calculated field in Orders. - QueryResultDto calculated = query(manifest, "SELECT nation_name FROM \"Orders\" LIMIT 1"); - assertThat(calculated.getColumns()).containsExactly(column("nation_name", "VARCHAR")); - - List expectedColumns = ImmutableList.of( - column("orderkey", "INTEGER"), - column("custkey", "INTEGER"), - column("orderstatus", "VARCHAR"), - column("totalprice", "DECIMAL(15,2)"), - column("orderdate", "DATE")); - - QueryResultDto case1 = query(manifest, "SELECT \"Orders\".* FROM \"Orders\" LIMIT 1"); - assertThat(case1.getColumns()).isEqualTo(expectedColumns); - - QueryResultDto case2 = query(manifest, "SELECT o.* FROM \"Orders\" AS o LIMIT 1"); - assertThat(case2.getColumns()).isEqualTo(expectedColumns); - - QueryResultDto case3 = query(manifest, "SELECT o.* FROM \"Orders\" AS o JOIN \"Customer\" AS c ON o.custkey = c.custkey LIMIT 1"); - assertThat(case3.getColumns()).isEqualTo(expectedColumns); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/duckdb/TestFunctionDuckDB.java b/wren-tests/src/test/java/io/wren/testing/duckdb/TestFunctionDuckDB.java deleted file mode 100644 index e63d62699..000000000 --- a/wren-tests/src/test/java/io/wren/testing/duckdb/TestFunctionDuckDB.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Licensed 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 io.wren.testing.duckdb; - -import com.google.common.collect.ImmutableMap; -import io.wren.base.dto.Manifest; -import io.wren.testing.AbstractFunctionTest; -import io.wren.testing.TestingWrenServer; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; - -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static io.wren.base.config.WrenConfig.WREN_DIRECTORY; - -public class TestFunctionDuckDB - extends AbstractFunctionTest -{ - @Override - protected TestingWrenServer createWrenServer() - { - Path mdlDir; - - try { - mdlDir = Files.createTempDirectory("wrenmdls"); - Path wrenMDLFilePath = mdlDir.resolve("wrenmdl.json"); - Files.write(wrenMDLFilePath, MANIFEST_JSON_CODEC.toJsonBytes(Manifest.builder().setCatalog("wren").setSchema("test").build())); - } - catch (IOException ex) { - throw new RuntimeException(ex); - } - - ImmutableMap.Builder properties = ImmutableMap.builder() - .put(WREN_DIRECTORY, mdlDir.toAbsolutePath().toString()) - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()); - - return TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/duckdb/TestStartWithDuckDB.java b/wren-tests/src/test/java/io/wren/testing/duckdb/TestStartWithDuckDB.java deleted file mode 100644 index 5e656bb93..000000000 --- a/wren-tests/src/test/java/io/wren/testing/duckdb/TestStartWithDuckDB.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Licensed 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 io.wren.testing.duckdb; - -import com.google.common.collect.ImmutableMap; -import io.wren.testing.TestingWrenServer; -import org.testng.annotations.Test; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Map; - -import static io.wren.base.client.duckdb.DuckDBConnectorConfig.DUCKDB_CONNECTOR_INIT_SQL_PATH; -import static io.wren.base.client.duckdb.DuckDBConnectorConfig.DUCKDB_CONNECTOR_SESSION_SQL_PATH; -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static org.assertj.core.api.Assertions.assertThatCode; - -public class TestStartWithDuckDB -{ - @Test - public void testStart() - throws Exception - { - Path mdlDir = Files.createTempDirectory("wren-mdl"); - String initSqlPath = mdlDir.resolve("init.sql").toAbsolutePath().toString(); - Files.writeString(Path.of(initSqlPath), "CREATE SCHEMA tpch;"); - String sessionSqlPath = mdlDir.resolve("session.sql").toAbsolutePath().toString(); - Files.writeString(Path.of(sessionSqlPath), "SET s3_region = 'us-east-2';"); - - assertServerStart(ImmutableMap.builder() - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()) - .put(DUCKDB_CONNECTOR_INIT_SQL_PATH, initSqlPath) - .put(DUCKDB_CONNECTOR_SESSION_SQL_PATH, sessionSqlPath) - .build()); - } - - @Test - public void testStartWithIllegalInitSql() - throws Exception - { - Path mdlDir = Files.createTempDirectory("wren-mdl"); - String initSqlPath = mdlDir.resolve("init.sql").toAbsolutePath().toString(); - Files.writeString(Path.of(initSqlPath), "Illegal SQL"); - String sessionSqlPath = mdlDir.resolve("session.sql").toAbsolutePath().toString(); - Files.writeString(Path.of(sessionSqlPath), "Illegal SQL"); - - assertServerStart(ImmutableMap.builder() - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()) - .put(DUCKDB_CONNECTOR_INIT_SQL_PATH, initSqlPath) - .put(DUCKDB_CONNECTOR_SESSION_SQL_PATH, sessionSqlPath) - .build()); - } - - private void assertServerStart(Map props) - { - assertThatCode(() -> TestingWrenServer.builder().setRequiredConfigs(props).build()) - .doesNotThrowAnyException(); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDB.java b/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDB.java deleted file mode 100644 index bfcfb48d6..000000000 --- a/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDB.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Licensed 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 io.wren.testing.duckdb; - -import com.google.common.collect.ImmutableMap; -import io.wren.base.dto.Manifest; -import io.wren.main.web.dto.QueryResultDto; -import io.wren.testing.AbstractTestFramework; -import io.wren.testing.TestingWrenServer; -import org.testng.annotations.DataProvider; -import org.testng.annotations.Test; - -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.List; - -import static io.wren.base.Column.column; -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static io.wren.base.config.WrenConfig.WREN_ENABLE_DYNAMIC_FIELDS; -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatNoException; - -public class TestWrenWithDuckDB - extends AbstractTestFramework -{ - private Manifest manifest; - - @Override - protected TestingWrenServer createWrenServer() - throws Exception - { - ImmutableMap.Builder properties = ImmutableMap.builder() - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()) - .put(WREN_ENABLE_DYNAMIC_FIELDS, "true"); - - try { - manifest = MANIFEST_JSON_CODEC.fromJson(Files.readString(Path.of(getClass().getClassLoader().getResource("duckdb/mdl.json").getPath()))); - } - catch (Exception ex) { - throw new RuntimeException(ex); - } - - return TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - } - - @DataProvider - public Object[][] queryModel() - { - return new Object[][] { - {"SELECT * FROM Orders"}, - {"SELECT * FROM Orders WHERE orderkey > 100"}, - {"SELECT * FROM Orders a JOIN Customer b ON a.custkey = b.custkey"}, - {"SELECT * FROM Orders WHERE nation_name IS NOT NULL"}, - {"SELECT sum(orderkey) FROM Orders"}, // DuckDB always returns HUGEINT when aggregating integers - }; - } - - @Test(dataProvider = "queryModel") - public void testQueryModel(String sql) - { - assertThatNoException().isThrownBy(() -> { - query(manifest, sql); - }); - } - - @Test - public void testQueryOnlyModelColumn() - { - QueryResultDto queryResultDto = query(manifest, "select * from Orders limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("orderkey", "integer"), - column("custkey", "integer"), - column("orderstatus", "varchar"), - column("totalprice", "DECIMAL(15,2)"), - column("orderdate", "date"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - } - - @Test - public void testQueryMetric() - { - // test the TO_ONE relationship - QueryResultDto queryResultDto = query(manifest, "select customer, totalprice from Revenue limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("customer", "varchar"), column("totalprice", "DECIMAL(38,2)"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - - // test the TO_MANY relationship - queryResultDto = query(manifest, "select custkey, totalprice from CustomerRevenue limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("custkey", "integer"), - column("totalprice", "DECIMAL(38,2)"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - - queryResultDto = query(manifest, "select customer, month, totalprice from CustomerMonthlyRevenue limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("customer", "varchar"), - column("month", "date"), - column("totalprice", "DECIMAL(38,2)"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - } - - @Test - public void testEnum() - { - QueryResultDto queryResultDto = query(manifest, "select Status.F as f1"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("f1", "VARCHAR"))); - assertThat(queryResultDto.getData().get(0)[0]).isEqualTo("F"); - - queryResultDto = query(manifest, "select count(*) as totalcount from Orders where orderstatus = Status.O"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("totalcount", "BIGINT"))); - assertThat(queryResultDto.getData().get(0)[0]).isEqualTo(7333); - } - - @Test - public void testView() - { - QueryResultDto queryResultDto = query(manifest, "select * from useModel limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("orderkey", "integer"), - column("custkey", "integer"), - column("orderstatus", "varchar"), - column("totalprice", "DECIMAL(15,2)"), - column("orderdate", "date"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - - queryResultDto = query(manifest, "select * from useMetric limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("customer", "varchar"), - column("totalprice", "DECIMAL(38,2)"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - - queryResultDto = query(manifest, "select * from useUseMetric limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("customer", "varchar"), - column("totalprice", "DECIMAL(38,2)"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - - queryResultDto = query(manifest, "select * from sameCte limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("orderkey", "integer"), - column("custkey", "integer"), - column("orderstatus", "varchar"), - column("totalprice", "DECIMAL(15,2)"), - column("orderdate", "date"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - } - - @Test - public void testQuerySqlReservedWord() - { - QueryResultDto queryResultDto = query(manifest, "select \"order\" from Lineitem limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("order", "integer"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - } - - @Test - public void testQueryMacro() - { - QueryResultDto queryResultDto = query(manifest, "select custkey_name, custkey_call_concat from Customer limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("custkey_name", "varchar"), - column("custkey_call_concat", "varchar"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - } - - @Test - public void testQueryJoinAliased() - { - QueryResultDto queryResultDto = query(manifest, "select totalprice from (Orders o join Customer c on o.custkey = c.custkey) join_relation limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("totalprice", "DECIMAL(15,2)"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - - queryResultDto = query(manifest, "select totalprice from ((Orders o join Customer c on o.custkey = c.custkey) j join Lineitem l on j.orderkey = l.orderkey) limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("totalprice", "DECIMAL(15,2)"))); - assertThat(queryResultDto.getData().size()).isEqualTo(100); - } - - @Test - public void testCountWithCalculatedFieldFilter() - { - QueryResultDto queryResultDto = query(manifest, "select count(*) from \"Orders\" where nation_name = 'ALGERIA'"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(691); - } - - @Test - public void testCount() - { - QueryResultDto queryResultDto = query(manifest, "select count(*) from Orders a"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(15000); - - queryResultDto = query(manifest, "select count(*) from Orders, Customer"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(22500000); - - queryResultDto = query(manifest, "select count(*) from Orders a, Customer b"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(22500000); - - queryResultDto = query(manifest, "select count(*) from Orders a JOIN Customer b ON a.custkey = b.custkey"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(15000); - - queryResultDto = query(manifest, "select count(*) from (select * from Orders) t1"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(15000); - - queryResultDto = query(manifest, "select count(*) from (Orders a JOIN Customer b ON a.custkey = b.custkey) t1"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(15000); - - queryResultDto = query(manifest, "with t1 as (select * from Orders) select count(*) from t1"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(15000); - - queryResultDto = query(manifest, "with t1 as (select * from Orders), t2 as (select count(*) from t1) select * from t2"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(15000); - - queryResultDto = query(manifest, "with t1 as (select * from Orders) select * from (select count(*) from t1) s1"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(15000); - - queryResultDto = query(manifest, "with t1 as (select * from Orders) select 15000 = (select count(*) from t1)"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(true); - - queryResultDto = query(manifest, "with t1 as (select * from Orders) select 1 from Orders where 15000 = (select count(*) from t1)"); - assertThat(queryResultDto.getData().getFirst()[0]).isEqualTo(1); - } - - @Test - public void testSelectAllExcludeCalculatedField() - { - QueryResultDto queryResultDto = query(manifest, "select * from Orders limit 100"); - assertThat(queryResultDto.getColumns()) - .isEqualTo(List.of(column("orderkey", "INTEGER"), - column("custkey", "INTEGER"), - column("orderstatus", "VARCHAR"), - column("totalprice", "DECIMAL(15,2)"), - column("orderdate", "DATE"))); - } - - @Test - public void testUnionDifferentModel() - { - QueryResultDto queryResultDto = query(manifest, "select custkey from Orders union select custkey from Customer limit 100"); - assertThat(queryResultDto.getColumns().size()).isEqualTo(1); - } -} diff --git a/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDBTableFunction.java b/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDBTableFunction.java deleted file mode 100644 index 3a91caa22..000000000 --- a/wren-tests/src/test/java/io/wren/testing/duckdb/TestWrenWithDuckDBTableFunction.java +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Licensed 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 io.wren.testing.duckdb; - -import com.google.common.collect.ImmutableMap; -import io.wren.base.dto.Manifest; -import io.wren.base.dto.Model; -import io.wren.main.web.dto.PreviewDto; -import io.wren.main.web.dto.QueryResultDto; -import io.wren.testing.RequireWrenServer; -import io.wren.testing.TestingWrenServer; -import org.testng.annotations.Test; - -import java.util.List; - -import static io.wren.base.config.WrenConfig.DataSourceType.DUCKDB; -import static io.wren.base.config.WrenConfig.WREN_DATASOURCE_TYPE; -import static io.wren.base.config.WrenConfig.WREN_ENABLE_DYNAMIC_FIELDS; -import static io.wren.base.dto.Column.column; -import static java.lang.String.format; -import static java.util.Objects.requireNonNull; -import static org.assertj.core.api.Assertions.assertThat; - -@Test(singleThreaded = true) -public class TestWrenWithDuckDBTableFunction - extends RequireWrenServer -{ - @Override - protected TestingWrenServer createWrenServer() - throws Exception - { - ImmutableMap.Builder properties = ImmutableMap.builder() - .put(WREN_DATASOURCE_TYPE, DUCKDB.name()) - .put(WREN_ENABLE_DYNAMIC_FIELDS, "true"); - TestingWrenServer testing = TestingWrenServer.builder() - .setRequiredConfigs(properties.build()) - .build(); - return testing; - } - - @Test - public void testQueryFile() - { - String url = requireNonNull(getClass().getClassLoader().getResource("tpch/data/orders.parquet")).getPath(); - Manifest manifest = Manifest.builder() - .setCatalog("wren") - .setSchema("test") - .setModels(List.of(Model.model( - "orders", - format("select * from read_parquet('%s')", url), - List.of(column("orderkey", "integer", null, false, "o_orderkey"), - column("custkey", "integer", null, false, "o_custkey"))))) - .build(); - - PreviewDto testDefaultDto = new PreviewDto(manifest, "select custkey from orders", null); - QueryResultDto testDefault = preview(testDefaultDto); - assertThat(testDefault.getData().size()).isEqualTo(100); - assertThat(testDefault.getColumns().size()).isEqualTo(1); - assertThat(testDefault.getColumns().get(0).getName()).isEqualTo("custkey"); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("INTEGER"); - } - - @Test - public void testQueryFileWithParam() - { - String url = requireNonNull(getClass().getClassLoader().getResource("csv/orders/orders.csv")).getPath(); - Manifest manifest = Manifest.builder() - .setCatalog("wren") - .setSchema("test") - .setModels(List.of(Model.model( - "orders", - format("select * from read_csv('%s', header = true)", url), - List.of(column("order_id", "varchar", null, false), - column("customer_id", "varchar", null, false))))) - .build(); - - PreviewDto testDefaultDto = new PreviewDto(manifest, "select order_id from orders", null); - QueryResultDto testDefault = preview(testDefaultDto); - assertThat(testDefault.getData().size()).isEqualTo(99); - assertThat(testDefault.getColumns().size()).isEqualTo(1); - assertThat(testDefault.getColumns().get(0).getName()).isEqualTo("order_id"); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("VARCHAR"); - - String folder = requireNonNull(getClass().getClassLoader().getResource("csv/orders")).getPath(); - manifest = Manifest.builder() - .setCatalog("wren") - .setSchema("test") - .setModels(List.of(Model.model( - "orders", - format("select * from read_csv(['%s', '%s'], header = true)", folder + "/orders.csv", folder + "/orders-2.csv"), - List.of(column("order_id", "varchar", null, false), - column("customer_id", "varchar", null, false))))) - .build(); - - testDefaultDto = new PreviewDto(manifest, "select order_id from orders", 200L); - testDefault = preview(testDefaultDto); - assertThat(testDefault.getData().size()).isEqualTo(181); - assertThat(testDefault.getColumns().size()).isEqualTo(1); - assertThat(testDefault.getColumns().get(0).getName()).isEqualTo("order_id"); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("VARCHAR"); - } - - @Test - public void testQueryWithFromStringLiteral() - { - String url = requireNonNull(getClass().getClassLoader().getResource("csv/orders/orders.csv")).getPath(); - Manifest manifest = Manifest.builder() - .setCatalog("wren") - .setSchema("test") - .setModels(List.of(Model.model( - "orders", - format("select * from '%s'", url), - List.of(column("order_id", "varchar", null, false), - column("customer_id", "varchar", null, false))))) - .build(); - - PreviewDto testDefaultDto = new PreviewDto(manifest, "select order_id from orders", null); - QueryResultDto testDefault = preview(testDefaultDto); - assertThat(testDefault.getData().size()).isEqualTo(99); - assertThat(testDefault.getColumns().size()).isEqualTo(1); - assertThat(testDefault.getColumns().get(0).getName()).isEqualTo("order_id"); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("VARCHAR"); - } - - @Test - public void testQueryNestedType() - { - setDuckDBInitSQL("create table nested_table as select * from (values ({'f1':'2'})) t(a1)"); - Manifest manifest = Manifest.builder() - .setCatalog("wren") - .setSchema("public") - .setModels(List.of( - Model.model( - "nested_table", - "select * from main.nested_table", - List.of(column("a1", "array", null, false))))) - .build(); - - PreviewDto previewDto = new PreviewDto(manifest, "select a1.f1 from nested_table", null); - QueryResultDto testDefault = preview(previewDto); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("VARCHAR"); - assertThat(testDefault.getData().get(0)[0]).isEqualTo("2"); - - setDuckDBInitSQL("create table nested_table as select * from (values ([{'f1':'2'}, {'f1':'3'}, {'f1':'4'}])) t(a1)"); - manifest = Manifest.builder() - .setCatalog("wren") - .setSchema("public") - .setModels(List.of( - Model.model( - "nested_table", - "select * from main.nested_table", - List.of(column("a1", "array>", null, false))))) - .build(); - - previewDto = new PreviewDto(manifest, "select a1[1].f1 from nested_table", null); - testDefault = preview(previewDto); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("VARCHAR"); - assertThat(testDefault.getData().get(0)[0]).isEqualTo("2"); - - setDuckDBInitSQL("create table nested_table as select * from (values ([1,2,3])) t(a1)"); - - previewDto = new PreviewDto(manifest, "select * from nested_table n, unnest(n.a1)", null); - testDefault = preview(previewDto); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("INTEGER[]"); - assertThat(testDefault.getData().get(0).length).isEqualTo(2); - assertThat(testDefault.getData().size()).isEqualTo(3); - - previewDto = new PreviewDto(manifest, "select * from nested_table n, unnest(n.a1) u(a1)", null); - testDefault = preview(previewDto); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("INTEGER[]"); - assertThat(testDefault.getData().get(0).length).isEqualTo(2); - assertThat(testDefault.getData().size()).isEqualTo(3); - - previewDto = new PreviewDto(manifest, "select u.a1 from nested_table n, unnest(n.a1) u(a1)", null); - testDefault = preview(previewDto); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("INTEGER"); - assertThat(testDefault.getData().get(0)[0]).isEqualTo(1); - assertThat(testDefault.getData().get(1)[0]).isEqualTo(2); - assertThat(testDefault.getData().get(2)[0]).isEqualTo(3); - - previewDto = new PreviewDto(manifest, "select * from nested_table n cross join lateral (select n.a1[1])", null); - testDefault = preview(previewDto); - assertThat(testDefault.getData().get(0).length).isEqualTo(2); - assertThat(testDefault.getData().size()).isEqualTo(1); - - previewDto = new PreviewDto(manifest, "select * from nested_table n cross join lateral (select n.a1[1]) l(a1)", null); - testDefault = preview(previewDto); - assertThat(testDefault.getData().get(0).length).isEqualTo(2); - assertThat(testDefault.getData().size()).isEqualTo(1); - - previewDto = new PreviewDto(manifest, "select l.a1 from nested_table n cross join lateral (select n.a1[1]) l(a1)", null); - testDefault = preview(previewDto); - assertThat(testDefault.getColumns().get(0).getType()).isEqualTo("INTEGER"); - assertThat(testDefault.getData().get(0)[0]).isEqualTo(1); - } -} diff --git a/wren-tests/src/test/resources/accounts b/wren-tests/src/test/resources/accounts deleted file mode 100644 index 66c908f58..000000000 --- a/wren-tests/src/test/resources/accounts +++ /dev/null @@ -1,7 +0,0 @@ -pekochan pekopeko -ina wah -gura a -wren ignored -empty -canner ignored - emptypass \ No newline at end of file diff --git a/wren-tests/src/test/resources/bigquery/TestResultSetMetadata.json b/wren-tests/src/test/resources/bigquery/TestResultSetMetadata.json deleted file mode 100644 index 6c5f06cf1..000000000 --- a/wren-tests/src/test/resources/bigquery/TestResultSetMetadata.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "Nation", - "refSql": "select * from wrenai.tpch_tiny.nation", - "columns": [ - { - "name": "nationkey", - "expression": "n_nationkey", - "type": "int4" - }, - { - "name": "name", - "expression": "n_name", - "type": "varchar" - }, - { - "name": "regionkey", - "expression": "n_regionkey", - "type": "int4" - }, - { - "name": "comment", - "expression": "n_comment", - "type": "varchar" - } - ], - "primaryKey": "nationkey" - } - ], - "views": [ - { - "name": "selectNation", - "statement": "select * from Nation" - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/bigquery/TestWireProtocolWithBigquery.json b/wren-tests/src/test/resources/bigquery/TestWireProtocolWithBigquery.json deleted file mode 100644 index 4cdb3daec..000000000 --- a/wren-tests/src/test/resources/bigquery/TestWireProtocolWithBigquery.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "relationships": [ - { - "name": "OrdersLineitem", - "models": [ - "Orders", - "Lineitem" - ], - "joinType": "ONE_TO_MANY", - "condition": "Orders.orderkey = Lineitem.orderkey" - }, - { - "name": "TableOrder", - "models": [ - "Table", - "Order" - ], - "joinType": "ONE_TO_MANY", - "condition": "\"Table\".\"select\" = \"Order\".\"alter\"" - } - ], - "models": [ - { - "name": "Orders", - "tableReference": { - "catalog": "wrenai", - "schema": "tpch_tiny", - "table": "orders" - }, - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "int4" - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "int4" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "OrderStatus" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float8" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - }, - { - "name": "lineitems", - "type": "Lineitem", - "relationship": "OrdersLineitem" - } - ], - "primaryKey": "orderkey" - }, - { - "name": "Lineitem", - "refSql": "select * from wrenai.tpch_tiny.lineitem", - "columns": [ - { - "name": "orderkey", - "expression": "l_orderkey", - "type": "int4" - }, - { - "name": "partkey", - "expression": "l_partkey", - "type": "int4" - }, - { - "name": "linenumber", - "expression": "l_linenumber", - "type": "int4" - }, - { - "name": "extendedprice", - "expression": "l_extendedprice", - "type": "float8" - }, - { - "name": "discount", - "expression": "l_discount", - "type": "float8" - }, - { - "name": "shipdate", - "expression": "l_shipdate", - "type": "date" - }, - { - "name": "orderkey_linenumber", - "type": "varchar", - "expression": "concat(l_orderkey, l_linenumber)" - }, - { - "name": "orders", - "type": "Orders", - "relationship": "OrdersLineitem" - } - ], - "primaryKey": "orderkey_linenumber" - }, - { - "name": "Table", - "refSql": "select * from wrenai.tpch_tiny.customer", - "columns": [ - { - "name": "select", - "expression": "c_custkey", - "type": "int4" - }, - { - "name": "column", - "expression": "c_name", - "type": "varchar" - }, - { - "name": "order", - "type": "Order", - "relationship": "TableOrder" - }, - { - "name": "totalprice", - "type": "float8", - "expression": "sum(\"order\".\"integer\")", - "isCalculated": true - } - ], - "primaryKey": "select" - }, - { - "name": "Order", - "refSql": "select * from wrenai.tpch_tiny.orders", - "columns": [ - { - "name": "alter", - "expression": "o_custkey", - "type": "int4" - }, - { - "name": "integer", - "expression": "o_totalprice", - "type": "float8" - } - ], - "primaryKey": "alter" - } - ], - "metrics": [ - { - "name": "Delete", - "baseObject": "Table", - "dimension": [ - { - "name": "key", - "type": "int4", - "expression": "\"select\"" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(\"order\".\"integer\")" - } - ], - "timeGrain": [] - } - ], - "metrics": [ - { - "name": "Revenue", - "baseObject": "Lineitem", - "dimension": [ - { - "name": "orderkey", - "type": "int4", - "expression": "orderkey" - }, - { - "name": "orderdate", - "type": "date", - "expression": "orders.orderdate" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(extendedprice)" - } - ], - "timeGrain": [] - } - ], - "views": [ - { - "name": "selectOrders", - "statement": "select * from Orders" - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/cache/cache_bigquery_mdl.json b/wren-tests/src/test/resources/cache/cache_bigquery_mdl.json deleted file mode 100644 index 6faf2dbfd..000000000 --- a/wren-tests/src/test/resources/cache/cache_bigquery_mdl.json +++ /dev/null @@ -1,127 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "cml_temp", - "models": [ - { - "name": "BigQueryType", - "refSql": "select * from wrenai.cml_temp.cache_bigquery_type", - "columns": [ - { - "name": "c_string", - "type": "string" - }, - { - "name": "c_bytes", - "type": "bytea" - }, - { - "name": "c_integer", - "type": "integer" - }, - { - "name": "c_float", - "type": "double" - }, - { - "name": "c_numeric", - "type": "numeric" - }, - { - "name": "c_bignumeric", - "type": "numeric" - }, - { - "name": "c_boolean", - "type": "boolean" - }, - { - "name": "c_timestamp", - "type": "timestamp" - }, - { - "name": "c_date", - "type": "date" - }, - { - "name": "c_datetime", - "type": "timestamp" - }, - { - "name": "c_time", - "type": "time" - }, - { - "name": "c_json", - "type": "json" - }, - { - "name": "c_interval", - "type": "interval" - } - ], - "primaryKey": "c_string" - } - ], - "metrics": [ - { - "cached": "true", - "name": "PrintBigQueryType", - "baseObject": "BigQueryType", - "dimension": [ - { - "name": "c_string", - "type": "string" - }, - { - "name": "c_bytes", - "type": "bytea" - }, - { - "name": "c_integer", - "type": "integer" - }, - { - "name": "c_float", - "type": "double" - }, - { - "name": "c_numeric", - "type": "numeric" - }, - { - "name": "c_boolean", - "type": "boolean" - }, - { - "name": "c_timestamp", - "type": "timestamp" - }, - { - "name": "c_date", - "type": "date" - }, - { - "name": "c_datetime", - "type": "timestamp" - } - ], - "measure": [ - { - "name": "print_bigquery_type", - "type": "string", - "expression": "c_string" - } - ], - "timeGrain": [ - { - "name": "c_timestamp", - "refColumn": "c_timestamp", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/cache/cache_frequently_mdl.json b/wren-tests/src/test/resources/cache/cache_frequently_mdl.json deleted file mode 100644 index 32ea2037b..000000000 --- a/wren-tests/src/test/resources/cache/cache_frequently_mdl.json +++ /dev/null @@ -1,109 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "Orders", - "refSql": "select * from wrenai.tpch_tiny.orders", - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "integer" - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "integer" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "string" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float" - }, - { - "name": "customer", - "type": "Customer", - "relationship": "OrdersCustomer" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - } - ], - "primaryKey": "orderkey", - "cached": "true" - }, - { - "name": "Customer", - "refSql": "select * from wrenai.tpch_tiny.customer", - "columns": [ - { - "name": "custkey", - "expression": "c_custkey", - "type": "integer" - }, - { - "name": "name", - "expression": "c_name", - "type": "string" - }, - { - "name": "orders", - "type": "Orders", - "relationship": "OrdersCustomer" - } - ], - "primaryKey": "custkey", - "cached": "true" - } - ], - "relationships": [ - { - "name": "OrdersCustomer", - "models": [ - "Orders", - "Customer" - ], - "joinType": "MANY_TO_ONE", - "condition": "Orders.custkey = Customer.custkey" - } - ], - "metrics": [ - { - "cached": "true", - "name": "RefreshFrequently", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey", - "type": "integer" - } - ], - "measure": [ - { - "name": "revenue", - "type": "integer", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ], - "refreshTime": "5s" - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/cache/cache_mdl.json b/wren-tests/src/test/resources/cache/cache_mdl.json deleted file mode 100644 index d8e0ddb20..000000000 --- a/wren-tests/src/test/resources/cache/cache_mdl.json +++ /dev/null @@ -1,217 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "Orders", - "refSql": "select * from wrenai.tpch_tiny.orders", - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "integer" - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "integer" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "string" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float" - }, - { - "name": "customer", - "type": "Customer", - "relationship": "OrdersCustomer" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - } - ], - "primaryKey": "orderkey", - "cached": "true" - }, - { - "name": "Customer", - "refSql": "select * from wrenai.tpch_tiny.customer", - "columns": [ - { - "name": "custkey", - "expression": "c_custkey", - "type": "integer" - }, - { - "name": "name", - "expression": "c_name", - "type": "string" - }, - { - "name": "orders", - "type": "Orders", - "relationship": "OrdersCustomer" - } - ], - "primaryKey": "custkey" - }, - { - "name": "RemoveCustomer", - "refSql": "select * from wrenai.tpch_tiny.customer", - "columns": [ - { - "name": "custkey", - "expression": "c_custkey", - "type": "integer" - }, - { - "name": "name", - "expression": "c_name", - "type": "string" - }, - { - "name": "orders", - "type": "Orders", - "relationship": "OrdersCustomer" - } - ], - "primaryKey": "custkey", - "cached": "true" - } - ], - "relationships": [ - { - "name": "OrdersCustomer", - "models": [ - "Orders", - "Customer" - ], - "joinType": "MANY_TO_ONE", - "condition": "Orders.custkey = Customer.custkey" - } - ], - "metrics": [ - { - "cached": "true", - "name": "Revenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey", - "type": "integer" - } - ], - "measure": [ - { - "name": "revenue", - "type": "integer", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "cached": "true", - "name": "unqualified", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey", - "type": "integer" - }, - { - "name": "fake", - "type": "integer" - } - ], - "measure": [ - { - "name": "revenue", - "type": "integer", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "name": "AvgRevenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey", - "type": "integer" - } - ], - "measure": [ - { - "name": "avg_revenue", - "type": "double", - "expression": "avg(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "cached": "true", - "name": "ForDropTable", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey", - "type": "integer" - } - ], - "measure": [ - { - "name": "revenue", - "type": "integer", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/cache/cache_reload_1_mdl.json b/wren-tests/src/test/resources/cache/cache_reload_1_mdl.json deleted file mode 100644 index a946f5dbc..000000000 --- a/wren-tests/src/test/resources/cache/cache_reload_1_mdl.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "Orders", - "refSql": "select * from wrenai.tpch_tiny.orders", - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "integer" - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "integer" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "string" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - } - ], - "primaryKey": "orderkey" - } - ], - "metrics": [ - { - "cached": "true", - "name": "Revenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey", - "type": "integer" - } - ], - "measure": [ - { - "name": "revenue", - "type": "integer", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ], - "refreshTime": "5m" - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/cache/cache_reload_2_mdl.json b/wren-tests/src/test/resources/cache/cache_reload_2_mdl.json deleted file mode 100644 index ce30293b3..000000000 --- a/wren-tests/src/test/resources/cache/cache_reload_2_mdl.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "Orders", - "refSql": "select * from wrenai.tpch_tiny.orders", - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "integer" - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "integer" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "string" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - } - ], - "primaryKey": "orderkey" - } - ], - "metrics": [ - { - "cached": "true", - "name": "Revenue_After", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey", - "type": "integer" - } - ], - "measure": [ - { - "name": "revenue", - "type": "integer", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ], - "refreshTime": "10m" - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/cache/cache_reload_3_mdl.json b/wren-tests/src/test/resources/cache/cache_reload_3_mdl.json deleted file mode 100644 index 157bb965b..000000000 --- a/wren-tests/src/test/resources/cache/cache_reload_3_mdl.json +++ /dev/null @@ -1,69 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "Orders", - "refSql": "select * from wrenai.tpch_tiny.orders", - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "integer" - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "integer" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "string" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - } - ], - "primaryKey": "orderkey" - } - ], - "metrics": [ - { - "cached": "true", - "name": "Revenue_Fake", - "baseObject": "Orders", - "dimension": [ - { - "name": "custkey_f", - "type": "integer" - } - ], - "measure": [ - { - "name": "revenue_f", - "type": "integer", - "expression": "sum(totalprice_f)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ], - "refreshTime": "10m" - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/csv/orders/orders-2.csv b/wren-tests/src/test/resources/csv/orders/orders-2.csv deleted file mode 100644 index 14172292d..000000000 --- a/wren-tests/src/test/resources/csv/orders/orders-2.csv +++ /dev/null @@ -1,83 +0,0 @@ -order_id,customer_id,status,purchase_timestamp,approved_timestamp,delivered_carrier_date,delivered_customer_date,estimated_delivery_date -0b382db57a557ff7703eaba5e991e7fb,0732c0881c70ebcda536a4b14e9db106,delivered,2022/11/2 12:04:00,2022/11/2 12:15:00,2022/11/3 22:25,2022/11/13 19:28,2022/11/29 0:00 -5fa37b0775f5467f987580b059bce54a,8e6e4cf2ce41cda407074b416f893269,delivered,2022/8/30 12:47:00,2022/8/31 13:45:00,2022/9/1 20:07,2022/9/10 15:33,2022/9/27 0:00 -08cc8c614786867bb0a845cd117d349b,79c153310ee3cfd3c2a760c9798b179a,shipped,2022/8/30 21:00:00,2022/9/2 13:50:00,2022/9/7 0:04,,2022/9/21 0:00 -2bcf1f79964f8b4f4f62f19441601b1a,711fff4266b53bae9de25be1473dc0bc,delivered,2022/9/3 2:42:00,2022/9/3 2:55:00,2022/9/6 18:42,2022/11/9 1:33,2022/10/16 0:00 -e71f1d602c3b94eb593d48a61a2163fd,7f02a8230a3ff5c0888ea3a2c8ae618c,delivered,2022/9/1 21:42:00,2022/9/1 22:07:00,2022/9/7 0:07,2022/9/15 19:42,2022/9/29 0:00 -efa7f60c6fa051986a5d8f220106b74f,a271788c6bad8633d39fac1fb388f677,delivered,2023/8/20 10:39:00,2023/8/20 14:55:00,2023/8/22 14:17,2023/8/27 15:49,2023/9/6 0:00 -bff7e590732738aa522782dc42dc7705,a4952f2f27f9fd084ec13468dcdf677b,delivered,2022/12/4 23:48:00,2022/12/6 2:39:00,2022/12/8 2:21,2022/12/22 22:32,2022/12/28 0:00 -0af4a846cbf75b456c934b786d683618,7194be434cc4eb4eb1a7a44bb4e9e24d,delivered,2022/8/29 20:25:00,2022/8/31 2:44:00,2022/9/1 20:07,2022/9/11 20:11,2022/9/25 0:00 -1ea7acde8dacf11a098d0b85b13cdc0e,281fb8b9868caf9889214e5a8d56e271,delivered,2022/10/27 16:21:00,2022/10/27 17:31:00,2022/11/1 0:07,2022/11/6 20:17,2022/11/22 0:00 -34d0587652282a8e4f05da5083e1f276,571bc28cad276e1be2a13b7ecb386a44,delivered,2022/8/29 23:47:00,2022/8/31 13:50:00,2022/9/1 20:07,2022/9/13 10:24,2022/9/27 0:00 -d237eb0a6caf6cc0d9cf5ba7a815c077,115847c3660c596c1bc526c4fd0c5b7c,delivered,2023/1/10 15:54:00,2023/1/10 16:10:00,2023/1/15 20:28,2023/1/23 22:24,2023/2/9 0:00 -ef442e129f56ec1234a402fc824686df,8c026df875ce27008c74eb034ce7020d,delivered,2023/6/30 18:30:00,2023/6/30 19:35:00,2023/7/3 6:58,2023/7/4 0:38,2023/7/20 0:00 -cc5e04828d40b15276efba4b0cd1f566,9a152225eeff3dced495ddfc1ee07f25,delivered,2023/4/18 15:08:00,2023/4/18 15:45:00,2023/4/19 19:06,2023/4/26 18:41,2023/5/14 0:00 -3689c2503baba1c0879d94cdbe6d6d60,176db5144496b2af02a70eff67f81d11,delivered,2022/8/29 4:40:00,2022/8/29 5:24:00,2022/8/30 16:59,2022/9/6 22:44,2022/9/20 0:00 -6b8a03d40f75b75ec65ed5ba13d80f95,72a4878a79935a45e5acec3b541af15a,delivered,2022/10/24 22:40:00,2022/10/24 22:56:00,2022/10/25 21:23,2022/11/9 18:17,2022/12/11 0:00 -8df1ba8711787d5cfe3b90f535d04dc4,547a0b4f2de7e4276e3cf1c92f15dcd6,delivered,2022/10/30 21:18:00,2022/10/31 16:55:00,2022/11/3 20:07,2022/11/13 20:18,2022/11/24 0:00 -5f66067164a5ca7adf49a87bfe4cccc1,319481c968caf99d5daa782270571d51,delivered,2023/7/31 18:29:00,2023/7/31 19:31:00,2023/8/2 17:46,2023/8/21 22:08,2023/8/20 0:00 -6ae192daf1b6e9b99225e7300b79df48,ac12022931d88a2a8688a62d0f583f51,delivered,2022/9/2 20:38:00,2022/9/2 20:54:00,2022/9/7 0:04,2022/9/12 17:55,2022/9/27 0:00 -1e0b82a0da7f09ea9ba1b82dfaf4fa23,5ffbac5f715d934689592f398af9130a,delivered,2023/4/19 23:15:00,2023/4/20 6:11:00,2023/4/23 20:08,2023/5/14 16:03,2023/5/22 0:00 -e96945cd2dc4e28e0089daf1c02476db,a5f95b21855ece6f75ed48e39bdba34c,delivered,2023/6/11 16:59:00,2023/6/11 17:20:00,2023/6/12 13:08,2023/6/23 11:07,2023/7/13 0:00 -869bb454aa7fd93af2e620c1d34d5e49,be55f2be3c967a6b77b75158d8d6260d,delivered,2022/9/2 17:37:00,2022/9/4 15:45:00,2022/9/5 20:13,2022/9/13 20:39,2022/9/28 0:00 -0be31296e8456f2017743c363de5a1da,7ca107237a9bd4f07595806d73b75edd,delivered,2022/9/3 17:30:00,2022/9/3 17:46:00,2022/9/5 20:13,2022/9/12 21:53,2022/9/26 0:00 -465c108e33e2b7e6953f020140a457ba,46f6a5bae4ef97e9769697f718523353,delivered,2022/9/4 15:18:00,2022/9/5 20:55:00,2022/9/8 19:21,2022/9/20 15:58,2022/9/27 0:00 -cb00b252d2c836eeeb1d73ec439a0849,3f4c1215f72bf4746c1cb05b436e64f1,delivered,2022/9/6 18:33:00,2022/9/6 18:50:00,2022/9/11 19:48,2022/9/17 13:22,2022/9/28 0:00 -90afb8151d6aca71ae7b52a029ebc165,3faee0bb2909b67bc79d9f5650f728c2,delivered,2022/11/3 12:43:00,2022/11/3 12:56:00,2022/11/16 21:31,2022/11/22 21:41,2022/11/28 0:00 -e56a1cb152fd9b915de07e0f4f5b462b,1f468c5a64641a32137d557ade625dbf,delivered,2022/9/6 9:52:00,2022/9/6 16:05:00,2022/9/11 19:27,2022/10/5 19:03,2022/10/17 0:00 -d9956b0805e324db3f2a546ef216c10b,10a86619816f9d2afce3f45b04aabc71,delivered,2022/10/10 14:30:00,2022/10/10 15:06:00,2022/10/11 15:47,2022/10/18 22:52,2022/11/1 0:00 -43f32db0dedd975e294e98ce23b24661,1217bf0350d846210fecc72bfa663ce1,delivered,2023/5/11 17:08:00,2023/5/15 4:12:00,2023/5/16 13:24,2023/5/21 22:47,2023/5/28 0:00 -3710f61b45bb40db596e352722b6937e,e54e09bbe2be2674c611aa7a6456a8e7,delivered,2022/9/7 18:43:00,2022/9/7 18:55:00,2022/9/11 19:48,2022/9/27 19:42,2022/10/9 0:00 -9e7752c172e3994115a2cd609a18de29,c2b15e2fdaf53bfb90b245f2ad21d94d,delivered,2022/9/4 14:28:00,2022/9/4 14:43:00,2022/9/5 20:13,2022/9/11 15:50,2022/9/22 0:00 -f1860618b7674572f1f08801ab36833f,f3fd434cefcc530bec7e71f31a914b60,delivered,2022/9/6 8:34:00,2022/9/8 10:25:00,2022/9/11 19:47,2022/9/15 13:37,2022/9/26 0:00 -60e233aaaa492c07368a9bac1c0ee2d4,0c7bb23d01c5c4c485b8967dbacb97b1,delivered,2022/10/9 19:26:00,2022/10/9 19:42:00,2022/10/10 21:42,2022/10/17 15:03,2022/10/26 0:00 -ed08d32792c528ba9942fd6b9e95cadb,c99b0b8a41674337a4165c53ceb7139b,delivered,2022/8/30 16:37:00,2022/8/30 16:45:00,2022/8/31 20:03,2022/9/11 18:38,2022/9/21 0:00 -1b0bc119ea5ac37e73e2275afc7904ee,75e945badd2a39af63ee8c8b05af8fb3,delivered,2023/8/14 14:19:00,2023/8/14 14:30:00,2023/8/21 11:53,2023/8/23 3:24,2023/8/23 0:00 -09f8cd8a102b3f3fa2d5db0c6aee489a,ce5c2647d9125a115851c01b5b356426,delivered,2022/9/15 16:35:00,2022/9/15 16:50:00,2022/9/19 18:58,2022/9/28 19:38,2022/10/11 0:00 -75adb6f5207887f03b547194819216fa,4d5e97a1930e2147547bbbf81715ceb7,delivered,2023/8/11 19:36:00,2023/8/13 18:04:00,2023/8/14 7:29,2023/8/21 19:32,2023/8/23 0:00 -dc825a422ff7a8e462852fc476ba5686,812620275ae6895f00773306dfc75769,delivered,2022/9/27 18:42:00,2022/9/27 18:56:00,2022/9/29 19:38,2022/10/9 14:03,2022/10/25 0:00 -c285661a8320d062c60574830bae4199,537b2215fad860dff368ec7bcf1dce65,delivered,2023/1/3 10:50:00,2023/1/3 10:58:00,2023/1/9 23:38,2023/1/22 23:28,2023/2/1 0:00 -4bfda23ff0ed8665aa9113bfb4130bf3,a42fce0a9fe2e8ba2f7b2b0dbaa4b626,delivered,2023/7/26 14:01:00,2023/7/26 14:40:00,2023/8/1 17:33,2023/8/3 19:21,2023/8/9 0:00 -3c140d933d3475ec823f9b748ca5c49f,d64c957183fc8d75e536e89468feccda,delivered,2022/12/12 11:30:00,2022/12/12 12:32:00,2022/12/19 1:39,2023/1/9 17:43,2023/1/10 0:00 -2d472b4b2d08108565852ca0782507f2,7c3c95a24ec40f62f817a4b46fa1130c,delivered,2022/9/14 23:46:00,2022/9/15 0:20:00,2022/9/19 21:47,2022/9/25 13:56,2022/10/3 0:00 -df85c824523500d4066a0dbdb5d95bed,39d6658037b1b5a07d0a24d423f0bd19,delivered,2022/2/21 18:35:00,2022/2/22 10:03:00,2022/2/24 7:58,2022/3/1 16:39,2022/3/16 0:00 -94781b7e571ded2ff6f80434f6fe2a43,4442ce3a2d4bb4bc6c5752a8dfb37806,delivered,2022/9/25 13:55:00,2022/9/25 14:06:00,2022/9/27 18:58,2022/10/4 18:58,2022/10/20 0:00 -6fd59e3ae7e24c50131f6bc97c4c7776,f41666558f4e35056a445c27c2ac3d8b,delivered,2022/10/31 20:32:00,2022/11/1 20:45:00,2022/11/3 22:25,2022/11/13 16:42,2022/11/21 0:00 -5f5a937b8e63ac95df2db115354de971,ed71d2c3a3ac53a772b0e8e9db89cc20,delivered,2022/12/23 14:11:00,2022/12/27 4:14:00,2023/1/3 23:08,2023/2/8 18:53,2023/1/30 0:00 -9322ed60e16ee4ff1efe8145cb66060f,79e3be07b961e4d6df3d52de6a560c47,delivered,2022/9/1 14:38:00,2022/9/1 14:50:00,2022/9/4 21:11,2022/9/15 18:57,2022/9/26 0:00 -f55a684badae11bd4d494dd474d82130,3c984113b6e566d2dd37ded86c65eb0a,delivered,2022/9/6 10:21:00,2022/9/6 10:38:00,2022/9/8 19:51,2022/9/14 14:10,2022/9/26 0:00 -894f6e0db677f7c543348befc4ecc7da,9b1d5f24edbeae5ce310d1fe6a15fd8d,delivered,2022/9/7 20:32:00,2022/9/9 6:34:00,2022/9/15 17:33,2022/9/20 17:27,2022/9/26 0:00 -53d6fdda7e6cd60c16d5051f00ac2af3,f33ce5c93bb775dce8f1ee9e1055e65e,delivered,2022/8/29 22:35:00,2022/8/29 22:45:00,2022/8/31 19:36,2022/9/5 19:16,2022/9/15 0:00 -c0abd38f3c86c3d4996c94bcf99df796,36f58303deca083523374389d472bfec,delivered,2022/8/29 9:29:00,2022/8/30 9:35:00,2022/8/31 19:37,2022/9/6 22:15,2022/9/20 0:00 -36db19001f33a6f23042adbc4a0e30a5,2421c7be6e7456c06f434ff26cb4223a,delivered,2022/8/28 23:02:00,2022/8/28 23:31:00,2022/8/30 17:17,2022/9/8 20:51,2022/9/19 0:00 -4f8fb49bd955f713c79333a0a2d9da57,dde98f2e220592ae6068bb273ec5c11b,delivered,2022/12/26 11:50:00,2022/12/26 12:49:00,2022/12/27 17:54,2023/1/10 15:36,2023/2/1 0:00 -b9ae09da0b039cc190c9d1cb607a4392,bf5b4a36dd34728d4ef30e6085f22ab3,delivered,2022/11/2 10:58:00,2022/11/2 11:10:00,2022/11/3 22:25,2022/11/10 20:54,2022/11/28 0:00 -edbfaeb8ad1b74d2dd3fa417465617fe,e24a84b778dca41f3760946e3ececa16,delivered,2023/4/19 3:39:00,2023/4/19 4:21:00,2023/4/19 19:06,2023/5/7 13:49,2023/5/21 0:00 -2e9d8685e015feaba98d02e5544583f6,d1c1552729f4a36ad3f2e9f2103681e1,delivered,2022/8/30 13:54:00,2022/8/30 14:05:00,2022/8/31 19:33,2022/9/6 21:57,2022/9/22 0:00 -c1eab66ff6c440a9f5d92f83b8f10550,31c45b49a140bc7c8a9bed80e74e8660,delivered,2022/10/29 3:49:00,2022/10/29 4:05:00,2022/11/1 0:22,2022/11/9 19:02,2022/11/24 0:00 -1457abef78cd241e85fd946503cb4e16,344ee65ac116bd585ab8ee04a18597e5,delivered,2022/10/27 13:13:00,2022/10/27 13:30:00,2022/11/1 0:03,2022/11/7 19:16,2022/11/13 0:00 -12c860cdab62139623897892199fea4f,714b234caa9995c089fcd8c7d7a77490,delivered,2023/4/17 8:43:00,2023/4/17 16:35:00,2023/4/18 18:28,2023/5/8 18:26,2023/5/11 0:00 -9af38cf8cc5906174070c0c591e630a5,078770bdd7ae21c5766a84d4cc70d135,delivered,2023/8/22 16:21:00,2023/8/22 16:30:00,2023/8/23 13:18,2023/8/27 17:12,2023/9/14 0:00 -17e8356af05cf890ac4604347b3c17a6,e6db53dc3619628a8e024f3e1f4abc86,delivered,2022/10/10 19:47:00,2022/10/10 19:56:00,2022/10/13 20:32,2022/10/19 22:32,2022/11/3 0:00 -0e6386e1cb625fe4fdbd3d101d2cb687,6482c915ec997dacbb610e3e6cf6c6bd,delivered,2022/9/1 0:23:00,2022/9/1 1:32:00,2022/9/1 20:09,2022/9/8 18:29,2022/9/21 0:00 -826456a3605c466dec176f032fa660a9,1ed4be846471fc0c529d51f2f8274c0a,delivered,2022/9/4 13:07:00,2022/9/4 13:24:00,2022/9/5 20:13,2022/9/12 22:37,2022/9/25 0:00 -a7e3fbb3111b4a3c0907fbfad7690ffd,a91aaf744244d91f36c917061c2568b0,delivered,2023/1/12 9:40:00,2023/1/12 9:54:00,2023/1/16 21:25,2023/1/22 15:49,2023/2/5 0:00 -ff098b9342213641be5da8163f0fcf2c,96247f13c0086e9d96b945227b7f8f25,delivered,2022/11/1 14:42:00,2022/11/4 5:05:00,2022/11/16 21:29,2022/11/22 20:18,2022/11/27 0:00 -a739bf4717343c5f9c84196b61a9c53f,daee6b701a5a602c82bc88c89b25e03b,delivered,2022/9/7 19:07:00,2022/9/8 19:03:00,2022/9/13 18:50,2022/9/20 17:30,2022/9/27 0:00 -2ca1528ba222dcef1b182632376e53a0,44d89c65f6578eb86f1db3cefdbdf9e6,delivered,2023/1/9 0:33:00,2023/1/9 1:34:00,2023/1/10 20:15,2023/1/24 20:18,2023/2/23 0:00 -5a902cc5a20f8cd076f116d16d5aef9d,ec5637e1b926c79b5472bd41d67882f8,delivered,2022/10/3 20:12:00,2022/10/3 20:25:00,2022/10/6 23:03,2022/10/18 16:17,2022/10/30 0:00 -17774450f243f686546b04633a04dbdb,2e28b2a4b665efc5157224222743d141,delivered,2022/12/16 1:04:00,2022/12/16 1:17:00,2022/12/22 22:24,2023/1/22 17:15,2023/1/17 0:00 -13b4f8c4b570d25d95bfd3c915ed9c38,3affba856e05494582eba561ff675db0,delivered,2023/1/27 16:50:00,2023/1/30 4:31:00,2023/1/30 23:26,2023/3/14 15:43,2023/3/9 0:00 -24536ae68dcaea969641d76fc4cc5e4a,6db251bad58edca6d53d44638936741a,delivered,2023/6/19 16:21:00,2023/6/21 4:36:00,2023/6/21 13:15,2023/6/25 15:29,2023/6/29 0:00 -ca47b8674b4881264380ff336ae5c195,9a91fb951e7fd3f4adf713cff82acf3d,delivered,2023/4/10 18:42:00,2023/4/10 18:55:00,2023/4/11 21:57,2023/4/13 22:26,2023/4/26 0:00 -4cfdd4464ee3dbf59c17a69045429af4,3a1b9fe3e0d0d7541f37438799c97571,delivered,2022/8/30 11:39:00,2022/8/31 2:50:00,2022/9/1 20:09,2022/9/12 19:50,2022/9/25 0:00 -8bcb04c1ca645d109ed37389fda5dbb0,dd977fc3619f271f431181f90e305a1f,delivered,2022/9/1 21:53:00,2022/9/1 22:25:00,2022/9/5 20:13,2022/10/5 9:47,2022/9/21 0:00 -442693e8e705ad1f9c91f762f0d297bc,0049e8442c2a3e4a8d1ff5a9549abd53,delivered,2022/8/28 21:16:00,2022/8/28 21:25:00,2022/8/31 19:26,2022/9/8 15:36,2022/9/20 0:00 -e9bf6a3daf9c2966192eaa98b5afb617,9020b6ec57368057e07cb365b54b9c90,delivered,2022/8/28 18:29:00,2022/8/28 18:44:00,2022/8/31 20:03,2022/9/4 14:43,2022/9/15 0:00 -b4c80521e552d11e209d1388067ce814,3a486addcf71802e8445e303ab0a09e3,delivered,2022/11/9 22:15:00,2022/11/9 22:31:00,2022/11/14 21:23,2022/12/12 22:46,2023/1/2 0:00 -c40c104dd1bde11aba73864c16a42f21,80cf55a439bbb373aea40a08515fb39b,delivered,2022/8/29 13:34:00,2022/8/29 13:45:00,2022/8/31 19:42,2022/9/5 19:32,2022/9/18 0:00 -a844f41afb956df11c5b6940656a3682,80fd5c24c23e4e64a13561bbd1b62ea5,delivered,2023/1/2 16:22:00,2023/1/2 17:00:00,2023/1/3 23:08,2023/1/15 15:36,2023/2/1 0:00 -754effa06b71f54d7f439034c128b509,c8d216b178057e7b76dad138f9bb2aae,delivered,2023/7/15 18:16:00,2023/7/15 18:25:00,2023/7/17 13:52,2023/7/23 20:12,2023/8/10 0:00 -dda0b2b9a46f5c43da98422227eaaccf,fc5795f8f743ecd3ccc0f4d89a50438a,delivered,2023/7/31 11:34:00,2023/8/2 5:30:00,2023/8/3 16:29,2023/8/14 17:37,2023/8/16 0:00 -742ba39f629d08705cf64769ff41dd3e,3453cda7c1f2565886229607f31e7ce1,delivered,2022/12/28 16:34:00,2022/12/28 16:47:00,2023/1/3 23:22,2023/1/4 17:52,2023/1/19 0:00 -bfb1d0f7664c36a532d74c4cf0da37af,811e55e5f48c8f37832963ff509ce85b,delivered,2022/8/31 15:05:00,2022/9/1 17:25:00,2022/9/4 21:21,2022/9/11 20:45,2022/9/22 0:00 \ No newline at end of file diff --git a/wren-tests/src/test/resources/csv/orders/orders.csv b/wren-tests/src/test/resources/csv/orders/orders.csv deleted file mode 100644 index d0c7a78cb..000000000 --- a/wren-tests/src/test/resources/csv/orders/orders.csv +++ /dev/null @@ -1,100 +0,0 @@ -order_id,customer_id,status,purchase_timestamp,approved_timestamp,delivered_carrier_date,delivered_customer_date,estimated_delivery_date -76754c0e642c8f99a8c3fcb8a14ac700,f6c39f83de772dd502809cee2fee4c41,delivered,2022/10/26 9:31:00,2022/10/26 9:49:00,2022/10/26 21:33,2022/11/1 21:17,2022/11/22 0:00 -607911c4ac62f9038b4ec434673e486e,7cec2ad3ecf1b10ce543161225a13a97,delivered,2023/8/6 16:41:00,2023/8/6 16:50:00,2023/8/8 11:09,2023/8/13 17:57,2023/8/22 0:00 -0af28d87520565eb3b57c9b2abe1a2cc,0a209a88c2e3dc2981c79ad85c558059,delivered,2022/10/5 19:23:00,2022/10/5 20:28:00,2022/10/6 17:15,2022/10/17 20:58,2022/11/6 0:00 -0d91fd5b8475f8f0576a6e8f90c6497d,9f34131462cd5edccdc9d4db9f7d2bbc,delivered,2023/5/10 14:49:00,2023/5/11 14:58:00,2023/5/15 7:43,2023/5/21 10:48,2023/5/29 0:00 -256ccc96b2c931006d95ba7a05181037,2a381888bc87c4fde2eda8bedb291234,delivered,2023/1/15 19:26:00,2023/1/15 19:35:00,2023/1/18 1:33,2023/1/19 13:32,2023/2/8 0:00 -e130d3f737127ae52681b9338aea9b64,b9da524b08224eaff1bf76ef4d4299ac,delivered,2023/5/25 14:41:00,2023/5/26 10:19:00,2023/5/28 13:48,2023/6/5 9:02,2023/6/19 0:00 -05d61bb749461f4805dbda51f767fa47,80f16375ce928674fe11f2e5130208e1,delivered,2022/8/29 19:04:00,2022/8/29 19:15:00,2022/8/31 19:37,2022/9/15 18:42,2022/10/10 0:00 -561cdd2accb4b96049e2f85972d8bffe,6ed3ba51865085a8de8bb730cefc8a32,delivered,2023/6/6 13:36:00,2023/6/6 13:53:00,2023/6/7 13:49,2023/6/25 19:29,2023/7/20 0:00 -63b0abee9c82e79c3b6e860d070f2c62,b51ecad2f840841fc7f24a4aca209f01,delivered,2022/8/28 21:45:00,2022/8/28 21:55:00,2022/8/31 19:26,2022/9/9 17:05,2022/9/19 0:00 -cf76d482b013f8af6dc046a3001c1c4f,04eafb40a16989307464f27f1fed8907,delivered,2023/7/4 13:08:00,2023/7/5 16:25:00,2023/7/6 9:09,2023/7/12 20:26,2023/8/6 0:00 -cc4687e4e102c1c8c606a5a0a8e475db,079e85f42f5af80c74240b97b7a4dee1,delivered,2022/10/31 20:13:00,2022/11/1 20:25:00,2022/11/3 22:25,2022/11/16 19:37,2022/12/6 0:00 -820349ed7a25bbfa196bb4f9a28442f2,687f63c64f1b99fbd97d3d1e940c781a,delivered,2022/11/4 9:35:00,2022/11/4 9:50:00,2022/11/16 21:58,2022/11/27 18:32,2022/11/29 0:00 -12f2f3174deba94de2aa43ad4adf6d3e,cc4fef4299b231a913af5205feed5e36,delivered,2022/10/11 9:50:00,2022/10/13 21:26:00,2022/10/17 20:14,2022/10/30 20:16,2022/11/16 0:00 -fb973be52c6622812266932dc2152017,652809adfb5055cf87dd32aca5a8b760,delivered,2022/8/29 16:07:00,2022/8/29 16:27:00,2022/8/31 19:37,2022/9/8 20:55,2022/9/20 0:00 -29dba01f92da927e611d340bc135f679,11eb7497f0981fd5b7cb235f4118c034,delivered,2023/4/18 18:08:00,2023/4/19 8:12:00,2023/4/19 19:06,2023/4/27 20:12,2023/5/15 0:00 -8a4f504a9826004fb1b0957a12aad33a,8d4fbbdcabdfc2f9b1f52cd523ea5865,delivered,2023/8/20 16:26:00,2023/8/21 16:35:00,2023/8/23 13:51,2023/8/29 21:38,2023/9/25 0:00 -a73de8635a0cb0aee3da3736197f76b2,d1f24011654af00df1a8326c6cb8aac1,delivered,2022/10/2 22:45:00,2022/10/2 22:56:00,2022/10/4 21:03,2022/10/9 17:20,2022/10/25 0:00 -cf6908e8b524d8fac0d70a5cc8bd749b,c85ab216eceb57e7059d16f16744b513,delivered,2022/8/29 13:58:00,2022/8/29 14:10:00,2022/8/31 19:37,2022/9/6 22:34,2022/9/20 0:00 -a23f4025d60af6199b5eb5631b070e7f,c69a08ef1c07bde2bbcab44dce1bd0b6,delivered,2022/12/7 20:48:00,2022/12/9 16:31:00,2022/12/13 22:10,2022/12/22 13:52,2023/1/5 0:00 -e72e22dce48aaee824371b8e02641f15,d1ea8164411774eb6b46718f894eaace,delivered,2022/10/16 10:31:00,2022/10/16 10:49:00,2022/10/19 20:37,2022/10/25 21:37,2022/11/3 0:00 -d858299446e4d2e4a686d1dcf9a93359,6ec162d7f7fafad0e98a7a8527f9a0fc,delivered,2023/1/7 10:18:00,2023/1/7 10:27:00,2023/1/9 23:39,2023/1/16 22:41,2023/2/2 0:00 -b5b103fe531168050d785d5b8de74174,c3ab6358d2556844d38ed5dbab0b41ce,delivered,2022/1/30 13:13:00,2022/1/31 13:33:00,2022/2/2 9:37,2022/2/21 12:01,2022/3/21 0:00 -245b2a09d0f787df368d4a370a63eb58,024dad8e71332c433bc9a494565b9c49,delivered,2022/12/6 19:26:00,2022/12/6 19:33:00,2022/12/11 22:55,2023/1/10 20:45,2023/1/11 0:00 -d4a07b48835f3637cdf8baeab13c8a9a,17b48c3c14659979aca9d9bb5e057dee,delivered,2022/10/7 14:59:00,2022/10/7 15:14:00,2022/10/11 22:46,2022/10/20 19:36,2022/11/7 0:00 -8193580d95dea97d43937711060b2846,4227cf6df4208d3ff1ce0aaa14e265a9,delivered,2022/11/9 11:20:00,2022/11/10 2:55:00,2022/11/14 21:22,2022/11/23 23:09,2022/12/5 0:00 -bb9e3fdfc33f7fe56fd38f6adacf760f,36d29f1c80a81a79fbf6185b00b5ce3c,delivered,2022/12/26 14:45:00,2022/12/26 14:53:00,2022/12/27 17:54,2023/1/20 0:18,2023/1/29 0:00 -2352f0c7b4fe903c071e032c9d6d6593,b115c9e03fe6ed4c0b0ad50733f1ae98,delivered,2023/4/13 8:15:00,2023/4/17 5:50:00,2023/4/17 22:46,2023/4/23 13:32,2023/5/18 0:00 -59b115dfb1007eca4cb7cd1a4cf2c790,c36218bce6a33d4814601c7744386d9e,delivered,2022/9/3 15:10:00,2022/9/3 15:23:00,2022/9/6 23:49,2022/9/12 22:15,2022/9/27 0:00 -08cbb1d4cd574b126569b208fd4b26ea,51478fa6f626871ba9023c80585e4952,delivered,2022/10/15 19:25:00,2022/10/15 19:35:00,2022/10/18 20:25,2022/10/26 21:14,2022/11/7 0:00 -70623d7ff2e126f3688dba1042ec9531,fe5113a38e3575c04f5a3413100d4e48,delivered,2022/10/23 16:09:00,2022/10/23 16:38:00,2022/10/25 21:43,2022/10/31 15:30,2022/11/14 0:00 -a8a52afd408a3023bafcd9ed3c0d2e15,bccacce2d37971951fd3e82965330b87,delivered,2022/8/30 22:43:00,2022/8/30 22:55:00,2022/9/1 20:07,2022/9/8 20:09,2022/9/19 0:00 -03c83b31dbc387f83f1b5579b53182fb,6d70d16ff8b3a0131e209b2bba542930,delivered,2023/1/6 16:00:00,2023/1/9 7:26:00,2023/1/9 23:38,2023/1/17 20:04,2023/2/6 0:00 -5a3483866ae86e48df2c0da23f2684f2,82b56e1af615d6fe0b24b8f706f172f9,delivered,2022/8/29 20:30:00,2022/8/29 20:44:00,2022/8/31 19:50,2022/9/4 14:51,2022/9/18 0:00 -f296152f7123f2d4455e82df8835f5a2,194e5864217a3571944250937dec0a41,delivered,2023/8/21 9:39:00,2023/8/22 20:30:00,2023/8/23 14:37,2023/8/28 21:04,2023/9/5 0:00 -106ff3ba3e84e22713bf2a10c582fd94,02d1b5b8831241174c6ef13efd35abbd,delivered,2023/4/8 1:21:00,2023/4/8 1:35:00,2023/4/10 18:06,2023/4/20 10:03,2023/4/25 0:00 -048e6e4623dbf118c43e0f5572016faa,7c43cc8f6953deea674d34207a646886,delivered,2022/12/31 17:57:00,2022/12/31 18:09:00,2023/1/3 23:22,2023/1/10 21:42,2023/2/8 0:00 -cdca52aa619c8e59bd64701d54571cc0,36da15e62a3ecf96427337aba9139f2e,delivered,2022/9/4 12:30:00,2022/9/5 4:24:00,2022/9/6 22:07,2022/9/12 17:10,2022/9/26 0:00 -a81957953164f65e49dd6af3972b9db5,607cac3b738f3e37909b517901df2e85,shipped,2023/5/31 12:58:00,2023/6/3 11:30:00,2023/6/4 14:55,,2023/7/23 0:00 -65d1a82f9ce69290556d70fc555cba43,e5f657faf489a605ece3d14855b8f2c4,delivered,2023/4/18 9:26:00,2023/4/18 9:35:00,2023/4/18 18:28,2023/4/26 18:19,2023/5/16 0:00 -4733b3de4bf04376a9d53930899ef18c,e8d32260f2ebace5f1b80c9b213601ff,shipped,2023/1/8 14:16:00,2023/1/8 14:28:00,2023/1/10 20:14,,2023/2/14 0:00 -3a4b013e014723cc38c9faa8ffdc6387,e7c905bf4bb13543e8df947af4f3d9e9,delivered,2023/4/9 11:32:00,2023/4/10 7:35:00,2023/4/11 17:51,2023/4/13 2:06,2023/4/24 0:00 -cd44196e80474114b859765d62f12ddf,38a63fe852918021685a1f656a4d5049,delivered,2023/4/15 21:41:00,2023/4/15 21:55:00,2023/4/16 20:07,2023/4/23 18:56,2023/5/8 0:00 -e3ef3902f4da2bf727f00602d912d034,897c8801e3fd285ce1196daed5ae2de7,delivered,2022/9/17 8:33:00,2022/9/17 8:45:00,2022/9/19 19:36,2022/10/2 17:19,2022/10/6 0:00 -63e700a4baf3602c94a8d6648e896d41,4c8f87ae1692e8e9cb90458557bcf4cb,delivered,2022/9/30 21:44:00,2022/10/2 10:07:00,2022/10/3 19:08,2022/10/13 17:42,2022/10/30 0:00 -564e414f20390e6417f5e6c6ad3f095e,3c8863310a791b2426da5c04de18e70c,delivered,2022/12/20 19:29:00,2022/12/21 2:11:00,2022/12/26 20:52,2023/1/12 12:28,2023/1/24 0:00 -3644344c9ad371ecfc67c6cbeb93531c,286cd699eec7a6faf30e808b715f1180,delivered,2022/9/1 16:54:00,2022/9/2 20:03:00,2022/9/7 0:04,2022/9/19 21:21,2022/9/25 0:00 -85ead861d8aad2f8734d85d187a42b7f,7c7165957bda66e88708766f34c334f3,delivered,2022/12/7 9:08:00,2022/12/11 18:15:00,2022/12/13 22:24,2022/12/19 21:42,2023/1/3 0:00 -34aed6e4313d7573b0d3b459f3a805ea,7afdb6b1737919a448daeb749ee49758,delivered,2022/10/31 18:50:00,2022/11/1 7:06:00,2022/11/3 20:52,2022/11/14 21:54,2022/11/27 0:00 -ca6e9fb5f1a78410c6e1a89640efa8f6,4d77bdf492f3c64a182a33b91618abae,delivered,2023/7/1 20:49:00,2023/7/1 21:10:00,2023/7/3 10:24,2023/7/4 0:38,2023/7/20 0:00 -28e418b320f6b759b6aea79734f165e5,97697c5f77b484cb0cec9eaa81c679d5,delivered,2022/9/2 15:09:00,2022/9/2 15:24:00,2022/9/7 0:04,2022/9/19 19:16,2022/9/27 0:00 -17affe817f6b2a24ec4a9b5bb67a1671,a2593be583c3bec897ec5664bb6e4770,delivered,2022/10/5 17:54:00,2022/10/5 18:25:00,2022/10/6 20:32,2022/10/10 20:37,2022/10/27 0:00 -fefacc66af859508bf1a7934eab1e97f,f48d464a0baaea338cb25f816991ab1f,delivered,2023/7/25 18:10:00,2023/7/27 4:05:00,2023/8/3 14:42,2023/8/15 14:57,2023/8/10 0:00 -e7bf5b3305b73ad31a0306f433c8dd84,192c6d78c5af56baf060b9b2792bdbb5,delivered,2022/9/6 13:14:00,2022/9/8 13:30:00,2022/9/15 17:38,2022/9/21 16:13,2022/10/4 0:00 -5e34ad6a26152d8d8743a70e214b1a98,a0e9c9c5a19366c5eec698ac38498a1e,delivered,2022/12/26 9:43:00,2022/12/27 17:11:00,2023/1/3 23:08,2023/1/8 16:03,2023/1/19 0:00 -90b3ce1268706ec7923743d5867f26a1,b77a36877fb9b74ab4dec5f4e939419a,delivered,2023/4/4 16:58:00,2023/4/5 16:55:00,2023/4/7 1:18,2023/4/11 1:10,2023/4/16 0:00 -1d6bda6e5595652f956770a32ae4ba0d,c903f7a5a846c6117e671107d202286c,delivered,2023/5/22 0:49:00,2023/5/24 2:18:00,2023/5/25 13:48,2023/6/4 21:54,2023/5/30 0:00 -706296e2ab240216ffef853d1095d04f,f0685eff82fe533447ab1a84c25704c1,delivered,2022/8/29 16:25:00,2022/8/30 16:25:00,2022/8/31 19:33,2022/9/4 19:27,2022/9/18 0:00 -b4869c2e4b11586a953130fa13632aa9,1f32801ff0c8f0aeaa8a6af5ca6ce862,delivered,2022/9/1 10:51:00,2022/9/1 11:04:00,2022/9/4 21:21,2022/9/11 20:03,2022/9/25 0:00 -b8b17051a70af754f5a15916490b578c,263f578b432f4c4a154e9c7002bc6c06,delivered,2023/1/4 12:32:00,2023/1/4 12:48:00,2023/1/9 23:52,2023/1/23 1:03,2023/2/2 0:00 -5383435eb2b05b6f4d5be7720974fe67,7fe98b2b2fa5e20a973f275bd5121c2a,delivered,2022/12/18 11:09:00,2022/12/19 9:59:00,2022/12/22 22:17,2023/1/4 23:09,2023/1/17 0:00 -afd5ca74e46f54e04d9104595814ccb1,3c12c66685930cfd507eb4201111b516,delivered,2022/10/1 19:27:00,2022/10/3 14:07:00,2022/10/6 22:35,2022/10/23 20:24,2022/10/30 0:00 -3bd820484fb08cbd09f9d3f378fae1a4,6260e99309fefdfaef12d0ef8fe82e77,delivered,2023/6/1 18:20:00,2023/6/1 18:33:00,2023/6/4 14:55,2023/8/10 17:52,2023/7/17 0:00 -1b2b354adeb38c1c308c915faf7d3288,b0962c45b3881a52d605fe965ca9a776,delivered,2022/8/30 9:33:00,2022/8/30 9:45:00,2022/8/31 19:32,2022/9/4 20:51,2022/9/19 0:00 -338515ff7c1216299678e18a593799a5,a5252e81424e5fb2c7ddf01256cf94e0,delivered,2022/10/22 17:32:00,2022/10/22 17:49:00,2022/10/24 22:07,2022/10/30 19:33,2022/11/14 0:00 -a806770e48c22cc0c2607982f3e87e30,ec690140f77f5ff4c884704c976e3489,delivered,2022/9/1 14:00:00,2022/9/1 14:15:00,2022/9/4 20:51,2022/9/15 18:53,2022/9/25 0:00 -2ce81d16edb6568f5ff5b9ec2e5cb4b7,a2a5fc7e8fc7e880cd68a9768b8caa22,delivered,2022/12/28 14:45:00,2022/12/28 14:55:00,2023/1/3 23:23,2023/1/8 16:28,2023/1/19 0:00 -ff2ac13b0f36dffb6af9699f59b18377,c7a68b2b2775db26644d8f4e28c03604,delivered,2022/9/4 14:26:00,2022/9/4 14:35:00,2022/9/6 18:08,2022/9/11 19:35,2022/9/26 0:00 -83e50e2e58cfc9839fb932948f1d7ce8,71c41989b581f59300b8dc475aa48c0b,delivered,2023/5/3 8:48:00,2023/5/3 9:12:00,2023/5/3 13:25,2023/5/8 15:48,2023/5/23 0:00 -1badd176eb41888c1a20a7614fba59e1,ed189d4d749b9877a2aa93d9d32f339b,delivered,2022/9/18 1:50:00,2022/9/19 9:50:00,2022/9/20 19:38,2022/10/2 19:25,2022/10/13 0:00 -694e3d121f16bcbb9b4595b6c6ab3baf,2e0339ff984d6f41f11dfdbc7c93dcda,delivered,2022/12/15 13:43:00,2022/12/16 16:20:00,2022/12/19 23:19,2022/12/22 1:07,2023/1/10 0:00 -397cda88cf14fa47dd00f8ce20346f25,b47024b93a109910a33dc796ea7593f9,delivered,2023/8/10 18:17:00,2023/8/14 4:55:00,2023/8/15 13:01,2023/8/16 18:28,2023/8/16 0:00 -ed35f59756edecbfcefb866146f00905,3a1e5902bb274b86dd980f371e207651,delivered,2022/12/16 19:41:00,2022/12/16 19:50:00,2022/12/22 21:58,2023/1/3 19:43,2023/1/16 0:00 -977649a07fb7be354cc39d9a79ee83e1,d7d1465f1de475b3d507ab913951fb3c,delivered,2023/7/11 10:10:00,2023/7/11 10:26:00,2023/7/12 12:19,2023/7/27 16:51,2023/7/30 0:00 -63a2ef605ed6a193d40b312ca1b014d5,a95ad7bcbf76f95fcb884dfdfa84ae68,delivered,2022/12/11 20:45:00,2022/12/13 21:10:00,2022/12/19 1:48,2023/1/6 14:05,2023/1/15 0:00 -8185ba302492c86291d7b1912c94ded3,f066138977b82fde31c0fa4c67c6600f,delivered,2023/4/18 22:10:00,2023/4/18 22:31:00,2023/4/19 22:37,2023/4/24 22:17,2023/5/14 0:00 -8dbc85d1447242f3b127dda390d56e19,3d979689f636322c62418b6346b1c6d2,delivered,2023/6/22 12:23:00,2023/6/22 12:36:00,2023/6/22 13:00,2023/7/6 1:08,2023/7/17 0:00 -8171523911786efd1d91c66d69051fcd,6152fbfc8a92ee25fd821740bd33b089,delivered,2023/6/11 21:17:00,2023/6/12 9:00:00,2023/6/14 13:27,2023/6/21 18:54,2023/7/4 0:00 -fdddc15fc7b9c37476820d6eb722f33b,66b84aaef46998841f07082b24004842,delivered,2022/8/29 10:55:00,2022/8/30 12:35:00,2022/8/31 19:50,2022/10/20 18:09,2022/9/19 0:00 -60dc36170c9cc8c0215fafa26627670f,7074bf81824d0b653d0f13bc3b846c18,delivered,2022/9/12 0:00:00,2022/9/13 0:15:00,2022/9/14 19:20,2022/9/21 15:58,2022/10/6 0:00 -2582e88a3e8a129cc809ccaf9a6d35d6,7d875beb796e3f0fb726c3854dbd3037,delivered,2022/10/16 21:33:00,2022/10/16 22:05:00,2022/10/19 20:28,2022/10/27 18:33,2022/11/8 0:00 -6b24cf0591948a0a949ee51131cb78ad,ac7c0515474bc3f9cf19474ee4d228eb,delivered,2022/8/29 17:42:00,2022/8/29 17:50:00,2022/8/31 19:36,2022/9/1 21:44,2022/9/13 0:00 -0945dadba69dad599e42c31e78450de4,be33968269bf8c51037b65cdf4edff1b,delivered,2022/8/29 15:20:00,2022/8/31 2:35:00,2022/9/1 20:07,2022/9/25 18:10,2022/10/10 0:00 -858d458b39082890e96fbb1fed8c2a52,f959b7bc834045511217e6410985963f,delivered,2022/9/6 16:10:00,2022/9/6 17:15:00,2022/9/11 19:48,2022/9/16 16:18,2022/9/26 0:00 -1407ed7d738d943469994266e9706b46,e85b1dcef5f92e0647dc214b455b83c8,delivered,2022/8/30 10:51:00,2022/8/30 11:05:00,2022/8/31 19:36,2022/9/13 20:10,2022/9/28 0:00 -a498326cbf752acac00b7d65561dcd98,efa2729fe65e29fa63ac050b9f9fe3df,delivered,2022/12/16 20:23:00,2022/12/16 20:32:00,2022/12/19 23:19,2022/12/27 20:24,2023/1/16 0:00 -5ca18035ac56a17dd903b0e8410aae06,4e5ca9b956b369f83366360cf7dbd9b6,delivered,2023/1/11 22:10:00,2023/1/13 4:55:00,2023/1/17 21:42,2023/1/25 19:23,2023/2/19 0:00 -5a50ee4e7bf3b3bf306a1c3f19a1a885,72680b3da61c269ad2e5d342356fec77,delivered,2022/8/30 17:50:00,2022/8/30 18:07:00,2022/8/31 19:36,2022/9/15 19:07,2022/10/10 0:00 -ccac1a9dee556f517bdb745dd29bcb68,1a46899c81a1f73c1338cffd1164751d,delivered,2022/9/5 18:45:00,2022/9/5 18:55:00,2022/9/8 19:27,2022/9/29 16:55,2022/10/2 0:00 -ceed0f54453282dec0cc7c591237d5b6,fa4de7819dda8ca15bf86e413ba6473f,delivered,2022/9/17 19:18:00,2022/9/17 19:30:00,2022/9/19 19:36,2022/10/3 19:22,2022/10/10 0:00 -c22f4ba5610aa110fb73444de7600a2e,ed7c9514731cc85c9cd18dbf8115e8b0,delivered,2022/9/28 15:52:00,2022/9/28 16:07:00,2022/10/2 21:32,2022/10/10 20:57,2022/10/25 0:00 -0a187dd7f4efe70e8c3b6e3779b3b133,23fafaadc0b11501176401ba0003c22d,delivered,2022/9/2 19:48:00,2022/9/2 20:03:00,2022/9/7 0:07,2022/9/13 22:02,2022/9/26 0:00 -f4b7ccd15f831ff995d4f307b0dc0f0b,223a807962e222b758aeee5610103f47,delivered,2022/8/29 22:38:00,2022/8/29 22:50:00,2022/8/31 19:41,2022/9/5 18:52,2022/9/15 0:00 -64582c699f99b4dd3c326b13c3bdc644,a095450e0630a3f9776ba4196dac1da1,delivered,2022/10/9 10:22:00,2022/10/9 10:36:00,2022/10/10 21:26,2022/10/30 14:54,2022/11/17 0:00 -d55b88c264e0cacf41c8f8ce846bc1ee,3e35e35a82de3fc574900adca713dff2,delivered,2023/6/11 23:05:00,2023/6/11 23:35:00,2023/6/12 13:08,2023/7/4 20:03,2023/7/4 0:00 -6d9da1dcc8d05c588e4ea617d0fe9465,ce9167d363251ec55e167d15816ea22e,delivered,2023/8/9 14:12:00,2023/8/9 14:26:00,2023/8/10 14:51,2023/8/14 16:04,2023/8/15 0:00 -82ee69216f11b23e2d21d2796e079366,7f8aa5f321fc28ae90ee6a38cd6e3150,delivered,2023/8/8 11:34:00,2023/8/8 11:45:00,2023/8/14 13:59,2023/8/17 12:28,2023/8/23 0:00 -5afaa7b618c8776fad63ca23a14a8035,bca5625f843661186a352a2c160843ee,delivered,2023/5/10 17:07:00,2023/5/10 17:15:00,2023/5/11 17:25,2023/5/14 16:31,2023/5/21 0:00 -d19772e154f0929b89a1dab65648767b,b95975b682b09a1890557a1ab4021873,delivered,2022/10/5 19:12:00,2022/10/6 19:07:00,2022/10/11 23:13,2022/10/23 20:17,2022/11/10 0:00 -bfb8512783ccd2271d2e96d3b856bf2b,4ee7fc32553f4f1cda85112b9a2719e3,invoiced,2022/9/16 12:37:00,2022/9/16 12:45:00,,,2022/10/6 0:00 diff --git a/wren-tests/src/test/resources/duckdb/init.sql b/wren-tests/src/test/resources/duckdb/init.sql deleted file mode 100644 index 0ffd0ed81..000000000 --- a/wren-tests/src/test/resources/duckdb/init.sql +++ /dev/null @@ -1,6 +0,0 @@ -CREATE SCHEMA tpch; -CREATE TABLE tpch.customer AS SELECT * FROM read_parquet('basePath/customer.parquet'); -CREATE TABLE tpch.lineitem AS SELECT * FROM read_parquet('basePath/lineitem.parquet'); -CREATE TABLE tpch.nation AS SELECT * FROM read_parquet('basePath/nation.parquet'); -CREATE TABLE tpch.orders AS SELECT * FROM read_parquet('basePath/orders.parquet'); -CREATE TABLE tpch.part AS SELECT * FROM read_parquet('basePath/part.parquet'); \ No newline at end of file diff --git a/wren-tests/src/test/resources/duckdb/mdl.json b/wren-tests/src/test/resources/duckdb/mdl.json deleted file mode 100644 index 145e5edb8..000000000 --- a/wren-tests/src/test/resources/duckdb/mdl.json +++ /dev/null @@ -1,433 +0,0 @@ -{ - "catalog": "memory", - "schema": "tpch", - "models": [ - { - "name": "Orders", - "refSql": "select * from memory.tpch.orders", - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "int4", - "properties": { - "field": "test1", - "nested": { - "n1": "test1", - "n2": "test2" - } - } - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "int4" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "OrderStatus" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float8" - }, - { - "name": "nation_name", - "isCalculated": true, - "expression": "customer.nation.name", - "type": "varchar" - }, - { - "name": "customer", - "type": "Customer", - "relationship": "OrdersCustomer" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - }, - { - "name": "lineitems", - "type": "Lineitem", - "relationship": "OrdersLineitem" - } - ], - "primaryKey": "orderkey" - }, - { - "name": "Customer", - "refSql": "select * from memory.tpch.customer", - "columns": [ - { - "name": "custkey", - "expression": "c_custkey", - "type": "int4" - }, - { - "name": "nationkey", - "expression": "c_nationkey", - "type": "integer" - }, - { - "name": "name", - "expression": "c_name", - "type": "varchar" - }, - { - "name": "orders", - "type": "Orders", - "relationship": "OrdersCustomer" - }, - { - "name": "nation", - "type": "Nation", - "relationship": "CustomerNation" - }, - { - "name": "custkey_name", - "type": "varchar", - "expression": "{{ concat('c_custkey', 'c_name') }} " - }, - { - "name": "custkey_call_concat", - "type": "varchar", - "expression": "{{ callConcat('c_custkey', concat) }} " - } - ], - "primaryKey": "custkey" - }, - { - "name": "Lineitem", - "refSql": "select * from memory.tpch.lineitem", - "columns": [ - { - "name": "orderkey", - "expression": "l_orderkey", - "type": "int4" - }, - { - "name": "partkey", - "expression": "l_partkey", - "type": "int4" - }, - { - "name": "linenumber", - "expression": "l_linenumber", - "type": "int4" - }, - { - "name": "extendedprice", - "expression": "l_extendedprice", - "type": "float8" - }, - { - "name": "discount", - "expression": "l_discount", - "type": "float8" - }, - { - "name": "shipdate", - "expression": "l_shipdate", - "type": "date" - }, - { - "name": "comment", - "expression": "l_comment", - "type": "varchar" - }, - { - "name": "order", - "type": "int4", - "expression": "1" - }, - { - "name": "part", - "type": "Part", - "relationship": "LineitemPart" - }, - { - "name": "orderkey_linenumber", - "type": "varchar", - "expression": "concat(l_orderkey, l_linenumber)" - } - ], - "primaryKey": "orderkey_linenumber" - }, - { - "name": "Part", - "refSql": "select * from memory.tpch.part", - "columns": [ - { - "name": "partkey", - "expression": "p_partkey", - "type": "int4" - }, - { - "name": "name", - "expression": "p_name", - "type": "varchar" - } - ], - "primaryKey": "partkey" - }, - { - "name": "Nation", - "refSql": "select * from memory.tpch.nation", - "columns": [ - { - "name": "nationkey", - "expression": "n_nationkey", - "type": "int4" - }, - { - "name": "name", - "expression": "n_name", - "type": "varchar" - }, - { - "name": "regionkey", - "expression": "n_regionkey", - "type": "int4" - }, - { - "name": "comment", - "expression": "n_comment", - "type": "varchar" - }, - { - "name": "region", - "type": "Region", - "relationship": "NationRegion" - }, - { - "name": "customer", - "type": "Customer", - "relationship": "CustomerNation" - }, - { - "name": "supplier", - "type": "Supplier", - "relationship": "NationSupplier" - } - ], - "primaryKey": "nationkey" - } - ], - "relationships": [ - { - "name": "OrdersCustomer", - "models": [ - "Orders", - "Customer" - ], - "joinType": "MANY_TO_ONE", - "condition": "Orders.custkey = Customer.custkey" - }, - { - "name": "OrdersLineitem", - "models": [ - "Orders", - "Lineitem" - ], - "joinType": "ONE_TO_MANY", - "condition": "Orders.orderkey = Lineitem.orderkey" - }, - { - "name": "LineitemPart", - "models": [ - "Lineitem", - "Part" - ], - "joinType": "MANY_TO_ONE", - "condition": "Lineitem.partkey = Part.partkey" - }, - { - "name": "CustomerNation", - "models": [ - "Customer", - "Nation" - ], - "joinType": "MANY_TO_ONE", - "condition": "Customer.nationkey = Nation.nationkey" - } - ], - "metrics": [ - { - "name": "Revenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "customer", - "type": "int4", - "expression": "customer.name" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "name": "CustomerRevenue", - "baseObject": "Customer", - "dimension": [ - { - "name": "custkey", - "type": "int4", - "expression": "custkey" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(orders.totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "name": "CustomerDailyRevenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "customer", - "type": "int4", - "expression": "customer.name" - }, - { - "name": "date", - "type": "int4", - "expression": "orderdate" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [] - }, - { - "name": "CustomerMonthlyRevenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "customer", - "type": "int4", - "expression": "customer.name" - }, - { - "name": "month", - "type": "date", - "expression": "date_trunc('MONTH', orderdate)" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [] - } - ], - "cumulativeMetrics": [ - { - "name": "WeeklyRevenue", - "baseObject": "Orders", - "measure": { - "name": "totalprice", - "type": "int4", - "operator": "sum", - "refColumn": "totalprice" - }, - "window": { - "name": "orderdate", - "refColumn": "orderdate", - "timeUnit": "WEEK", - "start": "1993-01-01", - "end": "1993-12-31" - }, - "cached": false, - "refreshTime": "30m", - "description": "" - } - ], - "enumDefinitions": [ - { - "name": "Status", - "values": [ - { - "name": "F" - }, - { - "name": "O" - }, - { - "name": "P" - } - ] - } - ], - "views": [ - { - "name": "useModel", - "statement": "select * from Orders" - }, - { - "name": "useMetric", - "statement": "select * from Revenue" - }, - { - "name": "useMetricRollUp", - "statement": "select * from roll_up(Revenue, orderdate, YEAR)" - }, - { - "name": "useUseMetric", - "statement": "select * from useMetric" - }, - { - "name": "sameCte", - "statement": "with sameCte as (select * from Orders) select * from sameCte" - } - ], - "macros": [ - { - "name": "concat", - "definition": "(arg1: Expression, arg2: Expression) => concat({{ arg1 }}, {{ arg2 }})" - }, - { - "name": "callConcat", - "definition": "(arg1: Expression, func: Macro) => {{ func(arg1, arg1) }}" - } - ] -} \ No newline at end of file diff --git a/wren-tests/src/test/resources/snowflake/mdl.json b/wren-tests/src/test/resources/snowflake/mdl.json deleted file mode 100644 index a4bb435ef..000000000 --- a/wren-tests/src/test/resources/snowflake/mdl.json +++ /dev/null @@ -1,388 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "ORDERS", - "refSql": "SELECT * FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.ORDERS", - "columns": [ - { - "name": "ORDERKEY", - "expression": "O_ORDERKEY", - "type": "int4" - }, - { - "name": "CUSTKEY", - "expression": "O_CUSTKEY", - "type": "int4" - }, - { - "name": "ORDERSTATUS", - "expression": "O_ORDERSTATUS", - "type": "OrderStatus" - }, - { - "name": "TOTALPRICE", - "expression": "O_TOTALPRICE", - "type": "float8" - }, - { - "name": "caseSensitive", - "type": "int4", - "expression": "1" - }, - { - "name": "NATION_NAME", - "isCalculated": true, - "expression": "CUSTOMER.NATION.NAME", - "type": "varchar" - }, - { - "name": "CUSTOMER", - "type": "CUSTOMER", - "relationship": "ORDERS_CUSTOMER" - }, - { - "name": "ORDERDATE", - "expression": "O_ORDERDATE", - "type": "date" - }, - { - "name": "LINEITEM", - "type": "LINEITEM", - "relationship": "ORDERS_LINEITEM" - } - ], - "primaryKey": "ORDERKEY" - }, - { - "name": "CUSTOMER", - "refSql": "SELECT * FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.CUSTOMER", - "columns": [ - { - "name": "CUSTKEY", - "expression": "C_CUSTKEY", - "type": "int4" - }, - { - "name": "NATIONKEY", - "expression": "C_NATIONKEY", - "type": "integer" - }, - { - "name": "NAME", - "expression": "C_NAME", - "type": "varchar" - }, - { - "name": "ORDERS", - "type": "ORDERS", - "relationship": "ORDERS_CUSTOMER" - }, - { - "name": "NATION", - "type": "NATION", - "relationship": "CUSTOMER_NATION" - }, - { - "name": "CUSTKEY_NAME", - "type": "varchar", - "expression": "{{ CONCAT('C_CUSTKEY', 'C_NAME') }} " - }, - { - "name": "CUSTKEY_CALL_CONCAT", - "type": "varchar", - "expression": "{{ CALL_CONCAT('C_CUSTKEY', CONCAT) }} " - } - ], - "primaryKey": "CUSTKEY" - }, - { - "name": "LINEITEM", - "refSql": "SELECT * FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.LINEITEM", - "columns": [ - { - "name": "ORDERKEY", - "expression": "L_ORDERKEY", - "type": "int4" - }, - { - "name": "PARTKEY", - "expression": "L_PARTKEY", - "type": "int4" - }, - { - "name": "LINENUMBER", - "expression": "L_LINENUMBER", - "type": "int4" - }, - { - "name": "EXTENDEDPRICE", - "expression": "L_EXTENDEDPRICE", - "type": "float8" - }, - { - "name": "DISCOUNT", - "expression": "L_DISCOUNT", - "type": "float8" - }, - { - "name": "SHIPDATE", - "expression": "L_SHIPDATE", - "type": "date" - }, - { - "name": "COMMENT", - "expression": "L_COMMENT", - "type": "varchar" - }, - { - "name": "CONSTANT", - "type": "int4", - "expression": "1" - }, - { - "name": "PART", - "type": "PART", - "relationship": "LINEITEM_PART" - }, - { - "name": "ORDERKEY_LINENUMBER", - "type": "varchar", - "expression": "CONCAT(L_ORDERKEY, L_LINENUMBER)" - } - ], - "primaryKey": "ORDERKEY_LINENUMBER" - }, - { - "name": "PART", - "refSql": "SELECT * FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.PART", - "columns": [ - { - "name": "PARTKEY", - "expression": "P_PARTKEY", - "type": "int4" - }, - { - "name": "NAME", - "expression": "P_NAME", - "type": "varchar" - } - ], - "primaryKey": "PARTKEY" - }, - { - "name": "NATION", - "refSql": "SELECT * FROM SNOWFLAKE_SAMPLE_DATA.TPCH_SF1.NATION", - "columns": [ - { - "name": "NATIONKEY", - "expression": "N_NATIONKEY", - "type": "int4" - }, - { - "name": "NAME", - "expression": "N_NAME", - "type": "varchar" - }, - { - "name": "COMMENT", - "expression": "N_COMMENT", - "type": "varchar" - }, - { - "name": "CUSTOMER", - "type": "CUSTOMER", - "relationship": "CUSTOMER_NATION" - } - ], - "primaryKey": "NATIONKEY" - } - ], - "relationships": [ - { - "name": "ORDERS_CUSTOMER", - "models": [ - "ORDERS", - "CUSTOMER" - ], - "joinType": "MANY_TO_ONE", - "condition": "ORDERS.CUSTKEY = CUSTOMER.CUSTKEY" - }, - { - "name": "ORDERS_LINEITEM", - "models": [ - "ORDERS", - "LINEITEM" - ], - "joinType": "ONE_TO_MANY", - "condition": "ORDERS.ORDERKEY = LINEITEM.ORDERKEY" - }, - { - "name": "LINEITEM_PART", - "models": [ - "LINEITEM", - "PART" - ], - "joinType": "MANY_TO_ONE", - "condition": "LINEITEM.PARTKEY = PART.PARTKEY" - }, - { - "name": "CUSTOMER_NATION", - "models": [ - "CUSTOMER", - "NATION" - ], - "joinType": "MANY_TO_ONE", - "condition": "CUSTOMER.NATIONKEY = NATION.NATIONKEY" - } - ], - "metrics": [ - { - "name": "REVENUE", - "baseObject": "ORDERS", - "dimension": [ - { - "name": "CUSTOMER", - "type": "int4", - "expression": "CUSTOMER.NAME" - } - ], - "measure": [ - { - "name": "TOTALPRICE", - "type": "int4", - "expression": "SUM(TOTALPRICE)" - } - ], - "timeGrain": [ - { - "name": "ORDERDATE", - "refColumn": "ORDERDATE", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "name": "CUSTOMER_REVENUE", - "baseObject": "CUSTOMER", - "dimension": [ - { - "name": "CUSTKEY", - "type": "int4", - "expression": "CUSTKEY" - } - ], - "measure": [ - { - "name": "TOTALPRICE", - "type": "int4", - "expression": "sum(ORDERS.TOTALPRICE)" - } - ], - "timeGrain": [ - { - "name": "ORDERDATE", - "refColumn": "ORDERDATE", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "name": "CUSTOMER_DAILY_REVENUE", - "baseObject": "ORDERS", - "dimension": [ - { - "name": "CUSTOMER", - "type": "int4", - "expression": "CUSTOMER.NAME" - }, - { - "name": "DATE", - "type": "int4", - "expression": "ORDERDATE" - } - ], - "measure": [ - { - "name": "TOTALPRICE", - "type": "int4", - "expression": "SUM(TOTALPRICE)" - } - ], - "timeGrain": [] - } - ], - "cumulativeMetrics": [ - { - "name": "WEEKLY_REVENUE", - "baseObject": "ORDERS", - "measure": { - "name": "TOTALPRICE", - "type": "int4", - "operator": "SUM", - "refColumn": "TOTALPRICE" - }, - "window": { - "name": "ORDERDATE", - "refColumn": "ORDERDATE", - "timeUnit": "WEEK", - "start": "1993-01-01", - "end": "1993-12-31" - }, - "cached": false, - "refreshTime": "30m", - "description": "" - } - ], - "enumDefinitions": [ - { - "name": "STATUS", - "values": [ - { - "name": "F" - }, - { - "name": "O" - }, - { - "name": "P" - } - ] - } - ], - "views": [ - { - "name": "USE_MODEL", - "statement": "SELECT * FROM ORDERS" - }, - { - "name": "USE_METRIC", - "statement": "SELECT * FROM REVENUE" - }, - { - "name": "USE_METRIC_ROLLUP", - "statement": "SELECT * FROM ROLLUP(REVENUE, ORDERDATE, YEAR)" - }, - { - "name": "USE_USE_METRIC", - "statement": "SELECT * FROM USE_METRIC" - } - ], - "macros": [ - { - "name": "CONCAT", - "definition": "(arg1: Expression, arg2: Expression) => CONCAT({{ arg1 }}, {{ arg2 }})" - }, - { - "name": "CALL_CONCAT", - "definition": "(arg1: Expression, func: Macro) => {{ func(arg1, arg1) }}" - } - ] -} diff --git a/wren-tests/src/test/resources/tpch/data/customer.parquet b/wren-tests/src/test/resources/tpch/data/customer.parquet deleted file mode 100644 index cda457ec5..000000000 Binary files a/wren-tests/src/test/resources/tpch/data/customer.parquet and /dev/null differ diff --git a/wren-tests/src/test/resources/tpch/data/lineitem.parquet b/wren-tests/src/test/resources/tpch/data/lineitem.parquet deleted file mode 100644 index f188b136e..000000000 Binary files a/wren-tests/src/test/resources/tpch/data/lineitem.parquet and /dev/null differ diff --git a/wren-tests/src/test/resources/tpch/data/nation.parquet b/wren-tests/src/test/resources/tpch/data/nation.parquet deleted file mode 100644 index 24653727c..000000000 Binary files a/wren-tests/src/test/resources/tpch/data/nation.parquet and /dev/null differ diff --git a/wren-tests/src/test/resources/tpch/data/orders.parquet b/wren-tests/src/test/resources/tpch/data/orders.parquet deleted file mode 100644 index 8c0aa64e0..000000000 Binary files a/wren-tests/src/test/resources/tpch/data/orders.parquet and /dev/null differ diff --git a/wren-tests/src/test/resources/tpch/data/part.parquet b/wren-tests/src/test/resources/tpch/data/part.parquet deleted file mode 100644 index 24feef0dd..000000000 Binary files a/wren-tests/src/test/resources/tpch/data/part.parquet and /dev/null differ diff --git a/wren-tests/src/test/resources/tpch/data/partsupp.parquet b/wren-tests/src/test/resources/tpch/data/partsupp.parquet deleted file mode 100644 index 5b7fe43de..000000000 Binary files a/wren-tests/src/test/resources/tpch/data/partsupp.parquet and /dev/null differ diff --git a/wren-tests/src/test/resources/tpch/data/region.parquet b/wren-tests/src/test/resources/tpch/data/region.parquet deleted file mode 100644 index 71507a5b2..000000000 Binary files a/wren-tests/src/test/resources/tpch/data/region.parquet and /dev/null differ diff --git a/wren-tests/src/test/resources/tpch/data/supplier.parquet b/wren-tests/src/test/resources/tpch/data/supplier.parquet deleted file mode 100644 index 5be91c358..000000000 Binary files a/wren-tests/src/test/resources/tpch/data/supplier.parquet and /dev/null differ diff --git a/wren-tests/src/test/resources/tpch/queries/1.sql b/wren-tests/src/test/resources/tpch/queries/1.sql deleted file mode 100644 index eabd9bbbf..000000000 --- a/wren-tests/src/test/resources/tpch/queries/1.sql +++ /dev/null @@ -1,26 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Pricing Summary Report Query (Q1) --- Functional Query Definition --- Approved February 1998 - -select - l_returnflag, - l_linestatus, - sum(l_quantity) as sum_qty, - sum(l_extendedprice) as sum_base_price, - sum(l_extendedprice * (1 - l_discount)) as sum_disc_price, - sum(l_extendedprice * (1 - l_discount) * (1 + l_tax)) as sum_charge, - avg(l_quantity) as avg_qty, - avg(l_extendedprice) as avg_price, - avg(l_discount) as avg_disc, - count(*) as count_order -from - lineitem -where - l_shipdate <= date '1998-12-01' - interval '3' day -group by - l_returnflag, - l_linestatus -order by - l_returnflag, - l_linestatus diff --git a/wren-tests/src/test/resources/tpch/queries/10.sql b/wren-tests/src/test/resources/tpch/queries/10.sql deleted file mode 100644 index 14806025c..000000000 --- a/wren-tests/src/test/resources/tpch/queries/10.sql +++ /dev/null @@ -1,36 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Returned Item Reporting Query (Q10) --- Functional Query Definition --- Approved February 1998 - -select - c_custkey, - c_name, - sum(l_extendedprice * (1 - l_discount)) as revenue, - c_acctbal, - n_name, - c_address, - c_phone, - c_comment -from - customer, - orders, - lineitem, - nation -where - c_custkey = o_custkey - and l_orderkey = o_orderkey - and o_orderdate >= date '1993-10-01' - and o_orderdate < date '1993-10-01' + interval '3' month - and l_returnflag = 'R' - and c_nationkey = n_nationkey -group by - c_custkey, - c_name, - c_acctbal, - c_phone, - n_name, - c_address, - c_comment -order by - revenue desc diff --git a/wren-tests/src/test/resources/tpch/queries/11.sql b/wren-tests/src/test/resources/tpch/queries/11.sql deleted file mode 100644 index 67c5df86d..000000000 --- a/wren-tests/src/test/resources/tpch/queries/11.sql +++ /dev/null @@ -1,32 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Important Stock Identification Query (Q11) --- Functional Query Definition --- Approved February 1998 - -select - ps_partkey, - sum(ps_supplycost * ps_availqty) as value1 -from - partsupp, - supplier, - nation -where - ps_suppkey = s_suppkey - and s_nationkey = n_nationkey - and n_name = 'GERMANY' -group by - ps_partkey having - sum(ps_supplycost * ps_availqty) > ( - select - sum(ps_supplycost * ps_availqty) * 0.0001 - from - partsupp, - supplier, - nation - where - ps_suppkey = s_suppkey - and s_nationkey = n_nationkey - and n_name = 'GERMANY' - ) -order by - value1 desc diff --git a/wren-tests/src/test/resources/tpch/queries/12.sql b/wren-tests/src/test/resources/tpch/queries/12.sql deleted file mode 100644 index 5899b32d6..000000000 --- a/wren-tests/src/test/resources/tpch/queries/12.sql +++ /dev/null @@ -1,33 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Shipping Modes and Order Priority Query (Q12) --- Functional Query Definition --- Approved February 1998 - -select - l_shipmode, - sum(case - when o_orderpriority = '1-URGENT' - or o_orderpriority = '2-HIGH' - then 1 - else 0 - end) as high_line_count, - sum(case - when o_orderpriority <> '1-URGENT' - and o_orderpriority <> '2-HIGH' - then 1 - else 0 - end) as low_line_count -from - orders, - lineitem -where - o_orderkey = l_orderkey - and l_shipmode in ('MAIL', 'SHIP') - and l_commitdate < l_receiptdate - and l_shipdate < l_commitdate - and l_receiptdate >= date '1994-01-01' - and l_receiptdate < date '1995-01-01' + interval '1' year -group by - l_shipmode -order by - l_shipmode diff --git a/wren-tests/src/test/resources/tpch/queries/13.sql b/wren-tests/src/test/resources/tpch/queries/13.sql deleted file mode 100644 index 179e15739..000000000 --- a/wren-tests/src/test/resources/tpch/queries/13.sql +++ /dev/null @@ -1,25 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Customer Distribution Query (Q13) --- Functional Query Definition --- Approved February 1998 - -select - c_count, - count(*) as custdist -from - ( - select - c_custkey, - count(o_orderkey) - from - customer left outer join orders on - c_custkey = o_custkey - and o_comment not like '%special%requests%' - group by - c_custkey - ) as c_orders (c_custkey, c_count) -group by - c_count -order by - custdist desc, - c_count desc diff --git a/wren-tests/src/test/resources/tpch/queries/14.sql b/wren-tests/src/test/resources/tpch/queries/14.sql deleted file mode 100644 index 04374bfdd..000000000 --- a/wren-tests/src/test/resources/tpch/queries/14.sql +++ /dev/null @@ -1,18 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Promotion Effect Query (Q14) --- Functional Query Definition --- Approved February 1998 - -select - 100.00 * sum(case - when p_type like 'PROMO%' - then l_extendedprice * (1 - l_discount) - else 0 - end) / sum(l_extendedprice * (1 - l_discount)) as promo_revenue -from - lineitem, - part -where - l_partkey = p_partkey - and l_shipdate >= date '1995-09-01' - and l_shipdate < date '1995-09-01' + interval '1' month \ No newline at end of file diff --git a/wren-tests/src/test/resources/tpch/queries/15.sql b/wren-tests/src/test/resources/tpch/queries/15.sql deleted file mode 100644 index 50295a2b3..000000000 --- a/wren-tests/src/test/resources/tpch/queries/15.sql +++ /dev/null @@ -1,37 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Top Supplier Query (Q15) --- Functional Query Definition --- Approved February 1998 - --- Refer to Impala https://github.com/apache/impala/blob/master/testdata/workloads/tpch/queries/tpch-q15.test -with revenue_view as ( - select - l_suppkey as supplier_no, - sum(l_extendedprice * (1 - l_discount)) as total_revenue - from - lineitem - where - l_shipdate >= '1996-01-01' - and l_shipdate < '1996-04-01' - group by - l_suppkey) -select - s_suppkey, - s_name, - s_address, - s_phone, - total_revenue -from - supplier, - revenue_view -where - s_suppkey = supplier_no - and total_revenue = ( - select - max(total_revenue) - from - revenue_view - ) -order by - s_suppkey - diff --git a/wren-tests/src/test/resources/tpch/queries/16.sql b/wren-tests/src/test/resources/tpch/queries/16.sql deleted file mode 100644 index 097c4392c..000000000 --- a/wren-tests/src/test/resources/tpch/queries/16.sql +++ /dev/null @@ -1,36 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Parts/Supplier Relationship Query (Q16) --- Functional Query Definition --- Approved February 1998 - -select - p_brand, - p_type, - p_size, - count(distinct ps_suppkey) as supplier_cnt -from - partsupp, - part -where - p_partkey = ps_partkey - and p_brand <> 'Brand#45' - and p_type not like 'MEDIUM POLISHED%' - and p_size in (49, 14, 23, 45, 19, 3, 36, 9) - and ps_suppkey not in ( - select - s_suppkey - from - supplier - where - s_comment like '%Customer%Complaints%' - ) -group by - p_brand, - p_type, - p_size -order by - supplier_cnt desc, - p_brand, - p_type, - p_size - diff --git a/wren-tests/src/test/resources/tpch/queries/17.sql b/wren-tests/src/test/resources/tpch/queries/17.sql deleted file mode 100644 index 6613dbc1c..000000000 --- a/wren-tests/src/test/resources/tpch/queries/17.sql +++ /dev/null @@ -1,22 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Small-Quantity-Order Revenue Query (Q17) --- Functional Query Definition --- Approved February 1998 - -select - sum(l_extendedprice) / 7.0 as avg_yearly -from - lineitem, - part -where - p_partkey = l_partkey - and p_brand = 'Brand#23' - and p_container = 'MED BOX' - and l_quantity < ( - select - 0.2 * avg(l_quantity) - from - lineitem - where - l_partkey = p_partkey - ) diff --git a/wren-tests/src/test/resources/tpch/queries/18.sql b/wren-tests/src/test/resources/tpch/queries/18.sql deleted file mode 100644 index 92a5bc9a9..000000000 --- a/wren-tests/src/test/resources/tpch/queries/18.sql +++ /dev/null @@ -1,37 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Large Volume Customer Query (Q18) --- Function Query Definition --- Approved February 1998 - -select - c_name, - c_custkey, - o_orderkey, - o_orderdate, - o_totalprice, - sum(l_quantity) -from - customer, - orders, - lineitem -where - o_orderkey in ( - select - l_orderkey - from - lineitem - group by - l_orderkey having - sum(l_quantity) > 300 - ) - and c_custkey = o_custkey - and o_orderkey = l_orderkey -group by - c_name, - c_custkey, - o_orderkey, - o_orderdate, - o_totalprice -order by - o_totalprice desc, - o_orderdate diff --git a/wren-tests/src/test/resources/tpch/queries/19.sql b/wren-tests/src/test/resources/tpch/queries/19.sql deleted file mode 100644 index 2436d69ea..000000000 --- a/wren-tests/src/test/resources/tpch/queries/19.sql +++ /dev/null @@ -1,40 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Discounted Revenue Query (Q19) --- Functional Query Definition --- Approved February 1998 - -select - sum(l_extendedprice * (1 - l_discount)) as revenue -from - lineitem, - part -where - p_partkey = l_partkey - and ( - ( - p_brand = 'Brand#12' - and p_container in ('SM CASE', 'SM BOX', 'SM PACK', 'SM PKG') - and l_quantity >= 1 and l_quantity <= 11 - and p_size between 1 and 5 - and l_shipmode in ('AIR', 'AIR REG') - and l_shipinstruct = 'DELIVER IN PERSON' - ) - or - ( - p_brand = 'Brand#23' - and p_container in ('MED BAG', 'MED BOX', 'MED PKG', 'MED PACK') - and l_quantity >= 10 and l_quantity <= 20 - and p_size between 1 and 10 - and l_shipmode in ('AIR', 'AIR REG') - and l_shipinstruct = 'DELIVER IN PERSON' - ) - or - ( - p_brand = 'Brand#34' - and p_container in ('LG CASE', 'LG BOX', 'LG PACK', 'LG PKG') - and l_quantity >= 20 and l_quantity <= 30 - and p_size between 1 and 15 - and l_shipmode in ('AIR', 'AIR REG') - and l_shipinstruct = 'DELIVER IN PERSON' - ) - ) diff --git a/wren-tests/src/test/resources/tpch/queries/2.sql b/wren-tests/src/test/resources/tpch/queries/2.sql deleted file mode 100644 index 108126fcf..000000000 --- a/wren-tests/src/test/resources/tpch/queries/2.sql +++ /dev/null @@ -1,48 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Minimum Cost Supplier Query (Q2) --- Functional Query Definition --- Approved February 1998 - -select - s_acctbal, - s_name, - n_name, - p_partkey, - p_mfgr, - s_address, - s_phone, - s_comment -from - part, - supplier, - partsupp, - nation, - region -where - p_partkey = ps_partkey - and s_suppkey = ps_suppkey - and p_size = 15 - and p_type like '%BRASS' - and s_nationkey = n_nationkey - and n_regionkey = r_regionkey - and r_name = 'EUROPE' - and ps_supplycost = ( - select - min(ps_supplycost) - from - partsupp, - supplier, - nation, - region - where - p_partkey = ps_partkey - and s_suppkey = ps_suppkey - and s_nationkey = n_nationkey - and n_regionkey = r_regionkey - and r_name = 'EUROPE' - ) -order by - s_acctbal desc, - n_name, - s_name, - p_partkey diff --git a/wren-tests/src/test/resources/tpch/queries/20.sql b/wren-tests/src/test/resources/tpch/queries/20.sql deleted file mode 100644 index b4fa7173b..000000000 --- a/wren-tests/src/test/resources/tpch/queries/20.sql +++ /dev/null @@ -1,41 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Potential Part Promotion Query (Q20) --- Function Query Definition --- Approved February 1998 -select - s_name, - s_address -from - supplier, nation -where - s_suppkey in ( - select - ps_suppkey - from - partsupp - where - ps_partkey in ( - select - p_partkey - from - part - where - p_name like 'forest%' - ) - and ps_availqty > ( - select - 0.5 * sum(l_quantity) - from - lineitem - where - l_partkey = ps_partkey - and l_suppkey = ps_suppkey - and l_shipdate >= '1994-01-01' - and l_shipdate < '1995-01-01' - ) - ) - and s_nationkey = n_nationkey - and n_name = 'CANADA' -order by - s_name - diff --git a/wren-tests/src/test/resources/tpch/queries/21.sql b/wren-tests/src/test/resources/tpch/queries/21.sql deleted file mode 100644 index c25427755..000000000 --- a/wren-tests/src/test/resources/tpch/queries/21.sql +++ /dev/null @@ -1,44 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Suppliers Who Kept Orders Waiting Query (Q21) --- Functional Query Definition --- Approved February 1998 -select - s_name, - count(*) as numwait -from - supplier, - lineitem l1, - orders, - nation -where - s_suppkey = l1.l_suppkey - and o_orderkey = l1.l_orderkey - and o_orderstatus = 'F' - and l1.l_receiptdate > l1.l_commitdate - and exists ( - select - * - from - lineitem l2 - where - l2.l_orderkey = l1.l_orderkey - and l2.l_suppkey <> l1.l_suppkey - ) - and not exists ( - select - * - from - lineitem l3 - where - l3.l_orderkey = l1.l_orderkey - and l3.l_suppkey <> l1.l_suppkey - and l3.l_receiptdate > l3.l_commitdate - ) - and s_nationkey = n_nationkey - and n_name = 'SAUDI ARABIA' -group by - s_name -order by - numwait desc, - s_name -limit 100 diff --git a/wren-tests/src/test/resources/tpch/queries/22.sql b/wren-tests/src/test/resources/tpch/queries/22.sql deleted file mode 100644 index 8435b7a43..000000000 --- a/wren-tests/src/test/resources/tpch/queries/22.sql +++ /dev/null @@ -1,38 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Global Sales Opportunity Query (Q22) --- Functional Query Definition --- Approved February 1998 -select - cntrycode, - count(*) as numcust, - sum(c_acctbal) as totacctbal -from ( - select - substr(c_phone, 1, 2) as cntrycode, - c_acctbal - from - customer - where - substr(c_phone, 1, 2) in ('13', '31', '23', '29', '30', '18', '17') - and c_acctbal > ( - select - avg(c_acctbal) - from - customer - where - c_acctbal > 0.00 - and substr(c_phone, 1, 2) in ('13', '31', '23', '29', '30', '18', '17') - ) - and not exists ( - select - * - from - orders - where - o_custkey = c_custkey - ) - ) as custsale -group by - cntrycode -order by - cntrycode diff --git a/wren-tests/src/test/resources/tpch/queries/3.sql b/wren-tests/src/test/resources/tpch/queries/3.sql deleted file mode 100644 index 62f33817a..000000000 --- a/wren-tests/src/test/resources/tpch/queries/3.sql +++ /dev/null @@ -1,28 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Shipping Priority Query (Q3) --- Functional Query Definition --- Approved February 1998 - -select - l_orderkey, - sum(l_extendedprice * (1 - l_discount)) as revenue, - o_orderdate, - o_shippriority -from - customer, - orders, - lineitem -where - c_mktsegment = 'BUILDING' - and c_custkey = o_custkey - and l_orderkey = o_orderkey - and o_orderdate < date '1995-03-15' - and l_shipdate > date '1995-03-15' -group by - l_orderkey, - o_orderdate, - o_shippriority -order by - revenue desc, - o_orderdate - diff --git a/wren-tests/src/test/resources/tpch/queries/4.sql b/wren-tests/src/test/resources/tpch/queries/4.sql deleted file mode 100644 index 2ae6ed419..000000000 --- a/wren-tests/src/test/resources/tpch/queries/4.sql +++ /dev/null @@ -1,27 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Order Priority Checking Query (Q4) --- Functional Query Definition --- Approved February 1998 - -select - o_orderpriority, - count(*) as order_count -from - orders -where - o_orderdate >= date '1993-07-01' - and o_orderdate < date '1993-10-01' + interval '3' month - and exists ( - select - * - from - lineitem - where - l_orderkey = o_orderkey - and l_commitdate < l_receiptdate - ) -group by - o_orderpriority -order by - o_orderpriority - diff --git a/wren-tests/src/test/resources/tpch/queries/5.sql b/wren-tests/src/test/resources/tpch/queries/5.sql deleted file mode 100644 index 5eb4ea686..000000000 --- a/wren-tests/src/test/resources/tpch/queries/5.sql +++ /dev/null @@ -1,29 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Local Supplier Volume Query (Q5) --- Functional Query Definition --- Approved February 1998 - -select - n_name, - sum(l_extendedprice * (1 - l_discount)) as revenue -from - customer, - orders, - lineitem, - supplier, - nation, - region -where - c_custkey = o_custkey - and l_orderkey = o_orderkey - and l_suppkey = s_suppkey - and c_nationkey = s_nationkey - and s_nationkey = n_nationkey - and n_regionkey = r_regionkey - and r_name = 'ASIA' - and o_orderdate >= date '1994-01-01' - and o_orderdate < date '1995-01-01' + interval '1' year -group by - n_name -order by - revenue desc diff --git a/wren-tests/src/test/resources/tpch/queries/6.sql b/wren-tests/src/test/resources/tpch/queries/6.sql deleted file mode 100644 index feea3dd6d..000000000 --- a/wren-tests/src/test/resources/tpch/queries/6.sql +++ /dev/null @@ -1,14 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Forecasting Revenue Change Query (Q6) --- Functional Query Definition --- Approved February 1998 - -select - sum(l_extendedprice * l_discount) as revenue -from - lineitem -where - l_shipdate >= date '1994-01-01' - and l_shipdate < date '1995-01-01' + interval '1' year - and l_discount between 0.06 - 0.01 and 0.06 + 0.01 - and l_quantity < 24 diff --git a/wren-tests/src/test/resources/tpch/queries/7.sql b/wren-tests/src/test/resources/tpch/queries/7.sql deleted file mode 100644 index bc8ed03eb..000000000 --- a/wren-tests/src/test/resources/tpch/queries/7.sql +++ /dev/null @@ -1,44 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Volume Shipping Query (Q7) --- Functional Query Definition --- Approved February 1998 - -select - supp_nation, - cust_nation, - l_year, - sum(volume) as revenue -from - ( - select - n1.n_name as supp_nation, - n2.n_name as cust_nation, - extract(year from l_shipdate) as l_year, - l_extendedprice * (1 - l_discount) as volume - from - supplier, - lineitem, - orders, - customer, - nation n1, - nation n2 - where - s_suppkey = l_suppkey - and o_orderkey = l_orderkey - and c_custkey = o_custkey - and s_nationkey = n1.n_nationkey - and c_nationkey = n2.n_nationkey - and ( - (n1.n_name = 'FRANCE' and n2.n_name = 'GERMANY') - or (n1.n_name = 'GERMANY' and n2.n_name = 'FRANCE') - ) - and l_shipdate between date '1995-01-01' and date '1996-12-31' - ) as shipping -group by - supp_nation, - cust_nation, - l_year -order by - supp_nation, - cust_nation, - l_year diff --git a/wren-tests/src/test/resources/tpch/queries/8.sql b/wren-tests/src/test/resources/tpch/queries/8.sql deleted file mode 100644 index 8c3c8c057..000000000 --- a/wren-tests/src/test/resources/tpch/queries/8.sql +++ /dev/null @@ -1,42 +0,0 @@ --- $ID$ --- TPC-H/TPC-R National Market Share Query (Q8) --- Functional Query Definition --- Approved February 1998 - -select - o_year, - sum(case - when nation = 'BRAZIL' then volume - else 0 - end) / sum(volume) as mkt_share -from - ( - select - extract(year from o_orderdate) as o_year, - l_extendedprice * (1 - l_discount) as volume, - n2.n_name as nation - from - part, - supplier, - lineitem, - orders, - customer, - nation n1, - nation n2, - region - where - p_partkey = l_partkey - and s_suppkey = l_suppkey - and l_orderkey = o_orderkey - and o_custkey = c_custkey - and c_nationkey = n1.n_nationkey - and n1.n_regionkey = r_regionkey - and r_name = 'AMERICA' - and s_nationkey = n2.n_nationkey - and o_orderdate between date '1995-01-01' and date '1996-12-31' - and p_type = 'ECONOMY ANODIZED STEEL' - ) as all_nations -group by - o_year -order by - o_year diff --git a/wren-tests/src/test/resources/tpch/queries/9.sql b/wren-tests/src/test/resources/tpch/queries/9.sql deleted file mode 100644 index 0a0a5f10e..000000000 --- a/wren-tests/src/test/resources/tpch/queries/9.sql +++ /dev/null @@ -1,37 +0,0 @@ --- $ID$ --- TPC-H/TPC-R Product Type Profit Measure Query (Q9) --- Functional Query Definition --- Approved February 1998 - -select - nation, - o_year, - sum(amount) as sum_profit -from - ( - select - n_name as nation, - extract(year from o_orderdate) as o_year, - l_extendedprice * (1 - l_discount) - ps_supplycost * l_quantity as amount - from - part, - supplier, - lineitem, - partsupp, - orders, - nation - where - s_suppkey = l_suppkey - and ps_suppkey = l_suppkey - and ps_partkey = l_partkey - and p_partkey = l_partkey - and o_orderkey = l_orderkey - and s_nationkey = n_nationkey - and p_name like '%green%' - ) as profit -group by - nation, - o_year -order by - nation, - o_year desc diff --git a/wren-tests/src/test/resources/tpch_mdl.json b/wren-tests/src/test/resources/tpch_mdl.json deleted file mode 100644 index 6592a28a1..000000000 --- a/wren-tests/src/test/resources/tpch_mdl.json +++ /dev/null @@ -1,404 +0,0 @@ -{ - "catalog": "wrenai", - "schema": "tpch_tiny", - "models": [ - { - "name": "Orders", - "refSql": "select * from tpch.orders", - "columns": [ - { - "name": "orderkey", - "expression": "o_orderkey", - "type": "int4", - "properties": { - "field": "test1", - "nested": { - "n1": "test1", - "n2": "test2" - } - } - }, - { - "name": "custkey", - "expression": "o_custkey", - "type": "int4" - }, - { - "name": "orderstatus", - "expression": "o_orderstatus", - "type": "OrderStatus" - }, - { - "name": "totalprice", - "expression": "o_totalprice", - "type": "float8" - }, - { - "name": "nation_name", - "isCalculated": true, - "expression": "customer.nation.name", - "type": "varchar" - }, - { - "name": "customer", - "type": "Customer", - "relationship": "OrdersCustomer" - }, - { - "name": "orderdate", - "expression": "o_orderdate", - "type": "date" - }, - { - "name": "lineitems", - "type": "Lineitem", - "relationship": "OrdersLineitem" - } - ], - "primaryKey": "orderkey" - }, - { - "name": "Customer", - "refSql": "select * from tpch.customer", - "columns": [ - { - "name": "custkey", - "expression": "c_custkey", - "type": "int4" - }, - { - "name": "nationkey", - "expression": "c_nationkey", - "type": "integer" - }, - { - "name": "name", - "expression": "c_name", - "type": "varchar" - }, - { - "name": "orders", - "type": "Orders", - "relationship": "OrdersCustomer" - }, - { - "name": "nation", - "type": "Nation", - "relationship": "CustomerNation" - }, - { - "name": "custkey_name", - "type": "varchar", - "expression": "{{ concat('c_custkey', 'c_name') }} " - }, - { - "name": "custkey_call_concat", - "type": "varchar", - "expression": "{{ callConcat('c_custkey', concat) }} " - } - ], - "primaryKey": "custkey" - }, - { - "name": "Lineitem", - "refSql": "select * from tpch.lineitem", - "columns": [ - { - "name": "orderkey", - "expression": "l_orderkey", - "type": "int4" - }, - { - "name": "partkey", - "expression": "l_partkey", - "type": "int4" - }, - { - "name": "linenumber", - "expression": "l_linenumber", - "type": "int4" - }, - { - "name": "extendedprice", - "expression": "l_extendedprice", - "type": "float8" - }, - { - "name": "discount", - "expression": "l_discount", - "type": "float8" - }, - { - "name": "shipdate", - "expression": "l_shipdate", - "type": "date" - }, - { - "name": "comment", - "expression": "l_comment", - "type": "varchar" - }, - { - "name": "order", - "type": "int4", - "expression": "1" - }, - { - "name": "part", - "type": "Part", - "relationship": "LineitemPart" - }, - { - "name": "orderkey_linenumber", - "type": "varchar", - "expression": "concat(l_orderkey, l_linenumber)" - } - ], - "primaryKey": "orderkey_linenumber" - }, - { - "name": "Part", - "refSql": "select * from tpch.part", - "columns": [ - { - "name": "partkey", - "expression": "p_partkey", - "type": "int4" - }, - { - "name": "name", - "expression": "p_name", - "type": "varchar" - } - ], - "primaryKey": "partkey" - }, - { - "name": "Nation", - "refSql": "select * from tpch.nation", - "columns": [ - { - "name": "nationkey", - "expression": "n_nationkey", - "type": "int4" - }, - { - "name": "name", - "expression": "n_name", - "type": "varchar" - }, - { - "name": "regionkey", - "expression": "n_regionkey", - "type": "int4" - }, - { - "name": "comment", - "expression": "n_comment", - "type": "varchar" - }, - { - "name": "region", - "type": "Region", - "relationship": "NationRegion" - }, - { - "name": "customer", - "type": "Customer", - "relationship": "CustomerNation" - }, - { - "name": "supplier", - "type": "Supplier", - "relationship": "NationSupplier" - } - ], - "primaryKey": "nationkey" - } - ], - "relationships": [ - { - "name": "OrdersCustomer", - "models": [ - "Orders", - "Customer" - ], - "joinType": "MANY_TO_ONE", - "condition": "Orders.custkey = Customer.custkey" - }, - { - "name": "OrdersLineitem", - "models": [ - "Orders", - "Lineitem" - ], - "joinType": "ONE_TO_MANY", - "condition": "Orders.orderkey = Lineitem.orderkey" - }, - { - "name": "LineitemPart", - "models": [ - "Lineitem", - "Part" - ], - "joinType": "MANY_TO_ONE", - "condition": "Lineitem.partkey = Part.partkey" - }, - { - "name": "CustomerNation", - "models": [ - "Customer", - "Nation" - ], - "joinType": "MANY_TO_ONE", - "condition": "Customer.nationkey = Nation.nationkey" - } - ], - "metrics": [ - { - "name": "Revenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "customer", - "type": "int4", - "expression": "customer.name" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "name": "CustomerRevenue", - "baseObject": "Customer", - "dimension": [ - { - "name": "custkey", - "type": "int4", - "expression": "custkey" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(orders.totalprice)" - } - ], - "timeGrain": [ - { - "name": "orderdate", - "refColumn": "orderdate", - "dateParts": [ - "YEAR", - "MONTH" - ] - } - ] - }, - { - "name": "CustomerDailyRevenue", - "baseObject": "Orders", - "dimension": [ - { - "name": "customer", - "type": "int4", - "expression": "customer.name" - }, - { - "name": "date", - "type": "int4", - "expression": "orderdate" - } - ], - "measure": [ - { - "name": "totalprice", - "type": "int4", - "expression": "sum(totalprice)" - } - ], - "timeGrain": [] - } - ], - "cumulativeMetrics": [ - { - "name": "WeeklyRevenue", - "baseObject": "Orders", - "measure": { - "name": "totalprice", - "type": "int4", - "operator": "sum", - "refColumn": "totalprice" - }, - "window": { - "name": "orderdate", - "refColumn": "orderdate", - "timeUnit": "WEEK", - "start": "1993-01-01", - "end": "1993-12-31" - }, - "cached": false, - "refreshTime": "30m" - } - ], - "enumDefinitions": [ - { - "name": "Status", - "values": [ - { - "name": "F" - }, - { - "name": "O" - }, - { - "name": "P" - } - ] - } - ], - "views": [ - { - "name": "useModel", - "statement": "select * from Orders" - }, - { - "name": "useMetric", - "statement": "select * from Revenue" - }, - { - "name": "useMetricRollUp", - "statement": "select * from roll_up(Revenue, orderdate, YEAR)" - }, - { - "name": "useUseMetric", - "statement": "select * from useMetric" - } - ], - "macros": [ - { - "name": "concat", - "definition": "(arg1: Expression, arg2: Expression) => concat({{ arg1 }}, {{ arg2 }})" - }, - { - "name": "callConcat", - "definition": "(arg1: Expression, func: Macro) => {{ func(arg1, arg1) }}" - } - ] -} \ No newline at end of file