text:
package org.apache.spark.sql.jdbc

import java.sql.{Connection, DriverManager}
import java.util.Properties

import org.apache.spark.SparkConf
import org.apache.spark.sql.{DataFrame, ExplainSuiteHelper, QueryTest, Row}
import org.apache.spark.sql.catalyst.analysis.CannotReplaceMissingTableException
import org.apache.spark.sql.catalyst.plans.logical.{Aggregate, Filter, Sort}
import org.apache.spark.sql.connector.expressions.{FieldReference, NullOrdering, SortDirection, SortValue}
import org.apache.spark.sql.execution.datasources.v2.{DataSourceV2ScanRelation, V1ScanWrapper}
import org.apache.spark.sql.execution.datasources.v2.jdbc.JDBCTableCatalog
import org.apache.spark.sql.functions.{avg, count, lit, sum, udf}
import org.apache.spark.sql.test.SharedSparkSession
import org.apache.spark.util.Utils

class JDBCV2Suite extends QueryTest with SharedSparkSession with ExplainSuiteHelper {
  import testImplicits._

  val tempDir = Utils.createTempDir()
  val url = s"jdbc:h2:${tempDir.getCanonicalPath};user=testUser;password=testPass"
  var conn: java.sql.Connection = null

  override def sparkConf: SparkConf = super.sparkConf
    .set("spark.sql.catalog.h2", classOf[JDBCTableCatalog].getName)
    .set("spark.sql.catalog.h2.url", url)
    .set("spark.sql.catalog.h2.driver", "org.h2.Driver")
    .set("spark.sql.catalog.h2.pushDownAggregate", "true")
    .set("spark.sql.catalog.h2.pushDownLimit", "true")

  private def withConnection[T](f: Connection => T): T = {
    val conn = DriverManager.getConnection(url, new Properties())
    try {
      f(conn)
    } finally {
      conn.close()
    }
  }

