Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * Copyright 2014-2015 the original author or authors.
    *
    * Licensed under the Apache License, Version 2.0 (the "License");
    * you may not use this file except in compliance with the License.
    * You may obtain a copy of the License at
    *
    *     http://www.apache.org/licenses/LICENSE-2.0
    *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
   * either express or implied. See the License for the specific language
   * governing permissions and limitations under the License.
   */
  package org.dbflute.cbean.coption;
  
  import java.sql.Time;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  
The option to filter by function.
You can filter an aggregate function by scalar function filters.

Author(s):
jflute
  
  public class FunctionFilterOption implements ParameterOption {
  
      // ===================================================================================
      //                                                                          Definition
      //                                                                          ==========
      protected static final String DATE_TRUNC_MONTH = "df:month";
      protected static final String DATE_TRUNC_DAY = "df:day";
      protected static final String DATE_TRUNC_TIME = "df:time";
  
      // ===================================================================================
      //                                                                           Attribute
      //                                                                           =========
      // -----------------------------------------------------
      //                                           Bound Value
      //                                           -----------
      protected Map<StringObject_bindMap// e.g. map:{ param0 = ... ; param1 = ... }
  
      // -----------------------------------------------------
      //                                   Parameter Direction
      //                                   -------------------
      protected List<ProcessCallback_callbackList// order should be guaranteed
      protected String _parameterKey;
      protected String _parameterMapPath;
  
      // -----------------------------------------------------
      //                                    called by internal
      //                                    ------------------
      protected ColumnInfo _targetColumnInfo// not required
      protected Object _mysticBindingSnapshot// e.g. to determine binding type
      protected Object _tmpTrunc;
      protected boolean _mayNullRevived;
      protected boolean _removeCalcAlias;
      protected boolean _databaseMySQL;
      protected boolean _databasePostgreSQL;
      protected boolean _databaseOracle;
      protected boolean _databaseDB2;
      protected boolean _databaseSQLServer;
      protected boolean _databaseH2;
      protected boolean _databaseDerby;

    
The time-zone for filtering. (NullAllowed: if null, default zone)
 
     protected TimeZone _timeZone;
 
     // ===================================================================================
     //                                                                              Option
     //                                                                              ======
     // -----------------------------------------------------
     //                                              Coalesce
     //                                              --------
     protected void doCoalesce(final Object coalesce) {
         assertOptionValueNotNull("coalesce"coalesce);
         addProcessCallback("coalesce"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processCoalesce(functionExpindexcoalesce);
             }
         });
          = true;
     }
 
     // -----------------------------------------------------
     //                                                 Round
     //                                                 -----
     protected void doRound(final Object round) {
         assertOptionValueNotNull("round"round);
         addProcessCallback("round"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processRound(functionExpindexround);
             }
         });
     }
 
     // -----------------------------------------------------
     //                                         Truncate Date
     //                                         -------------
     protected void doTrunc(final Object trunc) {
         assertOptionValueNotNull("trunc"trunc);
          = trunc;
         addProcessCallback("trunc"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processTrunc(functionExpindextrunc);
             }
         });
     }
 
     protected void doTruncMonth() {
         doTrunc();
     }
 
     protected void doTruncDay() {
         doTrunc();
     }
 
     protected void doTruncTime() {
         doTrunc();
     }
 
     // -----------------------------------------------------
     //                                              Add Date
     //                                              --------
     protected void doAddYear(Object addedYear) {
         doAddYear(addedYearfalse);
     }
 
     protected void doAddYear(final Object addedYearfinal boolean minus) {
         assertOptionValueNotNull("year"addedYear);
         addProcessCallback("addYear"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processAddYear(functionExpindexaddedYearminus);
             }
         });
     }
 
     protected void doAddMonth(Object addedMonth) {
         doAddMonth(addedMonthfalse);
     }
 
     protected void doAddMonth(final Object addedMonthfinal boolean minus) {
         assertOptionValueNotNull("month"addedMonth);
         addProcessCallback("addMonth"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processAddMonth(functionExpindexaddedMonthminus);
             }
         });
     }
 
     protected void doAddDay(Object addedDay) {
         doAddDay(addedDayfalse);
     }
 
     protected void doAddDay(final Object addedDayfinal boolean minus) {
         assertOptionValueNotNull("day"addedDay);
         addProcessCallback("addDay"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processAddDay(functionExpindexaddedDayminus);
             }
         });
     }
 
     protected void doAddHour(Object addedHour) {
         doAddHour(addedHourfalse);
     }
 
     protected void doAddHour(final Object addedHourfinal boolean minus) {
         assertOptionValueNotNull("hour"addedHour);
         addProcessCallback("addHour"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processAddHour(functionExpindexaddedHourminus);
             }
         });
     }
 
     protected void doAddMinute(Object addedMinute) {
         doAddMinute(addedMinutefalse);
     }
 
     protected void doAddMinute(final Object addedMinutefinal boolean minus) {
         assertOptionValueNotNull("minute"addedMinute);
         addProcessCallback("addMinute"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processAddMinute(functionExpindexaddedMinuteminus);
             }
         });
     }
 
     protected void doAddSecond(Object addedSecond) {
         doAddSecond(addedSecondfalse);
     }
 
     protected void doAddSecond(final Object addedSecondfinal boolean minus) {
         assertOptionValueNotNull("second"addedSecond);
         addProcessCallback("addSecond"new ProcessCallback() {
             public String callback(String functionExpint index) {
                 return processAddSecond(functionExpindexaddedSecondminus);
             }
         });
     }
 
     // ===================================================================================
     //                                                                              Filter
     //                                                                              ======
     
