forked from openGauss-Ecosystem/openGauss-server
!2845 【bugfixed】解决insert语句右值引用不支持jdbc方式;以及列存在not null约束时默认值与MySQL不一致的问题
Merge pull request !2845 from laishenghao/rightref-bugfixed
This commit is contained in:
commit
39c2d3eeef
|
@ -111,6 +111,8 @@ static ReplicaIdentityStmt* _copyReplicaIdentityStmt(const ReplicaIdentityStmt*
|
|||
static AlterSystemStmt* _copyAlterSystemStmt(const AlterSystemStmt* from);
|
||||
#endif
|
||||
static void CopyCursorFields(const Cursor_Data* from, Cursor_Data* newnode);
|
||||
static RightRefState* CopyRightRefState(const RightRefState* from);
|
||||
|
||||
/* ****************************************************************
|
||||
* plannodes.h copy functions
|
||||
* ****************************************************************
|
||||
|
@ -237,6 +239,8 @@ static void CopyPlanFields(const Plan* from, Plan* newnode)
|
|||
COPY_SCALAR_FIELD(pred_startup_time);
|
||||
COPY_SCALAR_FIELD(pred_total_time);
|
||||
COPY_SCALAR_FIELD(pred_max_memory);
|
||||
|
||||
newnode->rightRefState = CopyRightRefState(from->rightRefState);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4643,6 +4647,45 @@ static Query* _copyQuery(const Query* from)
|
|||
COPY_SCALAR_FIELD(isReplace);
|
||||
}
|
||||
|
||||
newnode->rightRefState = CopyRightRefState(from->rightRefState);
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
static RightRefState* CopyRightRefState(const RightRefState* from)
|
||||
{
|
||||
if (!from) {
|
||||
return nullptr;
|
||||
}
|
||||
RightRefState* newnode = (RightRefState*)palloc0(sizeof(RightRefState));
|
||||
|
||||
COPY_SCALAR_FIELD(isSupported);
|
||||
COPY_SCALAR_FIELD(isInsertHasRightRef);
|
||||
COPY_SCALAR_FIELD(explicitAttrLen);
|
||||
if (from->explicitAttrLen > 0) {
|
||||
COPY_POINTER_FIELD(explicitAttrNos, from->explicitAttrLen * sizeof(int));
|
||||
}
|
||||
|
||||
if (from->constValues && from->colCnt > 0) {
|
||||
newnode->constValues = (Const**)palloc0(sizeof(Const*) * from->colCnt);
|
||||
for (int i = 0; i < from->colCnt; ++i) {
|
||||
if (from->constValues[i]) {
|
||||
newnode->constValues[i] = _copyConst(from->constValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
COPY_SCALAR_FIELD(colCnt);
|
||||
|
||||
/* ignore values, hasExecs, isNulls */
|
||||
|
||||
COPY_SCALAR_FIELD(isUpsert);
|
||||
COPY_SCALAR_FIELD(isUpsertHasRightRef);
|
||||
COPY_SCALAR_FIELD(usExplicitAttrLen);
|
||||
if (from->usExplicitAttrLen > 0) {
|
||||
COPY_POINTER_FIELD(usExplicitAttrNos, from->usExplicitAttrLen * sizeof(int));
|
||||
}
|
||||
|
||||
return newnode;
|
||||
}
|
||||
|
||||
|
|
|
@ -86,6 +86,14 @@
|
|||
return false; \
|
||||
} while (0)
|
||||
|
||||
/* Check whether a field is null */
|
||||
#define CHECK_ANY_NULL(fildname) \
|
||||
do { \
|
||||
if (a->fildname == nullptr || b->fildname == nullptr) { \
|
||||
return false; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Compare a parse location field (this is a no-op, per note above) */
|
||||
#define COMPARE_LOCATION_FIELD(fldname) ((void)0)
|
||||
|
||||
|
@ -842,6 +850,54 @@ static bool _equalPlaceHolderInfo(const PlaceHolderInfo* a, const PlaceHolderInf
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool _equalRightRefState(const RightRefState* a, const RightRefState* b)
|
||||
{
|
||||
if (a == b) {
|
||||
return true;
|
||||
}
|
||||
if (a == nullptr || b == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
COMPARE_SCALAR_FIELD(isSupported);
|
||||
COMPARE_SCALAR_FIELD(isInsertHasRightRef);
|
||||
COMPARE_SCALAR_FIELD(explicitAttrLen);
|
||||
COMPARE_SCALAR_FIELD(colCnt);
|
||||
COMPARE_SCALAR_FIELD(isUpsert);
|
||||
COMPARE_SCALAR_FIELD(isUpsertHasRightRef);
|
||||
COMPARE_SCALAR_FIELD(usExplicitAttrLen);
|
||||
|
||||
/* ignore values, hasExecs, isNulls fields */
|
||||
|
||||
if (a->explicitAttrNos != b->explicitAttrNos) {
|
||||
CHECK_ANY_NULL(explicitAttrNos);
|
||||
if (a->explicitAttrLen > 0) {
|
||||
COMPARE_POINTER_FIELD(explicitAttrNos, a->explicitAttrLen);
|
||||
}
|
||||
}
|
||||
|
||||
if (a->usExplicitAttrNos != b->usExplicitAttrNos) {
|
||||
CHECK_ANY_NULL(usExplicitAttrNos);
|
||||
if (a->usExplicitAttrLen > 0) {
|
||||
COMPARE_POINTER_FIELD(usExplicitAttrNos, a->usExplicitAttrLen);
|
||||
}
|
||||
}
|
||||
|
||||
if (a->constValues != b->constValues) {
|
||||
CHECK_ANY_NULL(constValues);
|
||||
if (a->colCnt > 0) {
|
||||
for (int i = 0; i < a->colCnt; ++i) {
|
||||
if (a->constValues[i] != b->constValues[i]) {
|
||||
CHECK_ANY_NULL(constValues[i]);
|
||||
COMPARE_NODE_FIELD(constValues[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Stuff from parsenodes.h
|
||||
*/
|
||||
|
@ -904,6 +960,10 @@ static bool _equalQuery(const Query* a, const Query* b)
|
|||
COMPARE_SCALAR_FIELD(isReplace);
|
||||
}
|
||||
|
||||
if (!_equalRightRefState(a->rightRefState, b->rightRefState)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -155,6 +155,29 @@
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define WRITE_BASE_TYPE_ARRAY(fldname, size, format) \
|
||||
do { \
|
||||
appendStringInfo(str, " :" CppAsString(fldname) " "); \
|
||||
if (size <= 0) { \
|
||||
appendStringInfo(str, "<>"); \
|
||||
} else { \
|
||||
for (int i = 0; i < size; i++) { \
|
||||
appendStringInfo(str, format, node->fldname[i]); \
|
||||
} \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define WRITE_NODE_ARRAY(fldname, size) \
|
||||
do { \
|
||||
if (node->fldname == nullptr || size <= 0) { \
|
||||
appendStringInfo(str, " :" CppAsString(fldname) " <>"); \
|
||||
} else { \
|
||||
for (int i = 0; i < size; i++) { \
|
||||
WRITE_NODE_FIELD(fldname[i]); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Write full-text search configuration's name out of its oid
|
||||
*
|
||||
|
@ -4386,6 +4409,31 @@ static void _outHintState(StringInfo str, HintState* node)
|
|||
}
|
||||
}
|
||||
|
||||
static void _outRightRefState(StringInfo str, RightRefState* node)
|
||||
{
|
||||
if (node == nullptr) {
|
||||
appendStringInfo(str, "<>");
|
||||
return;
|
||||
}
|
||||
appendStringInfoChar(str, '{');
|
||||
WRITE_NODE_TYPE("RIGHTREFSTATE");
|
||||
WRITE_BOOL_FIELD(isSupported);
|
||||
WRITE_BOOL_FIELD(isInsertHasRightRef);
|
||||
WRITE_INT_FIELD(explicitAttrLen);
|
||||
WRITE_BASE_TYPE_ARRAY(explicitAttrNos, node->explicitAttrLen, "%d ");
|
||||
|
||||
WRITE_INT_FIELD(colCnt);
|
||||
WRITE_NODE_ARRAY(constValues, node->colCnt);
|
||||
|
||||
/* ignore values, hasExecs, isNulls fields */
|
||||
|
||||
WRITE_BOOL_FIELD(isUpsert);
|
||||
WRITE_BOOL_FIELD(isUpsertHasRightRef);
|
||||
WRITE_INT_FIELD(usExplicitAttrLen);
|
||||
WRITE_BASE_TYPE_ARRAY(usExplicitAttrNos, node->usExplicitAttrLen, "%d ");
|
||||
appendStringInfoChar(str, '}');
|
||||
}
|
||||
|
||||
static void _outQuery(StringInfo str, Query* node)
|
||||
{
|
||||
WRITE_NODE_TYPE("QUERY");
|
||||
|
@ -4499,6 +4547,10 @@ static void _outQuery(StringInfo str, Query* node)
|
|||
if (t_thrd.proc->workingVersionNum >= REPLACE_INTO_VERSION_NUM) {
|
||||
WRITE_BOOL_FIELD(isReplace);
|
||||
}
|
||||
if (t_thrd.proc->workingVersionNum >= INSERT_RIGHT_REF_VERSION_NUM) {
|
||||
appendStringInfo(str, " :" CppAsString(rightRefState) " ");
|
||||
_outRightRefState(str, node->rightRefState);
|
||||
}
|
||||
}
|
||||
|
||||
static void _outWithCheckOption(StringInfo str, const WithCheckOption* node)
|
||||
|
|
|
@ -175,6 +175,19 @@ THR_LOCAL bool skip_read_extern_fields = false;
|
|||
} \
|
||||
} while (0)
|
||||
|
||||
#define READ_INT_ARRAY_CAN_NULL(fldname, size) \
|
||||
if (local_node->size > 0) { \
|
||||
READ_INT_ARRAY(fldname, size); \
|
||||
} else { \
|
||||
token = pg_strtok(&length); /* skip :fldname */ \
|
||||
token = pg_strtok(&length); /* read <> */ \
|
||||
if (token == nullptr || token[0] != '<' || token[1] != '>') { \
|
||||
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE), \
|
||||
errmsg("did not find '<>' at end of null array"))); \
|
||||
} \
|
||||
local_node->fldname = nullptr; \
|
||||
}
|
||||
|
||||
#define READ_DOUBLE_ARRAY(fldname, size) \
|
||||
do { \
|
||||
local_node->fldname = (double*)palloc(local_node->size * sizeof(double)); \
|
||||
|
@ -405,6 +418,18 @@ THR_LOCAL bool skip_read_extern_fields = false;
|
|||
securec_check(reterrno, "\0", "\0"); \
|
||||
} while (0)
|
||||
|
||||
#define READ_NODE_ARRAY(fldname, size, itemtype) \
|
||||
do { \
|
||||
if (size <= 0) { \
|
||||
READ_NODE_FIELD(fldname); /* must be null */ \
|
||||
} else { \
|
||||
local_node->fldname = (itemtype*)palloc0(sizeof(itemtype) * (size)); \
|
||||
for (int i = 0; i < size; i++) { \
|
||||
READ_NODE_FIELD(fldname[i]); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/* Read a bitmapset field */
|
||||
#define READ_BITMAPSET_FIELD(fldname) \
|
||||
token = pg_strtok(&length); /* skip :fldname */ \
|
||||
|
@ -1409,6 +1434,68 @@ static HintState* _readHintState()
|
|||
READ_DONE();
|
||||
}
|
||||
|
||||
static RightRefState* _readRightRefState(Query* query)
|
||||
{
|
||||
check_stack_depth();
|
||||
RightRefState* local_node = (RightRefState*)palloc0(sizeof(RightRefState));
|
||||
char* token = nullptr;
|
||||
int length = 0;
|
||||
|
||||
READ_BOOL_FIELD(isSupported);
|
||||
READ_BOOL_FIELD(isInsertHasRightRef);
|
||||
READ_INT_FIELD(explicitAttrLen);
|
||||
READ_INT_ARRAY_CAN_NULL(explicitAttrNos, explicitAttrLen);
|
||||
|
||||
READ_INT_FIELD(colCnt);
|
||||
READ_NODE_ARRAY(constValues, local_node->colCnt, Const*);
|
||||
|
||||
/* ignore values, hasExecs, isNulls fields */
|
||||
|
||||
READ_BOOL_FIELD(isUpsert);
|
||||
READ_BOOL_FIELD(isUpsertHasRightRef);
|
||||
READ_INT_FIELD(usExplicitAttrLen);
|
||||
READ_INT_ARRAY_CAN_NULL(usExplicitAttrNos, usExplicitAttrLen);
|
||||
|
||||
token = pg_strtok(&length);
|
||||
if (token == nullptr || token[0] != '}') {
|
||||
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE),
|
||||
errmsg("did not find '}' at end of RightRefState node")));
|
||||
}
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
||||
static RightRefState* _readRightRefStateWrap(Query* query)
|
||||
{
|
||||
char* token = nullptr;
|
||||
int length = 0;
|
||||
token = pg_strtok(&length); /* skip :fldname */
|
||||
token = pg_strtok(&length, false);
|
||||
if (length == 0) {
|
||||
if (token && token[0] == '<' && token[1] == '>') {
|
||||
token = pg_strtok(&length); /* skip <> */
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
token = pg_strtok(&length); /* left brace */
|
||||
if (token == nullptr || token[0] != '{') {
|
||||
ereport(ERROR, (errcode(ERRCODE_UNEXPECTED_NULL_VALUE),
|
||||
errmsg("did not find '{' at end of RightRefState node")));
|
||||
}
|
||||
token = pg_strtok(&length); /* read node name */
|
||||
if (length != 13 && memcmp(token, "RIGHTREFSTATE", 13) != 0) {
|
||||
ereport(ERROR, (errcode(ERRCODE_UNRECOGNIZED_NODE_TYPE),
|
||||
errmsg("_readRightRefStateWrap(): badly formatted node string \"%s\"...", token)));
|
||||
}
|
||||
|
||||
if (token != nullptr) {
|
||||
token = nullptr;
|
||||
}
|
||||
|
||||
return _readRightRefState(query);
|
||||
}
|
||||
|
||||
/*
|
||||
* _readQuery
|
||||
*/
|
||||
|
@ -1544,6 +1631,10 @@ static Query* _readQuery(void)
|
|||
IF_EXIST(isReplace) {
|
||||
READ_BOOL_FIELD(isReplace);
|
||||
}
|
||||
|
||||
IF_EXIST(rightRefState) {
|
||||
local_node->rightRefState = _readRightRefStateWrap(local_node);
|
||||
}
|
||||
|
||||
READ_DONE();
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "postgres.h"
|
||||
#include "knl/knl_variable.h"
|
||||
|
||||
#include "catalog/pg_enum.h"
|
||||
#include "catalog/pg_type.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "catalog/gs_package.h"
|
||||
|
@ -105,6 +106,74 @@ static inline bool IsAutoIncrementColumn(TupleDesc rdAtt, int attrNo)
|
|||
return rdAtt->constr && rdAtt->constr->cons_autoinc && rdAtt->constr->cons_autoinc->attnum == attrNo;
|
||||
}
|
||||
|
||||
static bool IsBaseRightRefSupportType(Oid oid)
|
||||
{
|
||||
switch(oid) {
|
||||
case BOOLOID:
|
||||
case BYTEAOID:
|
||||
case CHAROID:
|
||||
case NAMEOID:
|
||||
case INT8OID:
|
||||
case INT2OID:
|
||||
case INT1OID:
|
||||
case INT4OID:
|
||||
case TEXTOID:
|
||||
case INT16OID:
|
||||
case RAWOID:
|
||||
case BLOBOID:
|
||||
case CLOBOID:
|
||||
case JSONOID:
|
||||
case XMLOID:
|
||||
case POINTOID:
|
||||
case LSEGOID:
|
||||
case PATHOID:
|
||||
case BOXOID:
|
||||
case POLYGONOID:
|
||||
case FLOAT4OID:
|
||||
case FLOAT8OID:
|
||||
case ABSTIMEOID:
|
||||
case RELTIMEOID:
|
||||
case TINTERVALOID:
|
||||
case CIRCLEOID:
|
||||
case CASHOID:
|
||||
case MACADDROID:
|
||||
case INETOID:
|
||||
case CIDROID:
|
||||
case BPCHAROID:
|
||||
case VARCHAROID:
|
||||
case NVARCHAR2OID:
|
||||
case DATEOID:
|
||||
case TIMEOID:
|
||||
case TIMESTAMPOID:
|
||||
case TIMESTAMPTZOID:
|
||||
case INTERVALOID:
|
||||
case TIMETZOID:
|
||||
case BITOID:
|
||||
case VARBITOID:
|
||||
case NUMERICOID:
|
||||
case UUIDOID:
|
||||
case TSVECTOROID:
|
||||
case TSQUERYOID:
|
||||
case JSONBOID:
|
||||
case INT4RANGEOID:
|
||||
case NUMRANGEOID:
|
||||
case TSRANGEOID:
|
||||
case TSTZRANGEOID:
|
||||
case DATERANGEOID:
|
||||
case INT8RANGEOID:
|
||||
case CSTRINGOID:
|
||||
case INTERNALOID:
|
||||
case SMALLDATETIMEOID:
|
||||
case HLL_OID:
|
||||
case HASH16OID:
|
||||
case HASH32OID:
|
||||
return true;
|
||||
default: {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void AddDefaultExprNode(ParseState* pstate)
|
||||
{
|
||||
RightRefState* refState = pstate->rightRefState;
|
||||
|
@ -152,6 +221,37 @@ static void AddDefaultExprNode(ParseState* pstate)
|
|||
refState->constValues[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* support not null constraint */
|
||||
if (refState->constValues[i] == nullptr && attTup && attTup->attnotnull) {
|
||||
Datum datum;
|
||||
if (IsBaseRightRefSupportType(attTup->atttypid)) {
|
||||
datum = GetTypeZeroValue(attTup);
|
||||
refState->constValues[i] = makeConst(attTup->atttypid, attTup->atttypmod, attTup->attcollation,
|
||||
attTup->attlen, datum, false, attTup->attbyval);
|
||||
} else if (type_is_enum(attTup->atttypid)) {
|
||||
Relation enumRel = heap_open(EnumRelationId, AccessShareLock);
|
||||
CatCList* items = SearchSysCacheList1(ENUMTYPOIDNAME, ObjectIdGetDatum(attTup->atttypid));
|
||||
int itemCnt = items->n_members;
|
||||
|
||||
for (int eindex = 0; eindex < itemCnt; ++eindex) {
|
||||
HeapTuple enumTup = t_thrd.lsc_cxt.FetchTupleFromCatCList(items, eindex);
|
||||
Form_pg_enum item = (Form_pg_enum)GETSTRUCT(enumTup);
|
||||
if (item && item->enumsortorder == 1) {
|
||||
datum = DirectFunctionCall2(enum_in, CStringGetDatum(pstrdup(NameStr(item->enumlabel))), attTup->atttypid);
|
||||
refState->constValues[i] = makeConst(attTup->atttypid, attTup->atttypmod, attTup->attcollation,
|
||||
attTup->attlen, datum, false, attTup->attbyval);
|
||||
break;
|
||||
}
|
||||
}
|
||||
ReleaseSysCacheList(items);
|
||||
heap_close(enumRel, AccessShareLock);
|
||||
} else if (type_is_set(attTup->atttypid)) {
|
||||
datum = CStringGetTextDatum("");
|
||||
refState->constValues[i] = makeConst(attTup->atttypid, attTup->atttypmod, attTup->attcollation,
|
||||
attTup->attlen, datum, false, attTup->attbyval);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,7 @@ bool open_join_children = true;
|
|||
bool will_shutdown = false;
|
||||
|
||||
/* hard-wired binary version number */
|
||||
const uint32 GRAND_VERSION_NUM = 92841;
|
||||
const uint32 GRAND_VERSION_NUM = 92842;
|
||||
|
||||
const uint32 SELECT_INTO_VAR_VERSION_NUM = 92834;
|
||||
const uint32 DOLPHIN_ENABLE_DROP_NUM = 92830;
|
||||
|
@ -117,6 +117,7 @@ const uint32 PLAN_SELECT_VERSION_NUM = 92826;
|
|||
const uint32 REPLACE_INTO_VERSION_NUM = 92828;
|
||||
const uint32 PG_AUTHID_PASSWORDEXT_VERSION_NUM = 92830;
|
||||
const uint32 SUPPORT_VIEW_AUTO_UPDATABLE = 92838;
|
||||
const uint32 INSERT_RIGHT_REF_VERSION_NUM = 92842;
|
||||
|
||||
/* Version number of the guc parameter backend_version added in V500R001C20 */
|
||||
const uint32 V5R1C20_BACKEND_VERSION_NUM = 92305;
|
||||
|
|
|
@ -440,9 +440,8 @@ void ExecuteQuery(ExecuteStmt* stmt, IntoClause* intoClause, const char* querySt
|
|||
eflags = 0;
|
||||
count = FETCH_ALL;
|
||||
}
|
||||
bool checkSQLBypass = IS_PGXC_DATANODE && !psrc->gpc.status.InShareTable() &&
|
||||
(psrc->cplan == NULL) && (psrc->is_checked_opfusion == false);
|
||||
if (checkSQLBypass) {
|
||||
|
||||
if (OpFusion::IsSqlBypass(psrc, plan_list)) {
|
||||
psrc->opFusionObj =
|
||||
OpFusion::FusionFactory(OpFusion::getFusionType(cplan, paramLI, NULL),
|
||||
u_sess->cache_mem_cxt, psrc, NULL, paramLI);
|
||||
|
|
|
@ -2236,7 +2236,7 @@ void exec_init_poolhandles(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
static bool IsRightRefState(List* plantreeList)
|
||||
bool IsRightRefState(List* plantreeList)
|
||||
{
|
||||
if (!plantreeList || !list_length(plantreeList)) {
|
||||
return false;
|
||||
|
@ -4899,8 +4899,7 @@ static void exec_bind_message(StringInfo input_message)
|
|||
|
||||
portal->nextval_default_expr_type = psrc->nextval_default_expr_type;
|
||||
|
||||
if (IS_PGXC_DATANODE && psrc->cplan == NULL && !psrc->gpc.status.InShareTable() &&
|
||||
psrc->is_checked_opfusion == false) {
|
||||
if (OpFusion::IsSqlBypass(psrc, cplan->stmt_list)) {
|
||||
psrc->opFusionObj = OpFusion::FusionFactory(OpFusion::getFusionType(cplan, params, NULL),
|
||||
u_sess->cache_mem_cxt, psrc, NULL, params);
|
||||
psrc->is_checked_opfusion = true;
|
||||
|
@ -10712,9 +10711,7 @@ static void exec_one_in_batch(CachedPlanSource* psrc, ParamListInfo params, int
|
|||
portal->stmts = *gpcCopyStmts;
|
||||
}
|
||||
|
||||
bool checkSQLBypass = IS_PGXC_DATANODE && !psrc->gpc.status.InShareTable() &&
|
||||
(psrc->cplan == NULL) && (psrc->is_checked_opfusion == false);
|
||||
if (checkSQLBypass) {
|
||||
if (OpFusion::IsSqlBypass(psrc, cplan->stmt_list)) {
|
||||
psrc->opFusionObj = OpFusion::FusionFactory(OpFusion::getFusionType(cplan, params, NULL),
|
||||
u_sess->cache_mem_cxt, psrc, NULL, params);
|
||||
psrc->is_checked_opfusion = true;
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "utils/json.h"
|
||||
#include "utils/jsonb.h"
|
||||
#include "utils/xml.h"
|
||||
#include "utils/rangetypes.h"
|
||||
#include "commands/sequence.h"
|
||||
|
||||
static bool get_last_attnums(Node* node, ProjectionInfo* projInfo);
|
||||
|
@ -2664,11 +2665,66 @@ Datum GetTypeZeroValue(Form_pg_attribute att_tup)
|
|||
result = (Datum)DirectFunctionCall3(bit_in, CStringGetDatum(""), ObjectIdGetDatum(0), Int32GetDatum(-1));
|
||||
break;
|
||||
}
|
||||
case VARBITOID: {
|
||||
result = (Datum)DirectFunctionCall3(varbit_in, CStringGetDatum(""), ObjectIdGetDatum(0), Int32GetDatum(-1));
|
||||
break;
|
||||
}
|
||||
case NUMERICOID: {
|
||||
result =
|
||||
(Datum)DirectFunctionCall3(numeric_in, CStringGetDatum("0"), ObjectIdGetDatum(0), Int32GetDatum(0));
|
||||
break;
|
||||
}
|
||||
case CIDROID: {
|
||||
result = DirectFunctionCall1(cidr_in, CStringGetDatum("0.0.0.0"));
|
||||
break;
|
||||
}
|
||||
case INETOID: {
|
||||
result = DirectFunctionCall1(inet_in, CStringGetDatum("0.0.0.0"));
|
||||
break;
|
||||
}
|
||||
case MACADDROID: {
|
||||
result = (Datum)DirectFunctionCall1(macaddr_in, CStringGetDatum("00:00:00:00:00:00"));
|
||||
break;
|
||||
}
|
||||
case NUMRANGEOID:
|
||||
case INT8RANGEOID:
|
||||
case INT4RANGEOID: {
|
||||
Type targetType = typeidType(att_tup->atttypid);
|
||||
result = stringTypeDatum(targetType, "(0,0)", att_tup->atttypmod, true);
|
||||
ReleaseSysCache(targetType);
|
||||
break;
|
||||
}
|
||||
case TSRANGEOID:
|
||||
case TSTZRANGEOID: {
|
||||
Type targetType = typeidType(att_tup->atttypid);
|
||||
result = stringTypeDatum(targetType, "(1970-01-01 00:00:00,1970-01-01 00:00:00)", att_tup->atttypmod, true);
|
||||
ReleaseSysCache(targetType);
|
||||
break;
|
||||
}
|
||||
case DATERANGEOID: {
|
||||
Type targetType = typeidType(att_tup->atttypid);
|
||||
result = stringTypeDatum(targetType, "(1970-01-01,1970-01-01)", att_tup->atttypmod, true);
|
||||
ReleaseSysCache(targetType);
|
||||
break;
|
||||
}
|
||||
case HASH16OID: {
|
||||
Type targetType = typeidType(att_tup->atttypid);
|
||||
result = stringTypeDatum(targetType, "0", att_tup->atttypmod, true);
|
||||
ReleaseSysCache(targetType);
|
||||
break;
|
||||
}
|
||||
case HASH32OID: {
|
||||
Type targetType = typeidType(att_tup->atttypid);
|
||||
result = stringTypeDatum(targetType, "00000000000000000000000000000000", att_tup->atttypmod, true);
|
||||
ReleaseSysCache(targetType);
|
||||
break;
|
||||
}
|
||||
case TSVECTOROID: {
|
||||
Type targetType = typeidType(att_tup->atttypid);
|
||||
result = stringTypeDatum(targetType, "", att_tup->atttypmod, true);
|
||||
ReleaseSysCache(targetType);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
bool typeIsVarlena = (!att_tup->attbyval) && (att_tup->attlen == -1);
|
||||
if (typeIsVarlena) {
|
||||
|
|
|
@ -693,18 +693,23 @@ DESCR("range of integers");
|
|||
DATA(insert OID = 3905 ( _int4range PGNSP PGUID -1 f b A f t \054 0 3904 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DATA(insert OID = 3906 ( numrange PGNSP PGUID -1 f r R f t \054 0 0 3907 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DESCR("range of numerics");
|
||||
#define NUMRANGEOID 3906
|
||||
DATA(insert OID = 3907 ( _numrange PGNSP PGUID -1 f b A f t \054 0 3906 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DATA(insert OID = 3908 ( tsrange PGNSP PGUID -1 f r R f t \054 0 0 3909 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DESCR("range of timestamps without time zone");
|
||||
#define TSRANGEOID 3908
|
||||
DATA(insert OID = 3909 ( _tsrange PGNSP PGUID -1 f b A f t \054 0 3908 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DATA(insert OID = 3910 ( tstzrange PGNSP PGUID -1 f r R f t \054 0 0 3911 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DESCR("range of timestamps with time zone");
|
||||
#define TSTZRANGEOID 3910
|
||||
DATA(insert OID = 3911 ( _tstzrange PGNSP PGUID -1 f b A f t \054 0 3910 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DATA(insert OID = 3912 ( daterange PGNSP PGUID -1 f r R f t \054 0 0 3913 range_in range_out range_recv range_send - - range_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DESCR("range of dates");
|
||||
#define DATERANGEOID 3912
|
||||
DATA(insert OID = 3913 ( _daterange PGNSP PGUID -1 f b A f t \054 0 3912 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DATA(insert OID = 3926 ( int8range PGNSP PGUID -1 f r R f t \054 0 0 3927 range_in range_out range_recv range_send - - range_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
DESCR("range of bigints");
|
||||
#define INT8RANGEOID 3926
|
||||
DATA(insert OID = 3927 ( _int8range PGNSP PGUID -1 f b A f t \054 0 3926 0 array_in array_out array_recv array_send - - array_typanalyze d x f 0 -1 0 0 _null_ _null_ _null_ ));
|
||||
/*
|
||||
* pseudo-types
|
||||
|
|
|
@ -119,6 +119,7 @@ extern const uint32 MAT_VIEW_RECURSIVE_VERSION_NUM;
|
|||
extern const uint32 SUPPORT_VIEW_AUTO_UPDATABLE;
|
||||
extern const uint32 FDW_SUPPORT_JOIN_AGG_VERSION_NUM;
|
||||
extern const uint32 UNION_NULL_VERSION_NUM;
|
||||
extern const uint32 INSERT_RIGHT_REF_VERSION_NUM;
|
||||
|
||||
extern void register_backend_version(uint32 backend_version);
|
||||
extern bool contain_backend_version(uint32 version_number);
|
||||
|
|
|
@ -43,6 +43,7 @@ typedef unsigned long (OpFusion::*OpFusionExecfuncType)(Relation rel, ResultRelI
|
|||
|
||||
extern void report_qps_type(CmdType commandType);
|
||||
extern void ExecCheckXactReadOnly(PlannedStmt* plannedstmt);
|
||||
extern bool IsRightRefState(List* plantreeList);
|
||||
EState* CreateExecutorStateForOpfusion(MemoryContext saveCxt, MemoryContext tmpCxt);
|
||||
void FreeExecutorStateForOpfusion(EState* estate);
|
||||
|
||||
|
@ -154,6 +155,13 @@ public:
|
|||
return (m_global && m_global->m_is_global);
|
||||
}
|
||||
|
||||
inline static bool IsSqlBypass(CachedPlanSource* psrc, List* stmtList)
|
||||
{
|
||||
return (IS_PGXC_DATANODE && !psrc->gpc.status.InShareTable() &&
|
||||
psrc->cplan == NULL && psrc->is_checked_opfusion == false &&
|
||||
!IsRightRefState(stmtList));
|
||||
}
|
||||
|
||||
public:
|
||||
struct ConstLoc {
|
||||
Datum constValue;
|
||||
|
|
|
@ -34,5 +34,6 @@ extern void AddStartWithTargetRelInfo(ParseState* pstate, Node* relNode,
|
|||
extern void AdaptSWSelectStmt(ParseState *pstate, SelectStmt *stmt);
|
||||
extern bool IsQuerySWCBRewrite(Query *query);
|
||||
extern bool IsSWCBRewriteRTE(RangeTblEntry *rte);
|
||||
extern Datum GetTypeZeroValue(Form_pg_attribute att_tup);
|
||||
|
||||
#endif /* PARSE_EXPR_H */
|
||||
|
|
|
@ -1,31 +1,21 @@
|
|||
create database rightref with dbcompatibility 'B';
|
||||
\c rightref
|
||||
|
||||
-- test fields order
|
||||
create table test_order_t(n1 int default 100, n2 int default 100, s int);
|
||||
insert into test_order_t values(1000, 1000, n1 + n2);
|
||||
insert into test_order_t(s, n1, n2) values(n1 + n2, 300, 300);
|
||||
select * from test_order_t;
|
||||
n1 | n2 | s
|
||||
------+------+------
|
||||
1000 | 1000 | 2000
|
||||
300 | 300 | 200
|
||||
(2 rows)
|
||||
|
||||
drop table test_order_t;
|
||||
|
||||
-- test non-idempotent function
|
||||
create table non_idempotent_t(c1 float, c2 float, c3 float);
|
||||
insert into non_idempotent_t values(random(), c1, c1);
|
||||
select c1 = c2 as f1, c1 = c3 as f2 from non_idempotent_t;
|
||||
f1 | f2
|
||||
----+----
|
||||
t | t
|
||||
(1 row)
|
||||
|
||||
drop table non_idempotent_t;
|
||||
|
||||
-- test auto increment
|
||||
create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "auto_increment_t_c1_seq" for serial column "auto_increment_t.c1"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "auto_increment_t_pkey" for table "auto_increment_t"
|
||||
insert into auto_increment_t values(1, c1, c1, c1);
|
||||
insert into auto_increment_t values(2, 0, c1, c1);
|
||||
insert into auto_increment_t values(3, 0, c1, c1);
|
||||
|
@ -33,36 +23,14 @@ insert into auto_increment_t values(4, -1, c1, c1);
|
|||
insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);
|
||||
insert into auto_increment_t values(5, c1, c1, c1);
|
||||
select * from auto_increment_t order by n;
|
||||
n | c1 | c2 | c3
|
||||
---+------+----+----
|
||||
1 | 1 | 0 | 0
|
||||
2 | 2 | 0 | 0
|
||||
3 | 3 | 0 | 0
|
||||
4 | -1 | -1 | -1
|
||||
5 | 1000 | 0 | 0
|
||||
5 | 1001 | 0 | 0
|
||||
(6 rows)
|
||||
|
||||
drop table auto_increment_t;
|
||||
|
||||
-- test series
|
||||
create table test_series_t(c1 int, c2 int, c3 int);
|
||||
insert into test_series_t values(c2 + 10, generate_series(1, 10), c2 * 2);
|
||||
select * from test_series_t;
|
||||
c1 | c2 | c3
|
||||
----+----+----
|
||||
| 1 | 2
|
||||
| 2 | 4
|
||||
| 3 | 6
|
||||
| 4 | 8
|
||||
| 5 | 10
|
||||
| 6 | 12
|
||||
| 7 | 14
|
||||
| 8 | 16
|
||||
| 9 | 18
|
||||
| 10 | 20
|
||||
(10 rows)
|
||||
|
||||
drop table test_series_t;
|
||||
|
||||
-- test upsert
|
||||
-- 1
|
||||
create table upser(c1 int, c2 int, c3 int);
|
||||
|
@ -73,24 +41,6 @@ insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 1
|
|||
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
|
||||
on duplicate key update c2 = 2000, c3 = 2000;
|
||||
select * from upser order by c1;
|
||||
c1 | c2 | c3
|
||||
----+------+------
|
||||
1 | 10 | 10
|
||||
2 | 10 | 10
|
||||
3 | 10 | 10
|
||||
4 | 10 | 10
|
||||
5 | 2000 | 2000
|
||||
6 | 2000 | 2000
|
||||
7 | 2000 | 2000
|
||||
8 | 2000 | 2000
|
||||
9 | 2000 | 2000
|
||||
10 | 2000 | 2000
|
||||
11 | 100 | 100
|
||||
12 | 100 | 100
|
||||
13 | 100 | 100
|
||||
14 | 100 | 100
|
||||
15 | 100 | 100
|
||||
(15 rows)
|
||||
|
||||
-- 2
|
||||
truncate upser;
|
||||
|
@ -100,54 +50,21 @@ insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 1
|
|||
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
|
||||
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
|
||||
select * from upser order by c1;
|
||||
c1 | c2 | c3
|
||||
----+-----+-----
|
||||
1 | 10 | 10
|
||||
2 | 10 | 10
|
||||
3 | 10 | 10
|
||||
4 | 10 | 10
|
||||
5 | 15 | 25
|
||||
6 | 16 | 26
|
||||
7 | 17 | 27
|
||||
8 | 18 | 28
|
||||
9 | 19 | 29
|
||||
10 | 20 | 30
|
||||
11 | 100 | 100
|
||||
12 | 100 | 100
|
||||
13 | 100 | 100
|
||||
14 | 100 | 100
|
||||
15 | 100 | 100
|
||||
(15 rows)
|
||||
|
||||
-- 3
|
||||
truncate upser;
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10),
|
||||
(7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
|
||||
insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100), (8, c1 + 100, 100),
|
||||
(9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100), (12, c1 + 100, 100),
|
||||
(13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)
|
||||
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
|
||||
|
||||
select * from upser order by c1;
|
||||
c1 | c2 | c3
|
||||
----+-----+-----
|
||||
1 | 10 | 10
|
||||
2 | 10 | 10
|
||||
3 | 10 | 10
|
||||
4 | 10 | 10
|
||||
5 | 15 | 25
|
||||
6 | 16 | 26
|
||||
7 | 17 | 27
|
||||
8 | 18 | 28
|
||||
9 | 19 | 29
|
||||
10 | 20 | 30
|
||||
11 | 111 | 100
|
||||
12 | 112 | 100
|
||||
13 | 113 | 100
|
||||
14 | 114 | 100
|
||||
15 | 115 | 130
|
||||
(15 rows)
|
||||
|
||||
drop table upser;
|
||||
|
||||
-- test var
|
||||
create table with_var(a int default 999);
|
||||
create function with_var_func() return int as
|
||||
|
@ -158,20 +75,13 @@ begin
|
|||
return a;
|
||||
end;
|
||||
/
|
||||
call with_var_func();
|
||||
with_var_func
|
||||
---------------
|
||||
666
|
||||
(1 row)
|
||||
|
||||
call with_var_func();
|
||||
select * from with_var;
|
||||
a
|
||||
-----
|
||||
666
|
||||
(1 row)
|
||||
|
||||
drop function with_var_func;
|
||||
drop table with_var;
|
||||
|
||||
-- test num type
|
||||
create table num_default_t (
|
||||
n serial,
|
||||
|
@ -200,7 +110,7 @@ create table num_default_t (
|
|||
c23 float default random() * 100,
|
||||
c24 float
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "num_default_t_n_seq" for serial column "num_default_t.n"
|
||||
|
||||
insert into num_default_t values(1);
|
||||
insert into num_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
|
@ -209,35 +119,15 @@ insert into num_default_t values(3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
|||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c20);
|
||||
insert into num_default_t(n, c23, c24) values(4, default, c23);
|
||||
|
||||
select 3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21
|
||||
from num_default_t;
|
||||
?column? | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21
|
||||
----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+--------+-----+-------+-----+-----+-----+------
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
|
||||
(4 rows)
|
||||
|
||||
select (c23 = c24) as equal from num_default_t where n = 4;
|
||||
equal
|
||||
-------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
select (c22 is null) as c22_is_null, (c23 is null) as c23_is_null from num_default_t where n = 2 or n = 3;
|
||||
c22_is_null | c23_is_null
|
||||
-------------+-------------
|
||||
t | t
|
||||
t | t
|
||||
(2 rows)
|
||||
|
||||
select (c22 is not null) as c22_is_not_null, (c23 is not null) as c23_is_not_null from num_default_t where n = 1;
|
||||
c22_is_not_null | c23_is_not_null
|
||||
-----------------+-----------------
|
||||
t | t
|
||||
(1 row)
|
||||
|
||||
|
||||
-- test char type
|
||||
create table char_default_t(
|
||||
|
@ -255,17 +145,12 @@ create table char_default_t(
|
|||
c11 varchar(20) default concat('hello', ' world'),
|
||||
c12 varchar(20)
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "char_default_t_n_seq" for serial column "char_default_t.n"
|
||||
|
||||
insert into char_default_t values(1);
|
||||
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
|
||||
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
|
||||
|
||||
select * from char_default_t;
|
||||
n | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12
|
||||
---+------------+----+-----+---------+-------+----+-------+----+-----+-----+-------------+-------------
|
||||
1 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | hello world |
|
||||
2 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | |
|
||||
3 | char20 | | vc3 | vc3 vc4 | vc210 | | c31 | | c33 | c34 | hello world | hello world
|
||||
(3 rows)
|
||||
|
||||
-- test time type
|
||||
create table time_default_t(
|
||||
|
@ -284,39 +169,25 @@ create table time_default_t(
|
|||
c12 time with time zone default current_time,
|
||||
c13 time
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "time_default_t_n_seq" for serial column "time_default_t.n"
|
||||
|
||||
insert into time_default_t values(1);
|
||||
insert into time_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
|
||||
insert into time_default_t values(3, default, c1, default, c3, default, default, c6,
|
||||
default, c8, default, c10, default, c12);
|
||||
|
||||
select n, c1, c2, c3, c4, c5 from time_default_t;
|
||||
n | c1 | c2 | c3 | c4 | c5
|
||||
---+--------------------------+--------------------------+------------+------------+----------
|
||||
1 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
|
||||
2 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
|
||||
3 | Mon Dec 12 22:22:22 2022 | Mon Dec 12 22:22:22 2022 | 12-12-2022 | 12-12-2022 | 22:22:22
|
||||
(3 rows)
|
||||
|
||||
select (c6 is not null) as c6_is_not_null,
|
||||
(c8 is not null) as c8_is_not_null,
|
||||
(c10 is not null) as c10_is_not_null,
|
||||
(c12 is not null) as c12_is_not_null
|
||||
from time_default_t where n = 1 or n = 3;
|
||||
c6_is_not_null | c8_is_not_null | c10_is_not_null | c12_is_not_null
|
||||
----------------+----------------+-----------------+-----------------
|
||||
t | t | t | t
|
||||
t | t | t | t
|
||||
(2 rows)
|
||||
|
||||
select (c6 is not null) c6_is_not_null,
|
||||
(c8 is null) as c8_is_null,
|
||||
(c10 is null) as c10_is_null,
|
||||
(c12 is null) as c12_is_null
|
||||
from time_default_t where n = 2;
|
||||
c6_is_not_null | c8_is_null | c10_is_null | c12_is_null
|
||||
----------------+------------+-------------+-------------
|
||||
t | t | t | t
|
||||
(1 row)
|
||||
|
||||
select (c1=c2) as c1c2,
|
||||
(c3=c4) as c3c4,
|
||||
|
@ -325,10 +196,183 @@ select (c1=c2) as c1c2,
|
|||
(c10=c11) as c10c11,
|
||||
(c12=c13) as c12c13
|
||||
from time_default_t where n = 3;
|
||||
c1c2 | c3c4 | c6c7 | c8c9 | c10c11 | c12c13
|
||||
------+------+------+------+--------+--------
|
||||
t | t | t | t | t | t
|
||||
(1 row)
|
||||
|
||||
-- test num type not null
|
||||
create table num_notnull_t (
|
||||
n serial not null,
|
||||
c1 int not null,
|
||||
c2 int not null,
|
||||
c3 tinyint not null,
|
||||
c4 tinyint not null,
|
||||
c5 smallint not null,
|
||||
c6 smallint not null,
|
||||
c7 integer not null,
|
||||
c8 integer not null,
|
||||
c9 binary_integer not null,
|
||||
c10 bigint not null,
|
||||
c11 bigint not null,
|
||||
c12 boolean not null,
|
||||
c13 boolean not null,
|
||||
c14 numeric not null,
|
||||
c15 numeric(10, 3) not null,
|
||||
c16 decimal not null,
|
||||
c17 dec(21, 6) not null,
|
||||
c18 double precision not null,
|
||||
c19 float8 not null,
|
||||
c20 float not null,
|
||||
c21 float(10) not null,
|
||||
c22 float(9) not null,
|
||||
c23 float(53) not null,
|
||||
c24 float(1) not null
|
||||
);
|
||||
|
||||
insert into num_notnull_t values(n,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24);
|
||||
insert into num_notnull_t values(n,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24);
|
||||
select * from num_notnull_t;
|
||||
|
||||
-- test char type not null
|
||||
create table char_notnull_t(
|
||||
c1 char(10) not null,
|
||||
c2 char(10),
|
||||
c3 varchar(20) not null,
|
||||
c4 varchar(20),
|
||||
c5 varchar2(20) not null,
|
||||
c6 varchar2(20),
|
||||
c7 nchar(20) not null,
|
||||
c8 nchar(20),
|
||||
c9 nvarchar2(20) not null,
|
||||
c10 nvarchar(20),
|
||||
c11 varchar(20) not null,
|
||||
c12 varchar(20)
|
||||
);
|
||||
insert into char_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11, concat(c11, 'display'));
|
||||
insert into char_notnull_t values(c1 + 66,
|
||||
c2 + 88,
|
||||
concat(c3, 'display'),
|
||||
concat(c4, 'not display'),
|
||||
concat(c5, 'display'),
|
||||
concat(c6, 'not display'),
|
||||
concat(c7, 'display'),
|
||||
concat(c8, 'not display'),
|
||||
concat(c5, ' display'), -- ref after
|
||||
concat(c10, 'not display'),
|
||||
concat(c5, ' display'),
|
||||
concat(c2, ' not display')); -- ref before
|
||||
select * from char_notnull_t;
|
||||
|
||||
-- test time type not null
|
||||
create table time_notnull_t(
|
||||
c1 date not null,
|
||||
c2 time(6) without time zone not null,
|
||||
c3 time with time zone not null,
|
||||
c4 time(5) with time zone not null,
|
||||
c5 timestamp not null,
|
||||
c6 timestamp without time zone not null,
|
||||
c7 timestamp(4) without time zone not null,
|
||||
c8 timestamp with time zone not null,
|
||||
c9 timestamp(3) with time zone not null,
|
||||
c10 smalldatetime not null,
|
||||
c11 interval year not null,
|
||||
c12 interval month (6) not null,
|
||||
c13 interval day (5) not null,
|
||||
c14 interval hour (4) not null,
|
||||
c15 interval minute (3) not null,
|
||||
c16 interval second (2) not null,
|
||||
c17 interval day (2) to second (2) not null,
|
||||
c18 interval day to hour not null,
|
||||
c19 interval day to minute not null,
|
||||
c20 interval hour to minute not null,
|
||||
c21 interval hour to second not null,
|
||||
c22 interval minute to second not null,
|
||||
c23 reltime not null,
|
||||
c24 abstime not null
|
||||
);
|
||||
|
||||
insert into time_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
|
||||
c16,c17,c18,c19, c20, c21, c22, c23, c24);
|
||||
select * from time_notnull_t;
|
||||
|
||||
-- test custom types
|
||||
create type TestEnum as enum ('ok', 'ook','ruok');
|
||||
create type TestEnum2 as enum ('ok2', 'ook2','ruok2');
|
||||
create type TestEnum3 as enum ();
|
||||
create type TestCom as (c1 int, c2 date[], c3 point);
|
||||
create type TestCom2 as (c1 int, c2 date[], c3 point);
|
||||
|
||||
create table enum_set_notnull_t(
|
||||
c1 TestEnum not null,
|
||||
c2 TestEnum2 not null,
|
||||
c3 set('666') not null,
|
||||
c4 set('hello', 'world') not null
|
||||
);
|
||||
insert into enum_set_notnull_t values(c1, c2, c3, c4);
|
||||
select * from enum_set_notnull_t;
|
||||
|
||||
-- test empty enu, other custom types should fail
|
||||
create table custom_notnull_t(
|
||||
c0 TestEnum3 not null,
|
||||
c1 TestEnum not null,
|
||||
c2 TestEnum2 not null,
|
||||
c3 TestCom not null,
|
||||
c4 TestCom2 not null,
|
||||
c5 int[] not null,
|
||||
c6 blob[][] not null
|
||||
);
|
||||
insert into custom_notnull_t values(c0, c1, c2, c3, c4, c5, c6);
|
||||
select * from custom_notnull_t;
|
||||
|
||||
-- test rest other types not null
|
||||
create table other_notnull_t(
|
||||
c1 money not null,
|
||||
c2 int4range not null,
|
||||
c3 BLOB not null,
|
||||
c4 RAW not null,
|
||||
c5 BYTEA not null,
|
||||
c6 point not null,
|
||||
c7 lseg not null,
|
||||
c8 box not null,
|
||||
c9 path not null,
|
||||
c10 polygon not null,
|
||||
c11 circle not null,
|
||||
c12 cidr not null,
|
||||
c13 inet not null,
|
||||
c14 macaddr not null,
|
||||
c15 BIT(3) not null,
|
||||
c16 BIT VARYING(5) not null,
|
||||
c17 UUID not null,
|
||||
c18 json not null,
|
||||
c19 jsonb not null,
|
||||
c20 int8range not null,
|
||||
c21 numrange not null,
|
||||
c22 tsrange not null,
|
||||
c23 tstzrange not null,
|
||||
c24 daterange not null,
|
||||
c25 hll not null,
|
||||
c26 hll(12, 4) not null,
|
||||
c27 SET('beijing','shanghai','nanjing','wuhan') not null,
|
||||
c28 tsvector not null,
|
||||
c29 tsquery not null,
|
||||
c30 HASH16 not null,
|
||||
c31 HASH32 not null,
|
||||
c32 SET('66') not null
|
||||
);
|
||||
insert into other_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
|
||||
c16,c17,c18,c19, c20, c21, c22, c23, c24, c25, c26,
|
||||
c27, c28, c29, c30, c31, c32);
|
||||
insert into other_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
|
||||
c16,c17,c18,c19, c20, c21, c22, c23, c24, c25, c26,
|
||||
concat(c27 ,'beijing'), c28, c29, c30, c31, c32);
|
||||
select * from other_notnull_t;
|
||||
|
||||
-- jdbc case
|
||||
DROP USER IF EXISTS rightref CASCADE;
|
||||
CREATE USER rightref WITH PASSWORD 'rightref@123';
|
||||
SET ROLE rightref PASSWORD 'rightref@123';
|
||||
\! chmod -R 700 @abs_bindir@/../jre
|
||||
\! @abs_bindir@/../jre/bin/java -cp $CLASSPATH:@abs_builddir@/jdbc_test/gsjdbc400.jar:@abs_builddir@/jdbc_test/insert_right_ref/. InsertRightRefTest localhost @portstring@ rightref rightref rightref@123
|
||||
RESET ROLE;
|
||||
DROP USER IF EXISTS rightref CASCADE;
|
||||
|
||||
\c postgres
|
||||
|
||||
drop database rightref;
|
Binary file not shown.
|
@ -0,0 +1,235 @@
|
|||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* test Case for insert stament with right value references
|
||||
*/
|
||||
public class InsertRightRefTest {
|
||||
private static final String DEFAULT_DRIVER_NAME = "org.postgresql.Driver";
|
||||
private static final String DEFAULT_DATABASE = "regression";
|
||||
private static final String DEFAULT_HOST = "localhost";
|
||||
private static final String DEFAULT_PORT = "";
|
||||
private static final String DEFAULT_USER_NAME = "";
|
||||
private static final String DEFAULT_PASSWORD = "";
|
||||
private static final int MAX_ROW = 50;
|
||||
|
||||
private final Connection con;
|
||||
private final StringBuilder outputBuffer;
|
||||
|
||||
InsertRightRefTest(Connection con) {
|
||||
this.con = con;
|
||||
outputBuffer = new StringBuilder();
|
||||
}
|
||||
|
||||
/**
|
||||
* main programme
|
||||
*
|
||||
* @param args args[0]: host
|
||||
* args[1]: port
|
||||
* args[2]: database
|
||||
* args[3]: user name
|
||||
* args[4]: password
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
try (Connection con = getConnection(args)) {
|
||||
new InsertRightRefTest(con).runTestCases();
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
static Connection getConnection(String[] args) throws SQLException, ClassNotFoundException {
|
||||
Class.forName(DEFAULT_DRIVER_NAME);
|
||||
String host = (args != null && args.length > 0) ? args[0] : DEFAULT_HOST;
|
||||
String port = (args != null && args.length > 1) ? args[1] : DEFAULT_PORT;
|
||||
String database = (args != null && args.length > 2) ? args[2] : DEFAULT_DATABASE;
|
||||
String name = (args != null && args.length > 3) ? args[3] : DEFAULT_USER_NAME;
|
||||
String password = (args != null && args.length > 4) ? args[4] : DEFAULT_PASSWORD;
|
||||
String url = "jdbc:postgresql://" + host + ":" + port + "/" + database + "?prepareThreshold=0&loggerLevel=off";
|
||||
|
||||
return DriverManager.getConnection(url, name, password);
|
||||
}
|
||||
|
||||
void runTestCases() {
|
||||
// case 1: base test
|
||||
execute("drop table if exists auto_increment_t;");
|
||||
execute("create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);");
|
||||
execute("insert into auto_increment_t values(1, c1, c1, c1);");
|
||||
String[] batch = {"insert into auto_increment_t values(2, 0, c1, c1);",
|
||||
"insert into auto_increment_t values(3, 0, c1, c1);",
|
||||
"insert into auto_increment_t values(4, -1, c1, c1);",
|
||||
"insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);",
|
||||
"insert into auto_increment_t values(5, c1, c1, c1);"};
|
||||
executeBatch(batch);
|
||||
select("select * from auto_increment_t order by n;", "n", "c1", "c2", "c3");
|
||||
execute("drop table auto_increment_t;");
|
||||
|
||||
execute("create table char_default_t(\n" +
|
||||
" n serial,\n" +
|
||||
" c1 char(10) default 'char20',\n" +
|
||||
" c2 char(10),\n" +
|
||||
" c3 varchar(10) default 'vc3',\n" +
|
||||
" c4 varchar(20),\n" +
|
||||
" c5 varchar2(10) default 'vc210',\n" +
|
||||
" c6 varchar2(20),\n" +
|
||||
" c7 nchar(5) default 'c31',\n" +
|
||||
" c8 nchar(5),\n" +
|
||||
" c9 nvarchar2(5) default 'c33',\n" +
|
||||
" c10 nvarchar(5) default 'c34',\n" +
|
||||
" c11 varchar(20) default concat('hello', ' world'),\n" +
|
||||
" c12 varchar(20)\n" +
|
||||
");");
|
||||
execute("insert into char_default_t values(1);\n" +
|
||||
"insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);\n" +
|
||||
"insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);");
|
||||
select("select * from char_default_t;",
|
||||
"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12");
|
||||
execute("drop table if exists char_default_t");
|
||||
|
||||
// case 2: upsert
|
||||
execute("drop table if exists upser;");
|
||||
execute("create table upser(c1 int, c2 int, c3 int);");
|
||||
execute("create unique index idx_upser_c1 on upser(c1);");
|
||||
executeBatch("insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10),\n" +
|
||||
" (6, 10, 10), (7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);",
|
||||
"insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100),(9, 100, 100),\n" +
|
||||
" (10, 100, 100), (11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)\n" +
|
||||
" on duplicate key update c2 = c1 + c2, c3 = c2 + c3;");
|
||||
select("select * from upser order by c1;", "c1", "c2", "c3");
|
||||
executeBatch("truncate upser;",
|
||||
"insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), \n" +
|
||||
"(6, 10, 10), (7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);",
|
||||
"insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100), \n" +
|
||||
"(8, c1 + 100, 100), (9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100),\n" +
|
||||
"(12, c1 + 100, 100), (13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)\n" +
|
||||
"on duplicate key update c2 = c1 + c2, c3 = c2 + c3;");
|
||||
select("select * from upser order by c1;", "c1", "c2", "c3");
|
||||
execute("drop table upser;");
|
||||
|
||||
// case 3: var & function
|
||||
execute("drop table if exists with_var;");
|
||||
execute("drop function if exists with_var_func;");
|
||||
execute("create table with_var(a int default 999);");
|
||||
execute("create function with_var_func() return int as\n" +
|
||||
"declare \n" +
|
||||
" a int := 666;\n" +
|
||||
"begin\n" +
|
||||
" insert into with_var values(a);\n" +
|
||||
" return a;\n" +
|
||||
"end;\n" +
|
||||
"/");
|
||||
executeBatch("call with_var_func();",
|
||||
"call with_var_func();",
|
||||
"call with_var_func();");
|
||||
select("select * from with_var;", "a");
|
||||
executeBatch("drop function with_var_func;",
|
||||
"drop table with_var;");
|
||||
// case 4: custum types
|
||||
execute("create table custom_notnull_t(\n" +
|
||||
" c0 TestEnum3 not null, \n" +
|
||||
" c1 TestEnum not null,\n" +
|
||||
" c2 TestEnum2 not null,\n" +
|
||||
" c3 TestCom not null,\n" +
|
||||
" c4 TestCom2 not null,\n" +
|
||||
" c5 int[] not null,\n" +
|
||||
" c6 blob[][] not null\n" +
|
||||
");");
|
||||
execute("insert into custom_notnull_t values(c0, c1, c2, c3, c4, c5, c6);");
|
||||
select("select * from custom_notnull_t;", "c0", "c1", "c2", "c3", "c4", "c5", "c6");
|
||||
// case 5: set, enum
|
||||
execute("create table enum_set_notnull_t(\n" +
|
||||
" c1 TestEnum not null,\n" +
|
||||
" c2 TestEnum2 not null,\n" +
|
||||
" c3 set('666') not null,\n" +
|
||||
" c4 set('hello', 'world') not null\n" +
|
||||
");\n" +
|
||||
"insert into enum_set_notnull_t values(c1, c2, c3, c4);");
|
||||
select("select * from enum_set_notnull_t;", "c1", "c2", "c3", "c4");
|
||||
}
|
||||
|
||||
void select(String sql, String... fields) {
|
||||
System.out.println(sql);
|
||||
try (Statement stmt = con.createStatement();
|
||||
ResultSet rs = stmt.executeQuery(sql)) {
|
||||
int[] maxWidths = new int[fields.length];
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
maxWidths[i] = fields[i].length();
|
||||
}
|
||||
|
||||
int cnt = 0;
|
||||
List<String[]> data = new ArrayList<>();
|
||||
while (cnt++ < MAX_ROW && rs.next()) {
|
||||
String[] row = new String[fields.length];
|
||||
for (int i = 0; i < fields.length; i++) {
|
||||
row[i] = rs.getString(fields[i]);
|
||||
if (row[i] == null) {
|
||||
row[i] = "?_?";
|
||||
}
|
||||
if (row[i].length() > maxWidths[i]) {
|
||||
maxWidths[i] = row[i].length();
|
||||
}
|
||||
}
|
||||
data.add(row);
|
||||
}
|
||||
|
||||
printRow(maxWidths, fields);
|
||||
printSeparator(maxWidths);
|
||||
for (String[] row : data) {
|
||||
printRow(maxWidths, row);
|
||||
}
|
||||
if (data.size() == 1) {
|
||||
System.out.println("(1 row)");
|
||||
} else {
|
||||
System.out.println("(" + data.size() + " rows)");
|
||||
}
|
||||
System.out.println();
|
||||
} catch (SQLException exception) {
|
||||
System.err.println(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void execute(String sql) {
|
||||
System.out.println(sql);
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
stmt.execute(sql);
|
||||
} catch (SQLException exception) {
|
||||
System.err.println(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void executeBatch(String... sqls) {
|
||||
try (Statement stmt = con.createStatement()) {
|
||||
for (String sql : sqls) {
|
||||
stmt.addBatch(sql);
|
||||
System.out.println(sql);
|
||||
}
|
||||
stmt.executeBatch();
|
||||
} catch (SQLException exception) {
|
||||
System.err.println(exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void printRow(int[] maxWidths, String[] values) {
|
||||
outputBuffer.append("|");
|
||||
for (int i = 0; i < maxWidths.length; i++) {
|
||||
outputBuffer.append(String.format(" %-" + maxWidths[i] + "s |", values[i]));
|
||||
}
|
||||
System.out.println(outputBuffer);
|
||||
outputBuffer.delete(0, outputBuffer.length());
|
||||
}
|
||||
|
||||
void printSeparator(int[] maxWidths) {
|
||||
for (int maxWidth : maxWidths) {
|
||||
String format = String.format("+-%-" + maxWidth + "s-", '-').replaceAll(" ", "-");
|
||||
outputBuffer.append(format);
|
||||
}
|
||||
outputBuffer.append("+");
|
||||
System.out.println(outputBuffer);
|
||||
outputBuffer.delete(0, outputBuffer.length());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,697 @@
|
|||
create database rightref with dbcompatibility 'B';
|
||||
\c rightref
|
||||
-- test fields order
|
||||
create table test_order_t(n1 int default 100, n2 int default 100, s int);
|
||||
insert into test_order_t values(1000, 1000, n1 + n2);
|
||||
insert into test_order_t(s, n1, n2) values(n1 + n2, 300, 300);
|
||||
select * from test_order_t;
|
||||
n1 | n2 | s
|
||||
------+------+------
|
||||
1000 | 1000 | 2000
|
||||
300 | 300 | 200
|
||||
(2 rows)
|
||||
|
||||
drop table test_order_t;
|
||||
-- test non-idempotent function
|
||||
create table non_idempotent_t(c1 float, c2 float, c3 float);
|
||||
insert into non_idempotent_t values(random(), c1, c1);
|
||||
select c1 = c2 as f1, c1 = c3 as f2 from non_idempotent_t;
|
||||
f1 | f2
|
||||
----+----
|
||||
t | t
|
||||
(1 row)
|
||||
|
||||
drop table non_idempotent_t;
|
||||
-- test auto increment
|
||||
create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "auto_increment_t_c1_seq" for serial column "auto_increment_t.c1"
|
||||
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "auto_increment_t_pkey" for table "auto_increment_t"
|
||||
insert into auto_increment_t values(1, c1, c1, c1);
|
||||
insert into auto_increment_t values(2, 0, c1, c1);
|
||||
insert into auto_increment_t values(3, 0, c1, c1);
|
||||
insert into auto_increment_t values(4, -1, c1, c1);
|
||||
insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);
|
||||
insert into auto_increment_t values(5, c1, c1, c1);
|
||||
select * from auto_increment_t order by n;
|
||||
n | c1 | c2 | c3
|
||||
---+------+----+----
|
||||
1 | 1 | 0 | 0
|
||||
2 | 2 | 0 | 0
|
||||
3 | 3 | 0 | 0
|
||||
4 | -1 | -1 | -1
|
||||
5 | 1000 | 0 | 0
|
||||
5 | 1001 | 0 | 0
|
||||
(6 rows)
|
||||
|
||||
drop table auto_increment_t;
|
||||
-- test series
|
||||
create table test_series_t(c1 int, c2 int, c3 int);
|
||||
insert into test_series_t values(c2 + 10, generate_series(1, 10), c2 * 2);
|
||||
select * from test_series_t;
|
||||
c1 | c2 | c3
|
||||
----+----+----
|
||||
| 1 | 2
|
||||
| 2 | 4
|
||||
| 3 | 6
|
||||
| 4 | 8
|
||||
| 5 | 10
|
||||
| 6 | 12
|
||||
| 7 | 14
|
||||
| 8 | 16
|
||||
| 9 | 18
|
||||
| 10 | 20
|
||||
(10 rows)
|
||||
|
||||
drop table test_series_t;
|
||||
-- test upsert
|
||||
-- 1
|
||||
create table upser(c1 int, c2 int, c3 int);
|
||||
create unique index idx_upser_c1 on upser(c1);
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10), (7, 10, 10),
|
||||
(8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100), (9, 100, 100), (10, 100, 100),
|
||||
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
|
||||
on duplicate key update c2 = 2000, c3 = 2000;
|
||||
select * from upser order by c1;
|
||||
c1 | c2 | c3
|
||||
----+------+------
|
||||
1 | 10 | 10
|
||||
2 | 10 | 10
|
||||
3 | 10 | 10
|
||||
4 | 10 | 10
|
||||
5 | 2000 | 2000
|
||||
6 | 2000 | 2000
|
||||
7 | 2000 | 2000
|
||||
8 | 2000 | 2000
|
||||
9 | 2000 | 2000
|
||||
10 | 2000 | 2000
|
||||
11 | 100 | 100
|
||||
12 | 100 | 100
|
||||
13 | 100 | 100
|
||||
14 | 100 | 100
|
||||
15 | 100 | 100
|
||||
(15 rows)
|
||||
|
||||
-- 2
|
||||
truncate upser;
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10), (7, 10, 10),
|
||||
(8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100), (9, 100, 100), (10, 100, 100),
|
||||
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
|
||||
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
|
||||
select * from upser order by c1;
|
||||
c1 | c2 | c3
|
||||
----+-----+-----
|
||||
1 | 10 | 10
|
||||
2 | 10 | 10
|
||||
3 | 10 | 10
|
||||
4 | 10 | 10
|
||||
5 | 15 | 25
|
||||
6 | 16 | 26
|
||||
7 | 17 | 27
|
||||
8 | 18 | 28
|
||||
9 | 19 | 29
|
||||
10 | 20 | 30
|
||||
11 | 100 | 100
|
||||
12 | 100 | 100
|
||||
13 | 100 | 100
|
||||
14 | 100 | 100
|
||||
15 | 100 | 100
|
||||
(15 rows)
|
||||
|
||||
-- 3
|
||||
truncate upser;
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10),
|
||||
(7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100), (8, c1 + 100, 100),
|
||||
(9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100), (12, c1 + 100, 100),
|
||||
(13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)
|
||||
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
|
||||
select * from upser order by c1;
|
||||
c1 | c2 | c3
|
||||
----+-----+-----
|
||||
1 | 10 | 10
|
||||
2 | 10 | 10
|
||||
3 | 10 | 10
|
||||
4 | 10 | 10
|
||||
5 | 15 | 25
|
||||
6 | 16 | 26
|
||||
7 | 17 | 27
|
||||
8 | 18 | 28
|
||||
9 | 19 | 29
|
||||
10 | 20 | 30
|
||||
11 | 111 | 100
|
||||
12 | 112 | 100
|
||||
13 | 113 | 100
|
||||
14 | 114 | 100
|
||||
15 | 115 | 130
|
||||
(15 rows)
|
||||
|
||||
drop table upser;
|
||||
-- test var
|
||||
create table with_var(a int default 999);
|
||||
create function with_var_func() return int as
|
||||
declare
|
||||
a int := 666;
|
||||
begin
|
||||
insert into with_var values(a);
|
||||
return a;
|
||||
end;
|
||||
/
|
||||
call with_var_func();
|
||||
with_var_func
|
||||
---------------
|
||||
666
|
||||
(1 row)
|
||||
|
||||
select * from with_var;
|
||||
a
|
||||
-----
|
||||
666
|
||||
(1 row)
|
||||
|
||||
drop function with_var_func;
|
||||
drop table with_var;
|
||||
-- test num type
|
||||
create table num_default_t (
|
||||
n serial,
|
||||
c1 int default 1,
|
||||
c2 int,
|
||||
c3 tinyint default 3,
|
||||
c4 tinyint,
|
||||
c5 smallint default 5,
|
||||
c6 smallint,
|
||||
c7 integer default 7,
|
||||
c8 integer,
|
||||
c9 binary_integer default 9,
|
||||
c10 bigint default 10,
|
||||
c11 bigint,
|
||||
c12 boolean default true,
|
||||
c13 boolean,
|
||||
c14 numeric default 14.,
|
||||
c15 numeric(10, 3) default 15.,
|
||||
c16 decimal default 16,
|
||||
c17 decimal(10, 2) default 17,
|
||||
c18 double precision default 18,
|
||||
c19 float8,
|
||||
c20 float default 100 / 10,
|
||||
c21 float default 20 * (100 + 2) - 3,
|
||||
c22 float default random(),
|
||||
c23 float default random() * 100,
|
||||
c24 float
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "num_default_t_n_seq" for serial column "num_default_t.n"
|
||||
insert into num_default_t values(1);
|
||||
insert into num_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c24);
|
||||
insert into num_default_t values(3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c20);
|
||||
insert into num_default_t(n, c23, c24) values(4, default, c23);
|
||||
select 3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21
|
||||
from num_default_t;
|
||||
?column? | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21
|
||||
----------+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+--------+-----+-------+-----+-----+-----+------
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | | 2037
|
||||
3 | 1 | | 3 | | 5 | | 7 | | 9 | 10 | | t | | 14 | 15.000 | 16 | 17.00 | 18 | | 10 | 2037
|
||||
(4 rows)
|
||||
|
||||
select (c23 = c24) as equal from num_default_t where n = 4;
|
||||
equal
|
||||
-------
|
||||
t
|
||||
(1 row)
|
||||
|
||||
select (c22 is null) as c22_is_null, (c23 is null) as c23_is_null from num_default_t where n = 2 or n = 3;
|
||||
c22_is_null | c23_is_null
|
||||
-------------+-------------
|
||||
t | t
|
||||
t | t
|
||||
(2 rows)
|
||||
|
||||
select (c22 is not null) as c22_is_not_null, (c23 is not null) as c23_is_not_null from num_default_t where n = 1;
|
||||
c22_is_not_null | c23_is_not_null
|
||||
-----------------+-----------------
|
||||
t | t
|
||||
(1 row)
|
||||
|
||||
-- test char type
|
||||
create table char_default_t(
|
||||
n serial,
|
||||
c1 char(10) default 'char20',
|
||||
c2 char(10),
|
||||
c3 varchar(10) default 'vc3',
|
||||
c4 varchar(20),
|
||||
c5 varchar2(10) default 'vc210',
|
||||
c6 varchar2(20),
|
||||
c7 nchar(5) default 'c31',
|
||||
c8 nchar(5),
|
||||
c9 nvarchar2(5) default 'c33',
|
||||
c10 nvarchar(5) default 'c34',
|
||||
c11 varchar(20) default concat('hello', ' world'),
|
||||
c12 varchar(20)
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "char_default_t_n_seq" for serial column "char_default_t.n"
|
||||
insert into char_default_t values(1);
|
||||
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
|
||||
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
|
||||
select * from char_default_t;
|
||||
n | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12
|
||||
---+------------+----+-----+---------+-------+----+-------+----+-----+-----+-------------+-------------
|
||||
1 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | hello world |
|
||||
2 | char20 | | vc3 | | vc210 | | c31 | | c33 | c34 | |
|
||||
3 | char20 | | vc3 | vc3 vc4 | vc210 | | c31 | | c33 | c34 | hello world | hello world
|
||||
(3 rows)
|
||||
|
||||
-- test time type
|
||||
create table time_default_t(
|
||||
n serial,
|
||||
c1 timestamp default '2022-12-12 22:22:22',
|
||||
c2 timestamp,
|
||||
c3 date default '2022-12-12',
|
||||
c4 date,
|
||||
c5 time default '22:22:22',
|
||||
c6 date default current_date,
|
||||
c7 date,
|
||||
c8 timestamp default current_timestamp,
|
||||
c9 timestamp,
|
||||
c10 time default current_time,
|
||||
c11 time,
|
||||
c12 time with time zone default current_time,
|
||||
c13 time
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "time_default_t_n_seq" for serial column "time_default_t.n"
|
||||
insert into time_default_t values(1);
|
||||
insert into time_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
|
||||
insert into time_default_t values(3, default, c1, default, c3, default, default, c6,
|
||||
default, c8, default, c10, default, c12);
|
||||
select n, c1, c2, c3, c4, c5 from time_default_t;
|
||||
n | c1 | c2 | c3 | c4 | c5
|
||||
---+--------------------------+--------------------------+------------+------------+----------
|
||||
1 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
|
||||
2 | Mon Dec 12 22:22:22 2022 | | 12-12-2022 | | 22:22:22
|
||||
3 | Mon Dec 12 22:22:22 2022 | Mon Dec 12 22:22:22 2022 | 12-12-2022 | 12-12-2022 | 22:22:22
|
||||
(3 rows)
|
||||
|
||||
select (c6 is not null) as c6_is_not_null,
|
||||
(c8 is not null) as c8_is_not_null,
|
||||
(c10 is not null) as c10_is_not_null,
|
||||
(c12 is not null) as c12_is_not_null
|
||||
from time_default_t where n = 1 or n = 3;
|
||||
c6_is_not_null | c8_is_not_null | c10_is_not_null | c12_is_not_null
|
||||
----------------+----------------+-----------------+-----------------
|
||||
t | t | t | t
|
||||
t | t | t | t
|
||||
(2 rows)
|
||||
|
||||
select (c6 is not null) c6_is_not_null,
|
||||
(c8 is null) as c8_is_null,
|
||||
(c10 is null) as c10_is_null,
|
||||
(c12 is null) as c12_is_null
|
||||
from time_default_t where n = 2;
|
||||
c6_is_not_null | c8_is_null | c10_is_null | c12_is_null
|
||||
----------------+------------+-------------+-------------
|
||||
t | t | t | t
|
||||
(1 row)
|
||||
|
||||
select (c1=c2) as c1c2,
|
||||
(c3=c4) as c3c4,
|
||||
(c6=c7) as c6c7,
|
||||
(c8=c9) as c8c9,
|
||||
(c10=c11) as c10c11,
|
||||
(c12=c13) as c12c13
|
||||
from time_default_t where n = 3;
|
||||
c1c2 | c3c4 | c6c7 | c8c9 | c10c11 | c12c13
|
||||
------+------+------+------+--------+--------
|
||||
t | t | t | t | t | t
|
||||
(1 row)
|
||||
|
||||
-- test num type not null
|
||||
create table num_notnull_t (
|
||||
n serial not null,
|
||||
c1 int not null,
|
||||
c2 int not null,
|
||||
c3 tinyint not null,
|
||||
c4 tinyint not null,
|
||||
c5 smallint not null,
|
||||
c6 smallint not null,
|
||||
c7 integer not null,
|
||||
c8 integer not null,
|
||||
c9 binary_integer not null,
|
||||
c10 bigint not null,
|
||||
c11 bigint not null,
|
||||
c12 boolean not null,
|
||||
c13 boolean not null,
|
||||
c14 numeric not null,
|
||||
c15 numeric(10, 3) not null,
|
||||
c16 decimal not null,
|
||||
c17 dec(21, 6) not null,
|
||||
c18 double precision not null,
|
||||
c19 float8 not null,
|
||||
c20 float not null,
|
||||
c21 float(10) not null,
|
||||
c22 float(9) not null,
|
||||
c23 float(53) not null,
|
||||
c24 float(1) not null
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit sequence "num_notnull_t_n_seq" for serial column "num_notnull_t.n"
|
||||
insert into num_notnull_t values(n,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24);
|
||||
insert into num_notnull_t values(n,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16,c17,c18,c19,c20,c21,c22,c23,c24);
|
||||
select * from num_notnull_t;
|
||||
n | c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21 | c22 | c23 | c24
|
||||
---+----+----+----+----+----+----+----+----+----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----
|
||||
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | f | f | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
|
||||
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | f | f | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0
|
||||
(2 rows)
|
||||
|
||||
-- test char type not null
|
||||
create table char_notnull_t(
|
||||
c1 char(10) not null,
|
||||
c2 char(10),
|
||||
c3 varchar(20) not null,
|
||||
c4 varchar(20),
|
||||
c5 varchar2(20) not null,
|
||||
c6 varchar2(20),
|
||||
c7 nchar(20) not null,
|
||||
c8 nchar(20),
|
||||
c9 nvarchar2(20) not null,
|
||||
c10 nvarchar(20),
|
||||
c11 varchar(20) not null,
|
||||
c12 varchar(20)
|
||||
);
|
||||
insert into char_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11, concat(c11, 'display'));
|
||||
insert into char_notnull_t values(c1 + 66,
|
||||
c2 + 88,
|
||||
concat(c3, 'display'),
|
||||
concat(c4, 'not display'),
|
||||
concat(c5, 'display'),
|
||||
concat(c6, 'not display'),
|
||||
concat(c7, 'display'),
|
||||
concat(c8, 'not display'),
|
||||
concat(c5, ' display'), -- ref after
|
||||
concat(c10, 'not display'),
|
||||
concat(c5, ' display'),
|
||||
concat(c2, ' not display')); -- ref before
|
||||
select * from char_notnull_t;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12
|
||||
------------+----+---------+----+---------+----+----------------------+----+-----------------+-----+-----------------+---------
|
||||
| | | | | | | | | | | display
|
||||
66 | | display | | display | | display | | display display | | display display |
|
||||
(2 rows)
|
||||
|
||||
-- test time type not null
|
||||
create table time_notnull_t(
|
||||
c1 date not null,
|
||||
c2 time(6) without time zone not null,
|
||||
c3 time with time zone not null,
|
||||
c4 time(5) with time zone not null,
|
||||
c5 timestamp not null,
|
||||
c6 timestamp without time zone not null,
|
||||
c7 timestamp(4) without time zone not null,
|
||||
c8 timestamp with time zone not null,
|
||||
c9 timestamp(3) with time zone not null,
|
||||
c10 smalldatetime not null,
|
||||
c11 interval year not null,
|
||||
c12 interval month (6) not null,
|
||||
c13 interval day (5) not null,
|
||||
c14 interval hour (4) not null,
|
||||
c15 interval minute (3) not null,
|
||||
c16 interval second (2) not null,
|
||||
c17 interval day (2) to second (2) not null,
|
||||
c18 interval day to hour not null,
|
||||
c19 interval day to minute not null,
|
||||
c20 interval hour to minute not null,
|
||||
c21 interval hour to second not null,
|
||||
c22 interval minute to second not null,
|
||||
c23 reltime not null,
|
||||
c24 abstime not null
|
||||
);
|
||||
insert into time_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
|
||||
c16,c17,c18,c19, c20, c21, c22, c23, c24);
|
||||
select * from time_notnull_t;
|
||||
--?.*
|
||||
--?.*
|
||||
--?01-01-1970 | 00:00:00 | 00:00:00-08 | 00:00:00-08 | .* | .* | .* | .* | .* | Thu Jan 01 00:00:00 1970 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | @ 0 | .*
|
||||
(1 row)
|
||||
|
||||
-- test custom types
|
||||
create type TestEnum as enum ('ok', 'ook','ruok');
|
||||
create type TestEnum2 as enum ('ok2', 'ook2','ruok2');
|
||||
create type TestEnum3 as enum ();
|
||||
create type TestCom as (c1 int, c2 date[], c3 point);
|
||||
create type TestCom2 as (c1 int, c2 date[], c3 point);
|
||||
create table enum_set_notnull_t(
|
||||
c1 TestEnum not null,
|
||||
c2 TestEnum2 not null,
|
||||
c3 set('666') not null,
|
||||
c4 set('hello', 'world') not null
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit set "enum_set_notnull_t_c3_set" for column "enum_set_notnull_t.c3"
|
||||
NOTICE: CREATE TABLE will create implicit set "enum_set_notnull_t_c4_set" for column "enum_set_notnull_t.c4"
|
||||
insert into enum_set_notnull_t values(c1, c2, c3, c4);
|
||||
select * from enum_set_notnull_t;
|
||||
c1 | c2 | c3 | c4
|
||||
----+-----+----+----
|
||||
ok | ok2 | |
|
||||
(1 row)
|
||||
|
||||
-- test empty enu, other custom types should fail
|
||||
create table custom_notnull_t(
|
||||
c0 TestEnum3 not null,
|
||||
c1 TestEnum not null,
|
||||
c2 TestEnum2 not null,
|
||||
c3 TestCom not null,
|
||||
c4 TestCom2 not null,
|
||||
c5 int[] not null,
|
||||
c6 blob[][] not null
|
||||
);
|
||||
insert into custom_notnull_t values(c0, c1, c2, c3, c4, c5, c6);
|
||||
ERROR: null value in column "c0" violates not-null constraint
|
||||
DETAIL: Failing row contains (null, ok, ok2, null, null, null, null).
|
||||
select * from custom_notnull_t;
|
||||
c0 | c1 | c2 | c3 | c4 | c5 | c6
|
||||
----+----+----+----+----+----+----
|
||||
(0 rows)
|
||||
|
||||
-- test rest other types not null
|
||||
create table other_notnull_t(
|
||||
c1 money not null,
|
||||
c2 int4range not null,
|
||||
c3 BLOB not null,
|
||||
c4 RAW not null,
|
||||
c5 BYTEA not null,
|
||||
c6 point not null,
|
||||
c7 lseg not null,
|
||||
c8 box not null,
|
||||
c9 path not null,
|
||||
c10 polygon not null,
|
||||
c11 circle not null,
|
||||
c12 cidr not null,
|
||||
c13 inet not null,
|
||||
c14 macaddr not null,
|
||||
c15 BIT(3) not null,
|
||||
c16 BIT VARYING(5) not null,
|
||||
c17 UUID not null,
|
||||
c18 json not null,
|
||||
c19 jsonb not null,
|
||||
c20 int8range not null,
|
||||
c21 numrange not null,
|
||||
c22 tsrange not null,
|
||||
c23 tstzrange not null,
|
||||
c24 daterange not null,
|
||||
c25 hll not null,
|
||||
c26 hll(12, 4) not null,
|
||||
c27 SET('beijing','shanghai','nanjing','wuhan') not null,
|
||||
c28 tsvector not null,
|
||||
c29 tsquery not null,
|
||||
c30 HASH16 not null,
|
||||
c31 HASH32 not null,
|
||||
c32 SET('66') not null
|
||||
);
|
||||
NOTICE: CREATE TABLE will create implicit set "other_notnull_t_c27_set" for column "other_notnull_t.c27"
|
||||
NOTICE: CREATE TABLE will create implicit set "other_notnull_t_c32_set" for column "other_notnull_t.c32"
|
||||
insert into other_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
|
||||
c16,c17,c18,c19, c20, c21, c22, c23, c24, c25, c26,
|
||||
c27, c28, c29, c30, c31, c32);
|
||||
insert into other_notnull_t values(c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,
|
||||
c16,c17,c18,c19, c20, c21, c22, c23, c24, c25, c26,
|
||||
concat(c27 ,'beijing'), c28, c29, c30, c31, c32);
|
||||
select * from other_notnull_t;
|
||||
c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 | c13 | c14 | c15 | c16 | c17 | c18 | c19 | c20 | c21 | c22 | c23 | c24 | c25 | c26 | c27 | c28 | c29 | c30 | c31 | c32
|
||||
-------+-------+----+----+----+-------+---------------+-------------+---------+---------+-----------+------------+---------+-------------------+-----+-----+--------------------------------------+------+------+-------+-------+-------+-------+-------+-----+-----+---------+-----+-----+------------------+----------------------------------+-----
|
||||
$0.00 | empty | | | \x | (0,0) | [(0,0),(0,0)] | (0,0),(0,0) | ((0,0)) | ((0,0)) | <(0,0),0> | 0.0.0.0/32 | 0.0.0.0 | 00:00:00:00:00:00 | | | 00000000-0000-0000-0000-000000000000 | null | null | empty | empty | empty | empty | empty | \x | \x | | | | 0000000000000000 | 00000000000000000000000000000000 |
|
||||
$0.00 | empty | | | \x | (0,0) | [(0,0),(0,0)] | (0,0),(0,0) | ((0,0)) | ((0,0)) | <(0,0),0> | 0.0.0.0/32 | 0.0.0.0 | 00:00:00:00:00:00 | | | 00000000-0000-0000-0000-000000000000 | null | null | empty | empty | empty | empty | empty | \x | \x | beijing | | | 0000000000000000 | 00000000000000000000000000000000 |
|
||||
(2 rows)
|
||||
|
||||
-- jdbc case
|
||||
DROP USER IF EXISTS rightref CASCADE;
|
||||
NOTICE: role "rightref" does not exist, skipping
|
||||
CREATE USER rightref WITH PASSWORD 'rightref@123';
|
||||
SET ROLE rightref PASSWORD 'rightref@123';
|
||||
--?.*
|
||||
--?.*
|
||||
drop table if exists auto_increment_t;
|
||||
create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);
|
||||
insert into auto_increment_t values(1, c1, c1, c1);
|
||||
insert into auto_increment_t values(2, 0, c1, c1);
|
||||
insert into auto_increment_t values(3, 0, c1, c1);
|
||||
insert into auto_increment_t values(4, -1, c1, c1);
|
||||
insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);
|
||||
insert into auto_increment_t values(5, c1, c1, c1);
|
||||
select * from auto_increment_t order by n;
|
||||
| n | c1 | c2 | c3 |
|
||||
+---+------+----+----+
|
||||
| 1 | 1 | 0 | 0 |
|
||||
| 2 | 2 | 0 | 0 |
|
||||
| 3 | 3 | 0 | 0 |
|
||||
| 4 | -1 | -1 | -1 |
|
||||
| 5 | 1000 | 0 | 0 |
|
||||
| 5 | 1001 | 0 | 0 |
|
||||
(6 rows)
|
||||
|
||||
drop table auto_increment_t;
|
||||
create table char_default_t(
|
||||
n serial,
|
||||
c1 char(10) default 'char20',
|
||||
c2 char(10),
|
||||
c3 varchar(10) default 'vc3',
|
||||
c4 varchar(20),
|
||||
c5 varchar2(10) default 'vc210',
|
||||
c6 varchar2(20),
|
||||
c7 nchar(5) default 'c31',
|
||||
c8 nchar(5),
|
||||
c9 nvarchar2(5) default 'c33',
|
||||
c10 nvarchar(5) default 'c34',
|
||||
c11 varchar(20) default concat('hello', ' world'),
|
||||
c12 varchar(20)
|
||||
);
|
||||
insert into char_default_t values(1);
|
||||
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
|
||||
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
|
||||
select * from char_default_t;
|
||||
| c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8 | c9 | c10 | c11 | c12 |
|
||||
+------------+-----+-----+---------+-------+-----+-------+-----+-----+-----+-------------+-------------+
|
||||
| char20 | ?_? | vc3 | ?_? | vc210 | ?_? | c31 | ?_? | c33 | c34 | hello world | ?_? |
|
||||
| char20 | ?_? | vc3 | ?_? | vc210 | ?_? | c31 | ?_? | c33 | c34 | ?_? | ?_? |
|
||||
| char20 | ?_? | vc3 | vc3 vc4 | vc210 | ?_? | c31 | ?_? | c33 | c34 | hello world | hello world |
|
||||
(3 rows)
|
||||
|
||||
drop table if exists char_default_t
|
||||
drop table if exists upser;
|
||||
create table upser(c1 int, c2 int, c3 int);
|
||||
create unique index idx_upser_c1 on upser(c1);
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10),
|
||||
(6, 10, 10), (7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100),(9, 100, 100),
|
||||
(10, 100, 100), (11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
|
||||
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
|
||||
select * from upser order by c1;
|
||||
| c1 | c2 | c3 |
|
||||
+----+-----+-----+
|
||||
| 1 | 10 | 10 |
|
||||
| 2 | 10 | 10 |
|
||||
| 3 | 10 | 10 |
|
||||
| 4 | 10 | 10 |
|
||||
| 5 | 15 | 25 |
|
||||
| 6 | 16 | 26 |
|
||||
| 7 | 17 | 27 |
|
||||
| 8 | 18 | 28 |
|
||||
| 9 | 19 | 29 |
|
||||
| 10 | 20 | 30 |
|
||||
| 11 | 100 | 100 |
|
||||
| 12 | 100 | 100 |
|
||||
| 13 | 100 | 100 |
|
||||
| 14 | 100 | 100 |
|
||||
| 15 | 100 | 100 |
|
||||
(15 rows)
|
||||
|
||||
truncate upser;
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10),
|
||||
(6, 10, 10), (7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100),
|
||||
(8, c1 + 100, 100), (9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100),
|
||||
(12, c1 + 100, 100), (13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)
|
||||
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
|
||||
select * from upser order by c1;
|
||||
| c1 | c2 | c3 |
|
||||
+----+-----+-----+
|
||||
| 1 | 10 | 10 |
|
||||
| 2 | 10 | 10 |
|
||||
| 3 | 10 | 10 |
|
||||
| 4 | 10 | 10 |
|
||||
| 5 | 15 | 25 |
|
||||
| 6 | 16 | 26 |
|
||||
| 7 | 17 | 27 |
|
||||
| 8 | 18 | 28 |
|
||||
| 9 | 19 | 29 |
|
||||
| 10 | 20 | 30 |
|
||||
| 11 | 111 | 100 |
|
||||
| 12 | 112 | 100 |
|
||||
| 13 | 113 | 100 |
|
||||
| 14 | 114 | 100 |
|
||||
| 15 | 115 | 130 |
|
||||
(15 rows)
|
||||
|
||||
drop table upser;
|
||||
drop table if exists with_var;
|
||||
drop function if exists with_var_func;
|
||||
create table with_var(a int default 999);
|
||||
create function with_var_func() return int as
|
||||
declare
|
||||
a int := 666;
|
||||
begin
|
||||
insert into with_var values(a);
|
||||
return a;
|
||||
end;
|
||||
/
|
||||
call with_var_func();
|
||||
call with_var_func();
|
||||
call with_var_func();
|
||||
select * from with_var;
|
||||
| a |
|
||||
+-----+
|
||||
| 666 |
|
||||
| 666 |
|
||||
| 666 |
|
||||
(3 rows)
|
||||
|
||||
drop function with_var_func;
|
||||
drop table with_var;
|
||||
create table custom_notnull_t(
|
||||
c0 TestEnum3 not null,
|
||||
c1 TestEnum not null,
|
||||
c2 TestEnum2 not null,
|
||||
c3 TestCom not null,
|
||||
c4 TestCom2 not null,
|
||||
c5 int[] not null,
|
||||
c6 blob[][] not null
|
||||
);
|
||||
insert into custom_notnull_t values(c0, c1, c2, c3, c4, c5, c6);
|
||||
--?.*ERROR: null value in column "c0" violates not-null constraint
|
||||
Detail: Failing row contains (null, ok, ok2, null, null, null, null).
|
||||
select * from custom_notnull_t;
|
||||
| c0 | c1 | c2 | c3 | c4 | c5 | c6 |
|
||||
+----+----+----+----+----+----+----+
|
||||
(0 rows)
|
||||
|
||||
create table enum_set_notnull_t(
|
||||
c1 TestEnum not null,
|
||||
c2 TestEnum2 not null,
|
||||
c3 set('666') not null,
|
||||
c4 set('hello', 'world') not null
|
||||
);
|
||||
insert into enum_set_notnull_t values(c1, c2, c3, c4);
|
||||
select * from enum_set_notnull_t;
|
||||
| c1 | c2 | c3 | c4 |
|
||||
+----+-----+----+----+
|
||||
| ok | ok2 | | |
|
||||
(1 row)
|
||||
|
||||
RESET ROLE;
|
||||
DROP USER IF EXISTS rightref CASCADE;
|
||||
\c postgres
|
||||
drop database rightref;
|
|
@ -1,202 +0,0 @@
|
|||
create database rightref with dbcompatibility 'B';
|
||||
\c rightref
|
||||
|
||||
-- test fields order
|
||||
create table test_order_t(n1 int default 100, n2 int default 100, s int);
|
||||
insert into test_order_t values(1000, 1000, n1 + n2);
|
||||
insert into test_order_t(s, n1, n2) values(n1 + n2, 300, 300);
|
||||
select * from test_order_t;
|
||||
drop table test_order_t;
|
||||
|
||||
-- test non-idempotent function
|
||||
create table non_idempotent_t(c1 float, c2 float, c3 float);
|
||||
insert into non_idempotent_t values(random(), c1, c1);
|
||||
select c1 = c2 as f1, c1 = c3 as f2 from non_idempotent_t;
|
||||
drop table non_idempotent_t;
|
||||
|
||||
-- test auto increment
|
||||
create table auto_increment_t(n int, c1 int primary key auto_increment, c2 int, c3 int);
|
||||
insert into auto_increment_t values(1, c1, c1, c1);
|
||||
insert into auto_increment_t values(2, 0, c1, c1);
|
||||
insert into auto_increment_t values(3, 0, c1, c1);
|
||||
insert into auto_increment_t values(4, -1, c1, c1);
|
||||
insert into auto_increment_t(n, c2, c3, c1) values(5, c1, c1, 1000);
|
||||
insert into auto_increment_t values(5, c1, c1, c1);
|
||||
select * from auto_increment_t order by n;
|
||||
drop table auto_increment_t;
|
||||
|
||||
-- test series
|
||||
create table test_series_t(c1 int, c2 int, c3 int);
|
||||
insert into test_series_t values(c2 + 10, generate_series(1, 10), c2 * 2);
|
||||
select * from test_series_t;
|
||||
drop table test_series_t;
|
||||
|
||||
-- test upsert
|
||||
-- 1
|
||||
create table upser(c1 int, c2 int, c3 int);
|
||||
create unique index idx_upser_c1 on upser(c1);
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10), (7, 10, 10),
|
||||
(8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100), (9, 100, 100), (10, 100, 100),
|
||||
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
|
||||
on duplicate key update c2 = 2000, c3 = 2000;
|
||||
select * from upser order by c1;
|
||||
|
||||
-- 2
|
||||
truncate upser;
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10), (7, 10, 10),
|
||||
(8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
insert into upser values (5, 100, 100), (6, 100, 100), (7, 100, 100), (8, 100, 100), (9, 100, 100), (10, 100, 100),
|
||||
(11, 100, 100), (12, 100, 100), (13, 100, 100), (14, 100, 100), (15, 100, 100)
|
||||
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
|
||||
select * from upser order by c1;
|
||||
|
||||
-- 3
|
||||
truncate upser;
|
||||
insert into upser values (1, 10, 10), (2, 10, 10), (3, 10, 10), (4, 10, 10), (5, 10, 10), (6, 10, 10),
|
||||
(7, 10, 10), (8, 10, 10), (9, 10, 10), (10, 10, 10);
|
||||
|
||||
insert into upser values (5, c1 + 100, 100), (6, c1 + 100, 100), (7, c1 + 100, 100), (8, c1 + 100, 100),
|
||||
(9, c1 + 100, 100), (10, c1 + 100, 100), (11, c1 + 100, 100), (12, c1 + 100, 100),
|
||||
(13, c1 + 100, 100), (14, c1 + 100, 100), (15, c1 + 100, c1 + c2)
|
||||
on duplicate key update c2 = c1 + c2, c3 = c2 + c3;
|
||||
|
||||
select * from upser order by c1;
|
||||
|
||||
drop table upser;
|
||||
|
||||
-- test var
|
||||
create table with_var(a int default 999);
|
||||
create function with_var_func() return int as
|
||||
declare
|
||||
a int := 666;
|
||||
begin
|
||||
insert into with_var values(a);
|
||||
return a;
|
||||
end;
|
||||
/
|
||||
|
||||
call with_var_func();
|
||||
select * from with_var;
|
||||
|
||||
drop function with_var_func;
|
||||
drop table with_var;
|
||||
|
||||
-- test num type
|
||||
create table num_default_t (
|
||||
n serial,
|
||||
c1 int default 1,
|
||||
c2 int,
|
||||
c3 tinyint default 3,
|
||||
c4 tinyint,
|
||||
c5 smallint default 5,
|
||||
c6 smallint,
|
||||
c7 integer default 7,
|
||||
c8 integer,
|
||||
c9 binary_integer default 9,
|
||||
c10 bigint default 10,
|
||||
c11 bigint,
|
||||
c12 boolean default true,
|
||||
c13 boolean,
|
||||
c14 numeric default 14.,
|
||||
c15 numeric(10, 3) default 15.,
|
||||
c16 decimal default 16,
|
||||
c17 decimal(10, 2) default 17,
|
||||
c18 double precision default 18,
|
||||
c19 float8,
|
||||
c20 float default 100 / 10,
|
||||
c21 float default 20 * (100 + 2) - 3,
|
||||
c22 float default random(),
|
||||
c23 float default random() * 100,
|
||||
c24 float
|
||||
);
|
||||
|
||||
insert into num_default_t values(1);
|
||||
insert into num_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c24);
|
||||
insert into num_default_t values(3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20,
|
||||
c21, c22, c23, c20);
|
||||
insert into num_default_t(n, c23, c24) values(4, default, c23);
|
||||
|
||||
select 3, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10,
|
||||
c11, c12, c13, c14, c15, c16, c17, c18, c19, c20, c21
|
||||
from num_default_t;
|
||||
|
||||
select (c23 = c24) as equal from num_default_t where n = 4;
|
||||
select (c22 is null) as c22_is_null, (c23 is null) as c23_is_null from num_default_t where n = 2 or n = 3;
|
||||
select (c22 is not null) as c22_is_not_null, (c23 is not null) as c23_is_not_null from num_default_t where n = 1;
|
||||
|
||||
|
||||
-- test char type
|
||||
create table char_default_t(
|
||||
n serial,
|
||||
c1 char(10) default 'char20',
|
||||
c2 char(10),
|
||||
c3 varchar(10) default 'vc3',
|
||||
c4 varchar(20),
|
||||
c5 varchar2(10) default 'vc210',
|
||||
c6 varchar2(20),
|
||||
c7 nchar(5) default 'c31',
|
||||
c8 nchar(5),
|
||||
c9 nvarchar2(5) default 'c33',
|
||||
c10 nvarchar(5) default 'c34',
|
||||
c11 varchar(20) default concat('hello', ' world'),
|
||||
c12 varchar(20)
|
||||
);
|
||||
|
||||
insert into char_default_t values(1);
|
||||
insert into char_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12);
|
||||
insert into char_default_t values(3, c1, c2, c3, concat(c3, ' vc4'), c5, c6, c7, c8, c9, c10, default, c11);
|
||||
|
||||
select * from char_default_t;
|
||||
|
||||
-- test time type
|
||||
create table time_default_t(
|
||||
n serial,
|
||||
c1 timestamp default '2022-12-12 22:22:22',
|
||||
c2 timestamp,
|
||||
c3 date default '2022-12-12',
|
||||
c4 date,
|
||||
c5 time default '22:22:22',
|
||||
c6 date default current_date,
|
||||
c7 date,
|
||||
c8 timestamp default current_timestamp,
|
||||
c9 timestamp,
|
||||
c10 time default current_time,
|
||||
c11 time,
|
||||
c12 time with time zone default current_time,
|
||||
c13 time
|
||||
);
|
||||
|
||||
insert into time_default_t values(1);
|
||||
insert into time_default_t values(2, c1, c2, c3, c4, c5, c6, c7, c8, c9, c10, c11, c12, c13);
|
||||
insert into time_default_t values(3, default, c1, default, c3, default, default, c6,
|
||||
default, c8, default, c10, default, c12);
|
||||
|
||||
select n, c1, c2, c3, c4, c5 from time_default_t;
|
||||
|
||||
select (c6 is not null) as c6_is_not_null,
|
||||
(c8 is not null) as c8_is_not_null,
|
||||
(c10 is not null) as c10_is_not_null,
|
||||
(c12 is not null) as c12_is_not_null
|
||||
from time_default_t where n = 1 or n = 3;
|
||||
|
||||
select (c6 is not null) c6_is_not_null,
|
||||
(c8 is null) as c8_is_null,
|
||||
(c10 is null) as c10_is_null,
|
||||
(c12 is null) as c12_is_null
|
||||
from time_default_t where n = 2;
|
||||
|
||||
select (c1=c2) as c1c2,
|
||||
(c3=c4) as c3c4,
|
||||
(c6=c7) as c6c7,
|
||||
(c8=c9) as c8c9,
|
||||
(c10=c11) as c10c11,
|
||||
(c12=c13) as c12c13
|
||||
from time_default_t where n = 3;
|
||||
|
||||
\c postgres
|
||||
|
||||
drop database rightref;
|
Loading…
Reference in New Issue