  override def beforeAll(): Unit = {
    super.beforeAll()
    Utils.classForName("org.h2.Driver")
    withConnection { conn =>
      conn.prepareStatement("CREATE SCHEMA \"test\"").executeUpdate()
      conn.prepareStatement(
        "CREATE TABLE \"test\".\"empty_table\" (name TEXT(32) NOT NULL, id INTEGER NOT NULL)")
        .executeUpdate()
      conn.prepareStatement(
        "CREATE TABLE \"test\".\"people\" (name TEXT(32) NOT NULL, id INTEGER NOT NULL)")
        .executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"people\" VALUES ('fred', 1)").executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"people\" VALUES ('mary', 2)").executeUpdate()
      conn.prepareStatement(
        "CREATE TABLE \"test\".\"employee\" (dept INTEGER, name TEXT(32), salary NUMERIC(20, 2)," +
          " bonus DOUBLE)").executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"employee\" VALUES (1, 'amy', 10000, 1000)")
        .executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"employee\" VALUES (2, 'alex', 12000, 1200)")
        .executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"employee\" VALUES (1, 'cathy', 9000, 1200)")
        .executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"employee\" VALUES (2, 'david', 10000, 1300)")
        .executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"employee\" VALUES (6, 'jen', 12000, 1200)")
        .executeUpdate()
      conn.prepareStatement(
        "CREATE TABLE \"test\".\"dept\" (\"dept id\" INTEGER NOT NULL)").executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"dept\" VALUES (1)").executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"dept\" VALUES (2)").executeUpdate()

      // scalastyle:off
      conn.prepareStatement(
        "CREATE TABLE \"test\".\"person\" (\"名\" INTEGER NOT NULL)").executeUpdate()
      // scalastyle:on
      conn.prepareStatement("INSERT INTO \"test\".\"person\" VALUES (1)").executeUpdate()
      conn.prepareStatement("INSERT INTO \"test\".\"person\" VALUES (2)").executeUpdate()
    }
  }

  override def afterAll(): Unit = {
    Utils.deleteRecursively(tempDir)
    super.afterAll()
  }

  test("simple scan") {
    checkAnswer(sql("SELECT * FROM h2.test.empty_table"), Seq())
    checkAnswer(sql("SELECT * FROM h2.test.people"), Seq(Row("fred", 1), Row("mary", 2)))
    checkAnswer(sql("SELECT name, id FROM h2.test.people"), Seq(Row("fred", 1), Row("mary", 2)))
  }

  // TABLESAMPLE ({integer_expression | decimal_expression} PERCENT) and
  // TABLESAMPLE (BUCKET integer_expression OUT OF integer_expression)
  // are tested in JDBC dialect tests because TABLESAMPLE is not supported by all the DBMS
  test("TABLESAMPLE (integer_expression ROWS) is the same as LIMIT") {
    val df = sql("SELECT NAME FROM h2.test.employee TABLESAMPLE (3 ROWS)")
    checkSchemaNames(df, Seq("NAME"))
    checkPushedLimit(df, Some(3))
    checkAnswer(df, Seq(Row("amy"), Row("alex"), Row("cathy")))
  }

  private def checkSchemaNames(df: DataFrame, names: Seq[String]): Unit = {
    val scan = df.queryExecution.optimizedPlan.collectFirst {
      case s: DataSourceV2ScanRelation => s
    }.get
    assert(scan.schema.names.sameElements(names))
  }

  test("simple scan with LIMIT") {
    val df1 = spark.read.table("h2.test.employee")
      .where($"dept" === 1).limit(1)
    checkPushedLimit(df1, Some(1))
    checkAnswer(df1, Seq(Row(1, "amy", 10000.00, 1000.0)))

    val df2 = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "2")
      .table("h2.test.employee")
      .filter($"dept" > 1)
      .limit(1)
    checkPushedLimit(df2, Some(1))
    checkAnswer(df2, Seq(Row(2, "alex", 12000.00, 1200.0)))

    val df3 = sql("SELECT name FROM h2.test.employee WHERE dept > 1 LIMIT 1")
    checkSchemaNames(df3, Seq("NAME"))
    checkPushedLimit(df3, Some(1))
    checkAnswer(df3, Seq(Row("alex")))

    val df4 = spark.read
      .table("h2.test.employee")
      .groupBy("DEPT").sum("SALARY")
      .limit(1)
    checkPushedLimit(df4, None)
    checkAnswer(df4, Seq(Row(1, 19000.00)))

    val name = udf { (x: String) => x.matches("cat|dav|amy") }
    val sub = udf { (x: String) => x.substring(0, 3) }
    val df5 = spark.read
      .table("h2.test.employee")
      .select($"SALARY", $"BONUS", sub($"NAME").as("shortName"))
      .filter(name($"shortName"))
      .limit(1)
    // LIMIT is pushed down only if all the filters are pushed down
    checkPushedLimit(df5, None)
    checkAnswer(df5, Seq(Row(10000.00, 1000.0, "amy")))
  }

  private def checkPushedLimit(df: DataFrame, limit: Option[Int] = None,
      sortValues: Seq[SortValue] = Nil): Unit = {
    df.queryExecution.optimizedPlan.collect {
      case relation: DataSourceV2ScanRelation => relation.scan match {
        case v1: V1ScanWrapper =>
          assert(v1.pushedDownOperators.limit === limit)
          assert(v1.pushedDownOperators.sortValues === sortValues)
      }
    }
    if (sortValues.nonEmpty) {
      val sorts = df.queryExecution.optimizedPlan.collect {
        case s: Sort => s
      }
      assert(sorts.isEmpty)
    }
  }

  test("simple scan with top N") {
    val df1 = spark.read
      .table("h2.test.employee")
      .sort("salary")
      .limit(1)
    checkPushedLimit(df1, Some(1), createSortValues())
    checkAnswer(df1, Seq(Row(1, "cathy", 9000.00, 1200.0)))

    val df2 = spark.read.table("h2.test.employee")
      .where($"dept" === 1).orderBy($"salary").limit(1)
    checkPushedLimit(df2, Some(1), createSortValues())
    checkAnswer(df2, Seq(Row(1, "cathy", 9000.00, 1200.0)))

    val df3 = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "2")
      .table("h2.test.employee")
      .filter($"dept" > 1)
      .orderBy($"salary".desc)
      .limit(1)
    checkPushedLimit(
      df3, Some(1), createSortValues(SortDirection.DESCENDING, NullOrdering.NULLS_LAST))
    checkAnswer(df3, Seq(Row(2, "alex", 12000.00, 1200.0)))

    val df4 =
      sql("SELECT name FROM h2.test.employee WHERE dept > 1 ORDER BY salary NULLS LAST LIMIT 1")
    checkSchemaNames(df4, Seq("NAME"))
    checkPushedLimit(df4, Some(1), createSortValues(nullOrdering = NullOrdering.NULLS_LAST))
    checkAnswer(df4, Seq(Row("david")))

    val df5 = spark.read.table("h2.test.employee")
      .where($"dept" === 1).orderBy($"salary")
    checkPushedLimit(df5, None)
    checkAnswer(df5, Seq(Row(1, "cathy", 9000.00, 1200.0), Row(1, "amy", 10000.00, 1000.0)))

    val df6 = spark.read
      .table("h2.test.employee")
      .groupBy("DEPT").sum("SALARY")
      .orderBy("DEPT")
      .limit(1)
    checkPushedLimit(df6)
    checkAnswer(df6, Seq(Row(1, 19000.00)))

    val name = udf { (x: String) => x.matches("cat|dav|amy") }
    val sub = udf { (x: String) => x.substring(0, 3) }
    val df7 = spark.read
      .table("h2.test.employee")
      .select($"SALARY", $"BONUS", sub($"NAME").as("shortName"))
      .filter(name($"shortName"))
      .sort($"SALARY".desc)
      .limit(1)
    // LIMIT is pushed down only if all the filters are pushed down
    checkPushedLimit(df7)
    checkAnswer(df7, Seq(Row(10000.00, 1000.0, "amy")))

    val df8 = spark.read
      .table("h2.test.employee")
      .sort(sub($"NAME"))
      .limit(1)
    checkPushedLimit(df8)
    checkAnswer(df8, Seq(Row(2, "alex", 12000.00, 1200.0)))
  }

  private def createSortValues(
      sortDirection: SortDirection = SortDirection.ASCENDING,
      nullOrdering: NullOrdering = NullOrdering.NULLS_FIRST): Seq[SortValue] = {
    Seq(SortValue(FieldReference("salary"), sortDirection, nullOrdering))
  }

  test("scan with filter push-down") {
    val df = spark.table("h2.test.people").filter($"id" > 1)

    checkFiltersRemoved(df)

    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedFilters: [IsNotNull(ID), GreaterThan(ID,1)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }

    checkAnswer(df, Row("mary", 2))
  }

  test("scan with column pruning") {
    val df = spark.table("h2.test.people").select("id")
    checkSchemaNames(df, Seq("ID"))
    checkAnswer(df, Seq(Row(1), Row(2)))
  }

  test("scan with filter push-down and column pruning") {
    val df = spark.table("h2.test.people").filter($"id" > 1).select("name")
    checkFiltersRemoved(df)
    checkSchemaNames(df, Seq("NAME"))
    checkAnswer(df, Row("mary"))
  }

  test("read/write with partition info") {
    withTable("h2.test.abc") {
      sql("CREATE TABLE h2.test.abc AS SELECT * FROM h2.test.people")
      val df1 = Seq(("evan", 3), ("cathy", 4), ("alex", 5)).toDF("NAME", "ID")
      val e = intercept[IllegalArgumentException] {
        df1.write
          .option("partitionColumn", "id")
          .option("lowerBound", "0")
          .option("upperBound", "3")
          .option("numPartitions", "0")
          .insertInto("h2.test.abc")
      }.getMessage
      assert(e.contains("Invalid value `0` for parameter `numPartitions` in table writing " +
        "via JDBC. The minimum value is 1."))

      df1.write
        .option("partitionColumn", "id")
        .option("lowerBound", "0")
        .option("upperBound", "3")
        .option("numPartitions", "3")
        .insertInto("h2.test.abc")

      val df2 = spark.read
        .option("partitionColumn", "id")
        .option("lowerBound", "0")
        .option("upperBound", "3")
        .option("numPartitions", "2")
        .table("h2.test.abc")

      assert(df2.rdd.getNumPartitions === 2)
      assert(df2.count() === 5)
    }
  }

  test("show tables") {
    checkAnswer(sql("SHOW TABLES IN h2.test"),
      Seq(Row("test", "people", false), Row("test", "empty_table", false),
        Row("test", "employee", false), Row("test", "dept", false), Row("test", "person", false)))
  }

  test("SQL API: create table as select") {
    withTable("h2.test.abc") {
      sql("CREATE TABLE h2.test.abc AS SELECT * FROM h2.test.people")
      checkAnswer(sql("SELECT name, id FROM h2.test.abc"), Seq(Row("fred", 1), Row("mary", 2)))
    }
  }

  test("DataFrameWriterV2: create table as select") {
    withTable("h2.test.abc") {
      spark.table("h2.test.people").writeTo("h2.test.abc").create()
      checkAnswer(sql("SELECT name, id FROM h2.test.abc"), Seq(Row("fred", 1), Row("mary", 2)))
    }
  }

  test("SQL API: replace table as select") {
    withTable("h2.test.abc") {
      intercept[CannotReplaceMissingTableException] {
        sql("REPLACE TABLE h2.test.abc AS SELECT 1 as col")
      }
      sql("CREATE OR REPLACE TABLE h2.test.abc AS SELECT 1 as col")
      checkAnswer(sql("SELECT col FROM h2.test.abc"), Row(1))
      sql("REPLACE TABLE h2.test.abc AS SELECT * FROM h2.test.people")
      checkAnswer(sql("SELECT name, id FROM h2.test.abc"), Seq(Row("fred", 1), Row("mary", 2)))
    }
  }

  test("DataFrameWriterV2: replace table as select") {
    withTable("h2.test.abc") {
      intercept[CannotReplaceMissingTableException] {
        sql("SELECT 1 AS col").writeTo("h2.test.abc").replace()
      }
      sql("SELECT 1 AS col").writeTo("h2.test.abc").createOrReplace()
      checkAnswer(sql("SELECT col FROM h2.test.abc"), Row(1))
      spark.table("h2.test.people").writeTo("h2.test.abc").replace()
      checkAnswer(sql("SELECT name, id FROM h2.test.abc"), Seq(Row("fred", 1), Row("mary", 2)))
    }
  }

  test("SQL API: insert and overwrite") {
    withTable("h2.test.abc") {
      sql("CREATE TABLE h2.test.abc AS SELECT * FROM h2.test.people")

      sql("INSERT INTO h2.test.abc SELECT 'lucy', 3")
      checkAnswer(
        sql("SELECT name, id FROM h2.test.abc"),
        Seq(Row("fred", 1), Row("mary", 2), Row("lucy", 3)))

      sql("INSERT OVERWRITE h2.test.abc SELECT 'bob', 4")
      checkAnswer(sql("SELECT name, id FROM h2.test.abc"), Row("bob", 4))
    }
  }

  test("DataFrameWriterV2: insert and overwrite") {
    withTable("h2.test.abc") {
      sql("CREATE TABLE h2.test.abc AS SELECT * FROM h2.test.people")

      // `DataFrameWriterV2` is by-name.
      sql("SELECT 3 AS ID, 'lucy' AS NAME").writeTo("h2.test.abc").append()
      checkAnswer(
        sql("SELECT name, id FROM h2.test.abc"),
        Seq(Row("fred", 1), Row("mary", 2), Row("lucy", 3)))

      sql("SELECT 'bob' AS NAME, 4 AS ID").writeTo("h2.test.abc").overwrite(lit(true))
      checkAnswer(sql("SELECT name, id FROM h2.test.abc"), Row("bob", 4))
    }
  }

  private def checkAggregateRemoved(df: DataFrame, removed: Boolean = true): Unit = {
    val aggregates = df.queryExecution.optimizedPlan.collect {
      case agg: Aggregate => agg
    }
    if (removed) {
      assert(aggregates.isEmpty)
    } else {
      assert(aggregates.nonEmpty)
    }
  }

  test("scan with aggregate push-down: MAX AVG with filter and group by") {
    val df = sql("select MAX(SaLaRY), AVG(BONUS) FROM h2.test.employee where dept > 0" +
      " group by DePt")
    checkFiltersRemoved(df)
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [MAX(SALARY), AVG(BONUS)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(10000, 1100.0), Row(12000, 1250.0), Row(12000, 1200.0)))
  }

  private def checkFiltersRemoved(df: DataFrame): Unit = {
    val filters = df.queryExecution.optimizedPlan.collect {
      case f: Filter => f
    }
    assert(filters.isEmpty)
  }

  test("scan with aggregate push-down: MAX AVG with filter without group by") {
    val df = sql("select MAX(ID), AVG(ID) FROM h2.test.people where id > 0")
    checkFiltersRemoved(df)
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [MAX(ID), AVG(ID)], " +
            "PushedFilters: [IsNotNull(ID), GreaterThan(ID,0)], " +
            "PushedGroupByColumns: []"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(2, 1.5)))
  }

  test("partitioned scan with aggregate push-down: complete push-down only") {
    withTempView("v") {
      spark.read
        .option("partitionColumn", "dept")
        .option("lowerBound", "0")
        .option("upperBound", "2")
        .option("numPartitions", "2")
        .table("h2.test.employee")
        .createTempView("v")
      val df = sql("select AVG(SALARY) FROM v GROUP BY name")
      // Partitioned JDBC Scan doesn't support complete aggregate push-down, and AVG requires
      // complete push-down so aggregate is not pushed at the end.
      checkAggregateRemoved(df, removed = false)
      checkAnswer(df, Seq(Row(9000.0), Row(10000.0), Row(10000.0), Row(12000.0), Row(12000.0)))
    }
  }

  test("scan with aggregate push-down: aggregate + number") {
    val df = sql("select MAX(SALARY) + 1 FROM h2.test.employee")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [MAX(SALARY)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(12001)))
  }

  test("scan with aggregate push-down: COUNT(*)") {
    val df = sql("select COUNT(*) FROM h2.test.employee")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [COUNT(*)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(5)))
  }

  test("scan with aggregate push-down: COUNT(col)") {
    val df = sql("select COUNT(DEPT) FROM h2.test.employee")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [COUNT(DEPT)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(5)))
  }

  test("scan with aggregate push-down: COUNT(DISTINCT col)") {
    val df = sql("select COUNT(DISTINCT DEPT) FROM h2.test.employee")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [COUNT(DISTINCT DEPT)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(3)))
  }

  test("scan with aggregate push-down: SUM without filer and group by") {
    val df = sql("SELECT SUM(SALARY) FROM h2.test.employee")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(SALARY)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(53000)))
  }

  test("scan with aggregate push-down: DISTINCT SUM without filer and group by") {
    val df = sql("SELECT SUM(DISTINCT SALARY) FROM h2.test.employee")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(DISTINCT SALARY)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(31000)))
  }

  test("scan with aggregate push-down: SUM with group by") {
    val df = sql("SELECT SUM(SALARY) FROM h2.test.employee GROUP BY DEPT")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(SALARY)], " +
            "PushedFilters: [], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(19000), Row(22000), Row(12000)))
  }

  test("scan with aggregate push-down: DISTINCT SUM with group by") {
    val df = sql("SELECT SUM(DISTINCT SALARY) FROM h2.test.employee GROUP BY DEPT")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(DISTINCT SALARY)], " +
            "PushedFilters: [], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(19000), Row(22000), Row(12000)))
  }

  test("scan with aggregate push-down: with multiple group by columns") {
    val df = sql("select MAX(SALARY), MIN(BONUS) FROM h2.test.employee where dept > 0" +
      " group by DEPT, NAME")
    checkFiltersRemoved(df)
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [MAX(SALARY), MIN(BONUS)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT, NAME]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(9000, 1200), Row(12000, 1200), Row(10000, 1300),
      Row(10000, 1000), Row(12000, 1200)))
  }

  test("scan with aggregate push-down: with concat multiple group key in project") {
    val df1 = sql("select concat_ws('#', DEPT, NAME), MAX(SALARY) FROM h2.test.employee" +
      " where dept > 0 group by DEPT, NAME")
    val filters1 = df1.queryExecution.optimizedPlan.collect {
      case f: Filter => f
    }
    assert(filters1.isEmpty)
    checkAggregateRemoved(df1)
    df1.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [MAX(SALARY)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT, NAME]"
        checkKeywordsExistsInExplain(df1, expected_plan_fragment)
    }
    checkAnswer(df1, Seq(Row("1#amy", 10000), Row("1#cathy", 9000), Row("2#alex", 12000),
      Row("2#david", 10000), Row("6#jen", 12000)))

    val df2 = sql("select concat_ws('#', DEPT, NAME), MAX(SALARY) + MIN(BONUS)" +
      " FROM h2.test.employee where dept > 0 group by DEPT, NAME")
    val filters2 = df2.queryExecution.optimizedPlan.collect {
      case f: Filter => f
    }
    assert(filters2.isEmpty)
    checkAggregateRemoved(df2)
    df2.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [MAX(SALARY), MIN(BONUS)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT, NAME]"
        checkKeywordsExistsInExplain(df2, expected_plan_fragment)
    }
    checkAnswer(df2, Seq(Row("1#amy", 11000), Row("1#cathy", 10200), Row("2#alex", 13200),
      Row("2#david", 11300), Row("6#jen", 13200)))

    val df3 = sql("select concat_ws('#', DEPT, NAME), MAX(SALARY) + MIN(BONUS)" +
      " FROM h2.test.employee where dept > 0 group by concat_ws('#', DEPT, NAME)")
    val filters3 = df3.queryExecution.optimizedPlan.collect {
      case f: Filter => f
    }
    assert(filters3.isEmpty)
    checkAggregateRemoved(df3, false)
    df3.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], "
        checkKeywordsExistsInExplain(df3, expected_plan_fragment)
    }
    checkAnswer(df3, Seq(Row("1#amy", 11000), Row("1#cathy", 10200), Row("2#alex", 13200),
      Row("2#david", 11300), Row("6#jen", 13200)))
  }

  test("scan with aggregate push-down: with having clause") {
    val df = sql("select MAX(SALARY), MIN(BONUS) FROM h2.test.employee where dept > 0" +
      " group by DEPT having MIN(BONUS) > 1000")
    val filters = df.queryExecution.optimizedPlan.collect {
      case f: Filter => f  // filter over aggregate not push down
    }
    assert(filters.nonEmpty)
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [MAX(SALARY), MIN(BONUS)], " +
          "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
          "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(12000, 1200), Row(12000, 1200)))
  }

  test("scan with aggregate push-down: alias over aggregate") {
    val df = sql("select * from h2.test.employee")
      .groupBy($"DEPT")
      .min("SALARY").as("total")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [MIN(SALARY)], " +
            "PushedFilters: [], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(1, 9000), Row(2, 10000), Row(6, 12000)))
  }

  test("scan with aggregate push-down: order by alias over aggregate") {
    val df = spark.table("h2.test.employee")
    val query = df.select($"DEPT", $"SALARY")
      .filter($"DEPT" > 0)
      .groupBy($"DEPT")
      .agg(sum($"SALARY").as("total"))
      .filter($"total" > 1000)
      .orderBy($"total")
    val filters = query.queryExecution.optimizedPlan.collect {
      case f: Filter => f
    }
    assert(filters.nonEmpty) // filter over aggregate not pushed down
    checkAggregateRemoved(df)
    query.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(SALARY)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(query, expected_plan_fragment)
    }
    checkAnswer(query, Seq(Row(6, 12000), Row(1, 19000), Row(2, 22000)))
  }

  test("scan with aggregate push-down: udf over aggregate") {
    val df = spark.table("h2.test.employee")
    val decrease = udf { (x: Double, y: Double) => x - y }
    val query = df.select(decrease(sum($"SALARY"), sum($"BONUS")).as("value"))
    checkAggregateRemoved(query)
    query.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(SALARY), SUM(BONUS)]"
        checkKeywordsExistsInExplain(query, expected_plan_fragment)
    }
    checkAnswer(query, Seq(Row(47100.0)))
  }

  test("scan with aggregate push-down: partition columns are same as group by columns") {
    val df = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "2")
      .table("h2.test.employee")
      .groupBy($"dept")
      .count()
    checkAggregateRemoved(df)
    checkAnswer(df, Seq(Row(1, 2), Row(2, 2), Row(6, 1)))
  }

  test("scan with aggregate push-down: VAR_POP VAR_SAMP with filter and group by") {
    val df = sql("select VAR_POP(bonus), VAR_SAMP(bonus) FROM h2.test.employee where dept > 0" +
      " group by DePt")
    checkFiltersRemoved(df)
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [VAR_POP(BONUS), VAR_SAMP(BONUS)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(10000d, 20000d), Row(2500d, 5000d), Row(0d, null)))
  }

  test("scan with aggregate push-down: STDDEV_POP STDDEV_SAMP with filter and group by") {
    val df = sql("select STDDEV_POP(bonus), STDDEV_SAMP(bonus) FROM h2.test.employee" +
      " where dept > 0 group by DePt")
    checkFiltersRemoved(df)
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [STDDEV_POP(BONUS), STDDEV_SAMP(BONUS)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(100d, 141.4213562373095d), Row(50d, 70.71067811865476d), Row(0d, null)))
  }

  test("scan with aggregate push-down: COVAR_POP COVAR_SAMP with filter and group by") {
    val df = sql("select COVAR_POP(bonus, bonus), COVAR_SAMP(bonus, bonus)" +
      " FROM h2.test.employee where dept > 0 group by DePt")
    checkFiltersRemoved(df)
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [COVAR_POP(BONUS, BONUS), COVAR_SAMP(BONUS, BONUS)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(10000d, 20000d), Row(2500d, 5000d), Row(0d, null)))
  }

  test("scan with aggregate push-down: CORR with filter and group by") {
    val df = sql("select CORR(bonus, bonus) FROM h2.test.employee where dept > 0" +
      " group by DePt")
    checkFiltersRemoved(df)
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [CORR(BONUS, BONUS)], " +
            "PushedFilters: [IsNotNull(DEPT), GreaterThan(DEPT,0)], " +
            "PushedGroupByColumns: [DEPT]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(1d), Row(1d), Row(null)))
  }

  test("scan with aggregate push-down: aggregate over alias NOT push down") {
    val cols = Seq("a", "b", "c", "d")
    val df1 = sql("select * from h2.test.employee").toDF(cols: _*)
    val df2 = df1.groupBy().sum("c")
    checkAggregateRemoved(df2, false)
    df2.queryExecution.optimizedPlan.collect {
      case relation: DataSourceV2ScanRelation => relation.scan match {
        case v1: V1ScanWrapper =>
          assert(v1.pushedDownOperators.aggregation.isEmpty)
      }
    }
    checkAnswer(df2, Seq(Row(53000.00)))
  }

  test("scan with aggregate push-down: aggregate with partially pushed down filters" +
    "will NOT push down") {
    val df = spark.table("h2.test.employee")
    val name = udf { (x: String) => x.matches("cat|dav|amy") }
    val sub = udf { (x: String) => x.substring(0, 3) }
    val query = df.select($"SALARY", $"BONUS", sub($"NAME").as("shortName"))
      .filter("SALARY > 100")
      .filter(name($"shortName"))
      .agg(sum($"SALARY").as("sum_salary"))
    checkAggregateRemoved(query, false)
    query.queryExecution.optimizedPlan.collect {
      case relation: DataSourceV2ScanRelation => relation.scan match {
        case v1: V1ScanWrapper =>
          assert(v1.pushedDownOperators.aggregation.isEmpty)
      }
    }
    checkAnswer(query, Seq(Row(29000.0)))
  }

  test("scan with aggregate push-down: SUM(CASE WHEN) with group by") {
    val df =
      sql("SELECT SUM(CASE WHEN SALARY > 0 THEN 1 ELSE 0 END) FROM h2.test.employee GROUP BY DEPT")
    checkAggregateRemoved(df, false)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedFilters: [], "
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(1), Row(2), Row(2)))
  }

  test("scan with aggregate push-down: partition columns with multi group by columns") {
    val df = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "2")
      .table("h2.test.employee")
      .groupBy($"dept", $"name")
      .count()
    checkAggregateRemoved(df, false)
    checkAnswer(df, Seq(Row(1, "amy", 1), Row(1, "cathy", 1),
      Row(2, "alex", 1), Row(2, "david", 1), Row(6, "jen", 1)))
  }

  test("scan with aggregate push-down: partition columns is different from group by columns") {
    val df = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "2")
      .table("h2.test.employee")
      .groupBy($"name")
      .count()
    checkAggregateRemoved(df, false)
    checkAnswer(df,
      Seq(Row("alex", 1), Row("amy", 1), Row("cathy", 1), Row("david", 1), Row("jen", 1)))
  }

  test("column name with composite field") {
    checkAnswer(sql("SELECT `dept id` FROM h2.test.dept"), Seq(Row(1), Row(2)))
    val df = sql("SELECT COUNT(`dept id`) FROM h2.test.dept")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [COUNT(`dept id`)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(2)))
  }

  test("column name with non-ascii") {
    // scalastyle:off
    checkAnswer(sql("SELECT `名` FROM h2.test.person"), Seq(Row(1), Row(2)))
    val df = sql("SELECT COUNT(`名`) FROM h2.test.person")
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [COUNT(`名`)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(2)))
    // scalastyle:on
  }

  test("scan with aggregate push-down: complete push-down SUM, AVG, COUNT") {
    val df = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "1")
      .table("h2.test.employee")
      .agg(sum($"SALARY").as("sum"), avg($"SALARY").as("avg"), count($"SALARY").as("count"))
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(SALARY), AVG(SALARY), COUNT(SALARY)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(53000.00, 10600.000000, 5)))

    val df2 = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "1")
      .table("h2.test.employee")
      .groupBy($"name")
      .agg(sum($"SALARY").as("sum"), avg($"SALARY").as("avg"), count($"SALARY").as("count"))
    checkAggregateRemoved(df)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(SALARY), AVG(SALARY), COUNT(SALARY)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df2, Seq(
      Row("alex", 12000.00, 12000.000000, 1),
      Row("amy", 10000.00, 10000.000000, 1),
      Row("cathy", 9000.00, 9000.000000, 1),
      Row("david", 10000.00, 10000.000000, 1),
      Row("jen", 12000.00, 12000.000000, 1)))
  }

  test("scan with aggregate push-down: partial push-down SUM, AVG, COUNT") {
    val df = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "2")
      .table("h2.test.employee")
      .agg(sum($"SALARY").as("sum"), avg($"SALARY").as("avg"), count($"SALARY").as("count"))
    checkAggregateRemoved(df, false)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(SALARY), COUNT(SALARY)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df, Seq(Row(53000.00, 10600.000000, 5)))

    val df2 = spark.read
      .option("partitionColumn", "dept")
      .option("lowerBound", "0")
      .option("upperBound", "2")
      .option("numPartitions", "2")
      .table("h2.test.employee")
      .groupBy($"name")
      .agg(sum($"SALARY").as("sum"), avg($"SALARY").as("avg"), count($"SALARY").as("count"))
    checkAggregateRemoved(df, false)
    df.queryExecution.optimizedPlan.collect {
      case _: DataSourceV2ScanRelation =>
        val expected_plan_fragment =
          "PushedAggregates: [SUM(SALARY), COUNT(SALARY)]"
        checkKeywordsExistsInExplain(df, expected_plan_fragment)
    }
    checkAnswer(df2, Seq(
      Row("alex", 12000.00, 12000.000000, 1),
      Row("amy", 10000.00, 10000.000000, 1),
      Row("cathy", 9000.00, 9000.000000, 1),
      Row("david", 10000.00, 10000.000000, 1),
      Row("jen", 12000.00, 12000.000000, 1)))
  }
}