Filter the expression of function part.
For example, an expression is like: max(foo.FOO_DATE), sum(bar.BAR_PRICE), ...

Parameters:
functionExp The expression of function part that is not filtered. (NotNull)
Returns:
The filtered expression. (NotNull)
 
     public String filterFunction(String functionExp) {
         String filtered = functionExp;
         final List<ProcessCallbackcallbackList = ;
         if (callbackList != null) {
             int index = 0;
             for (ProcessCallback callback : callbackList) {
                 filtered = callback.callback(filteredindex);
                 ++index;
             }
         }
         return processVarious(processCalculation(filtered));
     }
 
     protected static interface ProcessCallback {
         String callback(String functionExpint index);
     }
 
     protected void addProcessCallback(String functionKeyProcessCallback callback) {
         if ( == null) {
              = new ArrayList<ProcessCallback>(4);
         }
         // can be added several times
         //if (_callbackMap.containsKey(functionKey)) {
         //    String msg = "The function has been already set up: ";
         //    msg = msg + "function=" + functionKey + "() option=" + toString();
         //    throw new IllegalConditionBeanOperationException(msg);
         //}
         .add(callback);
     }
 
     // ===================================================================================
     //                                                                            Coalesce
     //                                                                            ========
     protected String processCoalesce(String functionExpint indexObject coalesce) {
         if (coalesce == null) {
             return functionExp;
         }
         final Object realParam;
         if (coalesce instanceof String && isDateTypeColumn()) {
             if (isJustDateTypeColumn()) {
                 // even if util.Date, use local date here (can be mapped correctly)
                 realParam = DfTypeUtil.toLocalDate(coalescegetTimeZone());
             } else if (isJustTimestampTypeColumn()) {
                 realParam = DfTypeUtil.toLocalDateTime(coalescegetTimeZone());
             } else if (isJustTimeTypeColumn()) {
                 realParam = DfTypeUtil.toLocalTime(coalescegetTimeZone());
             } else { // basically no way, just in case
                 realParam = DfTypeUtil.toLocalDateTime(coalescegetTimeZone());
             }
         } else {
             realParam = coalesce;
         }
         final Object bindKey = registerBindParameter(indexrealParam);
         final String functionName = "coalesce";
         return processSimpleFunction(functionExpfunctionNamenullfalsebindKey);
     }
 
     // ===================================================================================
     //                                                                               Round
     //                                                                               =====
     protected String processRound(String functionExpint indexObject round) {
         if (round == null) {
             return functionExp;
         }
         final Object bindKey = registerBindParameter(indexround);
         final String functionName = "round";
         return processSimpleFunction(functionExpfunctionNamenullfalsebindKey);
     }
 
     // ===================================================================================
     //                                                                            Truncate
     //                                                                            ========
     protected String processTrunc(String functionExpint indexObject trunc) {
         if (trunc == null) {
             return functionExp;
         }
         // save temporary variable
          = trunc// might be changed after the following process
         try {
             // process purpose case
             if (isDateTypeColumn()) {
                 final String processed = doProcessTruncPurposeDateType(functionExp);
                 if (processed != null) {
                     return processed;
                 }
             }
             // process simple case
             return doProcessTruncSimpleCase(functionExpindex);
         } finally {
              = null;
         }
     }
 
     protected String doProcessTruncPurposeDateType(String functionExp) {
         final String processed;
         if (isDatabaseMySQL()) {
             processed = doProcessTruncPurposeDateTypeMySQL(functionExp);
         } else if (isDatabasePostgreSQL()) {
             processed = doProcessTruncPurposeDateTypePostgreSQL(functionExp);
         } else if (isDatabaseOracle()) {
             processed = doProcessTruncPurposeDateTypeOracle(functionExp);
         } else if (isDatabaseDB2()) {
             processed = doProcessTruncPurposeDateTypeDB2(functionExp);
         } else if (isDatabaseSQLServer()) {
             processed = doProcessTruncPurposeDateTypeSQLServer(functionExp);
         } else { // as default
             processed = doProcessTruncPurposeDateTypeDefault(functionExp);
         }
         return processed// null means not processed or simple case (switched)
     }
 
     protected String doProcessTruncPurposeDateTypeMySQL(String functionExp) {
         if (isDateTruncMonth()) {
             return "cast(concat(substring(" + functionExp + ", 1, 4), '-01-01') as date)";
         } else if (isDateTruncDay()) {
             return "cast(concat(substring(" + functionExp + ", 1, 7), '-01') as date)";
         } else if (isDateTruncTime()) {
             return "cast(substring(" + functionExp + ", 1, 10) as date)";
         }
         return null;
         // e.g. cast(concat(substring(FOO_DATE, 1, 7), '-01') as date)
     }
 
     protected String doProcessTruncPurposeDateTypePostgreSQL(String functionExp) {
         // PostgreSQL can treat it as simple case by only switching
         if (isDateTruncMonth()) {
              = "year";
         } else if (isDateTruncDay()) {
              = "month";
         } else if (isDateTruncTime()) {
              = "day";
         }
         return null;
         // e.g. trunc(FOO_DATE, 'month')
     }
 
     protected String doProcessTruncPurposeDateTypeOracle(String functionExp) {
         // Oracle can treat it as simple case by only switching
         if (isDateTruncMonth()) {
              = "YYYY";
         } else if (isDateTruncDay()) {
              = "MM";
         } else if (isDateTruncTime()) {
              = "DD";
         }
         return null;
         // e.g. trunc(FOO_DATE, 'MM')
     }
 
     protected String doProcessTruncPurposeDateTypeDB2(String functionExp) {
         // DB2 is interested in difference between date and time-stamp
         final String baseExp = "cast(to_char(" + functionExp + ", 'yyyy";
         final String timePartBasicSuffix = isJustDateTypeColumn() ? "" : " 00:00:00";
         final String finalType = isJustDateTypeColumn() ? "date" : "timestamp";
         if (isDateTruncMonth()) {
             return baseExp + "') || '-01-01" + timePartBasicSuffix + "' as " + finalType + ")";
         } else if (isDateTruncDay()) {
             return baseExp + "-MM') || '-01" + timePartBasicSuffix + "' as " + finalType + ")";
         } else if (isDateTruncTime()) {
             final String timePartConnectSuffix = isJustDateTypeColumn() ? "" : " || ' 00:00:00'";
             return baseExp + "-MM-dd')" + timePartConnectSuffix + " as " + finalType + ")";
         }
         return null;
         // e.g. cast(to_char(FOO_DATE || '-01') as date)
     }
 
     protected String doProcessTruncPurposeDateTypeSQLServer(String functionExp) {
         final String baseExp = "cast(substring(convert(nvarchar, ";
         final String finalType = "datetime";
         if (isDateTruncMonth()) {
             return baseExp + functionExp + ", 120), 1, 4) + '-01-01' as " + finalType + ")";
         } else if (isDateTruncDay()) {
             return baseExp + functionExp + ", 120), 1, 7) + '-01' as " + finalType + ")";
         } else if (isDateTruncTime()) {
             return baseExp + functionExp + ", 120), 1, 10) as " + finalType + ")";
         }
         return null;
         // e.g. cast(substring(convert(nvarchar, FOO_DATE, 120), 1, 7) + '-01' as datetime)
     }
 
     protected String doProcessTruncPurposeDateTypeDefault(String functionExp) {
         final String baseExp = "cast(substring(";
         final String finalType = "date";
         if (isDateTruncMonth()) {
             return baseExp + functionExp + ", 1, 4) || '-01-01' as " + finalType + ")";
         } else if (isDateTruncDay()) {
             return baseExp + functionExp + ", 1, 7) || '-01' as " + finalType + ")";
         } else if (isDateTruncTime()) {
             return baseExp + functionExp + ", 1, 10) as " + finalType + ")";
         }
         return null;
         // e.g. cast(substring(FOO_DATE, 1, 7) || '-01' as date)
     }
 
     protected boolean isDateTruncMonth() {
         return .equals();
     }
 
     protected boolean isDateTruncDay() {
         return .equals();
     }
 
     protected boolean isDateTruncTime() {
         return .equals();
     }
 
     protected String doProcessTruncSimpleCase(String functionExpint indexObject trunc) {
         final String functionName;
         String thirdArg = null;
         boolean leftArg = false;
         if (isTruncNamedTruncate()) {
             functionName = "truncate";
         } else if (isDatabaseSQLServer()) {
             functionName = "round";
             thirdArg = "1";
         } else if (isDatabasePostgreSQL() && isDateTypeColumn()) {
             functionName = "date_trunc";
             leftArg = true;
         } else {
             functionName = "trunc";
         }
         final Object bindKey = registerBindParameter(indextrunc);
         return processSimpleFunction(functionExpfunctionNamethirdArgleftArgbindKey);
     }
 
     protected boolean isTruncNamedTruncate() {
         return isDatabaseMySQL() || isDatabaseH2();
     }
 
     // ===================================================================================
     //                                                                             DateAdd
     //                                                                             =======
     protected String processAddYear(String functionExpint indexObject addedYearboolean minus) {
         return doProcessDateAdd(functionExpindexaddedYear"addYear"minus);
     }
 
     protected String processAddMonth(String functionExpint indexObject addedMonthboolean minus) {
         return doProcessDateAdd(functionExpindexaddedMonth"addMonth"minus);
     }
 
     protected String processAddDay(String functionExpint indexObject addedDayboolean minus) {
         return doProcessDateAdd(functionExpindexaddedDay"addDay"minus);
     }
 
     protected String processAddHour(String functionExpint indexObject addedHourboolean minus) {
         return doProcessDateAdd(functionExpindexaddedHour"addHour"minus);
     }
 
     protected String processAddMinute(String functionExpint indexObject addedMinuteboolean minus) {
         return doProcessDateAdd(functionExpindexaddedMinute"addMinute"minus);
     }
 
     protected String processAddSecond(String functionExpint indexObject addedSecondboolean minus) {
         return doProcessDateAdd(functionExpindexaddedSecond"addSecond"minus);
     }
 
     protected String doProcessDateAdd(String functionExpint indexObject addedValueString propertyNameboolean minus) {
         if (addedValue == null) {
             return functionExp;
         }
         if (!isDateTypeColumn()) { // if info is null, means e.g. mystic
             String msg = "The column should be Date type for the function e.g. addDay():";
             msg = msg + " column=" + ;
             throw new IllegalConditionBeanOperationException(msg);
         }
         if (isDatabaseMySQL()) {
             return doProcessDateAddMySQL(functionExpindexaddedValuepropertyNameminus);
         } else if (isDatabasePostgreSQL()) {
             return doProcessDateAddPostgreSQL(functionExpindexaddedValuepropertyNameminus);
         } else if (isDatabaseOracle()) {
             return doProcessDateAddOracle(functionExpindexaddedValuepropertyNameminus);
         } else if (isDatabaseDB2()) {
             return doProcessDateAddDB2(functionExpindexaddedValuepropertyNameminus);
         } else if (isDatabaseSQLServer()) {
             return doProcessDateAddSQLServer(functionExpindexaddedValuepropertyNameminus);
         } else if (isDatabaseH2()) { // same as SQLServer
             return doProcessDateAddSQLServer(functionExpindexaddedValuepropertyNameminus);
         } else {
             String msg = "Unsupported database to the function addXxx(): " + propertyName;
             throw new IllegalConditionBeanOperationException(msg);
         }
     }
 
     protected String doProcessDateAddMySQL(String functionExpint indexObject addedValueString propertyNameboolean minus) {
         final String bindPath = buildAddedBindParameter(indexaddedValuepropertyName);
         final String type = buildDateAddExpType(propertyNamenullfalse);
         final String prefixSign = minus ? "-" : "";
         return "date_add(" + functionExp + ", interval " + prefixSign + bindPath + " " + type + ")";
         // e.g. date_add(FOO_DATE, interval 1 month)
     }
 
     protected String doProcessDateAddPostgreSQL(String functionExpint indexObject addedValueString propertyNameboolean minus) {
         // no binding because it does not allowed
         final String type = buildDateAddExpType(propertyNamenulltrue);
         final String valueExp;
         {
             final String baseValueExp = buildAddedEmbeddedValueExp(addedValue);
             if (isDreamCruiseTicket(addedValue)) {
                 valueExp = "(" + baseValueExp + " || '" + type + "')::interval";
             } else {
                 valueExp = "'" + baseValueExp + " " + type + "'";
             }
         }
         final String calcSign = minus ? "-" : "+";
         if (hasMysticBinding() || isJustDateTypeColumn()) { // mystic binding needs to cast (not sure why)
             return "cast(" + functionExp + " as timestamp) " + calcSign + " " + valueExp;
         } else {
             return functionExp + " " + calcSign + " " + valueExp;
         }
         // e.g.
         //  o cast(FOO_DATE as timestamp) + '1 months'
         //  o FOO_DATE + '1 months'
         //  o FOO_DATE + (FOO_DAYS || 'months')::interval
     }
 
     protected String doProcessDateAddOracle(String functionExpint indexObject addedValueString propertyNameboolean minus) {
         final String bindParameter = buildAddedBindParameter(indexaddedValuepropertyName);
         final String prefixSign = minus ? "-" : "";
         final String calcSign = minus ? "-" : "+";
         if (isPropertyAddYear(propertyName)) {
             return "add_months(" + functionExp + ", 12 * " + prefixSign + bindParameter + ")";
         } else if (isPropertyAddMonth(propertyName)) {
             return "add_months(" + functionExp + ", " + prefixSign + bindParameter + ")";
         } else if (isPropertyAddDay(propertyName)) {
             return functionExp + " " + calcSign + " " + bindParameter;
         } else if (isPropertyAddHour(propertyName)) {
             return functionExp + " " + calcSign + " " + bindParameter + " / 24";
         } else if (isPropertyAddMinute(propertyName)) {
             return functionExp + " " + calcSign + " " + bindParameter + " / 1440";
         } else if (isPropertyAddSecond(propertyName)) {
             return functionExp + " " + calcSign + " " + bindParameter + " / 86400";
         } else {
             String msg = "Unknown property for date-add: " + propertyName;
             throw new IllegalStateException(msg);
         }
         // e.g.
         //  o add_months(FOO_DATE, 1)
         //  o FOO_DATE + 1
         //  o FOO_DATE + 1 / 24
     }
 
     protected String doProcessDateAddDB2(String functionExpint indexObject addedValueString propertyNameboolean minus) {
         final String bindParameter = buildAddedBindParameter(indexaddedValuepropertyName);
         final String type = buildDateAddExpType(propertyNamenullfalse);
         final String calcSign = minus ? "-" : "+";
         final String baseFuncExp;
         final String closingSuffix;
         if (hasTargetColumnInfo()) {
             baseFuncExp = functionExp// no problem, so no cast
             closingSuffix = "";
         } else { // e.g. mystic binding
             // needs time-stamp to calculate (not sure why)
             final String castType;
             if (isJustDateTypeColumn()) {
                 // and needs to revert to original type so twice cast
                 castType = "date";
                 baseFuncExp = "cast(cast(" + functionExp + " as timestamp)";
                 closingSuffix = " as " + castType + ")";
             } else {
                 castType = "timestamp";
                 baseFuncExp = "cast(" + functionExp + " as timestamp)";
                 closingSuffix = "";
             }
         }
         return baseFuncExp + " " + calcSign + " " + bindParameter + " " + type + closingSuffix;
         // e.g. FOO_DATE + 1 month
     }
 
     protected String doProcessDateAddSQLServer(String functionExpint indexObject addedValueString propertyNameboolean minus) {
         final String valueExp = buildAddedEmbeddedValueExp(addedValue);
         final String type = buildDateAddExpType(propertyNamenullfalse);
         final String prefixSign = minus ? "-" : "";
         return "dateadd(" + type + ", " + prefixSign + valueExp + ", " + functionExp + ")";
         // e.g. dateadd(month, 1, FOO_DATE)
     }
 
     protected String buildDateAddExpType(String propertyNameString prefixboolean plural) {
         prefix = (prefix != null ? prefix : "");
         final String suffix = plural ? "s" : "";
         final String type;
         if (isPropertyAddYear(propertyName)) {
             type = prefix + "year" + suffix;
         } else if (isPropertyAddMonth(propertyName)) {
             type = prefix + "month" + suffix;
         } else if (isPropertyAddDay(propertyName)) {
             type = prefix + "day" + suffix;
         } else if (isPropertyAddHour(propertyName)) {
             type = prefix + "hour" + suffix;
         } else if (isPropertyAddMinute(propertyName)) {
             type = prefix + "minute" + suffix;
         } else if (isPropertyAddSecond(propertyName)) {
             type = prefix + "second" + suffix;
         } else {
             String msg = "Unknown property for date-add: " + propertyName;
             throw new IllegalStateException(msg);
         }
         return type;
     }
 
     protected boolean isPropertyAddYear(String propertyName) {
         return "addYear".equals(propertyName);
     }
 
     protected boolean isPropertyAddMonth(String propertyName) {
         return "addMonth".equals(propertyName);
     }
 
     protected boolean isPropertyAddDay(String propertyName) {
         return "addDay".equals(propertyName);
     }
 
     protected boolean isPropertyAddHour(String propertyName) {
         return "addHour".equals(propertyName);
     }
 
     protected boolean isPropertyAddMinute(String propertyName) {
         return "addMinute".equals(propertyName);
     }
 
     protected boolean isPropertyAddSecond(String propertyName) {
         return "addSecond".equals(propertyName);
     }
 
     protected String buildAddedBindParameter(int indexObject addedValueString propertyName) {
         final Object bindKey = registerBindParameter(indexaddedValue);
         return buildBindParameter(bindKey);
     }
 
     protected String buildAddedEmbeddedValueExp(Object addedValue) {
         final String valueExp;
         if (isDreamCruiseTicket(addedValue)) {
             valueExp = buildDreamCruiseTicketStatement(addedValue);
         } else {
             valueExp = addedValue.toString();
         }
         return valueExp;
     }
 
     // ===================================================================================
     //                                                                 Various Calculation
     //                                                                 ===================
     