text:
Raise taxes? Oklahoma gubernatorial candidates vary in their answers
Ben Felder
On a steamy June afternoon, three candidates vying for the Republican nomination in a special state Senate election gathered for a voter forum at a south Oklahoma City library.
The couple of dozen spectators who showed up picked over a spread of chicken nuggets and lemonade catered by a local restaurant before taking a seat.
Over the next hour, the Republican candidates pitched their ideas to the room, which was made up of a core of Republican primary voters — mostly white, older and fiercely anti-tax.
Rather than a shortage of tax revenue, the candidates targeted wasteful spending as the culprit for Oklahoma's budget woes. In answering a question from a voter in the audience, one candidate hinted at the need to "raise revenue," yet never came close to saying out loud that taxes on businesses and residents should be higher than they already are.
Standing in the back of the room was Gary Jones, the state auditor and inspector, who is running in the Republican primary for governor.
Before him was a reminder that the part of his platform that includes tax increases would have to be delivered with care when looking to win over some of the state's most conservative voters who will help determine which Republican wins the party's nomination for governor in June.
"We have way too many people who want to run government on a philosophy instead of a sound strategy," said Jones, who said he supports an increase in gross production tax to 5 percent, and supports an increase on the gasoline tax, if the money goes to road repairs.
"I'm the first to tell you I believe we can find efficiency in government, but I also believe we have to find new revenue."
Lt. Gov. Todd Lamb, a Republican who also is running for governor, is firmly in the anti-tax camp.
"Just on raising taxes, I'm opposed," Lamb said last month on an episode of The Oklahoman's Political State podcast. "It's not against the law to pay more than you owe, but you know why folks don't do it? They think they are paying enough."
Lamb said he didn't want to play "Monday morning quarterback" on the specific tax proposals that have been offered during a special session of the state Legislature, which has debated how to fill a nearly $215 million budget shortfall.
"But no one has convinced me yet that we have a serious revenue problem," Lamb said.
Earlier this year, Lamb resigned his position on Gov. Mary Fallin's cabinet in objection to her proposal to expand sales tax on a slate of services, reiterating the anti-tax platform he has carried into the gubernatorial race.
Tulsa attorney Gary Richardson, another Republican candidate for governor, has been an even fiercer critic of tax increase proposals from Fallin and the Legislature.
"Once again, our GOP leaders have failed to follow the principles of their party by supporting massive tax increases on gasoline, beer, and cigarettes," Richardson said in a statement while the Legislature was considering those tax increases during the special session. "As much as I support increasing teacher pay, we must first audit every state agency, trust, and authority before considering any new tax increases."
Voter shift?
But with the state facing a precarious budget situation, some believe the posture on tax increases by Republican voters might be shifting, if only a bit.
"It's a peculiar time for the Republican party right now because the party for many decades has been opposed to increasing taxes," said Trebor Worthen, a political consultant with Marathon Consulting, which does not currently represent any of the gubernatorial candidates. "But today the dynamic is you have a Republican governor who is insistent on raising taxes and you have (Republican) leadership in the House and Senate who are willing to have that conversation."
Worthen said the challenge for Republican candidates, of which there are several, is the state's budget challenges have more Oklahomans open to raising revenue — according to multiple polls — but the anti-tax message remains popular, especially among many primary voters.
"I think the (voter) intensity is still on the no tax side," Worthen said. "If you are a Republican who is opposed to tax increases right now you are probably more enthusiastic about it than someone who is for a tax increase on tobacco, for example."
Also in the run for the Republican primary is Mick Cornett, the mayor of Oklahoma City who helped lead efforts to retain the city's popular MAPS sales tax that has funded numerous capital projects, mostly in the downtown area.
"Raising taxes is never my first instinct to a budget issue," Cornett said in a statement to The Oklahoman when asked about the specific tax increases being proposed in the Legislature. "In Oklahoma City, we begin working on the budget early, with input from everyone, including citizens. Our leadership has brought Oklahoma City balanced budgets year after year, a 15 percent rainy day fund, and the highest bond rating available. This type of leadership is exactly what I hope to bring to the Governor's office."
Democratic opportunity?
But while some Republican candidates might find success in the primary with an objection to tax hikes, or at least an unwillingness to build their campaign around a specific tax increase, some believe the Democratic nominee could win the argument in the general election.
"This year the big debate wasn't about whether we should raise taxes, it was about which taxes should we raise," said Gene Perry, policy director at the Oklahoma Policy Institute. "I know that people who have been running for the Legislature recently have said what they are hearing on the doorstep is not cut my taxes, it's give our teachers a raise, and that takes a tax increase."
Democrat and gubernatorial candidate Drew Edmondson said he supports an increase on tobacco and gross production taxes, which he believes is supported by most Oklahomans.
"I think we desperately need additional revenue, particularly recurring revenue," said Edmondson, who added that his call to put an oil and gas production tax increase on a statewide ballot draws wide applause when he speaks to voters across the state.
"In what's perceived to be a fairly red state, that is a game changer," Edmondson said about a willingness from voters to raise taxes, and what it could mean for the chances of a Democratic candidate for governor. "I really believe that if I win this nomination I will have the high ground headed to November."
Former state Sen. Connie Johnson, who is the other Democratic candidate for governor, not only backs those same tax increases, but would like to see the state reform its policies on cannabis and expand production of hemp, creating a new source of taxable revenue.
"It's going to take some political courage to be willing to throw out innovative proposals, and I think Oklahomans are ready," Johnson said.
'The answer is the budget'
There may be other issues to address in a campaign for governor over the next several months, but Johnson said the budget shortfall is at the heart of most of the state's challenges.
"Regardless of the question, the answer is the budget," Johnson said. "You talk about health care, it's the budget. You can talk about jobs, infrastructure and education, but it's still about the budget."
Even if the Legislature can move past the current budget issues well before next year's elections, Perry said the problem of the state not having enough money is going to remain.
"None of these problems we are dealing with are going to be better next year," Perry said. "They might even be worse."
"I think it's going to be a huge issue in the primary and the general elections," Worthen said. "When it comes to the governor's race, voters are going to be looking for a candidate they believe is willing to present solutions.
"This is not an election cycle where I think the same old messaging is going to carry people through primaries. In many districts across the state, voters are looking for something new, even in the Republican primary."

redpajama_set_name: RedPajamaCommonCrawl


Andrew Katos makes the election pledge at Mount Moriac Reserve.
Member for South Barwon Andrew Katos MP announced that if elected to Government in November, the Liberals would commit $650,000 towards Stage 2 of upgrades for Mount Moriac Reserve.
The upgrades will consist of providing improved lighting, drainage and netball shelters for the Modewarre Football and Netball Club.
The upgrade will also go towards the Mt Moriac Reserve Equestrian Facility Pavilion Upgrade, which will allow for increased storage, female change facilities, new kitchen facilities and a new function space.
This announcement expands on the previous Liberal Nationals Government's $650,000 commitment towards Stage 1 of the Mount Moriac Reserve Master Plan which totally rebuilt the club rooms.
Established in 1879, Modewarre Football and Netball Club provide avenues for all ages and is the heart and soul of the local community. Completing these upgrades at Mount Moriac Reserve will allow for the football and netball club, and equestrian clubs to continue to flourish and give teams the best conditions to play, ride and train in.
The Modewarre Football and Netball Club is an ever-expanding club and Andrew Katos MP, Member for South Barwon said he was proud to be fighting for the club to expand even further – and continue to deliver excellent sporting results by upgrading their local reserve.
"This upgrade will continue to improve ground access for hundreds of club members and players and is a fantastic win for our local sporting clubs. I am beyond proud to have advocated for this result.
"Daniel Andrews gives $225 million away to the AFL but fails to ensure our local clubs receive anything when they are crying out for funding.