Process calculation filters defined by sub-class. (for extension)

Parameters:
functionExp The expression of derived function. (NotNull)
Returns:
The filtered expression. (NotNull)
 
     protected String processCalculation(String functionExp) { // for extension
         return functionExp;
     }

    
Process various filters defined by user. (for extension)

Parameters:
functionExp The expression of derived function. (NotNull)
Returns:
The filtered expression. (NotNull)
 
     protected String processVarious(String functionExp) { // for extension
         return functionExp;
     }
 
     // ===================================================================================
     //                                                                    Parameter Option
     //                                                                    ================
     public void acceptParameterKey(String parameterKeyString parameterMapPath) {
          = parameterKey;
          = parameterMapPath;
     }
 
     // ===================================================================================
     //                                                                    Create Processor
     //                                                                    ================
     public SpecifyDerivedReferrer createSpecifyDerivedReferrer(SubQueryPath subQueryPathColumnRealNameProvider localRealNameProvider,
             ColumnSqlNameProvider subQuerySqlNameProviderint subQueryLevelSqlClause subQueryClauseString subQueryIdentity,
             DBMeta subQueryDBMetaGearedCipherManager cipherManagerString mainSubQueryIdentityString aliasName) {
         return new SpecifyDerivedReferrer(subQueryPathlocalRealNameProvidersubQuerySqlNameProvidersubQueryLevelsubQueryClause,
                 subQueryIdentitysubQueryDBMetacipherManagermainSubQueryIdentityaliasName);
     }
 
     public QueryDerivedReferrer createQueryDerivedReferrer(SubQueryPath subQueryPathColumnRealNameProvider localRealNameProvider,
             ColumnSqlNameProvider subQuerySqlNameProviderint subQueryLevelSqlClause subQueryClauseString subQueryIdentity,
             DBMeta subQueryDBMetaGearedCipherManager cipherManagerString mainSubQueryIdentityString operandObject value,
             String parameterPath) {
         return new QueryDerivedReferrer(subQueryPathlocalRealNameProvidersubQuerySqlNameProvidersubQueryLevelsubQueryClause,
                 subQueryIdentitysubQueryDBMetacipherManagermainSubQueryIdentityoperandvalueparameterPath);
     }
 
     // ===================================================================================
     //                                                                       Determination
     //                                                                       =============
     public boolean mayNullRevived() { // basically for auto-detect of inner-join
         // coalesce can change a null value to an existing value
         return ;
     }
 
     // ===================================================================================
     //                                                                            TimeZone
     //                                                                            ========
     