text:
Preferred payment option is Google Wallet (send to: doghikingpayments@gmail.com). Cash and check are also accepted.
Membership payments are due in full on or before the 1st of each month. If paying by cash or check, please make arrangements to ensure that your payment is received by the 1st of the month.
Please provide 30 days written notice of any significant changes to your membership. See examples below:
"I'm going to be out of the country, can I skip x month?"
"I'm moving..."
"I'd like to take the summer off because..."
"I'm switching jobs and need to make x change..."
"I need to change my hike day(s) because..."
Vacation Policy
Please provide 30 days written notice of vacations.
Members may store their vacation days as a credit toward future hikes.
Example: A Single member is taking a one week vacation and will miss one hike during this time. This member can make-up the hike at a later date. The member pays the regular membership rate and will have one credit for a make-up hike. Limit 3 make-up credits at one time. Any unused credits will expire at the end of the following month (credits for hikes missed in January would expire at end of February). Members are responsible for initiating make-up hike scheduling.
Alternatively, members may use Rewards (see section below) as a credit toward vacation time.
Example: A Single member has earned 70 points and wants to use the points toward one hike which will be missed during an upcoming vacation. In this case, 50 points would be deducted from the member's point balance and applied as a credit to the member's account so that the membership fee would be prorated for that month. This member would then have a remaining Reward balance of 20 points.
Contracts are month-to-month with a 30 day cancellation policy. Please reference section 4 of your Service Contract for details.
We are excited to offer the below reward programs as a way to say thanks for being a loyal Dog Hiking Adventures member. Rewards points can be used to add additional hikes or applied toward monthly membership fees – you can even opt to gift your free hike to a friend!
Participating members are eligible to receive reward points for continued membership.
10 points awarded for each full month of active membership.
Participating members are eligible to receive reward points for referrals.
25 points awarded for each referral that leads to membership purchase.
Participating members are eligible to receive reward points for reviews.
20 points awarded for a detailed Yelp or Google+ review.
Redemption Value
25 points are redeemable for one free DogFit workout.
50 points are redeemable for one free hike.
50 points are redeemable for one free mini dog training session.
Please note that reward points are "use it or lose it" and expire at the end of the calendar year in which they were accrued.
allparkspublicuse.pdf
Dog friendly Midpeninsula Regional Open Space District (MROSD) maps.


text:
Oh but Coggin, I can hear you say as you leap from your La-Z-Boy, a week's worth of stale chips entangling themselves from your soiled tank top…what about funky buttloving?! What about the wacky coach Daniel Stern played? Remember when the coach pronounced Henry's name incorrectly the entire movie? What a laugh riot!
Spare me. Little Big League, a rival movie about Billy Heywood, a smart 12-year-old with a good head on his shoulders who finds himself in the major leagues, is a piece of art. It portrays a young man's pathway to adulthood as he deals with the pressures of owning the Minnesota Twins after the untimely death of his grandfather, the struggles of fitting in with professional athletes and their stereotyped opinions on hyper masculinity, and the shame of the team's first baseman plowing out his single mom on a nightly basis.
His struggle is all of our struggle. Who among us didn't question our place in society as a 12-year-old? Heywood is an everyman, who proved himself at the major league level and gained the respect of his peers through RESULTS. Henry Rowengartner is a freak, a sideshow clown only given a shot by a struggling franchise that needed a hook to sell out consecutive games and exploit a young rube who isn't smart enough to realize he's being taken advantage of.
Also, here's the thing folks. A kid can't pitch in the major leagues. I don't care if his tendons have tightened after shattering his arm or whatever piece of voodoo and hoodoo Henry Rowengartner did to his body to be able to throw 99 miles per hour (no injury does that, his mom probably had him so whacked out of his gourd on performance enhancing stimulants and goofballs it's criminal), you can't play in the MLB unless you're 18 years old (17 if you're an international player). Sorry gang, I don't make the rules, Major League Baseball does so take it up with them.
Show me in an official Major League Baseball rulebook where it says a 12-year-old CAN'T own his own baseball team and decree he'll also be its manager? You can't because it's simply not there. Rookie of the Year dabbles in pure fiction where Little Big League resides in pure scientific fact. Is it improbable? Sure it is! 12-year-olds usually don't own teams or coach rag tag squads to division tiebreakers against an absolutely stacked mid-90s Seattle Mariners organization, but who would have thought a backup quarterback could have led the Eagles to a miraculous Super Bowl victory over the powerhouse New England Patriots? Overcoming great odds makes for a fantastic movie…whimsical childhood dreams and crude writing do not.
Think about it this way….no 12-year-old in the history of sport could EVER strike out the author of this post on a regulation diamond. Put any little putz 60-feet and 6-inches from Old Uncle Coggin and the result is going to be the same every time….that kid's walking off the mound in tears as I shout obscenities in his direction and make lewd overtures to his mother while trotting around the bases, only stopping to admire the massive bomb I crushed off the pre-pubescent hack.
Now…could a 12-year-old out-coach your favorite blogger? Again, it's improbable, but it COULD happen, especially if he's a fountain of encyclopedic baseball knowledge like Billy.
And let's forget the rulebook or improbability of it all for just a moment. Suspension of disbelief is key for a good sports movie. Let's put aside the insanity of a literal child performing at an elite athletic level and magically striking out seasoned professionals and future hall of famers with only ONE pitch in his entire arsenal…one, I might add, that has been repeated many times by many athletes who came before and after Henry. 100 miles per hour is impressive, yes, but not un-hittable.
Let's put all that nonsense aside and look into the character of our two protagonists. One, as I mentioned, is a sideshow freak only given the opportunity to pitch after displaying his impressive, genetically altered arm while throwing a home run back onto the field of play in Wrigley, a highly illegal and dangerous act that should have resulted in immediate ejection from the stadium. I don't care if it's tradition, if a fan puts the safety of the players at risk he should be banned from attending games for the rest of his life. It was an ugly action and Rowengartner was lucky he didn't get anyone killed through his rash and impudent decision making.
The second is a clean cut, popular young man who EARNS his pinstripes, so to say, after his grandfather bequeaths him the Minnesota Twins franchise after his untimely death. Billy proves himself to seasoned pitching coach Mac Macnally during an impromptu tryout. After being thoroughly grilled with coaching scenario after coaching scenario, Heywood passes with flying colors and installs himself as the Twins new head coach. Immediately he shows a savvy and even-keeled approach with the media, answer questions like a professional and a man who is ready to take the weight of an entire franchise on his shoulders.
The same, sadly, cannot be said for Rowengartner, whose immaturity is seen at every level. He stammers and his voice cracks during his initial press conference. He displays an unprofessional and non-team oriented attitude when refusing to change with other players. He's late to practice and never pays the fine levied against him by Manager Sal Martinella. He's flaunting his position in the organization, knowing full well he won't be terminated because of his worth as merely an ATTRACTION to the Cubs. Frankly, his actions are unbecoming of a professional athlete and result in the distrust and dislike of him from his fellow teammates.
Immediate success doesn't come to either Heywood or Rowengartner. However, unlike Rowengartner, Heywood immediately puts his own job on the line. If his methods don't see results he'll fire himself, no questions asked.
This is what a leader does. He's literally leading by example. He knows respect is earned, not given, and wants to rise above his status as an "attraction," unlike his Chicago counterpart. He doesn't want to be above or below the team, just a valued member of it, and the players rally behind his unorthodox ways. The results are evident. His leadership is valued and his elite strategies are quickly revealed. He motivates and educates his players at every turn, breaking through their emotional walls to get through to them as MEN…he wrangles every ounce of talent out of a mediocre talent roster and propels them to success.
Heywood is unflappable and always willing to put the team first. Sadly, I wish I could say the same about Rowengartner, but the evidence just isn't there.
Take the finales of each movie. Both the Cubs and Twins find themselves in the incredible position of being one game away from the postseason. Of course, let's be real for just a moment…who had more value to their respective clubs? Rowengartner, a lowly relief pitcher, or Heywood, the mastermind of the Twins new identity? Exactly.
Rowengartner and the Cubs find themselves in a deciding game against the New York Mets. Veteran hurler Chet "The Rocket" Steadman, a salty prick who has dealt with Rowengartner's shit throughout the entire season, pitches his balls off until suffering a career ending injury recording the final out of the 6th inning. Never mind that Henry doesn't comfort Steadman as he LITERALLY limps off the field into retirement, but he's so jealous of the Rocket's success that he puts himself ahead of the team in order to outdo the mentor that has given Henry so much. Steadman had shared his wisdom of the game, his wisdom of life, and his wisdom of pitching to his young ward, all while fucking his mom in the process. 90s baseball movies loved having athletes mentor children and fuck their moms along the way.
Rowengartner injures himself before the 9th inning and knows full well that he no longer possesses the ability to throw at an elite level anymore, yet discloses the information from his manager. His narcissism knows no bounds, as he refuses to exit the game to let another reliever take his place. Bear in mind he's the second pitcher to appear for the Cubs and the team has an entire roster of relievers with more experience who are ready to go.
Rowengartner doesn't care and stubbornly keeps himself in the game. He resorts to insane measures, allowing the game tying run to reach base on an intentional walk, and then ILLEGALLY performs a hidden ball trick to record the first out of the inning. Remind me, are you allowed to be on the pitching rubber with the rosin bag posing as an official MLB baseball in your glove? YOU ARE NOT, GOOD SIR. Should have immediately been called a balk, runner advances, and the Cubs find themselves in dire straits.
This piece of illegal chicanery is somehow missed by the umpires and Rowengartner remains in the game, recording the final two outs through a series of hurtful and derogatory insults aimed towards a minority opponent that flusters him so much he makes a crucial mistake and allows himself to be caught in a rundown for the second out. The third out is pure Hollywood fantasy, striking out a brutish and stereotypical caricature of a professional athlete to win the game. Pure Hollywood nonsense.
Now, compare this with Billy Heywood's masterful managerial strategy in the Twins final game against the Mariners. Heywood fields the best possible team, realizing his bullheadedness was hurting the team and inserting professional hitter and team leader Lou Collins (who is fucking Billy's mom) back into the lineup weeks before. He's able to overcome his prejudices against Collins, a good man who makes Heywood's mother happy for the first time since the death of his father, and puts the team first.
It's a tight affair, and through Billy's genius lineup tinkering, his perfect handling of a worn out pitching staff, and an ingenious trick play the likes of which have never been seen on a baseball field to record a crucial out of Ken Griffey Jr. in the waning inning, and the Twins find themselves in extra innings with a shot at the playoffs.
Sadly, a manager can only do so much, and the Twins find themselves with a one run deficit in the bottom of the 11th inning. Before his final at bat with a man on base, Collins asks Billy's permission to marry his mother (who he's been fucking) … despite Lou's slight unprofessionalism, Billy cracks a joke about giving him permission if he hits a home run off of Randy Johnson to win the game. As any good manager would, Billy grants Lou's wish whether he hits a home run or not, knowing full well that life doesn't end or begin with professional sport. Lou does his best, and if not for the superhuman effort of a home run robbing catch by Griffey Jr., the Twins succumb in the end.
That's real life, gang. The Twins faithful stay behind to laud their hometown team and young ward, giving the squad a standing ovation even after the final out. Heywood realizes he's missing out on what it means to be a youth and decides to give up coaching. The team is devastated, but understands. We as viewers realize that not everything has to be coated in a glossy, high definition, saccharine sheen to be worth our time. The Twins grew as athletes, Billy grew into the man his grandfather wanted him to be, and Lou found a wife.
The Cubs somehow go on to win the World Series despite not having their rotation ace in Steadman, who in all probability likely refused to wear the Cubs uniform again if Rowengartner would be hanging around the clubhouse, and their pill-popping performance enhancement star reliever in Rowengartner. It's pure Hollywood fiction, only serving to placate the rubes that didn't want to put an ounce of thought into their cinematic experience.
It's no contest. Do you want a movie that's going to make you think, that will challenge all of your preconceived notions about masculinity and professional athletes? Do you want a movie that doesn't hold your hand through the dynamic sexual relationship between a single mother and a lonely man? That doesn't pull any punches about adolescent cravings of the flesh and the sexual awakening of a young man as he watches "Night Nurses from Jersey" in his hotel room?
Or do you want a movie that showcases all that is wrong with professional athletes and bullheaded, ignorant youths of America?
Billy Heywood and Little Big League, we salute you.
Buy a customized Billy Heywood Phillies jersey by clicking through the banner below.
a href="https://shareasale.com/r.cfm?b=1330743&u=1711396&m=7124&urllink=&afftrack=" target="_blank" rel="noopener">
← Your Most Embarrassing Sports Moments
ESPN Presents The 2020 Social Distancing Pastime Draft →
I can't believe I've been reading this for 8 minutes already – not complaining
I've never agreed with anything more than I agree with this post (as I'm with my kids watching ROTY.).
LBL forever!


text:
Home » Trending News » Kathleen Turner Says She "Didn't Feel Welcomed" By Friends Cast
Kathleen Turner Says She "Didn't Feel Welcomed" By Friends Cast
Most Shocking Revelations From The "Friends" Book "I'll Be There For You"
It's no surprise to fans that the cast of Friends were a tight-knit group while filming, and while that made for great chemistry on-screen, it also made it hard for guest stars according to Kathleen Turner.
Friends fans will remember Turner as one of the show's most popular guest stars, portraying Chandler Bing's father, Charles Bing/Helena Handbasket, and after more than 15 years the actress doesn't have great things to say about being on set.
"I'll be quite honest…I didn't feel very welcomed by the cast," she recalled to Vulture. "I remember I was wearing this difficult sequined gown—and my high heels were absolutely killing me. I found it odd that none of the actors thought to offer me a seat."
Kathleen continued, "Finally it was one of the older crew members that said, 'Get Miss Turner a chair.' The Friends actors were such a clique—but I don't think my experience with them was unique. I think it was simply that they were such a tight little group that nobody from the outside mattered."
When asked what she thought about the core groups' acting skills, Turner simply said she "wouldn't comment" on that, adding, "Maybe if I'd had months to work with them, I'd be in a better position to evaluate their skill. But I could only judge based on the period I worked on the show, which wasn't long," she shared. "I do respect the camaraderie they had. You can see camaraderie on the screen. When I did Body Heat with Larry Kasdan and Bill Hurt, we rehearsed significantly before shooting and there was a familiarity before the camera rolled. You see it in the film."
Friends: Behind The Scenes Secrets
Friends: Joey's Funniest Moments
Fame10's Ultimate Friends Quiz Collection
Things You Might Not Know About The Cast Of Friends
"Friends" Fashion: The Most Iconic Outfits Of All Time
Friends: Plot Holes You Might Not Remember
Friends: Joey's 12 Love Interests Ranked From Worst To Best
Friends: Chandler's Love Interests Ranked
Friends: All The Seasons Ranked
Friends: Ranking The Parents From Worst To Best
Friends: Times When Ross, Chandler, And Joey Were The Ultimate BFFs
Friends: Times Rachel, Monica, And Phoebe Were The Ultimate BFFs
Friends' 12 Most Memorable Family Members
Friends: Ross' Love Interests Ranked
Friends: Memorable Moments Between Monica And Chandler
Friends: Memorable Characters Ranked


text:
cd $(dirname "$0")/..

version_file=src/main/resources/flywheel.version
version=`cat $version_file`

build_file=src/main/resources/flywheel.build
if [ -f $build_file ]; then
  build=`cat $build_file`
else
  build=0
fi

echo ${version}_${build}

redpajama_set_name: RedPajamaGithub


After deadly suicide bombings in two Coptic churches killed at least 44 people in Egypt on Sunday, the country's president, Abdel Fattah al-Sisi, took to state television to declare a three-month state of emergency.
"A series of steps will be taken, most importantly, the announcement of a state of emergency for three months after legal and constitution steps are taken," Sisi said, according to Reuters.
The first bomb was detonated at the Mar Girgis church in the town of Tanta, Egypt, just before 10 a.m., as worshippers gathered for Palm Sunday, killing 27 people and injuring an estimated 78, the Egyptian Health Ministry told Time. Hours later, a suicide bomber entered St. Marks Coptic Orthodox Cathedral in Alexandria, Egypt, as police tried to apprehend him, killing three officers and 14 civilians and injuring 48 others.
In a rare move, Sisi also deployed troops to assist police in securing key locations amid calls for national unity.
"The attack ... will only harden the determination (of the Egyptian people) to move forward on their trajectory to realize security, stability and comprehensive development," President Sisi said in the statement.
The Islamic State group, also known as ISIS, claimed responsibility for the attacks, which are both just the latest instance of Egypt's Coptic-Christian minority being targeted by the extremist group.
In December, a similar attack St. Mark's Cathedral in Cairo killed 29 people. In February, an ISIS pledge to carry out further attacks caused around 250 Christians to flee the country.
"As a Coptic Christian, I no longer feel safe in Egypt," Hany Ezat, whose cousin was injured in Sunday's attack, told Time. "The security forces don't care about us. ... Each time, the security forces promise to protect us but nothing happens. Events like today will keep happening."
In a message to Egypt's Christian community following the deadly attacks, ISIS vowed that Sunday's violence would not be the last.
"Crusaders and their apostate allies should know the bill between us and them is very big, and they will pay it with rivers of blood from their children, God willing. Wait for us, for we will wait for you," the group said in a statement.


You interested by question repair out of service cd rom? You have got where it is necessary. This issue and devoted article.
Likely it you seem unusual, but still for a start has meaning wonder: whether fix your cd rom? may logical will purchase new? I think, there meaning least ask, how money is a new cd rom. it make, possible make appropriate inquiry yahoo.
The first step sense find workshop by repair cd rom. This can be done using yandex or corresponding community. If price repair for you would lift - can think problem solved. If no - in this case you will be forced to do fix own.
If you still decided own do repair, then in the first instance need get information how repair cd rom. For these objectives one may use mail.ru or bing, or communicate on appropriate community.
I hope this article help you repair cd rom. The next time I will tell how fix handbrake or nail.


Singapore has unveiled what it is calling its biggest integrated startup space, BASH.
BASH, which stands for Building Amazing Startups Here, is an initiative led by Infocomm Investments Pte Ltd (IIPL), the investment arm and wholly-owned subsidiary of the Infocomm Development Authority (IDA) of Singapore.
To further enhance the growth and popularity of its startup enclave, IIPL has signed a Memorandum of understanding with local publishing giant, Singapore Press Holdings (SPH) and Sunnyvale headquartered global accelerator Plug and Play, to run a corporate-accelerator programme to generate high growth, Singapore-based digital media startups.
Dr Yaacob Ibrahim, Minister for Communications and Information in a report in The Straits Times said large corporations such as SPH play a vital role in the startup ecosystem as invaluable pilot clients for new tech entrepreneurs as these corporations provide capital, domain, knowledge and customer base for innovation.
Located at Block 79 JTC LaunchPad @ one-north, the premises is being touted as the Lion City's very own "mini-Silicon Valley" and features 25,000 sq ft of space that offers business traction and market access to innovative technology startups.
BASH aims to provide extensive amenities ranging from a prototyping lab, to mentorship and community networks grooming tech-product startups and overseeing creative ideas from its inception to expansion. "It will allow members and partners of the tech building community across the entire value chain – from accelerators, investors, incubators to entrepreneurs – to meet under one roof," local media report in The Straits Times said.
Steve Leonard, IDA executive deputy chairman and chairman of IIPL told The Straits Times: "We have made great progress in having global partners such as the European accelerator Startupbootcamp set up a FinTech-focused operation here in Singapore.
eMarketer predicts advertisers in China will invest US$22.81 billion on programmatic digital display ads this year, with mobile ac..
"What can we say? Everyone loves U."..


I received this clip from Marcus Nispel's Conan the Barbarian last week but due to my overzealous Spam filter I only got around to watching it about 10 mins ago. Yowsers!
This is our first look at the young Cimmerian Conan and clearly shows even at a young age Conan was an over achiever. The clip starts off positioning Conan played by Leo Howard as possibly a little too young to join in with older kids on a training exercise overseen by Corin (Ron Perlman) Conan's father - the prize for the winner being the chance to fight with the warriors, but when another tribe, which look to be of Pict origin, attack the training party - things take an unexpected and bloody turn.
My eagerness to see Jason Momoa swing the sword of Conan just went up seven fold. I think there is a good chance Conan the Barbarian might actually live up to my expectations that it is going to rock.


Oh, okay. I did only make this cake so I could say out loud 'kladdkaka' a lot.
I don't speak another word of Swedish (Toscakaka apart, but arguably it doesn't count, 'Tosca' being a proper noun). 'Kladdkaka' just grabbed me by the eardrum and went straight for the heart via my cochlea. Every now and then it happens, a coup de foudre with the sound of a random word. It's comforting to repeat it and you feel an urge to do so as often as possible. Kladdkaka. Klaaad-kaka. KLADkaka.
The bad news - and I would dearly like to know how uniquely I'm affected - is that it's really a speech disorder called palilalia: involuntarily repeating syllables, words, or phrases. It is common in children; the tic distracts them in unpleasant situations, calms their anxiety and reduces stress levels. But it may also be sign of a neurological disorder like autism or Tourettes or OCD.
I hope it's not more than OCD.
And I just wanted to make a white chocolate cake.
Craving more chocolate? See my kladdkaka and other white chocolate desserts at TheBestDessertRecipes!
1. Butter and line with parchment a round cake tin, 23cm in diameter - or a similar flan tin. Preheat the oven to 180C/350F/gas 4.
2. Melt the butter in a little saucepan. Take it off the heat and stir in the chocolate until melted - it won't combine thoroughly but that's all right. Leave to cool.
3. Beat the eggs and sugar until pale and thick and the mixture leaves a ribbon trail when the beaters are lifted. Beat in the vanilla extract. Stir the salt into the flour and fold into the egg mix, followed by the lemon zest and the butter with chocolate. Fold gently until it's all combined.
4. Pour into the tin and bake for 20 - 25 minutes - there should be a firm-looking edge and the middle should look barely cooked, like brownie. Leave it to cool completely in the tin.
Kladdkaka can also be made with milk or dark chocolate - in precisely the same proportions as above.