Set time-zone, basically for LocalDate conversion.
Normally you don't need to set this, you can adjust other ways.
(DBFlute system's time-zone is used as default)
And it should be called before e.g. coalesce()

Parameters:
timeZone The time-zone for filtering. (NullAllowed: if null, default zone)
Returns:
this. (NotNull)
 
     public FunctionFilterOption zone(TimeZone timeZone) {
          = timeZone;
         return this;
     }

    
Get the time-zone in this option basically for filtering.

Returns:
The time-zone for filtering. (NotNull: if no setting, system zone)
 
     public TimeZone getTimeZone() {
         return  != null ?  : getDBFluteSystemFinalTimeZone();
     }
 
     protected TimeZone getDBFluteSystemFinalTimeZone() {
         return DBFluteSystem.getFinalTimeZone();
     }
 
     // ===================================================================================
     //                                                                       Assist Helper
     //                                                                       =============
     // -----------------------------------------------------
     //                                       Simple Function
     //                                       ---------------
     protected String processSimpleFunction(String functionExpString functionNameString thirdArgboolean leftArgObject bindKey) {
         final String bindExp = buildBindParameter(bindKey);
         final StringBuilder sb = new StringBuilder();
         sb.append(functionName).append("(");
         final String sqend = .;
         final boolean handleSqEnd = hasSubQueryEndOnLastLine(functionExp);
         final String pureFunction = handleSqEnd ? Srl.substringLastFront(functionExpsqend) : functionExp;
         if (leftArg) { // for example, PostgreSQL's date_trunc()
             sb.append(bindExp);
             if (handleSqEnd) {
                 // leftArg binding breaks formatting so add line here
                 // it's not perfect but almost OK
                 sb.append(ln()).append("       ");
             }
             sb.append(", ").append(pureFunction);
         } else { // normal
             sb.append(pureFunction).append(", ").append(bindExp);
         }
         if (Srl.is_NotNull_and_NotTrimmedEmpty(thirdArg)) {
             sb.append(", ").append(thirdArg);
         }
         sb.append(")");
         if (handleSqEnd) {
             sb.append(sqend).append(Srl.substringLastRear(functionExpsqend));
         }
         return sb.toString();
     }
 
     protected boolean hasSubQueryEndOnLastLine(String functionExp) {
         return SubQueryIndentProcessor.hasSubQueryEndOnLastLine(functionExp);
     }
 
     // -----------------------------------------------------
     //                                        Bind Parameter
     //                                        --------------
     protected String buildBindParameter(Object bindKey) {
         final String bindExp;
         if (isDreamCruiseTicket(bindKey)) {
             bindExp = buildDreamCruiseTicketStatement(bindKey);
         } else {
             bindExp = "/*pmb." +  + "." +  + ".bindMap." + bindKey + "*/null";
         }
         return bindExp;
     }
 
     protected Object registerBindParameter(int indexObject parameter) {
         if (isDreamCruiseTicket(parameter)) {
             return parameter;
         }
         if ( == null) {
              = new HashMap<StringObject>(4);
         }
         final String bindKey = "param" + index;
         .put(bindKeyparameter);
         return bindKey;
     }
 
     // -----------------------------------------------------
     //                                   Additional Variable
     //                                   -------------------
     protected boolean hasTargetColumnInfo() {
         return  != null;
     }
 
     protected boolean hasMysticBinding() {
         return  != null;
     }
 
     // -----------------------------------------------------
     //                                             Date Type
     //                                             ---------
     protected boolean isDateTypeColumn() { // #date_parade
         if ( != null && .isObjectNativeTypeDate()) {
             return true;
         }
         final Object snapshot = ;
         if (snapshot != null && (snapshot instanceof Date || DfTypeUtil.isAnyLocalDate(snapshot))) {
             return true;
         }
         return false;
     }
 
     protected boolean isJustDateTypeColumn() {
         if ( != null && .isObjectNativeTypeJustDate()) {
             return true;
         }
         final Object snapshot = ;
         if (snapshot != null) {
             final Class<?> snapType = snapshot.getClass();
             if (snapType.equals(Date.class) || snapType.equals(LocalDate.class)) {
                 return true;
             }
         }
         return false// unknown, basically no way
     }
 
     protected boolean isJustTimestampTypeColumn() {
         if ( != null && .isObjectNativeTypeJustTimestamp()) {
             return true;
         }
         final Object snapshot = ;
         if (snapshot != null) {
             final Class<?> snapType = snapshot.getClass();
             if (snapType.equals(Timestamp.class) || snapType.equals(LocalDateTime.class)) {
                 return true;
             }
         }
         return false// unknown, basically no way
     }
 
     protected boolean isJustTimeTypeColumn() {
         if ( != null && .isObjectNativeTypeJustTime()) {
             return true;
         }
         final Object snapshot = ;
         if (snapshot != null) {
             final Class<?> snapType = snapshot.getClass();
             if (snapType.equals(Time.class) || snapType.equals(LocalTime.class)) {
                 return true;
             }
         }
         return false// unknown, basically no way
     }
 
     // -----------------------------------------------------
     //                                          Dream Cruise
     //                                          ------------
     protected boolean isDreamCruiseTicket(Object value) {
         return value instanceof SpecifiedColumn;
     }
 
     protected String buildDreamCruiseTicketStatement(Object value) {
         final String bindPath;
         final SpecifiedColumn specifiedColumn = ((SpecifiedColumnvalue);
         final String columnExp;
         if () { // e.g. VaryingUpdate
             columnExp = specifiedColumn.toColumnSqlName().toString();
         } else { // normally here
             columnExp = specifiedColumn.toColumnRealName().toString();
         }
         if (specifiedColumn.hasSpecifyCalculation()) {
             specifiedColumn.xinitSpecifyCalculation();
             final HpCalcSpecification<ConditionBeancalcSpecification = specifiedColumn.getSpecifyCalculation();
             if () { // e.g. VaryingUpdate
                 bindPath = calcSpecification.buildStatementToSpecifidNameRemovedCalcAlias(columnExp);
             } else { // normally here
                 bindPath = calcSpecification.buildStatementToSpecifidName(columnExp);
             }
         } else {
             bindPath = columnExp;
         }
         return bindPath;
     }
 
     // ===================================================================================
     //                                                                       Assert Helper
     //                                                                       =============
     // -----------------------------------------------------
     //                                         Assert Object
     //                                         -------------
     
Assert that the object is not null.

Parameters:
variableName The check name of variable for message. (NotNull)
value The checked value. (NotNull)
Throws:
java.lang.IllegalArgumentException When the argument is null.
 
     protected void assertObjectNotNull(String variableNameObject value) {
         if (variableName == null) {
             String msg = "The value should not be null: variableName=null value=" + value;
             throw new IllegalArgumentException(msg);
         }
         if (value == null) {
             String msg = "The value should not be null: variableName=" + variableName;
             throw new IllegalArgumentException(msg);
         }
     }
 
     // -----------------------------------------------------
     //                                       Assert Pinpoint
     //                                       ---------------
     protected void assertCalculationColumnNumber(SpecifiedColumn specifiedColumn) {
         final ColumnInfo columnInfo = specifiedColumn.getColumnInfo();
         if (columnInfo == null) { // basically not null but just in case
             return;
         }
         if (!columnInfo.isObjectNativeTypeNumber()) {
             String msg = "The type of the calculation column should be Number: " + specifiedColumn;
             throw new IllegalArgumentException(msg);
         }
     }
 
     protected void assertSpecifiedDreamCruiseTicket(SpecifiedColumn column) {
         if (!column.isDreamCruiseTicket()) {
             final String msg = "The specified column was not dream cruise ticket: " + column;
             throw new IllegalConditionBeanOperationException(msg);
         }
     }
 
     protected void assertOptionValueNotNull(String keywordObject value) {
         if (isOptionValueNullIgnored()) {
             return;
         }
         if (value == null) {
             String msg = "The option value for " + keyword + " should not be null.";
             throw new IllegalConditionBeanOperationException(msg);
         }
     }
 
     protected boolean isOptionValueNullIgnored() {
         return false;
     }
 
     // ===================================================================================
     //                                                                      General Helper
     //                                                                      ==============
     protected final String ln() {
         return DBFluteSystem.ln();
     }
 
     // ===================================================================================
     //                                                                      Basic Override
     //                                                                      ==============
     @Override
     public String toString() {
         final String title = DfTypeUtil.toClassTitle(this);
         final String callbackExp =  != null ? .toString() : null;
         return title + ":{callback=" + callbackExp + ", bind=" +  + "}";
    }
    // ===================================================================================
    //                                                                            Accessor
    //                                                                            ========
    // -----------------------------------------------------
    //                            called by ParameterComment 
    //                            --------------------------
    public Map<StringObjectgetBindMap() {
        return ;
    }
    // -----------------------------------------------------
    //                                    called by internal
    //                                    ------------------
    public ColumnInfo xgetTargetColumnInfo() {
        return ;
    }
    public void xsetTargetColumnInfo(ColumnInfo targetColumnInfo) {
         = targetColumnInfo;
    }
        return ;
    }
    public void xsetMysticBindingSnapshot(Object mysticBindingSnapshot) {
         = mysticBindingSnapshot;
    }
    public Object getTrunc() {
        return ;
    }
    public void xremoveCalcAlias() {
         = true;
    }
    public void xjudgeDatabase(SqlClause sqlClause) {
        setDatabaseMySQL(sqlClause instanceof SqlClauseMySql);
        setDatabasePostgreSQL(sqlClause instanceof SqlClausePostgreSql);
        setDatabaseOracle(sqlClause instanceof SqlClauseOracle);
        setDatabaseDB2(