text:
Publish Date: 8:39 - 16 November 2018
North Korea tests 'ultramodern tactical weapon': State media
TEHRAN, November 16 - North Korea's state media says the country's leader Kim Jong-un has witnessed the test of an ultramodern tactical weapon in his first publicized visit to a weapons test site since the country's test-launch of an ICBM last November.
TEHRAN, Young Journalists Club (YJC) - Kim visited the testing ground of the Academy of Defense Science, the center of weapons development in North Korea, and "supervised a newly developed ultramodern tactical weapon test," official Korean Central News Agency said in a Friday report.
"After seeing the power of the tactical weapon, Supreme Leader Kim Jong-un was so excited to say that another great work was done by the defense scientists and munitions industrial workers to increase the defense capability of the country," the KCNA reported.
The type of the new weapon has not been identified, but the test does not seem to be in violation of the voluntary moratorium Pyongyang imposed on tests of nuclear and long-range ballistic missiles this year.
The new test, however, can further complicate the already stalled negotiations between North Korea and the US over the denuclearization of the Korean Peninsula.
The South Korean daily newspaper Chosun Ilbo on Friday quoted anonymous government sources as saying that North Korea had tested multiple-rocket launchers this month.
Kim last publicly attended a weapons test last November, when his country launched its Hwasong-15 ICBM, which was widely considered powerful enough to reach the continental United States.
Kim initiated a rapprochement with South Korea in January. And the US started diplomatically engaging North Korea only later.
The two Koreas have since been advancing their relations. But the US's failure to reciprocate North Korean moves has plagued diplomatic engagement between Washington and Pyongyang.
North Korean authorities have complained about continued US and international sanctions on their country, calling those measures a "source of mistrust."
North Korea's Foreign Minister Ri Yong-ho said at the United Nations General Assembly late September that "there is no way we will unilaterally disarm ourselves first."
Two Koreas hold groundbreaking rail project ceremony
'US, South Korea to reduce scope of joint drill next year'
Analyst: North Korea's economy initiatives reformative than ever
South Korea's income gap continues to grow
North Korea plans deporting detained US citizen amid new weapon test
north korea ، weapon ، test


text:
Q: Use ajax to retrieve data from Oracle database I am completely new to AJAX. I have an HTML page where I need to fetch some data from the server. I followed a few tutorials from w3schools then I set foot on AJAX.
This is my strategy. I have one plain HTML file as ajax.html and a jsp file as ajaxdb.jsp. When a button is pressed I call a function updateList().
This is my code:
xmlhttp.open("POST", url, true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(passParameter);

    if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
       document.getElementById("printBack").innerHTML = xmlhttp.responseText;
    }

I have made the visibility of printBack div hidden so whatever goes in there is invisible. In the jsp page I have a table which contains all the list of employees. After this I use dataTable.rows[0].cells[0].innerHTML = tempTable.rows[0].cells[0].innerHTML; Where tempTable is a reference to the hidden table.
I think this is not the optimal solution for retrieving table content in AJAX please suggest me how to solve it.

A: I´d recommend to use jQuery´s AJAX functionality to achieve this:
http://api.jquery.com/jQuery.ajax/
Also from the JSP you should output the list of employees in a valid format (i.e.: JSON/XML).
Then show this list on your ajax.html page by using the complete function which will trigger when the request finishes. (make sure you check that status sent was "success").
There are several libraries available to help you convert an java array/object into JSON/XML format.
EDIT
You can for example use http://code.google.com/p/json-simple/
Then just put the data you need in your JSONobject, and output it. From example:
<%@page contentType="text/html; charset=UTF-8"%>
<%@page import="org.json.simple.JSONObject"%>
<%
JSONObject obj=new JSONObject();
obj.put("name","foo");
obj.put("num",new Integer(100));
obj.put("balance",new Double(1000.21));
obj.put("is_vip",new Boolean(true));
obj.put("nickname",null);
out.print(obj);
out.flush();
%>

redpajama_set_name: RedPajamaStackExchange


text:
Il Campionato ucraino di scacchi (Чемпіонати України з шахів) si è svolto dal 1924 per determinare il campione nazionale di scacchi.

Dal 1924 al 1991 si è svolto nella Repubblica socialista sovietica ucraina e dal 1992 in poi nell'Ucraina indipendente (Repubblica Ucraina).

In alcuni campionati fu ammessa la partecipazione di giocatori stranieri. In tal caso veniva dichiarato campione il primo classificato tra i giocatori ucraini.

Campionati ucraini 1924-1991
{| class="sortable wikitable"
! # !! Anno !! Città !! Vincitore
|-
|  1 || 1924 || Kiev || Jakiv Vil'ner
|-
|  2 || 1925 || Charkiv || Jakiv Vil'ner
|-
|  3 || 1926 || Odessa || Borys Verlins'kyjMychajlo Mars'kyj
|-
|  4 || 1927 || Poltava || Oleksij Selezn'ovVsevolod Rayzer
|-
|  5 || 1928 || Odessa || Jakiv Vil'nerVolodymyr Kyrylov
|-
|  6 || 1931 || Charkiv || Abram Zamychovs'kyj
|-
|  7 || 1933 || Charkiv || Vsevolod RayzeVladimir Kirillov
|-
|  8 || 1936 || Kiev || Josyf Pohrebys'kyjPetro Šumylin
|-
|  9 || 1937 || Kiev || Fedir Bohatyrčuk
|-
| 10 || 1938 || Kiev || Isaak Boleslavs'kyj
|-
| 11 || 1939 || Dnipropetrovs'k || Isaak Boleslavs'kyj
|-
| 12 || 1940 || Kiev || Isaak Boleslavs'kyj
|-
| 13 || 1944 || Kiev || Borys Hol'denov
|-
| 14 || 1945 || Kiev || Anatolij Bannyk
|-
| 15 || 1946 || Kiev || Anatolij Bannyk
|-
| 16 || 1947 || Kiev || Oleksij Sokol's'kyj
|-
| 17 || 1948 || Kiev || Oleksij Sokol's'kyj
|-
| 18 || 1949 || Odessa || Isaak Lypnyc'kyj
|-
| 19 || 1950 || Kiev || Juchym Heller
|-
| 20 || 1951 || Kiev || Anatolij Bannyk
|-
| 21 || 1952 || Kiev || Vladlen Žurachov
|-
| 22 || 1953 || Kiev || Jakiv Juchtman
|-
| 23 || 1954 || Kiev || Abram Chavin
|-
| 24 || 1955 || Kiev || Anatolij Bannyk
|-
| 25 || 1956 || Kiev || Isaak Lypnyc'kyj
|-
| 26 || 1957 || Kiev || Juchym Heller
|-
| 27 || 1958 || Kiev || Juchym Heller
|-
| 28 || 1959 || Kiev || Juchym Heller
|-
| 29 || 1960 || Kiev || Leonid Štejn
|-
| 30 || 1961 || Kiev || Jurij Koc
|-
| 31 || 1962 || Kiev || Leonid Štejn
|-
| 32 || 1963 || Kiev || Jurij Nikolajevs'kyj
|-
| 33 || 1964 || Kiev || Anatolij Bannyk
|-
| 34 || 1965 || Dnipropetrovs'k || R. Hol'dštejn
|-
| 35 || 1966 || Kiev || Jurij Sacharov
|-
| 36 || 1967 || Kiev || Valerij ŽidkovJurij Nikolajevs'kyj
|-
| 37 || 1968 || Kiev || Jurij Sacharov
|-
| 38 || 1969 || Ivano-Frankivs'k  || Hennadij Kuz'minVolodymyr Savon
|-
| 39 || 1970 || Kiev || Volodymyr Tukmakov
|-
| 40 || 1971 || Donec'k || Jurij Koc
|-
| 41 || 1972 || Odessa || Lev Al'burt
|-
| 42 || 1973 || Dnipropetrovs'k || Lev Al'burt
|-
| 43 || 1974 || Leopoli || Lev Al'burt
|-
| 44 || 1975 || Dnipropetrovs'k || Oleksandr Vajsman
|-
| 45 || 1976 || Donec'k  || Mychajlo Pidhajec'
|-
| 46 || 1977 || Žytomyr || Jurij Nikolajevs'kyj
|-
| 47 || 1978 || Jalta || Konstantin Lerner
|-
| 48 || 1979 || Dnipropetrovs'k  || Volodymyr Ochotnyk
|-
| 49 || 1980 || Charkiv || Volodymyr Malanjuk
|-
| 50 || 1981 || Jalta || Volodymyr Malanjuk
|-
| 51 || 1982 || Jalta || Konstantin Lerner
|-
| 52 || 1983 || Melitopol' || Dmytro KomarovValerij Nevjerov
|-
| 53 || 1984 || Kiev || Michail Gurevič
|-
| 54 || 1985 || Užhorod || Valerij Nevjerov
|-
| 55 || 1986 || Leopoli || Volodymyr Malanjuk
|-
| 56 || 1987 || Mykolaïv || Viktor Moskalenko
|-
| 57 || 1988 || CharkivLeopoli || Valerij Nevjerov
|-
| 58 || 1989 || Cherson || Ihor NovikovHennadij Kuz'min
|-
| 59 || 1990 || Sinferopoli || Mychajlo Brods'kyj
|-
| 60 || 1991 || Sinferopoli || Vitalij Holod
|}

Campionati ucraini dal 1992
{| class="sortable wikitable"
! # !! Anno !! Città !! Vincitore
|-
| 1 || 1992 || Sinferopoli || Vladyslav Borovykov
|-
| 2 || 1993 || Donec'k || Orest Gricak
|-
| 3 || 1994 || Alušta || Jurij Kruppa
|-
| 4 || 1995 || ? || Serhij Kryvošeja
|-
| 5 || 1996 || Jalta || Mychajlo HolubjevValerij Nevjerov
|-
| 6 || 1997 || Alušta || Volodymyr Baklan
|-
| 7 || 1998 || Alušta || Lubomyr Mychalec'Volodymyr BaklanOleg Berezin
|-
| 8 || 1999 || Alušta || Hennadij Kuz'minOleksij BezhodovStanislav SavčenkoOleksandr MoïsejenkoAndrij Rachmangulov
|-
| 9 || 2000 || Sebastopoli || Volodymyr Rohovs'kyj
|-
| 10 || 2001 || Ordžonikidze  || Oleksandr Berelovyč
|-
| 11 || 2002 || Alušta || Anton Korobov
|-
| 12 || 2003 || Sinferopoli || Jevhen Mirošnyčenko
|-
| 13 || 2004 || Charkiv || Andrij Volokitin
|-
| 14 || 2005 || Rivne || Oleksandr Areščenko
|-
| 15 || 2006 || Poltava || Zachar Jefymenko
|-
| 16 || 2007 || Charkiv || Valerij Aveskulov
|-
| 17 || 2008 || Poltava || Jevhen Mirošnyčenko
|-
| 18 || 2009 || Alušta || Volodymyr Jakimov
|-
| 19 || 2010 || Alušta || Serhij Pavlov
|-
| 20 || 2011 || Kiev || Ruslan Ponomar'ov
|-
| 21 || 2012 || Kiev || Anton Korobov
|-
| 22 || 2013 || Kiev || Juriy Kryvoručko
|-
| 23 || 2014 || Leopoli || Jurij Kuzubov
|-
| 24 || 2015 || Leopoli || Andrij Volokitin
|-
| 25 || 2016 || Rivne || Mychajlo Oleksijenko
|-
| 26 || 2017 || Žytomyr || Petro Holubka
|-
| 27 || 2018 || Kiev || Anton Korobov
|-
| 28 || 2019 || Lutsk || Evgeny Shtembuliak
|-
| 29 || 2020 || Kremenchuk || Anton Korobov
|-
| 30 || 2021 || Charkiv || Andrij Volokitin
|}

Plurivincitori
 5 campionati:  Anatolij Bannyk.
 4 campionati:  Juchym Heller, Valerij Nevjerov, Anton Korobov..
 3 campionati:  Jakiv Vil'ner, Isaak Boleslavs'kyj, Lev Al'burt, Jurij Nikolajevs'kyj, Volodymyr Malanjuk, Hennadij Kuz'min, Andrij Volokitin.

Note

Collegamenti esterni

Ucraina
Scacchi in Ucraina

redpajama_set_name: RedPajamaWikipedia


I own a 2004 Winnebago Minnie 31C. Can anyone tell me what the switch inside my outside shower compartment does. Nothing to do with water flow.
Looking at your wiring diagrams, looks like it's a water pump switch. Maybe the right question is, "why doesn't it work?"
I attached small screen capture of it, the "64R" note is the outside shower option. Pretty much nails it down.
Thank you. I am a new RVer, with an older RV. As soon as I read you response, it was clear and common sense.


text:
Diplomacy & Foreign Affairs
Sustainability & Economy
Geopolitics & Global Order
Series European Union
EU-China Investments: Europe's strategic interest
Photo: Pixabay
While Chinese investments in Europe are rising, the topic is increasingly becoming more politically sensitive. In October 2018, Egmont Institute invited several experts to look in detail at the scope, trends and political aspects of Chinese investments in the EU as well as different perceptions of the direct investments across European regions. Is there a unified European strategy towards Chinese investments? And is there a unified Chinese strategy towards the EU? In this series, several of the invited speakers shed their light on EU-China investments. In part II: Programme Manager at Friends of Europe Amanda Rohde, states that as the US-China trade dispute widens, Europe should look to its own strategic priorities.
The Europe-China relationship is evolving, but the context in which it is doing so is strained. The ongoing dispute between the US and China has raised the stakes and pushed Europe and China closer together. What happens between China and the US matters for Europe. It is important, however, that Europe looks after its own strategic interest and avoids getting caught in the US-China crossfire.
Focus points in EU-China relations
Two issues dominate relations between Europe and China: the increase in Chinese investments in Europe and China's Belt and Road Initiative (BRI) and its impact both within Europe and in the world. On both issues, Europe and China must seek to find common ground and avoid confrontation or competition.
The global economic outlook is already feeling the fall-out from the US-China trade war. The International Monetary Fund (IMF) reports that US protectionist policies have resulted in a downgrade in the organisation's global growth forecast, and the repercussions will echo further. The trade war is likely to disrupt the global supply chain, with companies investing less in China and Chinese citizens cutting back on spending.
Of course, with US President Donald Trump at the helm, the future is uncertain. But when two of the world's biggest economies are at odds with each other, Europe should stay out of the fray.
This is the moment for Europe to make strategic choices about its future
This is the moment for Europe to make strategic choices about its future. European leaders should take the opportunity to think critically about ways of working with China which will be beneficial for European growth and jobs – while avoiding being naive about their strategic interests.
The EU-China Comprehensive Agreement on Investment offers an opportunity for such a balanced approach. The agreement offers the EU an opportunity to both improve market access and to push for reciprocity and a level playing field for European investors.
The ancient city Tuojiang. © Pixabay
And progress is – finally – being made: after 18 rounds of negotiations, the EU-China Summit in July this year saw the first exchange of market access offers between Brussels and Beijing, taking talks to the next level. Further negotiations should be speeded up.
Possible tools to deal with Chinese investments
If Europe is still concerned about the industries and sectors in which the Chinese are investing – and the sources of those funds – there is another tool available: foreign direct investment (FDI) screening. As it stands right now, the EU has no unified mechanism to screen the types of investment coming into Europe, and many EU member states even lack the legislation which would allow them to review FDI. That should change, and the EU is working to do so.
Screening allows Europeans to be smart about how they deal with their partners and to ensure that investment enters sectors which will benefit Europeans the most
During his 2017 State of the Union address, European Commission President Jean-Claude Juncker proposed a new framework for FDI screening, and negotiations are underway. The proposed regulations would allow the EU to remain open to FDI, while at the same time creating a framework to improve cooperation and information-sharing between the European Commission and Member States - particularly in cases where security and public order may be at risk.
By screening investments, European states can ensure that financing finds its way into the sectors that they believe can benefit from Chinese investments while safeguarding strategic energy infrastructure and cybersecurity. Such a screening mechanism will boost transparency. It also ensures that states know where the money being invested is coming from. In the case of China – where state-owned enterprises are moving into the international sphere – this is especially important.
Such measures should not be viewed as a pushback against China or other states seeking to invest in Europe. Indeed most countries, including China, already impose strict regulations on foreign investors in their own markets, creating a de facto screening process. Rather, screening allows Europeans to be smart about how they deal with their partners and to ensure that investment enters sectors which will benefit Europeans the most.
This is also where the Belt and Road Initiative comes in. Despite its enigmatic beginnings, the BRI now includes an impressive number of projects spanning the globe. These projects are important in building infrastructure and play a role in bringing Europe and Asia closer together.
Chinese lantern lampion © Pixabay
But it is not all good news. BRI projects are often not regulated according to the same standards as European-funded ones. They are more likely to contract Chinese companies and workers, side-lining European and local businesses. There are questions about the long-term financial impact since BRI project-funding comes in the form of loans, not grants.
If European states are to allow Chinese investments in BRI projects in Europe, they must do so in a smart and strategic way in order to avoid such pitfalls.
Outlook on development of EU-China relations
The EU's latest communication on a new and comprehensive strategy to better connect Europe and Asia opens up the potential for such cooperation. This strategy, which sets out standards for the EU's own projects, could also serve as a reference point for all international connectivity schemes. This would ensure that internationally recognised standards and norms are met worldwide.
Indeed, the strategy presents a perfect opportunity for the EU to build up its cooperation with China by ensuring that its member states are able to welcome investments while at the same time avoiding running into some of the stumbling blocks encountered by other countries.
As the US-China trade dispute widens, the EU has to make strategic choices which benefit its citizens while also allowing it to play an important global role and remain an attractive destination for foreign investors.
The connectivity strategy, which underlines the need for fair trade, strengthening regional resilience and support for the international rules-based order offers an opportunity to constructively work with China.
The EU's commitment to complying with international standards and norms opens the door for this cooperation to take place in a transparent and sustainable way. And with improvements and coordination through FDI screening, Europe can bring in Chinese investment where it is needed and support growth in its own economy.
What is key is that Europe uses these opportunities - for both cooperation and healthy competition - to move closer towards reaching common ground in its relationship with China.
Programme manager at Friends of Europe
SeriesEuropean Union
EU-China Investments: Barriers to market access in China
EU-China Investments: Solving the 16+1 equation
ColumnsConflict and Fragility
The US-DPRK summit & China's regional concerns
Benefit or threat
Very nice explanatory article! It is very true that these huge investments in the EU coming from China are balancing at the edge of beneficial and threatening. However, lately, I have read an article describing the new economic strategy of China as a one, which is focusing on investing in innovations (https://valuer.ai/blog/why-is-china-investing-so-much-in-europe/ ). Do you think with time, they will stop investing in infrastructures completely?
Text format Restricted HTMLPlain text
Stay updated on all Clingendael activities and more articles from the magazine
The Clingendael Spectator (since 1947) is the magazine of Dutch think tank Clingendael, freely accessible for all with an interest in current developments concerning world politics
Procedure of assessment


Available now is the story of a small-town PI, exposing the dirty underbelly of coastal Australia.
Mac Durridge used to be a cop. Now he runs a small detective agency out of a flat above the local TAB. He's making a living, barely, when he's hired to provide security at the local bank for an unusually large cash run.
Then the money goes missing, the guard he was replacing is found beat to death on the local beach and his former colleagues are looking at Mac as a prime suspect.